1 /* $NetBSD: boot.c,v 1.4 1999/10/23 14:42:22 ragge Exp $ */ 2 /*- 3 * Copyright (c) 1982, 1986 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by the University of 17 * California, Berkeley and its contributors. 18 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)boot.c 7.15 (Berkeley) 5/4/91 35 */ 36 37 #include "sys/param.h" 38 #include "sys/reboot.h" 39 #include "lib/libsa/stand.h" 40 41 #define V750UCODE(x) ((x>>8)&255) 42 43 #include "vaxstand.h" 44 45 /* 46 * Boot program... arguments passed in r10 and r11 determine 47 * whether boot stops to ask for system name and which device 48 * boot comes from. 49 */ 50 51 char line[100]; 52 int devtype, bootdev, howto, debug; 53 extern unsigned opendev; 54 extern unsigned *bootregs; 55 56 void usage(), boot(), halt(); 57 58 struct vals { 59 char *namn; 60 void (*func)(); 61 char *info; 62 } val[] = { 63 {"?", usage, "Show this help menu"}, 64 {"help", usage, "Same as '?'"}, 65 {"boot", boot, "Load and execute file"}, 66 {"halt", halt, "Halts the system"}, 67 {0, 0}, 68 }; 69 70 char *filer[] = { 71 "netbsd", 72 "netbsd.gz", 73 "netbsd.old", 74 "gennetbsd", 75 0, 76 }; 77 78 Xmain() 79 { 80 int io, type, sluttid, askname, filindex = 0; 81 int j, senast = 0, nu; 82 83 io=0; 84 autoconf(); 85 86 askname = howto & RB_ASKNAME; 87 printf("\n\r>> NetBSD/vax boot [%s %s] <<\n", __DATE__, __TIME__); 88 printf(">> Press any key to abort autoboot "); 89 sluttid = getsecs() + 5; 90 for (;;) { 91 nu = sluttid - getsecs(); 92 if (senast != nu) 93 printf("%c%d", 8, nu); 94 if (nu <= 0) 95 break; 96 senast = nu; 97 if ((j = (testkey() & 0177))) { 98 if (j != 10 && j != 13) { 99 printf("\nPress '?' for help"); 100 askname = 1; 101 } 102 break; 103 } 104 } 105 printf("\n"); 106 107 /* First try to autoboot */ 108 if (askname == 0) { 109 type = (devtype >> B_TYPESHIFT) & B_TYPEMASK; 110 if ((unsigned)type < ndevs && devsw[type].dv_name) 111 while (filer[filindex]) { 112 errno = 0; 113 printf("> boot %s\n", filer[filindex]); 114 exec(filer[filindex++], 0, 0); 115 printf("boot failed: %s\n", strerror(errno)); 116 if (testkey()) 117 break; 118 } 119 } 120 121 /* If any key pressed, go to conversational boot */ 122 for (;;) { 123 struct vals *v = &val[0]; 124 char *c, *d; 125 126 printf("> "); 127 gets(line); 128 129 c = line; 130 while (*c == ' ') 131 c++; 132 133 if (c[0] == 0) 134 continue; 135 136 if ((d = index(c, ' '))) 137 *d++ = 0; 138 139 while (v->namn) { 140 if (strcmp(v->namn, c) == 0) 141 break; 142 v++; 143 } 144 if (v->namn) 145 (*v->func)(d); 146 else 147 printf("Unknown command: %s\n", c); 148 149 } 150 } 151 152 void 153 halt() 154 { 155 asm("halt"); 156 } 157 158 void 159 boot(arg) 160 char *arg; 161 { 162 char *fn = "netbsd"; 163 164 if (arg) { 165 while (*arg == ' ') 166 arg++; 167 168 if (*arg != '-') { 169 fn = arg; 170 if ((arg = index(arg, ' '))) { 171 *arg++ = 0; 172 while (*arg == ' ') 173 arg++; 174 } else 175 goto load; 176 } 177 if (*arg != '-') { 178 fail: printf("usage: boot [filename] [-asd]\n"); 179 return; 180 } 181 182 while (*++arg) { 183 if (*arg == 'a') 184 howto |= RB_ASKNAME; 185 else if (*arg == 'd') 186 howto |= RB_KDB; 187 else if (*arg == 's') 188 howto |= RB_SINGLE; 189 else 190 goto fail; 191 } 192 } 193 load: exec(fn, 0, 0); 194 printf("Boot failed: %s\n", strerror(errno)); 195 } 196 197 /* 750 Patchable Control Store magic */ 198 199 #include "../include/mtpr.h" 200 #include "../include/cpu.h" 201 #include "../include/sid.h" 202 #define PCS_BITCNT 0x2000 /* number of patchbits */ 203 #define PCS_MICRONUM 0x400 /* number of ucode locs */ 204 #define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */ 205 #define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */ 206 #define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */ 207 #define PCS_ENABLE 0xfff00000 /* enable bits for pcs */ 208 209 #define extzv(one, two, three,four) \ 210 ({ \ 211 asm __volatile (" extzv %0,%3,(%1),(%2)+" \ 212 : \ 213 : "g"(one),"g"(two),"g"(three),"g"(four)); \ 214 }) 215 216 217 loadpcs() 218 { 219 static int pcsdone = 0; 220 int mid = mfpr(PR_SID); 221 int i, j, *ip, *jp; 222 char pcs[100]; 223 char *cp; 224 225 if ((mid >> 24) != VAX_750 || ((mid >> 8) & 255) < 95 || pcsdone) 226 return; 227 printf("Updating 11/750 microcode: "); 228 for (cp = line; *cp; cp++) 229 if (*cp == ')' || *cp == ':') 230 break; 231 if (*cp) { 232 bcopy(line, pcs, 99); 233 pcs[99] = 0; 234 i = cp - line + 1; 235 } else 236 i = 0; 237 strcpy(pcs + i, "pcs750.bin"); 238 i = open(pcs, 0); 239 if (i < 0) { 240 printf("bad luck - missing pcs750.bin :-(\n"); 241 return; 242 } 243 /* 244 * We ask for more than we need to be sure we get only what we expect. 245 * After read: 246 * locs 0 - 1023 packed patchbits 247 * 1024 - 11264 packed microcode 248 */ 249 if (read(i, (char *)0, 23*512) != 22*512) { 250 printf("Error reading %s\n", pcs); 251 close(i); 252 return; 253 } 254 close(i); 255 256 /* 257 * Enable patchbit loading and load the bits one at a time. 258 */ 259 *((int *)PCS_PATCHBIT) = 1; 260 ip = (int *)PCS_PATCHADDR; 261 jp = (int *)0; 262 for (i=0; i < PCS_BITCNT; i++) { 263 extzv(i,jp,ip,1); 264 } 265 *((int *)PCS_PATCHBIT) = 0; 266 267 /* 268 * Load PCS microcode 20 bits at a time. 269 */ 270 ip = (int *)PCS_PCSADDR; 271 jp = (int *)1024; 272 for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) { 273 extzv(i,jp,ip,20); 274 } 275 276 /* 277 * Enable PCS. 278 */ 279 i = *jp; /* get 1st 20 bits of microcode again */ 280 i &= 0xfffff; 281 i |= PCS_ENABLE; /* reload these bits with PCS enable set */ 282 *((int *)PCS_PCSADDR) = i; 283 284 mid = mfpr(PR_SID); 285 printf("new rev level=%d\n", V750UCODE(mid)); 286 pcsdone = 1; 287 } 288 289 void 290 usage() 291 { 292 struct vals *v = &val[0]; 293 294 printf("Commands:\n"); 295 while (v->namn) { 296 printf("%s\t%s\n", v->namn, v->info); 297 v++; 298 } 299 } 300