This commit is contained in:
cinap_lenrek 2020-04-04 17:17:15 +02:00
commit f5352eb501
29 changed files with 830 additions and 1808 deletions

View file

@ -120,7 +120,7 @@ extern int fpuemu(Ureg*);
/*
* Things called from port.
*/
extern void delay(int); /* only scheddump() */
extern void delay(int);
extern int islo(void);
extern void microdelay(int); /* only edf.c */
extern void evenaddr(uintptr);

View file

@ -118,7 +118,7 @@ extern Block* uciallocb(int);
/*
* Things called from port.
*/
extern void delay(int); /* only scheddump() */
extern void delay(int);
extern int islo(void);
extern void microdelay(int); /* only edf.c */
extern void evenaddr(uintptr);

View file

@ -85,10 +85,11 @@ mmusweep(void*)
sweepcolor = m->sweepcolor;
x = splhi();
p = proctab(0);
for(i = 0; i < conf.nproc; i++, p++)
for(i = 0; i < conf.nproc; i++) {
p = proctab(i);
if(PIDCOLOR(p->mmupid) == sweepcolor)
p->mmupid = 0;
}
splx(x);
ptab = (ulong*)m->ptabbase;

View file

@ -133,7 +133,7 @@ extern void ucfreeb(Block*);
/*
* Things called from port.
*/
extern void delay(int); /* only scheddump() */
extern void delay(int);
extern int islo(void);
extern void microdelay(int); /* only edf.c */
extern void evenaddr(uintptr);

View file

@ -113,8 +113,9 @@ maptable(uvlong xpa)
int i;
pa = xpa;
if((uvlong)pa != xpa || pa == 0)
if((uvlong)pa != xpa || pa == 0 || pa+7 < pa)
return;
if(ntblpa >= nelem(tblpa) || ntblmap >= nelem(tblmap))
return;
@ -124,21 +125,18 @@ maptable(uvlong xpa)
}
tblpa[ntblpa++] = pa;
memreserve(pa, 8);
if((t = vmap(pa, 8)) == nil)
return;
l = get32(t->len);
if(l < Tblsz){
vunmap(t, 8);
return;
}
if(memcheck(pa, l) != l){
print("maptable: ignoring %.4s at [%#p-%#p); overlaps usable memory\n",
(char*)t->sig, pa, pa+l);
if(l < Tblsz
|| l >= 0x10000000
|| pa+l-1 < pa){
vunmap(t, 8);
return;
}
memreserve(pa, l);
vunmap(t, 8);
if((t = vmap(pa, l)) == nil)
return;
if(checksum(t, l)){
@ -177,9 +175,10 @@ maptables(void)
return;
if(!checksum(rsd, 20))
maptable(get32(rsd->raddr));
if(rsd->rev >= 2)
if(rsd->rev >= 2){
if(!checksum(rsd, 36))
maptable(get64(rsd->xaddr));
}
}
static Apic*
@ -567,8 +566,6 @@ acpiinit(void)
ulong lapicbase;
int machno, i, c;
maptables();
amlinit();
/* load DSDT */
@ -789,14 +786,15 @@ identify(void)
pa = (uintptr)strtoull(cp, nil, 16);
if(pa <= 1)
rsd = rsdsearch();
else if(pa < MemMin)
rsd = KADDR(pa);
else
else {
memreserve(pa, sizeof(Rsd));
rsd = vmap(pa, sizeof(Rsd));
}
if(rsd == nil)
return 1;
if(checksum(rsd, 20) && checksum(rsd, 36))
return 1;
maptables();
addarchfile("acpitbls", 0444, readtbls, nil);
addarchfile("acpimem", 0600, readmem, writemem);
if(strcmp(cp, "0") == 0)

View file

@ -383,7 +383,7 @@ identify(void)
{
char *cp;
_MP_ *_mp_;
ulong len;
ulong pa, len;
if((cp = getconf("*nomp")) != nil && strcmp(cp, "0") != 0)
return 1;
@ -399,26 +399,28 @@ identify(void)
return 1;
len = PCMPsz;
if(_mp_->physaddr < MemMin)
pcmp = KADDR(_mp_->physaddr);
else if((pcmp = vmap(_mp_->physaddr, len)) == nil)
pa = _mp_->physaddr;
if(pa + len-1 < pa)
return 1;
if(pcmp->length < len
memreserve(pa, len);
if((pcmp = vmap(pa, len)) == nil)
return 1;
if(pcmp->length < PCMPsz
|| pa + pcmp->length-1 < pa
|| memcmp(pcmp, "PCMP", 4) != 0
|| (pcmp->version != 1 && pcmp->version != 4)){
Bad:
if((uintptr)pcmp < KZERO)
vunmap(pcmp, len);
vunmap(pcmp, len);
pcmp = nil;
return 1;
}
len = pcmp->length;
if((uintptr)pcmp < KZERO)
vunmap(pcmp, PCMPsz);
if(_mp_->physaddr < MemMin)
pcmp = KADDR(_mp_->physaddr);
else if((pcmp = vmap(_mp_->physaddr, len)) == nil)
memreserve(pa, len);
vunmap(pcmp, PCMPsz);
if((pcmp = vmap(pa, len)) == nil)
return 1;
if(checksum(pcmp, len) != 0)
goto Bad;

View file

@ -24,7 +24,7 @@ multibootargs(void)
ulong *m, l;
int i, n;
if(multibootptr == 0)
if(multibootptr == 0 || multibootptr >= MemMin)
return;
multiboot = (ulong*)KADDR(multibootptr);

View file

@ -268,7 +268,6 @@ pcmmap(int slotno, ulong offset, int len, int attr)
if((we & bit))
if(m->attr == attr)
if(offset >= m->ca && e <= m->cea){
m->ref++;
unlock(&pp->mlock);
return m;
@ -285,12 +284,13 @@ pcmmap(int slotno, ulong offset, int len, int attr)
/* if isa space isn't big enough, free it and get more */
if(m->len < len){
if(m->isa){
if(m->len){
umbfree(m->isa, m->len);
m->len = 0;
}
m->isa = PADDR(umbmalloc(0, len, Mgran));
if(m->isa == 0){
m->isa = umballoc(-1, len, Mgran);
if(m->isa == -1){
m->isa = 0;
print("pcmmap: out of isa space\n");
unlock(&pp->mlock);
return 0;

View file

@ -521,7 +521,6 @@ devpccardlink(void)
int i;
uchar intl;
char *p;
void *baddrva;
if (initialized)
return;
@ -543,7 +542,6 @@ devpccardlink(void)
while ((pci = pcimatch(pci, 0, 0)) != nil) {
ulong baddr;
Cardbus *cb;
int slot;
uchar pin;
if(pci->ccrb != 6 || pci->ccru != 7)
@ -555,8 +553,7 @@ devpccardlink(void)
continue;
/* initialize this slot */
slot = nslots++;
cb = &cbslots[slot];
cb = &cbslots[nslots];
cb->pci = pci;
cb->variant = &variant[i];
@ -635,27 +632,30 @@ devpccardlink(void)
pcicfgw8(cb->pci, 0xD4, 0xCA);
}
if (intl != 0xff && intl != pci->intl)
intrenable(pci->intl, cbinterrupt, cb, pci->tbdf, "cardbus");
intl = pci->intl;
if ((baddr = pcicfgr32(cb->pci, PciBAR0)) == 0) {
int size = (pci->did == Ricoh_478_did)? 0x10000: 0x1000;
baddr = upaalloc(size, size);
baddrva = vmap(baddr, size);
baddr = upaalloc(-1, size, size);
if(baddr == -1)
continue;
pcicfgw32(cb->pci, PciBAR0, baddr);
cb->regs = (ulong *)baddrva;
cb->regs = (ulong *)vmap(baddr, size);
}
else
cb->regs = (ulong *)vmap(baddr, 4096);
if(cb->regs == nil)
continue;
cb->state = SlotEmpty;
if (intl != 0xff && intl != pci->intl)
intrenable(pci->intl, cbinterrupt, cb, pci->tbdf, "cardbus");
/* Don't really know what to do with this... */
i82365probe(cb, LegacyAddr, LegacyAddr + 1);
print("#Y%ld: %s, %.8ulX intl %d\n", cb - cbslots,
variant[i].name, baddr, pci->intl);
nslots++;
}
if (nslots == 0){
@ -815,16 +815,22 @@ configure(Cardbus *cb)
if(iolen < 512)
iolen = 512;
iobase = ioreserve(~0, iolen, 0, "cardbus");
pcicfgw32(cb->pci, PciCBIBR0, iobase);
pcicfgw32(cb->pci, PciCBILR0, iobase + iolen-1);
pcicfgw32(cb->pci, PciCBIBR1, 0);
pcicfgw32(cb->pci, PciCBILR1, 0);
if(iobase == -1)
return;
rombase = memlen;
memlen += romlen;
if(memlen < 1*1024*1024)
memlen = 1*1024*1024;
membase = upaalloc(memlen, 4*1024*1024); /* TO DO: better alignment */
membase = upaalloc(-1, memlen, 4*1024*1024); /* TO DO: better alignment */
if(membase == -1)
return;
pcicfgw32(cb->pci, PciCBIBR0, iobase);
pcicfgw32(cb->pci, PciCBILR0, iobase + iolen-1);
pcicfgw32(cb->pci, PciCBIBR1, 0);
pcicfgw32(cb->pci, PciCBILR1, 0);
pcicfgw32(cb->pci, PciCBMBR0, membase);
pcicfgw32(cb->pci, PciCBMLR0, membase + memlen-1);
pcicfgw32(cb->pci, PciCBMBR1, 0);
@ -1451,7 +1457,6 @@ isamap(Cardbus *cb, ulong offset, int len, int attr)
if((we & bit))
if(m->attr == attr)
if(offset >= m->ca && e <= m->cea){
m->ref++;
return m;
}
@ -1465,12 +1470,13 @@ isamap(Cardbus *cb, ulong offset, int len, int attr)
/* if isa space isn't big enough, free it and get more */
if(m->len < len){
if(m->isa){
if(m->len){
umbfree(m->isa, m->len);
m->len = 0;
}
m->isa = PADDR(umbmalloc(0, len, Mgran));
if(m->isa == 0){
m->isa = umballoc(-1, len, Mgran);
if(m->isa == -1){
m->isa = 0;
print("isamap: out of isa space\n");
return 0;
}

View file

@ -88,7 +88,7 @@ reset8003(Ether* ether, uchar ea[Eaddrlen], uchar ic[8])
*/
if(memcmp(&ea[1], &ic[1], 5) == 0){
memset(ic, 0, sizeof(ic));
ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F;
ic[Msr] = (ether->mem>>13) & 0x3F;
}
else{
/*
@ -100,7 +100,7 @@ reset8003(Ether* ether, uchar ea[Eaddrlen], uchar ic[8])
inb(port+Msr); /* wiggle bus */
if(inb(port+Gp2) != 0xAA){
memset(ic, 0, sizeof(ic));
ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F;
ic[Msr] = (ether->mem>>13) & 0x3F;
}
else
ether->irq = irq8003[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)];
@ -122,7 +122,7 @@ reset8003(Ether* ether, uchar ea[Eaddrlen], uchar ic[8])
ctlr->width = 1;
}
ether->mem = (ulong)KADDR((ic[Msr] & 0x3F)<<13);
ether->mem = (ic[Msr] & 0x3F)<<13;
if(ctlr->width == 2)
ether->mem |= (ic[Laar] & 0x1F)<<19;
else
@ -163,7 +163,7 @@ reset8216(Ether* ether, uchar[8])
irq = inb(port+0x0D);
outb(port+Hcr, hcr);
ether->mem = (ulong)KADDR(0xC0000+((((addr>>2) & 0x30)|(addr & 0x0F))<<13));
ether->mem = 0xC0000+((((addr>>2) & 0x30)|(addr & 0x0F))<<13);
ether->size = 8192*(1<<((addr>>4) & 0x03));
ether->irq = irq8216[((irq>>4) & 0x04)|((irq>>2) & 0x03)];
@ -262,9 +262,8 @@ reset(Ether* ether)
}
dp8390setea(ether);
if(umbrwmalloc(PADDR(ether->mem), ether->size, 0) == 0)
print("ether8003: warning - 0x%luX unavailable\n",
PADDR(ether->mem));
if(umballoc(ether->mem, ether->size, 0) == -1)
print("ether8003: warning - 0x%luX unavailable\n", ether->mem);
return 0;
}

View file

@ -377,7 +377,7 @@ receive(Ether* ether)
for(curr = getcurr(ctlr); ctlr->nxtpkt != curr; curr = getcurr(ctlr)){
data = ctlr->nxtpkt*Dp8390BufSz;
if(ctlr->ram)
memmove(&hdr, (void*)(ether->mem+data), sizeof(Hdr));
memmove(&hdr, (uchar*)KADDR(ether->mem) + data, sizeof(Hdr));
else
_dp8390read(ctlr, &hdr, data, sizeof(Hdr));
@ -422,7 +422,7 @@ receive(Ether* ether)
if((data+len) >= ctlr->pstop*Dp8390BufSz){
count = ctlr->pstop*Dp8390BufSz - data;
if(ctlr->ram)
memmove(p, (void*)(ether->mem+data), count);
memmove(p, (uchar*)KADDR(ether->mem) + data, count);
else
_dp8390read(ctlr, p, data, count);
p += count;
@ -431,7 +431,7 @@ receive(Ether* ether)
}
if(len){
if(ctlr->ram)
memmove(p, (void*)(ether->mem+data), len);
memmove(p, (uchar*)KADDR(ether->mem) + data, len);
else
_dp8390read(ctlr, p, data, len);
}
@ -461,7 +461,6 @@ txstart(Ether* ether)
int len;
Dp8390 *ctlr;
Block *bp;
uchar minpkt[ETHERMINTU], *rp;
ctlr = ether->ctlr;
@ -476,23 +475,14 @@ txstart(Ether* ether)
return;
/*
* Make sure the packet is of minimum length;
* copy it to the card's memory by the appropriate means;
* start the transmission.
*/
len = BLEN(bp);
rp = bp->rp;
if(len < ETHERMINTU){
rp = minpkt;
memmove(rp, bp->rp, len);
memset(rp+len, 0, ETHERMINTU-len);
len = ETHERMINTU;
}
if(ctlr->ram)
memmove((void*)(ether->mem+ctlr->tstart*Dp8390BufSz), rp, len);
memmove((uchar*)KADDR(ether->mem) + ctlr->tstart*Dp8390BufSz, bp->rp, len);
else
dp8390write(ctlr, ctlr->tstart*Dp8390BufSz, rp, len);
dp8390write(ctlr, ctlr->tstart*Dp8390BufSz, bp->rp, len);
freeb(bp);
regw(ctlr, Tbcr0, len & 0xFF);

View file

@ -105,7 +105,8 @@ void mathinit(void);
void mb386(void);
void mb586(void);
void meminit(void);
void memorysummary(void);
void meminit0(void);
void memreserve(uintptr, uintptr);
void mfence(void);
#define mmuflushtlb(pdb) putcr3(pdb)
void mmuinit(void);
@ -158,7 +159,8 @@ int (*_pcmspecial)(char *, ISAConf *);
void pcmspecialclose(int);
void (*_pcmspecialclose)(int);
void pcmunmap(int, PCMmap*);
int pdbmap(ulong*, ulong, ulong, int);
void pmap(ulong, ulong, int);
void punmap(ulong, int);
void procrestore(Proc*);
void procsave(Proc*);
void procsetup(Proc*);
@ -188,13 +190,10 @@ void trapinit(void);
void trapinit0(void);
int tas(void*);
uvlong tscticks(uvlong*);
ulong umbmalloc(ulong, int, int);
void umbfree(ulong, int);
ulong umbrwmalloc(ulong, int, int);
void umbrwfree(ulong, int);
ulong upaalloc(int, int);
void upafree(ulong, int);
void upareserve(ulong, int);
ulong umballoc(ulong, ulong, ulong);
void umbfree(ulong, ulong);
ulong upaalloc(ulong, ulong, ulong);
void upafree(ulong, ulong);
void vectortable(void);
void* vmap(ulong, int);
int vmapsync(ulong);

View file

@ -34,11 +34,12 @@ main(void)
trapinit0();
i8253init();
cpuidentify();
meminit0();
archinit();
meminit();
ramdiskinit();
confinit();
xinit();
archinit();
bootscreeninit();
if(i8237alloc != nil)
i8237alloc();

View file

@ -54,7 +54,7 @@
#define USTKSIZE (16*1024*1024) /* size of user stack */
/*
* Fundamental addresses - bottom 64kB saved for return to real mode
* Fundamental addresses
*/
#define CONFADDR (KZERO+0x1200) /* info passed from boot loader */
#define APBOOTSTRAP (KZERO+0x7000) /* AP bootstrap code (overlaps CONFADDR) */

File diff suppressed because it is too large Load diff

View file

@ -35,6 +35,7 @@ PORT=\
random.$O\
rdb.$O\
rebootcmd.$O\
memmap.$O\
segment.$O\
syscallfmt.$O\
sysfile.$O\

View file

@ -544,6 +544,7 @@ static Lock vmaplock;
static int findhole(ulong *a, int n, int count);
static ulong vmapalloc(ulong size);
static int pdbmap(ulong *, ulong, ulong, int);
static void pdbunmap(ulong*, ulong, int);
/*
@ -679,7 +680,7 @@ vunmap(void *v, int size)
/*
* Add kernel mappings for pa -> va for a section of size bytes.
*/
int
static int
pdbmap(ulong *pdb, ulong pa, ulong va, int size)
{
int pse;
@ -749,6 +750,19 @@ pdbunmap(ulong *pdb, ulong va, int size)
}
}
void
pmap(ulong pa, ulong va, int size)
{
pdbmap(MACHP(0)->pdb, pa, va, size);
}
void
punmap(ulong va, int size)
{
pdbunmap(MACHP(0)->pdb, va, size);
mmuflushtlb(PADDR(m->pdb));
}
/*
* Handle a fault by bringing vmap up to date.
* Only copy pdb entries and they never go away,

View file

@ -1084,7 +1084,7 @@ pcireservemem(void)
for(p=pciroot; p; p=p->list)
for(i=0; i<nelem(p->mem); i++)
if((p->mem[i].bar&~4) != 0 && (p->mem[i].bar&1) == 0)
upareserve(p->mem[i].bar&~0x0F, p->mem[i].size);
upaalloc(p->mem[i].bar&~0x0F, p->mem[i].size, 0);
}
static int

View file

@ -94,6 +94,7 @@ int
screenaperture(int size, int align)
{
VGAscr *scr;
ulong pa;
scr = &vgascreen[0];
@ -113,10 +114,11 @@ screenaperture(int size, int align)
* The driver will tell the card to use it.
*/
size = PGROUND(size);
scr->paddr = upaalloc(size, align);
if(scr->paddr == 0)
pa = upaalloc(-1, size, align);
if(pa == -1)
return -1;
scr->vaddr = vmap(scr->paddr, size);
scr->paddr = pa;
scr->vaddr = vmap(pa, size);
if(scr->vaddr == nil)
return -1;
scr->apsize = size;
@ -482,8 +484,8 @@ vgalinearaddr0(VGAscr *scr, ulong paddr, int size)
if(nsize > 64*MB)
nsize = 64*MB;
scr->vaddr = vmap(npaddr, nsize);
if(scr->vaddr == 0)
return "cannot allocate vga frame buffer";
if(scr->vaddr == nil)
return "cannot map vga frame buffer";
patwc(scr->vaddr, nsize);
@ -576,6 +578,7 @@ bootmapfb(VGAscr *scr, ulong pa, ulong sz)
}
}
}
upaalloc(pa, sz, 0);
return vgalinearaddr0(scr, pa, sz);
}

View file

@ -103,7 +103,8 @@ void mathinit(void);
void mb386(void);
void mb586(void);
void meminit(void);
void memorysummary(void);
void meminit0(void);
void memreserve(uintptr, uintptr);
void mfence(void);
#define mmuflushtlb() putcr3(getcr3())
void mmuinit(void);
@ -157,7 +158,8 @@ int (*_pcmspecial)(char *, ISAConf *);
void pcmspecialclose(int);
void (*_pcmspecialclose)(int);
void pcmunmap(int, PCMmap*);
void pmap(uintptr *, uintptr, uintptr, vlong);
void pmap(uintptr, uintptr, vlong);
void punmap(uintptr, vlong);
void preallocpages(void);
void procrestore(Proc*);
void procsave(Proc*);
@ -187,13 +189,10 @@ void trapinit(void);
void trapinit0(void);
int tas(void*);
uvlong tscticks(uvlong*);
uintptr umbmalloc(uintptr, int, int);
void umbfree(uintptr, int);
uintptr umbrwmalloc(uintptr, int, int);
void umbrwfree(uintptr, int);
uintptr upaalloc(int, int);
void upafree(uintptr, int);
void upareserve(uintptr, int);
ulong umballoc(ulong, ulong, ulong);
void umbfree(ulong, ulong);
ulong upaalloc(ulong, ulong, ulong);
void upafree(ulong, ulong);
void vectortable(void);
void vmxprocrestore(Proc *);
void vmxshutdown(void);

View file

@ -184,11 +184,12 @@ main(void)
trapinit0();
i8253init();
cpuidentify();
meminit0();
archinit();
meminit();
ramdiskinit();
confinit();
xinit();
archinit();
bootscreeninit();
if(i8237alloc != nil)
i8237alloc();

View file

@ -60,7 +60,7 @@
#define KMAPSIZE (2*MiB)
/*
* Fundamental addresses - bottom 64kB saved for return to real mode
* Fundamental addresses
*/
#define CONFADDR (KZERO+0x1200ull) /* info passed from boot loader */
#define APBOOTSTRAP (KZERO+0x7000ull) /* AP bootstrap code */

View file

@ -1,802 +0,0 @@
/*
* Size memory and create the kernel page-tables on the fly while doing so.
* Called from main(), this code should only be run by the bootstrap processor.
*
* MemMin is what the bootstrap code in l.s has already mapped;
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "ureg.h"
u32int MemMin; /* set by l.s */
#define MEMDEBUG 0
enum {
MemUPA = 0, /* unbacked physical address */
MemRAM = 1, /* physical memory */
MemUMB = 2, /* upper memory block (<16MB) */
MemACPI = 3, /* ACPI tables */
MemReserved = 4,
NMemType = 5,
KB = 1024,
};
typedef struct Map Map;
struct Map {
uintptr size;
uintptr addr;
};
typedef struct RMap RMap;
struct RMap {
char* name;
Map* map;
Map* mapend;
Lock;
};
/*
* Memory allocation tracking.
*/
static Map mapupa[64];
static RMap rmapupa = {
"unallocated unbacked physical memory",
mapupa,
&mapupa[nelem(mapupa)-1],
};
static Map mapram[16];
static RMap rmapram = {
"physical memory",
mapram,
&mapram[nelem(mapram)-1],
};
static Map mapumb[64];
static RMap rmapumb = {
"upper memory block",
mapumb,
&mapumb[nelem(mapumb)-1],
};
static Map mapumbrw[16];
static RMap rmapumbrw = {
"UMB device memory",
mapumbrw,
&mapumbrw[nelem(mapumbrw)-1],
};
static Map mapacpi[16];
static RMap rmapacpi = {
"ACPI tables",
mapacpi,
&mapacpi[nelem(mapacpi)-1],
};
void
mapprint(RMap *rmap)
{
Map *mp;
print("%s\n", rmap->name);
for(mp = rmap->map; mp->size; mp++)
print("\t%#p %#p (%#p)\n", mp->addr, mp->addr+mp->size, mp->size);
}
void
memdebug(void)
{
ulong maxpa, maxpa1, maxpa2;
maxpa = (nvramread(0x18)<<8)|nvramread(0x17);
maxpa1 = (nvramread(0x31)<<8)|nvramread(0x30);
maxpa2 = (nvramread(0x16)<<8)|nvramread(0x15);
print("maxpa = %luX -> %luX, maxpa1 = %luX maxpa2 = %luX\n",
maxpa, MB+maxpa*KB, maxpa1, maxpa2);
mapprint(&rmapram);
mapprint(&rmapumb);
mapprint(&rmapumbrw);
mapprint(&rmapupa);
mapprint(&rmapacpi);
}
static void
mapfree(RMap* rmap, uintptr addr, uintptr size)
{
Map *mp;
uintptr t;
if(size <= 0)
return;
lock(rmap);
for(mp = rmap->map; mp->addr <= addr && mp->size; mp++)
;
if(mp > rmap->map && (mp-1)->addr+(mp-1)->size == addr){
(mp-1)->size += size;
if(addr+size == mp->addr){
(mp-1)->size += mp->size;
while(mp->size){
mp++;
(mp-1)->addr = mp->addr;
(mp-1)->size = mp->size;
}
}
}
else{
if(addr+size == mp->addr && mp->size){
mp->addr -= size;
mp->size += size;
}
else do{
if(mp >= rmap->mapend){
print("mapfree: %s: losing %#p, %#p\n",
rmap->name, addr, size);
break;
}
t = mp->addr;
mp->addr = addr;
addr = t;
t = mp->size;
mp->size = size;
mp++;
}while(size = t);
}
unlock(rmap);
}
static uintptr
mapalloc(RMap* rmap, uintptr addr, int size, int align)
{
Map *mp;
uintptr maddr, oaddr;
lock(rmap);
for(mp = rmap->map; mp->size; mp++){
maddr = mp->addr;
if(addr){
/*
* A specific address range has been given:
* if the current map entry is greater then
* the address is not in the map;
* if the current map entry does not overlap
* the beginning of the requested range then
* continue on to the next map entry;
* if the current map entry does not entirely
* contain the requested range then the range
* is not in the map.
*/
if(maddr > addr)
break;
if(mp->size < addr - maddr) /* maddr+mp->size < addr, but no overflow */
continue;
if(addr - maddr > mp->size - size) /* addr+size > maddr+mp->size, but no overflow */
break;
maddr = addr;
}
if(align > 0)
maddr = ((maddr+align-1)/align)*align;
if(mp->addr+mp->size-maddr < size)
continue;
oaddr = mp->addr;
mp->addr = maddr+size;
mp->size -= maddr-oaddr+size;
if(mp->size == 0){
do{
mp++;
(mp-1)->addr = mp->addr;
}while((mp-1)->size = mp->size);
}
unlock(rmap);
if(oaddr != maddr)
mapfree(rmap, oaddr, maddr-oaddr);
return maddr;
}
unlock(rmap);
return 0;
}
/*
* Allocate from the ram map directly to make page tables.
* Called by mmuwalk during e820scan.
*/
void*
rampage(void)
{
uintptr m;
if(conf.mem[0].npage != 0)
return xspanalloc(BY2PG, BY2PG, 0);
m = mapalloc(&rmapram, 0, BY2PG, BY2PG);
if(m == 0)
return nil;
return KADDR(m);
}
static void
umbexclude(void)
{
int size;
ulong addr;
char *op, *p, *rptr;
if((p = getconf("umbexclude")) == nil)
return;
while(p && *p != '\0' && *p != '\n'){
op = p;
addr = strtoul(p, &rptr, 0);
if(rptr == nil || rptr == p || *rptr != '-'){
print("umbexclude: invalid argument <%s>\n", op);
break;
}
p = rptr+1;
size = strtoul(p, &rptr, 0) - addr + 1;
if(size <= 0){
print("umbexclude: bad range <%s>\n", op);
break;
}
if(rptr != nil && *rptr == ',')
*rptr++ = '\0';
p = rptr;
mapalloc(&rmapumb, addr, size, 0);
}
}
static void
umbscan(void)
{
uchar *p;
/*
* Scan the Upper Memory Blocks (0xA0000->0xF0000) for pieces
* which aren't used; they can be used later for devices which
* want to allocate some virtual address space.
* Check for two things:
* 1) device BIOS ROM. This should start with a two-byte header
* of 0x55 0xAA, followed by a byte giving the size of the ROM
* in 512-byte chunks. These ROM's must start on a 2KB boundary.
* 2) device memory. This is read-write.
* There are some assumptions: there's VGA memory at 0xA0000 and
* the VGA BIOS ROM is at 0xC0000. Also, if there's no ROM signature
* at 0xE0000 then the whole 64KB up to 0xF0000 is theoretically up
* for grabs; check anyway.
*/
p = KADDR(0xD0000);
while(p < (uchar*)KADDR(0xE0000)){
/*
* Test for 0x55 0xAA before poking obtrusively,
* some machines (e.g. Thinkpad X20) seem to map
* something dynamic here (cardbus?) causing weird
* problems if it is changed.
*/
if(p[0] == 0x55 && p[1] == 0xAA){
p += p[2]*512;
continue;
}
p[0] = 0xCC;
p[2*KB-1] = 0xCC;
if(p[0] != 0xCC || p[2*KB-1] != 0xCC){
p[0] = 0x55;
p[1] = 0xAA;
p[2] = 4;
if(p[0] == 0x55 && p[1] == 0xAA){
p += p[2]*512;
continue;
}
if(p[0] == 0xFF && p[1] == 0xFF)
mapfree(&rmapumb, PADDR(p), 2*KB);
}
else
mapfree(&rmapumbrw, PADDR(p), 2*KB);
p += 2*KB;
}
p = KADDR(0xE0000);
if(p[0] != 0x55 || p[1] != 0xAA){
p[0] = 0xCC;
p[64*KB-1] = 0xCC;
if(p[0] != 0xCC && p[64*KB-1] != 0xCC)
mapfree(&rmapumb, PADDR(p), 64*KB);
}
umbexclude();
}
int
checksum(void *v, int n)
{
uchar *p, s;
s = 0;
p = v;
while(n-- > 0)
s += *p++;
return s;
}
static void*
sigscan(uchar *addr, int len, char *sig, int size, int step)
{
uchar *e, *p;
int sl;
sl = strlen(sig);
e = addr+len-(size > sl ? size : sl);
for(p = addr; p <= e; p += step){
if(memcmp(p, sig, sl) != 0)
continue;
if(size && checksum(p, size) != 0)
continue;
return p;
}
return nil;
}
static uintptr
convmemsize(void)
{
uintptr top;
uchar *bda;
bda = KADDR(0x400);
top = ((bda[0x14]<<8) | bda[0x13])*KB;
if(top < 64*KB || top > 640*KB)
top = 640*KB; /* sanity */
/* reserved for bios tables (EBDA) */
top -= 1*KB;
return top;
}
void*
sigsearch(char* signature, int size)
{
uintptr p;
uchar *bda;
void *r;
/*
* Search for the data structure:
* 1) within the first KiB of the Extended BIOS Data Area (EBDA), or
* 2) within the last KiB of system base memory if the EBDA segment
* is undefined, or
* 3) within the BIOS ROM address space between 0xf0000 and 0xfffff
* (but will actually check 0xe0000 to 0xfffff).
*/
bda = KADDR(0x400);
if(memcmp(KADDR(0xfffd9), "EISA", 4) == 0){
if((p = (bda[0x0f]<<8)|bda[0x0e]) != 0){
if((r = sigscan(KADDR(p<<4), 1024, signature, size, 16)) != nil)
return r;
}
}
if((r = sigscan(KADDR(convmemsize()), 1024, signature, size, 16)) != nil)
return r;
/* hack for virtualbox: look in KiB below 0xa0000 */
if((r = sigscan(KADDR(0xa0000-1024), 1024, signature, size, 16)) != nil)
return r;
return sigscan(KADDR(0xe0000), 0x20000, signature, size, 16);
}
void*
rsdsearch(void)
{
static char signature[] = "RSD PTR ";
uchar *v, *p;
Map *m;
if((p = sigsearch(signature, 36)) != nil)
return p;
if((p = sigsearch(signature, 20)) != nil)
return p;
for(m = rmapacpi.map; m < rmapacpi.mapend && m->size; m++){
if(m->size > 0x7FFFFFFF)
continue;
if((v = vmap(m->addr, m->size)) != nil){
p = sigscan(v, m->size, signature, 36, 4);
if(p == nil)
p = sigscan(v, m->size, signature, 20, 4);
vunmap(v, m->size);
if(p != nil)
return vmap(m->addr + (p - v), 64);
}
}
return nil;
}
static void
lowraminit(void)
{
uintptr pa, x;
/*
* Initialise the memory bank information for conventional memory
* (i.e. less than 640KB). The base is the first location after the
* bootstrap processor MMU information and the limit is obtained from
* the BIOS data area.
*/
x = PADDR(CPU0END);
pa = convmemsize();
if(x < pa){
mapfree(&rmapram, x, pa-x);
memset(KADDR(x), 0, pa-x); /* keep us honest */
}
x = PADDR(PGROUND((uintptr)end));
pa = MemMin;
if(x > pa)
panic("kernel too big");
mapfree(&rmapram, x, pa-x);
memset(KADDR(x), 0, pa-x); /* keep us honest */
}
static void
map(uintptr base, uintptr len, int type)
{
uintptr n, flags, maxkpa;
/*
* Split any call crossing MemMin to make below simpler.
*/
if(base < MemMin && len > MemMin-base){
n = MemMin - base;
map(base, n, type);
map(MemMin, len-n, type);
}
/*
* Let umbscan hash out the low MemMin.
*/
if(base < MemMin)
return;
/*
* Any non-memory below 16*MB is used as upper mem blocks.
*/
if(type == MemUPA && base < 16*MB && len > 16*MB-base){
map(base, 16*MB-base, MemUMB);
map(16*MB, len-(16*MB-base), MemUPA);
return;
}
/*
* Memory below CPU0END is reserved for the kernel
* and already mapped.
*/
if(base < PADDR(CPU0END)){
n = PADDR(CPU0END) - base;
if(len <= n)
return;
map(PADDR(CPU0END), len-n, type);
return;
}
/*
* Memory between KTZERO and end is the kernel itself
* and is already mapped.
*/
if(base < PADDR(KTZERO) && len > PADDR(KTZERO)-base){
map(base, PADDR(KTZERO)-base, type);
return;
}
if(PADDR(KTZERO) < base && base < PADDR(PGROUND((uintptr)end))){
n = PADDR(PGROUND((uintptr)end));
if(len <= n)
return;
map(PADDR(PGROUND((uintptr)end)), len-n, type);
return;
}
/*
* Now we have a simple case.
*/
switch(type){
case MemRAM:
mapfree(&rmapram, base, len);
flags = PTEWRITE|PTENOEXEC|PTEVALID;
break;
case MemUMB:
mapfree(&rmapumb, base, len);
flags = PTEWRITE|PTEUNCACHED|PTENOEXEC|PTEVALID;
break;
case MemUPA:
mapfree(&rmapupa, base, len);
flags = 0;
break;
case MemACPI:
mapfree(&rmapacpi, base, len);
flags = 0;
break;
case MemReserved:
default:
flags = 0;
break;
}
if(flags){
maxkpa = -KZERO;
if(base >= maxkpa)
return;
if(len > maxkpa-base)
len = maxkpa - base;
pmap(m->pml4, base|flags, base+KZERO, len);
}
}
typedef struct Emap Emap;
struct Emap
{
int type;
uvlong base;
uvlong top;
};
static Emap emap[128];
static int nemap;
static int
emapcmp(const void *va, const void *vb)
{
Emap *a, *b;
a = (Emap*)va;
b = (Emap*)vb;
if(a->top < b->top)
return -1;
if(a->top > b->top)
return 1;
if(a->base < b->base)
return -1;
if(a->base > b->base)
return 1;
return 0;
}
static void
e820clean(void)
{
Emap *e;
int i, j;
qsort(emap, nemap, sizeof emap[0], emapcmp);
for(i=j=0; i<nemap; i++){
e = &emap[i];
/* merge adjacent entries of the same type */
if(i+1 < nemap && e[0].top == e[1].base && e[0].type == e[1].type){
e[1].base = e[0].base;
continue;
}
memmove(&emap[j++], e, sizeof *e);
}
nemap = j;
}
static int
e820scan(void)
{
uintptr base, len, last;
Emap *e;
char *s;
int i;
/* passed by bootloader */
if((s = getconf("*e820")) == nil)
if((s = getconf("e820")) == nil)
return -1;
nemap = 0;
while(nemap < nelem(emap)){
while(*s == ' ')
s++;
if(*s == 0)
break;
e = emap + nemap;
e->type = 1;
if(s[1] == ' '){ /* new format */
e->type = s[0] - '0';
s += 2;
}
e->base = strtoull(s, &s, 16);
if(*s != ' ')
break;
e->top = strtoull(s, &s, 16);
if(*s != ' ' && *s != 0)
break;
if(e->base >= e->top)
continue;
if(++nemap == nelem(emap))
e820clean();
}
e820clean();
if(nemap == 0)
return -1;
last = 0;
for(i=0; i<nemap; i++){
e = &emap[i];
if(e->top <= last)
continue;
if(e->base < last)
base = last;
else
base = e->base;
len = e->top - base;
/*
* If the map skips addresses, mark them available.
*/
if(last < base)
map(last, base-last, MemUPA);
switch(e->type){
case 1:
map(base, len, MemRAM);
break;
case 3:
map(base, len, MemACPI);
break;
default:
map(base, len, MemReserved);
}
last = base + len;
if(last == 0)
break;
}
if(last != 0)
map(last, -last, MemUPA);
return 0;
}
void
meminit(void)
{
int i;
Map *mp;
Confmem *cm;
uintptr lost;
umbscan();
lowraminit();
e820scan();
/*
* Set the conf entries describing banks of allocatable memory.
*/
for(i=0; i<nelem(mapram) && i<nelem(conf.mem); i++){
mp = &rmapram.map[i];
cm = &conf.mem[i];
cm->base = mp->addr;
cm->npage = mp->size/BY2PG;
}
lost = 0;
for(; i<nelem(mapram); i++)
lost += rmapram.map[i].size;
if(lost)
print("meminit - lost %llud bytes\n", lost);
if(MEMDEBUG)
memdebug();
}
/*
* Allocate memory from the upper memory blocks.
*/
uintptr
umbmalloc(uintptr addr, int size, int align)
{
uintptr a;
if(a = mapalloc(&rmapumb, addr, size, align))
return (uintptr)KADDR(a);
return 0;
}
void
umbfree(uintptr addr, int size)
{
mapfree(&rmapumb, PADDR(addr), size);
}
uintptr
umbrwmalloc(uintptr addr, int size, int align)
{
uintptr a;
uchar *p;
if(a = mapalloc(&rmapumbrw, addr, size, align))
return (uintptr)KADDR(a);
/*
* Perhaps the memory wasn't visible before
* the interface is initialised, so try again.
*/
if((a = umbmalloc(addr, size, align)) == 0)
return 0;
p = (uchar*)a;
p[0] = 0xCC;
p[size-1] = 0xCC;
if(p[0] == 0xCC && p[size-1] == 0xCC)
return a;
umbfree(a, size);
return 0;
}
void
umbrwfree(uintptr addr, int size)
{
mapfree(&rmapumbrw, PADDR(addr), size);
}
/*
* Give out otherwise-unused physical address space
* for use in configuring devices. Note that upaalloc
* does not map the physical address into virtual memory.
* Call vmap to do that.
*/
uintptr
upaalloc(int size, int align)
{
uintptr a;
a = mapalloc(&rmapupa, 0, size, align);
if(a == 0){
print("out of physical address space allocating %d\n", size);
mapprint(&rmapupa);
}
return a;
}
void
upafree(uintptr pa, int size)
{
mapfree(&rmapupa, pa, size);
}
void
upareserve(uintptr pa, int size)
{
uintptr a;
a = mapalloc(&rmapupa, pa, size, 0);
if(a != pa){
/*
* This can happen when we're using the E820
* map, which might have already reserved some
* of the regions claimed by the pci devices.
*/
// print("upareserve: cannot reserve pa=%#p size=%d\n", pa, size);
if(a != 0)
mapfree(&rmapupa, a, size);
}
}
void
memorysummary(void)
{
memdebug();
}

View file

@ -22,6 +22,7 @@ PORT=\
dev.$O\
edf.$O\
fault.$O\
memmap.$O\
page.$O\
parse.$O\
pgrp.$O\

View file

@ -344,7 +344,7 @@ kernelro(void)
}
void
pmap(uintptr *pml4, uintptr pa, uintptr va, vlong size)
pmap(uintptr pa, uintptr va, vlong size)
{
uintptr *pte, *ptee, flags;
int z, l;
@ -361,9 +361,9 @@ pmap(uintptr *pml4, uintptr pa, uintptr va, vlong size)
flags |= PTESIZE;
l = (flags & PTESIZE) != 0;
z = PGLSZ(l);
pte = mmuwalk(pml4, va, l, 1);
if(pte == 0){
pte = mmuwalk(pml4, va, ++l, 0);
pte = mmuwalk(m->pml4, va, l, 1);
if(pte == nil){
pte = mmuwalk(m->pml4, va, ++l, 0);
if(pte && (*pte & PTESIZE)){
flags |= PTESIZE;
z = va & (PGLSZ(l)-1);
@ -384,6 +384,29 @@ pmap(uintptr *pml4, uintptr pa, uintptr va, vlong size)
}
}
void
punmap(uintptr va, vlong size)
{
uintptr *pte;
int l;
va = PPN(va);
while(size > 0){
if((va % PGLSZ(1)) != 0 || size < PGLSZ(1))
ptesplit(m->pml4, va);
l = 0;
pte = mmuwalk(m->pml4, va, l, 0);
if(pte == nil && (va % PGLSZ(1)) == 0 && size >= PGLSZ(1))
pte = mmuwalk(m->pml4, va, ++l, 0);
if(pte){
*pte = 0;
invlpg(va);
}
va += PGLSZ(l);
size -= PGLSZ(l);
}
}
static void
mmuzap(void)
{
@ -584,7 +607,7 @@ vmap(uintptr pa, int size)
pa -= o;
va -= o;
size += o;
pmap(m->pml4, pa | PTEUNCACHED|PTEWRITE|PTENOEXEC|PTEVALID, va, size);
pmap(pa | PTEUNCACHED|PTEWRITE|PTENOEXEC|PTEVALID, va, size);
return (void*)(va+o);
}
@ -667,7 +690,7 @@ preallocpages(void)
pm->npage = (top - pm->base)/BY2PG;
va = base + VMAP;
pmap(m->pml4, base | PTEGLOBAL|PTEWRITE|PTENOEXEC|PTEVALID, va, psize);
pmap(base | PTEGLOBAL|PTEWRITE|PTENOEXEC|PTEVALID, va, psize);
palloc.pages = (void*)(va + tsize);

271
sys/src/9/port/memmap.c Normal file
View file

@ -0,0 +1,271 @@
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
enum {
Allocated = 1UL<<31,
};
typedef struct Mapent Mapent;
struct Mapent
{
ulong type;
uvlong addr;
uvlong size;
};
static struct {
Lock;
int n;
int m;
Mapent a[256];
} mapalloc;
static void
dump1(Mapent *e)
{
print("%.16llux-%.16llux %lux\n", e->addr, e->addr + e->size, e->type);
}
static int
insert(uvlong addr, uvlong size, ulong type)
{
Mapent *e;
if(size == 0 || addr == -1 || addr + size-1 < addr)
return 0;
if(mapalloc.n+mapalloc.m >= nelem(mapalloc.a))
return 0;
e = &mapalloc.a[mapalloc.n + mapalloc.m++];
e->type = type;
e->addr = addr;
e->size = size;
return 1;
}
static Mapent*
lookup(uvlong addr)
{
Mapent *i, *e;
if(addr == -1)
return nil;
for(i = mapalloc.a, e = i + mapalloc.n; i < e; i++){
if(i->addr > addr)
break;
if(addr - i->addr < i->size)
return i;
}
return nil;
}
static int
compare(void *a, void *b)
{
Mapent *ma = a, *mb = b;
if(ma->addr < mb->addr)
return -1;
if(ma->addr > mb->addr)
return 1;
if(ma->type < mb->type)
return -1;
if(ma->type > mb->type)
return 1;
return 0;
}
static void
sort(void)
{
Mapent *d, *i, *j, *e;
Again:
if(mapalloc.m == 0)
return;
mapalloc.n += mapalloc.m;
mapalloc.m = 0;
qsort(mapalloc.a, mapalloc.n, sizeof(*e), compare);
d = i = mapalloc.a;
e = i + mapalloc.n;
while(i < e){
if(i->size == 0)
goto Skip;
for(j = i+1; j < e; j++){
if(j->size == 0)
continue;
if(j->addr - i->addr >= i->size)
break;
if(j->type <= i->type){
if(j->addr - i->addr + j->size <= i->size)
j->size = 0;
else {
j->size -= i->addr + i->size - j->addr;
j->addr = i->addr + i->size;
}
continue;
}
if(j->addr - i->addr + j->size < i->size)
if(!insert(j->addr + j->size, i->size - (j->addr + j->size - i->addr), i->type))
continue;
i->size = j->addr - i->addr;
if(i->size == 0)
goto Skip;
}
if(d > mapalloc.a){
j = d-1;
if(i->addr - j->addr == j->size && i->type == j->type){
j->size += i->size;
i->size = 0;
goto Skip;
}
}
memmove(d, i, sizeof(*i));
d++;
Skip:
i++;
}
if(mapalloc.m > 0)
memmove(d, e, mapalloc.m*sizeof(*e));
mapalloc.n = d - mapalloc.a;
goto Again;
}
void
memmapdump(void)
{
int i;
lock(&mapalloc);
sort();
for(i = 0; i < mapalloc.n; i++)
dump1(&mapalloc.a[i]);
unlock(&mapalloc);
}
uvlong
memmapnext(uvlong addr, ulong type)
{
Mapent *i, *e;
lock(&mapalloc);
sort();
for(i = mapalloc.a, e = i+mapalloc.n; i < e; i++){
if(((i->type ^ type) & ~Allocated) == 0
&& (addr == -1 || i->addr > addr)){
addr = i->addr;
unlock(&mapalloc);
return addr;
}
}
unlock(&mapalloc);
return -1;
}
uvlong
memmapsize(uvlong addr, uvlong align)
{
Mapent *i;
uvlong size;
size = 0;
lock(&mapalloc);
sort();
if((i = lookup(addr)) != nil){
if(align){
addr += align-1;
addr &= ~(align-1);
}
if(addr - i->addr < i->size)
size = i->size - (addr - i->addr);
}
unlock(&mapalloc);
return size;
}
void
memmapadd(uvlong addr, uvlong size, ulong type)
{
type &= ~Allocated;
lock(&mapalloc);
if(insert(addr, size, type))
if(mapalloc.n+mapalloc.m >= nelem(mapalloc.a)-1)
sort();
unlock(&mapalloc);
}
uvlong
memmapalloc(uvlong addr, uvlong size, uvlong align, ulong type)
{
Mapent *i, *e;
type &= ~Allocated;
lock(&mapalloc);
sort();
if(addr != -1){
i = lookup(addr);
if(i == nil || i->type != type)
goto Fail;
if(align){
addr += align-1;
addr &= ~(align-1);
if(addr - i->addr >= i->size)
goto Fail;
}
if(addr - i->addr + size > i->size)
goto Fail;
Alloc:
if(size > 0 && !insert(addr, size, type|Allocated))
goto Fail;
unlock(&mapalloc);
return addr;
}
e = mapalloc.a + mapalloc.n;
for(i = mapalloc.a; i < e; i++){
if(i->type != type)
continue;
addr = i->addr;
if(align){
addr += align-1;
addr &= ~(align-1);
if(addr - i->addr >= i->size)
continue;
}
if(addr - i->addr + size <= i->size)
goto Alloc;
}
Fail:
unlock(&mapalloc);
return -1;
}
void
memmapfree(uvlong addr, uvlong size, ulong type)
{
Mapent *i;
lock(&mapalloc);
sort();
i = lookup(addr);
if(i == nil
|| i->type != (type|Allocated)
|| addr - i->addr + size > i->size){
unlock(&mapalloc);
return;
}
if(i->addr < addr)
insert(i->addr, addr - i->addr, i->type);
if(addr - i->addr + size < i->size)
insert(addr+size, addr - i->addr + i->size - size, i->type);
i->type &= ~Allocated;
unlock(&mapalloc);
}

View file

@ -168,6 +168,12 @@ void* malloc(ulong);
void* mallocalign(ulong, ulong, long, ulong);
void mallocsummary(void);
Block* mem2bl(uchar*, int);
void memmapdump(void);
uvlong memmapnext(uvlong, ulong);
uvlong memmapsize(uvlong, uvlong);
void memmapadd(uvlong, uvlong, ulong);
uvlong memmapalloc(uvlong, uvlong, uvlong, ulong);
void memmapfree(uvlong, uvlong, ulong);
ulong mcountseg(Segment*);
void mfreeseg(Segment*, uintptr, ulong);
void microdelay(int);

View file

@ -89,10 +89,11 @@ mmusweep(void*)
sweepcolor = m->sweepcolor;
x = splhi();
p = proctab(0);
for(i = 0; i < conf.nproc; i++, p++)
for(i = 0; i < conf.nproc; i++){
p = proctab(i);
if(PIDCOLOR(p->mmupid) == sweepcolor)
p->mmupid = 0;
}
splx(x);
ptab = (ulong*)m->ptabbase;
@ -125,9 +126,10 @@ newmmupid(void)
m->mmupid = PIDBASE;
x = splhi();
tlbflushall();
p = proctab(0);
for(i = 0; i < conf.nproc; i++, p++)
for(i = 0; i < conf.nproc; i++){
p = proctab(i);
p->mmupid = 0;
}
splx(x);
wakeup(&m->sweepr);
}

View file

@ -190,7 +190,7 @@ extern void ucfreeb(Block*);
/*
* Things called from port.
*/
extern void delay(int); /* only scheddump() */
extern void delay(int);
extern int islo(void);
extern void microdelay(int); /* only edf.c */
extern void evenaddr(uintptr);