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