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
use super::SbiRet;
use crate::rfence;
use crate::hart_mask::HartMask;
use crate::ipi::max_hart_id;
const FUNCTION_RFENCE_REMOTE_FENCE_I: usize = 0x0;
const FUNCTION_RFENCE_REMOTE_SFENCE_VMA: usize = 0x1;
const FUNCTION_RFENCE_REMOTE_SFENCE_VMA_ASID: usize = 0x2;
const FUNCTION_RFENCE_REMOTE_HFENCE_GVMA_VMID: usize = 0x3;
const FUNCTION_RFENCE_REMOTE_HFENCE_GVMA: usize = 0x4;
const FUNCTION_RFENCE_REMOTE_HFENCE_VVMA_ASID: usize = 0x5;
const FUNCTION_RFENCE_REMOTE_HFENCE_VVMA: usize = 0x6;
#[inline]
pub fn handle_ecall_rfence(function: usize, param0: usize, param1: usize, param2: usize, param3: usize, param4: usize) -> SbiRet {
match function {
FUNCTION_RFENCE_REMOTE_FENCE_I => remote_fence_i(param0, param1),
FUNCTION_RFENCE_REMOTE_SFENCE_VMA => remote_sfence_vma(param0, param1, param2, param3),
FUNCTION_RFENCE_REMOTE_SFENCE_VMA_ASID => remote_sfence_vma_asid(param0, param1, param2, param3, param4),
FUNCTION_RFENCE_REMOTE_HFENCE_GVMA_VMID => remote_hfence_gvma_vmid(param0, param1, param2, param3, param4),
FUNCTION_RFENCE_REMOTE_HFENCE_GVMA => remote_hfence_gvma(param0, param1, param2, param3),
FUNCTION_RFENCE_REMOTE_HFENCE_VVMA_ASID => remote_hfence_vvma_asid(param0, param1, param2, param3, param4),
FUNCTION_RFENCE_REMOTE_HFENCE_VVMA => remote_hfence_vvma(param0, param1, param2, param3),
_ => SbiRet::not_supported(),
}
}
#[inline]
fn remote_fence_i(hart_mask: usize, hart_mask_base: usize) -> SbiRet {
let max_hart_id = if let Some(id) = max_hart_id() {
id
} else {
return SbiRet::not_supported()
};
let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
rfence::remote_fence_i(hart_mask)
}
#[inline]
fn remote_sfence_vma(hart_mask: usize, hart_mask_base: usize, start_addr: usize, size: usize) -> SbiRet {
let max_hart_id = if let Some(id) = max_hart_id() {
id
} else {
return SbiRet::not_supported()
};
let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
rfence::remote_sfence_vma(hart_mask, start_addr, size)
}
#[inline]
fn remote_sfence_vma_asid(hart_mask: usize, hart_mask_base: usize, start_addr: usize, size: usize, asid: usize) -> SbiRet {
let max_hart_id = if let Some(id) = max_hart_id() {
id
} else {
return SbiRet::not_supported()
};
let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
rfence::remote_sfence_vma_asid(hart_mask, start_addr, size, asid)
}
#[inline]
fn remote_hfence_gvma_vmid(hart_mask: usize, hart_mask_base: usize, start_addr: usize, size: usize, vmid: usize) -> SbiRet {
let max_hart_id = if let Some(id) = max_hart_id() {
id
} else {
return SbiRet::not_supported()
};
let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
rfence::remote_hfence_gvma_vmid(hart_mask, start_addr, size, vmid)
}
#[inline]
fn remote_hfence_gvma(hart_mask: usize, hart_mask_base: usize, start_addr: usize, size: usize) -> SbiRet {
let max_hart_id = if let Some(id) = max_hart_id() {
id
} else {
return SbiRet::not_supported()
};
let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
rfence::remote_hfence_gvma(hart_mask, start_addr, size)
}
#[inline]
fn remote_hfence_vvma_asid(hart_mask: usize, hart_mask_base: usize, start_addr: usize, size: usize, asid: usize) -> SbiRet {
let max_hart_id = if let Some(id) = max_hart_id() {
id
} else {
return SbiRet::not_supported()
};
let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
rfence::remote_hfence_vvma_asid(hart_mask, start_addr, size, asid)
}
#[inline]
fn remote_hfence_vvma(hart_mask: usize, hart_mask_base: usize, start_addr: usize, size: usize) -> SbiRet {
let max_hart_id = if let Some(id) = max_hart_id() {
id
} else {
return SbiRet::not_supported()
};
let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
rfence::remote_hfence_vvma(hart_mask, start_addr, size)
}