M pc/devastar.c => pc/devastar.c +3 -0
@@ 417,6 417,9 @@ astarreset(void)
a->irq = 15;
a->id = i;
+ if(isaget(a->mem, Pagesize, 0) == 0)
+ panic("astarreset: %lux", a->mem);
+
if(astarsetup(a) < 0){
xfree(a);
astar[nastar] = 0;
M pc/devi82365.c => pc/devi82365.c +3 -1
@@ 316,7 316,9 @@ getmap(Slot *pp, ulong offset, int attr)
/* grab ISA address space for memory maps */
for(i = 0; i < Nmap; i++)
- pp->mmap[i].isa = isamem(Mchunk);
+ pp->mmap[i].isa = getisa(0, Mchunk, BY2PG);
+ if(pp->mmap[i].isa == 0)
+ panic("getmap");
}
/* look for a map that starts in the right place */
M pc/ether8003.c => pc/ether8003.c +3 -0
@@ 190,6 190,9 @@ reset(Ether *ether)
}
dp8390setea(ether);
+ if(getisa(ether->mem, ether->size, 0) == 0)
+ panic("ether8003: %lux reused", ether->mem);
+
return 0;
}
M pc/fns.h => pc/fns.h +2 -1
@@ 42,7 42,8 @@ ulong inl(int);
void insl(int, void*, int);
int iprint(char*, ...);
int isaconfig(char*, int, ISAConf*);
-ulong isamem(int);
+ulong getisa(ulong, int, int);
+void putisa(ulong, int);
void kbdinit(void);
long* mapaddr(ulong);
void mathinit(void);
M pc/main.c => pc/main.c +36 -1
@@ 313,11 313,37 @@ memclrtest(int meg, int len, long seed)
for(n = 0; n < BY2PG/BY2WD; n++)
if(lp[n] != ~(seed + (n^((BY2PG/BY2WD)-1))))
return -1;
- memset(lp, '!', BY2PG);
+/* memset(lp, '!', BY2PG);/**/
}
return 0;
}
+/*
+ * look for unused address space in 0xC8000 to 1 meg
+ */
+void
+romscan(void)
+{
+ uchar *p;
+
+ p = (uchar*)(KZERO+0xC8000);
+ while(p < (uchar*)(KZERO+0xE0000)){
+ p[0] = 0x55;
+ p[1] = 0xAA;
+ p[2] = 4;
+ if(p[0] != 0x55 || p[1] != 0xAA){
+ putisa(PADDR(p), 2048);
+ p += 2048;
+ continue;
+ }
+ p += p[2]*512;
+ }
+
+ p = (uchar*)(KZERO+0xE0000);
+ if(p[0] != 0x55 || p[1] != 0xAA)
+ putisa(PADDR(p), 64*1024);
+}
+
void
confinit(void)
{
@@ 360,6 386,7 @@ confinit(void)
nconf++;
}
+
/*
* size memory above 1 meg. Kernel sits at 1 meg. We
* only recognize MB size chunks.
@@ 437,6 464,14 @@ confinit(void)
break;
}
+ /*
+ * add address space holes holes under 16 meg to available
+ * isa space.
+ */
+ romscan();
+ if(conf.topofmem < 16*MB)
+ putisa(conf.topofmem, 16*MB - conf.topofmem);
+
conf.npage = conf.npage0 + conf.npage1;
conf.ldepth = 0;
if(pcnt < 10)
M pc/mmu.c => pc/mmu.c +76 -19
@@ 88,12 88,15 @@ static ulong *kpt; /* 2nd level page tables for kernel mem */
#define MAXUMEG 64 /* maximum memory per user process in megabytes */
#define ONEMEG (1024*1024)
+enum {
+ Nisa= 256,
+};
struct
{
Lock;
- ulong addr; /* next available address for isa bus memory */
- ulong end; /* one past available isa bus memory */
-} isamemalloc;
+ ulong s[Nisa];
+ ulong e[Nisa];
+} isaalloc;
/*
* Change current page table and the stack to use for exceptions
@@ 149,10 152,8 @@ mmuinit(void)
ktoppg.va = (ulong)top;
ktoppg.pa = ktoppg.va & ~KZERO;
- /* map all memory to KZERO (add some address space for ISA memory) */
- isamemalloc.addr = 0xd8000;
- isamemalloc.end = 0xe0000;
- npage = 64*MB/BY2PG;
+ /* map all memory to KZERO */
+ npage = 128*MB/BY2PG;
nbytes = PGROUND(npage*BY2WD); /* words of page map */
nkpt = nbytes/BY2PG; /* pages of page map */
kpt = xspanalloc(nbytes, BY2PG, 0);
@@ 336,23 337,79 @@ putmmu(ulong va, ulong pa, Page *pg)
}
/*
+ * make isa address space available
+ */
+void
+putisa(ulong addr, int len)
+{
+ ulong e;
+ int i, hole;
+
+ addr &= ~KZERO;
+
+ e = addr + len;
+ lock(&isaalloc);
+ hole = -1;
+ for(i = 0; i < Nisa; i++){
+ if(isaalloc.s[i] == e){
+ isaalloc.s[i] = addr;
+ break;
+ }
+ if(isaalloc.e[i] == addr){
+ isaalloc.e[i] = e;
+ break;
+ }
+ if(isaalloc.s[i] == 0)
+ hole = i;
+ }
+ if(i >= Nisa && hole >= 0){
+ isaalloc.s[hole] = addr;
+ isaalloc.e[hole] = e;
+ }
+ unlock(&isaalloc);
+}
+
+/*
* allocate some address space (already mapped into the kernel)
* for ISA bus memory.
*/
ulong
-isamem(int len)
+getisa(ulong addr, int len, int align)
{
- ulong a, x;
-
- lock(&isamemalloc);
- len = PGROUND(len);
- x = isamemalloc.addr + len;
- if(x > isamemalloc.end)
- panic("isamem");
- a = isamemalloc.addr;
- isamemalloc.addr = x;
- unlock(&isamemalloc);
- return a;
+ int i;
+ ulong os, s, e;
+
+ lock(&isaalloc);
+ os = s = e = 0;
+ for(i = 0; i < Nisa; i++){
+ s = os = isaalloc.s[i];
+ if(s == 0)
+ continue;
+ e = isaalloc.e[i];
+ if(addr && addr >= s && addr < isaalloc.e[i])
+ break;
+ if(align > 0)
+ s = ((s + align - 1)/align)*align;
+ if(e - s >= len)
+ break;
+ }
+ if(i >= Nisa){
+ unlock(&isaalloc);
+ return 0;
+ }
+
+ /* remove */
+ isaalloc.s[i] = 0;
+ unlock(&isaalloc);
+
+ /* give back edges */
+ if(s != os)
+ putisa(os, s - os);
+ os = s + len;
+ if(os != e)
+ putisa(os, e - os);
+
+ return KZERO|s;
}
/*