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

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

1.1     ! nbrk        1: /* $OpenBSD: machdep.c,v 1.10 2007/06/06 17:15:11 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/autoconf.h>
        !            72: #include <machine/board.h>
        !            73: #include <machine/cmmu.h>
        !            74: #include <machine/cpu.h>
        !            75: #include <machine/kcore.h>
        !            76: #include <machine/prom.h>
        !            77: #include <machine/reg.h>
        !            78: #include <machine/trap.h>
        !            79:
        !            80: #include <dev/cons.h>
        !            81:
        !            82: #include <uvm/uvm_extern.h>
        !            83:
        !            84: #include "ksyms.h"
        !            85: #if DDB
        !            86: #include <machine/db_machdep.h>
        !            87: #include <ddb/db_extern.h>
        !            88: #include <ddb/db_interface.h>
        !            89: #include <ddb/db_var.h>
        !            90: #endif /* DDB */
        !            91:
        !            92: caddr_t        allocsys(caddr_t);
        !            93: void   aviion_bootstrap(void);
        !            94: int    aviion_identify(void);
        !            95: void   consinit(void);
        !            96: __dead void doboot(void);
        !            97: void   dumpconf(void);
        !            98: void   dumpsys(void);
        !            99: u_int  getipl(void);
        !           100: void   identifycpu(void);
        !           101: void   savectx(struct pcb *);
        !           102: void   secondary_main(void);
        !           103: void   secondary_pre_main(void);
        !           104:
        !           105: intrhand_t intr_handlers[NVMEINTR];
        !           106:
        !           107: int physmem;     /* available physical memory, in pages */
        !           108:
        !           109: struct vm_map *exec_map = NULL;
        !           110: struct vm_map *phys_map = NULL;
        !           111:
        !           112: #ifdef MULTIPROCESSOR
        !           113: __cpu_simple_lock_t cpu_mutex = __SIMPLELOCK_UNLOCKED;
        !           114: #endif
        !           115:
        !           116: /*
        !           117:  * Declare these as initialized data so we can patch them.
        !           118:  */
        !           119: #ifndef BUFCACHEPERCENT
        !           120: #define BUFCACHEPERCENT 5
        !           121: #endif
        !           122:
        !           123: #ifdef BUFPAGES
        !           124: int bufpages = BUFPAGES;
        !           125: #else
        !           126: int bufpages = 0;
        !           127: #endif
        !           128: int bufcachepercent = BUFCACHEPERCENT;
        !           129:
        !           130: /*
        !           131:  * Info for CTL_HW
        !           132:  */
        !           133: char  machine[] = MACHINE;      /* cpu "architecture" */
        !           134: char  cpu_model[120];
        !           135:
        !           136: #if defined(DDB) || NKSYMS > 0
        !           137: extern vaddr_t esym;
        !           138: #endif
        !           139:
        !           140: const char *prom_bootargs;                     /* set in locore.S */
        !           141: char bootargs[256];                            /* local copy */
        !           142: u_int bootdev, bootunit, bootpart;             /* set in locore.S */
        !           143:
        !           144: int cputyp;                                    /* set in locore.S */
        !           145: int cpuspeed = 20;                             /* safe guess */
        !           146: int avtyp;
        !           147: const struct board *platform;
        !           148:
        !           149: vaddr_t first_addr;
        !           150: vaddr_t last_addr;
        !           151:
        !           152: vaddr_t avail_start, avail_end;
        !           153: vaddr_t virtual_avail, virtual_end;
        !           154:
        !           155: extern struct user *proc0paddr;
        !           156:
        !           157: /*
        !           158:  * This is to fake out the console routines, while booting.
        !           159:  * We could use directly the bugtty console, but we want to be able to
        !           160:  * configure a kernel without bugtty since we do not necessarily need a
        !           161:  * full-blown console driver.
        !           162:  */
        !           163: cons_decl(boot);
        !           164:
        !           165: struct consdev bootcons = {
        !           166:        NULL,
        !           167:        NULL,
        !           168:        bootcngetc,
        !           169:        bootcnputc,
        !           170:        nullcnpollc,
        !           171:        NULL,
        !           172:        makedev(14, 0),
        !           173:        CN_NORMAL
        !           174: };
        !           175:
        !           176: /*
        !           177:  * Early console initialization: called early on from main, before vm init.
        !           178:  * We want to stick to the BUG routines for now, and we'll switch to the
        !           179:  * real console in cpu_startup().
        !           180:  */
        !           181: void
        !           182: consinit()
        !           183: {
        !           184:        cn_tab = NULL;
        !           185:        cninit();
        !           186:
        !           187: #if defined(DDB)
        !           188:        db_machine_init();
        !           189:        ddb_init();
        !           190:        if (boothowto & RB_KDB)
        !           191:                Debugger();
        !           192: #endif
        !           193: }
        !           194:
        !           195: void
        !           196: identifycpu()
        !           197: {
        !           198: #if 0
        !           199:        /* XXX FILL ME */
        !           200:        cpuspeed = getcpuspeed(&brdid);
        !           201: #endif
        !           202:
        !           203:        strlcpy(cpu_model, platform->descr, sizeof cpu_model);
        !           204: }
        !           205:
        !           206: /*
        !           207:  * Set up real-time clocks.
        !           208:  * These function pointers are set in dev/clock.c.
        !           209:  */
        !           210: void
        !           211: cpu_initclocks()
        !           212: {
        !           213:        platform->init_clocks();
        !           214: }
        !           215:
        !           216: void
        !           217: setstatclockrate(int newhz)
        !           218: {
        !           219:        /* function stub */
        !           220: }
        !           221:
        !           222:
        !           223: void
        !           224: cpu_startup()
        !           225: {
        !           226:        caddr_t v;
        !           227:        int sz, i;
        !           228:        vsize_t size;
        !           229:        int base, residual;
        !           230:        vaddr_t minaddr, maxaddr;
        !           231:
        !           232:        /*
        !           233:         * Initialize error message buffer (at end of core).
        !           234:         * avail_end was pre-decremented in aviion_bootstrap() to compensate.
        !           235:         */
        !           236:        for (i = 0; i < btoc(MSGBUFSIZE); i++)
        !           237:                pmap_kenter_pa((paddr_t)msgbufp + i * PAGE_SIZE,
        !           238:                    avail_end + i * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE);
        !           239:        pmap_update(pmap_kernel());
        !           240:        initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE));
        !           241:
        !           242:        /*
        !           243:         * Good {morning,afternoon,evening,night}.
        !           244:         */
        !           245:        printf(version);
        !           246:        identifycpu();
        !           247:        printf("real mem  = %d\n", ctob(physmem));
        !           248:
        !           249:        /*
        !           250:         * Find out how much space we need, allocate it,
        !           251:         * and then give everything true virtual addresses.
        !           252:         */
        !           253:        sz = (int)allocsys((caddr_t)0);
        !           254:
        !           255:        if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0)
        !           256:                panic("startup: no room for tables");
        !           257:        if (allocsys(v) - v != sz)
        !           258:                panic("startup: table size inconsistency");
        !           259:
        !           260:        /*
        !           261:         * Grab machine dependent memory spaces
        !           262:         */
        !           263:        platform->startup();
        !           264:
        !           265:        /*
        !           266:         * Determine how many buffers to allocate.
        !           267:         * We allocate bufcachepercent% of memory for buffer space.
        !           268:         */
        !           269:        if (bufpages == 0)
        !           270:                bufpages = physmem * bufcachepercent / 100;
        !           271:
        !           272:        /* Restrict to at most 25% filled kvm */
        !           273:        if (bufpages >
        !           274:            (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
        !           275:                bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
        !           276:                    PAGE_SIZE / 4;
        !           277:
        !           278:        /*
        !           279:         * Allocate a submap for exec arguments.  This map effectively
        !           280:         * limits the number of processes exec'ing at any time.
        !           281:         */
        !           282:        minaddr = vm_map_min(kernel_map);
        !           283:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           284:            16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
        !           285:
        !           286:        /*
        !           287:         * Allocate map for physio.
        !           288:         */
        !           289:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           290:            VM_PHYS_SIZE, 0, FALSE, NULL);
        !           291:
        !           292:        printf("avail mem = %ld (%d pages)\n", ptoa(uvmexp.free), uvmexp.free);
        !           293:
        !           294:        /*
        !           295:         * Set up buffers, so they can be used to read disk labels.
        !           296:         */
        !           297:        bufinit();
        !           298:
        !           299:        /*
        !           300:         * Set up interrupt handlers.
        !           301:         */
        !           302:        for (i = 0; i < NVMEINTR; i++)
        !           303:                SLIST_INIT(&intr_handlers[i]);
        !           304:
        !           305:        /*
        !           306:         * Configure the system.
        !           307:         */
        !           308:        if (boothowto & RB_CONFIG) {
        !           309: #ifdef BOOT_CONFIG
        !           310:                user_config();
        !           311: #else
        !           312:                printf("kernel does not support -c; continuing..\n");
        !           313: #endif
        !           314:        }
        !           315: }
        !           316:
        !           317: /*
        !           318:  * Allocate space for system data structures.  We are given
        !           319:  * a starting virtual address and we return a final virtual
        !           320:  * address; along the way we set each data structure pointer.
        !           321:  *
        !           322:  * We call allocsys() with 0 to find out how much space we want,
        !           323:  * allocate that much and fill it with zeroes, and then call
        !           324:  * allocsys() again with the correct base virtual address.
        !           325:  */
        !           326: caddr_t
        !           327: allocsys(v)
        !           328:        caddr_t v;
        !           329: {
        !           330:
        !           331: #define        valloc(name, type, num) \
        !           332:            v = (caddr_t)(((name) = (type *)v) + (num))
        !           333:
        !           334: #ifdef SYSVMSG
        !           335:        valloc(msgpool, char, msginfo.msgmax);
        !           336:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
        !           337:        valloc(msghdrs, struct msg, msginfo.msgtql);
        !           338:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
        !           339: #endif
        !           340:
        !           341:        return v;
        !           342: }
        !           343:
        !           344: __dead void
        !           345: doboot()
        !           346: {
        !           347:        printf("Rebooting system...\n\n");
        !           348:        cmmu_shutdown();
        !           349:        scm_reboot(NULL);
        !           350:        /*NOTREACHED*/
        !           351:        for (;;);               /* appease gcc */
        !           352: }
        !           353:
        !           354: __dead void
        !           355: boot(howto)
        !           356:        int howto;
        !           357: {
        !           358:        /* take a snapshot before clobbering any registers */
        !           359:        if (curproc && curproc->p_addr)
        !           360:                savectx(curpcb);
        !           361:
        !           362:        /* If system is cold, just halt. */
        !           363:        if (cold) {
        !           364:                /* (Unless the user explicitly asked for reboot.) */
        !           365:                if ((howto & RB_USERREQ) == 0)
        !           366:                        howto |= RB_HALT;
        !           367:                goto haltsys;
        !           368:        }
        !           369:
        !           370:        boothowto = howto;
        !           371:        if ((howto & RB_NOSYNC) == 0) {
        !           372:                vfs_shutdown();
        !           373:                /*
        !           374:                 * If we've been adjusting the clock, the todr
        !           375:                 * will be out of synch; adjust it now unless
        !           376:                 * the system was sitting in ddb.
        !           377:                 */
        !           378:                if ((howto & RB_TIMEBAD) == 0)
        !           379:                        resettodr();
        !           380:                else
        !           381:                        printf("WARNING: not updating battery clock\n");
        !           382:        }
        !           383:
        !           384:        /* Disable interrupts. */
        !           385:        splhigh();
        !           386:
        !           387:        /* If rebooting and a dump is requested, do it. */
        !           388:        if (howto & RB_DUMP)
        !           389:                dumpsys();
        !           390:
        !           391: haltsys:
        !           392:        /* Run any shutdown hooks. */
        !           393:        doshutdownhooks();
        !           394:
        !           395:        if (howto & RB_HALT) {
        !           396:                printf("System halted.\n\n");
        !           397:                cmmu_shutdown();
        !           398:                scm_halt();
        !           399:        }
        !           400:
        !           401:        doboot();
        !           402:
        !           403:        for (;;);
        !           404:        /*NOTREACHED*/
        !           405: }
        !           406:
        !           407: unsigned dumpmag = 0x8fca0101;  /* magic number for savecore */
        !           408: int   dumpsize = 0;    /* also for savecore */
        !           409: long  dumplo = 0;
        !           410: cpu_kcore_hdr_t cpu_kcore_hdr;
        !           411:
        !           412: /*
        !           413:  * This is called by configure to set dumplo and dumpsize.
        !           414:  * Dumps always skip the first PAGE_SIZE of disk space
        !           415:  * in case there might be a disk label stored there.
        !           416:  * If there is extra space, put dump at the end to
        !           417:  * reduce the chance that swapping trashes it.
        !           418:  */
        !           419: void
        !           420: dumpconf(void)
        !           421: {
        !           422:        int nblks;      /* size of dump area */
        !           423:
        !           424:        if (dumpdev == NODEV ||
        !           425:            (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
        !           426:                return;
        !           427:        if (nblks <= ctod(1))
        !           428:                return;
        !           429:
        !           430:        dumpsize = physmem;
        !           431:
        !           432:        /* aviion only uses a single segment. */
        !           433:        cpu_kcore_hdr.ram_segs[0].start = 0;
        !           434:        cpu_kcore_hdr.ram_segs[0].size = ctob(physmem);
        !           435:        cpu_kcore_hdr.cputype = cputyp;
        !           436:
        !           437:        /*
        !           438:         * Don't dump on the first block
        !           439:         * in case the dump device includes a disk label.
        !           440:         */
        !           441:        if (dumplo < ctod(1))
        !           442:                dumplo = ctod(1);
        !           443:
        !           444:        /* Put dump at end of partition, and make it fit. */
        !           445:        if (dumpsize + 1 > dtoc(nblks - dumplo))
        !           446:                dumpsize = dtoc(nblks - dumplo) - 1;
        !           447:        if (dumplo < nblks - ctod(dumpsize) - 1)
        !           448:                dumplo = nblks - ctod(dumpsize) - 1;
        !           449: }
        !           450:
        !           451: /*
        !           452:  * Doadump comes here after turning off memory management and
        !           453:  * getting on the dump stack, either when called above, or by
        !           454:  * the auto-restart code.
        !           455:  */
        !           456: void
        !           457: dumpsys()
        !           458: {
        !           459:        int maj;
        !           460:        int psize;
        !           461:        daddr64_t blkno;        /* current block to write */
        !           462:                                /* dump routine */
        !           463:        int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
        !           464:        int pg;                 /* page being dumped */
        !           465:        paddr_t maddr;          /* PA being dumped */
        !           466:        int error;              /* error code from (*dump)() */
        !           467:        kcore_seg_t *kseg_p;
        !           468:        cpu_kcore_hdr_t *chdr_p;
        !           469:        char dump_hdr[dbtob(1)];        /* XXX assume hdr fits in 1 block */
        !           470:
        !           471:        extern int msgbufmapped;
        !           472:
        !           473:        msgbufmapped = 0;
        !           474:
        !           475:        /* Make sure dump device is valid. */
        !           476:        if (dumpdev == NODEV)
        !           477:                return;
        !           478:        if (dumpsize == 0) {
        !           479:                dumpconf();
        !           480:                if (dumpsize == 0)
        !           481:                        return;
        !           482:        }
        !           483:        maj = major(dumpdev);
        !           484:        if (dumplo < 0) {
        !           485:                printf("\ndump to dev %u,%u not possible\n", maj,
        !           486:                    minor(dumpdev));
        !           487:                return;
        !           488:        }
        !           489:        dump = bdevsw[maj].d_dump;
        !           490:        blkno = dumplo;
        !           491:
        !           492:        printf("\ndumping to dev %u,%u offset %ld\n", maj,
        !           493:            minor(dumpdev), dumplo);
        !           494:
        !           495:        /* Setup the dump header */
        !           496:        kseg_p = (kcore_seg_t *)dump_hdr;
        !           497:        chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))];
        !           498:        bzero(dump_hdr, sizeof(dump_hdr));
        !           499:
        !           500:        CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
        !           501:        kseg_p->c_size = dbtob(1) - ALIGN(sizeof(*kseg_p));
        !           502:        *chdr_p = cpu_kcore_hdr;
        !           503:
        !           504:        printf("dump ");
        !           505:        psize = (*bdevsw[maj].d_psize)(dumpdev);
        !           506:        if (psize == -1) {
        !           507:                printf("area unavailable\n");
        !           508:                return;
        !           509:        }
        !           510:
        !           511:        /* Dump the header. */
        !           512:        error = (*dump)(dumpdev, blkno++, (caddr_t)dump_hdr, dbtob(1));
        !           513:        if (error != 0)
        !           514:                goto abort;
        !           515:
        !           516:        maddr = (paddr_t)0;
        !           517:        for (pg = 0; pg < dumpsize; pg++) {
        !           518: #define NPGMB  (1024 * 1024 / PAGE_SIZE)
        !           519:                /* print out how many MBs we have dumped */
        !           520:                if (pg != 0 && (pg % NPGMB) == 0)
        !           521:                        printf("%d ", pg / NPGMB);
        !           522: #undef NPGMB
        !           523:                pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
        !           524:                    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
        !           525:
        !           526:                error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
        !           527:                if (error == 0) {
        !           528:                        maddr += PAGE_SIZE;
        !           529:                        blkno += btodb(PAGE_SIZE);
        !           530:                } else
        !           531:                        break;
        !           532:        }
        !           533: abort:
        !           534:        switch (error) {
        !           535:        case 0:
        !           536:                printf("succeeded\n");
        !           537:                break;
        !           538:
        !           539:        case ENXIO:
        !           540:                printf("device bad\n");
        !           541:                break;
        !           542:
        !           543:        case EFAULT:
        !           544:                printf("device not ready\n");
        !           545:                break;
        !           546:
        !           547:        case EINVAL:
        !           548:                printf("area improper\n");
        !           549:                break;
        !           550:
        !           551:        case EIO:
        !           552:                printf("i/o error\n");
        !           553:                break;
        !           554:
        !           555:        case EINTR:
        !           556:                printf("aborted from console\n");
        !           557:                break;
        !           558:
        !           559:        default:
        !           560:                printf("error %d\n", error);
        !           561:                break;
        !           562:        }
        !           563: }
        !           564:
        !           565: #ifdef MULTIPROCESSOR
        !           566:
        !           567: /*
        !           568:  * Secondary CPU early initialization routine.
        !           569:  * Determine CPU number and set it, then allocate the idle pcb (and stack).
        !           570:  *
        !           571:  * Running on a minimal stack here, with interrupts disabled; do nothing fancy.
        !           572:  */
        !           573: void
        !           574: secondary_pre_main()
        !           575: {
        !           576:        struct cpu_info *ci;
        !           577:
        !           578:        set_cpu_number(cmmu_cpu_number()); /* Determine cpu number by CMMU */
        !           579:        ci = curcpu();
        !           580:        ci->ci_curproc = &proc0;
        !           581:
        !           582:        splhigh();
        !           583:
        !           584:        /*
        !           585:         * Setup CMMUs and translation tables (shared with the master cpu).
        !           586:         */
        !           587:        pmap_bootstrap_cpu(ci->ci_cpuid);
        !           588:
        !           589:        /*
        !           590:         * Allocate UPAGES contiguous pages for the idle PCB and stack.
        !           591:         */
        !           592:        ci->ci_idle_pcb = (struct pcb *)uvm_km_zalloc(kernel_map, USPACE);
        !           593:        if (ci->ci_idle_pcb == NULL) {
        !           594:                printf("cpu%d: unable to allocate idle stack\n", ci->ci_cpuid);
        !           595:        }
        !           596: }
        !           597:
        !           598: /*
        !           599:  * Further secondary CPU initialization.
        !           600:  *
        !           601:  * We are now running on our idle stack, with proper page tables.
        !           602:  * There is nothing to do but display some details about the CPU and its CMMUs.
        !           603:  */
        !           604: void
        !           605: secondary_main()
        !           606: {
        !           607:        struct cpu_info *ci = curcpu();
        !           608:
        !           609:        cpu_configuration_print(0);
        !           610:        ncpus++;
        !           611:        __cpu_simple_unlock(&cpu_mutex);
        !           612:
        !           613:        microuptime(&ci->ci_schedstate.spc_runtime);
        !           614:        ci->ci_curproc = NULL;
        !           615:
        !           616:        /*
        !           617:         * Upon return, the secondary cpu bootstrap code in locore will
        !           618:         * enter the idle loop, waiting for some food to process on this
        !           619:         * processor.
        !           620:         */
        !           621: }
        !           622:
        !           623: #endif /* MULTIPROCESSOR */
        !           624:
        !           625: /*
        !           626:  * Try to insert ihand in the list of handlers for vector vec.
        !           627:  */
        !           628: int
        !           629: intr_establish(int vec, struct intrhand *ihand, const char *name)
        !           630: {
        !           631:        struct intrhand *intr;
        !           632:        intrhand_t *list;
        !           633:
        !           634:        if (vec < 0 || vec >= NVMEINTR) {
        !           635: #ifdef DIAGNOSTIC
        !           636:                printf("intr_establish: vec (0x%x) not between 0x00 and 0xff\n",
        !           637:                      vec);
        !           638: #endif /* DIAGNOSTIC */
        !           639:                return (EINVAL);
        !           640:        }
        !           641:
        !           642:        list = &intr_handlers[vec];
        !           643:        if (!SLIST_EMPTY(list)) {
        !           644:                intr = SLIST_FIRST(list);
        !           645:                if (intr->ih_ipl != ihand->ih_ipl) {
        !           646: #ifdef DIAGNOSTIC
        !           647:                        printf("intr_establish: there are other handlers with "
        !           648:                            "vec (0x%x) at ipl %x, but you want it at %x\n",
        !           649:                            vec, intr->ih_ipl, ihand->ih_ipl);
        !           650: #endif /* DIAGNOSTIC */
        !           651:                        return (EINVAL);
        !           652:                }
        !           653:        }
        !           654:
        !           655:        evcount_attach(&ihand->ih_count, name, (void *)&ihand->ih_ipl,
        !           656:            &evcount_intr);
        !           657:        SLIST_INSERT_HEAD(list, ihand, ih_link);
        !           658:        return (0);
        !           659: }
        !           660:
        !           661: void
        !           662: nmihand(void *frame)
        !           663: {
        !           664: #ifdef DDB
        !           665:        printf("Abort switch pressed\n");
        !           666:        if (db_console) {
        !           667:                /*
        !           668:                 * We can't use Debugger() here, as we are coming from an
        !           669:                 * exception, and can't assume anything on the state we are
        !           670:                 * in. Invoke the post-trap ddb entry directly.
        !           671:                 */
        !           672:                extern void m88k_db_trap(int, struct trapframe *);
        !           673:                m88k_db_trap(T_KDB_ENTRY, (struct trapframe *)frame);
        !           674:        }
        !           675: #endif
        !           676: }
        !           677:
        !           678: int
        !           679: cpu_exec_aout_makecmds(p, epp)
        !           680:        struct proc *p;
        !           681:        struct exec_package *epp;
        !           682: {
        !           683:
        !           684:        return (ENOEXEC);
        !           685: }
        !           686:
        !           687: int
        !           688: sys_sysarch(p, v, retval)
        !           689:        struct proc *p;
        !           690:        void *v;
        !           691:        register_t *retval;
        !           692: {
        !           693: #if 0
        !           694:        struct sys_sysarch_args /* {
        !           695:           syscallarg(int) op;
        !           696:           syscallarg(char *) parm;
        !           697:        } */ *uap = v;
        !           698: #endif
        !           699:
        !           700:        return (ENOSYS);
        !           701: }
        !           702:
        !           703: /*
        !           704:  * machine dependent system variables.
        !           705:  */
        !           706:
        !           707: int
        !           708: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
        !           709:        int *name;
        !           710:        u_int namelen;
        !           711:        void *oldp;
        !           712:        size_t *oldlenp;
        !           713:        void *newp;
        !           714:        size_t newlen;
        !           715:        struct proc *p;
        !           716: {
        !           717:        dev_t consdev;
        !           718:
        !           719:        /* all sysctl names are this level are terminal */
        !           720:        if (namelen != 1)
        !           721:                return (ENOTDIR); /* overloaded */
        !           722:
        !           723:        switch (name[0]) {
        !           724:        case CPU_CONSDEV:
        !           725:                if (cn_tab != NULL)
        !           726:                        consdev = cn_tab->cn_dev;
        !           727:                else
        !           728:                        consdev = NODEV;
        !           729:                return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
        !           730:                    sizeof consdev));
        !           731:        default:
        !           732:                return (EOPNOTSUPP);
        !           733:        }
        !           734:        /*NOTREACHED*/
        !           735: }
        !           736:
        !           737: /*
        !           738:  * Called from locore.S during boot,
        !           739:  * this is the first C code that's run.
        !           740:  */
        !           741: void
        !           742: aviion_bootstrap()
        !           743: {
        !           744:        extern int kernelstart;
        !           745:        extern char *end;
        !           746: #ifndef MULTIPROCESSOR
        !           747:        cpuid_t master_cpu;
        !           748: #endif
        !           749:
        !           750:        /* Save a copy of our commandline before it gets overwritten. */
        !           751:        strlcpy(bootargs, prom_bootargs, sizeof bootargs);
        !           752:
        !           753:        avtyp = aviion_identify();
        !           754:
        !           755:        /* Set up interrupt and fp exception handlers based on the machine. */
        !           756:        switch (avtyp) {
        !           757: #ifdef AV400
        !           758:        case AV_400:
        !           759:                platform = &board_av400;
        !           760:                break;
        !           761: #endif
        !           762: #ifdef AV530
        !           763:        case AV_530:
        !           764:                platform = &board_av530;
        !           765:                break;
        !           766: #endif
        !           767: #ifdef AV5000
        !           768:        case AV_5000:
        !           769:                platform = &board_av5000;
        !           770:                break;
        !           771: #endif
        !           772: #ifdef AV6280
        !           773:        case AV_6280:
        !           774:                platform = &board_av6280;
        !           775:                break;
        !           776: #endif
        !           777:        default:
        !           778:                scm_printf("Sorry, OpenBSD/" MACHINE
        !           779:                    " does not support this model.\n");
        !           780:                scm_halt();
        !           781:                break;
        !           782:        };
        !           783:
        !           784:        cn_tab = &bootcons;
        !           785:        /* we can use printf() from here. */
        !           786:
        !           787:        platform->bootstrap();
        !           788:
        !           789:        /* Parse the commandline */
        !           790:        cmdline_parse();
        !           791:
        !           792:        uvmexp.pagesize = PAGE_SIZE;
        !           793:        uvm_setpagesize();
        !           794:
        !           795: #if defined(DDB) || NKSYMS > 0
        !           796:        if (esym != 0)
        !           797:                first_addr = esym;
        !           798:        else
        !           799: #endif
        !           800:                first_addr = (vaddr_t)&end;
        !           801:        first_addr = round_page(first_addr);
        !           802:
        !           803:        last_addr = platform->memsize();
        !           804:        physmem = btoc(last_addr);
        !           805:
        !           806:        setup_board_config();
        !           807:        master_cpu = cmmu_init();
        !           808:        set_cpu_number(master_cpu);
        !           809:
        !           810:        /*
        !           811:         * Now that set_cpu_number() set us with a valid cpu_info pointer,
        !           812:         * we need to initialize p_addr and curpcb before autoconf, for the
        !           813:         * fault handler to behave properly [except for badaddr() faults,
        !           814:         * which can be taken care of without a valid curcpu()].
        !           815:         */
        !           816:        proc0.p_addr = proc0paddr;
        !           817:        curproc = &proc0;
        !           818:        curpcb = &proc0paddr->u_pcb;
        !           819:
        !           820:        avail_start = round_page(first_addr);
        !           821:        avail_end = last_addr;
        !           822:
        !           823:        /* Steal MSGBUFSIZE at the top of physical memory for msgbuf. */
        !           824:        avail_end -= round_page(MSGBUFSIZE);
        !           825:        pmap_bootstrap((vaddr_t)trunc_page((unsigned)&kernelstart));
        !           826:
        !           827:        /*
        !           828:         * Tell the VM system about available physical memory.
        !           829:         * The aviion systems only have one contiguous area.
        !           830:         *
        !           831:         * XXX However, on series 5000, SRAM overlaps a low memory range,
        !           832:         * XXX so we will need to upload two ranges of pages on them.
        !           833:         */
        !           834:        uvm_page_physload(atop(avail_start), atop(avail_end),
        !           835:            atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT);
        !           836:
        !           837:        /* Initialize the "u-area" pages. */
        !           838:        bzero((caddr_t)curpcb, USPACE);
        !           839: }
        !           840:
        !           841: #ifdef MULTIPROCESSOR
        !           842: void
        !           843: cpu_boot_secondary_processors()
        !           844: {
        !           845:        cpuid_t cpu;
        !           846:        int rc;
        !           847:        extern void secondary_start(void);
        !           848:
        !           849:        for (cpu = 0; cpu < max_cpus; cpu++) {
        !           850:                if (cpu != curcpu()->ci_cpuid) {
        !           851:                        rc = scm_spincpu(cpu, (vaddr_t)secondary_start);
        !           852:                        if (rc != 0)
        !           853:                                printf("cpu%d: spin_cpu error %d\n", cpu, rc);
        !           854:                }
        !           855:        }
        !           856: }
        !           857: #endif
        !           858:
        !           859: /*
        !           860:  * Boot console routines:
        !           861:  * Enables printing of boot messages before consinit().
        !           862:  */
        !           863: void
        !           864: bootcnprobe(cp)
        !           865:        struct consdev *cp;
        !           866: {
        !           867:        cp->cn_dev = makedev(0, 0);
        !           868:        cp->cn_pri = CN_NORMAL;
        !           869: }
        !           870:
        !           871: void
        !           872: bootcninit(cp)
        !           873:        struct consdev *cp;
        !           874: {
        !           875:        /* Nothing to do */
        !           876: }
        !           877:
        !           878: int
        !           879: bootcngetc(dev)
        !           880:        dev_t dev;
        !           881: {
        !           882:        return (scm_getc());
        !           883: }
        !           884:
        !           885: void
        !           886: bootcnputc(dev, c)
        !           887:        dev_t dev;
        !           888:        int c;
        !           889: {
        !           890:        if (c == '\n')
        !           891:                scm_putcrlf();
        !           892:        else
        !           893:                scm_putc(c);
        !           894: }
        !           895:
        !           896: u_int
        !           897: getipl(void)
        !           898: {
        !           899:        u_int curspl, psr;
        !           900:
        !           901:        disable_interrupt(psr);
        !           902:        curspl = platform->getipl();
        !           903:        set_psr(psr);
        !           904:        return curspl;
        !           905: }
        !           906:
        !           907: u_int
        !           908: setipl(u_int level)
        !           909: {
        !           910:        u_int curspl, psr;
        !           911:
        !           912:        disable_interrupt(psr);
        !           913:        curspl = platform->setipl(level);
        !           914:
        !           915:        /*
        !           916:         * The flush pipeline is required to make sure the above change gets
        !           917:         * through the data pipe and to the hardware; otherwise, the next
        !           918:         * bunch of instructions could execute at the wrong spl protection.
        !           919:         */
        !           920:        flush_pipeline();
        !           921:
        !           922:        set_psr(psr);
        !           923:        return curspl;
        !           924: }
        !           925:
        !           926: u_int
        !           927: raiseipl(u_int level)
        !           928: {
        !           929:        u_int curspl, psr;
        !           930:
        !           931:        disable_interrupt(psr);
        !           932:        curspl = platform->raiseipl(level);
        !           933:
        !           934:        /*
        !           935:         * The flush pipeline is required to make sure the above change gets
        !           936:         * through the data pipe and to the hardware; otherwise, the next
        !           937:         * bunch of instructions could execute at the wrong spl protection.
        !           938:         */
        !           939:        flush_pipeline();
        !           940:
        !           941:        set_psr(psr);
        !           942:        return curspl;
        !           943: }
        !           944:
        !           945: u_char hostaddr[6];
        !           946:
        !           947: void
        !           948: myetheraddr(u_char *cp)
        !           949: {
        !           950:        bcopy(hostaddr, cp, 6);
        !           951: }
        !           952:
        !           953: /*
        !           954:  * Attempt to identify which AViiON flavour we are running on.
        !           955:  * The only thing we can do at this point is peek at random addresses and
        !           956:  * see if they cause bus errors, or not.
        !           957:  *
        !           958:  * These heuristics are probably not the best; feel free to come with better
        !           959:  * ones...
        !           960:  */
        !           961: int
        !           962: aviion_identify()
        !           963: {
        !           964:        /*
        !           965:         * We don't know anything about 88110-based models.
        !           966:         * Note that we can't use CPU_IS81x0 here since these are optimized
        !           967:         * if the kernel you're running is compiled for only one processor
        !           968:         * type, and we want to check against the real hardware.
        !           969:         */
        !           970:        if (cputyp == CPU_88110)
        !           971:                return (0);
        !           972:
        !           973:        /*
        !           974:         * Series 100/200/300/400/3000/4000/4300 do not have the VIRQLV
        !           975:         * register at 0xfff85000.
        !           976:         */
        !           977:        if (badaddr(0xfff85000, 4) != 0)
        !           978:                return (AV_400);
        !           979:
        !           980:        /*
        !           981:         * Series 5000 and 6000 do not have an RTC counter at 0xfff8f084.
        !           982:         */
        !           983:        if (badaddr(0xfff8f084, 4) != 0)
        !           984:                return (AV_5000);
        !           985:
        !           986:        /*
        !           987:         * Series 4600/530 have IOFUSEs at 0xfffb0040 and 0xfffb00c0.
        !           988:         */
        !           989:        if (badaddr(0xfffb0040, 1) == 0 && badaddr(0xfffb00c0, 1) == 0)
        !           990:                return (AV_530);
        !           991:
        !           992:        /*
        !           993:         * Series 6280/8000-8 fall here.
        !           994:         */
        !           995:        return (AV_6280);
        !           996: }

CVSweb