From 723e986e12255a7ce91be3f3cb66b35ff97023ea Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 10 Jan 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-01-10 --- gnot/dat.h | 1 + gnot/devport.c | 222 ++++++++++++++++++++ gnot/main.c | 1 + gnot/scsisubs.s | 67 ++++++ port/devroot.c | 2 + port/devscsi.c | 548 ++++++++++++++++++++++++++++++++++++++++++++++++ port/devwren.c | 254 ++++++++++++++++++++++ port/fault.c | 2 +- port/page.c | 4 +- port/proc.c | 10 +- ss/dat.h | 5 +- ss/faultsparc.c | 33 ++- ss/fns.h | 5 +- ss/io.h | 1 + ss/l.s | 86 +++++++- ss/main.c | 20 +- ss/mem.h | 11 +- ss/mmu.c | 115 ++++++---- ss/screen.c | 2 + ss/trap.c | 8 +- 20 files changed, 1328 insertions(+), 69 deletions(-) create mode 100644 gnot/devport.c create mode 100644 gnot/scsisubs.s create mode 100644 port/devscsi.c create mode 100644 port/devwren.c diff --git a/gnot/dat.h b/gnot/dat.h index 53799cfb8709292e7699760797a6a076239b7a39..b06826d358e4b3643f332e5ce56365eccfd4a151 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -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 diff --git a/gnot/devport.c b/gnot/devport.c new file mode 100644 index 0000000000000000000000000000000000000000..4b8f2df1b087b8befc00d1b665e3d6db11017ba4 --- /dev/null +++ b/gnot/devport.c @@ -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; + +} diff --git a/gnot/main.c b/gnot/main.c index fe61f1896071ce6bf5c76e7144ccf95bbc0a0648..7b0e39257e44077577a7945a985725b8559f6601 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -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; } /* diff --git a/gnot/scsisubs.s b/gnot/scsisubs.s new file mode 100644 index 0000000000000000000000000000000000000000..f8fe997bb1e710c354a42479083589901d4ac090 --- /dev/null +++ b/gnot/scsisubs.s @@ -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 diff --git a/port/devroot.c b/port/devroot.c index 7d3ff28c191fef934b926d05e75c548a2b31f356..a7193cc9601a8f5b261c124c4dd9607cf4ee4f13 100644 --- a/port/devroot.c +++ b/port/devroot.c @@ -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: diff --git a/port/devscsi.c b/port/devscsi.c new file mode 100644 index 0000000000000000000000000000000000000000..ec9a033ef8f0e26cdc9b1b2c303627a0850272e8 --- /dev/null +++ b/port/devscsi.c @@ -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); + } + } +} diff --git a/port/devwren.c b/port/devwren.c new file mode 100644 index 0000000000000000000000000000000000000000..fcdd38c5754700ef0ec9cf05c1065e35b75d6f62 --- /dev/null +++ b/port/devwren.c @@ -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. + */ +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); +} diff --git a/port/fault.c b/port/fault.c index 174fe71cc157f0478d817d6429991b5761d8f0c1..d4a969d092432a0a9000a205a629a163f38ea896 100644 --- a/port/fault.c +++ b/port/fault.c @@ -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 || addrmaxva-USTACKSIZE || addr>=s->maxva) diff --git a/port/page.c b/port/page.c index 6bc0e5d1df0897c481a92f4af4f26468e49a0559..4d2e5ead631b31aaa4f895817342702dd7f80bc3 100644 --- a/port/page.c +++ b/port/page.c @@ -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"); } diff --git a/port/proc.c b/port/proc.c index c70b3a6fea6d27e06916664d5b6396733efab2bd..4e8f8b112e94a4294d3b172b1ee2d402ee52bd6d 100644 --- a/port/proc.c +++ b/port/proc.c @@ -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]; diff --git a/ss/dat.h b/ss/dat.h index 7c5ef97133c999e2c4c4204001a928ea7c2dbd10..1580b742e5b0427c23c1484008c321c681a01cf4 100644 --- a/ss/dat.h +++ b/ss/dat.h @@ -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); diff --git a/ss/faultsparc.c b/ss/faultsparc.c index ee9e865a1715322facdacc1032ef217f587749b0..36ee842f0abdff5399e43fa93d89948fe19661c0 100644 --- a/ss/faultsparc.c +++ b/ss/faultsparc.c @@ -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"); } /* diff --git a/ss/fns.h b/ss/fns.h index 27522facde08c6e6e78140d373d5b3d7148a01e1..33f3d7681fa11017a8ce438ee19eb800deca4a3a 100644 --- a/ss/fns.h +++ b/ss/fns.h @@ -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*); diff --git a/ss/io.h b/ss/io.h index 1369355fd94f8035609c634fd3d7960970202ab9..f22094f80adb4f1e47a79e5ef14ef0b99f7b5897 100644 --- a/ss/io.h +++ b/ss/io.h @@ -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 diff --git a/ss/l.s b/ss/l.s index 85bd1bb82bb2a2fbca2099e48128a50cdd3c012f..aa5221243bed082b81a349332bf7cc4eed4b5371 100644 --- a/ss/l.s +++ b/ss/l.s @@ -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 diff --git a/ss/main.c b/ss/main.c index ecf111a3efef610caf34427877e08e297e0caa6b..f5b6ce34963542ef0d8e2ed6df87a0a612dad3d2 100644 --- a/ss/main.c +++ b/ss/main.c @@ -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(); @@ -82,6 +85,15 @@ main(void) schedinit(); } +void +intrinit(void) +{ + KMap *k; + + k = kmappa(INTRREG, PTEIO); + intrreg = (uchar*)k->va; +} + void reset(void) { @@ -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; diff --git a/ss/mem.h b/ss/mem.h index 8ffe716700b778ffaf438af3414192b60079e3ff..00751900b30481e8f9f48fd8c6aef17f7551ef3b 100644 --- a/ss/mem.h +++ b/ss/mem.h @@ -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 diff --git a/ss/mmu.c b/ss/mmu.c index 1e3e53fab1182f0f21a44df4c620724f83060793..fb743d7994ae631a14472826badd8e51e31bb340 100644 --- a/ss/mmu.c +++ b/ss/mmu.c @@ -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; jpidproc[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; jpidhere[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=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; cp->pidonmach[m->machno]; + /* + * Flush old entries from cache + */ + for(d=0; dva+(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; } diff --git a/ss/screen.c b/ss/screen.c index be39f01cee09c39f376b578ad74427cfcc1cb1f3..80e64436887e085cacffbdeb4ed10c766ddf6b79 100644 --- a/ss/screen.c +++ b/ss/screen.c @@ -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); } /* diff --git a/ss/trap.c b/ss/trap.c index 945f80737a7c091b4189f040a24be753fd85e381..9f84628913315ec53607203c8cf4746bd837b471 100644 --- a/ss/trap.c +++ b/ss/trap.c @@ -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); }