machdep.c revision 1.24
1/* $NetBSD: machdep.c,v 1.24 2003/08/07 16:26:31 agc 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.24 2003/08/07 16:26:31 agc 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 193/* The following are used externally (sysctl_hw). */ 194extern char cpu_model[]; 195 196struct user *proc0paddr; 197 198/* Our exported CPU info; we can have only one. */ 199struct cpu_info cpu_info_store; 200 201/* Maps for VM objects. */ 202struct vm_map *exec_map = NULL; 203struct vm_map *mb_map = NULL; 204struct vm_map *phys_map = NULL; 205 206int physmem; /* # pages of physical memory */ 207int maxmem; /* max memory per process */ 208 209int mem_cluster_cnt; 210phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 211 212char algor_ethaddr[ETHER_ADDR_LEN]; 213 214void mach_init(int, char *[], char *[]); /* XXX */ 215 216int cpuspeed = 150; /* XXX XXX XXX */ 217 218void 219mach_init(int argc, char *argv[], char *envp[]) 220{ 221 extern char kernel_text[], edata[], end[]; 222 vaddr_t kernstart, kernend; 223 paddr_t kernstartpfn, kernendpfn, pfn0, pfn1; 224 vsize_t size; 225 const char *cp; 226 char *cp0; 227 caddr_t v; 228 int i; 229 230 /* Disable interrupts. */ 231 (void) splhigh(); 232 233 /* 234 * First, find the start and end of the kernel and clear 235 * the BSS segment. Account for a bit of space for the 236 * bootstrap stack. 237 */ 238 led_display('b', 's', 's', ' '); 239 kernstart = (vaddr_t) mips_trunc_page(kernel_text) - 2 * NBPG; 240 kernend = (vaddr_t) mips_round_page(end); 241 memset(edata, 0, kernend - (vaddr_t)edata); 242 243 /* 244 * Initialize PAGE_SIZE-dependent variables. 245 */ 246 led_display('p', 'g', 's', 'z'); 247 uvm_setpagesize(); 248 249 kernstartpfn = atop(MIPS_KSEG0_TO_PHYS(kernstart)); 250 kernendpfn = atop(MIPS_KSEG0_TO_PHYS(kernend)); 251 252 /* 253 * Initialize bus space tags and bring up the console. 254 */ 255#if defined(ALGOR_P4032) 256 { 257 struct p4032_config *acp = &p4032_configuration; 258 struct vtpbc_config *vt = &vtpbc_configuration; 259 bus_space_handle_t sh; 260 261 strcpy(cpu_model, "Algorithmics P-4032"); 262 263 vt->vt_addr = MIPS_PHYS_TO_KSEG1(P4032_V962PBC); 264 vt->vt_cfgbase = MIPS_PHYS_TO_KSEG1(P4032_PCICFG); 265 vt->vt_adbase = 11; 266 267 led_display('v', '9', '6', '2'); 268 vtpbc_init(&acp->ac_pc, vt); 269 270 led_display('l', 'i', 'o', ' '); 271 algor_p4032loc_bus_io_init(&acp->ac_lociot, acp); 272 273 led_display('i', 'o', ' ', ' '); 274 algor_p4032_bus_io_init(&acp->ac_iot, acp); 275 276 led_display('m', 'e', 'm', ' '); 277 algor_p4032_bus_mem_init(&acp->ac_memt, acp); 278 279 led_display('d', 'm', 'a', ' '); 280 algor_p4032_dma_init(acp); 281#if NCOM > 0 282 /* 283 * Delay to allow firmware putchars to complete. 284 * FIFO depth * character time. 285 * character time = (1000000 / (defaultrate / 10)) 286 */ 287 led_display('c', 'o', 'n', 's'); 288 DELAY(160000000 / comcnrate); 289 if (comcnattach(&acp->ac_lociot, P4032_COM1, comcnrate, 290 COM_FREQ, COM_TYPE_NORMAL, 291 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 292 panic("p4032: unable to initialize serial console"); 293#else 294 panic("p4032: not configured to use serial console"); 295#endif /* NCOM > 0 */ 296 297 led_display('h', 'z', ' ', ' '); 298 bus_space_map(&acp->ac_lociot, P4032_RTC, 2, 0, &sh); 299 algor_p4032_cal_timer(&acp->ac_lociot, sh); 300 bus_space_unmap(&acp->ac_lociot, sh, 2); 301 } 302#elif defined(ALGOR_P5064) 303 { 304 struct p5064_config *acp = &p5064_configuration; 305 struct vtpbc_config *vt = &vtpbc_configuration; 306 bus_space_handle_t sh; 307 308 strcpy(cpu_model, "Algorithmics P-5064"); 309 310 vt->vt_addr = MIPS_PHYS_TO_KSEG1(P5064_V360EPC); 311 vt->vt_cfgbase = MIPS_PHYS_TO_KSEG1(P5064_PCICFG); 312 vt->vt_adbase = 24; 313 314 led_display('v', '3', '6', '0'); 315 vtpbc_init(&acp->ac_pc, vt); 316 317 led_display('i', 'o', ' ', ' '); 318 algor_p5064_bus_io_init(&acp->ac_iot, acp); 319 320 led_display('m', 'e', 'm', ' '); 321 algor_p5064_bus_mem_init(&acp->ac_memt, acp); 322 323 led_display('d', 'm', 'a', ' '); 324 algor_p5064_dma_init(acp); 325#if NCOM > 0 326 /* 327 * Delay to allow firmware putchars to complete. 328 * FIFO depth * character time. 329 * character time = (1000000 / (defaultrate / 10)) 330 */ 331 led_display('c', 'o', 'n', 's'); 332 DELAY(160000000 / comcnrate); 333 if (comcnattach(&acp->ac_iot, 0x3f8, comcnrate, 334 COM_FREQ, COM_TYPE_NORMAL, 335 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 336 panic("p5064: unable to initialize serial console"); 337#else 338 panic("p5064: not configured to use serial console"); 339#endif /* NCOM > 0 */ 340 341 led_display('h', 'z', ' ', ' '); 342 bus_space_map(&acp->ac_iot, 0x70, 2, 0, &sh); 343 algor_p5064_cal_timer(&acp->ac_iot, sh); 344 bus_space_unmap(&acp->ac_iot, sh, 2); 345 } 346#elif defined(ALGOR_P6032) 347 { 348 struct p6032_config *acp = &p6032_configuration; 349 struct bonito_config *bc = &acp->ac_bonito; 350 bus_space_handle_t sh; 351 352 strcpy(cpu_model, "Algorithmics P-6032"); 353 354 bc->bc_adbase = 11; 355 356 led_display('b','n','t','o'); 357 bonito_pci_init(&acp->ac_pc, bc); 358 359 led_display('i','o',' ',' '); 360 algor_p6032_bus_io_init(&acp->ac_iot, acp); 361 362 led_display('m','e','m',' '); 363 algor_p6032_bus_mem_init(&acp->ac_memt, acp); 364 365 led_display('d','m','a',' '); 366 algor_p6032_dma_init(acp); 367#if NCOM > 0 368 /* 369 * Delay to allow firmware putchars to complete. 370 * FIFO depth * character time. 371 * character time = (1000000 / (defaultrate / 10)) 372 */ 373 led_display('c','o','n','s'); 374 DELAY(160000000 / comcnrate); 375 if (comcnattach(&acp->ac_iot, 0x3f8, comcnrate, 376 COM_FREQ, COM_TYPE_NORMAL, 377 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 378 panic("p6032: unable to initialize serial console"); 379#else 380 panic("p6032: not configured to use serial console"); 381#endif /* NCOM > 0 */ 382 383 led_display('h','z',' ',' '); 384 bus_space_map(&acp->ac_iot, 0x70, 2, 0, &sh); 385 algor_p6032_cal_timer(&acp->ac_iot, sh); 386 bus_space_unmap(&acp->ac_iot, sh, 2); 387 } 388#endif /* ALGOR_P4032 || ALGOR_P5064 || ALGOR_P6032 */ 389 390 /* 391 * The Algorithmics boards have PMON firmware; set up our 392 * PMON state. 393 */ 394 led_display('p', 'm', 'o', 'n'); 395 pmon_init(envp); 396 397 /* 398 * Get the Ethernet address of the on-board Ethernet. 399 */ 400#if defined(ETHADDR) 401 cp = ETHADDR; 402#else 403 cp = pmon_getenv("ethaddr"); 404#endif 405 if (cp != NULL) { 406 for (i = 0; i < ETHER_ADDR_LEN; i++) { 407 algor_ethaddr[i] = strtoul(cp, &cp0, 16); 408 cp = cp0 + 1; 409 } 410 } 411 412 /* 413 * Get the boot options. 414 */ 415 led_display('b', 'o', 'p', 't'); 416 boothowto = 0; 417 if (argc > 1) { 418 for (cp = argv[1]; cp != NULL && *cp != '\0'; cp++) { 419 switch (*cp) { 420#if defined(KGDB) || defined(DDB) 421 case 'd': /* break into kernel debugger */ 422 boothowto |= RB_KDB; 423 break; 424#endif 425 426 case 'h': /* always halt, never reboot */ 427 boothowto |= RB_HALT; 428 break; 429 430 case 'n': /* askname */ 431 boothowto |= RB_ASKNAME; 432 break; 433 434 case 's': /* single-user mode */ 435 boothowto |= RB_SINGLE; 436 break; 437 438 case 'q': /* quiet boot */ 439 boothowto |= AB_QUIET; 440 break; 441 442 case 'v': /* verbose boot */ 443 boothowto |= AB_VERBOSE; 444 break; 445 446 case '-': 447 /* 448 * Just ignore this. It's not required, 449 * but it's common for it to be passed 450 * regardless. 451 */ 452 break; 453 454 default: 455 printf("Unrecognized boto flag '%c'.\n", *cp); 456 break; 457 } 458 } 459 } 460 461 /* 462 * Determine the memory size. Use the `memsize' PMON 463 * variable. If that's not available, panic. 464 * 465 * Note: Reserve the first page! That's where the trap 466 * vectors are located. 467 */ 468#if defined(MEMSIZE) 469 size = MEMSIZE; 470#else 471 if ((cp = pmon_getenv("memsize")) != NULL) 472 size = strtoul(cp, NULL, 0); 473 else { 474 printf("FATAL: `memsize' PMON variable not set. Set it to\n"); 475 printf(" the amount of memory (in MB) and try again.\n"); 476 printf(" Or, build a kernel with the `MEMSIZE' " 477 "option.\n"); 478 panic("algor_init"); 479 } 480#endif /* MEMSIZE */ 481 /* 482 * Deal with 2 different conventions of the contents 483 * of the memsize variable -- if it's > 1024, assume 484 * it's already in bytes, not megabytes. 485 */ 486 if (size < 1024) { 487 printf("Memory size: 0x%08lx (0x%08lx)\n", size * 1024 * 1024, 488 size); 489 size *= 1024 * 1024; 490 } else 491 printf("Memory size: 0x%08lx\n", size); 492 493 mem_clusters[mem_cluster_cnt].start = PAGE_SIZE; 494 mem_clusters[mem_cluster_cnt].size = 495 size - mem_clusters[mem_cluster_cnt].start; 496 mem_cluster_cnt++; 497 498 /* 499 * Copy the exception-dispatch code down to the exception vector. 500 * Initialize the locore function vector. Clear out the I- and 501 * D-caches. 502 * 503 * We can no longer call into PMON after this. 504 */ 505 led_display('v', 'e', 'c', 'i'); 506 mips_vector_init(); 507 508 /* 509 * Load the physical memory clusters into the VM system. 510 */ 511 led_display('v', 'm', 'p', 'g'); 512 for (i = 0; i < mem_cluster_cnt; i++) { 513 physmem += atop(mem_clusters[i].size); 514 pfn0 = atop(mem_clusters[i].start); 515 pfn1 = pfn0 + atop(mem_clusters[i].size); 516 if (pfn0 <= kernstartpfn && kernendpfn <= pfn1) { 517 /* 518 * Must compute the location of the kernel 519 * within the segment. 520 */ 521#if 1 522 printf("Cluster %d contains kernel\n", i); 523#endif 524 if (pfn0 < kernstartpfn) { 525 /* 526 * There is a chunk before the kernel. 527 */ 528#if 1 529 printf("Loading chunk before kernel: " 530 "0x%lx / 0x%lx\n", pfn0, kernstartpfn); 531#endif 532 uvm_page_physload(pfn0, kernstartpfn, 533 pfn0, kernstartpfn, VM_FREELIST_DEFAULT); 534 } 535 if (kernendpfn < pfn1) { 536 /* 537 * There is a chunk after the kernel. 538 */ 539#if 1 540 printf("Loading chunk after kernel: " 541 "0x%lx / 0x%lx\n", kernendpfn, pfn1); 542#endif 543 uvm_page_physload(kernendpfn, pfn1, 544 kernendpfn, pfn1, VM_FREELIST_DEFAULT); 545 } 546 } else { 547 /* 548 * Just load this cluster as one chunk. 549 */ 550#if 1 551 printf("Loading cluster %d: 0x%lx / 0x%lx\n", i, 552 pfn0, pfn1); 553#endif 554 uvm_page_physload(pfn0, pfn1, pfn0, pfn1, 555 VM_FREELIST_DEFAULT); 556 } 557 } 558 559 if (physmem == 0) 560 panic("can't happen: system seems to have no memory!"); 561 maxmem = physmem; 562 563 /* 564 * Initialize message buffer (at end of core). 565 */ 566 mips_init_msgbuf(); 567 568 /* 569 * Compute the size of system data structures. pmap_bootstrap() 570 * needs some of this information. 571 */ 572 size = (vsize_t) allocsys(NULL, NULL); 573 574 /* 575 * Initialize the virtual memory system. 576 */ 577 led_display('p', 'm', 'a', 'p'); 578 pmap_bootstrap(); 579 580 /* 581 * Init mapping for u page(s) for lwp0. 582 */ 583 led_display('u', 's', 'p', 'c'); 584 v = (caddr_t) uvm_pageboot_alloc(USPACE); 585 lwp0.l_addr = proc0paddr = (struct user *) v; 586 lwp0.l_md.md_regs = (struct frame *)(v + USPACE) - 1; 587 curpcb = &lwp0.l_addr->u_pcb; 588 curpcb->pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */ 589 590 /* 591 * Allocate space for system data structures. These data structures 592 * are allocated here instead of cpu_startup() because physical 593 * memory is directly addressable. We don't have to map these into 594 * the virtual address space. 595 */ 596 v = (caddr_t) uvm_pageboot_alloc(size); 597 if ((allocsys(v, NULL) - v) != size) 598 panic("mach_init: table size inconsistency"); 599 600 /* 601 * Initialize debuggers, and break into them, if appropriate. 602 */ 603#if NKSYMS || defined(DDB) || defined(LKM) 604 /* 605 * XXX Loader doesn't give us symbols the way we like. Need 606 * XXX dbsym(1) support for ELF. 607 */ 608 ksyms_init(0, 0, 0); 609#endif 610 611 if (boothowto & RB_KDB) { 612#if defined(DDB) 613 Debugger(); 614#endif 615 } 616} 617 618void 619consinit(void) 620{ 621 622 /* 623 * Everything related to console initialization is done 624 * in mach_init(). 625 */ 626 led_display('N', 'B', 'S', 'D'); 627} 628 629void 630cpu_startup(void) 631{ 632 vsize_t size; 633 u_int i, base, residual; 634 vaddr_t minaddr, maxaddr; 635 char pbuf[9]; 636#ifdef DEBUG 637 extern int pmapdebug; 638 int opmapdebug = pmapdebug; 639 640 pmapdebug = 0; /* Shut up pmap debug during bootstrap */ 641#endif 642 643 /* 644 * Good {morning,afternoon,evening,night}. 645 */ 646 printf(version); 647 printf("%s\n", cpu_model); 648 format_bytes(pbuf, sizeof(pbuf), ptoa(physmem)); 649 printf("total memory = %s\n", pbuf); 650 651 /* 652 * Virtual memory is bootstrapped -- notify the bus spaces 653 * that memory allocation is now safe. 654 */ 655#if defined(ALGOR_P4032) 656 { 657 struct p4032_config *acp = &p4032_configuration; 658 659 acp->ac_mallocsafe = 1; 660 } 661#elif defined(ALGOR_P5064) 662 { 663 struct p5064_config *acp = &p5064_configuration; 664 665 acp->ac_mallocsafe = 1; 666 } 667#elif defined(ALGOR_P6032) 668 { 669 struct p6032_config *acp = &p6032_configuration; 670 671 acp->ac_mallocsafe = 1; 672 } 673#endif 674 675 /* 676 * Allocate virtual address space for file I/O buffers. 677 * Note they are different than the array of headers, 'buf', 678 * and usually occupy more virtual memory than physical. 679 */ 680 size = MAXBSIZE * nbuf; 681 if (uvm_map(kernel_map, (vaddr_t *) &buffers, round_page(size), 682 NULL, UVM_UNKNOWN_OFFSET, 0, 683 UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, 684 UVM_ADV_NORMAL, 0)) != 0) 685 panic("cpu_startup: cannot allocate VM for buffers"); 686 base = bufpages / nbuf; 687 residual = bufpages % nbuf; 688 for (i = 0; i < nbuf; i++) { 689 vsize_t curbufsize; 690 vaddr_t curbuf; 691 struct vm_page *pg; 692 693 /* 694 * Each buffer has MAXBSIZE bytes of VM space allocated. Of 695 * that MAXBSIZE space, we allocate and map (base+1) pages 696 * for the first "residual" buffers, and then we allocate 697 * "base" pages for the rest. 698 */ 699 curbuf = (vaddr_t) buffers + (i * MAXBSIZE); 700 curbufsize = PAGE_SIZE * ((i < residual) ? (base+1) : base); 701 702 while (curbufsize) { 703 pg = uvm_pagealloc(NULL, 0, NULL, 0); 704 if (pg == NULL) 705 panic("cpu_startup: not enough memory for " 706 "buffer cache"); 707 pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg), 708 VM_PROT_READ|VM_PROT_WRITE); 709 curbuf += PAGE_SIZE; 710 curbufsize -= PAGE_SIZE; 711 } 712 } 713 pmap_update(pmap_kernel()); 714 715 /* 716 * Allocate a submap for exec arguments. This map effectively 717 * limits the number of processes exec'ing at any time. 718 */ 719 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 720 16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL); 721 722 /* 723 * Allocate a submap for physio. 724 */ 725 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 726 VM_PHYS_SIZE, 0, FALSE, NULL); 727 728 /* 729 * No need to allocate an mbuf cluster submap. Mbuf clusters 730 * are allocate via the pool allocator, and we use KSEG0 to 731 * map those pages. 732 */ 733 734#ifdef DEBUG 735 pmapdebug = opmapdebug; 736#endif 737 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 738 printf("avail memory = %s\n", pbuf); 739 format_bytes(pbuf, sizeof(pbuf), bufpages * PAGE_SIZE); 740 printf("using %u buffers containing %s of memory\n", nbuf, pbuf); 741 742 /* 743 * Set up buffers, so they can be used to read disklabels. 744 */ 745 bufinit(); 746} 747 748int waittime = -1; 749struct user dumppcb; /* Actually, struct pcb would do. */ 750 751void 752cpu_reboot(int howto, char *bootstr) 753{ 754 int tmp; 755 756 /* Take a snapshot before clobbering any registers. */ 757 if (curlwp) 758 savectx((struct user *) curpcb); 759 760 /* If "always halt" was specified as a boot flag, obey. */ 761 if (boothowto & RB_HALT) 762 howto |= RB_HALT; 763 764 boothowto = howto; 765 766 /* If system is cold, just halt. */ 767 if (cold) { 768 boothowto |= RB_HALT; 769 goto haltsys; 770 } 771 772 if ((boothowto & RB_NOSYNC) == 0 && waittime < 0) { 773 waittime = 0; 774 vfs_shutdown(); 775 /* 776 * If we've been adjusting the clock, the todr 777 * will be out of synch; adjust it now. 778 */ 779 resettodr(); 780 } 781 782 /* Disable interrupts. */ 783 (void) splhigh(); 784 785 if (boothowto & RB_DUMP) 786 dumpsys(); 787 788 haltsys: 789 /* Run any shutdown hooks. */ 790 doshutdownhooks(); 791 792 if (boothowto & RB_HALT) { 793 printf("\n"); 794 printf("The operating system has halted.\n"); 795 printf("Please press any key to return to the monitor.\n\n"); 796 led_display('h','a','l','t'); 797 cnpollc(1); 798 (void) cngetc(); 799 cnpollc(0); 800 } 801 802 printf("Returning to the monitor...\n\n"); 803 led_display('r', 'v', 'e', 'c'); 804 /* Jump to the reset vector. */ 805 __asm __volatile("li %0, 0xbfc00000; jr %0; nop" 806 : "=r" (tmp) 807 : /* no inputs */ 808 : "memory"); 809 led_display('R', 'S', 'T', 'F'); 810 for (;;) 811 /* spin forever */ ; 812} 813 814/* 815 * XXX This shouldn't be here -- it should be done w/ devprops, 816 * XXX but we don't have those yet. 817 */ 818int 819algor_get_ethaddr(struct pci_attach_args *pa, u_int8_t *buf) 820{ 821 822#if defined(ALGOR_P4032) 823 if (pa->pa_bus != 0 || pa->pa_device != 5 || pa->pa_function != 0) 824 return (0); 825#elif defined(ALGOR_P5064) 826 if (pa->pa_bus != 0 || pa->pa_device != 0 || pa->pa_function != 0) 827 return (0); 828#elif defined(ALGOR_P6032) 829 if (pa->pa_bus != 0 || pa->pa_device != 16 || pa->pa_function != 0) 830 return (0); 831#endif 832 833 if (buf != NULL) 834 memcpy(buf, algor_ethaddr, sizeof(algor_ethaddr)); 835#if defined(ALGOR_P4032) 836 /* 837 * XXX This is gross, disgusting, and otherwise vile, but 838 * XXX V962 rev. < B2 have broken DMA FIFOs. Give the 839 * XXX on-board Ethernet a different DMA window that 840 * XXX has pre-fetching enabled so that Ethernet performance 841 * XXX doesn't completely suck. 842 */ 843 pa->pa_dmat = &p4032_configuration.ac_pci_pf_dmat; 844 pa->pa_dmat64 = NULL; 845#endif 846 return (1); 847} 848