M gnot/dat.h => gnot/dat.h +1 -0
@@ 154,6 154,7 @@ struct Conf
int nfsyschan; /* number of filsys open channels */
ulong maxialloc; /* maximum bytes used by ialloc */
int copymode; /* 0 is copy on write, 1 is copy on reference */
+ int portispaged; /* ??? */
};
struct Dev
A gnot/devport.c => gnot/devport.c +222 -0
@@ 0,0 1,222 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "errno.h"
+
+#include "devtab.h"
+
+#include "port.h"
+
+enum {
+ Qdir,
+ Qdata,
+};
+
+Dirtab portdir[]={
+ "data", {Qdata}, 0, 0600,
+};
+
+#define NPORT (sizeof portdir/sizeof(Dirtab))
+
+int
+portprobe(char *what, int select, int addr, int rw, long val)
+{
+ int time;
+ if (!conf.portispaged)
+ return 0;
+ P_qlock(select);
+ switch (rw) {
+ case -1:
+ val = *(uchar *)(PORT+addr); break;
+ case -2:
+ val = *(ushort *)(PORT+addr); break;
+ case -4:
+ val = *(long *)(PORT+addr); break;
+ case 1:
+ *(uchar *)(PORT+addr) = val; break;
+ case 2:
+ *(ushort *)(PORT+addr) = val; break;
+ case 4:
+ *(long *)(PORT+addr) = val; break;
+ default:
+ panic("portprobe");
+ }
+ time = PORTSELECT & 0x1f;
+ P_qunlock(select);
+ if (what) {
+ print("%s at %d, %d", what, select, addr);
+ print("%s", time & 0x10 ? " -- NOT FOUND\n" : "\n");
+ }
+ if (time & 0x10)
+ return -1;
+ return val;
+}
+
+void
+portreset(void)
+{
+ portpage.select = -1;
+ lock(&portpage);
+ unlock(&portpage);
+}
+
+void
+portinit(void)
+{}
+
+Chan *
+portattach(char *param)
+{
+ return devattach('x', param);
+}
+
+Chan *
+portclone(Chan *c, Chan *nc)
+{
+ return devclone(c, nc);
+}
+
+int
+portwalk(Chan *c, char *name)
+{
+ return devwalk(c, name, portdir, NPORT, devgen);
+}
+
+void
+portstat(Chan *c, char *db)
+{
+ devstat(c, db, portdir, NPORT, devgen);
+}
+
+Chan *
+portopen(Chan *c, int omode)
+{
+ return devopen(c, omode, portdir, NPORT, devgen);
+}
+
+void
+portcreate(Chan *c, char *name, int omode, ulong perm)
+{
+ error(Eperm);
+}
+
+void
+portclose(Chan *c)
+{}
+
+long
+portread(Chan *c, char *a, long n)
+{
+ long s, k;
+ if (n == 0)
+ return 0;
+ switch ((int)(c->qid.path & ~CHDIR)) {
+ case Qdir:
+ return devdirread(c, a, n, portdir, NPORT, devgen);
+ case Qdata:
+ if (!conf.portispaged || (s = c->offset >> PORTSHIFT) > 0xff)
+ s = -1;
+ k = c->offset % PORTSIZE;
+ P_qlock(s);
+ switch ((int)n) {
+ case 1:
+ *a = PORT[k]; break;
+ case 2:
+ *(short *)a = *(short *)(PORT+k); break;
+ case 4:
+ *(long *)a = *(long *)(PORT+k); break;
+ default:
+ P_qunlock(s);
+ error(Ebadarg);
+ }
+ P_qunlock(s);
+ break;
+ default:
+ panic("portread");
+ }
+ return n;
+}
+
+long
+portwrite(Chan *c, char *a, long n)
+{
+ long s, k;
+ if (n == 0)
+ return 0;
+ switch ((int)c->qid.path) {
+ case Qdata:
+ if (!conf.portispaged || (s = c->offset >> PORTSHIFT) > 0xff)
+ s = -1;
+ k = c->offset % PORTSIZE;
+ P_qlock(s);
+ switch ((int)n) {
+ case 1:
+ PORT[k] = *a; break;
+ case 2:
+ *(short *)(PORT+k) = *(short *)a; break;
+ case 4:
+ *(long *)(PORT+k) = *(long *)a; break;
+ default:
+ P_qunlock(s);
+ error(Ebadarg);
+ }
+ P_qunlock(s);
+ break;
+ default:
+ panic("portwrite");
+ }
+ return n;
+}
+
+void
+portremove(Chan *c)
+{
+ error(Eperm);
+}
+
+void
+portwstat(Chan *c, char *dp)
+{
+ error(Eperm);
+}
+
+#define Nportservice 8
+int (*portservice[Nportservice])(void);
+
+Portpage portpage;
+
+Lock intrlock;
+
+void
+addportintr(int (*f)(void))
+{
+ int s = splhi();
+ int (**p)(void);
+ lock(&intrlock);
+ for (p=portservice; *p; p++)
+ if (*p == f)
+ goto out;
+ if (p >= &portservice[Nportservice-1])
+ panic("addportintr");
+ *p = f;
+out:
+ unlock(&intrlock);
+ splx(s);
+}
+
+void
+devportintr(void)
+{
+ int (**p)(void); int i = 0;
+ for (p=portservice; *p; p++)
+ i |= (**p)();
+ if (!i)
+ /*putstring("spurious portintr\n");*/
+ panic("portintr");
+ if (portpage.select >= 0)
+ PORTSELECT = portpage.select;
+
+}
M gnot/main.c => gnot/main.c +1 -0
@@ 340,6 340,7 @@ confinit(void)
conf.nservice = 3*mul; /* was conf.nproc/5 */
conf.nfsyschan = 31 + conf.nchan/20;
conf.copymode = 0; /* copy on write */
+ conf.portispaged = 0;
}
/*
A gnot/scsisubs.s => gnot/scsisubs.s +67 -0
@@ 0,0 1,67 @@
+#include "mem.h"
+
+TEXT spl1(SB), $0
+
+ MOVL $0, R0
+ MOVW SR, R0
+ MOVW $(SUPER|SPL(1)), SR
+ RTS
+
+TEXT spl2(SB), $0
+
+ MOVL $0, R0
+ MOVW SR, R0
+ MOVW $(SUPER|SPL(2)), SR
+ RTS
+
+TEXT scsirecv(SB), $0
+ MOVL $0x40300033, A0 /* data */
+ MOVL $0x40300032, A1 /* status */
+ MOVL p+0(FP), A2
+ BTST $1, (A1)
+ BEQ rout
+rloop:
+ MOVB (A0), (A2)+
+ BTST $1, (A1)
+ BEQ rout
+
+ MOVB (A0), (A2)+
+ BTST $1, (A1)
+ BEQ rout
+
+ MOVB (A0), (A2)+
+ BTST $1, (A1)
+ BEQ rout
+
+ MOVB (A0), (A2)+
+ BTST $1, (A1)
+ BNE rloop
+rout:
+ MOVL A2, R0
+ RTS
+
+TEXT scsixmit(SB), $0
+ MOVL $0x40300033, A0 /* data */
+ MOVL $0x40300032, A1 /* status */
+ MOVL p+0(FP), A2
+ BTST $1, (A1)
+ BEQ xout
+xloop:
+ MOVB (A2)+, (A0)
+ BTST $1, (A1)
+ BEQ xout
+
+ MOVB (A2)+, (A0)
+ BTST $1, (A1)
+ BEQ xout
+
+ MOVB (A2)+, (A0)
+ BTST $1, (A1)
+ BEQ xout
+
+ MOVB (A2)+, (A0)
+ BTST $1, (A1)
+ BNE xloop
+xout:
+ MOVL A2, R0
+ RTS
M port/devroot.c => port/devroot.c +2 -0
@@ 94,7 94,9 @@ rootread(Chan *c, void *buf, long n)
return 0;
if(c->offset+n > sizeof bootcode)
n = sizeof bootcode - c->offset;
+ck("1");
memcpy(buf, ((char*)bootcode)+c->offset, n);
+ck("2");
return n;
case Qdev:
A port/devscsi.c => port/devscsi.c +548 -0
@@ 0,0 1,548 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "errno.h"
+#include "devtab.h"
+#include "io.h"
+
+#include "port.h"
+#include "scsi.h"
+
+int scsiintr(void);
+
+#define DPRINT if(debug)kprint
+
+enum {
+ Qdir, Qcmd, Qdata, Qdebug,
+};
+
+static Dirtab scsidir[]={
+ "cmd", {Qcmd}, 0, 0600,
+ "data", {Qdata}, 0, 0600,
+ "debug", {Qdebug}, 1, 0600,
+};
+
+#define NSCSI (sizeof scsidir/sizeof(Dirtab))
+
+static Scsi staticcmd; /* BUG */
+static uchar datablk[8192]; /* BUG */
+
+static int debugs[8];
+static int isscsi;
+static int ownid = 0x08|7; /* enable advanced features */
+
+static int
+scsigen1(Chan *c, long qid, Dir *dp)
+{
+ if (qid == CHDIR)
+ devdir(c, (Qid){qid,0}, ".", 0, 0500, dp);
+ else if (qid == 1)
+ devdir(c, (Qid){qid,0}, "id", 1, 0600, dp);
+ else if (qid&CHDIR) {
+ char name[2];
+ name[0] = '0'+((qid>>4)&7), name[1] = 0;
+ devdir(c, (Qid){qid,0}, name, 0, 0500, dp);
+ } else {
+ Dirtab *tab = &scsidir[(qid&7)-1];
+ devdir(c, (Qid){qid,0}, tab->name, tab->length, tab->perm, dp);
+ }
+ return 1;
+}
+
+static int
+scsigeno(Chan *c, Dirtab *tab, long ntab, long s, Dir *dp)
+{
+ return scsigen1(c, c->qid.path, dp);
+}
+
+static int
+scsigen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dp)
+{
+ if (c->qid.path == CHDIR) {
+ if (0<=s && s<=7)
+ return scsigen1(c, CHDIR|0x100|(s<<4), dp);
+ else if (s == 8)
+ return scsigen1(c, 1, dp);
+ else
+ return -1;
+ }
+ if (s >= NSCSI)
+ return -1;
+ return scsigen1(c, (c->qid.path&~CHDIR)+s+1, dp);
+}
+
+void
+scsireset(void)
+{
+ addportintr(scsiintr);
+}
+
+Chan *
+scsiattach(char *param)
+{
+ return devattach('S', param);
+}
+
+Chan *
+scsiclone(Chan *c, Chan *nc)
+{
+ return devclone(c, nc);
+}
+
+int
+scsiwalk(Chan *c, char *name)
+{
+ return devwalk(c, name, 0, 0, scsigen);
+}
+
+void
+scsistat(Chan *c, char *db)
+{
+ devstat(c, db, 0, 0, scsigen);
+}
+
+Chan *
+scsiopen(Chan *c, int omode)
+{
+ return devopen(c, omode, 0, 0, scsigeno);
+}
+
+void
+scsicreate(Chan *c, char *name, int omode, ulong perm)
+{
+ error(Eperm);
+}
+
+void
+scsiclose(Chan *c)
+{}
+
+long
+scsiread(Chan *c, char *a, long n)
+{
+ Scsi *cmd = &staticcmd;
+ if (n == 0)
+ return 0;
+ if(c->qid.path & CHDIR)
+ return devdirread(c, a, n, 0, 0, scsigen);
+ if(c->qid.path==1){
+ if(c->offset == 0){
+ *a = ownid;
+ n = 1;
+ }else
+ n = 0;
+ }else switch((int)(c->qid.path & 0xf)){
+ case Qcmd:
+ if (n < 4)
+ error(Ebadarg);
+ /*if(canqlock(cmd)){
+ qunlock(cmd);
+ error(Egreg);
+ }*/
+ n = 4;
+ *a++ = cmd->state>>8; *a++ = cmd->state;
+ *a++ = cmd->status>>8; *a = cmd->status;
+ /*qunlock(cmd);*/
+ break;
+ case Qdata:
+ if (n > sizeof datablk)
+ error(Ebadarg);
+ cmd->data.base = datablk;
+ cmd->data.lim = cmd->data.base + n;
+ cmd->data.ptr = cmd->data.base;
+ cmd->save = cmd->data.base;
+ scsiexec(cmd, 1);
+ n = cmd->data.ptr - cmd->data.base;
+ memcpy(a, cmd->data.base, n);
+ break;
+ case Qdebug:
+ if (c->offset == 0) {
+ n=1;
+ *a="01"[debugs[(c->qid.path>>4)&7]!=0];
+ } else
+ n = 0;
+ break;
+ default:
+ panic("scsiread");
+ }
+ return n;
+}
+
+long
+scsiwrite(Chan *c, char *a, long n)
+{
+ Scsi *cmd = &staticcmd;
+ if(c->qid.path==1 && n>0){
+ if(c->offset == 0){
+ n = 1;
+ ownid=*a;
+ scsiinit();
+ }else
+ n = 0;
+ }else switch ((int)c->qid.path & 0xf){
+ case Qcmd:
+ if (n < 6 || n > sizeof cmd->cmdblk)
+ error(Ebadarg);
+ /*qlock(cmd);*/
+ cmd->cmd.base = cmd->cmdblk;
+ memcpy(cmd->cmd.base, a, n);
+ cmd->cmd.lim = cmd->cmd.base + n;
+ cmd->cmd.ptr = cmd->cmd.base;
+ cmd->target = (c->qid.path>>4)&7;
+ cmd->lun = (a[1]>>5)&7;
+ cmd->state = 0;
+ cmd->status = 0xFFFF;
+ break;
+ case Qdata:
+ if (n > sizeof datablk)
+ error(Ebadarg);
+ cmd->data.base = datablk;
+ cmd->data.lim = cmd->data.base + n;
+ cmd->data.ptr = cmd->data.base;
+ cmd->save = cmd->data.base;
+ memcpy(cmd->data.base, a, n);
+ scsiexec(cmd, 0);
+ n = cmd->data.ptr - cmd->data.base;
+ break;
+ case Qdebug:
+ if (c->offset == 0) {
+ debugs[(c->qid.path>>4)&7] = (*a=='1');
+ n = 1;
+ } else
+ n = 0;
+ break;
+ default:
+ panic("scsiwrite");
+ }
+ return n;
+}
+
+void
+scsiremove(Chan *c)
+{
+ error(Eperm);
+}
+
+void
+scsiwstat(Chan *c, char *dp)
+{
+ error(Eperm);
+}
+
+void
+scsicmd(Scsi *cmd, int dev, int cmdbyte, uchar *buf, long size)
+{
+ qlock(cmd);
+ cmd->target = dev>>3;
+ cmd->lun = dev&7;
+ cmd->cmd.base = cmd->cmdblk;
+ cmd->data.base = buf;
+ cmd->cmd.ptr = cmd->cmd.base;
+ memset(cmd->cmdblk, 0, sizeof cmd->cmdblk);
+ cmd->cmdblk[0] = cmdbyte;
+ switch (cmdbyte>>5) {
+ case 0:
+ cmd->cmd.lim = &cmd->cmdblk[6]; break;
+ case 1:
+ cmd->cmd.lim = &cmd->cmdblk[10]; break;
+ default:
+ cmd->cmd.lim = &cmd->cmdblk[12]; break;
+ }
+ switch (cmdbyte) {
+ case 0x00: /* test unit ready */
+ break;
+ case 0x03: /* read sense data */
+ cmd->cmdblk[4] = size;
+ break;
+ case 0x25: /* read capacity */
+ break;
+ }
+ cmd->data.lim = cmd->data.base + size;
+ cmd->data.ptr = cmd->data.base;
+ cmd->save = cmd->data.base;
+}
+
+int
+scsiready(int dev)
+{
+ static Scsi cmd;
+ int status;
+ scsicmd(&cmd, dev, 0x00, 0, 0);
+ status = scsiexec(&cmd, 0);
+ qunlock(&cmd);
+ if ((status&0xff00) != 0x6000)
+ error(Eio);
+ return status&0xff;
+}
+
+int
+scsisense(int dev, uchar *p)
+{
+ static Scsi cmd;
+ static uchar buf[18];
+ int status;
+ scsicmd(&cmd, dev, 0x03, buf, sizeof buf);
+ status = scsiexec(&cmd, 1);
+ memcpy(p, buf, sizeof buf);
+ qunlock(&cmd);
+ if ((status&0xff00) != 0x6000)
+ error(Eio);
+ return status&0xff;
+}
+
+int
+scsicap(int dev, uchar *p)
+{
+ static Scsi cmd;
+ static uchar buf[8];
+ int status;
+ scsicmd(&cmd, dev, 0x25, buf, sizeof buf);
+ status = scsiexec(&cmd, 1);
+ memcpy(p, buf, sizeof buf);
+ qunlock(&cmd);
+ if ((status&0xff00) != 0x6000)
+ error(Eio);
+ return status&0xff;
+}
+
+typedef struct Scsictl {
+ uchar asr;
+ uchar data;
+ uchar stat;
+ uchar dma;
+} Scsictl;
+
+#define Scsiaddr 48
+#define DEV ((Scsictl *)&PORT[Scsiaddr])
+
+static long poot;
+#define WAIT (poot=0, (poot==0?0:poot))
+
+#define PUT(a,d) (DEV->asr=(a), WAIT, DEV->data=(d))
+#define GET(a) (DEV->asr=(a), WAIT, DEV->data)
+
+enum Int_status {
+ Inten = 0x01, Scsirst = 0x02,
+ INTRQ = 0x01, DMA = 0x02,
+};
+
+enum SBIC_regs {
+ Own_id=0x00, Control=0x01, CDB=0x03, Target_LUN=0x0f,
+ Cmd_phase=0x10, Tc_hi=0x12,
+ Dest_id=0x15, Src_id=0x16, SCSI_Status=0x17,
+ Cmd=0x18, Data=0x19,
+};
+
+enum Commands {
+ Reset = 0x00,
+ Assert_ATN = 0x02,
+ Negate_ACK = 0x03,
+ Select_with_ATN = 0x06,
+ Select_with_ATN_and_Xfr = 0x08,
+ Select_and_Xfr = 0x09,
+ Transfer_Info = 0x20,
+ SBT = 0x80, /* modifier for single-byte transfer */
+};
+
+enum Aux_status {
+ INT=0x80, LCI=0x40, BSY=0x20, CIP=0x10,
+ PE=0x02, DBR=0x01,
+};
+
+static QLock scsilock;
+static Rendez scsirendez;
+static uchar *datap;
+static long debug, scsirflag, scsibusy, scsiinservice;
+
+static void
+nop(void)
+{}
+
+static int
+scsidone(void *arg)
+{
+ return (scsibusy == 0);
+}
+
+int
+scsiexec(Scsi *p, int rflag)
+{
+ long n;
+ debug = debugs[p->target&7];
+ DPRINT("scsi %d.%d ", p->target, p->lun);
+ qlock(&scsilock);
+ if(waserror()){
+ qunlock(&scsilock);
+ nexterror();
+ }
+ scsirflag = rflag;
+ datap = p->data.base;
+ if ((ownid & 0x08) && rflag)
+ PUT(Dest_id, 0x40|p->target);
+ else
+ PUT(Dest_id, p->target);
+ PUT(Target_LUN, p->lun);
+ n = p->data.lim - p->data.base;
+ PUT(Tc_hi, n>>16);
+ DEV->data = n>>8;
+ DEV->data = n;
+ if (ownid & 0x08) {
+ n = p->cmd.lim - p->cmd.ptr;
+ DPRINT("len=%d ", n);
+ PUT(Own_id, n);
+ }
+ PUT(CDB, *(p->cmd.ptr)++);
+ while (p->cmd.ptr < p->cmd.lim)
+ DEV->data = *(p->cmd.ptr)++;
+ scsibusy = 1;
+ PUT(Cmd, Select_and_Xfr);
+ DPRINT("S<");
+ sleep(&scsirendez, scsidone, 0);
+ DPRINT(">");
+ p->data.ptr = datap;
+ p->status = GET(Target_LUN);
+ p->status |= DEV->data<<8;
+ poperror();
+ qunlock(&scsilock);
+ debug = 0;
+ return p->status;
+}
+
+void
+scsirun(void)
+{
+ wakeup(&scsirendez);
+ scsibusy = 0;
+}
+
+void
+scsiinit(void)
+{
+ isscsi = portprobe("scsi", -1, Scsiaddr, -1, 0L);
+ if (isscsi >= 0) {
+ DEV->stat = Scsirst;
+ WAIT; nop(); WAIT;
+ DEV->stat = Inten;
+ while (DEV->stat & (INTRQ|DMA))
+ nop();
+ ownid &= 0x0f; /* possibly advanced features */
+ ownid |= 0x80; /* 16MHz */
+ PUT(Own_id, ownid);
+ PUT(Cmd, Reset);
+ }
+}
+
+void
+scsireset0(void)
+{
+ PUT(Control, 0x29); /* burst DMA, halt on parity error */
+ PUT(Control+1, 0xff); /* timeout */
+ PUT(Src_id, 0x80); /* enable reselection */
+ scsirun();
+ /*qunlock(&scsilock);*/
+}
+
+int
+scsiintr(void)
+{
+ int status, s;
+ if (isscsi < 0 || scsiinservice
+ || !((status = DEV->stat) & (DMA|INTRQ)))
+ return 0;
+ DEV->stat = 0;
+ scsiinservice = 1;
+ s = spl1();
+ DPRINT("i%x ", status);
+ do {
+ if (status & DMA)
+ scsidmaintr();
+ if (status & INTRQ)
+ scsictrlintr();
+ } while ((status = DEV->stat) & (DMA|INTRQ));
+ splx(s);
+ scsiinservice = 0;
+ DEV->stat = Inten;
+ return 1;
+}
+
+void
+scsidmaintr(void)
+{
+ uchar *p=0;
+/*
+ * if (scsirflag) {
+ * unsigned char *p;
+ * DPRINT("R", p=datap);
+ * do
+ * *datap++ = DEV->dma;
+ * while (DEV->stat & DMA);
+ * DPRINT("%d ", datap-p);
+ * } else {
+ * unsigned char *p;
+ * DPRINT("W", p=datap);
+ * do
+ * DEV->dma = *datap++;
+ * while (DEV->stat & DMA);
+ * DPRINT("%d ", datap-p);
+ * }
+ */
+ if (scsirflag) {
+ DPRINT("R", p=datap);
+ datap = scsirecv(datap);
+ DPRINT("%d ", datap-p);
+ } else {
+ DPRINT("X", p=datap);
+ datap = scsixmit(datap);
+ DPRINT("%d ", datap-p);
+ }
+}
+
+void
+scsictrlintr(void)
+{
+ int status;
+ status = GET(SCSI_Status);
+ DPRINT("I%2.2x ", status);
+ switch(status){
+ case 0x00: /* reset by command or power-up */
+ case 0x01: /* reset by command or power-up */
+ scsireset0();
+ break;
+ case 0x21: /* Save Data Pointers message received */
+ break;
+ case 0x16: /* select-and-transfer completed */
+ case 0x42: /* timeout during select */
+ scsirun();
+ break;
+ case 0x4b: /* unexpected status phase */
+ PUT(Tc_hi, 0);
+ DEV->data = 0;
+ DEV->data = 0;
+ PUT(Cmd_phase, 0x46);
+ PUT(Cmd, Select_and_Xfr);
+ break;
+ default:
+ kprint("scsintr 0x%ux\n", status);
+ DEV->asr = Target_LUN;
+ kprint("lun/status 0x%ux\n", DEV->data);
+ kprint("phase 0x%ux\n", DEV->data);
+ switch (status&0xf0) {
+ case 0x00:
+ case 0x10:
+ case 0x20:
+ case 0x40:
+ case 0x80:
+ if (status & 0x08) {
+ kprint("count 0x%ux", GET(Tc_hi));
+ kprint(" 0x%ux", DEV->data);
+ kprint(" 0x%ux\n", DEV->data);
+ }
+ scsirun();
+ break;
+ default:
+ panic("scsi status 0x%2.2ux", status);
+ }
+ }
+}
A port/devwren.c => port/devwren.c +254 -0
@@ 0,0 1,254 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "errno.h"
+#include "devtab.h"
+#include "io.h"
+
+#include "scsi.h"
+
+enum {
+ Qdir, Qdata, Qstruct,
+};
+
+static Dirtab wrendir[]={
+ "data", {Qdata}, 0, 0600,
+ "struct", {Qstruct}, 8, 0400,
+};
+
+#define NWREN (sizeof wrendir/sizeof(Dirtab))
+
+static long maxblock[64];
+static long blocksize[64];
+
+static Scsi staticcmd; /* BUG */
+static uchar datablk[4*512]; /* BUG */
+
+/*
+ * accepts [0-7].[0-7], or abbreviation
+ */
+static int
+wrendev(char *p)
+{
+ int dev = 0;
+ if (p==0 || p[0]==0)
+ goto out;
+ if (p[0]<'0' || p[0]>'7')
+ goto cant;
+ dev = (p[0]-'0')<<3;
+ if (p[1]==0)
+ goto out;
+ if (p[1]!='.')
+ goto cant;
+ if (p[2]==0)
+ goto out;
+ if (p[2]<'0' || p[2]>'7')
+ goto cant;
+ dev |= p[2]-'0';
+ if (p[3]!=0)
+ goto cant;
+out:
+ return dev;
+cant:
+ error(Ebadarg);
+}
+
+static int
+wrengen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dp)
+{
+ long l;
+ if(tab==0 || s>=ntab)
+ return -1;
+ tab+=s;
+ if (tab->qid.path==Qdata && 0<=c->dev && c->dev<64)
+ l = maxblock[c->dev]*blocksize[c->dev];
+ else
+ l = tab->length;
+ devdir(c, tab->qid, tab->name, l, tab->perm, dp);
+ return 1;
+}
+
+void
+wrenreset(void)
+{}
+
+void
+wreninit(void)
+{
+ Scsi *cmd = &staticcmd;
+ cmd->cmd.base = cmd->cmdblk;
+ cmd->data.base = datablk;
+}
+
+/*
+ * param is #r<target>.<lun>
+ */
+Chan *
+wrenattach(char *param)
+{
+ uchar buf[32];
+ int dev;
+ Chan *c;
+ dev = wrendev(param);
+ scsiready(dev);
+ scsisense(dev, buf);
+ scsicap(dev, buf);
+ c = devattach('r', param);
+ c->dev = dev;
+ maxblock[dev] = BGLONG(&buf[0]);
+ blocksize[dev] = BGLONG(&buf[4]);
+ return c;
+}
+
+Chan *
+wrenclone(Chan *c, Chan *nc)
+{
+ return devclone(c, nc);
+}
+
+int
+wrenwalk(Chan *c, char *name)
+{
+ return devwalk(c, name, wrendir, NWREN, wrengen);
+}
+
+void
+wrenstat(Chan *c, char *db)
+{
+ devstat(c, db, wrendir, NWREN, wrengen);
+}
+
+Chan *
+wrenopen(Chan *c, int omode)
+{
+ if (c->qid.path == Qdata && scsiready(c->dev) != 0)
+ error(Eio);
+ return devopen(c, omode, wrendir, NWREN, wrengen);
+}
+
+void
+wrencreate(Chan *c, char *name, int omode, ulong perm)
+{
+ error(Eperm);
+}
+
+void
+wrenclose(Chan *c)
+{}
+
+#define PSHORT(p, v) ((p)[0]=(v), (p)[1]=((v)>>8))
+#define PLONG(p, v) (PSHORT(p, (v)), PSHORT(p+2, (v)>>16))
+long
+wrenread(Chan *c, char *a, long n)
+{
+ Scsi *cmd = &staticcmd;
+ unsigned long lbn;
+ if (n == 0)
+ return 0;
+ switch ((int)(c->qid.path & ~CHDIR)) {
+ case Qdir:
+ return devdirread(c, a, n, wrendir, NWREN, wrengen);
+ case Qdata:
+ if (n % blocksize[c->dev] || c->offset % blocksize[c->dev])
+ error(Ebadarg);
+ lbn = c->offset/blocksize[c->dev];
+ if (lbn >= maxblock[c->dev])
+ error(Ebadarg);
+ if (n > sizeof datablk)
+ n = sizeof datablk;
+ qlock(cmd);
+ if (waserror()) {
+ qunlock(cmd);
+ nexterror();
+ }
+ cmd->target = c->dev>>3;
+ cmd->lun = c->dev&7;
+ cmd->cmd.ptr = cmd->cmd.base;
+ cmd->cmdblk[0] = 0x08;
+ cmd->cmdblk[1] = lbn>>16;
+ cmd->cmdblk[2] = lbn>>8;
+ cmd->cmdblk[3] = lbn;
+ cmd->cmdblk[4] = n/blocksize[c->dev];
+ cmd->cmdblk[5] = 0x00;
+ cmd->cmd.lim = &cmd->cmdblk[6];
+ cmd->data.lim = cmd->data.base + n;
+ cmd->data.ptr = cmd->data.base;
+ cmd->save = cmd->data.base;
+ scsiexec(cmd, 1);
+ n = cmd->data.ptr - cmd->data.base;
+ memcpy(a, cmd->data.base, n);
+ qunlock(cmd);
+ break;
+ case Qstruct:
+ if (n < 8)
+ error(Ebadarg);
+ if (c->offset >= 8)
+ return 0;
+ n = 8;
+ PLONG((uchar *)&a[0], maxblock[c->dev]);
+ PLONG((uchar *)&a[4], blocksize[c->dev]);
+ break;
+ default:
+ panic("wrenread");
+ }
+ return n;
+}
+
+long
+wrenwrite(Chan *c, char *a, long n)
+{
+ Scsi *cmd = &staticcmd;
+ unsigned long lbn;
+ if (n == 0)
+ return 0;
+ switch ((int)(c->qid.path & ~CHDIR)) {
+ case Qdata:
+ if (n % blocksize[c->dev] || c->offset % blocksize[c->dev])
+ error(Ebadarg);
+ lbn = c->offset/blocksize[c->dev];
+ if (lbn >= maxblock[c->dev])
+ error(Ebadarg);
+ if (n > sizeof datablk)
+ n = sizeof datablk;
+ qlock(cmd);
+ if (waserror()) {
+ qunlock(cmd);
+ nexterror();
+ }
+ cmd->target = c->dev>>3;
+ cmd->lun = c->dev&7;
+ cmd->cmd.ptr = cmd->cmd.base;
+ cmd->cmdblk[0] = 0x0a;
+ cmd->cmdblk[1] = lbn>>16;
+ cmd->cmdblk[2] = lbn>>8;
+ cmd->cmdblk[3] = lbn;
+ cmd->cmdblk[4] = n/blocksize[c->dev];
+ cmd->cmdblk[5] = 0x00;
+ cmd->cmd.lim = &cmd->cmdblk[6];
+ cmd->data.lim = cmd->data.base + n;
+ cmd->data.ptr = cmd->data.base;
+ cmd->save = cmd->data.base;
+ memcpy(cmd->data.base, a, n);
+ scsiexec(cmd, 0);
+ n = cmd->data.ptr - cmd->data.base;
+ qunlock(cmd);
+ break;
+ default:
+ panic("wrenwrite");
+ }
+ return n;
+}
+
+void
+wrenremove(Chan *c)
+{
+ error(Eperm);
+}
+
+void
+wrenwstat(Chan *c, char *dp)
+{
+ error(Eperm);
+}
M port/fault.c => port/fault.c +1 -1
@@ 21,7 21,7 @@ fault(ulong addr, int read)
s = seg(u->p, addr);
if(s == 0){
- if(addr>USTKTOP)
+ if(addr > USTKTOP)
return -1;
s = &u->p->seg[SSEG];
if(s->o==0 || addr<s->maxva-USTACKSIZE || addr>=s->maxva)
M port/page.c => port/page.c +2 -2
@@ 85,7 85,7 @@ audit(char *s)
do;while(here);
here=1;
p = palloc.head;
- nf=nb=0;
+ nf = nb = 0;
while(p){
print("%lux %lux %d\n", p->pa, p->va, p->ref);
if(p->o){
@@ 208,7 208,7 @@ loop:
goto loop;
out:
if(p->o){
- print("page in use %lux %lux %lux\n", p->va, p->o, origalloc.arena);
+ print("page in use %lux %lux %lux %lux\n", p, p->va, p->o, origalloc.arena);
print("%c %lux %lux, %d %d %d\n", devchar[p->o->type], p->o->va, p->o->qid, p->o->flag, p->o->nproc, p->o->npte);
panic("shit");
}
M port/proc.c => port/proc.c +6 -4
@@ 412,8 412,13 @@ pexit(char *s, int freemem)
Proc *p, *c, *k, *l;
int n;
Chan *ch;
+ char msg[ERRLEN];
ulong *up, *ucp, *wp;
+ if(s) /* squirrel away; we'll lose our address space */
+ strcpy(msg, s);
+ else
+ msg[0] = 0;
c = u->p;
mypid = c->pid;
if(freemem){
@@ 450,10 455,7 @@ pexit(char *s, int freemem)
qlock(&p->wait);
lock(&p->wait.queue);
if(p->pid==c->parentpid && !p->exiting){
- if(s)
- strcpy(p->waitmsg.msg, s);
- else
- p->waitmsg.msg[0] = 0;
+ memcpy(p->waitmsg.msg, msg, ERRLEN);
p->waitmsg.pid = mypid;
wp = &p->waitmsg.time[TUser];
up = &c->time[TUser];
M ss/dat.h => ss/dat.h +3 -2
@@ 228,9 228,9 @@ struct Mach
void (*intr)(ulong, ulong); /* !!Compatibility with mips!! */
ulong cause; /* ... */
ulong pc; /* ... */
- char pidhere[NCONTEXT]; /* is this tlbpid possibly in this mmu? */
+ char pidhere[NTLBPID]; /* is this tlbpid possibly in this mmu? */
int lastpid; /* last pid allocated on this machine */
- Proc *pidproc[NCONTEXT]; /* process that owns this pid on this mach */
+ Proc *pidproc[NTLBPID]; /* process that owns this pid on this mach */
int stack[1];
};
@@ 773,6 773,7 @@ extern FPsave initfp;
extern Mach mach0;
extern char user[NAMELEN];
extern char *errstrtab[];
+extern uchar *intrreg;
extern void (*kprofp)(ulong);
M ss/faultsparc.c => ss/faultsparc.c +32 -1
@@ 6,6 6,12 @@
#include "ureg.h"
#include "errno.h"
+ck(char *s)
+{
+ if(u->p->seg[SSEG].o->flag == 0)
+ panic(s);
+}
+
void
faultsparc(Ureg *ur)
{
@@ 28,7 34,8 @@ faultsparc(Ureg *ur)
return;
}
spllo();
-/* print("fault: %s pc=0x%lux addr %lux %d\n", excname(tbr), ur->pc, addr, read); /**/
+print("fault: %s pc=0x%lux addr %lux %d\n", excname(tbr), ur->pc, addr, read); /**/
+ck("faultsparc");
if(u == 0){
dumpregs(ur);
panic("fault u==0 pc=%lux", ur->pc);
@@ 41,6 48,11 @@ faultsparc(Ureg *ur)
user = !(ur->psr&PSRPSUPER);
if(fault(addr, read) < 0){
+print("death read %lux %d sizes %lux-%lux %lux-%lux, %lux-%lux %lux-%lux\n", addr, read,
+u->p->seg[SSEG].minva, u->p->seg[SSEG].maxva,
+u->p->seg[TSEG].minva, u->p->seg[TSEG].maxva,
+u->p->seg[DSEG].minva, u->p->seg[DSEG].maxva,
+u->p->seg[BSEG].minva, u->p->seg[BSEG].maxva);
if(user){
pprint("user %s error addr=0x%lux\n", read? "read" : "write", badvaddr);
pprint("psr=0x%lux pc=0x%lux sp=0x%lux\n", ur->psr, ur->pc, ur->sp);
@@ 52,6 64,25 @@ faultsparc(Ureg *ur)
exit();
}
u->p->insyscall = insyscall;
+ck("faultsparc return");
+}
+
+void
+faultasync(Ureg *ur)
+{
+ int user;
+
+ print("interrupt 15 ASER %lux ASEVAR %lux SER %lux\n", getw2(ASER), getw2(ASEVAR), getw2(SER));
+ dumpregs(ur);
+ /*
+ * Clear interrupt by toggling low bit of interrupt register
+ */
+ *intrreg &= ~1;
+ *intrreg |= 1;
+ user = !(ur->psr&PSRPSUPER);
+ if(user)
+ pexit("Suicide", 0);
+ panic("interrupt 15");
}
/*
M ss/fns.h => ss/fns.h +4 -1
@@ 58,7 58,7 @@ char *excname(ulong);
void execpc(ulong);
void exit(void);
int fault(ulong, int);
-void fault68020(Ureg*, FFrame*);
+void faultasync(Ureg*);
void fdclose(int);
Chan *fdtochan(int, int);
void filsys(Chan*, char*, long);
@@ 91,6 91,7 @@ void growpte(Orig*, ulong);
void *ialloc(ulong, int);
int incref(Ref*);
void insert(List**, List*, List*);
+void intrinit(void);
void invalidateu(void);
void isdir(Chan*);
void kbdchar(int);
@@ 168,7 169,9 @@ void putw2(ulong, ulong);
void putw4(ulong, ulong);
void putwC(ulong, ulong);
void putwD(ulong, ulong);
+void putwD16(ulong, ulong);
void putwE(ulong, ulong);
+void putwE16(ulong, ulong);
ulong pwait(Waitmsg*);
int readnum(ulong, char*, ulong, ulong, int);
void ready(Proc*);
M ss/io.h => ss/io.h +1 -0
@@ 7,6 7,7 @@ typedef struct Duart Duart;
#define KMDUART 0xF0000000 /* keyboard A, mouse B */
#define ETHER 0xF8C00000 /* RDP, RAP */
#define EEPROM 0xF2000000
+#define INTRREG 0xF5000000 /* interrupt register, IO space */
#define ENAB 0x40000000 /* ASI 2, System Enable Register */
#define ENABCACHE 0x10
M ss/l.s => ss/l.s +79 -7
@@ 1,6 1,6 @@
#include "mem.h"
-#define SYSPSR (PSREF|SPL(0x0)|PSRSUPER)
+#define SYSPSR (SPL(0xF)|PSRSUPER)
TEXT start(SB), $-4
@@ 33,13 33,11 @@ TEXT getpsr(SB), $0
MOVW PSR, R7
RETURN
-/*
-TEXT swap1_please(SB), $0
+TEXT swap1(SB), $0
MOVW keyaddr+0(FP), R8
- LDSTUB (R8), R7
+ TAS (R8), R7
RETURN
-*/
TEXT swap1_should_work(SB), $0
@@ 48,7 46,7 @@ TEXT swap1_should_work(SB), $0
SWAP (R8), R7
RETURN
-TEXT swap1(SB), $0
+TEXT swap1x(SB), $0
MOVW keyaddr+0(FP), R8
MOVW PSR, R9
@@ 100,7 98,7 @@ TEXT splx(SB), $0
TEXT touser(SB), $-4
- MOVW $SYSPSR, R7 /* BUG SPL(0xF) for now */
+ MOVW $SYSPSR, R7
MOVW R7, PSR
OR R0, R0
@@ 400,6 398,43 @@ TEXT putwD(SB), $0
MOVW R8, (R7, 0xD)
RETURN
+TEXT putwD16(SB), $0
+
+ MOVW 0(FP), R7
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ RETURN
+
TEXT putwE(SB), $0
MOVW 0(FP), R7
@@ 407,6 442,43 @@ TEXT putwE(SB), $0
MOVW R8, (R7, 0xE)
RETURN
+TEXT putwE16(SB), $0
+
+ MOVW 0(FP), R7
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ RETURN
+
TEXT putsegm(SB), $0
MOVW 0(FP), R7
M ss/main.c => ss/main.c +16 -4
@@ 15,6 15,8 @@ char bootline[64];
char bootserver[64];
char bootdevice[64];
+uchar *intrreg;
+
void unloadboot(void);
#ifdef asdf
@@ 68,6 70,7 @@ main(void)
trapinit();
kmapinit();
cacheinit();
+ intrinit();
procinit0();
pgrpinit();
chaninit();
@@ 83,6 86,15 @@ main(void)
}
void
+intrinit(void)
+{
+ KMap *k;
+
+ k = kmappa(INTRREG, PTEIO);
+ intrreg = (uchar*)k->va;
+}
+
+void
reset(void)
{
delay(100);
@@ 162,7 174,7 @@ userinit(void)
/*
* Kernel Stack
*/
- p->sched.pc = (ulong)init0;
+ p->sched.pc = (((ulong)init0) - 8); /* 8 because of RETURN in gotolabel */
p->sched.sp = USERADDR+BY2PG-20; /* BUG */
p->upage = newpage(0, 0, USERADDR|(p->pid&0xFFFF));
@@ 289,7 301,7 @@ confinit(void)
conf.nmach = 1;
if(conf.nmach > MAXMACH)
panic("confinit");
- conf.npage0 = (8*1024*1024)/BY2PG; /* BUG */
+ conf.npage0 = (6*1024*1024)/BY2PG; /* BUG */
conf.npage = conf.npage0;
conf.base0 = 0;
conf.npage = conf.npage0+conf.npage1;
@@ 297,8 309,8 @@ confinit(void)
mul = 2;
conf.nproc = 50*mul;
conf.npgrp = 12*mul;
- conf.npte = 700*mul;
- conf.nmod = 400*mul;
+ conf.npte = 1400*mul;
+ conf.nmod = 800*mul;
conf.nalarm = 1000;
conf.norig = 150*mul;
conf.nchan = 200*mul;
M ss/mem.h => ss/mem.h +4 -7
@@ 58,7 58,7 @@
#define NPMEG (1<<12)
#define BY2SEGM (1<<18)
#define PG2SEGM (1<<6)
-#define NTLBPID (NCONTEXT+1)
+#define NTLBPID (1+NCONTEXT) /* TLBPID 0 is unallocated */
#define NCONTEXT 8
#define CONTEXT 0x30000000 /* in ASI 2 */
@@ 77,9 77,7 @@
#define IOPMEG0 (SCREENPMEG-NIOSEGM)
#define IOSEGM ROMEND
#define IOEND SCREENSEGM
-#define LANCESEGM (16*1024*1024-BY2SEGM)
-#define LANCEPMEG (IOSEGM0-1)
-#define TOPPMEG LANCEPMEG
+#define TOPPMEG IOPMEG0
/*
* MMU entries
@@ 97,15 95,14 @@
#define INVALIDPTE 0
#define PPN(pa) ((pa>>12)&0xFFFF)
-#define KMAP ((unsigned long *)0xD0000000)
-#define UMAP ((unsigned long *)0x50000000)
-
/*
* Weird addresses in various ASI's
*/
#define CACHETAGS 0x80000000 /* ASI 2 */
#define SER 0x60000000 /* ASI 2 */
#define SEVAR 0x60000004 /* ASI 2 */
+#define ASER 0x60000008 /* ASI 2 */
+#define ASEVAR 0x6000000C /* ASI 2 */
/*
* Virtual addresses
M ss/mmu.c => ss/mmu.c +79 -36
@@ 14,12 14,15 @@ struct
KMap arena[(IOEND-IOSEGM)/BY2PG];
}kmapalloc;
+#define NKLUDGE 8
+
/*
* On SPARC, tlbpid i == context i-1 so that 0 means unallocated
*/
int newpid(Proc*);
void purgepid(int);
+int pidtime[NTLBPID]; /* should be per m */
/*
* Called splhi, not in Running state
@@ 36,14 39,12 @@ mapstack(Proc *p)
p->pidonmach[m->machno] = tp;
}
if(p->upage->va != (USERADDR|(p->pid&0xFFFF)))
- panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va);
- /* don't set m->pidhere[*tp] because we're only writing U entry */
+ panic("mapstack %s %d %lux 0x%lux 0x%lux", p->text, p->pid, p->upage, p->upage->pa, p->upage->va);
tlbphys = PPN(p->upage->pa)|PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM;
putcontext(tp-1);
/*
- * putw4(USERADDR, tlbphys) might be good enough but
- * there is that fuss in pexit/pwait() copying between
- * u areas and that might surprise any cache entries
+ * shouldn't need putpmeg because nothing has been mapped at
+ * USERADDR in this context except this page. however, it crashes.
*/
putpmeg(USERADDR, tlbphys);
u = (User*)USERADDR;
@@ 56,28 57,34 @@ int
newpid(Proc *p)
{
int i, j, k;
+ ulong t;
Proc *sp;
- i = m->lastpid+1;
- if(i >= NCONTEXT+1)
- i = 1;
+ t = ~0;
+ i = 1+((m->ticks)&(NCONTEXT-1)); /* random guess */
+ for(j=1; j<NTLBPID; j++)
+ if(pidtime[j] < t){
+ i = j;
+ t = pidtime[j];
+ }
+
sp = m->pidproc[i];
if(sp){
sp->pidonmach[m->machno] = 0;
purgepid(i);
}
+ pidtime[i] = m->ticks;
m->pidproc[i] = p;
m->lastpid = i;
putcontext(i-1);
-/* print("new pid %d\n", i); /**/
/*
- * kludge: each context is allowed 5 pmegs, four for text & data and one for stack
+ * kludge: each context is allowed NKLUDGE pmegs, NKLUDGE-1 for text & data and 1 for stack
*/
- for(j=0; j<4; j++)
- putsegm(UZERO, kmapalloc.lowpmeg+(2*i)+j);
- putsegm(TSTKTOP-BY2SEGM, kmapalloc.lowpmeg+(2*i)+4);
+ for(j=0; j<NKLUDGE-1; j++)
+ putsegm(UZERO+j*BY2SEGM, kmapalloc.lowpmeg+(NKLUDGE*(i-1))+j);
+ putsegm(TSTKTOP-BY2SEGM, kmapalloc.lowpmeg+(NKLUDGE*(i-1))+(NKLUDGE-1));
for(j=0; j<PG2SEGM; j++){
- for(k=0; k<4; k++)
+ for(k=0; k<NKLUDGE-1; k++)
putpmeg(UZERO+k*BY2SEGM+j*BY2PG, INVALIDPTE);
putpmeg((TSTKTOP-BY2SEGM)+j*BY2PG, INVALIDPTE);
}
@@ 87,26 94,30 @@ newpid(Proc *p)
void
putcontext(int c)
{
- m->pidhere[c] = 1;
+ m->pidhere[c+1] = 1;
putcxreg(c);
}
void
-purgepid(int pid)
+flushcontext(void)
{
- int i, rpid;
+ int i;
+
+ /*
+ * Clear context from cache
+ */
+ for(i=0; i<0x1000; i+=16)
+ putwE16((i<<4), 0);
+}
+void
+purgepid(int pid)
+{
if(m->pidhere[pid] == 0)
return;
-/* print("purge pid %d\n", pid);/**/
memset(m->pidhere, 0, sizeof m->pidhere);
putcontext(pid-1);
- /*
- * Clear context from cache
- */
- for(i=0; i<0x1000; i++)
- putwE((i<<4), 0);
-/* print("purge done\n");/**/
+ flushcontext();
}
@@ 129,7 140,6 @@ mmuinit(void)
pte = PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM;
for(i=0; i<conf.maxialloc/BY2PG; i++)
putpmeg(KZERO+i*BY2PG, pte+i);
-
/*
* Create invalid pmeg; use highest segment
@@ 178,10 188,6 @@ mmuinit(void)
for(i=0; i<PG2SEGM; i++)
putpmeg(IOSEGM0+j*BY2SEGM+i*BY2PG, INVALIDPTE);
}
- /*
- * Lance
- */
- putsegm(LANCESEGM, LANCEPMEG);
}
putcontext(0);
}
@@ 202,8 208,10 @@ putmmu(ulong tlbvirt, ulong tlbphys)
/*
* kludge part 2: make sure we've got a valid segment
*/
- if(tlbvirt>=TSTKTOP || (UZERO+4*BY2SEGM<=tlbvirt && tlbvirt<(TSTKTOP-BY2SEGM)))
- panic("putmmu %lux", tlbvirt);
+ if(tlbvirt>=TSTKTOP || (UZERO+(NKLUDGE-1)*BY2SEGM<=tlbvirt && tlbvirt<(TSTKTOP-BY2SEGM))){
+ pprint("putmmu %lux", tlbvirt);
+ pexit("Suicide", 0);
+ }
putpmeg(tlbvirt, tlbphys);
spllo();
}
@@ 219,8 227,8 @@ putpmeg(ulong virt, ulong phys)
/*
* Flush old entries from cache
*/
- for(i=0; i<0x100; i++)
- putwD(virt+(i<<4), 0);
+ for(i=0; i<0x100; i+=16)
+ putwD16(virt+(i<<4), 0);
if(u && u->p)
m->pidhere[u->p->pidonmach[m->machno]] = 1; /* UGH! */
putw4(virt, phys);
@@ 229,7 237,13 @@ putpmeg(ulong virt, ulong phys)
void
flushmmu(void)
{
+ int tp;
+
splhi();
+ flushcontext();
+ tp = u->p->pidonmach[m->machno];
+ if(tp)
+ pidtime[tp] = 0;
/* easiest is to forget what pid we had.... */
memset(u->p->pidonmach, 0, sizeof u->p->pidonmach);
/* ....then get a new one by trying to map our stack */
@@ 240,14 254,19 @@ flushmmu(void)
void
cacheinit(void)
{
- int i;
+ int c, i;
/*
* Initialize cache by clearing the valid bit
* (along with the others) in all cache entries
*/
- for(i=0; i<0x1000; i++)
- putw2(CACHETAGS+(i<<4), 0);
+ for(c=0; c<NCONTEXT; c++){ /* necessary? */
+ putcontext(c);
+ for(i=0; i<0x1000; i++)
+ putw2(CACHETAGS+(i<<4), 0);
+ }
+ putcontext(0);
+
/*
* Turn cache on
*/
@@ 260,6 279,7 @@ kmapinit(void)
KMap *k;
int i;
+print("low pmeg %d high pmeg %d\n", kmapalloc.lowpmeg, TOPPMEG);
kmapalloc.free = 0;
k = kmapalloc.arena;
for(i=0; i<(IOEND-IOSEGM)/BY2PG; i++,k++){
@@ 272,6 292,7 @@ KMap*
kmappa(ulong pa, ulong flag)
{
KMap *k;
+ ulong s;
lock(&kmapalloc);
k = kmapalloc.free;
@@ 287,7 308,29 @@ kmappa(ulong pa, ulong flag)
* Must avoid having the same entry in the cache twice, so
* must use NOCACHE or else extreme cleverness elsewhere.
*/
+ s = splhi();
+#ifdef stupid
+{
+ int i, c, d;
+
+ c = u->p->pidonmach[m->machno];
+ /*
+ * Flush old entries from cache
+ */
+ for(d=0; d<NCONTEXT; d++){
+ putcontext(d);
+ for(i=0; i<0x100; i+=16)
+ putwD16(k->va+(i<<4), 0);
+ }
+ putcontext(c-1);
+ if(u && u->p)
+ m->pidhere[c] = 1; /* UGH! */
+ putw4(k->va, PPN(pa)|PTEVALID|PTEKERNEL|PTEWRITE|PTENOCACHE|flag);
+}
+#else
putpmeg(k->va, PPN(pa)|PTEVALID|PTEKERNEL|PTEWRITE|PTENOCACHE|flag);
+#endif
+ splx(s);
return k;
}
M ss/screen.c => ss/screen.c +2 -0
@@ 266,6 266,7 @@ duartintr(void)
Duart *dp;
cause = duartrdreg(&duart[0], 3);
+
/*
* Keyboard
*/
@@ 290,6 291,7 @@ duartintr(void)
}
if(cause & TxPendB)
duartwrreg(dp, 0, ResTxPend);
+ cause = duartrdreg(&duart[0], 3);
}
/*
M ss/trap.c => ss/trap.c +4 -4
@@ 58,6 58,10 @@ trap(Ureg *ur)
ulong tbr;
tbr = (ur->tbr&0xFFF)>>4;
+ if(tbr == 16+15){ /* interrupt 14: counter 1 */
+ faultasync(ur);
+ return;
+ }
if(tbr == 16+14){ /* interrupt 14: counter 1 */
clock(ur);
return;
@@ 77,11 81,8 @@ trap(Ureg *ur)
u->p->pc = ur->pc; /* BUG */
if(user){
print("user trap: %s pc=0x%lux\n", excname(tbr), ur->pc);
-dumpregs(ur);
sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(tbr));
-print("call postnote\n");
postnote(u->p, 1, buf, NDebug);
-print("return from postnote\n");
}else{
print("kernel trap: %s pc=0x%lux\n", excname(tbr), ur->pc);
dumpregs(ur);
@@ 169,7 170,6 @@ notify(Ureg *ur)
if(u->note[0].flag == NDebug)
pprint("suicide: %s\n", u->note[0].msg);
Die:
-print("suicide: %s\n", u->note[0].msg);
unlock(&u->p->debug);
pexit(u->note[0].msg, u->note[0].flag!=NDebug);
}