Annotation of 43BSDReno/sys/hp300/machdep.c, revision 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.