WIP: Allow userspace to use stack

This commit is contained in:
2025-03-26 14:22:33 +02:00
parent 000b434c96
commit f57fd485c5
4 changed files with 35 additions and 12 deletions
+6 -2
View File
@@ -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();
+6 -2
View File
@@ -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();
+10 -2
View File
@@ -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");
+13 -6
View File
@@ -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;
}