M pc/fns.h => pc/fns.h +1 -0
@@ 39,6 39,7 @@ void i8042auxenable(void (*)(int, int));
void i8042reset(void);
void i8250console(void);
void* i8250alloc(int, int, int);
+void i8250mouse(char*, int (*)(Queue*, int), int);
void i8253init(void);
void i8253enable(void);
void i8253timerset(uvlong);
M pc/mouse.c => pc/mouse.c +21 -40
@@ 21,6 21,8 @@ enum
Mouseserial= 1,
MousePS2= 2,
};
+
+static QLock mousectlqlock;
static int mousetype;
static int intellimouse;
static int packetsize;
@@ 55,34 57,6 @@ static Cmdtab mousectlmsg[] =
};
/*
- * setup a serial mouse
- */
-static void
-serialmouse(int port, char *type, int setspeed)
-{
-#ifdef notdef
- if(mousetype == Mouseserial)
- error(Emouseset);
-
- if(port >= 3 || port < 0)
- error(Ebadarg);
-
- /* set up /dev/eia? as the mouse */
- if(setspeed)
- setspeed = 1200;
- if(type && *type == 'M')
- uartspecial(port, setspeed, 0, 0, m3mouseputc);
- else
- uartspecial(port, setspeed, 0, 0, mouseputc);
- mousetype = Mouseserial;
- packetsize = 3;
-#else
- error("serial mouse not supported yet");
- USED(port, type, setspeed);
-#endif /* notdef */
-}
-
-/*
* ps/2 mouse message is three bytes
*
* byte 0 - 0 0 SDY SDX 1 M R L
@@ 275,6 249,12 @@ mousectl(Cmdbuf *cb)
{
Cmdtab *ct;
+ qlock(&mousectlqlock);
+ if(waserror()){
+ qunlock(&mousectlqlock);
+ nexterror();
+ }
+
ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
switch(ct->index){
case CMaccelerated:
@@ 309,18 289,16 @@ mousectl(Cmdbuf *cb)
setintellimouse();
break;
case CMserial:
- switch(cb->nf){
- case 1:
- serialmouse(atoi(cb->f[0]+6), 0, 1);
- break;
- case 2:
- serialmouse(atoi(cb->f[1]), 0, 0);
- break;
- case 3:
- default:
- serialmouse(atoi(cb->f[1]), cb->f[2], 0);
- break;
- }
+ if(mousetype == Mouseserial)
+ error(Emouseset);
+
+ if(cb->nf > 2 && *cb->f[2] == 'M')
+ i8250mouse(cb->f[1], m3mouseputc, 0);
+ else
+ i8250mouse(cb->f[1], mouseputc, cb->nf == 1);
+
+ mousetype = Mouseserial;
+ packetsize = 3;
break;
case CMhwaccel:
if(strcmp(cb->f[1], "on")==0)
@@ 330,4 308,7 @@ mousectl(Cmdbuf *cb)
else
cmderror(cb, "bad mouse control message");
}
+
+ qunlock(&mousectlqlock);
+ poperror();
}
M pc/sdata.c => pc/sdata.c +1 -0
@@ 1699,6 1699,7 @@ atapnp(void)
pcicfgw32(p, 0x40, r);
break;
case (0x4D38<<16)|0x105A: /* Promise PDC20262 */
+ case (0x4D30<<16)|0x105A: /* Promise PDC202xx */
pi = 0x85;
break;
case (0x0640<<16)|0x1095: /* CMD 640B */
M pc/uarti8250.c => pc/uarti8250.c +12 -0
@@ 671,3 671,15 @@ i8250console(void)
consuart = uart;
uart->console = 1;
}
+
+void
+i8250mouse(char* which, int (*putc)(Queue*, int), int setb1200)
+{
+ char *p;
+ int port;
+
+ port = strtol(which, &p, 0);
+ if(p == which || port < 0 || port > 1)
+ error(Ebadarg);
+ uartmouse(&i8250uart[port], putc, setb1200);
+}
M port/devrealtime.c => port/devrealtime.c +10 -0
@@ 495,6 495,16 @@ devrtread(Chan *c, void *v, long n, vlong offs)
}
p = seprint(p, e, "'");
}
+ if (t->periods)
+ p = seprint(p, e, " n=%lud", t->periods);
+ if (t->missed)
+ p = seprint(p, e, " m=%lud", t->missed);
+ if (t->preemptions)
+ p = seprint(p, e, " p=%lud", t->preemptions);
+ if (t->total)
+ p = seprint(p, e, " t=%T", ticks2time(t->total));
+ if (t->aged)
+ p = seprint(p, e, " c=%T", ticks2time(t->aged));
seprint(p, e, "\n");
return readstr(offs, v, n, buf);
}
M port/devuart.c => port/devuart.c +15 -0
@@ 112,6 112,21 @@ uartdisable(Uart *p)
unlock(&uartalloc);
}
+void
+uartmouse(Uart* p, int (*putc)(Queue*, int), int setb1200)
+{
+ qlock(p);
+ if(p->opens++ == 0 && uartenable(p) == nil){
+ qunlock(p);
+ error(Enodev);
+ }
+ if(setb1200)
+ uartctl(p, "b1200");
+ p->putc = putc;
+ p->special = 1;
+ qunlock(p);
+}
+
static void
setlength(int i)
{
M port/edf.c => port/edf.c +13 -2
@@ 252,6 252,7 @@ static void
deadline(Proc *p, SEvent why)
{
Task *t, *nt;
+ Ticks used;
/* Task has reached its deadline, lock must be held */
DPRINT("%d deadline, %s, %d\n", m->machno, edfstatename[p->task->state], p->task->runq.n);
@@ 272,6 273,11 @@ deadline(Proc *p, SEvent why)
timerdel(&deadlinetimer[m->machno]);
deadlinetimer[m->machno].when = 0;
}
+ used = now - t->scheduled;
+ t->S -= used;
+ t->scheduled = now;
+ t->total += used;
+ t->aged = (t->aged*31 + t->C - t->S) >> 5;
t->d = now;
t->state = EdfDeadline;
if(devrt) devrt(t, now, why);
@@ 330,6 336,7 @@ edfadmit(Task *t)
t->S = t->C;
t->scheduled = now;
t->state = EdfRunning;
+ t->periods++;
if(devrt) devrt(t, now, SRun);
setdelta();
assert(t->runq.n > 0 || (up && up->task == t));
@@ 457,6 464,7 @@ edfdeadlineintr(Ureg*, Timer*)
used = now - t->scheduled;
t->scheduled = now;
+ t->total += used;
if (t->r < now){
if (t->S <= used)
@@ 466,8 474,10 @@ edfdeadlineintr(Ureg*, Timer*)
if (t->d <= now || t->S == 0LL){
/* Task has reached its deadline/slice, remove from queue */
- if (t->S > 0LL)
+ if (t->d <= now){
+ t->missed++;
misseddeadlines++;
+ }
deadline(up, SSlice);
while (t = edfstack[m->machno].head){
if (now < t->d)
@@ 728,9 738,9 @@ edfrunproc(void)
edfdequeue(&qreleased);
assert(nt->runq.n >= 1);
edfpush(nt);
- nt->state = EdfRunning;
t = nt;
t->scheduled = now;
+ t->periods++;
}else{
DPRINT("%d edfrunproc: current\n", m->machno);
}
@@ 741,6 751,7 @@ runt:
* No need to lock runq, edflock always held to access runq
*/
t->state = EdfRunning;
+ t->periods++;
p = t->runq.head;
if ((t->runq.head = p->rnext) == nil)
t->runq.tail = nil;
M port/edf.h => port/edf.h +6 -0
@@ 51,6 51,12 @@ struct Edf {
int testtype; /* Release or Deadline */
Ticks testtime;
Task * testnext;
+ /* statistics gathering */
+ ulong periods; /* number of periods */
+ ulong missed; /* number of deadlines missed */
+ ulong preemptions;
+ Ticks total; /* total time used */
+ Ticks aged; /* aged time used */
/* other */
Edfstate state;
};
M port/portfns.h => port/portfns.h +1 -0
@@ 340,6 340,7 @@ void tsleep(Rendez*, int (*)(void*), void*, int);
int uartctl(Uart*, char*);
int uartgetc(void);
void uartkick(void*);
+void uartmouse(Uart*, int (*)(Queue*, int), int);
void uartputc(int);
void uartputs(char*, int);
void uartrecv(Uart*, char);