Annotation of researchv9/sys/sun3/machdep.c, revision 1.1.1.2

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)machdep.c 1.1 86/02/03 Copyr 1986 Sun Micro";
                      3: #endif lint
                      4: 
                      5: /*
                      6:  * Copyright (c) 1986 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: #include "../h/param.h"
                     10: #include "../h/systm.h"
                     11: #include "../h/dir.h"
                     12: #include "../h/user.h"
                     13: #include "../h/map.h"
                     14: #include "../h/vm.h"
                     15: #include "../h/lnode.h"
                     16: #include "../h/proc.h"
                     17: #include "../h/msgbuf.h"
                     18: #include "../h/buf.h"
                     19: #include "../h/inode.h"
                     20: #include "../h/file.h"
                     21: #include "../h/text.h"
                     22: #include "../h/callout.h"
                     23: #include "../h/cmap.h"
                     24: #include "../h/reboot.h"
                     25: 
                     26: #include "../machine/mbvar.h"
                     27: #include "../machine/psl.h"
                     28: #include "../machine/reg.h"
                     29: #include "../machine/clock.h"
                     30: #include "../machine/pte.h"
                     31: #include "../machine/scb.h"
                     32: #include "../machine/mmu.h"
                     33: #include "../machine/cpu.h"
                     34: #include "../machine/eeprom.h"
                     35: #include "../machine/interreg.h"
                     36: #include "../machine/memerr.h"
                     37: #include "../machine/eccreg.h"
                     38: #include "../machine/frame.h"
                     39: 
                     40: /*
                     41:  * Declare these as initialized data so we can patch them.
                     42:  */
                     43: int nbuf = 0;
                     44: int nswbuf = 0;
                     45: int bufpages = 0;
                     46: int physmem = 0;       /* memory size in pages, patch if you want less */
                     47: int kernprot = 1;      /* write protect kernel text */
                     48: int msgbufinit = 0;    /* message buffer has been initialized, ok to printf */
                     49: dev_t consdev = 0;
                     50: 
                     51: int (*exit_vector)() = (int (*)())0;   /* Where to go when halting UNIX */
                     52: 
                     53: #define TESTVAL        0xA55A  /* memory test value */
                     54: 
                     55: u_char getsegmap(), pmegallocres();
                     56: long   getpgmap();
                     57: 
                     58: #ifdef SUN3_260
                     59: /*
                     60:  * Since there is no implied ordering of the memory cards, we store
                     61:  * a zero terminated list of pointers to eccreg's that are active so
                     62:  * that we only look at existent memory cards during softecc() handling.
                     63:  */
                     64: struct eccreg *ecc_alive[MAX_ECC+1];
                     65: #endif SUN3_260
                     66: 
                     67: /*
                     68:  * We make use of CMAPn (the pte address)
                     69:  * and CADDRn (the virtual address)
                     70:  * which are both temporaries defined in locore.s,
                     71:  * not preserved across context switches,
                     72:  * and not to be used in interrupt routines
                     73:  */
                     74: 
                     75: /*
                     76:  * Machine-dependent startup code
                     77:  */
                     78: startup()
                     79: {
                     80:        register int unixsize, dvmapage;
                     81:        register unsigned i;
                     82:        register int c;
                     83:        register struct pte *pte;
                     84:        register caddr_t v;
                     85:        u_int firstaddr;                /* next free physical page number */
                     86:        extern char start[], etext[], end[], CADDR1[], Syslimit[];
                     87:        u_char oc, u_pmeg;
                     88:        u_int mapaddr;
                     89:        caddr_t zmemall();
                     90:        void v_handler();
                     91:        int mon_mem;
                     92: 
                     93:        initscb();                      /* set trap vectors */
                     94:        *INTERREG |= IR_ENA_INT;        /* make sure interrupts can occur */
                     95:        firstaddr = btoc((int)end - KERNELBASE) + UPAGES;
                     96: 
                     97:        /* 
                     98:         * Initialize map of allocated page map groups.
                     99:         * Must be done before mapin of unallocated segments.
                    100:         */
                    101:        pmeginit();                     /* init list of pmeg data structures */
                    102:        ctxinit();                      /* init context data structures */
                    103: 
                    104:        /*
                    105:         * Reserve necessary pmegs and set segment mapping.
                    106:         * It is assumed here that the pmegs for low
                    107:         * memory have already been duplicated for the
                    108:         * segments up in the kernel virtual address space.
                    109:         */
                    110: 
                    111:        /*
                    112:         * invalidate to start of high mapping
                    113:         */
                    114:        for (i = 0; i < KERNELBASE >> SGSHIFT; i++)
                    115:                setsegmap(i, (u_char)SEGINV);
                    116: 
                    117:        /* reserve kernel pmegs */
                    118:        for (; i < ptos(NPAGSEG - 1 + btoc(end)); i++)
                    119:                pmegreserve(getsegmap(i));
                    120: 
                    121:        for (; i < (MONSTART >> SGSHIFT); i++)  /* invalidate to mon start */
                    122:                setsegmap(i, (u_char)SEGINV);
                    123: 
                    124:        for (; i < (MONEND >> SGSHIFT); i++)    /* reserve monitor pmegs */
                    125:                if ((oc = getsegmap(i)) != (u_char)SEGINV)      
                    126:                        pmegreserve(oc);
                    127: 
                    128:        for (; i < NSEGMAP - 1; i++)            /* invalid until last seg */
                    129:                setsegmap(i, (u_char)SEGINV);
                    130: 
                    131:        /*
                    132:         * Last segment contains the u area itself, 
                    133:         * the pmeg here is reserved for all contexts.
                    134:         * We also reserve the invalid pmeg itself.
                    135:         */
                    136:        u_pmeg = getsegmap(NSEGMAP - 1);
                    137:        pmegreserve(u_pmeg);
                    138:        pmegreserve((u_char)SEGINV);
                    139: 
                    140:        setcputype();                   /* sets cpu and dvmasize variables */
                    141: 
                    142:        /*
                    143:         * Make sure the memory error register is
                    144:         * set up to generate interrupts on error.
                    145:         */
                    146: #if defined(SUN3_160) || defined(SUN3_50)
                    147:        if (cpu == CPU_SUN3_160 || cpu == CPU_SUN3_50)
                    148:                MEMREG->mr_per = PER_INTENA | PER_CHECK;
                    149: #endif defined(SUN3_160) || defined(SUN3_50)
                    150: 
                    151: #ifdef SUN3_260
                    152:        if (cpu == CPU_SUN3_260) {
                    153:                register struct eccreg **ecc_nxt = ecc_alive;
                    154:                register struct eccreg *ecc;
                    155: 
                    156:                /*
                    157:                 * Go probe for all memory cards and perform initialization.
                    158:                 * The address of the cards found is stashed in ecc_alive[].
                    159:                 * We assume that the cards are already enabled and the
                    160:                 * base addresses have been set correctly by the monitor.
                    161:                 */
                    162:                for (ecc = ECCREG; ecc < &ECCREG[MAX_ECC]; ecc++) {
                    163:                        if (peekc((char *)ecc) == -1)
                    164:                                continue;
                    165:                        ecc->eccena.ena_scrub = 1;
                    166:                        ecc->eccena.ena_busena = 1;
                    167:                        *ecc_nxt++ = ecc;
                    168:                }
                    169:                *ecc_nxt = (struct eccreg *)0;          /* terminate list */
                    170: 
                    171:                MEMREG->mr_eer = EER_INTENA | EER_CE_ENA;
                    172:        }
                    173: #endif SUN3_260
                    174: 
                    175:        /*
                    176:         * Allocate pmegs for DVMA space
                    177:         */
                    178:        for (i = ptos(btop(DVMA)); i < ptos(btop(DVMA) + dvmasize); i++) {
                    179:                u_char pm = pmegallocres();
                    180: 
                    181:                setsegmap(i, pm);
                    182:                for (v = (caddr_t)ctob(NPAGSEG * i);
                    183:                        v < (caddr_t)ctob(NPAGSEG * (i+1));
                    184:                    v += NBPG)
                    185:                        setpgmap(v, (long)0);
                    186:        }
                    187: 
                    188:        /*
                    189:         * Now go through all the other contexts and set up the segment
                    190:         * maps so that all segments are mapped the same.
                    191:         * We have to use a PROM routine to do this since we don't want
                    192:         * to switch to a new (unmapped) context to call setsegmap()!
                    193:         */
                    194:        for (c = 0; c < NCONTEXT; c++) {
                    195:                if (c == KCONTEXT)
                    196:                        continue;
                    197: 
                    198:                for (v = (caddr_t)0, i = 0;
                    199:                    v < (caddr_t)ctob(NPAGSEG * NSEGMAP); v += NBSG, i++)
                    200:                        (*romp->v_setcxsegmap)(c, v, getsegmap(i));
                    201:        }
                    202: 
                    203:        /*
                    204:         * Initialize kernel page table entries.
                    205:         */
                    206:        pte = &Sysmap[0];
                    207: 
                    208:        /* invalid until start except scb page which is kernel writable */
                    209:        for (v = (caddr_t)KERNELBASE; v < (caddr_t)start; v += NBPG) {
                    210:                if (v == (caddr_t)&scb)
                    211:                        *(int *)pte = PG_V | PG_KW | getpgmap(v) & PG_PFNUM;
                    212:                else
                    213:                        *(int *)pte = 0;
                    214:                setpgmap(v, *(long *)pte++);
                    215:        }
                    216: 
                    217:        /* set up kernel text pages */
                    218:        for (; v < (caddr_t)etext; v += NBPG) {
                    219:                if (kernprot)           /* is kernel to be protected? */
                    220:                        *(int *)pte = PG_V | PG_KR | getpgmap(v) & PG_PFNUM;
                    221:                else
                    222:                        *(int *)pte = PG_V | PG_KW | getpgmap(v) & PG_PFNUM;
                    223:                setpgmap(v, *(long *)pte++);
                    224:        }
                    225: 
                    226:        /* set up kernel data/bss pages to be writeable */
                    227:        for (; v < (caddr_t)end; v += NBPG) {
                    228:                *(int *)pte = PG_V | PG_KW | getpgmap(v) & PG_PFNUM;
                    229:                setpgmap(v, *(long *)pte++);
                    230:        }
                    231: 
                    232:        /* invalid until end of this segment */
                    233:        i = ((u_int)end + SGOFSET) & ~SGOFSET;
                    234:        for (; v < (caddr_t)i; v += NBPG)
                    235:                setpgmap(v, (long)0);
                    236: 
                    237:        /*
                    238:         * Remove user access to monitor-set-up maps.
                    239:         */
                    240:        for (i = MONSTART>>SGSHIFT; i < MONEND>>SGSHIFT; i++) {
                    241:                if (getsegmap(i) == SEGINV)
                    242:                        continue;
                    243:                for (v = (caddr_t)ctob(NPAGSEG * i); 
                    244:                        v < (caddr_t)ctob(NPAGSEG * (i+1));
                    245:                    v += NBPG)
                    246:                        setpgmap(v, (long)(((getpgmap(v) & ~PG_PROT) | PG_KW)));
                    247:        }
                    248: 
                    249:        /*
                    250:         * Invalidate any other pages in last segment
                    251:         * besides the u area, EEPROM_ADDR, CLKADDR,
                    252:         * MEMREG, INTERREG and MONSHORTPAGE.  This sets
                    253:         * up the kernel redzone below the u area.  We
                    254:         * get interrupt redzone for free when the kernel
                    255:         * is write protected as the interrupt stack is
                    256:         * the first thing in the data area.  Since u
                    257:         * and MONSHORTPAGE are defined as 32 bit virtual
                    258:         * addresses (to get short references to work),
                    259:         * we must mask to get only the 28 bits we really
                    260:         * want to look at.
                    261:         */
                    262:        for (v = (caddr_t)ctob(NPAGSEG * (NSEGMAP - 1));
                    263:             v < (caddr_t)ctob(NPAGSEG * NSEGMAP); v += NBPG) {
                    264:                if (((u_int)v < ((u_int)&u & 0x0FFFFFFF) ||
                    265:                    (u_int)v >= (((u_int)&u & 0x0FFFFFFF) + UPAGES*NBPG)) &&
                    266:                    (u_int)v != ((u_int)MONSHORTPAGE & 0x0FFFFFFF) &&
                    267:                    (u_int)v != (u_int)EEPROM_ADDR &&
                    268:                    (u_int)v != (u_int)CLKADDR &&
                    269:                    (u_int)v != (u_int)MEMREG &&
                    270:                    (u_int)v != (u_int)INTERREG)
                    271:                        setpgmap(v, (long)0);
                    272:        }
                    273: 
                    274:        /*
                    275:         * v_memorysize is the amount of physical memory while
                    276:         * v_memoryavail is the amount of usable memory in versions
                    277:         * equal or greater to 1.  Mon_mem is the difference which
                    278:         * is the number of pages hidden by the monitor.
                    279:         */
                    280:        if (romp->v_romvec_version >= 1)
                    281:                mon_mem = btop(*romp->v_memorysize - *romp->v_memoryavail);
                    282:        else
                    283:                mon_mem = 0;
                    284:        /*
                    285:         * If physmem is patched to be non-zero, use it instead of
                    286:         * the monitor value unless physmem is larger than the total
                    287:         * amount of memory on hand.
                    288:         */
                    289:        if (physmem == 0 || physmem > btop(*romp->v_memorysize))
                    290:                physmem = btop(*romp->v_memorysize);
                    291:        /*
                    292:         * Adjust physmem down for the pages stolen by the monitor.
                    293:         */
                    294:        physmem -= mon_mem;
                    295:        maxmem = physmem;
                    296: 
                    297:        /*
                    298:         * v_vector_cmd is the handler for new monitor vector
                    299:         * command in versions equal or greater to 2.
                    300:         * We install v_handler() there for Unix.
                    301:         */
                    302:        if (romp->v_romvec_version >= 2)
                    303:                *romp->v_vector_cmd = v_handler;
                    304: 
                    305: #include "bwtwo.h"
                    306: #if NBWTWO > 0
                    307:        if (physmem > btop(OBFBADDR + FBSIZE))
                    308:                fbobmemavail = 1;
                    309:        else
                    310:                fbobmemavail = 0;
                    311: #else
                    312:        fbobmemavail = 0;
                    313: #endif
                    314: 
                    315:        /*
                    316:         * Determine if anything lives in DVMA bus space.
                    317:         * We're paranoid and go through both the 16 bit
                    318:         * and 32 bit device types.
                    319:         */
                    320:        disable_dvma();
                    321:        for (dvmapage = 0; dvmapage < btoc(dvmasize); dvmapage++) {
                    322:                mapin(CMAP1, btop(CADDR1), (u_int)(dvmapage | PGT_VME_D16),
                    323:                    1, PG_V | PG_KW);
                    324:                if (poke((short *)CADDR1, TESTVAL) == 0)
                    325:                        break;
                    326:                mapin(CMAP1, btop(CADDR1), (u_int)(dvmapage | PGT_VME_D32),
                    327:                    1, PG_V | PG_KW);
                    328:                if (poke((short *)CADDR1, TESTVAL) == 0)
                    329:                        break;
                    330:        }
                    331:        enable_dvma();
                    332: 
                    333:        /*
                    334:         * Initialize error message buffer (in low real memory before start).
                    335:         * Printf's which occur prior to this will not be captured.
                    336:         */
                    337:        mapin(msgbufmap, (u_int)btop(&msgbuf),
                    338:            (u_int)btop((int)start - sizeof (struct msgbuf) - KERNELBASE),
                    339:            (int)btoc(sizeof (struct msgbuf)), PG_V | PG_KW);
                    340:        msgbufinit = 1;
                    341: 
                    342:        /*
                    343:         * Allocate IOPB memory space just below the message
                    344:         * buffer and map it to the first pages of DVMA space.
                    345:         */
                    346:        maxmem -= IOPBMEM;
                    347:        for (v = (caddr_t)DVMA, i = maxmem; i < maxmem + IOPBMEM;
                    348:            v += NBPG, i++) {
                    349:                struct pte tmp;                 /* scratch pte */
                    350: 
                    351:                mapin(&tmp, btop(v), i, 1, PG_V | PG_KW);
                    352:        }
                    353: 
                    354:        /*
                    355:         * Good {morning,afternoon,evening,night}.
                    356:         * When printing memory, use the total including
                    357:         * those hidden by the monitor (mon_mem).
                    358:         */
                    359:        printf(version);
                    360: 
                    361:        if (dvmapage < btoc(dvmasize)) {
                    362:                printf("CAN'T HAVE PERIPHERALS IN RANGE 0 - %dKB\n",
                    363:                    ctob(dvmasize) / 1024);
                    364:                panic("dvma collision");
                    365:        }
                    366: 
                    367: #ifndef lint
                    368:        if ((int)start - (int)ctob(btoc(sizeof (struct msgbuf))) <= (int)&scb)
                    369:                panic("msgbuf too large");
                    370: 
                    371:        if (sizeof (struct user) > UPAGES * NBPG)
                    372:                panic("user area too large");
                    373: #endif lint
                    374: 
                    375:        if ((int)Syslimit > (CSEG << SGSHIFT))
                    376:                panic("system map tables too large");
                    377: 
                    378:         /*
                    379:         * Determine how many buffers to allocate.
                    380:         * Use 10% of memory (not counting 512K for kernel), with min of 16.
                    381:         * We allocate 1/4 as many swap buffer headers as file i/o buffers.
                    382:         */
                    383:        if (bufpages == 0)
                    384:                bufpages = (physmem * NBPG - 512 * 1024) / 10 / CLBYTES;
                    385:        if (nbuf == 0) {
                    386:                nbuf = bufpages;
                    387:                if (nbuf < 16)
                    388:                        nbuf = 16;
                    389:        }
                    390:        if (bufpages > nbuf * (BUFSIZE / CLBYTES))
                    391:                bufpages = nbuf * (BUFSIZE / CLBYTES);
                    392:        if (nswbuf == 0) {
                    393:                nswbuf = (nbuf / 4) &~ 1;       /* force even */
                    394:                if (nswbuf > 32)
                    395:                        nswbuf = 32;            /* sanity */
                    396:        }
                    397:        printf("real mem = %d nbuf = %d nswbuf = %d\n",
                    398:                ctob(physmem + mon_mem), nbuf, nswbuf);
                    399: 
                    400:        /*
                    401:         * Allocate space for system data structures.
                    402:         * The first available real memory address is in "firstaddr".
                    403:         * The first available kernel virtual address is in "v".
                    404:         * As pages of kernel virtual memory are allocated, "v" is incremented.
                    405:         * "mapaddr" is the real memory address where the tables start.
                    406:         * It is used when remapping the tables later.
                    407:         * In order to support the frame buffer which might appear in 
                    408:         * the middle of contiguous memory we adjust the map address to 
                    409:         * start after the end of the frame buffer.  Later we will adjust
                    410:         * the core map to take this hole into account.  The reason for
                    411:         * this is to keep all the kernel tables contiguous in virtual space.
                    412:         */
                    413:        if (fbobmemavail)
                    414:                mapaddr = btoc(OBFBADDR + FBSIZE);
                    415:        else
                    416:                mapaddr = firstaddr;
                    417:        v = (caddr_t)(ctob(firstaddr) + KERNELBASE);
                    418: #define        valloc(name, type, num) \
                    419:            (name) = (type *)(v); (v) = (caddr_t)((name)+(num))
                    420: #define        valloclim(name, type, num, lim) \
                    421:            (name) = (type *)(v); (v) = (caddr_t)((lim) = ((name)+(num)))
                    422:        valloc(swbuf, struct buf, nswbuf);
1.1.1.2 ! root      423:        valloc(swsize, short, nswbuf);  /* note: nswbuf is even */
        !           424:        valloc(swpf, int, nswbuf);
1.1       root      425:        valloclim(inode, struct inode, ninode, inodeNINODE);
                    426:        valloclim(file, struct file, nfile, fileNFILE);
                    427:        valloclim(proc, struct proc, nproc, procNPROC);
                    428:        valloclim(text, struct text, ntext, textNTEXT);
                    429:        valloclim(lnodes, struct kern_lnode, maxusers, lnodesMAXUSERS);
                    430:        valloc(callout, struct callout, ncallout);
                    431:        valloc(swapmap, struct map, nswapmap = nproc * 2);
                    432:        valloc(argmap, struct map, ARGMAPSIZE);
                    433:        valloc(kernelmap, struct map, nproc);
                    434:        valloc(iopbmap, struct map, IOPBMAPSIZE);
                    435:        valloc(mb_hd.mh_map, struct map, DVMAMAPSIZE);
                    436: 
                    437:        /*
                    438:         * Now allocate space for core map
                    439:         * Allow space for all of physical memory minus the amount 
                    440:         * dedicated to the system. The amount of physical memory
                    441:         * dedicated to the system is the total virtual memory of
                    442:         * the system minus the space in the buffers which is not
                    443:         * allocated real memory.
                    444:         */
                    445:        ncmap = physmem - firstaddr;
                    446:        valloclim(cmap, struct cmap, ncmap, ecmap);
                    447:        unixsize = btoc((int)(ecmap+1) - KERNELBASE);
                    448: 
                    449:        if ((int)unixsize > SYSPTSIZE)
                    450:                panic("sys pt too small");
                    451: 
                    452:        /*
                    453:         * Clear allocated space, and make r/w entries
                    454:         * for the space in the kernel map.
                    455:         */
                    456:        if (unixsize >= physmem - 8*UPAGES)
                    457:                panic("no memory");
                    458: 
                    459:        pte = &Sysmap[firstaddr];
                    460:        for (i = firstaddr + btop(KERNELBASE); i < btoc(v); i++) {
                    461:                mapin(pte++, i, mapaddr,  1, PG_V | PG_KW);
                    462:                clearseg(mapaddr++);
                    463:        }
                    464: 
                    465:        /*
                    466:         * Initialize callouts.
                    467:         */
                    468:        callfree = callout;
                    469:        for (i = 1; i < ncallout; i++)
                    470:                callout[i-1].c_next = &callout[i];
                    471: 
                    472:        /*
                    473:         * Initialize memory allocator and swap
                    474:         * and user page table maps.
                    475:         */
                    476:        if (fbobmemavail) {
                    477:                meminit((int)firstaddr, maxmem);
                    478:                memialloc((int)firstaddr, (int)btop(OBFBADDR));
                    479:                memialloc((int)(1 + mapaddr), maxmem);
                    480:        } else {
                    481:                meminit((int)mapaddr, maxmem);
                    482:                memialloc((int)mapaddr, maxmem);
                    483:        }
                    484:        maxmem = freemem;
                    485:        printf("avail mem = %d\n", ctob(maxmem));
                    486:        rminit(kernelmap, (long)(USRPTSIZE - CLSIZE), (long)CLSIZE,
                    487:            "usrpt", nproc);
                    488:        rminit(iopbmap, (long)ctob(IOPBMEM), (long)DVMA, 
                    489:            "IOPB space", IOPBMAPSIZE);
                    490:        rminit(mb_hd.mh_map, (long)(dvmasize - IOPBMEM), (long)IOPBMEM,
                    491:            "DVMA map space", DVMAMAPSIZE);
                    492: 
                    493:        /*
                    494:         * Configure the system.
                    495:         */
                    496:        bootflags();            /* get the boot options */
                    497:        configure();            /* set up devices */
                    498:        if (fbobmemavail) {
                    499:                /*
                    500:                 * Onboard frame buffer memory still
                    501:                 * available, put back onto the free list.
                    502:                 */
                    503:                memialloc((int)btop(OBFBADDR), (int)btop(OBFBADDR + FBSIZE));
                    504:                fbobmemavail = 0;
                    505:        }
                    506:        bufmemall();
                    507:        uinit();                /* initialize the u area */
                    508:        (void) spl0();          /* drop priority */
                    509: }
                    510: 
                    511: /*
                    512:  * set up a physical address
                    513:  * into users virtual address space.
                    514:  */
                    515: sysphys()
                    516: {
                    517: 
                    518:        if(!suser())
                    519:                return;
                    520:        u.u_error = EINVAL;
                    521: }
                    522: 
                    523: /*
                    524:  * This system call sets the time of year clock without touching
                    525:  * the software clock.  It returns the previous clock value.  If
                    526:  * the argument is zero or the caller is not the super-user, it
                    527:  * does not change the clock.
                    528:  * Since the clocks are the same on the SUN, it just calls stime.
                    529:  */
                    530: settod()
                    531: {
                    532:        register struct a {
                    533:                long unsigned tod;
                    534:        } *uap;
                    535: 
                    536:        u.u_r.r_time = time;
                    537:        if (uap->tod != 0 && suser())
                    538:                stime();
                    539: }
                    540: 
                    541: /*
                    542:  * Allocate physical memory for system buffers
                    543:  * In Ethernet memory if the right board exists &
                    544:  * the root device is ND & there are no block I/O DMA devices
                    545:  */
                    546: bufmemall()
                    547: {
                    548:        struct pte *pte;
                    549:        long a, va;
                    550:        int npages;
                    551:        int i, j, base, residual;
                    552: 
                    553:        a = rmalloc(kernelmap, (long)(nbuf*BUFSIZE/NBPG));
                    554:        if (a == 0)
                    555:                panic("no vmem for buffers");
                    556:        buffers = (caddr_t)kmxtob(a);
                    557:        pte = &Usrptmap[a];
                    558:        base = bufpages / nbuf;
                    559:        residual = bufpages % nbuf;
                    560:        for (i = 0; i < nbuf; i++) {
                    561:                if (i < residual)
                    562:                        npages = base+1;
                    563:                else
                    564:                        npages = base;
                    565:                /* XXX - this loop only works if CLSIZE == 1 */
                    566:                for (j = 0; j < npages; j += CLSIZE) {
                    567:                        if (memall(pte+j, CLSIZE, &proc[0], CSYS) == 0)
                    568:                                panic("no mem for buffers");
                    569:                        *(int *)(pte+j) |= PG_V|PG_KW;
                    570:                        va = (int)kmxtob(a+j);
                    571:                        vmaccess(pte+j, (caddr_t)va, 1);
                    572:                        bzero((caddr_t)va, CLBYTES);
                    573:                }
                    574:                pte += BUFSIZE/CLBYTES;
                    575:                a += BUFSIZE/CLBYTES;
                    576:        }
                    577:        /*
                    578:         * Double map and then unmap the last page of the last
                    579:         * buffer to insure the presence of a pmeg.
                    580:         * AARRRGGGHHH. Kludge away.
                    581:         */
                    582:        if (base < BUFSIZE/CLBYTES) {
                    583:                pte -= BUFSIZE/CLBYTES;
                    584:                va = (int)kmxtob(a-1);
                    585:                pte[BUFSIZE/CLBYTES - 1] = pte[0];
                    586:                vmaccess(&pte[BUFSIZE/CLBYTES - 1], (caddr_t)va, 1);
                    587:                /* now unmap without disturbing the pmeg */
                    588:                *(int *)&pte[BUFSIZE/CLBYTES - 1] = 0;
                    589:                setpgmap((caddr_t)va, (long)0);
                    590:        }
                    591:        buf = (struct buf *)zmemall(memall, nbuf * sizeof(struct buf));
                    592:        if (buf == 0)
                    593:                panic("no mem for buf headers");
                    594: }
                    595: 
                    596: struct bootf {
                    597:        char    let;
                    598:        short   bit;
                    599: } bootf[] = {
                    600:        'a',    RB_ASKNAME,
                    601:        's',    RB_SINGLE,
                    602:        'i',    RB_INITNAME,
                    603:        'h',    RB_HALT,
                    604:        0,      0,
                    605: };
                    606: char *initname = "/etc/init";
                    607: 
                    608: /*
                    609:  * Parse the boot line to determine boot flags .
                    610:  */
                    611: bootflags()
                    612: {
                    613:        register struct bootparam *bp = (*romp->v_bootparam);
                    614:        register char *cp;
                    615:        register int i;
                    616: 
                    617:        cp = bp->bp_argv[1];
                    618:        if (cp && *cp++ == '-')
                    619:                do {
                    620:                        for (i = 0; bootf[i].let; i++) {
                    621:                                if (*cp == bootf[i].let) {
                    622:                                        boothowto |= bootf[i].bit;
                    623:                                        break;
                    624:                                }
                    625:                        }
                    626:                        cp++;
                    627:                } while (bootf[i].let && *cp);
                    628:        if (boothowto & RB_INITNAME)
                    629:                initname = bp->bp_argv[2];
                    630:        if (boothowto & RB_HALT)
                    631:                halt("bootflags");
                    632: }
                    633: 
                    634: /*
                    635:  * Start the initial user process.
                    636:  * The program [initname] is invoked with one argument
                    637:  * containing the boot flags.
                    638:  */
                    639: icode()
                    640: {
                    641:        struct execa {
                    642:                char    *fname;
                    643:                char    **argp;
                    644:                char    **envp;
                    645:        } *ap;
                    646:        char *ucp, **uap, *arg0, *arg1;
                    647:        int i;
                    648: 
                    649:        u.u_error = 0;                          /* paranoid */
                    650:        /* Make a user stack (1 page) */
                    651:        expand(1, 1);
                    652:        (void) swpexpand(0, 1, &u.u_dmap, &u.u_smap);
                    653: 
                    654:        /* Move out the boot flag argument */
                    655:        ucp = (char *)USRSTACK;
                    656:        (void) subyte(--ucp, 0);                /* trailing zero */
                    657:        for (i = 0; bootf[i].let; i++) {
                    658:                if (boothowto & bootf[i].bit)
                    659:                        (void) subyte(--ucp, bootf[i].let);
                    660:        }
                    661:        (void) subyte(--ucp, '-');              /* leading hyphen */
                    662:        arg1 = ucp;
                    663: 
                    664:        /* Move out the file name (also arg 0) */
                    665:        for (i = 0; initname[i]; i++)
                    666:                ;                               /* size the name */
                    667:        for (; i >= 0; i--)
                    668:                (void) subyte(--ucp, initname[i]);
                    669:        arg0 = ucp;
                    670: 
                    671:        /* Move out the arg pointers */
                    672:        uap = (char **) ((int)ucp & ~(NBPW-1));
                    673:        (void) suword((caddr_t)--uap, 0);       /* terminator */
                    674:        (void) suword((caddr_t)--uap, (int)arg1);
                    675:        (void) suword((caddr_t)--uap, (int)arg0);
                    676: 
                    677:        /* Point at the arguments */
                    678:        u.u_ap = u.u_arg;
                    679:        ap = (struct execa *)u.u_ap;
                    680:        ap->fname = arg0;
                    681:        ap->argp = uap;
                    682:        ap->envp = 0;
                    683:        u.u_dirp = (caddr_t)u.u_arg[0];
                    684:        
                    685:        /* Now let exec do the hard work */
                    686:        exece();
                    687:        if (u.u_error) {
                    688:                printf("Can't invoke %s, error %d\n", initname, u.u_error);
                    689:                panic("icode");
                    690:        }
                    691: }
                    692: 
                    693: /*
                    694:  * Set up page tables for process 0 U pages.
                    695:  * This is closely related to way the code
                    696:  * in locore.s sets things up.
                    697:  */
                    698: uinit()
                    699: {
                    700:        register struct pte *pte;
                    701:        u_int page;
                    702:        register int i;
                    703:        extern char end[];
                    704: 
                    705:        /*
                    706:         * main() will initialize proc[0].p_p0br to u.u_pcb.pcb_p0br
                    707:         * and proc[0].p_szpt to 1.  All we have to do is set up
                    708:         * the pcb_p{0,1}{b,l}r registers in the pcb for now.
                    709:         */
                    710: 
                    711:        /* initialize base and length of P0 region */
                    712:        u.u_pcb.pcb_p0br = usrpt;
                    713:        u.u_pcb.pcb_p0lr = 0;           /* no user text/data (P0) for proc 0 */
                    714: 
                    715:        /*
                    716:         * initialize base and length of P1 region,
                    717:         * where the length here is for invalid pages
                    718:         */
                    719:        u.u_pcb.pcb_p1br = initp1br(usrpt + 1 * NPTEPG);
                    720:        u.u_pcb.pcb_p1lr = P1PAGES;     /* no user stack (P1) for proc 0 */
                    721: 
                    722:        /*
                    723:         * Doublely map the page containing the scb to contain the
                    724:         * ptes whose virtual address is usrpt.  Got that?
                    725:         */
                    726:        page = (u_int)(getpgmap((caddr_t)&scb) & PG_PFNUM);
                    727:        mapin(&Usrptmap[0], btop(usrpt), page, 1, PG_V | PG_KW); 
                    728: 
                    729:        /*
                    730:         * Now build the software page maps to map virtual U to physical U.
                    731:         * These pages have already been set up using the real pages beyond
                    732:         * end by locore.s.
                    733:         */
                    734:        pte = usrpt + 1 * NPTEPG - UPAGES;
                    735:        page = btop((int)end + (NBPG - 1) - KERNELBASE);
                    736:        for (i = 0; i < UPAGES; i++)
                    737:                *(int *)pte++ = PG_V | PG_KW | page++;
                    738: }
                    739: 
                    740: struct sigcontext {
                    741:        int     sc_sp;                  /* sp to restore */
                    742:        int     sc_pc;                  /* pc to retore */
                    743:        int     sc_ps;                  /* psl to restore */
                    744: };
                    745: /*
                    746:  * Send an interrupt to process.
                    747:  *
                    748:  * When using new signals user code must do a
                    749:  * sys #139 to return from the signal, which
                    750:  * calls sigcleanup below, which resets the
                    751:  * signal mask and the notion of onsigstack,
                    752:  * and returns from the signal handler.
                    753:  */
                    754: sendsig(p, sig)
                    755:        int (*p)(), sig;
                    756: {
                    757:        register int usp, *regs, scp;
                    758:        struct nframe {
                    759:                int     sig;
                    760:                int     code;
                    761:                int     scp;
                    762:        } frame;
                    763:        struct sigcontext sc;
                    764: 
                    765: #define        mask(s) (1<<((s)-1))
                    766:        regs = u.u_ar0;
                    767: 
                    768:        usp = regs[SP];
                    769:        usp -= sizeof (struct sigcontext);
                    770:        scp = usp;
                    771:        usp -= sizeof (frame);
                    772:        if (usp <= USRSTACK - ctob(u.u_ssize))
                    773:                (void) grow((unsigned)usp);
                    774:        if (useracc((caddr_t)usp, sizeof(frame) + sizeof(sc), B_WRITE) == 0) {
                    775:                /*
                    776:                 * Process has trashed its stack; give it an illegal
                    777:                 * instruction to halt it in its tracks.
                    778:                 */
                    779:                u.u_signal[SIGILL] = SIG_DFL;
                    780:                u.u_procp->p_siga0 &= ~(1<<(SIGILL-1));
                    781:                u.u_procp->p_siga1 &= ~(1<<(SIGILL-1));
                    782:                psignal(u.u_procp, SIGILL);
                    783:        }
                    784:        /*
                    785:         * push sigcontext structure.
                    786:         */
                    787:        sc.sc_sp = regs[SP];
                    788:        sc.sc_pc = regs[PC];
                    789:        sc.sc_ps = regs[PS];
                    790:        /*
                    791:         * If trace mode was on for the user process
                    792:         * when we came in here, it may have been because
                    793:         * of an ast-induced trace on a trap instruction,
                    794:         * in which case we do not want to restore the
                    795:         * trace bit in the status register later on
                    796:         * in sigcleanup().  If we were to restore it
                    797:         * and another ast trap had been posted, we would
                    798:         * end up marking the trace trap as a user-requested
                    799:         * real trace trap and send a bogus "Trace/BPT" signal.
                    800:         */
                    801:        if ((sc.sc_ps & PSL_T) && (u.u_pcb.pcb_p0lr & TRACE_AST))
                    802:                sc.sc_ps &= ~PSL_T;
                    803:        (void) copyout((caddr_t)&sc, (caddr_t)scp, sizeof (sc));
                    804:        /*
                    805:         * push call frame.
                    806:         */
                    807:        frame.sig = sig;
                    808:        if (sig == SIGILL || sig == SIGFPE || sig == SIGEMT) {
                    809:                frame.code = u.u_code;
                    810:                u.u_code = 0;
                    811:        } else
                    812:                frame.code = 0;
                    813:        frame.scp = scp;
                    814:        (void) copyout((caddr_t)&frame, (caddr_t)usp, sizeof (frame));
                    815:        regs[SP] = usp;
                    816:        regs[PC] = (int)p;
                    817: }
                    818: 
                    819: /*
                    820:  * Routine to cleanup state after a signal
                    821:  * has been taken.  Reset signal mask and
                    822:  * notion of on signal stack from context
                    823:  * left there by sendsig (above).  Pop these
                    824:  * values and perform rti.
                    825:  */
                    826: sigcleanup()
                    827: {
                    828:        struct sigcontext *scp, sc;
                    829: 
                    830:        scp = (struct sigcontext *)fuword((caddr_t)u.u_ar0[SP] + sizeof(int));
                    831:        if ((int)scp == -1)
                    832:                return;
                    833:        if (copyin((caddr_t)scp, (caddr_t)&sc, sizeof (sc)))
                    834:                return;
                    835:        u.u_ar0[SP] = sc.sc_sp;
                    836:        u.u_ar0[PC] = sc.sc_pc;
                    837:        u.u_ar0[PS] = sc.sc_ps;
                    838:        u.u_ar0[PS] &= ~PSL_USERCLR;
                    839:        u.u_ar0[PS] |= PSL_USERSET;
                    840:        u.u_eosys = REALLYRETURN;
                    841: }
                    842: #undef mask
                    843: 
                    844: int    waittime = -1;
                    845: 
                    846: boot(arghowto)
                    847:        int arghowto;
                    848: {
                    849:        register int howto;
                    850:        static int prevflag = 0;
                    851:        register struct buf *bp;
                    852:        int iter, nbusy;
                    853:        int s;
                    854: 
                    855:        consdev = 0;
                    856:        startnmi();
                    857:        howto = arghowto;
                    858:        if ((howto&RB_NOSYNC)==0 && waittime < 0 && bfreelist[0].b_forw) {
                    859:                waittime = 0;
                    860:                update();
                    861:                printf("syncing disks... ");
                    862:                while (++waittime <= 5)
                    863:                        sleep((caddr_t)&lbolt, PZERO);
                    864:                printf("done\n");
                    865:        }
                    866:        s = spl7();                             /* extreme priority */
                    867:        if (howto & RB_HALT) {
                    868:                halt((char *)NULL);
                    869:                /* MAYBE REACHED */
                    870:        } else {
                    871:                if ((howto & RB_PANIC) && prevflag == 0) {
                    872:                        prevflag = 1;
                    873:                        dumpsys();
                    874: 
                    875:                }
                    876:                printf("Rebooting Unix...\n");
                    877:                (*romp->v_boot_me)(howto & RB_SINGLE ? "-s" : "");
                    878:                /*NOTREACHED*/
                    879:        }
                    880:        (void) splx(s);
                    881: }
                    882: 
                    883: /*
                    884:  * Initialize UNIX's vector table:
                    885:  * Vectors are copied from protoscb unless
                    886:  * they are zero; zero means preserve whatever the
                    887:  * monitor put there.  If the protoscb is zero,
                    888:  * then the original contents are copied into
                    889:  * the scb we are setting up.
                    890:  */
                    891: initscb()
                    892: {
                    893:        register int *s, *p, *f;
                    894:        register int n;
                    895:        struct scb *orig, *getvbr();
                    896: 
                    897:        orig = getvbr();
                    898:        exit_vector = orig->scb_trap[14];
                    899:        s = (int *)&scb;
                    900:        p = (int *)&protoscb;
                    901:        f = (int *)orig;
                    902:        for (n = sizeof (struct scb)/sizeof (int); n--; s++, p++, f++) {
                    903:                if (*p) 
                    904:                        *s = *p;
                    905:                else
                    906:                        *s = *f;
                    907:        }
                    908:        setvbr(&scb);
                    909: }
                    910: 
                    911: /*
                    912:  * Clear a segment (page (click)).
                    913:  */
                    914: clearseg(pgno)
                    915:        u_int pgno;
                    916: {
                    917:        extern char CADDR1[];
                    918: 
                    919:        mapin(CMAP1, btop(CADDR1), pgno, 1, PG_V | PG_KW); 
                    920:        bzero(CADDR1, NBPG);
                    921: }
                    922: 
                    923: /*
                    924:  * Copy a segment (page) from a user virtual address
                    925:  * to a physical page number.
                    926:  */
                    927: copyseg(vaddr, pgno)
                    928:        caddr_t vaddr;
                    929:        int pgno;
                    930: {
                    931:        register struct pte *pte;
                    932:        register int lock;
                    933:        extern char CADDR1[];
                    934: 
                    935:        /*
                    936:         * Make sure the user's page is valid and locked.
                    937:         */
                    938:        pte = vtopte(u.u_procp, btop(vaddr));
                    939:        if (lock = !pte->pg_v) {
                    940:                pagein((u_int)vaddr, &u, 1);            /* return it locked */
                    941:                pte = vtopte(u.u_procp, btop(vaddr));   /* pte may move */
                    942:        }
                    943:        /*
                    944:         * Map the destination page into kernel address space.
                    945:         */
                    946:        mapin(CMAP1, btop(CADDR1), (u_int)pgno, 1, PG_V | PG_KW);
                    947:        (void) copyin(vaddr, CADDR1, CLBYTES);
                    948:        if (lock)
                    949:                munlock(pte->pg_pfnum);
                    950: }
                    951: 
                    952: /*
                    953:  * Handle "physical" block transfers.
                    954:  */
                    955: physstrat(bp, strat, pri)
                    956:        register struct buf *bp;
                    957:        int (*strat)();
                    958:        int pri;
                    959: {
                    960:        register int npte, n;
                    961:        register long a;
                    962:        unsigned v;
                    963:        register struct pte *pte, *kpte;
                    964:        struct proc *rp;
                    965:        int va, s, o;
                    966: 
                    967:        v = btop(bp->b_un.b_addr);
                    968:        o = (int)bp->b_un.b_addr & PGOFSET;
                    969:        npte = btoc(bp->b_bcount + o) + 1;
                    970:        while ((a = rmalloc(kernelmap, (long)npte)) == NULL) {
                    971:                kmapwnt++;
                    972:                sleep((caddr_t)kernelmap, PSWP+4);
                    973:        }
                    974:        kpte = &Usrptmap[a];
                    975:        rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;
                    976:        if ((bp->b_flags & B_PHYS) == 0)
                    977:                pte = &Sysmap[btop((int)bp->b_un.b_addr - KERNELBASE)];
                    978:        else if (bp->b_flags & B_UAREA)
                    979:                pte = &rp->p_addr[v];
                    980:        else if (bp->b_flags & B_PAGET)
                    981:                pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];
                    982:        else
                    983:                pte = vtopte(rp, v);
                    984:        for (n = npte; --n != 0; kpte++, pte++)
                    985:                *(int *)kpte = PG_V | PG_KW | (*(int *)pte & PG_PFNUM);
                    986:        *(int *)kpte = 0;
                    987:        va = (int)kmxtob(a);
                    988:        vmaccess(&Usrptmap[a], (caddr_t)va, npte);
                    989:        bp->b_saddr = bp->b_un.b_addr;
                    990:        bp->b_un.b_addr = (caddr_t)(va | o);
                    991:        bp->b_kmx = a;
                    992:        bp->b_npte = npte;
                    993:        (*strat)(bp);
                    994:        if (bp->b_flags & B_DIRTY)
                    995:                return;
                    996:        s = spl6();
                    997:        while ((bp->b_flags & B_DONE) == 0)
                    998:                sleep((caddr_t)bp, pri);
                    999:        (void) splx(s);
                   1000:        bp->b_un.b_addr = bp->b_saddr;
                   1001:        bp->b_kmx = 0;
                   1002:        bp->b_npte = 0;
                   1003:        mapout(&Usrptmap[a], npte);
                   1004:        rmfree(kernelmap, (long)npte, a);
                   1005: }
                   1006: 
                   1007: /*
                   1008:  * Halt the machine and return to the monitor
                   1009:  */
                   1010: halt(s)
                   1011:        char *s;
                   1012: {
                   1013:        extern struct scb *getvbr();
                   1014: 
                   1015:        if (s)
                   1016:                (*romp->v_printf)("(%s) ", s);
                   1017:        (*romp->v_printf)("Unix Halted\n\n");
                   1018:        startnmi();
                   1019:        if (exit_vector)
                   1020:                getvbr()->scb_trap[14] = exit_vector;
                   1021:        asm("trap #14");
                   1022:        if (exit_vector)
                   1023:                getvbr()->scb_trap[14] = protoscb.scb_trap[14];
                   1024:        stopnmi();
                   1025: }
                   1026: 
                   1027: /*
                   1028:  * Print out a traceback for the caller - can be called anywhere
                   1029:  * within the kernel or from the monitor by typing "g4" (for sun-2
                   1030:  * compatibility) or "w trace".  This causes the monitor to call
                   1031:  * the v_handler() routine which will call tracedump() for these cases.
                   1032:  */
                   1033: /*VARARGS0*/
                   1034: tracedump(x1)
                   1035:        caddr_t x1;
                   1036: {
                   1037:        struct frame *fp = (struct frame *)(&x1 - 2);
                   1038:        u_int tospage = btoc(fp);
                   1039: 
                   1040:        (*romp->v_printf)("Begin traceback...fp = %x\n", fp);
                   1041:        while (btoc(fp) == tospage) {
                   1042:                if (fp == fp->fr_savfp) {
                   1043:                        (*romp->v_printf)("FP loop at %x", fp);
                   1044:                        break;
                   1045:                }
                   1046:                (*romp->v_printf)("Called from %x, fp=%x, args=%x %x %x %x\n",
                   1047:                    fp->fr_savpc, fp->fr_savfp,
                   1048:                    fp->fr_arg[0], fp->fr_arg[1], fp->fr_arg[2], fp->fr_arg[3]);
                   1049:                fp = fp->fr_savfp;
                   1050:        }
                   1051:        (*romp->v_printf)("End traceback...\n");
                   1052: }
                   1053: 
                   1054: /*
                   1055:  * Buscheck is called by mbsetup to check to see it the requested
                   1056:  * setup is a valid busmem type (i.e. VMEbus).  Returns 1 if ok
                   1057:  * busmem type, returns 0 if not busmem type.  This routine
                   1058:  * make checks and panic's if an illegal busmem type request is detected.
                   1059:  */
                   1060: buscheck(pte, npf)
                   1061:        register struct pte *pte;
                   1062:        register int npf;
                   1063: {
                   1064:        register int i, pf;
                   1065:        register int pt = *(int *)pte & PGT_MASK;
                   1066: 
                   1067:        if (pt == PGT_VME_D16 || pt == PGT_VME_D32) {
                   1068:                pf = pte->pg_pfnum;
                   1069:                if (pf < btoc(DVMASIZE))
                   1070:                        panic("buscheck: busmem in DVMA range");
                   1071:                for (i = 0; i < npf; i++, pte++, pf++) {
                   1072:                        if ((*(int *)pte & PGT_MASK) != pt ||
                   1073:                            pte->pg_pfnum != pf)
                   1074:                                panic("buscheck: request not contiguous");
                   1075:                }
                   1076:                return (1);
                   1077:        }
                   1078:        return (0);
                   1079: }
                   1080: 
                   1081: /* 
                   1082:  * Compute the address of an I/O device within standard address
                   1083:  * ranges and return the result.  This is used by DKIOCINFO
                   1084:  * ioctl to get the best guess possible for the actual address
                   1085:  * set on the card.
                   1086:  */
                   1087: getdevaddr(addr)
                   1088:        caddr_t addr;
                   1089: {
                   1090:        int off = (int)addr & PGOFSET;
                   1091:        int pte = getkpgmap(addr);
                   1092:        int physaddr = ((pte & PG_PFNUM) & ~PGT_MASK) * NBPG;
                   1093: 
                   1094:        switch (pte & PGT_MASK) {
                   1095:        case PGT_VME_D16:
                   1096:        case PGT_VME_D32:
                   1097:                if (physaddr > VME16_BASE) {
                   1098:                        /* 16 bit VMEbus address */
                   1099:                        physaddr -= VME16_BASE;
                   1100:                } else if (physaddr > VME24_BASE) {
                   1101:                        /* 24 bit VMEbus address */
                   1102:                        physaddr -= VME24_BASE;
                   1103:                }
                   1104:                /*
                   1105:                 * else 32 bit VMEbus address,
                   1106:                 * physaddr doesn't require adjustments
                   1107:                 */
                   1108:                break;
                   1109: 
                   1110:        case PGT_OBMEM:
                   1111:        case PGT_OBIO:
                   1112:                /* physaddr doesn't require adjustments */
                   1113:                break;
                   1114:        }
                   1115: 
                   1116:        return (physaddr + off);
                   1117: }
                   1118: 
                   1119: static int (*mon_nmi)();               /* monitor's level 7 nmi routine */
                   1120: extern int level7();                   /* Unix's level 7 nmi routine */
                   1121: 
                   1122: stopnmi()
                   1123: {
                   1124:        struct scb *vbr, *getvbr();
                   1125: 
                   1126:        vbr = getvbr();
                   1127:        if (vbr->scb_autovec[7 - 1] != level7) {
                   1128: #ifndef GPROF
                   1129:                set_clk_mode(0, IR_ENA_CLK7);   /* disable level 7 clk intr */
                   1130: #endif !GPROF
                   1131:                mon_nmi = vbr->scb_autovec[7 - 1];      /* save mon vec */
                   1132:                vbr->scb_autovec[7 - 1] = level7;       /* install Unix vec */
                   1133:        }
                   1134: }
                   1135: 
                   1136: startnmi()
                   1137: {
                   1138:        struct scb *getvbr();
                   1139: 
                   1140:        if (mon_nmi) {
                   1141:                getvbr()->scb_autovec[7 - 1] = mon_nmi; /* install mon vec */
                   1142: #ifndef GPROF
                   1143:                set_clk_mode(IR_ENA_CLK7, 0);   /* enable level 7 clk intr */
                   1144: #endif !GPROF
                   1145:        }
                   1146: }
                   1147: 
                   1148: /*
                   1149:  * Handler for monitor vector cmd -
                   1150:  * For now we just implement the old "g0" and "g4"
                   1151:  * commands and a printf hack.
                   1152:  */
                   1153: void
                   1154: v_handler(addr, str)
                   1155:        int addr;
                   1156:        char *str;
                   1157: {
                   1158: 
                   1159:        switch (*str) {
                   1160:        case '\0':
                   1161:                /*
                   1162:                 * No (non-hex) letter was specified on
                   1163:                 * command line, use only the number given
                   1164:                 */
                   1165:                switch (addr) {
                   1166:                case 0:         /* old g0 */
                   1167:                case 0xd:       /* 'd'ump short hand */
                   1168:                        panic("zero");
                   1169:                        /*NOTREACHED*/
                   1170:                
                   1171:                case 4:         /* old g4 */
                   1172:                        tracedump();
                   1173:                        break;
                   1174: 
                   1175:                default:
                   1176:                        goto err;
                   1177:                }
                   1178:                break;
                   1179: 
                   1180:        case 'p':               /* 'p'rint string command */
                   1181:        case 'P':
                   1182:                (*romp->v_printf)("%s\n", (char *)addr);
                   1183:                break;
                   1184: 
                   1185:        case '%':               /* p'%'int anything a la printf */
                   1186:                (*romp->v_printf)(str, addr);
                   1187:                (*romp->v_printf)("\n");
                   1188:                break;
                   1189: 
                   1190:        case 't':               /* 't'race kernel stack */
                   1191:        case 'T':
                   1192:                tracedump();
                   1193:                break;
                   1194: 
                   1195:        case 'u':               /* d'u'mp hack ('d' look like hex) */
                   1196:        case 'U':
                   1197:                if (addr == 0xd) {
                   1198:                        panic("zero");
                   1199:                } else
                   1200:                        goto err;
                   1201:                break;
                   1202: 
                   1203:        default:
                   1204:        err:
                   1205:                (*romp->v_printf)("Don't understand 0x%x '%s'\n", addr, str);
                   1206:        }
                   1207: }
                   1208: 
                   1209: /*
                   1210:  * Handle parity/ECC memory errors.  XXX - use something like
                   1211:  * vax to only look for soft ecc errors periodically?
                   1212:  */
                   1213: memerr()
                   1214: {
                   1215:        u_char per, eer;
                   1216:        char *mess = 0;
                   1217:        int c;
                   1218:        long pme;
                   1219: 
                   1220:        eer = per = MEMREG->mr_er;
                   1221: #ifdef SUN3_260
                   1222:        if (cpu == CPU_SUN3_260 && (eer & EER_ERR) == EER_CE) {
                   1223:                softecc();
                   1224:                MEMREG->mr_dvma = 1;    /* clear latching */
                   1225:                return;
                   1226:        } 
                   1227: #endif SUN3_260
                   1228: 
                   1229:        /*
                   1230:         * Since we are going down in flames, disable further
                   1231:         * memory error interrupts to prevent confusion.
                   1232:         */
                   1233:        MEMREG->mr_er &= ~ER_INTENA;
                   1234: 
                   1235: #if defined(SUN3_160) || defined(SUN3_50)
                   1236:        if ((cpu == CPU_SUN3_160 || cpu == CPU_SUN3_50) &&
                   1237:            (per & PER_ERR) != 0) {
                   1238:                printf("Parity Error Register %b\n", per, PARERR_BITS);
                   1239:                mess = "parity error";
                   1240:        }
                   1241: #endif defined(SUN3_160) || defined(SUN3_50)
                   1242: 
                   1243: #ifdef SUN3_260
                   1244:        if ((cpu == CPU_SUN3_260) && (eer & EER_ERR) != 0) {
                   1245:                printf("ECC Error Register %b\n", eer, ECCERR_BITS);
                   1246:                mess = "uncorrectable ECC error";
                   1247:        }
                   1248: #endif SUN3_260
                   1249: 
                   1250:        if (!mess) {
                   1251:                printf("Memory Error Register %b %b\n",
                   1252:                    per, PARERR_BITS, eer, ECCERR_BITS);
                   1253:                mess = "unknown memory error";
                   1254:        }
                   1255: 
                   1256:        printf("DVMA = %x, context = %x, virtual address = %x\n",
                   1257:                MEMREG->mr_dvma, MEMREG->mr_ctx, MEMREG->mr_vaddr);
                   1258: 
                   1259:        c = getcontext();
                   1260:        setcontext((int)MEMREG->mr_ctx);
                   1261:        pme = getpgmap((caddr_t)MEMREG->mr_vaddr);
                   1262:        printf("pme = %x, physical address = %x\n", pme,
                   1263:            ptob(((struct pte *)&pme)->pg_pfnum) + (MEMREG->mr_vaddr&PGOFSET));
                   1264:        setcontext(c);
                   1265: 
                   1266:        /*
                   1267:         * Clear the latching by writing to the top
                   1268:         * nibble of the memory address register
                   1269:         */
                   1270:        MEMREG->mr_dvma = 1;
                   1271: 
                   1272:        panic(mess);
                   1273:        /*NOTREACHED*/
                   1274: }
                   1275: 
                   1276: #ifdef SUN3_260
                   1277: int prtsoftecc = 1;
                   1278: 
                   1279: /*
                   1280:  * Probe memory cards to find which one(s) had ecc error(s).
                   1281:  * If prtsoftecc is non-zero, log messages regarding the failing
                   1282:  * syndrome.  Then clear the latching on the memory card.
                   1283:  */
                   1284: softecc()
                   1285: {
                   1286:        register struct eccreg **ecc_nxt, *ecc;
                   1287: 
                   1288:        for (ecc_nxt = ecc_alive; *ecc_nxt != (struct eccreg *)0; ecc_nxt++) {
                   1289:                ecc = *ecc_nxt;
                   1290:                if (ecc->syndrome.sy_ce) {
                   1291:                        if (prtsoftecc) {
                   1292:                                printf("mem%d: soft ecc addr %x+%x=%x syn %b\n",
                   1293:                                    ecc - ECCREG,
                   1294:                                    (ecc->eccena.ena_addr << 22),
                   1295:                                    (ecc->syndrome.sy_addr << 3),
                   1296:                                    (ecc->eccena.ena_addr << 22) +
                   1297:                                      (ecc->syndrome.sy_addr << 3),
                   1298:                                    ecc->syndrome.sy_synd, SYNDERR_BITS);
                   1299:                        }
                   1300:                        ecc->syndrome.sy_ce = 1;        /* clear latching */
                   1301:                }
                   1302:        }
                   1303: }
                   1304: #endif SUN3_260

unix.superglobalmegacorp.com

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