Implement general VA2PA

This commit is contained in:
Ali Mashtizadeh 2014-12-29 20:14:46 -08:00
parent 2083b5f44e
commit 28fa88ef3c
2 changed files with 50 additions and 1 deletions

View File

@ -42,7 +42,7 @@
#define DMVA2PPN(dmva) (((dmva) - MEM_DIRECTMAP_BASE) >> PGSIZE)
#define DMVA2PA(dmva) ((dmva) - MEM_DIRECTMAP_BASE)
#define DMPA2VA(pa) ((pa) + MEM_DIRECTMAP_BASE)
//#define VA2PA(va)
#define VA2PA(va) PMap_Translate(va)
typedef struct AS AS;
@ -52,6 +52,8 @@ void PMap_DestroyAS(AS *space);
void PMap_LoadAS(AS *space);
void PMap_Dump(AS *space);
uintptr_t PMap_Translate(uintptr_t va);
// Manipulate User Memory
bool PMap_Map(AS *as, uint64_t phys, uint64_t virt, uint64_t pages, uint64_t flags);
bool PMap_AllocMap(AS *as, uint64_t virt, uint64_t len, uint64_t flags);

View File

@ -136,6 +136,53 @@ PMapAllocPageTable()
return pgtbl;
}
uintptr_t
PMap_Translate(uintptr_t va)
{
int i,j,k,l;
PageTable *table = systemAS.root;
PageEntry pte;
PageEntry *entry;
i = (va >> (HUGE_PGSHIFT + PGIDXSHIFT)) & PGIDXMASK;
j = (va >> HUGE_PGSHIFT) & PGIDXMASK;
k = (va >> LARGE_PGSHIFT) & PGIDXMASK;
l = (va >> PGSHIFT) & PGIDXMASK;
pte = table->entries[i];
if (pte == 0) {
ASSERT(pte);
return 0;
}
table = (PageTable *)DMPA2VA(pte & 0xFFFFFFFFFFFFF000);
pte = table->entries[j];
// XXX: Support 1GB pages
if (pte == 0) {
ASSERT(pte);
return 0;
}
table = (PageTable *)DMPA2VA(pte & 0xFFFFFFFFFFFFF000);
pte = table->entries[k];
if ((pte & PTE_PS) == PTE_PS) {
// Handle 2MB pages
entry = &table->entries[k];
return (*entry & ~(LARGE_PGMASK | PTE_NX)) + (va & LARGE_PGMASK);
}
if (pte == 0) {
ASSERT(pte);
return 0;
}
table = (PageTable *)DMPA2VA(pte & 0xFFFFFFFFFFFFF000);
// Handle 4KB pages
entry = &table->entries[l];
kprintf("%llx\n%llx\n", va, (*entry & ~(PGMASK | PTE_NX)) + (va & PGMASK));
return (*entry & ~(PGMASK | PTE_NX)) + (va & PGMASK);
}
void
PMapLookupEntry(AS *space, uint64_t va, PageEntry **entry, int size)
{