From 9f032393e9ff251d336308f07c8ec6ecbe6f3fed Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 5 Jul 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-07-05 --- gnot/dat.h | 12 +- gnot/fault68020.c | 3 + gnot/fns.h | 1 + gnot/lock.c | 11 - gnot/main.c | 54 +-- gnot/mem.h | 5 + gnot/mmu.c | 11 +- gnot/segment.h | 20 ++ gnot/trap.c | 24 +- pc/clock.c | 21 +- pc/fns.h | 4 +- pc/io.h | 14 +- pc/kbd.c | 2 +- pc/l.s | 6 + pc/main.c | 7 +- pc/mem.h | 14 +- pc/trap.c | 10 +- port/chan.c | 2 + port/devcons.c | 23 +- port/devdup.c | 5 +- port/devenv.c | 126 +++---- port/devip.c | 1 + port/deviproute.c | 2 +- port/devproc.c | 116 ++++-- port/devscsi.c | 6 +- port/devsrv.c | 3 +- port/devwren.c | 2 +- port/fault.c | 472 ++++++++++++------------ port/ipdat.h | 2 + port/page.c | 896 ++++++++++++++++------------------------------ port/pgrp.c | 174 +++++++-- port/portdat.h | 213 +++++++---- port/portfns.h | 97 +++-- port/proc.c | 132 +++++-- port/qlock.c | 5 +- port/queue.c | 1 + port/segment.c | 460 ++++++++++++++++++++++++ port/stream.c | 7 +- port/sturp.c | 2 +- port/swap.c | 333 +++++++++++++++++ port/sysfile.c | 120 ++++--- port/sysproc.c | 304 ++++++++-------- port/tcpinput.c | 13 + power/boot.h | 668 ++++++++++++++++------------------ power/conf.h | 7 +- power/dat.h | 13 +- power/faultmips.c | 9 +- power/fns.h | 14 +- power/l.s | 277 +++++++++----- power/lock.c | 29 +- power/main.c | 59 +-- power/mem.h | 8 +- power/mmu.c | 17 +- power/segment.h | 20 ++ power/trap.c | 44 ++- 55 files changed, 3000 insertions(+), 1901 deletions(-) create mode 100644 gnot/segment.h create mode 100644 port/segment.c create mode 100644 port/swap.c create mode 100644 power/segment.h diff --git a/gnot/dat.h b/gnot/dat.h index 34fdf9a72e32056fb4aac3f1ca6a785e628aea96..0fe99a4d1396ce13dca5b656766b1acb2cd94db8 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -72,12 +72,13 @@ struct Conf int npgrp; /* process groups */ ulong npage0; /* total physical pages of memory, bank 0 */ ulong npage1; /* total physical pages of memory, bank 1 */ + ulong npage; ulong base0; /* base of bank 0 */ ulong base1; /* base of bank 1 */ - ulong npage; /* total physical pages of memory */ - ulong norig; /* origins */ - ulong npte; /* contiguous page table entries */ - ulong nmod; /* single (modifying) page table entries */ + ulong nseg; /* number of segments */ + ulong nimage; /* number of page cache image headers */ + ulong npagetab; /* number of pte tables */ + ulong nswap; /* number of swap blocks */ int nalarm; /* alarms */ int nchan; /* channels */ int nenv; /* distinct environment values */ @@ -200,7 +201,6 @@ struct Scsi #define NERR 15 #define NNOTE 5 -#define NFD 100 struct User { Proc *p; @@ -211,8 +211,6 @@ struct User char elem[NAMELEN]; /* last name element from namec */ Chan *slash; Chan *dot; - Chan *fd[NFD]; - int maxfd; /* highest fd in use */ /* * Rest of structure controlled by devproc.c and friends. * lock(&p->debug) to modify. diff --git a/gnot/fault68020.c b/gnot/fault68020.c index c7c2dcbc0e7d677e9a2f84fe8b025f0a8c8543d5..b89facab036b9255411b73a85aef5bb49d655e87 100644 --- a/gnot/fault68020.c +++ b/gnot/fault68020.c @@ -73,14 +73,17 @@ fault68020(Ureg *ur, FFrame *f) panic("prefetch pagefault"); }else panic("prefetch format"); + addr &= VAMASK; badvaddr = addr; addr &= ~(BY2PG-1); user = !(ur->sr&SUPER); + if(f->ssw & DF) read = (f->ssw&READ) && !(f->ssw&RM); else read = f->ssw&(FB|FC); + /* print("fault pc=%lux addr=%lux read %d\n", ur->pc, badvaddr, read); /**/ if(fault(addr, read) < 0){ diff --git a/gnot/fns.h b/gnot/fns.h index 88b22b7ffb6fb9700640029eb6727c4cc48be31c..73431ae92a59d464fe418a6d6230d7d282299e8c 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -22,6 +22,7 @@ void fpregrestore(char*); void fpregsave(char*); void fprestore(FPsave*); void fpsave(FPsave*); +#define icflush(a, b) void incontoggle(void); KMap* kmap(Page*); void kmapinit(void); diff --git a/gnot/lock.c b/gnot/lock.c index a9776572cd6b7367683e13c5cce3bd1a42fc500b..43015f402012af5efd300b993eaea055e02b8897 100644 --- a/gnot/lock.c +++ b/gnot/lock.c @@ -66,14 +66,3 @@ unlock(Lock *l) if(u && u->p) u->p->hasspin = 0; } - -void -mklockseg(Seg *s) -{ - error(Esegaddr); -} - -Page* -lkpage(Orig* o, ulong va) -{ -} diff --git a/gnot/main.c b/gnot/main.c index 620bea0fb406f909add03a5ea4f13adfc40e2e61..1e1658ca3cb010a7efc3110b5b6d304652004c5d 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -46,13 +46,15 @@ main(void) print("bank 0: %dM bank 1: %dM\n", bank[0], bank[1]); flushmmu(); procinit0(); - pgrpinit(); + initseg(); + grpinit(); chaninit(); alarminit(); chandevreset(); streaminit(); /* serviceinit(); /**/ /* filsysinit(); /**/ + swapinit(); pageinit(); kmapinit(); userinit(); @@ -89,7 +91,7 @@ mmuinit(void) * Invalidate user addresses */ for(l=0; l<4*1024*1024; l+=BY2PG) - putmmu(l, INVALIDPTE); + putmmu(l, INVALIDPTE, 0); /* * Four meg of usable memory, with top 256K for screen */ @@ -129,6 +131,8 @@ init0(void) close(c); } poperror(); + + kickpager(); touser(); } @@ -138,23 +142,25 @@ void userinit(void) { Proc *p; - Seg *s; + Segment *s; User *up; KMap *k; p = newproc(); p->pgrp = newpgrp(); + p->egrp = newegrp(); + p->fgrp = newfgrp(); + strcpy(p->text, "*init*"); strcpy(p->pgrp->user, user); p->fpstate = FPinit; - /* * Kernel Stack */ p->sched.pc = (ulong)init0; p->sched.sp = USERADDR+BY2PG-20; /* BUG */ p->sched.sr = SUPER|SPL(0); - p->upage = newpage(0, 0, USERADDR|(p->pid&0xFFFF)); + p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); /* * User @@ -167,25 +173,18 @@ userinit(void) /* * User Stack */ - s = &p->seg[SSEG]; - s->proc = p; - s->o = neworig(USTKTOP-BY2PG, 1, OWRPERM, 0); - s->minva = USTKTOP-BY2PG; - s->maxva = USTKTOP; + s = newseg(SG_STACK, USTKTOP-BY2PG, 1); + p->seg[SSEG] = s; /* * Text */ - s = &p->seg[TSEG]; - s->proc = p; - s->o = neworig(UTZERO, 1, 0, 0); - s->o->pte[0].page = newpage(0, 0, UTZERO); - s->o->npage = 1; - k = kmap(s->o->pte[0].page); + s = newseg(SG_TEXT, UTZERO, 1); + p->seg[TSEG] = s; + segpage(s, newpage(1, 0, UTZERO)); + k = kmap(s->map[0]->pages[0]); memmove((ulong*)VA(k), initcode, sizeof initcode); kunmap(k); - s->minva = UTZERO; - s->maxva = UTZERO+BY2PG; ready(p); } @@ -277,19 +276,19 @@ banksize(int base) if(&end > (int *)((KZERO|1024L*1024L)-BY2PG)) return 0; va = UZERO; /* user page 1 is free to play with */ - putmmu(va, PTEVALID|(base+0)*1024L*1024L/BY2PG); + putmmu(va, PTEVALID|(base+0)*1024L*1024L/BY2PG, 0); *(ulong*)va = 0; /* 0 at 0M */ - putmmu(va, PTEVALID|(base+1)*1024L*1024L/BY2PG); + putmmu(va, PTEVALID|(base+1)*1024L*1024L/BY2PG, 0); *(ulong*)va = 1; /* 1 at 1M */ - putmmu(va, PTEVALID|(base+4)*1024L*1024L/BY2PG); + putmmu(va, PTEVALID|(base+4)*1024L*1024L/BY2PG, 0); *(ulong*)va = 4; /* 4 at 4M */ - putmmu(va, PTEVALID|(base+0)*1024L*1024L/BY2PG); + putmmu(va, PTEVALID|(base+0)*1024L*1024L/BY2PG, 0); if(*(ulong*)va == 0) return 16; - putmmu(va, PTEVALID|(base+1)*1024L*1024L/BY2PG); + putmmu(va, PTEVALID|(base+1)*1024L*1024L/BY2PG, 0); if(*(ulong*)va == 1) return 4; - putmmu(va, PTEVALID|(base+0)*1024L*1024L/BY2PG); + putmmu(va, PTEVALID|(base+0)*1024L*1024L/BY2PG, 0); if(*(ulong*)va == 4) return 1; return 0; @@ -314,11 +313,12 @@ confinit(void) conf.maxialloc = (4*1024*1024-256*1024-BY2PG); mul = 1 + (conf.npage1>0); conf.nproc = 50*mul; + conf.nseg = conf.nproc*4; + conf.npagetab = conf.nseg*2; + conf.nswap = 4096; + conf.nimage = 50; conf.npgrp = 20*mul; - conf.npte = 700*mul; - conf.nmod = 400*mul; conf.nalarm = 1000; - conf.norig = 150*mul; conf.nchan = 200*mul; conf.nenv = 100*mul; conf.nenvchar = 8000*mul; diff --git a/gnot/mem.h b/gnot/mem.h index e7225a815e75cbd13e22e04554f8202f419322fb..8326620b909afaf96adf32a7bbddd2dbd664f66c 100644 --- a/gnot/mem.h +++ b/gnot/mem.h @@ -13,6 +13,7 @@ #define WD2PG (BY2PG/BY2WD) /* words per page */ #define PGSHIFT 13 /* log(BY2PG) */ #define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1)) +#define ICACHESIZE 0 #define MAXMACH 1 /* max # cpus system can run */ @@ -74,6 +75,10 @@ #define PTEKERNEL (1<<15) #define PTEUNCACHED 0 #define INVALIDPTE 0 +#define PTEMAPMEM (1024*1024) +#define PTEPERTAB (PTEMAPMEM/BY2PG) +#define SEGMAPSIZE 16 + #define PPN(pa) ((pa>>13)&0x1FFF) #define KMAP ((unsigned long *)0xD0000000) diff --git a/gnot/mmu.c b/gnot/mmu.c index 9a866ee97d1f81c27e46b24d5ae14f80d8f71b2c..92b59374297fb453251916c42698a5c6f87b4499 100644 --- a/gnot/mmu.c +++ b/gnot/mmu.c @@ -22,6 +22,7 @@ mapstack(Proc *p) ulong next; MMU *mm, *mn, *me; + if(p->upage->va != (USERADDR|(p->pid&0xFFFF))) panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va); tlbvirt = USERADDR; @@ -29,6 +30,12 @@ mapstack(Proc *p) putkmmu(tlbvirt, tlbphys); u = (User*)USERADDR; + if(p->newtlb) { + flushmmu(); + clearmmucache(); + p->newtlb = 0; + } + /* * if not a kernel process and this process was not the * last process on this machine, flush & preload mmu @@ -69,7 +76,7 @@ putkmmu(ulong tlbvirt, ulong tlbphys) } void -putmmu(ulong tlbvirt, ulong tlbphys) +putmmu(ulong tlbvirt, ulong tlbphys, Page *p) { if(tlbvirt&KZERO) panic("putmmu"); @@ -101,7 +108,7 @@ void clearmmucache(void) { if(u == 0) - panic("flushmmucache"); + panic("clearmmucache"); u->mc.next = 0; } diff --git a/gnot/segment.h b/gnot/segment.h new file mode 100644 index 0000000000000000000000000000000000000000..09583003a19e98469bbee8ab55e4700cb0d6cbe9 --- /dev/null +++ b/gnot/segment.h @@ -0,0 +1,20 @@ +/* + * Attach segment types + */ + +typedef struct Physseg Physseg; +struct Physseg +{ + ulong attr; /* Segment attributes */ + char *name; /* Attach name */ + ulong pa; /* Physical address */ + ulong size; /* Maximum segment size in pages */ + Page *(*pgalloc)(ulong); /* Allocation if we need it */ + void (*pgfree)(Page*); +}physseg[] = { + { SG_SHARED, "lock", 0, SEGMAXSIZE, &snewpage, &putpage }, + { SG_SHARED, "shared", 0, SEGMAXSIZE, &snewpage, &putpage }, + { SG_PHYSICAL, "kmem", KZERO, SEGMAXSIZE, 0, 0 }, + { SG_BSS, "memory", 0, SEGMAXSIZE, &snewpage, &putpage }, + { 0, 0, 0, 0, 0, 0 }, +}; diff --git a/gnot/trap.c b/gnot/trap.c index 0c113c505b472e6b1bee42c43b0e8d7443341591..efb629af7ad332823b5ceb13ab851024a17f08e1 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -91,13 +91,14 @@ trap(Ureg *ur) if(u) u->p->pc = ur->pc; /* BUG */ if(user){ - sprint(buf, "sys: trap: pc=0x%lux %s", ur->pc, excname(ur->vo)); + sprint(buf, "sys: %s pc=0x%lux", excname(ur->vo), ur->pc); postnote(u->p, 1, buf, NDebug); }else{ print("kernel trap vo=0x%ux pc=0x%lux\n", ur->vo, ur->pc); dumpregs(ur); exit(); } + if(user && u->nnote) notify(ur); } @@ -130,6 +131,7 @@ dumpregs(Ureg *ur) l = &ur->r0; for(i=0; ipc, ((Ureg*)UREGADDR)->sp); + pprint("odd sp in sys call pc %lux sp %lux\n", + ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); msg = "sys: odd stack"; goto Bad; } @@ -298,14 +305,19 @@ syscall(Ureg *aur) ret = (*systab[r0])((ulong*)(sp+BY2WD)); poperror(); } + +#ifdef Check if(u->nerrlab){ - print("unbalanced error stack: %d extra\n", u->nerrlab); + print("bad errstack [%d]: %d extra\n", r0, u->nerrlab); for(i = 0; i < NERR; i++) print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc); panic("bad rob"); } +#endif + u->p->insyscall = 0; - if(r0 == NOTED) /* ugly hack */ + + if(r0 == NOTED) /* ugly hack */ noted(aur); /* doesn't return */ if(u->nnote){ ur->r0 = ret; diff --git a/pc/clock.c b/pc/clock.c index 797cf29c830f392055edac99e624ce222569106c..e84ffdb12d2cd9374a6ec9efde54eebb7fa4ec94 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -4,7 +4,18 @@ #include "dat.h" #include "fns.h" #include "io.h" -#include "ureg.h" + +/* + * 8253 timer + */ +enum +{ + Timerctl= 0x43, /* control port */ + Timercnt= 0x40, /* timer count port (outb count-1) */ + Timericnt= 0x41, /* timer count input port */ + + Timerlatch= 0x40, /* latch count into Timericnt */ +}; void clockinit(void) @@ -12,3 +23,11 @@ clockinit(void) setvec(Clockvec, clock, SEGIG); } +void +clock(void *arg) +{ + m->ticks++; + if((m->ticks%185)==0) + print("%d secs\n", TK2SEC(m->ticks)); + INT0ENABLE; +} diff --git a/pc/fns.h b/pc/fns.h index a28e0bdddc2792d81b8124ad220f6cb5e565d431..37b59f207daa93bd05a8f493633773d1f1ccbf35 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -1,5 +1,7 @@ #include "../port/portfns.h" +void clock(void*); +void clockinit(void); void delay(int); int inb(int); void intr0(void); @@ -31,8 +33,6 @@ void screeninit(void); void screenputc(int); void screenputs(char*, int); void setvec(int, void (*)(void*), int); -void spllo(void); -void splhi(void); void systrap(void); void trapinit(void); int tas(Lock*); diff --git a/pc/io.h b/pc/io.h index c4e81bf6de05a0bc7b216da1fc440012a82236dd..d41c219773b988db7fdeb642a1f19bc1d339e205 100644 --- a/pc/io.h +++ b/pc/io.h @@ -17,18 +17,6 @@ enum #define INT0ENABLE outb(Int0ctl, Intena) #define INT1ENABLE outb(Int1ctl, Intena) -/* - * 8253 timer - */ -enum -{ - Timerctl= 0x43, /* control port */ - Timercnt= 0x40, /* timer count port (outb count-1) */ - Timericnt= 0x41, /* timer count input port */ - - Timerlatch= 0x40, /* latch count into Timericnt */ -}; - /* * 8237 dma controllers */ @@ -46,5 +34,5 @@ enum */ Dma1= 0xC0, Dma1status= Dma1+2*0x8, /* status port */ - Dma0reset= Dma1+2*0xD, /* reset port */ + Dma1reset= Dma1+2*0xD, /* reset port */ }; diff --git a/pc/kbd.c b/pc/kbd.c index 716604b71626848644e719723e00d8e27b29ca9b..41ae2275fb4e2c5c7efa38a69234890faa84be85 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -378,6 +378,6 @@ kbdintr(void *a) } kbdputc(&kbdq, c); out: - INTENABLE; /* reenable interrupt */ + INT0ENABLE; /* reenable interrupt */ return; } diff --git a/pc/l.s b/pc/l.s index 88ce2413f0f20cc38fee103d0479ce548f25c2ce..a153b4343babfc08a68c8a0979e395efd0d32d03 100644 --- a/pc/l.s +++ b/pc/l.s @@ -305,3 +305,9 @@ TEXT spllo(SB),$0 TEXT splhi(SB),$0 CLI RET + +/* + * set interrupt level + */ +TEXT splx(SB),$0 + RET diff --git a/pc/main.c b/pc/main.c index 0eafae752e0e2bc398d11e23686701b874c9cdf2..98cb20bd14a4a7b258f659f8e268c6c529926ca1 100644 --- a/pc/main.c +++ b/pc/main.c @@ -11,7 +11,7 @@ main(void) print("traps inited\n"); kbdinit(); print("kbd inited\n"); - sti(); + spllo(); for(;;); } @@ -54,3 +54,8 @@ panic(char *fmt, ...) screenputs(buf, n); for(;;); } + +void +sched(void) +{ +} diff --git a/pc/mem.h b/pc/mem.h index dec719ac87d5307bdd3877a9fc78c65aeef47734..de5040c95b1822c5fba0cf31ee25d23c20b679e2 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -17,15 +17,15 @@ #define MAXMACH 1 /* max # cpus system can run */ /* - * Time (???) - * Clock frequency is 68.3900 HZ + * Time + * Clock frequency is ??? HZ */ -#define HZ (68) /* clock frequency */ -#define MS2HZ (1000/HZ) /* millisec per clock tick */ -#define TK2SEC(t) ((t)*100/6839) /* ticks to seconds */ -#define TK2MS(t) ((((ulong)(t))*100000)/6839) /* ticks to milliseconds */ -#define MS2TK(t) ((((ulong)(t))*6839)/100000) /* milliseconds to ticks */ +#define HZ (18) /* clock frequency */ +#define MS2HZ (54) /* millisec per clock tick */ +#define TK2SEC(t) ((t)*10/185) /* ticks to seconds */ +#define TK2MS(t) ((((ulong)(t))*10000)/185) /* ticks to milliseconds */ +#define MS2TK(t) ((((ulong)(t))*185)/10000) /* milliseconds to ticks */ /* * Fundamental addresses diff --git a/pc/trap.c b/pc/trap.c index 5a631fb0e92cf31db11cbd5e1202678e0baccac8..62b76a385e34a0b8585493c24ac1467505bfe062 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -75,11 +75,11 @@ trapinit(void) * IBM technical reference manual. I just * changed the vector. */ - outb(I8259ctl, 0x11); /* ICW1 - edge, master, ICW4 */ - outb(I8259aux, I8259vec); /* ICW2 - interrupt vector */ - outb(I8259aux, 0x04); /* ICW3 - master level 2 */ - outb(I8259aux, 0x01); /* ICW4 - master, 8086 mode */ - outb(I8259aux, 0x00); /* mask - all enabled */ + outb(Int0ctl, 0x11); /* ICW1 - edge, master, ICW4 */ + outb(Int0aux, Int0vec); /* ICW2 - interrupt vector */ + outb(Int0aux, 0x04); /* ICW3 - master level 2 */ + outb(Int0aux, 0x01); /* ICW4 - master, 8086 mode */ + outb(Int0aux, 0x00); /* mask - all enabled */ } diff --git a/port/chan.c b/port/chan.c index 376f44d50acade792d610ac080a8055a608d39d2..d6994fa45fa99295505554d87318cc9bf47b1ab3 100644 --- a/port/chan.c +++ b/port/chan.c @@ -30,6 +30,8 @@ decref(Ref *r) lock(r); x = --r->ref; unlock(r); + if(x < 0) + panic("decref"); return x; } diff --git a/port/devcons.c b/port/devcons.c index 71c6d3b5713f7e2b313d2c5875569e5d80da2b28..7f6353268074d9a23bba0aa7067c16f0e6733df3 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -159,7 +159,7 @@ pprint(char *fmt, ...) Chan *c; int n; - c = u->fd[2]; + c = u->p->fgrp->fd[2]; if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) return 0; n = sprint(buf, "%s %d: ", u->p->text, u->p->pid); @@ -294,6 +294,7 @@ enum{ Qmsec, Qclock, Qsysstat, + Qswap, }; Dirtab consdir[]={ @@ -312,6 +313,7 @@ Dirtab consdir[]={ "msec", {Qmsec}, NUMSIZE, 0400, "clock", {Qclock}, 2*NUMSIZE, 0400, "sysstat", {Qsysstat}, 0, 0600, + "swap", {Qswap}, 0, 0666, }; #define NCONS (sizeof consdir/sizeof(Dirtab)) @@ -581,6 +583,12 @@ consread(Chan *c, void *buf, long n, ulong offset) } return readstr(offset, buf, n, xbuf); + case Qswap: + sprint(xbuf, "%d/%d memory %d/%d swap\n", + palloc.user-palloc.freecount, palloc.user, + conf.nswap-swapalloc.free, conf.nswap); + + return readstr(offset, buf, n, xbuf); default: panic("consread %lux\n", c->qid); return 0; @@ -637,7 +645,8 @@ conswrite(Chan *c, void *va, long n, ulong offset) long l, m; char *a = va; Mach *mp; - int id; + int id, fd; + Chan *swc; switch(c->qid.path){ case Qrcons: @@ -710,6 +719,16 @@ conswrite(Chan *c, void *va, long n, ulong offset) } break; + case Qswap: + if(n >= sizeof buf) + error(Egreg); + memmove(buf, va, n); /* so we can NUL-terminate */ + buf[n] = 0; + fd = strtoul(buf, 0, 0); + swc = fdtochan(fd, -1); + setswapchan(swc); + return n; + default: error(Egreg); } diff --git a/port/devdup.c b/port/devdup.c index 4a0ca33f741112bd88a56e38657070233d8deab0..5962394371649afaa463015aa4e170fa9333914f 100644 --- a/port/devdup.c +++ b/port/devdup.c @@ -12,12 +12,13 @@ int dupgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) { char buf[8]; + Fgrp *fgrp = u->p->fgrp; Chan *f; static int perm[] = { 0400, 0200, 0600, 0 }; if(s >= NFD) return -1; - if((f=u->fd[s]) == 0) + if((f=fgrp->fd[s]) == 0) return 0; sprint(buf, "%ld", s); devdir(c, (Qid){s, 0}, buf, 0, perm[f->mode&3], dp); @@ -72,7 +73,7 @@ dupopen(Chan *c, int omode) return c; } fdtochan(c->qid.path, openmode(omode)); /* error check only */ - f = u->fd[c->qid.path]; + f = u->p->fgrp->fd[c->qid.path]; close(c); incref(f); if(omode & OCEXEC) diff --git a/port/devenv.c b/port/devenv.c index e450c0ba785c7127997f036d4f0ed1079572b7d5..387fb2959c2f50819a9914c297fc74378a70f339 100644 --- a/port/devenv.c +++ b/port/devenv.c @@ -211,15 +211,15 @@ int envgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) { Env *e; - Pgrp *pg; + Egrp *eg; int ans; - pg = u->p->pgrp; - lock(pg); - if(s >= pg->nenv) + eg = u->p->egrp; + lock(eg); + if(s >= eg->nenv) ans = -1; else{ - e = pg->etab[s].env; + e = eg->etab[s].env; if(e == 0) ans = 0; else{ @@ -229,7 +229,7 @@ envgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) ans = 1; } } - unlock(pg); + unlock(eg); return ans; } @@ -242,13 +242,13 @@ envattach(char *spec) Chan* envclone(Chan *c, Chan *nc) { - Pgrp *pg; + Egrp *eg; if(!(c->qid.path&CHDIR)){ - pg = u->p->pgrp; - lock(pg); - pg->etab[c->qid.path-1].chref++; - unlock(pg); + eg = u->p->egrp; + lock(eg); + eg->etab[c->qid.path-1].chref++; + unlock(eg); } return devclone(c, nc); } @@ -256,14 +256,14 @@ envclone(Chan *c, Chan *nc) int envwalk(Chan *c, char *name) { - Pgrp *pg; + Egrp *eg; if(devwalk(c, name, 0, 0, envgen)){ if(!(c->qid.path&CHDIR)){ - pg = u->p->pgrp; - lock(pg); - pg->etab[c->qid.path-1].chref++; - unlock(pg); + eg = u->p->egrp; + lock(eg); + eg->etab[c->qid.path-1].chref++; + unlock(eg); return 1; } } @@ -281,17 +281,17 @@ envopen(Chan *c, int omode) { Env *e, *ne; Envp *ep; - Pgrp *pg; + Egrp *eg; if(omode & (OWRITE|OTRUNC)){ if(c->qid.path & CHDIR) error(Eperm); - pg = u->p->pgrp; - lock(pg); - ep = &pg->etab[c->qid.path-1]; + eg = u->p->egrp; + lock(eg); + ep = &eg->etab[c->qid.path-1]; e = ep->env; if(!e){ - unlock(pg); + unlock(eg); error(Egreg); } lock(&envalloc); @@ -299,7 +299,7 @@ envopen(Chan *c, int omode) if(waserror()){ unlock(e); unlock(&envalloc); - unlock(pg); + unlock(eg); nexterror(); } if(e->pgref == 0) @@ -318,7 +318,7 @@ envopen(Chan *c, int omode) poperror(); unlock(e); unlock(&envalloc); - unlock(pg); + unlock(eg); } c->mode = openmode(omode); c->flag |= COPEN; @@ -330,17 +330,17 @@ void envcreate(Chan *c, char *name, int omode, ulong perm) { Env *e; - Pgrp *pg; + Egrp *eg; int i; if(c->qid.path != CHDIR) error(Eperm); - pg = u->p->pgrp; - lock(pg); + eg = u->p->egrp; + lock(eg); lock(&envalloc); if(waserror()){ unlock(&envalloc); - unlock(pg); + unlock(eg); nexterror(); } e = envalloc.efree; @@ -352,21 +352,21 @@ envcreate(Chan *c, char *name, int omode, ulong perm) e->next = 0; e->pgref = 1; strncpy(e->name, name, NAMELEN); - if(pg->nenv == conf.npgenv){ - for(i = 0; inenv; i++) - if(pg->etab[i].chref == 0) + if(eg->nenv == conf.npgenv){ + for(i = 0; inenv; i++) + if(eg->etab[i].chref == 0) break; - if(i == pg->nenv){ - print("out of pgroup envs\n"); + if(i == eg->nenv){ + print("out of egroup envs\n"); error(Enoenv); } }else - i = pg->nenv++; + i = eg->nenv++; c->qid.path = i+1; - pg->etab[i].env = e; - pg->etab[i].chref = 1; + eg->etab[i].env = e; + eg->etab[i].chref = 1; unlock(&envalloc); - unlock(pg); + unlock(eg); c->offset = 0; c->mode = openmode(omode); poperror(); @@ -378,22 +378,22 @@ envremove(Chan *c) { Env *e; Envp *ep; - Pgrp *pg; + Egrp *eg; if(c->qid.path & CHDIR) error(Eperm); - pg = u->p->pgrp; - lock(pg); - ep = &pg->etab[c->qid.path-1]; + eg = u->p->egrp; + lock(eg); + ep = &eg->etab[c->qid.path-1]; e = ep->env; if(!e){ - unlock(pg); + unlock(eg); error(Enonexist); } ep->env = 0; ep->chref--; envpgclose(e); - unlock(pg); + unlock(eg); } void @@ -407,14 +407,14 @@ envwstat(Chan *c, char *db) void envclose(Chan * c) { - Pgrp *pg; + Egrp *eg; if(c->qid.path & CHDIR) return; - pg = u->p->pgrp; - lock(pg); - pg->etab[c->qid.path-1].chref--; - unlock(pg); + eg = u->p->egrp; + lock(eg); + eg->etab[c->qid.path-1].chref--; + unlock(eg); } void @@ -441,16 +441,16 @@ envread(Chan *c, void *va, long n, ulong offset) Envval *ev; char *p; long vn; - Pgrp *pg; + Egrp *eg; char *a = va; if(c->qid.path & CHDIR) return devdirread(c, a, n, 0, 0, envgen); - pg = u->p->pgrp; - lock(pg); - e = pg->etab[c->qid.path-1].env; + eg = u->p->egrp; + lock(eg); + e = eg->etab[c->qid.path-1].env; if(!e){ - unlock(pg); + unlock(eg); error(Eio); } lock(e); @@ -463,7 +463,7 @@ envread(Chan *c, void *va, long n, ulong offset) else memmove(a, ev->dat+offset, n); unlock(e); - unlock(pg); + unlock(eg); return n; } @@ -474,16 +474,16 @@ envwrite(Chan *c, void *va, long n, ulong offset) char *p; Envval *ev; long vn; - Pgrp *pg; + Egrp *eg; char *a = va; if(n <= 0) return 0; - pg = u->p->pgrp; - lock(pg); - e = pg->etab[c->qid.path-1].env; /* caller checks for CHDIR */ + eg = u->p->egrp; + lock(eg); + e = eg->etab[c->qid.path-1].env; /* caller checks for CHDIR */ if(!e){ - unlock(pg); + unlock(eg); error(Eio); } lock(&envalloc); @@ -491,7 +491,7 @@ envwrite(Chan *c, void *va, long n, ulong offset) if(waserror()){ unlock(e); unlock(&envalloc); - unlock(pg); + unlock(eg); nexterror(); } if(e->pgref>1) @@ -506,7 +506,7 @@ envwrite(Chan *c, void *va, long n, ulong offset) poperror(); unlock(e); unlock(&envalloc); - unlock(pg); + unlock(eg); return n; } @@ -516,12 +516,12 @@ dumpenv(void) Env *e; Envp *ep; Envval *ev; - Pgrp *pg; + Egrp *eg; int i; char hold; - pg = u->p->pgrp; - for(ep=pg->etab, i=0; inenv; i++, ep++) + eg = u->p->egrp; + for(ep=eg->etab, i=0; inenv; i++, ep++) print("P%d(%lux %d)",i, ep->env, ep->chref); for(e=envalloc.earena; e<&envalloc.earena[conf.nenv]; e++) if(e->pgref){ diff --git a/port/devip.c b/port/devip.c index 006dfaa56bbf6a98c5d93180694cdfc7c9951f27..8faa1c89b796fee4c039118030b6a5188b9d38bb 100644 --- a/port/devip.c +++ b/port/devip.c @@ -71,6 +71,7 @@ ipreset(void) } initfrag(conf.frag); + tcpinit(); } void diff --git a/port/deviproute.c b/port/deviproute.c index 0b2167618bf864082b9d9138fb86efc9e651e297..2a6abb6f721f949b5b557f3dc4ec498a073f1ec2 100644 --- a/port/deviproute.c +++ b/port/deviproute.c @@ -190,7 +190,7 @@ enum{ Qdata, }; Dirtab iproutetab[]={ - "iproute", {Qdata}, 0, 0666, + "iproute", {Qdata}, 0, 0600, }; #define Niproutetab (sizeof(iproutetab)/sizeof(Dirtab)) diff --git a/port/devproc.c b/port/devproc.c index 0c459223ee46345a9b0eb313df76655d4898a3ee..07126527bff762e7213b98d1873eb660acc843e3 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -14,6 +14,7 @@ enum{ Qnote, Qnotepg, Qproc, + Qsegment, Qstatus, Qtext, }; @@ -24,10 +25,20 @@ Dirtab procdir[]={ "note", {Qnote}, 0, 0600, "notepg", {Qnotepg}, 0, 0200, "proc", {Qproc}, sizeof(Proc), 0600, + "segment", {Qsegment}, 0, 0400, "status", {Qstatus}, NAMELEN+12+6*12, 0600, "text", {Qtext}, 0, 0600, }; +char *sname[]={ /* Segment type from portdat.h */ + "Text", + "Data", + "Bss", + "Stack", + "Shared", + "Phys", +}; + /* * Qids are, in path: * 4 bits of file type (qids above) @@ -47,7 +58,7 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) { Proc *p; char buf[NAMELEN]; - ulong pid; + ulong pid, path; if(c->qid.path == CHDIR){ if(s >= conf.nproc) @@ -65,7 +76,8 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) if(tab) panic("procgen"); tab = &procdir[s]; - devdir(c, (Qid){(~CHDIR)&(c->qid.path|tab->qid.path), c->qid.vers}, + path = c->qid.path&~(CHDIR|((1<qid.path, c->qid.vers}, tab->name, tab->length, tab->perm, dp); return 1; } @@ -112,7 +124,7 @@ procopen(Chan *c, int omode) { Proc *p; Pgrp *pg; - Orig *o; + Segment *s; Chan *tc; if(c->qid.path == CHDIR){ @@ -129,11 +141,11 @@ procopen(Chan *c, int omode) switch(QID(c->qid)){ case Qtext: - o = p->seg[TSEG].o; - if(o==0 || p->state==Dead) + s = p->seg[TSEG]; + if(s==0 || p->state==Dead || s->image==0) goto Died; - tc = o->chan; + tc = s->image->c; if(tc == 0) goto Died; @@ -154,6 +166,7 @@ procopen(Chan *c, int omode) return tc; case Qctl: case Qnote: + case Qsegment: break; case Qnotepg: @@ -213,17 +226,18 @@ long procread(Chan *c, void *va, long n, ulong offset) { char *a = va, *b; - char statbuf[2*NAMELEN+12+6*12]; + char statbuf[NSEG*32]; Proc *p; - Seg *s; - Orig *o; + Pte *pte; + Segment *s; Page *pg; KMap *k; - PTE *pte, *opte; - int i; + int i, j; long l; long pid; User *up; + ulong soff; + Segment *sg; if(c->qid.path & CHDIR) return devdirread(c, a, n, 0, 0, procgen); @@ -242,32 +256,22 @@ procread(Chan *c, void *va, long n, ulong offset) */ if(((offset+n)&~(BY2PG-1)) != (offset&~(BY2PG-1))) n = BY2PG - (offset&(BY2PG-1)); - s = seg(p, offset); + s = seg(p, offset, 1); if(s){ - o = s->o; - if(o == 0) - error(Eprocdied); - lock(o); - if(s->o!=o || p->pid!=PID(c->qid)){ - unlock(o); + if(p->pid!=PID(c->qid)){ + qunlock(&s->lk); error(Eprocdied); } - if(seg(p, offset) != s){ - unlock(o); - error(Egreg); - } - pte = &o->pte[(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){ + + soff = offset-s->base; + pte = s->map[soff/PTEMAPMEM]; + pg = 0; + if(pte) + pg = pte->pages[(soff&(PTEMAPMEM-1))/BY2PG]; + + s->steal++; + qunlock(&s->lk); + if(pagedout(pg)){ pprint("nonresident page addr %lux (complain to rob)\n", offset); memset(a, 0, n); }else{ @@ -276,6 +280,9 @@ procread(Chan *c, void *va, long n, ulong offset) memmove(a, b+(offset&(BY2PG-1)), n); kunmap(k); } + qlock(&s->lk); + s->steal--; + qunlock(&s->lk); return n; } /* u area */ @@ -355,6 +362,19 @@ procread(Chan *c, void *va, long n, ulong offset) } memmove(a, statbuf+offset, n); return n; + case Qsegment: + j = 0; + for(i = 0; i < NSEG; i++) + if(sg = p->seg[i]) + j += sprint(&statbuf[j], "%-6s %c %.8lux %.8lux %4d\n", + sname[sg->type&SG_TYPE], sg->type&SG_RONLY ? 'R' : ' ', + sg->base, sg->top, sg->ref); + if(offset >= j) + return 0; + if(offset+n > j) + n = j-offset; + memmove(a, &statbuf[offset], n); + return n; } error(Egreg); } @@ -404,11 +424,31 @@ procwrite(Chan *c, void *va, long n, ulong offset) switch(QID(c->qid)){ case Qctl: - if(p->state==Broken && n>=4 && strncmp(va, "exit", 4)==0) - ready(p); + if(n >= 4 && strncmp(va, "exit", 4) == 0) { + if(p->state == Broken) { + ready(p); + break; + } + } else - error(Ebadctl); - break; + if(n >= 4 && strncmp(va, "stop", 4) == 0) { + p->procctl = Proc_stopme; + break; + } + else + if(n >= 5 && strncmp(va, "start", 5) == 0) { + if(p->state == Stopped) { + ready(p); + break; + } + errors("not stopped"); + } + else + if(n >= 4 && strncmp(va, "kill", 4) == 0) { + p->procctl = Proc_exitme; + break; + } + error(Ebadctl); case Qnote: k = kmap(p->upage); up = (User*)VA(k); diff --git a/port/devscsi.c b/port/devscsi.c index 0314ec8cec16b9411f32b60927661c0eb564c03f..1499e86bb4c8833ab4a5dce894ef6edba0fd1c63 100644 --- a/port/devscsi.c +++ b/port/devscsi.c @@ -104,7 +104,7 @@ scsiwalk(Chan *c, char *name) void scsistat(Chan *c, char *db) { - devstat(c, db, 0, 0, scsigeno); + devstat(c, db, 0, 0, scsigen); } Chan * @@ -579,9 +579,5 @@ scsictrlintr(void) default: panic("scsi status 0x%2.2ux", status); } - kprint("resetting..."); - PUT(Own_id, ownid); - PUT(Cmd, Reset); - break; } } diff --git a/port/devsrv.c b/port/devsrv.c index 58e6e4b61c9dd7f011eb399b41eddc3b5e7a7840..e7288f551cfc5224da33b83bda397841d98d01a3 100644 --- a/port/devsrv.c +++ b/port/devsrv.c @@ -275,8 +275,7 @@ srvwrite(Chan *c, void *va, long n, ulong offset) memmove(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; fd = strtoul(buf, 0, 0); - fdtochan(fd, -1); /* error check only */ - e->chan = u->fd[fd]; + e->chan = fdtochan(fd, -1); incref(e->chan); unlock(e); poperror(); diff --git a/port/devwren.c b/port/devwren.c index c313cf352f4b6f912f93a3e761375758229804d0..b0937a0f9c91c30fa3577576362fd7fd82cf9ccb 100644 --- a/port/devwren.c +++ b/port/devwren.c @@ -150,7 +150,7 @@ wrenattach(char *param) d = &wren[dev]; d->blocksize = BGLONG(&buf[4]); - plen = BGLONG(&buf[0])+1; + plen = BGLONG(&buf[0]); d->p[Npart].firstblock = 0; d->p[Npart].maxblock = plen; plen = plen/Npart; diff --git a/port/fault.c b/port/fault.c index 1cec35658293163a71d8fedd26d84bfa3ef6cfc4..6780f47e5b1178504231277c19370a1522ef186d 100644 --- a/port/fault.c +++ b/port/fault.c @@ -6,227 +6,211 @@ #include "ureg.h" #include "errno.h" +#define DPRINT + int fault(ulong addr, int read) { - ulong mmuvirt, mmuphys, n; - Seg *s; - PTE *opte, *pte, *npte; - Orig *o; - char *l; - Page *pg; - int zeroed = 0, head = 1; - int i, touched = 0; - KMap *k, *k1; + ulong mmuphys=0, soff; + Segment *s; + Pte **p; + Page **pg, *lkp, *new = 0; + int type; m->pfault++; - s = seg(u->p, addr); - if(s == 0){ - if(addr > USTKTOP) - return -1; - s = &u->p->seg[SSEG]; - if(s->o==0 || addrmaxva-USTKSIZE || addr>=s->maxva) - return -1; - /* grow stack */ - o = s->o; - n = o->npte; - if(waserror()){ - pprint("can't allocate stack page\n"); - return -1; - } - growpte(o, (s->maxva-addr)>>PGSHIFT); - poperror(); - /* stacks grown down, sigh */ - lock(o); - memmove(o->pte+(o->npte-n), o->pte, n*sizeof(PTE)); - memset(o->pte, 0, (o->npte-n)*sizeof(PTE)); - unlock(o); - s->minva = addr; - o->va = addr; - }else - o = s->o; - if(!read && (o->flag&OWRPERM)==0) +again: + s = seg(u->p, addr, 1); + if(s == 0) + return -1; + + if(!read && (s->type&SG_RONLY)) { + qunlock(&s->lk); return -1; - lock(o); - opte = &o->pte[(addr-o->va)>>PGSHIFT]; - pte = opte; - if(s->mod){ - while(pte = pte->nextmod) /* assign = */ - if(pte->proc == u->p){ - if(pte->page==0 || pte->page->va!=addr) - panic("bad page %lux", pte->page); - head = 0; - break; - } - if(pte == 0) - pte = opte; } - if(pte->page == 0){ - touched = 1; - if(o->chan==0 || addr>(o->va+(o->maxca-o->minca))){ - /* Make a new bss or lock segment page */ - if(s - u->p->seg == LSEG) { - pte->page = lkpage(o, addr); - if(pte->page == 0) { - unlock(o); - return -1; - } - } - else - pte->page = newpage(0, o, addr); - zeroed = 1; - o->npage++; - }else{ - /* - * Demand load. Release o because it could take a while. - */ - unlock(o); - n = (o->va+(o->maxca-o->minca)) - addr; - if(n > BY2PG) - n = BY2PG; - pg = newpage(1, o, addr); - k = kmap(pg); - qlock(&o->chan->rdl); - if(waserror()){ - kunmap(k); - qunlock(&o->chan->rdl); - pg->o = 0; - pg->ref--; - pexit("demand load i/o error", 0); - } - l = (char*)VA(k); - if((*devtab[o->chan->type].read)(o->chan, l, n, (addr-o->va) + o->minca) != n) - error(Eioload); - flushpage(pg->pa); - qunlock(&o->chan->rdl); - if(npte[(addr-s->minva)>>PGSHIFT]; /* could move */ - pte = opte; - if(pte->page == 0){ - pte->page = pg; - o->npage++; - }else{ /* someone beat us to it */ - pg->o = 0; - pg->ref--; - } + + addr &= ~(BY2PG-1); + soff = addr-s->base; + p = &s->map[soff/PTEMAPMEM]; + if(*p == 0) + *p = ptealloc(); + + pg = &(*p)->pages[(soff&(PTEMAPMEM-1))/BY2PG]; + type = s->type&SG_TYPE; + + switch(type) { + case SG_TEXT: + if(pagedout(*pg)) /* No data - must demand load */ + pio(s, addr, soff, pg); + + mmuphys = PPN((*pg)->pa) | PTERONLY|PTEVALID; + (*pg)->modref = PG_REF; + break; + case SG_SHARED: + case SG_BSS: + case SG_STACK: + /* Zero fill on demand */ + if(*pg == 0) { + if(new == 0 && (new = newpage(1, &s, addr)) && s == 0) + goto again; + *pg = new; + new = 0; } + /* NO break */ + case SG_DATA: + if(pagedout(*pg)) + pio(s, addr, soff, pg); + + if(type == SG_SHARED) + goto done; + + if(read && conf.copymode == 0) { + mmuphys = PPN((*pg)->pa) | PTERONLY|PTEVALID; + (*pg)->modref |= PG_REF; + break; + } + + lkp = *pg; + lockpage(lkp); + if(lkp->ref > 1) { + unlockpage(lkp); + if(new == 0 && (new = newpage(0, &s, addr)) && s == 0) + goto again; + *pg = new; + new = 0; + copypage(lkp, *pg); + putpage(lkp); + } + else { + /* put a duplicate of a text page back onto the free list */ + if(lkp->image) + duppage(lkp); + + unlockpage(lkp); + } + done: + mmuphys = PPN((*pg)->pa) | PTEWRITE|PTEVALID; + (*pg)->modref = PG_MOD|PG_REF; + break; + case SG_PHYSICAL: + if(*pg == 0) + *pg = (*s->pgalloc)(addr); + + mmuphys = PPN((*pg)->pa) | PTEWRITE|PTEUNCACHED|PTEVALID; + (*pg)->modref = PG_MOD|PG_REF; + break; + default: + panic("fault"); + } + + qunlock(&s->lk); + if(new) + putpage(new); + + putmmu(addr, mmuphys, *pg); + return 0; +} + +void +pio(Segment *s, ulong addr, ulong soff, Page **p) +{ + Page *new; + KMap *k; + Chan *c; + int n, ask; + char *kaddr; + ulong daddr; + Page *loadrec; + + loadrec = *p; + if(loadrec == 0) { + daddr = s->fstart+soff; /* Compute disc address */ + new = lookpage(s->image, daddr); + } + else { + daddr = swapaddr(loadrec); + new = lookpage(&swapimage, daddr); + if(new) + putswap(loadrec); } - if(o->flag&OSHARED) { - /* BUG: Does not cover enough flag options to shared data */ - mmuphys = PTERONLY; - if(o->flag & OWRPERM) - mmuphys = PTEWRITE; + if(new) { /* Page found from cache */ + *p = new; + return; } - else if((o->flag&OWRPERM) && (conf.copymode || !read) - && ((head && ((o->flag&OPURE) || o->nproc>1)) - || (!head && pte->page->ref>1))){ - /* - * Copy on reference (conf.copymode==1) or write (conf.copymode==0) - */ - - if(!(o->flag&OISMEM)) - panic("copy on ref/wr to non memory"); - touched = 1; - /* - * Look for the easy way out: are we the last non-modified? - */ - if(head && !(o->flag&OPURE)){ - npte = opte; - for(i=0; npte; i++) - npte = npte->nextmod; - if(i == o->nproc) - goto easy; + + qunlock(&s->lk); + + new = newpage(0, 0, addr); + k = kmap(new); + kaddr = (char*)VA(k); + + if(loadrec == 0) { /* This is demand load */ + c = s->image->c; + qlock(&c->rdl); + if(waserror()) { + qunlock(&c->rdl); + kunmap(k); + putpage(new); + qlock(&s->lk); + qunlock(&s->lk); + pexit("demand load I/O error", 0); } - if(head){ - /* - * Add to mod list - */ - pte = newmod(o); - pte->proc = u->p; - pte->page = opte->page; - pte->page->ref++; - o->npage++; - /* - * Link into opte mod list (same va) - */ - pte->nextmod = opte->nextmod; - opte->nextmod = pte; - /* - * Link into proc mod list (increasing va) - */ - npte = s->mod; - if(npte == 0){ - s->mod = pte; - pte->nextva = 0; - }else{ - while(npte->nextva && npte->nextva->page->vanextva; - pte->nextva = npte->nextva; - npte->nextva = pte; - } - head = 0; + + ask = s->flen-soff; + if(ask > BY2PG) + ask = BY2PG; + n = (*devtab[c->type].read)(c, kaddr, ask, daddr); + if(n != ask) + error(Eioload); + if(ask < BY2PG) + memset(kaddr+ask, 0, BY2PG-ask); + + if((s->type&SG_TYPE) == SG_TEXT) + memset(new->cachectl, PG_TXTFLUSH, sizeof(new->cachectl)); + + poperror(); + kunmap(k); + qunlock(&c->rdl); + qlock(&s->lk); + if(*p == 0) { /* Someone may have got there first */ + new->daddr = daddr; + cachepage(new, s->image); + *p = new; } - pg = pte->page; - /* when creating pages in the bss which are zfod we create a double - * increment on the mod list which must be removed - */ - if(zeroed){ - pg->ref--; - o->npage--; - opte->page = 0; - }else{ /* copy page */ - pte->page = newpage(1, o, addr); - k = kmap(pte->page); - k1 = kmap(pg); - memmove((void*)VA(k), (void*)VA(k1), BY2PG); + else + putpage(new); + } + else { /* This is paged out */ + c = swapimage.c; + qlock(&c->rdl); + + if(waserror()) { + qunlock(&c->rdl); kunmap(k); - kunmap(k1); - if(pg->ref <= 1) - panic("pg->ref <= 1"); - pg->ref--; + putpage(new); + qlock(&s->lk); + qunlock(&s->lk); + pexit("page in I/O error", 0); } - easy: - mmuphys = PTEWRITE; - }else{ - mmuphys = PTERONLY; - if(o->flag & OWRPERM) - if(o->flag & OPURE){ - if(!head && pte->page->ref==1) - mmuphys = PTEWRITE; - }else - if((head && o->nproc==1) - || (!head && pte->page->ref==1)) - mmuphys = PTEWRITE; - } - mmuvirt = addr; - - /* Non memory is always uncached */ - if(o->flag&OISMEM) { - mmuphys |= PPN(pte->page->pa) | PTEVALID; - usepage(pte->page, 1); - }else - mmuphys |= PPN(pte->page->pa) | PTEVALID | PTEUNCACHED; - - if(pte->page->va != addr) - panic("wrong addr in tail %lux %lux", pte->page->va, addr); - if(pte->proc && pte->proc != u->p){ - print("wrong proc in tail %d %s\n", head, u->p->text); - print("u->p %lux pte->proc %lux\n", u->p, pte->proc); - panic("addr %lux seg %d wrong proc in tail", addr, s-u->p->seg); - } + n = (*devtab[c->type].read)(c, kaddr, BY2PG, daddr); + if(n != BY2PG) + error(Eioload); - unlock(o); - if(touched == 0) - m->tlbfault++; + poperror(); + kunmap(k); + qunlock(&c->rdl); + qlock(&s->lk); - putmmu(mmuvirt, mmuphys); - return 0; + if(pagedout(*p)) { + new->daddr = daddr; + cachepage(new, &swapimage); + putswap(*p); + *p = new; + } + else + putpage(new); + } } /* @@ -235,36 +219,35 @@ fault(ulong addr, int read) void validaddr(ulong addr, ulong len, int write) { - Seg *s, *ns; + Segment *s; - if((long)len < 0){ - Err: - pprint("invalid address %lux in sys call pc %lux sp %lux\n", - addr, ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); - postnote(u->p, 1, "sys: bad address", NDebug); - error(Ebadarg); - } - Again: - s = seg(u->p, addr); - if(s==0){ - s = &u->p->seg[SSEG]; - if(s->o==0 || addrmaxva-USTKSIZE || addr>=s->maxva) - goto Err; - } - if(write && (s->o->flag&OWRPERM)==0) - goto Err; - if(addr+len > s->maxva){ - len -= s->maxva - addr; - addr = s->maxva; - goto Again; + if((long)len >= 0) { + for(;;) { + s = seg(u->p, addr, 0); + if(s == 0 || (write && (s->type&SG_RONLY))) + break; + + if(addr+len > s->top) { + len -= s->top - addr; + addr = s->top; + continue; + } + return; + } } -} + pprint("invalid address %lux in sys call pc %lux sp %lux\n", + addr, ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); + + postnote(u->p, 1, "sys: bad address", NDebug); + error(Ebadarg); +} + /* * &s[0] is known to be a valid address. */ void* -vmemchr(void *s, int c, ulong n) +vmemchr(void *s, int c, int n) { int m; char *t; @@ -272,32 +255,37 @@ vmemchr(void *s, int c, ulong n) a = (ulong)s; m = BY2PG - (a & (BY2PG-1)); - while(n){ - if(n < m) - m = n; - t = memchr(s, c, m); + if(m < n){ + t = vmemchr(s, c, m); if(t) return t; - if(n == m) - return 0; if(!(a & KZERO)) validaddr(a+m, 1, 0); - n -= m; - a += m; - m = BY2PG; + return vmemchr((void*)(a+m), c, n-m); } - return 0; + /* + * All in one page + */ + return memchr(s, c, n); } -Seg* -seg(Proc *p, ulong addr) +Segment* +seg(Proc *p, ulong addr, int dolock) { - Seg *s, *et; + Segment **s, **et, *n; et = &p->seg[NSEG]; - for(s=p->seg; s < et; s++) - if(s->o && s->minva<=addr && addrmaxva) - return s; + for(s = p->seg; s < et; s++) + if(n = *s) + if(addr >= n->base && addr < n->top) { + if(dolock == 0) + return n; + + qlock(&n->lk); + if(addr >= n->base && addr < n->top) + return n; + qunlock(&n->lk); + } return 0; } diff --git a/port/ipdat.h b/port/ipdat.h index 37ecd18825c57dd84a4f614cf8d5555749d0a027..92f9da266ad33d16fbdbc8a9a956722f662355e1 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -248,6 +248,8 @@ struct Ipconv { #define TIMER_RUN 1 #define TIMER_EXPIRE 2 +#define Nreseq 64 + #define set_timer(t,x) (((t)->start) = (x)/MSPTICK) #define dur_timer(t) ((t)->start) #define read_timer(t) ((t)->count) diff --git a/port/page.c b/port/page.c index 6ddccac1eb015b1fb98232058d46866e6235b9e1..7715e37497350b529918a9ec55f84afba13bc311 100644 --- a/port/page.c +++ b/port/page.c @@ -6,48 +6,49 @@ #include "ureg.h" #include "errno.h" -struct -{ - Lock; - ulong addr; - int active; - Page *page; /* base of Page structures, indexed by phys page number */ - ulong minppn; /* index of first usable page */ - Page *head; /* most recently used */ - Page *tail; /* least recently used */ -}palloc; - -struct -{ - Lock; - Orig *arena; - Orig *free; -}origalloc; - -typedef union PTEA PTEA; -union PTEA{ - PTE; - struct{ - ulong n; /* for growpte */ - Orig *o; /* for growpte */ - PTEA *next; /* for newmod */ - }; -}; - -struct -{ - Lock; - PTEA *arena; - PTEA *free; - PTEA *end; -}ptealloc; +#define PGHFUN(x, y) (((ulong)x^(ulong)y)%PGHSIZE) +#define pghash(s) palloc.hash[PGHFUN(s->image, p->daddr)] + +struct Palloc palloc; -struct{ +struct Ptealloc +{ Lock; - PTEA *free; -}modalloc; + Pte *free; + int pages; +}ptealloclk; extern long end; +static Lock pglock; + +/* Multiplex a hardware lock for per page manipulations */ +void +lockpage(Page *p) +{ + int s; + + for(;;) { + if(p->lock == 0) { + s = splhi(); + lock(&pglock); + if(p->lock == 0) { + p->lock = 1; + unlock(&pglock); + splx(s); + return; + } + unlock(&pglock); + splx(s); + } + sched(); + } +} + +void +unlockpage(Page *p) +{ + p->lock = 0; +} /* * Called to allocate permanent data structures, before calling pageinit(). @@ -72,73 +73,24 @@ ialloc(ulong n, int align) if(palloc.addr >= conf.maxialloc) panic("keep bill joy away"); - return (void*)(p|KZERO); -} -void -audit(char *s) -{ - int nf, nb; - Page *p; - static int here; - - do;while(here); - here=1; - p = palloc.head; - nf = nb = 0; - while(p){ - print("%lux %lux %d\n", p->pa, p->va, p->ref); - if(p->o){ - print("\t%d %lux %c\n", p->o->nproc, p->o->qid, devchar[p->o->type]); - delay(100); /* let it drain; there's a lot here */ - } - nf++; - p = p->next; - } - p = palloc.tail; - while(p){ - nb++; - p = p->prev; - } - print("%s: nf: %d nb: %d\n", s, nf, nb); - delay(1000); - here=0; + return (void*)(p|KZERO); } void pageinit(void) { ulong pa, nb, ppn; - ulong i; + ulong i, vmem, pmem; Page *p; - PTEA *pte; - Orig *o; - - ptealloc.arena = ialloc(conf.npte*sizeof(PTEA), 0); - ptealloc.free = ptealloc.arena; - ptealloc.end = ptealloc.arena+conf.npte; - modalloc.free = ialloc(conf.nmod*sizeof(PTEA), 0); - - pte = modalloc.free; - for(i=0; inext = pte+1; - pte->next = 0; - - origalloc.free = ialloc(conf.norig*sizeof(Orig), 0); - origalloc.arena = origalloc.free; - - o = origalloc.free; - for(i=0; inext = o+1; - o->next = 0; palloc.active = 1; nb = (conf.npage<>PGSHIFT)*sizeof(Page); /* safe overestimate */ nb &= ~(BY2PG-1); - pa = (conf.npage<> PGSHIFT; /* physical page number of first free page */ + pa = (conf.npage<> PGSHIFT; /* physical page number of first free page */ palloc.page = (Page *)((palloc.addr - ppn*sizeof(Page))|KZERO); /* * Now palloc.page[ppn] describes first free page @@ -149,7 +101,12 @@ pageinit(void) palloc.head = &palloc.page[ppn]; palloc.tail = &palloc.page[conf.npage-1]; memset(palloc.head, 0, (conf.npage-ppn)*sizeof(Page)); - print("%lud free pages\n", conf.npage-ppn); + + pmem = ((conf.npage-ppn)*BY2PG)/1024; + vmem = pmem + ((conf.nswap)*BY2PG)/1024; + palloc.user = conf.npage-ppn; + print("%lud free pages, %dK bytes, swap %dK bytes\n", palloc.user, pmem, vmem); + for(p=palloc.head; p<=palloc.tail; p++,ppn++){ p->next = p+1; p->prev = p-1; @@ -157,583 +114,336 @@ pageinit(void) p->pa = conf.base0+(ppn<pa = conf.base1+((ppn-conf.npage0)<prev = 0; palloc.tail->next = 0; } Page* -newpage(int noclear, Orig *o, ulong va) +newpage(int clear, Segment **s, ulong va) { Page *p; - Orig *o1; KMap *k; + int i; if(palloc.active == 0) print("newpage inactive\n"); -loop: + lock(&palloc); - for(p=palloc.tail; p; p=p->prev){ - if(p->ref == 0) - goto out; -#ifdef asdf - if(p->ref == 1){ /* a pageout daemon should do this */ - o1 = p->o; - if(o1 && o1->nproc==0 && canlock(o1)){ - if(o1->nproc){ - unlock(o1); - continue; - } - print("free %d pages va %lux %lux %c\n", o1->npage, o->va, o1->qid, devchar[o1->type]); - freepage(o1, 0); - /* neworig will free the orig and pte's later */ - unlock(o1); - if(p->ref == 0) - goto out; - print("newpage ref != 0"); - } + + /* The kp test is a poor guard against the pager deadlocking */ + while((palloc.freecount < HIGHWATER && u->p->kp == 0) || palloc.freecount == 0) { + palloc.wanted++; + unlock(&palloc); + if(s && *s) { + qunlock(&((*s)->lk)); + *s = 0; } -#endif + qlock(&palloc.pwait); /* Hold memory requesters here */ + + kickpager(); + tsleep(&palloc.r, ispages, 0, 1000); + + qunlock(&palloc.pwait); + lock(&palloc); + palloc.wanted--; } + + p = palloc.head; + if(palloc.head = p->next) /* = Assign */ + palloc.head->prev = 0; + else + palloc.tail = 0; + + palloc.freecount--; unlock(&palloc); - if(freebroken()) - goto loop; - if(u == 0) + + lockpage(p); + + if(p->ref != 0) panic("newpage"); - print("no physical memory\n"); - pprint("no physical memory\n"); - u->p->state = Wakeme; - alarm(1000, wakeme, u->p); - sched(); - goto loop; - out: - if(p->o){ - print("page in use %lux %lux %lux %lux\n", p, p->va, p->o, origalloc.arena); - print("%c %lux %lux, %d %d %d\n", devchar[p->o->type], p->o->va, p->o->qid, p->o->flag, p->o->nproc, p->o->npte); - panic("shit"); - } - p->ref = 1; - usepage(p, 0); - unlock(&palloc); - if(!noclear){ + + uncachepage(p); + p->ref++; + p->va = va; + p->modref = 0; + for(i = 0; i < MAXMACH; i++) + p->cachectl[i] = PG_NOFLUSH; + unlockpage(p); + + if(clear){ k = kmap(p); memset((void*)VA(k), 0, BY2PG); kunmap(k); } - p->o = o; - p->va = va; return p; } -/* - * Move page to head of list - */ -void -usepage(Page *p, int dolock) +int +ispages(void *p) { - if(dolock) - lock(&palloc); - /* - * Unlink - */ - if(p->prev) - p->prev->next = p->next; - else - palloc.head = p->next; - if(p->next) - p->next->prev = p->prev; - else - palloc.tail = p->prev; - /* - * Link - */ - p->next = palloc.head; - p->prev = 0; - if(p->next) - p->next->prev = p; - else - palloc.tail = p; - palloc.head = p; - if(dolock) - unlock(&palloc); + return palloc.freecount >= HIGHWATER; } -/* - * Move page to tail of list - */ void -unusepage(Page *p, int dolock) +putpage(Page *p) { - if(dolock) - lock(&palloc); - /* - * Unlink - */ - if(p->prev) - p->prev->next = p->next; - else - palloc.head = p->next; - if(p->next) - p->next->prev = p->prev; - else - palloc.tail = p->prev; - /* - * Link - */ - p->prev = palloc.tail; - p->next = 0; - if(p->prev) - p->prev->next = p; - else - palloc.head = p; - palloc.tail = p; - if(dolock) - unlock(&palloc); -} + int count; -Orig* -lookorig(ulong va, ulong npte, int flag, Chan *c) -{ - Orig *o; - ulong i; - - for(o=origalloc.arena,i=0; inpage && o->qid.path==c->qid.path && o->va==va){ - lock(o); - if(o->npage && eqqid(o->qid, c->qid)) - if(o->va==va && o->npte==npte && o->flag==flag) - if(o->mchan==c->mchan && o->type==c->type && eqqid(o->mqid, c->mqid)){ - if(o->chan == 0){ - o->chan = c; - incref(c); - } - o->nproc++; - unlock(o); - return o; - } - unlock(o); - } - return 0; -} + if(onswap(p)) { + putswap(p); + return; + } -Orig* -neworig(ulong va, ulong npte, int flag, Chan *c) -{ - Orig *o; - int i, freed; - -lockloop: - lock(&origalloc); -loop: - if(o = origalloc.free){ /* assign = */ - origalloc.free = o->next; - o->va = va; - o->pte = 0; - o->flag = flag; - o->nproc = 1; - o->npage = 0; - o->chan = c; - o->freepg = unusepage; - if(c){ - o->type = c->type; - o->qid = c->qid; - o->mchan = c->mchan; - o->mqid = c->mqid; - incref(c); - }else{ - o->type = 0xFFFF; - o->qid = (Qid){~0, ~0}; - o->mqid = (Qid){~0, ~0}; - o->mchan = 0; - } - if(u && u->p && waserror()){ - unlock(&origalloc); - nexterror(); + lockpage(p); + if(--p->ref == 0) { + lock(&palloc); + if(p->image) { + if(palloc.tail) { + p->prev = palloc.tail; + palloc.tail->next = p; + p->next = 0; + palloc.tail = p; + } + else { + palloc.head = palloc.tail = p; + p->prev = p->next = 0; + } } - growpte(o, npte); - if(u && u->p) - poperror(); - unlock(&origalloc); - return o; - } - /* - * This is feeble. Orig's should perhaps be held in - * an LRU list. This algorithm is too aggressive. - */ - freed = 0; - for(o=origalloc.arena,i=0; inproc==0 && canlock(o)){ - if(o->nproc){ - unlock(o); - continue; + else { + if(palloc.head) { + p->next = palloc.head; + palloc.head->prev = p; + p->prev = 0; + palloc.head = p; + } + else { + palloc.head = palloc.tail = p; + p->prev = p->next = 0; } - freepage(o, 1); - freepte(o); - unlock(o); - o->next = origalloc.free; - origalloc.free = o; - freed++; } - } - if(freed) - goto loop; - unlock(&origalloc); - if(freebroken()) - goto lockloop; - print("no origs freed\n"); - if(u == 0) - panic("neworig"); - u->p->state = Wakeme; - alarm(1000, wakeme, u->p); - sched(); - lock(&origalloc); - goto loop; -} -PTE* -newmod(Orig *o) -{ - PTEA *pte; - -loop: - lock(&modalloc); - if(pte = modalloc.free){ /* assign = */ - modalloc.free = pte->next; - unlock(&modalloc); - memset(pte, 0, sizeof(PTE)); - return pte; + palloc.freecount++; /* Release people waiting for memory */ + unlock(&palloc); } - unlock(&modalloc); - print("no mods\n"); - if(u == 0) - panic("newmod"); - u->p->state = Wakeme; - alarm(1000, wakeme, u->p); - sched(); - goto loop; + unlockpage(p); + + if(palloc.wanted) + wakeup(&palloc.r); } -/* - * Duplicate mod structure for this segment (old) in new process p. - * old->o must be locked. - */ void -forkmod(Seg *old, Seg *new, Proc *p) +duppage(Page *p) /* Always call with p locked */ { - Orig *o; - PTE *pte, *ppte, *opte, *npte; - ulong va; - - o = old->o; - ppte = 0; - pte = old->mod; - while(pte){ - npte = newmod(o); - npte->proc = p; - npte->page = pte->page; - pte->page->ref++; - o->npage++; - /* - * Link into mod list for this va - */ - npte->nextmod = pte->nextmod; - pte->nextmod = npte; - /* - * Link into mod list for new segment - */ - if(ppte == 0) - new->mod = npte; - else - ppte->nextva = npte; - npte->nextva = 0; - ppte = npte; - pte = pte->nextva; + Page *np; + + lock(&palloc); + + if(palloc.freecount < HIGHWATER || /* No freelist cache when memory is very low */ + p->image == &swapimage) { /* No dup for swap pages */ + unlock(&palloc); + uncachepage(p); + return; } -} -void -freesegs(int save) -{ - int i, j; - Seg *s; - Orig *o; - PTE *pte, *opte; - PTEA *old; - Page *pg; - Chan *c; + np = palloc.head; /* Allocate a new page from freelist */ + if(palloc.head = np->next) /* = Assign */ + palloc.head->prev = 0; + else + palloc.tail = 0; - /* - * flushvirt() is a no-op on machines without virtual write-back caches. - * On such machines it is necessary to make sure the caches are flushed - * before the pages are remapped. - */ - flushvirt(); - s = u->p->seg; - for(i=0; io; - s->o = 0; /* seg() won't match it (e.g. in procread()) */ - if(o == 0) - continue; - lock(o); - if(pte = s->mod){ /* assign = */ - while(pte){ - opte = &o->pte[(pte->page->va-o->va)>>PGSHIFT]; - while(opte->nextmod != pte){ - if(opte->page && opte->page->va != pte->page->va) - panic("pte %lux %lux\n", opte->page->va, pte->page->va); - opte = opte->nextmod; - if(opte == 0) - panic("freeseg opte==0"); - } - opte->nextmod = pte->nextmod; - pg = pte->page; - if(pg->ref == 1){ - pte->page = 0; - pg->o = 0; - } - pg->ref--; - o->npage--; - old = (PTEA*)pte; - pte = pte->nextva; - lock(&modalloc); - old->next = modalloc.free; - modalloc.free = old; - unlock(&modalloc); - } - } - o->nproc--; - if(o->nproc == 0){ - if(c = o->chan){ /* assign = */ - o->chan = 0; - close(c); - } - if(!(o->flag&OCACHED) || o->npage==0){ - freepage(o, 1); - freepte(o); - unlock(o); - lock(&origalloc); - o->next = origalloc.free; - origalloc.free = o; - unlock(&origalloc); - }else - unlock(o); - }else{ - /* - * BUG: there is a leak here. if the origin pte is being used only - * by the exiting process, the associated page will linger. the fix - * is to remember either the length of the mod list at each va or - * the number of processes sharing the origin pte, and to promote one - * of the mods to the origin pte when no process is left using the - * origin pte. - */ - unlock(o); - } + if(palloc.tail) { /* Link back onto tail to give us lru */ + np->prev = palloc.tail; + palloc.tail->next = np; + np->next = 0; + palloc.tail = np; + } + else { + palloc.head = palloc.tail = np; + np->prev = np->next = 0; } -} -/* - * Adjust segment to desired size. This implementation is rudimentary. - */ -int -segaddr(Seg *s, ulong min, ulong max) -{ - Orig *o; - - if(max < min) - return 0; - if(min != s->minva) /* can't grow down yet (stacks: fault.c) */ - return 0; - max = PGROUND(max); - o = s->o; - if(max == s->maxva) - return 1; - if(max > s->maxva){ - /* - * Grow - */ - /* BUG: check spill onto other segments */ - if(o->va+BY2PG*o->npte < max) - growpte(o, (max-o->va)>>PGSHIFT); - s->maxva = max; - return 1; + unlock(&palloc); + + lockpage(np); /* Cache the new version */ + if(np->ref != 0) { /* Stolen by new page */ + uncachepage(p); + unlockpage(np); + return; } - /* - * Shrink - */ - print("segaddr shrink"); - pexit("Suicide", 0); + + uncachepage(np); + np->va = p->va; + np->daddr = p->daddr; + copypage(p, np); + cachepage(np, p->image); + unlockpage(np); + uncachepage(p); } -/* - * o is locked - */ void -freepage(Orig *o, int dolock) +copypage(Page *f, Page *t) { - PTE *pte; - Page *pg; - int i; + KMap *ks, *kd; + + ks = kmap(f); + kd = kmap(t); + memmove((void*)VA(kd), (void*)VA(ks), BY2PG); + kunmap(ks); + kunmap(kd); +} - pte = o->pte; - for(i=0; inpte; i++,pte++) { - if(pg = pte->page){ /* assign = */ - if(pg->ref == 1){ - (*o->freepg)(pg, dolock); - pte->page = 0; - pg->o = 0; +void +uncachepage(Page *p) /* Alway called with a locked page */ +{ + Page **l, *f; + + if(p->image) { + lock(&palloc.hashlock); + l = &pghash(p); + for(f = *l; f; f = f->hash) { + if(f == p) { + *l = p->hash; + break; } - pg->ref--; + l = &f->hash; } + unlock(&palloc.hashlock); + putimage(p->image); + p->image = 0; } - o->npage = 0; } -/* - * Compacting allocator - */ - void -freepte(Orig *o) /* o is locked */ +cachepage(Page *p, Image *i) { - PTEA *p; - p = (PTEA*)(o->pte - 1); - p->o = 0; + Page **l; + + incref(i); + lock(&palloc.hashlock); + p->image = i; + l = &pghash(p); + p->hash = *l; + *l = p; + unlock(&palloc.hashlock); } -/* - * o is locked. this will always do a grow; if n<=o->npte someone - * else got here first and we can just return. - */ -void -growpte(Orig *o, ulong n) +Page * +lookpage(Image *i, ulong daddr) { - PTEA *p; - ulong nfree; - - lock(&ptealloc); - lock(o); - if(o->pte){ - if(o->npte >= n) - goto Return; - p = (PTEA*)(o->pte - 1); - n++; - if(p+p->n == ptealloc.free){ - if(!compactpte(o, n - p->n)) - goto Trouble; - p = (PTEA*)(o->pte - 1); - ptealloc.free += n - p->n; - }else{ - if(!compactpte(o, n)) - goto Trouble; - p = ptealloc.free; - ptealloc.free += n; - memmove(p+1, o->pte, o->npte*sizeof(PTE)); - p->o = o; - ((PTEA*)(o->pte-1))->o = 0; - o->pte = p+1; + Page *f; + + lock(&palloc.hashlock); + for(f = palloc.hash[PGHFUN(i, daddr)]; f; f = f->hash) { + if(f->image == i && f->daddr == daddr) { + unlock(&palloc.hashlock); + + lockpage(f); + if(f->image != i || f->daddr != daddr) { + unlockpage(f); + return 0; + } + + lock(&palloc); + if(++f->ref == 1) { + if(f->prev) + f->prev->next = f->next; + else + palloc.head = f->next; + + if(f->next) + f->next->prev = f->prev; + else + palloc.tail = f->prev; + palloc.freecount--; + } + unlock(&palloc); + + unlockpage(f); + return f; } - memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE)); - p->n = n; - o->npte = n-1; - goto Return; } - n++; - if(!compactpte(o, n)) - goto Trouble; - p = ptealloc.free; - ptealloc.free += n; - memset(p, 0, n*sizeof(PTE)); - p->n = n; - p->o = o; - o->pte = p+1; - o->npte = n-1; - Return: - unlock(&ptealloc); - unlock(o); - return; - - Trouble: - unlock(&ptealloc); - unlock(o); - if(u && u->p) - error(Enovmem); - panic("growpte fails %d %lux %d\n", n, o->va, o->npte); + unlock(&palloc.hashlock); + return 0; } -int -compactpte(Orig *o, ulong n) +Pte* +ptecpy(Pte *old) { - PTEA *p1, *p2; - Orig *p2o; - - if(ptealloc.end-ptealloc.free >= n) - return 1; - p1 = ptealloc.arena; /* dest */ - p2 = ptealloc.arena; /* source */ - while(p2 < ptealloc.free){ - p2o = p2->o; - if(p2o == 0){ - Free: - p2 += p2->n; - continue; - } - if(p1 != p2){ - if(p2o != o) - lock(p2o); - if(p2->o != p2o){ /* freepte()d very recently */ - if(p2->o) - panic("compactpte p2->o %lux\n", p2->o); - unlock(p2o); - goto Free; + Page **src, **dst, **end; + Pte *new; + + new = ptealloc(); + + end = &old->pages[PTEPERTAB]; + for(src = old->pages, dst = new->pages; src < end; src++, dst++) + if(*src) { + if(onswap(*src)) + dupswap(*src); + else { + lockpage(*src); + (*src)->ref++; + unlockpage(*src); } - memmove(p1, p2, p2->n*sizeof(PTE)); - p2o->pte = p1+1; - if(p2o != o) - unlock(p2o); + *dst = *src; } - p2 += p1->n; - p1 += p1->n; - } - ptealloc.free = p1; - if(ptealloc.end-ptealloc.free >= n) - return 1; - unlock(o); - unlock(&ptealloc); - if(u && u->p) - print("%s: %s: ", u->p->text, u->p->pgrp->user); - print("compactpte fails addr %lux %lux %d\n", o->va+n*BY2PG, o->va, n); - return 0; + + return new; } -long -ibrk(ulong addr, int seg) +Pte* +ptealloc(void) { - Seg *s; + Pte *new; + int i, n; + KMap *k; - s = &u->p->seg[seg]; - if(seg == LSEG && s->o == 0) - mklockseg(s); + lock(&ptealloclk); + while(ptealloclk.free == 0) { + unlock(&ptealloclk); - /* Allows us to determine the base of the segment */ - if(addr == 0) - return s->minva; + k = kmap(newpage(1, 0, 0)); + new = (Pte*)VA(k); + n = (BY2PG/sizeof(Pte))-1; + for(i = 0; i < n; i++) + new[i].next = &new[i+1]; - if(addr < s->endseg){ - pprint("addr below segment\n"); - pexit("Suicide", 0); - error(Esegaddr); + lock(&ptealloclk); + ptealloclk.pages++; + new[i].next = ptealloclk.free; + ptealloclk.free = new; } - if(addr > PGROUND(s->endseg)) - if(segaddr(s, s->minva, addr) == 0){ - pprint("bad segaddr in brk\n"); - pexit("Suicide", 0); - error(Esegaddr); - } + new = ptealloclk.free; + ptealloclk.free = new->next; + unlock(&ptealloclk); + memset(new->pages, 0, sizeof(new->pages)); + return new; +} - s->endseg = addr; - return 0; +void +freepte(Segment *s, Pte *p) +{ + Page **pg, **ptop; + + ptop = &p->pages[PTEPERTAB]; + + switch(s->type&SG_TYPE) { + case SG_PHYSICAL: + for(pg = p->pages; pg < ptop; pg++) + if(*pg) + (*s->pgfree)(*pg); + break; + default: + for(pg = p->pages; pg < ptop; pg++) + if(*pg) + putpage(*pg); + } + + lock(&ptealloclk); + p->next = ptealloclk.free; + ptealloclk.free = p; + unlock(&ptealloclk); } diff --git a/port/pgrp.c b/port/pgrp.c index 21edb77050767d30e8e390c227476cbed4eec9fe..70833cc42f417aa947540031d49af4245740abcf 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -5,13 +5,26 @@ #include "fns.h" #include "errno.h" -struct{ +struct +{ Lock; Pgrp *arena; Pgrp *free; ulong pgrpid; }pgrpalloc; +struct +{ + Lock; + Egrp *free; +}egrpalloc; + +struct +{ + Lock; + Fgrp *free; +}fgrpalloc; + struct{ Lock; Mount *free; @@ -19,11 +32,13 @@ struct{ }mountalloc; void -pgrpinit(void) +grpinit(void) { int i; Pgrp *p; - Mount *m; + Egrp *e, *ee; + Fgrp *f, *fe; + Mount *m, *em; pgrpalloc.arena = ialloc(conf.npgrp*sizeof(Pgrp), 0); pgrpalloc.free = pgrpalloc.arena; @@ -33,14 +48,26 @@ pgrpinit(void) p->index = i; p->next = p+1; p->mtab = ialloc(conf.nmtab*sizeof(Mtab), 0); - p->etab = ialloc(conf.npgenv*sizeof(Envp*), 0); } p[-1].next = 0; - mountalloc.free = ialloc(conf.nmount*sizeof(Mount), 0); + egrpalloc.free = ialloc(conf.npgrp*sizeof(Egrp), 0); + ee = &egrpalloc.free[conf.npgrp]; + for(e = egrpalloc.free; e < ee; e++) { + e->next = e+1; + e->etab = ialloc(conf.npgenv*sizeof(Envp*), 0); + } + e[-1].next = 0; + + fgrpalloc.free = ialloc(conf.nproc*sizeof(Fgrp), 0); + fe = &fgrpalloc.free[conf.nproc-1]; + for(f = fgrpalloc.free; f < fe; f++) + f->next = f+1; + f->next = 0; - m = mountalloc.free; - for(i=0; inext = m+1; m->next = 0; } @@ -86,25 +113,88 @@ newpgrp(void) { Pgrp *p; -loop: - lock(&pgrpalloc); - if(p = pgrpalloc.free){ /* assign = */ - pgrpalloc.free = p->next; - p->ref = 1; - p->pgrpid = ++pgrpalloc.pgrpid; - p->nmtab = 0; - p->nenv = 0; + for(;;) { + lock(&pgrpalloc); + if(p = pgrpalloc.free){ + pgrpalloc.free = p->next; + p->ref = 1; + p->pgrpid = ++pgrpalloc.pgrpid; + p->nmtab = 0; + unlock(&pgrpalloc); + return p; + } unlock(&pgrpalloc); - return p; + resrcwait("no pgrps"); } - unlock(&pgrpalloc); - print("no pgrps\n"); +} + +Egrp* +newegrp(void) +{ + Egrp *e; + + for(;;) { + lock(&egrpalloc); + if(e = egrpalloc.free) { + egrpalloc.free = e->next; + e->ref = 1; + e->nenv = 0; + unlock(&egrpalloc); + return e; + } + unlock(&egrpalloc); + resrcwait("no envgrps"); + } +} + +Fgrp* +newfgrp(void) +{ + Fgrp *f; + + for(;;) { + lock(&fgrpalloc); + if(f = fgrpalloc.free) { + fgrpalloc.free = f->next; + f->ref = 1; + f->maxfd = 0; + memset(f->fd, 0, sizeof(f->fd)); + unlock(&fgrpalloc); + return f; + } + unlock(&fgrpalloc); + resrcwait("no filegrps"); + } +} + +Fgrp* +dupfgrp(Fgrp *f) +{ + Fgrp *new; + Chan *c; + int i; + + new = newfgrp(); + + new->maxfd = f->maxfd; + for(i = 0; i <= f->maxfd; i++) + if(c = f->fd[i]){ + incref(c); + new->fd[i] = c; + } + + return new; +} + +void +resrcwait(char *reason) +{ + print("%s\n", reason); if(u == 0) - panic("newpgrp"); + panic("resched"); u->p->state = Wakeme; alarm(1000, wakeme, u->p); sched(); - goto loop; } void @@ -112,7 +202,6 @@ closepgrp(Pgrp *p) { int i; Mtab *m; - Envp *ep; if(decref(p) == 0){ qlock(&p->debug); @@ -123,10 +212,6 @@ closepgrp(Pgrp *p) close(m->c); closemount(m->mnt); } - ep = p->etab; - for(i=0; inenv; i++,ep++) - if(ep->env) - envpgclose(ep->env); lock(&pgrpalloc); p->next = pgrpalloc.free; pgrpalloc.free = p; @@ -135,6 +220,43 @@ closepgrp(Pgrp *p) } } +void +closeegrp(Egrp *e) +{ + Envp *ep; + int i; + + if(decref(e) == 0) { + ep = e->etab; + for(i=0; inenv; i++,ep++) + if(ep->env) + envpgclose(ep->env); + lock(&egrpalloc); + e->next = egrpalloc.free; + egrpalloc.free = e; + unlock(&egrpalloc); + } +} + +void +closefgrp(Fgrp *f) +{ + int i; + Chan *c; + + if(decref(f) == 0) { + for(i = 0; i <= f->maxfd; i++) + if(c = f->fd[i]) + close(c); + + lock(&fgrpalloc); + f->next = fgrpalloc.free; + fgrpalloc.free = f; + unlock(&fgrpalloc); + } +} + + Mount* newmount(void) { @@ -182,7 +304,7 @@ closemount(Mount *m) } void -envcpy(Pgrp *to, Pgrp *from) +envcpy(Egrp *to, Egrp *from) { Envp *ep; Env *e; diff --git a/port/portdat.h b/port/portdat.h index 31545362cc8d7a952ae1b8218b18490fbb5e54f1..44f20d510486c3f7df4fc3f95e93dc5b923cc9d3 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -5,27 +5,30 @@ typedef struct Blist Blist; typedef struct Chan Chan; typedef struct Dev Dev; typedef struct Dirtab Dirtab; +typedef struct Egrp Egrp; typedef struct Env Env; typedef struct Envp Envp; typedef struct Envval Envval; typedef struct Etherpkt Etherpkt; +typedef struct Fgrp Fgrp; +typedef struct Image Image; typedef struct IOQ IOQ; typedef struct KIOQ KIOQ; typedef struct List List; typedef struct Mount Mount; typedef struct Mtab Mtab; typedef struct Note Note; -typedef struct Orig Orig; -typedef struct PTE PTE; typedef struct Page Page; +typedef struct Palloc Palloc; typedef struct Pgrp Pgrp; typedef struct Proc Proc; +typedef struct Pte Pte; typedef struct Qinfo Qinfo; typedef struct QLock QLock; typedef struct Queue Queue; typedef struct Ref Ref; typedef struct Rendez Rendez; -typedef struct Seg Seg; +typedef struct Segment Segment; typedef struct Stream Stream; typedef int Devgen(Chan*, Dirtab*, int, int, Dir*); @@ -177,7 +180,7 @@ struct Env Lock; Envval *val; char name[NAMELEN]; - Env *next; /* in chain of Envs for a pgrp */ + Env *next; /* in chain of Envs for a egrp */ int pgref; /* # pgrps pointing here */ }; @@ -259,57 +262,146 @@ struct Note int flag; /* whether system posted it */ }; -#define OWRPERM 0x01 /* write permission */ -#define OPURE 0x02 /* original data mustn't be written */ -#define OCACHED 0x04 /* cached; don't discard on exit */ -#define OISMEM 0x08 /* origin contains real memory */ -#define OSHARED 0x10 /* origin does not copy on ref/wr */ +/* Fields for cache control of pages */ +#define PG_NOFLUSH 0 +#define PG_TXTFLUSH 1 +#define PG_DATFLUSH 2 +/* Simulated modified and referenced bits */ +#define PG_MOD 0x01 +#define PG_REF 0x02 -struct Orig +struct Page { - Lock; - Orig *next; /* for allocation */ - ushort nproc; /* processes using it */ - ushort npage; /* sum of refs of pages in it */ - ushort flag; - ulong va; /* va of 0th pte */ - ulong npte; /* #pte's in list */ - PTE *pte; - Chan *chan; /* channel deriving segment (if open) */ - ushort type; /* of channel (which could be non-open) */ - Qid qid; - Chan *mchan; + ulong pa; /* Physical address in memory */ + ulong va; /* Virtual address for user */ + ulong daddr; /* Disc address on swap */ + ushort ref; /* Reference count */ + char lock; /* Software lock */ + char modref; /* Simulated modify/reference bits */ + char cachectl[MAXMACH]; /* Cache flushing control for putmmu */ + Image *image; /* Associated text or swap image */ + Page *next; /* Lru free list */ + Page *prev; + Page *hash; /* Image hash chains */ +}; + +struct Swapalloc +{ + Lock; /* Free map lock */ + int free; /* Number of currently free swap pages */ + char *swmap; /* Base of swap map in memory */ + char *alloc; /* Round robin allocator */ + char *top; /* Top of swap map */ + Rendez r; /* Pager kproc idle sleep */ +}swapalloc; + +struct Image +{ + Ref; + Chan *c; /* Channel associated with running image */ + Qid qid; /* Qid for page cache coherence checks */ Qid mqid; - ulong minca; /* base of region in chan */ - ulong maxca; /* end of region in chan */ - void (*freepg)(Page*, int); /* how to free pages for this origin */ - Page (*allocpg)(int, Orig*, ulong); + Chan *mchan; + ushort type; /* Device type of owning channel */ + Segment *s; /* TEXT segment for image if running, may be null */ + Image *hash; /* Qid hash chains */ + Image *next; /* Free list */ }; -struct Page +struct Pte { - Orig *o; /* origin of segment owning page */ - ulong va; /* virtual address */ - ulong pa; /* physical address */ - ushort ref; - Page *next; - Page *prev; + union { + Pte *next; /* Free list */ + Page *pages[PTEPERTAB]; /* Page map for this chunk of pte */ + }; +}; + +/* Segment types */ +#define SG_TYPE 007 /* Mask type of segment */ +#define SG_TEXT 000 +#define SG_DATA 001 +#define SG_BSS 002 +#define SG_STACK 003 +#define SG_SHARED 004 +#define SG_PHYSICAL 005 +/* Segment flags */ +#define SG_RONLY 040 /* Segment is read only */ + +#define HIGHWATER ((conf.npage*5)/100) +#define MAXHEADROOM HIGHWATER*2 /* Silly but OK for debug */ +#define PG_ONSWAP 1 +#define pagedout(s) (((ulong)s)==0 || (((ulong)s)&PG_ONSWAP)) +#define swapaddr(s) (((ulong)s)&~PG_ONSWAP) +#define onswap(s) (((ulong)s)&PG_ONSWAP) + +#define SEGMAXSIZE (SEGMAPSIZE*PTEMAPMEM) + +struct Segment +{ + Ref; + QLock lk; + ushort steal; /* Page stealer lock */ + Segment *next; /* free list pointers */ + ushort type; /* segment type */ + ulong base; /* virtual base */ + ulong top; /* virtual top */ + ulong size; /* size in pages */ + ulong fstart; /* start address in file for demand load */ + ulong flen; /* length of segment in file */ + Image *image; /* image in file system attached to this segment */ + Page *(*pgalloc)(ulong addr);/* SG_PHYSICAL page allocator */ + void (*pgfree)(Page *); /* SG_PHYSICAL page free */ + Pte *map[SEGMAPSIZE]; /* segment pte map */ }; struct Pgrp { Ref; /* also used as a lock when mounting */ - Pgrp *next; + Pgrp *next; /* free list */ int index; /* index in pgrp table */ ulong pgrpid; char user[NAMELEN]; int nmtab; /* highest active mount table entry, +1 */ - int nenv; /* highest active env table entry, +1 */ QLock debug; /* single access via devproc.c */ Mtab *mtab; +}; + +struct Egrp +{ + Ref; + Egrp *next; + int nenv; /* highest active env table entry, +1 */ Envp *etab; }; +#define NFD 100 +struct Fgrp +{ + Ref; + Fgrp *next; + Chan *fd[NFD]; + int maxfd; /* highest fd in use */ +}; + +#define PGHSIZE 512 +struct Palloc +{ + Lock; + ulong addr; + int active; + Page *page; /* base of Page structures, indexed by phys page number */ + ulong minppn; /* index of first usable page */ + Page *head; /* most recently used */ + Page *tail; /* least recently used */ + ulong freecount; /* how many pages on free list now */ + ulong user; /* how many user pages */ + Page *hash[PGHSIZE]; + Lock hashlock; + Rendez r; /* Sleep for free mem */ + QLock pwait; /* Queue of procs waiting for memory */ + int wanted; /* Do the wakeup at free */ +}; + enum /* Argument to forkpgrp call */ { FPall = 0, /* Concession to back portablility */ @@ -324,17 +416,7 @@ enum /* Argument to forkpgrp call */ */ enum { - SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, NSEG -}; - -struct Seg -{ - Proc *proc; /* process owning this segment */ - Orig *o; /* root list of pte's */ - ulong minva; /* va of 0th pte (not necessarily Seg->o->va) */ - ulong maxva; /* va of last pte */ - PTE *mod; /* list of modified pte's */ - ulong endseg; /* segments end */ + SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, SEG1, SEG2, NSEG }; /* @@ -354,6 +436,16 @@ enum Inwait, Wakeme, Broken, + Stopped, +}; + +/* + * devproc requests + */ +enum +{ + Proc_stopme = 1, + Proc_exitme = 2, }; /* @@ -379,14 +471,18 @@ struct Proc QLock *qlock; /* address of qlock being queued for DEBUG */ int state; Page *upage; /* BUG: should be unlinked from page list */ - Seg seg[NSEG]; + Segment *seg[NSEG]; ulong pid; int nchild; QLock wait; /* exiting children to be waited for */ Waitmsg waitmsg; /* this is large but must be addressable */ Proc *child; Proc *parent; - Pgrp *pgrp; + + Pgrp *pgrp; /* Process group for notes and namespace */ + Egrp *egrp; /* Environment group */ + Fgrp *fgrp; /* File descriptor group */ + ulong parentpid; ulong time[6]; /* User, Sys, Real; child U, S, R */ short exiting; @@ -400,22 +496,15 @@ struct Proc int kp; /* true if a kernel process */ Proc *palarm; /* Next alarm time */ ulong alarm; /* Time of call */ - int hasspin; - + int hasspin; /* I hold a spin lock */ + int newtlb; /* Pager has touched my tables so I must flush */ + int procctl; /* Control for /proc debugging */ /* * machine specific MMU goo */ PMMU; }; -struct PTE -{ - Proc *proc; /* process owning this PTE (0 in Orig) */ - PTE *nextmod; /* next at this va */ - PTE *nextva; /* next in this proc at higher va */ - Page *page; -}; - /* * operations available to a queue */ @@ -504,10 +593,12 @@ extern char devchar[]; extern char user[NAMELEN]; extern char *errstrtab[]; extern char *statename[]; +extern Palloc palloc; +extern Image swapimage; -#define CHDIR 0x80000000L -#define CHAPPEND 0x40000000L -#define CHEXCL 0x20000000L +#define CHDIR 0x80000000L +#define CHAPPEND 0x40000000L +#define CHEXCL 0x20000000L diff --git a/port/portfns.h b/port/portfns.h index ac5c040e2788e38ffb082421cf93bb914d2408c3..70f16601071857be6e9e68aef848e2dc451a652d 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -1,19 +1,23 @@ + #define SET(x) x = 0 #define USED(x) if(x) -Alarm* alarm(int, void (*)(Alarm*), void*); void alarminit(void); +Alarm* alarm(int, void (*)(Alarm*), void*); Block* allocb(ulong); +Image* attachimage(int, Chan*, ulong, ulong); int anyready(void); void append(List**, List*); int blen(Block *); int bround(Block *, int); void buzz(int, int); +void cachepage(Page*, Image*); void cancel(Alarm*); int cangetc(void*); int canlock(Lock*); -int canputc(void*); int canqlock(QLock*); +int canpage(Proc*); +int canputc(void*); void chandevinit(void); void chandevreset(void); void chaninit(void); @@ -23,15 +27,17 @@ Chan* clone(Chan*, Chan*); void close(Chan*); void closemount(Mount*); void closepgrp(Pgrp*); +void closeegrp(Egrp*); +void closefgrp(Fgrp*); long clrfpintr(void); -int compactpte(Orig*, ulong); void confinit(void); int consactive(void); Env* copyenv(Env*, int); +void copypage(Page*, Page*); int decref(Ref*); void delay(int); -void delete(List**, List*, List*); void delete0(List**, List*); +void delete(List**, List*, List*); Chan* devattach(int, char*); Chan* devclone(Chan*, Chan*); void devdir(Chan*, Qid, char*, long, long, Dir*); @@ -45,8 +51,12 @@ void* dmaalloc(ulong); void dumpqueues(void); void dumpregs(Ureg*); void dumpstack(void); -void envcpy(Pgrp*, Pgrp*); +Fgrp* dupfgrp(Fgrp*); +void dupswap(Page*); void envpgclose(Env *); +void duppage(Page*); +Segment* dupseg(Segment*); +void envcpy(Egrp*, Egrp*); int eqchan(Chan*, Chan*, long); int eqqid(Qid, Qid); void error(int); @@ -54,61 +64,61 @@ void errors(char*); void execpc(ulong); void exit(void); int fault(ulong, int); -void fdclose(int); +void fdclose(int, int); Chan* fdtochan(int, int); void firmware(void); void flowctl(Queue*); void flushmmu(void); -void forkmod(Seg*, Seg*, Proc*); void freealarm(Alarm*); void freeb(Block*); int freebroken(void); void freechan(Chan*); -void freepage(Orig*, int); -void freepte(Orig*); +void freepte(Segment*, Pte*); void freesegs(int); Block* getb(Blist*); int getc(IOQ*); +int gets(IOQ*, void*, int); int getfields(char*, char**, int, char); Block* getq(Queue*); -int gets(IOQ*, void*, int); void gotolabel(Label*); -void growpte(Orig*, ulong); void* ialloc(ulong, int); long ibrk(ulong, int); int incref(Ref*); void initq(IOQ*); +void initseg(void); void insert(List**, List*, List*); void invalidateu(void); void isdir(Chan*); +int ispages(void*); void kbdclock(void); -int kbdputc(IOQ*, int); void kbdrepeat(int); +int kbdputc(IOQ*, int); int kprint(char*, ...); void kproc(char*, void(*)(void*), void*); +void kickpager(void); void lights(int); -Page* lkpage(Orig*, ulong); -void lkpgfree(Page*, int); void lock(Lock*); +void lockpage(Page*); void lockinit(void); -Orig* lookorig(ulong, ulong, int, Chan*); +Page* lookpage(Image*, ulong); void machinit(void); void mapstack(Proc*); -void mklockseg(Seg*); -void mmurelease(Proc*); +void mfreeseg(Segment*, ulong, int); void mntdump(void); -int mount(Chan*, Chan*, int); +void mmurelease(Proc*); int mouseputc(IOQ*, int); +int mount(Chan*, Chan*, int); Chan* namec(char*, int, int, ulong); Alarm* newalarm(void); Chan* newchan(void); -PTE* newmod(Orig*); +Egrp* newegrp(void); +Fgrp* newfgrp(void); Mount* newmount(void); -Orig* neworig(ulong, ulong, int, Chan*); -Page* newpage(int, Orig*, ulong); +Page* newpage(int, Segment **, ulong); Pgrp* newpgrp(void); Proc* newproc(void); void newqinfo(Qinfo*); +Segment* newseg(int, ulong, ulong); char* nextelem(char*, char*); void nexterror(void); void notify(Ureg*); @@ -116,61 +126,74 @@ void nullput(Queue*, Block*); int openmode(ulong); Block* padb(Block*, int); void pageinit(void); +int pagemeis0(void*); void panic(char*, ...); void pexit(char*, int); void pgrpcpy(Pgrp*, Pgrp*); -void pgrpinit(void); +void pio(Segment *, ulong, ulong, Page **); +Pte* ptecpy(Pte*); +void putseg(Segment*); +void putswap(Page*); +void grpinit(void); void pgrpnote(Pgrp*, char*, long, int); Pgrp* pgrptab(int); #define poperror() u->nerrlab-- int postnote(Proc*, int, char*, int); int pprint(char*, ...); void printinit(void); +void procctl(Proc *p); +void putimage(Image*); +void putpage(Page*); +void putstr(char*); +int putc(IOQ*, int); +void putstr(char*); +void putstrn(char*, long); +void puts(IOQ*, void*, int); ulong procalarm(ulong); void procdump(void); void procinit0(void); Proc* proctab(int); +Pte* ptealloc(void); Block* pullup(Block *, int); Queue* pushq(Stream*, Qinfo*); int putb(Blist*, Block*); void putbq(Blist*, Block*); -int putc(IOQ*, int); -void putmmu(ulong, ulong); +void putmmu(ulong, ulong, Page*); int putq(Queue*, Block*); -void puts(IOQ*, void*, int); -void putstr(char*); -void putstrn(char*, long); ulong pwait(Waitmsg*); void qlock(QLock*); void qunlock(QLock*); int readnum(ulong, char*, ulong, ulong, int); void ready(Proc*); +void relocateseg(Segment*, ulong); void resched(char*); +void resrcwait(char*); int return0(void*); Proc* runproc(void); void savefpregs(FPsave*); void sccintr(void); -void sccputs(IOQ*, char*, int); void sccsetup(void*); void sccspecial(int, IOQ*, IOQ*, int); -void sched(void); void schedinit(void); +void sched(void); long seconds(void); -Seg* seg(Proc*, ulong); -int segaddr(Seg*, ulong, ulong); +Segment* seg(Proc*, ulong, int); +void segpage(Segment*, Page*); +ulong segattach(Proc*, ulong, char *, ulong, ulong); int setlabel(Label*); +void setswapchan(Chan*); char* skipslash(char*); void sleep(Rendez*, int(*)(void*), void*); int splhi(void); int spllo(void); void splx(int); -int streamclose(Chan*); int streamclose1(Stream*); +int streamclose(Chan*); int streamenter(Stream*); int streamexit(Stream*, int); Devgen streamgen; -void streaminit(void); void streaminit0(void); +void streaminit(void); Stream* streamnew(ushort, ushort, ushort, Qinfo*, int); void streamopen(Chan*, Qinfo*); int streamparse(char*, Block*); @@ -178,15 +201,17 @@ long streamread(Chan*, void*, long); void streamstat(Chan*, char*, char*); long streamwrite(Chan*, void*, long, int); long stringread(Chan*, void*, long, char*, ulong); +void swapinit(void); long syscall(Ureg*); +void tcpinit(void); void tsleep(Rendez*, int (*)(void*), void*, int); void twakeme(Alarm*); +void uncachepage(Page*); long unionread(Chan*, void*, long); void unlock(Lock*); -void unusepage(Page*, int); -void usepage(Page*, int); +void unlockpage(Page*); void userinit(void); void validaddr(ulong, ulong, int); -void* vmemchr(void*, int, ulong); +void* vmemchr(void*, int, int); void wakeme(Alarm*); void wakeup(Rendez*); diff --git a/port/proc.c b/port/proc.c index 1e0dba1e2db3e815fc22ea8ad64595d1d4b252f2..64d316e6315d8d5035a2eed81eb6b0afb579f08c 100644 --- a/port/proc.c +++ b/port/proc.c @@ -40,6 +40,7 @@ char *statename[]={ /* BUG: generate automatically */ "Inwait", "Wakeme", "Broken", + "Stopped", }; /* @@ -49,6 +50,7 @@ void schedinit(void) /* never returns */ { Proc *p; + Page *pg; setlabel(&m->sched); if(u){ @@ -58,16 +60,38 @@ schedinit(void) /* never returns */ u = 0; if(p->state == Running) ready(p); - else if(p->state == Moribund){ + else if(p->state == Moribund) { + /* + * The Grim Reaper lays waste the bodies of the dead + */ p->pid = 0; mmurelease(p); - /* procalloc already locked */ + /* + * Holding locks: + * procalloc, debug, palloc + */ + pg = p->upage; + pg->ref = 0; + p->upage = 0; + palloc.freecount++; + if(palloc.head) { + pg->next = palloc.head; + palloc.head->prev = pg; + pg->prev = 0; + palloc.head = pg; + } + else { + palloc.head = palloc.tail = pg; + pg->prev = pg->next = 0; + } + p->qnext = procalloc.free; procalloc.free = p; - p->upage->ref--; - p->upage = 0; + + unlock(&palloc); unlock(&p->debug); unlock(&procalloc); + p->state = Dead; } p->mach = 0; @@ -78,7 +102,7 @@ schedinit(void) /* never returns */ void sched(void) { - uchar procstate[64]; /* sleaze for portability */ + uchar procstate[64]; Proc *p; ulong tlbvirt, tlbphys; void (*f)(ulong, ulong); @@ -175,6 +199,23 @@ loop: return p; } +int +canpage(Proc *p) +{ + int ok = 0; + + splhi(); + lock(&runhiq); + if(p->state != Running) { + p->newtlb = 1; + ok = 1; + } + unlock(&runhiq); + spllo(); + + return ok; +} + Proc* newproc(void) { @@ -192,8 +233,11 @@ loop: p->child = 0; p->exiting = 0; p->pgrp = 0; + p->egrp = 0; + p->fgrp = 0; p->fpstate = FPinit; p->kp = 0; + p->procctl = 0; memset(p->seg, 0, sizeof p->seg); lock(&pidalloc); p->pid = ++pidalloc.pid; @@ -300,8 +344,8 @@ wakeup(Rendez *r) p = r->p; if(p){ r->p = 0; - if(p->state != Wakeme) - panic("wakeup: not Wakeme"); + if(p->state != Wakeme) + panic("wakeup: state"); p->r = 0; ready(p); } @@ -359,7 +403,8 @@ postnote(Proc *p, int dolock, char *n, int flag) kunmap(k); if(dolock) unlock(&p->debug); - if(r = p->r){ /* assign = */ + + if(r = p->r) { /* assign = */ /* wake up */ s = splhi(); lock(r); @@ -432,27 +477,29 @@ pexit(char *s, int freemem) { ulong mypid; Proc *p, *c, *k, *l; - int n; + int n, i; Chan *ch; char msg[ERRLEN]; ulong *up, *ucp, *wp; - if(s) /* squirrel away; we'll lose our address space */ + if(s) /* squirrel away; we'll lose our address space */ strcpy(msg, s); else msg[0] = 0; + c = u->p; c->alarm = 0; mypid = c->pid; - for(n=0; n<=u->maxfd; n++) - if(ch = u->fd[n]) /* assign = */ - close(ch); - + closefgrp(c->fgrp); if(freemem){ - freesegs(-1); + flushvirt(); + for(i = 0; i < NSEG; i++) + if(c->seg[i]) + putseg(c->seg[i]); closepgrp(c->pgrp); + closeegrp(c->egrp); close(u->dot); } /* @@ -502,18 +549,27 @@ pexit(char *s, int freemem) out: if(!freemem){ addbroken(c); - freesegs(-1); + flushvirt(); + for(i = 0; i < NSEG; i++) + if(c->seg[i]) + putseg(c->seg[i]); closepgrp(c->pgrp); + closeegrp(c->egrp); close(u->dot); } done: - lock(&procalloc); /* sched() can't do this */ - lock(&c->debug); /* sched() can't do this */ - unusepage(c->upage, 1); /* sched() can't do this (it locks) */ + /* + * sched() cannot wait on these locks + */ + lock(&procalloc); + lock(&c->debug); + lock(&palloc); + c->state = Moribund; - sched(); /* never returns */ + sched(); + panic("pexit"); } ulong @@ -568,15 +624,14 @@ procdump(void) { int i; Proc *p; - Orig *o; - print("DEBUG\n"); + print("process table:\n"); for(i=0; istate != Dead){ print("%d:%s %s upc %lux %s ut %ld st %ld r %lux\n", - p->pid, p->text, p->pgrp->user, p->pc, statename[p->state], - p->time[0], p->time[1], p->r); + p->pid, p->text, p->pgrp->user, p->pc, + statename[p->state], p->time[0], p->time[1], p->r); } } } @@ -591,6 +646,7 @@ kproc(char *name, void (*func)(void *), void *arg) User *up; KMap *k; static Pgrp *kpgrp; + char *user; /* * Kernel stack @@ -616,9 +672,7 @@ kproc(char *name, void (*func)(void *), void *arg) * Refs */ incref(up->dot); - for(n=0; n<=up->maxfd; n++) - up->fd[n] = 0; - up->maxfd = 0; + p->fgrp = newfgrp(); kunmap(k); /* @@ -633,13 +687,19 @@ kproc(char *name, void (*func)(void *), void *arg) (*func)(arg); pexit(0, 1); } + + user = "bootes"; if(kpgrp == 0){ kpgrp = newpgrp(); - strcpy(kpgrp->user, "bootes"); + strcpy(kpgrp->user, user); } p->pgrp = kpgrp; incref(kpgrp); - sprint(p->text, "%s.%.6s", name, u->p->pgrp->user); + + if(u->p->pgrp->user[0] != '\0') + user = u->p->pgrp->user; + sprint(p->text, "%s.%.6s", name, user); + p->nchild = 0; p->parent = 0; memset(p->time, 0, sizeof(p->time)); @@ -652,3 +712,17 @@ kproc(char *name, void (*func)(void *), void *arg) */ flushmmu(); } + +void +procctl(Proc *p) +{ + switch(p->procctl) { + case Proc_exitme: + pexit("Killed", 1); + case Proc_stopme: + p->procctl = 0; + p->state = Stopped; + sched(); + return; + } +} diff --git a/port/qlock.c b/port/qlock.c index 61add69891a964e5d6ecdf7f107ad839a966eb43..ed4b1ff32205595817d99618acca46c43a0b3d8d 100644 --- a/port/qlock.c +++ b/port/qlock.c @@ -10,11 +10,8 @@ qlock(QLock *q) { Proc *p; - if(canlock(&q->use)){ - if(u) - u->p->hasspin = 0; + if(canlock(&q->use)) return; - } lock(&q->queue); if(canlock(&q->use)){ unlock(&q->queue); diff --git a/port/queue.c b/port/queue.c index d15e29ea5bd937e9514dc404ea9b180406fda362..db545ac915c32d99d8cae668fbfc9e84aa13c005 100644 --- a/port/queue.c +++ b/port/queue.c @@ -4,6 +4,7 @@ #include "dat.h" #include "fns.h" #include "io.h" +#include "errno.h" void initq(IOQ *q) diff --git a/port/segment.c b/port/segment.c new file mode 100644 index 0000000000000000000000000000000000000000..1f92bfcd7b8ed1883d147c518f52613c7e1f7e01 --- /dev/null +++ b/port/segment.c @@ -0,0 +1,460 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "ureg.h" +#include "errno.h" + +#define DPRINT + +Page *lkpage(ulong addr); +Page *snewpage(ulong addr); +void lkpgfree(Page*); + +/* System specific segattach devices */ +#include "segment.h" + +#define IHASHSIZE 64 +#define ihash(s) imagealloc.hash[s%IHASHSIZE] +struct Imagealloc +{ + Lock; + Image *free; + Image *hash[IHASHSIZE]; +}imagealloc; + +struct segalloc +{ + Lock; + Segment *free; +}segalloc; + +void +initseg(void) +{ + Segment *s, *se; + Image *i, *ie; + + segalloc.free = ialloc(conf.nseg*sizeof(Segment), 0); + imagealloc.free = ialloc(conf.nimage*sizeof(Image), 0); + + se = &segalloc.free[conf.nseg-1]; + for(s = segalloc.free; s < se; s++) + s->next = s+1; + s->next = 0; + + ie = &imagealloc.free[conf.nimage-1]; + for(i = imagealloc.free; i < ie; i++) + i->next = i+1; + i->next = 0; +} + +Segment * +newseg(int type, ulong base, ulong size) +{ + Segment *s; + + if(size > (SEGMAPSIZE*PTEPERTAB)) + errors("segment too large"); + + for(;;) { + lock(&segalloc); + if(s = segalloc.free) { + segalloc.free = s->next; + unlock(&segalloc); + + s->ref = 1; + s->steal = 0; + s->type = type; + s->base = base; + s->top = base+(size*BY2PG); + s->size = size; + s->image = 0; + s->fstart = 0; + s->flen = 0; + s->pgalloc = 0; + s->pgfree = 0; + memset(s->map, 0, sizeof(s->map)); + + return s; + } + unlock(&segalloc); + resrcwait("no segments"); + } +} + +void +putseg(Segment *s) +{ + Pte **pp, **emap; + Image *i; + + if(s && decref(s) == 0) { + emap = &s->map[SEGMAPSIZE]; + for(pp = s->map; pp < emap; pp++) + if(*pp) + freepte(s, *pp); + + if(i = s->image) { + lock(i); + if(i->s == s) + i->s = 0; + unlock(i); + putimage(i); + } + + lock(&segalloc); + s->next = segalloc.free; + segalloc.free = s; + unlock(&segalloc); + } +} + +void +relocateseg(Segment *s, ulong offset) +{ + Pte **p, **endpte; + Page **pg, **endpages; + + endpte = &s->map[SEGMAPSIZE]; + for(p = s->map; p < endpte; p++) + if(*p) { + endpages = &((*p)->pages[PTEPERTAB]); + for(pg = (*p)->pages; pg < endpages; pg++) + if(*pg) + (*pg)->va += offset; + } +} + +Segment* +dupseg(Segment *s) +{ + Pte *pte; + Segment *n; + int i; + + switch(s->type&SG_TYPE) { + case SG_TEXT: /* new segment shares pte set */ + case SG_SHARED: + case SG_PHYSICAL: + incref(s); + return s; + case SG_DATA: /* copy on write both old and new plus demand load info */ + lock(s); + n = newseg(s->type, s->base, s->size); + + incref(s->image); + n->image = s->image; + n->fstart = s->fstart; + n->flen = s->flen; + copypte: + for(i = 0; i < SEGMAPSIZE; i++) + if(pte = s->map[i]) + n->map[i] = ptecpy(pte); + unlock(s); + return n; + case SG_BSS: /* Just copy on write */ + case SG_STACK: + lock(s); + n = newseg(s->type, s->base, s->size); + goto copypte; + } + + panic("dupseg"); +} + +void +segpage(Segment *s, Page *p) +{ + Pte **pte; + ulong off; + + if(p->va < s->base || p->va >= s->top) + panic("segpage"); + + off = p->va - s->base; + pte = &s->map[off/PTEMAPMEM]; + if(*pte == 0) + *pte = ptealloc(); + + (*pte)->pages[(off&(PTEMAPMEM-1))/BY2PG] = p; +} + +Image* +attachimage(int type, Chan *c, ulong base, ulong len) +{ + Image *i, **l; + + lock(&imagealloc); + + for(i = ihash(c->qid.path); i; i = i->hash) { + if(c->qid.path == i->qid.path) { + lock(i); + if(eqqid(c->qid, i->qid)) + if(eqqid(c->mqid, i->mqid)) + if(c->mchan == i->mchan) + if(c->type == i->type) { + i->ref++; + goto found; + } + unlock(i); + } + } + + while(!(i = imagealloc.free)) { + unlock(&imagealloc); + resrcwait("no images"); + lock(&imagealloc); + } + + imagealloc.free = i->next; + + lock(i); + incref(c); + i->c = c; + i->type = c->type; + i->qid = c->qid; + i->mqid = c->mqid; + i->mchan = c->mchan; + i->ref = 1; + l = &ihash(c->qid.path); + i->hash = *l; + *l = i; +found: + unlock(&imagealloc); + + if(i->s == 0) { + i->s = newseg(type, base, len); + i->s->image = i; + } + else + incref(i->s); + + unlock(i); + return i; +} + +void +putimage(Image *i) +{ + Image *f, **l; + Chan *c; + + if(i == &swapimage) + return; + + lock(i); + if(--i->ref == 0) { + l = &ihash(i->qid.path); + i->qid = (Qid){~0, ~0}; + unlock(i); + c = i->c; + + lock(&imagealloc); + for(f = *l; f; f = f->hash) { + if(f == i) { + *l = i->hash; + break; + } + l = &f->hash; + } + + i->next = imagealloc.free; + imagealloc.free = i; + unlock(&imagealloc); + + close(c); /* Delay close because we could error */ + return; + } + unlock(i); +} + +long +ibrk(ulong addr, int seg) /* Called with a locked segment */ +{ + Segment *s, *ns; + ulong newtop, newsize; + int i; + + s = u->p->seg[seg]; + if(s == 0) + errors("no segment"); + + qlock(&s->lk); + + if(addr == 0) + return s->base; + + if(addr < s->base) { + /* We may start with the bss overlapping the data */ + if(seg != BSEG || u->p->seg[DSEG] == 0 || addr < u->p->seg[DSEG]->base) { + qunlock(&s->lk); + pprint("addr below segment\n"); + } + addr = s->base; + } + + newtop = PGROUND(addr); + newsize = (newtop-s->base)/BY2PG; + if(newtop < s->top) { + print("down brk\n"); + mfreeseg(s, newtop, (s->top-newtop)/BY2PG); + qunlock(&s->lk); + return 0; + } + + if(newsize > (PTEMAPMEM*SEGMAPSIZE)/BY2PG) { + qunlock(&s->lk); + pprint("exceeded max segment size\n"); + pexit("Suicide", 0); + error(Esegaddr); + } + + for(i = 0; i < NSEG; i++) { + ns = u->p->seg[i]; + if(ns == 0 || ns == s) + continue; + if(newtop >= ns->base && newtop < ns->top) { + qunlock(&s->lk); + pprint("segments overlap\n"); + pexit("Suicide", 0); + error(Esegaddr); + } + } + + s->top = newtop; + s->size = newsize; + + qunlock(&s->lk); + return 0; +} + +void +mfreeseg(Segment *s, ulong start, int pages) +{ + int i, j; + ulong soff; + Page *pg; + + soff = start-s->base; + j = (soff&(PTEMAPMEM-1))/BY2PG; + + for(i = soff/PTEMAPMEM; i < SEGMAPSIZE; i++) { + if(pages <= 0) + goto done; + if(s->map[i]) { + while(j < PTEPERTAB) { + if(pg = s->map[i]->pages[j]) { + putpage(pg); + s->map[i]->pages[j] = 0; + } + if(--pages == 0) + goto done; + j++; + } + j = 0; + } + else + pages -= PTEMAPMEM/BY2PG; + } +done: + flushmmu(); +} + +ulong +segattach(Proc *p, ulong attr, char *name, ulong va, ulong len) +{ + Segment *s, *ns, *new; + Physseg *ps; + ulong newtop; + int i, sno; + + if(va&KZERO) /* BUG: Only ok for now */ + errors("bad virtual address"); + + validaddr((ulong)name, 1, 0); + vmemchr(name, 0, ~0); + + for(sno = 0; sno < NSEG; sno++) + if(u->p->seg[sno] == 0 && sno != ESEG) + break; + + if(sno == NSEG) + errors("no per process segments"); + + va = va&~(BY2PG-1); + len = PGROUND(len); + newtop = va+len; + for(i = 0; i < NSEG; i++) { + ns = u->p->seg[i]; + if(ns == 0) + continue; + if(newtop >= ns->base && newtop < ns->top) + errors("segments overlap"); + } + + for(ps = physseg; *(ps->name); ps++) + if(strcmp(name, ps->name) == 0) + goto found; + + errors("bad segment name"); +found: + if(len > ps->size) + errors("segment too long"); + + attr &= ~SG_TYPE; /* Turn off what we are not allowed */ + attr |= ps->attr; /* Copy in defaults */ + + s = newseg(attr, va, len/BY2PG); + s->pgalloc = ps->pgalloc; + s->pgfree = ps->pgfree; + u->p->seg[sno] = s; + + /* Need some code build mapped devices here */ + + return 0; +} + +long +syssegflush(ulong *arg) +{ + Segment *s; + int i, j, pages; + ulong soff; + Page *pg; + + s = seg(u->p, arg[0], 1); + if(s == 0) + errors("bad segment address"); + + soff = arg[0]-s->base; + j = (soff&(PTEMAPMEM-1))/BY2PG; + pages = ((arg[0]+arg[1]+(BY2PG-1))&~(BY2PG-1))-(arg[0]&~(BY2PG-1)); + + for(i = soff/PTEMAPMEM; i < SEGMAPSIZE; i++) { + if(pages <= 0) + goto done; + if(s->map[i]) { + while(j < PTEPERTAB) { + if(pg = s->map[i]->pages[j]) + memset(pg->cachectl, PG_TXTFLUSH, sizeof pg->cachectl); + if(--pages == 0) + goto done; + j++; + } + j = 0; + } + else + pages -= PTEMAPMEM/BY2PG; + } +done: + qunlock(&s->lk); + flushmmu(); +} + +Page* +snewpage(ulong addr) +{ + return newpage(1, 0, addr); +} diff --git a/port/stream.c b/port/stream.c index 487a3d99413d52253414469b06a28f4a9019ce2e..bb6252d66c1889235faee0111cf4431b53e361f6 100644 --- a/port/stream.c +++ b/port/stream.c @@ -118,12 +118,12 @@ newblock(Bclass *bcp) if(bcp->made > bcp->lim) return -1; + page = newpage(1, 0, 0); + page->va = VA(kmap(page)); if(bcp == bclass){ /* * create some level zero blocks and return */ - page = newpage(1, 0, 0); - page->va = VA(kmap(page)); n = BY2PG/sizeof(Block); bp = (Block *)(page->va); while(n-- > 0){ @@ -141,8 +141,6 @@ newblock(Bclass *bcp) /* * create a page worth of new blocks */ - page = newpage(1, 0, 0); - page->va = VA(kmap(page)); n = BY2PG/bcp->size; cp = (uchar *)(page->va); @@ -419,7 +417,6 @@ popq(Stream *s) (*q->info->close)(RD(q)); s->procq->next = q->next; RD(q->next)->next = RD(s->procq); - poperror(); qunlock(s); freeq(q); } diff --git a/port/sturp.c b/port/sturp.c index ce6bde28e652814d1f46a919da7741c8deae27d3..35e69162e7e0f45dc0508c4c7abb56f173736f31 100644 --- a/port/sturp.c +++ b/port/sturp.c @@ -11,7 +11,7 @@ enum { Nmask= 0x7, }; -#define DPRINT if(q->flag&QDEBUG)kprint +#define DPRINT if(q->flag&QDEBUG)print typedef struct Urp Urp; diff --git a/port/swap.c b/port/swap.c new file mode 100644 index 0000000000000000000000000000000000000000..38e6062a0b4d4b15b2107261f8c8cd8829f4cea5 --- /dev/null +++ b/port/swap.c @@ -0,0 +1,333 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "ureg.h" +#include "errno.h" + +/* Predeclaration */ +void pageout(Proc *p, Segment*); +int pagepte(int, Segment*, Page**); +void openswap(void); +int needpages(void*); +void pager(void*); +void executeio(void); +int canflush(Proc *p, Segment*); + +enum +{ + Maxpages = 500, /* Max number of pageouts per process pass */ +}; + +Image swapimage; +static int swopen; +Page *iolist[Maxpages]; +int ioptr; + +void +swapinit(void) +{ + swapalloc.swmap = ialloc(conf.nswap, 0); + swapalloc.top = &swapalloc.swmap[conf.nswap]; + swapalloc.alloc = swapalloc.swmap; + + swapalloc.free = conf.nswap; +} + +ulong +newswap(void) +{ + char *look; + int n; + + lock(&swapalloc); + if(swapalloc.free == 0) + panic("out of swap space"); + + n = swapalloc.top - swapalloc.alloc; + look = swapalloc.alloc; + while(n && *look) { + n--; + look++; + } + if(n == 0) { + look = swapalloc.swmap; + while(*look) + look++; + } + if(look == swapalloc.top) + swapalloc.alloc = swapalloc.swmap; + else + swapalloc.alloc = look+1; + + *look = 1; + unlock(&swapalloc); + return (look-swapalloc.swmap) * BY2PG; +} + +void +putswap(Page *p) +{ + lock(&swapalloc); + if(--swapalloc.swmap[((ulong)p)/BY2PG] == 0) + swapalloc.free++; + unlock(&swapalloc); +} + +void +dupswap(Page *p) +{ + lock(&swapalloc); + swapalloc.swmap[((ulong)p)/BY2PG]++; + unlock(&swapalloc); +} + +void +kickpager(void) +{ + static int started; + + if(started) + wakeup(&swapalloc.r); + else { + kproc("pager", pager, 0); + started = 1; + } +} + +void +pager(void *junk) +{ + Proc *p, *ep; + Segment *s; + int i; + + p = proctab(0); + ep = &p[conf.nproc]; + for(;;) { + if(waserror()) + panic("pager: os error\n"); + + for(p = proctab(0); p < ep; p++) { + if(p->state == Dead || p->kp) + continue; + + sleep(&swapalloc.r, needpages, 0); + + if(swapimage.c) { + for(i = 0; i < NSEG; i++) + if(s = p->seg[i]) { + pageout(p, s); + executeio(); + } + } + else { + /* Emulate the old system if no swap channel */ + print("no physical memory\n"); + pprint("no physical memory\n"); + tsleep(&swapalloc.r, return0, 0, 1000); + wakeup(&palloc.r); + } + } + + poperror(); + } +} + +void +pageout(Proc *p, Segment *s) +{ + Pte **sm, **endsm; + Page **pg, **epg; + int type; + + if(!canqlock(&s->lk)) /* We cannot afford to wait, we will surely deadlock */ + return; + + if(!canflush(p, s) || s->steal) { + qunlock(&s->lk); + putseg(s); + return; + } + + if(waserror()) { + qunlock(&s->lk); + putseg(s); + return; + } + + /* Pass through the pte tables looking for memory pages to swap out */ + type = s->type&SG_TYPE; + endsm = &s->map[SEGMAPSIZE]; + for(sm = s->map; sm < endsm && ioptr < Maxpages; sm++) + if(*sm) { + pg = (*sm)->pages; + for(epg = &pg[PTEPERTAB]; pg < epg && ioptr < Maxpages; pg++) + if(!pagedout(*pg)) { + if((*pg)->modref & PG_REF) + (*pg)->modref &= ~PG_REF; + else + if(pagepte(type, s, pg) == 0) + break; + } + } + + poperror(); + qunlock(&s->lk); + putseg(s); + + wakeup(&palloc.r); +} + +int +canflush(Proc *p, Segment *s) +{ + Proc *ep; + int i; + + lock(s); + if(s->ref == 1) { /* Easy if we are the only user */ + s->ref++; + unlock(s); + return canpage(p); + } + s->ref++; + unlock(s); + + /* Now we must do hardwork to ensure all processes which have tlb + * entries for this segment are flushed + */ + p = proctab(0); + ep = &p[conf.nproc]; + for(; p < ep; p++) + if(p->state != Dead) + for(i = 0; i < NSEG; i++) + if(p->seg[i] == s) + if(!canpage(p)) + return 0; + return 1; +} + +int +pagepte(int type, Segment *s, Page **pg) +{ + ulong daddr; + char *kaddr; + int n; + Chan *c; + Page *outp; + KMap *k; + + outp = *pg; + + switch(type) { + case SG_TEXT: /* Revert to demand load */ + putpage(outp); + *pg = 0; + break; + case SG_DATA: + /* Unmodified data may be reverted to a demand load record if it + * is not the last page in the DSEG + */ +/* BUG: needs to check the last page + if((outp->modref&PG_MOD) == 0) { + putpage(outp); + *pg = 0; + break; + } +*/ + /* NO break */ + case SG_BSS: + case SG_STACK: + case SG_SHARED: + lockpage(outp); + outp->ref++; + uncachepage(outp); + unlockpage(outp); + + daddr = newswap(); + outp->daddr = daddr; + + /* Enter swap page into cache before segment is unlocked so that + * a fault will cause a cache recovery rather than a pagein on a + * partially written block. + */ + cachepage(outp, &swapimage); + *pg = (Page*)(daddr|PG_ONSWAP); + + /* Add me to IO transaction list */ + iolist[ioptr++] = outp; + } + + return 1; +} + +void +executeio(void) +{ + Page *out; + int i, n; + Chan *c; + char *kaddr; + KMap *k; + + c = swapimage.c; + + for(i = 0; i < ioptr; i++) { + out = iolist[i]; + if(out->ref > 2) { + lockpage(out); + if(out->ref > 2) { /* Page was reclaimed, abort io */ + out->ref -= 2; + unlockpage(out); + continue; + } + unlockpage(out); + } + k = kmap(out); + kaddr = (char*)VA(k); + qlock(&c->wrl); + + /* BUG: what to do ? Nobody to tell, nowhere to go: open to suggestions + * the problem is I do not know whose page this is. + */ + if(waserror()) + panic("executeio: page out I/O error"); + + n = (*devtab[c->type].write)(c, kaddr, BY2PG, out->daddr); + if(n != BY2PG) + nexterror(); + + qunlock(&c->wrl); + kunmap(k); + poperror(); + + /* Free up the page after I/O */ + lockpage(out); + out->ref--; + unlockpage(out); + putpage(out); + } + + ioptr = 0; +} + +int +needpages(void *p) +{ + return palloc.freecount < HIGHWATER+MAXHEADROOM; +} + +void +setswapchan(Chan *c) +{ + if(swapimage.c) { + if(swapalloc.free != conf.nswap) + errors("swap channel busy"); + close(swapimage.c); + } + incref(c); + swapimage.c = c; +} + diff --git a/port/sysfile.c b/port/sysfile.c index d2d95290e3a91d7a764905d9ea7d81f5c8ecba8c..fe65eb9f21a73969c77737842a7b7f0a2d4b9a46 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -11,16 +11,21 @@ */ int -newfd(void) +newfd(Chan *c) { + Fgrp *f = u->p->fgrp; int i; + lock(f); for(i=0; ifd[i] == 0){ - if(i > u->maxfd) - u->maxfd = i; + if(f->fd[i] == 0){ + if(i > f->maxfd) + f->maxfd = i; + f->fd[i] = c; + unlock(f); return i; } + unlock(f); error(Enofd); } @@ -29,8 +34,8 @@ fdtochan(int fd, int mode) { Chan *c; - c = 0; /* set */ - if(fd<0 || NFD<=fd || (c=u->fd[fd])==0) + USED(c); + if(fd<0 || NFD<=fd || (c = u->p->fgrp->fd[fd])==0) error(Ebadfd); if(mode<0 || c->mode==ORDWR) return c; @@ -62,6 +67,7 @@ syspipe(ulong *arg) int fd[2]; Chan *c[2]; Dev *d; + Fgrp *f = u->p->fgrp; validaddr(arg[0], 2*BY2WD, 1); evenaddr(arg[0]); @@ -75,9 +81,9 @@ syspipe(ulong *arg) if(c[1]) close(c[1]); if(fd[0] >= 0) - u->fd[fd[0]]=0; + f->fd[fd[0]]=0; if(fd[1] >= 0) - u->fd[fd[1]]=0; + f->fd[fd[1]]=0; nexterror(); } c[1] = (*d->clone)(c[0], 0); @@ -85,10 +91,8 @@ syspipe(ulong *arg) (*d->walk)(c[1], "data1"); c[0] = (*d->open)(c[0], ORDWR); c[1] = (*d->open)(c[1], ORDWR); - fd[0] = newfd(); - u->fd[fd[0]] = c[0]; - fd[1] = newfd(); - u->fd[fd[1]] = c[1]; + fd[0] = newfd(c[0]); + fd[1] = newfd(c[1]); ((long*)arg[0])[0] = fd[0]; ((long*)arg[0])[1] = fd[1]; poperror(); @@ -100,6 +104,7 @@ sysdup(ulong *arg) { int fd; Chan *c, *oc; + Fgrp *f = u->p->fgrp; /* * Close after dup'ing, so date > #d/1 works @@ -109,17 +114,26 @@ sysdup(ulong *arg) if(fd != -1){ if(fd<0 || NFD<=fd) error(Ebadfd); - if(fd > u->maxfd) - u->maxfd = fd; - oc = u->fd[fd]; - }else{ - oc = 0; - fd = newfd(); + + lock(f); + if(fd > f->maxfd) + f->maxfd = fd; + incref(c); + oc = f->fd[fd]; + f->fd[fd] = c; + unlock(f); + if(oc) + close(oc); + }else { + if(waserror()) { + close(c); + nexterror(); + } + incref(c); + fd = newfd(c); + poperror(); } - u->fd[fd] = c; - incref(c); - if(oc) - close(oc); + return fd; } @@ -127,25 +141,43 @@ long sysopen(ulong *arg) { int fd; - Chan *c; + Chan *c = 0; openmode(arg[1]); /* error check only */ - fd = newfd(); + if(waserror()) { + if(c) + close(c); + nexterror(); + } validaddr(arg[0], 1, 0); c = namec((char*)arg[0], Aopen, arg[1], 0); - u->fd[fd] = c; + fd = newfd(c); + poperror(); return fd; } void -fdclose(int fd) +fdclose(int fd, int flag) { int i; + Chan *c; + Fgrp *f = u->p->fgrp; + + lock(f); + c = f->fd[fd]; + if(flag){ + if(c==0 || !(c->flag&flag)){ + unlock(f); + return; + } + } + f->fd[fd] = 0; + if(fd == f->maxfd) + for(i=fd; --i>=0 && f->fd[i]==0; ) + f->maxfd = i; - u->fd[fd] = 0; - if(fd == u->maxfd) - for(i=fd; --i>=0 && u->fd[i]==0; ) - u->maxfd = i; + unlock(f); + close(c); } long @@ -154,8 +186,8 @@ sysclose(ulong *arg) Chan *c; c = fdtochan(arg[0], -1); - close(c); - fdclose(arg[0]); + fdclose(arg[0], 0); + return 0; } @@ -183,8 +215,8 @@ unionread(Chan *c, void *va, long n) nexterror(); } nc = clone(mc, 0); - close(mc); poperror(); + close(mc); if(waserror()){ close(nc); nexterror(); @@ -193,8 +225,8 @@ unionread(Chan *c, void *va, long n) nc->offset = c->offset; nr = (*devtab[nc->type].read)(nc, va, n, nc->offset); c->offset = nc->offset; /* devdirread e.g. changes it */ - close(nc); poperror(); + close(nc); if(nr > 0) return nr; /* @@ -364,6 +396,8 @@ bindmount(ulong *arg, int ismount) Chan *c0, *c1; ulong flag; long ret; + char *p; + int t; struct{ Chan *chan; char *spec; @@ -408,10 +442,9 @@ bindmount(ulong *arg, int ismount) close(c1); poperror(); close(c0); - if(ismount){ - close(bogus.chan); - fdclose(arg[0]); - } + if(ismount) + fdclose(arg[0], 0); + return ret; } @@ -431,13 +464,18 @@ long syscreate(ulong *arg) { int fd; - Chan *c; + Chan *c = 0; openmode(arg[1]); /* error check only */ - fd = newfd(); + if(waserror()) { + if(c) + close(c); + nexterror(); + } validaddr(arg[0], 1, 0); c = namec((char*)arg[0], Acreate, arg[1], arg[2]); - u->fd[fd] = c; + fd = newfd(c); + poperror(); return fd; } diff --git a/port/sysproc.c b/port/sysproc.c index 88a62eda0ccddd69b870d3561b14bc85981d0d23..4300cbcfe40588d5527e3d2a3cae9476a4dfe6b3 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -21,19 +21,19 @@ long sysfork(ulong *arg) { Proc *p; - Seg *s; + Segment *s; Page *np, *op; ulong usp, upa, pid; Chan *c; - Orig *o; KMap *k; int n, on, i; int lastvar; /* used to compute stack address */ - /* * Kernel stack */ p = newproc(); + + /* Page va of upage used as check in mapstack */ p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); k = kmap(p->upage); upa = VA(k); @@ -49,68 +49,23 @@ sysfork(ulong *arg) ((User *)upa)->p = p; kunmap(k); - /* - * User stack - */ - p->seg[SSEG] = u->p->seg[SSEG]; - s = &p->seg[SSEG]; - s->proc = p; - on = (s->maxva-s->minva)>>PGSHIFT; - usp = ((Ureg*)UREGADDR)->usp; - if(usp >= USTKTOP) - panic("fork bad usp %lux", usp); - if(usp < u->p->seg[SSEG].minva) - s->minva = u->p->seg[SSEG].minva; - else - s->minva = usp & ~(BY2PG-1); - usp = s->minva & (BY2PG-1); /* just low bits */ - s->maxva = USTKTOP; - n = (s->maxva-s->minva)>>PGSHIFT; - s->o = neworig(s->minva, n, OWRPERM|OISMEM, 0); - lock(s->o); - /* - * Only part of last stack page - */ - for(i=0; ip->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*)VA(k), 0, usp); - memmove((void*)(VA(k)+usp), - (void*)(op->va+usp), BY2PG-usp); - }else /* all of higher pages */ - memmove((void*)VA(k), (void*)op->va, BY2PG); - kunmap(k); - } - } - unlock(s->o); - /* - * Duplicate segments - */ - for(s=&u->p->seg[0], n=0; no == 0) - continue; - p->seg[n] = *s; - p->seg[n].proc = p; - o = s->o; - lock(o); - o->nproc++; - if(s->mod) - forkmod(s, &p->seg[n], p); - unlock(o); - } + /* Make a new set of memory segments */ + for(i = 0; i < NSEG; i++) + if(u->p->seg[i]) + p->seg[i] = dupseg(u->p->seg[i]); + /* * Refs */ - incref(u->dot); - for(n=0; n<=u->maxfd; n++) - if(c = u->fd[n]) /* assign = */ - incref(c); + incref(u->dot); /* File descriptors etc. */ + p->fgrp = dupfgrp(u->p->fgrp); + + p->pgrp = u->p->pgrp; /* Process groups */ + incref(p->pgrp); + + p->egrp = u->p->egrp; /* Environment group */ + incref(p->egrp); + /* * Sched */ @@ -122,11 +77,11 @@ sysfork(ulong *arg) spllo(); return 0; } + p->parent = u->p; p->parentpid = u->p->pid; - p->pgrp = u->p->pgrp; + p->fpstate = u->p->fpstate; - incref(p->pgrp); u->p->nchild++; pid = p->pid; memset(p->time, 0, sizeof(p->time)); @@ -147,11 +102,10 @@ long sysexec(ulong *arg) { Proc *p; - Seg *s; + Segment *s, *ts; ulong l, t, d, b, v; int i; Chan *tc, *c; - Orig *o; char **argv, **argp; char *a, *charp, *file; char *progarg[sizeof(Exec)/2+1], elem[NAMELEN]; @@ -160,6 +114,8 @@ sysexec(ulong *arg) int indir; Exec exec; char line[sizeof(Exec)]; + Fgrp *f; + Image *img; p = u->p; validaddr(arg[0], 1, 0); @@ -209,6 +165,7 @@ sysexec(ulong *arg) goto Header; Binary: + poperror(); t = (UTZERO+sizeof(Exec)+exec.text+(BY2PG-1)) & ~(BY2PG-1); d = (t + exec.data + (BY2PG-1)) & ~(BY2PG-1); bssend = t + exec.data + exec.bss; @@ -237,7 +194,7 @@ sysexec(ulong *arg) if(((ulong)argp&(BY2PG-1)) < BY2WD) validaddr((ulong)argp, BY2WD, 0); validaddr((ulong)a, 1, 0); - nbytes += (vmemchr(a, 0, ~0) - a) + 1; + nbytes += (vmemchr(a, 0, 0xFFFFFFFF) - a) + 1; nargs++; } ssize = BY2WD*(nargs+1) + ((nbytes+(BY2WD-1)) & ~(BY2WD-1)); @@ -248,11 +205,8 @@ sysexec(ulong *arg) if(spage > TSTKSIZ) errors("not enough argument stack space"); - s = &p->seg[ESEG]; - s->proc = p; - s->o = neworig(TSTKTOP-(spage<minva = s->o->va; - s->maxva = TSTKTOP; + + p->seg[ESEG] = newseg(SG_STACK, TSTKTOP-USTKSIZE, USTKSIZE/BY2PG); /* * Args: pass 2: assemble; the pages will be faulted in @@ -263,8 +217,9 @@ sysexec(ulong *arg) argp = progarg; else argp = (char**)arg[1]; + for(i=0; itext, elem, NAMELEN); + if(waserror()) + pexit("fatal exec error", 0); + /* - * Committed. Free old memory + * Committed. Free old memory. Special segments are maintained accross exec */ - freesegs(ESEG); + putseg(p->seg[TSEG]); + p->seg[TSEG] = 0; /* prevent a second free if we have an error */ + putseg(p->seg[DSEG]); + p->seg[DSEG] = 0; + putseg(p->seg[BSEG]); + p->seg[BSEG] = 0; + putseg(p->seg[SSEG]); + p->seg[SSEG] = 0; /* * Close on exec */ - for(i=0; i<=u->maxfd; i++) - if((c=u->fd[i]) && c->flag&CCEXEC){ - close(c); - fdclose(i); - } + f = u->p->fgrp; + for(i=0; i<=f->maxfd; i++) + fdclose(i, CCEXEC); - /* - * Text. Shared. - */ - s = &p->seg[TSEG]; - s->proc = p; - o = lookorig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED|OISMEM, tc); - if(o == 0){ - o = neworig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED|OISMEM, tc); - o->minca = 0; - o->maxca = sizeof(Exec)+exec.text; - } - s->o = o; - s->minva = UTZERO; - s->maxva = t; - s->mod = 0; + /* Text. Shared. Attaches to cache image if possible */ + img = attachimage(SG_TEXT|SG_RONLY, tc, UTZERO, (t-UTZERO)>>PGSHIFT); + ts = img->s; + p->seg[TSEG] = ts; + ts->fstart = 0; + ts->flen = sizeof(Exec)+exec.text; - /* - * Data. Shared. - */ - s = &p->seg[DSEG]; - s->proc = p; - o = lookorig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED|OISMEM, tc); - if(o == 0){ - o = neworig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED|OISMEM, tc); - o->minca = p->seg[TSEG].o->maxca; - o->maxca = o->minca + exec.data; - } - s->o = o; - s->minva = t; - s->maxva = d; - s->mod = 0; + /* Data. Shared. */ + s = newseg(SG_DATA, t, (d-t)>>PGSHIFT); + p->seg[DSEG] = s; - /* - * BSS. Created afresh. - */ - s = &p->seg[BSEG]; - s->proc = p; - o = neworig(d, (b-d)>>PGSHIFT, OWRPERM|OISMEM, 0); - o->minca = 0; - o->maxca = 0; - s->o = o; - s->minva = d; - s->maxva = b; - s->mod = 0; + /* Attached by hand */ + incref(img); + s->image = img; + s->fstart = ts->fstart+ts->flen; + s->flen = exec.data; - poperror(); - close(tc); - p->seg[BSEG].endseg = bssend; + /* BSS. Zero fill on demand */ + p->seg[BSEG] = newseg(SG_BSS, d, (b-d)>>PGSHIFT); + + close(tc); /* * Move the stack */ - s = &p->seg[SSEG]; - *s = p->seg[ESEG]; - p->seg[ESEG].o = 0; - o = s->o; - o->va += (USTKTOP-TSTKTOP); - s->minva = o->va; - s->maxva = USTKTOP; - lock(o); - for(i=0; inpte; i++) - o->pte[i].page->va += (USTKTOP-TSTKTOP); - unlock(o); + s = p->seg[ESEG]; + p->seg[SSEG] = s; + s->base = USTKTOP-USTKSIZE; + s->top = USTKTOP; + relocateseg(s, TSTKTOP-USTKTOP); + p->seg[ESEG] = 0; + + poperror(); /* - * at this point, the mmu contains info about the old address + * At this point, the mmu contains info about the old address * space and needs to be flushed */ flushmmu(); @@ -437,6 +370,7 @@ sysexits(ulong *arg) vmemchr(status, 0, ERRLEN); } poperror(); + } pexit(status, 1); } @@ -473,10 +407,13 @@ sysforkpgrp(ulong *arg) { int mask; Pgrp *pg; + Egrp *eg; pg = newpgrp(); + eg = newegrp(); if(waserror()){ closepgrp(pg); + closeegrp(eg); nexterror(); } @@ -490,7 +427,7 @@ sysforkpgrp(ulong *arg) pgrpcpy(pg, u->p->pgrp); if(mask & FPenv) - envcpy(pg, u->p->pgrp); + envcpy(eg, u->p->egrp); if((mask & FPnote) == 0) { u->nnote = 0; @@ -500,7 +437,9 @@ sysforkpgrp(ulong *arg) poperror(); closepgrp(u->p->pgrp); + closeegrp(u->p->egrp); u->p->pgrp = pg; + u->p->egrp = eg; return pg->pgrpid; } @@ -521,17 +460,92 @@ sysnoted(ulong *arg) return 0; } -/* - * Temporary; should be replaced by a generalized segment control operator - */ long -sysbrk_(ulong *arg) +syssegbrk(ulong *arg) { - return ibrk(arg[0], BSEG); + Segment *s; + int i; + + for(i = 0; i < NSEG; i++) + if(s = u->p->seg[i]) { + if(arg[0] >= s->base && arg[0] < s->top) { + switch(s->type&SG_TYPE) { + case SG_TEXT: + case SG_DATA: + errors("bad segment type"); + default: + return ibrk(arg[1], i); + } + } + } + + errors("not in address space"); } long -syslkbrk_(ulong *arg) +syssegattach(ulong *arg) { - return ibrk(arg[0], LSEG); + return segattach(u->p, arg[0], (char*)arg[1], arg[2], arg[3]); +} + +long +syssegdetach(ulong *arg) +{ + int i; + Segment *s; + + for(i = 0; i < NSEG; i++) + if(s = u->p->seg[i]) { + qlock(&s->lk); + if((arg[0] >= s->base && arg[0] < s->top) || + (s->top == s->base && arg[0] == s->base)) + goto found; + qunlock(&s->lk); + } + + errors("not in address space"); + +found: + if((ulong)arg >= s->base && (ulong)arg < s->top) { + qunlock(&s->lk); + errors("illegal address"); + } + u->p->seg[i] = 0; + qunlock(&s->lk); + putseg(s); + + /* Ensure we flush any entries from the lost segment */ + flushmmu(); + return 0; +} + +long +syssegfree(ulong *arg) +{ + Segment *s; + ulong from, len; + + s = seg(u->p, arg[0], 1); + if(s == 0) + errors("not in address space"); + + from = PGROUND(arg[1]); + len = arg[2]; + + if(from+len > s->top) { + qunlock(&s->lk); + errors("segment too short"); + } + + mfreeseg(s, from, len); + qunlock(&s->lk); + + return 0; +} + +/* For binary compatability */ +long +sysbrk_(ulong *arg) +{ + return ibrk(arg[0], BSEG); } diff --git a/port/tcpinput.c b/port/tcpinput.c index 432980dd7def31099ff58ab15f05fcfc9858d596..f76d9fc3fa7d871ed8f66f2dd01bc74e651573cd 100644 --- a/port/tcpinput.c +++ b/port/tcpinput.c @@ -20,6 +20,18 @@ char *tcpstate[] = { "Established", "Finwait1", "Finwait2", "Close_wait", "Closing", "Last_ack", "Time_wait" }; +void +tcpinit(void) +{ + Reseq *r; + + reseqfree = ialloc(sizeof(Reseq)*Nreseq, 0); + for(r = reseqfree; r < &reseqfree[Nreseq-1]; r++) + r->next = r+1; + + r->next = 0; +} + void tcp_input(Ipconv *ipc, Block *bp) { @@ -657,6 +669,7 @@ add_reseq(Tcpctl *tcb, char tos, Tcp *seg, Block *bp, ushort length) qlock(&reseqlock); if(!reseqfree) { qunlock(&reseqlock); + print("tcp: no resequence descriptors\n"); freeb(bp); return; } diff --git a/power/boot.h b/power/boot.h index 0ce3f38ba8877802db7f9d55af2e078b61d4f655..699e0a2b463427b7e2e4946876c4eda66d7e9459 100644 --- a/power/boot.h +++ b/power/boot.h @@ -1,6 +1,6 @@ ulong bootcode[]={ 0x000000407, - 0x000005638, + 0x000005588, 0x0000007d0, 0x000001190, 0x000000000, @@ -25,24 +25,24 @@ ulong bootcode[]={ 0x0afa00018, 0x023c282e1, 0x0afa20004, - 0x00c000a83, + 0x00c000a73, 0x0afa00008, 0x023c382e9, 0x0afa30004, 0x020020001, - 0x00c000a83, + 0x00c000a73, 0x0afa20008, 0x023c382f1, 0x0afa30004, 0x020020001, - 0x00c000a83, + 0x00c000a73, 0x0afa20008, 0x023c282f9, 0x0afa20004, 0x020040001, 0x0afa40008, 0x0200201b6, - 0x00c000a6a, + 0x00c000a5f, 0x0afa2000c, 0x004210004, 0x0afa1001c, @@ -52,13 +52,13 @@ ulong bootcode[]={ 0x08fa20028, 0x000000027, 0x08c420000, - 0x00c000a43, + 0x00c000a3b, 0x0afa20004, 0x0afa10014, 0x08fa40028, 0x000000027, 0x08c840000, - 0x00c000a43, + 0x00c000a3b, 0x0afa40004, 0x0afa10010, 0x08fa4001c, @@ -70,7 +70,7 @@ ulong bootcode[]={ 0x000000027, 0x0afa30008, 0x08fa40010, - 0x00c000a9c, + 0x00c000a87, 0x0afa4000c, 0x08fa30014, 0x000000027, @@ -80,14 +80,14 @@ ulong bootcode[]={ 0x00c0008d0, 0x0afa20004, 0x08fa3001c, - 0x00c000a65, + 0x00c000a5b, 0x0afa30004, 0x023c38314, 0x0afa30004, 0x020040001, 0x0afa40008, 0x0200301b6, - 0x00c000a6a, + 0x00c000a5f, 0x0afa3000c, 0x004210004, 0x0afa1001c, @@ -95,7 +95,7 @@ ulong bootcode[]={ 0x00c0008d0, 0x0afa20004, 0x023c48336, - 0x00c000a43, + 0x00c000a3b, 0x0afa40004, 0x0afa10014, 0x08fa4001c, @@ -103,7 +103,7 @@ ulong bootcode[]={ 0x0afa40004, 0x0afa20008, 0x08fa40014, - 0x00c000a9c, + 0x00c000a87, 0x0afa4000c, 0x004210004, 0x000000027, @@ -111,7 +111,7 @@ ulong bootcode[]={ 0x00c0008d0, 0x0afa20004, 0x08fa3001c, - 0x00c000a65, + 0x00c000a5b, 0x0afa30004, 0x08fa20028, 0x000000027, @@ -143,12 +143,12 @@ ulong bootcode[]={ 0x023c28026, 0x0afa20004, 0x023c3834c, - 0x00c000a03, + 0x00c0009fc, 0x0afa30008, 0x023c298d2, 0x0afa20004, 0x023c38357, - 0x00c000a03, + 0x00c0009fc, 0x0afa30008, 0x08fa60028, 0x08fa20024, @@ -165,14 +165,14 @@ ulong bootcode[]={ 0x000000027, 0x018a00003, 0x000000027, - 0x00c000a65, + 0x00c000a5b, 0x0afa50004, 0x08fc3801a, 0x000000027, 0x018600004, 0x000000027, 0x08fc2801a, - 0x00c000a65, + 0x00c000a5b, 0x0afa20004, 0x0afc0801a, 0x0afc08006, @@ -184,20 +184,20 @@ ulong bootcode[]={ 0x000000027, 0x0afa50004, 0x08cc30000, - 0x00c000a03, + 0x00c0009fc, 0x0afa30008, 0x023c28026, 0x0afa20004, 0x08fa30028, 0x000000027, 0x08c630004, - 0x00c000a03, + 0x00c0009fc, 0x0afa30008, 0x00800049f, 0x000000027, 0x0afa50004, 0x08cc30000, - 0x00c000a03, + 0x00c0009fc, 0x0afa30008, 0x00800049f, 0x000000027, @@ -206,7 +206,7 @@ ulong bootcode[]={ 0x023c3835f, 0x0afa30004, 0x020020002, - 0x00c000a83, + 0x00c000a73, 0x0afa20008, 0x08fa20000, 0x000000027, @@ -224,7 +224,7 @@ ulong bootcode[]={ 0x000000027, 0x0afa30004, 0x08fa40028, - 0x00c0009ed, + 0x00c0009e9, 0x0afa40008, 0x08fa50014, 0x0142000a5, @@ -248,7 +248,7 @@ ulong bootcode[]={ 0x023c28395, 0x0afa20004, 0x020040002, - 0x00c000a83, + 0x00c000a73, 0x0afa40008, 0x004210008, 0x000000027, @@ -264,12 +264,12 @@ ulong bootcode[]={ 0x023c483af, 0x0afa40008, 0x02003000d, - 0x00c000a9c, + 0x00c000a87, 0x0afa3000c, 0x08fa50020, 0x00421000a, 0x000000027, - 0x00c000a65, + 0x00c000a5b, 0x0afa50004, 0x023c383bd, 0x00c0008be, @@ -282,12 +282,12 @@ ulong bootcode[]={ 0x023c483cb, 0x0afa40008, 0x02003000c, - 0x00c000a9c, + 0x00c000a87, 0x0afa3000c, 0x08fa50020, 0x00421000a, 0x000000027, - 0x00c000a65, + 0x00c000a5b, 0x0afa50004, 0x023c383d8, 0x00c0008be, @@ -300,12 +300,12 @@ ulong bootcode[]={ 0x023c483e5, 0x0afa40008, 0x02003000c, - 0x00c000a9c, + 0x00c000a87, 0x0afa3000c, 0x00421000b, 0x000000027, 0x08fa20020, - 0x00c000a65, + 0x00c000a5b, 0x0afa20004, 0x023c383f2, 0x00c0008be, @@ -319,7 +319,7 @@ ulong bootcode[]={ 0x023c283ff, 0x0afa20004, 0x020040002, - 0x00c000a83, + 0x00c000a73, 0x0afa40008, 0x004210008, 0x0afa10018, @@ -333,12 +333,12 @@ ulong bootcode[]={ 0x023c38425, 0x0afa30004, 0x020040002, - 0x00c000a83, + 0x00c000a73, 0x0afa40008, 0x00421000c, 0x0afa1001c, 0x08fa20018, - 0x00c000a65, + 0x00c000a5b, 0x0afa20004, 0x023c28433, 0x0afa20004, @@ -351,7 +351,7 @@ ulong bootcode[]={ 0x08fa40014, 0x000000027, 0x08c840004, - 0x00c000a43, + 0x00c000a3b, 0x0afa40004, 0x0afa10010, 0x08fa4001c, @@ -363,15 +363,15 @@ ulong bootcode[]={ 0x000000027, 0x0afa20008, 0x08fa40010, - 0x00c000a9c, + 0x00c000a87, 0x0afa4000c, 0x004210012, 0x000000027, 0x08fa2001c, - 0x00c000a65, + 0x00c000a5b, 0x0afa20004, 0x08fa30018, - 0x00c000a65, + 0x00c000a5b, 0x0afa30004, 0x08fa30014, 0x000000027, @@ -404,7 +404,7 @@ ulong bootcode[]={ 0x023c28457, 0x0afa20004, 0x020040002, - 0x00c000a83, + 0x00c000a73, 0x0afa40008, 0x004210008, 0x0afc1801e, @@ -419,12 +419,12 @@ ulong bootcode[]={ 0x023c4846d, 0x0afa40008, 0x02003000a, - 0x00c000a9c, + 0x00c000a87, 0x0afa3000c, 0x08fc5801e, 0x00421000a, 0x000000027, - 0x00c000a65, + 0x00c000a5b, 0x0afa50004, 0x023c38478, 0x00c0008be, @@ -437,12 +437,12 @@ ulong bootcode[]={ 0x023c48483, 0x0afa40008, 0x020030017, - 0x00c000a9c, + 0x00c000a87, 0x0afa3000c, 0x00421000b, 0x000000027, 0x08fc2801e, - 0x00c000a65, + 0x00c000a5b, 0x0afa20004, 0x023c3849b, 0x00c0008be, @@ -454,12 +454,12 @@ ulong bootcode[]={ 0x020020001, 0x0afc280ce, 0x0200307d0, - 0x00c000a8d, + 0x00c000a7b, 0x0afa30004, 0x023c384b3, 0x0afa30004, 0x020040002, - 0x00c000a83, + 0x00c000a73, 0x0afa40008, 0x004210008, 0x0afa10054, @@ -473,12 +473,12 @@ ulong bootcode[]={ 0x023c284d3, 0x0afa20004, 0x020040002, - 0x00c000a83, + 0x00c000a73, 0x0afa40008, 0x00421000c, 0x0afc1801a, 0x08fa30054, - 0x00c000a65, + 0x00c000a5b, 0x0afa30004, 0x023c384de, 0x0afa30004, @@ -496,7 +496,7 @@ ulong bootcode[]={ 0x00c0009b1, 0x0afa2000c, 0x023a40014, - 0x00c000a43, + 0x00c000a3b, 0x0afa40004, 0x0afa10010, 0x08fc4801a, @@ -504,15 +504,15 @@ ulong bootcode[]={ 0x0afa40004, 0x0afa20008, 0x08fa40010, - 0x00c000a9c, + 0x00c000a87, 0x0afa4000c, 0x004210010, 0x000000027, 0x08fc2801a, - 0x00c000a65, + 0x00c000a5b, 0x0afa20004, 0x08fa30054, - 0x00c000a65, + 0x00c000a5b, 0x0afa30004, 0x02002ffff, 0x0afc2801a, @@ -549,7 +549,7 @@ ulong bootcode[]={ 0x08fa500d0, 0x014200007, 0x000000027, - 0x00c000a65, + 0x00c000a5b, 0x0afa50004, 0x08fa20000, 0x023bd00d4, @@ -562,14 +562,14 @@ ulong bootcode[]={ 0x023c28509, 0x0afa20010, 0x023c4850a, - 0x00c000a7e, + 0x00c000a6f, 0x0afa40014, 0x004210004, 0x000000027, 0x023c2850b, 0x00c0008d0, 0x0afa20004, - 0x00c000a79, + 0x00c000a6b, 0x000000027, 0x02003ffff, 0x01023002f, @@ -577,7 +577,7 @@ ulong bootcode[]={ 0x010200022, 0x000000027, 0x023a20018, - 0x00c000a97, + 0x00c000a83, 0x0afa20004, 0x083a3002c, 0x000000027, @@ -593,7 +593,7 @@ ulong bootcode[]={ 0x00c00098c, 0x0afa20008, 0x020030bb8, - 0x00c000a8d, + 0x00c000a7b, 0x0afa30004, 0x020020002, 0x0afa20004, @@ -603,7 +603,7 @@ ulong bootcode[]={ 0x023c2857b, 0x0afa20004, 0x020030002, - 0x00c000a83, + 0x00c000a73, 0x0afa30008, 0x08fa20000, 0x000000027, @@ -615,7 +615,7 @@ ulong bootcode[]={ 0x0afa20008, 0x023c38535, 0x0afa3000c, - 0x00c000a4f, + 0x00c000a47, 0x0afa00010, 0x023c28545, 0x00c0008d0, @@ -637,14 +637,14 @@ ulong bootcode[]={ 0x023c297d2, 0x0afa20004, 0x023c487d2, - 0x00c000ae9, + 0x00c000ad3, 0x0afa40008, 0x08fa30024, 0x023c487d2, 0x0afa30004, 0x0afa40008, 0x0afa1001c, - 0x00c000a9c, + 0x00c000a87, 0x0afa1000c, 0x08fa5001c, 0x000000027, @@ -666,7 +666,7 @@ ulong bootcode[]={ 0x0afa20004, 0x0afa40008, 0x020021000, - 0x00c000a88, + 0x00c000a77, 0x0afa2000c, 0x01c200008, 0x000000027, @@ -687,7 +687,7 @@ ulong bootcode[]={ 0x023c497d2, 0x0afa40008, 0x0afa1001c, - 0x00c000f10, + 0x00c000efa, 0x0afa1000c, 0x014200022, 0x000000027, @@ -756,14 +756,14 @@ ulong bootcode[]={ 0x023c397d2, 0x0afa30004, 0x023c487d2, - 0x00c000ae9, + 0x00c000ad3, 0x0afa40008, 0x08fa20024, 0x023c487d2, 0x0afa20004, 0x0afa40008, 0x0afa1001c, - 0x00c000a9c, + 0x00c000a87, 0x0afa1000c, 0x08fa4001c, 0x000000027, @@ -781,7 +781,7 @@ ulong bootcode[]={ 0x0afa20004, 0x0afa40008, 0x020021000, - 0x00c000a88, + 0x00c000a77, 0x0afa2000c, 0x01c200008, 0x000000027, @@ -796,7 +796,7 @@ ulong bootcode[]={ 0x0afa30004, 0x023c497d2, 0x0afa40008, - 0x00c000f10, + 0x00c000efa, 0x0afa1000c, 0x014200008, 0x000000027, @@ -919,7 +919,7 @@ ulong bootcode[]={ 0x020040001, 0x0afa40008, 0x0200201b6, - 0x00c000a6a, + 0x00c000a5f, 0x0afa2000c, 0x004210004, 0x0afa10148, @@ -934,11 +934,11 @@ ulong bootcode[]={ 0x00c0009b1, 0x0afa2000c, 0x023c387d2, - 0x00c000a43, + 0x00c000a3b, 0x0afa30004, 0x0afa10014, 0x023c487d2, - 0x00c000a43, + 0x00c000a3b, 0x0afa40004, 0x0afa10010, 0x08fa40148, @@ -946,7 +946,7 @@ ulong bootcode[]={ 0x0afa40004, 0x0afa30008, 0x08fa40010, - 0x00c000a9c, + 0x00c000a87, 0x0afa4000c, 0x08fa30014, 0x000000027, @@ -956,14 +956,14 @@ ulong bootcode[]={ 0x00c0008d0, 0x0afa20004, 0x08fa30148, - 0x00c000a65, + 0x00c000a5b, 0x0afa30004, 0x023c386ab, 0x0afa30004, 0x020040001, 0x0afa40008, 0x0200301b6, - 0x00c000a6a, + 0x00c000a5f, 0x0afa3000c, 0x004210004, 0x0afa10148, @@ -978,11 +978,11 @@ ulong bootcode[]={ 0x00c0009b1, 0x0afa3000c, 0x023c287d2, - 0x00c000a43, + 0x00c000a3b, 0x0afa20004, 0x0afa10014, 0x023c487d2, - 0x00c000a43, + 0x00c000a3b, 0x0afa40004, 0x0afa10010, 0x08fa40148, @@ -990,7 +990,7 @@ ulong bootcode[]={ 0x0afa40004, 0x0afa30008, 0x08fa40010, - 0x00c000a9c, + 0x00c000a87, 0x0afa4000c, 0x08fa30014, 0x000000027, @@ -1000,7 +1000,7 @@ ulong bootcode[]={ 0x00c0008d0, 0x0afa20004, 0x08fa30148, - 0x00c000a65, + 0x00c000a5b, 0x0afa30004, 0x023c286c3, 0x00c000967, @@ -1009,7 +1009,7 @@ ulong bootcode[]={ 0x0afa20004, 0x023c486ce, 0x0afa40008, - 0x00c000a60, + 0x00c000a57, 0x0afa0000c, 0x004210004, 0x000000027, @@ -1025,7 +1025,7 @@ ulong bootcode[]={ 0x023c486d7, 0x0afa40010, 0x023c286d8, - 0x00c000a7e, + 0x00c000a6f, 0x0afa20014, 0x004210004, 0x000000027, @@ -1038,7 +1038,7 @@ ulong bootcode[]={ 0x023c286e7, 0x0afa20004, 0x023a40058, - 0x00c000a92, + 0x00c000a7f, 0x0afa40008, 0x004210004, 0x000000027, @@ -1048,12 +1048,12 @@ ulong bootcode[]={ 0x023a30058, 0x0afa30004, 0x023a200cc, - 0x00c0011e0, + 0x00c0011ca, 0x0afa20008, 0x023c286f0, 0x0afa20004, 0x020040001, - 0x00c000a83, + 0x00c000a73, 0x0afa40008, 0x0afa10148, 0x023a20058, @@ -1064,7 +1064,7 @@ ulong bootcode[]={ 0x00c0009b1, 0x0afa2000c, 0x023a20058, - 0x00c000a43, + 0x00c000a3b, 0x0afa20004, 0x0afa10014, 0x08fa20148, @@ -1072,10 +1072,10 @@ ulong bootcode[]={ 0x0afa20004, 0x0afa30008, 0x08fa20014, - 0x00c000a9c, + 0x00c000a87, 0x0afa2000c, 0x08fa30148, - 0x00c000a65, + 0x00c000a5b, 0x0afa30004, 0x023c286fc, 0x00c000967, @@ -1095,13 +1095,13 @@ ulong bootcode[]={ 0x023a20018, 0x0afa30004, 0x0afa20008, - 0x00c000a60, + 0x00c000a57, 0x0afa0000c, 0x08fc3812a, 0x023c2870d, 0x0afa30004, 0x0afa20008, - 0x00c000a60, + 0x00c000a57, 0x0afa0000c, 0x08fc58022, 0x000000027, @@ -1122,7 +1122,7 @@ ulong bootcode[]={ 0x0afa30004, 0x023c28748, 0x0afa20008, - 0x00c000a60, + 0x00c000a57, 0x0afa0000c, 0x08fa30154, 0x000000027, @@ -1134,7 +1134,7 @@ ulong bootcode[]={ 0x0afa30008, 0x023c28769, 0x0afa2000c, - 0x00c000a4f, + 0x00c000a47, 0x0afa00010, 0x023c3877c, 0x00c0008d0, @@ -1147,7 +1147,7 @@ ulong bootcode[]={ 0x0afa30004, 0x023c28777, 0x0afa20008, - 0x00c000a4f, + 0x00c000a47, 0x0afa0000c, 0x023c3877c, 0x00c0008d0, @@ -1160,7 +1160,7 @@ ulong bootcode[]={ 0x00c000967, 0x0afa30004, 0x0200203e8, - 0x00c000a8d, + 0x00c000a7b, 0x0afa20004, 0x08fc68006, 0x08fa20144, @@ -1216,7 +1216,7 @@ ulong bootcode[]={ 0x023bdffac, 0x0afbf0000, 0x023a20014, - 0x00c000a6f, + 0x00c000a63, 0x0afa20004, 0x020030002, 0x0afa30004, @@ -1234,7 +1234,7 @@ ulong bootcode[]={ 0x023bdffac, 0x0afbf0000, 0x023a30014, - 0x00c000a6f, + 0x00c000a63, 0x0afa30004, 0x020020002, 0x0afa20004, @@ -1265,7 +1265,7 @@ ulong bootcode[]={ 0x023a30010, 0x0afa30008, 0x08fa40120, - 0x00c000a88, + 0x00c000a77, 0x0afa4000c, 0x014200003, 0x000012825, @@ -1287,7 +1287,7 @@ ulong bootcode[]={ 0x08fa3011c, 0x023a20010, 0x0afa30004, - 0x00c000a03, + 0x00c0009fc, 0x0afa20008, 0x08fa50110, 0x000000027, @@ -1376,7 +1376,7 @@ ulong bootcode[]={ 0x00800094f, 0x02484ffff, 0x08fa30014, - 0x00c000a5b, + 0x00c000a53, 0x0afa30004, 0x08fa20000, 0x000000027, @@ -1392,14 +1392,14 @@ ulong bootcode[]={ 0x023a41020, 0x0afa3000c, 0x024840004, - 0x00c00129d, + 0x00c001284, 0x0afa40010, 0x023a6001c, 0x020020001, 0x0afa20004, 0x0afa60008, 0x000261023, - 0x00c000a9c, + 0x00c000a87, 0x0afa2000c, 0x0afa10014, 0x00421000c, @@ -1429,14 +1429,14 @@ ulong bootcode[]={ 0x023a41024, 0x0afa3000c, 0x024840004, - 0x00c00129d, + 0x00c001284, 0x0afa40010, 0x08fa21020, 0x023a6001c, 0x0afa20004, 0x0afa60008, 0x000261023, - 0x00c000a9c, + 0x00c000a87, 0x0afa2000c, 0x0afa10014, 0x00421000c, @@ -1468,7 +1468,7 @@ ulong bootcode[]={ 0x023a40024, 0x0afa2000c, 0x024840004, - 0x00c00129d, + 0x00c001284, 0x0afa40010, 0x08fa20014, 0x000000027, @@ -1480,10 +1480,9 @@ ulong bootcode[]={ 0x000000027, 0x000400008, 0x023bd001c, - 0x023bdfffc, - 0x08fa70010, - 0x08fa6000c, - 0x08fa50008, + 0x08fa7000c, + 0x08fa60008, + 0x08fa50004, 0x000000027, 0x024e7ffff, 0x004e00007, @@ -1492,11 +1491,10 @@ ulong bootcode[]={ 0x000061025, 0x080420000, 0x000000027, - 0x01062000f, + 0x01062000d, 0x024c60001, - 0x004e10004, + 0x004e10003, 0x000000027, - 0x023bd0004, 0x003e00008, 0x000000825, 0x080a10000, @@ -1505,42 +1503,36 @@ ulong bootcode[]={ 0x000010e03, 0x000021600, 0x000021603, - 0x023bd0004, 0x003e00008, 0x000220823, 0x000051825, 0x080630000, 0x000000027, - 0x01460ffe5, + 0x01460ffe7, 0x024a50001, - 0x023bd0004, 0x003e00008, 0x000000825, - 0x023bdfffc, - 0x08fa30008, - 0x08fa2000c, + 0x08fa30004, + 0x08fa20008, 0x000000027, 0x080410000, 0x080640000, - 0x01020000c, + 0x01020000b, 0x000000027, 0x024630001, 0x01024fffa, 0x024420001, 0x00024082b, - 0x014200004, + 0x014200003, 0x000000027, - 0x023bd0004, 0x003e00008, 0x02001ffff, 0x003e00008, - 0x023bd0004, - 0x023bd0004, + 0x000000027, 0x003e00008, 0x00024082b, - 0x023bdfffc, - 0x08fa30008, - 0x08fa4000c, + 0x08fa30004, + 0x08fa40008, 0x000000027, 0x000830826, 0x030210003, @@ -1557,9 +1549,9 @@ ulong bootcode[]={ 0x024630001, 0x014a0fff8, 0x024840001, - 0x08fa10008, + 0x08fa10004, 0x003e00008, - 0x023bd0004, + 0x000000027, 0x08c850000, 0x024840004, 0x000a60824, @@ -1572,42 +1564,42 @@ ulong bootcode[]={ 0x030a200ff, 0x01440fff5, 0x0ac65fffc, - 0x08fa10008, + 0x08fa10004, 0x003e00008, - 0x023bd0004, + 0x000000027, 0x000050e02, 0x0a061fffc, 0x000052c02, 0x0a065fffd, 0x0a060fffe, - 0x08fa10008, + 0x08fa10004, 0x003e00008, - 0x023bd0004, + 0x000000027, 0x000052e02, 0x0a065fffc, 0x0a060fffd, - 0x08fa10008, + 0x08fa10004, 0x003e00008, - 0x023bd0004, + 0x000000027, 0x0a060fffc, - 0x08fa10008, + 0x08fa10004, 0x003e00008, - 0x023bd0004, + 0x000000027, 0x080850000, 0x000000027, 0x0a0650000, 0x024630001, 0x014a0fffb, 0x024840001, - 0x08fa10008, + 0x08fa10004, 0x003e00008, - 0x023bd0004, + 0x000000027, 0x023bdfff4, 0x0afbf0000, 0x08fa20010, 0x000000027, 0x0afa20004, - 0x00c00180c, + 0x00c0017e7, 0x0afa00008, 0x08fa30010, 0x08fa20000, @@ -1620,82 +1612,68 @@ ulong bootcode[]={ 0x023a30010, 0x0afa20004, 0x024630004, - 0x00c000a74, + 0x00c000a67, 0x0afa30008, 0x08fa20000, 0x000000027, 0x000400008, 0x023bd000c, - 0x023bdfffc, 0x020010008, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x020010002, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x020010004, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x020010016, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x020010001, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x020010007, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x020010009, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x02001000d, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x02001000e, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x02001000f, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x020010011, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x020010012, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x020010013, 0x00000000c, 0x003e00008, - 0x023bd0004, - 0x023bdfffc, + 0x000000027, 0x020010014, 0x00000000c, 0x003e00008, - 0x023bd0004, + 0x000000027, 0x023bdffe4, 0x0afbf0000, 0x023c280ea, @@ -1713,7 +1691,7 @@ ulong bootcode[]={ 0x08fa2002c, 0x000000027, 0x08c420000, - 0x00c000a88, + 0x00c000a77, 0x0afa2000c, 0x014200015, 0x0afa10018, @@ -1749,7 +1727,7 @@ ulong bootcode[]={ 0x08fa40028, 0x000000027, 0x0afa40008, - 0x00c000f10, + 0x00c000efa, 0x0afa1000c, 0x014200009, 0x0afa10018, @@ -1759,7 +1737,7 @@ ulong bootcode[]={ 0x00c00098c, 0x0afa30008, 0x023c28121, - 0x008000abb, + 0x008000aa5, 0x0afa20010, 0x08fa3002c, 0x000000027, @@ -1859,7 +1837,7 @@ ulong bootcode[]={ 0x024a20008, 0x0afa20008, 0x020030040, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa20010, 0x000000027, @@ -1885,7 +1863,7 @@ ulong bootcode[]={ 0x024a20008, 0x0afa20008, 0x02003001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa20010, 0x02003001c, @@ -1896,7 +1874,7 @@ ulong bootcode[]={ 0x000000027, 0x024420024, 0x0afa20008, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa20010, 0x02003001c, @@ -1907,7 +1885,7 @@ ulong bootcode[]={ 0x000000027, 0x024420040, 0x0afa20008, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa20010, 0x000000027, @@ -2039,7 +2017,7 @@ ulong bootcode[]={ 0x024a3000e, 0x0afa30008, 0x02002001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, 0x08fa2001c, @@ -2188,7 +2166,7 @@ ulong bootcode[]={ 0x024a2000e, 0x0afa20008, 0x02003001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa70018, 0x08fa20010, @@ -2268,7 +2246,7 @@ ulong bootcode[]={ 0x000000027, 0x0afa20008, 0x08ca3000c, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa20018, 0x08fa30010, @@ -2412,7 +2390,7 @@ ulong bootcode[]={ 0x000000027, 0x0afa20008, 0x08ca3000c, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa20018, 0x08fa30010, @@ -2543,7 +2521,7 @@ ulong bootcode[]={ 0x024a30008, 0x0afa30008, 0x020020074, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, 0x08fa2001c, @@ -2599,7 +2577,7 @@ ulong bootcode[]={ 0x024a20008, 0x0afa20008, 0x020030074, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa20010, 0x000000027, @@ -2647,7 +2625,7 @@ ulong bootcode[]={ 0x024a2000e, 0x0afa20008, 0x02003001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa20010, 0x000000027, @@ -2684,7 +2662,7 @@ ulong bootcode[]={ 0x08fa30018, 0x000000027, 0x0afa30008, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, 0x02002001c, @@ -2695,7 +2673,7 @@ ulong bootcode[]={ 0x000000027, 0x02463001c, 0x0afa30008, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, 0x02002001c, @@ -2706,7 +2684,7 @@ ulong bootcode[]={ 0x000000027, 0x024630038, 0x0afa30008, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa40018, 0x08fa30010, @@ -2916,17 +2894,17 @@ ulong bootcode[]={ 0x000031a00, 0x000431025, 0x024a50002, - 0x008000f42, + 0x008000f2c, 0x0a4c20008, 0x024c20008, 0x0afa20004, 0x0afa50010, 0x0afa50008, 0x020020040, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, - 0x008000f42, + 0x008000f2c, 0x024650040, 0x090a20000, 0x090a30001, @@ -2941,7 +2919,7 @@ ulong bootcode[]={ 0x0afa50010, 0x0afa50008, 0x02002001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, 0x08fa2001c, @@ -2951,7 +2929,7 @@ ulong bootcode[]={ 0x0afa50010, 0x0afa50008, 0x02002001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, 0x08fa2001c, @@ -2961,10 +2939,10 @@ ulong bootcode[]={ 0x0afa50010, 0x0afa50008, 0x02002001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, - 0x008000f42, + 0x008000f2c, 0x02465001c, 0x02003003e, 0x00062202a, @@ -2992,7 +2970,7 @@ ulong bootcode[]={ 0x000031a00, 0x000431025, 0x024a50002, - 0x008000f42, + 0x008000f2c, 0x0a4c20002, 0x090a20000, 0x090a30001, @@ -3009,7 +2987,7 @@ ulong bootcode[]={ 0x000031a00, 0x000431025, 0x024a50002, - 0x008000f42, + 0x008000f2c, 0x0a4c2000c, 0x090a20000, 0x090a30001, @@ -3050,7 +3028,7 @@ ulong bootcode[]={ 0x000031e00, 0x000431025, 0x024a50004, - 0x008000f42, + 0x008000f2c, 0x0acc20010, 0x090a20000, 0x090a30001, @@ -3065,10 +3043,10 @@ ulong bootcode[]={ 0x0afa50010, 0x0afa50008, 0x02002001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, - 0x008000f42, + 0x008000f2c, 0x02465001c, 0x02003003f, 0x010430040, @@ -3122,7 +3100,7 @@ ulong bootcode[]={ 0x000031e00, 0x000431025, 0x024a50004, - 0x008000f42, + 0x008000f2c, 0x0acc20010, 0x090a20000, 0x090a30001, @@ -3134,7 +3112,7 @@ ulong bootcode[]={ 0x024a30002, 0x024650001, 0x080630000, - 0x008000f42, + 0x008000f2c, 0x0a0c3002a, 0x090a20000, 0x090a30001, @@ -3175,7 +3153,7 @@ ulong bootcode[]={ 0x000031e00, 0x000431025, 0x024a50004, - 0x008000f42, + 0x008000f2c, 0x0acc20010, 0x090a20000, 0x090a30001, @@ -3190,7 +3168,7 @@ ulong bootcode[]={ 0x0afa50010, 0x0afa50008, 0x02002001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa6001c, 0x08fa30010, @@ -3214,7 +3192,7 @@ ulong bootcode[]={ 0x024a30004, 0x024650001, 0x080630000, - 0x008000f42, + 0x008000f2c, 0x0a0c3002a, 0x02003004a, 0x00062202a, @@ -3260,7 +3238,7 @@ ulong bootcode[]={ 0x024650001, 0x0acc50010, 0x08cc3000c, - 0x008000f42, + 0x008000f2c, 0x000a32821, 0x090a20000, 0x090a30001, @@ -3293,7 +3271,7 @@ ulong bootcode[]={ 0x000031a00, 0x000431025, 0x024a50002, - 0x008000f42, + 0x008000f2c, 0x0acc2000c, 0x090a20000, 0x090a30001, @@ -3334,7 +3312,7 @@ ulong bootcode[]={ 0x000031e00, 0x000431025, 0x024a50004, - 0x008000f42, + 0x008000f2c, 0x0acc20010, 0x090a20000, 0x090a30001, @@ -3371,7 +3349,7 @@ ulong bootcode[]={ 0x024650001, 0x0acc50010, 0x08cc3000c, - 0x008000f42, + 0x008000f2c, 0x000a32821, 0x020030047, 0x01043001d, @@ -3393,7 +3371,7 @@ ulong bootcode[]={ 0x000031a00, 0x000431025, 0x024a50002, - 0x008000f42, + 0x008000f2c, 0x0a4c20002, 0x090a20000, 0x090a30001, @@ -3402,7 +3380,7 @@ ulong bootcode[]={ 0x000031a00, 0x000431025, 0x024a50002, - 0x008000f42, + 0x008000f2c, 0x0a4c20002, 0x090a20000, 0x090a30001, @@ -3419,7 +3397,7 @@ ulong bootcode[]={ 0x000031a00, 0x000431025, 0x024a50002, - 0x008000f42, + 0x008000f2c, 0x0acc2000c, 0x090a20000, 0x090a30001, @@ -3428,7 +3406,7 @@ ulong bootcode[]={ 0x000031a00, 0x000431025, 0x024a50002, - 0x008000f42, + 0x008000f2c, 0x0a4c20002, 0x02003004e, 0x00062202a, @@ -3462,10 +3440,10 @@ ulong bootcode[]={ 0x0afa50010, 0x0afa50008, 0x020020074, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, - 0x008000f42, + 0x008000f2c, 0x024650074, 0x090a20000, 0x090a30001, @@ -3474,7 +3452,7 @@ ulong bootcode[]={ 0x000031a00, 0x000431025, 0x024a50002, - 0x008000f42, + 0x008000f2c, 0x0a4c20002, 0x090a20000, 0x090a30001, @@ -3483,7 +3461,7 @@ ulong bootcode[]={ 0x000031a00, 0x000431025, 0x024a50002, - 0x008000f42, + 0x008000f2c, 0x0a4c20002, 0x090a20000, 0x090a30001, @@ -3498,10 +3476,10 @@ ulong bootcode[]={ 0x0afa50010, 0x0afa50008, 0x020020074, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, - 0x008000f42, + 0x008000f2c, 0x024650074, 0x02003004f, 0x010430025, @@ -3537,10 +3515,10 @@ ulong bootcode[]={ 0x0afa50010, 0x0afa50008, 0x02002001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa2000c, 0x08fa30010, - 0x008000f42, + 0x008000f2c, 0x02465001c, 0x090a20000, 0x090a30001, @@ -3549,7 +3527,7 @@ ulong bootcode[]={ 0x000031a00, 0x000431025, 0x024a50002, - 0x008000f42, + 0x008000f2c, 0x0a4c20002, 0x023bdffec, 0x0afbf0000, @@ -3560,7 +3538,7 @@ ulong bootcode[]={ 0x0afa50010, 0x0afa50008, 0x02003001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa20010, 0x08fa3001c, @@ -3570,7 +3548,7 @@ ulong bootcode[]={ 0x0afa50010, 0x0afa50008, 0x02003001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa20010, 0x08fa3001c, @@ -3580,7 +3558,7 @@ ulong bootcode[]={ 0x0afa50010, 0x0afa50008, 0x02003001c, - 0x00c0018c5, + 0x00c00189a, 0x0afa3000c, 0x08fa5001c, 0x08fa20010, @@ -3704,16 +3682,14 @@ ulong bootcode[]={ 0x000000027, 0x000400008, 0x023bd0014, - 0x023bdfffc, 0x08fc780ca, - 0x083a2000b, + 0x083a20007, 0x028e3001e, 0x03042007f, 0x000022e00, 0x000052e03, - 0x014600004, + 0x014600003, 0x023c68146, - 0x023bd0004, 0x003e00008, 0x020010001, 0x000051e00, @@ -3734,10 +3710,9 @@ ulong bootcode[]={ 0x000021600, 0x000021603, 0x000021080, - 0x08fa4000c, + 0x08fa40008, 0x000431021, 0x000000825, - 0x023bd0004, 0x003e00008, 0x0ac440000, 0x023bdffcc, @@ -3799,7 +3774,7 @@ ulong bootcode[]={ 0x02002000a, 0x014a20003, 0x000000027, - 0x0080012ae, + 0x008001295, 0x0afc080de, 0x020020009, 0x014a2ffd2, @@ -3809,7 +3784,7 @@ ulong bootcode[]={ 0x024630007, 0x0201cfff8, 0x0007c1824, - 0x0080012ae, + 0x008001295, 0x0afc380de, 0x02007fc18, 0x0200bfc18, @@ -3823,7 +3798,7 @@ ulong bootcode[]={ 0x000052e03, 0x014a00003, 0x000000027, - 0x0080012ae, + 0x008001295, 0x024c6ffff, 0x02002002e, 0x014a20007, @@ -3832,7 +3807,7 @@ ulong bootcode[]={ 0x014e20002, 0x000000027, 0x000003825, - 0x0080012e7, + 0x0080012ce, 0x000005825, 0x028a20031, 0x014400025, @@ -3854,11 +3829,11 @@ ulong bootcode[]={ 0x000000027, 0x014a0ffe4, 0x000083825, - 0x0080012ae, + 0x008001295, 0x024c6ffff, 0x014a0ffe0, 0x000085825, - 0x0080012ae, + 0x008001295, 0x024c6ffff, 0x02002000a, 0x001020018, @@ -3871,7 +3846,7 @@ ulong bootcode[]={ 0x000000027, 0x000052e00, 0x000052e03, - 0x008001303, + 0x0080012ea, 0x02468ffd0, 0x020030030, 0x014a30006, @@ -3879,7 +3854,7 @@ ulong bootcode[]={ 0x02003fc18, 0x010e30003, 0x000000027, - 0x008001302, + 0x0080012e9, 0x000000027, 0x02002002a, 0x014a20009, @@ -3888,9 +3863,9 @@ ulong bootcode[]={ 0x02002fc18, 0x014e20003, 0x025290004, - 0x0080012e7, + 0x0080012ce, 0x000053825, - 0x0080012e7, + 0x0080012ce, 0x000055825, 0x030a5007f, 0x0afa90044, @@ -3923,9 +3898,9 @@ ulong bootcode[]={ 0x000000027, 0x08fa40028, 0x000011023, - 0x0080012e7, + 0x0080012ce, 0x000825025, - 0x0080012ae, + 0x008001295, 0x001214821, 0x023bdfff0, 0x0afbf0000, @@ -3943,13 +3918,13 @@ ulong bootcode[]={ 0x0afa30004, 0x0afa40008, 0x08fa3001c, - 0x00c00144b, + 0x00c001432, 0x0afa3000c, 0x08fa20000, 0x000000027, 0x000400008, 0x023bd0010, - 0x008001363, + 0x00800134a, 0x000042023, 0x023bdffa8, 0x0afbf0000, @@ -4042,7 +4017,7 @@ ulong bootcode[]={ 0x02002fc18, 0x0afa30008, 0x0afa2000c, - 0x00c001358, + 0x00c00133f, 0x0afa70010, 0x08fa10028, 0x08fa20000, @@ -4061,12 +4036,12 @@ ulong bootcode[]={ 0x024a5ffff, 0x001651021, 0x020040030, - 0x0080013bf, + 0x0080013a6, 0x0a0440000, 0x024a5ffff, 0x001651021, 0x020040078, - 0x0080013db, + 0x0080013c2, 0x0a0440000, 0x030e30040, 0x01060001e, @@ -4088,27 +4063,27 @@ ulong bootcode[]={ 0x000000027, 0x01d000003, 0x000000027, - 0x0080013b0, + 0x008001397, 0x000000027, 0x01d400003, 0x000000027, - 0x0080013b0, + 0x008001397, 0x000000027, 0x030e20040, 0x01440ffa0, 0x024a5ffff, 0x00149001b, - 0x0080013a5, + 0x00800138c, 0x000003010, 0x00149001b, - 0x0080013ec, + 0x0080013d3, 0x000005012, 0x0200d0001, - 0x00800139d, + 0x008001384, 0x0000a5023, 0x08caa0000, 0x020030004, - 0x008001398, + 0x00800137f, 0x0afa30028, 0x08ca20000, 0x000000027, @@ -4120,15 +4095,15 @@ ulong bootcode[]={ 0x000031c03, 0x020020004, 0x0afa20028, - 0x008001398, + 0x00800137f, 0x000035025, 0x08caa0000, 0x020030004, - 0x008001398, + 0x00800137f, 0x0afa30028, 0x08caa0000, 0x020030004, - 0x008001398, + 0x00800137f, 0x0afa30028, 0x020030030, 0x01043000a, @@ -4136,11 +4111,11 @@ ulong bootcode[]={ 0x020030048, 0x010430003, 0x000000027, - 0x008001395, + 0x00800137c, 0x000000027, 0x08ca80000, 0x020030004, - 0x008001398, + 0x00800137f, 0x0afa30028, 0x08ca30000, 0x000000027, @@ -4150,14 +4125,14 @@ ulong bootcode[]={ 0x03042ffff, 0x020030004, 0x0afa30028, - 0x008001398, + 0x00800137f, 0x000025025, - 0x008001385, + 0x00800136c, 0x02009000a, 0x0200e0001, - 0x008001385, + 0x00800136c, 0x020090010, - 0x008001385, + 0x00800136c, 0x020090008, 0x020030075, 0x011230006, @@ -4165,15 +4140,15 @@ ulong bootcode[]={ 0x020030078, 0x01123fff7, 0x000000027, - 0x008001385, + 0x00800136c, 0x000000027, 0x02009000a, - 0x008001385, + 0x00800136c, 0x034e70020, 0x023bdfff0, 0x0afbf0000, 0x08fa30014, - 0x00c000a43, + 0x00c000a3b, 0x0afa30004, 0x08fac0014, 0x08faa0018, @@ -4198,7 +4173,7 @@ ulong bootcode[]={ 0x000000027, 0x01ce00003, 0x000000027, - 0x00800145b, + 0x008001442, 0x000000027, 0x000c9202b, 0x010800005, @@ -4216,7 +4191,7 @@ ulong bootcode[]={ 0x02003fc18, 0x010e3ffe3, 0x000000027, - 0x00800145b, + 0x008001442, 0x024e7ffff, 0x020020009, 0x01562fff9, @@ -4227,7 +4202,7 @@ ulong bootcode[]={ 0x02003fc18, 0x010e3ffd8, 0x0afc880de, - 0x00800145b, + 0x008001442, 0x024e7ffff, 0x02002fc18, 0x011420003, @@ -4252,7 +4227,7 @@ ulong bootcode[]={ 0x0a0640000, 0x025080001, 0x024a50001, - 0x008001490, + 0x008001477, 0x0afc880de, 0x000aa202a, 0x01080ffba, @@ -4267,7 +4242,7 @@ ulong bootcode[]={ 0x0a0440000, 0x025080001, 0x024a50001, - 0x00800149f, + 0x008001486, 0x0afc880de, 0x023bdffec, 0x0afbf0000, @@ -4282,7 +4257,7 @@ ulong bootcode[]={ 0x0afa30004, 0x0afa00008, 0x02002fc18, - 0x00c00144b, + 0x00c001432, 0x0afa2000c, 0x08fa20000, 0x023bd0014, @@ -4300,7 +4275,7 @@ ulong bootcode[]={ 0x08fa3001c, 0x02002fc18, 0x0afa30008, - 0x00c00144b, + 0x00c001432, 0x0afa2000c, 0x08fa20000, 0x023bd0014, @@ -4320,13 +4295,12 @@ ulong bootcode[]={ 0x000000027, 0x0afa3000c, 0x08fa20024, - 0x00c001358, + 0x00c00133f, 0x0afa20010, 0x08fa20000, 0x023bd0014, 0x000400008, 0x020010004, - 0x023bdfffc, 0x08fc5805e, 0x08fc280da, 0x000000027, @@ -4337,62 +4311,51 @@ ulong bootcode[]={ 0x0afc2805e, 0x020040025, 0x0a0a40000, - 0x023bd0004, 0x003e00008, 0x000000825, - 0x023bdfffc, - 0x08fa30018, + 0x08fa30014, 0x020020068, 0x00043202a, - 0x01480001b, + 0x014800016, 0x000000027, - 0x010620016, + 0x010620012, 0x000000027, 0x020020023, - 0x010620010, + 0x01062000d, 0x000000027, 0x02002002b, - 0x01062000a, + 0x010620008, 0x000000027, 0x02002002d, - 0x010620004, + 0x010620003, 0x000000027, - 0x023bd0004, 0x003e00008, 0x000000825, - 0x023bd0004, 0x003e00008, 0x02001fffe, - 0x023bd0004, 0x003e00008, 0x02001ffff, - 0x023bd0004, 0x003e00008, 0x02001fffc, - 0x023bd0004, 0x003e00008, 0x02001fff0, 0x02002006c, - 0x01062000a, + 0x010620008, 0x000000027, 0x020020075, - 0x010620004, + 0x010620003, 0x000000027, - 0x023bd0004, 0x003e00008, 0x000000825, - 0x023bd0004, 0x003e00008, 0x02001ffe0, - 0x08fa20014, + 0x08fa20010, 0x000000027, 0x030420008, - 0x010400004, + 0x010400003, 0x000000027, - 0x023bd0004, 0x003e00008, 0x02001ffc0, - 0x023bd0004, 0x003e00008, 0x02001fff8, 0x023bdff60, @@ -4406,7 +4369,7 @@ ulong bootcode[]={ 0x0e7a6004c, 0x0e7a70004, 0x0e7a60008, - 0x00c00193d, + 0x00c001911, 0x000000027, 0x01020000e, 0x000000027, @@ -4417,7 +4380,7 @@ ulong bootcode[]={ 0x0afa30008, 0x0afa2000c, 0x08fa300b0, - 0x00c001358, + 0x00c00133f, 0x0afa30010, 0x08fa20000, 0x023bd00a0, @@ -4428,7 +4391,7 @@ ulong bootcode[]={ 0x020030001, 0x0e7a10004, 0x0e7a00008, - 0x00c00196d, + 0x00c001941, 0x0afa3000c, 0x01020000e, 0x000000027, @@ -4439,7 +4402,7 @@ ulong bootcode[]={ 0x0afa30008, 0x0afa2000c, 0x08fa300b0, - 0x00c001358, + 0x00c00133f, 0x0afa30010, 0x08fa20000, 0x023bd00a0, @@ -4450,7 +4413,7 @@ ulong bootcode[]={ 0x02003ffff, 0x0e7a10004, 0x0e7a00008, - 0x00c00196d, + 0x00c001941, 0x0afa3000c, 0x08fad00b4, 0x08fac00ac, @@ -4464,7 +4427,7 @@ ulong bootcode[]={ 0x0afa30008, 0x0afa2000c, 0x08fa300b0, - 0x00c001358, + 0x00c00133f, 0x0afa30010, 0x08fa20000, 0x023bd00a0, @@ -4508,7 +4471,7 @@ ulong bootcode[]={ 0x023a20034, 0x0e7a10004, 0x0e7a00008, - 0x00c00183e, + 0x00c001813, 0x0afa2000c, 0x08fa20034, 0x04444f800, @@ -4532,7 +4495,7 @@ ulong bootcode[]={ 0x000023043, 0x0afa60030, 0x000061023, - 0x00c0017e3, + 0x00c0017be, 0x0afa20004, 0x0c7a30048, 0x0c7a2004c, @@ -4544,7 +4507,7 @@ ulong bootcode[]={ 0x08fa30034, 0x000000027, 0x000431023, - 0x00c0017e3, + 0x00c0017be, 0x0afa20004, 0x08fad00b4, 0x023ae0078, @@ -4567,7 +4530,7 @@ ulong bootcode[]={ 0x08fa30034, 0x000000027, 0x000431023, - 0x00c0017e3, + 0x00c0017be, 0x0afa20004, 0x08fad00b4, 0x08fac00ac, @@ -4576,7 +4539,7 @@ ulong bootcode[]={ 0x0c7a2003c, 0x000000027, 0x046201182, - 0x0080015cc, + 0x0080015a7, 0x023ae0078, 0x0c7c180e2, 0x0c7c080e6, @@ -4593,7 +4556,7 @@ ulong bootcode[]={ 0x08fa30034, 0x000000027, 0x000431023, - 0x00c0017e3, + 0x00c0017be, 0x0afa20004, 0x08fad00b4, 0x08fac00ac, @@ -4602,7 +4565,7 @@ ulong bootcode[]={ 0x0c7a2003c, 0x000000027, 0x046201182, - 0x0080015e3, + 0x0080015be, 0x023ae0078, 0x02003fc18, 0x015830002, @@ -4637,7 +4600,7 @@ ulong bootcode[]={ 0x0200cffff, 0x0afac00ac, 0x0200d0065, - 0x008001590, + 0x00800156b, 0x0afad00b4, 0x0c7a70048, 0x0c7a6004c, @@ -4651,7 +4614,7 @@ ulong bootcode[]={ 0x08fa30034, 0x02002ffff, 0x000431023, - 0x00c0017e3, + 0x00c0017be, 0x0afa20004, 0x08fad00b4, 0x023ae0078, @@ -4673,7 +4636,7 @@ ulong bootcode[]={ 0x000671823, 0x004600134, 0x0afa7002c, - 0x00c0017e3, + 0x00c0017be, 0x0afa30004, 0x0c7a30040, 0x0c7a20044, @@ -4682,7 +4645,7 @@ ulong bootcode[]={ 0x046201083, 0x0e7a30004, 0x0e7a20008, - 0x00c0017a1, + 0x00c00177c, 0x000000027, 0x08fad00b4, 0x023ae0078, @@ -4740,7 +4703,7 @@ ulong bootcode[]={ 0x024e70001, 0x02484fff6, 0x0a0440001, - 0x008001673, + 0x00800164e, 0x024c6ffff, 0x010e00007, 0x0200b0001, @@ -4808,7 +4771,7 @@ ulong bootcode[]={ 0x020030030, 0x0a0430000, 0x024e7ffff, - 0x0080016ba, + 0x008001695, 0x024c60001, 0x019000013, 0x000000027, @@ -4828,7 +4791,7 @@ ulong bootcode[]={ 0x0256b0001, 0x0a0430000, 0x02508ffff, - 0x0080016cb, + 0x0080016a6, 0x024c60001, 0x08fa300b0, 0x000000027, @@ -4857,7 +4820,7 @@ ulong bootcode[]={ 0x0afa30008, 0x0afa2000c, 0x08fa300b0, - 0x00c001358, + 0x00c00133f, 0x0afa30010, 0x08fa20000, 0x023bd00a0, @@ -4913,19 +4876,19 @@ ulong bootcode[]={ 0x000001810, 0x024630030, 0x0a0430000, - 0x0080016f2, + 0x0080016cd, 0x024c60001, 0x000061825, 0x001231021, 0x02003002b, 0x0a0430000, - 0x008001713, + 0x0080016ee, 0x024c60001, 0x000061025, 0x001221821, 0x020020065, 0x0a0620000, - 0x008001709, + 0x0080016e4, 0x024c60001, 0x020030067, 0x011a30006, @@ -4933,7 +4896,7 @@ ulong bootcode[]={ 0x020030068, 0x011a30003, 0x000000027, - 0x0080016ec, + 0x0080016c7, 0x000000027, 0x024c7ffff, 0x004e00006, @@ -4953,11 +4916,11 @@ ulong bootcode[]={ 0x000000027, 0x01107ff93, 0x000073025, - 0x0080016ec, + 0x0080016c7, 0x024c60001, - 0x008001751, + 0x00800172c, 0x02508ffff, - 0x008001749, + 0x008001724, 0x024e7ffff, 0x08fa30034, 0x02002ffff, @@ -4967,7 +4930,7 @@ ulong bootcode[]={ 0x000003825, 0x08fa30034, 0x0200d0068, - 0x0080016a7, + 0x008001682, 0x001835023, 0x08fa200b0, 0x000000027, @@ -4978,7 +4941,7 @@ ulong bootcode[]={ 0x001221821, 0x02002002b, 0x0a0620000, - 0x008001698, + 0x008001673, 0x024c60001, 0x0c7c180e2, 0x0c7c080e6, @@ -4988,7 +4951,7 @@ ulong bootcode[]={ 0x0e7a60044, 0x0e7a70004, 0x0e7a60008, - 0x00c0017a1, + 0x00c00177c, 0x000000027, 0x08fad00b4, 0x023ae0078, @@ -5015,14 +4978,14 @@ ulong bootcode[]={ 0x046222181, 0x0e7a70040, 0x0e7a60044, - 0x00800166a, + 0x008001645, 0x000000027, - 0x008001606, + 0x0080015e1, 0x0258cffff, 0x020020001, 0x0afa20014, 0x025ad0020, - 0x008001590, + 0x00800156b, 0x0afad00b4, 0x023bdffe8, 0x0afbf0000, @@ -5039,7 +5002,7 @@ ulong bootcode[]={ 0x04624c081, 0x0e7a30004, 0x0e7a20008, - 0x00c00188c, + 0x00c001861, 0x0afa2000c, 0x04620c032, 0x000000027, @@ -5068,7 +5031,7 @@ ulong bootcode[]={ 0x023a2001c, 0x0e7a30004, 0x0e7a20008, - 0x00c00188c, + 0x00c001861, 0x0afa2000c, 0x0c7a1001c, 0x0c7a00020, @@ -5084,7 +5047,7 @@ ulong bootcode[]={ 0x04624c081, 0x0e7a30004, 0x0e7a20008, - 0x00c0017a1, + 0x00c00177c, 0x000000027, 0x08fa20000, 0x023bd000c, @@ -5097,7 +5060,7 @@ ulong bootcode[]={ 0x004810008, 0x000000027, 0x000041023, - 0x00c0017e3, + 0x00c0017be, 0x0afa20004, 0x08fa20000, 0x023bd0014, @@ -5118,12 +5081,12 @@ ulong bootcode[]={ 0x000042843, 0x0afa50010, 0x000851823, - 0x00c0017e3, + 0x00c0017be, 0x0afa30004, 0x0e7a10008, 0x0e7a0000c, 0x08fa20010, - 0x00c0017e3, + 0x00c0017be, 0x0afa20004, 0x0c7a30008, 0x0c7a2000c, @@ -5131,9 +5094,8 @@ ulong bootcode[]={ 0x023bd0014, 0x000400008, 0x046220002, - 0x023bdfffc, - 0x083a4000f, - 0x08fa30008, + 0x083a4000b, + 0x08fa30004, 0x01080000a, 0x000000027, 0x080610000, @@ -5144,15 +5106,14 @@ ulong bootcode[]={ 0x000000027, 0x02461ffff, 0x003e00008, - 0x023bd0004, + 0x000000027, 0x030610003, - 0x010200008, + 0x010200007, 0x000000027, 0x080610000, 0x000000027, 0x01420fffa, 0x024630001, - 0x023bd0004, 0x003e00008, 0x02461ffff, 0x03c06ff00, @@ -5161,24 +5122,20 @@ ulong bootcode[]={ 0x000000027, 0x000a60824, 0x000a71024, - 0x010200010, + 0x01020000d, 0x024630004, - 0x01040000b, + 0x010400009, 0x030a1ff00, - 0x010200006, + 0x010200005, 0x030a200ff, 0x01440fff5, 0x000000027, - 0x023bd0004, 0x003e00008, 0x02461ffff, - 0x023bd0004, 0x003e00008, 0x02461fffe, - 0x023bd0004, 0x003e00008, 0x02461fffd, - 0x023bd0004, 0x003e00008, 0x02461fffc, 0x023bdfff4, @@ -5314,12 +5271,11 @@ ulong bootcode[]={ 0x08fa4000c, 0x000000027, 0x000821024, - 0x0080018ad, + 0x008001882, 0x0afa2000c, - 0x023bdfffc, - 0x08fa30010, - 0x08fa40008, - 0x08fa5000c, + 0x08fa3000c, + 0x08fa40004, + 0x08fa50008, 0x000833021, 0x028620004, 0x000a4082b, @@ -5375,9 +5331,9 @@ ulong bootcode[]={ 0x0a0880000, 0x014e5fffc, 0x024840001, - 0x08fa10008, + 0x08fa10004, 0x003e00008, - 0x023bd0004, + 0x000000027, 0x014400028, 0x000000027, 0x000e60826, @@ -5425,7 +5381,7 @@ ulong bootcode[]={ 0x000000027, 0x0a0c8ffff, 0x024c6ffff, - 0x00800192c, + 0x008001900, 0x024e7ffff, 0x023bdfff4, 0x03c027ff0, @@ -5455,7 +5411,7 @@ ulong bootcode[]={ 0x000000825, 0x0e7a50004, 0x0e7a40008, - 0x00c00196d, + 0x00c001941, 0x0afa0000c, 0x014200005, 0x000000027, @@ -5638,13 +5594,13 @@ ulong bootcode[]={ 0x000010000, 0x002000000, 0x000000000, - 0x0000052b8, - 0x0000053d4, - 0x000004dc0, - 0x0000054b0, - 0x000005304, - 0x00000534c, - 0x00000539c, + 0x000005254, + 0x000005368, + 0x000004d5c, + 0x00000541c, + 0x0000052a0, + 0x0000052e8, + 0x000005338, 0x000000000, 0x000000000, 0x000000000, @@ -6025,6 +5981,6 @@ ulong bootcode[]={ 0x020726562, 0x06f6f7400, 0x000000000, - 0x00005e28, + 0x00005d78, 0x0, }; diff --git a/power/conf.h b/power/conf.h index 9877b5ce3e3f1451fe980329e1378ec6a4cdcace..278d4ba91a25b89234330cfe4703776dfa23a48c 100644 --- a/power/conf.h +++ b/power/conf.h @@ -4,9 +4,10 @@ Conftab conftab[] = { {"npgrp", &conf.npgrp }, {"npage0", &conf.npage0 }, {"npage", &conf.npage }, - {"norig", &conf.norig }, - {"npte", &conf.npte }, - {"nmod", &conf.nmod }, + {"nseg", &conf.nseg }, + {"nimage", &conf.nimage }, + {"npagetab", &conf.npagetab }, + {"nswap", &conf.nswap }, {"nalarm", &conf.nalarm }, {"nchan", &conf.nchan }, {"nenv", &conf.nenv }, diff --git a/power/dat.h b/power/dat.h index ca9575bc0269a3c6a72e97d328818e3d16169f4a..40d11c1f0cb6018f856aa9ec215a6e0118f5d791 100644 --- a/power/dat.h +++ b/power/dat.h @@ -41,9 +41,10 @@ struct Conf 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 */ - ulong nmod; /* single (modifying) page table entries */ + ulong nseg; /* number of segments */ + ulong nimage; /* number of page cache image headers */ + ulong npagetab; /* number of pte tables */ + ulong nswap; /* number of swap pages */ ulong nalarm; /* alarms */ ulong nchan; /* channels */ ulong nenv; /* distinct environment values */ @@ -133,6 +134,7 @@ struct Mach char pidhere[NTLBPID]; /* is this pid possibly in this mmu? */ int lastpid; /* last pid allocated on this machine */ Proc *pidproc[NTLBPID]; /* process that owns this tlbpid on this mach */ + Page *ufreeme; /* address of upage of exited process */ int tlbfault; int tlbpurge; @@ -159,7 +161,7 @@ struct Softtlb */ typedef void KMap; #define VA(k) ((ulong)(k)) -#define kmap(p) (KMap*)(p->pa|KZERO) +#define kmap(p) (KMap*)((p)->pa|KZERO) #define kunmap(k) #define PPN(x) x @@ -205,7 +207,6 @@ struct #define NERR 15 #define NNOTE 5 -#define NFD 100 struct User { Proc *p; @@ -216,8 +217,6 @@ struct User char elem[NAMELEN]; /* last name element from namec */ Chan *slash; Chan *dot; - Chan *fd[NFD]; - int maxfd; /* highest fd in use */ /* * Rest of structure controlled by devproc.c and friends. * lock(&p->debug) to modify. diff --git a/power/faultmips.c b/power/faultmips.c index a86a63ca34e92ac2026d008dbfbe9d8bd292b379..0cfff651db87828faf37496804ca5ade8040d5ce 100644 --- a/power/faultmips.c +++ b/power/faultmips.c @@ -15,6 +15,7 @@ faultmips(Ureg *ur, int user, int code) { ulong addr; extern char *excname[]; + char buf[ERRLEN]; int read; addr = ur->badvaddr; @@ -22,9 +23,11 @@ faultmips(Ureg *ur, int user, int code) read = !(code==CTLBM || code==CTLBS); if(fault(addr, read) < 0){ if(user){ - pprint("user %s badvaddr=0x%lux\n", excname[code], ur->badvaddr); - pprint("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->status, ur->pc, ur->sp); - pexit("Suicide", 0); + sprint(buf, "sys: fault %s pc=0x%lux addr=0x%lux", + read? "read" : "write", ur->pc, ur->badvaddr); + postnote(u->p, 1, buf, NDebug); + notify(ur); + return; } print("kernel %s badvaddr=0x%lux\n", excname[code], ur->badvaddr); print("status=0x%lux pc=0x%lux sp=0x%lux\n", ur->status, ur->pc, ur->sp); diff --git a/power/fns.h b/power/fns.h index 5ce367a15d056663a26745aacafed0cf3ce83b00..fe510987b8d97bdb258ee5e56bcc0c3f9d66074b 100644 --- a/power/fns.h +++ b/power/fns.h @@ -7,24 +7,29 @@ ulong confeval(char*); void confread(void); void confprint(void); void confset(char*); -void duartspecial(int, IOQ*, IOQ*, int); +int conschar(void); +void dcflush(void*, ulong); int duartactive(void); void duartenable0(void); void duartinit(void); void duartintr(void); +void duartreset(void); void duartslave(void); +void duartspecial(int, IOQ*, IOQ*, int); +void duartxmit(int); void evenaddr(ulong); void faultmips(Ureg*, int, int); ulong fcr31(void); void flushmmu(void); -#define flushpage(x) +#define flushpage(s) icflush((void*)(s), BY2PG) #define flushvirt() void gettlb(int, ulong*); ulong gettlbvirt(int); void gotopc(ulong); -void icflush(void *, int); +void icflush(void *, ulong); void ioboardinit(void); void intr(Ureg*); +void kbdchar(int); void lanceintr(void); void lanceparity(void); void lancesetup(Lance*); @@ -36,6 +41,7 @@ void novme(int); void online(void); Block* prepend(Block*, int); void prflush(void); +void printslave(void); #define procsetup(p) ((p)->fpstate = FPinit) #define procsave(x,y) #define procrestore(x,y) @@ -51,6 +57,8 @@ void setvmevec(int, void (*)(int)); void sinit(void); uchar* smap(int, uchar*); void sunmap(int, uchar*); +void sysloginit(void); +void syslog(char*, int); void tlbinit(void); Block* tolance(Block*, int); void touser(void*); diff --git a/power/l.s b/power/l.s index b761d443f2b384888a094388866bb4270be45b53..3a993d482425739738e27a4931355c25a2a8a254 100644 --- a/power/l.s +++ b/power/l.s @@ -148,14 +148,14 @@ TEXT gotolabel(SB), $-4 TEXT gotopc(SB), $8 + MOVW $(64*1024), R1 + MOVW R1, 8(SP) + JAL icflush(SB) MOVW 0(FP), R7 /* save arguments for later */ MOVW _argc(SB), R4 MOVW _argv(SB), R5 MOVW _env(SB), R6 MOVW R0, 4(SP) - MOVW $(64*1024), R1 - MOVW R1, 8(SP) - JAL icflush(SB) JMP (R7) TEXT puttlb(SB), $4 @@ -515,99 +515,212 @@ TEXT fcr31(SB), $0 MOVW FCR31, R1 RET -/* - * we avoid using R4, R5, R6, and R7 so gotopc can call us without saving them - */ -TEXT icflush(SB), $-4 /* icflush(physaddr, nbytes) */ - - MOVW M(STATUS), R10 - MOVW 0(FP), R8 - MOVW 4(FP), R9 - MOVW $KSEG0, R3 - OR R3, R8 - MOVW $0, M(STATUS) - MOVW $WBFLUSH, R1 /* wbflush */ - MOVW 0(R1), R1 - NOOP - MOVW $KSEG1, R3 - MOVW $icflush0(SB), R2 /* make sure PC is in uncached address space */ - MOVW $(SWC|ISC), R1 - OR R3, R2 +#define NOP WORD $0x0 + +TEXT icflush(SB), $-4 + MOVW 0(FP), R4 + MOVW 4(FP), R5 + MOVW $icflush0(SB), R2 /* Jump to uncache space */ + MOVW $0xA0000000, R1 + OR R1, R2 JMP (R2) + NOP TEXT icflush0(SB), $-4 - MOVW R1, M(STATUS) /* swap and isolate cache, splhi */ + MOVW $833, R12 /* cache_pass magic */ + MOVW $0x10000, R9 /* icache size */ + + MOVW $0, R13 + MOVW M(STATUS), R11 + + BEQ R9, R0, _icflush3 + MOVW $0x30000, R2 /* swap and isolate */ + + NOP + NOP + NOP + NOP + NOP + MOVW R2, M(STATUS) + NOP + NOP + NOP + NOP + NOP + + MOVW R4, R8 + MOVW R5, R9 + AND $0xFFFC, R8 + MOVW $0x9F200000, R1 + OR R1, R8 + MOVW $icflush1(SB), R2 JMP (R2) + NOP TEXT icflush1(SB), $-4 - _icflush1: - MOVBU R0, 0x00(R8) - MOVBU R0, 0x04(R8) - MOVBU R0, 0x08(R8) - MOVBU R0, 0x0C(R8) - MOVBU R0, 0x10(R8) - MOVBU R0, 0x14(R8) - MOVBU R0, 0x18(R8) - MOVBU R0, 0x1C(R8) - MOVBU R0, 0x20(R8) - MOVBU R0, 0x24(R8) - MOVBU R0, 0x28(R8) - MOVBU R0, 0x2C(R8) - MOVBU R0, 0x30(R8) - MOVBU R0, 0x34(R8) - MOVBU R0, 0x38(R8) - MOVBU R0, 0x3C(R8) - SUB $0x40, R9 - ADD $0x40, R8 + SGT R12, R13, R1 + BNE R1, _icflush2 + + MOVW $0, R13 + MOVW R11, M(STATUS) + MOVW $0x30000, R2 /* swap and isolate */ + + NOP + NOP + NOP + NOP + NOP + MOVW R2, M(STATUS) + NOP + NOP + NOP + NOP + NOP + +_icflush2: + MOVW R0, 0(R8) + MOVW R0, 4(R8) + MOVW R0, 8(R8) + MOVW R0, 12(R8) + MOVW R0, 16(R8) + MOVW R0, 20(R8) + MOVW R0, 24(R8) + MOVW R0, 28(R8) + ADDU $-32, R9 + ADDU $1, R13 + ADDU $32, R8 BGTZ R9, _icflush1 - MOVW $icflush2(SB), R2 /* make sure PC is in uncached address space */ - OR R3, R2 - JMP (R2) -TEXT icflush2(SB), $-4 + MOVW $icflush3(SB), R2 /* Jump to uncache space */ + MOVW $0xA0000000, R1 + OR R1, R2 + JMP (R2) + NOP + +TEXT icflush3(SB), $-4 +_icflush3: + NOP + NOP + NOP + NOP + NOP + MOVW R11, M(STATUS) + NOP + NOP + NOP + NOP + NOP + + MOVW $icflush4(SB), R2 + JMP (R2) + NOP - MOVW $0, M(STATUS) /* swap back caches, de-isolate them, and stay splhi */ - NOOP /* +++ */ - MOVW R10, M(STATUS) +TEXT icflush4(SB), $-4 RET -TEXT dcflush(SB), $-4 /* dcflush(physaddr, nbytes) */ - - MOVW M(STATUS), R6 +TEXT dcflush(SB), $-4 MOVW 0(FP), R4 MOVW 4(FP), R5 - MOVW $KSEG0, R3 - OR R3, R4 - MOVW $0, M(STATUS) - MOVW $WBFLUSH, R1 - MOVW 0(R1), R1 - NOOP - MOVW $ISC, R1 - MOVW R1, M(STATUS) -_dcflush0: - MOVBU R0, 0x00(R4) - MOVBU R0, 0x04(R4) - MOVBU R0, 0x08(R4) - MOVBU R0, 0x0C(R4) - MOVBU R0, 0x10(R4) - MOVBU R0, 0x14(R4) - MOVBU R0, 0x18(R4) - MOVBU R0, 0x1C(R4) - MOVBU R0, 0x20(R4) - MOVBU R0, 0x24(R4) - MOVBU R0, 0x28(R4) - MOVBU R0, 0x2C(R4) - MOVBU R0, 0x30(R4) - MOVBU R0, 0x34(R4) - MOVBU R0, 0x38(R4) - MOVBU R0, 0x3C(R4) - SUB $0x40, R5 - ADD $0x40, R4 - BGTZ R5, _dcflush0 - MOVW $0, M(STATUS) - NOOP /* +++ */ - MOVW R6, M(STATUS) + MOVW $dcflush0(SB), R2 /* Jump to uncache space */ + MOVW $0xA0000000, R1 + OR R1, R2 + JMP (R2) + NOP + +TEXT dcflush0(SB), $-4 + + MOVW $833, R12 /* cache_pass magdc */ + MOVW $0x10000, R9 /* dcache size */ + + MOVW $0, R13 + MOVW M(STATUS), R11 + + BEQ R9, R0, _dcflush3 + MOVW $0x10000, R2 /* isolate data cache */ + + NOP + NOP + NOP + NOP + NOP + MOVW R2, M(STATUS) + NOP + NOP + NOP + NOP + NOP + + MOVW R4, R8 + MOVW R5, R9 + AND $0xFFFC, R8 + MOVW $0x9F200000, R1 + OR R1, R8 + + MOVW $dcflush1(SB), R2 + JMP (R2) + NOP + +TEXT dcflush1(SB), $-4 +_dcflush1: + SGT R12, R13, R1 + BNE R1, _dcflush2 + + MOVW $0, R13 + MOVW R11, M(STATUS) + MOVW $0x10000, R2 /* isolate data cache */ + + NOP + NOP + NOP + NOP + NOP + MOVW R2, M(STATUS) + NOP + NOP + NOP + NOP + NOP + +_dcflush2: + MOVW R0, 0(R8) + MOVW R0, 4(R8) + MOVW R0, 8(R8) + MOVW R0, 12(R8) + MOVW R0, 16(R8) + MOVW R0, 20(R8) + MOVW R0, 24(R8) + MOVW R0, 28(R8) + ADDU $-32, R9 + ADDU $1, R13 + ADDU $32, R8 + BGTZ R9, _dcflush1 + + MOVW $dcflush3(SB), R2 /* Jump to uncache space */ + MOVW $0xA0000000, R1 + OR R1, R2 + JMP (R2) + NOP + +TEXT dcflush3(SB), $-4 +_dcflush3: + NOP + NOP + NOP + NOP + NOP + MOVW R11, M(STATUS) + NOP + NOP + NOP + NOP + NOP + + MOVW $dcflush4(SB), R2 + JMP (R2) + NOP + +TEXT dcflush4(SB), $-4 RET diff --git a/power/lock.c b/power/lock.c index 5ba14936a6079ec0a64f7d94377c1561254d8e2a..56121e54369008cac80f0db52037e2ad1a7a197a 100644 --- a/power/lock.c +++ b/power/lock.c @@ -59,7 +59,7 @@ lkpgalloc(void) /* Moral equivalent of newpage for pages of hardware lock */ Page* -lkpage(Orig *o, ulong va) +lkpage(ulong va) { uchar *p, *top; Page *pg; @@ -82,7 +82,6 @@ lkpage(Orig *o, ulong va) pg = &lkpgheader[i]; pg->pa = (ulong)((i*WD2PG) + SBSEM) & ~UNCACHED; pg->va = va; - pg->o = o; pg->ref = 1; unlock(&semalloc.lock); @@ -90,7 +89,7 @@ lkpage(Orig *o, ulong va) } void -lkpgfree(Page *pg, int dolock) +lkpgfree(Page *pg) { uchar *p; @@ -135,15 +134,11 @@ lock(Lock *ll) */ if((*sbsem&1) == 0){ l->pc = ((ulong*)&ll)[PCOFF]; - if(u && u->p) - u->p->hasspin = 1; return; } for(i=0; i<10000000; i++) if((*sbsem&1) == 0){ l->pc = ((ulong*)&ll)[PCOFF]; - if(u && u->p) - u->p->hasspin = 1; return; } *sbsem = 0; @@ -172,8 +167,6 @@ canlock(Lock *l) } if(*sbsem & 1) return 0; - if(u && u->p) - u->p->hasspin = 1; return 1; } @@ -182,22 +175,4 @@ unlock(Lock *l) { l->pc = 0; *l->sbsem = 0; - if(u && u->p) - u->p->hasspin = 0; -} - -void -mklockseg(Seg *s) -{ - Orig *o; - - s->proc = u->p; - o = neworig(LKSEGBASE, 0, OWRPERM|OSHARED, 0); - o->minca = 0; - o->maxca = 0; - o->freepg = lkpgfree; - s->o = o; - s->minva = LKSEGBASE; - s->maxva = LKSEGBASE; - s->mod = 0; } diff --git a/power/main.c b/power/main.c index 879ea32b8080f0d954ff8d29cfb499d32d7fdaca..92cb5fcddc8099c860ed61400e131aaa5bb74e04 100644 --- a/power/main.c +++ b/power/main.c @@ -61,13 +61,15 @@ main(void) tlbinit(); vecinit(); procinit0(); - pgrpinit(); + initseg(); + grpinit(); chaninit(); clockinit(); alarminit(); ioboardinit(); chandevreset(); streaminit(); + swapinit(); pageinit(); userinit(); launchinit(); @@ -228,6 +230,7 @@ init0(void) sp = (ulong*)(USTKTOP - argsize); + kickpager(); touser(sp); } @@ -237,14 +240,18 @@ void userinit(void) { Proc *p; - Seg *s; + Segment *s; User *up; KMap *k; int i; char **av; + Page *pg; p = newproc(); p->pgrp = newpgrp(); + p->egrp = newegrp(); + p->fgrp = newfgrp(); + strcpy(p->text, "*init*"); strcpy(p->pgrp->user, "bootes"); savefpregs(&initfp); @@ -269,35 +276,27 @@ userinit(void) /* * User Stack, pass input arguments to boot process */ - s = &p->seg[SSEG]; - s->proc = p; - s->o = neworig(USTKTOP-BY2PG, 1, OWRPERM|OISMEM, 0); - s->o->pte[0].page = newpage(0, 0, USTKTOP-BY2PG); - memmove((ulong*)(s->o->pte[0].page->pa|KZERO|(BY2PG-argsize)), + s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG); + p->seg[SSEG] = s; + pg = newpage(1, 0, USTKTOP-BY2PG); + segpage(s, pg); + + memmove((ulong*)(pg->pa|KZERO|(BY2PG-argsize)), argbuf + sizeof(argbuf) - argsize, argsize); - av = (char **)(s->o->pte[0].page->pa|KZERO|(BY2PG-argsize)); + + av = (char **)(pg->pa|KZERO|(BY2PG-argsize)); for(i = 0; i < _argc; i++) av[i] += (char *)USTKTOP - (argbuf + sizeof(argbuf)); - s->minva = USTKTOP-BY2PG; - s->maxva = USTKTOP; /* * Text */ - s = &p->seg[TSEG]; - s->proc = p; - /* - * On the mips, init text must be OCACHED to avoid reusing page - * and getting in trouble with the hardware instruction cache. - */ - s->o = neworig(UTZERO, 1, OCACHED|OISMEM, 0); - s->o->pte[0].page = newpage(0, 0, UTZERO); - s->o->npage = 1; - k = kmap(s->o->pte[0].page); + s = newseg(SG_TEXT, UTZERO, 1); + p->seg[TSEG] = s; + segpage(s, newpage(1, 0, UTZERO)); + k = kmap(s->map[0]->pages[0]); memmove((ulong*)VA(k), initcode, sizeof initcode); kunmap(k); - s->minva = 0x1000; - s->maxva = 0x2000; ready(p); } @@ -372,13 +371,13 @@ exit(void) unlock(&active); spllo(); print("cpu %d exiting\n", m->machno); - while(active.machs || duartactive()) + while(active.machs || consactive()) for(i=0; i<1000; i++) ; splhi(); for(i=0; i<2000000; i++) ; - duartenable0(); + duartreset(); firmware(); } @@ -625,14 +624,15 @@ confinit(void) conf.nenv = 4 * conf.nproc; conf.nenvchar = 20 * conf.nenv; conf.nmtab = conf.nproc; - conf.norig = 4 * conf.nproc; - conf.nmod = 10 * conf.norig; + conf.nseg = 4 * conf.nproc; + conf.npagetab = conf.nseg*3; + conf.nswap = 20000; + conf.nimage = 200; conf.nchan = 20 * conf.nproc; conf.nmntdev = conf.nproc; conf.nmntbuf = conf.nproc; conf.nmnthdr = conf.nproc; conf.nstream = 2 * conf.nproc; - conf.npte = 4 * conf.npage; conf.nalarm = 500; conf.nmount = 500; conf.nsrv = 3; @@ -645,15 +645,15 @@ confinit(void) conf.ip = 64; conf.arp = 32; conf.frag = 32; - conf.cntrlp = 1; confread(); conf.npipe = conf.nstream/2; /* must be after confread */ if(conf.nmach > MAXMACH) panic("confinit"); - conf.copymode = 1; /* copy on reference */ + conf.copymode = 1; /* copy on reference */ + conf.cntrlp = 1; } /* @@ -830,6 +830,7 @@ void buzz(int f, int d) { } + int mouseputc(IOQ *q, int c) { diff --git a/power/mem.h b/power/mem.h index 0ad5851aaf2e4407a598ff0dea27eee780d7086e..bf2c0a569b15390577c15a5ea6618f82c7347d2f 100644 --- a/power/mem.h +++ b/power/mem.h @@ -13,6 +13,7 @@ #define WD2PG (BY2PG/BY2WD) /* words per page */ #define PGSHIFT 12 /* log(BY2PG) */ #define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1)) +#define ICACHESIZE (64*1024) /* Power series */ #define MAXMACH 4 /* max # cpus system can run */ @@ -100,10 +101,13 @@ #define PTERONLY 0 #define PTEPID(n) ((n)<<6) #define TLBPID(n) (((n)>>6)&0x3F) - +#define PTEMAPMEM (1024*1024) +#define PTEPERTAB (PTEMAPMEM/BY2PG) #define STLBLOG 11 #define STLBSIZE (1<newtlb) { + /* see flushmmu. */ + memset(p->pidonmach, 0, sizeof p->pidonmach); + p->newtlb = 0; + } + tp = p->pidonmach[m->machno]; if(tp == 0) tp = newtlbpid(p); @@ -70,12 +76,21 @@ newtlbpid(Proc *p) } void -putmmu(ulong tlbvirt, ulong tlbphys) +putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) { short tp; Proc *p; + char *ctl; splhi(); + + ctl = &pg->cachectl[m->machno]; + if(*ctl == PG_TXTFLUSH) { + dcflush((void*)pg->pa, BY2PG); + icflush((void*)pg->pa, BY2PG); + *ctl = PG_NOFLUSH; + } + p = u->p; /* if(p->state != Running) panic("putmmu state %lux %lux %s\n", u, p, statename[p->state]); diff --git a/power/segment.h b/power/segment.h new file mode 100644 index 0000000000000000000000000000000000000000..4684efad0c2ccaba7aa393e361b7cd8c535570ab --- /dev/null +++ b/power/segment.h @@ -0,0 +1,20 @@ +/* + * Attach segment types + */ + +typedef struct Physseg Physseg; +struct Physseg +{ + ulong attr; /* Segment attributes */ + char *name; /* Attach name */ + ulong pa; /* Physical address */ + ulong size; /* Maximum segment size in pages */ + Page *(*pgalloc)(ulong); /* Allocation if we need it */ + void (*pgfree)(Page*); +}physseg[] = { + { SG_SHARED, "lock", 0, 1024*BY2PG, &lkpage, &lkpgfree }, + { SG_SHARED, "shared", 0, SEGMAXSIZE, &snewpage, &putpage }, + { SG_PHYSICAL, "kmem", KZERO, SEGMAXSIZE, 0, 0 }, + { SG_BSS, "memory", 0, SEGMAXSIZE, &snewpage, &putpage }, + { 0, 0, 0, 0, 0, 0 }, +}; diff --git a/power/trap.c b/power/trap.c index e0d340c3804496598d19250a67a03250464bb2ac..a3ebf1d1b7e552508faa1d8ebf00d9f0f2e9580f 100644 --- a/power/trap.c +++ b/power/trap.c @@ -84,6 +84,7 @@ trap(Ureg *ur) user = ur->status&KUP; if(u) u->p->pc = ur->pc; /* BUG */ + switch(ecode){ case CINT: if(u && u->p->state==Running){ @@ -142,15 +143,15 @@ trap(Ureg *ur) } Default: /* - * This isn't good enough; can still deadlock because we may hold print's locks - * in this processor. + * This isn't good enough; can still deadlock because we may + * hold print's locks in this processor. */ if(user){ spllo(); if(ecode == FPEXC) sprint(buf, "sys: fp: %s FCR31 %lux", fpexcname(x), x); else - sprint(buf, "sys: trap: %s[%d]", excname[ecode], m->machno); + sprint(buf, "sys: %s pc=0x%lux", excname[ecode], ur->pc); postnote(u->p, 1, buf, NDebug); }else{ @@ -163,8 +164,14 @@ trap(Ureg *ur) exit(); } } - if(user && u->nnote) - notify(ur); + + if(user) { + if(u->p->procctl) + procctl(u->p); + if(u->nnote) + notify(ur); + } + splhi(); if(user && u && u->p->fpstate == FPinactive) { restfpregs(&u->fpsave, u->fpsave.fpstatus); @@ -383,6 +390,13 @@ notify(Ureg *ur) u->svstatus = ur->status; sp = ur->usp; sp -= sizeof(Ureg); + if(waserror()){ + pprint("suicide: trap in notify\n"); + pexit("Suicide", 0); + } + validaddr((ulong)u->notify, 1, 0); + validaddr(sp-ERRLEN-3*BY2WD, sizeof(Ureg)+ERRLEN-3*BY2WD, 0); + poperror(); u->ureg = (void*)sp; memmove((Ureg*)sp, ur, sizeof(Ureg)); sp -= ERRLEN; @@ -442,8 +456,9 @@ Syscall sysbind, sysbrk_, syschdir, sysclose, syscreate, sysdeath; Syscall sysdup, syserrstr, sysexec, sysexits, sysfork, sysforkpgrp; Syscall sysfstat, sysfwstat, sysgetpid, sysmount, sysnoted; Syscall sysnotify, sysopen, syspipe, sysr1, sysread, sysremove, sysseek; -Syscall syssleep, sysstat, syswait, syswrite, syswstat, sysalarm, syslkbrk_; -#define LKBRK_ 12 +Syscall syssleep, sysstat, syswait, syswrite, syswstat, sysalarm, syssegbrk; +Syscall syssegattach, syssegdetach, syssegfree, syssegflush; + Syscall *systab[]={ [SYSR1] sysr1, [ERRSTR] syserrstr, @@ -457,7 +472,7 @@ Syscall *systab[]={ [FORK] sysfork, [FORKPGRP] sysforkpgrp, [FSTAT] sysfstat, - [LKBRK_] syslkbrk_, + [SEGBRK] syssegbrk, [MOUNT] sysmount, [OPEN] sysopen, [READ] sysread, @@ -475,6 +490,10 @@ Syscall *systab[]={ [FWSTAT] sysfwstat, [NOTIFY] sysnotify, [NOTED] sysnoted, + [SEGATTACH] syssegattach, + [SEGDETACH] syssegdetach, + [SEGFREE] syssegfree, + [SEGFLUSH] syssegflush, }; long @@ -502,6 +521,10 @@ syscall(Ureg *aur) ur->status &= ~CU1; } spllo(); + + if(u->p->procctl) + procctl(u->p); + r1 = ur->r1; sp = ur->sp; u->nerrlab = 0; @@ -527,6 +550,10 @@ syscall(Ureg *aur) } ur->pc += 4; u->nerrlab = 0; + + if(u->p->procctl) + procctl(u->p); + splhi(); u->p->insyscall = 0; if(r1 == NOTED) /* ugly hack */ @@ -535,6 +562,7 @@ syscall(Ureg *aur) ur->r1 = ret; notify(ur); } + return ret; }