1: /* 2: * Copyright (c) 1982, 1986 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * @(#)boot.c 7.1 (Berkeley) 6/5/86 7: */ 8: 9: #include "../h/param.h" 10: #include "../h/inode.h" 11: #include "../h/fs.h" 12: #include "../h/vm.h" 13: #include <a.out.h> 14: #include "saio.h" 15: #include "../h/reboot.h" 16: 17: /* 18: * Boot program... arguments passed in r10 and r11 determine 19: * whether boot stops to ask for system name and which device 20: * boot comes from. 21: */ 22: 23: /* Types in r10 specifying major device */ 24: char devname[][2] = { 25: 'h','p', /* 0 = hp */ 26: 0,0, /* 1 = ht */ 27: 'u','p', /* 2 = up */ 28: 'h','k', /* 3 = hk */ 29: 0,0, /* 4 = sw */ 30: 0,0, /* 5 = tm */ 31: 0,0, /* 6 = ts */ 32: 0,0, /* 7 = mt */ 33: 0,0, /* 8 = tu */ 34: 'r','a', /* 9 = ra */ 35: 'u','t', /* 10 = ut */ 36: 'r','b', /* 11 = rb */ 37: 0,0, /* 12 = uu */ 38: 0,0, /* 13 = rx */ 39: 'r','l', /* 14 = rl */ 40: }; 41: #define MAXTYPE (sizeof(devname) / sizeof(devname[0])) 42: 43: #define UNIX "vmunix" 44: char line[100]; 45: 46: int retry = 0; 47: 48: main() 49: { 50: register unsigned howto, devtype; /* howto=r11, devtype=r10 */ 51: int io, i; 52: register type, part, unit; 53: register char *cp; 54: long atol(); 55: 56: #ifdef lint 57: howto = 0; devtype = 0; 58: #endif 59: printf("\nBoot\n"); 60: #ifdef JUSTASK 61: howto = RB_ASKNAME|RB_SINGLE; 62: #else 63: type = (devtype >> B_TYPESHIFT) & B_TYPEMASK; 64: unit = (devtype >> B_UNITSHIFT) & B_UNITMASK; 65: unit += 8 * ((devtype >> B_ADAPTORSHIFT) & B_ADAPTORMASK); 66: part = (devtype >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 67: if ((howto & RB_ASKNAME) == 0) { 68: if (type >= 0 && type <= MAXTYPE && devname[type][0]) { 69: cp = line; 70: *cp++ = devname[type][0]; 71: *cp++ = devname[type][1]; 72: *cp++ = '('; 73: if (unit >= 10) 74: *cp++ = unit / 10 + '0'; 75: *cp++ = unit % 10 + '0'; 76: *cp++ = ','; 77: *cp++ = part + '0'; 78: *cp++ = ')'; 79: strcpy(cp, UNIX); 80: } else 81: howto = RB_SINGLE|RB_ASKNAME; 82: } 83: #endif 84: for (;;) { 85: if (howto & RB_ASKNAME) { 86: printf(": "); 87: gets(line); 88: } else 89: printf(": %s\n", line); 90: io = open(line, 0); 91: if (io >= 0) { 92: if (howto & RB_ASKNAME) { 93: /* 94: * Build up devtype register to pass on to 95: * booted program. 96: */ 97: cp = line; 98: for (i = 0; i <= MAXTYPE; i++) 99: if ((devname[i][0] == cp[0]) && 100: (devname[i][1] == cp[1])) 101: break; 102: if (i <= MAXTYPE) { 103: devtype = i << B_TYPESHIFT; 104: cp += 3; 105: i = *cp++ - '0'; 106: if (*cp >= '0' && *cp <= '9') 107: i = i * 10 + *cp++ - '0'; 108: cp++; 109: devtype |= ((i % 8) << B_UNITSHIFT); 110: devtype |= ((i / 8) << B_ADAPTORSHIFT); 111: devtype |= atol(cp) << B_PARTITIONSHIFT; 112: } 113: } 114: devtype |= B_DEVMAGIC; 115: loadpcs(); 116: copyunix(howto, devtype, io); 117: close(io); 118: howto = RB_SINGLE|RB_ASKNAME; 119: } 120: if (++retry > 2) 121: howto = RB_SINGLE|RB_ASKNAME; 122: } 123: } 124: 125: /*ARGSUSED*/ 126: copyunix(howto, devtype, io) 127: register howto, devtype, io; /* howto=r11, devtype=r10 */ 128: { 129: struct exec x; 130: register int i; 131: char *addr; 132: 133: i = read(io, (char *)&x, sizeof x); 134: if (i != sizeof x || 135: (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) 136: _stop("Bad format\n"); 137: printf("%d", x.a_text); 138: if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) 139: goto shread; 140: if (read(io, (char *)0, x.a_text) != x.a_text) 141: goto shread; 142: addr = (char *)x.a_text; 143: if (x.a_magic == 0413 || x.a_magic == 0410) 144: while ((int)addr & CLOFSET) 145: *addr++ = 0; 146: printf("+%d", x.a_data); 147: if (read(io, addr, x.a_data) != x.a_data) 148: goto shread; 149: addr += x.a_data; 150: printf("+%d", x.a_bss); 151: x.a_bss += 128*512; /* slop */ 152: for (i = 0; i < x.a_bss; i++) 153: *addr++ = 0; 154: x.a_entry &= 0x7fffffff; 155: printf(" start 0x%x\n", x.a_entry); 156: (*((int (*)()) x.a_entry))(); 157: return; 158: shread: 159: _stop("Short read\n"); 160: } 161: 162: /* 750 Patchable Control Store magic */ 163: 164: #include "../vax/mtpr.h" 165: #include "../vax/cpu.h" 166: #define PCS_BITCNT 0x2000 /* number of patchbits */ 167: #define PCS_MICRONUM 0x400 /* number of ucode locs */ 168: #define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */ 169: #define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */ 170: #define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */ 171: #define PCS_ENABLE 0xfff00000 /* enable bits for pcs */ 172: 173: loadpcs() 174: { 175: register int *ip; /* known to be r11 below */ 176: register int i; /* known to be r10 below */ 177: register int *jp; /* known to be r9 below */ 178: register int j; 179: static int pcsdone = 0; 180: union cpusid sid; 181: char pcs[100]; 182: char *closeparen; 183: char *index(); 184: 185: sid.cpusid = mfpr(SID); 186: if (sid.cpuany.cp_type!=VAX_750 || sid.cpu750.cp_urev<95 || pcsdone) 187: return; 188: printf("Updating 11/750 microcode: "); 189: strncpy(pcs, line, 99); 190: pcs[99] = 0; 191: closeparen = index(pcs, ')'); 192: if (closeparen) 193: *(++closeparen) = 0; 194: else 195: return; 196: strcat(pcs, "pcs750.bin"); 197: i = open(pcs, 0); 198: if (i < 0) 199: return; 200: /* 201: * We ask for more than we need to be sure we get only what we expect. 202: * After read: 203: * locs 0 - 1023 packed patchbits 204: * 1024 - 11264 packed microcode 205: */ 206: if (read(i, (char *)0, 23*512) != 22*512) { 207: printf("Error reading %s\n", pcs); 208: close(i); 209: return; 210: } 211: close(i); 212: 213: /* 214: * Enable patchbit loading and load the bits one at a time. 215: */ 216: *((int *)PCS_PATCHBIT) = 1; 217: ip = (int *)PCS_PATCHADDR; 218: jp = (int *)0; 219: for (i=0; i < PCS_BITCNT; i++) { 220: asm(" extzv r10,$1,(r9),(r11)+"); 221: } 222: *((int *)PCS_PATCHBIT) = 0; 223: 224: /* 225: * Load PCS microcode 20 bits at a time. 226: */ 227: ip = (int *)PCS_PCSADDR; 228: jp = (int *)1024; 229: for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) { 230: asm(" extzv r10,$20,(r9),(r11)+"); 231: } 232: 233: /* 234: * Enable PCS. 235: */ 236: i = *jp; /* get 1st 20 bits of microcode again */ 237: i &= 0xfffff; 238: i |= PCS_ENABLE; /* reload these bits with PCS enable set */ 239: *((int *)PCS_PCSADDR) = i; 240: 241: sid.cpusid = mfpr(SID); 242: printf("new rev level=%d\n", sid.cpu750.cp_urev); 243: pcsdone = 1; 244: }