aboutsummaryrefslogtreecommitdiff
path: root/src/sbi.zig
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-04-19 19:48:06 +0200
committerHimbeer <himbeer@disroot.org>2024-04-19 19:48:06 +0200
commit8451d36574fa4348c27bf9f83e0eb03f45bc5c53 (patch)
treec2b773a176bd1dee11a0ba16417ab839ef197484 /src/sbi.zig
parentfe1c80db9f7826967267a3533476ef3a771e7035 (diff)
merge sbi base and error handling modules into single main module file
Diffstat (limited to 'src/sbi.zig')
-rw-r--r--src/sbi.zig123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/sbi.zig b/src/sbi.zig
new file mode 100644
index 0000000..2072b90
--- /dev/null
+++ b/src/sbi.zig
@@ -0,0 +1,123 @@
+// SPDX-FileCopyrightText: 2024 Himbeer <himbeer@disroot.org>
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+const instructions = @import("instructions.zig");
+
+pub const Error = error{
+ Success,
+ Failed,
+ NotSupported,
+ InvalidParam,
+ Denied,
+ InvalidAddr,
+ AlreadyAvail,
+ AlreadyStarted,
+ AlreadyStopped,
+ NoSharedMem,
+ Unknown,
+};
+
+pub fn errorFromCode(code: isize) Error {
+ return switch (code) {
+ 0 => Error.Success,
+ -1 => Error.Failed,
+ -2 => Error.NotSupported,
+ -3 => Error.InvalidParam,
+ -4 => Error.Denied,
+ -5 => Error.InvalidAddr,
+ -6 => Error.AlreadyAvail,
+ -7 => Error.AlreadyStarted,
+ -8 => Error.AlreadyStopped,
+ -9 => Error.NoSharedMem,
+ else => Error.Unknown,
+ };
+}
+
+const BaseExtId: usize = 0x10;
+
+const BaseFnId = enum(usize) {
+ GetSpecVer = 0,
+ GetImpId = 1,
+ GetImpVer = 2,
+ ProbeExt = 3,
+ GetMVendorId = 4,
+ GetMArchId = 5,
+ GetMImpId = 6,
+};
+
+pub const ImpId = enum(isize) {
+ Bbl = 0,
+ OpenSbi = 1,
+ Xvisor = 2,
+ Kvm = 3,
+ RustSbi = 4,
+ Diosix = 5,
+ Coffer = 6,
+ Xen = 7,
+ PolarFire = 8,
+ _,
+};
+
+pub fn specVer() !isize {
+ const ret = instructions.ecall(BaseExtId, @intFromEnum(BaseFnId.GetSpecVer), 0, 0, 0);
+ if (ret.err != 0) {
+ return errorFromCode(ret.err);
+ }
+
+ return ret.val;
+}
+
+pub fn impId() !ImpId {
+ const ret = instructions.ecall(BaseExtId, @intFromEnum(BaseFnId.GetImpId), 0, 0, 0);
+ if (ret.err != 0) {
+ return errorFromCode(ret.err);
+ }
+
+ return @enumFromInt(ret.val);
+}
+
+pub fn impVer() !isize {
+ const ret = instructions.ecall(BaseExtId, @intFromEnum(BaseFnId.GetImpVer), 0, 0, 0);
+ if (ret.err != 0) {
+ return errorFromCode(ret.err);
+ }
+
+ return ret.val;
+}
+
+pub fn probeExt(ext_id: usize) !bool {
+ const ret = instructions.ecall(BaseExtId, @intFromEnum(BaseFnId.ProbeExt), ext_id, 0, 0);
+ if (ret.err != 0) {
+ return errorFromCode(ret.err);
+ }
+
+ return ret.val != 0;
+}
+
+pub fn mVendorId() !isize {
+ const ret = instructions.ecall(BaseExtId, @intFromEnum(BaseFnId.GetMVendorId), 0, 0, 0);
+ if (ret.err != 0) {
+ return errorFromCode(ret.err);
+ }
+
+ return ret.val;
+}
+
+pub fn mArchId() !isize {
+ const ret = instructions.ecall(BaseExtId, @intFromEnum(BaseFnId.GetMarchId), 0, 0, 0);
+ if (ret.err != 0) {
+ return errorFromCode(ret.err);
+ }
+
+ return ret.val;
+}
+
+pub fn mImpId() !isize {
+ const ret = instructions.ecall(BaseExtId, @intFromEnum(BaseFnId.GetMImpId), 0, 0, 0);
+ if (ret.err != 0) {
+ return errorFromCode(ret.err);
+ }
+
+ return ret.val;
+}