summaryrefslogtreecommitdiff
path: root/src/arch/amd64/paging.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-01-29 13:22:50 -0500
committerFreya Murphy <freya@freyacat.org>2024-01-29 13:22:50 -0500
commite71a141533c742d05c0612d3a87ffb3810a4b5de (patch)
tree06f8b5f8d33b287e8443caa65dea4abb64a5d3c4 /src/arch/amd64/paging.c
parentchanges (diff)
downloadcorn-e71a141533c742d05c0612d3a87ffb3810a4b5de.tar.gz
corn-e71a141533c742d05c0612d3a87ffb3810a4b5de.tar.bz2
corn-e71a141533c742d05c0612d3a87ffb3810a4b5de.zip
memory works
Diffstat (limited to 'src/arch/amd64/paging.c')
-rw-r--r--src/arch/amd64/paging.c85
1 files changed, 43 insertions, 42 deletions
diff --git a/src/arch/amd64/paging.c b/src/arch/amd64/paging.c
index 3140a2a..836f602 100644
--- a/src/arch/amd64/paging.c
+++ b/src/arch/amd64/paging.c
@@ -7,18 +7,9 @@
#include <memory/physalloc.h>
#include <memory/virtalloc.h>
+#include "paging.h"
#include "bindings.h"
-#define F_PRESENT 0x001
-#define F_WRITEABLE 0x002
-#define F_UNPRIVILEGED 0x004
-#define F_WRITETHROUGH 0x008
-#define F_CACHEDISABLE 0x010
-#define F_ACCESSED 0x020
-#define F_DIRTY 0x040
-#define F_MEGABYTE 0x080
-#define F_GLOBAL 0x100
-
// PAGE MAP LEVEL 4 ENTRY
struct pml4e {
uint64_t flags : 6;
@@ -61,19 +52,19 @@ struct pte {
};
// bss segment, can write to
-extern struct pml4e pml4_list[512];
-extern struct pdpte init_pdpt[512];
-extern struct pde init_pd[512];
-extern struct pte init_pt[512];
+extern struct pml4e kernel_pml4[512];
+extern struct pdpte kernel_pdpt_0[512];
+extern struct pde kernel_pd_0[512];
+extern struct pte bootstrap_pt[512];
extern struct pte paging_pt[512]; // paging_pt should NEVER be outside of this file, NEVER i say
// paged address to read page tables
// the structures are not gurenteed to be ident mapped
// map them here with map_<type>(phys_addr) before useing structures
-static struct pdpte *pdpt_mapped = (void *) (uintptr_t) 0x1000;
-static struct pdpte *pd_mapped = (void *) (uintptr_t) 0x2000;
-static struct pdpte *pt_mapped = (void *) (uintptr_t) 0x3000;
-void *addr_mapped = (void *) (uintptr_t) 0x4000;
+static struct pdpte *pdpt_mapped = (void *) (uintptr_t) 0x201000;
+static struct pdpte *pd_mapped = (void *) (uintptr_t) 0x202000;
+static struct pdpte *pt_mapped = (void *) (uintptr_t) 0x203000;
+void *addr_mapped = (void *) (uintptr_t) 0x204000;
static inline void invlpg(void *addr) {
__asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
@@ -172,6 +163,7 @@ int map_page(struct pml4e *pml4, void *virt_addr, void *phys_addr, unsigned int
map_pt(__pt);
pt_mapped[pt_offset].flags = F_PRESENT | flags;
pt_mapped[pt_offset].address = (((uint64_t)phys_addr) >> 12);
+
invlpg(virt_addr);
return 0;
}
@@ -236,51 +228,52 @@ done:
}
void paging_init(void) {
- memset(pml4_list, 0, 4096);
- pml4_list[0].flags = F_PRESENT | F_WRITEABLE;
- pml4_list[0].address = (uint64_t)init_pdpt >> 12;
-
- memset(init_pdpt, 0, 4096);
- init_pdpt[0].flags = F_PRESENT | F_WRITEABLE;
- init_pdpt[0].address = (uint64_t)init_pd >> 12;
-
- memset(pml4_list, 0, 4096);
- init_pd[0].flags = F_PRESENT | F_WRITEABLE;
- init_pd[0].address = (uint64_t)paging_pt >> 12;
- init_pd[1].flags = F_PRESENT | F_WRITEABLE;
- init_pd[1].address = (uint64_t)init_pt >> 12;
+
+ kernel_pml4[0].flags = F_PRESENT | F_WRITEABLE;
+ kernel_pml4[0].address = (uint64_t)(&kernel_pdpt_0) >> 12;
+
+ kernel_pdpt_0[0].flags = F_PRESENT | F_WRITEABLE;
+ kernel_pdpt_0[0].address = (uint64_t)(&kernel_pd_0) >> 12;
+
+ kernel_pd_0[1].flags = F_PRESENT | F_WRITEABLE;
+ kernel_pd_0[1].address = (uint64_t)(&paging_pt) >> 12;
+ kernel_pd_0[2].flags = F_PRESENT | F_WRITEABLE;
+ kernel_pd_0[2].address = (uint64_t)(&bootstrap_pt) >> 12;
- memset(init_pt, 0, 4096);
- memset(paging_pt, 0, 4096);
+ memset(&paging_pt, 0, 4096);
+ memset(&bootstrap_pt, 0, 4096);
}
static inline void *page_align(void *addr) {
uintptr_t a = (uintptr_t) addr;
- a += PAGE_SIZE + 1;
+ a += PAGE_SIZE - 1;
a /= PAGE_SIZE;
+ a *= PAGE_SIZE;
return (void *) a;
}
void *mmap(void *addr, size_t len) {
- len += (uintptr_t)addr % PAGE_SIZE;
- int pages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
+ len += (long)addr % PAGE_SIZE;
+ long pages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
void *virt = virtaddr_alloc(pages);
- if (virt == NULL)
+ if (virt == NULL) {
return NULL;
+ }
void *phys = page_align(addr);
for (long i = 0; i < pages; i++) {
void *virt_temp = (char *)virt + (i * PAGE_SIZE);
void *phys_temp = (char *)phys + (i * PAGE_SIZE);
- map_page(pml4_list, virt_temp, phys_temp, F_WRITEABLE);
+ map_page(kernel_pml4, virt_temp, phys_temp, F_WRITEABLE);
}
- return addr;
+ map_page(kernel_pml4, virt, (void*)0x23443, F_WRITEABLE);
+ return virt;
}
void unmap(void *addr) {
long pages = virtaddr_free(addr);
for (long i = 0; i < pages; i++) {
void *virt = (char *)addr + (i * PAGE_SIZE);
- unmap_page(pml4_list, virt);
+ unmap_page(kernel_pml4, virt);
}
}
@@ -296,7 +289,7 @@ void *alloc_pages(int count) {
for (int i = 0; i < count; i++) {
void *virt_temp = (char *)virt + (i * PAGE_SIZE);
void *phys_temp = (char *)phys + (i * PAGE_SIZE);
- map_page(pml4_list, virt_temp, phys_temp, F_WRITEABLE);
+ map_page(kernel_pml4, virt_temp, phys_temp, F_WRITEABLE);
}
return virt;
}
@@ -307,7 +300,7 @@ void free_page(void *virt) {
return;
for (long i = 0; i < pages; i++) {
void *virt_temp = (char *)virt + (i * PAGE_SIZE);
- unmap_page(pml4_list, virt_temp);
+ unmap_page(kernel_pml4, virt_temp);
}
}
@@ -318,3 +311,11 @@ void memory_lock(void) {
void memory_unlock(void) {
sti();
}
+
+int kmap_page(void *virt_addr, void *phys_addr, unsigned int flags) {
+ return map_page(kernel_pml4, virt_addr, phys_addr, flags);
+}
+
+int kunmap_page(void *virt_addr) {
+ return unmap_page(kernel_pml4, virt_addr);
+}