M gnot/dat.h => gnot/dat.h +5 -7
@@ 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.
M gnot/fault68020.c => gnot/fault68020.c +3 -0
@@ 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){
M gnot/fns.h => gnot/fns.h +1 -0
@@ 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);
M gnot/lock.c => gnot/lock.c +0 -11
@@ 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)
-{
-}
M gnot/main.c => gnot/main.c +27 -27
@@ 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;
M gnot/mem.h => gnot/mem.h +5 -0
@@ 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)
M gnot/mmu.c => gnot/mmu.c +9 -2
@@ 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;
}
A gnot/segment.h => gnot/segment.h +20 -0
@@ 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 },
+};
M gnot/trap.c => gnot/trap.c +18 -6
@@ 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; i<sizeof regname/sizeof(char*); i+=2, l+=2)
print("%s\t%.8lux\t%s\t%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
+ for(;;);
dumpstack();
}
@@ 212,6 214,7 @@ Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswai
Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat;
Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate;
Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm;
+Syscall syssegattach, syssegdetach, syssegfree, syssegflush, syssegbrk;
Syscall *systab[]={
sysr1,
@@ 226,7 229,7 @@ Syscall *systab[]={
sysfork,
sysforkpgrp,
sysfstat,
- sysdeath,
+ syssegbrk,
sysmount,
sysopen,
sysread,
@@ 244,7 247,10 @@ Syscall *systab[]={
sysfwstat,
sysnotify,
sysnoted,
- sysdeath, /* sysfilsys */
+ syssegattach,
+ syssegdetach,
+ syssegfree,
+ syssegflush,
};
long
@@ 289,7 295,8 @@ syscall(Ureg *aur)
error(Ebadarg);
}
if(sp & (BY2WD-1)){
- pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((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;
M pc/clock.c => pc/clock.c +20 -1
@@ 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;
+}
M pc/fns.h => pc/fns.h +2 -2
@@ 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*);
M pc/io.h => pc/io.h +1 -13
@@ 18,18 18,6 @@ enum
#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
*/
enum
@@ 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 */
};
M pc/kbd.c => pc/kbd.c +1 -1
@@ 378,6 378,6 @@ kbdintr(void *a)
}
kbdputc(&kbdq, c);
out:
- INTENABLE; /* reenable interrupt */
+ INT0ENABLE; /* reenable interrupt */
return;
}
M pc/l.s => pc/l.s +6 -0
@@ 305,3 305,9 @@ TEXT spllo(SB),$0
TEXT splhi(SB),$0
CLI
RET
+
+/*
+ * set interrupt level
+ */
+TEXT splx(SB),$0
+ RET
M pc/main.c => pc/main.c +6 -1
@@ 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)
+{
+}
M pc/mem.h => pc/mem.h +7 -7
@@ 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
M pc/trap.c => pc/trap.c +5 -5
@@ 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 */
}
M port/chan.c => port/chan.c +2 -0
@@ 30,6 30,8 @@ decref(Ref *r)
lock(r);
x = --r->ref;
unlock(r);
+ if(x < 0)
+ panic("decref");
return x;
}
M port/devcons.c => port/devcons.c +21 -2
@@ 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);
}
M port/devdup.c => port/devdup.c +3 -2
@@ 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)
M port/devenv.c => port/devenv.c +63 -63
@@ 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; i<pg->nenv; i++)
- if(pg->etab[i].chref == 0)
+ if(eg->nenv == conf.npgenv){
+ for(i = 0; i<eg->nenv; 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; i<pg->nenv; i++, ep++)
+ eg = u->p->egrp;
+ for(ep=eg->etab, i=0; i<eg->nenv; 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){
M port/devip.c => port/devip.c +1 -0
@@ 71,6 71,7 @@ ipreset(void)
}
initfrag(conf.frag);
+ tcpinit();
}
void
M port/deviproute.c => port/deviproute.c +1 -1
@@ 190,7 190,7 @@ enum{
Qdata,
};
Dirtab iproutetab[]={
- "iproute", {Qdata}, 0, 0666,
+ "iproute", {Qdata}, 0, 0600,
};
#define Niproutetab (sizeof(iproutetab)/sizeof(Dirtab))
M port/devproc.c => port/devproc.c +78 -38
@@ 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<<QSHIFT)-1)); /* slot component */
+ devdir(c, (Qid){path|tab->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);
M port/devscsi.c => port/devscsi.c +1 -5
@@ 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;
}
}
M port/devsrv.c => port/devsrv.c +1 -2
@@ 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();
M port/devwren.c => port/devwren.c +1 -1
@@ 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;
M port/fault.c => port/fault.c +230 -242
@@ 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 || addr<s->maxva-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(n<BY2PG)
- memset(l+n, 0, BY2PG-n);
- lock(o);
- kunmap(k);
- poperror();
- opte = &o->pte[(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->va<addr)
- npte = npte->nextva;
- 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 || addr<s->maxva-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 && addr<s->maxva)
- 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;
}
M port/ipdat.h => port/ipdat.h +2 -0
@@ 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)
M port/page.c => port/page.c +303 -593
@@ 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; i<conf.nmod-1; i++,pte++)
- pte->next = pte+1;
- pte->next = 0;
-
- origalloc.free = ialloc(conf.norig*sizeof(Orig), 0);
- origalloc.arena = origalloc.free;
-
- o = origalloc.free;
- for(i=0; i<conf.norig-1; i++,o++)
- o->next = o+1;
- o->next = 0;
palloc.active = 1;
nb = (conf.npage<<PGSHIFT) - palloc.addr;
nb -= ((nb+(BY2PG-1))>>PGSHIFT)*sizeof(Page); /* safe overestimate */
nb &= ~(BY2PG-1);
- pa = (conf.npage<<PGSHIFT) - nb; /* physical addr of first free page */
- ppn = pa >> PGSHIFT; /* physical page number of first free page */
+ pa = (conf.npage<<PGSHIFT) - nb; /* physical addr of first free page */
+ ppn = pa >> 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<<PGSHIFT);
else
p->pa = conf.base1+((ppn-conf.npage0)<<PGSHIFT);
+ palloc.freecount++;
}
palloc.head->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; i<conf.norig; i++,o++)
- if(o->npage && 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; i<conf.norig; i++,o++){
- if(o->nproc==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; i<NSEG; i++,s++){
- if(i == save)
- continue;
- o = s->o;
- 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; i<o->npte; 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);
}
M port/pgrp.c => port/pgrp.c +148 -26
@@ 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; i<conf.nmount-1; i++,m++)
+ mountalloc.free = ialloc(conf.nmount*sizeof(Mount), 0);
+ em = &mountalloc.free[conf.nmount-1];
+ for(m = mountalloc.free; m < em; m++)
m->next = 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; i<p->nenv; 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; i<e->nenv; 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;
M port/portdat.h => port/portdat.h +152 -61
@@ 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
M port/portfns.h => port/portfns.h +61 -36
@@ 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*);
M port/proc.c => port/proc.c +103 -29
@@ 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; i<conf.nproc; i++){
p = procalloc.arena+i;
if(p->state != 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;
+ }
+}
M port/qlock.c => port/qlock.c +1 -4
@@ 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);
M port/queue.c => port/queue.c +1 -0
@@ 4,6 4,7 @@
#include "dat.h"
#include "fns.h"
#include "io.h"
+#include "errno.h"
void
initq(IOQ *q)
A port/segment.c => port/segment.c +460 -0
@@ 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);
+}
M port/stream.c => port/stream.c +2 -5
@@ 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);
}
M port/sturp.c => port/sturp.c +1 -1
@@ 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;
A port/swap.c => port/swap.c +333 -0
@@ 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;
+}
+
M port/sysfile.c => port/sysfile.c +79 -41
@@ 11,16 11,21 @@
*/
int
-newfd(void)
+newfd(Chan *c)
{
+ Fgrp *f = u->p->fgrp;
int i;
+ lock(f);
for(i=0; i<NFD; i++)
- if(u->fd[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;
}
M port/sysproc.c => port/sysproc.c +159 -145
@@ 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; i<n; i++){
- op = u->p->seg[SSEG].o->pte[i+(on-n)].page;
- if(op){
- np = newpage(1, s->o, op->va);
- k = kmap(np);
- p->seg[SSEG].o->pte[i].page = np;
- if(i == 0){ /* only part of last stack page */
- memset((void*)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; n<NSEG; n++, s++){
- if(n == SSEG) /* already done */
- continue;
- if(s->o == 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<<PGSHIFT), spage, OWRPERM|OISMEM, 0);
- s->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; i<nargs; i++){
- if(indir && *argp==0){
+ if(indir && *argp==0) {
indir = 0;
argp = (char**)arg[1];
}
@@ 276,87 231,65 @@ sysexec(ulong *arg)
memmove(p->text, 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; i<o->npte; 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);
}
M port/tcpinput.c => port/tcpinput.c +13 -0
@@ 21,6 21,18 @@ char *tcpstate[] = {
"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)
{
Ipconv *s, *new, *etab;
@@ 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;
}
M power/boot.h => power/boot.h +312 -356
@@ 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,
};
M power/conf.h => power/conf.h +4 -3
@@ 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 },
M power/dat.h => power/dat.h +6 -7
@@ 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.
M power/faultmips.c => power/faultmips.c +6 -3
@@ 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);
M power/fns.h => power/fns.h +11 -3
@@ 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*);
M power/l.s => power/l.s +195 -82
@@ 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
M power/lock.c => power/lock.c +2 -27
@@ 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;
}
M power/main.c => power/main.c +30 -29
@@ 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)
{
M power/mem.h => power/mem.h +6 -2
@@ 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<<STLBLOG)
+#define SEGMAPSIZE 64
+
#define NTLBPID 64 /* number of pids */
#define NTLB 64 /* number of entries */
#define TLBROFF 8 /* offset of first randomly indexed entry */
@@ 115,7 119,7 @@
#define UZERO KUSEG /* base of user address space */
#define UTZERO (UZERO+BY2PG) /* first address in user text */
#define USTKTOP KZERO /* byte just beyond user stack */
-#define TSTKTOP (USERADDR+TSTKSIZ*BY2PG)/* top of temporary stack */
+#define TSTKTOP (USERADDR+USTKSIZE) /* top of temporary stack */
#define TSTKSIZ 100
#define KZERO KSEG0 /* base of kernel address space */
#define KTZERO (KZERO+0x20000) /* first address in kernel text */
M power/mmu.c => power/mmu.c +16 -1
@@ 13,6 13,12 @@ mapstack(Proc *p)
short tp;
ulong tlbvirt, tlbphys;
+ if(p->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]);
A power/segment.h => power/segment.h +20 -0
@@ 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 },
+};
M power/trap.c => power/trap.c +36 -8
@@ 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;
}