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

Annotation of sys/arch/mvmeppc/mvmeppc/machdep.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: machdep.c,v 1.53 2007/05/26 20:26:51 pedro Exp $      */
                      2: /*     $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $   */
                      3:
                      4: /*
                      5:  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
                      6:  * Copyright (C) 1995, 1996 TooLs GmbH.
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *     This product includes software developed by TooLs GmbH.
                     20:  * 4. The name of TooLs GmbH may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     26:  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     27:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     28:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     29:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     30:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     31:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     32:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: #include <sys/param.h>
                     36: #include <sys/buf.h>
                     37: #include <sys/timeout.h>
                     38: #include <sys/exec.h>
                     39: #include <sys/malloc.h>
                     40: #include <sys/mbuf.h>
                     41: #include <sys/mount.h>
                     42: #include <sys/msgbuf.h>
                     43: #include <sys/proc.h>
                     44: #include <sys/signalvar.h>
                     45: #include <sys/reboot.h>
                     46: #include <sys/syscallargs.h>
                     47: #ifdef SYSVMSG
                     48: #include <sys/msg.h>
                     49: #endif
                     50: #include <sys/syslog.h>
                     51: #include <sys/extent.h>
                     52: #include <sys/systm.h>
                     53: #include <sys/user.h>
                     54:
                     55: #include <net/netisr.h>
                     56:
                     57: #include <machine/bat.h>
                     58: #include <machine/bugio.h>
                     59: #include <machine/pmap.h>
                     60: #include <machine/powerpc.h>
                     61: #include <machine/trap.h>
                     62: #include <machine/autoconf.h>
                     63: #include <machine/bus.h>
                     64: #include <machine/conf.h>
                     65: #include <machine/pio.h>
                     66: #include <machine/prom.h>
                     67:
                     68: #include <dev/cons.h>
                     69:
                     70: #include <uvm/uvm_extern.h>
                     71:
                     72: #ifdef DDB
                     73: #include <machine/db_machdep.h>
                     74: #include <ddb/db_access.h>
                     75: #include <ddb/db_sym.h>
                     76: #include <ddb/db_extern.h>
                     77: #endif
                     78:
                     79: void initppc(u_int, u_int, char *);
                     80: void dumpsys(void);
                     81: int lcsplx(int);
                     82: void myetheraddr(u_char *);
                     83:
                     84: /*
                     85:  * Global variables used here and there
                     86:  */
                     87: struct pcb *curpcb;
                     88: struct pmap *curpm;
                     89: struct proc *fpuproc;
                     90:
                     91: extern struct user *proc0paddr;
                     92:
                     93: /*
                     94:  * This is to fake out the console routines, while booting.
                     95:  */
                     96: cons_decl(boot);
                     97: #define bootcnpollc nullcnpollc
                     98:
                     99: static struct consdev bootcons = {
                    100:        NULL,
                    101:        NULL,
                    102:        bootcngetc,
                    103:        bootcnputc,
                    104:        bootcnpollc,
                    105:        NULL,
                    106:        makedev(14, 0),
                    107:        CN_NORMAL,
                    108: };
                    109:
                    110: /*
                    111:  * Declare these as initialized data so we can patch them.
                    112:  */
                    113: #ifndef BUFCACHEPERCENT
                    114: #define BUFCACHEPERCENT 5
                    115: #endif
                    116:
                    117: #ifdef BUFPAGES
                    118: int bufpages = BUFPAGES;
                    119: #else
                    120: int bufpages = 0;
                    121: #endif
                    122: int bufcachepercent = BUFCACHEPERCENT;
                    123:
                    124: struct bat battable[16];
                    125:
                    126: struct vm_map *exec_map = NULL;
                    127: struct vm_map *phys_map = NULL;
                    128:
                    129: int ppc_malloc_ok;
                    130:
                    131: #ifndef SYS_TYPE
                    132: /* XXX Hardwire it for now */
                    133: #define SYS_TYPE MVME
                    134: #endif
                    135:
                    136: int system_type = SYS_TYPE;    /* XXX Hardwire it for now */
                    137:
                    138: struct firmware *fw = NULL;
                    139: extern struct firmware ppc1_firmware;
                    140:
                    141: caddr_t allocsys(caddr_t);
                    142:
                    143: /*
                    144:  * Extent maps to manage I/O. Allocate storage for 8 regions in each,
                    145:  * initially. Later devio_malloc_safe will indicate that it's safe to
                    146:  * use malloc() to dynamically allocate region descriptors.
                    147:  */
                    148: static long devio_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof (long)];
                    149: struct extent *devio_ex;
                    150: static int devio_malloc_safe = 0;
                    151:
                    152: void
                    153: initppc(startkernel, endkernel, args)
                    154:        u_int startkernel, endkernel;
                    155:        char *args;
                    156: {
                    157:        extern void *trapcode; extern int trapsize;
                    158:        extern void *dsitrap; extern int dsisize;
                    159:        extern void *isitrap; extern int isisize;
                    160:        extern void *alitrap; extern int alisize;
                    161:        extern void *decrint; extern int decrsize;
                    162:        extern void *tlbimiss; extern int tlbimsize;
                    163:        extern void *tlbdlmiss; extern int tlbdlmsize;
                    164:        extern void *tlbdsmiss; extern int tlbdsmsize;
                    165: #ifdef DDB
                    166:        extern void *ddblow; extern int ddbsize;
                    167: #endif
                    168:        extern void consinit(void);
                    169:        extern void *msgbuf_addr;
                    170:        int exc, scratch;
                    171:
                    172:        proc0.p_addr = proc0paddr;
                    173:        bzero(proc0.p_addr, sizeof *proc0.p_addr);
                    174:
                    175:        fw = &ppc1_firmware; /*  Just PPC1-Bug for now... */
                    176:        buginit();
                    177:
                    178:        curpcb = &proc0paddr->u_pcb;
                    179:
                    180:        curpm = curpcb->pcb_pmreal = curpcb->pcb_pm = pmap_kernel();
                    181:
                    182:        /* startup fake console driver.  It will be replaced by consinit() */
                    183:        cn_tab = &bootcons;
                    184:
                    185:        /*
                    186:         * Initialize BAT registers to unmapped to not generate
                    187:         * overlapping mappings below.
                    188:         */
                    189:        ppc_mtibat0u(0);
                    190:        ppc_mtibat1u(0);
                    191:        ppc_mtibat2u(0);
                    192:        ppc_mtibat3u(0);
                    193:        ppc_mtdbat0u(0);
                    194:        ppc_mtdbat1u(0);
                    195:        ppc_mtdbat2u(0);
                    196:        ppc_mtdbat3u(0);
                    197:
                    198:        /*
                    199:         * Set up initial BAT table
                    200:         */
                    201:        battable[0].batl = BATL(0x00000000, BAT_M);
                    202:        battable[0].batu = BATU(0x00000000);
                    203:
                    204:        /*
                    205:         * Now setup fixed bat registers
                    206:         *
                    207:         * Note that we still run in real mode, and the BAT
                    208:         * registers were cleared above.
                    209:         */
                    210:        /* IBAT0 used for initial 256 MB segment */
                    211:        ppc_mtibat0l(battable[0].batl);
                    212:        ppc_mtibat0u(battable[0].batu);
                    213:
                    214:        /* DBAT0 used similar */
                    215:        ppc_mtdbat0l(battable[0].batl);
                    216:        ppc_mtdbat0u(battable[0].batu);
                    217:
                    218:        /*
                    219:         * Set up trap vectors
                    220:         */
                    221:        for (exc = EXC_RSVD; exc <= EXC_LAST; exc += 0x100) {
                    222:                switch (exc) {
                    223:                default:
                    224:                        bcopy(&trapcode, (void *)exc, (size_t)&trapsize);
                    225:                        break;
                    226:                case EXC_EXI:
                    227:                        /*
                    228:                         * This one is (potentially) installed during autoconf
                    229:                         */
                    230:                        break;
                    231:
                    232:                case EXC_DSI:
                    233:                        bcopy(&dsitrap, (void *)exc, (size_t)&dsisize);
                    234:                        break;
                    235:                case EXC_ISI:
                    236:                        bcopy(&isitrap, (void *)exc, (size_t)&isisize);
                    237:                        break;
                    238:                case EXC_ALI:
                    239:                        bcopy(&alitrap, (void *)exc, (size_t)&alisize);
                    240:                        break;
                    241:                case EXC_DECR:
                    242:                        bcopy(&decrint, (void *)exc, (size_t)&decrsize);
                    243:                        break;
                    244:                case EXC_IMISS:
                    245:                        bcopy(&tlbimiss, (void *)exc, (size_t)&tlbimsize);
                    246:                        break;
                    247:                case EXC_DLMISS:
                    248:                        bcopy(&tlbdlmiss, (void *)exc, (size_t)&tlbdlmsize);
                    249:                        break;
                    250:                case EXC_DSMISS:
                    251:                        bcopy(&tlbdsmiss, (void *)exc, (size_t)&tlbdsmsize);
                    252:                        break;
                    253: #ifdef DDB
                    254:                case EXC_PGM:
                    255:                case EXC_TRC:
                    256:                case EXC_BPT:
                    257:                        bcopy(&ddblow, (void *)exc, (size_t)&ddbsize);
                    258:                        break;
                    259: #endif
                    260:                }
                    261:        }
                    262:
                    263:        /* Grr, ALTIVEC_UNAVAIL is a vector not ~0xff aligned: 0x0f20 */
                    264:        bcopy(&trapcode, (void *)0xf20, (size_t)&trapsize);
                    265:
                    266:        /*
                    267:         * since trapsize is > 0x20, we just overwrote the EXC_PERF handler
                    268:         * since we do not use it, we will "share" it with the EXC_VEC,
                    269:         * we dont support EXC_VEC either.
                    270:         * should be a 'ba 0xf20 written' at address 0xf00, but we
                    271:         * do not generate EXC_PERF exceptions...
                    272:         */
                    273:
                    274:        syncicache((void *)EXC_RST, EXC_LAST - EXC_RST + 0x100);
                    275:
                    276:        /*
                    277:         * Initialize pmap module.
                    278:         */
                    279:        uvmexp.pagesize = 4096;
                    280:        uvm_setpagesize();
                    281:        pmap_bootstrap(startkernel, endkernel);
                    282:
                    283: #if 1
                    284:        /* MVME2[67]00 max out at 256MB, and we need BAT2 for now. */
                    285: #else
                    286:        /* use BATs to map 1GB memory, no pageable BATs now */
                    287:        if (physmem > btoc(0x10000000)) {
                    288:                ppc_mtdbat1l(BATL(0x10000000, BAT_M));
                    289:                ppc_mtdbat1u(BATU(0x10000000));
                    290:        }
                    291:        if (physmem > btoc(0x20000000)) {
                    292:                ppc_mtdbat2l(BATL(0x20000000, BAT_M));
                    293:                ppc_mtdbat2u(BATU(0x20000000));
                    294:        }
                    295:        if (physmem > btoc(0x30000000)) {
                    296:                ppc_mtdbat3l(BATL(0x30000000, BAT_M));
                    297:                ppc_mtdbat3u(BATU(0x30000000));
                    298:        }
                    299: #endif
                    300:
                    301:        /*
                    302:         * Now enable translation (and machine checks/recoverable interrupts).
                    303:         * This will also start using the exception vector prefix of 0x000.
                    304:         */
                    305:        (fw->vmon)();
                    306:
                    307:        __asm__ volatile ("eieio; mfmsr %0; ori %0,%0,%1; mtmsr %0; sync;isync"
                    308:                      : "=r"(scratch) : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI));
                    309:
                    310:        /*
                    311:         * use the memory provided by pmap_bootstrap for message buffer
                    312:         */
                    313:        initmsgbuf(msgbuf_addr, MSGBUFSIZE);
                    314:
                    315: #ifdef DDB
                    316: #ifdef notyet
                    317:        db_machine_init();
                    318: #endif
                    319:        ddb_init();
                    320: #endif
                    321:
                    322:        /*
                    323:         * Set up extents for pci mappings
                    324:         * Is this too late?
                    325:         *
                    326:         * what are good start and end values here??
                    327:         * 0x0 - 0x80000000 mcu bus
                    328:         * MAP A                                MAP B
                    329:         * 0x80000000 - 0xbfffffff io           0x80000000 - 0xefffffff mem
                    330:         * 0xc0000000 - 0xffffffff mem          0xf0000000 - 0xffffffff io
                    331:         *
                    332:         * of course bsd uses 0xe and 0xf
                    333:         * So the BSD PPC memory map will look like this
                    334:         * 0x0 - 0x80000000 memory (whatever is filled)
                    335:         * 0x80000000 - 0xdfffffff (pci space, memory or io)
                    336:         * 0xe0000000 - kernel vm segment
                    337:         * 0xf0000000 - kernel map segment (user space mapped here)
                    338:         */
                    339:
                    340:        devio_ex = extent_create("devio", 0x80000000, 0xffffffff, M_DEVBUF,
                    341:                (caddr_t)devio_ex_storage, sizeof(devio_ex_storage),
                    342:                EX_NOCOALESCE|EX_NOWAIT);
                    343:
                    344:        /*
                    345:         * Now we can set up the console as mapping is enabled.
                    346:         */
                    347:        consinit();
                    348:
                    349:        if (boothowto & RB_CONFIG) {
                    350: #ifdef BOOT_CONFIG
                    351:                user_config();
                    352: #else
                    353:                printf("kernel does not support -c; continuing..\n");
                    354: #endif
                    355:        }
                    356:
                    357: #ifdef DDB
                    358:        if (boothowto & RB_KDB)
                    359:                Debugger();
                    360: #endif
                    361: }
                    362:
                    363: void
                    364: install_extint(handler)
                    365:        void (*handler)(void);
                    366: {
                    367:        extern caddr_t extint, extsize;
                    368:        extern u_long extint_call;
                    369:        u_long offset = (u_long)handler - (u_long)&extint_call;
                    370:        int msr;
                    371:
                    372: #ifdef DIAGNOSTIC
                    373:        if (offset > 0x1ffffff)
                    374:                panic("install_extint: too far away");
                    375: #endif
                    376:        msr = ppc_intr_disable();
                    377:        extint_call = (extint_call & 0xfc000003) | offset;
                    378:        bcopy(&extint, (void *)EXC_EXI, (size_t)&extsize);
                    379:        syncicache((void *)&extint_call, sizeof extint_call);
                    380:        syncicache((void *)EXC_EXI, (int)&extsize);
                    381:        ppc_intr_enable(msr);
                    382: }
                    383:
                    384: /*
                    385:  * Machine dependent startup code.
                    386:  */
                    387: void
                    388: cpu_startup()
                    389: {
                    390:        int sz;
                    391:        caddr_t v;
                    392:        vaddr_t minaddr, maxaddr;
                    393:
                    394:        proc0.p_addr = proc0paddr;
                    395:
                    396:        printf("%s", version);
                    397:
                    398:        printf("real mem = %u (%uMB)\n", ctob(physmem),
                    399:            ctob(physmem)/1024/1024);
                    400:
                    401:        /*
                    402:         * Find out how much space we need, allocate it,
                    403:         * and then give everything true virtual addresses.
                    404:         */
                    405:        sz = (int)allocsys((caddr_t)0);
                    406:        if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0)
                    407:                panic("startup: no room for tables");
                    408:        if (allocsys(v) - v != sz)
                    409:                panic("startup: table size inconsistency");
                    410:
                    411:        /*
                    412:         * Determine how many buffers to allocate.
                    413:         * We allocate bufcachepercent% of memory for buffer space.
                    414:         */
                    415:        if (bufpages == 0)
                    416:                bufpages = physmem * bufcachepercent / 100;
                    417:
                    418:        /* Restrict to at most 25% filled kvm */
                    419:        if (bufpages >
                    420:            (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
                    421:                bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
                    422:                    PAGE_SIZE / 4;
                    423:
                    424:        /*
                    425:         * Allocate a submap for exec arguments.  This map effectively
                    426:         * limits the number of processes exec'ing at any time.
                    427:         */
                    428:        minaddr = vm_map_min(kernel_map);
                    429:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 16 * NCARGS,
                    430:            VM_MAP_PAGEABLE, FALSE, NULL);
                    431:
                    432:        /*
                    433:         * Allocate a submap for physio
                    434:         */
                    435:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
                    436:            VM_PHYS_SIZE, 0, FALSE, NULL);
                    437:        ppc_malloc_ok = 1;
                    438:
                    439:        printf("avail mem = %lu (%luMB)\n", ptoa(uvmexp.free),
                    440:            ptoa(uvmexp.free) / 1024 / 1024);
                    441:
                    442:        /*
                    443:         * Set up the buffers.
                    444:         */
                    445:        bufinit();
                    446:
                    447:        /*
                    448:         * Set up early mappings
                    449:         */
                    450:        devio_malloc_safe = 1;
                    451:        nvram_map();
                    452:        prep_bus_space_init();
                    453: }
                    454:
                    455: /*
                    456:  * Allocate space for system data structures.
                    457:  */
                    458: caddr_t
                    459: allocsys(v)
                    460:        caddr_t v;
                    461: {
                    462: #define        valloc(name, type, num) \
                    463:        v = (caddr_t)(((name) = (type *)v) + (num))
                    464:
                    465: #ifdef SYSVMSG
                    466:        valloc(msgpool, char, msginfo.msgmax);
                    467:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
                    468:        valloc(msghdrs, struct msg, msginfo.msgtql);
                    469:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
                    470: #endif
                    471:
                    472:        return v;
                    473: }
                    474:
                    475: /*
                    476:  * consinit
                    477:  * Initialize system console.
                    478:  */
                    479: void
                    480: consinit()
                    481: {
                    482:        static int cons_initted = 0;
                    483:
                    484:        if (cons_initted)
                    485:                return;
                    486:        cn_tab = NULL;
                    487:        cninit();
                    488:        cons_initted = 1;
                    489: }
                    490:
                    491: /*
                    492:  * Clear registers on exec
                    493:  */
                    494: void
                    495: setregs(p, pack, stack, retval)
                    496:        struct proc *p;
                    497:        struct exec_package *pack;
                    498:        u_long stack;
                    499:        register_t *retval;
                    500: {
                    501:        u_int32_t newstack;
                    502:        u_int32_t pargs;
                    503:        u_int32_t args[4];
                    504:
                    505:        struct trapframe *tf = trapframe(p);
                    506:        pargs = -roundup(-stack + 8, 16);
                    507:        newstack = (u_int32_t)(pargs - 32);
                    508:
                    509:        copyin ((void *)(VM_MAX_ADDRESS-0x10), &args, 0x10);
                    510:
                    511:        bzero(tf, sizeof *tf);
                    512:        tf->fixreg[1] = newstack;
                    513:        tf->fixreg[3] = retval[0] = args[1];    /* XXX */
                    514:        tf->fixreg[4] = retval[1] = args[0];    /* XXX */
                    515:        tf->fixreg[5] = args[2];                /* XXX */
                    516:        tf->fixreg[6] = args[3];                /* XXX */
                    517:        tf->srr0 = pack->ep_entry;
                    518:        tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT;
                    519:        p->p_addr->u_pcb.pcb_flags = 0;
                    520: }
                    521:
                    522: /*
                    523:  * Send a signal to process.
                    524:  */
                    525: void
                    526: sendsig(catcher, sig, mask, code, type, val)
                    527:        sig_t catcher;
                    528:        int sig, mask;
                    529:        u_long code;
                    530:        int type;
                    531:        union sigval val;
                    532: {
                    533:        struct proc *p = curproc;
                    534:        struct trapframe *tf;
                    535:        struct sigframe *fp, frame;
                    536:        struct sigacts *psp = p->p_sigacts;
                    537:        int oldonstack;
                    538:
                    539:        frame.sf_signum = sig;
                    540:
                    541:        tf = trapframe(p);
                    542:        oldonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
                    543:
                    544:        /*
                    545:         * Allocate stack space for signal handler.
                    546:         */
                    547:        if ((psp->ps_flags & SAS_ALTSTACK)
                    548:            && !oldonstack
                    549:            && (psp->ps_sigonstack & sigmask(sig))) {
                    550:                fp = (struct sigframe *)(psp->ps_sigstk.ss_sp
                    551:                                         + psp->ps_sigstk.ss_size);
                    552:                psp->ps_sigstk.ss_flags |= SS_ONSTACK;
                    553:        } else
                    554:                fp = (struct sigframe *)tf->fixreg[1];
                    555:
                    556:        fp = (struct sigframe *)((int)(fp - 1) & ~0xf);
                    557:
                    558:        /*
                    559:         * Generate signal context for SYS_sigreturn.
                    560:         */
                    561:        frame.sf_sc.sc_onstack = oldonstack;
                    562:        frame.sf_sc.sc_mask = mask;
                    563:        frame.sf_sip = NULL;
                    564:        bcopy(tf, &frame.sf_sc.sc_frame, sizeof *tf);
                    565:        if (psp->ps_siginfo & sigmask(sig)) {
                    566:                frame.sf_sip = &fp->sf_si;
                    567:                initsiginfo(&frame.sf_si, sig, code, type, val);
                    568:        }
                    569:        if (copyout(&frame, fp, sizeof frame) != 0)
                    570:                sigexit(p, SIGILL);
                    571:
                    572:
                    573:        tf->fixreg[1] = (int)fp;
                    574:        tf->lr = (int)catcher;
                    575:        tf->fixreg[3] = (int)sig;
                    576:        tf->fixreg[4] = (psp->ps_siginfo & sigmask(sig)) ? (int)&fp->sf_si : 0;
                    577:        tf->fixreg[5] = (int)&fp->sf_sc;
                    578:        tf->srr0 = p->p_sigcode;
                    579:
                    580: #if WHEN_WE_ONLY_FLUSH_DATA_WHEN_DOING_PMAP_ENTER
                    581:        pmap_extract(vm_map_pmap(&p->p_vmspace->vm_map),tf->srr0, &pa);
                    582:        syncicache(pa, (p->p_emul->e_esigcode - p->p_emul->e_sigcode));
                    583: #endif
                    584: }
                    585:
                    586: /*
                    587:  * System call to cleanup state after a signal handler returns.
                    588:  */
                    589: int
                    590: sys_sigreturn(p, v, retval)
                    591:        struct proc *p;
                    592:        void *v;
                    593:        register_t *retval;
                    594: {
                    595:        struct sys_sigreturn_args /* {
                    596:                syscallarg(struct sigcontext *) sigcntxp;
                    597:        } */ *uap = v;
                    598:        struct sigcontext sc;
                    599:        struct trapframe *tf;
                    600:        int error;
                    601:
                    602:        if ((error = copyin(SCARG(uap, sigcntxp), &sc, sizeof sc)) != 0)
                    603:                return error;
                    604:        tf = trapframe(p);
                    605:        if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC))
                    606:                return EINVAL;
                    607:        bcopy(&sc.sc_frame, tf, sizeof *tf);
                    608:        if (sc.sc_onstack & 1)
                    609:                p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
                    610:        else
                    611:                p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
                    612:        p->p_sigmask = sc.sc_mask & ~sigcantmask;
                    613:        return EJUSTRETURN;
                    614: }
                    615:
                    616: /*
                    617:  * Machine dependent system variables.
                    618:  * None for now.
                    619:  */
                    620: int
                    621: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
                    622:        int *name;
                    623:        u_int namelen;
                    624:        void *oldp;
                    625:        size_t *oldlenp;
                    626:        void *newp;
                    627:        size_t newlen;
                    628:        struct proc *p;
                    629: {
                    630:        /* all sysctl names at this level are terminal */
                    631:        if (namelen != 1)
                    632:                return ENOTDIR;
                    633:        switch (name[0]) {
                    634:        default:
                    635:                return EOPNOTSUPP;
                    636:        }
                    637: }
                    638:
                    639: void
                    640: dumpsys()
                    641: {
                    642:        printf("dumpsys: TBD\n");
                    643: }
                    644:
                    645: volatile int cpl, ipending, astpending;
                    646: int imask[IPL_NUM];
                    647: int netisr;
                    648:
                    649: /*
                    650:  * Soft networking interrupts.
                    651:  */
                    652: void
                    653: softnet(isr)
                    654:        int isr;
                    655: {
                    656: #define        DONETISR(flag, func) \
                    657:        if (isr & (1 << (flag))) \
                    658:                (func)();
                    659:
                    660: #include <net/netisr_dispatch.h>
                    661: #undef DONETISR
                    662: }
                    663:
                    664: int
                    665: lcsplx(ipl)
                    666:        int ipl;
                    667: {
                    668:        int oldcpl;
                    669:
                    670:        oldcpl = cpl;
                    671:        splx(ipl);
                    672:        return oldcpl;
                    673: }
                    674:
                    675: /*
                    676:  * Halt or reboot the machine after syncing/dumping according to howto.
                    677:  */
                    678: void
                    679: boot(howto)
                    680:        int howto;
                    681: {
                    682:        static int syncing;
                    683:        static char str[256];
                    684:
                    685:        boothowto = howto;
                    686:        if (!cold && !(howto & RB_NOSYNC) && !syncing) {
                    687:                syncing = 1;
                    688:                vfs_shutdown();         /* sync */
                    689:
                    690:                /*
                    691:                 * If we've been adjusting the clock, the todr
                    692:                 * will be out of synch; adjust it now unless
                    693:                 * the system was sitting in ddb.
                    694:                 */
                    695:                if ((howto & RB_TIMEBAD) == 0) {
                    696:                        resettodr();
                    697:                } else {
                    698:                        printf("WARNING: not updating battery clock\n");
                    699:                }
                    700:        }
                    701:        splhigh();
                    702:        if (howto & RB_HALT) {
                    703:                doshutdownhooks();
                    704:                printf("halted\n\n");
                    705:                (fw->exit)();
                    706:        }
                    707:        if (!cold && (howto & RB_DUMP))
                    708:                dumpsys();
                    709:        doshutdownhooks();
                    710:        printf("rebooting\n\n");
                    711:
                    712:        (fw->boot)(str);
                    713:        for (;;) ;      /* spinning */
                    714: }
                    715:
                    716: /*
                    717:  *  Get Ethernet address for the onboard ethernet chip.
                    718:  */
                    719: void
                    720: myetheraddr(cp)
                    721:        u_char *cp;
                    722: {
                    723:        struct mvmeprom_brdid brdid;
                    724:
                    725:        mvmeprom_brdid(&brdid);
                    726:        bcopy(&brdid.etheraddr, cp, 6);
                    727: }
                    728:
                    729: typedef void  (void_f) (void);
                    730: void_f *pending_int_f = NULL;
                    731:
                    732: /* call the bus/interrupt controller specific pending interrupt handler
                    733:  * would be nice if the offlevel interrupt code was handled here
                    734:  * instead of being in each of the specific handler code
                    735:  */
                    736: void
                    737: do_pending_int()
                    738: {
                    739:        if (pending_int_f != NULL) {
                    740:                (*pending_int_f)();
                    741:        }
                    742: }
                    743:
                    744: /*
                    745:  * one attempt at interrupt stuff..
                    746:  *
                    747:  */
                    748: #include <dev/pci/pcivar.h>
                    749: typedef void     *(intr_establish_t)(void *, pci_intr_handle_t,
                    750:             int, int, int (*func)(void *), void *, char *);
                    751: typedef void     (intr_disestablish_t)(void *, void *);
                    752:
                    753: int ppc_configed_intr_cnt = 0;
                    754: struct intrhand ppc_configed_intr[MAX_PRECONF_INTR];
                    755:
                    756: void *ppc_intr_establish(void *, pci_intr_handle_t, int, int, int (*)(void *),
                    757:     void *, char *);
                    758: void ppc_intr_setup(intr_establish_t *, intr_disestablish_t *);
                    759: void ppc_intr_enable(int);
                    760: int ppc_intr_disable(void);
                    761:
                    762: void *
                    763: ppc_intr_establish(lcv, ih, type, level, func, arg, name)
                    764:        void *lcv;
                    765:        pci_intr_handle_t ih;
                    766:        int type;
                    767:        int level;
                    768:        int (*func)(void *);
                    769:        void *arg;
                    770:        char *name;
                    771: {
                    772:        if (ppc_configed_intr_cnt < MAX_PRECONF_INTR) {
                    773:                ppc_configed_intr[ppc_configed_intr_cnt].ih_fun = func;
                    774:                ppc_configed_intr[ppc_configed_intr_cnt].ih_arg = arg;
                    775:                ppc_configed_intr[ppc_configed_intr_cnt].ih_level = level;
                    776:                ppc_configed_intr[ppc_configed_intr_cnt].ih_irq = ih;
                    777:                ppc_configed_intr[ppc_configed_intr_cnt].ih_what = name;
                    778:                ppc_configed_intr_cnt++;
                    779:        } else {
                    780:                panic("ppc_intr_establish called before interrupt controller"
                    781:                        " configured: driver %s has too many interrupts", name);
                    782:        }
                    783:        /* disestablish is going to be tricky to supported for these :-) */
                    784:        return (void *)ppc_configed_intr_cnt;
                    785: }
                    786:
                    787: intr_establish_t *intr_establish_func = ppc_intr_establish;
                    788: intr_disestablish_t *intr_disestablish_func;
                    789:
                    790: void
                    791: ppc_intr_setup(intr_establish_t *establish, intr_disestablish_t *disestablish)
                    792: {
                    793:        intr_establish_func = establish;
                    794:        intr_disestablish_func = disestablish;
                    795: }
                    796:
                    797: vaddr_t ppc_kvm_stolen = VM_KERN_ADDRESS_SIZE;
                    798:
                    799: void *
                    800: mapiodev(pa, len)
                    801:        paddr_t pa;
                    802:        psize_t len;
                    803: {
                    804:        paddr_t spa;
                    805:        vaddr_t vaddr, va;
                    806:        int off;
                    807:        int size;
                    808:
                    809:        spa = trunc_page(pa);
                    810:        off = pa - spa;
                    811:        size = round_page(off+len);
                    812:
                    813:        if (ppc_malloc_ok == 0) {
                    814:                /* need to steal vm space before kernel vm is initialized */
                    815:                va = VM_MIN_KERNEL_ADDRESS + ppc_kvm_stolen;
                    816:                ppc_kvm_stolen += size;
                    817:                if (ppc_kvm_stolen > PPC_SEGMENT_LENGTH) {
                    818:                        panic("ppc_kvm_stolen: out of space");
                    819:                }
                    820:        } else {
                    821:                va = uvm_km_valloc_wait(phys_map, size);
                    822:        }
                    823:
                    824:        if (va == 0)
                    825:                return NULL;
                    826:
                    827:        for (vaddr = va; size > 0; size -= PAGE_SIZE) {
                    828:                pmap_kenter_cache(vaddr, spa,
                    829:                        VM_PROT_READ | VM_PROT_WRITE, PMAP_CACHE_DEFAULT);
                    830:                spa += PAGE_SIZE;
                    831:                vaddr += PAGE_SIZE;
                    832:        }
                    833:        return (void *) (va+off);
                    834: }
                    835: void
                    836: unmapiodev(kva, p_size)
                    837:        void *kva;
                    838:        psize_t p_size;
                    839: {
                    840:        vaddr_t vaddr;
                    841:        int size;
                    842:
                    843:        size = p_size;
                    844:
                    845:        vaddr = trunc_page((vaddr_t)kva);
                    846:
                    847:        uvm_km_free_wakeup(phys_map, vaddr, size);
                    848:
                    849:        for (; size > 0; size -= PAGE_SIZE) {
                    850:                pmap_remove(pmap_kernel(), vaddr,  vaddr+PAGE_SIZE-1);
                    851:                vaddr += PAGE_SIZE;
                    852:        }
                    853:        pmap_update(pmap_kernel());
                    854: }
                    855:
                    856: /* bcopy(), error on fault */
                    857: int
                    858: kcopy(from, to, size)
                    859:        const void *from;
                    860:        void *to;
                    861:        size_t size;
                    862: {
                    863:        faultbuf env;
                    864:        void *oldh = curproc->p_addr->u_pcb.pcb_onfault;
                    865:
                    866:        if (setfault(&env)) {
                    867:                curproc->p_addr->u_pcb.pcb_onfault = oldh;
                    868:                return EFAULT;
                    869:        }
                    870:        bcopy(from, to, size);
                    871:        curproc->p_addr->u_pcb.pcb_onfault = oldh;
                    872:
                    873:        return 0;
                    874: }

CVSweb