[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

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