diff options
author | Danny Holman <dholman@gymli.org> | 2024-06-21 21:53:05 -0500 |
---|---|---|
committer | Danny Holman <dholman@gymli.org> | 2024-06-21 21:53:05 -0500 |
commit | 1b09993e4fd0b1aebb3747818a1fc670abf6a02c (patch) | |
tree | 915b2155f33660cdfe4a5e61362f3f69c9814dc5 | |
parent | 056087596de64696f18f9b32f604b69280be079e (diff) |
arch: i386: pmem: refactor the physical memory manager
Refactor the physical memory manager to be more efficient and require
fewer function calls from layers above.
Signed-off-by: Danny Holman <dholman@gymli.org>
-rw-r--r-- | arch/i386/include/kernel/pmem.h | 8 | ||||
-rw-r--r-- | arch/i386/kernel/pmem.c | 65 |
2 files changed, 30 insertions, 43 deletions
diff --git a/arch/i386/include/kernel/pmem.h b/arch/i386/include/kernel/pmem.h index da169c7..e6e4f57 100644 --- a/arch/i386/include/kernel/pmem.h +++ b/arch/i386/include/kernel/pmem.h @@ -3,8 +3,7 @@ #include <kernel/multiboot.h> #include <stdint.h> - -#define PFA_ALLOC_ERR 0xFFFFFFFF +#include <stddef.h> struct pfa_page { struct pfa_page *next; @@ -12,8 +11,7 @@ struct pfa_page { void pfa_init(struct mboot_info *header); -uintptr_t pfa_alloc(void); -void pfa_free(uintptr_t paddr); -void pfa_free_range(uintptr_t start, uintptr_t end); +void pfa_free_dma(uintptr_t paddr, size_t num_pages); +void pfa_free(uintptr_t paddr, size_t num_pages); #endif diff --git a/arch/i386/kernel/pmem.c b/arch/i386/kernel/pmem.c index 0e53507..40e3400 100644 --- a/arch/i386/kernel/pmem.c +++ b/arch/i386/kernel/pmem.c @@ -1,56 +1,45 @@ #include <kernel/pmem.h> #include <kernel/asm.h> +#include <kernel/vmem.h> #include <kernel/panic.h> #include <kernel/paging.h> #include <libk/io.h> #include <libk/string.h> -struct pfa_page freelist; +static struct pfa_page freelist; void pfa_init(struct mboot_info *header) { struct mboot_mmap_entry *mme; - struct mboot_mmap_entry *temp_map; for (uintptr_t i = 0; i < header->mmap_length; i += sizeof(struct mboot_mmap_entry)) { mme = (struct mboot_mmap_entry*)(header->mmap_addr + i); - temp_map = (struct mboot_mmap_entry*)GET_VADDR(mme); - map_page(NULL, (uintptr_t)mme, (uintptr_t)temp_map, PD_PRES); - if (temp_map->type == MBOOT_MEM_AVAILABLE) - pfa_free_range(temp_map->addr_low, temp_map->addr_low + temp_map->len_low); - unmap_page(NULL, (uintptr_t)temp_map); + if (mme->type == MBOOT_MEM_AVAILABLE) + pfa_free(mme->addr_low, mme->len_low / PAGE_SIZE); } } -uintptr_t pfa_alloc(void) { - struct pfa_page *ret = freelist.next; - if (ret == NULL) - return PFA_ALLOC_ERR; - - struct pfa_page *temp_map = (struct pfa_page*)0xD0000000; - map_page(NULL, (uintptr_t)ret, (uintptr_t)temp_map, PD_PRES | PD_RW); - memset((char*)temp_map, 0, PAGE_SIZE); - unmap_page(NULL, (uintptr_t)temp_map); - return (uintptr_t)ret; +uintptr_t pfa_alloc(size_t num_pages) { + struct pfa_page *temp = (struct pfa_page*)PAGE_TMP_MAP; + map_page(freelist.next, PAGE_TMP_MAP, PD_PRES | PD_RW); + uintptr_t ret = freelist.next; + freelist.next = temp->next; + memset(temp, 0, 32); + unmap_page(PAGE_TMP_MAP); + return ret; } -void pfa_free(uintptr_t paddr) { - if (paddr % PAGE_SIZE != 0) - panic("Task attempted to free non-aligned memory"); - if (paddr == 0) - return; - if (paddr >= KSTART && paddr < KEND) - return; - if (paddr >= 0x80000 && paddr < 0x100000) - return; - - struct pfa_page *temp_map = (struct pfa_page*)0x1000; - map_page(NULL, paddr, (uintptr_t)temp_map, PD_PRES | PD_RW); - memset(temp_map, 1, 32); - temp_map->next = freelist.next; - freelist.next = (struct pfa_page*)paddr; - unmap_page(NULL, (uintptr_t)temp_map); -} - -void pfa_free_range(uintptr_t start, uintptr_t end) { - for (uintptr_t i = start; i < end; i += PAGE_SIZE) - pfa_free(i); +void pfa_free(uintptr_t paddr, size_t num_pages) { + uintptr_t addr; + struct pfa_page *temp = (struct pfa_page*)PAGE_TMP_MAP; + for (size_t i = 0; i < num_pages; i++) { + addr = (i * PAGE_SIZE + paddr); + if (addr >= KSTART && addr < KEND) + continue; + if (addr == 0) + continue; + map_page(addr, PAGE_TMP_MAP, PD_PRES | PD_RW); + memset(PAGE_TMP_MAP, 1, 32); + temp->next = freelist.next; + freelist.next = addr; + unmap_page(PAGE_TMP_MAP); + } } |