machdep.c revision 1.36
1/* $NetBSD: machdep.c,v 1.36 2007/10/17 19:52:54 garbled Exp $ */ 2 3/*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39/* 40 * Copyright (c) 1992, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * This code is derived from software contributed to Berkeley by 44 * the Systems Programming Group of the University of Utah Computer 45 * Science Department, The Mach Operating System project at 46 * Carnegie-Mellon University and Ralph Campbell. 47 * 48 * Redistribution and use in source and binary forms, with or without 49 * modification, are permitted provided that the following conditions 50 * are met: 51 * 1. Redistributions of source code must retain the above copyright 52 * notice, this list of conditions and the following disclaimer. 53 * 2. Redistributions in binary form must reproduce the above copyright 54 * notice, this list of conditions and the following disclaimer in the 55 * documentation and/or other materials provided with the distribution. 56 * 3. Neither the name of the University nor the names of its contributors 57 * may be used to endorse or promote products derived from this software 58 * without specific prior written permission. 59 * 60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 * SUCH DAMAGE. 71 * 72 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 73 * from: Utah Hdr: machdep.c 1.63 91/04/24 74 */ 75/* 76 * Copyright (c) 1988 University of Utah. 77 * 78 * This code is derived from software contributed to Berkeley by 79 * the Systems Programming Group of the University of Utah Computer 80 * Science Department, The Mach Operating System project at 81 * Carnegie-Mellon University and Ralph Campbell. 82 * 83 * Redistribution and use in source and binary forms, with or without 84 * modification, are permitted provided that the following conditions 85 * are met: 86 * 1. Redistributions of source code must retain the above copyright 87 * notice, this list of conditions and the following disclaimer. 88 * 2. Redistributions in binary form must reproduce the above copyright 89 * notice, this list of conditions and the following disclaimer in the 90 * documentation and/or other materials provided with the distribution. 91 * 3. All advertising materials mentioning features or use of this software 92 * must display the following acknowledgement: 93 * This product includes software developed by the University of 94 * California, Berkeley and its contributors. 95 * 4. Neither the name of the University nor the names of its contributors 96 * may be used to endorse or promote products derived from this software 97 * without specific prior written permission. 98 * 99 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 100 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 101 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 102 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 103 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 104 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 105 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 106 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 107 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 108 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 109 * SUCH DAMAGE. 110 * 111 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 112 * from: Utah Hdr: machdep.c 1.63 91/04/24 113 */ 114 115#include <sys/cdefs.h> 116__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.36 2007/10/17 19:52:54 garbled Exp $"); 117 118#include "opt_algor_p4032.h" 119#include "opt_algor_p5064.h" 120#include "opt_algor_p6032.h" 121 122#include "opt_ddb.h" 123#include "opt_kgdb.h" 124 125#include "opt_memsize.h" 126#include "opt_ethaddr.h" 127 128#include <sys/param.h> 129#include <sys/systm.h> 130#include <sys/kernel.h> 131#include <sys/buf.h> 132#include <sys/reboot.h> 133#include <sys/user.h> 134#include <sys/mount.h> 135#include <sys/kcore.h> 136#include <sys/boot_flag.h> 137#include <sys/termios.h> 138#include <sys/ksyms.h> 139 140#include <net/if.h> 141#include <net/if_ether.h> 142 143#include <uvm/uvm_extern.h> 144 145#include <dev/cons.h> 146 147#ifdef DDB 148#include <machine/db_machdep.h> 149#include <ddb/db_extern.h> 150#endif 151 152#include <machine/bus.h> 153#include <machine/autoconf.h> 154#include <machine/pmon.h> 155 156#include <algor/pci/vtpbcvar.h> 157 158#include "ksyms.h" 159 160#include "com.h" 161#if NCOM > 0 162#include <dev/ic/comreg.h> 163#include <dev/ic/comvar.h> 164 165int comcnrate = TTYDEF_SPEED; 166#endif /* NCOM > 0 */ 167 168#if defined(ALGOR_P4032) + \ 169 defined(ALGOR_P5064) + \ 170 defined(ALGOR_P6032) + \ 171 0 != 1 172#error Must configure exactly one platform. 173#endif 174 175#ifdef ALGOR_P4032 176#include <algor/algor/algor_p4032reg.h> 177#include <algor/algor/algor_p4032var.h> 178struct p4032_config p4032_configuration; 179#endif 180 181#ifdef ALGOR_P5064 182#include <algor/algor/algor_p5064reg.h> 183#include <algor/algor/algor_p5064var.h> 184struct p5064_config p5064_configuration; 185#endif 186 187#ifdef ALGOR_P6032 188#include <algor/algor/algor_p6032reg.h> 189#include <algor/algor/algor_p6032var.h> 190struct p6032_config p6032_configuration; 191#endif 192 193struct user *proc0paddr; 194 195/* Our exported CPU info; we can have only one. */ 196struct cpu_info cpu_info_store; 197 198/* Maps for VM objects. */ 199struct vm_map *exec_map = NULL; 200struct vm_map *mb_map = NULL; 201struct vm_map *phys_map = NULL; 202 203int physmem; /* # pages of physical memory */ 204int maxmem; /* max memory per process */ 205 206int mem_cluster_cnt; 207phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 208 209char algor_ethaddr[ETHER_ADDR_LEN]; 210 211void mach_init(int, char *[], char *[]); /* XXX */ 212 213int cpuspeed = 150; /* XXX XXX XXX */ 214 215void 216mach_init(int argc, char *argv[], char *envp[]) 217{ 218 extern char kernel_text[], edata[], end[]; 219 vaddr_t kernstart, kernend; 220 paddr_t kernstartpfn, kernendpfn, pfn0, pfn1; 221 vsize_t size; 222 const char *cp; 223 char *cp0; 224 void *v; 225 int i; 226 227 /* Disable interrupts. */ 228 (void) splhigh(); 229 230 /* 231 * First, find the start and end of the kernel and clear 232 * the BSS segment. Account for a bit of space for the 233 * bootstrap stack. 234 */ 235 led_display('b', 's', 's', ' '); 236 kernstart = (vaddr_t) mips_trunc_page(kernel_text) - 2 * NBPG; 237 kernend = (vaddr_t) mips_round_page(end); 238 memset(edata, 0, kernend - (vaddr_t)edata); 239 240 /* 241 * Initialize PAGE_SIZE-dependent variables. 242 */ 243 led_display('p', 'g', 's', 'z'); 244 uvm_setpagesize(); 245 246 kernstartpfn = atop(MIPS_KSEG0_TO_PHYS(kernstart)); 247 kernendpfn = atop(MIPS_KSEG0_TO_PHYS(kernend)); 248 249 /* 250 * Initialize bus space tags and bring up the console. 251 */ 252#if defined(ALGOR_P4032) 253 { 254 struct p4032_config *acp = &p4032_configuration; 255 struct vtpbc_config *vt = &vtpbc_configuration; 256 bus_space_handle_t sh; 257 258 strcpy(cpu_model, "Algorithmics P-4032"); 259 260 vt->vt_addr = MIPS_PHYS_TO_KSEG1(P4032_V962PBC); 261 vt->vt_cfgbase = MIPS_PHYS_TO_KSEG1(P4032_PCICFG); 262 vt->vt_adbase = 11; 263 264 led_display('v', '9', '6', '2'); 265 vtpbc_init(&acp->ac_pc, vt); 266 267 led_display('l', 'i', 'o', ' '); 268 algor_p4032loc_bus_io_init(&acp->ac_lociot, acp); 269 270 led_display('i', 'o', ' ', ' '); 271 algor_p4032_bus_io_init(&acp->ac_iot, acp); 272 273 led_display('m', 'e', 'm', ' '); 274 algor_p4032_bus_mem_init(&acp->ac_memt, acp); 275 276 led_display('d', 'm', 'a', ' '); 277 algor_p4032_dma_init(acp); 278#if NCOM > 0 279 /* 280 * Delay to allow firmware putchars to complete. 281 * FIFO depth * character time. 282 * character time = (1000000 / (defaultrate / 10)) 283 */ 284 led_display('c', 'o', 'n', 's'); 285 DELAY(160000000 / comcnrate); 286 if (comcnattach(&acp->ac_lociot, P4032_COM1, comcnrate, 287 COM_FREQ, COM_TYPE_NORMAL, 288 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 289 panic("p4032: unable to initialize serial console"); 290#else 291 panic("p4032: not configured to use serial console"); 292#endif /* NCOM > 0 */ 293 294 led_display('h', 'z', ' ', ' '); 295 bus_space_map(&acp->ac_lociot, P4032_RTC, 2, 0, &sh); 296 algor_p4032_cal_timer(&acp->ac_lociot, sh); 297 bus_space_unmap(&acp->ac_lociot, sh, 2); 298 } 299#elif defined(ALGOR_P5064) 300 { 301 struct p5064_config *acp = &p5064_configuration; 302 struct vtpbc_config *vt = &vtpbc_configuration; 303 bus_space_handle_t sh; 304 305 strcpy(cpu_model, "Algorithmics P-5064"); 306 307 vt->vt_addr = MIPS_PHYS_TO_KSEG1(P5064_V360EPC); 308 vt->vt_cfgbase = MIPS_PHYS_TO_KSEG1(P5064_PCICFG); 309 vt->vt_adbase = 24; 310 311 led_display('v', '3', '6', '0'); 312 vtpbc_init(&acp->ac_pc, vt); 313 314 led_display('i', 'o', ' ', ' '); 315 algor_p5064_bus_io_init(&acp->ac_iot, acp); 316 317 led_display('m', 'e', 'm', ' '); 318 algor_p5064_bus_mem_init(&acp->ac_memt, acp); 319 320 led_display('d', 'm', 'a', ' '); 321 algor_p5064_dma_init(acp); 322#if NCOM > 0 323 /* 324 * Delay to allow firmware putchars to complete. 325 * FIFO depth * character time. 326 * character time = (1000000 / (defaultrate / 10)) 327 */ 328 led_display('c', 'o', 'n', 's'); 329 DELAY(160000000 / comcnrate); 330 if (comcnattach(&acp->ac_iot, 0x3f8, comcnrate, 331 COM_FREQ, COM_TYPE_NORMAL, 332 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 333 panic("p5064: unable to initialize serial console"); 334#else 335 panic("p5064: not configured to use serial console"); 336#endif /* NCOM > 0 */ 337 338 led_display('h', 'z', ' ', ' '); 339 bus_space_map(&acp->ac_iot, 0x70, 2, 0, &sh); 340 algor_p5064_cal_timer(&acp->ac_iot, sh); 341 bus_space_unmap(&acp->ac_iot, sh, 2); 342 } 343#elif defined(ALGOR_P6032) 344 { 345 struct p6032_config *acp = &p6032_configuration; 346 struct bonito_config *bc = &acp->ac_bonito; 347 bus_space_handle_t sh; 348 349 strcpy(cpu_model, "Algorithmics P-6032"); 350 351 bc->bc_adbase = 11; 352 353 led_display('b','n','t','o'); 354 bonito_pci_init(&acp->ac_pc, bc); 355 356 led_display('i','o',' ',' '); 357 algor_p6032_bus_io_init(&acp->ac_iot, acp); 358 359 led_display('m','e','m',' '); 360 algor_p6032_bus_mem_init(&acp->ac_memt, acp); 361 362 led_display('d','m','a',' '); 363 algor_p6032_dma_init(acp); 364#if NCOM > 0 365 /* 366 * Delay to allow firmware putchars to complete. 367 * FIFO depth * character time. 368 * character time = (1000000 / (defaultrate / 10)) 369 */ 370 led_display('c','o','n','s'); 371 DELAY(160000000 / comcnrate); 372 if (comcnattach(&acp->ac_iot, 0x3f8, comcnrate, 373 COM_FREQ, COM_TYPE_NORMAL, 374 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 375 panic("p6032: unable to initialize serial console"); 376#else 377 panic("p6032: not configured to use serial console"); 378#endif /* NCOM > 0 */ 379 380 led_display('h','z',' ',' '); 381 bus_space_map(&acp->ac_iot, 0x70, 2, 0, &sh); 382 algor_p6032_cal_timer(&acp->ac_iot, sh); 383 bus_space_unmap(&acp->ac_iot, sh, 2); 384 } 385#endif /* ALGOR_P4032 || ALGOR_P5064 || ALGOR_P6032 */ 386 387 /* 388 * The Algorithmics boards have PMON firmware; set up our 389 * PMON state. 390 */ 391 led_display('p', 'm', 'o', 'n'); 392 pmon_init(envp); 393 394 /* 395 * Get the Ethernet address of the on-board Ethernet. 396 */ 397#if defined(ETHADDR) 398 cp = ETHADDR; 399#else 400 cp = pmon_getenv("ethaddr"); 401#endif 402 if (cp != NULL) { 403 for (i = 0; i < ETHER_ADDR_LEN; i++) { 404 algor_ethaddr[i] = strtoul(cp, &cp0, 16); 405 cp = cp0 + 1; 406 } 407 } 408 409 /* 410 * Get the boot options. 411 */ 412 led_display('b', 'o', 'p', 't'); 413 boothowto = 0; 414 if (argc > 1) { 415 for (cp = argv[1]; cp != NULL && *cp != '\0'; cp++) { 416 switch (*cp) { 417#if defined(KGDB) || defined(DDB) 418 case 'd': /* break into kernel debugger */ 419 boothowto |= RB_KDB; 420 break; 421#endif 422 423 case 'h': /* always halt, never reboot */ 424 boothowto |= RB_HALT; 425 break; 426 427 case 'n': /* askname */ 428 boothowto |= RB_ASKNAME; 429 break; 430 431 case 's': /* single-user mode */ 432 boothowto |= RB_SINGLE; 433 break; 434 435 case 'q': /* quiet boot */ 436 boothowto |= AB_QUIET; 437 break; 438 439 case 'v': /* verbose boot */ 440 boothowto |= AB_VERBOSE; 441 break; 442 443 case '-': 444 /* 445 * Just ignore this. It's not required, 446 * but it's common for it to be passed 447 * regardless. 448 */ 449 break; 450 451 default: 452 printf("Unrecognized boto flag '%c'.\n", *cp); 453 break; 454 } 455 } 456 } 457 458 /* 459 * Determine the memory size. Use the `memsize' PMON 460 * variable. If that's not available, panic. 461 * 462 * Note: Reserve the first page! That's where the trap 463 * vectors are located. 464 */ 465#if defined(MEMSIZE) 466 size = MEMSIZE; 467#else 468 if ((cp = pmon_getenv("memsize")) != NULL) 469 size = strtoul(cp, NULL, 0); 470 else { 471 printf("FATAL: `memsize' PMON variable not set. Set it to\n"); 472 printf(" the amount of memory (in MB) and try again.\n"); 473 printf(" Or, build a kernel with the `MEMSIZE' " 474 "option.\n"); 475 panic("algor_init"); 476 } 477#endif /* MEMSIZE */ 478 /* 479 * Deal with 2 different conventions of the contents 480 * of the memsize variable -- if it's > 1024, assume 481 * it's already in bytes, not megabytes. 482 */ 483 if (size < 1024) { 484 printf("Memory size: 0x%08lx (0x%08lx)\n", size * 1024 * 1024, 485 size); 486 size *= 1024 * 1024; 487 } else 488 printf("Memory size: 0x%08lx\n", size); 489 490 mem_clusters[mem_cluster_cnt].start = PAGE_SIZE; 491 mem_clusters[mem_cluster_cnt].size = 492 size - mem_clusters[mem_cluster_cnt].start; 493 mem_cluster_cnt++; 494 495 /* 496 * Copy the exception-dispatch code down to the exception vector. 497 * Initialize the locore function vector. Clear out the I- and 498 * D-caches. 499 * 500 * We can no longer call into PMON after this. 501 */ 502 led_display('v', 'e', 'c', 'i'); 503 mips_vector_init(); 504 505 /* 506 * Load the physical memory clusters into the VM system. 507 */ 508 led_display('v', 'm', 'p', 'g'); 509 for (i = 0; i < mem_cluster_cnt; i++) { 510 physmem += atop(mem_clusters[i].size); 511 pfn0 = atop(mem_clusters[i].start); 512 pfn1 = pfn0 + atop(mem_clusters[i].size); 513 if (pfn0 <= kernstartpfn && kernendpfn <= pfn1) { 514 /* 515 * Must compute the location of the kernel 516 * within the segment. 517 */ 518#if 1 519 printf("Cluster %d contains kernel\n", i); 520#endif 521 if (pfn0 < kernstartpfn) { 522 /* 523 * There is a chunk before the kernel. 524 */ 525#if 1 526 printf("Loading chunk before kernel: " 527 "0x%lx / 0x%lx\n", pfn0, kernstartpfn); 528#endif 529 uvm_page_physload(pfn0, kernstartpfn, 530 pfn0, kernstartpfn, VM_FREELIST_DEFAULT); 531 } 532 if (kernendpfn < pfn1) { 533 /* 534 * There is a chunk after the kernel. 535 */ 536#if 1 537 printf("Loading chunk after kernel: " 538 "0x%lx / 0x%lx\n", kernendpfn, pfn1); 539#endif 540 uvm_page_physload(kernendpfn, pfn1, 541 kernendpfn, pfn1, VM_FREELIST_DEFAULT); 542 } 543 } else { 544 /* 545 * Just load this cluster as one chunk. 546 */ 547#if 1 548 printf("Loading cluster %d: 0x%lx / 0x%lx\n", i, 549 pfn0, pfn1); 550#endif 551 uvm_page_physload(pfn0, pfn1, pfn0, pfn1, 552 VM_FREELIST_DEFAULT); 553 } 554 } 555 556 if (physmem == 0) 557 panic("can't happen: system seems to have no memory!"); 558 maxmem = physmem; 559 560 /* 561 * Initialize message buffer (at end of core). 562 */ 563 mips_init_msgbuf(); 564 565 /* 566 * Initialize the virtual memory system. 567 */ 568 led_display('p', 'm', 'a', 'p'); 569 pmap_bootstrap(); 570 571 /* 572 * Init mapping for u page(s) for lwp0. 573 */ 574 led_display('u', 's', 'p', 'c'); 575 v = (void *) uvm_pageboot_alloc(USPACE); 576 lwp0.l_addr = proc0paddr = (struct user *) v; 577 lwp0.l_md.md_regs = (struct frame *)((char*)v + USPACE) - 1; 578 proc0paddr->u_pcb.pcb_context[11] = 579 MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */ 580 581 /* 582 * Initialize debuggers, and break into them, if appropriate. 583 */ 584#if NKSYMS || defined(DDB) || defined(LKM) 585 /* 586 * XXX Loader doesn't give us symbols the way we like. Need 587 * XXX dbsym(1) support for ELF. 588 */ 589 ksyms_init(0, 0, 0); 590#endif 591 592 if (boothowto & RB_KDB) { 593#if defined(DDB) 594 Debugger(); 595#endif 596 } 597} 598 599void 600consinit(void) 601{ 602 603 /* 604 * Everything related to console initialization is done 605 * in mach_init(). 606 */ 607 led_display('N', 'B', 'S', 'D'); 608} 609 610void 611cpu_startup(void) 612{ 613 vaddr_t minaddr, maxaddr; 614 char pbuf[9]; 615#ifdef DEBUG 616 extern int pmapdebug; 617 int opmapdebug = pmapdebug; 618 619 pmapdebug = 0; /* Shut up pmap debug during bootstrap */ 620#endif 621 622 /* 623 * Good {morning,afternoon,evening,night}. 624 */ 625 printf("%s%s", copyright, version); 626 printf("%s\n", cpu_model); 627 format_bytes(pbuf, sizeof(pbuf), ptoa(physmem)); 628 printf("total memory = %s\n", pbuf); 629 630 /* 631 * Virtual memory is bootstrapped -- notify the bus spaces 632 * that memory allocation is now safe. 633 */ 634#if defined(ALGOR_P4032) 635 { 636 struct p4032_config *acp = &p4032_configuration; 637 638 acp->ac_mallocsafe = 1; 639 } 640#elif defined(ALGOR_P5064) 641 { 642 struct p5064_config *acp = &p5064_configuration; 643 644 acp->ac_mallocsafe = 1; 645 } 646#elif defined(ALGOR_P6032) 647 { 648 struct p6032_config *acp = &p6032_configuration; 649 650 acp->ac_mallocsafe = 1; 651 } 652#endif 653 654 minaddr = 0; 655 656 /* 657 * Allocate a submap for exec arguments. This map effectively 658 * limits the number of processes exec'ing at any time. 659 */ 660 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 661 16 * NCARGS, VM_MAP_PAGEABLE, false, NULL); 662 663 /* 664 * Allocate a submap for physio. 665 */ 666 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 667 VM_PHYS_SIZE, 0, false, NULL); 668 669 /* 670 * No need to allocate an mbuf cluster submap. Mbuf clusters 671 * are allocate via the pool allocator, and we use KSEG0 to 672 * map those pages. 673 */ 674 675#ifdef DEBUG 676 pmapdebug = opmapdebug; 677#endif 678 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 679 printf("avail memory = %s\n", pbuf); 680} 681 682int waittime = -1; 683struct user dumppcb; /* Actually, struct pcb would do. */ 684 685void 686cpu_reboot(int howto, char *bootstr) 687{ 688 int tmp; 689 690 /* Take a snapshot before clobbering any registers. */ 691 if (curlwp) 692 savectx((struct user *) curpcb); 693 694 /* If "always halt" was specified as a boot flag, obey. */ 695 if (boothowto & RB_HALT) 696 howto |= RB_HALT; 697 698 boothowto = howto; 699 700 /* If system is cold, just halt. */ 701 if (cold) { 702 boothowto |= RB_HALT; 703 goto haltsys; 704 } 705 706 if ((boothowto & RB_NOSYNC) == 0 && waittime < 0) { 707 waittime = 0; 708 vfs_shutdown(); 709 /* 710 * If we've been adjusting the clock, the todr 711 * will be out of synch; adjust it now. 712 */ 713 resettodr(); 714 } 715 716 /* Disable interrupts. */ 717 (void) splhigh(); 718 719 if (boothowto & RB_DUMP) 720 dumpsys(); 721 722 haltsys: 723 /* Run any shutdown hooks. */ 724 doshutdownhooks(); 725 726 if (boothowto & RB_HALT) { 727 printf("\n"); 728 printf("The operating system has halted.\n"); 729 printf("Please press any key to return to the monitor.\n\n"); 730 led_display('h','a','l','t'); 731 cnpollc(1); 732 (void) cngetc(); 733 cnpollc(0); 734 } 735 736 printf("Returning to the monitor...\n\n"); 737 led_display('r', 'v', 'e', 'c'); 738 /* Jump to the reset vector. */ 739 __asm volatile("li %0, 0xbfc00000; jr %0; nop" 740 : "=r" (tmp) 741 : /* no inputs */ 742 : "memory"); 743 led_display('R', 'S', 'T', 'F'); 744 for (;;) 745 /* spin forever */ ; 746} 747