Annotation of sys/arch/mvme68k/mvme68k/machdep.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: machdep.c,v 1.106 2007/06/06 17:15:12 deraadt Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 1995 Theo de Raadt
! 5: * Copyright (c) 1999 Steve Murphree, Jr. (68060 support)
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: *
! 16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
! 17: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 18: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 19: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
! 20: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 21: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 22: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 24: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 25: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 26: * SUCH DAMAGE.
! 27: *
! 28: * Copyright (c) 1988 University of Utah.
! 29: * Copyright (c) 1982, 1986, 1990, 1993
! 30: * The Regents of the University of California. All rights reserved.
! 31: *
! 32: * This code is derived from software contributed to Berkeley by
! 33: * the Systems Programming Group of the University of Utah Computer
! 34: * Science Department.
! 35: *
! 36: * Redistribution and use in source and binary forms, with or without
! 37: * modification, are permitted provided that the following conditions
! 38: * are met:
! 39: * 1. Redistributions of source code must retain the above copyright
! 40: * notice, this list of conditions and the following disclaimer.
! 41: * 2. Redistributions in binary form must reproduce the above copyright
! 42: * notice, this list of conditions and the following disclaimer in the
! 43: * documentation and/or other materials provided with the distribution.
! 44: * 3. Neither the name of the University nor the names of its contributors
! 45: * may be used to endorse or promote products derived from this software
! 46: * without specific prior written permission.
! 47: *
! 48: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 49: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 50: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 51: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 52: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 53: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 54: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 55: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 56: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 57: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 58: * SUCH DAMAGE.
! 59: *
! 60: * from: Utah $Hdr: machdep.c 1.74 92/12/20$
! 61: *
! 62: * @(#)machdep.c 8.10 (Berkeley) 4/20/94
! 63: */
! 64:
! 65: #include <sys/param.h>
! 66: #include <sys/systm.h>
! 67: #include <sys/signalvar.h>
! 68: #include <sys/kernel.h>
! 69: #include <sys/proc.h>
! 70: #include <sys/buf.h>
! 71: #include <sys/reboot.h>
! 72: #include <sys/conf.h>
! 73: #include <sys/file.h>
! 74: #include <sys/timeout.h>
! 75: #include <sys/malloc.h>
! 76: #include <sys/mbuf.h>
! 77: #include <sys/msgbuf.h>
! 78: #include <sys/ioctl.h>
! 79: #include <sys/tty.h>
! 80: #include <sys/mount.h>
! 81: #include <sys/user.h>
! 82: #include <sys/exec.h>
! 83: #include <sys/core.h>
! 84: #include <sys/kcore.h>
! 85: #include <sys/vnode.h>
! 86: #include <sys/sysctl.h>
! 87: #include <sys/syscallargs.h>
! 88: #ifdef SYSVMSG
! 89: #include <sys/msg.h>
! 90: #endif
! 91: #include <sys/evcount.h>
! 92:
! 93: #include <machine/atomic.h>
! 94: #include <machine/autoconf.h>
! 95: #include <machine/cpu.h>
! 96: #include <machine/kcore.h>
! 97: #include <machine/prom.h>
! 98: #include <machine/psl.h>
! 99: #include <machine/pte.h>
! 100: #include <machine/reg.h>
! 101:
! 102: #ifdef MVME147
! 103: #include <mvme68k/dev/pccreg.h>
! 104: #endif
! 105:
! 106: #include <dev/cons.h>
! 107:
! 108: #include <net/netisr.h>
! 109:
! 110: #ifdef DDB
! 111: #include <machine/db_machdep.h>
! 112: #include <ddb/db_extern.h>
! 113: #include <ddb/db_interface.h>
! 114: #include <ddb/db_var.h>
! 115: #endif
! 116:
! 117: #include <uvm/uvm_extern.h>
! 118:
! 119: /* the following is used externally (sysctl_hw) */
! 120: char machine[] = MACHINE; /* cpu "architecture" */
! 121:
! 122: struct vm_map *exec_map = NULL;
! 123: struct vm_map *phys_map = NULL;
! 124:
! 125: extern vaddr_t avail_end;
! 126:
! 127: /*
! 128: * Declare these as initialized data so we can patch them.
! 129: */
! 130: #ifndef BUFCACHEPERCENT
! 131: #define BUFCACHEPERCENT 5
! 132: #endif
! 133:
! 134: #ifdef BUFPAGES
! 135: int bufpages = BUFPAGES;
! 136: #else
! 137: int bufpages = 0;
! 138: #endif
! 139: int bufcachepercent = BUFCACHEPERCENT;
! 140:
! 141: int physmem; /* size of physical memory, in pages */
! 142: /*
! 143: * safepri is a safe priority for sleep to set for a spin-wait
! 144: * during autoconfiguration or after a panic.
! 145: */
! 146: int safepri = PSL_LOWIPL;
! 147:
! 148: #ifdef COMPAT_SUNOS
! 149: extern struct emul emul_sunos;
! 150: #endif
! 151:
! 152: void dumpsys(void);
! 153: void initvectors(void);
! 154: void mvme68k_init(void);
! 155: void identifycpu(void);
! 156: int cpu_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *);
! 157: void dumpconf(void);
! 158: void straytrap(int, u_short);
! 159: void netintr(void *);
! 160: void myetheraddr(u_char *);
! 161: int fpu_gettype(void);
! 162: int memsize162(void);
! 163: int memsize1x7(void); /* in locore */
! 164: int memsize(void);
! 165: caddr_t allocsys(caddr_t);
! 166:
! 167: void
! 168: mvme68k_init()
! 169: {
! 170: extern vaddr_t avail_start;
! 171:
! 172: /*
! 173: * Tell the VM system about available physical memory. The
! 174: * mvme68k only has one segment.
! 175: */
! 176:
! 177: uvmexp.pagesize = NBPG;
! 178: uvm_setpagesize();
! 179: uvm_page_physload(atop(avail_start), atop(avail_end),
! 180: atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT);
! 181:
! 182: /*
! 183: * Put machine specific exception vectors in place.
! 184: */
! 185: initvectors();
! 186: }
! 187:
! 188: /*
! 189: * Console initialization: called early on from main,
! 190: * before vm init or startup, but already running virtual.
! 191: * Do enough configuration to choose and initialize a console.
! 192: */
! 193: void
! 194: consinit()
! 195: {
! 196: /*
! 197: * Initialize the console before we print anything out.
! 198: */
! 199: cninit();
! 200:
! 201: #ifdef DDB
! 202: db_machine_init();
! 203: ddb_init();
! 204:
! 205: if (boothowto & RB_KDB)
! 206: Debugger();
! 207: #endif
! 208: }
! 209:
! 210: /*
! 211: * cpu_startup: allocate memory for variable-sized tables,
! 212: * initialize cpu, and do autoconfiguration.
! 213: */
! 214: void
! 215: cpu_startup()
! 216: {
! 217: unsigned i;
! 218: caddr_t v;
! 219: vaddr_t minaddr, maxaddr;
! 220: vsize_t size;
! 221: #ifdef DEBUG
! 222: extern int pmapdebug;
! 223: int opmapdebug = pmapdebug;
! 224:
! 225: pmapdebug = 0;
! 226: #endif
! 227:
! 228: /*
! 229: * Initialize error message buffer (at end of core).
! 230: * avail_end was pre-decremented in pmap_bootstrap to compensate.
! 231: */
! 232: for (i = 0; i < btoc(MSGBUFSIZE); i++)
! 233: pmap_kenter_pa((vaddr_t)msgbufp + i * PAGE_SIZE,
! 234: avail_end + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE);
! 235: pmap_update(pmap_kernel());
! 236: initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE));
! 237:
! 238: /*
! 239: * Good {morning,afternoon,evening,night}.
! 240: */
! 241: printf("%s", version);
! 242: identifycpu();
! 243: printf("real mem = %u (%uMB)\n", ctob(physmem),
! 244: ctob(physmem) / 1024 / 1024);
! 245:
! 246: /*
! 247: * Find out how much space we need, allocate it,
! 248: * and then give everything true virtual addresses.
! 249: */
! 250: size = (vsize_t)allocsys((caddr_t)0);
! 251: if ((v = (caddr_t) uvm_km_zalloc(kernel_map, round_page(size))) == 0)
! 252: panic("startup: no room for tables");
! 253: if (allocsys(v) - v != size)
! 254: panic("startup: table size inconsistency");
! 255:
! 256: /*
! 257: * Determine how many buffers to allocate.
! 258: * We allocate bufcachepercent% of memory for buffer space.
! 259: */
! 260: if (bufpages == 0)
! 261: bufpages = physmem * bufcachepercent / 100;
! 262:
! 263: /* Restrict to at most 25% filled kvm */
! 264: if (bufpages >
! 265: (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
! 266: bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
! 267: PAGE_SIZE / 4;
! 268:
! 269: /*
! 270: * Allocate a submap for exec arguments. This map effectively
! 271: * limits the number of processes exec'ing at any time.
! 272: */
! 273: minaddr = vm_map_min(kernel_map);
! 274: exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
! 275: 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
! 276:
! 277: /*
! 278: * Allocate a submap for physio.
! 279: */
! 280: phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
! 281: VM_PHYS_SIZE, 0, FALSE, NULL);
! 282:
! 283: #ifdef DEBUG
! 284: pmapdebug = opmapdebug;
! 285: #endif
! 286:
! 287: /*
! 288: * Set up buffers, so they can be used to read disk labels.
! 289: */
! 290: bufinit();
! 291:
! 292: printf("avail mem = %u (%uMB)\n",
! 293: ptoa(uvmexp.free), ptoa(uvmexp.free) / 1024 / 1024);
! 294:
! 295: /*
! 296: * Configure the system.
! 297: */
! 298: if (boothowto & RB_CONFIG) {
! 299: #ifdef BOOT_CONFIG
! 300: user_config();
! 301: #else
! 302: printf("kernel does not support -c; continuing..\n");
! 303: #endif
! 304: }
! 305: }
! 306:
! 307: /*
! 308: * Allocate space for system data structures. We are given
! 309: * a starting virtual address and we return a final virtual
! 310: * address; along the way we set each data structure pointer.
! 311: *
! 312: * You call allocsys() with 0 to find out how much space we want,
! 313: * allocate that much and fill it with zeroes, and then call
! 314: * allocsys() again with the correct base virtual address.
! 315: */
! 316: caddr_t
! 317: allocsys(caddr_t v)
! 318: {
! 319:
! 320: #define valloc(name, type, num) \
! 321: (name) = (type *)v; v = (caddr_t)((name) + (num))
! 322: #ifdef SYSVMSG
! 323: valloc(msgpool, char, msginfo.msgmax);
! 324: valloc(msgmaps, struct msgmap, msginfo.msgseg);
! 325: valloc(msghdrs, struct msg, msginfo.msgtql);
! 326: valloc(msqids, struct msqid_ds, msginfo.msgmni);
! 327: #endif
! 328:
! 329: return (v);
! 330: }
! 331:
! 332: /*
! 333: * Info for CTL_HW
! 334: */
! 335: char cpu_model[120];
! 336:
! 337: int cputyp;
! 338: int cpuspeed;
! 339:
! 340: struct mvmeprom_brdid brdid;
! 341:
! 342: void
! 343: identifycpu()
! 344: {
! 345: char mc;
! 346: char speed[6];
! 347: char suffix[30];
! 348: int len;
! 349:
! 350: bzero(suffix, sizeof suffix);
! 351:
! 352: switch (mmutype) {
! 353: case MMU_68060:
! 354: mc = '6';
! 355: break;
! 356: case MMU_68040:
! 357: mc = '4';
! 358: break;
! 359: case MMU_68030:
! 360: mc = '3';
! 361: break;
! 362: default:
! 363: mc = '2';
! 364: }
! 365:
! 366: switch (cputyp) {
! 367: #ifdef MVME147
! 368: case CPU_147:
! 369: snprintf(suffix, sizeof suffix, "MVME%x", brdid.model);
! 370: cpuspeed = pccspeed((struct pccreg *)IIOV(0xfffe1000));
! 371: snprintf(speed, sizeof speed, "%02d", cpuspeed);
! 372: break;
! 373: #endif
! 374: #if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177)
! 375: case CPU_162:
! 376: case CPU_167:
! 377: case CPU_172:
! 378: case CPU_177:
! 379: bzero(speed, sizeof speed);
! 380: speed[0] = brdid.speed[0];
! 381: speed[1] = brdid.speed[1];
! 382: if (brdid.speed[2] != '0' &&
! 383: brdid.speed[3] != '0') {
! 384: speed[2] = '.';
! 385: speed[3] = brdid.speed[2];
! 386: speed[4] = brdid.speed[3];
! 387: }
! 388: cpuspeed = (speed[0] - '0') * 10 + (speed[1] - '0');
! 389: bcopy(brdid.longname, suffix, sizeof(brdid.longname));
! 390: for (len = strlen(suffix)-1; len; len--) {
! 391: if (suffix[len] == ' ')
! 392: suffix[len] = '\0';
! 393: else
! 394: break;
! 395: }
! 396: break;
! 397: #endif
! 398: }
! 399: snprintf(cpu_model, sizeof cpu_model,
! 400: "Motorola %s: %sMHz MC680%c0 CPU", suffix, speed, mc);
! 401: switch (mmutype) {
! 402: #if defined(M68040)
! 403: case MMU_68040:
! 404: /* FALLTHROUGH */
! 405: #endif
! 406: #if defined(M68060)
! 407: case MMU_68060:
! 408: /* FALLTHROUGH */
! 409: #endif
! 410: case MMU_68030:
! 411: strlcat(cpu_model, "+MMU", sizeof cpu_model);
! 412: break;
! 413: case MMU_68851:
! 414: strlcat(cpu_model, ", MC68851 MMU", sizeof cpu_model);
! 415: break;
! 416: default:
! 417: printf("%s\n", cpu_model);
! 418: panic("unknown MMU type %d", mmutype);
! 419: }
! 420:
! 421: switch (mmutype) {
! 422: #if defined(M68060)
! 423: case MMU_68060:
! 424: strlcat(cpu_model,"+FPU, 8k on-chip physical I/D caches",
! 425: sizeof cpu_model);
! 426: break;
! 427: #endif
! 428: #if defined(M68040)
! 429: case MMU_68040:
! 430: strlcat(cpu_model, "+FPU, 4k on-chip physical I/D caches",
! 431: sizeof cpu_model);
! 432: break;
! 433: #endif
! 434: #if defined(M68030) || defined(M68020)
! 435: default:
! 436: fputype = fpu_gettype();
! 437:
! 438: switch (fputype) {
! 439: case FPU_NONE:
! 440: break;
! 441: case FPU_68881:
! 442: case FPU_68882:
! 443: len = strlen (cpu_model);
! 444: snprintf(cpu_model + len, sizeof cpu_model - len,
! 445: ", MC6888%d FPU", fputype);
! 446: break;
! 447: default:
! 448: strlcat(cpu_model, ", unknown FPU", sizeof cpu_model);
! 449: break;
! 450: }
! 451: break;
! 452: #endif
! 453: }
! 454: printf("%s\n", cpu_model);
! 455: }
! 456:
! 457: /*
! 458: * machine dependent system variables.
! 459: */
! 460: int
! 461: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
! 462: int *name;
! 463: u_int namelen;
! 464: void *oldp;
! 465: size_t *oldlenp;
! 466: void *newp;
! 467: size_t newlen;
! 468: struct proc *p;
! 469: {
! 470: dev_t consdev;
! 471:
! 472: /* all sysctl names at this level are terminal */
! 473: if (namelen != 1)
! 474: return (ENOTDIR); /* overloaded */
! 475:
! 476: switch (name[0]) {
! 477: case CPU_CONSDEV:
! 478: if (cn_tab != NULL)
! 479: consdev = cn_tab->cn_dev;
! 480: else
! 481: consdev = NODEV;
! 482: return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
! 483: sizeof consdev));
! 484: default:
! 485: return (EOPNOTSUPP);
! 486: }
! 487: /* NOTREACHED */
! 488: }
! 489:
! 490: int waittime = -1;
! 491:
! 492: __dead void
! 493: boot(howto)
! 494: int howto;
! 495: {
! 496: /* If system is cold, just halt. */
! 497: if (cold) {
! 498: /* (Unless the user explicitly asked for reboot.) */
! 499: if ((howto & RB_USERREQ) == 0)
! 500: howto |= RB_HALT;
! 501: goto haltsys;
! 502: }
! 503:
! 504: /* take a snap shot before clobbering any registers */
! 505: if (curproc && curproc->p_addr)
! 506: savectx(&curproc->p_addr->u_pcb);
! 507:
! 508: boothowto = howto;
! 509: if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
! 510: extern struct proc proc0;
! 511: /* do that another panic fly away */
! 512: if (curproc == NULL)
! 513: curproc = &proc0;
! 514: waittime = 0;
! 515: vfs_shutdown();
! 516: /*
! 517: * If we've been adjusting the clock, the todr
! 518: * will be out of synch; adjust it now unless
! 519: * the system was sitting in ddb.
! 520: */
! 521: if ((howto & RB_TIMEBAD) == 0) {
! 522: resettodr();
! 523: } else {
! 524: printf("WARNING: not updating battery clock\n");
! 525: }
! 526: }
! 527:
! 528: /* Disable interrupts. */
! 529: splhigh();
! 530:
! 531: /* If rebooting and a dump is requested, do it. */
! 532: if (howto & RB_DUMP)
! 533: dumpsys();
! 534:
! 535: haltsys:
! 536: /* Run any shutdown hooks. */
! 537: doshutdownhooks();
! 538:
! 539: if (howto & RB_HALT) {
! 540: printf("System halted. Press any key to reboot...\n\n");
! 541: cngetc();
! 542: }
! 543:
! 544: doboot();
! 545:
! 546: for (;;);
! 547: /*NOTREACHED*/
! 548: }
! 549:
! 550: /*
! 551: * These variables are needed by /sbin/savecore
! 552: */
! 553: u_long dumpmag = 0x8fca0101; /* magic number */
! 554: int dumpsize = 0; /* pages */
! 555: long dumplo = 0; /* blocks */
! 556: cpu_kcore_hdr_t cpu_kcore_hdr;
! 557:
! 558: /*
! 559: * This is called by configure to set dumplo and dumpsize.
! 560: * Dumps always skip the first PAGE_SIZE of disk space
! 561: * in case there might be a disk label stored there.
! 562: * If there is extra space, put dump at the end to
! 563: * reduce the chance that swapping trashes it.
! 564: */
! 565: void
! 566: dumpconf(void)
! 567: {
! 568: int nblks; /* size of dump area */
! 569:
! 570: if (dumpdev == NODEV ||
! 571: (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
! 572: return;
! 573: if (nblks <= ctod(1))
! 574: return;
! 575:
! 576: dumpsize = physmem;
! 577:
! 578: /* mvme68k only uses a single segment. */
! 579: cpu_kcore_hdr.ram_segs[0].start = 0;
! 580: cpu_kcore_hdr.ram_segs[0].size = ctob(physmem);
! 581: cpu_kcore_hdr.mmutype = mmutype;
! 582: cpu_kcore_hdr.kernel_pa = 0;
! 583: cpu_kcore_hdr.sysseg_pa = pmap_kernel()->pm_stpa;
! 584:
! 585: /* Always skip the first block, in case there is a label there. */
! 586: if (dumplo < ctod(1))
! 587: dumplo = ctod(1);
! 588:
! 589: /* Put dump at end of partition, and make it fit. */
! 590: if (dumpsize + 1 > dtoc(nblks - dumplo))
! 591: dumpsize = dtoc(nblks - dumplo) - 1;
! 592: if (dumplo < nblks - ctod(dumpsize) - 1)
! 593: dumplo = nblks - ctod(dumpsize) - 1;
! 594: }
! 595:
! 596: /*
! 597: * Doadump comes here after turning off memory management and
! 598: * getting on the dump stack, either when called above, or by
! 599: * the auto-restart code.
! 600: */
! 601: void
! 602: dumpsys()
! 603: {
! 604: int maj;
! 605: int psize;
! 606: daddr64_t blkno; /* current block to write */
! 607: /* dump routine */
! 608: int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
! 609: int pg; /* page being dumped */
! 610: paddr_t maddr; /* PA being dumped */
! 611: int error; /* error code from (*dump)() */
! 612: kcore_seg_t *kseg_p;
! 613: cpu_kcore_hdr_t *chdr_p;
! 614: char dump_hdr[dbtob(1)]; /* XXX assume hdr fits in 1 block */
! 615:
! 616: extern int msgbufmapped;
! 617:
! 618: msgbufmapped = 0;
! 619:
! 620: /* Make sure dump device is valid. */
! 621: if (dumpdev == NODEV)
! 622: return;
! 623: if (dumpsize == 0) {
! 624: dumpconf();
! 625: if (dumpsize == 0)
! 626: return;
! 627: }
! 628: maj = major(dumpdev);
! 629: if (dumplo < 0) {
! 630: printf("\ndump to dev %u,%u not possible\n", maj,
! 631: minor(dumpdev));
! 632: return;
! 633: }
! 634: dump = bdevsw[maj].d_dump;
! 635: blkno = dumplo;
! 636:
! 637: printf("\ndumping to dev %u,%u offset %ld\n", maj,
! 638: minor(dumpdev), dumplo);
! 639:
! 640: kseg_p = (kcore_seg_t *)dump_hdr;
! 641: chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))];
! 642: bzero(dump_hdr, sizeof(dump_hdr));
! 643:
! 644: /*
! 645: * Generate a segment header
! 646: */
! 647: CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
! 648: kseg_p->c_size = dbtob(1) - ALIGN(sizeof(*kseg_p));
! 649:
! 650: /*
! 651: * Add the md header
! 652: */
! 653: *chdr_p = cpu_kcore_hdr;
! 654:
! 655: printf("dump ");
! 656: psize = (*bdevsw[maj].d_psize)(dumpdev);
! 657: if (psize == -1) {
! 658: printf("area unavailable\n");
! 659: return;
! 660: }
! 661:
! 662: /* Dump the header. */
! 663: error = (*dump) (dumpdev, blkno++, (caddr_t)dump_hdr, dbtob(1));
! 664: if (error != 0)
! 665: goto abort;
! 666:
! 667: maddr = (paddr_t)0;
! 668: for (pg = 0; pg < dumpsize; pg++) {
! 669: #define NPGMB (1024 * 1024 / PAGE_SIZE)
! 670: /* print out how many MBs we have dumped */
! 671: if (pg != 0 && (pg % NPGMB) == 0)
! 672: printf("%d ", pg / NPGMB);
! 673: #undef NPGMB
! 674: pmap_kenter_pa((vaddr_t)vmmap, maddr, VM_PROT_READ);
! 675: pmap_update(pmap_kernel());
! 676: error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
! 677: pmap_kremove((vaddr_t)vmmap, PAGE_SIZE);
! 678: pmap_update(pmap_kernel());
! 679:
! 680: if (error == 0) {
! 681: maddr += PAGE_SIZE;
! 682: blkno += btodb(PAGE_SIZE);
! 683: } else
! 684: break;
! 685: }
! 686: abort:
! 687: switch (error) {
! 688: case 0:
! 689: printf("succeeded\n");
! 690: break;
! 691:
! 692: case ENXIO:
! 693: printf("device bad\n");
! 694: break;
! 695:
! 696: case EFAULT:
! 697: printf("device not ready\n");
! 698: break;
! 699:
! 700: case EINVAL:
! 701: printf("area improper\n");
! 702: break;
! 703:
! 704: case EIO:
! 705: printf("i/o error\n");
! 706: break;
! 707:
! 708: case EINTR:
! 709: printf("aborted from console\n");
! 710: break;
! 711:
! 712: default:
! 713: printf("error %d\n", error);
! 714: break;
! 715: }
! 716: }
! 717:
! 718: #if defined(M68060)
! 719: int m68060_pcr_init = 0x20 | PCR_SUPERSCALAR; /* make this patchable */
! 720: #endif
! 721:
! 722: void
! 723: initvectors()
! 724: {
! 725: typedef void trapfun(void);
! 726: extern trapfun *vectab[256];
! 727: #if defined(M68060)
! 728: #if defined(M060SP)
! 729: extern trapfun intemu60, fpiemu60, fpdemu60, fpeaemu60;
! 730: extern u_int8_t FP_CALL_TOP[];
! 731: #else
! 732: extern trapfun illinst;
! 733: #endif
! 734: extern trapfun fpfault;
! 735: #endif
! 736: #if defined(M68040) && defined(FPSP)
! 737: extern u_long fpvect_tab, fpvect_end, fpsp_tab;
! 738: #endif
! 739:
! 740: switch (cputype) {
! 741: #ifdef M68060
! 742: case CPU_68060:
! 743: asm volatile ("movl %0,d0; .word 0x4e7b,0x0808" : :
! 744: "d"(m68060_pcr_init):"d0" );
! 745:
! 746: #if defined(M060SP)
! 747: /* integer support */
! 748: vectab[61] = intemu60/*(trapfun *)&I_CALL_TOP[128 + 0x00]*/;
! 749:
! 750: /* floating point support */
! 751: /*
! 752: * XXX maybe we really should run-time check for the
! 753: * stack frame format here:
! 754: */
! 755: vectab[11] = fpiemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x30]*/;
! 756:
! 757: vectab[55] = fpdemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x38]*/;
! 758: vectab[60] = fpeaemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x40]*/;
! 759:
! 760: vectab[54] = (trapfun *)&FP_CALL_TOP[128 + 0x00];
! 761: vectab[52] = (trapfun *)&FP_CALL_TOP[128 + 0x08];
! 762: vectab[53] = (trapfun *)&FP_CALL_TOP[128 + 0x10];
! 763: vectab[51] = (trapfun *)&FP_CALL_TOP[128 + 0x18];
! 764: vectab[50] = (trapfun *)&FP_CALL_TOP[128 + 0x20];
! 765: vectab[49] = (trapfun *)&FP_CALL_TOP[128 + 0x28];
! 766: #else
! 767: vectab[61] = illinst;
! 768: #endif
! 769: vectab[48] = fpfault;
! 770: break;
! 771: #endif
! 772: #if defined(M68040) && defined(FPSP)
! 773: case CPU_68040:
! 774: bcopy(&fpsp_tab, &fpvect_tab,
! 775: (&fpvect_end - &fpvect_tab) * sizeof (fpvect_tab));
! 776: break;
! 777: #endif
! 778: default:
! 779: break;
! 780: }
! 781: }
! 782:
! 783: void
! 784: straytrap(pc, evec)
! 785: int pc;
! 786: u_short evec;
! 787: {
! 788: printf("unexpected trap (vector 0x%x) from %x\n",
! 789: (evec & 0xFFF) >> 2, pc);
! 790: }
! 791:
! 792: int *nofault;
! 793:
! 794: int
! 795: badpaddr(addr, size)
! 796: paddr_t addr;
! 797: int size;
! 798: {
! 799: int off = (int)addr & PGOFSET;
! 800: vaddr_t v;
! 801: paddr_t p = trunc_page(addr);
! 802: int x;
! 803:
! 804: v = mapiodev(p, NBPG);
! 805: if (v == 0)
! 806: return (1);
! 807: x = badvaddr(v + off, size);
! 808: unmapiodev(v, NBPG);
! 809: return (x);
! 810: }
! 811:
! 812: int
! 813: badvaddr(addr, size)
! 814: vaddr_t addr;
! 815: int size;
! 816: {
! 817: int i;
! 818: label_t faultbuf;
! 819:
! 820: nofault = (int *) &faultbuf;
! 821: if (setjmp((label_t *)nofault)) {
! 822: nofault = (int *)0;
! 823: return (1);
! 824: }
! 825: switch (size) {
! 826: case 1:
! 827: i = *(volatile char *)addr;
! 828: break;
! 829: case 2:
! 830: i = *(volatile short *)addr;
! 831: break;
! 832: case 4:
! 833: i = *(volatile long *)addr;
! 834: break;
! 835: }
! 836: nofault = (int *)0;
! 837: return (0);
! 838: }
! 839:
! 840: int netisr;
! 841:
! 842: void
! 843: netintr(arg)
! 844: void *arg;
! 845: {
! 846: int n;
! 847:
! 848: while ((n = netisr) != 0) {
! 849: atomic_clearbits_int(&netisr, n);
! 850:
! 851: #define DONETISR(bit, fn) \
! 852: do { \
! 853: if (n & (1 << (bit))) \
! 854: (fn)(); \
! 855: } while (0)
! 856:
! 857: #include <net/netisr_dispatch.h>
! 858:
! 859: #undef DONETISR
! 860: }
! 861: }
! 862:
! 863: /*
! 864: * Level 7 interrupts are normally caused by the ABORT switch,
! 865: * drop into ddb.
! 866: */
! 867: void
! 868: nmihand(frame)
! 869: void *frame;
! 870: {
! 871: #ifdef DDB
! 872: printf("NMI ... going to debugger\n");
! 873: Debugger();
! 874: #else
! 875: /* panic?? */
! 876: printf("unexpected level 7 interrupt ignored\n");
! 877: #endif
! 878: }
! 879:
! 880: /*
! 881: * cpu_exec_aout_makecmds():
! 882: * cpu-dependent a.out format hook for execve().
! 883: *
! 884: * Determine of the given exec package refers to something which we
! 885: * understand and, if so, set up the vmcmds for it.
! 886: */
! 887: int
! 888: cpu_exec_aout_makecmds(p, epp)
! 889: struct proc *p;
! 890: struct exec_package *epp;
! 891: {
! 892: int error = ENOEXEC;
! 893:
! 894: #ifdef COMPAT_SUNOS
! 895: {
! 896: extern int sunos_exec_aout_makecmds(struct proc *, struct exec_package *);
! 897: if ((error = sunos_exec_aout_makecmds(p, epp)) == 0)
! 898: return (0);
! 899: }
! 900: #endif
! 901: return (error);
! 902: }
! 903:
! 904: u_char myea[6] = { 0x08, 0x00, 0x3e, 0xff, 0xff, 0xff};
! 905:
! 906: void
! 907: myetheraddr(ether)
! 908: u_char *ether;
! 909: {
! 910: bcopy(myea, ether, sizeof myea);
! 911: }
! 912:
! 913: #if defined(M68030) || defined(M68020)
! 914: int
! 915: fpu_gettype()
! 916: {
! 917: /*
! 918: * A 68881 idle frame is 28 bytes and a 68882's is 60 bytes.
! 919: * We, of course, need to have enough room for either.
! 920: */
! 921: int fpframe[60 / sizeof(int)];
! 922: label_t faultbuf;
! 923: u_char b;
! 924:
! 925: nofault = (int *) &faultbuf;
! 926: if (setjmp((label_t *)nofault)) {
! 927: nofault = (int *)0;
! 928: return (0); /* no FPU */
! 929: }
! 930:
! 931: /*
! 932: * Synchronize FPU or cause a fault.
! 933: * This should leave the 881/882 in the IDLE state,
! 934: * state, so we can determine which we have by
! 935: * examining the size of the FP state frame
! 936: */
! 937: asm("fnop");
! 938:
! 939: nofault = (int *)0;
! 940:
! 941: /*
! 942: * Presumably, this will not cause a fault--the fnop should
! 943: * have if this will. We save the state in order to get the
! 944: * size of the frame.
! 945: */
! 946: asm("movl %0, a0; fsave a0@" : : "a" (fpframe) : "a0" );
! 947: b = *((u_char *) fpframe + 1);
! 948:
! 949: /*
! 950: * Now, restore a NULL state to reset the FPU.
! 951: */
! 952: fpframe[0] = fpframe[1] = 0;
! 953: m68881_restore((struct fpframe *)fpframe);
! 954:
! 955: if (b == 0x18)
! 956: return (FPU_68881); /* The size of a 68881 IDLE frame is 0x18 */
! 957: if (b == 0x38)
! 958: return (FPU_68882); /* 68882 frame is 0x38 bytes long */
! 959: return (FPU_UNKNOWN); /* unknown FPU type */
! 960: }
! 961: #endif
! 962:
! 963:
! 964: #if defined(MVME162) || defined(MVME172)
! 965: #include <mvme68k/dev/mcreg.h>
! 966: /*
! 967: * XXX
! 968: * used by locore.s to figure out how much memory is on the machine.
! 969: * At this stage we only know that our machine is a 162. It is very
! 970: * unfortunate that the MCchip's address must be encoded here.
! 971: */
! 972: int
! 973: memsize162()
! 974: {
! 975: struct mcreg *mc = (struct mcreg *)0xfff42000;
! 976:
! 977: switch (mc->mc_memoptions & MC_MEMOPTIONS_DRAMMASK) {
! 978: case MC_MEMOPTIONS_DRAM1M:
! 979: return (1*1024*1024);
! 980: case MC_MEMOPTIONS_DRAM2M:
! 981: return (2*1024*1024);
! 982: case MC_MEMOPTIONS_DRAM4M:
! 983: return (4*1024*1024);
! 984: case MC_MEMOPTIONS_DRAM4M2:
! 985: return (4*1024*1024);
! 986: case MC_MEMOPTIONS_DRAM8M:
! 987: return (8*1024*1024);
! 988: case MC_MEMOPTIONS_DRAM16M:
! 989: return (16*1024*1024);
! 990: default:
! 991: /*
! 992: * XXX if the machine has no MC-controlled memory,
! 993: * perhaps it has a MCECC or MEMC040 controller?
! 994: */
! 995: return (memsize1x7());
! 996: }
! 997: }
! 998: #endif
CVSweb