[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     ! 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