123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- use super::SbiRet;
- use crate::hart_mask::HartMask;
- use crate::ipi::max_hart_id;
- use crate::rfence;
- 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(),
- }
- }
- // If None = max_hart_id(), that means IPI extension is not supported.
- // In RustSBI, RFENCE support requires an IPI support is implemented.
- // If platform does not provide IPI support, RustSBI will disable RFENCE
- // interface access from supervisor level.
- #[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)
- }
|