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
//! Chapter 14. CPPC Extension (EID #0x43505043 "CPPC")
use crate::binary::sbi_call_1;
#[cfg(target_pointer_width = "64")]
use crate::binary::sbi_call_2;
#[cfg(target_pointer_width = "32")]
use crate::binary::sbi_call_3;
use sbi_spec::{
binary::SbiRet,
cppc::{EID_CPPC, PROBE, READ, READ_HI, WRITE},
};
/// Probe whether the CPPC register is implemented or not by the platform.
///
/// # Parameters
///
/// The `cppc_reg_id` parameter specifies the CPPC register ID.
///
/// # Return value
///
/// If the register is implemented, `SbiRet.value` will contain the register width.
/// If the register is not implemented, `SbiRet.value` will be set to 0.
///
/// The possible error codes returned in `SbiRet.error` are shown in the table below:
///
/// | Return code | Description
/// |:--------------------------|:----------------------------------------------
/// | `SbiRet::success()` | Probe completed successfully.
/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved.
/// | `SbiRet::failed()` | The probe request failed for unspecified or unknown other reasons.
///
/// This function is defined in RISC-V SBI Specification chapter 14.1.
#[inline]
pub fn cppc_probe(cppc_reg_id: u32) -> SbiRet {
sbi_call_1(EID_CPPC, PROBE, cppc_reg_id as _)
}
/// Read the CPPC register identified by given `cppc_reg_id`.
///
/// # Parameters
///
/// The `cppc_reg_id` parameter specifies the CPPC register ID.
///
/// # Return value
///
/// `SbiRet.value` will contain the register value. When supervisor mode XLEN is 32, the `SbiRet.value`
/// will only contain the lower 32 bits of the CPPC register value.
///
/// The possible error codes returned in `SbiRet.error` are shown in the table below:
///
/// | Return code | Description
/// |:--------------------------|:----------------------------------------------
/// | `SbiRet::success()` | Read completed successfully.
/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved.
/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform.
/// | `SbiRet::denied()` | `cppc_reg_id` is a write-only register.
/// | `SbiRet::failed()` | The read request failed for unspecified or unknown other reasons.
///
/// This function is defined in RISC-V SBI Specification chapter 14.2.
#[inline]
pub fn cppc_read(cppc_reg_id: u32) -> SbiRet {
sbi_call_1(EID_CPPC, READ, cppc_reg_id as _)
}
/// Read the upper 32-bit value of the CPPC register identified by `cppc_reg_id`.
///
/// # Parameters
///
/// The `cppc_reg_id` parameter specifies the CPPC register ID.
///
/// # Return value
///
/// `SbiRet.value` will contain the upper 32 bits of the register value. This function always
/// returns zero in `SbiRet.value` when supervisor mode XLEN is 64 or higher.
///
/// The possible error codes returned in `SbiRet.error` are shown in the table below:
///
/// | Return code | Description
/// |:--------------------------|:----------------------------------------------
/// | `SbiRet::success()` | Read completed successfully.
/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved.
/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform.
/// | `SbiRet::denied()` | `cppc_reg_id` is a write-only register.
/// | `SbiRet::failed()` | The read operation request failed for unspecified or unknown other reasons.
///
/// This function is defined in RISC-V SBI Specification chapter 14.3.
#[inline]
pub fn cppc_read_hi(cppc_reg_id: u32) -> SbiRet {
sbi_call_1(EID_CPPC, READ_HI, cppc_reg_id as _)
}
/// Write 64-bit value to the CPPC register identified by given `cppc_reg_id`.
///
/// # Parameters
///
/// The `cppc_reg_id` parameter specifies the CPPC register ID.
///
/// The `value` parameter specifies the value to be written to the register.
///
/// # Return value
///
/// The possible error codes returned in `SbiRet.error` are shown in the table below:
///
/// | Return code | Description
/// |:--------------------------|:----------------------------------------------
/// | `SbiRet::success()` | Write completed successfully.
/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved.
/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform.
/// | `SbiRet::denied()` | `cppc_reg_id` is a read-only register.
/// | `SbiRet::failed()` | The write operation request failed for unspecified or unknown other reasons.
///
/// This function is defined in RISC-V SBI Specification chapter 14.4.
#[inline]
pub fn cppc_write(cppc_reg_id: u32, value: u64) -> SbiRet {
match () {
#[cfg(target_pointer_width = "32")]
() => sbi_call_3(
EID_CPPC,
WRITE,
cppc_reg_id as _,
value as _,
(value >> 32) as _,
),
#[cfg(target_pointer_width = "64")]
() => sbi_call_2(EID_CPPC, WRITE, cppc_reg_id as _, value as _),
}
}