[BACK]Return to machdep.c CVS log [TXT][DIR] Up to [local] / sys / arch / mvme68k / mvme68k

Annotation of sys/arch/mvme68k/mvme68k/machdep.c, Revision 1.1.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