M pc/clock.c => pc/clock.c +5 -1
@@ 60,9 60,13 @@ clock(Ureg *ur)
m->ticks++;
+ uartintr0(ur);
+
+ if(m->ticks % 50)
+ return;
+
checkalarms();
mouseclock();
- uartintr0(ur);
p = m->proc;
if(p){
M pc/devuart.c => pc/devuart.c +38 -18
@@ 51,6 51,7 @@ struct Uart
int port;
uchar sticky[8]; /* sticky write register values */
int printing; /* true if printing */
+ int enabled;
/* console interface */
int nostream; /* can't use the stream interface */
@@ 185,7 186,6 @@ uartputs(IOQ *cq, char *s, int n)
puts(cq, s, n);
if(up->printing == 0){
ch = getc(cq);
-print("<start %2.2ux>", ch);/**/
if(ch >= 0){
up->printing = 1;
for(tries = 0; tries<10000 && !(uartrdreg(up, Lstat)&Outready);
@@ 214,7 214,6 @@ uartintr(Uart *up)
cq = up->iq;
while(l & Inready){
ch = uartrdreg(up, Data) & 0xff;
-print("<get %2.2ux>", ch);
if(cq->putc)
(*cq->putc)(cq, ch);
else {
@@ 232,7 231,6 @@ print("<get %2.2ux>", ch);
cq = up->oq;
lock(cq);
ch = getc(cq);
-print("<put %2.2ux>", ch);/**/
if(ch < 0){
up->printing = 0;
wakeup(&cq->r);
@@ 244,7 242,8 @@ print("<put %2.2ux>", ch);/**/
void
uartintr0(Ureg *ur)
{
- uartintr(&uart[0]);
+ if(uart[0].enabled)
+ uartintr(&uart[0]);
}
void
uartintr1(Ureg *ur)
@@ 261,6 260,14 @@ uartenable(Uart *up)
int x;
/*
+ * turn on power to the port
+ */
+ if(up == &uart[0]){
+ if(serial(0) < 0)
+ print("can't turn on serial port power\n");
+ }
+
+ /*
* set up i/o routines
*/
if(up->oq){
@@ 272,6 279,7 @@ uartenable(Uart *up)
up->iq->ptr = up;
up->sticky[Iena] |= Ircv;
}
+ up->enabled = 1;
up->sticky[Iena] |= (1<<2) | (1<<3);
/*
@@ 284,14 292,33 @@ uartenable(Uart *up)
*/
uartdtr(up, 1);
uartrts(up, 1);
+}
+
+/*
+ * turn off the uart
+ */
+uartdisable(Uart *up)
+{
/*
- * read interrupt status till there aren't any pending
+ * turn off interrupts
*/
- while(uartrdreg(up, Istat) != 1){
- x = splhi();
- uartintr(up);
- splx(x);
+ up->sticky[Iena] = 0;
+ uartwrreg(up, Iena, 0);
+
+ /*
+ * turn off DTR and RTS
+ */
+ uartdtr(up, 0);
+ uartrts(up, 0);
+ up->enabled = 0;
+
+ /*
+ * turn off power
+ */
+ if(up == &uart[0]){
+ if(serial(1) < 0)
+ print("can't turn off serial power\n");
}
}
@@ 309,10 336,6 @@ 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){
/*
@@ 381,8 404,6 @@ print("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n",
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);
@@ 407,6 428,8 @@ uartstclose(Queue *q)
{
Uart *up = q->ptr;
+ uartdisable(up);
+
qlock(up);
kprint("uartstclose: q=0x%ux, id=%d\n", q, up-uart);
up->wq = 0;
@@ 414,9 437,6 @@ 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
M pc/l.s => pc/l.s +6 -0
@@ 390,28 390,34 @@ TEXT intrbad(SB),$0
intrcommon:
PUSHL DS
+ PUSHL ES
PUSHAL
MOVL $(KDSEL),AX
MOVW AX,DS
+ MOVW AX,ES
LEAL 0(SP),AX
PUSHL AX
CALL trap(SB)
POPL AX
POPAL
+ POPL ES
POPL DS
ADDL $8,SP /* error code and trap type */
IRETL
intrscommon:
PUSHL DS
+ PUSHL ES
PUSHAL
MOVL $(KDSEL),AX
MOVW AX,DS
+ MOVW AX,ES
LEAL 0(SP),AX
PUSHL AX
CALL trap(SB)
POPL AX
POPAL
+ POPL ES
POPL DS
ADDL $8,SP /* error code and trap type */
IRETL
M pc/mem.h => pc/mem.h +2 -2
@@ 18,7 18,7 @@
/*
* Time
*/
-#define HZ (20) /* clock frequency */
+#define HZ (1000) /* clock frequency */
#define MS2HZ (1000/HZ) /* millisec per clock tick */
#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */
@@ 43,7 43,7 @@
#define KZERO 0x80000000 /* base of kernel address space */
#define KTZERO KZERO /* first address in kernel text */
#define USERADDR 0xC0000000 /* struct User */
-#define UREGADDR (USERADDR+BY2PG-4*16)
+#define UREGADDR (USERADDR+BY2PG-4*17)
#define TSTKTOP USERADDR /* end of new stack in sysexec */
#define TSTKSIZ 10
#define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */
M pc/trap.c => pc/trap.c +4 -2
@@ 173,8 173,10 @@ trap(Ureg *ur)
int c;
v = ur->trap;
- if(v>=256 || ivec[v] == 0)
- panic("bad trap type %d %lux\n", v, ur->pc);
+ if(v>=256 || ivec[v] == 0){
+ print("bad trap type %d %lux %lux %lux\n", v, ur->pc, int0mask, int1mask);
+ return;
+ }
if(v==19 || v==20)
print("trap = %d\n", v);
M port/devcons.c => port/devcons.c +0 -1
@@ 141,7 141,6 @@ panic(char *fmt, ...)
char buf[PRINTSIZE];
int n;
- print("panic: %lux m=%lux\n", &fmt, m);
strcpy(buf, "panic: ");
n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
buf[n] = '\n';
M port/devproc.c => port/devproc.c +1 -1
@@ 27,7 27,7 @@ Dirtab procdir[]={
"notepg", {Qnotepg}, 0, 0200,
"proc", {Qproc}, sizeof(Proc), 0600,
"segment", {Qsegment}, 0, 0400,
- "status", {Qstatus}, STATSIZE, 0600,
+ "status", {Qstatus}, STATSIZE, 0400,
"text", {Qtext}, 0, 0600,
};
M port/page.c => port/page.c +2 -1
@@ 64,7 64,8 @@ ialloc(ulong n, int align)
print("ialloc bad\n");
if(palloc.addr0 == 0){
- palloc.addr0 = ((ulong)&end)&~KZERO;
+ /* addr0 and addr1 are physical addresses */
+ palloc.addr0 = (((ulong)&end)&~KZERO) + conf.base0;
palloc.addr1 = conf.base1;
}
M port/portdat.h => port/portdat.h +7 -0
@@ 415,6 415,13 @@ enum /* Argument to forkpgrp call */
FPclear = 8,
};
+enum
+{
+ Forkpg = 1,
+ Forkeg = 2,
+ Forkfd = 4,
+};
+
/*
* process memory segments - NSEG always last !
*/
M port/proc.c => port/proc.c +7 -3
@@ 302,8 302,10 @@ sleep1(Rendez *r, int (*f)(void*), void *arg)
* now we are committed to
* change state and call scheduler
*/
- if(r->p)
+ if(r->p){
print("double sleep %d %d\n", r->p->pid, p->pid);
+ dumpstack();
+ }
p->state = Wakeme;
r->p = p;
unlock(r);
@@ 438,10 440,11 @@ 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;
+ p->rendval = ~0;
l = &REND(p->pgrp, p->rendtag);
for(d = *l; d; d = d->rendhash) {
if(d == p) {
@@ 674,7 677,8 @@ procdump(void)
p = procalloc.arena+i;
if(p->state != Dead){
print("%d:%s %s upc %lux %s ut %ld st %ld r %lux\n",
- p->pid, p->text, p->pgrp ? p->pgrp->user : "pgrp=0", p->pc,
+ p->pid, p->text,
+ p->pgrp ? p->pgrp->user : "pgrp=0", p->pc,
statename[p->state], p->time[0], p->time[1], p->r);
}
}
M port/sysproc.c => port/sysproc.c +44 -10
@@ 9,6 9,7 @@
#include <a.out.h>
int shargs(char*, int, char**);
+long rfork(ulong);
long
sysr1(ulong *arg)
@@ 20,6 21,19 @@ sysr1(ulong *arg)
long
sysfork(ulong *arg)
{
+ return rfork(Forkfd|Forkeg|Forkpg);
+}
+
+/* This call will obsolete fork */
+long
+sysrfork(ulong *arg)
+{
+ return rfork(arg[0]);
+}
+
+long
+rfork(ulong flag)
+{
Proc *p;
Segment *s;
Page *np, *op;
@@ 27,7 41,10 @@ sysfork(ulong *arg)
Chan *c;
KMap *k;
int n, on, i;
- int lastvar; /* used to compute stack address */
+ /*
+ * used to compute last valid system stack address for copy
+ */
+ int lastvar;
p = newproc();
@@ 56,13 73,31 @@ sysfork(ulong *arg)
* Refs
*/
incref(u->dot); /* File descriptors etc. */
- p->fgrp = dupfgrp(u->p->fgrp);
- p->pgrp = u->p->pgrp; /* Process groups */
- incref(p->pgrp);
+ if(flag & Forkfd)
+ p->fgrp = dupfgrp(u->p->fgrp);
+ else {
+ p->fgrp = u->p->fgrp;
+ incref(p->fgrp);
+ }
- p->egrp = u->p->egrp; /* Environment group */
- incref(p->egrp);
+ if(flag & Forkpg) {
+ p->pgrp = u->p->pgrp; /* Process groups */
+ incref(p->pgrp);
+ }
+ else {
+ p->pgrp = newpgrp();
+ pgrpcpy(p->pgrp, u->p->pgrp);
+ }
+
+ if(flag & Forkeg) {
+ p->egrp = u->p->egrp; /* Environment group */
+ incref(p->egrp);
+ }
+ else {
+ p->egrp = newegrp();
+ envcpy(p->egrp, u->p->egrp);
+ }
/*
* Sched
@@ 580,8 615,8 @@ sysrendezvous(ulong *arg)
val = p->rendval;
p->rendval = arg[1];
- if(p->state != Rendezvous)
- panic("rendezvous");
+ while(p->state != Rendezvous)
+ ;
ready(p);
unlock(u->p->pgrp);
return val;
@@ 596,9 631,8 @@ sysrendezvous(ulong *arg)
p->rendhash = *l;
*l = p;
- unlock(p->pgrp);
-
s = splhi();
+ unlock(p->pgrp);
u->p->state = Rendezvous;
sched();
splx(s);
M port/systab.h => port/systab.h +2 -2
@@ 8,7 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 sysrendezvous, sysrfork;
Syscall *systab[]={
[SYSR1] sysr1,
@@ 34,7 34,7 @@ Syscall *systab[]={
[WRITE] syswrite,
[PIPE] syspipe,
[CREATE] syscreate,
- [___USERSTR___] sysdeath,
+ [RFORK] sysrfork,
[BRK_] sysbrk_,
[REMOVE] sysremove,
[WSTAT] syswstat,