M gnot/dat.h => gnot/dat.h +1 -0
@@ 187,6 187,7 @@ struct KMap
ulong pa;
ulong va;
};
+#define VA(k) ((k)->va)
struct Mach
{
M gnot/devproc.c => gnot/devproc.c +4 -4
@@ 255,7 255,7 @@ procread(Chan *c, void *va, long n)
memset(a, 0, n);
}else{
k = kmap(pg);
- b = (char*)k->va;
+ b = (char*)VA(k);
memcpy(a, b+(c->offset&(BY2PG-1)), n);
kunmap(k);
}
@@ 270,7 270,7 @@ procread(Chan *c, void *va, long n)
if(pg==0 || (p->pid&PIDMASK)!=PID(c->qid))
error(0, Eprocdied);
k = kmap(pg);
- b = (char*)k->va;
+ b = (char*)VA(k);
memcpy(a, b+(c->offset-USERADDR), n);
kunmap(k);
return n;
@@ 295,7 295,7 @@ procread(Chan *c, void *va, long n)
if((p->pid&PIDMASK) != PID(c->qid))
error(0, Eprocdied);
k = kmap(p->upage);
- up = (User*)k->va;
+ up = (User*)VA(k);
if(up->p != p){
kunmap(k);
pprint("note read u/p mismatch");
@@ 372,7 372,7 @@ procwrite(Chan *c, void *va, long n)
break;
case Qnote:
k = kmap(p->upage);
- up = (User*)k->va;
+ up = (User*)VA(k);
if(up->p != p){
kunmap(k);
pprint("note write u/p mismatch");
M gnot/fault.c => gnot/fault.c +2 -2
@@ 163,7 163,7 @@ fault(Ureg *ur, FFrame *f)
goto cant;
}
o->chan->offset = (addr-o->va) + o->minca;
- l = (char*)k->va;
+ l = (char*)VA(k);
if((*devtab[o->chan->type].read)(o->chan, l, n) != n)
error(0, Eioload);
qunlock(o->chan);
@@ 239,7 239,7 @@ fault(Ureg *ur, FFrame *f)
pte->page = newpage(1, o, addr);
k = kmap(pte->page);
k1 = kmap(pg);
- memcpy((void*)k->va, (void*)k1->va, BY2PG);
+ memcpy((void*)VA(k), (void*)VA(k1), BY2PG);
kunmap(k);
kunmap(k1);
if(pg->ref <= 1)
M gnot/main.c => gnot/main.c +2 -2
@@ 140,7 140,7 @@ userinit(void)
* User
*/
k = kmap(p->upage);
- up = (User*)k->va;
+ up = (User*)VA(k);
up->p = p;
kunmap(k);
@@ 161,7 161,7 @@ userinit(void)
s->o = neworig(UTZERO, 1, 0, 0);
s->o->pte[0].page = newpage(0, 0, UTZERO);
k = kmap(s->o->pte[0].page);
- memcpy((ulong*)k->va, initcode, sizeof initcode);
+ memcpy((ulong*)VA(k), initcode, sizeof initcode);
kunmap(k);
s->minva = UTZERO;
s->maxva = UTZERO+BY2PG;
M gnot/page.c => gnot/page.c +1 -1
@@ 213,7 213,7 @@ loop:
unlock(&palloc);
if(!noclear){
k = kmap(p);
- memset((void*)k->va, 0, BY2PG);
+ memset((void*)VA(k), 0, BY2PG);
kunmap(k);
}
p->o = o;
M gnot/proc.c => gnot/proc.c +4 -4
@@ 310,7 310,7 @@ postnote(Proc *p, int dolock, char *n, int flag)
if(dolock)
lock(&p->debug);
k = kmap(p->upage);
- up = (User*)k->va;
+ up = (User*)VA(k);
if(flag!=NUser && (up->notify==0 || up->notified))
up->nnote = 0; /* force user's hand */
else if(up->nnote == NNOTE-1){
@@ 529,8 529,8 @@ again:
p->child = 0;
k = kmap(c->upage);
if(w)
- *w = *(Waitmsg*)(p->waitmsg|k->va);
- cpid = ((Waitmsg*)(p->waitmsg|k->va))->pid;
+ *w = *(Waitmsg*)(p->waitmsg|VA(k));
+ cpid = ((Waitmsg*)(p->waitmsg|VA(k)))->pid;
kunmap(k);
p->time[TCUser] += c->time[TUser] + c->time[TCUser];
p->time[TCSys] += c->time[TSys] + c->time[TCSys];
@@ 580,7 580,7 @@ kproc(char *name, void (*func)(void *), void *arg)
p = newproc();
p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
k = kmap(p->upage);
- upa = k->va;
+ upa = VA(k);
up = (User*)upa;
up->p = p;
M gnot/sysproc.c => gnot/sysproc.c +4 -4
@@ 36,7 36,7 @@ sysfork(ulong *arg)
p = newproc();
p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
k = kmap(p->upage);
- upa = k->va;
+ upa = VA(k);
/*
* Save time: only copy u-> data and useful stack
@@ 77,11 77,11 @@ sysfork(ulong *arg)
k = kmap(np);
p->seg[SSEG].o->pte[i].page = np;
if(i == 0){ /* only part of last stack page */
- memset((void*)k->va, 0, usp);
- memcpy((void*)(k->va+usp),
+ memset((void*)VA(k), 0, usp);
+ memcpy((void*)(VA(k)+usp),
(void*)(op->va+usp), BY2PG-usp);
}else /* all of higher pages */
- memcpy((void*)k->va, (void*)op->va, BY2PG);
+ memcpy((void*)VA(k), (void*)op->va, BY2PG);
kunmap(k);
}
}
M port/devcons.c => port/devcons.c +3 -3
@@ 315,7 315,7 @@ ulong boottime; /* seconds since epoch at boot */
long
seconds(void)
{
- return boottime + MACHP(0)->ticks*MS2HZ/1000;
+ return boottime + TK2MS(MACHP(0)->ticks);
}
int
@@ 470,7 470,7 @@ consread(Chan *c, void *buf, long n)
l = u->p->time[i];
if(i == TReal)
l = MACHP(0)->ticks - l;
- l *= MS2HZ;
+ l = TK2MS(l);
readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE);
}
memcpy(buf, tmp+k, n);
@@ 486,7 486,7 @@ consread(Chan *c, void *buf, long n)
return readnum(c->offset, buf, n, u->p->parentpid, NUMSIZE);
case Qtime:
- return readnum(c->offset, buf, n, boottime+MACHP(0)->ticks/(1000/MS2HZ), 12);
+ return readnum(c->offset, buf, n, boottime+TK2MS(MACHP(0)->ticks), 12);
case Quser:
return readstr(c->offset, buf, n, u->p->pgrp->user);
M port/devproc.c => port/devproc.c +33 -14
@@ 147,15 147,12 @@ procopen(Chan *c, int omode)
case Qnote:
break;
case Qdir:
+ case Qmem:
case Qproc:
case Qstatus:
if(omode!=OREAD)
error(0, Eperm);
break;
- case Qmem:
- if(omode!=OREAD)
- error(0, Eperm);
- break;
default:
pprint("unknown qid in devopen\n");
error(0, Egreg);
@@ 204,6 201,8 @@ procread(Chan *c, void *va, long n)
Seg *s;
Orig *o;
Page *pg;
+ KMap *k;
+ PTE *pte, *opte;
int i;
long l;
long pid;
@@ 240,14 239,25 @@ procread(Chan *c, void *va, long n)
unlock(o);
error(0, Egreg);
}
- pg = o->pte[(c->offset-o->va)>>PGSHIFT].page;
+ pte = &o->pte[(c->offset-o->va)>>PGSHIFT];
+ if(s->mod){
+ opte = pte;
+ while(pte = pte->nextmod) /* assign = */
+ if(pte->proc == p)
+ break;
+ if(pte == 0)
+ pte = opte;
+ }
+ pg = pte->page;
unlock(o);
if(pg == 0){
- pprint("nonresident page (complain to rob)\n");
+ pprint("nonresident page addr %lux (complain to rob)\n", c->offset);
memset(a, 0, n);
}else{
- b = (char*)(pg->pa|KZERO);
+ k = kmap(pg);
+ b = (char*)VA(k);
memcpy(a, b+(c->offset&(BY2PG-1)), n);
+ kunmap(k);
}
return n;
}
@@ 259,15 269,17 @@ procread(Chan *c, void *va, long n)
pg = p->upage;
if(pg==0 || (p->pid&PIDMASK)!=PID(c->qid))
error(0, Eprocdied);
- b = (char*)(pg->pa|KZERO);
+ k = kmap(pg);
+ b = (char*)VA(k);
memcpy(a, b+(c->offset-USERADDR), n);
+ kunmap(k);
return n;
}
/* kernel memory. BUG: shouldn't be so easygoing. BUG: mem mapping? */
- if(c->offset>=KZERO && c->offset<KZERO+conf.npage*BY2PG){
- if(c->offset+n > KZERO+conf.npage*BY2PG)
- n = KZERO+conf.npage*BY2PG - c->offset;
+ if(c->offset>=KZERO && c->offset<KZERO+conf.npage0*BY2PG){
+ if(c->offset+n > KZERO+conf.npage0*BY2PG)
+ n = KZERO+conf.npage0*BY2PG - c->offset;
memcpy(a, (char*)c->offset, n);
return n;
}
@@ 282,8 294,10 @@ procread(Chan *c, void *va, long n)
}
if((p->pid&PIDMASK) != PID(c->qid))
error(0, Eprocdied);
- up = (User*)(p->upage->pa|KZERO);
+ k = kmap(p->upage);
+ up = (User*)VA(k);
if(up->p != p){
+ kunmap(k);
pprint("note read u/p mismatch");
error(0, Egreg);
}
@@ 297,6 311,7 @@ procread(Chan *c, void *va, long n)
memcpy(&up->note[0], &up->note[1], up->nnote*sizeof(Note));
n = ERRLEN;
}
+ kunmap(k);
unlock(&p->debug);
return n;
@@ 318,7 333,7 @@ procread(Chan *c, void *va, long n)
l = p->time[i];
if(i == TReal)
l = MACHP(0)->ticks - l;
- l *= MS2HZ;
+ l = TK2MS(l);
readnum(0, statbuf+2*NAMELEN+12+NUMSIZE*i, NUMSIZE, l, NUMSIZE);
}
memcpy(a, statbuf+c->offset, n);
@@ 333,6 348,7 @@ procwrite(Chan *c, void *va, long n)
{
Proc *p;
User *up;
+ KMap *k;
char buf[ERRLEN];
if(c->qid & CHDIR)
@@ 355,11 371,14 @@ procwrite(Chan *c, void *va, long n)
error(0, Ebadctl);
break;
case Qnote:
- up = (User*)(p->upage->pa|KZERO);
+ k = kmap(p->upage);
+ up = (User*)VA(k);
if(up->p != p){
+ kunmap(k);
pprint("note write u/p mismatch");
error(0, Egreg);
}
+ kunmap(k);
if(n >= ERRLEN-1)
error(0, Etoobig);
if(n>=4 && strncmp(va, "sys:", 4)==0)
M port/lib.h => port/lib.h +1 -0
@@ 43,6 43,7 @@ struct Op
};
extern void strconv(char*, Op*, int, int);
extern int numbconv(Op*, int);
+extern char *doprint(char*, char*, char*, void*);
extern int fmtinstall(char, int (*)(Op*));
extern int sprint(char*, char*, ...);
extern int print(char*, ...);
M port/proc.c => port/proc.c +3 -3
@@ 391,9 391,9 @@ pexit(char *s, int freemem)
wp = &w.time[TUser];
up = &c->time[TUser];
ucp = &c->time[TCUser];
- *wp++ = (*up++ + *ucp++)*MS2HZ;
- *wp++ = (*up++ + *ucp )*MS2HZ;
- *wp = (*up )*MS2HZ;
+ *wp++ = TK2MS(*up++ + *ucp++);
+ *wp++ = TK2MS(*up++ + *ucp );
+ *wp = TK2MS(*up );
p->child = c;
/*
* Pass info through back door, to avoid huge Proc's
M port/sysproc.c => port/sysproc.c +14 -8
@@ 26,6 26,7 @@ sysfork(ulong *arg)
ulong usp, upa, pid;
Chan *c;
Orig *o;
+ KMap *k;
int n, on, i;
int lastvar; /* used to compute stack address */
@@ 34,15 35,18 @@ sysfork(ulong *arg)
*/
p = newproc();
p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
- upa = p->upage->pa|KZERO;
+ k = kmap(p->upage);
+ upa = VA(k);
+
/*
* Save time: only copy u-> data and useful stack
*/
memcpy((void*)upa, u, sizeof(User));
n = USERADDR+BY2PG - (ulong)&lastvar;
n = (n+32) & ~(BY2WD-1); /* be safe & word align */
- memcpy((void*)(upa+BY2PG-n), (void*)((u->p->upage->pa|KZERO)+BY2PG-n), n);
+ memcpy((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n);
((User *)upa)->p = p;
+ kunmap(k);
/*
* User stack
@@ 51,7 55,7 @@ sysfork(ulong *arg)
s = &p->seg[SSEG];
s->proc = p;
on = (s->maxva-s->minva)>>PGSHIFT;
- usp = ((Ureg*)UREGADDR)->sp;
+ usp = ((Ureg*)UREGADDR)->usp;
if(usp >= USTKTOP)
panic("fork bad usp %lux", usp);
if(usp < u->p->seg[SSEG].minva)
@@ 70,13 74,15 @@ sysfork(ulong *arg)
op = u->p->seg[SSEG].o->pte[i+(on-n)].page;
if(op){
np = newpage(1, s->o, op->va);
+ k = kmap(np);
p->seg[SSEG].o->pte[i].page = np;
if(i == 0){ /* only part of last stack page */
- memset((void*)(np->pa|KZERO), 0, usp);
- memcpy((void*)((np->pa+usp)|KZERO),
- (void*)((op->pa+usp)|KZERO), BY2PG-usp);
+ memset((void*)VA(k), 0, usp);
+ memcpy((void*)(VA(k)+usp),
+ (void*)(op->va+usp), BY2PG-usp);
}else /* all of higher pages */
- memcpy((void*)(np->pa|KZERO), (void*)(op->pa|KZERO), BY2PG);
+ memcpy((void*)VA(k), (void*)op->va, BY2PG);
+ kunmap(k);
}
}
unlock(s->o);
@@ 350,7 356,7 @@ sysexec(ulong *arg)
((Ureg*)UREGADDR)->pc = exec.entry - 4;
sp = (ulong*)(USTKTOP - ssize);
*--sp = nargs;
- ((Ureg*)UREGADDR)->sp = (ulong)sp;
+ ((Ureg*)UREGADDR)->usp = (ulong)sp;
lock(&p->debug);
u->nnote = 0;
u->notify = 0;
M power/clock.c => power/clock.c +1 -1
@@ 17,7 17,7 @@ alarm(int ms, void (*f)(Alarm*), void *arg)
if(ms < 0)
ms = 0;
a = newalarm();
- a->dt = ms/MS2HZ;
+ a->dt = MS2TK(ms);
a->f = f;
a->arg = arg;
s = splhi();
M power/conf.h => power/conf.h +1 -0
@@ 2,6 2,7 @@ Conftab conftab[] = {
{"nmach", &conf.nmach },
{"nproc", &conf.nproc },
{"npgrp", &conf.npgrp },
+ {"npage0", &conf.npage0 },
{"npage", &conf.npage },
{"norig", &conf.norig },
{"npte", &conf.npte },
M power/dat.h => power/dat.h +9 -0
@@ 118,6 118,7 @@ struct Conf
ulong nmach; /* processors */
ulong nproc; /* processes */
ulong npgrp; /* process groups */
+ ulong npage0; /* total physical pages of memory */
ulong npage; /* total physical pages of memory */
ulong norig; /* origins */
ulong npte; /* contiguous page table entries */
@@ 359,6 360,14 @@ struct User
};
/*
+ * Fake kmap
+ */
+typedef void KMap;
+#define VA(k) ((ulong)(k))
+#define kmap(p) (KMap*)(p->pa|KZERO)
+#define kunmap(k)
+
+/*
* operations available to a queue
*/
struct Qinfo
M power/main.c => power/main.c +2 -1
@@ 546,7 546,8 @@ confinit(void)
break;
x += 0x3141526;
}
- conf.npage = i*1024/4;
+ conf.npage0 = i*1024/4;
+ conf.npage = conf.npage0;
/*
* set minimal default values
M power/mem.h => power/mem.h +8 -1
@@ 12,11 12,18 @@
#define BY2PG 4096 /* bytes per page */
#define WD2PG (BY2PG/BY2WD) /* words per page */
#define PGSHIFT 12 /* log(BY2PG) */
-#define MS2HZ 50 /* millisec per clock tick */
#define MAXMACH 4 /* max # cpus system can run */
/*
+ * Time
+ */
+#define MS2HZ 50 /* millisec per clock tick */
+#define TK2SEC(t) ((t)/20) /* ticks to seconds */
+#define TK2MS(t) ((t)*MS2HZ) /* ticks to milliseconds */
+#define MS2TK(t) ((t)/MS2HZ) /* milliseconds to ticks */
+
+/*
* CP0 registers
*/
M power/ureg.h => power/ureg.h +4 -1
@@ 2,7 2,10 @@ struct Ureg
{
ulong status;
ulong pc;
- ulong sp; /* r29 */
+ union{
+ ulong sp; /* r29 */
+ ulong usp; /* r29 */
+ };
ulong cause;
ulong badvaddr;
ulong tlbvirt;