machdep.c revision 1.11
1/* $NetBSD: machdep.c,v 1.11 2000/09/24 12:32:36 jdolecek Exp $ */ 2 3/* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer 10 * Science Department, The Mach Operating System project at 11 * Carnegie-Mellon University and Ralph Campbell. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. All advertising materials mentioning features or use of this software 22 * must display the following acknowledgement: 23 * This product includes software developed by the University of 24 * California, Berkeley and its contributors. 25 * 4. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 42 */ 43 44#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 45 46__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.11 2000/09/24 12:32:36 jdolecek Exp $"); 47 48/* from: Utah Hdr: machdep.c 1.63 91/04/24 */ 49 50#include <sys/param.h> 51#include <sys/systm.h> 52#include <sys/signalvar.h> 53#include <sys/kernel.h> 54#include <sys/map.h> 55#include <sys/proc.h> 56#include <sys/buf.h> 57#include <sys/reboot.h> 58#include <sys/conf.h> 59#include <sys/file.h> 60#include <sys/callout.h> 61#include <sys/malloc.h> 62#include <sys/mbuf.h> 63#include <sys/msgbuf.h> 64#include <sys/ioctl.h> 65#include <sys/device.h> 66#include <sys/user.h> 67#include <sys/exec.h> 68#include <sys/sysctl.h> 69#include <sys/mount.h> 70#include <sys/syscallargs.h> 71#include <sys/kcore.h> 72 73#include <uvm/uvm_extern.h> 74 75#include <ufs/mfs/mfs_extern.h> /* mfs_initminiroot() */ 76 77#include <machine/cpu.h> 78#include <machine/reg.h> 79#include <machine/psl.h> 80#include <machine/pte.h> 81 82#ifdef DDB 83#include <machine/db_machdep.h> 84#include <ddb/db_extern.h> 85#endif 86 87#include <machine/intr.h> 88#include <machine/mainboard.h> 89#include <machine/sysconf.h> 90#include <machine/autoconf.h> 91#include <machine/bootinfo.h> 92#include <machine/prom.h> 93#include <dev/clock_subr.h> 94#include <dev/cons.h> 95 96#include <sys/boot_flag.h> 97 98#include "fs_mfs.h" 99#include "opt_ddb.h" 100#include "opt_execfmt.h" 101 102/* the following is used externally (sysctl_hw) */ 103char machine[] = MACHINE; /* from <machine/param.h> */ 104char machine_arch[] = MACHINE_ARCH; 105char cpu_model[40]; 106unsigned ssir; 107 108/* Our exported CPU info; we can have only one. */ 109struct cpu_info cpu_info_store; 110 111/* maps for VM objects */ 112 113vm_map_t exec_map = NULL; 114vm_map_t mb_map = NULL; 115vm_map_t phys_map = NULL; 116 117int physmem; /* max supported memory, changes to actual */ 118char *bootinfo = NULL; /* pointer to bootinfo structure */ 119 120phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 121int mem_cluster_cnt; 122 123void to_monitor __P((int)) __attribute__((__noreturn__)); 124void prom_halt __P((int)) __attribute__((__noreturn__)); 125 126struct evcnt soft_evcnt[IPL_NSOFT]; 127 128/* 129 * Local functions. 130 */ 131int initcpu __P((void)); 132void configure __P((void)); 133 134void mach_init __P((int, char *[], char*[], u_int, char *)); 135void softintr_init __P((void)); 136int memsize_scan __P((caddr_t)); 137 138#ifdef DEBUG 139/* stacktrace code violates prototypes to get callee's registers */ 140extern void stacktrace __P((void)); /*XXX*/ 141#endif 142 143/* 144 * safepri is a safe priority for sleep to set for a spin-wait 145 * during autoconfiguration or after a panic. Used as an argument to splx(). 146 * XXX disables interrupt 5 to disable mips3 on-chip clock, which also 147 * disables mips1 FPU interrupts. 148 */ 149int safepri = MIPS3_PSL_LOWIPL; /* XXX */ 150extern struct user *proc0paddr; 151 152/* locore callback-vector setup */ 153extern void mips_vector_init __P((void)); 154extern void prom_init __P((void)); 155extern void pizazz_init __P((void)); 156 157/* platform-specific initialization vector */ 158static void unimpl_cons_init __P((void)); 159static void unimpl_iointr __P((unsigned, unsigned, unsigned, unsigned)); 160static int unimpl_memsize __P((caddr_t)); 161static unsigned unimpl_clkread __P((void)); 162static void unimpl_todr __P((struct clock_ymdhms *)); 163static void unimpl_intr_establish __P((int, int (*)__P((void *)), void *)); 164 165struct platform platform = { 166 "iobus not set", 167 unimpl_cons_init, 168 unimpl_iointr, 169 unimpl_memsize, 170 unimpl_clkread, 171 unimpl_todr, 172 unimpl_todr, 173 unimpl_intr_establish, 174}; 175 176struct consdev *cn_tab = NULL; 177extern struct consdev consdev_prom; 178extern struct consdev consdev_zs; 179 180static void null_cnprobe __P((struct consdev *)); 181static void prom_cninit __P((struct consdev *)); 182static int prom_cngetc __P((dev_t)); 183static void prom_cnputc __P((dev_t, int)); 184static void null_cnpollc __P((dev_t, int)); 185 186struct consdev consdev_prom = { 187 null_cnprobe, 188 prom_cninit, 189 prom_cngetc, 190 prom_cnputc, 191 null_cnpollc, 192}; 193 194 195/* 196 * Do all the stuff that locore normally does before calling main(). 197 * Process arguments passed to us by the prom monitor. 198 * Return the first page address following the system. 199 */ 200void 201mach_init(argc, argv, envp, bim, bip) 202 int argc; 203 char *argv[]; 204 char *envp[]; 205 u_int bim; 206 char *bip; 207{ 208 u_long first, last; 209 caddr_t kernend, v; 210 vsize_t size; 211 char *cp; 212 int i, howto; 213 extern char edata[], end[]; 214 char *bi_msg; 215#ifdef DDB 216 int nsym = 0; 217 caddr_t ssym = 0; 218 caddr_t esym = 0; 219 struct btinfo_symtab *bi_syms; 220#endif 221 222 223 /* Check for valid bootinfo passed from bootstrap */ 224 if (bim == BOOTINFO_MAGIC) { 225 struct btinfo_magic *bi_magic; 226 227 bootinfo = (char *)BOOTINFO_ADDR; /* XXX */ 228 bi_magic = lookup_bootinfo(BTINFO_MAGIC); 229 if (bi_magic == NULL || bi_magic->magic != BOOTINFO_MAGIC) 230 bi_msg = "invalid bootinfo structure.\n"; 231 else 232 bi_msg = NULL; 233 } else 234 bi_msg = "invalid bootinfo (standalone boot?)\n"; 235 236 /* clear the BSS segment */ 237 kernend = (caddr_t)mips_round_page(end); 238 bzero(edata, kernend - edata); 239 240#ifdef DDB 241 bi_syms = lookup_bootinfo(BTINFO_SYMTAB); 242 243 /* Load sysmbol table if present */ 244 if (bi_syms != NULL) { 245 nsym = bi_syms->nsym; 246 ssym = (caddr_t)bi_syms->ssym; 247 esym = (caddr_t)bi_syms->esym; 248 kernend = (caddr_t)mips_round_page(esym); 249 } 250#endif 251 252 prom_init(); 253 consinit(); 254 255 if (bi_msg != NULL) 256 printf(bi_msg); 257 258 /* 259 * Set the VM page size. 260 */ 261 uvm_setpagesize(); 262 263 /* Find out how much memory is available. */ 264 physmem = memsize_scan(kernend); 265 266 /* 267 * Now that we know how much memory we have, initialize the 268 * mem cluster array. 269 */ 270 mem_clusters[0].start = 0; /* XXX is this correct? */ 271 mem_clusters[0].size = ctob(physmem); 272 mem_cluster_cnt = 1; 273 274 /* 275 * Copy exception-dispatch code down to exception vector. 276 * Initialize locore-function vector. 277 * Clear out the I and D caches. 278 */ 279 mips_vector_init(); 280 281 /* Look at argv[0] and compute bootdev */ 282 makebootdev(argv[0]); 283 284 /* 285 * Look at arguments passed to us and compute boothowto. 286 */ 287 boothowto = RB_SINGLE; 288 for (i = 1; i < argc; i++) { 289 for (cp = argv[i]; *cp; cp++) { 290 /* Ignore superfluous '-', if there is one */ 291 if (*cp == '-') 292 continue; 293 294 howto = 0; 295 BOOT_FLAG(*cp, howto); 296 if (! howto) 297 printf("bootflag '%c' not recognised\n", *cp); 298 else 299 boothowto |= howto; 300 } 301 } 302 303 304#ifdef DDB 305 /* 306 * Initialize machine-dependent DDB commands, in case of early panic. 307 */ 308 db_machine_init(); 309 /* init symbols if present */ 310 if (esym) 311 ddb_init(esym - ssym, ssym, esym); 312 if (boothowto & RB_KDB) 313 Debugger(); 314#endif 315 316#ifdef MFS 317 /* 318 * Check to see if a mini-root was loaded into memory. It resides 319 * at the start of the next page just after the end of BSS. 320 */ 321 if (boothowto & RB_MINIROOT) 322 kernend += round_page(mfs_initminiroot(kernend)); 323#endif 324 325 /* 326 * Alloc u pages for proc0 stealing KSEG0 memory. 327 */ 328 proc0.p_addr = proc0paddr = (struct user *)kernend; 329 proc0.p_md.md_regs = (struct frame *)(kernend + USPACE) - 1; 330 memset(proc0.p_addr, 0, USPACE); 331 curpcb = &proc0.p_addr->u_pcb; 332 curpcb->pcb_context[11] = MIPS_INT_MASK | MIPS_SR_INT_IE; /* SR */ 333 334 kernend += USPACE; 335 336 /* 337 * Load the rest of the available pages into the VM system. 338 */ 339 first = round_page(MIPS_KSEG0_TO_PHYS(kernend)); 340 last = mem_clusters[0].start + mem_clusters[0].size; 341 uvm_page_physload(atop(first), atop(last), atop(first), atop(last), 342 VM_FREELIST_DEFAULT); 343 344 /* 345 * Initialize error message buffer (at end of core). 346 */ 347 mips_init_msgbuf(); 348 349 /* 350 * Allocate space for system data structures. These data structures 351 * are allocated here instead of cpu_startup() because physical 352 * memory is directly addressable. We don't have to map these into 353 * virtual address space. 354 */ 355 size = (vsize_t)allocsys(NULL, NULL); 356 v = (caddr_t)pmap_steal_memory(size, NULL, NULL); 357 if ((allocsys(v, NULL) - v) != size) 358 panic("mach_init: table size inconsistency"); 359 /* 360 * Set up interrupt handling and I/O addresses. 361 */ 362 363 pizazz_init(); 364 365 /* 366 * Initialize the virtual memory system. 367 */ 368 pmap_bootstrap(); 369} 370 371 372 373/* 374 * cpu_startup: allocate memory for variable-sized tables, 375 * initialize cpu, and do autoconfiguration. 376 */ 377void 378cpu_startup() 379{ 380 register unsigned i; 381 int base, residual; 382 vaddr_t minaddr, maxaddr; 383 vsize_t size; 384 char pbuf[9]; 385#ifdef DEBUG 386 extern int pmapdebug; 387 int opmapdebug = pmapdebug; 388 389 pmapdebug = 0; 390#endif 391 392 /* 393 * Good {morning,afternoon,evening,night}. 394 */ 395 printf(version); 396 printf("%s\n", cpu_model); 397 format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); 398 printf("total memory = %s\n", pbuf); 399 400 /* 401 * Allocate virtual address space for file I/O buffers. 402 * Note they are different than the array of headers, 'buf', 403 * and usually occupy more virtual memory than physical. 404 */ 405 size = MAXBSIZE * nbuf; 406 if (uvm_map(kernel_map, (vaddr_t *)&buffers, round_page(size), 407 NULL, UVM_UNKNOWN_OFFSET, 0, 408 UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, 409 UVM_ADV_NORMAL, 0)) != KERN_SUCCESS) 410 panic("startup: cannot allocate VM for buffers"); 411 minaddr = (vaddr_t)buffers; 412 base = bufpages / nbuf; 413 residual = bufpages % nbuf; 414 for (i = 0; i < nbuf; i++) { 415 vsize_t curbufsize; 416 vaddr_t curbuf; 417 struct vm_page *pg; 418 419 /* 420 * Each buffer has MAXBSIZE bytes of VM space allocated. Of 421 * that MAXBSIZE space, we allocate and map (base+1) pages 422 * for the first "residual" buffers, and then we allocate 423 * "base" pages for the rest. 424 */ 425 curbuf = (vaddr_t) buffers + (i * MAXBSIZE); 426 curbufsize = NBPG * ((i < residual) ? (base+1) : base); 427 428 while (curbufsize) { 429 pg = uvm_pagealloc(NULL, 0, NULL, 0); 430 if (pg == NULL) 431 panic("cpu_startup: not enough memory for " 432 "buffer cache"); 433 pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg), 434 VM_PROT_READ|VM_PROT_WRITE); 435 curbuf += PAGE_SIZE; 436 curbufsize -= PAGE_SIZE; 437 } 438 } 439 /* 440 * Allocate a submap for exec arguments. This map effectively 441 * limits the number of processes exec'ing at any time. 442 */ 443 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 444 16 * NCARGS, TRUE, FALSE, NULL); 445 /* 446 * Allocate a submap for physio 447 */ 448 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 449 VM_PHYS_SIZE, TRUE, FALSE, NULL); 450 451 /* 452 * No need to allocate an mbuf cluster submap. Mbuf clusters 453 * are allocated via the pool allocator, and we use KSEG to 454 * map those pages. 455 */ 456 457#ifdef DEBUG 458 pmapdebug = opmapdebug; 459#endif 460 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 461 printf("avail memory = %s\n", pbuf); 462 format_bytes(pbuf, sizeof(pbuf), bufpages * NBPG); 463 printf("using %d buffers containing %s of memory\n", nbuf, pbuf); 464 465 /* 466 * Set up buffers, so they can be used to read disk labels. 467 */ 468 bufinit(); 469} 470 471void 472softintr_init() 473{ 474 int i; 475 static const char *intr_names[] = IPL_SOFTNAMES; 476 477 for (i=0; i < IPL_NSOFT; i++) { 478 evcnt_attach_dynamic(&soft_evcnt[i], EVCNT_TYPE_INTR, NULL, 479 "soft", intr_names[i]); 480 } 481} 482 483/* 484 * machine dependent system variables. 485 */ 486int 487cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 488 int *name; 489 u_int namelen; 490 void *oldp; 491 size_t *oldlenp; 492 void *newp; 493 size_t newlen; 494 struct proc *p; 495{ 496 /* all sysctl names at this level are terminal */ 497 if (namelen != 1) 498 return (ENOTDIR); /* overloaded */ 499 500 switch (name[0]) { 501 default: 502 return (EOPNOTSUPP); 503 } 504 /* NOTREACHED */ 505} 506 507/* 508 * Look up information in bootinfo of boot loader. 509 */ 510void * 511lookup_bootinfo(type) 512 int type; 513{ 514 struct btinfo_common *bt; 515 char *help = bootinfo; 516 517 /* Check for a bootinfo record first. */ 518 if (help == NULL) 519 return (NULL); 520 521 do { 522 bt = (struct btinfo_common *)help; 523 if (bt->type == type) 524 return ((void *)help); 525 help += bt->next; 526 } while (bt->next != 0 && 527 (size_t)help < (size_t)bootinfo + BOOTINFO_SIZE); 528 529 return (NULL); 530} 531 532int waittime = -1; 533 534/* 535 * call PROM to halt or reboot. 536 */ 537void 538prom_halt(howto) 539 int howto; 540{ 541 if (howto & RB_HALT) 542 MIPS_PROM(reinit)(); 543 MIPS_PROM(reboot)(); 544 /* NOTREACHED */ 545} 546 547void 548cpu_reboot(howto, bootstr) 549 volatile int howto; 550 char *bootstr; 551{ 552 extern int cold; 553 554 /* take a snap shot before clobbering any registers */ 555 if (curproc) 556 savectx((struct user *)curpcb); 557 558#ifdef DEBUG 559 if (panicstr) 560 stacktrace(); 561#endif 562 563 /* If system is cold, just halt. */ 564 if (cold) { 565 howto |= RB_HALT; 566 goto haltsys; 567 } 568 569 /* If "always halt" was specified as a boot flag, obey. */ 570 if ((boothowto & RB_HALT) != 0) 571 howto |= RB_HALT; 572 573 boothowto = howto; 574 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 575 /* 576 * Synchronize the disks.... 577 */ 578 waittime = 0; 579 vfs_shutdown(); 580 581 /* 582 * If we've been adjusting the clock, the todr 583 * will be out of synch; adjust it now. 584 */ 585 resettodr(); 586 } 587 588 /* Disable interrupts. */ 589 splhigh(); 590 591 /* If rebooting and a dump is requested do it. */ 592#if 0 593 if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) 594#else 595 if (howto & RB_DUMP) 596#endif 597 dumpsys(); 598 599haltsys: 600 601 /* run any shutdown hooks */ 602 doshutdownhooks(); 603 604 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) 605 prom_halt(0x80); /* rom monitor RB_PWOFF */ 606 607 /* Finally, halt/reboot the system. */ 608 printf("%s\n\n", howto & RB_HALT ? "halted." : "rebooting..."); 609 prom_halt(howto & RB_HALT); 610 /*NOTREACHED*/ 611} 612 613/* 614 * Return the best possible estimate of the time in the timeval 615 * to which tvp points. Unfortunately, we can't read the hardware registers. 616 * We guarantee that the time will be greater than the value obtained by a 617 * previous call. 618 */ 619void 620microtime(tvp) 621 register struct timeval *tvp; 622{ 623 static struct timeval lasttime; 624 int s = splclock(); 625 626 *tvp = time; 627 628 tvp->tv_usec += (*platform.clkread)(); 629 630 while (tvp->tv_usec >= 1000000) { 631 tvp->tv_usec -= 1000000; 632 tvp->tv_sec++; 633 } 634 635 if (tvp->tv_sec == lasttime.tv_sec && 636 tvp->tv_usec <= lasttime.tv_usec && 637 (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) { 638 tvp->tv_sec++; 639 tvp->tv_usec -= 1000000; 640 } 641 lasttime = *tvp; 642 splx(s); 643} 644 645int 646initcpu() 647{ 648 softintr_init(); 649 spl0(); /* safe to turn interrupts on now */ 650 return 0; 651} 652 653static void 654unimpl_cons_init() 655{ 656 657 panic("sysconf.init didn't set cons_init"); 658} 659 660static void 661unimpl_iointr(mask, pc, statusreg, causereg) 662 u_int mask; 663 u_int pc; 664 u_int statusreg; 665 u_int causereg; 666{ 667 668 panic("sysconf.init didn't set intr"); 669} 670 671static int 672unimpl_memsize(first) 673caddr_t first; 674{ 675 676 panic("sysconf.init didn't set memsize"); 677} 678 679static unsigned 680unimpl_clkread() 681{ 682 panic("sysconf.init didn't set clkread"); 683} 684 685static void 686unimpl_todr(dt) 687 struct clock_ymdhms *dt; 688{ 689 panic("sysconf.init didn't init TOD"); 690} 691 692void 693unimpl_intr_establish(level, func, arg) 694 int level; 695 int (*func) __P((void *)); 696 void *arg; 697{ 698 panic("sysconf.init didn't init intr_establish\n"); 699} 700 701void 702delay(n) 703 int n; 704{ 705 DELAY(n); 706} 707 708void 709cpu_intr(status, cause, pc, ipending) 710 u_int32_t status; 711 u_int32_t cause; 712 u_int32_t pc; 713 u_int32_t ipending; 714{ 715 uvmexp.intrs++; 716 717 /* device interrupts */ 718 (*platform.iointr)(status, cause, pc, ipending); 719 720 /* software simulated interrupt */ 721 if ((ipending & MIPS_SOFT_INT_MASK_1) || 722 (ssir && (status & MIPS_SOFT_INT_MASK_1))) { 723 724#define DO_SIR(bit, fn, ev) \ 725 do { \ 726 if (n & (bit)) { \ 727 uvmexp.softs++; \ 728 soft_evcnt[ev].ev_count++; \ 729 fn; \ 730 } \ 731 } while (0) 732 733 unsigned n; 734 n = ssir; ssir = 0; 735 _clrsoftintr(MIPS_SOFT_INT_MASK_1); 736 737#if NZSC > 0 738 DO_SIR(SIR_SERIAL, zssoft(), IPL_SOFTSERIAL); 739#endif 740 DO_SIR(SIR_NET, netintr(), IPL_SOFTNET); 741#undef DO_SIR 742 } 743 744 /* 'softclock' interrupt */ 745 if (ipending & MIPS_SOFT_INT_MASK_0) { 746 _clrsoftintr(MIPS_SOFT_INT_MASK_0); 747 uvmexp.softs++; 748 soft_evcnt[IPL_SOFTCLOCK].ev_count++; 749 softclock(); 750 } 751} 752 753/* 754 * Find out how much memory is available by testing memory. 755 * Be careful to save and restore the original contents for msgbuf. 756 */ 757int 758memsize_scan(first) 759 caddr_t first; 760{ 761 volatile int *vp, *vp0; 762 int mem, tmp, tmp0; 763 764#define PATTERN1 0xa5a5a5a5 765#define PATTERN2 ~PATTERN1 766 767 /* 768 * Non destructive scan of memory to determine the size 769 * Use the first page to test for memory aliases. This 770 * also has the side effect of flushing the bus alignment 771 * buffer 772 */ 773 mem = btoc((paddr_t)first - MIPS_KSEG0_START); 774 vp = (int *)MIPS_PHYS_TO_KSEG1(mem << PGSHIFT); 775 vp0 = (int *)MIPS_PHYS_TO_KSEG1(0); /* Start of physical memory */ 776 tmp0 = *vp0; 777 while (vp < (int *)MIPS_MAX_MEM_ADDR) { 778 tmp = *vp; 779 *vp = PATTERN1; 780 *vp0 = PATTERN2; 781 wbflush(); 782 if (*vp != PATTERN1) 783 break; 784 *vp = PATTERN2; 785 *vp0 = PATTERN1; 786 wbflush(); 787 if (*vp != PATTERN2) 788 break; 789 *vp = tmp; 790 vp += NBPG/sizeof(int); 791 mem++; 792 } 793 *vp0 = tmp0; 794 return mem; 795} 796 797 798#ifdef EXEC_ECOFF 799#include <sys/exec_ecoff.h> 800 801int 802cpu_exec_ecoff_hook(p, epp) 803 struct proc *p; 804 struct exec_package *epp; 805{ 806 extern struct emul emul_netbsd; 807 808 epp->ep_emul = &emul_netbsd; 809 810 return 0; 811} 812#endif 813 814/* 815 * Console initialization: called early on from main, 816 * before vm init or startup. Do enough configuration 817 * to choose and initialize a console. 818 */ 819 820static void 821null_cnprobe(cn) 822 struct consdev *cn; 823{ 824} 825 826static void 827prom_cninit(cn) 828 struct consdev *cn; 829{ 830 cn->cn_dev = makedev(0, 0); 831 cn->cn_pri = CN_REMOTE; 832} 833 834static int 835prom_cngetc(dev) 836 dev_t dev; 837{ 838 return MIPS_PROM(getchar)(); 839} 840 841static void 842prom_cnputc(dev, c) 843 dev_t dev; 844 int c; 845{ 846 MIPS_PROM(putchar)(c); 847} 848 849static void 850null_cnpollc(dev, on) 851 dev_t dev; 852 int on; 853{ 854} 855 856void 857consinit() 858{ 859 int zs_unit; 860 861 zs_unit = 0; 862 cn_tab = &consdev_zs; 863 864 (*cn_tab->cn_init)(cn_tab); 865} 866