M pc/clock.c => pc/clock.c +1 -0
@@ 62,6 62,7 @@ clock(Ureg *ur)
checkalarms();
mouseclock();
+ uartintr0(ur);
p = m->proc;
if(p){
M pc/devfloppy.c => pc/devfloppy.c +1 -0
@@ 754,6 754,7 @@ print("new offset %d instead of %d\n", offset, off+dp->len);
static void
floppyintr(Ureg *ur)
{
+print("floppy intr\n");
floppy.intr = 1;
wakeup(&floppy.r);
}
M pc/devuart.c => pc/devuart.c +53 -39
@@ 206,44 206,39 @@ uartintr(Uart *up)
{
int ch;
IOQ *cq;
- int s;
+ int s, l;
+ l = uartrdreg(up, Lstat);
s = uartrdreg(up, Istat);
-print("uartintr %lux\n", s);
- switch(s){
- case 3:
- /*
- * get any input characters
- */
- cq = up->iq;
- while(uartrdreg(up, Lstat) & Inready){
- ch = uartrdreg(up, Data) & 0xff;
- if(cq->putc)
- (*cq->putc)(cq, ch);
- else {
- putc(cq, ch);
- if(up->delim[ch/8] & (1<<(ch&7)) )
- wakeup(&cq->r);
- }
- }
- break;
- case 5:
- /*
- * send next output character
- */
- if(uartrdreg(up, Lstat)&Outready){
- cq = up->oq;
- lock(cq);
- ch = getc(cq);
-print("<cont %2.2ux>", ch);/**/
- if(ch < 0){
- up->printing = 0;
+
+ cq = up->iq;
+ while(l & Inready){
+ ch = uartrdreg(up, Data) & 0xff;
+print("<get %2.2ux>", ch);
+ if(cq->putc)
+ (*cq->putc)(cq, ch);
+ else {
+ putc(cq, ch);
+ if(up->delim[ch/8] & (1<<(ch&7)) )
wakeup(&cq->r);
- }else
- outb(up->port + Data, ch);
- unlock(cq);
}
- break;
+ l = uartrdreg(up, Lstat);
+ }
+
+ /*
+ * send next output character
+ */
+ if(up->printing && (l&Outready)){
+ cq = up->oq;
+ lock(cq);
+ ch = getc(cq);
+print("<put %2.2ux>", ch);/**/
+ if(ch < 0){
+ up->printing = 0;
+ wakeup(&cq->r);
+ }else
+ outb(up->port + Data, ch);
+ unlock(cq);
}
}
void
@@ 263,6 258,8 @@ uartintr1(Ureg *ur)
void
uartenable(Uart *up)
{
+ int x;
+
/*
* set up i/o routines
*/
@@ 287,6 284,15 @@ uartenable(Uart *up)
*/
uartdtr(up, 1);
uartrts(up, 1);
+
+ /*
+ * read interrupt status till there aren't any pending
+ */
+ while(uartrdreg(up, Istat) != 1){
+ x = splhi();
+ uartintr(up);
+ splx(x);
+ }
}
/*
@@ 303,6 309,10 @@ uartspecial(int port, IOQ *oq, IOQ *iq, int baud)
up->iq = iq;
uartenable(up);
uartsetbaud(up, baud);
+ if(port == 0){
+ if(serial(0) < 0)
+ print("can't turn on serial port power\n");
+ }
if(iq){
/*
@@ 366,9 376,14 @@ uartstopen(Queue *q, Stream *s)
Uart *up;
char name[NAMELEN];
- kprint("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n",
+print("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n",
q, s->inuse, s->type, s->dev, s->id);
+
up = &uart[s->id];
+ uartenable(up);
+ if(s->id==0 && serial(0)<0)
+ print("can't turn on serial power\n");
+
qlock(up);
up->wq = WR(q);
WR(q)->ptr = up;
@@ 399,6 414,9 @@ uartstclose(Queue *q)
WR(q)->ptr = 0;
RD(q)->ptr = 0;
qunlock(up);
+
+ if(serial(1) < 0)
+ print("can't turn off serial power\n");
}
static void
@@ 511,9 529,6 @@ uartreset(void)
{
Uart *up;
- if(serial(0) < 0)
- print("can't turn on power\n");
-
uartsetup();
for(up = uart; up < &uart[2]; up++){
if(up->nostream)
@@ 522,7 537,6 @@ uartreset(void)
initq(up->iq);
up->oq = ialloc(sizeof(IOQ), 0);
initq(up->oq);
- uartenable(up);
}
}
M pc/io.h => pc/io.h +2 -2
@@ 7,8 7,8 @@ enum
Int0vec= 16, /* first 8259 */
Clockvec= Int0vec+0, /* clock interrupts */
Kbdvec= Int0vec+1, /* keyboard interrupts */
- Uart0vec= Int0vec+3, /* inerrupt from uart b */
- Uart1vec= Int0vec+4, /* inerrupt from uart a */
+ Uart0vec= Int0vec+3, /* serial line */
+ Uart1vec= Int0vec+4, /* modem line */
Floppyvec= Int0vec+6, /* floppy interrupts */
Int1vec= Int0vec+8, /* second 8259 */
Mousevec= Int1vec+4, /* mouse interrupt */
M pc/l.s => pc/l.s +10 -0
@@ 488,3 488,13 @@ TEXT fpsave(SB),$0
TEXT fprestore(SB),$0
RET
+
+/*
+ * set configuration register
+ */
+TEXT config(SB),$0
+ MOVL l+0(FP),AX
+ MOVL $0x3F3,DX
+ OUTB
+ OUTB
+ RET
M pc/main.c => pc/main.c +14 -1
@@ 285,7 285,12 @@ enum
Pmudata= 0x198,
Pmucsr= 0x199,
- Busy= 0x1,
+ Busy= 0x1,
+
+ /*
+ * configuration port
+ */
+ Pconfig= 0x3F3,
};
/*
@@ 368,6 373,14 @@ pmuwrbit(int index, int bit, int pos)
int
serial(int onoff)
{
+ int x;
+
+ /*
+ * set config (enable everything)
+ */
+ x = splhi();
+ config(0x00);
+ splx(x);
return pmuwrbit(1, onoff, 6);
}
M pc/trap.c => pc/trap.c +25 -1
@@ 176,6 176,9 @@ trap(Ureg *ur)
if(v>=256 || ivec[v] == 0)
panic("bad trap type %d %lux\n", v, ur->pc);
+ if(v==19 || v==20)
+ print("trap = %d\n", v);
+
/*
* tell the 8259 that we're done with the
* highest level interrupt (interrupts are still
@@ 183,9 186,9 @@ trap(Ureg *ur)
*/
c = v&~0x7;
if(c==Int0vec || c==Int1vec){
- outb(Int0ctl, EOI);
if(c == Int1vec)
outb(Int1ctl, EOI);
+ outb(Int0ctl, EOI);
}
/*
@@ 195,6 198,27 @@ trap(Ureg *ur)
}
/*
+ * print 8259 status
+ */
+void
+dump8259(void)
+{
+ int c;
+
+ outb(Int0ctl, 0x0a); /* read ir */
+ print("ir0 %lux\n", inb(Int0ctl));
+ outb(Int0ctl, 0x0b); /* read is */
+ print("is0 %lux\n", inb(Int0ctl));
+ print("im0 %lux\n", inb(Int0aux));
+
+ outb(Int1ctl, 0x0a); /* read ir */
+ print("ir1 %lux\n", inb(Int1ctl));
+ outb(Int1ctl, 0x0b); /* read is */
+ print("is1 %lux\n", inb(Int1ctl));
+ print("im1 %lux\n", inb(Int1aux));
+}
+
+/*
* dump registers
*/
void
M port/page.c => port/page.c +11 -1
@@ 168,16 168,26 @@ newpage(int clear, Segment **s, ulong va)
/* The kp test is a poor guard against the pager deadlocking */
while((palloc.freecount < HIGHWATER && u->p->kp == 0) || palloc.freecount == 0) {
palloc.wanted++;
- unlock(&palloc);
+ unlock(&palloc);
if(s && *s) {
qunlock(&((*s)->lk));
*s = 0;
}
qlock(&palloc.pwait); /* Hold memory requesters here */
+ if(waserror()) {
+ qunlock(&palloc.pwait);
+ lock(&palloc);
+ palloc.wanted--;
+ unlock(&palloc);
+ nexterror();
+ }
+
kickpager();
tsleep(&palloc.r, ispages, 0, 1000);
+ poperror();
+
qunlock(&palloc.pwait);
lock(&palloc);
palloc.wanted--;
M port/pgrp.c => port/pgrp.c +1 -0
@@ 120,6 120,7 @@ newpgrp(void)
p->ref = 1;
p->pgrpid = ++pgrpalloc.pgrpid;
p->nmtab = 0;
+ memset(p->rendhash, 0, sizeof(p->rendhash));
unlock(&pgrpalloc);
return p;
}
M port/portdat.h => port/portdat.h +9 -0
@@ 355,6 355,9 @@ struct Segment
Pte *map[SEGMAPSIZE]; /* segment pte map */
};
+#define RENDHASH 32
+#define REND(p,s) ((p)->rendhash[(s)%RENDHASH])
+
struct Pgrp
{
Ref; /* also used as a lock when mounting */
@@ 365,6 368,7 @@ struct Pgrp
int nmtab; /* highest active mount table entry, +1 */
QLock debug; /* single access via devproc.c */
Mtab *mtab;
+ Proc *rendhash[RENDHASH]; /* Rendezvous tag hash */
};
struct Egrp
@@ 437,6 441,7 @@ enum
Wakeme,
Broken,
Stopped,
+ Rendezvous,
};
/*
@@ 499,6 504,10 @@ struct Proc
int hasspin; /* I hold a spin lock */
int newtlb; /* Pager has touched my tables so I must flush */
int procctl; /* Control for /proc debugging */
+
+ ulong rendtag; /* Tag for rendezvous */
+ ulong rendval; /* Value for rendezvous */
+ Proc *rendhash; /* Hash list for tag values */
/*
* machine specific MMU goo
*/
M port/proc.c => port/proc.c +19 -0
@@ 41,6 41,7 @@ char *statename[]={ /* BUG: generate automatically */
"Wakeme",
"Broken",
"Stopped",
+ "Rendez",
};
/*
@@ 390,6 391,7 @@ postnote(Proc *p, int dolock, char *n, int flag)
KMap *k;
int s;
Rendez *r;
+ Proc *d, **l;
SET(k);
USED(k);
@@ 436,6 438,23 @@ postnote(Proc *p, int dolock, char *n, int flag)
unlock(r);
splx(s);
}
+ if(p->state == Rendezvous) {
+ lock(p->pgrp);
+ if(p->state == Rendezvous) {
+ p->rendval = 0;
+ l = &REND(p->pgrp, p->rendtag);
+ for(d = *l; d; d = d->rendhash) {
+ if(d == p) {
+ *l = p->rendhash;
+ break;
+ }
+ l = &d->rendhash;
+ }
+ ready(p);
+ }
+ unlock(p->pgrp);
+ }
+
return 1;
}
M port/sysproc.c => port/sysproc.c +43 -0
@@ 562,3 562,46 @@ sysbrk_(ulong *arg)
{
return ibrk(arg[0], BSEG);
}
+
+long
+sysrendezvous(ulong *arg)
+{
+ Proc *p, *d, **l;
+ int s, tag;
+ ulong val;
+
+ tag = arg[0];
+ l = &REND(u->p->pgrp, tag);
+
+ lock(u->p->pgrp);
+ for(p = *l; p; p = p->rendhash) {
+ if(p->rendtag == tag) {
+ *l = p->rendhash;
+ val = p->rendval;
+ p->rendval = arg[1];
+
+ if(p->state != Rendezvous)
+ panic("rendezvous");
+ ready(p);
+ unlock(u->p->pgrp);
+ return val;
+ }
+ l = &p->rendhash;
+ }
+
+ /* Going to sleep here */
+ p = u->p;
+ p->rendtag = tag;
+ p->rendval = arg[1];
+ p->rendhash = *l;
+ *l = p;
+
+ unlock(p->pgrp);
+
+ s = splhi();
+ u->p->state = Rendezvous;
+ sched();
+ splx(s);
+
+ return u->p->rendval;
+}
M port/systab.h => port/systab.h +2 -0
@@ 8,6 8,7 @@ Syscall sysfstat, sysfwstat, sysgetpid, sysmount, sysnoted;
Syscall sysnotify, sysopen, syspipe, sysr1, sysread, sysremove, sysseek;
Syscall syssleep, sysstat, syswait, syswrite, syswstat, sysalarm, syssegbrk;
Syscall syssegattach, syssegdetach, syssegfree, syssegflush;
+Syscall sysrendezvous;
Syscall *systab[]={
[SYSR1] sysr1,
@@ 44,4 45,5 @@ Syscall *systab[]={
[SEGDETACH] syssegdetach,
[SEGFREE] syssegfree,
[SEGFLUSH] syssegflush,
+ [RENDEZVOUS] sysrendezvous,
};
M power/boot.c => power/boot.c +0 -1
@@ 485,7 485,6 @@ error(char *s)
* prompt and get input
*/
int
-int
outin(char *prompt, char *def, int len)
{
int n;
M power/devhotrod.c => power/devhotrod.c +3 -2
@@ 13,7 13,6 @@
/*
* If defined, ENABMEMTEST causes memory test to be run at device open
*/
-#define ENABMEMTEST
#ifdef ENABMEMTEST
void mem(Hot*, ulong*, ulong);
#define NTESTBUF 256
@@ 22,6 21,7 @@ ulong testbuf[NTESTBUF];
/*
* If defined, ENABBUSTEST causes bus error diagnostic to be run at device open
*/
+#define ENABBUSTEST
/*
* If 1, ENABCKSUM causes data transfers to have checksums
@@ 224,8 224,9 @@ hotrodopen(Chan *c, int omode)
*/
mp = &u->khot;
mp->cmd = Ubus;
- hmp = hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot, 0);
+ hmp = hotsend(hp, &((User*)(u->p->upage->pa|KZERO))->khot);
hotwait(hmp);
+for(;;) ;
#endif
}
c->mode = openmode(omode);