merge
This commit is contained in:
commit
81e6b7e9c9
6 changed files with 94 additions and 10 deletions
|
@ -134,7 +134,7 @@ Cmdtab proccmd[] = {
|
|||
};
|
||||
|
||||
/* Segment type from portdat.h */
|
||||
static char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys", };
|
||||
static char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys", "Fixed", };
|
||||
|
||||
/*
|
||||
* Qids are, in path:
|
||||
|
|
|
@ -56,6 +56,7 @@ static Segment* globalsegattach(Proc *p, char *name);
|
|||
static int cmddone(void*);
|
||||
static void segmentkproc(void*);
|
||||
static void docmd(Globalseg *g, int cmd);
|
||||
static Segment* fixedseg(uintptr va, ulong len);
|
||||
|
||||
/*
|
||||
* returns with globalseg incref'd
|
||||
|
@ -98,7 +99,7 @@ segmentgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
|
|||
{
|
||||
Qid q;
|
||||
Globalseg *g;
|
||||
ulong size;
|
||||
uintptr size;
|
||||
|
||||
switch(TYPE(c)) {
|
||||
case Qtopdir:
|
||||
|
@ -328,7 +329,11 @@ segmentread(Chan *c, void *a, long n, vlong voff)
|
|||
g = c->aux;
|
||||
if(g->s == nil)
|
||||
error("segment not yet allocated");
|
||||
sprint(buf, "va %#lux %#lux\n", g->s->base, g->s->top-g->s->base);
|
||||
if(g->s->type&SG_TYPE == SG_FIXED)
|
||||
sprint(buf, "va %#p %#p fixed %#p\n", g->s->base, g->s->top-g->s->base,
|
||||
g->s->map[0]->pages[0]->pa);
|
||||
else
|
||||
sprint(buf, "va %#p %#p\n", g->s->base, g->s->top-g->s->base);
|
||||
return readstr(voff, a, n, buf);
|
||||
case Qdata:
|
||||
g = c->aux;
|
||||
|
@ -362,7 +367,7 @@ segmentwrite(Chan *c, void *a, long n, vlong voff)
|
|||
{
|
||||
Cmdbuf *cb;
|
||||
Globalseg *g;
|
||||
ulong va, len, top;
|
||||
uintptr va, top, len;
|
||||
|
||||
if(c->qid.type == QTDIR)
|
||||
error(Eperm);
|
||||
|
@ -376,14 +381,19 @@ segmentwrite(Chan *c, void *a, long n, vlong voff)
|
|||
error("already has a virtual address");
|
||||
if(cb->nf < 3)
|
||||
error(Ebadarg);
|
||||
va = strtoul(cb->f[1], 0, 0);
|
||||
len = strtoul(cb->f[2], 0, 0);
|
||||
va = strtoull(cb->f[1], 0, 0);
|
||||
len = strtoull(cb->f[2], 0, 0);
|
||||
top = PGROUND(va + len);
|
||||
va = va&~(BY2PG-1);
|
||||
len = (top - va) / BY2PG;
|
||||
if(len == 0)
|
||||
if(va == 0 || top > USTKTOP || top <= va)
|
||||
error(Ebadarg);
|
||||
g->s = newseg(SG_SHARED, va, len);
|
||||
len = (top - va) / BY2PG;
|
||||
if(cb->nf >= 4 && strcmp(cb->f[3], "fixed") == 0){
|
||||
if(!iseve())
|
||||
error(Eperm);
|
||||
g->s = fixedseg(va, len);
|
||||
} else
|
||||
g->s = newseg(SG_SHARED, va, len);
|
||||
} else
|
||||
error(Ebadctl);
|
||||
break;
|
||||
|
@ -561,6 +571,73 @@ segmentkproc(void *arg)
|
|||
pexit("done", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate a fixed segment with sequential run of of adjacent
|
||||
* user memory pages.
|
||||
*/
|
||||
static Segment*
|
||||
fixedseg(uintptr va, ulong len)
|
||||
{
|
||||
KMap *k;
|
||||
Segment *s;
|
||||
Page **f, *p;
|
||||
ulong n, i, j;
|
||||
int color;
|
||||
|
||||
s = newseg(SG_FIXED, va, len);
|
||||
if(waserror()){
|
||||
putseg(s);
|
||||
nexterror();
|
||||
}
|
||||
lock(&palloc);
|
||||
i = 0;
|
||||
p = palloc.pages;
|
||||
color = getpgcolor(va);
|
||||
for(n = palloc.user; n >= len; n--, p++){
|
||||
if(p->ref != 0 || i != 0 && (p[-1].pa+BY2PG) != p->pa || i == 0 && p->color != color){
|
||||
Retry:
|
||||
i = 0;
|
||||
continue;
|
||||
}
|
||||
if(++i < len)
|
||||
continue;
|
||||
for(j = 0; j < i; j++, p--){
|
||||
for(f = &palloc.head; *f != nil; f = &((*f)->next)){
|
||||
if(*f == p){
|
||||
*f = p->next;
|
||||
goto Freed;
|
||||
}
|
||||
}
|
||||
while(j-- > 0)
|
||||
pagechainhead(++p);
|
||||
goto Retry;
|
||||
Freed:
|
||||
palloc.freecount--;
|
||||
}
|
||||
unlock(&palloc);
|
||||
|
||||
while(i-- > 0){
|
||||
p++;
|
||||
p->ref = 1;
|
||||
p->va = va;
|
||||
p->modref = 0;
|
||||
p->txtflush = ~0;
|
||||
|
||||
k = kmap(p);
|
||||
memset((void*)VA(k), 0, BY2PG);
|
||||
kunmap(k);
|
||||
|
||||
segpage(s, p);
|
||||
va += BY2PG;
|
||||
}
|
||||
poperror();
|
||||
return s;
|
||||
}
|
||||
unlock(&palloc);
|
||||
error(Enomem);
|
||||
return nil;
|
||||
}
|
||||
|
||||
Dev segmentdevtab = {
|
||||
'g',
|
||||
"segment",
|
||||
|
|
|
@ -267,6 +267,7 @@ fixfault(Segment *s, uintptr addr, int read, int doputmmu)
|
|||
copypage(old, *pg);
|
||||
putpage(old);
|
||||
}
|
||||
case SG_FIXED: /* Never paged out */
|
||||
mmuphys = PPN((*pg)->pa) | PTEWRITE | PTEVALID;
|
||||
(*pg)->modref = PG_MOD|PG_REF;
|
||||
break;
|
||||
|
|
|
@ -341,6 +341,7 @@ enum
|
|||
SG_STACK = 03,
|
||||
SG_SHARED = 04,
|
||||
SG_PHYSICAL = 05,
|
||||
SG_FIXED = 06,
|
||||
|
||||
SG_RONLY = 0040, /* Segment is read only */
|
||||
SG_CEXEC = 0100, /* Detach at exec */
|
||||
|
|
|
@ -156,6 +156,7 @@ dupseg(Segment **seg, int segno, int share)
|
|||
case SG_TEXT: /* New segment shares pte set */
|
||||
case SG_SHARED:
|
||||
case SG_PHYSICAL:
|
||||
case SG_FIXED:
|
||||
goto sameseg;
|
||||
|
||||
case SG_STACK:
|
||||
|
@ -489,8 +490,11 @@ mfreeseg(Segment *s, uintptr start, ulong pages)
|
|||
if(pages == 0)
|
||||
return;
|
||||
|
||||
if((s->type&SG_TYPE) == SG_PHYSICAL)
|
||||
switch(s->type&SG_TYPE){
|
||||
case SG_PHYSICAL:
|
||||
case SG_FIXED:
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* we have to make sure other processors flush the
|
||||
|
|
|
@ -751,6 +751,7 @@ syssegbrk(va_list list)
|
|||
case SG_DATA:
|
||||
case SG_STACK:
|
||||
case SG_PHYSICAL:
|
||||
case SG_FIXED:
|
||||
error(Ebadarg);
|
||||
default:
|
||||
return (uintptr)ibrk(va_arg(list, uintptr), i);
|
||||
|
|
Loading…
Reference in a new issue