[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

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