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
use core::arch::asm;
use log::info;
const CONSOLE_PUTCHAR_EXTENSION: usize = 0x01;
const CONSOLE_GETCHAR_EXTENSION: usize = 0x02;
const SYSTEM_RESET_EXTENSION: usize = 0x53525354;
const TIMER_EXTENSION: usize = 0x54494D45;
#[inline]
fn sbi_call(extension: usize, function: usize, arg0: usize, arg1: usize) -> (isize, isize) {
let (error, value);
unsafe {
asm!(
"ecall",
inlateout("a0") arg0 => error,
inlateout("a1") arg1 => value,
in("a6") function,
in("a7") extension,
)
}
(error, value)
}
#[inline]
pub fn set_timer(stime_value: usize) {
sbi_call(TIMER_EXTENSION, 0, stime_value, 0);
}
#[inline]
pub fn console_putchar(char: usize) {
sbi_call(CONSOLE_PUTCHAR_EXTENSION, 0, char, 0);
}
#[inline]
pub fn console_getchar() -> usize {
let (value, _) = sbi_call(CONSOLE_GETCHAR_EXTENSION, 0, 0, 0);
value.max(0) as usize
}
#[inline]
pub fn shutdown() -> ! {
info!("shutdown");
sbi_call(SYSTEM_RESET_EXTENSION, 0, 0, 0);
panic!("failed to shutdown");
}