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