to track page-overlapping vmaps such as acpi produces, introduce vmapoverlap() as a temporary measure. this is a slightly better rearrangment of previous code to prepare for acpi-only (no mp tables) booting. Reference: /n/atom/patch/applied2013/vmapoverlap Date: Thu Aug 22 23:35:32 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/nix/k10/fns.h Thu Aug 22 23:34:00 2013 +++ /sys/src/nix/k10/fns.h Thu Aug 22 23:34:01 2013 @@ -1,5 +1,4 @@ #include "../port/portfns.h" -void aamloop(int); int acpiinit(void); Dirtab* addarchfile(char*, int, long(*)(Chan*, void*, long, vlong), long(*)(Chan*, void*, long, vlong)); void adrinit(void); @@ -119,6 +118,7 @@ int userureg(Ureg*); void* vmap(uintmem, usize); void* vmappat(uintmem, usize, uint); +void* vmapoverlap(uintmem, usize); int vmapsync(uintptr); void vsvminit(int); void vunmap(void*, usize); --- /sys/src/nix/k10/mmu.c Thu Aug 22 23:34:02 2013 +++ /sys/src/nix/k10/mmu.c Thu Aug 22 23:34:03 2013 @@ -650,6 +650,51 @@ return vmap(pa, size); } +/* + * sleezy code to deal with overlapping page-size vmaps. + * this is currently necessary because acpi maps overlap. + * please remove this by either just mapping all acpi + * memory (can we count on good acpi tables?), or + * keeping one map at a time. + * assume boot time, omit locks. + */ +typedef struct Remap Remap; +struct Remap { + uintmem map[150]; + usize n; +}; +static Remap smap; + +void* +vmapoverlap(uintmem pa0, usize size) +{ + int i, o; + uintmem pa, p; + + o = pa0 - (pa0 & ~(PGSZ-1)); + pa = pa0 - o; + size = ROUNDUP(size+o, PGSZ); + + if(pa+size < 1ull*MiB) + return KADDR(pa); + if(pa < 1ull*MiB) + return nil; + for(p = pa; p < pa+size; p += PGSZ){ + for(i = 0; i < smap.n; i++) + if(p == smap.map[i]) + break; + if(i == smap.n){ + if(smap.n == nelem(smap.map)) + panic("smap.map too small %ld", smap.n); + if(vmap(p, PGSZ) == nil) + return nil; + smap.map[smap.n++] = p; + } + } + /* sleezy assumption, we know everything's direct mapped at KSEG2 */ + return UINT2PTR(KSEG2 + pa0); +} + void vunmap(void* v, usize size) { --- /sys/src/nix/k10/devacpi.c Thu Aug 22 23:34:05 2013 +++ /sys/src/nix/k10/devacpi.c Thu Aug 22 23:34:06 2013 @@ -424,49 +424,6 @@ return nil; } -/* - * sleezy code to deal with overlapping allocations. - * please remove this by either just mapping all acpi - * memory (can we count on good acpi tables?), or - * keeping one map at a time. - */ -typedef struct Sdtmap Sdtmap; -struct Sdtmap { - uintmem map[150]; - uint n; -}; -static Sdtmap smap; - -static void* -findmap(uintmem pa0, uint size) -{ - int i, o; - uintmem pa, p; - - o = pa0 - (pa0 & ~(PGSZ-1)); - pa = pa0 - o; - size = ROUNDUP(size+o, PGSZ); - - if(pa+size < 1ull*MiB) - return KADDR(pa); - if(pa < 1ull*MiB) - return nil; - for(p = pa; p < pa+size; p += PGSZ){ - for(i = 0; i < smap.n; i++) - if(p == smap.map[i]) - break; - if(i == smap.n){ - if(smap.n == nelem(smap.map)) - panic("smap.map too small %d", smap.n); - if(vmap(p, PGSZ) == nil) - return nil; - smap.map[smap.n++] = p; - } - } - /* sleezy assumption, we know everything's direct mapped at KSEG2 */ - return UINT2PTR(KSEG2 + pa0); -} - static void sdtunmap(void *va, usize sz) { @@ -479,9 +436,9 @@ { Sdthdr* sdt; - sdt = findmap(pa, sizeof *sdt); + sdt = vmapoverlap(pa, sizeof *sdt); if(sdt == nil){ - DBG("acpi: findmap: nil\n"); + DBG("acpi: vmapoverlap: nil\n"); return nil; } *n = l32get(sdt->length); @@ -495,8 +452,8 @@ } sdtunmap(sdt, sizeof(Sdthdr)); - if((sdt = findmap(pa, *n)) == nil){ - DBG("acpi: findmap: nil\n"); + if((sdt = vmapoverlap(pa, *n)) == nil){ + DBG("acpi: vmapoverlap: nil\n"); return nil; } if(cksum != 0 && sdtchecksum(sdt, *n) == nil){