mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
Support lower half addresses on the VMM
This commit is contained in:
+72
-26
@@ -69,8 +69,6 @@ static vmm_mapping* allocentry(vmm_cache* cache){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static vmm_mapping* allocatefirst(){
|
static vmm_mapping* allocatefirst(){
|
||||||
|
|
||||||
// FIXME there's a possible race condition here I think
|
|
||||||
|
|
||||||
vmm_mapping *map = NULL;
|
vmm_mapping *map = NULL;
|
||||||
vmm_cache *cache = caches;
|
vmm_cache *cache = caches;
|
||||||
@@ -82,13 +80,19 @@ static vmm_mapping* allocatefirst(){
|
|||||||
map = allocentry(cache);
|
map = allocentry(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spinlock_acquire(&cache->header.lock);
|
||||||
|
|
||||||
if(!map){
|
if(!map){
|
||||||
// try allocating new cache
|
// try allocating new cache
|
||||||
vmm_cache* new = newcache();
|
vmm_cache* new = newcache();
|
||||||
if(!new) return NULL;
|
if(!new) goto done;
|
||||||
map = allocentry(new);
|
map = allocentry(new);
|
||||||
cache->header.next = new;
|
cache->header.next = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
spinlock_release(&cache->header.lock);
|
||||||
|
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
@@ -138,8 +142,7 @@ static void fragcheck(vmm_mapping* map){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME I snatched this from the old codebase. This is ugly and it should definetively be
|
// this could be rewritten later
|
||||||
// rewritten
|
|
||||||
|
|
||||||
static bool setmap(vmm_mapping** mapstart, void* addr, size_t pagec, size_t mmuflags, size_t type, void* data, size_t offset){
|
static bool setmap(vmm_mapping** mapstart, void* addr, size_t pagec, size_t mmuflags, size_t type, void* data, size_t offset){
|
||||||
|
|
||||||
@@ -238,6 +241,7 @@ static bool setmap(vmm_mapping** mapstart, void* addr, size_t pagec, size_t mmuf
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(map->start == newmap->start){
|
if(map->start == newmap->start){
|
||||||
|
//start
|
||||||
newmap->next = map;
|
newmap->next = map;
|
||||||
newmap->prev = map->prev;
|
newmap->prev = map->prev;
|
||||||
if(newmap->prev){
|
if(newmap->prev){
|
||||||
@@ -285,10 +289,9 @@ static bool setmap(vmm_mapping** mapstart, void* addr, size_t pagec, size_t mmuf
|
|||||||
}
|
}
|
||||||
|
|
||||||
static vmm_mapping* findmappingfromaddr(vmm_mapping* map, void* addr){
|
static vmm_mapping* findmappingfromaddr(vmm_mapping* map, void* addr){
|
||||||
|
while(map && !(addr >= map->start && addr <= map->end))
|
||||||
while(map && !(addr > map->start && addr <= map->end))
|
|
||||||
map = map->next;
|
map = map->next;
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -336,8 +339,20 @@ static bool unmap(vmm_mapping** mapstart, void* addr, size_t pagec){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void getcontextinfo(void* addr, int** lock, vmm_mapping*** start){
|
||||||
|
|
||||||
|
if(addr >= KERNEL_SPACE_START){
|
||||||
|
*lock = &klock;
|
||||||
|
*start = &kmapstart;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO do it in the lower half of memory as well
|
vmm_context *context = arch_getcls()->context;
|
||||||
|
|
||||||
|
*lock = &context->lock;
|
||||||
|
*start = context->userstart;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void* vmm_alloc(size_t pagec, size_t mmuflags){
|
void* vmm_alloc(size_t pagec, size_t mmuflags){
|
||||||
spinlock_acquire(&klock);
|
spinlock_acquire(&klock);
|
||||||
@@ -361,40 +376,61 @@ void* vmm_alloc(size_t pagec, size_t mmuflags){
|
|||||||
|
|
||||||
bool vmm_unmap(void* addr, size_t pagec){
|
bool vmm_unmap(void* addr, size_t pagec){
|
||||||
|
|
||||||
spinlock_acquire(&klock);
|
int* lock;
|
||||||
|
vmm_mapping** start;
|
||||||
|
|
||||||
|
getcontextinfo(addr, &lock, &start);
|
||||||
|
|
||||||
|
spinlock_acquire(lock);
|
||||||
|
|
||||||
unmap(kmapstart, addr, pagec);
|
unmap(start, addr, pagec);
|
||||||
|
|
||||||
spinlock_release(&klock);
|
spinlock_release(lock);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vmm_setused(void* addr, size_t pagec, size_t mmuflags){
|
bool vmm_setused(void* addr, size_t pagec, size_t mmuflags){
|
||||||
spinlock_acquire(&klock);
|
|
||||||
|
int* lock;
|
||||||
|
vmm_mapping** start;
|
||||||
|
|
||||||
bool result = setmap(&kmapstart, addr, pagec, mmuflags, VMM_TYPE_ANON, 0, 0);
|
getcontextinfo(addr, &lock, &start);
|
||||||
|
|
||||||
spinlock_release(&klock);
|
spinlock_acquire(lock);
|
||||||
|
|
||||||
|
bool result = setmap(start, addr, pagec, mmuflags, VMM_TYPE_ANON, 0, 0);
|
||||||
|
|
||||||
|
spinlock_release(lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vmm_setfree(void* addr, size_t pagec){
|
bool vmm_setfree(void* addr, size_t pagec){
|
||||||
spinlock_acquire(&klock);
|
int* lock;
|
||||||
|
vmm_mapping** start;
|
||||||
bool result = setmap(&kmapstart, addr, pagec, 0, VMM_TYPE_FREE, 0, 0);
|
|
||||||
|
|
||||||
spinlock_release(&klock);
|
getcontextinfo(addr, &lock, &start);
|
||||||
|
|
||||||
|
spinlock_acquire(lock);
|
||||||
|
|
||||||
|
bool result = setmap(start, addr, pagec, 0, VMM_TYPE_FREE, 0, 0);
|
||||||
|
|
||||||
|
spinlock_release(lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vmm_map(void* paddr, void* vaddr, size_t pagec, size_t mmuflags){
|
bool vmm_map(void* paddr, void* vaddr, size_t pagec, size_t mmuflags){
|
||||||
spinlock_acquire(&klock);
|
int* lock;
|
||||||
bool result = setmap(&kmapstart, vaddr, pagec, mmuflags, VMM_TYPE_ANON, 0, 0);
|
vmm_mapping** start;
|
||||||
|
|
||||||
|
getcontextinfo(vaddr, &lock, &start);
|
||||||
|
|
||||||
|
spinlock_acquire(lock);
|
||||||
|
bool result = setmap(start, vaddr, pagec, mmuflags, VMM_TYPE_ANON, 0, 0);
|
||||||
|
|
||||||
for(size_t page = 0; page < pagec && result; ++page)
|
for(size_t page = 0; page < pagec && result; ++page)
|
||||||
result = arch_mmu_map(arch_getcls()->context->context, paddr + page*PAGE_SIZE, vaddr + page*PAGE_SIZE, mmuflags);
|
result = arch_mmu_map(arch_getcls()->context->context, paddr + page*PAGE_SIZE, vaddr + page*PAGE_SIZE, mmuflags);
|
||||||
|
|
||||||
spinlock_release(&klock);
|
spinlock_release(lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,11 +438,15 @@ bool vmm_map(void* paddr, void* vaddr, size_t pagec, size_t mmuflags){
|
|||||||
|
|
||||||
bool vmm_dealwithrequest(void* addr){
|
bool vmm_dealwithrequest(void* addr){
|
||||||
|
|
||||||
spinlock_acquire(&klock);
|
int* lock;
|
||||||
|
vmm_mapping** start;
|
||||||
|
|
||||||
|
getcontextinfo(addr, &lock, &start);
|
||||||
|
|
||||||
|
spinlock_acquire(lock);
|
||||||
|
|
||||||
bool status;
|
bool status;
|
||||||
|
vmm_mapping* map = findmappingfromaddr(*start, addr);
|
||||||
vmm_mapping* map = findmappingfromaddr(kmapstart, addr);
|
|
||||||
void* paddr;
|
void* paddr;
|
||||||
|
|
||||||
if((!map) || map->type == VMM_TYPE_FREE){
|
if((!map) || map->type == VMM_TYPE_FREE){
|
||||||
@@ -440,7 +480,7 @@ bool vmm_dealwithrequest(void* addr){
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
spinlock_release(&klock);
|
spinlock_release(lock);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -482,6 +522,12 @@ void vmm_init(){
|
|||||||
setmap(&kmapstart, rodatastart, (rodataend - rodatastart) / PAGE_SIZE, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_NOEXEC, VMM_TYPE_ANON, 0, 0);
|
setmap(&kmapstart, rodatastart, (rodataend - rodatastart) / PAGE_SIZE, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_NOEXEC, VMM_TYPE_ANON, 0, 0);
|
||||||
|
|
||||||
setmap(&kmapstart, datastart, (dataend - datastart) / PAGE_SIZE, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_WRITE | ARCH_MMU_MAP_NOEXEC, VMM_TYPE_ANON, 0, 0);
|
setmap(&kmapstart, datastart, (dataend - datastart) / PAGE_SIZE, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_WRITE | ARCH_MMU_MAP_NOEXEC, VMM_TYPE_ANON, 0, 0);
|
||||||
|
|
||||||
|
volatile char* a = vmm_alloc(1, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_WRITE);
|
||||||
|
*a = 0;
|
||||||
|
vmm_unmap(a, 1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
debug_dumpkernelmappings();
|
debug_dumpkernelmappings();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user