M boot/boot.c => boot/boot.c +11 -12
@@ 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);
M boot/local.c => boot/local.c +18 -11
@@ 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;
}
M pc/dat.h => pc/dat.h +8 -3
@@ 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;
M pc/devhard.c => pc/devhard.c +73 -23
@@ 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);
@@ 607,6 629,37 @@ hardsetbuf(Drive *dp)
}
/*
+ * 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
*/
static void
@@ 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);
M pc/devrtc.c => pc/devrtc.c +1 -1
@@ 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:
M pc/kbd.c => pc/kbd.c +25 -5
@@ 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
M pc/main.c => pc/main.c +30 -40
@@ 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;
M port/devcdrom.c => port/devcdrom.c +0 -2
@@ 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;
M port/devroot.c => port/devroot.c +12 -12
@@ 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:
M port/portdat.h => port/portdat.h +1 -1
@@ 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;
M port/proc.c => port/proc.c +5 -2
@@ 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())
;
M power/devrtc.c => power/devrtc.c +3 -3
@@ 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);
M ss/devrtc.c => ss/devrtc.c +3 -3
@@ 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);