M mtx/dat.h => mtx/dat.h +3 -2
@@ 155,8 155,9 @@ struct Mach
ulong ptabbase; /* start of page table in kernel virtual space */
int slotgen; /* next pte (byte offset) when pteg is full */
int mmupid; /* next mmu pid to use */
- int minpid;
- int maxpid;
+ int sweepcolor;
+ int trigcolor;
+ Rendez sweepr;
ulong spuriousintr;
int lastintr;
M mtx/fns.h => mtx/fns.h +1 -1
@@ 63,7 63,7 @@ void kernelmmu(void);
void links(void);
void mathinit(void);
void mmuinit(void);
-ulong* mmuwalk(ulong*, ulong, int);
+void mmusweep(void*);
void mpicdisable(int);
void mpicenable(int, Vctl*);
int mpiceoi(int);
M mtx/main.c => mtx/main.c +1 -0
@@ 142,6 142,7 @@ init0(void)
poperror();
}
kproc("alarm", alarmkproc, 0);
+ kproc("mmusweep", mmusweep, 0);
touser((void*)(USTKTOP-8));
}
M mtx/mmu.c => mtx/mmu.c +73 -17
@@ 19,16 19,23 @@ static ulong ptabmask; /* hash mask */
/*
* VSID is 24 bits. 3 are required to distinguish segments in user
- * space (kernel space only uses the BATs).
+ * space (kernel space only uses the BATs). pid 0 is reserved.
+ * The top 2 bits of the pid are used as a `color' for the background
+ * pid reclaimation algorithm.
*/
-#define VSID(pid, i) (((pid)<<3)|i)
-
enum {
PIDBASE = 1,
- PIDMAX = ((1<<21)-1),
+ PIDBITS = 21,
+ COLBITS = 2,
+ PIDMAX = ((1<<PIDBITS)-1),
+ COLMASK = ((1<<COLBITS)-1),
};
+#define VSID(pid, i) (((pid)<<3)|i)
+#define PIDCOLOR(pid) ((pid)>>(PIDBITS-COLBITS))
+#define PTECOL(color) PTE0(1, VSID(((color)<<(PIDBITS-COLBITS)), 0), 0, 0)
+
void
mmuinit(void)
{
@@ 50,6 57,68 @@ mmuinit(void)
m->ptabbase = (ulong)xspanalloc(ptabsize, 0, ptabsize);
putsdr1(PADDR(m->ptabbase) | (ptabmask>>10));
m->mmupid = PIDBASE;
+ m->sweepcolor = 0;
+ m->trigcolor = 2;
+}
+
+static int
+work(void*)
+{
+ return PIDCOLOR(m->mmupid) == m->trigcolor;
+}
+
+void
+mmusweep(void*)
+{
+ Proc *p;
+ int i, x, sweepcolor;
+ ulong *ptab, *ptabend, ptecol;
+
+ for(;;) {
+ if(PIDCOLOR(m->mmupid) != m->trigcolor)
+ sleep(&m->sweepr, work, nil);
+
+ sweepcolor = m->sweepcolor;
+//print("sweep %d trig %d\n", sweepcolor, m->trigcolor);
+ x = splhi();
+ p = proctab(0);
+ for(i = 0; i < conf.nproc; i++, p++)
+ if(PIDCOLOR(p->mmupid) == sweepcolor)
+ p->mmupid = 0;
+ splx(x);
+
+ ptab = (ulong*)m->ptabbase;
+ ptabend = (ulong*)(m->ptabbase+ptabsize);
+ ptecol = PTECOL(sweepcolor);
+ while(ptab < ptabend) {
+ if((*ptab & PTECOL(3)) == ptecol)
+ *ptab = 0;
+ ptab += 2;
+ }
+//print("swept %d\n", sweepcolor);
+
+ m->sweepcolor = (sweepcolor+1) & COLMASK;
+ m->trigcolor = (m->trigcolor+1) & COLMASK;
+ }
+}
+
+int
+newmmupid(void)
+{
+ int pid, newcolor;
+
+ pid = m->mmupid++;
+ if(m->mmupid > PIDMAX)
+ m->mmupid = PIDBASE;
+ newcolor = PIDCOLOR(m->mmupid);
+ if(newcolor != PIDCOLOR(pid)) {
+ if(newcolor == m->sweepcolor)
+ panic("ran out of pids");
+ else if(newcolor == m->trigcolor)
+ wakeup(&m->sweepr);
+ }
+ up->mmupid = pid;
+ return pid;
}
void
@@ 150,16 219,3 @@ if(q[1] == pa) print("putmmu already set pte\n");
break;
}
}
-
-int
-newmmupid(void)
-{
- int pid;
-
- pid = m->mmupid++;
- if(m->mmupid > PIDMAX)
- panic("ran out of mmu pids");
-// m->mmupid = PIDBASE;
- up->mmupid = pid;
- return pid;
-}
M pc/devusb.c => pc/devusb.c +26 -6
@@ 307,6 307,7 @@ enum
CMdebug,
CMep,
CMmaxpkt,
+ CMadjust,
CMspeed,
CMunstall,
};
@@ 325,6 326,7 @@ static Cmdtab usbctlmsg[] =
CMdebug, "debug", 3,
CMep, "ep", 6,
CMmaxpkt, "maxpkt", 3,
+ CMadjust, "adjust", 3,
CMspeed, "speed", 2,
CMunstall, "unstall", 2,
};
@@ 1825,8 1827,6 @@ isoio(Endpt *e, void *a, long n, ulong offset, int w)
if (e->psize > e->maxpkt)
panic("packet size > maximum");
}
- isolock = 0;
- iunlock(&activends);
td->flags &= ~IsoClean;
bp = e->bp0 + (td - e->td0) * e->maxpkt / e->pollms;
q = bp + e->off;
@@ 1860,9 1860,11 @@ isoio(Endpt *e, void *a, long n, ulong offset, int w)
} while(n > 0);
n = p-(uchar*)a;
e->foffset += n;
- poperror();
- if (isolock)
+ if (isolock){
+ isolock = 0;
iunlock(&activends);
+ }
+ poperror();
qunlock(&e->rlock);
return n;
}
@@ 2163,6 2165,25 @@ usbwrite(Chan *c, void *a, long n, vlong offset)
if(e->maxpkt > 1500)
e->maxpkt = 1500;
break;
+ case CMadjust:
+ i = strtoul(cb->f[1], nil, 0);
+ if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
+ error(Ebadusbmsg);
+ e = d->ep[i];
+ if (e->iso == 0)
+ error(Eperm);
+ i = strtoul(cb->f[2], nil, 0);
+ /* speed may not result in change of maxpkt */
+ if (i < (e->maxpkt-1)/e->samplesz * 1000/e->pollms
+ || i > e->maxpkt/e->samplesz * 1000/e->pollms){
+ snprint(cmd, sizeof(cmd), "%d < %d < %d?",
+ (e->maxpkt-1)/e->samplesz * 1000/e->pollms,
+ i,
+ e->maxpkt/e->samplesz * 1000/e->pollms);
+ error(cmd);
+ }
+ e->hz = i;
+ break;
case CMdebug:
i = strtoul(cb->f[1], nil, 0);
if(i < -1 || i >= nelem(d->ep) || d->ep[i] == nil)
@@ 2184,7 2205,7 @@ usbwrite(Chan *c, void *a, long n, vlong offset)
break;
case CMep:
/* ep n `bulk' mode maxpkt nbuf OR
- * ep n period mode samplesize KHz
+ * ep n period mode samplesize Hz
*/
i = strtoul(cb->f[1], nil, 0);
if(i < 0 || i >= nelem(d->ep)) {
@@ 2249,7 2270,6 @@ usbwrite(Chan *c, void *a, long n, vlong offset)
if(i >= 1 && i <= 100000){
/* Hz */
e->hz = i;
- // e->remain = 999/e->pollms;
e->remain = 0;
}else {
XPRINT("field 5: 1 < %d <= 100000 Hz\n", i);
M pc/pci.c => pc/pci.c +18 -16
@@ 616,6 616,7 @@ cyrix_init(Pcidev *router, uchar link, uchar irq)
enum {
Intel = 0x8086,
Intel_82371FB_0 = 0x122e,
+ Intel_82371MX_0 = 0x1234,
Intel_82371SB_0 = 0x7000,
Intel_82371AB_0 = 0x7110,
Intel_82443MX_1 = 0x7198,
@@ 641,25 642,26 @@ enum {
typedef struct {
ushort sb_vid, sb_did;
uchar (*sb_translate)(Pcidev *, uchar);
- void (*sb_initialize)(Pcidev *, uchar, uchar);
+ void (*sb_initialize)(Pcidev *, uchar, uchar);
} bridge_t;
static bridge_t southbridges[] = {
-{ Intel, Intel_82371FB_0, pIIx_link, pIIx_init },
-{ Intel, Intel_82371SB_0, pIIx_link, pIIx_init },
-{ Intel, Intel_82371AB_0, pIIx_link, pIIx_init },
-{ Intel, Intel_82443MX_1, pIIx_link, pIIx_init },
-{ Intel, Intel_82801AA_0, pIIx_link, pIIx_init },
-{ Intel, Intel_82801AB_0, pIIx_link, pIIx_init },
-{ Intel, Intel_82801BA_0, pIIx_link, pIIx_init },
-{ Intel, Intel_82801BAM_0, pIIx_link, pIIx_init },
-{ Viatech, Via_82C586_0, via_link, via_init },
-{ Viatech, Via_82C596, via_link, via_init },
-{ Viatech, Via_82C686, via_link, via_init },
-{ Opti, Opti_82C700, opti_link, opti_init },
-{ Al, Al_M1533, ali_link, ali_init },
-{ SI, SI_503, pIIx_link, pIIx_init },
-{ SI, SI_496, pIIx_link, pIIx_init },
+{ Intel, Intel_82371FB_0, pIIx_link, pIIx_init },
+{ Intel, Intel_82371MX_0, pIIx_link, pIIx_init },
+{ Intel, Intel_82371SB_0, pIIx_link, pIIx_init },
+{ Intel, Intel_82371AB_0, pIIx_link, pIIx_init },
+{ Intel, Intel_82443MX_1, pIIx_link, pIIx_init },
+{ Intel, Intel_82801AA_0, pIIx_link, pIIx_init },
+{ Intel, Intel_82801AB_0, pIIx_link, pIIx_init },
+{ Intel, Intel_82801BA_0, pIIx_link, pIIx_init },
+{ Intel, Intel_82801BAM_0, pIIx_link, pIIx_init },
+{ Viatech, Via_82C586_0, via_link, via_init },
+{ Viatech, Via_82C596, via_link, via_init },
+{ Viatech, Via_82C686, via_link, via_init },
+{ Opti, Opti_82C700, opti_link, opti_init },
+{ Al, Al_M1533, ali_link, ali_init },
+{ SI, SI_503, pIIx_link, pIIx_init },
+{ SI, SI_496, pIIx_link, pIIx_init },
{ Cyrix, Cyrix_5530_Legacy, cyrix_link, cyrix_init }
};