From ace215e79cb72065fe219e86d3583bbd34da94be Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 2 Sep 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-09-02 --- boot/boot.c | 23 ++++++------ boot/local.c | 29 +++++++++------ pc/dat.h | 11 ++++-- pc/devhard.c | 96 +++++++++++++++++++++++++++++++++++++------------ pc/devrtc.c | 2 +- pc/kbd.c | 30 +++++++++++++--- pc/main.c | 70 ++++++++++++++++-------------------- port/devcdrom.c | 2 -- port/devroot.c | 24 ++++++------- port/portdat.h | 2 +- port/proc.c | 7 ++-- power/devrtc.c | 6 ++-- ss/devrtc.c | 6 ++-- 13 files changed, 190 insertions(+), 118 deletions(-) diff --git a/boot/boot.c b/boot/boot.c index 562b189cf5957d9691e49d4ed0bcef135ffa285b..37ebf49ab7eea240efbc6953aeab78fa0ab5db12 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -115,19 +115,18 @@ boot(int argc, char *argv[]) * if a local file server exists and it's not * running, start it and mount it onto /n/kfs */ - for(mp = method; mp->name; mp++){ - if(strcmp(mp->name, "local") != 0) - continue; - if(access("#s/kfs", ORDWR) >= 0) - break; - (*mp->config)(mp); - fd = (*mp->connect)(); - if(fd < 0) + if(!islocal){ + for(mp = method; mp->name; mp++){ + if(strcmp(mp->name, "local") != 0) + continue; + (*mp->config)(mp); + fd = (*mp->connect)(); + if(fd < 0) + break; + mount(fd, "/n/kfs", MAFTER|MCREATE, "", "") ; + close(fd); break; - if(mount(fd, "/n/kfs", MAFTER|MCREATE, "", "") < 0) - print("failed to mount kfs\n"); - close(fd); - break; + } } settime(islocal); diff --git a/boot/local.c b/boot/local.c index e5545207730d607c5d1c25abb9c6082362a5ea98..55dc528e188550e5e0020afc60a3b2fd069d11c5 100644 --- a/boot/local.c +++ b/boot/local.c @@ -25,16 +25,21 @@ connectlocal(void) { int p[2]; char d[DIRLEN]; - char sbuf[32]; - char rbuf[32]; char partition[2*NAMELEN]; + char *dev; - if(stat("/kfs", d) < 0) + if(stat("/fs", d) < 0) return -1; - sprint(partition, "%sfs", disk ? disk : bootdisk); - if(stat(partition, d) < 0) - return -1; - print("kfs..."); + + dev = disk ? disk : bootdisk; + sprint(partition, "%sfs", dev); + if(stat(partition, d) < 0){ + strcpy(partition, dev); + if(stat(partition, d) < 0) + return -1; + } + + print("fs..."); if(bind("#c", "/dev", MREPL) < 0) fatal("bind #c"); if(bind("#p", "/proc", MREPL) < 0) @@ -45,10 +50,12 @@ connectlocal(void) case -1: fatal("fork"); case 0: - sprint(sbuf, "%d", p[0]); - sprint(rbuf, "%d", p[1]); - execl("/kfs", "kfs", "-f", partition, "-s", sbuf, rbuf, 0); - fatal("can't exec kfs"); + dup(p[0], 0); + dup(p[1], 1); + close(p[0]); + close(p[1]); + execl("/fs", "fs", "-f", partition, "-s", 0); + fatal("can't exec fs"); default: break; } diff --git a/pc/dat.h b/pc/dat.h index 55e188491d5de3dea58aee66dcaa55bc98e8c674..bb094b441d6631f37ae29747772c25be9595f727 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -184,7 +184,12 @@ extern int flipD[]; /* for flipping bitblt destination polarity */ enum { - At= 0, - Attnsx= 1, + PMUnsx20= 0, + PMUother= 1, + + Mouseserial= 0, + MousePS2= 1, + Mouseother= 2, }; -extern int machtype; +extern int mousetype; +extern int pmutype; diff --git a/pc/devhard.c b/pc/devhard.c index 22a641b29e76f71584afb550758f8409678de594..f308dc39d8f26065209fc4ab65b5a2994fc080e8 100644 --- a/pc/devhard.c +++ b/pc/devhard.c @@ -40,6 +40,7 @@ enum Cident= 0xEC, Cident2= 0xFF, /* pseudo command for post Cident interrupt */ Csetbuf= 0xEF, + Cinitparam= 0x91, /* file types */ Qdir= 0, @@ -159,7 +160,8 @@ Drive *hard; static void hardintr(Ureg*); static long hardxfer(Drive*, Partition*, int, long, long, char*); static void hardident(Drive*); -static void hardsetbuf(Drive*); +static void hardsetbuf(Drive*, int); +static void hardinitparam(Drive*); static void hardpart(Drive*); static int @@ -239,28 +241,32 @@ hardattach(char *spec) for(dp = hard; dp < &hard[conf.nhard]; dp++){ if(!waserror()){ - dp->bytes = 512; + /* + * the following is magic to determine the parameters + * (number of cylinders/sectors/heads) on an IDE drive. + * I haven't found a method that is guaranteed to work. + * For some drives, it may be necessary to compile the + * numbers into this driver and circumvent this code. + * The BIOS disk type & tables doesn't help since the + * types are inconsistent from one BIOS to the next. + */ + dp->bytes = 512; /* until we know better */ + hardsetbuf(dp, 0); /* turned off during ident */ hardident(dp); + hardsetbuf(dp, 1); + /* + * for now use the configuration word to identify the + * wayward 6386 disk. BUG!!! This word isn't + * meant to identify disks, but we have nothing + * better. + */ switch(dp->id.magic){ - case 0xA5A: /* conner drive on the AT&T NSX (safari) */ - dp->cyl = dp->id.lcyls; - dp->heads = dp->id.lheads; - dp->sectors = dp->id.ls2t; - hardsetbuf(dp); - break; - case 0x324A: /* hard drive on the AT&T 6386 */ + case 0x324A: /* hard drive on the AT&T 6386, it lies */ dp->cyl = dp->id.lcyls - 4; dp->heads = dp->id.lheads; dp->sectors = dp->id.ls2t - 1; break; default: /* others: we hope this works */ - if (drivecomment) { - print("unknown hard disk type, magic=%04x", - dp->id.magic); - print(" cyl=%d h=%d sec=%d\n", - dp->id.lcyls, dp->id.lheads, dp->id.ls2t); - } - case 0x427a: /* for now: a list of those that work */ dp->cyl = dp->id.lcyls; dp->heads = dp->id.lheads; dp->sectors = dp->id.ls2t; @@ -269,7 +275,23 @@ hardattach(char *spec) dp->bytes = 512; dp->cap = dp->bytes * dp->cyl * dp->heads * dp->sectors; dp->online = 1; - hardpart(dp); + /* + * Try reading the partition table (last disk sector). + * If an error occurs set the drive parameters and try + * again. This works if the parameters reported + * by the disk are the physical parameters rather than + * the current logical ones (as they are on the NCR 3170). + * + * We don't routinely set the parameters since it confuses + * some disks (on the Gateway and AT&T Safari for example). + */ + if(waserror()){ + hardinitparam(dp); /* set drive parameters */ + hardpart(); + } else { + hardpart(); + poperror(); + } poperror(); } else dp->online = 0; @@ -579,7 +601,7 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf) * set read ahead mode */ static void -hardsetbuf(Drive *dp) +hardsetbuf(Drive *dp, int on) { Controller *cp = dp->cp; @@ -592,7 +614,7 @@ hardsetbuf(Drive *dp) cmdreadywait(cp); cp->cmd = Csetbuf; - outb(cp->pbase+Pprecomp, 0xAA); + outb(cp->pbase+Pprecomp, on ? 0xAA : 0x55); outb(cp->pbase+Pdh, 0x20 | (dp->drive<<4)); outb(cp->pbase+Pcmd, Csetbuf); @@ -606,6 +628,37 @@ hardsetbuf(Drive *dp) qunlock(cp); } +/* + * set the drive parameters + */ +static void +hardinitparam(Drive *dp) +{ + Controller *cp = dp->cp; + + qlock(cp); + if(waserror()){ + qunlock(cp); + nexterror(); + } + + cmdreadywait(cp); + + cp->cmd = Cinitparam; + outb(cp->pbase+Psector, dp->sectors); + outb(cp->pbase+Pdh, 0x20 | (dp->heads-1) | (dp->drive<<4)); + outb(cp->pbase+Pcmd, Cinitparam); + + sleep(&cp->r, cmddone, cp); + + if(cp->status & Serr) + DPRINT("hd%d initparam err: status %lux, err %lux\n", + dp-hard, cp->status, cp->error); + + poperror(); + qunlock(cp); +} + /* * get parameters from the drive */ @@ -865,6 +918,7 @@ hardintr(Ureg *ur) wakeup(&cp->r); } break; + case Cinitparam: case Csetbuf: cp->lastcmd = cp->cmd; cp->cmd = 0; @@ -874,10 +928,6 @@ hardintr(Ureg *ur) cp->lastcmd = cp->cmd; cp->cmd = 0; break; - case 0: - print("interrupt cmd=0, lastcmd=%02x status=%02x\n", - cp->lastcmd, cp->status); - break; default: print("weird disk interrupt, cmd=%02x, status=%02x\n", cp->cmd, cp->status); diff --git a/pc/devrtc.c b/pc/devrtc.c index 4674fda1f720402409ba16bb60021daa233a2b0b..08ad71931b4adc7a5db6ddba5707f739e350c54a 100644 --- a/pc/devrtc.c +++ b/pc/devrtc.c @@ -92,7 +92,7 @@ rtcopen(Chan *c, int omode) omode = openmode(omode); switch(c->qid.path){ case Qrtc: - if(omode != OREAD && strcmp(u->p->user, eve)!=0) + if(strcmp(u->p->user, eve)!=0 && omode!=OREAD) error(Eperm); break; case Qnvram: diff --git a/pc/kbd.c b/pc/kbd.c index 15a4319caa260adad4167864cf4318dcefd6f754..226e23a0e99054b1f65856b99550f79798238af4 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -182,6 +182,19 @@ i8042a20(void) outready(); } +/* + * ask 8042 to reset the machine + */ +void +i8042reset(void) +{ + outready(); + outb(Cmd, 0xD1); + outready(); + outb(Data, 0xDE); + outready(); +} + void kbdinit(void) { @@ -194,8 +207,8 @@ kbdinit(void) if(c & Inready) inb(Data); - switch(machtype){ - case Attnsx: + switch(mousetype){ + case MousePS2: bigcursor(); setvec(Mousevec, kbdintr); @@ -216,7 +229,7 @@ kbdinit(void) /* turn on mouse acceleration */ mouseaccelerate(0); break; - case At: + case Mouseserial: /* enable kbd xfers and interrupts */ outb(Cmd, 0x60); if(outready() < 0) @@ -226,6 +239,13 @@ kbdinit(void) /* set up /dev/eia0 as the mouse */ uartspecial(0, 0, &mouseq, 1200); break; + case Mouseother: + /* enable kbd xfers and interrupts */ + outb(Cmd, 0x60); + if(outready() < 0) + print("kbd init failed\n"); + outb(Data, 0x65); + break; } } @@ -236,8 +256,8 @@ void mouseaccelerate(int on) { - switch(machtype){ - case Attnsx: + switch(mousetype){ + case MousePS2: if(on) mousecmd(0xE7); else diff --git a/pc/main.c b/pc/main.c index 81753b566fae26a2bccd4cf230019f4b6c8e1c5a..af1cd8955a433a1dea3fd6ba2c8b5890d25e0e9e 100644 --- a/pc/main.c +++ b/pc/main.c @@ -7,14 +7,15 @@ #include "ureg.h" #include "init.h" -int machtype; /* machine type, mostly for power management */ +int mousetype; +int pmutype; uchar *sp; /* stack pointer for /boot */ void main(void) { ident(); - meminit(); + i8042a20(); /* enable address lines 20 and up */ machinit(); active.exiting = 0; active.machs = 1; @@ -39,16 +40,26 @@ main(void) schedinit(); } +/* + * this should be changed to describe architecture dependencies outside the + * PC model + */ void ident(void) { char *id = (char*)(ROMBIOS + 0xFF40); /* check for a safari (tres special) */ - if(strncmp(id, "AT&TNSX", 7) == 0) - machtype = Attnsx; - else - machtype = At; + if(strncmp(id, "AT&TNSX", 7) == 0){ + mousetype = MousePS2; + pmutype = PMUnsx20; + }else if(strncmp(id, "NCRD.0", 6) == 0){ + mousetype = MousePS2; + pmutype = PMUother; + }else{ + mousetype = Mouseserial; + pmutype = PMUother; + } } void @@ -243,7 +254,6 @@ confinit(void) conf.npage0 -= ktop/BY2PG; conf.base0 += ktop; - /* for meminit() */ conf.topofmem = i*MB; conf.monitor = 1; @@ -393,20 +403,6 @@ procrestore(Proc *p) * PC to PC. */ -/* enable address bit 20 (extended memory) */ -void -meminit(void) -{ - switch(machtype){ - case Attnsx: - heada20(); /* via headland chip */ - break; - case At: - i8042a20(); /* via keyboard controller */ - break; - } -} - /* * reset the i387 chip */ @@ -417,15 +413,9 @@ exit(int ispanic) print("exiting\n"); if(ispanic) for(;;); - switch(machtype){ - case Attnsx: - headreset(); /* via headland chip */ - break; - case At: - print("hit the button..."); - for(;;); - putcr3(0); /* crash and burn */ - } + i8042reset(); /* via keyboard controller */ + print("can't reset via software, do something drastic!\n"); + for(;;); } /* @@ -436,8 +426,8 @@ exit(int ispanic) int cpuspeed(int speed) { - switch(machtype){ - case Attnsx: + switch(pmutype){ + case PMUnsx20: return pmucpuspeed(speed); default: return 0; @@ -451,8 +441,8 @@ cpuspeed(int speed) void buzz(int f, int d) { - switch(machtype){ - case Attnsx: + switch(pmutype){ + case PMUnsx20: pmubuzz(f, d); break; default: @@ -466,8 +456,8 @@ buzz(int f, int d) void lights(int val) { - switch(machtype){ - case Attnsx: + switch(pmutype){ + case PMUnsx20: pmulights(val); break; default: @@ -483,8 +473,8 @@ lights(int val) int serial(int onoff) { - switch(machtype){ - case Attnsx: + switch(pmutype){ + case PMUnsx20: return pmuserial(onoff); default: return 0; @@ -499,8 +489,8 @@ serial(int onoff) int modem(int onoff) { - switch(machtype){ - case Attnsx: + switch(pmutype){ + case PMUnsx20: return pmumodem(onoff); default: return 0; diff --git a/port/devcdrom.c b/port/devcdrom.c index 8823055e07f6772a4643fcf597064a775bf755f9..ba6802d45acc287d349e2926b5bc957f4619defc 100644 --- a/port/devcdrom.c +++ b/port/devcdrom.c @@ -226,8 +226,6 @@ cdromsize(int dev) error(Ecap); scsiinquiry(dev, buf, sizeof buf); - if(buf[0]!=5 || buf[0]!=4) /* CD-ROM or CD-R writer */ - print("warning: scsi device %d type=%d, not type 4 or 5\n", dev>>3, buf[0]); dp->drive = dev; dp->blocks = nb; dp->bsize = bs; diff --git a/port/devroot.c b/port/devroot.c index 2a4cba44fa4dd2592bb2d959ac7cccc69285f43f..bf332c831d869724a03ba6cf49feeb33767934c9 100644 --- a/port/devroot.c +++ b/port/devroot.c @@ -16,15 +16,15 @@ enum{ Qboot, Qcfs, - Qkfs, + Qfs, }; extern long cfslen; extern ulong cfscode[]; -extern long kfslen; -extern ulong kfscode[]; +extern long fslen; +extern ulong fscode[]; extern ulong bootlen; -extern ulong bootcode[]; +extern uchar bootcode[]; Dirtab rootdir[]={ "bin", {Qbin|CHDIR}, 0, 0777, @@ -37,7 +37,7 @@ Dirtab rootdir[]={ #define NROOT (sizeof rootdir/sizeof(Dirtab)) Dirtab rootpdir[]={ "cfs", {Qcfs}, 0, 0777, - "kfs", {Qkfs}, 0, 0777, + "fs", {Qfs}, 0, 0777, }; Dirtab *rootmap[sizeof rootpdir/sizeof(Dirtab)]; int nroot; @@ -67,7 +67,7 @@ rootreset(void) i = 0; if(cfslen) rootmap[i++] = &rootpdir[0]; - if(kfslen) + if(fslen) rootmap[i++] = &rootpdir[1]; nroot = NROOT + i; } @@ -142,7 +142,7 @@ rootread(Chan *c, void *buf, long n, ulong offset) return 0; if(offset+n > bootlen) n = bootlen - offset; - memmove(buf, ((char*)bootcode)+offset, n); + memmove(buf, bootcode+offset, n); return n; case Qcfs: /* cfs */ @@ -153,12 +153,12 @@ rootread(Chan *c, void *buf, long n, ulong offset) memmove(buf, ((char*)cfscode)+offset, n); return n; - case Qkfs: /* kfs */ - if(offset >= kfslen) + case Qfs: /* fs */ + if(offset >= fslen) return 0; - if(offset+n > kfslen) - n = kfslen - offset; - memmove(buf, ((char*)kfscode)+offset, n); + if(offset+n > fslen) + n = fslen - offset; + memmove(buf, ((char*)fscode)+offset, n); return n; case Qdev: diff --git a/port/portdat.h b/port/portdat.h index ed012183e13da66c2f51dcd2f10db8cf3c45959a..08e785644447243d542da9dd54ffca356344dc24 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -732,7 +732,7 @@ extern int cpuserver; extern char* devchar; extern Dev devtab[]; extern char eve[]; -extern ulong initcode[]; +extern uchar initcode[]; extern FPsave initfp; extern KIOQ kbdq; extern IOQ lineq; diff --git a/port/proc.c b/port/proc.c index 0ef2cd044203551e479fc344dd75720b29aa30ed..0e9492b94e1be9319ca42e55fc828e0c6a5a51b0 100644 --- a/port/proc.c +++ b/port/proc.c @@ -529,8 +529,11 @@ pexit(char *exitstr, int freemem) * do some housekeeping. */ if(c->kp == 0) { - if((p = c->parent) == 0) - panic("boot process died"); + if((p = c->parent) == 0) { + if(exitstr == 0) + exitstr = "unknown"; + panic("boot process died: %s", exitstr); + } while(waserror()) ; diff --git a/power/devrtc.c b/power/devrtc.c index 66158fd0f29eccb0c0621e099e29a77468edd9e3..bdda527dd3be2f50142369a8e331905a507839e2 100644 --- a/power/devrtc.c +++ b/power/devrtc.c @@ -100,9 +100,9 @@ rtcopen(Chan *c, int omode) omode = openmode(omode); switch(c->qid.path){ case Qrtc: - if(omode == OREAD) - break; - /* fall through */ + if(strcmp(u->p->user, eve)!=0 && omode!=OREAD) + error(Eperm); + break; case Qnvram: if(strcmp(u->p->user, eve)!=0 || !cpuserver) error(Eperm); diff --git a/ss/devrtc.c b/ss/devrtc.c index 89bd7025d44855db7bde02d443e8861a5f48e290..d57f222d42ffb4c0fe1bcbe49384130b5a601eeb 100644 --- a/ss/devrtc.c +++ b/ss/devrtc.c @@ -92,9 +92,9 @@ rtcopen(Chan *c, int omode) omode = openmode(omode); switch(c->qid.path){ case Qrtc: - if(omode == OREAD) - break; - /* fall through */ + if(strcmp(u->p->user, eve)!=0 && omode!=OREAD) + error(Eperm); + break; case Qnvram: if(strcmp(u->p->user, eve)!=0 || !cpuserver) error(Eperm);