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

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

1.1       nbrk        1: /*     $OpenBSD: machdep.c,v 1.115 2007/06/06 17:15:11 deraadt Exp $   */
                      2: /*     $NetBSD: machdep.c,v 1.121 1999/03/26 23:41:29 mycroft Exp $    */
                      3:
                      4: /*
                      5:  * Copyright (c) 1988 University of Utah.
                      6:  * Copyright (c) 1982, 1986, 1990, 1993
                      7:  *     The Regents of the University of California.  All rights reserved.
                      8:  *
                      9:  * This code is derived from software contributed to Berkeley by
                     10:  * the Systems Programming Group of the University of Utah Computer
                     11:  * Science Department.
                     12:  *
                     13:  * Redistribution and use in source and binary forms, with or without
                     14:  * modification, are permitted provided that the following conditions
                     15:  * are met:
                     16:  * 1. Redistributions of source code must retain the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer.
                     18:  * 2. Redistributions in binary form must reproduce the above copyright
                     19:  *    notice, this list of conditions and the following disclaimer in the
                     20:  *    documentation and/or other materials provided with the distribution.
                     21:  * 3. Neither the name of the University nor the names of its contributors
                     22:  *    may be used to endorse or promote products derived from this software
                     23:  *    without specific prior written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     35:  * SUCH DAMAGE.
                     36:  *
                     37:  * from: Utah $Hdr: machdep.c 1.74 92/12/20$
                     38:  *
                     39:  *     @(#)machdep.c   8.10 (Berkeley) 4/20/94
                     40:  */
                     41:
                     42: #include <sys/param.h>
                     43: #include <sys/systm.h>
                     44: #include <sys/buf.h>
                     45: #include <sys/timeout.h>
                     46: #include <sys/conf.h>
                     47: #include <sys/exec.h>
                     48: #include <sys/file.h>
                     49: #include <sys/ioctl.h>
                     50: #include <sys/kernel.h>
                     51: #include <sys/device.h>
                     52: #include <sys/malloc.h>
                     53: #include <sys/extent.h>
                     54: #include <sys/mbuf.h>
                     55: #include <sys/mount.h>
                     56: #include <sys/msgbuf.h>
                     57: #include <sys/proc.h>
                     58: #include <sys/reboot.h>
                     59: #include <sys/signalvar.h>
                     60: #include <sys/tty.h>
                     61: #include <sys/user.h>
                     62: #include <sys/exec.h>
                     63: #include <sys/core.h>
                     64: #include <sys/kcore.h>
                     65: #include <sys/vnode.h>
                     66: #include <sys/sysctl.h>
                     67: #include <sys/syscallargs.h>
                     68: #include <sys/syslog.h>
                     69: #ifdef SYSVMSG
                     70: #include <sys/msg.h>
                     71: #endif
                     72:
                     73: #include <machine/db_machdep.h>
                     74: #ifdef DDB
                     75: #include <ddb/db_var.h>
                     76: #endif
                     77: #include <ddb/db_sym.h>
                     78: #include <ddb/db_extern.h>
                     79:
                     80: #include <machine/autoconf.h>
                     81: #include <machine/cpu.h>
                     82: #include <machine/hp300spu.h>
                     83: #include <machine/kcore.h>
                     84: #include <machine/reg.h>
                     85: #include <machine/psl.h>
                     86: #include <machine/pte.h>
                     87:
                     88: #include <dev/cons.h>
                     89:
                     90: #include <uvm/uvm_extern.h>
                     91:
                     92: #ifdef USELEDS
                     93: #include <hp300/hp300/leds.h>
                     94: #endif
                     95:
                     96: /* the following is used externally (sysctl_hw) */
                     97: char   machine[] = MACHINE;    /* from <machine/param.h> */
                     98:
                     99: struct vm_map *exec_map = NULL;
                    100: struct vm_map *phys_map = NULL;
                    101:
                    102: extern paddr_t avail_start, avail_end;
                    103:
                    104: /*
                    105:  * Declare these as initialized data so we can patch them.
                    106:  */
                    107: #ifndef        BUFCACHEPERCENT
                    108: #define        BUFCACHEPERCENT 5
                    109: #endif
                    110:
                    111: #ifdef BUFPAGES
                    112: int    bufpages = BUFPAGES;
                    113: #else
                    114: int    bufpages = 0;
                    115: #endif
                    116: int    bufcachepercent = BUFCACHEPERCENT;
                    117:
                    118: int    physmem;                /* size of physical memory, in pages */
                    119: /*
                    120:  * safepri is a safe priority for sleep to set for a spin-wait
                    121:  * during autoconfiguration or after a panic.
                    122:  */
                    123: int    safepri = PSL_LOWIPL;
                    124:
                    125: extern u_int lowram;
                    126: extern short exframesize[];
                    127:
                    128: #ifdef COMPAT_HPUX
                    129: extern struct emul emul_hpux;
                    130: #endif
                    131: #ifdef COMPAT_SUNOS
                    132: extern struct emul emul_sunos;
                    133: #endif
                    134:
                    135: /*
                    136:  * Some storage space must be allocated statically because of the
                    137:  * early console initialization.
                    138:  */
                    139: char   extiospace[EXTENT_FIXED_STORAGE_SIZE(8)];
                    140: extern int eiomapsize;
                    141:
                    142: /* prototypes for local functions */
                    143: caddr_t        allocsys(caddr_t);
                    144: void   parityenable(void);
                    145: int    parityerror(struct frame *);
                    146: int    parityerrorfind(void);
                    147: void    identifycpu(void);
                    148: void    initcpu(void);
                    149: void   dumpmem(int *, int, int);
                    150: char   *hexstr(int, int);
                    151:
                    152: /* functions called from locore.s */
                    153: void    dumpsys(void);
                    154: void   hp300_init(void);
                    155: void    straytrap(int, u_short);
                    156: void   nmihand(struct frame);
                    157:
                    158: /*
                    159:  * Select code of console.  Set to CONSCODE_INTERNAL if console is on
                    160:  * "internal" framebuffer.
                    161:  */
                    162: int    conscode;
                    163: caddr_t        conaddr;                /* for drivers in cn_init() */
                    164: int    convasize;              /* size of mapped console device */
                    165:
                    166: /*
                    167:  * Note that the value of delay_divisor is roughly
                    168:  * 2048 / cpuspeed (where cpuspeed is in MHz) on 68020
                    169:  * and 68030 systems.  See clock.c for the delay
                    170:  * calibration algorithm.
                    171:  */
                    172: int    cpuspeed;               /* relative cpu speed */
                    173: int    delay_divisor;          /* delay constant */
                    174:
                    175:  /*
                    176:  * Early initialization, before main() is called.
                    177:  */
                    178: void
                    179: hp300_init()
                    180: {
                    181:        /*
                    182:         * Tell the VM system about available physical memory.  The
                    183:         * hp300 only has one segment.
                    184:         */
                    185:        uvm_page_physload(atop(avail_start), atop(avail_end),
                    186:            atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT);
                    187:
                    188:        /* Initialize the interrupt handlers. */
                    189:        intr_init();
                    190:
                    191:        /* Calibrate the delay loop. */
                    192:        hp300_calibrate_delay();
                    193: }
                    194:
                    195: /*
                    196:  * Console initialization: called early on from main,
                    197:  * before vm init or startup.  Do enough configuration
                    198:  * to choose and initialize a console.
                    199:  */
                    200: void
                    201: consinit()
                    202: {
                    203:        extern struct extent *extio;
                    204:        extern char *extiobase;
                    205:
                    206:        /*
                    207:         * Initialize some variables for sanity.
                    208:         */
                    209:        convasize = 0;
                    210:        conscode = CONSCODE_INVALID;
                    211:
                    212:        /*
                    213:         * Initialize the bus resource map.
                    214:         */
                    215:        extio = extent_create("extio",
                    216:            (u_long)extiobase, (u_long)extiobase + ctob(eiomapsize),
                    217:            M_DEVBUF, extiospace, sizeof(extiospace), EX_NOWAIT);
                    218:
                    219:        /*
                    220:         * Initialize the console before we print anything out.
                    221:         */
                    222:        hp300_cninit();
                    223:
                    224: #ifdef DDB
                    225:        ddb_init();
                    226:        if (boothowto & RB_KDB)
                    227:                Debugger();
                    228: #endif
                    229: }
                    230:
                    231: /*
                    232:  * cpu_startup: allocate memory for variable-sized tables,
                    233:  * initialize cpu, and do autoconfiguration.
                    234:  */
                    235: void
                    236: cpu_startup()
                    237: {
                    238:        extern char *etext;
                    239:        unsigned i;
                    240:        caddr_t v;
                    241:        vaddr_t minaddr, maxaddr;
                    242:        vsize_t size;
                    243: #ifdef DEBUG
                    244:        extern int pmapdebug;
                    245:        int opmapdebug = pmapdebug;
                    246:
                    247:        pmapdebug = 0;
                    248: #endif
                    249:
                    250:        /*
                    251:         * Now that VM services are available, give another chance at
                    252:         * console devices to initialize, if they could not before.
                    253:         */
                    254:        hp300_cninit();
                    255:
                    256:        /*
                    257:         * Initialize error message buffer (at end of core).
                    258:         * avail_end was pre-decremented in pmap_bootstrap to compensate.
                    259:         */
                    260:        for (i = 0; i < btoc(MSGBUFSIZE); i++)
                    261:                pmap_enter(pmap_kernel(), (vaddr_t)msgbufp + i * NBPG,
                    262:                    avail_end + i * NBPG, VM_PROT_READ|VM_PROT_WRITE,
                    263:                    VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
                    264:        pmap_update(pmap_kernel());
                    265:        initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE));
                    266:
                    267:        /*
                    268:         * Good {morning,afternoon,evening,night}.
                    269:         */
                    270:        printf(version);
                    271:        identifycpu();
                    272:        printf("real mem = %u (%uMB)\n", ctob(physmem),
                    273:            ctob(physmem)/1024/1024);
                    274:
                    275:        /*
                    276:         * Find out how much space we need, allocate it,
                    277:         * and then give everything true virtual addresses.
                    278:         */
                    279:        size = (vsize_t)allocsys((caddr_t)0);
                    280:        if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(size))) == 0)
                    281:                panic("startup: no room for tables");
                    282:        if ((allocsys(v) - v) != size)
                    283:                panic("startup: table size inconsistency");
                    284:
                    285:        /*
                    286:         * Determine how many buffers to allocate.
                    287:         * We allocate bufcachepercent% of memory for buffer space.
                    288:         */
                    289:        if (bufpages == 0)
                    290:                bufpages = physmem * bufcachepercent / 100;
                    291:
                    292:        /* Restrict to at most 25% filled kvm */
                    293:        if (bufpages >
                    294:            (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
                    295:                bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
                    296:                    PAGE_SIZE / 4;
                    297:
                    298:        /*
                    299:         * Allocate a submap for exec arguments.  This map effectively
                    300:         * limits the number of processes exec'ing at any time.
                    301:         */
                    302:        minaddr = vm_map_min(kernel_map);
                    303:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
                    304:                                   16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
                    305:
                    306:        /*
                    307:         * Allocate a submap for physio
                    308:         */
                    309:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
                    310:                                   VM_PHYS_SIZE, 0, FALSE, NULL);
                    311:
                    312: #ifdef DEBUG
                    313:        pmapdebug = opmapdebug;
                    314: #endif
                    315:        printf("avail mem = %lu (%luMB)\n", ptoa(uvmexp.free),
                    316:            ptoa(uvmexp.free)/1024/1024);
                    317:
                    318:        /*
                    319:         * Tell the VM system that page 0 isn't mapped.
                    320:         *
                    321:         * XXX This is bogus; should just fix KERNBASE and
                    322:         * XXX VM_MIN_KERNEL_ADDRESS, but not right now.
                    323:         */
                    324:        if (uvm_map_protect(kernel_map, 0, NBPG, UVM_PROT_NONE, TRUE))
                    325:                panic("can't mark page 0 off-limits");
                    326:
                    327:        /*
                    328:         * Tell the VM system that writing to kernel text isn't allowed.
                    329:         * If we don't, we might end up COW'ing the text segment!
                    330:         *
                    331:         * XXX Should be trunc_page(&kernel_text) instead
                    332:         * XXX of NBPG.
                    333:         */
                    334:        if (uvm_map_protect(kernel_map, NBPG, round_page((vaddr_t)&etext),
                    335:            UVM_PROT_READ|UVM_PROT_EXEC, TRUE))
                    336:                panic("can't protect kernel text");
                    337:
                    338:        /*
                    339:         * Set up CPU-specific registers, cache, etc.
                    340:         */
                    341:        initcpu();
                    342:
                    343:        /*
                    344:         * Set up buffers, so they can be used to read disk labels.
                    345:         */
                    346:        bufinit();
                    347:
                    348:        /*
                    349:         * Configure the system.
                    350:         */
                    351:        if (boothowto & RB_CONFIG) {
                    352: #ifdef BOOT_CONFIG
                    353:                user_config();
                    354: #else
                    355:                printf("kernel does not support -c; continuing..\n");
                    356: #endif
                    357:        }
                    358: }
                    359:
                    360: /*
                    361:  * Allocate space for system data structures.  We are given
                    362:  * a starting virtual address and we return a final virtual
                    363:  * address; along the way we set each data structure pointer.
                    364:  *
                    365:  * We call allocsys() with 0 to find out how much space we want,
                    366:  * allocate that much and fill it with zeroes, and then call
                    367:  * allocsys() again with the correct base virtual address.
                    368:  */
                    369: caddr_t
                    370: allocsys(v)
                    371:        caddr_t v;
                    372: {
                    373:
                    374: #define        valloc(name, type, num) \
                    375:            (name) = (type *)v; v = (caddr_t)((name)+(num))
                    376: #define        valloclim(name, type, num, lim) \
                    377:            (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
                    378:
                    379: #ifdef SYSVMSG
                    380:        valloc(msgpool, char, msginfo.msgmax);
                    381:        valloc(msgmaps, struct msgmap, msginfo.msgseg);
                    382:        valloc(msghdrs, struct msg, msginfo.msgtql);
                    383:        valloc(msqids, struct msqid_ds, msginfo.msgmni);
                    384: #endif
                    385:
                    386:        return (v);
                    387: }
                    388:
                    389: /*
                    390:  * Info for CTL_HW
                    391:  */
                    392: char   cpu_model[120];
                    393:
                    394: /*
                    395:  * Text description of models we support, indexed by machineid.
                    396:  */
                    397: const char *hp300_models[] = {
                    398:        "320",          /* HP_320 */
                    399:        "318/319/330",  /* HP_330 */
                    400:        "350",          /* HP_350 */
                    401:        "360",          /* HP_360 */
                    402:        "370",          /* HP_370 */
                    403:        "340",          /* HP_340 */
                    404:        "345",          /* HP_345 */
                    405:        "375",          /* HP_375 */
                    406:        "400",          /* HP_400 */
                    407:        "380",          /* HP_380 */
                    408:        "425",          /* HP_425 */
                    409:        "433",          /* HP_433 */
                    410:        "385",          /* HP_385 */
                    411:        "362",          /* HP_362 */
                    412:        "382",          /* HP_382 */
                    413: };
                    414:
                    415: /* Map mmuid to single letter designation in 4xx models (e.g. 425s, 425t) */
                    416: char hp300_designations[] = "    ttss e";
                    417:
                    418: void
                    419: identifycpu()
                    420: {
                    421:        const char *t;
                    422:        char mc, *td;
                    423:        int len;
                    424: #ifdef FPSP
                    425:        extern u_long fpvect_tab, fpvect_end, fpsp_tab;
                    426: #endif
                    427:
                    428:        /*
                    429:         * Map machineid to model name.
                    430:         */
                    431:        if (machineid >= sizeof(hp300_models) / sizeof(char *)) {
                    432:                printf("\nunknown machineid %d\n", machineid);
                    433:                goto lose;
                    434:        }
                    435:        t = hp300_models[machineid];
                    436:
                    437:        /*
                    438:         * Look up special designation (425s, 425t, etc) by mmuid.
                    439:         */
                    440:        if (mmuid < strlen(hp300_designations) &&
                    441:            hp300_designations[mmuid] != ' ') {
                    442:                td = &hp300_designations[mmuid];
                    443:                td[1] = '\0';
                    444:        } else
                    445:                td = "";
                    446:
                    447:        /*
                    448:         * ...and the CPU type
                    449:         */
                    450:        switch (cputype) {
                    451:        case CPU_68040:
                    452:                mc = '4';
                    453:                /* adjust cpuspeed by 3/8 on '040 boxes */
                    454:                cpuspeed *= 3;
                    455:                cpuspeed /= 8;
                    456:                break;
                    457:        case CPU_68030:
                    458:                mc = '3';
                    459:                break;
                    460:        case CPU_68020:
                    461:                mc = '2';
                    462:                break;
                    463:        default:
                    464:                printf("\nunknown cputype %d\n", cputype);
                    465:                goto lose;
                    466:        }
                    467:        snprintf(cpu_model, sizeof cpu_model,
                    468:            "HP 9000/%s%s (%dMHz MC680%c0 CPU", t, td, cpuspeed, mc);
                    469:
                    470:        /*
                    471:         * ...and the MMU type.
                    472:         */
                    473:        switch (mmutype) {
                    474:        case MMU_68040:
                    475:        case MMU_68030:
                    476:                strlcat(cpu_model, "+MMU", sizeof cpu_model);
                    477:                break;
                    478:        case MMU_68851:
                    479:                strlcat(cpu_model, ", MC68851 MMU", sizeof cpu_model);
                    480:                break;
                    481:        case MMU_HP:
                    482:                strlcat(cpu_model, ", HP MMU", sizeof cpu_model);
                    483:                break;
                    484:        default:
                    485:                printf("%s\nunknown MMU type %d\n", cpu_model, mmutype);
                    486:                panic("startup");
                    487:        }
                    488:
                    489:        /*
                    490:         * ...and the FPU type.
                    491:         */
                    492:        switch (fputype) {
                    493:        case FPU_68040:
                    494:                strlcat(cpu_model, "+FPU", sizeof cpu_model);
                    495:                break;
                    496:        case FPU_68882:
                    497:                len = strlen(cpu_model);
                    498:                snprintf(cpu_model + len, sizeof cpu_model - len,
                    499:                    ", %dMHz MC68882 FPU", cpuspeed);
                    500:                break;
                    501:        case FPU_68881:
                    502:                len = strlen(cpu_model);
                    503:                snprintf(cpu_model + len, sizeof cpu_model - len,
                    504:                    ", %dMHz MC68881 FPU", machineid == HP_350 ? 20 : 16);
                    505:                break;
                    506:        default:
                    507:                strlcat(cpu_model, ", unknown FPU", sizeof cpu_model);
                    508:        }
                    509:
                    510:        /*
                    511:         * ...and finally, the cache type.
                    512:         */
                    513:        if (cputype == CPU_68040)
                    514:                strlcat(cpu_model, ", 4k on-chip physical I/D caches",
                    515:                    sizeof cpu_model);
                    516:        else {
                    517:                len = strlen(cpu_model);
                    518:                switch (ectype) {
                    519:                case EC_VIRT:
                    520:                        snprintf(cpu_model + len, sizeof cpu_model - len,
                    521:                            ", %dK virtual-address cache",
                    522:                            machineid == HP_320 ? 16 : 32);
                    523:                        break;
                    524:                case EC_PHYS:
                    525:                        snprintf(cpu_model + len, sizeof cpu_model - len,
                    526:                            ", %dK physical-address cache",
                    527:                            machineid == HP_370 ? 64 : 32);
                    528:                        break;
                    529:                }
                    530:        }
                    531:
                    532:        printf("%s)\n", cpu_model);
                    533: #ifdef DEBUG
                    534:        printf("cpu: delay divisor %d", delay_divisor);
                    535:        if (mmuid)
                    536:                printf(", mmuid %d", mmuid);
                    537:        printf("\n");
                    538: #endif
                    539:
                    540:        /*
                    541:         * Now that we have told the user what they have,
                    542:         * let them know if that machine type isn't configured.
                    543:         */
                    544:        switch (machineid) {
                    545:        case -1:                /* keep compilers happy */
                    546: #if !defined(HP320)
                    547:        case HP_320:
                    548: #endif
                    549: #if !defined(HP330)
                    550:        case HP_330:
                    551: #endif
                    552: #if !defined(HP340)
                    553:        case HP_340:
                    554: #endif
                    555: #if !defined(HP345)
                    556:        case HP_345:
                    557: #endif
                    558: #if !defined(HP350)
                    559:        case HP_350:
                    560: #endif
                    561: #if !defined(HP360)
                    562:        case HP_360:
                    563: #endif
                    564: #if !defined(HP362)
                    565:        case HP_362:
                    566: #endif
                    567: #if !defined(HP370)
                    568:        case HP_370:
                    569: #endif
                    570: #if !defined(HP375)
                    571:        case HP_375:
                    572: #endif
                    573: #if !defined(HP380)
                    574:        case HP_380:
                    575: #endif
                    576: #if !defined(HP382)
                    577:        case HP_382:
                    578: #endif
                    579: #if !defined(HP385)
                    580:        case HP_385:
                    581: #endif
                    582: #if !defined(HP400)
                    583:        case HP_400:
                    584: #endif
                    585: #if !defined(HP425)
                    586:        case HP_425:
                    587: #endif
                    588: #if !defined(HP433)
                    589:        case HP_433:
                    590: #endif
                    591:                panic("SPU type not configured for machineid %d", machineid);
                    592:        default:
                    593:                break;
                    594:        }
                    595:
                    596: #ifdef FPSP
                    597:        if (cputype == CPU_68040) {
                    598:                bcopy(&fpsp_tab, &fpvect_tab,
                    599:                    (&fpvect_end - &fpvect_tab) * sizeof (fpvect_tab));
                    600:        }
                    601: #endif
                    602:
                    603:        return;
                    604: lose:
                    605:        panic("startup");
                    606: }
                    607:
                    608: /*
                    609:  * machine dependent system variables.
                    610:  */
                    611: int
                    612: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
                    613:        int *name;
                    614:        u_int namelen;
                    615:        void *oldp;
                    616:        size_t *oldlenp;
                    617:        void *newp;
                    618:        size_t newlen;
                    619:        struct proc *p;
                    620: {
                    621:        dev_t consdev;
                    622:
                    623:        /* all sysctl names at this level are terminal */
                    624:        if (namelen != 1)
                    625:                return (ENOTDIR);               /* overloaded */
                    626:
                    627:        switch (name[0]) {
                    628:        case CPU_CONSDEV:
                    629:                if (cn_tab != NULL)
                    630:                        consdev = cn_tab->cn_dev;
                    631:                else
                    632:                        consdev = NODEV;
                    633:                return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
                    634:                    sizeof consdev));
                    635:        case CPU_CPUSPEED:
                    636:                return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed));
                    637:        case CPU_MACHINEID:
                    638:                return (sysctl_rdint(oldp, oldlenp, newp, machineid));
                    639:        case CPU_MMUID:
                    640:                return (sysctl_rdint(oldp, oldlenp, newp, mmuid));
                    641:        default:
                    642:                return (EOPNOTSUPP);
                    643:        }
                    644:        /* NOTREACHED */
                    645: }
                    646:
                    647: int    waittime = -1;
                    648:
                    649: void
                    650: boot(howto)
                    651:        int howto;
                    652: {
                    653:        /* take a snap shot before clobbering any registers */
                    654:        if (curproc && curproc->p_addr)
                    655:                savectx(&curproc->p_addr->u_pcb);
                    656:
                    657:        /* If system is cold, just halt. */
                    658:        if (cold) {
                    659:                /* (Unless the user explicitly asked for reboot.) */
                    660:                if ((howto & RB_USERREQ) == 0)
                    661:                        howto |= RB_HALT;
                    662:                goto haltsys;
                    663:        }
                    664:
                    665:        boothowto = howto;
                    666:        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
                    667:                waittime = 0;
                    668:                vfs_shutdown();
                    669:                /*
                    670:                 * If we've been adjusting the clock, the todr
                    671:                 * will be out of synch; adjust it now unless
                    672:                 * the system was sitting in ddb.
                    673:                 */
                    674:                if ((howto & RB_TIMEBAD) == 0) {
                    675:                        resettodr();
                    676:                } else {
                    677:                        printf("WARNING: not updating battery clock\n");
                    678:                }
                    679:        }
                    680:
                    681:        /* Disable interrupts. */
                    682:        splhigh();
                    683:
                    684:        /* If rebooting and a dump is requested do it. */
                    685:        if (howto & RB_DUMP)
                    686:                dumpsys();
                    687:
                    688: haltsys:
                    689:        /* Run any shutdown hooks. */
                    690:        doshutdownhooks();
                    691:
                    692:        /* Finally, halt/reboot the system. */
                    693:        if (howto & RB_HALT) {
                    694:                printf("System halted.  Hit any key to reboot.\n\n");
                    695:                while (cngetc() == 0);
                    696:        }
                    697:
                    698:        printf("rebooting...\n");
                    699:        DELAY(1000000);
                    700:        doboot();
                    701:        /*NOTREACHED*/
                    702: }
                    703:
                    704: /*
                    705:  * These variables are needed by /sbin/savecore
                    706:  */
                    707: u_long dumpmag = 0x8fca0101;   /* magic number */
                    708: int    dumpsize = 0;           /* pages */
                    709: long   dumplo = 0;             /* blocks */
                    710: cpu_kcore_hdr_t cpu_kcore_hdr;
                    711:
                    712: /*
                    713:  * This is called by configure to set dumplo and dumpsize.
                    714:  * Dumps always skip the first PAGE_SIZE of disk space
                    715:  * in case there might be a disk label stored there.
                    716:  * If there is extra space, put dump at the end to
                    717:  * reduce the chance that swapping trashes it.
                    718:  */
                    719: void
                    720: dumpconf(void)
                    721: {
                    722:        int nblks;      /* size of dump area */
                    723:
                    724:        if (dumpdev == NODEV ||
                    725:            (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
                    726:                return;
                    727:        if (nblks <= ctod(1))
                    728:                return;
                    729:
                    730:        /*
                    731:         * XXX include the final RAM page which is not included in physmem.
                    732:         */
                    733:        dumpsize = physmem;
                    734:
                    735:        /* hp300 only uses a single segment. */
                    736:        cpu_kcore_hdr.ram_segs[0].start = lowram;
                    737:        cpu_kcore_hdr.ram_segs[0].size = ctob(dumpsize);
                    738:        cpu_kcore_hdr.mmutype = mmutype;
                    739:        cpu_kcore_hdr.kernel_pa = lowram;
                    740:        cpu_kcore_hdr.sysseg_pa = pmap_kernel()->pm_stpa;
                    741:
                    742:        /* Always skip the first block, in case there is a label there. */
                    743:        if (dumplo < ctod(1))
                    744:                dumplo = ctod(1);
                    745:
                    746:        /* Put dump at end of partition, and make it fit. */
                    747:        if (dumpsize > dtoc(nblks - dumplo))
                    748:                dumpsize = dtoc(nblks - dumplo);
                    749:        if (dumplo < nblks - ctod(dumpsize))
                    750:                dumplo = nblks - ctod(dumpsize);
                    751: }
                    752:
                    753: /*
                    754:  * Dump physical memory onto the dump device.  Called by doadump()
                    755:  * in locore.s or by boot() here in machdep.c
                    756:  */
                    757: void
                    758: dumpsys()
                    759: {
                    760:        daddr64_t blkno;        /* current block to write */
                    761:                                /* dump routine */
                    762:        int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
                    763:        int pg;                 /* page being dumped */
                    764:        paddr_t maddr;          /* PA being dumped */
                    765:        int error;              /* error code from (*dump)() */
                    766:        kcore_seg_t *kseg_p;
                    767:        cpu_kcore_hdr_t *chdr_p;
                    768:        char dump_hdr[dbtob(1)];        /* XXX assume hdr fits in 1 block */
                    769:        extern int msgbufmapped;
                    770:
                    771:        /* XXX initialized here because of gcc lossage */
                    772:        maddr = lowram;
                    773:        pg = 0;
                    774:
                    775:        /* Don't put dump messages in msgbuf. */
                    776:        msgbufmapped = 0;
                    777:
                    778:        /* Make sure dump device is valid. */
                    779:        if (dumpdev == NODEV)
                    780:                return;
                    781:        if (dumpsize == 0) {
                    782:                dumpconf();
                    783:                if (dumpsize == 0)
                    784:                        return;
                    785:        }
                    786:        if (dumplo <= 0) {
                    787:                printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
                    788:                    minor(dumpdev));
                    789:                return;
                    790:        }
                    791:        dump = bdevsw[major(dumpdev)].d_dump;
                    792:        blkno = dumplo;
                    793:
                    794:        printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
                    795:            minor(dumpdev), dumplo);
                    796:
                    797:        kseg_p = (kcore_seg_t *)dump_hdr;
                    798:        chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))];
                    799:        bzero(dump_hdr, sizeof(dump_hdr));
                    800:
                    801:        /*
                    802:         * Generate a segment header
                    803:         */
                    804:        CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
                    805:        kseg_p->c_size = dbtob(1) - ALIGN(sizeof(*kseg_p));
                    806:
                    807:        /*
                    808:         * Add the md header
                    809:         */
                    810:
                    811:        *chdr_p = cpu_kcore_hdr;
                    812:
                    813:        printf("dump ");
                    814:        maddr = cpu_kcore_hdr.ram_segs[0].start;
                    815:        /* Dump the header. */
                    816:        error = (*dump) (dumpdev, blkno++, (caddr_t)dump_hdr, dbtob(1));
                    817:        switch (error) {
                    818:        case 0:
                    819:                break;
                    820:
                    821:        case ENXIO:
                    822:                printf("device bad\n");
                    823:                return;
                    824:
                    825:        case EFAULT:
                    826:                printf("device not ready\n");
                    827:                return;
                    828:
                    829:        case EINVAL:
                    830:                printf("area improper\n");
                    831:                return;
                    832:
                    833:        case EIO:
                    834:                printf("i/o error\n");
                    835:                return;
                    836:
                    837:        case EINTR:
                    838:                printf("aborted from console\n");
                    839:                        return;
                    840:
                    841:                default:
                    842:                        printf("error %d\n", error);
                    843:                        return;
                    844:        }
                    845:        for (pg = 0; pg < dumpsize; pg++) {
                    846: #define NPGMB  (1024*1024/NBPG)
                    847:                /* print out how many MBs we have dumped */
                    848:                if (pg && (pg % NPGMB) == 0)
                    849:                        printf("%d ", pg / NPGMB);
                    850: #undef NPGMB
                    851:                pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
                    852:                    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
                    853:
                    854:                pmap_update(pmap_kernel());
                    855:                error = (*dump)(dumpdev, blkno, vmmap, NBPG);
                    856:                switch (error) {
                    857:                case 0:
                    858:                        maddr += NBPG;
                    859:                        blkno += btodb(NBPG);
                    860:                        break;
                    861:
                    862:                case ENXIO:
                    863:                        printf("device bad\n");
                    864:                        return;
                    865:
                    866:                case EFAULT:
                    867:                        printf("device not ready\n");
                    868:                        return;
                    869:
                    870:                case EINVAL:
                    871:                        printf("area improper\n");
                    872:                        return;
                    873:
                    874:                case EIO:
                    875:                        printf("i/o error\n");
                    876:                        return;
                    877:
                    878:                case EINTR:
                    879:                        printf("aborted from console\n");
                    880:                        return;
                    881:
                    882:                default:
                    883:                        printf("error %d\n", error);
                    884:                        return;
                    885:                }
                    886:        }
                    887:        printf("succeeded\n");
                    888: }
                    889:
                    890: void
                    891: initcpu()
                    892: {
                    893:
                    894:        parityenable();
                    895: #ifdef USELEDS
                    896:        ledinit();
                    897: #endif
                    898: }
                    899:
                    900: void
                    901: straytrap(pc, evec)
                    902:        int pc;
                    903:        u_short evec;
                    904: {
                    905:        printf("unexpected trap (vector offset %x) from %x\n",
                    906:               evec & 0xFFF, pc);
                    907: }
                    908:
                    909: /* XXX should change the interface, and make one badaddr() function */
                    910:
                    911: int    *nofault;
                    912:
                    913: int
                    914: badaddr(addr)
                    915:        caddr_t addr;
                    916: {
                    917:        int i;
                    918:        label_t faultbuf;
                    919:
                    920:        nofault = (int *) &faultbuf;
                    921:        if (setjmp((label_t *)nofault)) {
                    922:                nofault = (int *) 0;
                    923:                return(1);
                    924:        }
                    925:        i = *(volatile short *)addr;
                    926:        nofault = (int *) 0;
                    927:        return(0);
                    928: }
                    929:
                    930: int
                    931: badbaddr(addr)
                    932:        caddr_t addr;
                    933: {
                    934:        int i;
                    935:        label_t faultbuf;
                    936:
                    937:        nofault = (int *) &faultbuf;
                    938:        if (setjmp((label_t *)nofault)) {
                    939:                nofault = (int *) 0;
                    940:                return(1);
                    941:        }
                    942:        i = *(volatile char *)addr;
                    943:        nofault = (int *) 0;
                    944:        return(0);
                    945: }
                    946:
                    947: static int innmihand;  /* simple mutex */
                    948:
                    949: /*
                    950:  * Level 7 interrupts can be caused by HIL keyboards (in cooked mode only,
                    951:  * but we run them in raw mode) or parity errors.
                    952:  */
                    953: void
                    954: nmihand(frame)
                    955:        struct frame frame;
                    956: {
                    957:
                    958:        /* Prevent unwanted recursion. */
                    959:        if (innmihand)
                    960:                return;
                    961:        innmihand = 1;
                    962:
                    963:        if (parityerror(&frame)) {
                    964:                innmihand = 0;
                    965:                return;
                    966:        }
                    967:
                    968:        /* panic?? */
                    969:        printf("unexpected level 7 interrupt ignored\n");
                    970:
                    971:        innmihand = 0;
                    972: }
                    973:
                    974: /*
                    975:  * Parity error section.  Contains magic.
                    976:  */
                    977: #define PARREG         ((volatile short *)IIOV(0x5B0000))
                    978: static int gotparmem = 0;
                    979: #ifdef DEBUG
                    980: int ignorekperr = 0;   /* ignore kernel parity errors */
                    981: #endif
                    982:
                    983: /*
                    984:  * Enable parity detection
                    985:  */
                    986: void
                    987: parityenable()
                    988: {
                    989:        label_t faultbuf;
                    990:
                    991:        nofault = (int *) &faultbuf;
                    992:        if (setjmp((label_t *)nofault)) {
                    993:                nofault = (int *) 0;
                    994:                printf("No parity memory\n");
                    995:                return;
                    996:        }
                    997:        *PARREG = 1;
                    998:        nofault = (int *) 0;
                    999:        gotparmem = 1;
                   1000:        printf("Parity detection enabled\n");
                   1001: }
                   1002:
                   1003: /*
                   1004:  * Determine if level 7 interrupt was caused by a parity error
                   1005:  * and deal with it if it was.  Returns 1 if it was a parity error.
                   1006:  */
                   1007: int
                   1008: parityerror(fp)
                   1009:        struct frame *fp;
                   1010: {
                   1011:        if (!gotparmem)
                   1012:                return(0);
                   1013:        *PARREG = 0;
                   1014:        DELAY(10);
                   1015:        *PARREG = 1;
                   1016:        if (panicstr) {
                   1017:                printf("parity error after panic ignored\n");
                   1018:                return (1);
                   1019:        }
                   1020:        if (!parityerrorfind())
                   1021:                printf("WARNING: transient parity error ignored\n");
                   1022:        else if (USERMODE(fp->f_sr)) {
                   1023:                log(LOG_ERR, "pid %d was killed: memory parity error\n",
                   1024:                    curproc->p_pid);
                   1025:                uprintf("sorry, pid %d killed: memory parity error\n",
                   1026:                    curproc->p_pid);
                   1027:                psignal(curproc, SIGKILL);
                   1028: #ifdef DEBUG
                   1029:        } else if (ignorekperr) {
                   1030:                printf("WARNING: kernel parity error ignored\n");
                   1031: #endif
                   1032:        } else {
                   1033:                regdump(&(fp->F_t), 128);
                   1034:                panic("kernel parity error");
                   1035:        }
                   1036:        return (1);
                   1037: }
                   1038:
                   1039: /*
                   1040:  * Yuck!  There has got to be a better way to do this!
                   1041:  * Searching all of memory with interrupts blocked can lead to disaster.
                   1042:  */
                   1043: int
                   1044: parityerrorfind()
                   1045: {
                   1046:        static label_t parcatch;
                   1047:        static int looking = 0;
                   1048:        volatile int pg, o, s;
                   1049:        volatile int *ip;
                   1050:        int i;
                   1051:        int found;
                   1052:
                   1053: #ifdef lint
                   1054:        i = o = pg = 0; if (i) return(0);
                   1055: #endif
                   1056:        /*
                   1057:         * If looking is true we are searching for a known parity error
                   1058:         * and it has just occurred.  All we do is return to the higher
                   1059:         * level invocation.
                   1060:         */
                   1061:        if (looking)
                   1062:                longjmp(&parcatch);
                   1063:        s = splhigh();
                   1064:        /*
                   1065:         * If setjmp returns true, the parity error we were searching
                   1066:         * for has just occurred (longjmp above) at the current pg+o
                   1067:         */
                   1068:        if (setjmp(&parcatch)) {
                   1069:                printf("Parity error at 0x%x\n", ctob(pg)|o);
                   1070:                found = 1;
                   1071:                goto done;
                   1072:        }
                   1073:        /*
                   1074:         * If we get here, a parity error has occurred for the first time
                   1075:         * and we need to find it.  We turn off any external caches and
                   1076:         * loop thru memory, testing every longword til a fault occurs and
                   1077:         * we regain control at setjmp above.  Note that because of the
                   1078:         * setjmp, pg and o need to be volatile or their values will be lost.
                   1079:         */
                   1080:        looking = 1;
                   1081:        ecacheoff();
                   1082:        for (pg = btoc(lowram); pg < btoc(lowram)+physmem; pg++) {
                   1083:                pmap_kenter_pa((vaddr_t)vmmap, ptoa(pg), VM_PROT_READ);
                   1084:                pmap_update(pmap_kernel());
                   1085:                ip = (int *)vmmap;
                   1086:                for (o = 0; o < PAGE_SIZE; o += sizeof(int))
                   1087:                        i = *ip++;
                   1088:        }
                   1089:        /*
                   1090:         * Getting here implies no fault was found.  Should never happen.
                   1091:         */
                   1092:        printf("Couldn't locate parity error\n");
                   1093:        found = 0;
                   1094: done:
                   1095:        looking = 0;
                   1096:        ecacheon();     /* pmap_kremove() may cause a cache flush */
                   1097:        pmap_kremove((vaddr_t)vmmap, PAGE_SIZE);
                   1098:        pmap_update(pmap_kernel());
                   1099:        splx(s);
                   1100:        return(found);
                   1101: }
                   1102:
                   1103: /*
                   1104:  * cpu_exec_aout_makecmds():
                   1105:  *     cpu-dependent a.out format hook for execve().
                   1106:  *
                   1107:  * Determine of the given exec package refers to something which we
                   1108:  * understand and, if so, set up the vmcmds for it.
                   1109:  */
                   1110: int
                   1111: cpu_exec_aout_makecmds(p, epp)
                   1112:        struct proc *p;
                   1113:        struct exec_package *epp;
                   1114: {
                   1115: #if defined(COMPAT_44) || defined(COMPAT_SUNOS)
                   1116:        u_long midmag, magic;
                   1117:        u_short mid;
                   1118:        int error;
                   1119:        struct exec *execp = epp->ep_hdr;
                   1120: #ifdef COMPAT_SUNOS
                   1121:        extern int sunos_exec_aout_makecmds(struct proc *, struct exec_package *);
                   1122: #endif
                   1123:
                   1124:        midmag = ntohl(execp->a_midmag);
                   1125:        mid = (midmag >> 16) & 0xffff;
                   1126:        magic = midmag & 0xffff;
                   1127:
                   1128:        midmag = mid << 16 | magic;
                   1129:
                   1130:        switch (midmag) {
                   1131: #ifdef COMPAT_44
                   1132:        case (MID_HP300 << 16) | ZMAGIC:
                   1133:                error = exec_aout_prep_oldzmagic(p, epp);
                   1134:                break;
                   1135: #endif
                   1136:        default:
                   1137: #ifdef COMPAT_SUNOS
                   1138:                /* Hand it over to the SunOS emulation package. */
                   1139:                error = sunos_exec_aout_makecmds(p, epp);
                   1140: #else
                   1141:                error = ENOEXEC;
                   1142: #endif
                   1143:        }
                   1144:
                   1145:        return error;
                   1146: #else /* !(defined(COMPAT_44) || defined(COMPAT_SUNOS)) */
                   1147:        return ENOEXEC;
                   1148: #endif
                   1149: }

CVSweb