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.7 (Berkeley) 03/08/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 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 #ifdef JUSTASK 68 howto = RB_ASKNAME|RB_SINGLE; 69 #else 70 type = devtype & 0xff; 71 unit = (int)((unsigned)devtype >> UNITSHIFT) & UNITMASK; 72 part = unit & PARTITIONMASK; 73 unit = unit >> PARTITIONSHIFT; 74 if ((howto&RB_ASKNAME)==0) { 75 if (type >= 0 && type < sizeof(devname) / 2 76 && devname[type][0]) { 77 cp = line; 78 *cp++ = devname[type][0]; 79 *cp++ = devname[type][1]; 80 *cp++ = '('; 81 if (unit >= 10) 82 *cp++ = unit / 10 + '0'; 83 *cp++ = unit % 10 + '0'; 84 *cp++ = ','; 85 *cp++ = part + '0'; 86 *cp++ = ')'; 87 strcpy(cp, UNIX); 88 } else 89 howto = RB_SINGLE|RB_ASKNAME; 90 } 91 #endif 92 for (;;) { 93 if (howto & RB_ASKNAME) { 94 printf(": "); 95 gets(line); 96 } else 97 printf(": %s\n", line); 98 io = open(line, 0); 99 if (io >= 0) { 100 loadpcs(); 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 #ifndef SMALL 148 /* 750 Patchable Control Store magic */ 149 150 #include "../vax/mtpr.h" 151 #include "../vax/cpu.h" 152 #define PCS_BITCNT 0x2000 /* number of patchbits */ 153 #define PCS_MICRONUM 0x400 /* number of ucode locs */ 154 #define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */ 155 #define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */ 156 #define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */ 157 #define PCS_ENABLE 0xfff00000 /* enable bits for pcs */ 158 159 loadpcs() 160 { 161 register int *ip; /* known to be r11 below */ 162 register int i; /* known to be r10 below */ 163 register int *jp; /* known to be r9 below */ 164 register int j; 165 static int pcsdone = 0; 166 union cpusid sid; 167 char pcs[100]; 168 char *closeparen; 169 char *index(); 170 171 sid.cpusid = mfpr(SID); 172 if (sid.cpuany.cp_type!=VAX_750 || sid.cpu750.cp_urev<95 || pcsdone) 173 return; 174 printf("Updating 11/750 microcode: "); 175 strncpy(pcs, line, 99); 176 pcs[99] = 0; 177 closeparen = index(pcs, ')'); 178 if (closeparen) 179 *(++closeparen) = 0; 180 else 181 return; 182 strcat(pcs, "pcs750.bin"); 183 i = open(pcs, 0); 184 if (i < 0) 185 return; 186 /* 187 * We ask for more than we need to be sure we get only what we expect. 188 * After read: 189 * locs 0 - 1023 packed patchbits 190 * 1024 - 11264 packed microcode 191 */ 192 if (read(i, (char *)0, 23*512) != 22*512) { 193 printf("Error reading %s\n", pcs); 194 close(i); 195 return; 196 } 197 close(i); 198 199 /* 200 * Enable patchbit loading and load the bits one at a time. 201 */ 202 *((int *)PCS_PATCHBIT) = 1; 203 ip = (int *)PCS_PATCHADDR; 204 jp = (int *)0; 205 for (i=0; i < PCS_BITCNT; i++) { 206 asm(" extzv r10,$1,(r9),(r11)+"); 207 } 208 *((int *)PCS_PATCHBIT) = 0; 209 210 /* 211 * Load PCS microcode 20 bits at a time. 212 */ 213 ip = (int *)PCS_PCSADDR; 214 jp = (int *)1024; 215 for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) { 216 asm(" extzv r10,$20,(r9),(r11)+"); 217 } 218 219 /* 220 * Enable PCS. 221 */ 222 i = *jp; /* get 1st 20 bits of microcode again */ 223 i &= 0xfffff; 224 i |= PCS_ENABLE; /* reload these bits with PCS enable set */ 225 *((int *)PCS_PCSADDR) = i; 226 227 sid.cpusid = mfpr(SID); 228 printf("new rev level=%d\n", sid.cpu750.cp_urev); 229 pcsdone = 1; 230 } 231 #endif SMALL 232