M alphapc/devfloppy.c => alphapc/devfloppy.c +88 -69
@@ 92,7 92,7 @@ FController fl;
* predeclared
*/
static int cmddone(void*);
-static void floppyformat(FDrive*, char*);
+static void floppyformat(FDrive*, Cmdbuf*);
static void floppykproc(void*);
static void floppypos(FDrive*,long);
static int floppyrecal(FDrive*);
@@ 100,12 100,12 @@ static int floppyresult(void);
static void floppyrevive(void);
static long floppyseek(FDrive*, long);
static int floppysense(void);
-static void floppywait(void);
+static void floppywait(int);
static long floppyxfer(FDrive*, int, void*, long, long);
Dirtab floppydir[]={
".", {Qdir, 0, QTDIR}, 0, 0550,
- "fd0disk", {Qdata + 0}, 0, 0666,
+ "fd0disk", {Qdata + 0}, 0, 0660,
"fd0ctl", {Qctl + 0}, 0, 0660,
"fd1disk", {Qdata + 1}, 0, 0660,
"fd1ctl", {Qctl + 1}, 0, 0660,
@@ 116,6 116,22 @@ Dirtab floppydir[]={
};
#define NFDIR 2 /* directory entries/drive */
+enum
+{
+ CMdebug,
+ CMeject,
+ CMformat,
+ CMreset,
+};
+
+static Cmdtab floppyctlmsg[] =
+{
+ CMdebug, "debug", 1,
+ CMeject, "eject", 1,
+ CMformat, "format", 0,
+ CMreset, "reset", 1,
+};
+
static void
fldump(void)
{
@@ 147,6 163,8 @@ floppyreset(void)
ulong maxtsize;
floppysetup0(&fl);
+ if(fl.ndrive == 0)
+ return;
/*
* init dependent parameters
@@ 202,6 220,9 @@ floppyattach(char *spec)
{
static int kstarted;
+ if(fl.ndrive == 0)
+ error(Enodev);
+
if(kstarted == 0){
/*
* watchdog to turn off the motors
@@ 268,12 289,24 @@ changed(Chan *c, FDrive *dp)
DPRINT("changed\n");
fldump();
dp->vers++;
- floppysetdef(dp);
start = dp->t;
+ dp->maxtries = 3; /* limit it when we're probing */
+
+ /* floppyon will fail if there's a controller but no drive */
dp->confused = 1; /* make floppyon recal */
- floppyon(dp);
+ if(floppyon(dp) < 0)
+ error(Eio);
+
+ /* seek to the first track */
floppyseek(dp, dp->t->heads*dp->t->tsize);
while(waserror()){
+ /*
+ * if first attempt doesn't reset changed bit, there's
+ * no floppy there
+ */
+ if(inb(Pdir)&Fchange)
+ nexterror();
+
while(++dp->t){
if(dp->t == &floppytype[nelem(floppytype)])
dp->t = floppytype;
@@ 281,14 314,21 @@ changed(Chan *c, FDrive *dp)
break;
}
floppydir[1+NFDIR*dp->dev].length = dp->t->cap;
- floppyon(dp);
+
+ /* floppyon will fail if there's a controller but no drive */
+ if(floppyon(dp) < 0)
+ error(Eio);
+
DPRINT("changed: trying %s\n", dp->t->name);
fldump();
if(dp->t == start)
nexterror();
}
+
+ /* if the read succeeds, we've got the density right */
floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize);
poperror();
+ dp->maxtries = 20;
}
old = c->qid.vers;
@@ 372,14 412,14 @@ floppyread(Chan *c, void *a, long n, vlong off)
return rv;
}
-#define SNCMP(a, b) strncmp(a, b, sizeof(b)-1)
static long
floppywrite(Chan *c, void *a, long n, vlong off)
{
FDrive *dp;
long rv, i;
char *aa = a;
- char ctlmsg[64];
+ Cmdbuf *cb;
+ Cmdtab *ct;
ulong offset = off;
rv = 0;
@@ 409,28 449,36 @@ floppywrite(Chan *c, void *a, long n, vlong off)
break;
case Qctl:
rv = n;
+ cb = parsecmd(a, n);
+ if(waserror()){
+ free(cb);
+ nexterror();
+ }
qlock(&fl);
if(waserror()){
qunlock(&fl);
nexterror();
}
- if(n >= sizeof(ctlmsg))
- n = sizeof(ctlmsg) - 1;
- memmove(ctlmsg, aa, n);
- ctlmsg[n] = 0;
- if(SNCMP(ctlmsg, "eject") == 0){
+ ct = lookupcmd(cb, floppyctlmsg, nelem(floppyctlmsg));
+ switch(ct->index){
+ case CMeject:
floppyeject(dp);
- } else if(SNCMP(ctlmsg, "reset") == 0){
+ break;
+ case CMformat:
+ floppyformat(dp, cb);
+ break;
+ case CMreset:
fl.confused = 1;
floppyon(dp);
- } else if(SNCMP(ctlmsg, "format") == 0){
- floppyformat(dp, ctlmsg);
- } else if(SNCMP(ctlmsg, "debug") == 0){
+ break;
+ case CMdebug:
floppydebug = 1;
- } else
- error(Ebadctl);
+ break;
+ }
poperror();
qunlock(&fl);
+ poperror();
+ free(cb);
break;
default:
panic("floppywrite: bad qid");
@@ 463,7 511,7 @@ floppykproc(void *)
/*
* start a floppy drive's motor.
*/
-static void
+static int
floppyon(FDrive *dp)
{
int alreadyon;
@@ 497,6 545,11 @@ floppyon(FDrive *dp)
break;
dp->lasttouched = m->ticks;
fl.selected = dp;
+
+ /* return -1 if this didn't work */
+ if(dp->confused)
+ return -1;
+ return 0;
}
/*
@@ 635,9 688,9 @@ cmddone(void *)
* routine to try to clear any conditions.
*/
static void
-floppywait(void)
+floppywait(int slow)
{
- tsleep(&fl.r, cmddone, 0, 5000);
+ tsleep(&fl.r, cmddone, 0, slow ? 5000 : 1000);
if(!cmddone(0)){
floppyintr(0);
fl.confused = 1;
@@ 658,7 711,7 @@ floppyrecal(FDrive *dp)
fl.cmd[fl.ncmd++] = dp->dev;
if(floppycmd() < 0)
return -1;
- floppywait();
+ floppywait(1);
if(fl.nstat < 2){
DPRINT("recalibrate: confused %ux\n", inb(Pmsr));
fl.confused = 1;
@@ 681,39 734,6 @@ floppyrecal(FDrive *dp)
return 0;
}
-static void
-dumpreg(void)
-{
- int i;
-
- fl.ncmd = 0;
- fl.cmd[fl.ncmd++] = Fdumpreg;
- if(floppycmd() < 0)
- return;
- floppywait();
- if(fl.nstat < 0){
- print("dumpreg bad %d\n", fl.nstat);
- fldump();
- return;
- }
- for(i = 0; i < fl.nstat; i++)
- print(" %2.2uX", fl.stat[i]);
- print("\n");
-}
-
-static void
-specify(void)
-{
- fl.ncmd = 0;
- fl.cmd[fl.ncmd++] = Fspec;
- fl.cmd[fl.ncmd++] = 0;
- fl.cmd[fl.ncmd++] = 1;
- if(floppycmd() < 0)
- return;
- floppywait();
- fldump();
-}
-
/*
* if the controller or a specific drive is in a confused state,
* reset it and get back to a known state
@@ 741,7 761,7 @@ floppyrevive(void)
spllo();
fl.motor = 0;
fl.confused = 0;
- floppywait();
+ floppywait(0);
/* mark all drives in an unknown state */
for(dp = fl.d; dp < &fl.d[fl.ndrive]; dp++)
@@ 775,7 795,7 @@ floppyseek(FDrive *dp, long off)
fl.cmd[fl.ncmd++] = dp->tcyl * dp->t->steps;
if(floppycmd() < 0)
return -1;
- floppywait();
+ floppywait(1);
if(fl.nstat < 2){
DPRINT("seek: confused\n");
fl.confused = 1;
@@ 804,16 824,13 @@ floppyxfer(FDrive *dp, int cmd, void *a, long off, long n)
return 0;
if(off + n > dp->t->cap)
n = dp->t->cap - off;
-if(cmd == Fread)
- memset(a, 0x55, n);
/* retry on error (until it gets ridiculous) */
tries = 0;
while(waserror()){
- if(tries++ > 20)
+ if(tries++ >= dp->maxtries)
nexterror();
DPRINT("floppyxfer: retrying\n");
- /*floppyon(dp);*/
}
dp->len = n;
@@ 856,7 873,7 @@ if(cmd == Fread)
/*
* give bus to DMA, floppyintr() will read result
*/
- floppywait();
+ floppywait(0);
dmaend(DMAchan);
poperror();
@@ 900,20 917,19 @@ if(cmd == Fread)
* format a track
*/
static void
-floppyformat(FDrive *dp, char *params)
+floppyformat(FDrive *dp, Cmdbuf *cb)
{
int cyl, h, sec;
ulong track;
uchar *buf, *bp;
FType *t;
- char *f[3];
/*
* set the type
*/
- if(tokenize(params, f, 3) > 1){
+ if(cb->nf == 2){
for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
- if(strcmp(f[1], t->name)==0 && t->dt==dp->dt){
+ if(strcmp(cb->f[1], t->name)==0 && t->dt==dp->dt){
dp->t = t;
floppydir[1+NFDIR*dp->dev].length = dp->t->cap;
break;
@@ 921,9 937,12 @@ floppyformat(FDrive *dp, char *params)
}
if(t >= &floppytype[nelem(floppytype)])
error(Ebadarg);
- } else {
+ } else if(cb->nf == 1){
floppysetdef(dp);
t = dp->t;
+ } else {
+ cmderror(cb, "invalid floppy format command");
+ SET(t);
}
/*
@@ 992,7 1011,7 @@ floppyformat(FDrive *dp, char *params)
/*
* give bus to DMA, floppyintr() will read result
*/
- floppywait();
+ floppywait(1);
dmaend(DMAchan);
poperror();
M alphapc/floppy.h => alphapc/floppy.h +2 -1
@@ 3,7 3,7 @@ typedef struct FDrive FDrive;
typedef struct FType FType;
static void floppyintr(Ureg*);
-static void floppyon(FDrive*);
+static int floppyon(FDrive*);
static void floppyoff(FDrive*);
static void floppysetdef(FDrive*);
@@ 20,6 20,7 @@ struct FDrive
int cyl; /* current arm position */
int confused; /* needs to be recalibrated */
int vers;
+ int maxtries; /* max read attempts before Eio */
int tcyl; /* target cylinder */
int thead; /* target head */
M ip/icmp.c => ip/icmp.c +2 -0
@@ 350,6 350,7 @@ icmpiput(Proto *icmp, Ipifc*, Block *bp)
break;
case Unreachable:
code = p->code;
+ x = 0;
switch(code){
default:
msg = unreachcode[1];
@@ 401,6 402,7 @@ icmpiput(Proto *icmp, Ipifc*, Block *bp)
(*pr->advise)(pr, bp, m2);
return;
}
+ bp->rp -= ICMP_IPSIZE+ICMP_HDRSIZE;
}
goticmpkt(icmp, bp);
M mtx/dat.h => mtx/dat.h +4 -3
@@ 79,9 79,10 @@ struct Conf
/*
* mmu goo in the Proc structure
*/
+#define NCOLOR 1
struct PMMU
{
-int dummy;
+ int pidonmach[MAXMACH];
};
/*
@@ 219,8 220,8 @@ struct ISAConf {
extern PCArch *arch;
-#define MACHP(n) ((Mach *)((int)&mach0+n*BY2PG))
-extern Mach mach0;
+//#define MACHP(n) ((Mach *)((int)&mach0+n*BY2PG))
+//extern Mach mach0;
extern register Mach *m;
extern register Proc *up;
M mtx/fns.h => mtx/fns.h +2 -1
@@ 61,6 61,7 @@ int isaconfig(char*, int, ISAConf*);
void kbdinit(void);
void kbdreset(void);
void kernelmmu(void);
+#define kmapinval()
void links(void);
void mathinit(void);
void mmuinit(void);
@@ 98,7 99,7 @@ void tlbflushall(void);
void uartinstall(void);
void uartwait(void); /* debugging */
int unsac(uchar *dst, uchar *src, int n, int nsrc);
-#define userureg(ur) ((ur)->status & KUSER)
+#define userureg(ur) (((ur)->status & MSR_PR) != 0)
void wbflush(void);
#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
M mtx/l.s => mtx/l.s +0 -1
@@ 1,5 1,4 @@
#include "mem.h"
-#include "mpc60x.h"
#define BDNZ BC 16,0,
#define BDNE BC 0,2,
M mtx/mem.h => mtx/mem.h +106 -14
@@ 1,5 1,3 @@
-/* none of this is meant to be correct yet */
-
/*
* Memory and machine-specific definitions. Used in C and assembler.
*/
@@ 12,17 10,22 @@
#define BI2WD 32 /* bits per word */
#define BY2WD 4 /* bytes per word */
#define BY2V 8 /* bytes per vlong */
-#define BY2PG 8192 /* bytes per page */
+#define BY2PG 4096 /* bytes per page */
#define WD2PG (BY2PG/BY2WD) /* words per page */
-#define PGSHIFT 13 /* log(BY2PG) */
+#define PGSHIFT 12 /* log(BY2PG) */
#define ROUND(s, sz) (((s)+(sz-1))&~(sz-1))
#define PGROUND(s) ROUND(s, BY2PG)
-#define BLOCKALIGN 8
+#define CACHELINELOG 4
+#define CACHELINESZ (1<<CACHELINELOG)
+#define BLOCKALIGN CACHELINESZ
+
+#define MHz 1000000
-#define BY2PTE 8 /* bytes per pte entry */
-#define PTE2PG (BY2PG/BY2PTE) /* pte entries per page */
+//#define BY2PTE 8 /* bytes per pte entry */
+//#define PTE2PG (BY2PG/BY2PTE) /* pte entries per page */
#define MAXMACH 1 /* max # cpus system can run */
+#define MACHSIZE BY2PG
#define KSTACK 4096 /* Size of kernel stack */
/*
@@ 31,8 34,51 @@
#define HZ 100 /* clock frequency */
#define MS2HZ (1000/HZ)
#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
+#define TK2MS(t) ((t)*MS2HZ) /* ticks to milliseconds */
#define MS2TK(t) (((t)*HZ+500)/1000) /* milliseconds to closest tick */
+/* Bit encodings for Machine State Register (MSR) */
+#define MSR_POW (1<<18) /* Enable Power Management */
+#define MSR_TGPR (1<<17) /* TLB Update registers in use */
+#define MSR_ILE (1<<16) /* Interrupt Little-Endian enable */
+#define MSR_EE (1<<15) /* External Interrupt enable */
+#define MSR_PR (1<<14) /* Supervisor/User privelege */
+#define MSR_FP (1<<13) /* Floating Point enable */
+#define MSR_ME (1<<12) /* Machine Check enable */
+#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */
+#define MSR_SE (1<<10) /* Single Step */
+#define MSR_BE (1<<9) /* Branch Trace */
+#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */
+#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */
+#define MSR_IR (1<<5) /* Instruction MMU enable */
+#define MSR_DR (1<<4) /* Data MMU enable */
+#define MSR_RI (1<<1) /* Recoverable Exception */
+#define MSR_LE (1<<0) /* Little-Endian enable */
+
+#define MSR_ MSR_FP|MSR_FE0|MSR_FE1|MSR_ME
+
+/*
+ * Exception codes (trap vectors)
+ */
+#define CRESET 0x01
+#define CMCHECK 0x02
+#define CDSI 0x03
+#define CISI 0x04
+#define CEI 0x05
+#define CALIGN 0x06
+#define CPROG 0x07
+#define CFPU 0x08
+#define CDEC 0x09
+#define CSYSCALL 0x0C
+#define CTRACE 0x0D
+// #define CFPA 0x0E
+/* rest are power-implementation dependent */
+#define CIMISS 0x10
+#define CDLMISS 0x11
+#define CDSMISS 0x12
+#define CIBREAK 0x13
+#define CSMI 0x14
+
/*
* Magic registers
*/
@@ 42,14 88,24 @@
/*
+ * virtual MMU
+ */
+#define PTEMAPMEM (1024*1024)
+#define PTEPERTAB (PTEMAPMEM/BY2PG)
+#define SEGMAPSIZE 1984
+#define SSEGMAPSIZE 16
+#define PPN(x) ((x)&~(BY2PG-1))
+
+/*
* Fundamental addresses
*/
+#define MACHADDR (KTZERO-MAXMACH*MACHSIZE)
+#define MACHP(n) ((Mach *)(MACHADDR+(n)*MACHSIZE))
#define UREGSIZE ((8+32)*4)
/*
* MMU
- *
*/
/* L1 table entry and Mx_TWC flags */
@@ 64,18 120,36 @@
#define PTECI (1<<1) /* cache inhibit */
#define PTESH (1<<2) /* page is shared; ASID ignored */
#define PTELPS (1<<3) /* large page size */
-#define PTEWRITE 0x9F0
+//#define PTEWRITE 0x9F0
+
+#define PTEKERNEL (0<<2)
+#define PTEUSER (1<<2)
+#define PTESIZE (1<<7)
+
+#define NTLBPID 16
+#define TLBPID(n) ((n)&(NTLBPID-1))
+
+/* soft tlb */
+#define STLBLOG 12
+#define STLBSIZE (1<<STLBLOG)
+
+/*
+ * portable MMU bits for fault.c - though still machine specific
+ */
+//#define PTEVALID (MMUPP|MMUV)
+#define PTEWRITE (2<<10)
+#define PTERONLY (3<<10)
+#define PTEUNCACHED (1<<4)
+
+/*
+ * physical MMU bits
+ */
/* TLB and MxEPN flag */
#define TLBVALID (1<<9)
#define TLBSETS 32 /* number of tlb sets (603/603e) */
-#define PTEMAPMEM (1024*1024)
-#define PTEPERTAB (PTEMAPMEM/BY2PG)
-#define SEGMAPSIZE 512
-#define SSEGMAPSIZE 16
-
/*
* Address spaces
*/
@@ 99,3 173,21 @@
#define FLASHAorB 0xfff00000
#define isphys(x) (((ulong)x&KZERO)!=0)
+
+/*
+ * standard ppc special purpose registers
+ */
+#define DSISR 18
+#define DAR 19 /* Data Address Register */
+#define DEC 22 /* Decrementer */
+#define SRR0 26 /* Saved Registers (exception) */
+#define SRR1 27
+#define SPRG0 272 /* Supervisor Private Registers */
+#define SPRG1 273
+#define SPRG2 274
+#define SPRG3 275
+#define TBRU 269 /* Time base Upper/Lower (Reading) */
+#define TBRL 268
+#define TBWU 284 /* Time base Upper/Lower (Writing) */
+#define TBWL 285
+#define PVR 287 /* Processor Version */
A mtx/mmu.c => mtx/mmu.c +172 -0
@@ 0,0 1,172 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+
+#define TLBINVLAID KZERO
+
+void
+mmuinit(void)
+{
+ int i;
+
+ print("mmuinit\n");
+ for(i=0; i<STLBSIZE; i++)
+ m->stb[i].virt = TLBINVLAID;
+}
+
+void
+flushmmu(void)
+{
+ int x;
+
+if(0)print("flushmmu(%ld)\n", up->pid);
+ x = splhi();
+ up->newtlb = 1;
+ mmuswitch(up);
+ splx(x);
+}
+
+/*
+ * called with splhi
+ */
+void
+mmuswitch(Proc *p)
+{
+ int tp;
+
+if(0)print("mmuswitch()\n");
+ if(p->newtlb) {
+ memset(p->pidonmach, 0, sizeof p->pidonmach);
+ p->newtlb = 0;
+ }
+ tp = p->pidonmach[m->machno];
+ putcasid(tp);
+}
+
+void
+mmurelease(Proc* p)
+{
+if(0)print("mmurelease(%ld)\n", p->pid);
+ memset(p->pidonmach, 0, sizeof p->pidonmach);
+}
+
+void
+purgetlb(int pid)
+{
+ int i, mno;
+ Proc *sp, **pidproc;
+ Softtlb *entry, *etab;
+
+if(0)print("purgetlb: pid = %d\n", pid);
+ m->tlbpurge++;
+ /*
+ * find all pid entries that are no longer used by processes
+ */
+ mno = m->machno;
+ pidproc = m->pidproc;
+ for(i=1; i<NTLBPID; i++) {
+ sp = pidproc[i];
+ if(sp && sp->pidonmach[mno] != i)
+ pidproc[i] = 0;
+ }
+
+ /*
+ * shoot down the one we want
+ */
+ sp = pidproc[pid];
+ if(sp != 0)
+ sp->pidonmach[mno] = 0;
+ pidproc[pid] = 0;
+
+ /*
+ * clean out all dead pids from the stlb;
+ */
+ entry = m->stb;
+ for(etab = &entry[STLBSIZE]; entry < etab; entry++)
+ if(pidproc[TLBPID(entry->virt)] == 0)
+ entry->virt = TLBINVLAID;
+
+ /*
+ * clean up the hardware
+ */
+ tlbflushall();
+}
+
+int
+newtlbpid(Proc *p)
+{
+ int i, s;
+ Proc **h;
+
+ i = m->lastpid;
+ h = m->pidproc;
+ for(s = 0; s < NTLBPID; s++) {
+ i++;
+ if(i >= NTLBPID)
+ i = 1;
+ if(h[i] == 0)
+ break;
+ }
+
+ if(h[i]) {
+ i = m->purgepid+1;
+ if(i >= NTLBPID)
+ i = 1;
+ m->purgepid = i;
+ purgetlb(i);
+ }
+
+ if(h[i] != 0)
+ panic("newtlb");
+
+ m->pidproc[i] = p;
+ p->pidonmach[m->machno] = i;
+ m->lastpid = i;
+if(0)print("newtlbpid: pid=%ld = tlbpid = %d\n", p->pid, i);
+ return i;
+}
+
+void
+putmmu(ulong va, ulong pa, Page *pg)
+{
+ char *ctl;
+ int tp;
+ ulong h;
+
+ qlock(&m->stlblk);
+
+ tp = up->pidonmach[m->machno];
+ if(tp == 0) {
+ tp = newtlbpid(up);
+ putcasid(tp);
+ }
+
+ h = ((va>>12)^(va>>24)^(tp<<8)) & 0xfff;
+ m->stb[h].virt = va|tp;
+ m->stb[h].phys = pa;
+ tlbflush(va);
+
+ qunlock(&m->stlblk);
+
+ ctl = &pg->cachectl[m->machno];
+if(0)print("putmmu tp=%d h=%ld va=%lux pa=%lux ctl=%x\n", tp, h,va, pa, *ctl);
+ switch(*ctl) {
+ default:
+ panic("putmmu: %d\n", *ctl);
+ break;
+ case PG_NOFLUSH:
+ break;
+ case PG_TXTFLUSH:
+ dcflush((void*)pg->va, BY2PG);
+ icflush((void*)pg->va, BY2PG);
+ *ctl = PG_NOFLUSH;
+ break;
+ case PG_NEWCOL:
+print("PG_NEWCOL!!\n");
+ *ctl = PG_NOFLUSH;
+ break;
+ }
+}
A mtx/random.c => mtx/random.c +138 -0
@@ 0,0 1,138 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+
+struct Rb
+{
+ QLock;
+ Rendez producer;
+ Rendez consumer;
+ ulong randomcount;
+ uchar buf[1024];
+ uchar *ep;
+ uchar *rp;
+ uchar *wp;
+ uchar next;
+ uchar wakeme;
+ ushort bits;
+ ulong randn;
+} rb;
+
+static int
+rbnotfull(void*)
+{
+ int i;
+
+ i = rb.rp - rb.wp;
+ return i != 1 && i != (1 - sizeof(rb.buf));
+}
+
+static int
+rbnotempty(void*)
+{
+ return rb.wp != rb.rp;
+}
+
+static void
+genrandom(void*)
+{
+ up->basepri = PriNormal;
+ up->priority = up->basepri;
+
+ for(;;){
+ for(;;)
+ if(++rb.randomcount > 100000)
+ break;
+ if(anyhigher())
+ sched();
+ if(!rbnotfull(0))
+ sleep(&rb.producer, rbnotfull, 0);
+ }
+}
+
+/*
+ * produce random bits in a circular buffer
+ */
+static void
+randomclock(void)
+{
+ if(rb.randomcount == 0 || !rbnotfull(0))
+ return;
+
+ rb.bits = (rb.bits<<2) ^ rb.randomcount;
+ rb.randomcount = 0;
+
+ rb.next++;
+ if(rb.next != 8/2)
+ return;
+ rb.next = 0;
+
+ *rb.wp ^= rb.bits;
+ if(rb.wp+1 == rb.ep)
+ rb.wp = rb.buf;
+ else
+ rb.wp = rb.wp+1;
+
+ if(rb.wakeme)
+ wakeup(&rb.consumer);
+}
+
+void
+randominit(void)
+{
+ addclock0link(randomclock);
+ rb.ep = rb.buf + sizeof(rb.buf);
+ rb.rp = rb.wp = rb.buf;
+ kproc("genrandom", genrandom, 0);
+}
+
+/*
+ * consume random bytes from a circular buffer
+ */
+ulong
+randomread(void *xp, ulong n)
+{
+ uchar *e, *p;
+ ulong x;
+
+ p = xp;
+
+ if(waserror()){
+ qunlock(&rb);
+ nexterror();
+ }
+
+ qlock(&rb);
+ for(e = p + n; p < e; ){
+ if(rb.wp == rb.rp){
+ rb.wakeme = 1;
+ wakeup(&rb.producer);
+ sleep(&rb.consumer, rbnotempty, 0);
+ rb.wakeme = 0;
+ continue;
+ }
+
+ /*
+ * beating clocks will be precictable if
+ * they are synchronized. Use a cheap pseudo
+ * random number generator to obscure any cycles.
+ */
+ x = rb.randn*1103515245 ^ *rb.rp;
+ *p++ = rb.randn = x;
+
+ if(rb.rp+1 == rb.ep)
+ rb.rp = rb.buf;
+ else
+ rb.rp = rb.rp+1;
+ }
+ qunlock(&rb);
+ poperror();
+
+ wakeup(&rb.producer);
+
+ return n;
+}
M mtx/trap.c => mtx/trap.c +7 -12
@@ 157,9 157,9 @@ trap(Ureg *ur)
m->intrts = fastticks(nil);
ecode = (ur->cause >> 8) & 0xff;
-// user = (ur->srr1 & MSR_PR) != 0;
+ user = (ur->srr1 & MSR_PR) != 0;
-/* if(ur->status & MSR_RI == 0)
+if(ur->status & MSR_RI == 0)
print("double fault?: ecode = %d\n", ecode);
switch(ecode){
case CEI:
@@ 169,6 169,7 @@ print("double fault?: ecode = %d\n", ecode);
case CDEC:
clockintr(ur);
break;
+/*
case CIMISS:
faultpower(ur, ur->pc, 1);
break;
@@ 182,12 183,7 @@ if(0) print("CDMISS: %lux %lux\n", m->epn, m->cmp1);
case CDTLBE:
faultpower(ur, m->dar, !(m->dsisr & (1<<25)));
break;
-
- case CEMU:
- print("CEMU: pc=#%lux op=#%8.8lux\n", ur->pc, *(ulong*)ur->pc);
- sprint(buf, "sys: trap: illegal op addr=0x%lux", ur->pc);
- postnote(up, 1, buf, NDebug);
- break;
+*/
case CSYSCALL:
syscall(ur);
@@ 214,7 210,6 @@ if(0) print("CDMISS: %lux %lux\n", m->epn, m->cmp1);
delay(100);
reset();
}
-*/
splhi();
if(user)
notify(ur);
@@ 226,7 221,7 @@ faultpower(Ureg *ureg, ulong addr, int read)
int user, insyscall, n;
char buf[ERRMAX];
-// user = (ureg->srr1 & MSR_PR) != 0;
+ user = (ureg->srr1 & MSR_PR) != 0;
if(0)print("fault: pid=%ld pc = %lux, addr = %lux read = %d user = %d stack=%ulx\n", up->pid, ureg->pc, addr, read, user, &ureg);
insyscall = up->insyscall;
up->insyscall = 1;
@@ 633,8 628,8 @@ syscall(Ureg* ureg)
long ret;
int i, scallnr;
-// if((ureg->srr1 & MSR_PR) == 0)
-// panic("syscall: srr1 0x%4.4uX\n", ureg->srr1);
+ if((ureg->srr1 & MSR_PR) == 0)
+ panic("syscall: srr1 0x%4.4uX\n", ureg->srr1);
m->syscall++;
up->insyscall = 1;
M pc/devusb.c => pc/devusb.c +8 -8
@@ 1351,14 1351,14 @@ usbreset(void)
*/
if(cfg->ccrb != 0x0C || cfg->ccru != 0x03)
continue;
- switch(cfg->vid | cfg->did<<16){
- default:
- continue;
- case 0x8086 | 0x7112<<16: /* 82371[AE]B (PIIX4[E]) */
- case 0x8086 | 0x719A<<16: /* 82443MX */
- case 0x0586 | 0x1106<<16: /* VIA 82C586 */
- break;
- }
+// switch(cfg->vid | cfg->did<<16){
+// default:
+// continue;
+// case 0x8086 | 0x7112<<16: /* 82371[AE]B (PIIX4[E]) */
+// case 0x8086 | 0x719A<<16: /* 82443MX */
+// case 0x0586 | 0x1106<<16: /* VIA 82C586 */
+// break;
+// }
if((cfg->mem[4].bar & ~0x0F) != 0)
break;
}
M port/portdat.h => port/portdat.h +1 -3
@@ 4,7 4,6 @@ typedef struct Chan Chan;
typedef struct Cmdbuf Cmdbuf;
typedef struct Cmdtab Cmdtab;
typedef struct Cname Cname;
-typedef struct Crypt Crypt;
typedef struct Dev Dev;
typedef struct Dirtab Dirtab;
typedef struct Egrp Egrp;
@@ 41,10 40,9 @@ typedef struct Sargs Sargs;
typedef struct Segment Segment;
typedef struct Session Session;
typedef struct Talarm Talarm;
-typedef struct Target Target;
typedef struct Uart Uart;
typedef struct Waitq Waitq;
-typedef struct Walkqid Walkqid;
+typedef struct Walkqid Walkqid;
typedef int Devgen(Chan*, char*, Dirtab*, int, int, Dir*);