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

Annotation of sys/arch/mvme88k/mvme88k/machdep.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: machdep.c,v 1.192 2007/06/06 17:15:12 deraadt Exp $       */
        !             2: /*
        !             3:  * Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
        !             4:  * Copyright (c) 1996 Nivas Madhur
        !             5:  * All rights reserved.
        !             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:  * 3. All advertising materials mentioning features or use of this software
        !            16:  *    must display the following acknowledgement:
        !            17:  *      This product includes software developed by Nivas Madhur.
        !            18:  * 4. The name of the author may not be used to endorse or promote products
        !            19:  *    derived from this software without specific prior written permission
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            31:  *
        !            32:  */
        !            33: /*
        !            34:  * Mach Operating System
        !            35:  * Copyright (c) 1993-1991 Carnegie Mellon University
        !            36:  * Copyright (c) 1991 OMRON Corporation
        !            37:  * All Rights Reserved.
        !            38:  *
        !            39:  * Permission to use, copy, modify and distribute this software and its
        !            40:  * documentation is hereby granted, provided that both the copyright
        !            41:  * notice and this permission notice appear in all copies of the
        !            42:  * software, derivative works or modified versions, and any portions
        !            43:  * thereof, and that both notices appear in supporting documentation.
        !            44:  *
        !            45:  */
        !            46:
        !            47: #include <sys/param.h>
        !            48: #include <sys/systm.h>
        !            49: #include <sys/kernel.h>
        !            50: #include <sys/proc.h>
        !            51: #include <sys/user.h>
        !            52: #include <sys/buf.h>
        !            53: #include <sys/reboot.h>
        !            54: #include <sys/conf.h>
        !            55: #include <sys/malloc.h>
        !            56: #include <sys/mount.h>
        !            57: #include <sys/msgbuf.h>
        !            58: #include <sys/syscallargs.h>
        !            59: #ifdef SYSVMSG
        !            60: #include <sys/msg.h>
        !            61: #endif
        !            62: #include <sys/exec.h>
        !            63: #include <sys/sysctl.h>
        !            64: #include <sys/errno.h>
        !            65: #include <sys/extent.h>
        !            66: #include <sys/core.h>
        !            67: #include <sys/kcore.h>
        !            68:
        !            69: #include <machine/asm.h>
        !            70: #include <machine/asm_macro.h>
        !            71: #include <machine/bug.h>
        !            72: #include <machine/bugio.h>
        !            73: #include <machine/cmmu.h>
        !            74: #include <machine/cpu.h>
        !            75: #include <machine/kcore.h>
        !            76: #include <machine/reg.h>
        !            77: #ifdef M88100
        !            78: #include <machine/m88100.h>
        !            79: #endif
        !            80:
        !            81: #include <dev/cons.h>
        !            82:
        !            83: #include <uvm/uvm_extern.h>
        !            84:
        !            85: #include "ksyms.h"
        !            86: #if DDB
        !            87: #include <machine/db_machdep.h>
        !            88: #include <ddb/db_extern.h>
        !            89: #include <ddb/db_interface.h>
        !            90: #include <ddb/db_var.h>
        !            91: #endif /* DDB */
        !            92:
        !            93: caddr_t        allocsys(caddr_t);
        !            94: void   consinit(void);
        !            95: void   dumpconf(void);
        !            96: void   dumpsys(void);
        !            97: int    getcpuspeed(struct mvmeprom_brdid *);
        !            98: u_int  getipl(void);
        !            99: void   identifycpu(void);
        !           100: void   mvme_bootstrap(void);
        !           101: void   mvme88k_vector_init(u_int32_t *, u_int32_t *);
        !           102: void   myetheraddr(u_char *);
        !           103: void   savectx(struct pcb *);
        !           104: void   secondary_main(void);
        !           105: void   secondary_pre_main(void);
        !           106: void   _doboot(void);
        !           107:
        !           108: extern void setlevel(unsigned int);
        !           109:
        !           110: extern void    m187_bootstrap(void);
        !           111: extern vaddr_t m187_memsize(void);
        !           112: extern void    m187_startup(void);
        !           113: extern void    m188_bootstrap(void);
        !           114: extern vaddr_t m188_memsize(void);
        !           115: extern void    m188_startup(void);
        !           116: extern void    m197_bootstrap(void);
        !           117: extern vaddr_t m197_memsize(void);
        !           118: extern void    m197_startup(void);
        !           119:
        !           120: intrhand_t intr_handlers[NVMEINTR];
        !           121:
        !           122: /* board dependent pointers */
        !           123: void (*md_interrupt_func_ptr)(u_int, struct trapframe *);
        !           124: void (*md_init_clocks)(void);
        !           125: u_int (*md_getipl)(void);
        !           126: u_int (*md_setipl)(u_int);
        !           127: u_int (*md_raiseipl)(u_int);
        !           128: #ifdef MULTIPROCESSOR
        !           129: void (*md_send_ipi)(int, cpuid_t);
        !           130: #endif
        !           131:
        !           132: int physmem;     /* available physical memory, in pages */
        !           133:
        !           134: struct vm_map *exec_map = NULL;
        !           135: struct vm_map *phys_map = NULL;
        !           136:
        !           137: #ifdef MULTIPROCESSOR
        !           138: __cpu_simple_lock_t cpu_mutex = __SIMPLELOCK_UNLOCKED;
        !           139: #endif
        !           140:
        !           141: /*
        !           142:  * Declare these as initialized data so we can patch them.
        !           143:  */
        !           144: #ifndef BUFCACHEPERCENT
        !           145: #define BUFCACHEPERCENT 5
        !           146: #endif
        !           147:
        !           148: #ifdef BUFPAGES
        !           149: int bufpages = BUFPAGES;
        !           150: #else
        !           151: int bufpages = 0;
        !           152: #endif
        !           153: int bufcachepercent = BUFCACHEPERCENT;
        !           154:
        !           155: /*
        !           156:  * Info for CTL_HW
        !           157:  */
        !           158: char  machine[] = MACHINE;      /* cpu "architecture" */
        !           159: char  cpu_model[120];
        !           160:
        !           161: #if defined(DDB) || NKSYMS > 0
        !           162: extern char *esym;
        !           163: #endif
        !           164:
        !           165: int boothowto;                                 /* set in locore.S */
        !           166: int bootdev;                                   /* set in locore.S */
        !           167: int cputyp;                                    /* set in locore.S */
        !           168: int brdtyp;                                    /* set in locore.S */
        !           169: int cpumod;                                    /* set in mvme_bootstrap() */
        !           170: int cpuspeed = 25;                             /* safe guess */
        !           171:
        !           172: vaddr_t first_addr;
        !           173: vaddr_t last_addr;
        !           174:
        !           175: vaddr_t avail_start, avail_end;
        !           176: vaddr_t virtual_avail, virtual_end;
        !           177:
        !           178: extern struct user *proc0paddr;
        !           179:
        !           180: /*
        !           181:  * This is to fake out the console routines, while booting.
        !           182:  */
        !           183: cons_decl(boot);
        !           184: #define bootcnpollc nullcnpollc
        !           185:
        !           186: struct consdev bootcons = {
        !           187:        NULL,
        !           188:        NULL,
        !           189:        bootcngetc,
        !           190:        bootcnputc,
        !           191:        bootcnpollc,
        !           192:        NULL,
        !           193:        makedev(14, 0),
        !           194:        CN_NORMAL,
        !           195: };
        !           196:
        !           197: /*
        !           198:  * Early console initialization: called early on from main, before vm init.
        !           199:  * We want to stick to the BUG routines for now, and we'll switch to the
        !           200:  * real console in cpu_startup().
        !           201:  */
        !           202: void
        !           203: consinit()
        !           204: {
        !           205:        cn_tab = &bootcons;
        !           206:
        !           207: #if defined(DDB)
        !           208:        db_machine_init();
        !           209:        ddb_init();
        !           210:        if (boothowto & RB_KDB)
        !           211:                Debugger();
        !           212: #endif
        !           213: }
        !           214:
        !           215: int
        !           216: getcpuspeed(struct mvmeprom_brdid *brdid)
        !           217: {
        !           218:        int speed = 0;
        !           219:        u_int i, c;
        !           220:
        !           221:        for (i = 0; i < 4; i++) {
        !           222:                c = (u_int)brdid->speed[i];
        !           223:                if (c == ' ')
        !           224:                        c = '0';
        !           225:                else if (c > '9' || c < '0') {
        !           226:                        speed = 0;
        !           227:                        break;
        !           228:                }
        !           229:                speed = speed * 10 + (c - '0');
        !           230:        }
        !           231:        speed = speed / 100;
        !           232:
        !           233:        switch (brdtyp) {
        !           234: #ifdef MVME187
        !           235:        case BRD_187:
        !           236:        case BRD_8120:
        !           237:                if (speed == 25 || speed == 33)
        !           238:                        return speed;
        !           239:                speed = 25;
        !           240:                break;
        !           241: #endif
        !           242: #ifdef MVME188
        !           243:        case BRD_188:
        !           244:                /*
        !           245:                 * If BUG version prior to 5.x, there is no CNFG block and
        !           246:                 * speed can be found in the environment.
        !           247:                 * XXX We don't process ENV data yet - assume 20MHz in this
        !           248:                 * case.
        !           249:                 */
        !           250:                if ((u_int)brdid->rev < 0x50) {
        !           251:                        speed = 20;
        !           252:                } else {
        !           253:                        if (speed == 20 || speed == 25)
        !           254:                                return speed;
        !           255:                        speed = 25;
        !           256:                }
        !           257:                break;
        !           258: #endif
        !           259: #ifdef MVME197
        !           260:        case BRD_197:
        !           261:                if (speed == 40 || speed == 50)
        !           262:                        return speed;
        !           263:                speed = 50;
        !           264:                break;
        !           265: #endif
        !           266:        }
        !           267:
        !           268:        /*
        !           269:         * If we end up here, the board information block is damaged and
        !           270:         * we can't trust it.
        !           271:         * Suppose we are running at the most common speed for our board,
        !           272:         * and hope for the best (this really only affects osiop).
        !           273:         */
        !           274:        printf("WARNING: Board Configuration Data invalid, "
        !           275:            "replace NVRAM and restore values\n");
        !           276:        return speed;
        !           277: }
        !           278:
        !           279: void
        !           280: identifycpu()
        !           281: {
        !           282:        struct mvmeprom_brdid brdid;
        !           283:        char suffix[4];
        !           284:        u_int i;
        !           285:
        !           286:        bzero(&brdid, sizeof(brdid));
        !           287:        bugbrdid(&brdid);
        !           288:
        !           289:        cpuspeed = getcpuspeed(&brdid);
        !           290:
        !           291:        i = 0;
        !           292:        if (brdid.suffix[0] >= ' ' && brdid.suffix[0] < 0x7f) {
        !           293:                if (brdid.suffix[0] != '-')
        !           294:                        suffix[i++] = '-';
        !           295:                suffix[i++] = brdid.suffix[0];
        !           296:        }
        !           297:        if (brdid.suffix[1] >= ' ' && brdid.suffix[1] < 0x7f)
        !           298:                suffix[i++] = brdid.suffix[1];
        !           299:        suffix[i++] = '\0';
        !           300:
        !           301:        snprintf(cpu_model, sizeof cpu_model,
        !           302:            "Motorola MVME%x%s, %dMHz", brdtyp, suffix, cpuspeed);
        !           303: }
        !           304:
        !           305: /*
        !           306:  * Set up real-time clocks.
        !           307:  * These function pointers are set in dev/clock.c.
        !           308:  */
        !           309: void
        !           310: cpu_initclocks()
        !           311: {
        !           312:        (*md_init_clocks)();
        !           313: }
        !           314:
        !           315: void
        !           316: setstatclockrate(int newhz)
        !           317: {
        !           318:        /* function stub */
        !           319: }
        !           320:
        !           321:
        !           322: void
        !           323: cpu_startup()
        !           324: {
        !           325:        caddr_t v;
        !           326:        int sz, i;
        !           327:        vaddr_t minaddr, maxaddr;
        !           328:
        !           329:        /*
        !           330:         * Initialize error message buffer (at end of core).
        !           331:         * avail_end was pre-decremented in mvme_bootstrap() to compensate.
        !           332:         */
        !           333:        for (i = 0; i < btoc(MSGBUFSIZE); i++)
        !           334:                pmap_kenter_pa((paddr_t)msgbufp + i * PAGE_SIZE,
        !           335:                    avail_end + i * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE);
        !           336:        pmap_update(pmap_kernel());
        !           337:        initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE));
        !           338:
        !           339:        /*
        !           340:         * Good {morning,afternoon,evening,night}.
        !           341:         */
        !           342:        printf(version);
        !           343:        identifycpu();
        !           344:        printf("real mem = %u (%uMB)\n", ctob(physmem),
        !           345:            ctob(physmem)/1024/1024);
        !           346:
        !           347:        /*
        !           348:         * Find out how much space we need, allocate it,
        !           349:         * and then give everything true virtual addresses.
        !           350:         */
        !           351:        sz = (int)allocsys((caddr_t)0);
        !           352:
        !           353:        if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0)
        !           354:                panic("startup: no room for tables");
        !           355:        if (allocsys(v) - v != sz)
        !           356:                panic("startup: table size inconsistency");
        !           357:
        !           358:        /*
        !           359:         * Grab machine dependent memory spaces
        !           360:         */
        !           361:        switch (brdtyp) {
        !           362: #ifdef MVME187
        !           363:        case BRD_187:
        !           364:        case BRD_8120:
        !           365:                m187_startup();
        !           366:                break;
        !           367: #endif
        !           368: #ifdef MVME188
        !           369:        case BRD_188:
        !           370:                m188_startup();
        !           371:                break;
        !           372: #endif
        !           373: #ifdef MVME197
        !           374:        case BRD_197:
        !           375:                m197_startup();
        !           376:                break;
        !           377: #endif
        !           378:        }
        !           379:
        !           380:        /*
        !           381:         * Determine how many buffers to allocate.
        !           382:         * We allocate bufcachepercent% of memory for buffer space.
        !           383:         */
        !           384:        if (bufpages == 0)
        !           385:                bufpages = physmem * bufcachepercent / 100;
        !           386:
        !           387:        /* Restrict to at most 25% filled kvm */
        !           388:        if (bufpages >
        !           389:            (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
        !           390:                bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
        !           391:                    PAGE_SIZE / 4;
        !           392:
        !           393:        /*
        !           394:         * Allocate a submap for exec arguments.  This map effectively
        !           395:         * limits the number of processes exec'ing at any time.
        !           396:         */
        !           397:        minaddr = vm_map_min(kernel_map);
        !           398:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           399:            16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
        !           400:
        !           401:        /*
        !           402:         * Allocate map for physio.
        !           403:         */
        !           404:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           405:            VM_PHYS_SIZE, 0, FALSE, NULL);
        !           406:
        !           407:        printf("avail mem = %lu (%luMB)\n", ptoa(uvmexp.free),
        !           408:            ptoa(uvmexp.free)/1024/1024);
        !           409:
        !           410:        /*
        !           411:         * Set up buffers, so they can be used to read disk labels.
        !           412:         */
        !           413:        bufinit();
        !           414:
        !           415:        /*
        !           416:         * Set up interrupt handlers.
        !           417:         */
        !           418:        for (i = 0; i < NVMEINTR; i++)
        !           419:                SLIST_INIT(&intr_handlers[i]);
        !           420:
        !           421:        /*
        !           422:         * Configure the system.
        !           423:         */
        !           424:        if (boothowto & RB_CONFIG) {
        !           425: #ifdef BOOT_CONFIG
        !           426:                user_config();
        !           427: #else
        !           428:                printf("kernel does not support -c; continuing..\n");
        !           429: #endif
        !           430:        }
        !           431: }
        !           432:
        !           433: /*
        !           434:  * Allocate space for system data structures.  We are given
        !           435:  * a starting virtual address and we return a final virtual
        !           436:  * address; along the way we set each data structure pointer.
        !           437:  *
        !           438:  * We call allocsys() with 0 to find out how much space we want,
        !           439:  * allocate that much and fill it with zeroes, and then call
        !           440:  * allocsys() again with the correct base virtual address.
        !           441:  */
        !           442: caddr_t
        !           443: allocsys(v)
        !           444:        caddr_t v;
        !           445: {
        !           446:
        !           447: #define        valloc(name, type, num) \
        !           448:            v = (caddr_t)(((name) = (type *)v) + (num))
        !           449:
        !           450: #ifdef SYSVMSG
        !           451:        valloc(msgpool, char, msginfo.msgmax);
        !           452:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
        !           453:        valloc(msghdrs, struct msg, msginfo.msgtql);
        !           454:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
        !           455: #endif
        !           456:
        !           457:        return v;
        !           458: }
        !           459:
        !           460: __dead void
        !           461: _doboot()
        !           462: {
        !           463:        cmmu_shutdown();
        !           464:        bugreturn();
        !           465:        /*NOTREACHED*/
        !           466:        for (;;);               /* appease gcc */
        !           467: }
        !           468:
        !           469: __dead void
        !           470: boot(howto)
        !           471:        int howto;
        !           472: {
        !           473:        /* take a snapshot before clobbering any registers */
        !           474:        if (curproc && curproc->p_addr)
        !           475:                savectx(curpcb);
        !           476:
        !           477:        /* If system is cold, just halt. */
        !           478:        if (cold) {
        !           479:                /* (Unless the user explicitly asked for reboot.) */
        !           480:                if ((howto & RB_USERREQ) == 0)
        !           481:                        howto |= RB_HALT;
        !           482:                goto haltsys;
        !           483:        }
        !           484:
        !           485:        boothowto = howto;
        !           486:        if ((howto & RB_NOSYNC) == 0) {
        !           487:                vfs_shutdown();
        !           488:                /*
        !           489:                 * If we've been adjusting the clock, the todr
        !           490:                 * will be out of synch; adjust it now unless
        !           491:                 * the system was sitting in ddb.
        !           492:                 */
        !           493:                if ((howto & RB_TIMEBAD) == 0)
        !           494:                        resettodr();
        !           495:                else
        !           496:                        printf("WARNING: not updating battery clock\n");
        !           497:        }
        !           498:
        !           499:        /* Disable interrupts. */
        !           500:        splhigh();
        !           501:
        !           502:        /* If rebooting and a dump is requested, do it. */
        !           503:        if (howto & RB_DUMP)
        !           504:                dumpsys();
        !           505:
        !           506: haltsys:
        !           507:        /* Run any shutdown hooks. */
        !           508:        doshutdownhooks();
        !           509:
        !           510:        if (howto & RB_HALT) {
        !           511:                printf("System halted. Press any key to reboot...\n\n");
        !           512:                cngetc();
        !           513:        }
        !           514:
        !           515:        doboot();
        !           516:
        !           517:        for (;;);
        !           518:        /*NOTREACHED*/
        !           519: }
        !           520:
        !           521: unsigned dumpmag = 0x8fca0101;  /* magic number for savecore */
        !           522: int   dumpsize = 0;    /* also for savecore */
        !           523: long  dumplo = 0;
        !           524: cpu_kcore_hdr_t cpu_kcore_hdr;
        !           525:
        !           526: /*
        !           527:  * This is called by configure to set dumplo and dumpsize.
        !           528:  * Dumps always skip the first PAGE_SIZE of disk space
        !           529:  * in case there might be a disk label stored there.
        !           530:  * If there is extra space, put dump at the end to
        !           531:  * reduce the chance that swapping trashes it.
        !           532:  */
        !           533: void
        !           534: dumpconf(void)
        !           535: {
        !           536:        int nblks;      /* size of dump area */
        !           537:
        !           538:        if (dumpdev == NODEV ||
        !           539:            (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
        !           540:                return;
        !           541:        if (nblks <= ctod(1))
        !           542:                return;
        !           543:
        !           544:        dumpsize = physmem;
        !           545:
        !           546:        /* mvme88k only uses a single segment. */
        !           547:        cpu_kcore_hdr.ram_segs[0].start = 0;
        !           548:        cpu_kcore_hdr.ram_segs[0].size = ctob(physmem);
        !           549:        cpu_kcore_hdr.cputype = cputyp;
        !           550:
        !           551:        /*
        !           552:         * Don't dump on the first block
        !           553:         * in case the dump device includes a disk label.
        !           554:         */
        !           555:        if (dumplo < ctod(1))
        !           556:                dumplo = ctod(1);
        !           557:
        !           558:        /* Put dump at end of partition, and make it fit. */
        !           559:        if (dumpsize + 1 > dtoc(nblks - dumplo))
        !           560:                dumpsize = dtoc(nblks - dumplo) - 1;
        !           561:        if (dumplo < nblks - ctod(dumpsize) - 1)
        !           562:                dumplo = nblks - ctod(dumpsize) - 1;
        !           563: }
        !           564:
        !           565: /*
        !           566:  * Doadump comes here after turning off memory management and
        !           567:  * getting on the dump stack, either when called above, or by
        !           568:  * the auto-restart code.
        !           569:  */
        !           570: void
        !           571: dumpsys()
        !           572: {
        !           573:        int maj;
        !           574:        int psize;
        !           575:        daddr64_t blkno;        /* current block to write */
        !           576:                                /* dump routine */
        !           577:        int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
        !           578:        int pg;                 /* page being dumped */
        !           579:        paddr_t maddr;          /* PA being dumped */
        !           580:        int error;              /* error code from (*dump)() */
        !           581:        kcore_seg_t *kseg_p;
        !           582:        cpu_kcore_hdr_t *chdr_p;
        !           583:        char dump_hdr[dbtob(1)];        /* XXX assume hdr fits in 1 block */
        !           584:
        !           585:        extern int msgbufmapped;
        !           586:
        !           587:        msgbufmapped = 0;
        !           588:
        !           589:        /* Make sure dump device is valid. */
        !           590:        if (dumpdev == NODEV)
        !           591:                return;
        !           592:        if (dumpsize == 0) {
        !           593:                dumpconf();
        !           594:                if (dumpsize == 0)
        !           595:                        return;
        !           596:        }
        !           597:        maj = major(dumpdev);
        !           598:        if (dumplo < 0) {
        !           599:                printf("\ndump to dev %u,%u not possible\n", maj,
        !           600:                    minor(dumpdev));
        !           601:                return;
        !           602:        }
        !           603:        dump = bdevsw[maj].d_dump;
        !           604:        blkno = dumplo;
        !           605:
        !           606:        printf("\ndumping to dev %u,%u offset %ld\n", maj,
        !           607:            minor(dumpdev), dumplo);
        !           608:
        !           609:        /* Setup the dump header */
        !           610:        kseg_p = (kcore_seg_t *)dump_hdr;
        !           611:        chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))];
        !           612:        bzero(dump_hdr, sizeof(dump_hdr));
        !           613:
        !           614:        CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
        !           615:        kseg_p->c_size = dbtob(1) - ALIGN(sizeof(*kseg_p));
        !           616:        *chdr_p = cpu_kcore_hdr;
        !           617:
        !           618:        printf("dump ");
        !           619:        psize = (*bdevsw[maj].d_psize)(dumpdev);
        !           620:        if (psize == -1) {
        !           621:                printf("area unavailable\n");
        !           622:                return;
        !           623:        }
        !           624:
        !           625:        /* Dump the header. */
        !           626:        error = (*dump)(dumpdev, blkno++, (caddr_t)dump_hdr, dbtob(1));
        !           627:        if (error != 0)
        !           628:                goto abort;
        !           629:
        !           630:        maddr = (paddr_t)0;
        !           631:        for (pg = 0; pg < dumpsize; pg++) {
        !           632: #define NPGMB  (1024 * 1024 / PAGE_SIZE)
        !           633:                /* print out how many MBs we have dumped */
        !           634:                if (pg != 0 && (pg % NPGMB) == 0)
        !           635:                        printf("%d ", pg / NPGMB);
        !           636: #undef NPGMB
        !           637:                pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
        !           638:                    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
        !           639:
        !           640:                error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
        !           641:                if (error == 0) {
        !           642:                        maddr += PAGE_SIZE;
        !           643:                        blkno += btodb(PAGE_SIZE);
        !           644:                } else
        !           645:                        break;
        !           646:        }
        !           647: abort:
        !           648:        switch (error) {
        !           649:        case 0:
        !           650:                printf("succeeded\n");
        !           651:                break;
        !           652:
        !           653:        case ENXIO:
        !           654:                printf("device bad\n");
        !           655:                break;
        !           656:
        !           657:        case EFAULT:
        !           658:                printf("device not ready\n");
        !           659:                break;
        !           660:
        !           661:        case EINVAL:
        !           662:                printf("area improper\n");
        !           663:                break;
        !           664:
        !           665:        case EIO:
        !           666:                printf("i/o error\n");
        !           667:                break;
        !           668:
        !           669:        case EINTR:
        !           670:                printf("aborted from console\n");
        !           671:                break;
        !           672:
        !           673:        default:
        !           674:                printf("error %d\n", error);
        !           675:                break;
        !           676:        }
        !           677: }
        !           678:
        !           679: #ifdef MULTIPROCESSOR
        !           680:
        !           681: /*
        !           682:  * Secondary CPU early initialization routine.
        !           683:  * Determine CPU number and set it, then allocate the idle pcb (and stack).
        !           684:  *
        !           685:  * Running on a minimal stack here, with interrupts disabled; do nothing fancy.
        !           686:  */
        !           687: void
        !           688: secondary_pre_main()
        !           689: {
        !           690:        struct cpu_info *ci;
        !           691:
        !           692:        set_cpu_number(cmmu_cpu_number()); /* Determine cpu number by CMMU */
        !           693:        ci = curcpu();
        !           694:        ci->ci_curproc = &proc0;
        !           695:
        !           696:        splhigh();
        !           697:
        !           698:        /*
        !           699:         * Setup CMMUs and translation tables (shared with the master cpu).
        !           700:         */
        !           701:        pmap_bootstrap_cpu(ci->ci_cpuid);
        !           702:
        !           703:        /*
        !           704:         * Allocate UPAGES contiguous pages for the idle PCB and stack.
        !           705:         */
        !           706:        ci->ci_idle_pcb = (struct pcb *)uvm_km_zalloc(kernel_map, USPACE);
        !           707:        if (ci->ci_idle_pcb == NULL) {
        !           708:                printf("cpu%d: unable to allocate idle stack\n", ci->ci_cpuid);
        !           709:        }
        !           710: }
        !           711:
        !           712: /*
        !           713:  * Further secondary CPU initialization.
        !           714:  *
        !           715:  * We are now running on our idle stack, with proper page tables.
        !           716:  * There is nothing to do but display some details about the CPU and its CMMUs.
        !           717:  */
        !           718: void
        !           719: secondary_main()
        !           720: {
        !           721:        struct cpu_info *ci = curcpu();
        !           722:
        !           723:        cpu_configuration_print(0);
        !           724:        ncpus++;
        !           725:        __cpu_simple_unlock(&cpu_mutex);
        !           726:
        !           727:        microuptime(&ci->ci_schedstate.spc_runtime);
        !           728:        ci->ci_curproc = NULL;
        !           729:
        !           730:        /*
        !           731:         * Upon return, the secondary cpu bootstrap code in locore will
        !           732:         * enter the idle loop, waiting for some food to process on this
        !           733:         * processor.
        !           734:         */
        !           735: }
        !           736:
        !           737: #endif /* MULTIPROCESSOR */
        !           738:
        !           739: /*
        !           740:  * Search for the first available interrupt vector in the range start, end.
        !           741:  * This should really only be used by VME devices.
        !           742:  */
        !           743: int
        !           744: intr_findvec(int start, int end, int skip)
        !           745: {
        !           746:        int vec;
        !           747:
        !           748: #ifdef DEBUG
        !           749:        if (start < 0 || end >= NVMEINTR || start > end)
        !           750:                panic("intr_findvec(%d,%d): bad parameters", start, end);
        !           751: #endif
        !           752:
        !           753:        for (vec = start; vec <= end; vec++) {
        !           754:                if (vec == skip)
        !           755:                        continue;
        !           756:                if (SLIST_EMPTY(&intr_handlers[vec]))
        !           757:                        return vec;
        !           758:        }
        !           759: #ifdef DIAGNOSTIC
        !           760:        printf("intr_findvec(%d,%d,%d): no vector available\n",
        !           761:            start, end, skip);
        !           762: #endif
        !           763:        return -1;
        !           764: }
        !           765:
        !           766: /*
        !           767:  * Try to insert ihand in the list of handlers for vector vec.
        !           768:  */
        !           769: int
        !           770: intr_establish(int vec, struct intrhand *ihand, const char *name)
        !           771: {
        !           772:        struct intrhand *intr;
        !           773:        intrhand_t *list;
        !           774:
        !           775:        if (vec < 0 || vec >= NVMEINTR) {
        !           776: #ifdef DIAGNOSTIC
        !           777:                panic("intr_establish: vec (0x%x) not between 0x00 and 0xff",
        !           778:                      vec);
        !           779: #endif /* DIAGNOSTIC */
        !           780:                return (EINVAL);
        !           781:        }
        !           782:
        !           783:        list = &intr_handlers[vec];
        !           784:        if (!SLIST_EMPTY(list)) {
        !           785:                intr = SLIST_FIRST(list);
        !           786:                if (intr->ih_ipl != ihand->ih_ipl) {
        !           787: #ifdef DIAGNOSTIC
        !           788:                        panic("intr_establish: there are other handlers with "
        !           789:                            "vec (0x%x) at ipl %x, but you want it at %x",
        !           790:                            vec, intr->ih_ipl, ihand->ih_ipl);
        !           791: #endif /* DIAGNOSTIC */
        !           792:                        return (EINVAL);
        !           793:                }
        !           794:        }
        !           795:
        !           796:        evcount_attach(&ihand->ih_count, name, (void *)&ihand->ih_ipl,
        !           797:            &evcount_intr);
        !           798:        SLIST_INSERT_HEAD(list, ihand, ih_link);
        !           799:        return (0);
        !           800: }
        !           801:
        !           802: void
        !           803: nmihand(void *frame)
        !           804: {
        !           805: #ifdef DDB
        !           806:        printf("Abort switch pressed\n");
        !           807:        if (db_console) {
        !           808:                /*
        !           809:                 * We can't use Debugger() here, as we are coming from an
        !           810:                 * exception handler, and can't assume anything about the
        !           811:                 * state we are in. Invoke the post-trap ddb entry directly.
        !           812:                 */
        !           813:                extern void m88k_db_trap(int, struct trapframe *);
        !           814:                m88k_db_trap(T_KDB_ENTRY, (struct trapframe *)frame);
        !           815:        }
        !           816: #endif
        !           817: }
        !           818:
        !           819: int
        !           820: cpu_exec_aout_makecmds(p, epp)
        !           821:        struct proc *p;
        !           822:        struct exec_package *epp;
        !           823: {
        !           824:
        !           825:        return (ENOEXEC);
        !           826: }
        !           827:
        !           828: int
        !           829: sys_sysarch(p, v, retval)
        !           830:        struct proc *p;
        !           831:        void *v;
        !           832:        register_t *retval;
        !           833: {
        !           834: #if 0
        !           835:        struct sys_sysarch_args /* {
        !           836:           syscallarg(int) op;
        !           837:           syscallarg(char *) parm;
        !           838:        } */ *uap = v;
        !           839: #endif
        !           840:
        !           841:        return (ENOSYS);
        !           842: }
        !           843:
        !           844: /*
        !           845:  * machine dependent system variables.
        !           846:  */
        !           847:
        !           848: int
        !           849: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
        !           850:        int *name;
        !           851:        u_int namelen;
        !           852:        void *oldp;
        !           853:        size_t *oldlenp;
        !           854:        void *newp;
        !           855:        size_t newlen;
        !           856:        struct proc *p;
        !           857: {
        !           858:        dev_t consdev;
        !           859:
        !           860:        /* all sysctl names are this level are terminal */
        !           861:        if (namelen != 1)
        !           862:                return (ENOTDIR); /* overloaded */
        !           863:
        !           864:        switch (name[0]) {
        !           865:        case CPU_CONSDEV:
        !           866:                if (cn_tab != NULL)
        !           867:                        consdev = cn_tab->cn_dev;
        !           868:                else
        !           869:                        consdev = NODEV;
        !           870:                return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
        !           871:                    sizeof consdev));
        !           872:        default:
        !           873:                return (EOPNOTSUPP);
        !           874:        }
        !           875:        /*NOTREACHED*/
        !           876: }
        !           877:
        !           878: void
        !           879: myetheraddr(cp)
        !           880:        u_char *cp;
        !           881: {
        !           882:        struct mvmeprom_brdid brdid;
        !           883:
        !           884:        bugbrdid(&brdid);
        !           885:        bcopy(&brdid.etheraddr, cp, 6);
        !           886: }
        !           887:
        !           888: void
        !           889: mvme88k_vector_init(u_int32_t *vbr, u_int32_t *vectors)
        !           890: {
        !           891:        extern void vector_init(u_int32_t *, u_int32_t *);      /* gross */
        !           892:
        !           893:        /* Save BUG vector */
        !           894:        bugvec[0] = vbr[MVMEPROM_VECTOR * 2 + 0];
        !           895:        bugvec[1] = vbr[MVMEPROM_VECTOR * 2 + 1];
        !           896:
        !           897:        vector_init(vbr, vectors);
        !           898:
        !           899:        /* Save new BUG vector */
        !           900:        sysbugvec[0] = vbr[MVMEPROM_VECTOR * 2 + 0];
        !           901:        sysbugvec[1] = vbr[MVMEPROM_VECTOR * 2 + 1];
        !           902: }
        !           903:
        !           904: /*
        !           905:  * Called from locore.S during boot,
        !           906:  * this is the first C code that's run.
        !           907:  */
        !           908: void
        !           909: mvme_bootstrap()
        !           910: {
        !           911:        extern int kernelstart;
        !           912:        extern struct consdev *cn_tab;
        !           913:        struct mvmeprom_brdid brdid;
        !           914: #ifndef MULTIPROCESSOR
        !           915:        cpuid_t master_cpu;
        !           916: #endif
        !           917:
        !           918:        buginit();
        !           919:        bugbrdid(&brdid);
        !           920:        brdtyp = brdid.model;
        !           921:
        !           922:        /*
        !           923:         * Use the BUG as console for now. After autoconf, we'll switch to
        !           924:         * real hardware.
        !           925:         */
        !           926:        cn_tab = &bootcons;
        !           927:
        !           928:        /*
        !           929:         * Set up interrupt and fp exception handlers based on the machine.
        !           930:         */
        !           931:        switch (brdtyp) {
        !           932: #ifdef MVME187
        !           933:        case BRD_187:
        !           934:        case BRD_8120:
        !           935:                m187_bootstrap();
        !           936:                break;
        !           937: #endif
        !           938: #ifdef MVME188
        !           939:        case BRD_188:
        !           940:                m188_bootstrap();
        !           941:                break;
        !           942: #endif
        !           943: #ifdef MVME197
        !           944:        case BRD_197:
        !           945:                m197_bootstrap();
        !           946:                break;
        !           947: #endif
        !           948:        default:
        !           949:                panic("Sorry, this kernel does not support MVME%x", brdtyp);
        !           950:        }
        !           951:
        !           952:        uvmexp.pagesize = PAGE_SIZE;
        !           953:        uvm_setpagesize();
        !           954:        first_addr = round_page(first_addr);
        !           955:
        !           956:        switch (brdtyp) {
        !           957: #ifdef MVME187
        !           958:        case BRD_187:
        !           959:        case BRD_8120:
        !           960:                last_addr = m187_memsize();
        !           961:                break;
        !           962: #endif
        !           963: #ifdef MVME188
        !           964:        case BRD_188:
        !           965:                last_addr = m188_memsize();
        !           966:                break;
        !           967: #endif
        !           968: #ifdef MVME197
        !           969:        case BRD_197:
        !           970:                last_addr = m197_memsize();
        !           971:                break;
        !           972: #endif
        !           973:        }
        !           974:        physmem = btoc(last_addr);
        !           975:
        !           976:        setup_board_config();
        !           977:        master_cpu = cmmu_init();
        !           978:        set_cpu_number(master_cpu);
        !           979:
        !           980: #ifdef M88100
        !           981:        if (CPU_IS88100) {
        !           982:                m88100_apply_patches();
        !           983:        }
        !           984: #endif
        !           985:
        !           986:        /*
        !           987:         * Now that set_cpu_number() set us with a valid cpu_info pointer,
        !           988:         * we need to initialize p_addr and curpcb before autoconf, for the
        !           989:         * fault handler to behave properly [except for badaddr() faults,
        !           990:         * which can be taken care of without a valid curcpu()].
        !           991:         */
        !           992:        proc0.p_addr = proc0paddr;
        !           993:        curproc = &proc0;
        !           994:        curpcb = &proc0paddr->u_pcb;
        !           995:
        !           996:        avail_start = first_addr;
        !           997:        avail_end = last_addr;
        !           998:
        !           999:        /*
        !          1000:         * Steal MSGBUFSIZE at the top of physical memory for msgbuf
        !          1001:         */
        !          1002:        avail_end -= round_page(MSGBUFSIZE);
        !          1003:
        !          1004: #ifdef DEBUG
        !          1005:        printf("MVME%x boot: memory from 0x%x to 0x%x\n",
        !          1006:            brdtyp, avail_start, avail_end);
        !          1007: #endif
        !          1008:        pmap_bootstrap((vaddr_t)trunc_page((unsigned)&kernelstart));
        !          1009:
        !          1010:        /*
        !          1011:         * Tell the VM system about available physical memory.
        !          1012:         *
        !          1013:         * The mvme88k boards only have one contiguous area, although BUG
        !          1014:         * could be set up to configure a non-contiguous scheme; also, we
        !          1015:         * might want to register ECC memory separately later on...
        !          1016:         */
        !          1017:        uvm_page_physload(atop(avail_start), atop(avail_end),
        !          1018:            atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT);
        !          1019:
        !          1020:        /* Initialize the "u-area" pages. */
        !          1021:        bzero((caddr_t)curpcb, USPACE);
        !          1022: #ifdef DEBUG
        !          1023:        printf("leaving mvme_bootstrap()\n");
        !          1024: #endif
        !          1025: }
        !          1026:
        !          1027: #ifdef MULTIPROCESSOR
        !          1028: void
        !          1029: cpu_boot_secondary_processors()
        !          1030: {
        !          1031:        cpuid_t cpu;
        !          1032:        int rc;
        !          1033:        extern void secondary_start(void);
        !          1034:
        !          1035:        switch (brdtyp) {
        !          1036: #if defined(MVME188) || defined(MVME197)
        !          1037: #ifdef MVME188
        !          1038:        case BRD_188:
        !          1039: #endif
        !          1040: #ifdef MVME197
        !          1041:        case BRD_197:
        !          1042: #endif
        !          1043:                for (cpu = 0; cpu < max_cpus; cpu++) {
        !          1044:                        if (cpu != curcpu()->ci_cpuid) {
        !          1045:                                rc = spin_cpu(cpu, (vaddr_t)secondary_start);
        !          1046:                                if (rc != 0 && rc != FORKMPU_NO_MPU)
        !          1047:                                        printf("cpu%d: spin_cpu error %d\n",
        !          1048:                                            cpu, rc);
        !          1049:                        }
        !          1050:                }
        !          1051:                break;
        !          1052: #endif
        !          1053:        default:
        !          1054:                break;
        !          1055:        }
        !          1056: }
        !          1057: #endif
        !          1058:
        !          1059: /*
        !          1060:  * Boot console routines:
        !          1061:  * Enables printing of boot messages before consinit().
        !          1062:  */
        !          1063: void
        !          1064: bootcnprobe(cp)
        !          1065:        struct consdev *cp;
        !          1066: {
        !          1067:        cp->cn_dev = makedev(14, 0);
        !          1068:        cp->cn_pri = CN_NORMAL;
        !          1069: }
        !          1070:
        !          1071: void
        !          1072: bootcninit(cp)
        !          1073:        struct consdev *cp;
        !          1074: {
        !          1075:        /* Nothing to do */
        !          1076: }
        !          1077:
        !          1078: int
        !          1079: bootcngetc(dev)
        !          1080:        dev_t dev;
        !          1081: {
        !          1082:        return (buginchr());
        !          1083: }
        !          1084:
        !          1085: void
        !          1086: bootcnputc(dev, c)
        !          1087:        dev_t dev;
        !          1088:        int c;
        !          1089: {
        !          1090:        if (c == '\n')
        !          1091:                bugpcrlf();
        !          1092:        else
        !          1093:                bugoutchr(c);
        !          1094: }
        !          1095:
        !          1096: u_int
        !          1097: getipl(void)
        !          1098: {
        !          1099:        u_int curspl, psr;
        !          1100:
        !          1101:        disable_interrupt(psr);
        !          1102:        curspl = (*md_getipl)();
        !          1103:        set_psr(psr);
        !          1104:        return curspl;
        !          1105: }
        !          1106:
        !          1107: unsigned
        !          1108: setipl(unsigned level)
        !          1109: {
        !          1110:        u_int curspl, psr;
        !          1111:
        !          1112:        disable_interrupt(psr);
        !          1113:        curspl = (*md_setipl)(level);
        !          1114:
        !          1115:        /*
        !          1116:         * The flush pipeline is required to make sure the above change gets
        !          1117:         * through the data pipe and to the hardware; otherwise, the next
        !          1118:         * bunch of instructions could execute at the wrong spl protection.
        !          1119:         */
        !          1120:        flush_pipeline();
        !          1121:
        !          1122:        set_psr(psr);
        !          1123:        return curspl;
        !          1124: }
        !          1125:
        !          1126: unsigned
        !          1127: raiseipl(unsigned level)
        !          1128: {
        !          1129:        u_int curspl, psr;
        !          1130:
        !          1131:        disable_interrupt(psr);
        !          1132:        curspl = (*md_raiseipl)(level);
        !          1133:
        !          1134:        /*
        !          1135:         * The flush pipeline is required to make sure the above change gets
        !          1136:         * through the data pipe and to the hardware; otherwise, the next
        !          1137:         * bunch of instructions could execute at the wrong spl protection.
        !          1138:         */
        !          1139:        flush_pipeline();
        !          1140:
        !          1141:        set_psr(psr);
        !          1142:        return curspl;
        !          1143: }
        !          1144:
        !          1145: #ifdef MULTIPROCESSOR
        !          1146:
        !          1147: void
        !          1148: m88k_send_ipi(int ipi, cpuid_t cpu)
        !          1149: {
        !          1150:        struct cpu_info *ci;
        !          1151:
        !          1152:        ci = &m88k_cpus[cpu];
        !          1153:        if (ci->ci_alive)
        !          1154:                (*md_send_ipi)(ipi, cpu);
        !          1155: }
        !          1156:
        !          1157: void
        !          1158: m88k_broadcast_ipi(int ipi)
        !          1159: {
        !          1160:        struct cpu_info *ci;
        !          1161:        CPU_INFO_ITERATOR cii;
        !          1162:
        !          1163:        CPU_INFO_FOREACH(cii, ci) {
        !          1164:                if (ci == curcpu())
        !          1165:                        continue;
        !          1166:
        !          1167:                if (ci->ci_alive)
        !          1168:                        (*md_send_ipi)(ipi, ci->ci_cpuid);
        !          1169:        }
        !          1170: }
        !          1171:
        !          1172: #endif

CVSweb