summaryrefslogtreecommitdiff
path: root/kernel/memory
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-19 16:36:51 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-19 16:37:54 -0400
commit472ec944d2ed81d0304cc6cac80946a6a44776be (patch)
treef6cae641c143a0b45bb289d9d9fc6145706025b0 /kernel/memory
parentset mmap limit (diff)
downloadcomus-472ec944d2ed81d0304cc6cac80946a6a44776be.tar.gz
comus-472ec944d2ed81d0304cc6cac80946a6a44776be.tar.bz2
comus-472ec944d2ed81d0304cc6cac80946a6a44776be.zip
UEFI and republicans
Diffstat (limited to 'kernel/memory')
-rw-r--r--kernel/memory/memory.c12
-rw-r--r--kernel/memory/paging.c41
-rw-r--r--kernel/memory/physalloc.c22
3 files changed, 41 insertions, 34 deletions
diff --git a/kernel/memory/memory.c b/kernel/memory/memory.c
index 2d560f4..6bdfe38 100644
--- a/kernel/memory/memory.c
+++ b/kernel/memory/memory.c
@@ -2,6 +2,7 @@
#include <comus/memory.h>
#include <comus/asm.h>
#include <comus/mboot.h>
+#include <comus/efi.h>
#include <lib.h>
#include "memory.h"
@@ -68,7 +69,8 @@ void memory_init(void)
{
struct memory_map mmap;
if (mboot_get_mmap(&mmap))
- panic("failed to load memory map");
+ if (efi_get_mmap(&mmap))
+ panic("failed to load memory map");
kernel_mem_ctx = &_kernel_mem_ctx;
kernel_mem_ctx->pml4 = kernel_pml4;
@@ -79,4 +81,12 @@ void memory_init(void)
virtaddr_init(kernel_mem_ctx->virtctx);
physalloc_init(&mmap);
sti();
+
+ // identiy map EFI functions
+ for (size_t i = 0; i < mmap.entry_count; i++) {
+ struct memory_segment *seg = &mmap.entries[i];
+ if (seg->type != SEG_TYPE_EFI)
+ continue;
+ kmapaddr((void *)seg->addr, (void *)seg->addr, seg->len, F_WRITEABLE);
+ }
}
diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c
index 5177928..3764abb 100644
--- a/kernel/memory/paging.c
+++ b/kernel/memory/paging.c
@@ -56,6 +56,7 @@ struct pte {
extern volatile struct pml4e kernel_pml4[512];
extern volatile struct pdpte kernel_pdpt_0[512];
extern volatile struct pde kernel_pd_0[512];
+extern volatile struct pte kernel_pt_0[512];
extern volatile struct pte bootstrap_pt[512];
extern volatile struct pte
paging_pt[512]; // paging_pt should NEVER be outside of this file, NEVER i say
@@ -502,49 +503,51 @@ void paging_init(void)
kernel_pdpt_0[0].flags = F_PRESENT | F_WRITEABLE;
kernel_pdpt_0[0].address = (uint64_t)(&kernel_pd_0) >> 12;
+ kernel_pd_0[0].flags = F_PRESENT | F_WRITEABLE;
+ kernel_pd_0[0].address = (uint64_t)(&kernel_pt_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;
+ for (size_t i = 0; i < 512; i++) {
+ kernel_pt_0[i].flags = F_PRESENT | F_WRITEABLE;
+ kernel_pt_0[i].address = (i * PAGE_SIZE) >> 12;
+ }
+
memsetv(&paging_pt, 0, 4096);
memsetv(&bootstrap_pt, 0, 4096);
-}
-static inline void *page_align(void *addr)
-{
- uintptr_t a = (uintptr_t)addr;
- a /= PAGE_SIZE;
- a *= PAGE_SIZE;
- return (void *)a;
+ // make sure we are using THESE pagetables
+ // EFI doesnt on boot
+ __asm__ volatile("mov %0, %%cr3" ::"r"(kernel_pml4) : "memory");
}
void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len,
unsigned int flags)
{
long pages;
- ptrdiff_t error;
- void *aligned_phys;
+ int alloc = 0;
- // get length and physical page aligned address
- aligned_phys = page_align(phys);
- error = (char *)phys - (char *)aligned_phys;
- len += error;
- pages = len / PAGE_SIZE + 1;
+ pages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
+ len += (PAGE_SIZE - len) % PAGE_SIZE;
- // get page aligned (or allocate) vitural address
- if (virt == NULL)
+ if (virt == NULL) {
virt = virtaddr_alloc(ctx->virtctx, pages);
+ alloc = 1;
+ }
+
if (virt == NULL)
return NULL;
- if (map_pages((volatile struct pml4e *)ctx->pml4, virt, aligned_phys,
+ if (map_pages((volatile struct pml4e *)ctx->pml4, virt, phys,
F_WRITEABLE | flags, pages)) {
- virtaddr_free(ctx->virtctx, virt);
+ if (alloc)
+ virtaddr_free(ctx->virtctx, virt);
return NULL;
}
- return (char *)virt + error;
+ return (char *)virt;
}
void mem_unmapaddr(mem_ctx_t ctx, void *virt)
diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c
index 676e68e..87072c4 100644
--- a/kernel/memory/physalloc.c
+++ b/kernel/memory/physalloc.c
@@ -20,10 +20,11 @@ static uint64_t segment_count;
struct memory_map phys_mmap;
struct memory_segment *page_start;
-static const char *segment_type_str[] = { "Reserved", "Free",
- "Reserved", "ACPI Reserved",
- "Hibernation", "Defective",
- "Unknown" };
+static const char *segment_type_str[] = {
+ [SEG_TYPE_FREE] = "Free", [SEG_TYPE_RESERVED] = "Reserved",
+ [SEG_TYPE_ACPI] = "ACPI Reserved", [SEG_TYPE_HIBERNATION] = "Hibernation",
+ [SEG_TYPE_DEFECTIVE] = "Defective", [SEG_TYPE_EFI] = "EFI Reserved",
+};
static int n_pages(const struct memory_segment *m)
{
@@ -124,7 +125,7 @@ static bool segment_invalid(const struct memory_segment *segment)
{
if (segment->len < 1)
return true;
- if (segment->type != 1)
+ if (segment->type != SEG_TYPE_FREE)
return true;
if (segment->addr < kaddr(kernel_start))
return true;
@@ -245,16 +246,9 @@ void memory_report(void)
kprintf("MEMORY MAP\n");
for (uint32_t i = 0; i < phys_mmap.entry_count; i++) {
struct memory_segment *seg;
- const char *type_str;
-
seg = &phys_mmap.entries[i];
- if (seg->type > 6)
- type_str = segment_type_str[6];
- else
- type_str = segment_type_str[seg->type];
-
- kprintf("ADDR: %16p LEN: %4s TYPE: %s (%d)\n", (void *)seg->addr,
- btoa(seg->len, buf), type_str, seg->type);
+ kprintf("ADDR: %16p LEN: %4s TYPE: %s\n", (void *)seg->addr,
+ btoa(seg->len, buf), segment_type_str[seg->type]);
}
kprintf("\nMEMORY USAGE\n");