aboutsummaryrefslogtreecommitdiff
path: root/mirai/memory/paging.zig
diff options
context:
space:
mode:
Diffstat (limited to 'mirai/memory/paging.zig')
-rw-r--r--mirai/memory/paging.zig114
1 files changed, 48 insertions, 66 deletions
diff --git a/mirai/memory/paging.zig b/mirai/memory/paging.zig
index 7dade55..e50fc56 100644
--- a/mirai/memory/paging.zig
+++ b/mirai/memory/paging.zig
@@ -1,35 +1,32 @@
-//! Page Table Manager - Hybrid kernel with independent user page tables
+//! Page Table Manager
-const memory = @import("../asm/memory.zig");
+const asm_memory = @import("../asm/memory.zig");
+const memory_const = @import("../common/constants/memory.zig");
+const paging_const = @import("../common/constants/paging.zig");
const pmm = @import("pmm.zig");
-const system = @import("../system/system.zig");
+const pmm_const = @import("../common/constants/pmm.zig");
-pub const PAGE_SIZE = system.constants.PAGE_SIZE;
-pub const HIGHER_HALF_START = system.constants.HIGHER_HALF_START;
+pub const PAGE_SIZE = memory_const.PAGE_SIZE;
+pub const HIGHER_HALF_START = memory_const.HIGHER_HALF_START;
-pub const PAGE_PRESENT = system.constants.PTE_PRESENT;
-pub const PAGE_WRITABLE = system.constants.PTE_WRITABLE;
-pub const PAGE_USER = system.constants.PTE_USER;
-
-const KERNEL_START = system.constants.KERNEL_PHYSICAL_START;
-const KERNEL_END = system.constants.KERNEL_PHYSICAL_END;
+pub const PAGE_PRESENT = paging_const.PTE_PRESENT;
+pub const PAGE_WRITABLE = paging_const.PTE_WRITABLE;
+pub const PAGE_USER = paging_const.PTE_USER;
fn zero_page(virt: u64) void {
const ptr: [*]volatile u8 = @ptrFromInt(virt);
- var i: usize = 0;
- while (i < PAGE_SIZE) : (i += 1) {
+ for (0..PAGE_SIZE) |i| {
ptr[i] = 0;
}
}
-// Map a page in the current page table (used by kernel for its own mappings)
pub fn map_page(virt: u64, phys: u64, flags: u64) !void {
const pml4_index = (virt >> 39) & 0x1FF;
const pdpt_index = (virt >> 30) & 0x1FF;
const pd_index = (virt >> 21) & 0x1FF;
const pt_index = (virt >> 12) & 0x1FF;
- const pml4_phys = memory.read_page_table_base() & ~@as(u64, 0xFFF);
+ const pml4_phys = asm_memory.read_page_table_base() & ~@as(u64, paging_const.OFFSET_MASK);
const pml4: [*]volatile u64 = @ptrFromInt(pml4_phys + HIGHER_HALF_START);
var pdpt_phys: u64 = undefined;
@@ -39,12 +36,11 @@ pub fn map_page(virt: u64, phys: u64, flags: u64) !void {
pml4[pml4_index] = pdpt_phys | PAGE_PRESENT | PAGE_WRITABLE | flags;
pdpt_was_new = true;
} else {
- pdpt_phys = pml4[pml4_index] & ~@as(u64, 0xFFF);
+ pdpt_phys = pml4[pml4_index] & paging_const.PTE_MASK;
}
const pdpt: [*]volatile u64 = @ptrFromInt(pdpt_phys + HIGHER_HALF_START);
- // If we just created this PDPT, zero only the entry we're about to use
if (pdpt_was_new) {
pdpt[pdpt_index] = 0;
}
@@ -56,12 +52,11 @@ pub fn map_page(virt: u64, phys: u64, flags: u64) !void {
pdpt[pdpt_index] = pd_phys | PAGE_PRESENT | PAGE_WRITABLE | flags;
pd_was_new = true;
} else {
- pd_phys = pdpt[pdpt_index] & ~@as(u64, 0xFFF);
+ pd_phys = pdpt[pdpt_index] & paging_const.PTE_MASK;
}
const pd: [*]volatile u64 = @ptrFromInt(pd_phys + HIGHER_HALF_START);
- // If we just created this PD, zero only the entry we're about to use
if (pd_was_new) {
pd[pd_index] = 0;
}
@@ -73,58 +68,48 @@ pub fn map_page(virt: u64, phys: u64, flags: u64) !void {
pd[pd_index] = pt_phys | PAGE_PRESENT | PAGE_WRITABLE | flags;
pt_was_new = true;
} else {
- pt_phys = pd[pd_index] & ~@as(u64, 0xFFF);
+ pt_phys = pd[pd_index] & paging_const.PTE_MASK;
}
const pt: [*]volatile u64 = @ptrFromInt(pt_phys + HIGHER_HALF_START);
- // If we just created this PT, zero only the entry we're about to use
if (pt_was_new) {
pt[pt_index] = 0;
}
pt[pt_index] = phys | PAGE_PRESENT | flags;
- // Flush TLB for the new mapping
- memory.invalidate_page(virt);
+ asm_memory.invalidate_page(virt);
}
-// Create completely independent page table structure for user
pub fn create_page_table() !u64 {
const new_pml4_phys = pmm.alloc_page() orelse return error.OutOfMemory;
const new_pml4: [*]volatile u64 = @ptrFromInt(new_pml4_phys + HIGHER_HALF_START);
- var i: usize = 0;
- while (i < 512) : (i += 1) {
+ for (0..paging_const.PML4_ENTRIES) |i| {
new_pml4[i] = 0;
}
- const kernel_pml4_phys = memory.read_page_table_base() & ~@as(u64, 0xFFF);
+ const kernel_pml4_phys = asm_memory.read_page_table_base() & ~@as(u64, paging_const.OFFSET_MASK);
const kernel_pml4: [*]volatile u64 = @ptrFromInt(kernel_pml4_phys + HIGHER_HALF_START);
- // Copy higher-half mappings (PML4[256-511]) for kernel heap/data access
- i = 256;
- while (i < 512) : (i += 1) {
+ for (paging_const.KERNEL_PML4_START..paging_const.PML4_ENTRIES) |i| {
new_pml4[i] = kernel_pml4[i];
}
- // Map kernel (0x100000-0x1000000 = 16MB) as supervisor-only
- var addr: u64 = 0x100000;
- while (addr < 0x1000000) : (addr += PAGE_SIZE) {
+ var addr: u64 = pmm_const.KERNEL_BASE;
+ while (addr < pmm_const.KERNEL_MAP_END) : (addr += PAGE_SIZE) {
_ = try map_page_in_table(new_pml4_phys, addr, addr, PAGE_PRESENT | PAGE_WRITABLE);
}
- // Map MMIO region (0x80000000-0x82000000 = 32MB) for framebuffer and AHCI
- // Supervisor-only
- addr = 0x80000000;
- while (addr < 0x82000000) : (addr += PAGE_SIZE) {
+ addr = pmm_const.MMIO_FRAMEBUFFER_BASE;
+ while (addr < pmm_const.MMIO_FRAMEBUFFER_BASE + 0x2000000) : (addr += PAGE_SIZE) {
_ = try map_page_in_table(new_pml4_phys, addr, addr, PAGE_PRESENT | PAGE_WRITABLE);
}
return new_pml4_phys;
}
-// Map a page in a specific page table
pub fn map_page_in_table(page_table_phys: u64, virt: u64, phys: u64, flags: u64) !struct { bool, u64 } {
const pml4_index = (virt >> 39) & 0x1FF;
const pdpt_index = (virt >> 30) & 0x1FF;
@@ -139,7 +124,7 @@ pub fn map_page_in_table(page_table_phys: u64, virt: u64, phys: u64, flags: u64)
zero_page(pdpt_phys + HIGHER_HALF_START);
pml4[pml4_index] = pdpt_phys | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
} else {
- pdpt_phys = pml4[pml4_index] & ~@as(u64, 0xFFF);
+ pdpt_phys = pml4[pml4_index] & paging_const.PTE_MASK;
}
const pdpt: [*]volatile u64 = @ptrFromInt(pdpt_phys + HIGHER_HALF_START);
@@ -150,7 +135,7 @@ pub fn map_page_in_table(page_table_phys: u64, virt: u64, phys: u64, flags: u64)
zero_page(pd_phys + HIGHER_HALF_START);
pdpt[pdpt_index] = pd_phys | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
} else {
- pd_phys = pdpt[pdpt_index] & ~@as(u64, 0xFFF);
+ pd_phys = pdpt[pdpt_index] & paging_const.PTE_MASK;
}
const pd: [*]volatile u64 = @ptrFromInt(pd_phys + HIGHER_HALF_START);
@@ -161,7 +146,7 @@ pub fn map_page_in_table(page_table_phys: u64, virt: u64, phys: u64, flags: u64)
zero_page(pt_phys + HIGHER_HALF_START);
pd[pd_index] = pt_phys | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
} else {
- pt_phys = pd[pd_index] & ~@as(u64, 0xFFF);
+ pt_phys = pd[pd_index] & paging_const.PTE_MASK;
}
const pt: [*]volatile u64 = @ptrFromInt(pt_phys + HIGHER_HALF_START);
@@ -171,8 +156,7 @@ pub fn map_page_in_table(page_table_phys: u64, virt: u64, phys: u64, flags: u64)
pt[pt_index] = phys | flags | PAGE_PRESENT;
return .{ false, phys };
} else {
- const existing_phys = pt[pt_index] & ~@as(u64, 0xFFF);
- // Update entry if flags changed (e.g., upgrading to writable)
+ const existing_phys = pt[pt_index] & paging_const.PTE_MASK;
pt[pt_index] = existing_phys | flags | PAGE_PRESENT;
return .{ true, existing_phys };
}
@@ -183,24 +167,23 @@ pub fn get_physical_address(page_table: u64, vaddr: u64) !u64 {
const pdp_index = (vaddr >> 30) & 0x1FF;
const pd_index = (vaddr >> 21) & 0x1FF;
const pt_index = (vaddr >> 12) & 0x1FF;
- const offset = vaddr & 0xFFF;
+ const offset = vaddr & paging_const.OFFSET_MASK;
const pml4 = @as([*]u64, @ptrFromInt(page_table + HIGHER_HALF_START));
- if ((pml4[pml4_index] & 1) == 0) return error.NotMapped;
+ if ((pml4[pml4_index] & PAGE_PRESENT) == 0) return error.NotMapped;
- const pdp = @as([*]u64, @ptrFromInt((pml4[pml4_index] & ~@as(u64, 0xFFF)) + HIGHER_HALF_START));
- if ((pdp[pdp_index] & 1) == 0) return error.NotMapped;
+ const pdp = @as([*]u64, @ptrFromInt((pml4[pml4_index] & paging_const.PTE_MASK) + HIGHER_HALF_START));
+ if ((pdp[pdp_index] & PAGE_PRESENT) == 0) return error.NotMapped;
- const pd = @as([*]u64, @ptrFromInt((pdp[pdp_index] & ~@as(u64, 0xFFF)) + HIGHER_HALF_START));
- if ((pd[pd_index] & 1) == 0) return error.NotMapped;
+ const pd = @as([*]u64, @ptrFromInt((pdp[pdp_index] & paging_const.PTE_MASK) + HIGHER_HALF_START));
+ if ((pd[pd_index] & PAGE_PRESENT) == 0) return error.NotMapped;
- const pt = @as([*]u64, @ptrFromInt((pd[pd_index] & ~@as(u64, 0xFFF)) + HIGHER_HALF_START));
- if ((pt[pt_index] & 1) == 0) return error.NotMapped;
+ const pt = @as([*]u64, @ptrFromInt((pd[pd_index] & paging_const.PTE_MASK) + HIGHER_HALF_START));
+ if ((pt[pt_index] & PAGE_PRESENT) == 0) return error.NotMapped;
- return (pt[pt_index] & ~@as(u64, 0xFFF)) + offset;
+ return (pt[pt_index] & paging_const.PTE_MASK) + offset;
}
-// Get the page table entry for a virtual address (returns null if not mapped)
pub fn get_page_entry(page_table_phys: u64, virt: u64) ?u64 {
const pml4_index = (virt >> 39) & 0x1FF;
const pdpt_index = (virt >> 30) & 0x1FF;
@@ -210,56 +193,55 @@ pub fn get_page_entry(page_table_phys: u64, virt: u64) ?u64 {
const pml4: [*]volatile u64 = @ptrFromInt(page_table_phys + HIGHER_HALF_START);
if ((pml4[pml4_index] & PAGE_PRESENT) == 0) return null;
- const pdpt_phys = pml4[pml4_index] & ~@as(u64, 0xFFF);
+ const pdpt_phys = pml4[pml4_index] & paging_const.PTE_MASK;
const pdpt: [*]volatile u64 = @ptrFromInt(pdpt_phys + HIGHER_HALF_START);
if ((pdpt[pdpt_index] & PAGE_PRESENT) == 0) return null;
- const pd_phys = pdpt[pdpt_index] & ~@as(u64, 0xFFF);
+ const pd_phys = pdpt[pdpt_index] & paging_const.PTE_MASK;
const pd: [*]volatile u64 = @ptrFromInt(pd_phys + HIGHER_HALF_START);
if ((pd[pd_index] & PAGE_PRESENT) == 0) return null;
- const pt_phys = pd[pd_index] & ~@as(u64, 0xFFF);
+ const pt_phys = pd[pd_index] & paging_const.PTE_MASK;
const pt: [*]volatile u64 = @ptrFromInt(pt_phys + HIGHER_HALF_START);
return pt[pt_index];
}
pub fn virt_to_phys(cr3: u64, virt: u64) ?u64 {
- // Walk the 4-level page table
const pml4_addr = cr3 + HIGHER_HALF_START;
const pml4 = @as([*]u64, @ptrFromInt(pml4_addr));
const pml4_index = (virt >> 39) & 0x1FF;
const pml4_entry = pml4[pml4_index];
- if ((pml4_entry & 1) == 0) return null; // Not present
+ if ((pml4_entry & PAGE_PRESENT) == 0) return null;
- const pdp_addr = (pml4_entry & 0x000FFFFFFFFFF000) + HIGHER_HALF_START;
+ const pdp_addr = (pml4_entry & paging_const.PTE_MASK) + HIGHER_HALF_START;
const pdp = @as([*]u64, @ptrFromInt(pdp_addr));
const pdp_index = (virt >> 30) & 0x1FF;
const pdp_entry = pdp[pdp_index];
- if ((pdp_entry & 1) == 0) return null; // Not present
+ if ((pdp_entry & PAGE_PRESENT) == 0) return null;
- const pd_addr = (pdp_entry & 0x000FFFFFFFFFF000) + HIGHER_HALF_START;
+ const pd_addr = (pdp_entry & paging_const.PTE_MASK) + HIGHER_HALF_START;
const pd = @as([*]u64, @ptrFromInt(pd_addr));
const pd_index = (virt >> 21) & 0x1FF;
const pd_entry = pd[pd_index];
- if ((pd_entry & 1) == 0) return null; // Not present
+ if ((pd_entry & PAGE_PRESENT) == 0) return null;
- const pt_addr = (pd_entry & 0x000FFFFFFFFFF000) + HIGHER_HALF_START;
+ const pt_addr = (pd_entry & paging_const.PTE_MASK) + HIGHER_HALF_START;
const pt = @as([*]u64, @ptrFromInt(pt_addr));
const pt_index = (virt >> 12) & 0x1FF;
const pt_entry = pt[pt_index];
- if ((pt_entry & 1) == 0) return null; // Not present
+ if ((pt_entry & PAGE_PRESENT) == 0) return null;
- const phys_base = pt_entry & 0x000FFFFFFFFFF000;
- const offset = virt & 0xFFF;
+ const phys_base = pt_entry & paging_const.PTE_MASK;
+ const offset = virt & paging_const.OFFSET_MASK;
return phys_base + offset;
}