// SPDX-FileCopyrightText: 2024 Himbeer // // SPDX-License-Identifier: AGPL-3.0-or-later const riscv = @import("riscv.zig"); pub const Error = error{ Success, Failed, NotSupported, InvalidParam, Denied, InvalidAddr, AlreadyAvail, AlreadyStarted, AlreadyStopped, NoSharedMem, InvalidState, BadRange, SbiUnknown, }; 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, -10 => Error.InvalidState, -11 => Error.BadRange, else => Error.SbiUnknown, }; } const BaseExtId: usize = 0x10; const BaseFnId = enum(usize) { GetSpecVer, GetImpId, GetImpVer, ProbeExt, GetMVendorId, GetMArchId, GetMImpId, }; pub const ImpId = enum(isize) { Bbl, OpenSbi, Xvisor, Kvm, RustSbi, Diosix, Coffer, Xen, PolarFire, _, }; pub fn specVer() !isize { const ret = riscv.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 = riscv.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 = riscv.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 = riscv.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 = riscv.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 = riscv.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 = riscv.ecall(BaseExtId, @intFromEnum(BaseFnId.GetMImpId), 0, 0, 0); if (ret.err != 0) { return errorFromCode(ret.err); } return ret.val; }