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

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

1.1       nbrk        1: /*     $OpenBSD: machdep.c,v 1.93 2007/06/06 17:15:12 deraadt 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: #include <sys/syslog.h>
                     48: #include <sys/extent.h>
                     49: #include <sys/systm.h>
                     50: #include <sys/user.h>
                     51: #include <sys/conf.h>
                     52: #include <sys/core.h>
                     53: #include <sys/kcore.h>
                     54:
                     55: #include <uvm/uvm_extern.h>
                     56:
                     57: #ifdef SYSVMSG
                     58: #include <sys/msg.h>
                     59: #endif
                     60: #include <net/netisr.h>
                     61:
                     62: #include <dev/cons.h>
                     63:
                     64: #include <machine/bat.h>
                     65: #include <machine/pmap.h>
                     66: #include <machine/powerpc.h>
                     67: #include <machine/trap.h>
                     68: #include <machine/autoconf.h>
                     69: #include <machine/bus.h>
                     70: #include <machine/pio.h>
                     71: #include <machine/intr.h>
                     72:
                     73: #include <dev/pci/pcivar.h>
                     74:
                     75: #include <arch/macppc/macppc/ofw_machdep.h>
                     76: #include <dev/ofw/openfirm.h>
                     77:
                     78: #include "adb.h"
                     79: #if NADB > 0
                     80: #include <arch/macppc/dev/adbvar.h>
                     81: #endif
                     82:
                     83: #ifdef DDB
                     84: #include <machine/db_machdep.h>
                     85: #include <ddb/db_access.h>
                     86: #include <ddb/db_sym.h>
                     87: #include <ddb/db_extern.h>
                     88: #endif
                     89:
                     90: /*
                     91:  * Global variables used here and there
                     92:  */
                     93: extern struct user *proc0paddr;
                     94: struct pool ppc_vecpl;
                     95:
                     96: /*
                     97:  * Declare these as initialized data so we can patch them.
                     98:  */
                     99: #ifndef BUFCACHEPERCENT
                    100: #define BUFCACHEPERCENT 5
                    101: #endif
                    102:
                    103: #ifdef BUFPAGES
                    104: int bufpages = BUFPAGES;
                    105: #else
                    106: int bufpages = 0;
                    107: #endif
                    108: int bufcachepercent = BUFCACHEPERCENT;
                    109:
                    110: struct bat battable[16];
                    111:
                    112: struct vm_map *exec_map = NULL;
                    113: struct vm_map *phys_map = NULL;
                    114:
                    115: int ppc_malloc_ok = 0;
                    116:
                    117: #ifndef SYS_TYPE
                    118: /* XXX Hardwire it for now */
                    119: #define SYS_TYPE POWER4e
                    120: #endif
                    121:
                    122: int system_type = SYS_TYPE;    /* XXX Hardwire it for now */
                    123:
                    124: char ofw_eth_addr[6];          /* Save address of first network ifc found */
                    125: char *bootpath;
                    126: char bootpathbuf[512];
                    127:
                    128: struct firmware *fw = NULL;
                    129:
                    130: #ifdef DDB
                    131: void * startsym, *endsym;
                    132: #endif
                    133:
                    134: #ifdef APERTURE
                    135: #ifdef INSECURE
                    136: int allowaperture = 1;
                    137: #else
                    138: int allowaperture = 0;
                    139: #endif
                    140: #endif
                    141:
                    142: void ofw_dbg(char *str);
                    143:
                    144: caddr_t allocsys(caddr_t);
                    145: void dumpsys(void);
                    146: void systype(char *name);
                    147: int lcsplx(int ipl);   /* called from LCore */
                    148: int power4e_get_eth_addr(void);
                    149: void ppc_intr_setup(intr_establish_t *establish,
                    150:     intr_disestablish_t *disestablish);
                    151: void *ppc_intr_establish(void *lcv, pci_intr_handle_t ih, int type,
                    152:     int level, int (*func)(void *), void *arg, char *name);
                    153: int bus_mem_add_mapping(bus_addr_t bpa, bus_size_t size, int cacheable,
                    154:     bus_space_handle_t *bshp);
                    155: bus_addr_t bus_space_unmap_p(bus_space_tag_t t, bus_space_handle_t bsh,
                    156:     bus_size_t size);
                    157: void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
                    158:     bus_size_t size);
                    159:
                    160:
                    161: /*
                    162:  * Extent maps to manage I/O. Allocate storage for 8 regions in each,
                    163:  * initially. Later devio_malloc_safe will indicate that it's safe to
                    164:  * use malloc() to dynamically allocate region descriptors.
                    165:  */
                    166: static long devio_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof (long)];
                    167: struct extent *devio_ex;
                    168: static int devio_malloc_safe = 0;
                    169:
                    170: extern int OF_stdout;
                    171:
                    172: /* XXX, called from asm */
                    173: void initppc(u_int startkernel, u_int endkernel, char *args);
                    174:
                    175: void
                    176: initppc(startkernel, endkernel, args)
                    177:        u_int startkernel, endkernel;
                    178:        char *args;
                    179: {
                    180:        extern void *trapcode; extern int trapsize;
                    181:        extern void *dsitrap; extern int dsisize;
                    182:        extern void *isitrap; extern int isisize;
                    183:        extern void *alitrap; extern int alisize;
                    184:        extern void *decrint; extern int decrsize;
                    185:        extern void *tlbimiss; extern int tlbimsize;
                    186:        extern void *tlbdlmiss; extern int tlbdlmsize;
                    187:        extern void *tlbdsmiss; extern int tlbdsmsize;
                    188: #ifdef DDB
                    189:        extern void *ddblow; extern int ddbsize;
                    190: #endif
                    191:        extern void consinit(void);
                    192:        extern void callback(void *);
                    193:        extern void *msgbuf_addr;
                    194:        int exc, scratch;
                    195:
                    196:        proc0.p_cpu = &cpu_info[0];
                    197:        proc0.p_addr = proc0paddr;
                    198:        bzero(proc0.p_addr, sizeof *proc0.p_addr);
                    199:
                    200:        curpcb = &proc0paddr->u_pcb;
                    201:
                    202:        curpm = curpcb->pcb_pmreal = curpcb->pcb_pm = pmap_kernel();
                    203:
                    204:        ppc_check_procid();
                    205:
                    206:        /*
                    207:         * Initialize BAT registers to unmapped to not generate
                    208:         * overlapping mappings below.
                    209:         */
                    210:        ppc_mtibat0u(0);
                    211:        ppc_mtibat1u(0);
                    212:        ppc_mtibat2u(0);
                    213:        ppc_mtibat3u(0);
                    214:        ppc_mtdbat0u(0);
                    215:        ppc_mtdbat1u(0);
                    216:        ppc_mtdbat2u(0);
                    217:        ppc_mtdbat3u(0);
                    218:
                    219:        /*
                    220:         * Set up initial BAT table to only map the lowest 256 MB area
                    221:         */
                    222:        battable[0].batl = BATL(0x00000000, BAT_M);
                    223:        battable[0].batu = BATU(0x00000000);
                    224:
                    225:        /*
                    226:         * Now setup fixed bat registers
                    227:         *
                    228:         * Note that we still run in real mode, and the BAT
                    229:         * registers were cleared above.
                    230:         */
                    231:        /* IBAT0 used for initial 256 MB segment */
                    232:        ppc_mtibat0l(battable[0].batl);
                    233:        ppc_mtibat0u(battable[0].batu);
                    234:
                    235:        /* DBAT0 used similar */
                    236:        ppc_mtdbat0l(battable[0].batl);
                    237:        ppc_mtdbat0u(battable[0].batu);
                    238:
                    239:        /*
                    240:         * Set up trap vectors
                    241:         */
                    242:        for (exc = EXC_RSVD; exc <= EXC_LAST; exc += 0x100) {
                    243:                switch (exc) {
                    244:                default:
                    245:                        bcopy(&trapcode, (void *)exc, (size_t)&trapsize);
                    246:                        break;
                    247:                case EXC_EXI:
                    248:                        /*
                    249:                         * This one is (potentially) installed during autoconf
                    250:                         */
                    251:                        break;
                    252:
                    253:                case EXC_DSI:
                    254:                        bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize);
                    255:                        break;
                    256:                case EXC_ISI:
                    257:                        bcopy(&isitrap, (void *)EXC_ISI, (size_t)&isisize);
                    258:                        break;
                    259:                case EXC_ALI:
                    260:                        bcopy(&alitrap, (void *)EXC_ALI, (size_t)&alisize);
                    261:                        break;
                    262:                case EXC_DECR:
                    263:                        bcopy(&decrint, (void *)EXC_DECR, (size_t)&decrsize);
                    264:                        break;
                    265:                case EXC_IMISS:
                    266:                        bcopy(&tlbimiss, (void *)EXC_IMISS, (size_t)&tlbimsize);
                    267:                        break;
                    268:                case EXC_DLMISS:
                    269:                        bcopy(&tlbdlmiss, (void *)EXC_DLMISS, (size_t)&tlbdlmsize);
                    270:                        break;
                    271:                case EXC_DSMISS:
                    272:                        bcopy(&tlbdsmiss, (void *)EXC_DSMISS, (size_t)&tlbdsmsize);
                    273:                        break;
                    274:                case EXC_PGM:
                    275:                case EXC_TRC:
                    276:                case EXC_BPT:
                    277: #if defined(DDB)
                    278:                        bcopy(&ddblow, (void *)exc, (size_t)&ddbsize);
                    279: #endif
                    280:                        break;
                    281:                }
                    282:        }
                    283:
                    284:        /* Grr, ALTIVEC_UNAVAIL is a vector not ~0xff aligned: 0x0f20 */
                    285:        bcopy(&trapcode, (void *)0xf20, (size_t)&trapsize);
                    286:
                    287:        /*
                    288:         * since trapsize is > 0x20, we just overwrote the EXC_PERF handler
                    289:         * since we do not use it, we will "share" it with the EXC_VEC,
                    290:         * we dont support EXC_VEC either.
                    291:         * should be a 'ba 0xf20 written' at address 0xf00, but we
                    292:         * do not generate EXC_PERF exceptions...
                    293:         */
                    294:
                    295:        syncicache((void *)EXC_RST, EXC_LAST - EXC_RST + 0x100);
                    296:
                    297:
                    298:        uvmexp.pagesize = 4096;
                    299:        uvm_setpagesize();
                    300:
                    301:        /*
                    302:         * Initialize pmap module.
                    303:         */
                    304:        pmap_bootstrap(startkernel, endkernel);
                    305:
                    306:        /* now that we know physmem size, map physical memory with BATs */
                    307:        if (physmem > btoc(0x10000000)) {
                    308:                battable[0x1].batl = BATL(0x10000000, BAT_M);
                    309:                battable[0x1].batu = BATU(0x10000000);
                    310:        }
                    311:        if (physmem > btoc(0x20000000)) {
                    312:                battable[0x2].batl = BATL(0x20000000, BAT_M);
                    313:                battable[0x2].batu = BATU(0x20000000);
                    314:        }
                    315:        if (physmem > btoc(0x30000000)) {
                    316:                battable[0x3].batl = BATL(0x30000000, BAT_M);
                    317:                battable[0x3].batu = BATU(0x30000000);
                    318:        }
                    319:        if (physmem > btoc(0x40000000)) {
                    320:                battable[0x4].batl = BATL(0x40000000, BAT_M);
                    321:                battable[0x4].batu = BATU(0x40000000);
                    322:        }
                    323:        if (physmem > btoc(0x50000000)) {
                    324:                battable[0x5].batl = BATL(0x50000000, BAT_M);
                    325:                battable[0x5].batu = BATU(0x50000000);
                    326:        }
                    327:        if (physmem > btoc(0x60000000)) {
                    328:                battable[0x6].batl = BATL(0x60000000, BAT_M);
                    329:                battable[0x6].batu = BATU(0x60000000);
                    330:        }
                    331:        if (physmem > btoc(0x70000000)) {
                    332:                battable[0x7].batl = BATL(0x70000000, BAT_M);
                    333:                battable[0x7].batu = BATU(0x70000000);
                    334:        }
                    335:
                    336:        /*
                    337:         * Now enable translation (and machine checks/recoverable interrupts).
                    338:         */
                    339:        (fw->vmon)();
                    340:
                    341:        __asm__ volatile ("eieio; mfmsr %0; ori %0,%0,%1; mtmsr %0; sync;isync"
                    342:                      : "=r"(scratch) : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI));
                    343:
                    344:        /*
                    345:         * use the memory provided by pmap_bootstrap for message buffer
                    346:         */
                    347:        initmsgbuf(msgbuf_addr, MSGBUFSIZE);
                    348:
                    349:        /*
                    350:         * Look at arguments passed to us and compute boothowto.
                    351:         * Default to SINGLE and ASKNAME if no args or
                    352:         * SINGLE and DFLTROOT if this is a ramdisk kernel.
                    353:         */
                    354: #ifdef RAMDISK_HOOKS
                    355:        boothowto = RB_SINGLE | RB_DFLTROOT;
                    356: #else
                    357:        boothowto = RB_AUTOBOOT;
                    358: #endif /* RAMDISK_HOOKS */
                    359:
                    360:        /*
                    361:         * Parse arg string.
                    362:         */
                    363:
                    364:        /* make a copy of the args! */
                    365:        strncpy(bootpathbuf, args, 512);
                    366:        bootpath= &bootpathbuf[0];
                    367:        while ( *++bootpath && *bootpath != ' ');
                    368:        if (*bootpath) {
                    369:                *bootpath++ = 0;
                    370:                while (*bootpath) {
                    371:                        switch (*bootpath++) {
                    372:                        case 'a':
                    373:                                boothowto |= RB_ASKNAME;
                    374:                                break;
                    375:                        case 's':
                    376:                                boothowto |= RB_SINGLE;
                    377:                                break;
                    378:                        case 'd':
                    379:                                boothowto |= RB_KDB;
                    380:                                break;
                    381:                        case 'c':
                    382:                                boothowto |= RB_CONFIG;
                    383:                                break;
                    384:                        default:
                    385:                                break;
                    386:                        }
                    387:                }
                    388:        }
                    389:        bootpath= &bootpathbuf[0];
                    390:
                    391: #ifdef DDB
                    392:        ddb_init();
                    393: #endif
                    394:
                    395:        /*
                    396:         * Set up extents for pci mappings
                    397:         * Is this too late?
                    398:         *
                    399:         * what are good start and end values here??
                    400:         * 0x0 - 0x80000000 mcu bus
                    401:         * MAP A                                MAP B
                    402:         * 0x80000000 - 0xbfffffff io           0x80000000 - 0xefffffff mem
                    403:         * 0xc0000000 - 0xffffffff mem          0xf0000000 - 0xffffffff io
                    404:         *
                    405:         * of course bsd uses 0xe and 0xf
                    406:         * So the BSD PPC memory map will look like this
                    407:         * 0x0 - 0x80000000 memory (whatever is filled)
                    408:         * 0x80000000 - 0xdfffffff (pci space, memory or io)
                    409:         * 0xe0000000 - kernel vm segment
                    410:         * 0xf0000000 - kernel map segment (user space mapped here)
                    411:         */
                    412:
                    413:        devio_ex = extent_create("devio", 0x80000000, 0xffffffff, M_DEVBUF,
                    414:                (caddr_t)devio_ex_storage, sizeof(devio_ex_storage),
                    415:                EX_NOCOALESCE|EX_NOWAIT);
                    416:
                    417:        /*
                    418:         * Now we can set up the console as mapping is enabled.
                    419:         */
                    420:        ofwconsinit();
                    421:        /* while using openfirmware, run userconfig */
                    422:        if (boothowto & RB_CONFIG) {
                    423: #ifdef BOOT_CONFIG
                    424:                user_config();
                    425: #else
                    426:                printf("kernel does not support -c; continuing..\n");
                    427: #endif
                    428:        }
                    429:        /*
                    430:         * Replace with real console.
                    431:         */
                    432:        ofwconprobe();
                    433:        consinit();
                    434:
                    435: #ifdef DDB
                    436:        if (boothowto & RB_KDB)
                    437:                Debugger();
                    438: #endif
                    439:
                    440:        /*
                    441:         * Figure out ethernet address.
                    442:         */
                    443:        (void)power4e_get_eth_addr();
                    444:
                    445:         pool_init(&ppc_vecpl, sizeof(struct vreg), 16, 0, 0, "ppcvec", NULL);
                    446:
                    447: }
                    448: void ofw_dbg(char *str)
                    449: {
                    450:        int i = strlen (str);
                    451:        OF_write(OF_stdout, str, i);
                    452: }
                    453:
                    454:
                    455: void
                    456: install_extint(void (*handler)(void))
                    457: {
                    458:        void extint(void);
                    459:        void extsize(void);
                    460:        extern u_long extint_call;
                    461:        u_long offset = (u_long)handler - (u_long)&extint_call;
                    462:        int omsr, msr;
                    463:
                    464: #ifdef DIAGNOSTIC
                    465:        if (offset > 0x1ffffff)
                    466:                panic("install_extint: too far away");
                    467: #endif
                    468:        omsr = ppc_mfmsr();
                    469:        msr = omsr & ~PSL_EE;
                    470:        ppc_mtmsr(msr);
                    471:        extint_call = (extint_call & 0xfc000003) | offset;
                    472:        bcopy(&extint, (void *)EXC_EXI, (size_t)&extsize);
                    473:        syncicache((void *)&extint_call, sizeof extint_call);
                    474:        syncicache((void *)EXC_EXI, (int)&extsize);
                    475:        ppc_mtmsr(omsr);
                    476: }
                    477:
                    478: /*
                    479:  * Machine dependent startup code.
                    480:  */
                    481: void
                    482: cpu_startup()
                    483: {
                    484:        int sz;
                    485:        caddr_t v;
                    486:        vaddr_t minaddr, maxaddr;
                    487:
                    488:        v = (caddr_t)proc0paddr + USPACE;
                    489:        proc0.p_addr = proc0paddr;
                    490:
                    491:        printf("%s", version);
                    492:
                    493:        printf("real mem = %u (%uMB)\n", ctob(physmem),
                    494:            ctob(physmem)/1024/1024);
                    495:
                    496:        /*
                    497:         * Find out how much space we need, allocate it,
                    498:         * and then give everything true virtual addresses.
                    499:         */
                    500:        sz = (int)allocsys((caddr_t)0);
                    501:        if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0)
                    502:                panic("startup: no room for tables");
                    503:        if (allocsys(v) - v != sz)
                    504:                panic("startup: table size inconsistency");
                    505:
                    506:        /*
                    507:         * Determine how many buffers to allocate.
                    508:         * We allocate bufcachepercent% of memory for buffer space.
                    509:         */
                    510:        if (bufpages == 0)
                    511:                bufpages = physmem * bufcachepercent / 100;
                    512:
                    513:        /* Restrict to at most 25% filled kvm */
                    514:        if (bufpages >
                    515:            (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
                    516:                bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
                    517:                    PAGE_SIZE / 4;
                    518:
                    519:        /*
                    520:         * Allocate a submap for exec arguments.  This map effectively
                    521:         * limits the number of processes exec'ing at any time.
                    522:         */
                    523:        minaddr = vm_map_min(kernel_map);
                    524:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 16 * NCARGS,
                    525:            VM_MAP_PAGEABLE, FALSE, NULL);
                    526:
                    527:        /*
                    528:         * Allocate a submap for physio
                    529:         */
                    530:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
                    531:            VM_PHYS_SIZE, 0, FALSE, NULL);
                    532:        ppc_malloc_ok = 1;
                    533:
                    534:        printf("avail mem = %lu (%luMB)\n", ptoa(uvmexp.free),
                    535:            ptoa(uvmexp.free) / 1024 / 1024);
                    536:
                    537:        /*
                    538:         * Set up the buffers.
                    539:         */
                    540:        bufinit();
                    541:
                    542:        devio_malloc_safe = 1;
                    543: }
                    544:
                    545: /*
                    546:  * Allocate space for system data structures.
                    547:  */
                    548: caddr_t
                    549: allocsys(caddr_t v)
                    550: {
                    551: #define        valloc(name, type, num) \
                    552:        v = (caddr_t)(((name) = (type *)v) + (num))
                    553:
                    554: #ifdef SYSVMSG
                    555:        valloc(msgpool, char, msginfo.msgmax);
                    556:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
                    557:        valloc(msghdrs, struct msg, msginfo.msgtql);
                    558:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
                    559: #endif
                    560:
                    561:        return v;
                    562: }
                    563:
                    564: /*
                    565:  * consinit
                    566:  * Initialize system console.
                    567:  */
                    568: void
                    569: consinit()
                    570: {
                    571:        static int cons_initted = 0;
                    572:
                    573:        if (cons_initted)
                    574:                return;
                    575:        cninit();
                    576:        cons_initted = 1;
                    577: }
                    578:
                    579: /*
                    580:  * Clear registers on exec
                    581:  */
                    582: void
                    583: setregs(struct proc *p, struct exec_package *pack, u_long stack,
                    584:     register_t *retval)
                    585: {
                    586:        u_int32_t newstack;
                    587:        u_int32_t pargs;
                    588:        u_int32_t args[4];
                    589:
                    590:        struct trapframe *tf = trapframe(p);
                    591:        pargs = -roundup(-stack + 8, 16);
                    592:        newstack = (u_int32_t)(pargs - 32);
                    593:
                    594:        copyin ((void *)(VM_MAX_ADDRESS-0x10), &args, 0x10);
                    595:
                    596:        bzero(tf, sizeof *tf);
                    597:        tf->fixreg[1] = newstack;
                    598:        tf->fixreg[3] = retval[0] = args[1];    /* XXX */
                    599:        tf->fixreg[4] = retval[1] = args[0];    /* XXX */
                    600:        tf->fixreg[5] = args[2];                /* XXX */
                    601:        tf->fixreg[6] = args[3];                /* XXX */
                    602:        tf->srr0 = pack->ep_entry;
                    603:        tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT;
                    604:        p->p_addr->u_pcb.pcb_flags = 0;
                    605: }
                    606:
                    607: /*
                    608:  * Send a signal to process.
                    609:  */
                    610: void
                    611: sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
                    612:     union sigval val)
                    613: {
                    614:        struct proc *p = curproc;
                    615:        struct trapframe *tf;
                    616:        struct sigframe *fp, frame;
                    617:        struct sigacts *psp = p->p_sigacts;
                    618:        int oldonstack;
                    619:
                    620:        frame.sf_signum = sig;
                    621:
                    622:        tf = trapframe(p);
                    623:        oldonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
                    624:
                    625:        /*
                    626:         * Allocate stack space for signal handler.
                    627:         */
                    628:        if ((psp->ps_flags & SAS_ALTSTACK)
                    629:            && !oldonstack
                    630:            && (psp->ps_sigonstack & sigmask(sig))) {
                    631:                fp = (struct sigframe *)(psp->ps_sigstk.ss_sp
                    632:                                         + psp->ps_sigstk.ss_size);
                    633:                psp->ps_sigstk.ss_flags |= SS_ONSTACK;
                    634:        } else
                    635:                fp = (struct sigframe *)tf->fixreg[1];
                    636:
                    637:        fp = (struct sigframe *)((int)(fp - 1) & ~0xf);
                    638:
                    639:        /*
                    640:         * Generate signal context for SYS_sigreturn.
                    641:         */
                    642:        frame.sf_sc.sc_onstack = oldonstack;
                    643:        frame.sf_sc.sc_mask = mask;
                    644:        frame.sf_sip = NULL;
                    645:        bcopy(tf, &frame.sf_sc.sc_frame, sizeof *tf);
                    646:        if (psp->ps_siginfo & sigmask(sig)) {
                    647:                frame.sf_sip = &fp->sf_si;
                    648:                initsiginfo(&frame.sf_si, sig, code, type, val);
                    649:        }
                    650:        if (copyout(&frame, fp, sizeof frame) != 0)
                    651:                sigexit(p, SIGILL);
                    652:
                    653:
                    654:        tf->fixreg[1] = (int)fp;
                    655:        tf->lr = (int)catcher;
                    656:        tf->fixreg[3] = (int)sig;
                    657:        tf->fixreg[4] = (psp->ps_siginfo & sigmask(sig)) ? (int)&fp->sf_si : 0;
                    658:        tf->fixreg[5] = (int)&fp->sf_sc;
                    659:        tf->srr0 = p->p_sigcode;
                    660:
                    661: #if WHEN_WE_ONLY_FLUSH_DATA_WHEN_DOING_PMAP_ENTER
                    662:        pmap_extract(vm_map_pmap(&p->p_vmspace->vm_map),tf->srr0, &pa);
                    663:        syncicache(pa, (p->p_emul->e_esigcode - p->p_emul->e_sigcode));
                    664: #endif
                    665: }
                    666:
                    667: /*
                    668:  * System call to cleanup state after a signal handler returns.
                    669:  */
                    670: int
                    671: sys_sigreturn(struct proc *p, void *v, register_t *retval)
                    672: {
                    673:        struct sys_sigreturn_args /* {
                    674:                syscallarg(struct sigcontext *) sigcntxp;
                    675:        } */ *uap = v;
                    676:        struct sigcontext sc;
                    677:        struct trapframe *tf;
                    678:        int error;
                    679:
                    680:        if ((error = copyin(SCARG(uap, sigcntxp), &sc, sizeof sc)))
                    681:                return error;
                    682:        tf = trapframe(p);
                    683:        if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC))
                    684:                return EINVAL;
                    685:        bcopy(&sc.sc_frame, tf, sizeof *tf);
                    686:        if (sc.sc_onstack & 1)
                    687:                p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
                    688:        else
                    689:                p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
                    690:        p->p_sigmask = sc.sc_mask & ~sigcantmask;
                    691:        return EJUSTRETURN;
                    692: }
                    693:
                    694: /*
                    695:  * Machine dependent system variables.
                    696:  * None for now.
                    697:  */
                    698: int
                    699: cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
                    700:     size_t newlen, struct proc *p)
                    701: {
                    702:        /* all sysctl names at this level are terminal */
                    703:        if (namelen != 1)
                    704:                return ENOTDIR;
                    705:        switch (name[0]) {
                    706:        case CPU_ALLOWAPERTURE:
                    707: #ifdef APERTURE
                    708:                if (securelevel > 0)
                    709:                        return (sysctl_int_lower(oldp, oldlenp, newp, newlen,
                    710:                            &allowaperture));
                    711:                else
                    712:                        return (sysctl_int(oldp, oldlenp, newp, newlen,
                    713:                            &allowaperture));
                    714: #else
                    715:                return (sysctl_rdint(oldp, oldlenp, newp, 0));
                    716: #endif
                    717:        case CPU_ALTIVEC:
                    718:                return (sysctl_rdint(oldp, oldlenp, newp, ppc_altivec));
                    719:        default:
                    720:                return EOPNOTSUPP;
                    721:        }
                    722: }
                    723:
                    724:
                    725: u_long dumpmag = 0x04959fca;                   /* magic number */
                    726: int dumpsize = 0;                      /* size of dump in pages */
                    727: long dumplo = -1;                      /* blocks */
                    728:
                    729: /*
                    730:  * This is called by configure to set dumplo and dumpsize.
                    731:  * Dumps always skip the first CLBYTES of disk space
                    732:  * in case there might be a disk label stored there.
                    733:  * If there is extra space, put dump at the end to
                    734:  * reduce the chance that swapping trashes it.
                    735:  */
                    736: void dumpconf(void);
                    737:
                    738: void
                    739: dumpconf(void)
                    740: {
                    741:        int nblks;      /* size of dump area */
                    742:        int i;
                    743:
                    744:        if (dumpdev == NODEV ||
                    745:            (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
                    746:                return;
                    747:        if (nblks <= ctod(1))
                    748:                return;
                    749:
                    750:        /* Always skip the first block, in case there is a label there. */
                    751:        if (dumplo < ctod(1))
                    752:                dumplo = ctod(1);
                    753:
                    754:         for (i = 0; i < ndumpmem; i++)
                    755:                dumpsize = max(dumpsize, dumpmem[i].end);
                    756:
                    757:        /* Put dump at end of partition, and make it fit. */
                    758:        if (dumpsize > dtoc(nblks - dumplo - 1))
                    759:                dumpsize = dtoc(nblks - dumplo - 1);
                    760:        if (dumplo < nblks - ctod(dumpsize) - 1)
                    761:                dumplo = nblks - ctod(dumpsize) - 1;
                    762:
                    763: }
                    764:
                    765: #define BYTES_PER_DUMP  (PAGE_SIZE)  /* must be a multiple of pagesize */
                    766: vaddr_t dumpspace;
                    767:
                    768: int
                    769: reserve_dumppages(caddr_t p)
                    770: {
                    771:        dumpspace = (vaddr_t)p;
                    772:        return BYTES_PER_DUMP;
                    773: }
                    774:
                    775: /*
                    776:  * cpu_dump: dump machine-dependent kernel core dump headers.
                    777:  */
                    778: int cpu_dump(void);
                    779: int
                    780: cpu_dump()
                    781: {
                    782:        int (*dump) (dev_t, daddr64_t, caddr_t, size_t);
                    783:        long buf[dbtob(1) / sizeof (long)];
                    784:        kcore_seg_t     *segp;
                    785:
                    786:        dump = bdevsw[major(dumpdev)].d_dump;
                    787:
                    788:        segp = (kcore_seg_t *)buf;
                    789:
                    790:        /*
                    791:         * Generate a segment header.
                    792:         */
                    793:        CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
                    794:        segp->c_size = dbtob(1) - ALIGN(sizeof(*segp));
                    795:
                    796:        return (dump(dumpdev, dumplo, (caddr_t)buf, dbtob(1)));
                    797: }
                    798:
                    799: void
                    800: dumpsys()
                    801: {
                    802: #if 0
                    803:        u_int npg;
                    804:        u_int i, j;
                    805:        daddr64_t blkno;
                    806:        int (*dump) (dev_t, daddr64_t, caddr_t, size_t);
                    807:        char *str;
                    808:        int maddr;
                    809:        extern int msgbufmapped;
                    810:        int error;
                    811:
                    812:        /* save registers */
                    813:
                    814:        msgbufmapped = 0;       /* don't record dump msgs in msgbuf */
                    815:        if (dumpdev == NODEV)
                    816:                return;
                    817:        /*
                    818:         * For dumps during autoconfiguration,
                    819:         * if dump device has already configured...
                    820:         */
                    821:        if (dumpsize == 0)
                    822:                dumpconf();
                    823:        if (dumplo < 0)
                    824:                return;
                    825:        printf("dumping to dev %x, offset %ld\n", dumpdev, dumplo);
                    826:
                    827:        error = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
                    828:        if (error == -1) {
                    829:                printf("area unavailable\n");
                    830:                delay (10000000);
                    831:                return;
                    832:        }
                    833:
                    834:        dump = bdevsw[major(dumpdev)].d_dump;
                    835:        error = cpu_dump();
                    836:        for (i = 0; !error && i < ndumpmem; i++) {
                    837:                npg = dumpmem[i].end - dumpmem[i].start;
                    838:                maddr = ctob(dumpmem[i].start);
                    839:                blkno = dumplo + btodb(maddr) + 1;
                    840:
                    841:                for (j = npg; j;
                    842:                        j--, maddr += PAGE_SIZE, blkno+= btodb(PAGE_SIZE))
                    843:                {
                    844:                        /* Print out how many MBs we have to go. */
                    845:                         if (dbtob(blkno - dumplo) % (1024 * 1024) < NBPG)
                    846:                                 printf("%d ",
                    847:                                     (ctob(dumpsize) - maddr) / (1024 * 1024));
                    848:
                    849:                        pmap_enter(pmap_kernel(), dumpspace, maddr,
                    850:                                VM_PROT_READ, PMAP_WIRED);
                    851:                        if ((error = (*dump)(dumpdev, blkno,
                    852:                            (caddr_t)dumpspace, PAGE_SIZE)) != 0)
                    853:                                break;
                    854:                }
                    855:        }
                    856:
                    857:        switch (error) {
                    858:
                    859:        case 0:         str = "succeeded\n\n";                  break;
                    860:        case ENXIO:     str = "device bad\n\n";                 break;
                    861:        case EFAULT:    str = "device not ready\n\n";           break;
                    862:        case EINVAL:    str = "area improper\n\n";              break;
                    863:        case EIO:       str = "i/o error\n\n";                  break;
                    864:        case EINTR:     str = "aborted from console\n\n";       break;
                    865:        default:        str = "error %d\n\n";                   break;
                    866:        }
                    867:        printf(str, error);
                    868:
                    869: #else
                    870:        printf("dumpsys() - no yet supported\n");
                    871:
                    872: #endif
                    873:        delay(5000000);         /* 5 seconds */
                    874:
                    875: }
                    876:
                    877: int imask[IPL_NUM];
                    878:
                    879: /*
                    880:  * this is a hack interface to allow zs to work better until
                    881:  * a true soft interrupt mechanism is created.
                    882:  */
                    883: #include "zstty.h"
                    884: #if NZSTTY > 0
                    885:        extern void zssoft(void *);
                    886: #endif
                    887: void
                    888: softtty()
                    889: {
                    890: #if NZSTTY > 0
                    891:        zssoft(0);
                    892: #endif
                    893: }
                    894:
                    895: int netisr;
                    896:
                    897: /*
                    898:  * Soft networking interrupts.
                    899:  */
                    900: void
                    901: softnet(int isr)
                    902: {
                    903: #define DONETISR(flag, func) \
                    904:        if (isr & (1 << flag))\
                    905:                func();
                    906:
                    907: #include <net/netisr_dispatch.h>
                    908: }
                    909:
                    910: int
                    911: lcsplx(int ipl)
                    912: {
                    913:        return spllower(ipl);
                    914: }
                    915:
                    916: /*
                    917:  * Halt or reboot the machine after syncing/dumping according to howto.
                    918:  */
                    919: void
                    920: boot(int howto)
                    921: {
                    922:        static int syncing;
                    923:
                    924:        boothowto = howto;
                    925:        if (!cold && !(howto & RB_NOSYNC) && !syncing) {
                    926:                syncing = 1;
                    927:                vfs_shutdown();         /* sync */
                    928:
                    929:                /*
                    930:                 * If we've been adjusting the clock, the todr
                    931:                 * will be out of synch; adjust it now unless
                    932:                 * the system was sitting in ddb.
                    933:                 */
                    934:                if ((howto & RB_TIMEBAD) == 0) {
                    935:                        resettodr();
                    936:                } else {
                    937:                        printf("WARNING: not updating battery clock\n");
                    938:                }
                    939:        }
                    940:        splhigh();
                    941:        if (howto & RB_HALT) {
                    942:                doshutdownhooks();
                    943:                if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
                    944: #if NADB > 0
                    945:                        delay(1000000);
                    946:                        adb_poweroff();
                    947:                        printf("WARNING: adb powerdown failed!\n");
                    948: #endif
                    949:                        OF_interpret("shut-down", 0);
                    950:                }
                    951:
                    952:                printf("halted\n\n");
                    953:                (fw->exit)();
                    954:        }
                    955:        if (!cold && (howto & RB_DUMP))
                    956:                dumpsys();
                    957:        doshutdownhooks();
                    958:        printf("rebooting\n\n");
                    959:
                    960: #if NADB > 0
                    961:        adb_restart();  /* not return */
                    962: #endif
                    963:
                    964:        OF_interpret("reset-all", 0);
                    965:        OF_exit();
                    966:        printf("boot failed, spinning\n");
                    967:        while(1) /* forever */;
                    968: }
                    969:
                    970: /*
                    971:  *  Get Ethernet address for the onboard ethernet chip.
                    972:  */
                    973: int
                    974: power4e_get_eth_addr()
                    975: {
                    976:        int qhandle, phandle;
                    977:        char name[32];
                    978:
                    979:        for (qhandle = OF_peer(0); qhandle; qhandle = phandle) {
                    980:                if (OF_getprop(qhandle, "device_type", name, sizeof name) >= 0
                    981:                    && !strcmp(name, "network")
                    982:                    && OF_getprop(qhandle, "local-mac-address",
                    983:                                  &ofw_eth_addr, sizeof ofw_eth_addr) >= 0) {
                    984:                        return(0);
                    985:                }
                    986:                if ((phandle = OF_child(qhandle)))
                    987:                        continue;
                    988:                while (qhandle) {
                    989:                        if ((phandle = OF_peer(qhandle)))
                    990:                                break;
                    991:                        qhandle = OF_parent(qhandle);
                    992:                }
                    993:        }
                    994:        return(-1);
                    995: }
                    996:
                    997: typedef void  (void_f) (void);
                    998: void_f *pending_int_f = NULL;
                    999:
                   1000: /* call the bus/interrupt controller specific pending interrupt handler
                   1001:  * would be nice if the offlevel interrupt code was handled here
                   1002:  * instead of being in each of the specific handler code
                   1003:  */
                   1004: void
                   1005: do_pending_int()
                   1006: {
                   1007:        if (pending_int_f != NULL) {
                   1008:                (*pending_int_f)();
                   1009:        }
                   1010: }
                   1011:
                   1012: /*
                   1013:  * set system type from string
                   1014:  */
                   1015: void
                   1016: systype(char *name)
                   1017: {
                   1018:        /* this table may be order specific if substrings match several
                   1019:         * computers but a longer string matches a specific
                   1020:         */
                   1021:        int i;
                   1022:        struct systyp {
                   1023:                char *name;
                   1024:                char *systypename;
                   1025:                int type;
                   1026:        } systypes[] = {
                   1027:                { "MOT",        "(PWRSTK) MCG powerstack family", PWRSTK },
                   1028:                { "V-I Power",  "(POWER4e) V-I ppc vme boards ",  POWER4e},
                   1029:                { "iMac",       "(APPL) Apple iMac ",  APPL},
                   1030:                { "PowerMac",   "(APPL) Apple PowerMac ",  APPL},
                   1031:                { "PowerBook",  "(APPL) Apple Powerbook ",  APPL},
                   1032:                { NULL,"",0}
                   1033:        };
                   1034:        for (i = 0; systypes[i].name != NULL; i++) {
                   1035:                if (strncmp( name , systypes[i].name,
                   1036:                        strlen (systypes[i].name)) == 0)
                   1037:                {
                   1038:                        system_type = systypes[i].type;
                   1039:                        printf("recognized system type of %s as %s\n",
                   1040:                                name, systypes[i].systypename);
                   1041:                        break;
                   1042:                }
                   1043:        }
                   1044:        if (system_type == OFWMACH) {
                   1045:                printf("System type %snot recognized, good luck\n",
                   1046:                        name);
                   1047:        }
                   1048: }
                   1049:
                   1050: /*
                   1051:  * one attempt at interrupt stuff..
                   1052:  *
                   1053:  */
                   1054: #include <dev/pci/pcivar.h>
                   1055:
                   1056: int ppc_configed_intr_cnt = 0;
                   1057: struct intrhand ppc_configed_intr[MAX_PRECONF_INTR];
                   1058:
                   1059: void *
                   1060: ppc_intr_establish(void *lcv, pci_intr_handle_t ih, int type, int level,
                   1061:     int (*func)(void *), void *arg, char *name)
                   1062: {
                   1063:        if (ppc_configed_intr_cnt < MAX_PRECONF_INTR) {
                   1064:                ppc_configed_intr[ppc_configed_intr_cnt].ih_fun = func;
                   1065:                ppc_configed_intr[ppc_configed_intr_cnt].ih_arg = arg;
                   1066:                ppc_configed_intr[ppc_configed_intr_cnt].ih_level = level;
                   1067:                ppc_configed_intr[ppc_configed_intr_cnt].ih_irq = ih;
                   1068:                ppc_configed_intr[ppc_configed_intr_cnt].ih_what = name;
                   1069:                ppc_configed_intr_cnt++;
                   1070:        } else {
                   1071:                panic("ppc_intr_establish called before interrupt controller"
                   1072:                        " configured: driver %s too many interrupts", name);
                   1073:        }
                   1074:        /* disestablish is going to be tricky to supported for these :-) */
                   1075:        return (void *)ppc_configed_intr_cnt;
                   1076: }
                   1077:
                   1078: intr_establish_t *intr_establish_func = (intr_establish_t *)ppc_intr_establish;
                   1079: intr_disestablish_t *intr_disestablish_func;
                   1080:
                   1081: void
                   1082: ppc_intr_setup(intr_establish_t *establish, intr_disestablish_t *disestablish)
                   1083: {
                   1084:        intr_establish_func = establish;
                   1085:        intr_disestablish_func = disestablish;
                   1086: }
                   1087:
                   1088: /* BUS functions */
                   1089: int
                   1090: bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
                   1091:     int cacheable, bus_space_handle_t *bshp)
                   1092: {
                   1093:        int error;
                   1094:
                   1095:        if  (POWERPC_BUS_TAG_BASE(t) == 0) {
                   1096:                /* if bus has base of 0 fail. */
                   1097:                return 1;
                   1098:        }
                   1099:        bpa |= POWERPC_BUS_TAG_BASE(t);
                   1100:        if ((error = extent_alloc_region(devio_ex, bpa, size, EX_NOWAIT |
                   1101:            (ppc_malloc_ok ? EX_MALLOCOK : 0))))
                   1102:                return error;
                   1103:
                   1104:        if ((error  = bus_mem_add_mapping(bpa, size, cacheable, bshp))) {
                   1105:                if (extent_free(devio_ex, bpa, size, EX_NOWAIT |
                   1106:                        (ppc_malloc_ok ? EX_MALLOCOK : 0)))
                   1107:                {
                   1108:                        printf("bus_space_map: pa 0x%lx, size 0x%x\n",
                   1109:                                bpa, size);
                   1110:                        printf("bus_space_map: can't free region\n");
                   1111:                }
                   1112:        }
                   1113:        return 0;
                   1114: }
                   1115: bus_addr_t
                   1116: bus_space_unmap_p(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
                   1117: {
                   1118:        bus_addr_t paddr;
                   1119:
                   1120:        pmap_extract(pmap_kernel(), bsh, &paddr);
                   1121:        bus_space_unmap((t), (bsh), (size));
                   1122:        return paddr ;
                   1123: }
                   1124: void
                   1125: bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
                   1126: {
                   1127:        bus_addr_t sva;
                   1128:        bus_size_t off, len;
                   1129:        bus_addr_t bpa;
                   1130:
                   1131:        /* should this verify that the proper size is freed? */
                   1132:        sva = trunc_page(bsh);
                   1133:        off = bsh - sva;
                   1134:        len = size+off;
                   1135:
                   1136:        if (pmap_extract(pmap_kernel(), sva, &bpa) == TRUE) {
                   1137:                if (extent_free(devio_ex, bpa | (bsh & PAGE_MASK), size, EX_NOWAIT |
                   1138:                        (ppc_malloc_ok ? EX_MALLOCOK : 0)))
                   1139:                {
                   1140:                        printf("bus_space_map: pa 0x%lx, size 0x%x\n",
                   1141:                                bpa, size);
                   1142:                        printf("bus_space_map: can't free region\n");
                   1143:                }
                   1144:        }
                   1145:        /* do not free memory which was stolen from the vm system */
                   1146:        if (ppc_malloc_ok &&
                   1147:            ((sva >= VM_MIN_KERNEL_ADDRESS) && (sva < VM_MAX_KERNEL_ADDRESS)))
                   1148:                uvm_km_free(phys_map, sva, len);
                   1149:        else {
                   1150:                pmap_remove(vm_map_pmap(phys_map), sva, sva+len);
                   1151:                pmap_update(pmap_kernel());
                   1152:        }
                   1153: }
                   1154:
                   1155: vaddr_t ppc_kvm_stolen = VM_KERN_ADDRESS_SIZE;
                   1156:
                   1157: int
                   1158: bus_mem_add_mapping(bus_addr_t bpa, bus_size_t size, int cacheable,
                   1159:     bus_space_handle_t *bshp)
                   1160: {
                   1161:        bus_addr_t vaddr;
                   1162:        bus_addr_t spa, epa;
                   1163:        bus_size_t off;
                   1164:        int len;
                   1165:
                   1166:        spa = trunc_page(bpa);
                   1167:        epa = bpa + size;
                   1168:        off = bpa - spa;
                   1169:        len = size+off;
                   1170:
                   1171: #if 0
                   1172:        if (epa <= spa) {
                   1173:                panic("bus_mem_add_mapping: overflow");
                   1174:        }
                   1175: #endif
                   1176:        if (ppc_malloc_ok == 0) {
                   1177:                bus_size_t alloc_size;
                   1178:
                   1179:                /* need to steal vm space before kernel vm is initialized */
                   1180:                alloc_size = round_page(len);
                   1181:
                   1182:                vaddr = VM_MIN_KERNEL_ADDRESS + ppc_kvm_stolen;
                   1183:                ppc_kvm_stolen += alloc_size;
                   1184:                if (ppc_kvm_stolen > PPC_SEGMENT_LENGTH) {
                   1185:                        panic("ppc_kvm_stolen, out of space");
                   1186:                }
                   1187:        } else {
                   1188:                vaddr = uvm_km_kmemalloc(phys_map, NULL, len,
                   1189:                    UVM_KMF_NOWAIT|UVM_KMF_VALLOC);
                   1190:                if (vaddr == 0)
                   1191:                        panic("bus_mem_add_mapping: kvm alloc of 0x%x failed",
                   1192:                            len);
                   1193:        }
                   1194:        *bshp = vaddr + off;
                   1195: #ifdef DEBUG_BUS_MEM_ADD_MAPPING
                   1196:        printf("mapping %x size %x to %x vbase %x\n",
                   1197:                bpa, size, *bshp, spa);
                   1198: #endif
                   1199:        for (; len > 0; len -= PAGE_SIZE) {
                   1200:                pmap_kenter_cache(vaddr, spa,
                   1201:                        VM_PROT_READ | VM_PROT_WRITE,
                   1202:                        cacheable ? PMAP_CACHE_WT : PMAP_CACHE_CI);
                   1203:                spa += PAGE_SIZE;
                   1204:                vaddr += PAGE_SIZE;
                   1205:        }
                   1206:        return 0;
                   1207: }
                   1208:
                   1209: int
                   1210: bus_space_alloc(bus_space_tag_t tag, bus_addr_t rstart, bus_addr_t rend,
                   1211:     bus_size_t size, bus_size_t alignment, bus_size_t boundary, int cacheable,
                   1212:     bus_addr_t *addrp, bus_space_handle_t *handlep)
                   1213: {
                   1214:
                   1215:        panic("bus_space_alloc: unimplemented");
                   1216: }
                   1217:
                   1218: void
                   1219: bus_space_free(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t size)
                   1220: {
                   1221:
                   1222:        panic("bus_space_free: unimplemented");
                   1223: }
                   1224:
                   1225: void *
                   1226: mapiodev(paddr_t pa, psize_t len)
                   1227: {
                   1228:        paddr_t spa;
                   1229:        vaddr_t vaddr, va;
                   1230:        int off;
                   1231:        int size;
                   1232:
                   1233:        spa = trunc_page(pa);
                   1234:        off = pa - spa;
                   1235:        size = round_page(off+len);
                   1236:        if (ppc_malloc_ok == 0) {
                   1237:                /* need to steal vm space before kernel vm is initialized */
                   1238:                va = VM_MIN_KERNEL_ADDRESS + ppc_kvm_stolen;
                   1239:                ppc_kvm_stolen += size;
                   1240:                if (ppc_kvm_stolen > PPC_SEGMENT_LENGTH) {
                   1241:                        panic("ppc_kvm_stolen, out of space");
                   1242:                }
                   1243:        } else {
                   1244:                va = uvm_km_kmemalloc(phys_map, NULL, size,
                   1245:                    UVM_KMF_NOWAIT|UVM_KMF_VALLOC);
                   1246:        }
                   1247:
                   1248:        if (va == 0)
                   1249:                return NULL;
                   1250:
                   1251:        for (vaddr = va; size > 0; size -= PAGE_SIZE) {
                   1252:                pmap_kenter_cache(vaddr, spa,
                   1253:                        VM_PROT_READ | VM_PROT_WRITE, PMAP_CACHE_DEFAULT);
                   1254:                spa += PAGE_SIZE;
                   1255:                vaddr += PAGE_SIZE;
                   1256:        }
                   1257:        return (void *) (va+off);
                   1258: }
                   1259: void
                   1260: unmapiodev(void *kva, psize_t p_size)
                   1261: {
                   1262:        vaddr_t vaddr;
                   1263:        int size;
                   1264:
                   1265:        size = p_size;
                   1266:
                   1267:        vaddr = trunc_page((vaddr_t)kva);
                   1268:
                   1269:        uvm_km_free_wakeup(phys_map, vaddr, size);
                   1270:
                   1271:        for (; size > 0; size -= PAGE_SIZE) {
                   1272: #if 0
                   1273:                pmap_remove(vm_map_pmap(phys_map), vaddr, vaddr+PAGE_SIZE-1);
                   1274: #else
                   1275:                pmap_remove(pmap_kernel(), vaddr,  vaddr+PAGE_SIZE-1);
                   1276: #endif
                   1277:                vaddr += PAGE_SIZE;
                   1278:        }
                   1279:        pmap_update(pmap_kernel());
                   1280: }
                   1281:
                   1282:
                   1283:
                   1284: /*
                   1285:  * probably should be ppc_space_copy
                   1286:  */
                   1287:
                   1288: #define _CONCAT(A,B) A ## B
                   1289: #define __C(A,B)       _CONCAT(A,B)
                   1290:
                   1291: #define BUS_SPACE_COPY_N(BYTES,TYPE)                                   \
                   1292: void                                                                   \
                   1293: __C(bus_space_copy_,BYTES)(void *v, bus_space_handle_t h1,             \
                   1294:     bus_size_t o1, bus_space_handle_t h2, bus_size_t o2,               \
                   1295:     bus_size_t c)                                                      \
                   1296: {                                                                      \
                   1297:        TYPE *src, *dst;                                                \
                   1298:        int i;                                                          \
                   1299:                                                                        \
                   1300:        src = (TYPE *) (h1+o1);                                         \
                   1301:        dst = (TYPE *) (h2+o2);                                         \
                   1302:                                                                        \
                   1303:        if (h1 == h2 && o2 > o1)                                        \
                   1304:                for (i = c-1; i >= 0; i--)                              \
                   1305:                        dst[i] = src[i];                                \
                   1306:        else                                                            \
                   1307:                for (i = 0; i < c; i++)                                 \
                   1308:                        dst[i] = src[i];                                \
                   1309: }
                   1310: BUS_SPACE_COPY_N(1,u_int8_t)
                   1311: BUS_SPACE_COPY_N(2,u_int16_t)
                   1312: BUS_SPACE_COPY_N(4,u_int32_t)
                   1313:
                   1314: void
                   1315: bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
                   1316:     u_int8_t val, bus_size_t c)
                   1317: {
                   1318:        u_int8_t *dst;
                   1319:        int i;
                   1320:
                   1321:        dst = (u_int8_t *) (h+o);
                   1322:
                   1323:        for (i = 0; i < c; i++)
                   1324:                dst[i] = val;
                   1325: }
                   1326:
                   1327: void
                   1328: bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
                   1329:     u_int16_t val, bus_size_t c)
                   1330: {
                   1331:        u_int16_t *dst;
                   1332:        int i;
                   1333:
                   1334:        dst = (u_int16_t *) (h+o);
                   1335:        val = swap16(val);
                   1336:
                   1337:        for (i = 0; i < c; i++)
                   1338:                dst[i] = val;
                   1339: }
                   1340: void
                   1341: bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
                   1342:     u_int32_t val, bus_size_t c)
                   1343: {
                   1344:        u_int32_t *dst;
                   1345:        int i;
                   1346:
                   1347:        dst = (u_int32_t *) (h+o);
                   1348:        val = swap32(val);
                   1349:
                   1350:        for (i = 0; i < c; i++)
                   1351:                dst[i] = val;
                   1352: }
                   1353:
                   1354: #define BUS_SPACE_READ_RAW_MULTI_N(BYTES,SHIFT,TYPE)                   \
                   1355: void                                                                   \
                   1356: __C(bus_space_read_raw_multi_,BYTES)(bus_space_tag_t bst,              \
                   1357:     bus_space_handle_t h, bus_addr_t o, u_int8_t *dst, bus_size_t size)        \
                   1358: {                                                                      \
                   1359:        TYPE *src;                                                      \
                   1360:        TYPE *rdst = (TYPE *)dst;                                       \
                   1361:        int i;                                                          \
                   1362:        int count = size >> SHIFT;                                      \
                   1363:                                                                        \
                   1364:        src = (TYPE *)(h+o);                                            \
                   1365:        for (i = 0; i < count; i++) {                                   \
                   1366:                rdst[i] = *src;                                         \
                   1367:                __asm__("eieio");                                       \
                   1368:        }                                                               \
                   1369: }
                   1370: BUS_SPACE_READ_RAW_MULTI_N(2,1,u_int16_t)
                   1371: BUS_SPACE_READ_RAW_MULTI_N(4,2,u_int32_t)
                   1372:
                   1373: #define BUS_SPACE_WRITE_RAW_MULTI_N(BYTES,SHIFT,TYPE)                  \
                   1374: void                                                                   \
                   1375: __C(bus_space_write_raw_multi_,BYTES)( bus_space_tag_t bst,            \
                   1376:     bus_space_handle_t h, bus_addr_t o, const u_int8_t *src,           \
                   1377:     bus_size_t size)                                                   \
                   1378: {                                                                      \
                   1379:        int i;                                                          \
                   1380:        TYPE *dst;                                                      \
                   1381:        TYPE *rsrc = (TYPE *)src;                                       \
                   1382:        int count = size >> SHIFT;                                      \
                   1383:                                                                        \
                   1384:        dst = (TYPE *)(h+o);                                            \
                   1385:        for (i = 0; i < count; i++) {                                   \
                   1386:                *dst = rsrc[i];                                         \
                   1387:                __asm__("eieio");                                       \
                   1388:        }                                                               \
                   1389: }
                   1390:
                   1391: BUS_SPACE_WRITE_RAW_MULTI_N(2,1,u_int16_t)
                   1392: BUS_SPACE_WRITE_RAW_MULTI_N(4,2,u_int32_t)
                   1393:
                   1394: int
                   1395: bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
                   1396:     bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
                   1397: {
                   1398:        *nbshp = bsh + offset;
                   1399:        return (0);
                   1400: }
                   1401:
                   1402: int
                   1403: ppc_open_pci_bridge()
                   1404: {
                   1405:        char *
                   1406:        pci_bridges[] = {
                   1407:                "/pci",
                   1408:                NULL
                   1409:        };
                   1410:        int handle;
                   1411:        int i;
                   1412:
                   1413:        for (i = 0; pci_bridges[i] != NULL; i++) {
                   1414:                handle = OF_open(pci_bridges[i]);
                   1415:                if ( handle != -1) {
                   1416:                        return handle;
                   1417:                }
                   1418:        }
                   1419:        return 0;
                   1420: }
                   1421: void
                   1422: ppc_close_pci_bridge(int handle)
                   1423: {
                   1424:        OF_close(handle);
                   1425: }
                   1426:
                   1427: /* bcopy(), error on fault */
                   1428: int
                   1429: kcopy(const void *from, void *to, size_t size)
                   1430: {
                   1431:        faultbuf env;
                   1432:        void *oldh = curproc->p_addr->u_pcb.pcb_onfault;
                   1433:
                   1434:        if (setfault(&env)) {
                   1435:                curproc->p_addr->u_pcb.pcb_onfault = oldh;
                   1436:                return EFAULT;
                   1437:        }
                   1438:        bcopy(from, to, size);
                   1439:        curproc->p_addr->u_pcb.pcb_onfault = oldh;
                   1440:
                   1441:        return 0;
                   1442: }

CVSweb