From f57fd485c5637ac4bc6bf5fdb9e0e43b5ba7fa50 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Wed, 26 Mar 2025 14:22:33 +0200 Subject: [PATCH] WIP: Allow userspace to use stack --- src/arch/aarch64/vmm.zig | 8 ++++++-- src/arch/riscv64/vmm.zig | 8 ++++++-- src/kernel.zig | 12 ++++++++++-- src/thread.zig | 19 +++++++++++++------ 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/arch/aarch64/vmm.zig b/src/arch/aarch64/vmm.zig index def4634..dea1441 100644 --- a/src/arch/aarch64/vmm.zig +++ b/src/arch/aarch64/vmm.zig @@ -155,6 +155,10 @@ pub fn Table(comptime Level: type) type { return table; } + pub fn from_physical_address(physical: PhysicalAddress) *@This() { + return @ptrFromInt(physical.virtualize()); + } + pub inline fn entry(self: *@This(), index: usize) *Entry { return &self.entries[index]; } @@ -167,7 +171,7 @@ pub fn Table(comptime Level: type) type { pub fn get_next_level(self: *Table(Level), index: usize) ?*Table(NextLevel) { const ent = self.entry(index); if (ent.raw.V and !ent.raw.P) { - @panic("TODO: translate existing table"); + return Table(NextLevel).from_physical_address(ent.address()); } return null; } @@ -180,7 +184,7 @@ pub fn Table(comptime Level: type) type { } // Entry is a table - @panic("TODO: translate existing table"); + return Table(NextLevel).from_physical_address(ent.address()); } else { const table = try Table(NextLevel).allocate_empty(); const physical = table.physical_address(); diff --git a/src/arch/riscv64/vmm.zig b/src/arch/riscv64/vmm.zig index 3799c01..f9eb6ca 100644 --- a/src/arch/riscv64/vmm.zig +++ b/src/arch/riscv64/vmm.zig @@ -115,6 +115,10 @@ pub fn Table(comptime Level: type) type { return .{ .entries = [_]Entry{.INVALID} ** 512 }; } + pub fn from_physical_address(physical: PhysicalAddress) *@This() { + return @ptrFromInt(physical.virtualize()); + } + pub fn allocate_empty() Error!*@This() { const page = mem.phys.alloc_page() orelse return error.out_of_pages; const table = @as(*@This(), @ptrFromInt(page.virtualize())); @@ -136,7 +140,7 @@ pub fn Table(comptime Level: type) type { pub fn get_next_level(self: *Table(Level), index: usize) ?*Table(NextLevel) { const ent = self.entry(index); if (ent.raw.v and ent.raw.is_table()) { - @panic("TODO: translate existing table"); + return Table(NextLevel).from_physical_address(ent.address()); } return null; } @@ -150,7 +154,7 @@ pub fn Table(comptime Level: type) type { @panic("TODO: handle mixed hugepages and tables"); } // It is a table - @panic("TODO: translate existing table"); + return Table(NextLevel).from_physical_address(ent.address()); } else { // Allocate a new entry const table = try Table(NextLevel).allocate_empty(); diff --git a/src/kernel.zig b/src/kernel.zig index d7e8b64..df5d777 100644 --- a/src/kernel.zig +++ b/src/kernel.zig @@ -40,9 +40,17 @@ pub export fn kernel_main() callconv(.C) noreturn { const t0 = thread.Thread.create_kernel(&a, &f0, 1234); const code = switch (comptime arch.cpu) { - .riscv64 => &[_]u8{ 0x6F, 0x00, 0x00, 0x00 }, + .riscv64 => &[_]u8{ + 0x93, 0x02, 0xB0, 0x07, // li t0, 123 + 0x13, 0x01, 0x81, 0xFF, // addi sp, sp, -8 + 0x23, 0x30, 0x51, 0x00, // sd t0, (sp) + 0x6F, 0x00, 0x00, 0x00, // j . + }, .aarch64 => &[_]u8{ - 0x00, 0x00, 0x00, 0x14, + 0x60, 0x0F, 0x80, 0xD2, // mov x0, #123 + 0xFF, 0x23, 0x00, 0xD1, // sub sp, sp, #8 + 0xE0, 0x03, 0x00, 0xF9, // str x0, [sp] + 0x00, 0x00, 0x00, 0x14, // b . }, }; const t1 = thread.test_create_user_from_code(&a, code) catch @panic("Could not create test thread"); diff --git a/src/thread.zig b/src/thread.zig index 9f21473..a906cdf 100644 --- a/src/thread.zig +++ b/src/thread.zig @@ -217,17 +217,24 @@ pub fn test_create_user_from_code(a: *arena.Arena, code: []const u8) Thread.Erro address_space.clear(); } - // Map 0x200000 - const page = mem.phys.alloc_page() orelse return error.out_of_memory; + // @ 0x200000 + const code_page = mem.phys.alloc_page() orelse return error.out_of_memory; errdefer { - mem.phys.free_page(page); + mem.phys.free_page(code_page); + } + // @ 0x201000 + const stack_page = mem.phys.alloc_page() orelse return error.out_of_memory; + errdefer { + mem.phys.free_page(stack_page); } - try address_space.map_single_page(0x200000, page); - const page_data = @as([*]u8, @ptrFromInt(page.virtualize()))[0..code.len]; + try address_space.map_single_page(0x200000, code_page); + try address_space.map_single_page(0x201000, stack_page); + + const page_data = @as([*]u8, @ptrFromInt(code_page.virtualize()))[0..code.len]; @memcpy(page_data, code); - const thread = Thread.create_user(a, address_space, 0x200000, 0, 0); + const thread = Thread.create_user(a, address_space, 0x200000, 0x201000, 0); return thread; }