1 /* 2 * Copyright (c) 1982 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 6.9 (Berkeley) 03/13/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 } 245