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

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

1.1     ! nbrk        1: /*     $OpenBSD: machdep.c,v 1.47 2007/07/18 20:05:25 miod Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2003-2004 Opsycon AB  (www.opsycon.se / www.opsycon.com)
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  *
        !            15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
        !            16:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            18:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
        !            19:  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            20:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            21:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            23:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            25:  * SUCH DAMAGE.
        !            26:  *
        !            27:  */
        !            28: #include <sys/param.h>
        !            29: #include <sys/systm.h>
        !            30: #include <sys/signalvar.h>
        !            31: #include <sys/kernel.h>
        !            32: #include <sys/proc.h>
        !            33: #include <sys/buf.h>
        !            34: #include <sys/reboot.h>
        !            35: #include <sys/conf.h>
        !            36: #include <sys/file.h>
        !            37: #include <sys/malloc.h>
        !            38: #include <sys/mbuf.h>
        !            39: #include <sys/msgbuf.h>
        !            40: #include <sys/ioctl.h>
        !            41: #include <sys/tty.h>
        !            42: #include <sys/user.h>
        !            43: #include <sys/exec.h>
        !            44: #include <sys/sysctl.h>
        !            45: #include <sys/mount.h>
        !            46: #include <sys/syscallargs.h>
        !            47: #include <sys/exec_elf.h>
        !            48: #include <sys/extent.h>
        !            49: #ifdef SYSVSHM
        !            50: #include <sys/shm.h>
        !            51: #endif
        !            52: #ifdef SYSVSEM
        !            53: #include <sys/sem.h>
        !            54: #endif
        !            55: #ifdef SYSVMSG
        !            56: #include <sys/msg.h>
        !            57: #endif
        !            58:
        !            59: #include <uvm/uvm_extern.h>
        !            60:
        !            61: #include <machine/db_machdep.h>
        !            62: #include <ddb/db_interface.h>
        !            63:
        !            64: #include <machine/pte.h>
        !            65: #include <machine/cpu.h>
        !            66: #include <machine/frame.h>
        !            67: #include <machine/pio.h>
        !            68: #include <machine/psl.h>
        !            69: #include <machine/autoconf.h>
        !            70: #include <machine/memconf.h>
        !            71: #include <machine/regnum.h>
        !            72: #if defined(TGT_ORIGIN200) || defined(TGT_ORIGIN2000)
        !            73: #include <machine/mnode.h>
        !            74: #endif
        !            75:
        !            76: #include <mips64/rm7000.h>
        !            77:
        !            78: #include <dev/cons.h>
        !            79:
        !            80: #include <mips64/arcbios.h>
        !            81: #include <mips64/archtype.h>
        !            82: #include <machine/bus.h>
        !            83:
        !            84: #include <sgi/localbus/crimebus.h>
        !            85: #include <sgi/localbus/macebus.h>
        !            86: #if defined(TGT_ORIGIN200) || defined(TGT_ORIGIN2000)
        !            87: #include <sgi/localbus/xbowmux.h>
        !            88: #endif
        !            89:
        !            90: extern struct consdev *cn_tab;
        !            91: extern char kernel_text[];
        !            92: extern int makebootdev(const char *, int);
        !            93: extern void stacktrace(void);
        !            94:
        !            95: #ifdef DEBUG
        !            96: void dump_tlb(void);
        !            97: #endif
        !            98:
        !            99: /* the following is used externally (sysctl_hw) */
        !           100: char   machine[] = MACHINE;            /* machine "architecture" */
        !           101: char   cpu_model[30];
        !           102:
        !           103: /*
        !           104:  * Declare these as initialized data so we can patch them.
        !           105:  */
        !           106: #ifndef        BUFCACHEPERCENT
        !           107: #define        BUFCACHEPERCENT 5       /* Can be changed in config */
        !           108: #endif
        !           109: #ifndef        BUFPAGES
        !           110: #define BUFPAGES 0             /* Can be changed in config */
        !           111: #endif
        !           112:
        !           113: int    bufpages = BUFPAGES;
        !           114: int    bufcachepercent = BUFCACHEPERCENT;
        !           115:
        !           116: vm_map_t exec_map;
        !           117: vm_map_t phys_map;
        !           118:
        !           119: int    extent_malloc_flags = 0;
        !           120:
        !           121: caddr_t        msgbufbase;
        !           122:
        !           123: int    physmem;                /* max supported memory, changes to actual */
        !           124: int    rsvdmem;                /* reserved memory not usable */
        !           125: int    ncpu = 1;               /* At least one cpu in the system */
        !           126: struct user *proc0paddr;
        !           127: struct user *curprocpaddr;
        !           128: int    console_ok;             /* set when console initialized */
        !           129: int    bootdriveoffs = 0;
        !           130:
        !           131: int32_t *environment;
        !           132: struct sys_rec sys_config;
        !           133:
        !           134:
        !           135: /* ddb symbol init stuff */
        !           136: caddr_t        ssym;
        !           137: caddr_t        esym;
        !           138: caddr_t        ekern;
        !           139:
        !           140: struct phys_mem_desc mem_layout[MAXMEMSEGS];
        !           141:
        !           142: void crime_configure_memory(void);
        !           143:
        !           144: caddr_t mips_init(int, void *);
        !           145: void initcpu(void);
        !           146: void dumpsys(void);
        !           147: void dumpconf(void);
        !           148: caddr_t allocsys(caddr_t);
        !           149:
        !           150: void db_command_loop(void);
        !           151:
        !           152: static void dobootopts(int, void *);
        !           153: static int atoi(const char *, int, const char **);
        !           154:
        !           155: #if BYTE_ORDER == BIG_ENDIAN
        !           156: int    my_endian = 1;
        !           157: #else
        !           158: int    my_endian = 0;
        !           159: #endif
        !           160:
        !           161: #if defined(TGT_O2)
        !           162: void
        !           163: crime_configure_memory(void)
        !           164: {
        !           165:        struct phys_mem_desc *m;
        !           166:        volatile u_int64_t *bank_ctrl;
        !           167:        paddr_t addr;
        !           168:        psize_t size;
        !           169:        u_int32_t first_page, last_page;
        !           170:        int bank, i;
        !           171:
        !           172:        bank_ctrl = (void *)PHYS_TO_KSEG1(CRIMEBUS_BASE + CRIME_MEM_BANK0_CONTROL);
        !           173:        for (bank = 0; bank < CRIME_MAX_BANKS; bank++) {
        !           174:                addr = (bank_ctrl[bank] & CRIME_MEM_BANK_ADDR) << 25;
        !           175:                size = (bank_ctrl[bank] & CRIME_MEM_BANK_128MB) ? 128 : 32;
        !           176: #ifdef DEBUG
        !           177:                bios_printf("crime: bank %d contains %ld MB at 0x%lx\n",
        !           178:                    bank, size, addr);
        !           179: #endif
        !           180:
        !           181:                /*
        !           182:                 * Do not report memory regions below 256MB, since
        !           183:                 * arcbios will do. Moreover, empty banks are reported
        !           184:                 * at address zero.
        !           185:                 */
        !           186:                if (addr < 256 * 1024 * 1024)
        !           187:                        continue;
        !           188:
        !           189:                addr += 1024 * 1024 * 1024;
        !           190:                size *= 1024 * 1024;
        !           191:                first_page = atop(addr);
        !           192:                last_page = atop(addr + size);
        !           193:
        !           194:                /*
        !           195:                 * Try to coalesce with other memory segments if banks
        !           196:                 * are contiguous.
        !           197:                 */
        !           198:                m = NULL;
        !           199:                for (i = 0; i < MAXMEMSEGS; i++) {
        !           200:                        if (mem_layout[i].mem_last_page == 0) {
        !           201:                                if (m == NULL)
        !           202:                                        m = &mem_layout[i];
        !           203:                        } else if (last_page == mem_layout[i].mem_first_page) {
        !           204:                                m = &mem_layout[i];
        !           205:                                m->mem_first_page = first_page;
        !           206:                        } else if (mem_layout[i].mem_last_page == first_page) {
        !           207:                                m = &mem_layout[i];
        !           208:                                m->mem_last_page = last_page;
        !           209:                        }
        !           210:                }
        !           211:                if (m != NULL && m->mem_last_page == 0) {
        !           212:                        m->mem_first_page = first_page;
        !           213:                        m->mem_last_page = last_page;
        !           214:                }
        !           215:                if (m != NULL)
        !           216:                        physmem += atop(size);
        !           217:        }
        !           218:
        !           219: #ifdef DEBUG
        !           220:        for (i = 0; i < MAXMEMSEGS; i++)
        !           221:                if (mem_layout[i].mem_first_page)
        !           222:                        bios_printf("MEM %d, 0x%x to  0x%x\n",i,
        !           223:                                ptoa(mem_layout[i].mem_first_page),
        !           224:                                ptoa(mem_layout[i].mem_last_page));
        !           225: #endif
        !           226: }
        !           227: #endif
        !           228:
        !           229: /*
        !           230:  * Do all the stuff that locore normally does before calling main().
        !           231:  * Reset mapping and set up mapping to hardware and init "wired" reg.
        !           232:  */
        !           233:
        !           234: caddr_t
        !           235: mips_init(int argc, void *argv)
        !           236: {
        !           237:        char *cp;
        !           238:        int i;
        !           239:        caddr_t sd;
        !           240:        extern char start[], edata[], end[];
        !           241:        extern char tlb_miss_tramp[], e_tlb_miss_tramp[];
        !           242:        extern char xtlb_miss_tramp[], e_xtlb_miss_tramp[];
        !           243:        extern char exception[], e_exception[];
        !           244:
        !           245:        /*
        !           246:         * Make sure we can access the extended address space.
        !           247:         * Note that r10k and later do not allow XUSEG accesses
        !           248:         * from kernel mode unless SR_UX is set.
        !           249:         */
        !           250:        setsr(getsr() | SR_KX | SR_UX);
        !           251:
        !           252:        /*
        !           253:         * Clear the compiled BSS segment in OpenBSD code
        !           254:         */
        !           255:        bzero(edata, end - edata);
        !           256:
        !           257:        /*
        !           258:         *  Reserve symbol table space. If invalid pointers no table.
        !           259:         */
        !           260:        ssym = (char *)*(u_int64_t *)end;
        !           261:        esym = (char *)*((u_int64_t *)end + 1);
        !           262:        ekern = esym;
        !           263:        if (((long)ssym - (long)end) < 0 ||
        !           264:            ((long)ssym - (long)end) > 0x1000 ||
        !           265:            ssym[0] != ELFMAG0 || ssym[1] != ELFMAG1 ||
        !           266:            ssym[2] != ELFMAG2 || ssym[3] != ELFMAG3 ) {
        !           267:                ssym = NULL;
        !           268:                esym = NULL;
        !           269:                ekern = end;
        !           270:        }
        !           271:
        !           272:        /*
        !           273:         *  Initialize the system type and set up memory layout
        !           274:         *  Note that some systems have more complex memory setup.
        !           275:         */
        !           276:        bios_ident();
        !           277:
        !           278: bios_printf("SR=%08x\n", getsr()); /* leave this in for now. need to see sr */
        !           279:
        !           280:        /*
        !           281:         * Determine system type and set up configuration record data.
        !           282:         */
        !           283:        switch (sys_config.system_type) {
        !           284: #if defined(TGT_O2)
        !           285:        case SGI_O2:
        !           286:                bios_printf("Found SGI-IP32, setting up.\n");
        !           287:                strlcpy(cpu_model, "SGI-O2 (IP32)", sizeof(cpu_model));
        !           288:                sys_config.cons_ioaddr[0] = MACE_ISA_SER1_OFFS;
        !           289:                sys_config.cons_ioaddr[1] = MACE_ISA_SER2_OFFS;
        !           290:                sys_config.cons_baudclk = 1843200;              /*XXX*/
        !           291:                sys_config.cons_iot = &macebus_tag;
        !           292:                sys_config.local.bus_base = 0x0;                /*XXX*/
        !           293:                sys_config.pci_io[0].bus_base = 0xffffffff00000000;/*XXX*/
        !           294:                sys_config.pci_mem[0].bus_base = 0xffffffff00000000;/*XXX*/
        !           295:                sys_config.pci_mem[0].bus_base_dma = 0x00000000;/*XXX*/
        !           296:                sys_config.pci_mem[0].bus_reverse = my_endian;
        !           297:                sys_config.cpu[0].tlbwired = 2;
        !           298:
        !           299:                crime_configure_memory();
        !           300:
        !           301:                sys_config.cpu[0].clock = 180000000;  /* Reasonable default */
        !           302:                cp = Bios_GetEnvironmentVariable("cpufreq");
        !           303:                if (cp && atoi(cp, 10, NULL) > 100)
        !           304:                        sys_config.cpu[0].clock = atoi(cp, 10, NULL) * 1000000;
        !           305:
        !           306:                /* R1xK O2's are one disk slot machines. Offset slotno */
        !           307:                switch ((cp0_get_prid() >> 8) & 0xff) {
        !           308:                case MIPS_R10000:
        !           309:                case MIPS_R12000:
        !           310:                        bootdriveoffs = -1;
        !           311:                        break;
        !           312:                }
        !           313:                /* R12K O2's must run with DSD on */
        !           314:                switch ((cp0_get_prid() >> 8) & 0xff) {
        !           315:                case MIPS_R12000:
        !           316:                        setsr(getsr() | SR_DSD);
        !           317:                        break;
        !           318:                }
        !           319:                break;
        !           320: #endif
        !           321:
        !           322: #if defined(TGT_ORIGIN200) || defined(TGT_ORIGIN2000)
        !           323:        case SGI_O200:
        !           324:                bios_printf("Found SGI-IP27, setting up.\n");
        !           325:                strlcpy(cpu_model, "SGI- Origin200 (IP27)", sizeof(cpu_model));
        !           326:
        !           327:                kl_scan_config(0);
        !           328:
        !           329:                sys_config.cons_ioaddr[0] = kl_get_console_base();
        !           330:                sys_config.cons_ioaddr[1] = kl_get_console_base() - 8;
        !           331:                sys_config.cons_baudclk = 22000000 / 3; /*XXX*/
        !           332:                sys_config.cons_iot = &xbowmux_tag;
        !           333:                sys_config.local.bus_base = 0x0;                /*XXX*/
        !           334:                sys_config.pci_io[0].bus_base = 0xffffffff00000000;/*XXX*/
        !           335:                sys_config.pci_mem[0].bus_base = 0xffffffff00000000;/*XXX*/
        !           336:                sys_config.pci_mem[0].bus_base_dma = 0x00000000;/*XXX*/
        !           337:                sys_config.pci_mem[0].bus_reverse = my_endian;
        !           338:                sys_config.cpu[0].tlbwired = 2;
        !           339:                break;
        !           340: #endif
        !           341:
        !           342:        default:
        !           343:                bios_printf("Kernel doesn't support this system type!\n");
        !           344:                bios_printf("Halting system.\n");
        !           345:                Bios_Halt();
        !           346:                while(1);
        !           347:        }
        !           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_SINGLE | RB_ASKNAME;
        !           358: #endif /* RAMDISK_HOOKS */
        !           359:
        !           360:        dobootopts(argc, argv);
        !           361:
        !           362:        /*
        !           363:         *  Figure out where we was booted from.
        !           364:         */
        !           365:        cp = Bios_GetEnvironmentVariable("OSLoadPartition");
        !           366:        if (cp == NULL)
        !           367:                cp = "unknown";
        !           368:        if (makebootdev(cp, bootdriveoffs))
        !           369:                bios_printf("Boot device unrecognized: '%s'\n", cp);
        !           370:
        !           371:        /*
        !           372:         * Read platform-specific environment variables.
        !           373:         */
        !           374:        switch (sys_config.system_type) {
        !           375: #if defined(TGT_O2)
        !           376:        case SGI_O2:
        !           377:                /* get ethernet address from ARCBIOS */
        !           378:                cp = Bios_GetEnvironmentVariable("eaddr");
        !           379:                if (cp != NULL && strlen(cp) > 0)
        !           380:                        strlcpy(bios_enaddr, cp, sizeof bios_enaddr);
        !           381:                break;
        !           382: #endif
        !           383:        default:
        !           384:                break;
        !           385:        }
        !           386:
        !           387:        /*
        !           388:         *  Set pagesize to enable use of page macros and functions.
        !           389:         *  Commit available memory to UVM system
        !           390:         */
        !           391:        uvmexp.pagesize = PAGE_SIZE;
        !           392:        uvm_setpagesize();
        !           393:
        !           394:        for (i = 0; i < MAXMEMSEGS && mem_layout[i].mem_first_page != 0; i++) {
        !           395:                u_int32_t fp, lp;
        !           396:                u_int32_t firstkernpage, lastkernpage;
        !           397:                paddr_t firstkernpa, lastkernpa;
        !           398:
        !           399:                if (IS_XKPHYS((vaddr_t)start))
        !           400:                        firstkernpa = XKPHYS_TO_PHYS((vaddr_t)start);
        !           401:                else
        !           402:                        firstkernpa = KSEG0_TO_PHYS((vaddr_t)start);
        !           403:                if (IS_XKPHYS((vaddr_t)ekern))
        !           404:                        lastkernpa = XKPHYS_TO_PHYS((vaddr_t)ekern);
        !           405:                else
        !           406:                        lastkernpa = KSEG0_TO_PHYS((vaddr_t)ekern);
        !           407:
        !           408:                firstkernpage = atop(trunc_page(firstkernpa));
        !           409:                lastkernpage = atop(round_page(lastkernpa));
        !           410:
        !           411:                fp = mem_layout[i].mem_first_page;
        !           412:                lp = mem_layout[i].mem_last_page;
        !           413:
        !           414:                /* Account for kernel and kernel symbol table */
        !           415:                if (fp >= firstkernpage && lp < lastkernpage)
        !           416:                        continue;       /* In kernel */
        !           417:
        !           418:                if (lp < firstkernpage || fp > lastkernpage) {
        !           419:                        uvm_page_physload(fp, lp, fp, lp, VM_FREELIST_DEFAULT);
        !           420:                        continue;       /* Outside kernel */
        !           421:                }
        !           422:
        !           423:                if (fp >= firstkernpage)
        !           424:                        fp = lastkernpage;
        !           425:                else if (lp < lastkernpage)
        !           426:                        lp = firstkernpage;
        !           427:                else { /* Need to split! */
        !           428:                        u_int32_t xp = firstkernpage;
        !           429:                        uvm_page_physload(fp, xp, fp, xp, VM_FREELIST_DEFAULT);
        !           430:                        fp = lastkernpage;
        !           431:                }
        !           432:                if (lp >= fp)
        !           433:                        uvm_page_physload(fp, lp, fp, lp, VM_FREELIST_DEFAULT);
        !           434:        }
        !           435:
        !           436:
        !           437:        switch (sys_config.system_type) {
        !           438: #if defined(TGT_O2)
        !           439:        case SGI_O2:
        !           440:                sys_config.cpu[0].type = (cp0_get_prid() >> 8) & 0xff;
        !           441:                sys_config.cpu[0].vers_maj = (cp0_get_prid() >> 4) & 0x0f;
        !           442:                sys_config.cpu[0].vers_min = cp0_get_prid() & 0x0f;
        !           443:                sys_config.cpu[0].fptype = (cp1_get_prid() >> 8) & 0xff;
        !           444:                sys_config.cpu[0].fpvers_maj = (cp1_get_prid() >> 4) & 0x0f;
        !           445:                sys_config.cpu[0].fpvers_min = cp1_get_prid() & 0x0f;
        !           446:
        !           447:                /*
        !           448:                 *  Configure TLB.
        !           449:                 */
        !           450:                switch(sys_config.cpu[0].type) {
        !           451:                case MIPS_RM7000:
        !           452:                        /* Rev A (version >= 2) CPU's have 64 TLB entries. */
        !           453:                        if (sys_config.cpu[0].vers_maj < 2) {
        !           454:                                sys_config.cpu[0].tlbsize = 48;
        !           455:                        } else {
        !           456:                                sys_config.cpu[0].tlbsize = 64;
        !           457:                        }
        !           458:                        break;
        !           459:
        !           460:                case MIPS_R10000:
        !           461:                case MIPS_R12000:
        !           462:                        sys_config.cpu[0].tlbsize = 64;
        !           463:                        break;
        !           464:
        !           465:                default:
        !           466:                        sys_config.cpu[0].tlbsize = 48;
        !           467:                        break;
        !           468:                }
        !           469:                break;
        !           470: #endif
        !           471:        default:
        !           472:                break;
        !           473:        }
        !           474:
        !           475:        /*
        !           476:         *  Configure Cache.
        !           477:         */
        !           478:        switch(sys_config.cpu[0].type) {
        !           479:        case MIPS_R10000:
        !           480:        case MIPS_R12000:
        !           481:        case MIPS_R14000:
        !           482:                sys_config.cpu[0].cfg_reg = Mips10k_ConfigCache();
        !           483:                sys_config._SyncCache = Mips10k_SyncCache;
        !           484:                sys_config._InvalidateICache = Mips10k_InvalidateICache;
        !           485:                sys_config._InvalidateICachePage = Mips10k_InvalidateICachePage;
        !           486:                sys_config._SyncDCachePage = Mips10k_SyncDCachePage;
        !           487:                sys_config._HitSyncDCache = Mips10k_HitSyncDCache;
        !           488:                sys_config._IOSyncDCache = Mips10k_IOSyncDCache;
        !           489:                sys_config._HitInvalidateDCache = Mips10k_HitInvalidateDCache;
        !           490:                break;
        !           491:
        !           492:        default:
        !           493:                sys_config.cpu[0].cfg_reg = Mips5k_ConfigCache();
        !           494:                sys_config._SyncCache = Mips5k_SyncCache;
        !           495:                sys_config._InvalidateICache = Mips5k_InvalidateICache;
        !           496:                sys_config._InvalidateICachePage = Mips5k_InvalidateICachePage;
        !           497:                sys_config._SyncDCachePage = Mips5k_SyncDCachePage;
        !           498:                sys_config._HitSyncDCache = Mips5k_HitSyncDCache;
        !           499:                sys_config._IOSyncDCache = Mips5k_IOSyncDCache;
        !           500:                sys_config._HitInvalidateDCache = Mips5k_HitInvalidateDCache;
        !           501:                break;
        !           502:        }
        !           503:
        !           504:        /*
        !           505:         *  Last chance to call the bios. Wiping the TLB means
        !           506:         *  bios data areas are demapped on most systems.
        !           507:         *  O2's are OK. Does not have mapped bios text or data.
        !           508:         */
        !           509:        delay(20*1000);         /* Let any uart fifo drain... */
        !           510:        tlb_set_wired(0);
        !           511:        tlb_flush(sys_config.cpu[0].tlbsize);
        !           512:        tlb_set_wired(sys_config.cpu[0].tlbwired);
        !           513:
        !           514: #if 0
        !           515:        /* XXX Save the following as an example on how to optimize I/O mapping */
        !           516:
        !           517:        /*
        !           518:         *  Set up some fixed mappings. These are so frequently
        !           519:         *  used so faulting them in will waste to many cycles.
        !           520:         */
        !           521:        if (sys_config.system_type == MOMENTUM_CP7000G ||
        !           522:            sys_config.system_type == MOMENTUM_CP7000 ||
        !           523:            sys_config.system_type == GALILEO_EV64240) {
        !           524:                struct tlb tlb;
        !           525:
        !           526:                tlb.tlb_mask = PG_SIZE_16M;
        !           527: #if defined(LP64)
        !           528:                tlb.tlb_hi = vad_to_vpn(0xfffffffffc000000) | 1;
        !           529:                tlb.tlb_lo0 = vad_to_pfn(0xfffffffff4000000) | PG_IOPAGE;
        !           530: #else
        !           531:                tlb.tlb_hi = vad_to_vpn(0xfc000000) | 1;
        !           532:                tlb.tlb_lo0 = vad_to_pfn(0xf4000000) | PG_IOPAGE;
        !           533: #endif
        !           534:                tlb.tlb_lo1 = vad_to_pfn(sys_config.cons_ioaddr[0]) | PG_IOPAGE;
        !           535:                tlb_write_indexed(2, &tlb);
        !           536:
        !           537:                if (sys_config.system_type == GALILEO_EV64240) {
        !           538:                        tlb.tlb_mask = PG_SIZE_16M;
        !           539:                        tlb.tlb_hi = vad_to_vpn(0xf8000000) | 1;
        !           540:                        tlb.tlb_lo0 = vad_to_pfn(sys_config.pci_io[0].bus_base) | PG_IOPAGE;
        !           541:                        tlb.tlb_lo1 = vad_to_pfn(sys_config.pci_mem[0].bus_base) | PG_IOPAGE;
        !           542:                        tlb_write_indexed(3, &tlb);
        !           543:                }
        !           544:        }
        !           545: /* XXX */
        !           546: #endif
        !           547:
        !           548: #if defined(TGT_ORIGIN200) || defined(TGT_ORIGIN2000)
        !           549:        /*
        !           550:         *  If an IP27 system set up Node 0's HUB.
        !           551:         */
        !           552:        if (sys_config.system_type == SGI_O200) {
        !           553:                IP27_LHUB_S(PI_REGION_PRESENT, 1);
        !           554:                IP27_LHUB_S(PI_CALIAS_SIZE, PI_CALIAS_SIZE_0);
        !           555:        }
        !           556: #endif
        !           557:
        !           558:        /*
        !           559:         *  Get a console, very early but after initial mapping setup.
        !           560:         */
        !           561:        consinit();
        !           562:        printf("Initial setup done, switching console.\n");
        !           563:
        !           564:        /*
        !           565:         * Init message buffer.
        !           566:         */
        !           567:        msgbufbase = (caddr_t)pmap_steal_memory(MSGBUFSIZE, NULL,NULL);
        !           568:        initmsgbuf(msgbufbase, MSGBUFSIZE);
        !           569:
        !           570:        /*
        !           571:         * Allocate U page(s) for proc[0], pm_tlbpid 1.
        !           572:         */
        !           573:        proc0.p_addr = proc0paddr = curprocpaddr =
        !           574:            (struct user *)pmap_steal_memory(USPACE, NULL, NULL);
        !           575:        proc0.p_md.md_regs = (struct trap_frame *)&proc0paddr->u_pcb.pcb_regs;
        !           576:        tlb_set_pid(1);
        !           577:
        !           578:        /*
        !           579:         * Allocate system data structures.
        !           580:         */
        !           581:        i = (vsize_t)allocsys(NULL);
        !           582:        sd = (caddr_t)pmap_steal_memory(i, NULL, NULL);
        !           583:        allocsys(sd);
        !           584:
        !           585:        /*
        !           586:         * Bootstrap VM system.
        !           587:         */
        !           588:        pmap_bootstrap();
        !           589:
        !           590:
        !           591:        /*
        !           592:         * Copy down exception vector code.
        !           593:         */
        !           594:        bcopy(tlb_miss_tramp, (char *)TLB_MISS_EXC_VEC,
        !           595:            e_tlb_miss_tramp - tlb_miss_tramp);
        !           596:        bcopy(xtlb_miss_tramp, (char *)XTLB_MISS_EXC_VEC,
        !           597:            e_xtlb_miss_tramp - xtlb_miss_tramp);
        !           598:        bcopy(exception, (char *)CACHE_ERR_EXC_VEC, e_exception - exception);
        !           599:        bcopy(exception, (char *)GEN_EXC_VEC, e_exception - exception);
        !           600:
        !           601:        /*
        !           602:         *  Turn off bootstrap exception vectors.
        !           603:         */
        !           604:        setsr(getsr() & ~SR_BOOT_EXC_VEC);
        !           605:        proc0.p_md.md_regs->sr = getsr();
        !           606:
        !           607:        /*
        !           608:         * Clear out the I and D caches.
        !           609:         */
        !           610:        Mips_SyncCache();
        !           611:
        !           612: #ifdef DDB
        !           613:        db_machine_init();
        !           614:        if (boothowto & RB_KDB)
        !           615:                Debugger();
        !           616: #endif
        !           617:
        !           618:        /*
        !           619:         *  Return new stack pointer.
        !           620:         */
        !           621:        return ((caddr_t)proc0paddr + USPACE - 64);
        !           622: }
        !           623:
        !           624: /*
        !           625:  * Allocate space for system data structures. Doesn't need to be mapped.
        !           626:  */
        !           627: caddr_t
        !           628: allocsys(caddr_t v)
        !           629: {
        !           630:        caddr_t start;
        !           631:
        !           632:        start = v;
        !           633:
        !           634: #define        valloc(name, type, num) \
        !           635:            (name) = (type *)v; v = (caddr_t)((name)+(num))
        !           636: #ifdef SYSVMSG
        !           637:        valloc(msgpool, char, msginfo.msgmax);
        !           638:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
        !           639:        valloc(msghdrs, struct msg, msginfo.msgtql);
        !           640:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
        !           641: #endif
        !           642:
        !           643:        return(v);
        !           644: }
        !           645:
        !           646:
        !           647: /*
        !           648:  *  Decode boot options.
        !           649:  */
        !           650: static void
        !           651: dobootopts(int argc, void *argv)
        !           652: {
        !           653:        char *cp;
        !           654:        int i;
        !           655:
        !           656:        /* XXX Should this be done differently, eg env vs. args? */
        !           657:        for (i = 1; i < argc; i++) {
        !           658:                if (bios_is_32bit)
        !           659:                        cp = (char *)(long)((int32_t *)argv)[i];
        !           660:                else
        !           661:                        cp = ((char **)argv)[i];
        !           662:                if (cp != NULL && strncmp(cp, "OSLoadOptions=", 14) == 0) {
        !           663:                        if (strcmp(&cp[14], "auto") == 0)
        !           664:                                        boothowto &= ~(RB_SINGLE|RB_ASKNAME);
        !           665:                        else if (strcmp(&cp[14], "single") == 0)
        !           666:                                        boothowto |= RB_SINGLE;
        !           667:                        else if (strcmp(&cp[14], "debug") == 0)
        !           668:                                        boothowto |= RB_KDB;
        !           669:                }
        !           670:        }
        !           671:
        !           672:        /* Catch serial consoles on O2's */
        !           673:        cp = Bios_GetEnvironmentVariable("ConsoleOut");
        !           674:        if (cp != NULL && strncmp(cp, "serial", 6) == 0)
        !           675:                boothowto |= RB_SERCONS;
        !           676: }
        !           677:
        !           678:
        !           679: /*
        !           680:  * Console initialization: called early on from main,
        !           681:  * before vm init or startup.  Do enough configuration
        !           682:  * to choose and initialize a console.
        !           683:  */
        !           684: void
        !           685: consinit()
        !           686: {
        !           687:        if (console_ok) {
        !           688:                return;
        !           689:        }
        !           690:        cninit();
        !           691:        console_ok = 1;
        !           692: }
        !           693:
        !           694: /*
        !           695:  * cpu_startup: allocate memory for variable-sized tables,
        !           696:  * initialize cpu, and do autoconfiguration.
        !           697:  */
        !           698: void
        !           699: cpu_startup()
        !           700: {
        !           701:        vaddr_t minaddr, maxaddr;
        !           702: #ifdef PMAPDEBUG
        !           703:        extern int pmapdebug;
        !           704:        int opmapdebug = pmapdebug;
        !           705:
        !           706:        pmapdebug = 0;  /* Shut up pmap debug during bootstrap */
        !           707: #endif
        !           708:
        !           709:        /*
        !           710:         * Good {morning,afternoon,evening,night}.
        !           711:         */
        !           712:        printf(version);
        !           713:        printf("real mem = %u (%uMB)\n", ptoa(physmem),
        !           714:            ptoa(physmem)/1024/1024);
        !           715:        printf("rsvd mem = %u (%uMB)\n", ptoa(rsvdmem),
        !           716:            ptoa(rsvdmem)/1024/1024);
        !           717:
        !           718:        /*
        !           719:         * Determine how many buffers to allocate.
        !           720:         * We allocate bufcachepercent% of memory for buffer space.
        !           721:         */
        !           722:        if (bufpages == 0)
        !           723:                bufpages = physmem * bufcachepercent / 100;
        !           724:
        !           725:        /* Restrict to at most 25% filled kvm */
        !           726:        if (bufpages >
        !           727:            (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
        !           728:                bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
        !           729:                    PAGE_SIZE / 4;
        !           730:
        !           731:        /*
        !           732:         * Allocate a submap for exec arguments.  This map effectively
        !           733:         * limits the number of processes exec'ing at any time.
        !           734:         */
        !           735:        minaddr = vm_map_min(kernel_map);
        !           736:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           737:            16 * NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
        !           738:        /* Allocate a submap for physio */
        !           739:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
        !           740:            VM_PHYS_SIZE, 0, FALSE, NULL);
        !           741:
        !           742: #ifdef PMAPDEBUG
        !           743:        pmapdebug = opmapdebug;
        !           744: #endif
        !           745:        printf("avail mem = %u (%uMB)\n", ptoa(uvmexp.free),
        !           746:            ptoa(uvmexp.free)/1024/1024);
        !           747:
        !           748:        extent_malloc_flags = EX_MALLOCOK;
        !           749:
        !           750:        /*
        !           751:         * Set up CPU-specific registers, cache, etc.
        !           752:         */
        !           753:        initcpu();
        !           754:
        !           755:        /*
        !           756:         * Set up buffers, so they can be used to read disk labels.
        !           757:         */
        !           758:        bufinit();
        !           759:
        !           760:        /*
        !           761:         * Configure the system.
        !           762:         */
        !           763:        if (boothowto & RB_CONFIG) {
        !           764: #ifdef BOOT_CONFIG
        !           765:                user_config();
        !           766: #else
        !           767:                printf("kernel does not support -c; continuing..\n");
        !           768: #endif
        !           769:        }
        !           770: }
        !           771:
        !           772: /*
        !           773:  * machine dependent system variables.
        !           774:  */
        !           775: int
        !           776: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
        !           777:        int *name;
        !           778:        u_int namelen;
        !           779:        void *oldp;
        !           780:        size_t *oldlenp;
        !           781:        void *newp;
        !           782:        size_t newlen;
        !           783:        struct proc *p;
        !           784: {
        !           785:        /* all sysctl names at this level are terminal */
        !           786:        if (namelen != 1)
        !           787:                return ENOTDIR;         /* overloaded */
        !           788:
        !           789:        switch (name[0]) {
        !           790:        default:
        !           791:                return EOPNOTSUPP;
        !           792:        }
        !           793: }
        !           794:
        !           795: /*
        !           796:  * Set registers on exec for native exec format. For o64/64.
        !           797:  */
        !           798: void
        !           799: setregs(p, pack, stack, retval)
        !           800:        struct proc *p;
        !           801:        struct exec_package *pack;
        !           802:        u_long stack;
        !           803:        register_t *retval;
        !           804: {
        !           805:        extern struct proc *machFPCurProcPtr;
        !           806: #if 0
        !           807: /* XXX should check validity of header and perhaps be 32/64 indep. */
        !           808:        Elf64_Ehdr *eh = pack->ep_hdr;
        !           809:
        !           810:        if ((((eh->e_flags & EF_MIPS_ABI) != E_MIPS_ABI_NONE) &&
        !           811:            ((eh->e_flags & EF_MIPS_ABI) != E_MIPS_ABI_O32)) ||
        !           812:            ((eh->e_flags & EF_MIPS_ARCH) >= E_MIPS_ARCH_3) ||
        !           813:            (eh->e_ident[EI_CLASS] != ELFCLASS32)) {
        !           814:                p->p_md.md_flags |= MDP_O32;
        !           815:        }
        !           816: #endif
        !           817:
        !           818: #if !defined(__LP64__)
        !           819:        p->p_md.md_flags |= MDP_O32;
        !           820: #else
        !           821:        p->p_md.md_flags &= ~MDP_O32;
        !           822: #endif
        !           823:
        !           824:        bzero((caddr_t)p->p_md.md_regs, sizeof(struct trap_frame));
        !           825:        p->p_md.md_regs->sp = stack;
        !           826:        p->p_md.md_regs->pc = pack->ep_entry & ~3;
        !           827:        p->p_md.md_regs->t9 = pack->ep_entry & ~3; /* abicall req */
        !           828: #if defined(__LP64__)
        !           829:        p->p_md.md_regs->sr = SR_FR_32 | SR_XX | SR_KSU_USER | SR_KX | SR_UX |
        !           830:            SR_EXL | SR_INT_ENAB;
        !           831:        if (sys_config.cpu[0].type == MIPS_R12000 &&
        !           832:            sys_config.system_type == SGI_O2)
        !           833:                p->p_md.md_regs->sr |= SR_DSD;
        !           834: #else
        !           835:        p->p_md.md_regs->sr = SR_KSU_USER|SR_XX|SR_EXL|SR_INT_ENAB;
        !           836: #endif
        !           837:        p->p_md.md_regs->sr |= idle_mask & SR_INT_MASK;
        !           838:        p->p_md.md_regs->ic = (idle_mask << 8) & IC_INT_MASK;
        !           839:        p->p_md.md_flags &= ~MDP_FPUSED;
        !           840:        if (machFPCurProcPtr == p)
        !           841:                machFPCurProcPtr = (struct proc *)0;
        !           842:        p->p_md.md_ss_addr = 0;
        !           843:        p->p_md.md_pc_ctrl = 0;
        !           844:        p->p_md.md_watch_1 = 0;
        !           845:        p->p_md.md_watch_2 = 0;
        !           846:
        !           847:        retval[1] = 0;
        !           848: }
        !           849:
        !           850:
        !           851: int    waittime = -1;
        !           852:
        !           853: void
        !           854: boot(int howto)
        !           855: {
        !           856:
        !           857:        /* take a snap shot before clobbering any registers */
        !           858:        if (curproc)
        !           859:                savectx(curproc->p_addr, 0);
        !           860:
        !           861: #ifdef DEBUG
        !           862:        if (panicstr)
        !           863:                stacktrace();
        !           864: #endif
        !           865:
        !           866:        if (cold) {
        !           867:                /*
        !           868:                 * If the system is cold, just halt, unless the user
        !           869:                 * explicitely asked for reboot.
        !           870:                 */
        !           871:                if ((howto & RB_USERREQ) == 0)
        !           872:                        howto |= RB_HALT;
        !           873:                goto haltsys;
        !           874:        }
        !           875:
        !           876:        boothowto = howto;
        !           877:        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
        !           878:                extern struct proc proc0;
        !           879:                /* fill curproc with live object */
        !           880:                if (curproc == NULL)
        !           881:                        curproc = &proc0;
        !           882:                /*
        !           883:                 * Synchronize the disks....
        !           884:                 */
        !           885:                waittime = 0;
        !           886:                vfs_shutdown();
        !           887:
        !           888:                /*
        !           889:                 * If we've been adjusting the clock, the todr
        !           890:                 * will be out of synch; adjust it now.
        !           891:                 */
        !           892:                if ((howto & RB_TIMEBAD) == 0) {
        !           893:                        resettodr();
        !           894:                } else {
        !           895:                        printf("WARNING: not updating battery clock\n");
        !           896:                }
        !           897:        }
        !           898:
        !           899:        (void) splhigh();               /* extreme priority */
        !           900:
        !           901:        if (howto & RB_DUMP)
        !           902:                dumpsys();
        !           903:
        !           904: haltsys:
        !           905:        doshutdownhooks();
        !           906:
        !           907:        if (howto & RB_HALT) {
        !           908:                if (howto & RB_POWERDOWN) {
        !           909:                        printf("System Power Down.\n");
        !           910:                        delay(1000000);
        !           911:                        Bios_PowerDown();
        !           912:                } else {
        !           913:                        printf("System Halt.\n");
        !           914:                        delay(1000000);
        !           915:                        Bios_EnterInteractiveMode();
        !           916:                }
        !           917:                printf("Didn't want to die!!! Reset manually.\n");
        !           918:        } else {
        !           919:                printf("System restart.\n");
        !           920:                delay(1000000);
        !           921:                Bios_Reboot();
        !           922:                printf("Restart failed!!! Reset manually.\n");
        !           923:        }
        !           924:        for (;;) ;
        !           925:        /*NOTREACHED*/
        !           926: }
        !           927:
        !           928: int    dumpmag = (int)0x8fca0101;      /* magic number for savecore */
        !           929: int    dumpsize = 0;           /* also for savecore */
        !           930: long   dumplo = 0;
        !           931:
        !           932: void
        !           933: dumpconf(void)
        !           934: {
        !           935:        int nblks;
        !           936:
        !           937:        if (dumpdev == NODEV ||
        !           938:            (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
        !           939:                return;
        !           940:        if (nblks <= ctod(1))
        !           941:                return;
        !           942:
        !           943:        dumpsize = ptoa(physmem);
        !           944:        if (dumpsize > btoc(dbtob(nblks - dumplo)))
        !           945:                dumpsize = btoc(dbtob(nblks - dumplo));
        !           946:        else if (dumplo == 0)
        !           947:                dumplo = nblks - btodb(ctob(physmem));
        !           948:
        !           949:        /*
        !           950:         * Don't dump on the first page
        !           951:         * in case the dump device includes a disk label.
        !           952:         */
        !           953:        if (dumplo < btodb(PAGE_SIZE))
        !           954:                dumplo = btodb(PAGE_SIZE);
        !           955: }
        !           956:
        !           957: /*
        !           958:  * Doadump comes here after turning off memory management and
        !           959:  * getting on the dump stack, either when called above, or by
        !           960:  * the auto-restart code.
        !           961:  */
        !           962: void
        !           963: dumpsys()
        !           964: {
        !           965:        extern int msgbufmapped;
        !           966:
        !           967:        msgbufmapped = 0;
        !           968:        if (dumpdev == NODEV)
        !           969:                return;
        !           970:        /*
        !           971:         * For dumps during autoconfiguration,
        !           972:         * if dump device has already configured...
        !           973:         */
        !           974:        if (dumpsize == 0)
        !           975:                dumpconf();
        !           976:        if (dumplo < 0)
        !           977:                return;
        !           978:        printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
        !           979:        printf("dump not yet implemented");
        !           980: #if 0 /* XXX HAVE TO FIX XXX */
        !           981:        switch (error = (*bdevsw[major(dumpdev)].d_dump)(dumpdev, dumplo,)) {
        !           982:
        !           983:        case ENXIO:
        !           984:                printf("device bad\n");
        !           985:                break;
        !           986:
        !           987:        case EFAULT:
        !           988:                printf("device not ready\n");
        !           989:                break;
        !           990:
        !           991:        case EINVAL:
        !           992:                printf("area improper\n");
        !           993:                break;
        !           994:
        !           995:        case EIO:
        !           996:                printf("i/o error\n");
        !           997:                break;
        !           998:
        !           999:        default:
        !          1000:                printf("error %d\n", error);
        !          1001:                break;
        !          1002:
        !          1003:        case 0:
        !          1004:                printf("succeeded\n");
        !          1005:        }
        !          1006: #endif
        !          1007: }
        !          1008:
        !          1009: void
        !          1010: initcpu()
        !          1011: {
        !          1012: }
        !          1013:
        !          1014: /*
        !          1015:  * Convert "xx:xx:xx:xx:xx:xx" string to ethernet hardware address.
        !          1016:  */
        !          1017: void
        !          1018: enaddr_aton(const char *s, u_int8_t *a)
        !          1019: {
        !          1020:        int i;
        !          1021:
        !          1022:        if (s != NULL) {
        !          1023:                for(i = 0; i < 6; i++) {
        !          1024:                        a[i] = atoi(s, 16, &s);
        !          1025:                        if (*s == ':')
        !          1026:                                s++;
        !          1027:                }
        !          1028:        }
        !          1029: }
        !          1030:
        !          1031: /*
        !          1032:  * Convert an ASCII string into an integer.
        !          1033:  */
        !          1034: static int
        !          1035: atoi(const char *s, int b, const char **o)
        !          1036: {
        !          1037:        int c;
        !          1038:        unsigned base = b, d;
        !          1039:        int neg = 0, val = 0;
        !          1040:
        !          1041:        if (s == NULL || *s == 0) {
        !          1042:                if (o != NULL)
        !          1043:                        *o = s;
        !          1044:                return 0;
        !          1045:        }
        !          1046:
        !          1047:        /* skip spaces if any */
        !          1048:        do {
        !          1049:                c = *s++;
        !          1050:        } while (c == ' ' || c == '\t');
        !          1051:
        !          1052:        /* parse sign, allow more than one (compat) */
        !          1053:        while (c == '-') {
        !          1054:                neg = !neg;
        !          1055:                c = *s++;
        !          1056:        }
        !          1057:
        !          1058:        /* parse base specification, if any */
        !          1059:        if (c == '0') {
        !          1060:                c = *s++;
        !          1061:                switch (c) {
        !          1062:                case 'X':
        !          1063:                case 'x':
        !          1064:                        base = 16;
        !          1065:                        c = *s++;
        !          1066:                        break;
        !          1067:                case 'B':
        !          1068:                case 'b':
        !          1069:                        base = 2;
        !          1070:                        c = *s++;
        !          1071:                        break;
        !          1072:                default:
        !          1073:                        base = 8;
        !          1074:                }
        !          1075:        }
        !          1076:
        !          1077:        /* parse number proper */
        !          1078:        for (;;) {
        !          1079:                if (c >= '0' && c <= '9')
        !          1080:                        d = c - '0';
        !          1081:                else if (c >= 'a' && c <= 'z')
        !          1082:                        d = c - 'a' + 10;
        !          1083:                else if (c >= 'A' && c <= 'Z')
        !          1084:                        d = c - 'A' + 10;
        !          1085:                else
        !          1086:                        break;
        !          1087:                val *= base;
        !          1088:                val += d;
        !          1089:                c = *s++;
        !          1090:        }
        !          1091:        if (neg)
        !          1092:                val = -val;
        !          1093:        if (o != NULL)
        !          1094:                *o = s - 1;
        !          1095:        return val;
        !          1096: }
        !          1097:
        !          1098: /*
        !          1099:  *  RM7000 Performance counter support.
        !          1100:  */
        !          1101:
        !          1102: int
        !          1103: rm7k_perfcntr(cmd, arg1, arg2, arg3)
        !          1104:        int cmd;
        !          1105:        long  arg1, arg2, arg3;
        !          1106: {
        !          1107:        int result;
        !          1108:        quad_t cntval;
        !          1109:        struct proc *p = curproc;
        !          1110:
        !          1111:
        !          1112:        switch(cmd) {
        !          1113:        case PCNT_FNC_SELECT:
        !          1114:                if ((arg1 & 0xff) > PCNT_SRC_MAX ||
        !          1115:                   (arg1 & ~(PCNT_CE|PCNT_UM|PCNT_KM|0xff)) != 0) {
        !          1116:                        result = EINVAL;
        !          1117:                        break;
        !          1118:                }
        !          1119: #ifdef DEBUG
        !          1120: printf("perfcnt select %x, proc %p\n", arg1, p);
        !          1121: #endif
        !          1122:                p->p_md.md_pc_count = 0;
        !          1123:                p->p_md.md_pc_spill = 0;
        !          1124:                p->p_md.md_pc_ctrl = arg1;
        !          1125:                result = 0;
        !          1126:                break;
        !          1127:
        !          1128:        case PCNT_FNC_READ:
        !          1129:                cntval = p->p_md.md_pc_count;
        !          1130:                cntval += (quad_t)p->p_md.md_pc_spill << 31;
        !          1131:                result = copyout(&cntval, (void *)arg1, sizeof(cntval));
        !          1132:                break;
        !          1133:
        !          1134:        default:
        !          1135: #ifdef DEBUG
        !          1136: printf("perfcnt error %d\n", cmd);
        !          1137: #endif
        !          1138:                result = -1;
        !          1139:                break;
        !          1140:        }
        !          1141:        return(result);
        !          1142: }
        !          1143:
        !          1144: /*
        !          1145:  *  Called when the performance counter d31 gets set.
        !          1146:  *  Increase spill value and reset d31.
        !          1147:  */
        !          1148: void
        !          1149: rm7k_perfintr(trapframe)
        !          1150:        struct trap_frame *trapframe;
        !          1151: {
        !          1152:        struct proc *p = curproc;
        !          1153:
        !          1154:        printf("perfintr proc %p!\n", p);
        !          1155:        cp0_setperfcount(cp0_getperfcount() & 0x7fffffff);
        !          1156:        if (p != NULL) {
        !          1157:                p->p_md.md_pc_spill++;
        !          1158:        }
        !          1159: }
        !          1160:
        !          1161: int
        !          1162: rm7k_watchintr(trapframe)
        !          1163:        struct trap_frame *trapframe;
        !          1164: {
        !          1165:        return(0);
        !          1166: }
        !          1167:
        !          1168: #ifdef DEBUG
        !          1169: /*
        !          1170:  *     Dump TLB contents.
        !          1171:  */
        !          1172: void
        !          1173: dump_tlb()
        !          1174: {
        !          1175: char *attr[] = {
        !          1176:        "CWTNA", "CWTA ", "UCBL ", "CWB  ", "RES  ", "RES  ", "UCNB ", "BPASS"
        !          1177: };
        !          1178:
        !          1179:        int tlbno, last;
        !          1180:        struct tlb_entry tlb;
        !          1181:
        !          1182:        last = 64;
        !          1183:
        !          1184:        for (tlbno = 0; tlbno < last; tlbno++) {
        !          1185:                tlb_read(tlbno, &tlb);
        !          1186:
        !          1187:                if (tlb.tlb_lo0 & PG_V || tlb.tlb_lo1 & PG_V) {
        !          1188:                        bios_printf("%2d v=%p", tlbno, tlb.tlb_hi & 0xffffffffffffff00);
        !          1189:                        bios_printf("/%02x ", tlb.tlb_hi & 0xff);
        !          1190:
        !          1191:                        if (tlb.tlb_lo0 & PG_V) {
        !          1192:                                bios_printf("0x%09x ", pfn_to_pad(tlb.tlb_lo0));
        !          1193:                                bios_printf("%c", tlb.tlb_lo0 & PG_M ? 'M' : ' ');
        !          1194:                                bios_printf("%c", tlb.tlb_lo0 & PG_G ? 'G' : ' ');
        !          1195:                                bios_printf(" %s ", attr[(tlb.tlb_lo0 >> 3) & 7]);
        !          1196:                        } else {
        !          1197:                                bios_printf("invalid             ");
        !          1198:                        }
        !          1199:
        !          1200:                        if (tlb.tlb_lo1 & PG_V) {
        !          1201:                                bios_printf("0x%08x ", pfn_to_pad(tlb.tlb_lo1));
        !          1202:                                bios_printf("%c", tlb.tlb_lo1 & PG_M ? 'M' : ' ');
        !          1203:                                bios_printf("%c", tlb.tlb_lo1 & PG_G ? 'G' : ' ');
        !          1204:                                bios_printf(" %s ", attr[(tlb.tlb_lo1 >> 3) & 7]);
        !          1205:                        } else {
        !          1206:                                bios_printf("invalid             ");
        !          1207:                        }
        !          1208:                        bios_printf(" sz=%x", tlb.tlb_mask);
        !          1209:                }
        !          1210:                else {
        !          1211:                        bios_printf("%2d v=invalid    ", tlbno);
        !          1212:                }
        !          1213:                bios_printf("\n");
        !          1214:        }
        !          1215: }
        !          1216: #endif

CVSweb