summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/include/kernel/pmem.h8
-rw-r--r--arch/i386/kernel/pmem.c65
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);
+ }
}