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.6 (Berkeley) 01/28/88 7 */ 8 9 #include "param.h" 10 #include "inode.h" 11 #include "fs.h" 12 #include "vm.h" 13 #include "reboot.h" 14 15 #include <a.out.h> 16 #include "saio.h" 17 18 /* 19 * Boot program... arguments passed in r10 and r11 determine 20 * whether boot stops to ask for system name and which device 21 * boot comes from. 22 */ 23 24 #define UNIX "/vmunix" 25 char line[100]; 26 27 int retry = 0; 28 extern unsigned opendev; 29 30 main() 31 { 32 register unsigned howto, devtype; /* howto=r11, devtype=r10 */ 33 int io, type; 34 35 #ifdef lint 36 howto = 0; devtype = 0; 37 #endif 38 printf("\nBoot\n"); 39 #ifdef JUSTASK 40 howto = RB_ASKNAME|RB_SINGLE; 41 #else 42 if ((howto & RB_ASKNAME) == 0) { 43 type = (devtype >> B_TYPESHIFT) & B_TYPEMASK; 44 if ((unsigned)type < ndevs && devsw[type].dv_name) 45 strcpy(line, UNIX); 46 else 47 howto |= RB_SINGLE|RB_ASKNAME; 48 } 49 #endif 50 for (;;) { 51 if (howto & RB_ASKNAME) { 52 printf(": "); 53 gets(line); 54 if (line[0] == 0) { 55 strcpy(line, UNIX); 56 printf(": %s\n", line); 57 } 58 } else 59 printf(": %s\n", line); 60 io = open(line, 0); 61 if (io >= 0) { 62 #ifdef VAX750 63 loadpcs(); 64 #endif 65 copyunix(howto, opendev, io); 66 close(io); 67 howto |= RB_SINGLE|RB_ASKNAME; 68 } 69 if (++retry > 2) 70 howto |= RB_SINGLE|RB_ASKNAME; 71 } 72 } 73 74 /*ARGSUSED*/ 75 copyunix(howto, devtype, aio) 76 register howto, devtype; /* howto=r11, devtype=r10 */ 77 int aio; 78 { 79 register int esym; /* must be r9 */ 80 struct exec x; 81 register int io = aio, i; 82 char *addr; 83 84 i = read(io, (char *)&x, sizeof x); 85 if (i != sizeof x || 86 (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) { 87 printf("Bad format\n"); 88 return; 89 } 90 printf("%d", x.a_text); 91 if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) 92 goto shread; 93 if (read(io, (char *)0, x.a_text) != x.a_text) 94 goto shread; 95 addr = (char *)x.a_text; 96 if (x.a_magic == 0413 || x.a_magic == 0410) 97 while ((int)addr & CLOFSET) 98 *addr++ = 0; 99 printf("+%d", x.a_data); 100 if (read(io, addr, x.a_data) != x.a_data) 101 goto shread; 102 addr += x.a_data; 103 printf("+%d", x.a_bss); 104 for (i = 0; i < x.a_bss; i++) 105 *addr++ = 0; 106 if (howto & RB_KDB && x.a_syms) { 107 *(int *)addr = x.a_syms; /* symbol table size */ 108 addr += sizeof (int); 109 printf("[+%d", x.a_syms); 110 if (read(io, addr, x.a_syms) != x.a_syms) 111 goto shread; 112 addr += x.a_syms; 113 if (read(io, addr, sizeof (int)) != sizeof (int)) 114 goto shread; 115 i = *(int *)addr - sizeof (int); /* string table size */ 116 addr += sizeof (int); 117 printf("+%d]", i); 118 if (read(io, addr, i) != i) 119 goto shread; 120 addr += i; 121 esym = roundup((int)addr, sizeof (int)); 122 x.a_bss = 0; 123 } else 124 howto &= ~RB_KDB; 125 for (i = 0; i < 128*512; i++) /* slop */ 126 *addr++ = 0; 127 x.a_entry &= 0x7fffffff; 128 printf(" start 0x%x\n", x.a_entry); 129 (*((int (*)()) x.a_entry))(); 130 return; 131 shread: 132 printf("Short read\n"); 133 return; 134 } 135 136 #ifdef VAX750 137 /* 750 Patchable Control Store magic */ 138 139 #include "../vax/mtpr.h" 140 #include "../vax/cpu.h" 141 #define PCS_BITCNT 0x2000 /* number of patchbits */ 142 #define PCS_MICRONUM 0x400 /* number of ucode locs */ 143 #define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */ 144 #define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */ 145 #define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */ 146 #define PCS_ENABLE 0xfff00000 /* enable bits for pcs */ 147 148 loadpcs() 149 { 150 register int *ip; /* known to be r11 below */ 151 register int i; /* known to be r10 below */ 152 register int *jp; /* known to be r9 below */ 153 register int j; 154 static int pcsdone = 0; 155 union cpusid sid; 156 char pcs[100]; 157 char *cp; 158 159 sid.cpusid = mfpr(SID); 160 if (sid.cpuany.cp_type!=VAX_750 || sid.cpu750.cp_urev<95 || pcsdone) 161 return; 162 printf("Updating 11/750 microcode: "); 163 for (cp = line; *cp; cp++) 164 if (*cp == ')' || *cp == ':') 165 break; 166 if (*cp) { 167 strncpy(pcs, line, 99); 168 pcs[99] = 0; 169 i = cp - line + 1; 170 } else 171 i = 0; 172 strcpy(pcs + i, "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 pcsdone = 1; 220 } 221 #endif 222