123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- //! Chapter 8. RFENCE Extension (EID #0x52464E43 "RFNC")
- use crate::binary::{sbi_call_2, sbi_call_4, sbi_call_5};
- use sbi_spec::{
- binary::{HartMask, SbiRet},
- rfnc::{
- EID_RFNC, REMOTE_FENCE_I, REMOTE_HFENCE_GVMA, REMOTE_HFENCE_GVMA_VMID, REMOTE_HFENCE_VVMA,
- REMOTE_HFENCE_VVMA_ASID, REMOTE_SFENCE_VMA, REMOTE_SFENCE_VMA_ASID,
- },
- };
- /// Execute `FENCE.I` instruction on remote harts.
- ///
- /// # Return value
- ///
- /// Returns `SbiRet::success()` when a remote fence was sent to all the targeted harts successfully.
- ///
- /// This function is defined in RISC-V SBI Specification chapter 8.1.
- #[inline]
- pub fn remote_fence_i(hart_mask: HartMask) -> SbiRet {
- let (hart_mask, hart_mask_base) = hart_mask.into_inner();
- sbi_call_2(EID_RFNC, REMOTE_FENCE_I, hart_mask, hart_mask_base)
- }
- /// Execute `SFENCE.VMA` instructions for all address spaces on remote harts.
- ///
- /// This function instructs the remote harts to execute one or more `SFENCE.VMA` instructions,
- /// covering the range of virtual addresses between `start_addr` and `size`.
- ///
- /// # Return value
- ///
- /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
- ///
- /// | Return code | Description
- /// |:----------------------------|:----------------------------------------------
- /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
- /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
- ///
- /// This function is defined in RISC-V SBI Specification chapter 8.2.
- #[inline]
- pub fn remote_sfence_vma(hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
- let (hart_mask, hart_mask_base) = hart_mask.into_inner();
- sbi_call_4(
- EID_RFNC,
- REMOTE_SFENCE_VMA,
- hart_mask,
- hart_mask_base,
- start_addr,
- size,
- )
- }
- /// Execute address-space-based `SFENCE.VMA` instructions on remote harts.
- ///
- /// This function instructs the remote harts to execute one or more `SFENCE.VMA` instructions,
- /// covering the range of virtual addresses between `start_addr` and `size`.
- /// This covers only the given address space by `asid`.
- ///
- /// # Return value
- ///
- /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
- ///
- /// | Return code | Description
- /// |:----------------------------|:----------------------------------------------
- /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
- /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
- ///
- /// This function is defined in RISC-V SBI Specification chapter 8.3.
- #[inline]
- pub fn remote_sfence_vma_asid(
- hart_mask: HartMask,
- start_addr: usize,
- size: usize,
- asid: usize,
- ) -> SbiRet {
- let (hart_mask, hart_mask_base) = hart_mask.into_inner();
- sbi_call_5(
- EID_RFNC,
- REMOTE_SFENCE_VMA_ASID,
- hart_mask,
- hart_mask_base,
- start_addr,
- size,
- asid,
- )
- }
- /// Execute virtual machine id based `HFENCE.GVMA` instructions on remote harts.
- ///
- /// This function instructs the remote harts to execute one or more `HFENCE.GVMA`
- /// instructions, covering the range of guest physical addresses between `start_addr`
- /// and `size` only for the given virtual machine by `vmid`.
- ///
- /// This function call is only valid on harts implementing the RISC-V hypervisor extension.
- ///
- /// # Return value
- ///
- /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
- ///
- /// | Return code | Description
- /// |:----------------------------|:----------------------------------------------
- /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
- /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart doesn’t support hypervisor extension.
- /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
- ///
- /// This function is defined in RISC-V SBI Specification chapter 8.4.
- #[inline]
- pub fn remote_hfence_gvma_vmid(
- hart_mask: HartMask,
- start_addr: usize,
- size: usize,
- vmid: usize,
- ) -> SbiRet {
- let (hart_mask, hart_mask_base) = hart_mask.into_inner();
- sbi_call_5(
- EID_RFNC,
- REMOTE_HFENCE_GVMA_VMID,
- hart_mask,
- hart_mask_base,
- start_addr,
- size,
- vmid,
- )
- }
- /// Execute `HFENCE.GVMA` instructions for all virtual machines on remote harts.
- ///
- /// This function instructs the remote harts to execute one or more `HFENCE.GVMA` instructions,
- /// covering the range of guest physical addresses between `start_addr` and `size`
- /// for all the guests.
- ///
- /// This function call is only valid on harts implementing the RISC-V hypervisor extension.
- ///
- /// # Return value
- ///
- /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
- ///
- /// | Return code | Description
- /// |:----------------------------|:----------------------------------------------
- /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
- /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart does not support hypervisor extension.
- /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
- ///
- /// This function is defined in RISC-V SBI Specification chapter 8.5.
- #[inline]
- pub fn remote_hfence_gvma(hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
- let (hart_mask, hart_mask_base) = hart_mask.into_inner();
- sbi_call_4(
- EID_RFNC,
- REMOTE_HFENCE_GVMA,
- hart_mask,
- hart_mask_base,
- start_addr,
- size,
- )
- }
- /// Execute address space based `HFENCE.VVMA` for current virtual machine on remote harts.
- ///
- /// This function instructs the remote harts to execute one or more `HFENCE.VVMA` instructions,
- /// covering the range of guest virtual addresses between `start_addr` and `size` for the given
- /// address space by `asid` and current virtual machine (by `vmid` in `hgatp` CSR)
- /// of calling hart.
- ///
- /// This function call is only valid on harts implementing the RISC-V hypervisor extension.
- ///
- /// # Return value
- ///
- /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
- ///
- /// | Return code | Description
- /// |:----------------------------|:----------------------------------------------
- /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
- /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart does not support hypervisor extension.
- /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
- ///
- /// This function is defined in RISC-V SBI Specification chapter 8.6.
- #[inline]
- pub fn remote_hfence_vvma_asid(
- hart_mask: HartMask,
- start_addr: usize,
- size: usize,
- asid: usize,
- ) -> SbiRet {
- let (hart_mask, hart_mask_base) = hart_mask.into_inner();
- sbi_call_5(
- EID_RFNC,
- REMOTE_HFENCE_VVMA_ASID,
- hart_mask,
- hart_mask_base,
- start_addr,
- size,
- asid,
- )
- }
- /// Execute `HFENCE.VVMA` for all address spaces in the current virtual machine on remote harts.
- ///
- /// This function instructs the remote harts to execute one or more `HFENCE.VVMA` instructions,
- /// covering the range of guest virtual addresses between `start_addr` and `size`
- /// for current virtual machine (by `vmid` in `hgatp` CSR) of calling hart.
- ///
- /// This function call is only valid on harts implementing the RISC-V hypervisor extension.
- ///
- /// # Return value
- ///
- /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
- ///
- /// | Return code | Description
- /// |:----------------------------|:----------------------------------------------
- /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
- /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart doesn’t support hypervisor extension.
- /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
- ///
- /// This function is defined in RISC-V SBI Specification chapter 8.7.
- #[inline]
- pub fn remote_hfence_vvma(hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
- let (hart_mask, hart_mask_base) = hart_mask.into_inner();
- sbi_call_4(
- EID_RFNC,
- REMOTE_HFENCE_VVMA,
- hart_mask,
- hart_mask_base,
- start_addr,
- size,
- )
- }
|