Annotation of 43BSDReno/sys/hp300/machdep.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988 University of Utah.
                      3:  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
                      4:  * All rights reserved.
                      5:  *
                      6:  * This code is derived from software contributed to Berkeley by
                      7:  * the Systems Programming Group of the University of Utah Computer
                      8:  * Science Department.
                      9:  *
                     10:  * Redistribution is only permitted until one year after the first shipment
                     11:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                     12:  * binary forms are permitted provided that: (1) source distributions retain
                     13:  * this entire copyright notice and comment, and (2) distributions including
                     14:  * binaries display the following acknowledgement:  This product includes
                     15:  * software developed by the University of California, Berkeley and its
                     16:  * contributors'' in the documentation or other materials provided with the
                     17:  * distribution and in all advertising materials mentioning features or use
                     18:  * of this software.  Neither the name of the University nor the names of
                     19:  * its contributors may be used to endorse or promote products derived from
                     20:  * this software without specific prior written permission.
                     21:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     22:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     23:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     24:  *
                     25:  * from: Utah $Hdr: machdep.c 1.51 89/11/28$
                     26:  *
                     27:  *     @(#)machdep.c   7.7 (Berkeley) 6/28/90
                     28:  */
                     29: 
                     30: #include "param.h"
                     31: #include "systm.h"
                     32: #include "user.h"
                     33: #include "kernel.h"
                     34: #include "map.h"
                     35: #include "vm.h"
                     36: #include "proc.h"
                     37: #include "buf.h"
                     38: #include "reboot.h"
                     39: #include "conf.h"
                     40: #include "file.h"
                     41: #include "text.h"
                     42: #include "clist.h"
                     43: #include "callout.h"
                     44: #include "cmap.h"
                     45: #include "malloc.h"
                     46: #include "mbuf.h"
                     47: #include "msgbuf.h"
                     48: #ifdef SYSVSHM
                     49: #include "shm.h"
                     50: #endif
                     51: #ifdef HPUXCOMPAT
                     52: #include "../hpux/hpux.h"
                     53: #endif
                     54: 
                     55: #include "cpu.h"
                     56: #include "reg.h"
                     57: #include "pte.h"
                     58: #include "psl.h"
                     59: #include "isr.h"
                     60: #include "../net/netisr.h"
                     61: 
                     62: /*
                     63:  * Declare these as initialized data so we can patch them.
                     64:  */
                     65: int    nswbuf = 0;
                     66: #ifdef NBUF
                     67: int    nbuf = NBUF;
                     68: #else
                     69: int    nbuf = 0;
                     70: #endif
                     71: #ifdef BUFPAGES
                     72: int    bufpages = BUFPAGES;
                     73: #else
                     74: int    bufpages = 0;
                     75: #endif
                     76: int    msgbufmapped;           /* set when safe to use msgbuf */
                     77: int    physmem = MAXMEM;       /* max supported memory, changes to actual */
                     78: 
                     79: extern u_int lowram;
                     80: 
                     81: /*
                     82:  * Machine-dependent startup code
                     83:  */
                     84: startup(firstaddr)
                     85:        int firstaddr;
                     86: {
                     87:        register int unixsize;
                     88:        register unsigned i;
                     89:        register struct pte *pte;
                     90:        int mapaddr, j, n;
                     91:        register caddr_t v;
                     92:        int maxbufs, base, residual;
                     93:        extern long Usrptsize;
                     94:        extern struct map *useriomap;
                     95: 
                     96:        /*
                     97:         * Set cpuspeed immediately since cninit() called routines
                     98:         * might use delay.
                     99:         */
                    100:        switch (machineid) {
                    101:        case HP_320:
                    102:        case HP_330:
                    103:        case HP_340:
                    104:                cpuspeed = MHZ_16;
                    105:                break;
                    106:        case HP_350:
                    107:        case HP_360:
                    108:                cpuspeed = MHZ_25;
                    109:                break;
                    110:        case HP_370:
                    111:                cpuspeed = MHZ_33;
                    112:                break;
                    113:        case HP_375:
                    114:                cpuspeed = MHZ_50;
                    115:                break;
                    116:        }
                    117:        /*
                    118:          * Find what hardware is attached to this machine.
                    119:          */
                    120:        find_devs();
                    121:        /*
                    122:         * Initialize the console before we print anything out.
                    123:         */
                    124:        cninit();
                    125:        /*
                    126:         * Initialize error message buffer (at end of core).
                    127:         */
                    128:        maxmem -= btoc(sizeof (struct msgbuf));
                    129:        pte = msgbufmap;
                    130:        for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
                    131:                *(int *)pte++ = PG_CI | PG_V | PG_KW | (ctob(maxmem + i));
                    132:        TBIAS();
                    133:        msgbufmapped = 1;
                    134: 
                    135:        /*
                    136:         * Good {morning,afternoon,evening,night}.
                    137:         */
                    138:        printf(version);
                    139:        identifycpu();
                    140:        printf("real mem = %d\n", ctob(physmem));
                    141: 
                    142:        /*
                    143:         * Allocate space for system data structures.
                    144:         * The first available real memory address is in "firstaddr".
                    145:         * The first available kernel virtual address is in "v".
                    146:         * As pages of kernel virtual memory are allocated, "v" is incremented.
                    147:         * As pages of memory are allocated and cleared,
                    148:         * "firstaddr" is incremented.
                    149:         * An index into the kernel page table corresponding to the
                    150:         * virtual memory address maintained in "v" is kept in "mapaddr".
                    151:         */
                    152:        v = (caddr_t)((firstaddr * NBPG) - lowram);
                    153:        mapaddr = (int)v;
                    154: #define        valloc(name, type, num) \
                    155:            (name) = (type *)v; v = (caddr_t)((name)+(num))
                    156: #define        valloclim(name, type, num, lim) \
                    157:            (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
                    158:        valloclim(file, struct file, nfile, fileNFILE);
                    159:        valloclim(proc, struct proc, nproc, procNPROC);
                    160:        valloclim(text, struct text, ntext, textNTEXT);
                    161:        valloc(cfree, struct cblock, nclist);
                    162:        valloc(callout, struct callout, ncallout);
                    163:        valloc(swapmap, struct map, nswapmap = nproc * 2);
                    164:        valloc(argmap, struct map, ARGMAPSIZE);
                    165:        valloc(kernelmap, struct map, nproc);
                    166:        valloc(mbmap, struct map, nmbclusters/4);
                    167:        valloc(kmemmap, struct map, ekmempt - kmempt);
                    168:        valloc(kmemusage, struct kmemusage, ekmempt - kmempt);
                    169:        valloc(useriomap, struct map, nproc);
                    170: #ifdef SYSVSHM
                    171:        valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
                    172: #endif
                    173:        
                    174:        /*
                    175:         * Determine how many buffers to allocate.
                    176:         * Since HPs tend to be long on memory and short on disk speed,
                    177:         * we allocate more buffer space than the BSD standard of
                    178:         * use 10% of memory for the first 2 Meg, 5% of remaining.
                    179:         * We just allocate a flat 10%.  Insure a minimum of 16 buffers.
                    180:         * We allocate 1/2 as many swap buffer headers as file i/o buffers.
                    181:         */
                    182:        if (bufpages == 0)
                    183:                bufpages = physmem / 10 / CLSIZE;
                    184:        if (nbuf == 0) {
                    185:                nbuf = bufpages;
                    186:                if (nbuf < 16)
                    187:                        nbuf = 16;
                    188:        }
                    189:        if (nswbuf == 0) {
                    190:                nswbuf = (nbuf / 2) &~ 1;       /* force even */
                    191:                if (nswbuf > 256)
                    192:                        nswbuf = 256;           /* sanity */
                    193:        }
                    194:        valloc(swbuf, struct buf, nswbuf);
                    195: 
                    196:        /*
                    197:         * Now the amount of virtual memory remaining for buffers
                    198:         * can be calculated, estimating needs for the cmap.
                    199:         */
                    200:        ncmap = (maxmem*NBPG - (firstaddr*NBPG + ((int)v - mapaddr))) /
                    201:                (CLBYTES + sizeof(struct cmap)) + 2;
                    202:        maxbufs = ((SYSPTSIZE * NBPG) -
                    203:                (int)(v + ncmap * sizeof(struct cmap))) /
                    204:                (MAXBSIZE + sizeof(struct buf));
                    205:        if (maxbufs < 16)
                    206:                panic("sys pt too small");
                    207:        if (nbuf > maxbufs) {
                    208:                printf("SYSPTSIZE limits number of buffers to %d\n", maxbufs);
                    209:                nbuf = maxbufs;
                    210:        }
                    211:        if (bufpages > nbuf * (MAXBSIZE / CLBYTES))
                    212:                bufpages = nbuf * (MAXBSIZE / CLBYTES);
                    213:        valloc(buf, struct buf, nbuf);
                    214: 
                    215:        /*
                    216:         * Allocate space for core map.
                    217:         * Allow space for all of physical memory minus the amount 
                    218:         * dedicated to the system. The amount of physical memory
                    219:         * dedicated to the system is the total virtual memory of
                    220:         * the system thus far, plus core map, buffer pages,
                    221:         * and buffer headers not yet allocated.
                    222:         * Add 2: 1 because the 0th entry is unused, 1 for rounding.
                    223:         */
                    224:        ncmap = (maxmem*NBPG - (firstaddr * NBPG +
                    225:                ((int)(v + bufpages*CLBYTES) - mapaddr))) /
                    226:                (CLBYTES + sizeof(struct cmap)) + 2;
                    227:        valloclim(cmap, struct cmap, ncmap, ecmap);
                    228: 
                    229:        /*
                    230:         * Clear space allocated thus far, and make r/w entries
                    231:         * for the space in the kernel map.
                    232:         */
                    233:        unixsize = btoc(v);
                    234:        mapaddr = btoc(mapaddr);
                    235:        while (mapaddr < unixsize) {
                    236:                *(int *)(&Sysmap[mapaddr]) = PG_V | PG_KW | ctob(firstaddr);
                    237:                clearseg((unsigned)firstaddr);
                    238:                firstaddr++;
                    239:                mapaddr++;
                    240:        }
                    241: 
                    242:        /*
                    243:         * Now allocate buffers proper.  They are different than the above
                    244:         * in that they usually occupy more virtual memory than physical.
                    245:         */
                    246:        v = (caddr_t) ((int)(v + PGOFSET) &~ PGOFSET);
                    247:        valloc(buffers, char, MAXBSIZE * nbuf);
                    248:        base = bufpages / nbuf;
                    249:        residual = bufpages % nbuf;
                    250:        for (i = 0; i < nbuf; i++) {
                    251:                n = (i < residual ? base + 1 : base) * CLSIZE;
                    252:                for (j = 0; j < n; j++) {
                    253:                        *(int *)(&Sysmap[mapaddr+j]) =
                    254:                            PG_CI | PG_V | PG_KW | ctob(firstaddr);
                    255:                        clearseg((unsigned)firstaddr);
                    256:                        firstaddr++;
                    257:                }
                    258:                mapaddr += MAXBSIZE / NBPG;
                    259:        }
                    260: 
                    261:        unixsize = btoc(v);
                    262:        if (firstaddr - Sysmap[0].pg_pfnum >= physmem - 8*UPAGES)
                    263:                panic("no memory");
                    264:        TBIA();                         /* After we just cleared it all! */
                    265: 
                    266:        /*
                    267:         * Initialize callouts
                    268:         */
                    269:        callfree = callout;
                    270:        for (i = 1; i < ncallout; i++)
                    271:                callout[i-1].c_next = &callout[i];
                    272: 
                    273:        /*
                    274:         * Initialize memory allocator and swap
                    275:         * and user page table maps.
                    276:         *
                    277:         * THE USER PAGE TABLE MAP IS CALLED ``kernelmap''
                    278:         * WHICH IS A VERY UNDESCRIPTIVE AND INCONSISTENT NAME.
                    279:         */
                    280:        meminit(firstaddr, maxmem);
                    281:        maxmem = freemem;
                    282:        printf("avail mem = %d\n", ctob(maxmem));
                    283:        printf("using %d buffers containing %d bytes of memory\n",
                    284:                nbuf, bufpages * CLBYTES);
                    285:        rminit(kernelmap, (long)&Usrptsize-CLSIZE, (long)1, "usrpt", nproc);
                    286:        rminit(useriomap, (long)USRIOSIZE, (long)1, "usrio", nproc);
                    287:        rminit(mbmap, (long)(nmbclusters * MCLBYTES / NBPG), (long)CLSIZE,
                    288:            "mbclusters", nmbclusters/4);
                    289:        kmeminit();     /* now safe to do malloc/free */
                    290: 
                    291:        /*
                    292:         * Set up CPU-specific registers, cache, etc.
                    293:         */
                    294:        initcpu();
                    295: 
                    296:        /*
                    297:         * Set up buffers, so they can be used to read disk labels.
                    298:         */
                    299:        bhinit();
                    300:        binit();
                    301: 
                    302:        /*
                    303:         * Configure the system.
                    304:         */
                    305:        configure();
                    306: }
                    307: 
                    308: #ifdef PGINPROF
                    309: /*
                    310:  * Return the difference (in microseconds)
                    311:  * between the  current time and a previous
                    312:  * time as represented by the arguments.
                    313:  */
                    314: /*ARGSUSED*/
                    315: vmtime(otime, olbolt, oicr)
                    316:        register int otime, olbolt, oicr;
                    317: {
                    318: 
                    319:        return (((time.tv_sec-otime)*100 + lbolt-olbolt)*10000);
                    320: }
                    321: #endif
                    322: 
                    323: /*
                    324:  * Clear registers on exec
                    325:  */
                    326: setregs(entry, retval)
                    327:        u_long entry;
                    328:        int retval[2];
                    329: {
                    330:        u.u_ar0[PC] = entry & ~1;
                    331: #ifdef FPCOPROC
                    332:        /* restore a null state frame */
                    333:        u.u_pcb.pcb_fpregs.fpf_null = 0;
                    334:        m68881_restore(&u.u_pcb.pcb_fpregs);
                    335: #endif
                    336: #ifdef HPUXCOMPAT
                    337:        if (u.u_procp->p_flag & SHPUX) {
                    338: 
                    339:                u.u_ar0[A0] = 0;        /* not 68010 (bit 31), no FPA (30) */
                    340:                retval[0] = 0;          /* no float card */
                    341: #ifdef FPCOPROC
                    342:                retval[1] = 1;          /* yes 68881 */
                    343: #else
                    344:                retval[1] = 0;          /* no 68881 */
                    345: #endif
                    346:        }
                    347:        /*
                    348:         * Ensure we perform the right action on traps type 1 and 2:
                    349:         * If our parent is an HPUX process and we are being traced, turn
                    350:         * on HPUX style interpretation.  Else if we were using the HPUX
                    351:         * style interpretation, revert to the BSD interpretation.
                    352:         *
                    353:         * XXX This doesn't have much to do with setting registers but
                    354:         * I didn't want to muck up kern_exec.c with this code, so I
                    355:         * stuck it here.
                    356:         */
                    357:        if ((u.u_procp->p_pptr->p_flag & SHPUX) &&
                    358:            (u.u_procp->p_flag & STRC)) {
                    359:                tweaksigcode(1);
                    360:                u.u_pcb.pcb_flags |= PCB_HPUXTRACE;
                    361:        } else if (u.u_pcb.pcb_flags & PCB_HPUXTRACE) {
                    362:                tweaksigcode(0);
                    363:                u.u_pcb.pcb_flags &= ~PCB_HPUXTRACE;
                    364:        }
                    365: #endif
                    366: }
                    367: 
                    368: identifycpu()
                    369: {
                    370:        printf("HP9000/");
                    371:        switch (machineid) {
                    372:        case HP_320:
                    373:                printf("320 (16.67Mhz");
                    374:                break;
                    375:        case HP_330:
                    376:                printf("318/319/330 (16.67Mhz");
                    377:                break;
                    378:        case HP_340:
                    379:                printf("340 (16.67Mhz");
                    380:                break;
                    381:        case HP_350:
                    382:                printf("350 (25Mhz");
                    383:                break;
                    384:        case HP_360:
                    385:                printf("360 (25Mhz");
                    386:                break;
                    387:        case HP_370:
                    388:                printf("370 (33.33Mhz");
                    389:                break;
                    390:        case HP_375:
                    391:                printf("345/375 (50Mhz");
                    392:                break;
                    393:        default:
                    394:                printf("\nunknown machine type %d\n", machineid);
                    395:                panic("startup");
                    396:        }
                    397:        printf(" MC680%s CPU", mmutype == MMU_68030 ? "30" : "20");
                    398:        switch (mmutype) {
                    399:        case MMU_68030:
                    400:                printf("+MMU");
                    401:                break;
                    402:        case MMU_68851:
                    403:                printf(", MC68851 MMU");
                    404:                break;
                    405:        case MMU_HP:
                    406:                printf(", HP MMU");
                    407:                break;
                    408:        default:
                    409:                printf("\nunknown MMU type %d\n", mmutype);
                    410:                panic("startup");
                    411:        }
                    412:        if (mmutype == MMU_68030)
                    413:                printf(", %sMhz MC68882 FPU",
                    414:                       machineid == HP_340 ? "16.67" :
                    415:                       (machineid == HP_360 ? "25" :
                    416:                        (machineid == HP_370 ? "33.33" : "50")));
                    417:        else
                    418:                printf(", %sMhz MC68881 FPU",
                    419:                       machineid == HP_350 ? "20" : "16.67");
                    420:        switch (ectype) {
                    421:        case EC_VIRT:
                    422:                printf(", %dK virtual-address cache",
                    423:                       machineid == HP_320 ? 16 : 32);
                    424:                break;
                    425:        case EC_PHYS:
                    426:                printf(", %dK physical-address cache",
                    427:                       machineid == HP_370 ? 64 : 32);
                    428:                break;
                    429:        }
                    430:        printf(")\n");
                    431:        /*
                    432:         * Now that we have told the user what they have,
                    433:         * let them know if that machine type isn't configured.
                    434:         */
                    435:        switch (machineid) {
                    436:        case -1:                /* keep compilers happy */
                    437: #if !defined(HP320) && !defined(HP350)
                    438:        case HP_320:
                    439:        case HP_350:
                    440: #endif
                    441: #ifndef HP330
                    442:        case HP_330:
                    443: #endif
                    444: #if !defined(HP360) && !defined(HP370)
                    445:        case HP_340:
                    446:        case HP_360:
                    447:        case HP_370:
                    448: #endif
                    449:                panic("CPU type not configured");
                    450:        default:
                    451:                break;
                    452:        }
                    453: }
                    454: 
                    455: #ifdef HPUXCOMPAT
                    456: tweaksigcode(ishpux)
                    457: {
                    458:        static short *sigtrap = NULL;
                    459: 
                    460:        /* locate trap instruction in pcb_sigc */
                    461:        if (sigtrap == NULL) {
                    462:                register struct pcb *pcp = &u.u_pcb;
                    463: 
                    464:                sigtrap = &pcp->pcb_sigc[sizeof(pcp->pcb_sigc)/sizeof(short)];
                    465:                while (--sigtrap >= pcp->pcb_sigc)
                    466:                        if ((*sigtrap & 0xFFF0) == 0x4E40)
                    467:                                break;
                    468:                if (sigtrap < pcp->pcb_sigc)
                    469:                        panic("bogus sigcode\n");
                    470:        }
                    471:        *sigtrap = ishpux ? 0x4E42 : 0x4E41;
                    472: }
                    473: #endif
                    474: 
                    475: #define SS_RTEFRAME    1
                    476: #define SS_FPSTATE     2
                    477: #define SS_USERREGS    4
                    478: 
                    479: struct sigstate {
                    480:        int     ss_flags;               /* which of the following are valid */
                    481:        struct  frame ss_frame;         /* original exception frame */
                    482:        struct  fpframe ss_fpstate;     /* 68881/68882 state info */
                    483: };
                    484: 
                    485: /*
                    486:  * WARNING: code in locore.s assumes the layout shown for sf_signum
                    487:  * thru sf_handler so... don't screw with them!
                    488:  */
                    489: struct sigframe {
                    490:        int     sf_signum;              /* signo for handler */
                    491:        int     sf_code;                /* additional info for handler */
                    492:        struct  sigcontext *sf_scp;     /* context ptr for handler */
                    493:        sig_t   sf_handler;             /* handler addr for u_sigc */
                    494:        struct  sigstate sf_state;      /* state of the hardware */
                    495:        struct  sigcontext sf_sc;       /* actual context */
                    496: };
                    497: 
                    498: #ifdef HPUXCOMPAT
                    499: struct hpuxsigcontext {
                    500:        int     hsc_syscall;
                    501:        char    hsc_action;
                    502:        char    hsc_pad1;
                    503:        char    hsc_pad2;
                    504:        char    hsc_onstack;
                    505:        int     hsc_mask;
                    506:        int     hsc_sp;
                    507:        short   hsc_ps;
                    508:        int     hsc_pc;
                    509: /* the rest aren't part of the context but are included for our convenience */
                    510:        short   hsc_pad;
                    511:        u_int   hsc_magic;              /* XXX sigreturn: cookie */
                    512:        struct  sigcontext *hsc_realsc; /* XXX sigreturn: ptr to BSD context */
                    513: };
                    514: 
                    515: /*
                    516:  * For an HP-UX process, a partial hpuxsigframe follows the normal sigframe.
                    517:  * Tremendous waste of space, but some HP-UX applications (e.g. LCL) need it.
                    518:  */
                    519: struct hpuxsigframe {
                    520:        int     hsf_signum;
                    521:        int     hsf_code;
                    522:        struct  sigcontext *hsf_scp;
                    523:        struct  hpuxsigcontext hsf_sc;
                    524:        int     hsf_regs[15];
                    525: };
                    526: #endif
                    527: 
                    528: #ifdef DEBUG
                    529: int sigdebug = 0;
                    530: int sigpid = 0;
                    531: #define SDB_FOLLOW     0x01
                    532: #define SDB_KSTACK     0x02
                    533: #define SDB_FPSTATE    0x04
                    534: #endif
                    535: 
                    536: /*
                    537:  * Send an interrupt to process.
                    538:  */
                    539: sendsig(catcher, sig, mask, code)
                    540:        sig_t catcher;
                    541:        int sig, mask;
                    542:        unsigned code;
                    543: {
                    544:        register struct proc *p = u.u_procp;
                    545:        register struct sigframe *fp, *kfp;
                    546:        register struct frame *frame;
                    547:        register short ft;
                    548:        int oonstack, fsize;
                    549: 
                    550:        frame = (struct frame *)u.u_ar0;
                    551:        ft = frame->f_format;
                    552:        oonstack = u.u_onstack;
                    553:        /*
                    554:         * Allocate and validate space for the signal handler
                    555:         * context. Note that if the stack is in P0 space, the
                    556:         * call to grow() is a nop, and the useracc() check
                    557:         * will fail if the process has not already allocated
                    558:         * the space with a `brk'.
                    559:         */
                    560: #ifdef HPUXCOMPAT
                    561:        if (p->p_flag & SHPUX)
                    562:                fsize = sizeof(struct sigframe) + sizeof(struct hpuxsigframe);
                    563:        else
                    564: #endif
                    565:        fsize = sizeof(struct sigframe);
                    566:        if (!u.u_onstack && (u.u_sigonstack & sigmask(sig))) {
                    567:                fp = (struct sigframe *)(u.u_sigsp - fsize);
                    568:                u.u_onstack = 1;
                    569:        } else
                    570:                fp = (struct sigframe *)(frame->f_regs[SP] - fsize);
                    571:        if ((unsigned)fp <= USRSTACK - ctob(u.u_ssize)) 
                    572:                (void)grow((unsigned)fp);
                    573: #ifdef DEBUG
                    574:        if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
                    575:                printf("sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n",
                    576:                       p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
                    577: #endif
                    578:        if (useracc((caddr_t)fp, fsize, B_WRITE) == 0) {
                    579: #ifdef DEBUG
                    580:                if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
                    581:                        printf("sendsig(%d): useracc failed on sig %d\n",
                    582:                               p->p_pid, sig);
                    583: #endif
                    584:                /*
                    585:                 * Process has trashed its stack; give it an illegal
                    586:                 * instruction to halt it in its tracks.
                    587:                 */
                    588:                SIGACTION(p, SIGILL) = SIG_DFL;
                    589:                sig = sigmask(SIGILL);
                    590:                p->p_sigignore &= ~sig;
                    591:                p->p_sigcatch &= ~sig;
                    592:                p->p_sigmask &= ~sig;
                    593:                psignal(p, SIGILL);
                    594:                return;
                    595:        }
                    596:        kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK);
                    597:        /* 
                    598:         * Build the argument list for the signal handler.
                    599:         */
                    600:        kfp->sf_signum = sig;
                    601:        kfp->sf_code = code;
                    602:        kfp->sf_scp = &fp->sf_sc;
                    603:        kfp->sf_handler = catcher;
                    604:        /*
                    605:         * Save necessary hardware state.  Currently this includes:
                    606:         *      - general registers
                    607:         *      - original exception frame (if not a "normal" frame)
                    608:         *      - FP coprocessor state
                    609:         */
                    610:        kfp->sf_state.ss_flags = SS_USERREGS;
                    611:        bcopy((caddr_t)frame->f_regs,
                    612:              (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs);
                    613:        if (ft >= FMT9) {
                    614: #ifdef DEBUG
                    615:                if (ft != FMT9 && ft != FMTA && ft != FMTB)
                    616:                        panic("sendsig: bogus frame type");
                    617: #endif
                    618:                kfp->sf_state.ss_flags |= SS_RTEFRAME;
                    619:                kfp->sf_state.ss_frame.f_format = frame->f_format;
                    620:                kfp->sf_state.ss_frame.f_vector = frame->f_vector;
                    621:                bcopy((caddr_t)&frame->F_u,
                    622:                      (caddr_t)&kfp->sf_state.ss_frame.F_u,
                    623:                      (ft == FMT9) ? FMT9SIZE :
                    624:                      (ft == FMTA) ? FMTASIZE : FMTBSIZE);
                    625:                /*
                    626:                 * Gag!  Leave an indicator that we need to clean up the
                    627:                 * kernel stack.  We do this by setting the "pad word"
                    628:                 * above the hardware stack frame.  "bexit" in locore
                    629:                 * will then know that it must compress the kernel stack
                    630:                 * and create a normal four word stack frame.
                    631:                 */
                    632:                frame->f_stackadj = -1;
                    633: #ifdef DEBUG
                    634:                if (sigdebug & SDB_FOLLOW)
                    635:                        printf("sendsig(%d): copy out %d of frame %d\n",
                    636:                               p->p_pid,
                    637:                               (ft == FMT9) ? FMT9SIZE :
                    638:                               (ft == FMTA) ? FMTASIZE : FMTBSIZE, ft);
                    639: #endif
                    640:        }
                    641: #ifdef FPCOPROC
                    642:        kfp->sf_state.ss_flags |= SS_FPSTATE;
                    643:        m68881_save(&kfp->sf_state.ss_fpstate);
                    644: #ifdef DEBUG
                    645:        if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate)
                    646:                printf("sendsig(%d): copy out FP state (%x) to %x\n",
                    647:                       p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate,
                    648:                       &kfp->sf_state.ss_fpstate);
                    649: #endif
                    650: #endif
                    651:        /*
                    652:         * Build the signal context to be used by sigreturn.
                    653:         */
                    654:        kfp->sf_sc.sc_onstack = oonstack;
                    655:        kfp->sf_sc.sc_mask = mask;
                    656:        kfp->sf_sc.sc_sp = frame->f_regs[SP];
                    657:        kfp->sf_sc.sc_fp = frame->f_regs[A6];
                    658:        kfp->sf_sc.sc_ap = (int)&fp->sf_state;
                    659:        kfp->sf_sc.sc_pc = frame->f_pc;
                    660:        kfp->sf_sc.sc_ps = frame->f_sr;
                    661: #ifdef HPUXCOMPAT
                    662:        /*
                    663:         * Create an HP-UX style sigcontext structure and associated goo
                    664:         */
                    665:        if (p->p_flag & SHPUX) {
                    666:                register struct hpuxsigframe *hkfp;
                    667: 
                    668:                hkfp = (struct hpuxsigframe *)&kfp[1];
                    669:                hkfp->hsf_signum = bsdtohpuxsig(kfp->sf_signum);
                    670:                hkfp->hsf_code = kfp->sf_code;
                    671:                hkfp->hsf_scp = (struct sigcontext *)
                    672:                        &((struct hpuxsigframe *)(&fp[1]))->hsf_sc;
                    673:                hkfp->hsf_sc.hsc_syscall = 0;           /* XXX */
                    674:                hkfp->hsf_sc.hsc_action = 0;            /* XXX */
                    675:                hkfp->hsf_sc.hsc_pad1 = hkfp->hsf_sc.hsc_pad2 = 0;
                    676:                hkfp->hsf_sc.hsc_onstack = kfp->sf_sc.sc_onstack;
                    677:                hkfp->hsf_sc.hsc_mask = kfp->sf_sc.sc_mask;
                    678:                hkfp->hsf_sc.hsc_sp = kfp->sf_sc.sc_sp;
                    679:                hkfp->hsf_sc.hsc_ps = kfp->sf_sc.sc_ps;
                    680:                hkfp->hsf_sc.hsc_pc = kfp->sf_sc.sc_pc;
                    681:                hkfp->hsf_sc.hsc_pad = 0;
                    682:                hkfp->hsf_sc.hsc_magic = 0xdeadbeef;
                    683:                hkfp->hsf_sc.hsc_realsc = kfp->sf_scp;
                    684:                bcopy((caddr_t)frame->f_regs, (caddr_t)hkfp->hsf_regs,
                    685:                      sizeof (hkfp->hsf_regs));
                    686: 
                    687:                kfp->sf_signum = hkfp->hsf_signum;
                    688:                kfp->sf_scp = hkfp->hsf_scp;
                    689:        }
                    690: #endif
                    691:        (void) copyout((caddr_t)kfp, (caddr_t)fp, fsize);
                    692:        frame->f_regs[SP] = (int)fp;
                    693: #ifdef DEBUG
                    694:        if (sigdebug & SDB_FOLLOW)
                    695:                printf("sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n",
                    696:                       p->p_pid, sig, kfp->sf_scp, fp,
                    697:                       kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);
                    698: #endif
                    699:        /*
                    700:         * User PC is set to signal trampoline code.  The catch is that
                    701:         * it must be set to reference the pcb via the user space address
                    702:         * NOT via u.  Assumption: u-area is at USRSTACK.
                    703:         */
                    704:        frame->f_pc = (int)((struct user *)USRSTACK)->u_pcb.pcb_sigc;
                    705: #ifdef DEBUG
                    706:        if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
                    707:                printf("sendsig(%d): sig %d returns\n",
                    708:                       p->p_pid, sig);
                    709: #endif
                    710:        free((caddr_t)kfp, M_TEMP);
                    711: }
                    712: 
                    713: /*
                    714:  * System call to cleanup state after a signal
                    715:  * has been taken.  Reset signal mask and
                    716:  * stack state from context left by sendsig (above).
                    717:  * Return to previous pc and psl as specified by
                    718:  * context left by sendsig. Check carefully to
                    719:  * make sure that the user has not modified the
                    720:  * psl to gain improper priviledges or to cause
                    721:  * a machine fault.
                    722:  */
                    723: /* ARGSUSED */
                    724: sigreturn(p, uap, retval)
                    725:        struct proc *p;
                    726:        struct args {
                    727:                struct sigcontext *sigcntxp;
                    728:        } *uap;
                    729:        int *retval;
                    730: {
                    731:        register struct sigcontext *scp;
                    732:        register struct frame *frame;
                    733:        register int rf;
                    734:        struct sigcontext tsigc;
                    735:        struct sigstate tstate;
                    736:        int flags;
                    737: 
                    738:        scp = uap->sigcntxp;
                    739: #ifdef DEBUG
                    740:        if (sigdebug & SDB_FOLLOW)
                    741:                printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
                    742: #endif
                    743:        if ((int)scp & 1)
                    744:                return (EINVAL);
                    745: #ifdef HPUXCOMPAT
                    746:        /*
                    747:         * Grab context as an HP-UX style context and determine if it
                    748:         * was one that we contructed in sendsig.
                    749:         */
                    750:        if (p->p_flag & SHPUX) {
                    751:                struct hpuxsigcontext *hscp = (struct hpuxsigcontext *)scp;
                    752:                struct hpuxsigcontext htsigc;
                    753: 
                    754:                if (useracc((caddr_t)hscp, sizeof (*hscp), B_WRITE) == 0 ||
                    755:                    copyin((caddr_t)hscp, (caddr_t)&htsigc, sizeof htsigc))
                    756:                        return (EINVAL);
                    757:                /*
                    758:                 * If not generated by sendsig or we cannot restore the
                    759:                 * BSD-style sigcontext, just restore what we can -- state
                    760:                 * will be lost, but them's the breaks.
                    761:                 */
                    762:                hscp = &htsigc;
                    763:                if (hscp->hsc_magic != 0xdeadbeef ||
                    764:                    (scp = hscp->hsc_realsc) == 0 ||
                    765:                    useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
                    766:                    copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) {
                    767:                        u.u_onstack = hscp->hsc_onstack & 01;
                    768:                        p->p_sigmask = hscp->hsc_mask &~ sigcantmask;
                    769:                        frame = (struct frame *) u.u_ar0;
                    770:                        frame->f_regs[SP] = hscp->hsc_sp;
                    771:                        frame->f_pc = hscp->hsc_pc;
                    772:                        frame->f_sr = hscp->hsc_ps &~ PSL_USERCLR;
                    773:                        return (EJUSTRETURN);
                    774:                }
                    775:                /*
                    776:                 * Otherwise, overlay BSD context with possibly modified
                    777:                 * HP-UX values.
                    778:                 */
                    779:                tsigc.sc_onstack = hscp->hsc_onstack;
                    780:                tsigc.sc_mask = hscp->hsc_mask;
                    781:                tsigc.sc_sp = hscp->hsc_sp;
                    782:                tsigc.sc_ps = hscp->hsc_ps;
                    783:                tsigc.sc_pc = hscp->hsc_pc;
                    784:        } else
                    785: #endif
                    786:        /*
                    787:         * Test and fetch the context structure.
                    788:         * We grab it all at once for speed.
                    789:         */
                    790:        if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
                    791:            copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
                    792:                return (EINVAL);
                    793:        scp = &tsigc;
                    794:        if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0)
                    795:                return (EINVAL);
                    796:        /*
                    797:         * Restore the user supplied information
                    798:         */
                    799:        u.u_onstack = scp->sc_onstack & 01;
                    800:        p->p_sigmask = scp->sc_mask &~ sigcantmask;
                    801:        frame = (struct frame *) u.u_ar0;
                    802:        frame->f_regs[SP] = scp->sc_sp;
                    803:        frame->f_regs[A6] = scp->sc_fp;
                    804:        frame->f_pc = scp->sc_pc;
                    805:        frame->f_sr = scp->sc_ps;
                    806:        /*
                    807:         * Grab pointer to hardware state information.
                    808:         * If zero, the user is probably doing a longjmp.
                    809:         */
                    810:        if ((rf = scp->sc_ap) == 0)
                    811:                return (EJUSTRETURN);
                    812:        /*
                    813:         * See if there is anything to do before we go to the
                    814:         * expense of copying in close to 1/2K of data
                    815:         */
                    816:        flags = fuword((caddr_t)rf);
                    817: #ifdef DEBUG
                    818:        if (sigdebug & SDB_FOLLOW)
                    819:                printf("sigreturn(%d): sc_ap %x flags %x\n",
                    820:                       p->p_pid, rf, flags);
                    821: #endif
                    822:        if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
                    823:                return (EJUSTRETURN);
                    824: #ifdef DEBUG
                    825:        if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
                    826:                printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n",
                    827:                       p->p_pid, &flags, scp->sc_sp, uap->sigcntxp,
                    828:                       (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1);
                    829: #endif
                    830:        /*
                    831:         * Restore most of the users registers except for A6 and SP
                    832:         * which were handled above.
                    833:         */
                    834:        if (flags & SS_USERREGS)
                    835:                bcopy((caddr_t)tstate.ss_frame.f_regs,
                    836:                      (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
                    837:        /*
                    838:         * Restore long stack frames.  Note that we do not copy
                    839:         * back the saved SR or PC, they were picked up above from
                    840:         * the sigcontext structure.
                    841:         */
                    842:        if (flags & SS_RTEFRAME) {
                    843:                register int sz;
                    844:                
                    845:                /* grab frame type and validate */
                    846:                sz = tstate.ss_frame.f_format;
                    847:                if (sz == FMT9)
                    848:                        sz = FMT9SIZE;
                    849:                else if (sz == FMTA)
                    850:                        sz = FMTASIZE;
                    851:                else if (sz == FMTB) {
                    852:                        sz = FMTBSIZE;
                    853:                        /* no k-stack adjustment necessary */
                    854:                        frame->f_stackadj = 0;
                    855:                } else
                    856:                        return (EINVAL);
                    857:                frame->f_format = tstate.ss_frame.f_format;
                    858:                frame->f_vector = tstate.ss_frame.f_vector;
                    859:                bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz);
                    860: #ifdef DEBUG
                    861:                if (sigdebug & SDB_FOLLOW)
                    862:                        printf("sigreturn(%d): copy in %d of frame type %d\n",
                    863:                               p->p_pid, sz, tstate.ss_frame.f_format);
                    864: #endif
                    865:        }
                    866: #ifdef FPCOPROC
                    867:        /*
                    868:         * Finally we restore the original FP context
                    869:         */
                    870:        if (flags & SS_FPSTATE)
                    871:                m68881_restore(&tstate.ss_fpstate);
                    872: #ifdef DEBUG
                    873:        if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
                    874:                printf("sigreturn(%d): copied in FP state (%x) at %x\n",
                    875:                       p->p_pid, *(u_int *)&tstate.ss_fpstate,
                    876:                       &tstate.ss_fpstate);
                    877: #endif
                    878: #endif
                    879: #ifdef DEBUG
                    880:        if ((sigdebug & SDB_FOLLOW) ||
                    881:            ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
                    882:                printf("sigreturn(%d): returns\n", p->p_pid);
                    883: #endif
                    884:        return (EJUSTRETURN);
                    885: }
                    886: 
                    887: int    waittime = -1;
                    888: 
                    889: boot(howto)
                    890:        register int howto;
                    891: {
                    892:        /* take a snap shot before clobbering any registers */
                    893:        resume((u_int)pcbb(u.u_procp));
                    894: 
                    895:        boothowto = howto;
                    896:        if ((howto&RB_NOSYNC) == 0 && waittime < 0 && bfreelist[0].b_forw) {
                    897:                register struct buf *bp;
                    898:                int iter, nbusy;
                    899: 
                    900:                waittime = 0;
                    901:                (void) spl0();
                    902:                printf("syncing disks... ");
                    903:                /*
                    904:                 * Release vnodes held by texts before sync.
                    905:                 */
                    906:                if (panicstr == 0)
                    907:                        xumount(NULL);
                    908: #include "fd.h"
                    909: #if NFD > 0
                    910:                fdshutdown();
                    911: #endif
                    912:                sync((struct sigcontext *)0);
                    913: 
                    914:                for (iter = 0; iter < 20; iter++) {
                    915:                        nbusy = 0;
                    916:                        for (bp = &buf[nbuf]; --bp >= buf; )
                    917:                                if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
                    918:                                        nbusy++;
                    919:                        if (nbusy == 0)
                    920:                                break;
                    921:                        printf("%d ", nbusy);
                    922:                        DELAY(40000 * iter);
                    923:                }
                    924:                if (nbusy)
                    925:                        printf("giving up\n");
                    926:                else
                    927:                        printf("done\n");
                    928:                /*
                    929:                 * If we've been adjusting the clock, the todr
                    930:                 * will be out of synch; adjust it now.
                    931:                 */
                    932:                resettodr();
                    933:        }
                    934:        splhigh();                      /* extreme priority */
                    935:        if (howto&RB_HALT) {
                    936:                printf("halted\n\n");
                    937:                asm("   stop    #0x2700");
                    938:        } else {
                    939:                if (howto & RB_DUMP)
                    940:                        dumpsys();
                    941:                doboot();
                    942:                /*NOTREACHED*/
                    943:        }
                    944:        /*NOTREACHED*/
                    945: }
                    946: 
                    947: int    dumpmag = 0x8fca0101;   /* magic number for savecore */
                    948: int    dumpsize = 0;           /* also for savecore */
                    949: 
                    950: dumpconf()
                    951: {
                    952:        int nblks;
                    953: 
                    954:        dumpsize = physmem;
                    955:        if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
                    956:                nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
                    957:                if (dumpsize > btoc(dbtob(nblks - dumplo)))
                    958:                        dumpsize = btoc(dbtob(nblks - dumplo));
                    959:                else if (dumplo == 0)
                    960:                        dumplo = nblks - btodb(ctob(physmem));
                    961:        }
                    962:        /*
                    963:         * Don't dump on the first CLBYTES (why CLBYTES?)
                    964:         * in case the dump device includes a disk label.
                    965:         */
                    966:        if (dumplo < btodb(CLBYTES))
                    967:                dumplo = btodb(CLBYTES);
                    968: }
                    969: 
                    970: /*
                    971:  * Doadump comes here after turning off memory management and
                    972:  * getting on the dump stack, either when called above, or by
                    973:  * the auto-restart code.
                    974:  */
                    975: dumpsys()
                    976: {
                    977: 
                    978:        msgbufmapped = 0;
                    979:        if (dumpdev == NODEV)
                    980:                return;
                    981:        /*
                    982:         * For dumps during autoconfiguration,
                    983:         * if dump device has already configured...
                    984:         */
                    985:        if (dumpsize == 0)
                    986:                dumpconf();
                    987:        if (dumplo < 0)
                    988:                return;
                    989:        printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
                    990:        printf("dump ");
                    991:        switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
                    992: 
                    993:        case ENXIO:
                    994:                printf("device bad\n");
                    995:                break;
                    996: 
                    997:        case EFAULT:
                    998:                printf("device not ready\n");
                    999:                break;
                   1000: 
                   1001:        case EINVAL:
                   1002:                printf("area improper\n");
                   1003:                break;
                   1004: 
                   1005:        case EIO:
                   1006:                printf("i/o error\n");
                   1007:                break;
                   1008: 
                   1009:        default:
                   1010:                printf("succeeded\n");
                   1011:                break;
                   1012:        }
                   1013: }
                   1014: 
                   1015: /*
                   1016:  * Return the best possible estimate of the time in the timeval
                   1017:  * to which tvp points.  We do this by returning the current time
                   1018:  * plus the amount of time since the last clock interrupt (clock.c:clkread).
                   1019:  *
                   1020:  * Check that this time is no less than any previously-reported time,
                   1021:  * which could happen around the time of a clock adjustment.  Just for fun,
                   1022:  * we guarantee that the time will be greater than the value obtained by a
                   1023:  * previous call.
                   1024:  */
                   1025: microtime(tvp)
                   1026:        register struct timeval *tvp;
                   1027: {
                   1028:        int s = splhigh();
                   1029:        static struct timeval lasttime;
                   1030: 
                   1031:        *tvp = time;
                   1032:        tvp->tv_usec += clkread();
                   1033:        while (tvp->tv_usec > 1000000) {
                   1034:                tvp->tv_sec++;
                   1035:                tvp->tv_usec -= 1000000;
                   1036:        }
                   1037:        if (tvp->tv_sec == lasttime.tv_sec &&
                   1038:            tvp->tv_usec <= lasttime.tv_usec &&
                   1039:            (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {
                   1040:                tvp->tv_sec++;
                   1041:                tvp->tv_usec -= 1000000;
                   1042:        }
                   1043:        lasttime = *tvp;
                   1044:        splx(s);
                   1045: }
                   1046: 
                   1047: initcpu()
                   1048: {
                   1049:        parityenable();
                   1050: }
                   1051: 
                   1052: straytrap(addr)
                   1053:        register int addr;
                   1054: {
                   1055:        printf("stray trap, addr 0x%x\n", addr);
                   1056: }
                   1057: 
                   1058: int    *nofault;
                   1059: 
                   1060: badaddr(addr)
                   1061:        register caddr_t addr;
                   1062: {
                   1063:        register int i;
                   1064:        label_t faultbuf;
                   1065: 
                   1066: #ifdef lint
                   1067:        i = *addr; if (i) return(0);
                   1068: #endif
                   1069:        nofault = (int *) &faultbuf;
                   1070:        if (setjmp((label_t *)nofault)) {
                   1071:                nofault = (int *) 0;
                   1072:                return(1);
                   1073:        }
                   1074:        i = *(volatile short *)addr;
                   1075:        nofault = (int *) 0;
                   1076:        return(0);
                   1077: }
                   1078: 
                   1079: badbaddr(addr)
                   1080:        register caddr_t addr;
                   1081: {
                   1082:        register int i;
                   1083:        label_t faultbuf;
                   1084: 
                   1085: #ifdef lint
                   1086:        i = *addr; if (i) return(0);
                   1087: #endif
                   1088:        nofault = (int *) &faultbuf;
                   1089:        if (setjmp((label_t *)nofault)) {
                   1090:                nofault = (int *) 0;
                   1091:                return(1);
                   1092:        }
                   1093:        i = *(volatile char *)addr;
                   1094:        nofault = (int *) 0;
                   1095:        return(0);
                   1096: }
                   1097: 
                   1098: netintr()
                   1099: {
                   1100: #ifdef INET
                   1101:        if (netisr & (1 << NETISR_IP)) {
                   1102:                netisr &= ~(1 << NETISR_IP);
                   1103:                ipintr();
                   1104:        }
                   1105: #endif
                   1106: #ifdef NS
                   1107:        if (netisr & (1 << NETISR_NS)) {
                   1108:                netisr &= ~(1 << NETISR_NS);
                   1109:                nsintr();
                   1110:        }
                   1111: #endif
                   1112: #ifdef ISO
                   1113:        if (netisr & (1 << NETISR_ISO)) {
                   1114:                netisr &= ~(1 << NETISR_ISO);
                   1115:                clnlintr();
                   1116:        }
                   1117: #endif
                   1118: }
                   1119: 
                   1120: intrhand(sr)
                   1121:        int sr;
                   1122: {
                   1123:        register struct isr *isr;
                   1124:        register int found = 0;
                   1125:        register int ipl;
                   1126:        extern struct isr isrqueue[];
                   1127: 
                   1128:        ipl = (sr >> 8) & 7;
                   1129:        switch (ipl) {
                   1130: 
                   1131:        case 3:
                   1132:        case 4:
                   1133:        case 5:
                   1134:                ipl = ISRIPL(ipl);
                   1135:                isr = isrqueue[ipl].isr_forw;
                   1136:                for (; isr != &isrqueue[ipl]; isr = isr->isr_forw) {
                   1137:                        if ((isr->isr_intr)(isr->isr_arg)) {
                   1138:                                found++;
                   1139:                                break;
                   1140:                        }
                   1141:                }
                   1142:                if (found == 0)
                   1143:                        printf("stray interrupt, sr 0x%x\n", sr);
                   1144:                break;
                   1145: 
                   1146:        case 0:
                   1147:        case 1:
                   1148:        case 2:
                   1149:        case 6:
                   1150:        case 7:
                   1151:                printf("intrhand: unexpected sr 0x%x\n", sr);
                   1152:                break;
                   1153:        }
                   1154: }
                   1155: 
                   1156: #if defined(DEBUG) && !defined(PANICBUTTON)
                   1157: #define PANICBUTTON
                   1158: #endif
                   1159: 
                   1160: #ifdef PANICBUTTON
                   1161: int panicbutton = 1;   /* non-zero if panic buttons are enabled */
                   1162: int crashandburn = 0;
                   1163: int candbdelay = 50;   /* give em half a second */
                   1164: 
                   1165: candbtimer()
                   1166: {
                   1167:        crashandburn = 0;
                   1168: }
                   1169: #endif
                   1170: 
                   1171: /*
                   1172:  * Level 7 interrupts can be caused by the keyboard or parity errors.
                   1173:  */
                   1174: nmihand(frame)
                   1175:        struct frame frame;
                   1176: {
                   1177:        if (kbdnmi()) {
                   1178: #ifdef PANICBUTTON
                   1179:                printf("Got a keyboard NMI\n");
                   1180:                if (panicbutton) {
                   1181:                        if (crashandburn) {
                   1182:                                crashandburn = 0;
                   1183:                                panic(panicstr ?
                   1184:                                      "forced crash, nosync" : "forced crash");
                   1185:                        }
                   1186:                        crashandburn++;
                   1187:                        timeout(candbtimer, (caddr_t)0, candbdelay);
                   1188:                }
                   1189: #endif
                   1190:                return;
                   1191:        }
                   1192:        if (parityerror(&frame))
                   1193:                return;
                   1194:        /* panic?? */
                   1195:        printf("unexpected level 7 interrupt ignored\n");
                   1196: }
                   1197: 
                   1198: /*
                   1199:  * Parity error section.  Contains magic.
                   1200:  */
                   1201: #define PARREG         ((volatile short *)IOV(0x5B0000))
                   1202: static int gotparmem = 0;
                   1203: #ifdef DEBUG
                   1204: int ignorekperr = 0;   /* ignore kernel parity errors */
                   1205: #endif
                   1206: 
                   1207: /*
                   1208:  * Enable parity detection
                   1209:  */
                   1210: parityenable()
                   1211: {
                   1212:        label_t faultbuf;
                   1213: 
                   1214:        nofault = (int *) &faultbuf;
                   1215:        if (setjmp((label_t *)nofault)) {
                   1216:                nofault = (int *) 0;
                   1217: #ifdef DEBUG
                   1218:                printf("No parity memory\n");
                   1219: #endif
                   1220:                return;
                   1221:        }
                   1222:        *PARREG = 1;
                   1223:        nofault = (int *) 0;
                   1224:        gotparmem = 1;
                   1225: #ifdef DEBUG
                   1226:        printf("Parity detection enabled\n");
                   1227: #endif
                   1228: }
                   1229: 
                   1230: /*
                   1231:  * Determine if level 7 interrupt was caused by a parity error
                   1232:  * and deal with it if it was.  Returns 1 if it was a parity error.
                   1233:  */
                   1234: parityerror(fp)
                   1235:        struct frame *fp;
                   1236: {
                   1237:        if (!gotparmem)
                   1238:                return(0);
                   1239:        *PARREG = 0;
                   1240:        DELAY(10);
                   1241:        *PARREG = 1;
                   1242:        if (panicstr) {
                   1243:                printf("parity error after panic ignored\n");
                   1244:                return(1);
                   1245:        }
                   1246:        if (!findparerror())
                   1247:                printf("WARNING: transient parity error ignored\n");
                   1248:        else if (USERMODE(fp->f_sr)) {
                   1249:                printf("pid %d: parity error\n", u.u_procp->p_pid);
                   1250:                uprintf("sorry, pid %d killed due to memory parity error\n",
                   1251:                        u.u_procp->p_pid);
                   1252:                psignal(u.u_procp, SIGKILL);
                   1253: #ifdef DEBUG
                   1254:        } else if (ignorekperr) {
                   1255:                printf("WARNING: kernel parity error ignored\n");
                   1256: #endif
                   1257:        } else {
                   1258:                regdump(fp->f_regs, 128);
                   1259:                panic("kernel parity error");
                   1260:        }
                   1261:        return(1);
                   1262: }
                   1263: 
                   1264: /*
                   1265:  * Yuk!  There has got to be a better way to do this!
                   1266:  * Searching all of memory with interrupts blocked can lead to disaster.
                   1267:  */
                   1268: findparerror()
                   1269: {
                   1270:        static label_t parcatch;
                   1271:        static int looking = 0;
                   1272:        volatile struct pte opte;
                   1273:        volatile int pg, o, s;
                   1274:        register volatile int *ip;
                   1275:        register int i;
                   1276:        int found;
                   1277: 
                   1278: #ifdef lint
                   1279:        ip = &found;
                   1280:        i = o = pg = 0; if (i) return(0);
                   1281: #endif
                   1282:        /*
                   1283:         * If looking is true we are searching for a known parity error
                   1284:         * and it has just occured.  All we do is return to the higher
                   1285:         * level invocation.
                   1286:         */
                   1287:        if (looking)
                   1288:                longjmp(&parcatch);
                   1289:        s = splhigh();
                   1290:        /*
                   1291:         * If setjmp returns true, the parity error we were searching
                   1292:         * for has just occured (longjmp above) at the current pg+o
                   1293:         */
                   1294:        if (setjmp(&parcatch)) {
                   1295:                printf("Parity error at 0x%x\n", ctob(pg)|o);
                   1296:                found = 1;
                   1297:                goto done;
                   1298:        }
                   1299:        /*
                   1300:         * If we get here, a parity error has occured for the first time
                   1301:         * and we need to find it.  We turn off any external caches and
                   1302:         * loop thru memory, testing every longword til a fault occurs and
                   1303:         * we regain control at setjmp above.  Note that because of the
                   1304:         * setjmp, pg and o need to be volatile or their values will be lost.
                   1305:         */
                   1306:        looking = 1;
                   1307:        ecacheoff();
                   1308:        opte = mmap[0];
                   1309:        for (pg = btoc(lowram); pg < btoc(lowram)+physmem; pg++) {
                   1310:                *(u_int *)mmap = PG_RO|PG_CI|PG_V;
                   1311:                mmap[0].pg_pfnum = pg;
                   1312:                TBIS(vmmap);
                   1313:                ip = (int *)vmmap;
                   1314:                for (o = 0; o < NBPG; o += sizeof(int))
                   1315:                        i = *ip++;
                   1316:        }
                   1317:        /*
                   1318:         * Getting here implies no fault was found.  Should never happen.
                   1319:         */
                   1320:        printf("Couldn't locate parity error\n");
                   1321:        found = 0;
                   1322: done:
                   1323:        looking = 0;
                   1324:        mmap[0] = opte;
                   1325:        TBIS(vmmap);
                   1326:        ecacheon();
                   1327:        splx(s);
                   1328:        return(found);
                   1329: }
                   1330: 
                   1331: regdump(rp, sbytes)
                   1332:   int *rp; /* must not be register */
                   1333:   int sbytes;
                   1334: {
                   1335:        static int doingdump = 0;
                   1336:        register int i;
                   1337:        int s;
                   1338:        extern char *hexstr();
                   1339: 
                   1340:        if (doingdump)
                   1341:                return;
                   1342:        s = splhigh();
                   1343:        doingdump = 1;
                   1344:        printf("pid = %d, pc = %s, ", u.u_procp->p_pid, hexstr(rp[PC], 8));
                   1345:        printf("ps = %s, ", hexstr(rp[PS], 4));
                   1346:        printf("sfc = %s, ", hexstr(getsfc(), 4));
                   1347:        printf("dfc = %s\n", hexstr(getdfc(), 4));
                   1348:        printf("p0 = %x@%s, ",
                   1349:               u.u_pcb.pcb_p0lr, hexstr((int)u.u_pcb.pcb_p0br, 8));
                   1350:        printf("p1 = %x@%s\n\n",
                   1351:               u.u_pcb.pcb_p1lr, hexstr((int)u.u_pcb.pcb_p1br, 8));
                   1352:        printf("Registers:\n     ");
                   1353:        for (i = 0; i < 8; i++)
                   1354:                printf("        %d", i);
                   1355:        printf("\ndreg:");
                   1356:        for (i = 0; i < 8; i++)
                   1357:                printf(" %s", hexstr(rp[i], 8));
                   1358:        printf("\nareg:");
                   1359:        for (i = 0; i < 8; i++)
                   1360:                printf(" %s", hexstr(rp[i+8], 8));
                   1361:        if (sbytes > 0) {
                   1362:                if (rp[PS] & PSL_S) {
                   1363:                        printf("\n\nKernel stack (%s):",
                   1364:                               hexstr((int)(((int *)&rp)-1), 8));
                   1365:                        dumpmem(((int *)&rp)-1, sbytes, 0);
                   1366:                } else {
                   1367:                        printf("\n\nUser stack (%s):", hexstr(rp[SP], 8));
                   1368:                        dumpmem((int *)rp[SP], sbytes, 1);
                   1369:                }
                   1370:        }
                   1371:        doingdump = 0;
                   1372:        splx(s);
                   1373: }
                   1374: 
                   1375: #define KSADDR ((int *)&(((char *)&u)[(UPAGES-1)*NBPG]))
                   1376: 
                   1377: dumpmem(ptr, sz, ustack)
                   1378:  register int *ptr;
                   1379:  int sz;
                   1380: {
                   1381:        register int i, val;
                   1382:        extern char *hexstr();
                   1383: 
                   1384:        for (i = 0; i < sz; i++) {
                   1385:                if ((i & 7) == 0)
                   1386:                        printf("\n%s: ", hexstr((int)ptr, 6));
                   1387:                else
                   1388:                        printf(" ");
                   1389:                if (ustack == 1) {
                   1390:                        if ((val = fuword(ptr++)) == -1)
                   1391:                                break;
                   1392:                } else {
                   1393:                        if (ustack == 0 && (ptr < KSADDR || ptr > KSADDR+(NBPG/4-1)))
                   1394:                                break;
                   1395:                        val = *ptr++;
                   1396:                }
                   1397:                printf("%s", hexstr(val, 8));
                   1398:        }
                   1399:        printf("\n");
                   1400: }
                   1401: 
                   1402: char *
                   1403: hexstr(val, len)
                   1404:        register int val;
                   1405: {
                   1406:        static char nbuf[9];
                   1407:        register int x, i;
                   1408: 
                   1409:        if (len > 8)
                   1410:                return("");
                   1411:        nbuf[len] = '\0';
                   1412:        for (i = len-1; i >= 0; --i) {
                   1413:                x = val & 0xF;
                   1414:                if (x > 9)
                   1415:                        nbuf[i] = x - 10 + 'A';
                   1416:                else
                   1417:                        nbuf[i] = x + '0';
                   1418:                val >>= 4;
                   1419:        }
                   1420:        return(nbuf);
                   1421: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.