1 /* $NetBSD: boot.c,v 1.9 2000/05/26 20:15:21 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 "machine/rpb.h" 44 45 #include "vaxstand.h" 46 47 /* 48 * Boot program... arguments passed in r10 and r11 determine 49 * whether boot stops to ask for system name and which device 50 * boot comes from. 51 */ 52 53 char line[100]; 54 int bootdev, debug; 55 extern unsigned opendev; 56 57 void usage(char *), boot(char *), halt(char *); 58 void Xmain(struct rpb *); 59 void autoconf(void); 60 int getsecs(void); 61 int setjmp(int *); 62 int testkey(void); 63 void loadpcs(void); 64 65 const struct vals { 66 char *namn; 67 void (*func)(char *); 68 char *info; 69 } val[] = { 70 {"?", usage, "Show this help menu"}, 71 {"help", usage, "Same as '?'"}, 72 {"boot", boot, "Load and execute file"}, 73 {"halt", halt, "Halts the system"}, 74 {0, 0}, 75 }; 76 77 static struct { 78 char name[12]; 79 int quiet; 80 } filelist[] = { 81 { "netbsd.vax", 1 }, 82 { "netbsd", 0 }, 83 { "netbsd.gz", 0 }, 84 { "netbsd.old", 0 }, 85 { "gennetbsd", 0 }, 86 { "", 0 }, 87 }; 88 89 int jbuf[10]; 90 int sluttid, senast, skip, askname; 91 struct rpb bootrpb; 92 93 void 94 Xmain(struct rpb *prpb) 95 { 96 int io; 97 int j, nu; 98 99 /* First copy rpb/bqo to its new location */ 100 bcopy((caddr_t)prpb, &bootrpb, sizeof(struct rpb)); 101 if (prpb->iovec) { 102 bootrpb.iovec = (int)alloc(prpb->iovecsz); 103 bcopy((caddr_t)prpb->iovec, (caddr_t)bootrpb.iovec, 104 prpb->iovecsz); 105 } 106 io = 0; 107 skip = 1; 108 autoconf(); 109 110 askname = bootrpb.rpb_bootr5 & RB_ASKNAME; 111 printf("\n\r>> NetBSD/vax boot [%s %s] <<\n", __DATE__, __TIME__); 112 printf(">> Press any key to abort autoboot "); 113 sluttid = getsecs() + 5; 114 senast = 0; 115 skip = 0; 116 setjmp(jbuf); 117 for (;;) { 118 nu = sluttid - getsecs(); 119 if (senast != nu) 120 printf("%c%d", 8, nu); 121 if (nu <= 0) 122 break; 123 senast = nu; 124 if ((j = (testkey() & 0177))) { 125 skip = 1; 126 if (j != 10 && j != 13) { 127 printf("\nPress '?' for help"); 128 askname = 1; 129 } 130 break; 131 } 132 } 133 skip = 1; 134 printf("\n"); 135 136 /* First try to autoboot */ 137 if (askname == 0) { 138 int fileindex; 139 for (fileindex = 0; filelist[fileindex].name[0] != '\0'; 140 fileindex++) { 141 errno = 0; 142 if (!filelist[fileindex].quiet) 143 printf("> boot %s\n", filelist[fileindex].name); 144 exec(filelist[fileindex].name, 0, 0); 145 if (!filelist[fileindex].quiet) 146 printf("%s: boot failed: %s\n", 147 filelist[fileindex].name, strerror(errno)); 148 #if 0 /* Will hang VAX 4000 machines */ 149 if (testkey()) 150 break; 151 #endif 152 } 153 } 154 155 /* If any key pressed, go to conversational boot */ 156 for (;;) { 157 const struct vals *v = &val[0]; 158 char *c, *d; 159 160 printf("> "); 161 gets(line); 162 163 c = line; 164 while (*c == ' ') 165 c++; 166 167 if (c[0] == 0) 168 continue; 169 170 if ((d = index(c, ' '))) 171 *d++ = 0; 172 173 while (v->namn) { 174 if (strcmp(v->namn, c) == 0) 175 break; 176 v++; 177 } 178 if (v->namn) 179 (*v->func)(d); 180 else 181 printf("Unknown command: %s\n", c); 182 } 183 } 184 185 void 186 halt(char *hej) 187 { 188 asm("halt"); 189 } 190 191 void 192 boot(char *arg) 193 { 194 char *fn = "netbsd"; 195 196 if (arg) { 197 while (*arg == ' ') 198 arg++; 199 200 if (*arg != '-') { 201 fn = arg; 202 if ((arg = index(arg, ' '))) { 203 *arg++ = 0; 204 while (*arg == ' ') 205 arg++; 206 } else 207 goto load; 208 } 209 if (*arg != '-') { 210 fail: printf("usage: boot [filename] [-asd]\n"); 211 return; 212 } 213 214 while (*++arg) { 215 if (*arg == 'a') 216 bootrpb.rpb_bootr5 |= RB_ASKNAME; 217 else if (*arg == 'd') 218 bootrpb.rpb_bootr5 |= RB_KDB; 219 else if (*arg == 's') 220 bootrpb.rpb_bootr5 |= RB_SINGLE; 221 else 222 goto fail; 223 } 224 } 225 load: exec(fn, 0, 0); 226 printf("Boot failed: %s\n", strerror(errno)); 227 } 228 229 /* 750 Patchable Control Store magic */ 230 231 #include "../include/mtpr.h" 232 #include "../include/cpu.h" 233 #include "../include/sid.h" 234 #define PCS_BITCNT 0x2000 /* number of patchbits */ 235 #define PCS_MICRONUM 0x400 /* number of ucode locs */ 236 #define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */ 237 #define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */ 238 #define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */ 239 #define PCS_ENABLE 0xfff00000 /* enable bits for pcs */ 240 241 #define extzv(one, two, three,four) \ 242 ({ \ 243 asm __volatile (" extzv %0,%3,(%1),(%2)+" \ 244 : \ 245 : "g"(one),"g"(two),"g"(three),"g"(four)); \ 246 }) 247 248 249 void 250 loadpcs() 251 { 252 static int pcsdone = 0; 253 int mid = mfpr(PR_SID); 254 int i, j, *ip, *jp; 255 char pcs[100]; 256 char *cp; 257 258 if ((mid >> 24) != VAX_750 || ((mid >> 8) & 255) < 95 || pcsdone) 259 return; 260 printf("Updating 11/750 microcode: "); 261 for (cp = line; *cp; cp++) 262 if (*cp == ')' || *cp == ':') 263 break; 264 if (*cp) { 265 bcopy(line, pcs, 99); 266 pcs[99] = 0; 267 i = cp - line + 1; 268 } else 269 i = 0; 270 strcpy(pcs + i, "pcs750.bin"); 271 i = open(pcs, 0); 272 if (i < 0) { 273 printf("bad luck - missing pcs750.bin :-(\n"); 274 return; 275 } 276 /* 277 * We ask for more than we need to be sure we get only what we expect. 278 * After read: 279 * locs 0 - 1023 packed patchbits 280 * 1024 - 11264 packed microcode 281 */ 282 if (read(i, (char *)0, 23*512) != 22*512) { 283 printf("Error reading %s\n", pcs); 284 close(i); 285 return; 286 } 287 close(i); 288 289 /* 290 * Enable patchbit loading and load the bits one at a time. 291 */ 292 *((int *)PCS_PATCHBIT) = 1; 293 ip = (int *)PCS_PATCHADDR; 294 jp = (int *)0; 295 for (i=0; i < PCS_BITCNT; i++) { 296 extzv(i,jp,ip,1); 297 } 298 *((int *)PCS_PATCHBIT) = 0; 299 300 /* 301 * Load PCS microcode 20 bits at a time. 302 */ 303 ip = (int *)PCS_PCSADDR; 304 jp = (int *)1024; 305 for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) { 306 extzv(i,jp,ip,20); 307 } 308 309 /* 310 * Enable PCS. 311 */ 312 i = *jp; /* get 1st 20 bits of microcode again */ 313 i &= 0xfffff; 314 i |= PCS_ENABLE; /* reload these bits with PCS enable set */ 315 *((int *)PCS_PCSADDR) = i; 316 317 mid = mfpr(PR_SID); 318 printf("new rev level=%d\n", V750UCODE(mid)); 319 pcsdone = 1; 320 } 321 322 void 323 usage(char *hej) 324 { 325 const struct vals *v = &val[0]; 326 327 printf("Commands:\n"); 328 while (v->namn) { 329 printf("%s\t%s\n", v->namn, v->info); 330 v++; 331 } 332 } 333