[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

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