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.6 (Berkeley) 12/19/85 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 42 /* 43 * constants for converting a "minor" device numbers to unit number 44 * and partition number 45 */ 46 #define UNITSHIFT 16 47 #define UNITMASK 0x1ff 48 #define PARTITIONMASK 0x7 49 #define PARTITIONSHIFT 3 50 51 #define UNIX "vmunix" 52 char line[100]; 53 54 int retry = 0; 55 56 main() 57 { 58 register howto, devtype; /* howto=r11, devtype=r10 */ 59 int io; 60 register type, part, unit; 61 register char *cp; 62 63 #ifdef lint 64 howto = 0; devtype = 0; 65 #endif 66 printf("\nBoot\n"); 67 loadpcs(); 68 #ifdef JUSTASK 69 howto = RB_ASKNAME|RB_SINGLE; 70 #else 71 type = devtype & 0xff; 72 unit = (int)((unsigned)devtype >> UNITSHIFT) & UNITMASK; 73 part = unit & PARTITIONMASK; 74 unit = unit >> PARTITIONSHIFT; 75 if ((howto&RB_ASKNAME)==0) { 76 if (type >= 0 && type < sizeof(devname) / 2 77 && devname[type][0]) { 78 cp = line; 79 *cp++ = devname[type][0]; 80 *cp++ = devname[type][1]; 81 *cp++ = '('; 82 if (unit >= 10) 83 *cp++ = unit / 10 + '0'; 84 *cp++ = unit % 10 + '0'; 85 *cp++ = ','; 86 *cp++ = part + '0'; 87 *cp++ = ')'; 88 strcpy(cp, UNIX); 89 } else 90 howto = RB_SINGLE|RB_ASKNAME; 91 } 92 #endif 93 for (;;) { 94 if (howto & RB_ASKNAME) { 95 printf(": "); 96 gets(line); 97 } else 98 printf(": %s\n", line); 99 io = open(line, 0); 100 if (io >= 0) { 101 copyunix(howto, io); 102 close(io); 103 howto = RB_SINGLE|RB_ASKNAME; 104 } 105 if (++retry > 2) 106 howto = RB_SINGLE|RB_ASKNAME; 107 } 108 } 109 110 /*ARGSUSED*/ 111 copyunix(howto, io) 112 register howto, io; 113 { 114 struct exec x; 115 register int i; 116 char *addr; 117 118 i = read(io, (char *)&x, sizeof x); 119 if (i != sizeof x || 120 (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) 121 _stop("Bad format\n"); 122 printf("%d", x.a_text); 123 if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) 124 goto shread; 125 if (read(io, (char *)0, x.a_text) != x.a_text) 126 goto shread; 127 addr = (char *)x.a_text; 128 if (x.a_magic == 0413 || x.a_magic == 0410) 129 while ((int)addr & CLOFSET) 130 *addr++ = 0; 131 printf("+%d", x.a_data); 132 if (read(io, addr, x.a_data) != x.a_data) 133 goto shread; 134 addr += x.a_data; 135 printf("+%d", x.a_bss); 136 x.a_bss += 128*512; /* slop */ 137 for (i = 0; i < x.a_bss; i++) 138 *addr++ = 0; 139 x.a_entry &= 0x7fffffff; 140 printf(" start 0x%x\n", x.a_entry); 141 (*((int (*)()) x.a_entry))(); 142 return; 143 shread: 144 _stop("Short read\n"); 145 } 146 147 /* 750 Patchable Control Store magic */ 148 149 #include "../vax/mtpr.h" 150 #include "../vax/cpu.h" 151 #define PCS_BITCNT 0x2000 /* number of patchbits */ 152 #define PCS_MICRONUM 0x400 /* number of ucode locs */ 153 #define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */ 154 #define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */ 155 #define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */ 156 #define PCS_ENABLE 0xfff00000 /* enable bits for pcs */ 157 158 loadpcs() 159 { 160 register int *ip; /* known to be r11 below */ 161 register int i; /* known to be r10 below */ 162 register int *jp; /* known to be r9 below */ 163 register int j; 164 union cpusid sid; 165 char pcs[100]; 166 char *closeparen; 167 char *index(); 168 169 sid.cpusid = mfpr(SID); 170 if (sid.cpuany.cp_type!=VAX_750 || sid.cpu750.cp_urev<95) 171 return; 172 printf("Updating 11/750 microcode: "); 173 strncpy(pcs, line, 99); 174 pcs[99] = 0; 175 closeparen = index(pcs, ')'); 176 if (closeparen) 177 *(++closeparen) = 0; 178 else 179 return; 180 strcat(pcs, "pcs750.bin"); 181 i = open(pcs, 0); 182 if (i < 0) 183 return; 184 /* 185 * We ask for more than we need to be sure we get only what we expect. 186 * After read: 187 * locs 0 - 1023 packed patchbits 188 * 1024 - 11264 packed microcode 189 */ 190 if (read(i, (char *)0, 23*512) != 22*512) { 191 printf("Error reading %s\n", pcs); 192 close(i); 193 return; 194 } 195 close(i); 196 197 /* 198 * Enable patchbit loading and load the bits one at a time. 199 */ 200 *((int *)PCS_PATCHBIT) = 1; 201 ip = (int *)PCS_PATCHADDR; 202 jp = (int *)0; 203 for (i=0; i < PCS_BITCNT; i++) { 204 asm(" extzv r10,$1,(r9),(r11)+"); 205 } 206 *((int *)PCS_PATCHBIT) = 0; 207 208 /* 209 * Load PCS microcode 20 bits at a time. 210 */ 211 ip = (int *)PCS_PCSADDR; 212 jp = (int *)1024; 213 for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) { 214 asm(" extzv r10,$20,(r9),(r11)+"); 215 } 216 217 /* 218 * Enable PCS. 219 */ 220 i = *jp; /* get 1st 20 bits of microcode again */ 221 i &= 0xfffff; 222 i |= PCS_ENABLE; /* reload these bits with PCS enable set */ 223 *((int *)PCS_PCSADDR) = i; 224 225 sid.cpusid = mfpr(SID); 226 printf("new rev level=%d\n", sid.cpu750.cp_urev); 227 } 228