summaryrefslogtreecommitdiff
path: root/arch/i386/kernel/paging.c
diff options
context:
space:
mode:
authorDanny Holman <dholman@gymli.org>2024-02-24 14:44:38 -0600
committerDanny Holman <dholman@gymli.org>2024-02-24 14:44:38 -0600
commit2ce0f8af51dae9e7d591ff5fd038f89d6ca9dbbe (patch)
tree314f6105fc2996923070ed7f82c3acc8d5b2b20c /arch/i386/kernel/paging.c
parent5d06824289868c5a345fbcfa8ed4d1e63af84fdb (diff)
arch: i386: cleanup everything and reorganize
Clean up everything in the i386 arch directory. This code has been in dire need of refactoring for a long while. All the inline assembly functions and the data structures related to the architecture should be placed into their own header file. Now the scheduler can access registers and ISRs without having to deal with arch-specific code. Signed-off-by: Danny Holman <dholman@gymli.org>
Diffstat (limited to 'arch/i386/kernel/paging.c')
-rw-r--r--arch/i386/kernel/paging.c78
1 files changed, 33 insertions, 45 deletions
diff --git a/arch/i386/kernel/paging.c b/arch/i386/kernel/paging.c
index 54539ac..b2a1392 100644
--- a/arch/i386/kernel/paging.c
+++ b/arch/i386/kernel/paging.c
@@ -10,63 +10,42 @@ static uintptr_t kend = (uintptr_t)&_kernel_end - 0xC0000000;
static uintptr_t page_directory[1024] __attribute__((aligned(PAGE_SIZE)));
static uintptr_t first_page_table[1024] __attribute__((aligned(PAGE_SIZE)));
+static uintptr_t second_page_table[1024] __attribute__((aligned(PAGE_SIZE)));
static int paging_enabled = 0;
-static uint32_t dma_zone_bitmap[DMA_BITMAP_SZ];
-static uint32_t buddy_bitmap[BDY_BITMAP_SZ];
-static struct pfa_buddy first_buddy;
-
-static void _pfa_init(void) {
- first_buddy.start = 0x01000000;
- first_buddy.bitmap = buddy_bitmap;
+uint32_t* init_page_table(uint32_t flags) {
+ uint32_t *ret = kmalloc(sizeof(uint32_t)*1024);
+ for (int i = 0; i < 1024; i++)
+ ret[i] = flags;
}
-static void _pfa_alloc(uintptr_t paddr) {
- uintptr_t index = (paddr & 0xFFFFF000) / 4096 / 32;
- uintptr_t bit = (paddr & 0xFFFFF000) / 4096 % 32;
- uint32_t *bitmap;
- if (paddr < 0x01000000)
- bitmap = dma_zone_bitmap;
- else
- bitmap = first_buddy.bitmap;
-
- bitmap[index] |= (1 << bit);
-}
-
-static void _pfa_free(uintptr_t paddr) {
- uintptr_t index = (paddr & 0xFFFFF000) / 4096 / 32;
- uintptr_t bit = (paddr & 0xFFFFF000) / 4096 % 32;
- uint32_t *bitmap;
- if (paddr < 0x01000000)
- bitmap = dma_zone_bitmap;
- else
- bitmap = first_buddy.bitmap;
-
- bitmap[index] &= ~(1 << bit);
+uint32_t* init_page_dir(uint32_t flags) {
+ uint32_t *ret = init_page_table(flags);
+ ret[0] = ((uintptr_t)&first_page_table - 0xC0000000) | 3;
+ ret[768] = ((uintptr_t)&second_page_table - 0xC0000000) | 3;
}
void paging_init(void) {
- _pfa_init();
- for (int i = 0; i < 1024; i++)
- page_directory[i] = 0x00000002;
+ for (int i = 0; i < 1024; i++) {
+ page_directory[i] = PD_RW;
+ first_page_table[i] = PD_RW;
+ second_page_table[i] = PD_RW;
+ }
page_directory[1023] = ((uintptr_t)&page_directory - 0xC0000000) | 3;
page_directory[0] = ((uintptr_t)&first_page_table - 0xC0000000) | 3;
- page_directory[768] = ((uintptr_t)&first_page_table - 0xC0000000) | 3;
- for (uintptr_t i = kstart; i < kend; i += 4096) {
- _pfa_alloc(get_vaddr(i));
- map_page(page_directory, i, get_vaddr(i), 0x003);
- }
+ page_directory[768] = ((uintptr_t)&second_page_table - 0xC0000000) | 3;
+ for (uintptr_t i = kstart; i < kend; i += PAGE_SIZE)
+ map_page(page_directory, i, i + 0xC0000000, 0x003);
- load_page_dir(((uintptr_t)&page_directory) - 0xC0000000);
- enable_paging();
+ enable_paging(((uintptr_t)&page_directory) - 0xC0000000);
paging_enabled = 1;
return;
}
-void page_fault_handler(struct isr_frame *frame) {
- uintptr_t errno = frame->errno;
+void page_fault_handler(struct regs *regs) {
+ uintptr_t errno = regs->isr_err;
uintptr_t fault_addr;
__asm__ volatile("movl %%cr2, %0" : "=r"(fault_addr));
@@ -76,9 +55,9 @@ void page_fault_handler(struct isr_frame *frame) {
int reserved = errno & ERR_RESERVED;
int ifetch = errno & ERR_INST;
+ uintptr_t first_free;
if (!present)
- _pfa_alloc(fault_addr);
- map_page(NULL, fault_addr, fault_addr, 0x003);
+ map_page(regs->cr3, fault_addr, fault_addr, PD_PRES | PD_RW | PD_USR);
if (user)
panic("Usermode attempted to read supervisor page");
if (rw)
@@ -89,8 +68,17 @@ void page_fault_handler(struct isr_frame *frame) {
panic("Task paging instruction fetch failure");
}
-uintptr_t get_vaddr(uintptr_t paddr) {
- return paddr + 0xC0000000;
+uintptr_t get_paddr(uintptr_t vaddr) {
+ uint32_t pdindex = (uint32_t)vaddr >> 22;
+ uint32_t ptindex = (uint32_t)vaddr >> 12 & 0x03FF;
+
+ uint32_t *pd = (uint32_t*)0xFFFFF000;
+ if (*pd & PD_PRES != 1)
+ return NULL;
+ uint32_t *pt = ((uint32_t*)0xFFC00000) + (0x400 * pdindex);
+ if (*pt & PD_PRES != 1)
+ return NULL;
+ return (uintptr_t)((pt[ptindex] & ~0xFFF) + ((uint32_t)vaddr & 0xFFF));
}
void map_page(uint32_t *pd, uintptr_t paddr, uintptr_t vaddr, uint32_t flags) {