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