diff options
Diffstat (limited to 'src/kernel/paging.c')
-rw-r--r-- | src/kernel/paging.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/src/kernel/paging.c b/src/kernel/paging.c index 36fb8a7..a0f7c3d 100644 --- a/src/kernel/paging.c +++ b/src/kernel/paging.c @@ -77,27 +77,47 @@ void *new_task_pd() { void *pd_user_allocate(void *pd, uint32_t vma, uint32_t pages, bool writable) { void *pma = allocate_user_pages(pages); if (!pma) - panic("Could not allocate user pages."); + PANIC("Could not allocate user pages."); for (uint32_t i = 0; i < pages; ++i) pd_map(pd, (uint32_t)pma + (i << 12), vma + (i << 12), writable); return pma; } -void *pd_user_allocate_anywhere_writable(void *pd, uint32_t pages) { +__attribute__ ((pure)) +static void *find_user_vma_run(void *pd, uint32_t pages) { uint32_t run = 0; for (void *vma = (void *)KERNEL_END; vma; vma += 4096) { if (pd_is_mapped(pd, (uint32_t)vma)) run = 0; - else if (++run == pages) { - vma -= (pages - 1) * 4096; - for (uint32_t i = 0; i < pages; ++i) - pd_map(pd, (uint32_t)allocate_user_pages(1), (uint32_t)vma + 4096 * i, true); - return vma; - } + else if (++run == pages) + return vma - (pages - 1) * 4096; } return 0; } +void *pd_user_allocate_anywhere_writable(void *pd, uint32_t pages) { + void *vma = find_user_vma_run(pd, pages); + if (!vma) + return 0; + for (uint32_t i = 0; i < pages; ++i) + pd_map(pd, (uint32_t)allocate_user_pages(1), (uint32_t)vma + 4096 * i, true); + return vma; +} + +void user_allocate_anywhere_readonly_together(void *pd, uint32_t pages, void **vma_out, void **pma_out) { + *vma_out = find_user_vma_run(pd, pages); + if (!*vma_out) { + *pma_out = 0; + return; + } + *pma_out = allocate_user_pages(pages); + if (!*pma_out) { + *vma_out = 0; + return; + } + pd_map(pd, (uint32_t)*pma_out, (uint32_t)*vma_out, false); +} + #define KPAGE_DIR ((uint32_t *)0x00005000) #define KPAGE_TABLE_0 ((uint32_t *)0x00400000) @@ -118,6 +138,11 @@ void init_paging() { : : : "eax"); } +__attribute__ ((pure)) +void *vma_to_pma(void *pd, const void *vma) { + return (void *)(((uint32_t *)(((uint32_t *)pd)[(uint32_t)vma >> 22] & PE_ADDR_MASK))[((uint32_t)vma >> 12) % 1024] & PE_ADDR_MASK) + (uint32_t)vma % 4096; +} + void switch_to_kernel_cr3() { asm volatile ( "mov $0x00005000, %%eax\n" |