void physallocinit(void) { uintmem top, avail, base, size, lim, pa, lo, hi; RMapel *e; if(DBGFLG) rmapprint(&rmapram); avail = rmapsize(&rmapram); DBG("avail: %#P\n", avail); top = 0; for(e = rmapram.map; e != nil; e = e->next) top = e->addr + e->size; if(top > 4ull*GiB){ physgig = bpoolcreate(MidK, MaxK, 4ull*GiB, top, alloc0); phys = bpoolcreate(MinK, MaxK, 0, 4ull*GiB, alloc0); }else phys = bpoolcreate(MinK, MaxK, 0, top, alloc0); pa = mmuphysaddr(sys->vmstart) + sys->pmunassigned; if(DBGFLG) rmapprint(&rmapram); DBG("pa lim: %#llux top %#llux\n", pa, top); while(rmapfirst(&rmapram, pa, &base, &size)){ if(base >= 4ull*GiB) break; lim = base+size; if(lim > 4ull*GiB) lim = 4ull*GiB; lo = ROUNDUP(base, (1<<MinK)); hi = ROUNDDN(lim, (1<<MinK)); if(lo != hi){ DBG("lo=%#llux hi=%#llux\n", lo, hi); pa = rmapalloc(&rmapram, lo, hi-lo, 0); if(pa == 0) break; physinitfree(lo, hi); sys->pmpaged += hi - lo; } } if(DBGFLG) physdump(); }
void asmmeminit(void) { Proc *up = externup(); int i, l; Asm* assem; PTE *pte, *pml4; uintptr va; uintmem hi, lo, mem, nextmem, pa; #ifdef ConfCrap int cx; #endif /* ConfCrap */ assert(!((sys->vmunmapped|sys->vmend) & machp()->pgszmask[1])); if((pa = mmuphysaddr(sys->vmunused)) == ~0) panic("asmmeminit 1"); pa += sys->vmunmapped - sys->vmunused; mem = asmalloc(pa, sys->vmend - sys->vmunmapped, 1, 0); if(mem != pa) panic("asmmeminit 2"); DBG("pa %#llux mem %#llux\n", pa, mem); /* assume already 2MiB aligned*/ assert(ALIGNED(sys->vmunmapped, 2*MiB)); pml4 = UINT2PTR(machp()->pml4->va); while(sys->vmunmapped < sys->vmend) { l = mmuwalk(pml4, sys->vmunmapped, 1, &pte, asmwalkalloc); DBG("%#p l %d\n", sys->vmunmapped, l); *pte = pa|PtePS|PteRW|PteP; sys->vmunmapped += 2*MiB; pa += 2*MiB; } #ifdef ConfCrap cx = 0; #endif /* ConfCrap */ for(assem = asmlist; assem != nil; assem = assem->next) { if(assem->type != AsmMEMORY) continue; va = KSEG2+assem->addr; print("asm: addr %#P end %#P type %d size %P\n", assem->addr, assem->addr+assem->size, assem->type, assem->size); lo = assem->addr; hi = assem->addr+assem->size; /* Convert a range into pages */ for(mem = lo; mem < hi; mem = nextmem) { nextmem = (mem + PGLSZ(0)) & ~machp()->pgszmask[0]; /* Try large pages first */ for(i = m->npgsz - 1; i >= 0; i--) { if((mem & machp()->pgszmask[i]) != 0) continue; if(mem + PGLSZ(i) > hi) continue; /* This page fits entirely within the range. */ /* Mark it a usable */ if((l = mmuwalk(pml4, va, i, &pte, asmwalkalloc)) < 0) panic("asmmeminit 3"); *pte = mem|PteRW|PteP; if(l > 0) *pte |= PtePS; nextmem = mem + PGLSZ(i); va += PGLSZ(i); npg[i]++; break; } } #ifdef ConfCrap /* * Fill in conf crap. */ if(cx >= nelem(conf.mem)) continue; lo = ROUNDUP(assem->addr, PGSZ); //if(lo >= 600ull*MiB) // continue; conf.mem[cx].base = lo; hi = ROUNDDN(hi, PGSZ); //if(hi > 600ull*MiB) // hi = 600*MiB; conf.mem[cx].npage = (hi - lo)/PGSZ; conf.npage += conf.mem[cx].npage; print("cm %d: addr %#llux npage %lud\n", cx, conf.mem[cx].base, conf.mem[cx].npage); cx++; #endif /* ConfCrap */ } print("%d %d %d\n", npg[0], npg[1], npg[2]); #ifdef ConfCrap /* * Fill in more conf crap. * This is why I hate Plan 9. */ conf.upages = conf.npage; i = (sys->vmend - sys->vmstart)/PGSZ; /* close enough */ conf.ialloc = (i/2)*PGSZ; print("npage %llud upage %lud kpage %d\n", conf.npage, conf.upages, i); #endif /* ConfCrap */ }