aboutsummaryrefslogtreecommitdiff
path: root/src/lib/instructions.zig
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-05-23 13:48:01 +0200
committerHimbeer <himbeer@disroot.org>2024-05-23 13:48:01 +0200
commit3274a700daff545437f919041cbdce6938eede06 (patch)
tree60a4ec5ebb1406af20733027a2bb4a5d54e54908 /src/lib/instructions.zig
parent0f61d3bed969fecb35e438bfac2fe34f588834c6 (diff)
Drop FDT support in favor of custom HWI format
Fixes numerous parsing bugs and increases efficiency. The kernel now runs successfully on the Lichee Pi 4A.
Diffstat (limited to 'src/lib/instructions.zig')
-rw-r--r--src/lib/instructions.zig66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/lib/instructions.zig b/src/lib/instructions.zig
new file mode 100644
index 0000000..2ae53ec
--- /dev/null
+++ b/src/lib/instructions.zig
@@ -0,0 +1,66 @@
+// SPDX-FileCopyrightText: 2024 Himbeer <himbeer@disroot.org>
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+const std = @import("std");
+
+const paging = @import("paging.zig");
+
+pub const SbiRet = struct {
+ err: isize,
+ val: isize,
+};
+
+// # Arguments
+//
+// * ext_id: Extension ID
+// * fn_id: Function ID (within extension)
+// * a0: Argument 0
+// * a1: Argument 1
+// * a2: Argument 2
+pub fn ecall(ext_id: usize, fn_id: usize, a0: usize, a1: usize, a2: usize) SbiRet {
+ var ret = SbiRet{ .err = 0, .val = 0 };
+
+ asm volatile (
+ \\ ecall
+ \\ sw a0, 0(%[err])
+ \\ sw a1, 0(%[val])
+ :
+ : [err] "r" (&ret.err),
+ [val] "r" (&ret.val),
+ [eid] "{a7}" (ext_id),
+ [fid] "{a6}" (fn_id),
+ [a0] "{a0}" (a0),
+ [a1] "{a1}" (a1),
+ [a2] "{a2}" (a2),
+ );
+
+ return ret;
+}
+
+pub fn stackPointer() usize {
+ return asm volatile (""
+ : [value] "={sp}" (-> usize),
+ );
+}
+
+pub const setSatp = setCsrFn(paging.Satp, "satp").?;
+pub const setSscratch = setCsrFn(usize, "sscratch").?;
+pub const setSepc = setCsrFn(usize, "sepc").?;
+
+pub fn setCsrFn(comptime T: type, csr: []const u8) ?fn (T) callconv(.Inline) void {
+ if (csr.len > 8) return null;
+
+ return struct {
+ inline fn setCsr(value: T) void {
+ const bits: usize = @bitCast(value);
+
+ comptime var buf = [_]u8{0} ** 23;
+
+ asm volatile (std.fmt.bufPrint(buf[0..], "csrw {s}, %[bits]", .{csr}) catch unreachable
+ :
+ : [bits] "r" (bits),
+ );
+ }
+ }.setCsr;
+}