1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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;
}
|