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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use core::time::Duration;
use crate::panic;
use riscv::register::*;
use crate::symbols::*;
use core::sync::atomic::Ordering;
pub fn time() -> Duration {
let mtime = crate::clint::CLINT_MTIME_BASE as *const u64;
Duration::from_nanos(unsafe { mtime.read_volatile() } * 100)
}
pub fn build_satp(mode: usize, asid: usize, addr: usize) -> usize {
if addr % PAGE_SIZE != 0 {
panic!("satp not aligned!");
}
(mode as usize) << 60 | (asid & 0xffff) << 44 | (addr >> 12) & 0xff_ffff_ffff
}
pub fn intr_on() {
use crate::panic_println;
unsafe {
sie::set_sext();
sie::set_ssoft();
sie::set_stimer();
sstatus::set_sie();
}
}
pub fn intr_off() {
use crate::panic_println;
unsafe {
sstatus::clear_sie();
}
}
pub fn intr_get() -> bool {
sstatus::read().sie()
}
#[inline(always)]
#[allow(unused_assignments)]
pub fn hart_id() -> usize {
let mut hart_id: usize = 0;
unsafe { llvm_asm!("mv $0, tp" : "=r"(hart_id) ::: "volatile"); }
hart_id
}
#[inline]
#[allow(unused_assignments)]
pub fn r_sip() -> usize {
let mut sip: usize = 0;
unsafe { llvm_asm!("csrr $0, sip" : "=r"(sip) ::: "volatile"); }
sip
}
#[inline]
pub fn w_sip(x: usize) {
unsafe { llvm_asm!("csrw sip, $0" :: "r"(x) :: "volatile"); }
}
#[inline]
#[allow(unused_assignments)]
pub fn r_sstatus() -> usize {
let mut x: usize = 0;
unsafe { llvm_asm!("csrr $0, sstatus" : "=r"(x) ::: "volatile"); }
x
}
#[inline]
#[allow(unused_assignments)]
pub fn r_satp() -> usize {
let mut x: usize = 0;
unsafe { llvm_asm!("csrr $0, satp" : "=r"(x) ::: "volatile"); }
x
}
#[inline]
pub fn w_sstatus(x: usize) {
unsafe { llvm_asm!("csrw sstatus, $0" :: "r"(x) :: "volatile"); }
}
#[inline(always)]
pub fn __sync_synchronize() {
core::sync::atomic::compiler_fence(Ordering::SeqCst);
unsafe { asm!("fence"); }
}
#[inline(always)]
pub fn __sync_lock_test_and_set(a: &u32, mut b: u32) -> u32 {
unsafe { llvm_asm!("amoswap.w.aq $0, $1, ($2)" :"=r"(b): "r"(b), "r"(a) :: "volatile"); }
b
}
#[inline(always)]
pub fn __sync_lock_release(a: &u32) {
unsafe { llvm_asm!("amoswap.w zero, zero, ($0)" :: "r"(a) :: "volatile"); }
}
#[inline(always)]
pub unsafe fn w_ra(x: usize) {
llvm_asm!("mv ra, $0" :: "r"(x) :: "volatile");
}
pub fn sp() -> usize {
let mut sp: usize = 0;
unsafe { llvm_asm!("mv $0, sp" : "=r"(sp) ::: "volatile"); }
sp
}
pub fn wait_forever() -> ! {
loop {
unsafe {
riscv::asm::wfi();
}
}
}