From 790abd1bce4d3c0ae9a1da631e72d38b5ec37039 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 4 Aug 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-08-04 --- pc/main.c | 2 + pc/mem.h | 2 +- pc/mmu.c | 122 ++++++++++++++++++---------------------------------- pc/trap.c | 22 ++++++++++ port/swap.c | 6 ++- ss/dat.h | 1 + ss/fns.h | 2 +- ss/fptrap.c | 10 ++++- ss/l.s | 2 +- ss/trap.c | 17 +++----- 10 files changed, 90 insertions(+), 96 deletions(-) diff --git a/pc/main.c b/pc/main.c index 62bc68fc563eed83d723bc9e6235336ac20a6c91..889efe829e3ad7ebd489684dbc44c958ba370ab6 100644 --- a/pc/main.c +++ b/pc/main.c @@ -356,6 +356,8 @@ void procsave(Proc *p) { USED(p); + if(u->p->state == Moribund) + return; if(u->p->fpstate == FPactive){ fpsave(&u->fpsave); u->p->fpstate = FPinactive; diff --git a/pc/mem.h b/pc/mem.h index 78ed71ece5fc33c4d0dbb33ecaff4c9fbe14c5e6..5cd0e85ba5db5a5b9dc807a0a0b8ab849d86c968 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -108,7 +108,7 @@ * physical MMU */ #define PTEVALID (1<<0) -#define PTEUNCACHED 0 /* everything is uncached */ +#define PTEUNCACHED (1<<4) #define PTEWRITE (1<<1) #define PTERONLY (0<<1) #define PTEKERNEL (0<<2) diff --git a/pc/mmu.c b/pc/mmu.c index 3634d7f4ccd908c9dde6653d37d7b9fae478fa7e..75b57a5c2e43b39e520dd3e242fe4da7e001e838 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -86,6 +86,10 @@ static ulong *upt; /* 2nd level page table for struct User */ */ #define BTMOFF(v) ((((ulong)(v))>>(PGSHIFT))&(WD2PG-1)) +#define MAXUMEG 64 /* maximum memory per user process in megabytes */ +#define ONEMEG (1024*1024) + + /* * Create a prototype page map that maps all of memory into * kernel (KZERO) space. This is the default map. It is used @@ -152,56 +156,19 @@ mmuinit(void) } /* - * Get a page for a process's page map. - * - * Each process maintains its own free list of page - * table pages. All page table pages are put on - * this list in flushmmu(). flushmmu() doesn't - * putpage() the pages since the process will soon need - * them back. Also, this avoids worrying about deadlocks - * twixt flushmmu() and putpage(). - * - * mmurelease() will give back the pages when the process - * exits. - */ -static Page* -mmugetpage(int clear) -{ - Proc *p = u->p; - Page *pg; - - if(p->mmufree){ - pg = p->mmufree; - p->mmufree = pg->next; - if(clear) - memset((void*)pg->va, 0, BY2PG); - } else { - pg = newpage(clear, 0, 0); - pg->va = VA(kmap(pg)); - } - return pg; -} - -/* - * Put all bottom level page map pages on the process's free list and - * call mapstack to set up the prototype page map. This - * effectively forgets all of the process's mappings. - * - * Don't free the top level page. Just zero the used entries. This - * avoids a 4k copy each flushmmu. + * Mark the mmu and tlb as inconsistent and call mapstack to fix it up. */ void flushmmu(void) { int s; - Proc *p; - if(u == 0) - return; - p = u->p; - p->newtlb = 1; s = splhi(); - mapstack(p); + if(u){ + u->p->newtlb = 1; + mapstack(u->p); + } else + putcr3(ktoppg.pa); splx(s); } @@ -213,27 +180,24 @@ flushmmu(void) void mapstack(Proc *p) { - Page *pg; - ulong *top; + Page *pg, **l; if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0) panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va); if(p->newtlb){ /* - * bin the current second level page tables. newtlb - * set means that they are inconsistent with the segment.c - * data structures. + * bin the current second level page tables. + * newtlb set means that they are inconsistent + * with the segment.c data structures. */ - if(p->mmutop && p->mmuused){ - top = (ulong*)p->mmutop->va; - for(pg = p->mmuused; pg->next; pg = pg->next) - top[pg->daddr] = 0; - top[pg->daddr] = 0; - pg->next = p->mmufree; - p->mmufree = p->mmuused; - p->mmuused = 0; - } + if(p->mmutop) + memmove((void*)p->mmutop->va, (void*)ktoppg.va, BY2PG); + l = &p->mmufree; + for(pg = p->mmufree; pg; pg = pg->next) + l = &pg->next; + *l = p->mmuused; + p->mmuused = 0; p->newtlb = 0; } @@ -282,7 +246,6 @@ mmurelease(Proc *p) /* * Add an entry into the mmu. */ -#define FOURMEG (4*1024*1024) void putmmu(ulong va, ulong pa, Page *pg) { @@ -290,46 +253,44 @@ putmmu(ulong va, ulong pa, Page *pg) ulong *top; ulong *pt; Proc *p; + int s; if(u==0) panic("putmmu"); - p = u->p; - if(va >= USERADDR && va < USERADDR + FOURMEG) - print("putmmu in USERADDR page table 0x%lux\n", va); - if((va & 0xF0000000) == KZERO) - print("putmmu in kernel page table 0x%lux\n", va); - /* - * if no top level page, allocate one and copy the prototype - * into it. + * create a top level page if we don't already have one. + * copy the kernel top level page into it for kernel mappings. */ if(p->mmutop == 0){ - /* - * N.B. The assignment to pg is neccessary. - * We can't assign to p->mmutop until after - * copying ktoppg into the new page since we might - * get scheded in this code and p->mmutop will be - * pointing to a bad map. - */ - pg = mmugetpage(0); + pg = newpage(0, 0, 0); + pg->va = VA(kmap(pg)); memmove((void*)pg->va, (void*)ktoppg.va, BY2PG); p->mmutop = pg; } top = (ulong*)p->mmutop->va; + topoff = TOPOFF(va); /* - * if bottom level page table missing, allocate one and point - * the top level page at it. + * if bottom level page table missing, allocate one + * and point the top level page at it. */ - topoff = TOPOFF(va); - if(top[topoff] == 0){ - pg = mmugetpage(1); + s = splhi(); + if(PPN(top[topoff]) == 0){ + if(p->mmufree == 0){ + spllo(); + pg = newpage(1, 0, 0); + pg->va = VA(kmap(pg)); + splhi(); + } else { + pg = p->mmufree; + p->mmufree = pg->next; + memset((void*)pg->va, 0, BY2PG); + } top[topoff] = PPN(pg->pa) | PTEVALID | PTEUSER | PTEWRITE; pg->next = p->mmuused; p->mmuused = pg; - pg->daddr = topoff; } /* @@ -340,6 +301,7 @@ putmmu(ulong va, ulong pa, Page *pg) /* flush cached mmu entries */ putcr3(p->mmutop->pa); + splx(s); } void diff --git a/pc/trap.c b/pc/trap.c index 6caa14859e7be8b321960162c12e5950e1bf2f9f..b8cd6978af4996dd8422fa45b44cbf3948acc088 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -274,6 +274,25 @@ dumpregs(Ureg *ur) void dumpstack(void) { + ulong l, v, i; + extern ulong etext; + + if(u == 0) + return; + + i = 0; + for(l=(ulong)&l; ls = *((Sargs*)(sp+1*BY2WD)); u->p->psstate = sysctab[u->scallnr]; +if(u->p->fgrp->ref <= 0) print("before syscall %s\n", u->p->psstate); ret = (*systab[u->scallnr])(u->s.args); poperror(); +if(u->p->fgrp->ref <= 0) print("after syscall %s\n", u->p->psstate); } if(u->nerrlab){ print("bad errstack [%d]: %d extra\n", u->scallnr, u->nerrlab); @@ -361,6 +382,7 @@ syscall(Ureg *ur) splhi(); /* avoid interrupts during the iret */ if(u->scallnr!=RFORK && (u->p->procctl || u->nnote)) notify(ur); + return ret; } diff --git a/port/swap.c b/port/swap.c index cc836c47201ae94648ac0fe7f986ed39cada3c3f..78f6b3aba1b18daaf936e580bbb4bd18d88b8ca0 100644 --- a/port/swap.c +++ b/port/swap.c @@ -21,7 +21,7 @@ enum Image swapimage; static int swopen; Page *iolist[Maxpages]; -int ioptr; +int ioptr, npage; void swapinit(void) @@ -101,6 +101,7 @@ loop: sleep(&swapalloc.r, needpages, 0); u->p->psstate = "Pageout"; + npage = 0; for(;;) { p++; if(p >= ep) @@ -141,6 +142,8 @@ loop: wakeup(&palloc.r); } } + if(npage == 0) + print("swap: pass took no pages\n"); goto loop; } @@ -269,6 +272,7 @@ pagepte(int type, Page **pg) /* Add me to IO transaction list */ iolist[ioptr++] = outp; } + npage++; } void diff --git a/ss/dat.h b/ss/dat.h index da145dad68d95a890040b8cdc62483deac10b9bc..389a54b79ce603c72d14a12e5258442d879c5a6f 100644 --- a/ss/dat.h +++ b/ss/dat.h @@ -58,6 +58,7 @@ struct FPsave ulong a; /* address */ ulong i; /* instruction */ }q[NFPQ]; + long fppc; /* for recursive traps only */ }; struct Conf diff --git a/ss/fns.h b/ss/fns.h index a673e8ae8cf34ac975457c4e0e1cef3d71ff9a52..d6296c0b90a3f926fbd5693a988007939f6f6131 100644 --- a/ss/fns.h +++ b/ss/fns.h @@ -63,7 +63,7 @@ void putwD(ulong, ulong); void putwE16(ulong, ulong); void putwE(ulong, ulong); void systemreset(void); -void restfpregs(FPsave*); +void restfpregs(FPsave*, ulong); void screeninit(void); void screenputc(int); void screenputs(char*, int); diff --git a/ss/fptrap.c b/ss/fptrap.c index a0d75440c02272a5672b73123b9964972aad519c..a4047bbfcf6d1447ad086efe70cc04eec03f6213 100644 --- a/ss/fptrap.c +++ b/ss/fptrap.c @@ -20,7 +20,11 @@ fptrap(void) n = getfpq(&u->fpsave.q[0].a); if(n > NFPQ) panic("FPQ %d\n", n); - again: + /* + * If faulted during restart, recover PC for debugging + */ + if(u->fpsave.fppc) + u->fpsave.q[0].a = u->fpsave.fppc; fsr = getfsr(); savefpregs(&u->fpsave); u->fpsave.fsr = fsr; @@ -33,7 +37,7 @@ fptrap(void) if(ret){ enabfp(); /* savefpregs disables it */ clearftt(fsr & ~0x1F); /* clear ftt and cexc */ - restfpregs(&u->fpsave); + restfpregs(&u->fpsave, fsr); enabfp(); /* restfpregs disables it */ fixq(&u->fpsave, n); } @@ -202,7 +206,9 @@ fixq(FPsave *f, int n) * the trap by examining the non-zero members of the FPQ. * Tough. */ + f->fppc = f->q[0].a; (*(void(*)(void))ip)(); + f->fppc = 0; if(!fpquiet()) break; } diff --git a/ss/l.s b/ss/l.s index d6d0b1f62251ee263b91592d50ee1041da8d0b18..9e8ab41f5742a3686c731265e97827b711152634 100644 --- a/ss/l.s +++ b/ss/l.s @@ -564,7 +564,7 @@ TEXT restfpregs(SB), $0 MOVW R8, PSR NOOP /* wait for PSR to quiesce */ - MOVW 0(R7), FSR + MOVW fsr+4(FP), FSR ADD $4, R7 MOVD (0*4)(R7), F0 diff --git a/ss/trap.c b/ss/trap.c index 19b484460faac20ddfd0cdf30cf99d82dc6812e1..95b40b1c2301ed863c6a124ce5a8bf86195814b9 100644 --- a/ss/trap.c +++ b/ss/trap.c @@ -166,9 +166,9 @@ trap(Ureg *ur) case 4: /* floating point disabled */ if(u && u->p){ if(u->p->fpstate == FPinit) - restfpregs(initfpp); + restfpregs(initfpp, initfpp->fsr); else if(u->p->fpstate == FPinactive) - restfpregs(&u->fpsave); + restfpregs(&u->fpsave, u->fpsave.fsr); else break; u->p->fpstate = FPactive; @@ -205,7 +205,7 @@ trap(Ureg *ur) if(user){ notify(ur); if(u->p->fpstate == FPinactive) { - restfpregs(&u->fpsave); + restfpregs(&u->fpsave, u->fpsave.fsr); u->p->fpstate = FPactive; ur->psr |= PSREF; } @@ -525,20 +525,14 @@ syscall(Ureg *aur) if(conf.ss2) putw2(CACHETAGS+((TRAPS+16*128)&(VACSIZE-1)), 0); - /* - * since the system call interface does not - * guarantee anything about registers, - */ if(u->p->fpstate == FPactive) { fpquiet(); u->p->fpstate = FPinit; + u->fpsave.fsr = getfsr(); ur->psr &= ~PSREF; } spllo(); - if(u->p->procctl) - procctl(u->p); - u->scallnr = ur->r7; sp = ur->usp; @@ -570,6 +564,9 @@ syscall(Ureg *aur) ur->pc += 4; ur->npc = ur->pc+4; u->nerrlab = 0; + if(u->p->procctl) + procctl(u->p); + u->p->insyscall = 0; u->p->psstate = 0; if(u->scallnr == NOTED) /* ugly hack */