M carrera/dat.h => carrera/dat.h +10 -0
@@ 7,6 7,7 @@ typedef struct Label Label;
typedef struct Lock Lock;
typedef struct Mach Mach;
typedef struct MMU MMU;
+typedef struct Notsave Notsave;
typedef struct PMMU PMMU;
typedef struct Softtlb Softtlb;
typedef struct Ureg Ureg;
@@ 78,6 79,15 @@ struct PMMU
int pidonmach[MAXMACH];
};
+/*
+ * things saved in the Proc structure during a notify
+ */
+struct Notsave
+{
+ ulong svstatus;
+ ulong svr1;
+};
+
#include "../port/portdat.h"
/* First FOUR members offsets known by l.s */
M carrera/fns.h => carrera/fns.h +1 -1
@@ 43,7 43,7 @@ void ioinit(int);
int iprint(char*, ...);
int kbdinit(void);
int kbdintr(void);
-void kfault(ulong);
+void kfault(Ureg*);
KMap* kmap(Page*);
void kmapinit(void);
void kmapinval(void);
M carrera/mmu.c => carrera/mmu.c +4 -1
@@ 4,6 4,7 @@
#include "dat.h"
#include "fns.h"
#include "io.h"
+#include "ureg.h"
/*
* tlb entry 0 is used only by mmuswitch() to set the current tlb pid.
@@ 141,11 142,13 @@ kunmap(KMap *k)
}
void
-kfault(ulong addr)
+kfault(Ureg *ur)
{
KMap *k, *f;
ulong x, index, virt;
+ ulong addr;
+ addr = ur->badvaddr;
index = (addr & ~KMAPADDR) >> KMAPSHIFT;
if(index >= KPTESIZE)
panic("kmapfault: %lux", addr);
M carrera/trap.c => carrera/trap.c +1 -1
@@ 205,7 205,7 @@ trap(Ureg *ur)
kernfault(ur, ecode);
if(!user && (ur->badvaddr & KMAPMASK) == KMAPADDR) {
- kfault(ur->badvaddr);
+ kfault(ur);
break;
}
M pc/dat.h => pc/dat.h +12 -0
@@ 5,6 5,7 @@ typedef struct Label Label;
typedef struct Lock Lock;
typedef struct MMU MMU;
typedef struct Mach Mach;
+typedef struct Notsave Notsave;
typedef struct PCArch PCArch;
typedef struct Page Page;
typedef struct PMMU PMMU;
@@ 96,6 97,16 @@ struct PMMU
Page *mmuused; /* used page table pages */
};
+/*
+ * things saved in the Proc structure during a notify
+ */
+struct Notsave
+{
+ ulong svflags;
+ ulong svcs;
+ ulong svss;
+};
+
#include "../port/portdat.h"
/*
@@ 177,6 188,7 @@ struct ISAConf {
extern int flipD[]; /* for flipping bitblt destination polarity */
extern PCArch *arch; /* PC architecture */
+extern int cpuflag; /* true if this is a CPU */
extern Mach *m;
extern Proc *up;
M pc/main.c => pc/main.c +12 -7
@@ 95,15 95,21 @@ machinit(void)
ulong garbage;
void
+ksetterm(char *f)
+{
+ char buf[2*NAMELEN];
+
+ sprint(buf, f, conffile);
+ ksetenv("terminal", buf);
+}
+
+void
init0(void)
{
int i;
char tstr[32];
up->nerrlab = 0;
- m->proc = up->p;
- up->state = Running;
- up->mach = m;
spllo();
@@ 136,7 142,6 @@ userinit(void)
{
Proc *p;
Segment *s;
- User *up;
KMap *k;
Page *pg;
@@ 434,12 439,12 @@ matherror(Ureg *ur)
if((1<<i) & status){
msg = mathmsg[i];
sprint(note, "sys: fp: %s fppc=0x%lux", msg, up->fpsave.pc);
- postnote(up->p, 1, note, NDebug);
+ postnote(up, 1, note, NDebug);
break;
}
if(msg == 0){
sprint(note, "sys: fp: unknown fppc=0x%lux", up->fpsave.pc);
- postnote(up->p, 1, note, NDebug);
+ postnote(up, 1, note, NDebug);
}
if(ur->pc & KZERO)
panic("fp: status %lux fppc=0x%lux pc=0x%lux", status,
@@ 534,7 539,7 @@ procrestore(Proc *p)
void
exit(int ispanic)
{
- u = 0;
+ up = 0;
print("exiting\n");
if(ispanic){
if(cpuflag)
M pc/mem.h => pc/mem.h +2 -0
@@ 117,3 117,5 @@
* flag register bits that we care about
*/
#define IFLAG 0x200
+
+#define getpgcolor(a) 0
M pc/mmu.c => pc/mmu.c +5 -5
@@ 165,7 165,7 @@ mmuinit(void)
* set up the task segment
*/
memset(&tss, 0, sizeof(tss));
- taskswitch(ktoppg.pa, BY2BG + (ulong)m);
+ taskswitch(ktoppg.pa, BY2PG + (ulong)m);
puttr(TSSSEL);
}
@@ 218,9 218,9 @@ mmuswitch(Proc *p)
/* tell processor about new page table (flushes cached entries) */
if(p->mmutop)
- taskswitch(p->mmutop->pa, p->kstack+KSTACK);
+ taskswitch(p->mmutop->pa, (ulong)(p->kstack+KSTACK));
else
- taskswitch(ktoppg.pa, p->kstack+KSTACK);
+ taskswitch(ktoppg.pa, (ulong)(p->kstack+KSTACK));
}
/*
@@ 273,7 273,7 @@ putmmu(ulong va, ulong pa, Page *pg)
memmove((void*)pg->va, (void*)ktoppg.va, BY2PG);
up->mmutop = pg;
}
- top = (ulong*)up->mmutoup->va;
+ top = (ulong*)up->mmutop->va;
topoff = TOPOFF(va);
/*
@@ 305,7 305,7 @@ putmmu(ulong va, ulong pa, Page *pg)
pt[BTMOFF(va)] = pa | PTEUSER;
/* flush cached mmu entries */
- taskswitch(up->mmutoup->pa, up->kstack);
+ taskswitch(up->mmutop->pa, (ulong)up->kstack);
splx(s);
}
M pc/trap.c => pc/trap.c +15 -12
@@ 103,7 103,7 @@ debugbpt(Ureg *ur)
/* restore pc to instruction that caused the trap */
ur->pc--;
sprint(buf, "sys: breakpoint");
- postnote(up->p, 1, buf, NDebug);
+ postnote(up, 1, buf, NDebug);
}
/*
@@ 261,7 261,7 @@ lastur = ur;
if(v <= 16){
if(user){
sprint(buf, "sys: trap: %s", excname[v]);
- postnote(up->p, 1, buf, NDebug);
+ postnote(up, 1, buf, NDebug);
return;
} else {
dumpregs(ur);
@@ 308,10 308,7 @@ dumpregs2(Ureg *ur)
print("registers for kernel\n");
print("FLAGS=%lux TRAP=%lux ECODE=%lux CS=%lux PC=%lux", ur->flags, ur->trap,
ur->ecode, ur->cs&0xff, ur->pc);
- if(ur == (Ureg*)UREGADDR)
- print(" SS=%lux USP=%lux\n", ur->ss&0xff, ur->usp);
- else
- print("\n");
+ print(" SS=%lux USP=%lux\n", ur->ss&0xff, ur->usp);
print(" AX %8.8lux BX %8.8lux CX %8.8lux DX %8.8lux\n",
ur->ax, ur->bx, ur->cx, ur->dx);
print(" SI %8.8lux DI %8.8lux BP %8.8lux\n",
@@ 340,7 337,7 @@ dumpstack(void)
return;
i = 0;
- for(l=(ulong)&l; l<up->kstack+BY2PG; l+=4){
+ for(l=(ulong)&l; l<(ulong)(up->kstack+BY2PG); l+=4){
v = *(ulong*)l;
if(KTZERO < v && v < (ulong)&etext){
print("%lux ", v);
@@ 358,18 355,24 @@ long
execregs(ulong entry, ulong ssize, ulong nargs)
{
ulong *sp;
+ Ureg *ur;
sp = (ulong*)(USTKTOP - ssize);
*--sp = nargs;
- ((Ureg*)UREGADDR)->usp = (ulong)sp;
- ((Ureg*)UREGADDR)->pc = entry;
+
+ ur = up->dbgreg;
+ ur->usp = (ulong)sp;
+ ur->pc = entry;
return USTKTOP-BY2WD; /* address of user-level clock */
}
ulong
userpc(void)
{
- return ((Ureg*)UREGADDR)->pc;
+ Ureg *ur;
+
+ ur = (Ureg*)up->dbgreg;
+ return ur->pc;
}
/*
@@ 411,7 414,7 @@ syscall(Ureg *ur)
if(!waserror()){
if(up->scallnr >= sizeof systab/BY2WD){
pprint("bad sys call number %d pc %lux\n", up->scallnr, ur->pc);
- postnote(up->p, 1, "sys: bad sys call", NDebug);
+ postnote(up, 1, "sys: bad sys call", NDebug);
error(Ebadarg);
}
@@ 464,7 467,7 @@ notify(Ureg *ur)
Note *n;
if(up->procctl)
- procctl(up->p);
+ procctl(up);
if(up->nnote == 0)
return 0;
M port/cache.c => port/cache.c +256 -13
@@ 6,26 6,269 @@
#include "../port/error.h"
#include "devtab.h"
-typedef struct Fcache Fcache;
-typedef struct Fcalloc Fcalloc;
-struct Fcache
+Image fscache;
+
+typedef Extent Extent;
+struct Extent
+{
+ int bid;
+ ulong start;
+ int len;
+ Extent *next;
+};
+
+typedef struct Mntcache Mntcache;
+struct Mntcache
{
- QLock;
Qid;
- Page* alloc;
- Fcache* hash;
- Fcache* next;
+ int dev;
+ int type;
+ Qlock;
+ Extent *list;
+ Mntcache *hash;
+ Mntcache *prev;
+ Mntcache *next;
};
-struct Fcalloc
+typedef struct Cache Cache;
+struct Cache
{
- ulong start;
- short len;
- Page* data;
+ Ref;
+ Mntcache *head;
+ Mntcache *tail;
+ Mntcache *hash[NHASH];
};
+Cache cache;
+
+Mntcache*
+clook(Chan *c)
+{
+ int h;
+
+ h = c->qid.path%NHASH;
+
+ lock(&cache);
+ for(m = cache.hash[h]; m; m = m->hash) {
+ if(m->path == c->path) {
+ qlock(m);
+ if(m->path == c->qid.path)
+ if(m->dev == c->dev)
+ if(m->type == c->type) {
+ unlock(&cache);
+ return m;
+ }
+ qunlock(m);
+ }
+ }
+ unlock(&cache);
+ return 0;
+}
-Fcache*
-clook(Qid *qid)
+void
+cnodata(Mntcache *m)
{
+ Extent *e, *n;
+
+ /*
+ * Invalidate all extent data
+ * Image lru will waste the pages
+ */
+ for(e = m->list; e; e = n) {
+ n = e->list;
+ free(e);
+ }
+}
+
+void
+ctail(Mntcache *m)
+{
+ lock(&cache);
+
+ /* Unlink and send to the tail */
+ if(m->prev)
+ m->prev->next = m->next;
+ else
+ cache.head = m->next;
+ if(m->next)
+ m->next->prev = m->prev;
+ else
+ cache.tail = m->prev;
+
+ if(cache.tail) {
+ m->prev = cache.tail;
+ cache.tail->next = m;
+ m->next = 0;
+ cache.tail = m;
+ }
+ else {
+ cache.head = cache.tail = m;
+ m->prev = m->next = 0;
+ }
+
+ unlock(&cache);
+}
+
+void
+copen(Chan *c)
+{
+ Mntcache *m, *f, **l;
+
+ m = clook(c);
+ if(m != 0) {
+ /* File was updated */
+ if(m->vers != c->vers)
+ cnodata(m);
+
+ ctail(m);
+ qunlock(m);
+ return;
+ }
+
+ /* LRU the cache headers */
+ m = cache.head;
+ qlock(m);
+ lock(cache);
+ l = &cache.hash[m->qid.path%NHASH];
+ for(f = *l; f; f = f->next) {
+ if(f == m) {
+ *l = f->next;
+ break;
+ }
+ l = &f->next;
+ }
+ l = &cache.hash[c->qid.path%NHASH];
+ m->hash = *l;
+ *l = m;
+ unlock(cache);
+ m->qid = c->qid;
+ m->dev = c->dev;
+ m->type = c->type;
+ cnodata(m);
+ ctail(m);
+ c->mcp = m;
+ qunlock(m);
+}
+
+static int
+cdev(Mntcache *m, Chan *c)
+{
+ if(m->path != c->path)
+ return 0;
+ if(m->vers != c->vers)
+ return 0;
+ if(m->dev != c->dev)
+ return 0;
+ if(m->type != c->type)
+ return 0;
+ return 1;
+}
+
+int
+cread(Chan *c, uchar *buf, int len, long offset)
+{
+ KMap *k;
+ Page *p;
+ Mntcache *m;
+ Extent *e, **l;
+ int o, l, total;
+
+ m = c->mcp;
+ if(m == 0)
+ return 0;
+ qlock(m);
+ if(cdev(m, c) == 0) {
+ qunlock(m);
+ return 0;
+ }
+
+ end = offset+len;
+ l = &m->list;
+ for(e = *l; e; e = e->next) {
+ if(e->start >= offset && e->start+e->len < end)
+ break;
+ l = &e->next;
+ }
+
+ if(e == 0) {
+ qunlock(m);
+ return 0;
+ }
+
+ total = 0;
+ while(len) {
+ p = lookpage(&fscache, e->bid);
+ if(p == 0) {
+ *l = e->next;
+ free(e);
+ qunlock(m);
+ return total;
+ }
+
+ k = kmap(p);
+ if(waserror()) {
+ kunmap(k);
+ putpage(p);
+ qunlock(m);
+ nexterror();
+ }
+
+ o = offset - e->start;
+ l = len;
+ if(l > e->len-o)
+ l = e->len-o;
+
+ p = (uchar*)VA(k) + o;
+ memset(buf, p, l);
+ kunmap(k);
+ putpage(p);
+
+ buf += l;
+ len -= l;
+ offset += l;
+ total += l;
+ l = &e->next;
+ e = e->next;
+ if(e == 0 || e->start != offset)
+ break;
+ }
+ qunlock(m)
+ return total;
+}
+
+void
+cwrite(Chan *c, uchar *buf, int len, long offset)
+{
+ Extent *e;
+ Mntcache *m;
+
+ if(offset > MAXCACHE)
+ return;
+
+ m = c->mcp;
+ if(m == 0)
+ return;
+ qlock(m);
+ if(cdev(m, c) == 0) {
+ qunlock(m);
+ return;
+ }
+ if(m->list == 0) {
+ e = malloc(sizeof(Extent));
+ if(e == 0)
+ return;
+ e->start = offset;
+ l = len;
+ if(l > BY2PG)
+ l = BY2PG;
+ p = auxpage();
+ if(p == 0)
+ return;
+ e->bid = incref(&cache);
+ p->daddr = e->bid;
+ cachepage(p, fscache);
+ k = kmap(p);
+
+ kunmap(p);
+ }
}
M port/chan.c => port/chan.c +1 -0
@@ 99,6 99,7 @@ newchan(void)
c->aux = 0;
c->mchan = 0;
c->path = 0;
+ c->mcp = 0;
c->mqid = (Qid){0, 0};
return c;
}
M port/dev.c => port/dev.c +1 -0
@@ 98,6 98,7 @@ devclone(Chan *c, Chan *nc)
nc->aux = c->aux;
nc->mchan = c->mchan;
nc->mqid = c->mqid;
+ nc->mcp = c->mcp;
nc->path = c->path;
incref(nc->path);
return nc;
M port/devproc.c => port/devproc.c +2 -2
@@ 243,7 243,6 @@ procwstat(Chan *c, char *db)
if(c->qid.path&CHDIR)
error(Eperm);
- convM2D(db, &d);
p = proctab(SLOT(c->qid));
if(p->pid != PID(c->qid))
error(Eprocdied);
@@ 251,13 250,14 @@ procwstat(Chan *c, char *db)
if(strcmp(up->user, p->user) != 0 && strcmp(up->user, eve) != 0)
error(Eperm);
+ convM2D(db, &d);
p->procmode = d.mode&0777;
}
void
procclose(Chan * c)
{
- if(QID(c->qid) == Qns)
+ if(QID(c->qid) == Qns && c->aux != 0)
free(c->aux);
}
M port/portdat.h => port/portdat.h +3 -2
@@ 11,6 11,7 @@ typedef struct Image Image;
typedef struct IOQ IOQ;
typedef struct KIOQ KIOQ;
typedef struct List List;
+typedef struct Mntcache Mntcache;
typedef struct Mount Mount;
typedef struct Mntrpc Mntrpc;
typedef struct Mntwalk Mntwalk;
@@ 135,6 136,7 @@ struct Chan
Mount *mnt; /* mount point that derived Chan */
Mount *xmnt; /* Last mount point crossed */
ulong mountid;
+ Mntcache *mcp; /* Mount cache pointer */
union {
void *aux;
Qid pgrpid; /* for #p/notepg */
@@ 597,8 599,7 @@ struct Proc
void *ureg; /* User registers for notes */
void *dbgreg; /* User registers for devproc */
- ulong svstatus;
- ulong svr1;
+ Notsave;
/*
* machine specific MMU