1 /* $NetBSD: machdep.c,v 1.112 2010/11/15 06:25:42 uebayasi Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 Shin Takemura, All rights reserved. 5 * Copyright (c) 1999-2001 SATO Kazumi, All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32 /* 33 * Copyright (c) 1992, 1993 34 * The Regents of the University of California. All rights reserved. 35 * 36 * This code is derived from software contributed to Berkeley by 37 * the Systems Programming Group of the University of Utah Computer 38 * Science Department, The Mach Operating System project at 39 * Carnegie-Mellon University and Ralph Campbell. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * from: Utah Hdr: machdep.c 1.63 91/04/24 66 * 67 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 68 */ 69 /* 70 * Copyright (c) 1988 University of Utah. 71 * 72 * This code is derived from software contributed to Berkeley by 73 * the Systems Programming Group of the University of Utah Computer 74 * Science Department, The Mach Operating System project at 75 * Carnegie-Mellon University and Ralph Campbell. 76 * 77 * Redistribution and use in source and binary forms, with or without 78 * modification, are permitted provided that the following conditions 79 * are met: 80 * 1. Redistributions of source code must retain the above copyright 81 * notice, this list of conditions and the following disclaimer. 82 * 2. Redistributions in binary form must reproduce the above copyright 83 * notice, this list of conditions and the following disclaimer in the 84 * documentation and/or other materials provided with the distribution. 85 * 3. All advertising materials mentioning features or use of this software 86 * must display the following acknowledgement: 87 * This product includes software developed by the University of 88 * California, Berkeley and its contributors. 89 * 4. Neither the name of the University nor the names of its contributors 90 * may be used to endorse or promote products derived from this software 91 * without specific prior written permission. 92 * 93 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 94 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 95 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 96 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 97 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 98 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 99 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 101 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 102 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 103 * SUCH DAMAGE. 104 * 105 * from: Utah Hdr: machdep.c 1.63 91/04/24 106 * 107 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 108 */ 109 110 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 111 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.112 2010/11/15 06:25:42 uebayasi Exp $"); 112 113 #include "opt_vr41xx.h" 114 #include "opt_tx39xx.h" 115 #include "opt_boot_standalone.h" 116 #include "opt_modular.h" 117 #include "opt_spec_platform.h" 118 #include "biconsdev.h" 119 #include "opt_ddb.h" 120 #include "opt_kgdb.h" 121 #include "opt_rtc_offset.h" 122 #include "opt_kloader.h" 123 #include "opt_kloader_kernel_path.h" 124 #include "debug_hpc.h" 125 #include "opt_md.h" 126 #include "opt_memsize.h" 127 #include "opt_no_symbolsz_entry.h" 128 129 #include <sys/param.h> 130 #include <sys/systm.h> 131 #include <sys/kernel.h> 132 #include <sys/buf.h> 133 #include <sys/reboot.h> 134 #include <sys/mount.h> 135 #include <sys/boot_flag.h> 136 #include <sys/ksyms.h> 137 #include <sys/device.h> 138 #include <sys/lwp.h> 139 140 #include <uvm/uvm_extern.h> 141 142 #include <ufs/mfs/mfs_extern.h> /* mfs_initminiroot() */ 143 #include <dev/cons.h> /* cntab access (cpu_reboot) */ 144 145 #include <machine/psl.h> 146 #include <machine/sysconf.h> 147 #include <machine/platid.h> 148 #include <machine/platid_mask.h> 149 #include <machine/kloader.h> 150 #include <machine/debug.h> 151 152 #ifdef KGDB 153 #include <sys/kgdb.h> 154 #endif 155 156 #include "ksyms.h" 157 158 #if NKSYMS || defined(DDB) || defined(MODULAR) 159 #include <machine/db_machdep.h> 160 #include <ddb/db_sym.h> 161 #include <ddb/db_extern.h> 162 #ifndef DB_ELFSIZE 163 #error Must define DB_ELFSIZE! 164 #endif 165 #define ELFSIZE DB_ELFSIZE 166 #include <sys/exec_elf.h> 167 #endif 168 169 #if NBICONSDEV > 0 170 #include <sys/conf.h> 171 #include <dev/hpc/biconsvar.h> 172 #include <dev/hpc/bicons.h> 173 #define biconscnpollc nullcnpollc 174 cons_decl(bicons); 175 static struct consdev bicons __attribute((__unused__)) = cons_init(bicons); 176 static int __bicons_enable; 177 #define DPRINTF(arg) { if (__bicons_enable) printf arg; } 178 #else /* NBICONSDEV > 0 */ 179 #define DPRINTF(arg) 180 #endif /* NBICONSDEV > 0 */ 181 182 #include <nfs/rpcv2.h> 183 #include <nfs/nfsproto.h> 184 #include <nfs/nfs.h> 185 #include <nfs/nfsmount.h> 186 187 #ifdef MEMORY_DISK_DYNAMIC 188 #include <dev/md.h> 189 #endif 190 191 /* the following is used externally (sysctl_hw) */ 192 char hpcmips_cpuname[40]; /* set CPU depend xx_init() */ 193 194 struct cpu_info cpu_info_store; /* only one CPU */ 195 int cpuspeed = 1; /* approx # instr per usec. */ 196 197 /* CPU core switch table */ 198 struct platform platform; 199 #ifdef VR41XX 200 extern void vr_init(void); 201 #endif 202 #ifdef TX39XX 203 extern void tx_init(void); 204 #endif 205 206 /* boot environment */ 207 static struct bootinfo bi_copy; 208 struct bootinfo *bootinfo; 209 char booted_kernel[128]; 210 extern void makebootdev(const char *); 211 #ifdef KLOADER 212 #if !defined(KLOADER_KERNEL_PATH) 213 #define KLOADER_KERNEL_PATH "/netbsd" 214 #endif /* !KLOADER_KERNEL_PATH */ 215 static char kernel_path[] = KLOADER_KERNEL_PATH; 216 #endif /* KLOADER */ 217 218 /* maps for VM objects */ 219 struct vm_map *phys_map; 220 221 /* physical memory */ 222 int physmem; /* max supported memory, changes to actual */ 223 int mem_cluster_cnt; 224 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 225 226 /* 227 * safepri is a safe priority for sleep to set for a spin-wait 228 * during autoconfiguration or after a panic. 229 * Used as an argument to splx(). 230 * XXX disables interrupt 5 to disable mips3 on-chip clock, which also 231 * disables mips1 FPU interrupts. 232 */ 233 int safepri = MIPS3_PSL_LOWIPL; /* XXX */ 234 235 void mach_init(int, char *[], struct bootinfo *); 236 237 #ifdef DEBUG 238 /* stacktrace code violates prototypes to get callee's registers */ 239 extern void stacktrace(void); /*XXX*/ 240 #endif 241 242 /* 243 * Do all the stuff that locore normally does before calling main(). 244 * Process arguments passed to us by the boot loader. 245 * Return the first page address following the system. 246 */ 247 void 248 mach_init(int argc, char *argv[], struct bootinfo *bi) 249 { 250 /* 251 * this routines stack is never polluted since stack pointer 252 * is lower than kernel text segment, and at exiting, stack pointer 253 * is changed to proc0. 254 */ 255 #ifdef KLOADER 256 struct kloader_bootinfo kbi; 257 #endif 258 extern char edata[], end[]; 259 #if NKSYMS || defined(DDB) || defined(MODULAR) 260 extern void *esym; 261 #endif 262 void *kernend; 263 char *cp; 264 int i; 265 266 /* clear the BSS segment */ 267 #if NKSYMS || defined(DDB) || defined(MODULAR) 268 size_t symbolsz = 0; 269 Elf_Ehdr *eh = (void *)end; 270 if (memcmp(eh->e_ident, ELFMAG, SELFMAG) == 0 && 271 eh->e_ident[EI_CLASS] == ELFCLASS) { 272 esym = end; 273 #ifndef NO_SYMBOLSZ_ENTRY 274 if (eh->e_entry != 0) { 275 /* pbsdboot */ 276 symbolsz = eh->e_entry; 277 } else 278 #endif 279 { 280 /* hpcboot */ 281 Elf_Shdr *sh = (void *)(end + eh->e_shoff); 282 for(i = 0; i < eh->e_shnum; i++, sh++) 283 if (sh->sh_offset > 0 && 284 (sh->sh_offset + sh->sh_size) > symbolsz) 285 symbolsz = sh->sh_offset + sh->sh_size; 286 } 287 esym = (char*)esym + symbolsz; 288 kernend = (void *)mips_round_page(esym); 289 memset(edata, 0, end - edata); 290 } else 291 #endif /* NKSYMS || defined(DDB) || defined(MODULAR) */ 292 { 293 kernend = (void *)mips_round_page(end); 294 memset(edata, 0, (char *)kernend - edata); 295 } 296 297 #if defined(BOOT_STANDALONE) 298 #if !defined (SPEC_PLATFORM) || SPEC_PLATFORM == 1 299 #error specify SPEC_PLATFORM=platid_mask_MACH_xxx_yyy in BOOT_STANDALONE case. 300 #error see platid_mask.c for platid_mask_MACH_xxx_yyy. 301 #else 302 memcpy(&platid, &SPEC_PLATFORM, sizeof(platid)); 303 #endif 304 #endif /* defined(BOOT_STANDALONE) && defined(SPEC_PLATFORM) */ 305 /* 306 * Arguments are set up by boot loader. 307 */ 308 if (bi && bi->magic == BOOTINFO_MAGIC) { 309 memset(&bi_copy, 0, sizeof(struct bootinfo)); 310 memcpy(&bi_copy, bi, min(bi->length, sizeof(struct bootinfo))); 311 bootinfo = &bi_copy; 312 if (bootinfo->platid_cpu != 0) { 313 platid.dw.dw0 = bootinfo->platid_cpu; 314 } 315 if (bootinfo->platid_machine != 0) { 316 platid.dw.dw1 = bootinfo->platid_machine; 317 } 318 } 319 /* copy boot parameter for kloader */ 320 #ifdef KLOADER 321 kloader_bootinfo_set(&kbi, argc, argv, bi, false); 322 #endif 323 324 /* 325 * CPU core Specific Function Hooks 326 */ 327 #if defined(VR41XX) && defined(TX39XX) 328 if (platid_match(&platid, &platid_mask_CPU_MIPS_VR_41XX)) 329 vr_init(); 330 else if (platid_match(&platid, &platid_mask_CPU_MIPS_TX_3900) || 331 platid_match(&platid, &platid_mask_CPU_MIPS_TX_3920)) 332 tx_init(); 333 #elif defined(VR41XX) 334 vr_init(); 335 #elif defined(TX39XX) 336 tx_init(); 337 #else 338 #error "define TX39XX and/or VR41XX" 339 #endif 340 341 #if NBICONSDEV > 0 342 /* 343 * bicons don't need actual device initialize. only bootinfo needed. 344 */ 345 __bicons_enable = (bicons_init(&bicons) == 0); 346 if (__bicons_enable) 347 cn_tab = &bicons; 348 #endif 349 350 /* Initialize frame buffer (to steal DMA buffer, stay here.) */ 351 #ifdef HPC_DEBUG_LCD 352 dbg_lcd_test(); 353 #endif 354 (*platform.fb_init)(&kernend); 355 kernend = (void *)mips_round_page(kernend); 356 357 /* 358 * Set the VM page size. 359 */ 360 uvmexp.pagesize = NBPG; /* Notify the VM system of our page size. */ 361 uvm_setpagesize(); 362 363 /* 364 * Copy exception-dispatch code down to exception vector. 365 * Initialize locore-function vector. 366 * Clear out the I and D caches. 367 */ 368 mips_vector_init(); 369 intr_init(); 370 371 #ifdef DEBUG 372 /* 373 * Look at arguments passed to us and compute boothowto. 374 */ 375 if (bootinfo) { 376 DPRINTF(("Bootinfo. available, ")); 377 } 378 DPRINTF(("args: ")); 379 for (i = 0; i < argc; i++) { 380 DPRINTF(("%s ", argv[i])); 381 } 382 DPRINTF(("\n")); 383 DPRINTF(("platform ID: %08lx %08lx\n", platid.dw.dw0, platid.dw.dw1)); 384 #endif /* DEBUG */ 385 386 #ifndef RTC_OFFSET 387 /* 388 * rtc_offset from bootinfo.timezone set by pbsdboot.exe 389 */ 390 if (rtc_offset == 0 && bootinfo 391 && bootinfo->timezone > (-12*60) 392 && bootinfo->timezone <= (12*60)) 393 rtc_offset = bootinfo->timezone; 394 #endif /* RTC_OFFSET */ 395 396 /* Compute bootdev */ 397 makebootdev("wd0"); /* default boot device */ 398 399 boothowto = 0; 400 #ifdef KADB 401 boothowto |= RB_KDB; 402 #endif 403 strncpy(booted_kernel, argv[0], sizeof(booted_kernel)); 404 booted_kernel[sizeof(booted_kernel)-1] = 0; 405 for (i = 1; i < argc; i++) { 406 for (cp = argv[i]; *cp; cp++) { 407 switch (*cp) { 408 case 'h': /* XXX, serial console */ 409 bootinfo->bi_cnuse |= BI_CNUSE_SERIAL; 410 break; 411 412 case 'b': 413 /* boot device: -b=sd0 etc. */ 414 if (strcmp(cp+2, "nfs") == 0) 415 rootfstype = MOUNT_NFS; 416 else 417 makebootdev(cp+2); 418 cp += strlen(cp); 419 break; 420 default: 421 BOOT_FLAG(*cp, boothowto); 422 break; 423 } 424 } 425 } 426 /* 427 * Check to see if a mini-root was loaded into memory. It resides 428 * at the start of the next page just after the end of BSS. 429 */ 430 if (boothowto & RB_MINIROOT) { 431 size_t fssz; 432 fssz = round_page(mfs_initminiroot(kernend)); 433 #ifdef MEMORY_DISK_DYNAMIC 434 md_root_setconf(kernend, fssz); 435 #endif /* MEMORY_DISK_DYNAMIC */ 436 kernend = (char *)kernend + fssz; 437 } 438 439 #if NKSYMS || defined(DDB) || defined(MODULAR) 440 /* init symbols if present */ 441 if (esym) 442 ksyms_addsyms_elf(symbolsz, &end, esym); 443 #endif /* DDB */ 444 445 /* Initialize console and KGDB serial port. */ 446 (*platform.cons_init)(); 447 448 #if defined(DDB) || defined(KGDB) 449 if (boothowto & RB_KDB) { 450 #ifdef DDB 451 Debugger(); 452 #endif /* DDB */ 453 #ifdef KGDB 454 kgdb_debug_init = 1; 455 kgdb_connect(1); 456 #endif /* KGDB */ 457 } 458 #endif /* DDB || KGDB */ 459 460 /* Find physical memory regions. */ 461 #ifdef MEMSIZE 462 mem_clusters[0].start = 0; 463 mem_clusters[0].size = (paddr_t) kernend - MIPS_KSEG0_START; 464 mem_clusters[1].start = (paddr_t) kernend - MIPS_KSEG0_START; 465 mem_clusters[1].size = MEMSIZE * 0x100000 - mem_clusters[1].start; 466 mem_cluster_cnt = 2; 467 #else 468 (*platform.mem_init)((paddr_t)kernend - MIPS_KSEG0_START); 469 #endif 470 /* 471 * Clear currently unused D-RAM area 472 * (For reboot Windows CE clearly) 473 */ 474 { 475 u_int32_t sp; 476 __asm volatile("move %0, $29" : "=r"(sp)); 477 KDASSERT(sp > KERNBASE + 0x400); 478 memset((void *)(KERNBASE + 0x400), 0, sp - (KERNBASE + 0x400)); 479 } 480 481 printf("mem_cluster_cnt = %d\n", mem_cluster_cnt); 482 physmem = 0; 483 for (i = 0; i < mem_cluster_cnt; i++) { 484 printf("mem_clusters[%d] = {%#"PRIxPADDR",%#"PRIxPSIZE"}\n", i, 485 (paddr_t)mem_clusters[i].start, 486 (psize_t)mem_clusters[i].size); 487 physmem += atop(mem_clusters[i].size); 488 } 489 490 /* Cluster 0 is always the kernel, which doesn't get loaded. */ 491 for (i = 1; i < mem_cluster_cnt; i++) { 492 paddr_t start; 493 psize_t size; 494 495 start = (paddr_t)mem_clusters[i].start; 496 size = (psize_t)mem_clusters[i].size; 497 498 printf("loading %#"PRIxPADDR",%#"PRIxPSIZE"\n", start, size); 499 500 memset((void *)MIPS_PHYS_TO_KSEG1(start), 0, size); 501 502 uvm_page_physload(atop(start), atop(start + size), 503 atop(start), atop(start + size), 504 VM_FREELIST_DEFAULT); 505 } 506 507 /* 508 * Initialize error message buffer (at end of core). 509 */ 510 mips_init_msgbuf(); 511 512 /* 513 * Initialize the virtual memory system. 514 */ 515 pmap_bootstrap(); 516 517 /* 518 * Initialize lwp0's uarea. 519 */ 520 mips_init_lwp0_uarea(); 521 } 522 523 /* 524 * Machine-dependent startup code. 525 * allocate memory for variable-sized tables, initialize CPU. 526 */ 527 void 528 cpu_startup(void) 529 { 530 vaddr_t minaddr, maxaddr; 531 char pbuf[9]; 532 size_t i; 533 #ifdef DEBUG 534 extern int pmapdebug; 535 int opmapdebug = pmapdebug; 536 537 pmapdebug = 0; 538 #endif 539 540 /* 541 * Good {morning,afternoon,evening,night}. 542 */ 543 printf("%s%s", copyright, version); 544 sprintf(cpu_model, "%s (%s)", platid_name(&platid), hpcmips_cpuname); 545 printf("%s\n", cpu_model); 546 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 547 printf("total memory = %s\n", pbuf); 548 if (bootverbose) { 549 /* show again when verbose mode */ 550 printf("total memory banks = %d\n", mem_cluster_cnt); 551 for (i = 0; i < mem_cluster_cnt; i++) { 552 printf("memory bank %zu = " 553 "0x%08"PRIxPADDR" %"PRIdPSIZE"KB(0x%08"PRIxPSIZE")\n", i, 554 (paddr_t)mem_clusters[i].start, 555 (psize_t)mem_clusters[i].size/1024, 556 (psize_t)mem_clusters[i].size); 557 } 558 } 559 560 minaddr = 0; 561 562 /* 563 * Allocate a submap for physio 564 */ 565 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 566 VM_PHYS_SIZE, 0, false, NULL); 567 568 /* 569 * No need to allocate an mbuf cluster submap. Mbuf clusters 570 * are allocated via the pool allocator, and we use KSEG to 571 * map those pages. 572 */ 573 574 #ifdef DEBUG 575 pmapdebug = opmapdebug; 576 #endif 577 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 578 printf("avail memory = %s\n", pbuf); 579 } 580 581 void 582 cpu_reboot(int howto, char *bootstr) 583 { 584 585 /* take a snap shot before clobbering any registers */ 586 if (curlwp) 587 savectx(curpcb); 588 589 #ifdef DEBUG 590 if (panicstr) 591 stacktrace(); 592 #endif 593 594 /* If system is cold, just halt. */ 595 if (cold) { 596 howto |= RB_HALT; 597 goto haltsys; 598 } 599 600 /* If "always halt" was specified as a boot flag, obey. */ 601 if ((boothowto & RB_HALT) != 0) { 602 howto |= RB_HALT; 603 } 604 605 #ifdef KLOADER 606 if ((howto & RB_HALT) == 0) { 607 if (howto & RB_STRING) 608 kloader_reboot_setup(bootstr); 609 else 610 kloader_reboot_setup(kernel_path); 611 } 612 #endif 613 614 boothowto = howto; 615 if ((howto & RB_NOSYNC) == 0) { 616 /* 617 * Synchronize the disks.... 618 */ 619 vfs_shutdown(); 620 621 /* 622 * If we've been adjusting the clock, the todr 623 * will be out of synch; adjust it now. 624 */ 625 resettodr(); 626 } 627 628 /* Disable interrupts. */ 629 splhigh(); 630 631 /* If rebooting and a dump is requested do it. */ 632 if (howto & RB_DUMP) 633 dumpsys(); 634 635 haltsys: 636 637 /* run any shutdown hooks */ 638 doshutdownhooks(); 639 640 pmf_system_shutdown(boothowto); 641 642 /* Finally, halt/reboot the system. */ 643 if (howto & RB_HALT) { 644 printf("halted.\n"); 645 } else { 646 #ifdef KLOADER 647 kloader_reboot(); 648 /* NOTREACHED */ 649 #endif 650 } 651 652 (*platform.reboot)(howto, bootstr); 653 while(1) 654 ; 655 /*NOTREACHED*/ 656 } 657 658 void 659 consinit(void) 660 { 661 /* platform.cons_init() do it */ 662 } 663