1 /* $NetBSD: machdep.c,v 1.37 2002/05/03 01:49:22 rafal Exp $ */ 2 3 /* 4 * Copyright (c) 2000 Soren S. Jorvang 5 * Copyright (c) 2001, 2002 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 "opt_ddb.h" 37 #include "opt_kgdb.h" 38 #include "opt_execfmt.h" 39 #include "opt_cputype.h" 40 #include "opt_machtypes.h" 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/kernel.h> 45 #include <sys/map.h> 46 #include <sys/proc.h> 47 #include <sys/buf.h> 48 #include <sys/reboot.h> 49 #include <sys/conf.h> 50 #include <sys/file.h> 51 #include <sys/malloc.h> 52 #include <sys/mbuf.h> 53 #include <sys/msgbuf.h> 54 #include <sys/device.h> 55 #include <sys/user.h> 56 #include <sys/exec.h> 57 #include <sys/mount.h> 58 #include <sys/syscallargs.h> 59 #include <sys/kcore.h> 60 61 #include <uvm/uvm_extern.h> 62 #include <sys/sysctl.h> 63 64 #include <machine/cpu.h> 65 #include <machine/reg.h> 66 #include <machine/psl.h> 67 #include <machine/pte.h> 68 #include <machine/autoconf.h> 69 #include <machine/machtype.h> 70 #include <machine/sysconf.h> 71 #include <machine/intr.h> 72 #include <machine/bootinfo.h> 73 #include <mips/locore.h> 74 75 #include <dev/arcbios/arcbios.h> 76 #include <dev/arcbios/arcbiosvar.h> 77 78 #if defined(DDB) || defined(KGDB) 79 #include <machine/db_machdep.h> 80 #include <ddb/db_access.h> 81 #include <ddb/db_sym.h> 82 #include <ddb/db_extern.h> 83 #ifndef DB_ELFSIZE 84 #error Must define DB_ELFSIZE! 85 #endif 86 #define ELFSIZE DB_ELFSIZE 87 #include <sys/exec_elf.h> 88 #endif 89 90 #include <dev/cons.h> 91 92 /* For sysctl(3). */ 93 char machine[] = MACHINE; 94 char machine_arch[] = MACHINE_ARCH; 95 char cpu_model[64 + 1]; /* sizeof(arcbios_system_identifier) */ 96 97 struct sgimips_intrhand intrtab[NINTR]; 98 99 /* Our exported CPU info; we can have only one. */ 100 struct cpu_info cpu_info_store; 101 102 /* Maps for VM objects. */ 103 struct vm_map *exec_map = NULL; 104 struct vm_map *mb_map = NULL; 105 struct vm_map *phys_map = NULL; 106 107 int mach_type; /* IPxx type */ 108 int mach_subtype; /* subtype: eg., Guiness/Fullhouse for IP22 */ 109 int mach_boardrev; /* machine board revision, in case it matters */ 110 111 int physmem; /* Total physical memory */ 112 int arcsmem; /* Memory used by the ARCS firmware */ 113 114 int ncpus; 115 116 /* CPU interrupt masks */ 117 u_int32_t biomask; 118 u_int32_t netmask; 119 u_int32_t ttymask; 120 u_int32_t clockmask; 121 122 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 123 int mem_cluster_cnt; 124 125 #ifdef IP20 126 void ip20_init(void); 127 #endif 128 129 #ifdef IP22 130 void ip22_init(void); 131 #endif 132 133 #ifdef IP32 134 void ip32_init(void); 135 #endif 136 137 void * cpu_intr_establish(int, int, int (*)(void *), void *); 138 139 void mach_init(int, char **, int, struct btinfo_common *); 140 void unconfigured_system_type(int); 141 142 void sgimips_count_cpus(struct arcbios_component *, 143 struct arcbios_treewalk_context *); 144 145 #ifdef KGDB 146 void zs_kgdb_init(void); 147 void kgdb_connect(int); 148 #endif 149 150 /* Motherboard or system-specific initialization vector */ 151 static void unimpl_bus_reset(void); 152 static void unimpl_cons_init(void); 153 static void unimpl_iointr(unsigned, unsigned, unsigned, unsigned); 154 static void unimpl_intr_establish(int, int, int (*)(void *), void *); 155 static unsigned long nullwork(void); 156 157 void ddb_trap_hook(int where); 158 159 struct platform platform = { 160 unimpl_bus_reset, 161 unimpl_cons_init, 162 unimpl_iointr, 163 unimpl_intr_establish, 164 (void *)nullwork, 165 }; 166 167 /* 168 * safepri is a safe priority for sleep to set for a spin-wait during 169 * autoconfiguration or after a panic. Used as an argument to splx(). 170 */ 171 int safepri = MIPS1_PSL_LOWIPL; 172 173 extern caddr_t esym; 174 extern u_int32_t ssir; 175 extern struct user *proc0paddr; 176 177 static struct btinfo_common *bootinfo; 178 179 /* 180 * Do all the stuff that locore normally does before calling main(). 181 * Process arguments passed to us by the ARCS firmware. 182 */ 183 void 184 mach_init(argc, argv, magic, btinfo) 185 int argc; 186 char **argv; 187 int magic; 188 struct btinfo_common *btinfo; 189 { 190 extern char kernel_text[], _end[]; 191 paddr_t first, last; 192 int firstpfn, lastpfn; 193 caddr_t v; 194 vsize_t size; 195 struct arcbios_mem *mem; 196 char *cpufreq; 197 struct btinfo_symtab *bi_syms; 198 caddr_t ssym; 199 vaddr_t kernend; 200 int kernstartpfn, kernendpfn; 201 int i, nsym; 202 203 #if 0 204 /* Clear the BSS segment. XXX Is this really necessary? */ 205 memset(_edata, 0, _end - _edata); 206 #endif 207 208 /* 209 * Initialize ARCS. This will set up the bootstrap console. 210 */ 211 arcbios_init(MIPS_PHYS_TO_KSEG0(0x00001000)); 212 strcpy(cpu_model, arcbios_system_identifier); 213 214 uvm_setpagesize(); 215 216 if (magic == BOOTINFO_MAGIC && btinfo != NULL) { 217 #ifdef DEBUG 218 printf("Found bootinfo at %p\n", btinfo); 219 #endif 220 bootinfo = btinfo; 221 } 222 223 bi_syms = lookup_bootinfo(BTINFO_SYMTAB); 224 if (bi_syms != NULL) { 225 nsym = bi_syms->nsym; 226 ssym = (caddr_t) bi_syms->ssym; 227 esym = (caddr_t) bi_syms->esym; 228 kernend = round_page((vaddr_t) esym); 229 } else { 230 nsym = 0; 231 ssym = esym = NULL; 232 kernend = round_page((vaddr_t) _end); 233 } 234 235 kernstartpfn = atop(MIPS_KSEG0_TO_PHYS((vaddr_t) kernel_text)); 236 kernendpfn = atop(MIPS_KSEG0_TO_PHYS(kernend)); 237 238 /* 239 * Now set up the real console. 240 * XXX Should be done later after we determine systype. 241 */ 242 consinit(); 243 244 #if 1 /* skidt? */ 245 ARCBIOS->FlushAllCaches(); 246 #endif 247 248 cpufreq = ARCBIOS->GetEnvironmentVariable("cpufreq"); 249 250 if (cpufreq == 0) 251 panic("no $cpufreq"); 252 253 /* 254 * Note initial estimate of CPU speed... If we care enough, we'll 255 * use the RTC to get a better estimate later. 256 */ 257 curcpu()->ci_cpu_freq = strtoul(cpufreq, NULL, 10) * 1000000; 258 259 /* 260 * argv[0] can be either the bootloader loaded by the PROM, or a 261 * kernel loaded directly by the PROM. 262 * 263 * If argv[0] is the bootloader, then argv[1] might be the kernel 264 * that was loaded. How to tell which one to use? 265 * 266 * If argv[1] isn't an environment string, try to use it to set the 267 * boot device. 268 */ 269 if (strchr(argv[1], '=') != 0) 270 makebootdev(argv[1]); 271 272 boothowto = RB_SINGLE; 273 274 /* 275 * Single- or multi-user ('auto' in SGI terms). 276 */ 277 for (i = 0; i < argc; i++) { 278 if (strcmp(argv[i], "OSLoadOptions=auto") == 0) 279 boothowto &= ~RB_SINGLE; 280 281 /* 282 * The case where the kernel has been loaded by a 283 * boot loader will usually have been catched by 284 * the first makebootdev() case earlier on, but 285 * we still use OSLoadPartition to get the preferred 286 * root filesystem location, even if it's not 287 * actually the location of the loaded kernel. 288 */ 289 if (strncmp(argv[i], "OSLoadPartition=", 15) == 0) 290 makebootdev(argv[i] + 16); 291 } 292 293 /* 294 * When the kernel is loaded directly by the firmware, and 295 * no explicit OSLoadPartition is set, we fall back on 296 * SystemPartition for the boot device. 297 */ 298 for (i = 0; i < argc; i++) { 299 if (strncmp(argv[i], "SystemPartition", 15) == 0) 300 makebootdev(argv[i] + 16); 301 302 #ifdef DEBUG 303 printf("argv[%d]: %s\n", i, argv[i]); 304 #endif 305 } 306 307 #if defined(KGDB) || defined(DDB) 308 /* Set up DDB hook to turn off watchdog on entry */ 309 db_trap_callback = ddb_trap_hook; 310 311 #ifdef DDB 312 ddb_init(nsym, ssym, esym); 313 if (boothowto & RB_KDB) 314 Debugger(); 315 #endif 316 #ifdef KGDB 317 zs_kgdb_init(); /* XXX */ 318 if (boothowto & RB_KDB) 319 kgdb_connect(0); 320 #endif 321 #endif 322 323 for (i = 0; arcbios_system_identifier[i] != '\0'; i++) { 324 if (arcbios_system_identifier[i] >= '0' && 325 arcbios_system_identifier[i] <= '9') { 326 mach_type = strtoul(&arcbios_system_identifier[i], 327 NULL, 10); 328 break; 329 } 330 } 331 332 if (mach_type <= 0) 333 panic("invalid architecture"); 334 335 switch (mach_type) { 336 case MACH_SGI_IP20: 337 #ifdef IP20 338 ip20_init(); 339 #else 340 unconfigured_system_type(mach_type); 341 #endif 342 break; 343 344 case MACH_SGI_IP22: 345 #ifdef IP22 346 ip22_init(); 347 #else 348 unconfigured_system_type(mach_type); 349 #endif 350 break; 351 352 case MACH_SGI_IP32: 353 #ifdef IP32 354 ip32_init(); 355 #else 356 unconfigured_system_type(mach_type); 357 #endif 358 break; 359 360 default: 361 panic("IP%d architecture not yet supported\n", mach_type); 362 break; 363 } 364 365 physmem = arcsmem = 0; 366 mem_cluster_cnt = 0; 367 mem = NULL; 368 369 #ifdef DEBUG 370 i = 0; 371 mem = NULL; 372 373 do { 374 if ((mem = ARCBIOS->GetMemoryDescriptor(mem)) != NULL) { 375 i++; 376 printf("Mem block %d: type %d, base 0x%x, size 0x%x\n", 377 i, mem->Type, mem->BasePage, mem->PageCount); 378 } 379 } while (mem != NULL); 380 #endif 381 382 /* 383 * XXX This code assumes that ARCS provides the memory 384 * XXX sorted in ascending order. 385 */ 386 mem = NULL; 387 for (i = 0; mem_cluster_cnt < VM_PHYSSEG_MAX; i++) { 388 mem = ARCBIOS->GetMemoryDescriptor(mem); 389 390 if (mem == NULL) 391 break; 392 393 first = round_page(mem->BasePage * ARCBIOS_PAGESIZE); 394 last = trunc_page(first + mem->PageCount * ARCBIOS_PAGESIZE); 395 size = last - first; 396 397 firstpfn = atop(first); 398 lastpfn = atop(last); 399 400 switch (mem->Type) { 401 case ARCBIOS_MEM_FreeContiguous: 402 case ARCBIOS_MEM_FreeMemory: 403 case ARCBIOS_MEM_LoadedProgram: 404 if (firstpfn <= kernstartpfn && 405 kernendpfn <= lastpfn) { 406 /* 407 * Must compute the location of the kernel 408 * within the segment. 409 */ 410 #ifdef DEBUG 411 printf("Cluster %d contains kernel\n", i); 412 #endif 413 if (firstpfn < kernstartpfn) { 414 /* 415 * There is a chunk before the kernel. 416 */ 417 #ifdef DEBUG 418 printf("Loading chunk before kernel: " 419 "0x%x / 0x%x\n", firstpfn, 420 kernstartpfn); 421 #endif 422 uvm_page_physload(firstpfn, 423 kernstartpfn, 424 firstpfn, kernstartpfn, 425 VM_FREELIST_DEFAULT); 426 } 427 if (kernendpfn < lastpfn) { 428 /* 429 * There is a chunk after the kernel. 430 */ 431 #ifdef DEBUG 432 printf("Loading chunk after kernel: " 433 "0x%x / 0x%x\n", kernendpfn, 434 lastpfn); 435 #endif 436 uvm_page_physload(kernendpfn, 437 lastpfn, kernendpfn, 438 lastpfn, VM_FREELIST_DEFAULT); 439 } 440 } else { 441 /* 442 * Just load this cluster as one chunk. 443 */ 444 #ifdef DEBUG 445 printf("Loading cluster %d: 0x%x / 0x%x\n", i, 446 firstpfn, lastpfn); 447 #endif 448 uvm_page_physload(firstpfn, lastpfn, 449 firstpfn, lastpfn, VM_FREELIST_DEFAULT); 450 } 451 mem_clusters[mem_cluster_cnt].start = first; 452 mem_clusters[mem_cluster_cnt].size = size; 453 mem_cluster_cnt++; 454 break; 455 456 case ARCBIOS_MEM_FirmwareTemporary: 457 case ARCBIOS_MEM_FirmwarePermanent: 458 arcsmem += btoc(size); 459 break; 460 461 case ARCBIOS_MEM_ExecptionBlock: 462 case ARCBIOS_MEM_SystemParameterBlock: 463 case ARCBIOS_MEM_BadMemory: 464 break; 465 466 default: 467 panic("unknown memory descriptor %d type %d", 468 i, mem->Type); 469 } 470 471 physmem += btoc(size); 472 473 } 474 475 if (mem_cluster_cnt == 0) 476 panic("no free memory descriptors found"); 477 478 /* We can now no longer use bootinfo. */ 479 bootinfo = NULL; 480 481 /* 482 * Walk the component tree and count the number of CPUs 483 * present in the system. 484 */ 485 arcbios_tree_walk(sgimips_count_cpus, NULL); 486 487 /* 488 * Copy exception-dispatch code down to exception vector. 489 * Initialize locore-function vector. 490 * Clear out the I and D caches. 491 */ 492 mips_vector_init(); 493 494 /* 495 * Initialize error message buffer (at end of core). 496 */ 497 mips_init_msgbuf(); 498 499 /* 500 * Compute the size of system data structures. pmap_bootstrap() 501 * needs some of this information. 502 */ 503 size = (vsize_t)allocsys(NULL, NULL); 504 505 pmap_bootstrap(); 506 507 /* 508 * Allocate space for proc0's USPACE. 509 */ 510 v = (caddr_t)uvm_pageboot_alloc(USPACE); 511 proc0.p_addr = proc0paddr = (struct user *)v; 512 proc0.p_md.md_regs = (struct frame *)(v + USPACE) - 1; 513 curpcb = &proc0.p_addr->u_pcb; 514 curpcb->pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */ 515 516 /* 517 * Allocate space for system data structures. These data structures 518 * are allocated here instead of cpu_startup() because physical 519 * memory is directly addressable. We don't have to map these into 520 * virtual address space. 521 */ 522 v = (caddr_t)uvm_pageboot_alloc(size); 523 if ((allocsys(v, NULL) - v) != size) 524 panic("mach_init: table size inconsistency"); 525 } 526 527 void 528 sgimips_count_cpus(struct arcbios_component *node, 529 struct arcbios_treewalk_context *atc) 530 { 531 532 switch (node->Class) { 533 case COMPONENT_CLASS_ProcessorClass: 534 if (node->Type == COMPONENT_TYPE_CPU) 535 ncpus++; 536 break; 537 538 default: 539 break; 540 } 541 } 542 543 /* 544 * Allocate memory for variable-sized tables. 545 */ 546 void 547 cpu_startup() 548 { 549 unsigned i; 550 int base, residual; 551 vaddr_t minaddr, maxaddr; 552 vsize_t size; 553 char pbuf[9]; 554 555 printf(version); 556 557 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 558 printf("%s memory", pbuf); 559 560 /* 561 * Allocate virtual address space for file I/O buffers. 562 * Note they are different than the array of headers, 'buf', 563 * and usually occupy more virtual memory than physical. 564 */ 565 size = MAXBSIZE * nbuf; 566 if (uvm_map(kernel_map, (vaddr_t *)&buffers, round_page(size), 567 NULL, UVM_UNKNOWN_OFFSET, 0, 568 UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, 569 UVM_ADV_NORMAL, 0)) != 0) 570 panic("startup: cannot allocate VM for buffers"); 571 minaddr = (vaddr_t)buffers; 572 base = bufpages / nbuf; 573 residual = bufpages % nbuf; 574 for (i = 0; i < nbuf; i++) { 575 vsize_t curbufsize; 576 vaddr_t curbuf; 577 struct vm_page *pg; 578 579 /* 580 * Each buffer has MAXBSIZE bytes of VM space allocated. Of 581 * that MAXBSIZE space, we allocate and map (base+1) pages 582 * for the first "residual" buffers, and then we allocate 583 * "base" pages for the rest. 584 */ 585 curbuf = (vaddr_t) buffers + (i * MAXBSIZE); 586 curbufsize = NBPG * ((i < residual) ? (base + 1) : base); 587 588 while (curbufsize) { 589 pg = uvm_pagealloc(NULL, 0, NULL, 0); 590 if (pg == NULL) 591 panic("cpu_startup: not enough memory for " 592 "buffer cache"); 593 pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg), 594 VM_PROT_READ|VM_PROT_WRITE); 595 curbuf += PAGE_SIZE; 596 curbufsize -= PAGE_SIZE; 597 } 598 } 599 pmap_update(pmap_kernel()); 600 601 /* 602 * Allocate a submap for exec arguments. This map effectively 603 * limits the number of processes exec'ing at any time. 604 */ 605 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 606 16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL); 607 /* 608 * Allocate a submap for physio. 609 */ 610 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 611 VM_PHYS_SIZE, 0, FALSE, NULL); 612 613 /* 614 * (No need to allocate an mbuf cluster submap. Mbuf clusters 615 * are allocated via the pool allocator, and we use KSEG to 616 * map those pages.) 617 */ 618 619 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 620 printf(", %s free", pbuf); 621 format_bytes(pbuf, sizeof(pbuf), ctob(arcsmem)); 622 printf(", %s for ARCS", pbuf); 623 format_bytes(pbuf, sizeof(pbuf), bufpages * NBPG); 624 printf(", %s in %d buffers\n", pbuf, nbuf); 625 626 /* 627 * Set up buffers, so they can be used to read disk labels. 628 */ 629 bufinit(); 630 } 631 632 int 633 cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 634 int *name; 635 u_int namelen; 636 void *oldp; 637 size_t *oldlenp; 638 void *newp; 639 size_t newlen; 640 struct proc *p; 641 { 642 /* All sysctl names at this level are terminal. */ 643 if (namelen != 1) 644 return ENOTDIR; 645 646 switch (name[0]) { 647 default: 648 return EOPNOTSUPP; 649 } 650 } 651 652 int waittime = -1; 653 654 void 655 cpu_reboot(howto, bootstr) 656 int howto; 657 char *bootstr; 658 { 659 /* Take a snapshot before clobbering any registers. */ 660 if (curproc) 661 savectx((struct user *)curpcb); 662 663 #if 1 664 /* Clear and disable watchdog timer. */ 665 switch (mach_type) { 666 case MACH_SGI_IP22: 667 *(volatile u_int32_t *)0xbfa00014 = 0; 668 *(volatile u_int32_t *)0xbfa00004 &= ~0x100; 669 break; 670 671 case MACH_SGI_IP32: 672 *(volatile u_int32_t *)0xb4000034 = 0; 673 *(volatile u_int32_t *)0xb400000c &= ~0x200; 674 break; 675 } 676 #endif 677 678 if (cold) { 679 howto |= RB_HALT; 680 goto haltsys; 681 } 682 683 /* If "always halt" was specified as a boot flag, obey. */ 684 if (boothowto & RB_HALT) 685 howto |= RB_HALT; 686 687 boothowto = howto; 688 if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 689 waittime = 0; 690 vfs_shutdown(); 691 692 /* 693 * If we've been adjusting the clock, the todr 694 * will be out of synch; adjust it now. 695 */ 696 resettodr(); 697 } 698 699 splhigh(); 700 701 if (howto & RB_DUMP) 702 dumpsys(); 703 704 haltsys: 705 706 doshutdownhooks(); 707 708 /* 709 * Calling ARCBIOS->PowerDown() results in a "CP1 unusable trap" 710 * which lands me back in DDB, at least on my Indy. So, enable 711 * the FPU before asking the PROM to power down to avoid this.. 712 * It seems to want the FPU to play the `poweroff tune' 8-/ 713 */ 714 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { 715 /* Set CP1 usable bit in SR */ 716 mips_cp0_status_write(mips_cp0_status_read() | 717 MIPS_SR_COP_1_BIT); 718 719 printf("powering off...\n\n"); 720 delay(500000); 721 ARCBIOS->PowerDown(); 722 printf("WARNING: powerdown failed\n"); 723 /* 724 * RB_POWERDOWN implies RB_HALT... fall into it... 725 */ 726 } 727 728 if (howto & RB_HALT) { 729 printf("halting...\n\n"); 730 ARCBIOS->EnterInteractiveMode(); 731 } 732 733 printf("rebooting...\n\n"); 734 ARCBIOS->Reboot(); 735 736 for (;;); 737 } 738 739 void 740 microtime(tvp) 741 struct timeval *tvp; 742 { 743 int s = splclock(); 744 static struct timeval lasttime; 745 746 *tvp = time; 747 tvp->tv_usec += (*platform.clkread)(); 748 749 /* 750 * Make sure that the time returned is always greater 751 * than that returned by the previous call. 752 */ 753 if (tvp->tv_sec == lasttime.tv_sec && 754 tvp->tv_usec <= lasttime.tv_usec && 755 (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) { 756 tvp->tv_sec++; 757 tvp->tv_usec -= 1000000; 758 } 759 lasttime = *tvp; 760 splx(s); 761 } 762 763 __inline void 764 delay(n) 765 unsigned long n; 766 { 767 u_long i; 768 long divisor = curcpu()->ci_divisor_delay; 769 770 while (n-- > 0) 771 for (i = divisor; i > 0; i--) 772 ; 773 } 774 775 /* 776 * Ensure all platform vectors are always initialized. 777 */ 778 static void 779 unimpl_bus_reset() 780 { 781 782 panic("target init didn't set bus_reset"); 783 } 784 785 static void 786 unimpl_cons_init() 787 { 788 789 panic("target init didn't set cons_init"); 790 } 791 792 static void 793 unimpl_iointr(mask, pc, statusreg, causereg) 794 u_int mask; 795 u_int pc; 796 u_int statusreg; 797 u_int causereg; 798 { 799 800 panic("target init didn't set intr"); 801 } 802 803 static void 804 unimpl_intr_establish(level, ipl, handler, arg) 805 int level; 806 int ipl; 807 int (*handler) __P((void *)); 808 void *arg; 809 { 810 panic("target init didn't set intr_establish"); 811 } 812 813 static unsigned long 814 nullwork() 815 { 816 817 return (0); 818 } 819 820 void * 821 cpu_intr_establish(level, ipl, func, arg) 822 int level; 823 int ipl; 824 int (*func)(void *); 825 void *arg; 826 { 827 (*platform.intr_establish)(level, ipl, func, arg); 828 return (void *) -1; 829 } 830 831 void 832 cpu_intr(status, cause, pc, ipending) 833 u_int32_t status; 834 u_int32_t cause; 835 u_int32_t pc; 836 u_int32_t ipending; 837 { 838 uvmexp.intrs++; 839 840 if (ipending & MIPS_HARD_INT_MASK) 841 (*platform.iointr)(status, cause, pc, ipending); 842 843 /* 844 * Service pending soft interrupts -- make sure to re-enable 845 * only those hardware interrupts that are not masked and 846 * that weren't pending on the current invocation of the 847 * interrupt handler, else we risk infinite stack growth 848 * due to nested interrupts. 849 */ 850 /* software simulated interrupt */ 851 if ((ipending & MIPS_SOFT_INT_MASK_1) || 852 (ssir && (status & MIPS_SOFT_INT_MASK_1))) { 853 _splset(MIPS_SR_INT_IE | 854 (status & ~ipending & MIPS_HARD_INT_MASK)); 855 _clrsoftintr(MIPS_SOFT_INT_MASK_1); 856 softintr_dispatch(); 857 } 858 } 859 860 void unconfigured_system_type(int ipnum) 861 { 862 printf("Kernel not configured for IP%d support. Add options `IP%d'\n", 863 ipnum, ipnum); 864 printf("to kernel configuration file to enable IP%d support!\n", 865 ipnum); 866 printf("\n"); 867 868 panic("Kernel not configured for current hardware!"); 869 } 870 871 void * 872 lookup_bootinfo(int type) 873 { 874 struct btinfo_common *b = bootinfo; 875 876 while (bootinfo != NULL) { 877 if (b->type == type) 878 return (b); 879 b = b->next; 880 } 881 882 return (NULL); 883 } 884 885 #if defined(DDB) || defined(KGDB) 886 887 void ddb_trap_hook(int where) 888 { 889 switch (where) { 890 case 1: /* Entry to DDB, turn watchdog off */ 891 switch (mach_type) { 892 case MACH_SGI_IP32: 893 *(volatile u_int32_t *)0xb4000034 = 0; 894 *(volatile u_int32_t *)0xb400000c &= ~0x200; 895 break; 896 897 case MACH_SGI_IP22: 898 *(volatile u_int32_t *)0xbfa00014 = 0; 899 *(volatile u_int32_t *)0xbfa00004 &= ~0x100; 900 break; 901 } 902 break; 903 904 case 0: /* Exit from DDB, turn watchdog back on */ 905 switch (mach_type) { 906 case MACH_SGI_IP32: 907 *(volatile u_int32_t *)0xb400000c |= 0x200; 908 *(volatile u_int32_t *)0xb4000034 = 0; 909 break; 910 911 case MACH_SGI_IP22: 912 *(volatile u_int32_t *)0xbfa00004 |= 0x100; 913 *(volatile u_int32_t *)0xbfa00014 = 0; 914 915 break; 916 } 917 break; 918 } 919 } 920 921 #endif 922