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