diff --git a/src/thread.zig b/src/thread.zig index 319a7d5..424b01a 100644 --- a/src/thread.zig +++ b/src/thread.zig @@ -327,7 +327,7 @@ pub fn test_create_user_from_code(a: *arena.Arena, code: []const u8) Thread.Erro log.info("Enter with sp = 0x{x}", .{sp}); - const thread = Thread.create_user(a, address_space, 0x200000, sp, 0); + const thread = Thread.create_user(a, address_space, 0x200000, sp, 1234); return thread; } diff --git a/user/arch.zig b/user/arch.zig new file mode 100644 index 0000000..0b726e9 --- /dev/null +++ b/user/arch.zig @@ -0,0 +1,9 @@ +const builtin = @import("builtin"); + +const impl = switch (builtin.cpu.arch) { + .riscv64 => @import("arch/riscv64.zig"), + .aarch64 => @import("arch/aarch64.zig"), + else => @compileError("Unsupported architecture"), +}; + +pub const syscall = impl.syscall; diff --git a/user/arch/aarch64.zig b/user/arch/aarch64.zig new file mode 100644 index 0000000..69b0c24 --- /dev/null +++ b/user/arch/aarch64.zig @@ -0,0 +1,20 @@ +pub const syscall = struct { + pub fn syscall1(func: usize, arg0: usize) usize { + return asm volatile ("svc #0" + : [result] "={x0}" (-> usize), + : [arg0] "{x0}" (arg0), + [func] "{x8}" (func), + : "memory" + ); + } + + pub fn syscall2(func: usize, arg0: usize, arg1: usize) usize { + return asm volatile ("svc #0" + : [result] "={x0}" (-> usize), + : [arg0] "{x0}" (arg0), + [arg1] "{x1}" (arg1), + [func] "{x8}" (func), + : "memory" + ); + } +}; diff --git a/user/arch/riscv64.zig b/user/arch/riscv64.zig new file mode 100644 index 0000000..dcfc0a2 --- /dev/null +++ b/user/arch/riscv64.zig @@ -0,0 +1,20 @@ +pub const syscall = struct { + pub fn syscall1(func: usize, arg0: usize) usize { + return asm volatile ("ecall" + : [result] "={a0}" (-> usize), + : [func] "{a0}" (func), + [arg0] "{a1}" (arg0), + : "memory" + ); + } + + pub fn syscall2(func: usize, arg0: usize, arg1: usize) usize { + return asm volatile ("ecall" + : [result] "={a0}" (-> usize), + : [func] "{a0}" (func), + [arg0] "{a1}" (arg0), + [arg1] "{a2}" (arg1), + : "memory" + ); + } +}; diff --git a/user/log.zig b/user/log.zig new file mode 100644 index 0000000..69209fe --- /dev/null +++ b/user/log.zig @@ -0,0 +1,28 @@ +const std = @import("std"); +const syscall = @import("syscall.zig"); + +pub const BUFFER_SIZE: usize = 512; + +pub const Writer = struct { + buffer: [BUFFER_SIZE]u8 = undefined, + position: usize = 0, + + fn write(self: *Writer, bytes: []const u8) error{}!usize { + const amount = @min(BUFFER_SIZE - self.position, bytes.len); + if (amount != 0) { + @memcpy(self.buffer[self.position .. self.position + amount], bytes[0..amount]); + self.position += amount; + } + return amount; + } +}; + +pub fn println(comptime format: []const u8, args: anytype) void { + const W = std.io.GenericWriter(*Writer, error{}, Writer.write); + var context = Writer{}; + var w = W{ .context = &context }; + w.print(format, args) catch return; + if (context.position != 0) { + syscall.debug_print(context.buffer[0..context.position]); + } +} diff --git a/user/main.zig b/user/main.zig index 9fd9b64..4d05b1a 100644 --- a/user/main.zig +++ b/user/main.zig @@ -1,59 +1,8 @@ -const builtin = @import("builtin"); +pub const arch = @import("arch.zig"); +pub const syscall = @import("syscall.zig"); +pub const log = @import("log.zig"); -const syscall = switch (builtin.cpu.arch) { - .aarch64 => struct { - pub fn syscall1(func: usize, arg0: usize) usize { - return asm volatile ("svc #0" - : [result] "={x0}" (-> usize), - : [arg0] "{x0}" (arg0), - [func] "{x8}" (func), - : "memory" - ); - } - - pub fn syscall2(func: usize, arg0: usize, arg1: usize) usize { - return asm volatile ("svc #0" - : [result] "={x0}" (-> usize), - : [arg0] "{x0}" (arg0), - [arg1] "{x1}" (arg1), - [func] "{x8}" (func), - : "memory" - ); - } - }, - .riscv64 => struct { - pub fn syscall1(func: usize, arg0: usize) usize { - return asm volatile ("ecall" - : [result] "={a0}" (-> usize), - : [func] "{a0}" (func), - [arg0] "{a1}" (arg0), - : "memory" - ); - } - - pub fn syscall2(func: usize, arg0: usize, arg1: usize) usize { - return asm volatile ("ecall" - : [result] "={a0}" (-> usize), - : [func] "{a0}" (func), - [arg0] "{a1}" (arg0), - [arg1] "{a2}" (arg1), - : "memory" - ); - } - }, - else => @compileError("Unsupported architecture"), -}; - -fn exit(code: u32) noreturn { - _ = syscall.syscall1(2, code); - unreachable; -} - -fn debug_print(text: []const u8) void { - _ = syscall.syscall2(1, @intFromPtr(text.ptr), text.len); -} - -export fn _start() linksection(".text.entry") callconv(.C) noreturn { - debug_print("Hello!"); - exit(0); +export fn _start(arg: usize) linksection(".text.entry") callconv(.C) noreturn { + log.println("arg=0x{x} ({})", .{ arg, arg }); + syscall.exit(0); } diff --git a/user/syscall.zig b/user/syscall.zig new file mode 100644 index 0000000..7ac13d3 --- /dev/null +++ b/user/syscall.zig @@ -0,0 +1,12 @@ +const arch = @import("arch.zig"); + +const sc = arch.syscall; + +pub fn exit(code: u32) noreturn { + _ = sc.syscall1(2, code); + unreachable; +} + +pub fn debug_print(text: []const u8) void { + _ = sc.syscall2(1, @intFromPtr(text.ptr), text.len); +}