From 4d55f1cdece7317e730b9e8fdf816e0cf9cbeb5a Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 13 Oct 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-10-13 --- carrera/dat.h | 10 ++ carrera/fns.h | 2 +- carrera/mmu.c | 5 +- carrera/trap.c | 2 +- pc/dat.h | 12 +++ pc/main.c | 19 ++-- pc/mem.h | 2 + pc/mmu.c | 10 +- pc/trap.c | 27 ++--- port/cache.c | 269 ++++++++++++++++++++++++++++++++++++++++++++++--- port/chan.c | 1 + port/dev.c | 1 + port/devproc.c | 4 +- port/portdat.h | 5 +- 14 files changed, 325 insertions(+), 44 deletions(-) diff --git a/carrera/dat.h b/carrera/dat.h index 5630ba3db1a5fc0c82d26405acee32d2a8d7172a..0efa888a6d03501c7bd5fcb399c76689cdad95f5 100644 --- a/carrera/dat.h +++ b/carrera/dat.h @@ -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 */ diff --git a/carrera/fns.h b/carrera/fns.h index 0ec152d929251857feef5637424db7fb4ea7dbce..a0af9e4ea297b9abcfd65f0ac8af13266b1fa238 100644 --- a/carrera/fns.h +++ b/carrera/fns.h @@ -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); diff --git a/carrera/mmu.c b/carrera/mmu.c index 258376d5c82812bfb1ee9c4ae33cab682f3f42d1..41b39aa55089e8f3d0d3a8f9e7e45327e2bdff8d 100644 --- a/carrera/mmu.c +++ b/carrera/mmu.c @@ -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); diff --git a/carrera/trap.c b/carrera/trap.c index 251a185e1391b78a72cb04df1d1264eb82135833..f0031645ecc804e6d5b916f09db9cb28ccfec111 100644 --- a/carrera/trap.c +++ b/carrera/trap.c @@ -205,7 +205,7 @@ trap(Ureg *ur) kernfault(ur, ecode); if(!user && (ur->badvaddr & KMAPMASK) == KMAPADDR) { - kfault(ur->badvaddr); + kfault(ur); break; } diff --git a/pc/dat.h b/pc/dat.h index 9cd3e86fdf765bd4883302344d69ac3a6e94fb13..c6fac5e3d6284f3c58c391aabf90fb54b6311414 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -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; diff --git a/pc/main.c b/pc/main.c index db0ae715c73bd2f3818ed7bb75af5d75342fc7d4..5b7c8825909f9b14561ad8882ae0c820dd735cf9 100644 --- a/pc/main.c +++ b/pc/main.c @@ -94,6 +94,15 @@ machinit(void) ulong garbage; +void +ksetterm(char *f) +{ + char buf[2*NAMELEN]; + + sprint(buf, f, conffile); + ksetenv("terminal", buf); +} + void init0(void) { @@ -101,9 +110,6 @@ init0(void) 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<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) diff --git a/pc/mem.h b/pc/mem.h index f29cda42312856dbc2ffe89b5e7140b6e2a27ba0..25c3b4dd722acf5688fe2f306b03d9607691fc4f 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -117,3 +117,5 @@ * flag register bits that we care about */ #define IFLAG 0x200 + +#define getpgcolor(a) 0 diff --git a/pc/mmu.c b/pc/mmu.c index c4ca0088078dd3c1728f8bda562607ca4b7f0552..b3b66444dbdcb519e3aa08ffd311a9b44fe48ebf 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -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); } diff --git a/pc/trap.c b/pc/trap.c index b5ef247bd18f1e6d9a83ea3f41f81a64cb99d2dc..ddbc73e940ce145952f72cbe4ce05443ab4e8282 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -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; lkstack+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; diff --git a/port/cache.c b/port/cache.c index ab667d9f98a85bd79021b535c800a920161f22bc..f2cb2b1cfe8bcda5bc6efbeb70cf0bdf4d8e7de1 100644 --- a/port/cache.c +++ b/port/cache.c @@ -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); + } } diff --git a/port/chan.c b/port/chan.c index 943b375ec50414bb248c9d7548639fa0661ab9c4..d201d77dcc7e8449a8cbbd97aad109e96ee2b601 100644 --- a/port/chan.c +++ b/port/chan.c @@ -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; } diff --git a/port/dev.c b/port/dev.c index c80c210993488b3f09ec5510eaba6e8f31aa9199..f2d0774fe5b65c225eaa290a6e22d1ddaddb2d7e 100644 --- a/port/dev.c +++ b/port/dev.c @@ -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; diff --git a/port/devproc.c b/port/devproc.c index 78f347cb470fd50fcd3504a3fdd47fead5156b6a..e5b58f323b81b4a3c71d1b8a85683c8f2284a665 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -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); } diff --git a/port/portdat.h b/port/portdat.h index b77042a0858dad697de0c694636b5e1a57114036..b119c7b0da11e4e8198c9b64b3bbc54ee26db738 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -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