/* * This file contains * 1. oem modifiable configuration personality parameters * 2. oem modifiable system specific kernel personality code */ #include "sys/param.h" #include "sys/config.h" #include "sys/mmu.h" #include "sys/types.h" #include "sys/sysmacros.h" #include "sys/systm.h" #include "sys/map.h" #include "sys/dir.h" #include "sys/signal.h" #include "sys/user.h" #include "sys/errno.h" #include "sys/proc.h" #include "sys/buf.h" #include "sys/iobuf.h" #include "sys/reg.h" #include "sys/file.h" #include "sys/inode.h" #include "sys/seg.h" #include "sys/acct.h" #include "sys/sysinfo.h" #include "sys/var.h" #include "sys/ipc.h" #include "sys/shm.h" #include "sys/termio.h" #include "sys/conf.h" #include "sys/cops.h" #include "sys/pport.h" #include "sys/local.h" #include "sys/l2.h" #include "sys/kb.h" #include "sys/swapsz.h" /*char oemmsg[] = "UniSoft Systems distribution system release 1.5";*/ char oemmsg[] = "UniSoft Systems pre-distribution system (release 1.5+)"; int sspeed = B9600; /* default console speed */ int parityno = 28; /* parity interrupt vector */ int cmask = CMASK; /* default file creation mask */ int cdlimit = CDLIMIT; /* default file size limit */ char slot[NSLOTS]; /* card ID numbers for expansion cards */ /* * Kernel initialization functions. * Called from main.c while at spl7 in the kernel. */ oem7init() /* alias (formerly) "lisainit" */ { #ifdef SUNIX int dev; extern dev_t swapdev; extern int nswap; #endif SUNIX extern struct rtime rtime; extern int pmvect[]; extern int tevect[]; register short *sidp; /* slot ID pointer */ register slotid, i; register long *ip; l2init(); /* setup the COPS ports */ /* This mess disables the verticle retrace interrupt, for now. */ do { VRON = 1; } while ((STATUS & S_VR) != 0); do { VROFF = 1; } while ((STATUS & S_VR) == 0); /* Some of the initialization requires that interrupts be enabled to * pick up coded sequences from the keyboard cops. If interrupts were * masked out then the time returned by READCLOCK would fill the * buffer and KBENABLE, which also returns a value, would have trouble. */ SPL1(); /* ok, do it to me */ l2copscmd(MOUSEOFF); /* shut off mouse interrupts */ l2copscmd(READCLOCK); /* get time of day */ l2copscmd(KBENABLE); /* enable keyboard */ sninit(); /* Sony initialization */ /* Wait 'til the clock data (from READCLOCK) and keyboard ID (from KBENABLE) have come in, and the keyboard is back in NORMALWAIT */ while (kb_state); time = rtime.rt_tod; SPL7(); /* it should be at level 7 for the rest (?) */ /* Find out what's in each of the expansion slots. */ for (i = 0, sidp = SLOTIDS; i < NSLOTS; i++, sidp++) { slot[i] = 0xFF; /* not supported */ slotid = *sidp & SLOTMASK; if (!slotid) { if (iocheck((caddr_t)(STDIO+i*0x4000+1))) { printf("Expansion slot %d: quad serial card\n", i+1); if (teinit(i) == 0) { /* * point to interrupt vector, * set tecmar quad serial board inter loc, * and initialize hdwr */ ip = &((long *) 0)[EXPIVECT+devtoslot(i)]; *ip = (long)tevect + (long)(devtoslot(i)<<2); } } continue; } printf("Expansion slot %d: ", i+1); switch (slotid) { case ID_APLNET: printf("applenet card\n"); break; case ID_PRO: printf("ProFile card\n"); break; case ID_2PORT: printf("two port card\n"); slot[i] = PR0; /* valid */ break; case ID_PRIAM: printf("Priam card\n"); ip = &((long *) 0)[EXPIVECT+devtoslot(i)]; /* point to int vector */ *ip = (long)pmvect + (long)(devtoslot(i)<<2); /* set to Priam intr */ if (pmcinit(i) == 0) /* initialize controller */ slot[i] = PM3; /* valid */ break; default: printf("card ID 0x%x\n", slotid); } } scinit(); /* SCC serial initialization */ #ifdef UCB_NET netinit(); #endif /* Now enable the verticle retrace interrupt, used for the system clock. */ do { VRON = 1; } while ((STATUS & S_VR) != 0); #ifdef SUNIX SPL0(); /* This is the first unix booted during installation so find swapdev. */ if (rootdev == makedev(SN1, 0)) { while (chkdev(dev = getdevnam())) printf("Unable to use that device\nTry again:\n"); printf("\n\nswapdev = 0x%x\n\n", dev); swapdev = dev; if (major(dev) == PR0) nswap = PRNSWAP; else if (major(dev) == PM3) nswap = PMNSWAP; else if (major(dev) == CV2) nswap = CVNSWAP; else panic("cannot determine size of swapdev"); } #endif SUNIX } /* * Kernel initialization functions. * Called from main.c while at spl0 in the kernel. */ oem0init() { } /* * parityerror() * Called from trap for parity error traps via * interrupt level "parityno" (conf.c). * Should return non-zero for fatal errors. * Should return zero for a transient warning error. */ parityerror() { printf("parity error\n"); return(-1); } /* * reboot the system * called from reboot function */ doboot() { kb_state = SHUTDOWN; /* SHUTDOWN (see kb.c)*/ SPL7(); /* extreme priority */ rom_mon(); /* return to the ROM monitor */ /*NOTREACHED*/ } /* * OEM supplied subroutine called on process exit */ /* ARGSUSED */ oemexit(p) register struct proc *p; { #ifdef lint /* for lint use p */ p->p_flag++; #endif } struct device_d *pro_da[NPPDEVS] = { /* DEV Description */ PPADDR, /* 0x00 parallel port */ (struct device_d *)(STDIO+0x2000), /* 0x10 FPC port 0 slot 1 */ (struct device_d *)(STDIO+0x2800), /* 0x20 FPC port 1 slot 1 */ (struct device_d *)(STDIO+0x3000), /* 0x30 FPC port 2 slot 1 !!!*/ (struct device_d *)(STDIO+0x6000), /* 0x40 FPC port 0 slot 2 */ (struct device_d *)(STDIO+0x6800), /* 0x50 FPC port 1 slot 2 */ (struct device_d *)(STDIO+0x7000), /* 0x60 FPC port 2 slot 2 !!!*/ (struct device_d *)(STDIO+0xA000), /* 0x70 FPC port 0 slot 3 */ (struct device_d *)(STDIO+0xA800), /* 0x80 FPC port 1 slot 3 */ (struct device_d *)(STDIO+0xB000) /* 0x90 FPC port 2 slot 3 !!!*/ }; int (*pi_fnc[NPPDEVS])(); /* slots for interrupt handler addresses */ /* Set the interrupt handler for a given parallel port controller. */ setppint(addr, fnc) struct device_d *addr; int (*fnc)(); { register int i; extern int cvint(), prointr(), lpintr(); for (i=0; ia_dev) == 0) { /* special case for pp 0 */ if(fnc = pi_fnc[i]) { fnc(i); return; } } j = i + 2; while (i < j) { dp = pro_da[i]; if ((a = dp->d_ifr) & FCA1) { asm(" nop "); dp->d_ifr = a; /* reset interrupt */ if (fnc = pi_fnc[i]) { if (fnc == lpintr) lpflg[i] = 0; else if (fnc != ebintr && fnc != prointr && fnc != cvint) { printf("pi_fnc[%d] = 0x%x invalid!!\n", i,fnc); return; } fnc(i); return; } #ifdef INTDUMP ppdump(i,dp); #endif INTDUMP return; } i++; } } #ifdef INTDUMP ppdump(n, p) register struct device_d *p; { printf("pport %d: ",n); printf("ifr=%x acr=%x pcr=%x ddra=%x ddrb=%x irb=%x\n", p->d_ifr&0xFF, p->d_acr&0xFF, p->d_pcr&0xFF, p->d_ddra&0xFF, p->d_ddrb&0xFF, p->d_irb&0xFF); } #endif INTDUMP /* * called from clock if there's a panic in progress */ clkstop() { VROFF = 1; /* disable vertical retrace intr */ } nmikey() { int i; register short status; /* added 7/25/84 to provide more info than "NMI key". * (taken from section 2.8 of Lisa Theory of Operations) */ printf("non-maskable interrupt: "); status = STATUS; if (status & S_SMEMERR) printf("soft memory error\n"); else if (status & S_HMEMERR) printf("hard memory error\n"); else printf("power failure/keyboard reset\n"); #ifdef HOWFAR showbus(); #endif HOWFAR for (i=0xC00000; i>0; i--) ; /* delay */ } #ifdef SUNIX /* Get swap device name */ getdevnam () { char *p, *gets(); int unit, dev; retry: printf("\n\nWhere is the swap area?\n"); printf("Enter: 'p' for builtin disk or a profile disk\n"); printf(" 'c' for Corvus disk\n"); printf(" 'pm' for Priam disk\n"); p = gets(); switch (p[0]) { case 'p': dev = PR0; if (p[1] == 'm') dev = PM3; break; case 'c': dev = CV2; break; default: printf("Invalid input. Try again.\n"); goto retry; } printf("Where will the disk be?\n"); if ((dev == PR0) || (dev == CV2)) { printf("Enter: '0' for builtin port\n"); printf(" '1' for Expansion Slot 1, Bottom Port\n"); printf(" '2' for Expansion Slot 1, Top Port\n"); printf(" '4' for Expansion Slot 2, Bottom Port\n"); printf(" '5' for Expansion Slot 2, Top Port\n"); printf(" '7' for Expansion Slot 3, Bottom Port\n"); printf(" '8' for Expansion Slot 3, Top Port\n"); p = gets(); switch (p[0]) { case '0': case '1': case '2': case '4': case '5': case '7': case '8': unit = p[0] - '0'; break; default: printf("Invalid input. Try again.\n"); goto retry; } } else { /* dev == PM3 */ printf("Enter: '0' for Slot 1\n"); printf(" '1' for Slot 2\n"); printf(" '2' for Slot 3\n"); p = gets(); switch (p[0]) { case '0': case '1': case '2': unit = p[0] - '0'; break; default: printf("Invalid input. Try again.\n"); goto retry; } } return makedev(dev, (unit<<4) | 1 ); } chkdev(d) { return(*bdevsw[bmajor(d)].d_open)(minor(d), FREAD | FWRITE); } /* * This version of getchar reads directly from the keyboard in order to get * swapdev when the parallel port is not available. It will not work once * the console has been formally opened. */ char kb_getchr; cogetchar() { SPL0(); while(kb_state) ; /* wait for kb driver to finish special cmd */ kb_getchr = 1; /* wait flag */ while (kb_getchr) ; /* wait for it to happen */ return kb_chrbuf; } /* Kernel get string routine. * Useful for getting information from the console before the system * comes up. The getchar routine will not work once the console has * been opened. */ int (*getchar)() = cogetchar; extern int (*putchar)(); char getsbuf[100]; char * gets () { register char *p; register char c; extern short kb_keycount; p = getsbuf; while (c = (*getchar)()) { switch (c) { case '\r': case '\n': goto out; case '\b': if (p > getsbuf) { p--; } break; case '@': case 'X'&0x1F: /* line kill */ if (p > getsbuf) { p = getsbuf; c = '\n'; /* echo a newline */ } break; default: *p++ = c; } (*putchar)(c); if (p >= getsbuf + sizeof(getsbuf)) { printf("\nInput line too long, try again ...\n"); p = getsbuf; } } out: *p = '\0'; (*putchar)('\n'); return getsbuf; } #endif SUNIX