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

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

1.1     ! nbrk        1: /*     $OpenBSD: machdep.c,v 1.44 2007/06/06 17:15:12 deraadt Exp $    */
        !             2: /*
        !             3:  * Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
        !             4:  * Copyright (c) 1996 Nivas Madhur
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. All advertising materials mentioning features or use of this software
        !            16:  *    must display the following acknowledgement:
        !            17:  *      This product includes software developed by Nivas Madhur.
        !            18:  * 4. The name of the author may not be used to endorse or promote products
        !            19:  *    derived from this software without specific prior written permission
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            31:  *
        !            32:  */
        !            33: /*
        !            34:  * Mach Operating System
        !            35:  * Copyright (c) 1993-1991 Carnegie Mellon University
        !            36:  * Copyright (c) 1991 OMRON Corporation
        !            37:  * All Rights Reserved.
        !            38:  *
        !            39:  * Permission to use, copy, modify and distribute this software and its
        !            40:  * documentation is hereby granted, provided that both the copyright
        !            41:  * notice and this permission notice appear in all copies of the
        !            42:  * software, derivative works or modified versions, and any portions
        !            43:  * thereof, and that both notices appear in supporting documentation.
        !            44:  *
        !            45:  * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            46:  * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
        !            47:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            48:  *
        !            49:  * Carnegie Mellon requests users of this software to return to
        !            50:  *
        !            51:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
        !            52:  *  School of Computer Science
        !            53:  *  Carnegie Mellon University
        !            54:  *  Pittsburgh PA 15213-3890
        !            55:  *
        !            56:  * any improvements or extensions that they make and grant Carnegie the
        !            57:  * rights to redistribute these changes.
        !            58:  */
        !            59:
        !            60: #include <sys/param.h>
        !            61: #include <sys/systm.h>
        !            62: #include <sys/kernel.h>
        !            63: #include <sys/proc.h>
        !            64: #include <sys/user.h>
        !            65: #include <sys/buf.h>
        !            66: #include <sys/reboot.h>
        !            67: #include <sys/conf.h>
        !            68: #include <sys/malloc.h>
        !            69: #include <sys/mount.h>
        !            70: #include <sys/msgbuf.h>
        !            71: #include <sys/syscallargs.h>
        !            72: #ifdef SYSVMSG
        !            73: #include <sys/msg.h>
        !            74: #endif
        !            75: #include <sys/exec.h>
        !            76: #include <sys/sysctl.h>
        !            77: #include <sys/errno.h>
        !            78: #include <sys/extent.h>
        !            79: #include <sys/core.h>
        !            80: #include <sys/kcore.h>
        !            81:
        !            82: #include <machine/asm.h>
        !            83: #include <machine/asm_macro.h>
        !            84: #include <machine/board.h>
        !            85: #include <machine/cmmu.h>
        !            86: #include <machine/cpu.h>
        !            87: #include <machine/kcore.h>
        !            88: #include <machine/reg.h>
        !            89: #include <machine/trap.h>
        !            90: #include <machine/m88100.h>
        !            91:
        !            92: #include <luna88k/luna88k/isr.h>
        !            93:
        !            94: #include <dev/cons.h>
        !            95:
        !            96: #include <uvm/uvm_extern.h>
        !            97:
        !            98: #include "ksyms.h"
        !            99: #if DDB
        !           100: #include <machine/db_machdep.h>
        !           101: #include <ddb/db_extern.h>
        !           102: #include <ddb/db_interface.h>
        !           103: #include <ddb/db_output.h>             /* db_printf()          */
        !           104: #endif /* DDB */
        !           105:
        !           106: caddr_t        allocsys(caddr_t);
        !           107: void   consinit(void);
        !           108: void   dumpconf(void);
        !           109: void   dumpsys(void);
        !           110: int    getcpuspeed(void);
        !           111: u_int  getipl(void);
        !           112: void   identifycpu(void);
        !           113: void   luna88k_bootstrap(void);
        !           114: void   savectx(struct pcb *);
        !           115: void   secondary_main(void);
        !           116: void   secondary_pre_main(void);
        !           117: void   setlevel(unsigned int);
        !           118:
        !           119: vaddr_t size_memory(void);
        !           120: void powerdown(void);
        !           121: void get_fuse_rom_data(void);
        !           122: void get_nvram_data(void);
        !           123: char *nvram_by_symbol(char *);
        !           124: void get_autoboot_device(void);                        /* in disksubr.c */
        !           125: int clockintr(void *);                         /* in clock.c */
        !           126:
        !           127: /*
        !           128:  * *int_mask_reg[CPU]
        !           129:  * Points to the hardware interrupt status register for each CPU.
        !           130:  */
        !           131: unsigned int *volatile int_mask_reg[] = {
        !           132:        (unsigned int *)INT_ST_MASK0,
        !           133:        (unsigned int *)INT_ST_MASK1,
        !           134:        (unsigned int *)INT_ST_MASK2,
        !           135:        (unsigned int *)INT_ST_MASK3
        !           136: };
        !           137:
        !           138: unsigned int luna88k_curspl[] = {0, 0, 0, 0};
        !           139:
        !           140: unsigned int int_set_val[INT_LEVEL] = {
        !           141:        INT_SET_LV0,
        !           142:        INT_SET_LV1,
        !           143:        INT_SET_LV2,
        !           144:        INT_SET_LV3,
        !           145:        INT_SET_LV4,
        !           146:        INT_SET_LV5,
        !           147:        INT_SET_LV6,
        !           148:        INT_SET_LV7
        !           149: };
        !           150:
        !           151: /*
        !           152:  * *clock_reg[CPU]
        !           153:  */
        !           154: unsigned int *volatile clock_reg[] = {
        !           155:        (unsigned int *)OBIO_CLOCK0,
        !           156:        (unsigned int *)OBIO_CLOCK1,
        !           157:        (unsigned int *)OBIO_CLOCK2,
        !           158:        (unsigned int *)OBIO_CLOCK3
        !           159: };
        !           160:
        !           161: /*
        !           162:  * FUSE ROM and NVRAM data
        !           163:  */
        !           164: struct fuse_rom_byte {
        !           165:        u_int32_t h;
        !           166:        u_int32_t l;
        !           167: };
        !           168: #define FUSE_ROM_BYTES        (FUSE_ROM_SPACE / sizeof(struct fuse_rom_byte))
        !           169: char fuse_rom_data[FUSE_ROM_BYTES];
        !           170:
        !           171: #define NNVSYM         8
        !           172: #define NVSYMLEN       16
        !           173: #define NVVALLEN       16
        !           174: struct nvram_t {
        !           175:        char symbol[NVSYMLEN];
        !           176:        char value[NVVALLEN];
        !           177: } nvram[NNVSYM];
        !           178:
        !           179: vaddr_t obiova;
        !           180:
        !           181: int physmem;     /* available physical memory, in pages */
        !           182:
        !           183: struct vm_map *exec_map = NULL;
        !           184: struct vm_map *phys_map = NULL;
        !           185:
        !           186: /*
        !           187:  * Declare these as initialized data so we can patch them.
        !           188:  */
        !           189: #ifndef BUFCACHEPERCENT
        !           190: #define BUFCACHEPERCENT 5
        !           191: #endif
        !           192:
        !           193: #ifdef BUFPAGES
        !           194: int bufpages = BUFPAGES;
        !           195: #else
        !           196: int bufpages = 0;
        !           197: #endif
        !           198: int bufcachepercent = BUFCACHEPERCENT;
        !           199:
        !           200: /*
        !           201:  * Info for CTL_HW
        !           202:  */
        !           203: char  machine[] = MACHINE;      /* cpu "architecture" */
        !           204: char  cpu_model[120];
        !           205:
        !           206: #if defined(DDB) || NKSYMS > 0
        !           207: extern char *esym;
        !           208: #endif
        !           209:
        !           210: int machtype = LUNA_88K;       /* may be overwritten in cpu_startup() */
        !           211: int cputyp = CPU_88100;                /* XXX: aoyama */
        !           212: int boothowto;                 /* XXX: should be set in boot loader and locore.S */
        !           213: int bootdev;                   /* XXX: should be set in boot loader and locore.S */
        !           214: int cpuspeed = 33;             /* safe guess */
        !           215: int sysconsole = 1;            /* 0 = ttya, 1 = keyboard/mouse, used in dev/sio.c */
        !           216: u_int16_t dipswitch = 0;       /* set in locore.S */
        !           217: int hwplanebits;               /* set in locore.S */
        !           218:
        !           219: extern struct consdev syscons; /* in dev/siotty.c */
        !           220:
        !           221: extern void syscnattach(int);  /* in dev/siotty.c */
        !           222: extern int omfb_cnattach(void);        /* in dev/lunafb.c */
        !           223: extern void ws_cnattach(void); /* in dev/lunaws.c */
        !           224:
        !           225: vaddr_t first_addr;
        !           226: vaddr_t last_addr;
        !           227:
        !           228: vaddr_t avail_start, avail_end;
        !           229: vaddr_t virtual_avail, virtual_end;
        !           230:
        !           231: extern struct user *proc0paddr;
        !           232:
        !           233: /*
        !           234:  * This is to fake out the console routines, while booting.
        !           235:  * We could use directly the romtty console, but we want to be able to
        !           236:  * configure a kernel without romtty since we do not necessarily need a
        !           237:  * full-blown console driver.
        !           238:  */
        !           239: cons_decl(romtty);
        !           240: extern void nullcnpollc(dev_t, int);
        !           241:
        !           242: struct consdev romttycons = {
        !           243:        NULL,
        !           244:        NULL,
        !           245:        romttycngetc,
        !           246:        romttycnputc,
        !           247:        nullcnpollc,
        !           248:        NULL,
        !           249:        makedev(14, 0),
        !           250:        CN_NORMAL,
        !           251: };
        !           252:
        !           253: /*
        !           254:  * Early console initialization: called early on from main, before vm init.
        !           255:  */
        !           256: void
        !           257: consinit()
        !           258: {
        !           259:        /*
        !           260:         * Initialize the console before we print anything out.
        !           261:         */
        !           262:        if (sysconsole == 0) {
        !           263:                 syscnattach(0);
        !           264:         } else {
        !           265:                 omfb_cnattach();
        !           266:                 ws_cnattach();
        !           267:         }
        !           268:
        !           269: #if defined(DDB)
        !           270:        db_machine_init();
        !           271:        ddb_init();
        !           272:        if (boothowto & RB_KDB)
        !           273:                Debugger();
        !           274: #endif
        !           275: }
        !           276:
        !           277: /*
        !           278:  * Figure out how much real memory is available.
        !           279:  * Start looking from the megabyte after the end of the kernel data,
        !           280:  * until we find non-memory.
        !           281:  */
        !           282: vaddr_t
        !           283: size_memory()
        !           284: {
        !           285:        unsigned int *volatile look;
        !           286:        unsigned int *max;
        !           287: #if 0
        !           288:        extern char *end;
        !           289: #endif
        !           290: #define PATTERN   0x5a5a5a5a
        !           291: #define STRIDE    (4*1024)     /* 4k at a time */
        !           292: #define Roundup(value, stride) (((unsigned)(value) + (stride) - 1) & ~((stride)-1))
        !           293:        /*
        !           294:         * count it up.
        !           295:         */
        !           296:        max = (void *)MAXPHYSMEM;
        !           297: #if 0
        !           298:        for (look = (void *)Roundup(end, STRIDE); look < max;
        !           299: #else
        !           300:        for (look = (void *)first_addr; look < max;
        !           301: #endif
        !           302:            look = (int *)((unsigned)look + STRIDE)) {
        !           303:                unsigned save;
        !           304:
        !           305:                /* if can't access, we've reached the end */
        !           306:                if (badaddr((vaddr_t)look, 4)) {
        !           307: #if defined(DEBUG)
        !           308:                        printf("%x\n", look);
        !           309: #endif
        !           310:                        look = (int *)((int)look - STRIDE);
        !           311:                        break;
        !           312:                }
        !           313:
        !           314:                /*
        !           315:                 * If we write a value, we expect to read the same value back.
        !           316:                 * We'll do this twice, the 2nd time with the opposite bit
        !           317:                 * pattern from the first, to make sure we check all bits.
        !           318:                 */
        !           319:                save = *look;
        !           320:                if (*look = PATTERN, *look != PATTERN)
        !           321:                        break;
        !           322:                if (*look = ~PATTERN, *look != ~PATTERN)
        !           323:                        break;
        !           324:                *look = save;
        !           325:        }
        !           326:
        !           327:        return (trunc_page((unsigned)look));
        !           328: }
        !           329:
        !           330: int
        !           331: getcpuspeed()
        !           332: {
        !           333:        switch(machtype) {
        !           334:        case LUNA_88K:
        !           335:                return 25;
        !           336:        case LUNA_88K2:
        !           337:                return 33;
        !           338:        default:
        !           339:                panic("getcpuspeed: can not determine CPU speed");
        !           340:        }
        !           341: }
        !           342:
        !           343: void
        !           344: identifycpu()
        !           345: {
        !           346:        cpuspeed = getcpuspeed();
        !           347:        snprintf(cpu_model, sizeof cpu_model,
        !           348:            "OMRON LUNA-88K%s, %dMHz",
        !           349:            machtype == LUNA_88K2 ? "2" : "", cpuspeed);
        !           350: }
        !           351:
        !           352: void
        !           353: cpu_startup()
        !           354: {
        !           355:        caddr_t v;
        !           356:        int sz, i;
        !           357:        vaddr_t minaddr, maxaddr;
        !           358:
        !           359:        /*
        !           360:         * Initialize error message buffer (at end of core).
        !           361:         * avail_end was pre-decremented in luna88k_bootstrap() to compensate.
        !           362:         */
        !           363:        for (i = 0; i < btoc(MSGBUFSIZE); i++)
        !           364:                pmap_kenter_pa((paddr_t)msgbufp + i * PAGE_SIZE,
        !           365:                    avail_end + i * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE);
        !           366:        pmap_update(pmap_kernel());
        !           367:        initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE));
        !           368:
        !           369:        /* Determine the machine type from FUSE ROM data.  */
        !           370:        get_fuse_rom_data();
        !           371:        if (strncmp(fuse_rom_data, "MNAME=LUNA88K+", 14) == 0) {
        !           372:                machtype = LUNA_88K2;
        !           373:        }
        !           374:
        !           375:         /* Determine the 'auto-boot' device from NVRAM data */
        !           376:         get_nvram_data();
        !           377:         get_autoboot_device();
        !           378:
        !           379:        /*
        !           380:         * Good {morning,afternoon,evening,night}.
        !           381:         */
        !           382:        printf(version);
        !           383:        identifycpu();
        !           384:        printf("real mem  = %d\n", ctob(physmem));
        !           385:
        !           386:        /*
        !           387:         * Check front DIP switch setting
        !           388:         */
        !           389: #ifdef DEBUG
        !           390:        printf("dipsw = 0x%x\n", dipswitch);
        !           391: #endif
        !           392:
        !           393:        /* Check DIP switch 1 - 1 */
        !           394:        if ((0x8000 & dipswitch) == 0) {
        !           395:                boothowto |= RB_SINGLE;
        !           396:        }
        !           397:
        !           398:        /* Check DIP switch 1 - 3 */
        !           399:        if ((0x2000 & dipswitch) == 0) {
        !           400:                boothowto |= RB_ASKNAME;
        !           401:        }
        !           402:
        !           403:        /* Check DIP switch 1 - 4 */
        !           404:        if ((0x1000 & dipswitch) == 0) {
        !           405:                boothowto |= RB_CONFIG;
        !           406:        }
        !           407:
        !           408:        /*
        !           409:         * Check frame buffer depth.
        !           410:         */
        !           411:        switch (hwplanebits) {
        !           412:        case 0:                         /* No frame buffer */
        !           413:        case 1:
        !           414:        case 4:
        !           415:        case 8:
        !           416:                break;
        !           417:        default:
        !           418:                printf("unexpected frame buffer depth = %d\n", hwplanebits);
        !           419:                hwplanebits = 0;
        !           420:                break;
        !           421:        }
        !           422:
        !           423: #if 0 /* just for test */
        !           424:        /*
        !           425:         * Get boot arguments
        !           426:         */
        !           427:        {
        !           428:                char buf[256];
        !           429:                char **p = (volatile char **)0x00001120;
        !           430:
        !           431:                strncpy(buf, *p, 256);
        !           432:                if (buf[255] != '\0')
        !           433:                        buf[255] = '\0';
        !           434:
        !           435:                printf("boot arg: (0x%x) %s\n", *p, buf);
        !           436:        }
        !           437: #endif
        !           438:
        !           439:        /*
        !           440:         * Find out how much space we need, allocate it,
        !           441:         * and then give everything true virtual addresses.
        !           442:         */
        !           443:        sz = (int)allocsys((caddr_t)0);
        !           444:
        !           445:        if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0)
        !           446:                panic("startup: no room for tables");
        !           447:        if (allocsys(v) - v != sz)
        !           448:                panic("startup: table size inconsistency");
        !           449:
        !           450:        /*
        !           451:         * Grab the OBIO space that we hardwired in pmap_bootstrap
        !           452:         */
        !           453:        obiova = OBIO_START;
        !           454:        uvm_map(kernel_map, (vaddr_t *)&obiova, OBIO_SIZE,
        !           455:            NULL, UVM_UNKNOWN_OFFSET, 0,
        !           456:              UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE,
        !           457:                UVM_ADV_NORMAL, 0));
        !           458:        if (obiova != OBIO_START)
        !           459:                panic("obiova %lx: OBIO not free", obiova);
        !           460:
        !           461:        /*
        !           462:         * Determine how many buffers to allocate.
        !           463:         * We allocate bufcachepercent% of memory for buffer space.
        !           464:         */
        !           465:        if (bufpages == 0)
        !           466:                bufpages = physmem * bufcachepercent / 100;
        !           467:
        !           468:        /* Restrict to at most 25% filled kvm */
        !           469:        if (bufpages >
        !           470:            (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
        !           471:                bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
        !           472:                    PAGE_SIZE / 4;
        !           473:
        !           474:        /*
        !           475:         * Allocate a submap for exec arguments.  This map effectively
        !           476:         * limits the number of processes exec'ing at any time.
        !           477:         */
        !           478:        minaddr = vm_map_min(kernel_map);
        !           479:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           480:            16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
        !           481:
        !           482:        /*
        !           483:         * Allocate map for physio.
        !           484:         */
        !           485:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           486:            VM_PHYS_SIZE, 0, FALSE, NULL);
        !           487:
        !           488:        printf("avail mem = %ld (%d pages)\n", ptoa(uvmexp.free), uvmexp.free);
        !           489:
        !           490:        /*
        !           491:         * Set up buffers, so they can be used to read disk labels.
        !           492:         */
        !           493:        bufinit();
        !           494:
        !           495:        /*
        !           496:         * Initialize the autovectored interrupt list.
        !           497:         */
        !           498:        isrinit();
        !           499:
        !           500:        /*
        !           501:         * Configure the system.
        !           502:         */
        !           503:        if (boothowto & RB_CONFIG) {
        !           504: #ifdef BOOT_CONFIG
        !           505:                user_config();
        !           506: #else
        !           507:                printf("kernel does not support -c; continuing..\n");
        !           508: #endif
        !           509:        }
        !           510: }
        !           511:
        !           512: /*
        !           513:  * Allocate space for system data structures.  We are given
        !           514:  * a starting virtual address and we return a final virtual
        !           515:  * address; along the way we set each data structure pointer.
        !           516:  *
        !           517:  * We call allocsys() with 0 to find out how much space we want,
        !           518:  * allocate that much and fill it with zeroes, and then call
        !           519:  * allocsys() again with the correct base virtual address.
        !           520:  */
        !           521: caddr_t
        !           522: allocsys(v)
        !           523:        caddr_t v;
        !           524: {
        !           525:
        !           526: #define        valloc(name, type, num) \
        !           527:            v = (caddr_t)(((name) = (type *)v) + (num))
        !           528:
        !           529: #ifdef SYSVMSG
        !           530:        valloc(msgpool, char, msginfo.msgmax);
        !           531:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
        !           532:        valloc(msghdrs, struct msg, msginfo.msgtql);
        !           533:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
        !           534: #endif
        !           535:
        !           536:        return v;
        !           537: }
        !           538:
        !           539: __dead void
        !           540: boot(howto)
        !           541:        int howto;
        !           542: {
        !           543:        /* take a snapshot before clobbering any registers */
        !           544:        if (curproc && curproc->p_addr)
        !           545:                savectx(curpcb);
        !           546:
        !           547:        /* If system is cold, just halt. */
        !           548:        if (cold) {
        !           549:                /* (Unless the user explicitly asked for reboot.) */
        !           550:                if ((howto & RB_USERREQ) == 0)
        !           551:                        howto |= RB_HALT;
        !           552:                goto haltsys;
        !           553:        }
        !           554:
        !           555:        boothowto = howto;
        !           556:        if ((howto & RB_NOSYNC) == 0) {
        !           557:                vfs_shutdown();
        !           558:                /*
        !           559:                 * If we've been adjusting the clock, the todr
        !           560:                 * will be out of synch; adjust it now unless
        !           561:                 * the system was sitting in ddb.
        !           562:                 */
        !           563:                if ((howto & RB_TIMEBAD) == 0)
        !           564:                        resettodr();
        !           565:                else
        !           566:                        printf("WARNING: not updating battery clock\n");
        !           567:        }
        !           568:
        !           569:        /* Disable interrupts. */
        !           570:        splhigh();
        !           571:
        !           572:        /* If rebooting and a dump is requested, do it. */
        !           573:        if (howto & RB_DUMP)
        !           574:                dumpsys();
        !           575:
        !           576: haltsys:
        !           577:        /* Run any shutdown hooks. */
        !           578:        doshutdownhooks();
        !           579:
        !           580:        /* Luna88k supports automatic powerdown */
        !           581:        if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
        !           582:                printf("attempting to power down...\n");
        !           583:                powerdown();
        !           584:                /* if failed, fall through. */
        !           585:        }
        !           586:
        !           587:        if (howto & RB_HALT) {
        !           588:                printf("halted\n\n");
        !           589:        } else {
        !           590:                /* Reset all cpus, which causes reboot */
        !           591:                *((volatile unsigned *)0x6d000010) = 0;
        !           592:        }
        !           593:
        !           594:        for (;;);  /* to keep compiler happy, and me from going crazy */
        !           595:        /*NOTREACHED*/
        !           596: }
        !           597:
        !           598: unsigned dumpmag = 0x8fca0101;  /* magic number for savecore */
        !           599: int   dumpsize = 0;    /* also for savecore */
        !           600: long  dumplo = 0;
        !           601: cpu_kcore_hdr_t cpu_kcore_hdr;
        !           602:
        !           603: /*
        !           604:  * This is called by configure to set dumplo and dumpsize.
        !           605:  * Dumps always skip the first PAGE_SIZE of disk space
        !           606:  * in case there might be a disk label stored there.
        !           607:  * If there is extra space, put dump at the end to
        !           608:  * reduce the chance that swapping trashes it.
        !           609:  */
        !           610: void
        !           611: dumpconf(void)
        !           612: {
        !           613:        int nblks;      /* size of dump area */
        !           614:
        !           615:        if (dumpdev == NODEV ||
        !           616:            (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
        !           617:                return;
        !           618:        if (nblks <= ctod(1))
        !           619:                return;
        !           620:
        !           621:        dumpsize = physmem;
        !           622:
        !           623:        /* luna88k only uses a single segment. */
        !           624:        cpu_kcore_hdr.ram_segs[0].start = 0;
        !           625:        cpu_kcore_hdr.ram_segs[0].size = ctob(physmem);
        !           626:        cpu_kcore_hdr.cputype = cputyp;
        !           627:
        !           628:        /*
        !           629:         * Don't dump on the first block
        !           630:         * in case the dump device includes a disk label.
        !           631:         */
        !           632:        if (dumplo < ctod(1))
        !           633:                dumplo = ctod(1);
        !           634:
        !           635:        /* Put dump at end of partition, and make it fit. */
        !           636:        if (dumpsize + 1 > dtoc(nblks - dumplo))
        !           637:                dumpsize = dtoc(nblks - dumplo) - 1;
        !           638:        if (dumplo < nblks - ctod(dumpsize) - 1)
        !           639:                dumplo = nblks - ctod(dumpsize) - 1;
        !           640: }
        !           641:
        !           642: /*
        !           643:  * Doadump comes here after turning off memory management and
        !           644:  * getting on the dump stack, either when called above, or by
        !           645:  * the auto-restart code.
        !           646:  */
        !           647: void
        !           648: dumpsys()
        !           649: {
        !           650:        int maj;
        !           651:        int psize;
        !           652:        daddr64_t blkno;        /* current block to write */
        !           653:                                /* dump routine */
        !           654:        int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
        !           655:        int pg;                 /* page being dumped */
        !           656:        paddr_t maddr;          /* PA being dumped */
        !           657:        int error;              /* error code from (*dump)() */
        !           658:        kcore_seg_t *kseg_p;
        !           659:        cpu_kcore_hdr_t *chdr_p;
        !           660:        char dump_hdr[dbtob(1)];        /* XXX assume hdr fits in 1 block */
        !           661:
        !           662:        extern int msgbufmapped;
        !           663:
        !           664:        msgbufmapped = 0;
        !           665:
        !           666:        /* Make sure dump device is valid. */
        !           667:        if (dumpdev == NODEV)
        !           668:                return;
        !           669:        if (dumpsize == 0) {
        !           670:                dumpconf();
        !           671:                if (dumpsize == 0)
        !           672:                        return;
        !           673:        }
        !           674:        maj = major(dumpdev);
        !           675:        if (dumplo < 0) {
        !           676:                printf("\ndump to dev %u,%u not possible\n", maj,
        !           677:                    minor(dumpdev));
        !           678:                return;
        !           679:        }
        !           680:        dump = bdevsw[maj].d_dump;
        !           681:        blkno = dumplo;
        !           682:
        !           683:        printf("\ndumping to dev %u,%u offset %ld\n", maj,
        !           684:            minor(dumpdev), dumplo);
        !           685:
        !           686:        /* Setup the dump header */
        !           687:        kseg_p = (kcore_seg_t *)dump_hdr;
        !           688:        chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))];
        !           689:        bzero(dump_hdr, sizeof(dump_hdr));
        !           690:
        !           691:        CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
        !           692:        kseg_p->c_size = dbtob(1) - ALIGN(sizeof(*kseg_p));
        !           693:        *chdr_p = cpu_kcore_hdr;
        !           694:
        !           695:        printf("dump ");
        !           696:        psize = (*bdevsw[maj].d_psize)(dumpdev);
        !           697:        if (psize == -1) {
        !           698:                printf("area unavailable\n");
        !           699:                return;
        !           700:        }
        !           701:
        !           702:        /* Dump the header. */
        !           703:        error = (*dump)(dumpdev, blkno++, (caddr_t)dump_hdr, dbtob(1));
        !           704:        if (error != 0)
        !           705:                goto abort;
        !           706:
        !           707:        maddr = (paddr_t)0;
        !           708:        for (pg = 0; pg < dumpsize; pg++) {
        !           709: #define NPGMB  (1024 * 1024 / PAGE_SIZE)
        !           710:                /* print out how many MBs we have dumped */
        !           711:                if (pg != 0 && (pg % NPGMB) == 0)
        !           712:                        printf("%d ", pg / NPGMB);
        !           713: #undef NPGMB
        !           714:                pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
        !           715:                    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
        !           716:
        !           717:                error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
        !           718:                if (error == 0) {
        !           719:                        maddr += PAGE_SIZE;
        !           720:                        blkno += btodb(PAGE_SIZE);
        !           721:                } else
        !           722:                        break;
        !           723:        }
        !           724: abort:
        !           725:        switch (error) {
        !           726:        case 0:
        !           727:                printf("succeeded\n");
        !           728:                break;
        !           729:
        !           730:        case ENXIO:
        !           731:                printf("device bad\n");
        !           732:                break;
        !           733:
        !           734:        case EFAULT:
        !           735:                printf("device not ready\n");
        !           736:                break;
        !           737:
        !           738:        case EINVAL:
        !           739:                printf("area improper\n");
        !           740:                break;
        !           741:
        !           742:        case EIO:
        !           743:                printf("i/o error\n");
        !           744:                break;
        !           745:
        !           746:        case EINTR:
        !           747:                printf("aborted from console\n");
        !           748:                break;
        !           749:
        !           750:        default:
        !           751:                printf("error %d\n", error);
        !           752:                break;
        !           753:        }
        !           754: }
        !           755:
        !           756: #ifdef MULTIPROCESSOR
        !           757:
        !           758: /*
        !           759:  * Secondary CPU early initialization routine.
        !           760:  * Determine CPU number and set it, then allocate the idle pcb (and stack).
        !           761:  *
        !           762:  * Running on a minimal stack here, with interrupts disabled; do nothing fancy.
        !           763:  */
        !           764: void
        !           765: secondary_pre_main()
        !           766: {
        !           767:        struct cpu_info *ci;
        !           768:
        !           769:        set_cpu_number(cmmu_cpu_number());
        !           770:        ci = curcpu();
        !           771:
        !           772:        /*
        !           773:         * Setup CMMUs and translation tables (shared with the master cpu).
        !           774:         */
        !           775:        pmap_bootstrap_cpu(ci->ci_cpuid);
        !           776:
        !           777:        /*
        !           778:         * Allocate UPAGES contiguous pages for the idle PCB and stack.
        !           779:         */
        !           780:        ci->ci_idle_pcb = (struct pcb *)uvm_km_zalloc(kernel_map, USPACE);
        !           781:        if (ci->ci_idle_pcb == NULL) {
        !           782:                printf("cpu%d: unable to allocate idle stack\n", ci->ci_cpuid);
        !           783:        }
        !           784: }
        !           785:
        !           786: /*
        !           787:  * Further secondary CPU initialization.
        !           788:  *
        !           789:  * We are now running on our idle stack, with proper page tables.
        !           790:  * There is nothing to do but display some details about the CPU and its CMMUs.
        !           791:  */
        !           792: void
        !           793: secondary_main()
        !           794: {
        !           795:        struct cpu_info *ci = curcpu();
        !           796:
        !           797:        cpu_configuration_print(0);
        !           798:        ncpus++;
        !           799:
        !           800:        microuptime(&ci->ci_schedstate.spc_runtime);
        !           801:
        !           802:        /*
        !           803:         * Upon return, the secondary cpu bootstrap code in locore will
        !           804:         * enter the idle loop, waiting for some food to process on this
        !           805:         * processor.
        !           806:         */
        !           807: }
        !           808:
        !           809: #endif /* MULTIPROCESSOR */
        !           810:
        !           811: /*
        !           812:  *     Device interrupt handler for LUNA88K
        !           813:  */
        !           814:
        !           815: void
        !           816: luna88k_ext_int(u_int v, struct trapframe *eframe)
        !           817: {
        !           818:        int cpu = cpu_number();
        !           819:        unsigned int cur_mask, cur_int;
        !           820:        unsigned int level, old_spl;
        !           821:
        !           822:        cur_mask = *int_mask_reg[cpu];
        !           823:        old_spl = luna88k_curspl[cpu];
        !           824:        eframe->tf_mask = old_spl;
        !           825:
        !           826:        cur_int = cur_mask >> 29;
        !           827:
        !           828:        if (cur_int == 0) {
        !           829:                /*
        !           830:                 * Spurious interrupts - may be caused by debug output clearing
        !           831:                 * serial port interrupts.
        !           832:                 */
        !           833: #ifdef DEBUG
        !           834:                printf("luna88k_ext_int(): Spurious interrupts?\n");
        !           835: #endif
        !           836:                flush_pipeline();
        !           837:                goto out;
        !           838:        }
        !           839:
        !           840:        uvmexp.intrs++;
        !           841:
        !           842:        /*
        !           843:         * We want to service all interrupts marked in the IST register
        !           844:         * They are all valid because the mask would have prevented them
        !           845:         * from being generated otherwise.  We will service them in order of
        !           846:         * priority.
        !           847:         */
        !           848:
        !           849:        /* XXX: This is very rough. Should be considered more. (aoyama) */
        !           850:        do {
        !           851:                level = (cur_int > old_spl ? cur_int : old_spl);
        !           852:
        !           853: #ifdef DEBUG
        !           854:                if (level > 7 || (char)level < 0) {
        !           855:                        panic("int level (%x) is not between 0 and 7", level);
        !           856:                }
        !           857: #endif
        !           858:
        !           859:                setipl(level);
        !           860:
        !           861:                set_psr(get_psr() & ~PSR_IND);
        !           862:
        !           863:                switch(cur_int) {
        !           864:                case CLOCK_INT_LEVEL:
        !           865:                        clockintr((void *)eframe);
        !           866:                        break;
        !           867:                case 5:
        !           868:                case 4:
        !           869:                case 3:
        !           870:                        isrdispatch_autovec(cur_int);
        !           871:                        break;
        !           872:                default:
        !           873:                        printf("luna88k_ext_int(): level %d interrupt.\n", cur_int);
        !           874:                        break;
        !           875:                }
        !           876:        } while ((cur_int = (*int_mask_reg[cpu]) >> 29) != 0);
        !           877:
        !           878: out:
        !           879:        /*
        !           880:         * process any remaining data access exceptions before
        !           881:         * returning to assembler
        !           882:         */
        !           883:        if (eframe->tf_dmt0 & DMT_VALID)
        !           884:                m88100_trap(T_DATAFLT, eframe);
        !           885:
        !           886:        /*
        !           887:         * Disable interrupts before returning to assembler, the spl will
        !           888:         * be restored later.
        !           889:         */
        !           890:        set_psr(get_psr() | PSR_IND);
        !           891: }
        !           892:
        !           893: int
        !           894: cpu_exec_aout_makecmds(p, epp)
        !           895:        struct proc *p;
        !           896:        struct exec_package *epp;
        !           897: {
        !           898:
        !           899:        return (ENOEXEC);
        !           900: }
        !           901:
        !           902: int
        !           903: sys_sysarch(p, v, retval)
        !           904:        struct proc *p;
        !           905:        void *v;
        !           906:        register_t *retval;
        !           907: {
        !           908: #if 0
        !           909:        struct sys_sysarch_args /* {
        !           910:           syscallarg(int) op;
        !           911:           syscallarg(char *) parm;
        !           912:        } */ *uap = v;
        !           913: #endif
        !           914:
        !           915:        return (ENOSYS);
        !           916: }
        !           917:
        !           918: /*
        !           919:  * machine dependent system variables.
        !           920:  */
        !           921:
        !           922: int
        !           923: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
        !           924:        int *name;
        !           925:        u_int namelen;
        !           926:        void *oldp;
        !           927:        size_t *oldlenp;
        !           928:        void *newp;
        !           929:        size_t newlen;
        !           930:        struct proc *p;
        !           931: {
        !           932:        dev_t consdev;
        !           933:
        !           934:        /* all sysctl names are this level are terminal */
        !           935:        if (namelen != 1)
        !           936:                return (ENOTDIR); /* overloaded */
        !           937:
        !           938:        switch (name[0]) {
        !           939:        case CPU_CONSDEV:
        !           940:                if (cn_tab != NULL)
        !           941:                        consdev = cn_tab->cn_dev;
        !           942:                else
        !           943:                        consdev = NODEV;
        !           944:                return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
        !           945:                    sizeof consdev));
        !           946:        default:
        !           947:                return (EOPNOTSUPP);
        !           948:        }
        !           949:        /*NOTREACHED*/
        !           950: }
        !           951:
        !           952: /*
        !           953:  * Called from locore.S during boot,
        !           954:  * this is the first C code that's run.
        !           955:  */
        !           956: void
        !           957: luna88k_bootstrap()
        !           958: {
        !           959:        extern int kernelstart;
        !           960:        extern struct consdev *cn_tab;
        !           961:        extern struct cmmu_p cmmu8820x;
        !           962:        extern char *end;
        !           963: #ifndef MULTIPROCESSOR
        !           964:        cpuid_t master_cpu;
        !           965: #endif
        !           966:        cpuid_t cpu;
        !           967:        extern void m8820x_initialize_cpu(cpuid_t);
        !           968:        extern void m8820x_set_sapr(cpuid_t, apr_t);
        !           969:        extern void cpu_boot_secondary_processors(void);
        !           970:
        !           971:        cmmu = &cmmu8820x;
        !           972:
        !           973:        /* clear and disable all interrupts */
        !           974:        *int_mask_reg[0] = 0;
        !           975:        *int_mask_reg[1] = 0;
        !           976:        *int_mask_reg[2] = 0;
        !           977:        *int_mask_reg[3] = 0;
        !           978:
        !           979:        /* startup fake console driver.  It will be replaced by consinit() */
        !           980:        cn_tab = &romttycons;
        !           981:
        !           982:        uvmexp.pagesize = PAGE_SIZE;
        !           983:        uvm_setpagesize();
        !           984:
        !           985:        first_addr = round_page((vaddr_t)&end); /* XXX temp until symbols */
        !           986:        last_addr = size_memory();
        !           987:        physmem = btoc(last_addr);
        !           988:
        !           989:        setup_board_config();
        !           990:        master_cpu = cmmu_init();
        !           991:        set_cpu_number(master_cpu);
        !           992:
        !           993:        m88100_apply_patches();
        !           994:
        !           995:        /*
        !           996:         * Now that set_cpu_number() set us with a valid cpu_info pointer,
        !           997:         * we need to initialize p_addr and curpcb before autoconf, for the
        !           998:         * fault handler to behave properly [except for badaddr() faults,
        !           999:         * which can be taken care of without a valid curcpu()].
        !          1000:         */
        !          1001:        proc0.p_addr = proc0paddr;
        !          1002:        curproc = &proc0;
        !          1003:        curpcb = &proc0paddr->u_pcb;
        !          1004:
        !          1005:        avail_start = first_addr;
        !          1006:        avail_end = last_addr;
        !          1007:
        !          1008:        /*
        !          1009:         * Steal MSGBUFSIZE at the top of physical memory for msgbuf
        !          1010:         */
        !          1011:        avail_end -= round_page(MSGBUFSIZE);
        !          1012:
        !          1013: #ifdef DEBUG
        !          1014:        printf("LUNA88K boot: memory from 0x%x to 0x%x\n",
        !          1015:            avail_start, avail_end);
        !          1016: #endif
        !          1017:        pmap_bootstrap((vaddr_t)trunc_page((unsigned)&kernelstart));
        !          1018:
        !          1019:        /*
        !          1020:         * Tell the VM system about available physical memory.
        !          1021:         * luna88k only has one segment.
        !          1022:         */
        !          1023:        uvm_page_physload(atop(avail_start), atop(avail_end),
        !          1024:            atop(avail_start), atop(avail_end),VM_FREELIST_DEFAULT);
        !          1025:
        !          1026:        /* Initialize the "u-area" pages. */
        !          1027:        bzero((caddr_t)curpcb, USPACE);
        !          1028:
        !          1029:        /*
        !          1030:         * On the luna88k, secondary processors are not disabled while the
        !          1031:         * kernel is initializing. We just initialized the CMMUs tied to the
        !          1032:         * currently-running CPU; initialize the others with similar settings
        !          1033:         * as well, after calling pmap_bootstrap() above.
        !          1034:         */
        !          1035:        for (cpu = 0; cpu < max_cpus; cpu++) {
        !          1036:                if (cpu == master_cpu)
        !          1037:                        continue;
        !          1038:                if (m88k_cpus[cpu].ci_alive == 0)
        !          1039:                        continue;
        !          1040:                m8820x_initialize_cpu(cpu);
        !          1041:                cmmu_set_sapr(cpu, kernel_pmap->pm_apr);
        !          1042:        }
        !          1043:        /* Release the cpu_mutex */
        !          1044:        cpu_boot_secondary_processors();
        !          1045:
        !          1046: #ifdef DEBUG
        !          1047:        printf("leaving luna88k_bootstrap()\n");
        !          1048: #endif
        !          1049: }
        !          1050:
        !          1051: /*
        !          1052:  * Rom console routines:
        !          1053:  * Enables printing of boot messages before consinit().
        !          1054:  */
        !          1055:
        !          1056: #define __ROM_FUNC_TABLE       ((int **)0x00001100)
        !          1057: #define ROMGETC()      (*(int (*)(void))__ROM_FUNC_TABLE[3])()
        !          1058: #define ROMPUTC(x)     (*(void (*)(int))__ROM_FUNC_TABLE[4])(x)
        !          1059:
        !          1060: void
        !          1061: romttycnprobe(cp)
        !          1062:        struct consdev *cp;
        !          1063: {
        !          1064:        cp->cn_dev = makedev(14, 0);
        !          1065:        cp->cn_pri = CN_NORMAL;
        !          1066: }
        !          1067:
        !          1068: void
        !          1069: romttycninit(cp)
        !          1070:        struct consdev *cp;
        !          1071: {
        !          1072:        /* Nothing to do */
        !          1073: }
        !          1074:
        !          1075: int
        !          1076: romttycngetc(dev)
        !          1077:        dev_t dev;
        !          1078: {
        !          1079:        int s, c;
        !          1080:
        !          1081:        do {
        !          1082:                s = splhigh();
        !          1083:                c = ROMGETC();
        !          1084:                splx(s);
        !          1085:        } while (c == -1);
        !          1086:        return c;
        !          1087: }
        !          1088:
        !          1089: void
        !          1090: romttycnputc(dev, c)
        !          1091:        dev_t dev;
        !          1092:        int c;
        !          1093: {
        !          1094:        int s;
        !          1095:
        !          1096: #if 0
        !          1097:        if ((char)c == '\n')
        !          1098:                ROMPUTC('\r');
        !          1099: #endif
        !          1100:        s = splhigh();
        !          1101:        ROMPUTC(c);
        !          1102:        splx(s);
        !          1103: }
        !          1104:
        !          1105: /* taken from NetBSD/luna68k */
        !          1106: void
        !          1107: microtime(tvp)
        !          1108:         register struct timeval *tvp;
        !          1109: {
        !          1110:         int s = splclock();
        !          1111:         static struct timeval lasttime;
        !          1112:
        !          1113:         *tvp = time;
        !          1114: #ifdef notdef
        !          1115:         tvp->tv_usec += clkread();
        !          1116:         while (tvp->tv_usec >= 1000000) {
        !          1117:                 tvp->tv_sec++;
        !          1118:                 tvp->tv_usec -= 1000000;
        !          1119:         }
        !          1120: #endif
        !          1121:         if (tvp->tv_sec == lasttime.tv_sec &&
        !          1122:             tvp->tv_usec <= lasttime.tv_usec &&
        !          1123:             (tvp->tv_usec = lasttime.tv_usec + 1) >= 1000000) {
        !          1124:                 tvp->tv_sec++;
        !          1125:                 tvp->tv_usec -= 1000000;
        !          1126:         }
        !          1127:         lasttime = *tvp;
        !          1128:         splx(s);
        !          1129: }
        !          1130:
        !          1131: /* powerdown */
        !          1132:
        !          1133: struct pio {
        !          1134:        volatile u_int8_t portA;
        !          1135:        volatile unsigned : 24;
        !          1136:        volatile u_int8_t portB;
        !          1137:        volatile unsigned : 24;
        !          1138:        volatile u_int8_t portC;
        !          1139:        volatile unsigned : 24;
        !          1140:        volatile u_int8_t cntrl;
        !          1141:        volatile unsigned : 24;
        !          1142: };
        !          1143:
        !          1144: #define        PIO1_POWER      0x04
        !          1145:
        !          1146: #define        PIO1_ENABLE     0x01
        !          1147: #define        PIO1_DISABLE    0x00
        !          1148:
        !          1149: void
        !          1150: powerdown(void)
        !          1151: {
        !          1152:        struct pio *p1 = (struct pio *)OBIO_PIO1_BASE;
        !          1153:
        !          1154:        DELAY(100000);
        !          1155:        p1->cntrl = (PIO1_POWER << 1) | PIO1_DISABLE;
        !          1156:        *(volatile u_int8_t *)&p1->portC;
        !          1157: }
        !          1158:
        !          1159: /* Get data from FUSE ROM */
        !          1160:
        !          1161: void
        !          1162: get_fuse_rom_data(void)
        !          1163: {
        !          1164:        int i;
        !          1165:        struct fuse_rom_byte *p = (struct fuse_rom_byte *)FUSE_ROM_ADDR;
        !          1166:
        !          1167:        for (i = 0; i < FUSE_ROM_BYTES; i++) {
        !          1168:                fuse_rom_data[i] =
        !          1169:                    (char)((((p->h) >> 24) & 0x000000f0) |
        !          1170:                           (((p->l) >> 28) & 0x0000000f));
        !          1171:                p++;
        !          1172:        }
        !          1173: }
        !          1174:
        !          1175: /* Get data from NVRAM */
        !          1176:
        !          1177: void
        !          1178: get_nvram_data(void)
        !          1179: {
        !          1180:        int i, j;
        !          1181:        u_int8_t *page;
        !          1182:        char buf[NVSYMLEN], *data;
        !          1183:
        !          1184:        if (machtype == LUNA_88K) {
        !          1185:                data = (char *)(NVRAM_ADDR + 0x80);
        !          1186:
        !          1187:                for (i = 0; i < NNVSYM; i++) {
        !          1188:                        for (j = 0; j < NVSYMLEN; j++) {
        !          1189:                                buf[j] = *data;
        !          1190:                                data += 4;
        !          1191:                        }
        !          1192:                        strlcpy(nvram[i].symbol, buf, sizeof(nvram[i].symbol));
        !          1193:
        !          1194:                        for (j = 0; j < NVVALLEN; j++) {
        !          1195:                                buf[j] = *data;
        !          1196:                                data += 4;
        !          1197:                        }
        !          1198:                        strlcpy(nvram[i].value, buf, sizeof(nvram[i].value));
        !          1199:                }
        !          1200:        } else if (machtype == LUNA_88K2) {
        !          1201:                page = (u_int8_t *)(NVRAM_ADDR_88K2 + 0x20);
        !          1202:
        !          1203:                for (i = 0; i < NNVSYM; i++) {
        !          1204:                        *page = (u_int8_t)i;
        !          1205:
        !          1206:                        data = (char *)NVRAM_ADDR_88K2;
        !          1207:                        strlcpy(nvram[i].symbol, data, sizeof(nvram[i].symbol));
        !          1208:
        !          1209:                        data = (char *)(NVRAM_ADDR_88K2 + 0x10);
        !          1210:                        strlcpy(nvram[i].value, data, sizeof(nvram[i].value));
        !          1211:                }
        !          1212:        }
        !          1213: }
        !          1214:
        !          1215: char *
        !          1216: nvram_by_symbol(symbol)
        !          1217:        char *symbol;
        !          1218: {
        !          1219:        char *value;
        !          1220:        int i;
        !          1221:
        !          1222:        value = NULL;
        !          1223:
        !          1224:        for (i = 0; i < NNVSYM; i++) {
        !          1225:                if (strncmp(nvram[i].symbol, symbol, NVSYMLEN) == 0) {
        !          1226:                        value = nvram[i].value;
        !          1227:                        break;
        !          1228:                }
        !          1229:        }
        !          1230:
        !          1231:        return value;
        !          1232: }
        !          1233:
        !          1234: void
        !          1235: setlevel(unsigned int level)
        !          1236: {
        !          1237:        unsigned int set_value;
        !          1238:        int cpu = cpu_number();
        !          1239:
        !          1240:        set_value = int_set_val[level];
        !          1241:
        !          1242: #ifdef MULTIPROCESSOR
        !          1243:        if (cpu != master_cpu)
        !          1244:                set_value &= INT_SLAVE_MASK;
        !          1245: #endif
        !          1246:
        !          1247:        *int_mask_reg[cpu] = set_value;
        !          1248:        luna88k_curspl[cpu] = level;
        !          1249: }
        !          1250:
        !          1251: u_int
        !          1252: getipl(void)
        !          1253: {
        !          1254:        u_int curspl, psr;
        !          1255:
        !          1256:        disable_interrupt(psr);
        !          1257:        curspl = luna88k_curspl[cpu_number()];
        !          1258:        set_psr(psr);
        !          1259:        return curspl;
        !          1260: }
        !          1261:
        !          1262: unsigned
        !          1263: setipl(unsigned level)
        !          1264: {
        !          1265:        unsigned int curspl, psr;
        !          1266:
        !          1267:        disable_interrupt(psr);
        !          1268:        curspl = luna88k_curspl[cpu_number()];
        !          1269:        setlevel(level);
        !          1270:
        !          1271:        /*
        !          1272:         * The flush pipeline is required to make sure the above write gets
        !          1273:         * through the data pipe and to the hardware; otherwise, the next
        !          1274:         * bunch of instructions could execute at the wrong spl protection.
        !          1275:         */
        !          1276:        flush_pipeline();
        !          1277:
        !          1278:        set_psr(psr);
        !          1279:        return curspl;
        !          1280: }
        !          1281:
        !          1282: unsigned
        !          1283: raiseipl(unsigned level)
        !          1284: {
        !          1285:        unsigned int curspl, psr;
        !          1286:
        !          1287:        disable_interrupt(psr);
        !          1288:        curspl = luna88k_curspl[cpu_number()];
        !          1289:        if (curspl < level)
        !          1290:                setlevel(level);
        !          1291:
        !          1292:        /*
        !          1293:         * The flush pipeline is required to make sure the above write gets
        !          1294:         * through the data pipe and to the hardware; otherwise, the next
        !          1295:         * bunch of instructions could execute at the wrong spl protection.
        !          1296:         */
        !          1297:        flush_pipeline();
        !          1298:
        !          1299:        set_psr(psr);
        !          1300:        return curspl;
        !          1301: }

CVSweb