1 1.36 rin /* $NetBSD: boot.c,v 1.36 2024/10/23 12:47:39 rin Exp $ */ 2 1.1 ragge /*- 3 1.1 ragge * Copyright (c) 1982, 1986 The Regents of the University of California. 4 1.1 ragge * All rights reserved. 5 1.1 ragge * 6 1.1 ragge * Redistribution and use in source and binary forms, with or without 7 1.1 ragge * modification, are permitted provided that the following conditions 8 1.1 ragge * are met: 9 1.1 ragge * 1. Redistributions of source code must retain the above copyright 10 1.1 ragge * notice, this list of conditions and the following disclaimer. 11 1.1 ragge * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 ragge * notice, this list of conditions and the following disclaimer in the 13 1.1 ragge * documentation and/or other materials provided with the distribution. 14 1.20 agc * 3. Neither the name of the University nor the names of its contributors 15 1.1 ragge * may be used to endorse or promote products derived from this software 16 1.1 ragge * without specific prior written permission. 17 1.1 ragge * 18 1.1 ragge * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 1.1 ragge * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 1.1 ragge * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 1.1 ragge * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 1.1 ragge * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 1.1 ragge * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 1.1 ragge * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 1.1 ragge * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 1.1 ragge * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 1.1 ragge * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 1.1 ragge * SUCH DAMAGE. 29 1.1 ragge * 30 1.1 ragge * @(#)boot.c 7.15 (Berkeley) 5/4/91 31 1.1 ragge */ 32 1.1 ragge 33 1.13 jdolecek #include <sys/param.h> 34 1.13 jdolecek #include <sys/reboot.h> 35 1.14 jdolecek #include <sys/boot_flag.h> 36 1.23 junyoung 37 1.23 junyoung #include <lib/libsa/stand.h> 38 1.27 tsutsui #include <lib/libsa/net.h> 39 1.23 junyoung #include <lib/libsa/loadfile.h> 40 1.23 junyoung #include <lib/libkern/libkern.h> 41 1.1 ragge 42 1.1 ragge #define V750UCODE(x) ((x>>8)&255) 43 1.1 ragge 44 1.6 ragge #include "machine/rpb.h" 45 1.6 ragge 46 1.1 ragge #include "vaxstand.h" 47 1.1 ragge 48 1.1 ragge /* 49 1.1 ragge * Boot program... arguments passed in r10 and r11 determine 50 1.1 ragge * whether boot stops to ask for system name and which device 51 1.1 ragge * boot comes from. 52 1.1 ragge */ 53 1.1 ragge 54 1.1 ragge char line[100]; 55 1.6 ragge int bootdev, debug; 56 1.1 ragge extern unsigned opendev; 57 1.1 ragge 58 1.6 ragge void usage(char *), boot(char *), halt(char *); 59 1.10 ragge void Xmain(void); 60 1.6 ragge void autoconf(void); 61 1.6 ragge int setjmp(int *); 62 1.6 ragge int testkey(void); 63 1.6 ragge void loadpcs(void); 64 1.1 ragge 65 1.8 matt const struct vals { 66 1.1 ragge char *namn; 67 1.6 ragge void (*func)(char *); 68 1.1 ragge char *info; 69 1.1 ragge } val[] = { 70 1.1 ragge {"?", usage, "Show this help menu"}, 71 1.1 ragge {"help", usage, "Same as '?'"}, 72 1.3 ragge {"boot", boot, "Load and execute file"}, 73 1.3 ragge {"halt", halt, "Halts the system"}, 74 1.1 ragge {0, 0}, 75 1.1 ragge }; 76 1.1 ragge 77 1.8 matt static struct { 78 1.8 matt char name[12]; 79 1.8 matt int quiet; 80 1.8 matt } filelist[] = { 81 1.8 matt { "netbsd.vax", 1 }, 82 1.8 matt { "netbsd", 0 }, 83 1.8 matt { "netbsd.gz", 0 }, 84 1.8 matt { "netbsd.old", 0 }, 85 1.8 matt { "gennetbsd", 0 }, 86 1.8 matt { "", 0 }, 87 1.1 ragge }; 88 1.1 ragge 89 1.5 ragge int jbuf[10]; 90 1.6 ragge int sluttid, senast, skip, askname; 91 1.6 ragge struct rpb bootrpb; 92 1.5 ragge 93 1.6 ragge void 94 1.10 ragge Xmain(void) 95 1.1 ragge { 96 1.33 martin int j, nu, fd; 97 1.12 matt u_long marks[MARK_MAX]; 98 1.31 joerg extern const char bootprog_rev[]; 99 1.1 ragge 100 1.5 ragge skip = 1; 101 1.1 ragge autoconf(); 102 1.1 ragge 103 1.6 ragge askname = bootrpb.rpb_bootr5 & RB_ASKNAME; 104 1.31 joerg printf("\n\r>> NetBSD/vax boot [%s] <<\n", bootprog_rev); 105 1.1 ragge printf(">> Press any key to abort autoboot "); 106 1.1 ragge sluttid = getsecs() + 5; 107 1.5 ragge senast = 0; 108 1.5 ragge skip = 0; 109 1.5 ragge setjmp(jbuf); 110 1.1 ragge for (;;) { 111 1.3 ragge nu = sluttid - getsecs(); 112 1.3 ragge if (senast != nu) 113 1.3 ragge printf("%c%d", 8, nu); 114 1.3 ragge if (nu <= 0) 115 1.1 ragge break; 116 1.3 ragge senast = nu; 117 1.1 ragge if ((j = (testkey() & 0177))) { 118 1.5 ragge skip = 1; 119 1.1 ragge if (j != 10 && j != 13) { 120 1.1 ragge printf("\nPress '?' for help"); 121 1.1 ragge askname = 1; 122 1.1 ragge } 123 1.1 ragge break; 124 1.1 ragge } 125 1.1 ragge } 126 1.5 ragge skip = 1; 127 1.1 ragge printf("\n"); 128 1.18 ragge if (setjmp(jbuf)) 129 1.18 ragge askname = 1; 130 1.1 ragge 131 1.2 ragge /* First try to autoboot */ 132 1.1 ragge if (askname == 0) { 133 1.8 matt int fileindex; 134 1.9 ragge for (fileindex = 0; filelist[fileindex].name[0] != '\0'; 135 1.9 ragge fileindex++) { 136 1.6 ragge errno = 0; 137 1.8 matt if (!filelist[fileindex].quiet) 138 1.8 matt printf("> boot %s\n", filelist[fileindex].name); 139 1.12 matt marks[MARK_START] = 0; 140 1.33 martin fd = loadfile(filelist[fileindex].name, marks, 141 1.18 ragge LOAD_KERNEL|COUNT_KERNEL); 142 1.33 martin if (fd >= 0) { 143 1.33 martin close(fd); 144 1.17 matt machdep_start((char *)marks[MARK_ENTRY], 145 1.17 matt marks[MARK_NSYM], 146 1.12 matt (void *)marks[MARK_START], 147 1.12 matt (void *)marks[MARK_SYM], 148 1.12 matt (void *)marks[MARK_END]); 149 1.12 matt } 150 1.8 matt if (!filelist[fileindex].quiet) 151 1.22 junyoung printf("%s: boot failed: %s\n", 152 1.8 matt filelist[fileindex].name, strerror(errno)); 153 1.9 ragge #if 0 /* Will hang VAX 4000 machines */ 154 1.6 ragge if (testkey()) 155 1.6 ragge break; 156 1.9 ragge #endif 157 1.6 ragge } 158 1.1 ragge } 159 1.1 ragge 160 1.2 ragge /* If any key pressed, go to conversational boot */ 161 1.1 ragge for (;;) { 162 1.8 matt const struct vals *v = &val[0]; 163 1.1 ragge char *c, *d; 164 1.1 ragge 165 1.3 ragge printf("> "); 166 1.34 dholland kgets(line, sizeof(line)); 167 1.3 ragge 168 1.3 ragge c = line; 169 1.3 ragge while (*c == ' ') 170 1.3 ragge c++; 171 1.3 ragge 172 1.3 ragge if (c[0] == 0) 173 1.1 ragge continue; 174 1.1 ragge 175 1.21 jdolecek if ((d = strchr(c, ' '))) 176 1.3 ragge *d++ = 0; 177 1.1 ragge 178 1.1 ragge while (v->namn) { 179 1.3 ragge if (strcmp(v->namn, c) == 0) 180 1.1 ragge break; 181 1.1 ragge v++; 182 1.1 ragge } 183 1.1 ragge if (v->namn) 184 1.3 ragge (*v->func)(d); 185 1.1 ragge else 186 1.3 ragge printf("Unknown command: %s\n", c); 187 1.3 ragge } 188 1.3 ragge } 189 1.3 ragge 190 1.3 ragge void 191 1.6 ragge halt(char *hej) 192 1.3 ragge { 193 1.26 perry __asm("halt"); 194 1.3 ragge } 195 1.3 ragge 196 1.3 ragge void 197 1.6 ragge boot(char *arg) 198 1.3 ragge { 199 1.3 ragge char *fn = "netbsd"; 200 1.33 martin int howto, fl, fd; 201 1.16 matt u_long marks[MARK_MAX]; 202 1.3 ragge 203 1.3 ragge if (arg) { 204 1.3 ragge while (*arg == ' ') 205 1.3 ragge arg++; 206 1.3 ragge 207 1.3 ragge if (*arg != '-') { 208 1.3 ragge fn = arg; 209 1.21 jdolecek if ((arg = strchr(arg, ' '))) { 210 1.3 ragge *arg++ = 0; 211 1.3 ragge while (*arg == ' ') 212 1.3 ragge arg++; 213 1.3 ragge } else 214 1.3 ragge goto load; 215 1.3 ragge } 216 1.3 ragge if (*arg != '-') { 217 1.14 jdolecek fail: printf("usage: boot [filename] [-asdqv]\n"); 218 1.3 ragge return; 219 1.3 ragge } 220 1.3 ragge 221 1.14 jdolecek howto = 0; 222 1.3 ragge while (*++arg) { 223 1.14 jdolecek fl = 0; 224 1.14 jdolecek BOOT_FLAG(*arg, fl); 225 1.14 jdolecek if (!fl) 226 1.3 ragge goto fail; 227 1.14 jdolecek howto |= fl; 228 1.3 ragge } 229 1.14 jdolecek bootrpb.rpb_bootr5 = howto; 230 1.1 ragge } 231 1.22 junyoung load: 232 1.16 matt marks[MARK_START] = 0; 233 1.33 martin fd = loadfile(fn, marks, LOAD_KERNEL|COUNT_KERNEL); 234 1.33 martin if (fd >= 0) { 235 1.33 martin close(fd); 236 1.17 matt machdep_start((char *)marks[MARK_ENTRY], 237 1.17 matt marks[MARK_NSYM], 238 1.16 matt (void *)marks[MARK_START], 239 1.16 matt (void *)marks[MARK_SYM], 240 1.16 matt (void *)marks[MARK_END]); 241 1.16 matt } 242 1.3 ragge printf("Boot failed: %s\n", strerror(errno)); 243 1.1 ragge } 244 1.1 ragge 245 1.1 ragge /* 750 Patchable Control Store magic */ 246 1.1 ragge 247 1.1 ragge #include "../include/mtpr.h" 248 1.1 ragge #include "../include/cpu.h" 249 1.1 ragge #include "../include/sid.h" 250 1.1 ragge #define PCS_BITCNT 0x2000 /* number of patchbits */ 251 1.1 ragge #define PCS_MICRONUM 0x400 /* number of ucode locs */ 252 1.1 ragge #define PCS_PATCHADDR 0xf00000 /* start addr of patchbits */ 253 1.1 ragge #define PCS_PCSADDR (PCS_PATCHADDR+0x8000) /* start addr of pcs */ 254 1.1 ragge #define PCS_PATCHBIT (PCS_PATCHADDR+0xc000) /* patchbits enable reg */ 255 1.1 ragge #define PCS_ENABLE 0xfff00000 /* enable bits for pcs */ 256 1.1 ragge 257 1.1 ragge #define extzv(one, two, three,four) \ 258 1.1 ragge ({ \ 259 1.26 perry __asm volatile ("extzv %0,%3,%1,%2" \ 260 1.1 ragge : \ 261 1.19 matt : "g"(one),"m"(two),"mo>"(three),"g"(four)); \ 262 1.1 ragge }) 263 1.1 ragge 264 1.1 ragge 265 1.6 ragge void 266 1.28 cegger loadpcs(void) 267 1.1 ragge { 268 1.1 ragge static int pcsdone = 0; 269 1.1 ragge int mid = mfpr(PR_SID); 270 1.1 ragge int i, j, *ip, *jp; 271 1.1 ragge char pcs[100]; 272 1.1 ragge char *cp; 273 1.1 ragge 274 1.1 ragge if ((mid >> 24) != VAX_750 || ((mid >> 8) & 255) < 95 || pcsdone) 275 1.1 ragge return; 276 1.1 ragge printf("Updating 11/750 microcode: "); 277 1.1 ragge for (cp = line; *cp; cp++) 278 1.1 ragge if (*cp == ')' || *cp == ':') 279 1.1 ragge break; 280 1.1 ragge if (*cp) { 281 1.30 cegger memcpy(pcs, line, 99); 282 1.1 ragge pcs[99] = 0; 283 1.1 ragge i = cp - line + 1; 284 1.1 ragge } else 285 1.1 ragge i = 0; 286 1.1 ragge strcpy(pcs + i, "pcs750.bin"); 287 1.1 ragge i = open(pcs, 0); 288 1.1 ragge if (i < 0) { 289 1.1 ragge printf("bad luck - missing pcs750.bin :-(\n"); 290 1.1 ragge return; 291 1.1 ragge } 292 1.1 ragge /* 293 1.1 ragge * We ask for more than we need to be sure we get only what we expect. 294 1.1 ragge * After read: 295 1.1 ragge * locs 0 - 1023 packed patchbits 296 1.1 ragge * 1024 - 11264 packed microcode 297 1.1 ragge */ 298 1.1 ragge if (read(i, (char *)0, 23*512) != 22*512) { 299 1.1 ragge printf("Error reading %s\n", pcs); 300 1.1 ragge close(i); 301 1.1 ragge return; 302 1.1 ragge } 303 1.1 ragge close(i); 304 1.1 ragge 305 1.1 ragge /* 306 1.1 ragge * Enable patchbit loading and load the bits one at a time. 307 1.1 ragge */ 308 1.1 ragge *((int *)PCS_PATCHBIT) = 1; 309 1.1 ragge ip = (int *)PCS_PATCHADDR; 310 1.1 ragge jp = (int *)0; 311 1.1 ragge for (i=0; i < PCS_BITCNT; i++) { 312 1.19 matt extzv(i,*jp,*ip++,1); 313 1.1 ragge } 314 1.1 ragge *((int *)PCS_PATCHBIT) = 0; 315 1.1 ragge 316 1.1 ragge /* 317 1.1 ragge * Load PCS microcode 20 bits at a time. 318 1.1 ragge */ 319 1.1 ragge ip = (int *)PCS_PCSADDR; 320 1.35 kalvisd 321 1.35 kalvisd /* 322 1.35 kalvisd * XXXGCC12 323 1.36 rin * GCC12 blames pointer access to 0-th page, [0, 0xfff], for 324 1.35 kalvisd * -Warray-bounds. Just silence as it is harmless. 325 1.35 kalvisd */ 326 1.35 kalvisd #pragma GCC diagnostic push 327 1.35 kalvisd #pragma GCC diagnostic ignored "-Warray-bounds" 328 1.1 ragge jp = (int *)1024; 329 1.1 ragge for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) { 330 1.19 matt extzv(i,*jp,*ip++,20); 331 1.1 ragge } 332 1.1 ragge 333 1.1 ragge /* 334 1.1 ragge * Enable PCS. 335 1.1 ragge */ 336 1.1 ragge i = *jp; /* get 1st 20 bits of microcode again */ 337 1.35 kalvisd #pragma GCC diagnostic pop 338 1.35 kalvisd 339 1.1 ragge i &= 0xfffff; 340 1.1 ragge i |= PCS_ENABLE; /* reload these bits with PCS enable set */ 341 1.1 ragge *((int *)PCS_PCSADDR) = i; 342 1.1 ragge 343 1.1 ragge mid = mfpr(PR_SID); 344 1.1 ragge printf("new rev level=%d\n", V750UCODE(mid)); 345 1.1 ragge pcsdone = 1; 346 1.1 ragge } 347 1.1 ragge 348 1.1 ragge void 349 1.6 ragge usage(char *hej) 350 1.1 ragge { 351 1.8 matt const struct vals *v = &val[0]; 352 1.1 ragge 353 1.1 ragge printf("Commands:\n"); 354 1.1 ragge while (v->namn) { 355 1.1 ragge printf("%s\t%s\n", v->namn, v->info); 356 1.1 ragge v++; 357 1.1 ragge } 358 1.1 ragge } 359