|
|
|
|
@@ -2,49 +2,57 @@
|
|
|
|
|
|
|
|
|
|
#include"ppm.h"
|
|
|
|
|
#include"mem.h"
|
|
|
|
|
#include"consts.h"
|
|
|
|
|
|
|
|
|
|
extern void *_kernel_end;
|
|
|
|
|
static void invlpg(uint32_t virtaddr) {
|
|
|
|
|
asm volatile("invlpg %0" : : "m"(*(char*)virtaddr) : "memory");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void set_temporary_mapping(uint32_t addr) {
|
|
|
|
|
static void set_temporary_mapping(uint32_t addr) {
|
|
|
|
|
if((addr & 0xFFF) != 0) asm volatile("xchgw %bx, %bx");
|
|
|
|
|
|
|
|
|
|
*(volatile uint32_t*) 0xFFFFFFF8 = addr | 3;
|
|
|
|
|
asm volatile("invlpg 0xFFFFE000" : : : "memory");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint32_t nextAllocs[2] = {[VPM_KERNEL] = 0, [VPM_USER] = 1 * 1024 * 1024 * 1024};
|
|
|
|
|
static uint32_t spaceBoundaries[2] = {[VPM_KERNEL] = 4096, [VPM_USER] = 1 * 1024 * 1024 * 1024};
|
|
|
|
|
|
|
|
|
|
void vpm_init(uint32_t kernelEnd) {
|
|
|
|
|
nextAllocs[VPM_KERNEL] = (kernelEnd + 4095) & ~4095;
|
|
|
|
|
//spaceBoundaries[VPM_KERNEL] = (kernelEnd + 4095) & ~4095;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO: Make better. */
|
|
|
|
|
uint32_t vpm_find_free(uint32_t addrspace, AllocationOwner owner, size_t lenBytes) {
|
|
|
|
|
size_t len = (lenBytes + 4095) / 4096;
|
|
|
|
|
/* This is a linear search. Improve? */
|
|
|
|
|
uint32_t vpm_find_free(uint32_t addrspace, AllocationOwner owner, size_t len) {
|
|
|
|
|
len = ROUND_UP_POT(len, PAGE_SIZE);
|
|
|
|
|
|
|
|
|
|
uint32_t ret = nextAllocs[owner];
|
|
|
|
|
for(size_t i = 0; i < len;) {
|
|
|
|
|
uint32_t pdeid = (ret + i * 4096) >> 22;
|
|
|
|
|
uint32_t pteid = ((ret + i * 4096) >> 12) & 1023;
|
|
|
|
|
for(uint32_t attempt = spaceBoundaries[owner]; attempt != 0;) {
|
|
|
|
|
for(size_t i = 0; i < len;) {
|
|
|
|
|
uint32_t pdeid = (attempt + i) >> 22;
|
|
|
|
|
uint32_t pteid = ((attempt + i) >> 12) & 1023;
|
|
|
|
|
|
|
|
|
|
set_temporary_mapping(addrspace);
|
|
|
|
|
set_temporary_mapping(addrspace);
|
|
|
|
|
|
|
|
|
|
volatile uint32_t *pde = &((volatile uint32_t*) 0xFFFFE000)[pdeid];
|
|
|
|
|
if((*pde & 1) == 0) {
|
|
|
|
|
i += 4096;
|
|
|
|
|
} else {
|
|
|
|
|
set_temporary_mapping(*pde & ~0xFFF);
|
|
|
|
|
|
|
|
|
|
if((((volatile uint32_t*) 0xFFFFE000)[pteid] & 1) == 0) {
|
|
|
|
|
i++;
|
|
|
|
|
volatile uint32_t *pde = &((volatile uint32_t*) 0xFFFFE000)[pdeid];
|
|
|
|
|
if(!PAGE_PRESENT(*pde)) {
|
|
|
|
|
i += PAGE_SIZE * 1024 * 1024; // 4MB
|
|
|
|
|
} else {
|
|
|
|
|
ret += (i + 1) * 4096;
|
|
|
|
|
i = 0;
|
|
|
|
|
set_temporary_mapping((*pde) & ~0xFFF);
|
|
|
|
|
|
|
|
|
|
volatile uint32_t *pte = &((volatile uint32_t*) 0xFFFFE000)[pteid];
|
|
|
|
|
|
|
|
|
|
if(!PAGE_PRESENT(*pte)) {
|
|
|
|
|
i += PAGE_SIZE;
|
|
|
|
|
} else {
|
|
|
|
|
attempt += i + PAGE_SIZE;
|
|
|
|
|
goto try_next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return attempt;
|
|
|
|
|
try_next:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If phys is -1, map to uncontiguous physical pages anywhere, else map contiguous span of physical memory. */
|
|
|
|
|
@@ -99,8 +107,8 @@ void *vpm_map(uint32_t addrspace, AllocationOwner owner, uint32_t virt, uint32_t
|
|
|
|
|
*pte |= 3 | (owner == VPM_USER ? 4 : 0);
|
|
|
|
|
|
|
|
|
|
if(thisspace == addrspace) {
|
|
|
|
|
//~ asm volatile("xchg %bx, %bx");
|
|
|
|
|
asm volatile("invlpg %0" : : "m"(*(char*) (virt + i * 4096)) : "memory");
|
|
|
|
|
invlpg(virt + i * 4096);
|
|
|
|
|
//asm volatile("invlpg %0" : : "m"(*(char*) (virt + i * 4096)) : "memory");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -164,7 +172,8 @@ int vpm_double_map(uint32_t cr3a, uint32_t cr3b, uint32_t *va, uint32_t *vb, uin
|
|
|
|
|
*pte = backend | 3 | 4;
|
|
|
|
|
|
|
|
|
|
if(thisspace == cr3a) {
|
|
|
|
|
asm volatile("invlpg %0" : : "m"(*(char*) (*va + i * 4096)) : "memory");
|
|
|
|
|
invlpg(*va + i * 4096);
|
|
|
|
|
//asm volatile("invlpg %0" : : "m"(*(char*) (*va + i * 4096)) : "memory");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -193,7 +202,8 @@ int vpm_double_map(uint32_t cr3a, uint32_t cr3b, uint32_t *va, uint32_t *vb, uin
|
|
|
|
|
*pte = backend | 3 | 4;
|
|
|
|
|
|
|
|
|
|
if(thisspace == cr3b) {
|
|
|
|
|
asm volatile("invlpg %0" : : "m"(*(char*) (*vb + i * 4096)) : "memory");
|
|
|
|
|
invlpg(*vb + i * 4096);
|
|
|
|
|
//asm volatile("invlpg %0" : : "m"(*(char*) (*vb + i * 4096)) : "memory");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -262,7 +272,8 @@ void vpm_unmap(uint32_t cr3, uint32_t virt, size_t len) {
|
|
|
|
|
((volatile uint32_t*) 0xFFFFE000)[pteid] = 0;
|
|
|
|
|
|
|
|
|
|
if(thisspace == cr3) {
|
|
|
|
|
asm volatile("invlpg %0" : : "m"(*(char*) (virt + i * 4096)) : "memory");
|
|
|
|
|
invlpg(virt + i * 4096);
|
|
|
|
|
//asm volatile("invlpg %0" : : "m"(*(char*) (virt + i * 4096)) : "memory");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|