1 /* $NetBSD: machdep.c,v 1.158 2026/06/10 21:24:11 andvar Exp $ */ 2 3 /* 4 * Copyright (c) 2000 Soren S. Jorvang 5 * Copyright (c) 2001, 2002, 2003 Rafal K. Boni 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed for the 19 * NetBSD Project. See http://www.NetBSD.org/ for 20 * information about NetBSD. 21 * 4. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include <sys/cdefs.h> 37 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.158 2026/06/10 21:24:11 andvar Exp $"); 38 39 #include "opt_ddb.h" 40 #include "opt_kgdb.h" 41 #include "opt_execfmt.h" 42 #include "opt_cputype.h" 43 #include "opt_mips_cache.h" 44 #include "opt_modular.h" 45 46 #define __INTR_PRIVATE 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/kernel.h> 51 #include <sys/proc.h> 52 #include <sys/buf.h> 53 #include <sys/bus.h> 54 #include <sys/reboot.h> 55 #include <sys/conf.h> 56 #include <sys/file.h> 57 #include <sys/intr.h> 58 #include <sys/mbuf.h> 59 #include <sys/msgbuf.h> 60 #include <sys/device.h> 61 #include <sys/exec.h> 62 #include <sys/mount.h> 63 #include <sys/syscallargs.h> 64 #include <sys/kcore.h> 65 #include <sys/boot_flag.h> 66 #include <sys/ksyms.h> 67 #include <sys/cpu.h> 68 69 #include <uvm/uvm_extern.h> 70 71 #include <mips/locore.h> 72 73 #include <machine/reg.h> 74 #include <machine/psl.h> 75 #include <machine/autoconf.h> 76 #include <machine/machtype.h> 77 #include <machine/sysconf.h> 78 #include <machine/bootinfo.h> 79 80 #include <mips/cache.h> 81 #include <mips/cache_r5k.h> 82 #ifdef ENABLE_MIPS4_CACHE_R10K 83 #include <mips/cache_r10k.h> 84 #endif 85 86 #include <sgimips/dev/int2reg.h> 87 #include <sgimips/dev/crimevar.h> 88 #include <sgimips/sgimips/arcemu.h> 89 90 #include <dev/arcbios/arcbios.h> 91 #include <dev/arcbios/arcbiosvar.h> 92 93 #include "ksyms.h" 94 95 #if NKSYMS || defined(DDB) || defined(MODULAR) || defined(KGDB) 96 #include <machine/db_machdep.h> 97 #include <ddb/db_access.h> 98 #include <ddb/db_sym.h> 99 #include <ddb/db_extern.h> 100 #include <sys/exec_elf.h> 101 #endif 102 103 #include "mcclock_mace.h" 104 #include "crime.h" 105 106 #if NMCCLOCK_MACE > 0 107 void mcclock_poweroff(void); 108 #endif 109 110 struct sgimips_intrhand intrtab[NINTR]; 111 112 /* Maps for VM objects. */ 113 struct vm_map *phys_map = NULL; 114 115 int mach_type = 0; /* IPxx type */ 116 int mach_subtype = 0; /* subtype: eg., Guinness/Fullhouse for IP22 */ 117 int mach_boardrev = 0; /* machine board revision, in case it matters */ 118 119 int arcsmem; /* Memory used by the ARCS firmware */ 120 121 int ncpus; 122 123 #define IPL2SPL_TABLE_COMMON \ 124 [IPL_NONE] = 0, \ 125 [IPL_SOFTCLOCK] = MIPS_SOFT_INT_MASK_0, \ 126 [IPL_SOFTNET] = MIPS_SOFT_INT_MASK, \ 127 [IPL_DDB] = MIPS_INT_MASK, \ 128 [IPL_HIGH] = MIPS_INT_MASK 129 130 /* CPU interrupt sr maps */ 131 #if defined(MIPS1) 132 static const struct ipl_sr_map sgi_ip6_ipl_sr_map = { 133 .sr_bits = { 134 IPL2SPL_TABLE_COMMON, 135 [IPL_VM] = MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, 136 [IPL_SCHED] = MIPS_INT_MASK_4|MIPS_INT_MASK_2| 137 MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, 138 }, 139 }; 140 static const struct ipl_sr_map sgi_ip12_ipl_sr_map = { 141 .sr_bits = { 142 IPL2SPL_TABLE_COMMON, 143 [IPL_VM] = MIPS_INT_MASK_2|MIPS_INT_MASK_1|MIPS_INT_MASK_0| 144 MIPS_SOFT_INT_MASK, 145 [IPL_SCHED] = MIPS_INT_MASK_4|MIPS_INT_MASK_3|MIPS_INT_MASK_2| 146 MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, 147 }, 148 }; 149 #endif /* defined(MIPS1) */ 150 151 #if defined(MIPS3) 152 static const struct ipl_sr_map sgi_ip2x_ipl_sr_map = { 153 .sr_bits = { 154 IPL2SPL_TABLE_COMMON, 155 [IPL_VM] = MIPS_INT_MASK_1|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, 156 [IPL_SCHED] = MIPS_INT_MASK, 157 }, 158 }; 159 static const struct ipl_sr_map sgi_ip3x_ipl_sr_map = { 160 .sr_bits = { 161 IPL2SPL_TABLE_COMMON, 162 [IPL_VM] = MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, 163 [IPL_SCHED] = MIPS_INT_MASK_5|MIPS_INT_MASK_0|MIPS_SOFT_INT_MASK, 164 }, 165 }; 166 #endif /* defined(MIPS3) */ 167 168 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 169 int mem_cluster_cnt; 170 171 #if defined(INDY_R4600_CACHE) 172 extern void ip22_sdcache_disable(void); 173 extern void ip22_sdcache_enable(void); 174 #endif 175 176 #if defined(MIPS3) 177 extern void mips3_clock_intr(vaddr_t, uint32_t, uint32_t); 178 #endif 179 180 void mach_init(int, int32_t *, uintptr_t, int32_t); 181 182 void sgimips_count_cpus(struct arcbios_component *, 183 struct arcbios_treewalk_context *); 184 185 #ifdef KGDB 186 void kgdb_port_init(void); 187 void kgdb_connect(int); 188 #endif 189 190 void mips_machdep_find_l2cache(struct arcbios_component *comp, struct arcbios_treewalk_context *atc); 191 192 /* Motherboard or system-specific initialization vector */ 193 static void unimpl_bus_reset(void); 194 static void unimpl_cons_init(void); 195 static void *unimpl_intr_establish(int, int, int (*)(void *), void *); 196 static void unimpl_intr(vaddr_t, uint32_t, uint32_t); 197 static unsigned long nulllong(void); 198 static void nullvoid(void); 199 200 void ddb_trap_hook(int where); 201 202 static int badaddr_workaround(void *, size_t); 203 204 struct platform platform = { 205 .badaddr = badaddr_workaround, 206 .bus_reset = unimpl_bus_reset, 207 .cons_init = unimpl_cons_init, 208 .intr_establish = unimpl_intr_establish, 209 .clkread = nulllong, 210 .watchdog_reset = nullvoid, 211 .watchdog_disable = nullvoid, 212 .watchdog_enable = nullvoid, 213 .intr0 = unimpl_intr, 214 .intr1 = unimpl_intr, 215 .intr2 = unimpl_intr, 216 .intr3 = unimpl_intr, 217 .intr4 = unimpl_intr, 218 .intr5 = unimpl_intr 219 }; 220 221 extern u_int32_t ssir; 222 extern char kernel_text[], edata[], end[]; 223 224 uint8_t *bootinfo; /* pointer to bootinfo structure */ 225 static uint8_t bi_buf[BOOTINFO_SIZE]; /* buffer to store bootinfo data */ 226 static const char *bootinfo_msg = NULL; 227 228 #define ARCS_VECTOR MIPS_PHYS_TO_KSEG0(0x00001000) 229 230 /* 231 * Do all the stuff that locore normally does before calling main(). 232 * Process arguments passed to us by the ARCS firmware. 233 */ 234 void 235 mach_init(int argc, int32_t argv32[], uintptr_t magic, int32_t bip32) 236 { 237 paddr_t first, last; 238 vsize_t size; 239 void *bip = (void *)(intptr_t)bip32; 240 struct arcbios_mem *mem; 241 const char *cpufreq, *osload; 242 char *bootpath = NULL; 243 vaddr_t kernend; 244 u_int i; 245 int rv; 246 #if NKSYMS || defined(DDB) || defined(MODULAR) 247 int nsym = 0; 248 char *ssym = NULL; 249 char *esym = NULL; 250 struct btinfo_symtab *bi_syms; 251 #endif /* NKSYMS || defined(DDB) || defined(MODULAR) */ 252 #ifdef _LP64 253 char *argv[20]; 254 255 if (argc >= __arraycount(argv)) 256 panic("too many args"); 257 258 for (i = 0; i < argc; i++) { 259 argv[i] = (void *)(intptr_t)argv32[i]; 260 } 261 #else 262 char **argv = (void *)argv32; 263 #endif 264 265 /* 266 * Initialize firmware. This will set up the bootstrap console. 267 * At this point we do not yet know the machine type, so we 268 * try to init real arcbios, and if that fails (return value 1), 269 * fall back to the emulator. If the latter fails also we 270 * don't have much to panic with. 271 * 272 * The third argument (magic) is the environment variable array if 273 * there's no bootinfo. 274 */ 275 if (arcbios_init(ARCS_VECTOR) == 1) { 276 #ifdef _LP64 277 panic("no ARCS firmware"); 278 #else 279 if (magic == BOOTINFO_MAGIC) 280 arcemu_init(NULL); /* XXX - need some prom env */ 281 else 282 arcemu_init((const char **)magic); 283 #endif 284 } 285 286 cpu_setmodel("%s", arcbios_system_identifier); 287 288 /* 289 * Copy exception-dispatch code down to exception vector. 290 * Initialize locore-function vector. 291 * Clear out the I and D caches. 292 */ 293 mips_vector_init(NULL, false); 294 295 uvm_md_init(); 296 297 /* set up bootinfo structures */ 298 if (magic == BOOTINFO_MAGIC && bip != NULL) { 299 struct btinfo_magic *bi_magic; 300 struct btinfo_bootpath *bi_path; 301 302 memcpy(bi_buf, bip, BOOTINFO_SIZE); 303 bootinfo = bi_buf; 304 bi_magic = lookup_bootinfo(BTINFO_MAGIC); 305 if (bi_magic != NULL && bi_magic->magic == BOOTINFO_MAGIC) { 306 bootinfo_msg = "bootinfo found.\n"; 307 bi_path = lookup_bootinfo(BTINFO_BOOTPATH); 308 if (bi_path != NULL) 309 bootpath = bi_path->bootpath; 310 } else 311 bootinfo_msg = 312 "invalid magic number in bootinfo structure.\n"; 313 } else 314 bootinfo_msg = "no bootinfo found. (old bootblocks?)\n"; 315 316 #if NKSYMS || defined(DDB) || defined(MODULAR) 317 bi_syms = lookup_bootinfo(BTINFO_SYMTAB); 318 319 /* check whether there is valid bootinfo symtab info */ 320 if (bi_syms != NULL) { 321 nsym = bi_syms->nsym; 322 ssym = (char *)bi_syms->ssym; 323 esym = (char *)bi_syms->esym; 324 kernend = mips_round_page(esym); 325 } else 326 #endif /* NKSYMS || defined(DDB) || defined(MODULAR) */ 327 { 328 kernend = mips_round_page(end); 329 } 330 331 cpufreq = arcbios_GetEnvironmentVariable("cpufreq"); 332 333 if (cpufreq == 0) 334 panic("no $cpufreq"); 335 336 /* 337 * Note initial estimate of CPU speed... If we care enough, we'll 338 * use the RTC to get a better estimate later. 339 */ 340 curcpu()->ci_cpu_freq = strtoul(cpufreq, NULL, 10) * 1000000; 341 342 /* 343 * Also initialize ci members for delay and clock by the temporary 344 * ci_cpu_freq value for early use of delay(9). 345 * These values will be calibrated later in MD code: 346 * - int_attach() in dev/int.c for IP6/10/12/20/22 347 * - crime_attach() in dev/crime.c for IP32 348 * 349 * XXX: ci_divisor_delay is for mips3_delay() in mips/mips3_clock.c 350 * but sgimips abuse it as "instructions per microsecond" 351 * for traditional delay(9) implementation derived from 352 * 4.4BSD/mips (also used in pmax and news3400). 353 * (see sys/arch/mips/mips/mips_mcclock.c etc.) 354 * 355 * Note ci_cycles_per_hz is for mips3_clockintr.c for MIPS3 so 356 * there is no early use, but initialize it as a sane default. 357 */ 358 curcpu()->ci_cycles_per_hz = curcpu()->ci_cpu_freq / (2 * hz); 359 curcpu()->ci_divisor_delay = curcpu()->ci_cpu_freq / (2 * 1000000); 360 361 /* 362 * Check machine (IPn) type. 363 * 364 * Note even on IP12 (which doesn't have ARCBIOS), 365 * arcbios_system_identifier[] has been initialized 366 * in arcemu_ip12_init(). 367 */ 368 for (i = 0; arcbios_system_identifier[i] != '\0'; i++) { 369 if (mach_type == 0 && 370 arcbios_system_identifier[i] >= '0' && 371 arcbios_system_identifier[i] <= '9') { 372 mach_type = strtoul(&arcbios_system_identifier[i], 373 NULL, 10); 374 break; 375 } 376 } 377 if (mach_type <= 0) 378 panic("invalid architecture"); 379 380 /* 381 * Initialise the IP22 Indy/Indigo2 subtype early. 382 * 383 * This is needed for various subsystems that require mach_subtype 384 * to properly initialise. It's also setup in ioc/ioc.c but 385 * that's far too late for some peripherals (notably Indigo2 INT2 386 * timer programming/calibration.) 387 */ 388 if (mach_type == MACH_SGI_IP22) { 389 i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd9858); 390 if (i & 0x01) 391 mach_subtype = MACH_SGI_IP22_FULLHOUSE; /* Indigo2 */ 392 else 393 mach_subtype = MACH_SGI_IP22_GUINNESS; /* Indy */ 394 } 395 396 /* 397 * Get boot device information. 398 */ 399 400 /* Try to get the boot device information from bootinfo first. */ 401 if (bootpath != NULL) 402 makebootdev(bootpath); 403 else { 404 /* 405 * The old bootloader prior to 5.0 doesn't pass bootinfo. 406 * If argv[0] is the bootloader, then argv[1] might be 407 * the kernel that was loaded. 408 * If argv[1] isn't an environment string, try to use it 409 * to set the boot device. 410 */ 411 if (argc > 1 && strchr(argv[1], '=') != 0) 412 makebootdev(argv[1]); 413 414 /* 415 * If we are loaded directly by ARCBIOS, 416 * argv[0] is the path of the loaded kernel, 417 * but booted_partition could be SGIVOLHDR in such case, 418 * so assume root is partition a. 419 */ 420 if (argc > 0 && argv[0] != NULL) { 421 makebootdev(argv[0]); 422 booted_partition = 0; 423 } 424 } 425 426 /* 427 * Also try to get the default bootpath from ARCBIOS environment 428 * because bootpath is not set properly by old bootloaders and 429 * argv[0] might be invalid on some machine. 430 */ 431 osload = arcbios_GetEnvironmentVariable("OSLoadPartition"); 432 if (osload != NULL) 433 makebootdev(osload); 434 435 /* 436 * The case where the kernel has been loaded by a 437 * boot loader will usually have been caught by 438 * the first makebootdev() case earlier on, but 439 * we still use OSLoadPartition to get the preferred 440 * root filesystem location, even if it's not 441 * actually the location of the loaded kernel. 442 */ 443 for (i = 0; i < argc; i++) { 444 if (strncmp(argv[i], "OSLoadPartition=", 15) == 0) 445 makebootdev(argv[i] + 16); 446 } 447 448 /* 449 * When the kernel is loaded directly by the firmware, and 450 * no explicit OSLoadPartition is set, we fall back on 451 * SystemPartition for the boot device. 452 */ 453 for (i = 0; i < argc; i++) { 454 if (strncmp(argv[i], "SystemPartition", 15) == 0) 455 makebootdev(argv[i] + 16); 456 } 457 458 /* 459 * Single- or multi-user ('auto' in SGI terms). 460 * 461 * Query ARCBIOS first, then default to environment variables. 462 */ 463 464 /* Set default to single user. */ 465 boothowto = RB_SINGLE; 466 467 osload = arcbios_GetEnvironmentVariable("OSLoadOptions"); 468 if (osload != NULL && strcmp(osload, "auto") == 0) 469 boothowto &= ~RB_SINGLE; 470 471 for (i = 0; i < argc; i++) { 472 if (strcmp(argv[i], "OSLoadOptions=auto") == 0) 473 boothowto &= ~RB_SINGLE; 474 } 475 476 /* 477 * Pass the args again to check for flags -- This is done 478 * AFTER checking for OSLoadOptions to ensure that "auto" 479 * does not override the "-s" flag. 480 */ 481 482 for (i = 0; i < argc; i++) { 483 /* 484 * Unfortunately, it appears that IP12's prom passes a '-a' 485 * flag when booting a kernel directly from a disk volume 486 * header. This corresponds to RB_ASKNAME in NetBSD, but 487 * appears to mean 'autoboot' in prehistoric SGI-speak. 488 */ 489 if (mach_type < MACH_SGI_IP20 && bootinfo == NULL && 490 strcmp(argv[i], "-a") == 0) 491 continue; 492 493 /* 494 * Extract out any flags passed for the kernel in the 495 * argument string. Warn for unknown/invalid flags, 496 * but silently skip non-flag arguments, as they are 497 * likely PROM environment values (if I knew those 498 * would always precede *any* flags, then I'd say we 499 * should warn about *all* unexpected values, but for 500 * now this should be fine). 501 * 502 * Use the MI boot-flag extractor since we don't use 503 * any special MD flags and to make sure we're up-to 504 * date with new MI flags whenever they're added. 505 */ 506 if (argv[i][0] == '-') { 507 rv = 0; 508 BOOT_FLAG(argv[i][1], rv); 509 510 if (rv == 0) { 511 printf("Unexpected option '%s' ignored", 512 argv[i]); 513 } else { 514 boothowto |= rv; 515 } 516 } 517 } 518 519 #ifdef DEBUG 520 boothowto |= AB_DEBUG; 521 #endif 522 aprint_debug("argc = %d\n", argc); 523 for (i = 0; i < argc; i++) 524 aprint_debug("argv[%d] = %s\n", i, argv[i]); 525 526 #if NKSYMS || defined(DDB) || defined(MODULAR) 527 /* init symbols if present */ 528 if (esym) 529 ksyms_addsyms_elf(nsym, ssym, esym); 530 #endif /* NKSYMS || defined(DDB) || defined(MODULAR) */ 531 532 #if defined(KGDB) || defined(DDB) 533 /* Set up DDB hook to turn off watchdog on entry */ 534 db_trap_callback = ddb_trap_hook; 535 536 #ifdef DDB 537 if (boothowto & RB_KDB) 538 Debugger(); 539 #endif 540 541 #ifdef KGDB 542 kgdb_port_init(); 543 544 if (boothowto & RB_KDB) 545 kgdb_connect(0); 546 #endif 547 #endif 548 549 switch (mach_type) { 550 #if defined(MIPS1) 551 case MACH_SGI_IP6 | MACH_SGI_IP10: 552 platform.intr3 = mips1_fpu_intr; 553 ipl_sr_map = sgi_ip6_ipl_sr_map; 554 break; 555 556 case MACH_SGI_IP12: 557 i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000); 558 mach_boardrev = (i & 0x7000) >> 12; 559 560 if ((i & 0x8000) == 0) { 561 if (mach_boardrev < 7) 562 mach_subtype = MACH_SGI_IP12_4D_3X; 563 else 564 mach_subtype = MACH_SGI_IP12_VIP12; 565 } else { 566 if (mach_boardrev < 6) 567 mach_subtype = MACH_SGI_IP12_HP1; 568 else 569 mach_subtype = MACH_SGI_IP12_HPLC; 570 } 571 572 ipl_sr_map = sgi_ip12_ipl_sr_map; 573 platform.intr0 = mips1_fpu_intr; 574 break; 575 #endif /* MIPS1 */ 576 577 #if defined(MIPS3) 578 case MACH_SGI_IP20: 579 i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000); 580 mach_boardrev = (i & 0x7000) >> 12; 581 ipl_sr_map = sgi_ip2x_ipl_sr_map; 582 platform.intr5 = mips3_clock_intr; 583 break; 584 case MACH_SGI_IP22: 585 ipl_sr_map = sgi_ip2x_ipl_sr_map; 586 platform.intr5 = mips3_clock_intr; 587 break; 588 case MACH_SGI_IP30: 589 ipl_sr_map = sgi_ip3x_ipl_sr_map; 590 platform.intr5 = mips3_clock_intr; 591 break; 592 case MACH_SGI_IP32: 593 ipl_sr_map = sgi_ip3x_ipl_sr_map; 594 platform.intr5 = mips3_clock_intr; 595 break; 596 #endif /* MIPS3 */ 597 default: 598 panic("IP%d architecture not supported", mach_type); 599 break; 600 } 601 602 physmem = arcsmem = 0; 603 mem_cluster_cnt = 0; 604 mem = NULL; 605 606 #ifdef DEBUG 607 i = 0; 608 mem = NULL; 609 610 do { 611 if ((mem = arcbios_GetMemoryDescriptor(mem)) != NULL) { 612 i++; 613 printf("Mem block %d: type %d, " 614 "base 0x%04"PRIx32", size 0x%04"PRIx32"\n", 615 i, mem->Type, mem->BasePage, mem->PageCount); 616 } 617 } while (mem != NULL); 618 #endif 619 620 /* 621 * XXX This code assumes that ARCS provides the memory 622 * XXX sorted in ascending order. 623 */ 624 mem = NULL; 625 for (i = 0; mem_cluster_cnt < VM_PHYSSEG_MAX; i++) { 626 mem = arcbios_GetMemoryDescriptor(mem); 627 628 if (mem == NULL) 629 break; 630 631 first = round_page(mem->BasePage * ARCBIOS_PAGESIZE); 632 last = trunc_page(first + mem->PageCount * ARCBIOS_PAGESIZE); 633 size = last - first; 634 635 switch (mem->Type) { 636 case ARCBIOS_MEM_FreeContiguous: 637 case ARCBIOS_MEM_FreeMemory: 638 case ARCBIOS_MEM_LoadedProgram: 639 mem_clusters[mem_cluster_cnt].start = first; 640 mem_clusters[mem_cluster_cnt].size = size; 641 mem_cluster_cnt++; 642 break; 643 644 case ARCBIOS_MEM_FirmwareTemporary: 645 case ARCBIOS_MEM_FirmwarePermanent: 646 arcsmem += btoc(size); 647 break; 648 649 case ARCBIOS_MEM_ExceptionBlock: 650 case ARCBIOS_MEM_SystemParameterBlock: 651 case ARCBIOS_MEM_BadMemory: 652 break; 653 654 default: 655 panic("unknown memory descriptor %d type %d", 656 i, mem->Type); 657 } 658 659 physmem += btoc(size); 660 661 } 662 663 if (mem_cluster_cnt == 0) 664 panic("no free memory descriptors found"); 665 666 /* Leave 1 page before kernel untouched as that's where our initial 667 * kernel stack is */ 668 /* XXX We could free it in cpu_startup() though XXX */ 669 mips_page_physload((vaddr_t)kernel_text - PAGE_SIZE, (vaddr_t)kernend, 670 mem_clusters, mem_cluster_cnt, NULL, 0); 671 672 /* We can now no longer use bootinfo. */ 673 bootinfo = NULL; 674 675 /* 676 * Initialize mips version-dependent DMA handlers. 677 */ 678 sgimips_bus_dma_init(); 679 680 /* 681 * Walk the component tree and count the number of CPUs 682 * present in the system. 683 */ 684 arcbios_tree_walk(sgimips_count_cpus, NULL); 685 686 /* 687 * Initialize error message buffer (at end of core). 688 */ 689 mips_init_msgbuf(); 690 691 pmap_bootstrap(); 692 693 /* 694 * Allocate uarea for lwp0 and set it. 695 */ 696 mips_init_lwp0_uarea(); 697 } 698 699 void 700 sgimips_count_cpus(struct arcbios_component *node, 701 struct arcbios_treewalk_context *atc) 702 { 703 704 switch (node->Class) { 705 case COMPONENT_CLASS_ProcessorClass: 706 if (node->Type == COMPONENT_TYPE_CPU) 707 ncpus++; 708 break; 709 710 default: 711 break; 712 } 713 } 714 715 /* 716 * Allocate memory for variable-sized tables. 717 */ 718 void 719 cpu_startup(void) 720 { 721 vaddr_t minaddr, maxaddr; 722 char pbuf[9]; 723 724 #ifdef BOOTINFO_DEBUG 725 if (bootinfo_msg) 726 printf(bootinfo_msg); 727 #endif 728 729 printf("%s%s", copyright, version); 730 731 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 732 printf("total memory = %s\n", pbuf); 733 format_bytes(pbuf, sizeof(pbuf), ctob(arcsmem)); 734 printf("(%s reserved for ARCS)\n", pbuf); 735 736 minaddr = 0; 737 /* 738 * Allocate a submap for physio. 739 */ 740 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 741 VM_PHYS_SIZE, 0, false, NULL); 742 743 /* 744 * (No need to allocate an mbuf cluster submap. Mbuf clusters 745 * are allocated via the pool allocator, and we use KSEG to 746 * map those pages.) 747 */ 748 format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false))); 749 printf("avail memory = %s\n", pbuf); 750 } 751 752 int waittime = -1; 753 754 void 755 cpu_reboot(int howto, char *bootstr) 756 { 757 /* Take a snapshot before clobbering any registers. */ 758 savectx(curpcb); 759 760 if (cold) { 761 howto |= RB_HALT; 762 goto haltsys; 763 } 764 765 /* If "always halt" was specified as a boot flag, obey. */ 766 if (boothowto & RB_HALT) 767 howto |= RB_HALT; 768 769 boothowto = howto; 770 if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 771 waittime = 0; 772 vfs_shutdown(); 773 } 774 775 /* Clear and disable watchdog timer. */ 776 (void)(*platform.watchdog_disable)(); 777 778 splhigh(); 779 780 if (howto & RB_DUMP) 781 dumpsys(); 782 783 haltsys: 784 785 doshutdownhooks(); 786 787 pmf_system_shutdown(boothowto); 788 789 /* 790 * Calling arcbios_PowerDown() results in a "CP1 unusable trap" 791 * which lands me back in DDB, at least on my Indy. So, enable 792 * the FPU before asking the PROM to power down to avoid this.. 793 * It seems to want the FPU to play the `poweroff tune' 8-/ 794 */ 795 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { 796 /* Set CP1 usable bit in SR */ 797 mips_cp0_status_write(mips_cp0_status_read() | 798 MIPS_SR_COP_1_BIT); 799 800 printf("powering off...\n\n"); 801 delay(500000); 802 #if NMCCLOCK_MACE > 0 803 if (mach_type == MACH_SGI_IP32) { 804 mcclock_poweroff(); 805 } else 806 #endif 807 arcbios_PowerDown(); 808 printf("WARNING: powerdown failed\n"); 809 /* 810 * RB_POWERDOWN implies RB_HALT... fall into it... 811 */ 812 } 813 814 if (howto & RB_HALT) { 815 printf("halting...\n\n"); 816 arcbios_EnterInteractiveMode(); 817 } 818 819 printf("rebooting...\n\n"); 820 #if NCRIME > 0 821 if (mach_type == MACH_SGI_IP32) { 822 crime_reboot(); 823 } else 824 #endif 825 arcbios_Reboot(); 826 827 for (;;); 828 } 829 830 void delay(unsigned long n) 831 { 832 register int __N = curcpu()->ci_divisor_delay * n; 833 834 do { 835 __asm("addiu %0,%1,-1" : "=r" (__N) : "0" (__N)); 836 } while (__N > 0); 837 } 838 839 /* 840 * IP12 appears to be buggy and unable to reliably support badaddr. 841 * Approximately 1.8% of the time a false negative (bad address said to 842 * be good) is generated and we stomp on invalid registers. Testing has 843 * not shown false positives, nor consecutive false negatives to occur. 844 */ 845 static int 846 badaddr_workaround(void *addr, size_t size) 847 { 848 int i, bad; 849 850 for (i = bad = 0; i < 100; i++) { 851 if (badaddr(addr, size)) 852 bad++; 853 } 854 855 /* false positives appear not to occur */ 856 return (bad != 0); 857 } 858 859 /* 860 * Ensure all platform vectors are always initialized. 861 */ 862 static void 863 unimpl_bus_reset(void) 864 { 865 866 panic("target init didn't set bus_reset"); 867 } 868 869 static void 870 unimpl_cons_init(void) 871 { 872 873 panic("target init didn't set cons_init"); 874 } 875 876 static void * 877 unimpl_intr_establish(int level, int ipl, int (*handler) (void *), void *arg) 878 { 879 panic("target init didn't set intr_establish"); 880 return NULL; 881 } 882 883 static void 884 unimpl_intr(vaddr_t pc, uint32_t status, uint32_t pending) 885 { 886 printf("spurious interrupt pending %#x\n", pending); 887 } 888 889 static unsigned long 890 nulllong(void) 891 { 892 printf("nulllong\n"); 893 return (0); 894 } 895 896 static void 897 nullvoid(void) 898 { 899 printf("nullvoid\n"); 900 return; 901 } 902 903 void * 904 lookup_bootinfo(int type) 905 { 906 struct btinfo_common *bt; 907 uint8_t *bip; 908 909 /* check for a bootinfo record first */ 910 if (bootinfo == NULL) 911 return NULL; 912 913 bip = bootinfo; 914 do { 915 bt = (struct btinfo_common *)bip; 916 if (bt->type == type) 917 return (void *)bt; 918 bip += bt->next; 919 } while (bt->next != 0 && 920 bt->next < BOOTINFO_SIZE /* sanity */ && 921 (size_t)bip < (size_t)bootinfo + BOOTINFO_SIZE); 922 923 return NULL; 924 } 925 926 #if defined(DDB) || defined(KGDB) 927 928 void ddb_trap_hook(int where) 929 { 930 switch (where) { 931 case 1: /* Entry to DDB, turn watchdog off */ 932 (void)(*platform.watchdog_disable)(); 933 break; 934 935 case 0: /* Exit from DDB, turn watchdog back on */ 936 (void)(*platform.watchdog_enable)(); 937 break; 938 } 939 } 940 941 #endif 942 943 void mips_machdep_cache_config(void) 944 { 945 946 arcbios_tree_walk(mips_machdep_find_l2cache, NULL); 947 948 switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) { 949 #if defined(INDY_R4600_CACHE) 950 case MIPS_R4600: 951 /* 952 * R4600 is on Indy-class machines only. Disable and 953 * flush pcache. 954 */ 955 mips_cache_info.mci_sdcache_size = 0; 956 mips_cache_info.mci_sdcache_line_size = 0; 957 ip22_sdcache_disable(); 958 break; 959 #endif 960 #if defined(MIPS3) 961 case MIPS_R5000: 962 case MIPS_RM5200: 963 r5k_enable_sdcache(); 964 break; 965 #endif 966 } 967 } 968 969 void 970 mips_machdep_find_l2cache(struct arcbios_component *comp, struct arcbios_treewalk_context *atc) 971 { 972 struct mips_cache_info * const mci = &mips_cache_info; 973 device_t self = atc->atc_cookie; 974 975 if (comp->Class != COMPONENT_CLASS_CacheClass) 976 return; 977 978 switch (comp->Type) { 979 case COMPONENT_TYPE_SecondaryICache: 980 panic("%s: split L2 cache", device_xname(self)); 981 case COMPONENT_TYPE_SecondaryDCache: 982 case COMPONENT_TYPE_SecondaryCache: 983 mci->mci_sdcache_size = COMPONENT_KEY_Cache_CacheSize(comp->Key); 984 mci->mci_sdcache_line_size = 985 COMPONENT_KEY_Cache_LineSize(comp->Key); 986 /* XXX */ 987 mci->mci_sdcache_ways = 1; 988 break; 989 } 990 } 991