[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     ! 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