1/* $NetBSD: machdep.c,v 1.156 2024/05/23 06:14:12 skrll 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.156 2024/05/23 06:14:12 skrll 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 107void mcclock_poweroff(void); 108#endif 109 110struct sgimips_intrhand intrtab[NINTR]; 111 112/* Maps for VM objects. */ 113struct vm_map *phys_map = NULL; 114 115int mach_type = 0; /* IPxx type */ 116int mach_subtype = 0; /* subtype: eg., Guinness/Fullhouse for IP22 */ 117int mach_boardrev = 0; /* machine board revision, in case it matters */ 118 119int arcsmem; /* Memory used by the ARCS firmware */ 120 121int 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) 132static 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}; 140static 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) 152static 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}; 159static 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 168phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 169int mem_cluster_cnt; 170 171#if defined(INDY_R4600_CACHE) 172extern void ip22_sdcache_disable(void); 173extern void ip22_sdcache_enable(void); 174#endif 175 176#if defined(MIPS3) 177extern void mips3_clock_intr(vaddr_t, uint32_t, uint32_t); 178#endif 179 180void mach_init(int, int32_t *, uintptr_t, int32_t); 181 182void sgimips_count_cpus(struct arcbios_component *, 183 struct arcbios_treewalk_context *); 184 185#ifdef KGDB 186void kgdb_port_init(void); 187void kgdb_connect(int); 188#endif 189 190void mips_machdep_find_l2cache(struct arcbios_component *comp, struct arcbios_treewalk_context *atc); 191 192/* Motherboard or system-specific initialization vector */ 193static void unimpl_bus_reset(void); 194static void unimpl_cons_init(void); 195static void *unimpl_intr_establish(int, int, int (*)(void *), void *); 196static void unimpl_intr(vaddr_t, uint32_t, uint32_t); 197static unsigned long nulllong(void); 198static void nullvoid(void); 199 200void ddb_trap_hook(int where); 201 202static int badaddr_workaround(void *, size_t); 203 204struct 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 221extern u_int32_t ssir; 222extern char kernel_text[], edata[], end[]; 223 224uint8_t *bootinfo; /* pointer to bootinfo structure */ 225static uint8_t bi_buf[BOOTINFO_SIZE]; /* buffer to store bootinfo data */ 226static 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 */ 234void 235mach_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_identifiler[] has been initilialized 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 * Get boot device information. 382 */ 383 384 /* Try to get the boot device information from bootinfo first. */ 385 if (bootpath != NULL) 386 makebootdev(bootpath); 387 else { 388 /* 389 * The old bootloader prior to 5.0 doesn't pass bootinfo. 390 * If argv[0] is the bootloader, then argv[1] might be 391 * the kernel that was loaded. 392 * If argv[1] isn't an environment string, try to use it 393 * to set the boot device. 394 */ 395 if (argc > 1 && strchr(argv[1], '=') != 0) 396 makebootdev(argv[1]); 397 398 /* 399 * If we are loaded directly by ARCBIOS, 400 * argv[0] is the path of the loaded kernel, 401 * but booted_partition could be SGIVOLHDR in such case, 402 * so assume root is partition a. 403 */ 404 if (argc > 0 && argv[0] != NULL) { 405 makebootdev(argv[0]); 406 booted_partition = 0; 407 } 408 } 409 410 /* 411 * Also try to get the default bootpath from ARCBIOS environment 412 * because bootpath is not set properly by old bootloaders and 413 * argv[0] might be invalid on some machine. 414 */ 415 osload = arcbios_GetEnvironmentVariable("OSLoadPartition"); 416 if (osload != NULL) 417 makebootdev(osload); 418 419 /* 420 * The case where the kernel has been loaded by a 421 * boot loader will usually have been caught by 422 * the first makebootdev() case earlier on, but 423 * we still use OSLoadPartition to get the preferred 424 * root filesystem location, even if it's not 425 * actually the location of the loaded kernel. 426 */ 427 for (i = 0; i < argc; i++) { 428 if (strncmp(argv[i], "OSLoadPartition=", 15) == 0) 429 makebootdev(argv[i] + 16); 430 } 431 432 /* 433 * When the kernel is loaded directly by the firmware, and 434 * no explicit OSLoadPartition is set, we fall back on 435 * SystemPartition for the boot device. 436 */ 437 for (i = 0; i < argc; i++) { 438 if (strncmp(argv[i], "SystemPartition", 15) == 0) 439 makebootdev(argv[i] + 16); 440 } 441 442 /* 443 * Single- or multi-user ('auto' in SGI terms). 444 * 445 * Query ARCBIOS first, then default to environment variables. 446 */ 447 448 /* Set default to single user. */ 449 boothowto = RB_SINGLE; 450 451 osload = arcbios_GetEnvironmentVariable("OSLoadOptions"); 452 if (osload != NULL && strcmp(osload, "auto") == 0) 453 boothowto &= ~RB_SINGLE; 454 455 for (i = 0; i < argc; i++) { 456 if (strcmp(argv[i], "OSLoadOptions=auto") == 0) 457 boothowto &= ~RB_SINGLE; 458 } 459 460 /* 461 * Pass the args again to check for flags -- This is done 462 * AFTER checking for OSLoadOptions to ensure that "auto" 463 * does not override the "-s" flag. 464 */ 465 466 for (i = 0; i < argc; i++) { 467 /* 468 * Unfortunately, it appears that IP12's prom passes a '-a' 469 * flag when booting a kernel directly from a disk volume 470 * header. This corresponds to RB_ASKNAME in NetBSD, but 471 * appears to mean 'autoboot' in prehistoric SGI-speak. 472 */ 473 if (mach_type < MACH_SGI_IP20 && bootinfo == NULL && 474 strcmp(argv[i], "-a") == 0) 475 continue; 476 477 /* 478 * Extract out any flags passed for the kernel in the 479 * argument string. Warn for unknown/invalid flags, 480 * but silently skip non-flag arguments, as they are 481 * likely PROM environment values (if I knew those 482 * would always precede *any* flags, then I'd say we 483 * should warn about *all* unexpected values, but for 484 * now this should be fine). 485 * 486 * Use the MI boot-flag extractor since we don't use 487 * any special MD flags and to make sure we're up-to 488 * date with new MI flags whenever they're added. 489 */ 490 if (argv[i][0] == '-') { 491 rv = 0; 492 BOOT_FLAG(argv[i][1], rv); 493 494 if (rv == 0) { 495 printf("Unexpected option '%s' ignored", 496 argv[i]); 497 } else { 498 boothowto |= rv; 499 } 500 } 501 } 502 503#ifdef DEBUG 504 boothowto |= AB_DEBUG; 505#endif 506 aprint_debug("argc = %d\n", argc); 507 for (i = 0; i < argc; i++) 508 aprint_debug("argv[%d] = %s\n", i, argv[i]); 509 510#if NKSYMS || defined(DDB) || defined(MODULAR) 511 /* init symbols if present */ 512 if (esym) 513 ksyms_addsyms_elf(nsym, ssym, esym); 514#endif /* NKSYMS || defined(DDB) || defined(MODULAR) */ 515 516#if defined(KGDB) || defined(DDB) 517 /* Set up DDB hook to turn off watchdog on entry */ 518 db_trap_callback = ddb_trap_hook; 519 520#ifdef DDB 521 if (boothowto & RB_KDB) 522 Debugger(); 523#endif 524 525#ifdef KGDB 526 kgdb_port_init(); 527 528 if (boothowto & RB_KDB) 529 kgdb_connect(0); 530#endif 531#endif 532 533 switch (mach_type) { 534#if defined(MIPS1) 535 case MACH_SGI_IP6 | MACH_SGI_IP10: 536 platform.intr3 = mips1_fpu_intr; 537 ipl_sr_map = sgi_ip6_ipl_sr_map; 538 break; 539 540 case MACH_SGI_IP12: 541 i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000); 542 mach_boardrev = (i & 0x7000) >> 12; 543 544 if ((i & 0x8000) == 0) { 545 if (mach_boardrev < 7) 546 mach_subtype = MACH_SGI_IP12_4D_3X; 547 else 548 mach_subtype = MACH_SGI_IP12_VIP12; 549 } else { 550 if (mach_boardrev < 6) 551 mach_subtype = MACH_SGI_IP12_HP1; 552 else 553 mach_subtype = MACH_SGI_IP12_HPLC; 554 } 555 556 ipl_sr_map = sgi_ip12_ipl_sr_map; 557 platform.intr0 = mips1_fpu_intr; 558 break; 559#endif /* MIPS1 */ 560 561#if defined(MIPS3) 562 case MACH_SGI_IP20: 563 i = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd0000); 564 mach_boardrev = (i & 0x7000) >> 12; 565 ipl_sr_map = sgi_ip2x_ipl_sr_map; 566 platform.intr5 = mips3_clock_intr; 567 break; 568 case MACH_SGI_IP22: 569 ipl_sr_map = sgi_ip2x_ipl_sr_map; 570 platform.intr5 = mips3_clock_intr; 571 break; 572 case MACH_SGI_IP30: 573 ipl_sr_map = sgi_ip3x_ipl_sr_map; 574 platform.intr5 = mips3_clock_intr; 575 break; 576 case MACH_SGI_IP32: 577 ipl_sr_map = sgi_ip3x_ipl_sr_map; 578 platform.intr5 = mips3_clock_intr; 579 break; 580#endif /* MIPS3 */ 581 default: 582 panic("IP%d architecture not supported", mach_type); 583 break; 584 } 585 586 physmem = arcsmem = 0; 587 mem_cluster_cnt = 0; 588 mem = NULL; 589 590#ifdef DEBUG 591 i = 0; 592 mem = NULL; 593 594 do { 595 if ((mem = arcbios_GetMemoryDescriptor(mem)) != NULL) { 596 i++; 597 printf("Mem block %d: type %d, " 598 "base 0x%04"PRIx32", size 0x%04"PRIx32"\n", 599 i, mem->Type, mem->BasePage, mem->PageCount); 600 } 601 } while (mem != NULL); 602#endif 603 604 /* 605 * XXX This code assumes that ARCS provides the memory 606 * XXX sorted in ascending order. 607 */ 608 mem = NULL; 609 for (i = 0; mem_cluster_cnt < VM_PHYSSEG_MAX; i++) { 610 mem = arcbios_GetMemoryDescriptor(mem); 611 612 if (mem == NULL) 613 break; 614 615 first = round_page(mem->BasePage * ARCBIOS_PAGESIZE); 616 last = trunc_page(first + mem->PageCount * ARCBIOS_PAGESIZE); 617 size = last - first; 618 619 switch (mem->Type) { 620 case ARCBIOS_MEM_FreeContiguous: 621 case ARCBIOS_MEM_FreeMemory: 622 case ARCBIOS_MEM_LoadedProgram: 623 mem_clusters[mem_cluster_cnt].start = first; 624 mem_clusters[mem_cluster_cnt].size = size; 625 mem_cluster_cnt++; 626 break; 627 628 case ARCBIOS_MEM_FirmwareTemporary: 629 case ARCBIOS_MEM_FirmwarePermanent: 630 arcsmem += btoc(size); 631 break; 632 633 case ARCBIOS_MEM_ExceptionBlock: 634 case ARCBIOS_MEM_SystemParameterBlock: 635 case ARCBIOS_MEM_BadMemory: 636 break; 637 638 default: 639 panic("unknown memory descriptor %d type %d", 640 i, mem->Type); 641 } 642 643 physmem += btoc(size); 644 645 } 646 647 if (mem_cluster_cnt == 0) 648 panic("no free memory descriptors found"); 649 650 /* Leave 1 page before kernel untouched as that's where our initial 651 * kernel stack is */ 652 /* XXX We could free it in cpu_startup() though XXX */ 653 mips_page_physload((vaddr_t)kernel_text - PAGE_SIZE, (vaddr_t)kernend, 654 mem_clusters, mem_cluster_cnt, NULL, 0); 655 656 /* We can now no longer use bootinfo. */ 657 bootinfo = NULL; 658 659 /* 660 * Initialize mips version-dependent DMA handlers. 661 */ 662 sgimips_bus_dma_init(); 663 664 /* 665 * Walk the component tree and count the number of CPUs 666 * present in the system. 667 */ 668 arcbios_tree_walk(sgimips_count_cpus, NULL); 669 670 /* 671 * Initialize error message buffer (at end of core). 672 */ 673 mips_init_msgbuf(); 674 675 pmap_bootstrap(); 676 677 /* 678 * Allocate uarea for lwp0 and set it. 679 */ 680 mips_init_lwp0_uarea(); 681} 682 683void 684sgimips_count_cpus(struct arcbios_component *node, 685 struct arcbios_treewalk_context *atc) 686{ 687 688 switch (node->Class) { 689 case COMPONENT_CLASS_ProcessorClass: 690 if (node->Type == COMPONENT_TYPE_CPU) 691 ncpus++; 692 break; 693 694 default: 695 break; 696 } 697} 698 699/* 700 * Allocate memory for variable-sized tables. 701 */ 702void 703cpu_startup(void) 704{ 705 vaddr_t minaddr, maxaddr; 706 char pbuf[9]; 707 708#ifdef BOOTINFO_DEBUG 709 if (bootinfo_msg) 710 printf(bootinfo_msg); 711#endif 712 713 printf("%s%s", copyright, version); 714 715 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 716 printf("total memory = %s\n", pbuf); 717 format_bytes(pbuf, sizeof(pbuf), ctob(arcsmem)); 718 printf("(%s reserved for ARCS)\n", pbuf); 719 720 minaddr = 0; 721 /* 722 * Allocate a submap for physio. 723 */ 724 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 725 VM_PHYS_SIZE, 0, false, NULL); 726 727 /* 728 * (No need to allocate an mbuf cluster submap. Mbuf clusters 729 * are allocated via the pool allocator, and we use KSEG to 730 * map those pages.) 731 */ 732 format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false))); 733 printf("avail memory = %s\n", pbuf); 734} 735 736int waittime = -1; 737 738void 739cpu_reboot(int howto, char *bootstr) 740{ 741 /* Take a snapshot before clobbering any registers. */ 742 savectx(curpcb); 743 744 if (cold) { 745 howto |= RB_HALT; 746 goto haltsys; 747 } 748 749 /* If "always halt" was specified as a boot flag, obey. */ 750 if (boothowto & RB_HALT) 751 howto |= RB_HALT; 752 753 boothowto = howto; 754 if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 755 waittime = 0; 756 vfs_shutdown(); 757 } 758 759 /* Clear and disable watchdog timer. */ 760 (void)(*platform.watchdog_disable)(); 761 762 splhigh(); 763 764 if (howto & RB_DUMP) 765 dumpsys(); 766 767haltsys: 768 769 doshutdownhooks(); 770 771 pmf_system_shutdown(boothowto); 772 773 /* 774 * Calling arcbios_PowerDown() results in a "CP1 unusable trap" 775 * which lands me back in DDB, at least on my Indy. So, enable 776 * the FPU before asking the PROM to power down to avoid this.. 777 * It seems to want the FPU to play the `poweroff tune' 8-/ 778 */ 779 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { 780 /* Set CP1 usable bit in SR */ 781 mips_cp0_status_write(mips_cp0_status_read() | 782 MIPS_SR_COP_1_BIT); 783 784 printf("powering off...\n\n"); 785 delay(500000); 786#if NMCCLOCK_MACE > 0 787 if (mach_type == MACH_SGI_IP32) { 788 mcclock_poweroff(); 789 } else 790#endif 791 arcbios_PowerDown(); 792 printf("WARNING: powerdown failed\n"); 793 /* 794 * RB_POWERDOWN implies RB_HALT... fall into it... 795 */ 796 } 797 798 if (howto & RB_HALT) { 799 printf("halting...\n\n"); 800 arcbios_EnterInteractiveMode(); 801 } 802 803 printf("rebooting...\n\n"); 804#if NCRIME > 0 805 if (mach_type == MACH_SGI_IP32) { 806 crime_reboot(); 807 } else 808#endif 809 arcbios_Reboot(); 810 811 for (;;); 812} 813 814void delay(unsigned long n) 815{ 816 register int __N = curcpu()->ci_divisor_delay * n; 817 818 do { 819 __asm("addiu %0,%1,-1" : "=r" (__N) : "0" (__N)); 820 } while (__N > 0); 821} 822 823/* 824 * IP12 appears to be buggy and unable to reliably support badaddr. 825 * Approximately 1.8% of the time a false negative (bad address said to 826 * be good) is generated and we stomp on invalid registers. Testing has 827 * not shown false positives, nor consecutive false negatives to occur. 828 */ 829static int 830badaddr_workaround(void *addr, size_t size) 831{ 832 int i, bad; 833 834 for (i = bad = 0; i < 100; i++) { 835 if (badaddr(addr, size)) 836 bad++; 837 } 838 839 /* false positives appear not to occur */ 840 return (bad != 0); 841} 842 843/* 844 * Ensure all platform vectors are always initialized. 845 */ 846static void 847unimpl_bus_reset(void) 848{ 849 850 panic("target init didn't set bus_reset"); 851} 852 853static void 854unimpl_cons_init(void) 855{ 856 857 panic("target init didn't set cons_init"); 858} 859 860static void * 861unimpl_intr_establish(int level, int ipl, int (*handler) (void *), void *arg) 862{ 863 panic("target init didn't set intr_establish"); 864 return NULL; 865} 866 867static void 868unimpl_intr(vaddr_t pc, uint32_t status, uint32_t pending) 869{ 870 printf("spurious interrupt pending %#x\n", pending); 871} 872 873static unsigned long 874nulllong(void) 875{ 876 printf("nulllong\n"); 877 return (0); 878} 879 880static void 881nullvoid(void) 882{ 883 printf("nullvoid\n"); 884 return; 885} 886 887void * 888lookup_bootinfo(int type) 889{ 890 struct btinfo_common *bt; 891 uint8_t *bip; 892 893 /* check for a bootinfo record first */ 894 if (bootinfo == NULL) 895 return NULL; 896 897 bip = bootinfo; 898 do { 899 bt = (struct btinfo_common *)bip; 900 if (bt->type == type) 901 return (void *)bt; 902 bip += bt->next; 903 } while (bt->next != 0 && 904 bt->next < BOOTINFO_SIZE /* sanity */ && 905 (size_t)bip < (size_t)bootinfo + BOOTINFO_SIZE); 906 907 return NULL; 908} 909 910#if defined(DDB) || defined(KGDB) 911 912void ddb_trap_hook(int where) 913{ 914 switch (where) { 915 case 1: /* Entry to DDB, turn watchdog off */ 916 (void)(*platform.watchdog_disable)(); 917 break; 918 919 case 0: /* Exit from DDB, turn watchdog back on */ 920 (void)(*platform.watchdog_enable)(); 921 break; 922 } 923} 924 925#endif 926 927void mips_machdep_cache_config(void) 928{ 929 930 arcbios_tree_walk(mips_machdep_find_l2cache, NULL); 931 932 switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) { 933#if defined(INDY_R4600_CACHE) 934 case MIPS_R4600: 935 /* 936 * R4600 is on Indy-class machines only. Disable and 937 * flush pcache. 938 */ 939 mips_cache_info.mci_sdcache_size = 0; 940 mips_cache_info.mci_sdcache_line_size = 0; 941 ip22_sdcache_disable(); 942 break; 943#endif 944#if defined(MIPS3) 945 case MIPS_R5000: 946 case MIPS_RM5200: 947 r5k_enable_sdcache(); 948 break; 949#endif 950 } 951} 952 953void 954mips_machdep_find_l2cache(struct arcbios_component *comp, struct arcbios_treewalk_context *atc) 955{ 956 struct mips_cache_info * const mci = &mips_cache_info; 957 device_t self = atc->atc_cookie; 958 959 if (comp->Class != COMPONENT_CLASS_CacheClass) 960 return; 961 962 switch (comp->Type) { 963 case COMPONENT_TYPE_SecondaryICache: 964 panic("%s: split L2 cache", device_xname(self)); 965 case COMPONENT_TYPE_SecondaryDCache: 966 case COMPONENT_TYPE_SecondaryCache: 967 mci->mci_sdcache_size = COMPONENT_KEY_Cache_CacheSize(comp->Key); 968 mci->mci_sdcache_line_size = 969 COMPONENT_KEY_Cache_LineSize(comp->Key); 970 /* XXX */ 971 mci->mci_sdcache_ways = 1; 972 break; 973 } 974} 975