M bitsy/clock.c => bitsy/clock.c +17 -11
@@ 9,11 9,11 @@
typedef struct OSTimer
{
- ulong osmr[4]; /* match registers */
- ulong oscr; /* counter register */
- ulong ossr; /* status register */
- ulong ower; /* watchdog enable register */
- ulong oier; /* timer interrupt enable register */
+ ulong osmr[4]; /* match registers */
+ volatile ulong oscr; /* counter register */
+ ulong ossr; /* status register */
+ ulong ower; /* watchdog enable register */
+ ulong oier; /* timer interrupt enable register */
} OSTimer;
OSTimer *timerregs = (OSTimer*)OSTIMERREGS;
@@ 23,7 23,7 @@ static void clockintr(Ureg*, void*);
enum
{
- Minfreq = ClockFreq/HZ, /* At least one interrupt per HZ (10 ms) */
+ Minfreq = ClockFreq/HZ, /* At least one interrupt per HZ (50 ms) */
Maxfreq = ClockFreq/10000, /* At most one interrupt every 100 µs */
};
@@ 79,7 79,7 @@ clockinit(void)
vlong
fastticks(uvlong *hz)
{
- static vlong high;
+ static uvlong high;
static ulong last;
ulong x;
@@ 93,9 93,10 @@ fastticks(uvlong *hz)
}
void
-timerset(vlong v)
+timerset(uvlong v)
{
- ulong when; /* Must be unsigned! */
+ ulong when, tics; /* Must be unsigned! */
+ static int count;
if (v == 0LL)
when = timerregs->oscr + Minfreq;
@@ 103,9 104,11 @@ timerset(vlong v)
when = v;
/* post next interrupt: calculate # of tics from now */
- when = when - timerregs->oscr - Maxfreq;
- if (when - timerregs->oscr > Minfreq)
+ tics = when - timerregs->oscr - Maxfreq;
+ if (tics > Minfreq){
+ iprint("%lud %lud %lud %d\n", when, tics, timerregs->oscr, Minfreq);
when = timerregs->oscr + Maxfreq;
+ }
}
timerregs->osmr[0] = when;
}
@@ 113,11 116,14 @@ timerset(vlong v)
static void
clockintr(Ureg *ureg, void*)
{
+ static ulong count;
/* reset previous interrupt */
timerregs->ossr |= 1<<0;
timerset(timerintr(ureg, nil));
+ if ((count++ % 100) == 0)
+ iprint("%lud ", timerregs->osmr[0] - timerregs->oscr);
}
void
M bitsy/dat.h => bitsy/dat.h +2 -2
@@ 268,8 268,8 @@ struct DevConf
*/
struct Timer
{
- vlong when; /* fastticks when f should be called */
- vlong period; /* non-zero for recurring periodic timers */
+ uvlong when; /* fastticks when f should be called */
+ ulong period; /* non-zero for recurring periodic timers */
void (*f)(Ureg*, Timer*); /* function to call */
void *a; /* User parameter */
Timer *next;
M bitsy/fns.h => bitsy/fns.h +2 -2
@@ 103,8 103,8 @@ uchar* tarlookup(uchar*, char*, int*);
void timersinit(void);
void timeradd(Timer*);
void timerdel(Timer*);
-vlong timerintr(Ureg *, void*);
-void timerset(vlong);
+uvlong timerintr(Ureg *, void*);
+void timerset(uvlong);
void touser(void*);
void trapdump(char *tag);
void trapinit(void);
M pc/clock.c => pc/clock.c +0 -2
@@ 10,11 10,9 @@
* this is called both by the mp's clock interrupt and
* by the clockintr0 for the i8253
*/
-int nclockintr;
void
clockintr(Ureg* ureg, void*)
{
-nclockintr++;
/* this has to get called every tick or the 8253 timer will overflow */
fastticks(nil);
M pc/i8253.c => pc/i8253.c +8 -2
@@ 241,13 241,13 @@ clockintrsched(void)
iunlock(&i8253);
}
-int nclockintr0;
+ulong i8253ding[2];
+
static void
clockintr0(Ureg* ureg, void *v)
{
vlong now, when;
-nclockintr0++;
/* goes with syncing in squidboy */
if(m->havetsc)
rdtsc(&m->lasttsc);
@@ 255,6 255,12 @@ nclockintr0++;
now = fastticks(nil);
when = i8253.when;
+if(i8253.last1 == 0 || i8253.last1 >= 0xffe0)
+ i8253ding[1]++;
+else
+ i8253ding[0]++;
+
+
if(now >= i8253.when){
clockintr(ureg, v);
do
M port/devwpsd.c => port/devwpsd.c +13 -9
@@ 34,6 34,8 @@ enum
{
CMpart,
CMdelpart,
+ CMwpenable,
+ CMwpblocks,
CMwildcard,
};
@@ 41,6 43,8 @@ Cmdtab ctlmsg[] =
{
CMpart, "part", 3,
CMdelpart, "delpart", 1,
+ CMwpenable, "wpenable", 0,
+ CMwpblocks, "wpblocks", 2,
CMwildcard, "*", 0,
};
@@ 719,7 723,7 @@ sdclose(Chan* c)
}
static long
-sdbio(Chan* c, int write, char* a, long len, vlong off)
+sdio(Chan* c, int write, char* a, long len, vlong off)
{
int nchange;
long l;
@@ 785,11 789,11 @@ sdbio(Chan* c, int write, char* a, long len, vlong off)
poperror();
}
- b = sdmalloc(nb*unit->secsize);
+ b = malloc(nb*unit->secsize);
if(b == nil)
error(Enomem);
if(waserror()){
- sdfree(b);
+ free(b);
if(!(unit->inquiry[1] & 0x80))
decref(&sdev->r); /* gadverdamme! */
nexterror();
@@ 829,7 833,7 @@ sdbio(Chan* c, int write, char* a, long len, vlong off)
len = l - offset;
memmove(a, b+offset, len);
}
- sdfree(b);
+ free(b);
poperror();
if(unit->inquiry[1] & 0x80){
@@ 851,7 855,7 @@ sdrio(SDreq* r, void* a, long n)
data = nil;
if(n){
- if((data = sdmalloc(n)) == nil)
+ if((data = malloc(n)) == nil)
error(Enomem);
if(r->write)
memmove(data, a, n);
@@ 861,7 865,7 @@ sdrio(SDreq* r, void* a, long n)
if(waserror()){
if(data != nil){
- sdfree(data);
+ free(data);
r->data = nil;
}
nexterror();
@@ 873,7 877,7 @@ sdrio(SDreq* r, void* a, long n)
if(!r->write && r->rlen > 0)
memmove(a, data, r->rlen);
if(data != nil){
- sdfree(data);
+ free(data);
r->data = nil;
}
poperror();
@@ 986,7 990,7 @@ sdread(Chan *c, void *a, long n, vlong off)
return i;
case Qpart:
- return sdbio(c, 0, a, n, off);
+ return sdio(c, 0, a, n, off);
}
return 0;
@@ 1238,7 1242,7 @@ sdwrite(Chan* c, void* a, long n, vlong off)
poperror();
break;
case Qpart:
- return sdbio(c, 1, a, n, off);
+ return sdio(c, 1, a, n, off);
}
return n;
M port/proc.c => port/proc.c +0 -6
@@ 107,9 107,6 @@ schedinit(void) /* never returns */
break;
}
up->mach = 0;
-#ifdef RSC
-le('e', up);
-#endif
up = nil;
}
sched();
@@ 143,9 140,6 @@ sched(void)
gotolabel(&m->sched);
}
up = runproc();
-#ifdef RSC
-le('u',up);
-#endif
up->state = Running;
up->mach = MACHP(m->machno);
m->proc = up;
M port/sd.h => port/sd.h +35 -12
@@ 7,22 7,42 @@ typedef struct SDpart SDpart;
typedef struct SDperm SDperm;
typedef struct SDreq SDreq;
typedef struct SDunit SDunit;
+typedef struct SDwp SDwp;
+typedef struct SDcache SDcache;
-typedef struct SDperm {
+enum {
+ SDcachesize = 20,
+};
+
+struct SDperm {
char* name;
char* user;
ulong perm;
-} SDperm;
+};
-typedef struct SDpart {
+struct SDpart {
ulong start;
ulong end;
SDperm;
int valid;
ulong vers;
-} SDpart;
+};
+
+struct SDcache {
+ ulong age;
+ ulong bn;
+ uchar *data;
+};
-typedef struct SDunit {
+struct SDwp {
+ QLock;
+ ulong age;
+ ulong start;
+ ulong end;
+ SDcache cache[SDcachesize];
+};
+
+struct SDunit {
SDev* dev;
int subno;
uchar inquiry[256]; /* format follows SCSI spec */
@@ 42,14 62,17 @@ typedef struct SDunit {
int state;
SDreq* req;
SDperm rawperm;
-} SDunit;
+
+ int wpunit; /* whole unit is write protected */
+ SDwp *wp; /* block level write prtection */
+};
/*
* Each controller is represented by a SDev.
* Each controller is responsible for allocating its unit structures.
* Each controller has at least one unit.
*/
-typedef struct SDev {
+struct SDev {
Ref r; /* Number of callers using device */
SDifc* ifc; /* pnp/legacy */
void* ctlr;
@@ 63,9 86,9 @@ typedef struct SDev {
QLock unitlock; /* `Loading' of units */
int* unitflg; /* Unit flags */
SDunit**unit;
-} SDev;
+};
-typedef struct SDifc {
+struct SDifc {
char* name;
SDev* (*pnp)(void);
@@ 84,9 107,9 @@ typedef struct SDifc {
SDev* (*probe)(DevConf*);
void (*clear)(SDev*);
char* (*stat)(SDev*, char*, char*);
-} SDifc;
+};
-typedef struct SDreq {
+struct SDreq {
SDunit* unit;
int lun;
int write;
@@ 100,7 123,7 @@ typedef struct SDreq {
int status;
long rlen;
uchar sense[256];
-} SDreq;
+};
enum {
SDnosense = 0x00000001,
M port/taslock.c => port/taslock.c +6 -2
@@ 162,11 162,15 @@ unlock(Lock *l)
if(l->p != up)
print("unlock: up changed: pc %lux, acquired at pc %lux, lock p 0x%p, unlock up 0x%p\n", getcallerpc(&l), l->pc, l->p, up);
l->key = 0;
- if (up && --up->nlocks == 0 && up->delaysched){
+ coherence();
+
+ /* give up the processor if ... */
+ if(up && --up->nlocks == 0 /* we've closed the last nexted lock */
+ && up->delaysched /* we delayed scheduling because of the lock */
+ && up->state == Running){ /* we're in running state */
up->delaysched = 0;
sched();
}
- coherence();
}
void