Skip to main content

sbi_rt/
cppc.rs

1//! Chapter 14. CPPC Extension (EID #0x43505043 "CPPC")
2
3use crate::binary::sbi_call_1;
4#[cfg(target_pointer_width = "64")]
5use crate::binary::sbi_call_2;
6#[cfg(target_pointer_width = "32")]
7use crate::binary::sbi_call_3;
8use sbi_spec::{
9    binary::SbiRet,
10    cppc::{EID_CPPC, PROBE, READ, READ_HI, WRITE},
11};
12
13/// Probe whether the CPPC register is implemented or not by the platform.
14///
15/// # Parameters
16///
17/// The `cppc_reg_id` parameter specifies the CPPC register ID.
18///
19/// # Return value
20///
21/// If the register is implemented, `SbiRet.value` will contain the register width.
22/// If the register is not implemented, `SbiRet.value` will be set to 0.
23///
24/// The possible error codes returned in `SbiRet.error` are shown in the table below:
25///
26/// | Return code               | Description
27/// |:--------------------------|:----------------------------------------------
28/// | `SbiRet::success()`       | Probe completed successfully.
29/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved.
30/// | `SbiRet::failed()`        | The probe request failed for unspecified or unknown other reasons.
31///
32/// This function is defined in RISC-V SBI Specification chapter 14.1.
33#[inline]
34#[doc(alias = "sbi_cppc_probe")]
35pub fn cppc_probe(cppc_reg_id: u32) -> SbiRet {
36    sbi_call_1(EID_CPPC, PROBE, cppc_reg_id as _)
37}
38
39/// Read the CPPC register identified by given `cppc_reg_id`.
40///
41/// # Parameters
42///
43/// The `cppc_reg_id` parameter specifies the CPPC register ID.
44///
45/// # Return value
46///
47/// `SbiRet.value` will contain the register value. When supervisor mode XLEN is 32, the `SbiRet.value`
48/// will only contain the lower 32 bits of the CPPC register value.
49///
50/// The possible error codes returned in `SbiRet.error` are shown in the table below:
51///
52/// | Return code               | Description
53/// |:--------------------------|:----------------------------------------------
54/// | `SbiRet::success()`       | Read completed successfully.
55/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved.
56/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform.
57/// | `SbiRet::denied()`        | `cppc_reg_id` is a write-only register.
58/// | `SbiRet::failed()`        | The read request failed for unspecified or unknown other reasons.
59///
60/// This function is defined in RISC-V SBI Specification chapter 14.2.
61#[inline]
62#[doc(alias = "sbi_cppc_read")]
63pub fn cppc_read(cppc_reg_id: u32) -> SbiRet {
64    sbi_call_1(EID_CPPC, READ, cppc_reg_id as _)
65}
66
67/// Read the upper 32-bit value of the CPPC register identified by `cppc_reg_id`.
68///
69/// # Parameters
70///
71/// The `cppc_reg_id` parameter specifies the CPPC register ID.
72///
73/// # Return value
74///
75/// `SbiRet.value` will contain the upper 32 bits of the register value. This function always
76/// returns zero in `SbiRet.value` when supervisor mode XLEN is 64 or higher.
77///
78/// The possible error codes returned in `SbiRet.error` are shown in the table below:
79///
80/// | Return code               | Description
81/// |:--------------------------|:----------------------------------------------
82/// | `SbiRet::success()`       | Read completed successfully.
83/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved.
84/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform.
85/// | `SbiRet::denied()`        | `cppc_reg_id` is a write-only register.
86/// | `SbiRet::failed()`        | The read operation request failed for unspecified or unknown other reasons.
87///
88/// This function is defined in RISC-V SBI Specification chapter 14.3.
89#[inline]
90#[doc(alias = "sbi_cppc_read_hi")]
91pub fn cppc_read_hi(cppc_reg_id: u32) -> SbiRet {
92    sbi_call_1(EID_CPPC, READ_HI, cppc_reg_id as _)
93}
94
95/// Write 64-bit value to the CPPC register identified by given `cppc_reg_id`.
96///
97/// # Parameters
98///
99/// The `cppc_reg_id` parameter specifies the CPPC register ID.
100///
101/// The `value` parameter specifies the value to be written to the register.
102///
103/// # Return value
104///
105/// The possible error codes returned in `SbiRet.error` are shown in the table below:
106///
107/// | Return code               | Description
108/// |:--------------------------|:----------------------------------------------
109/// | `SbiRet::success()`       | Write completed successfully.
110/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved.
111/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform.
112/// | `SbiRet::denied()`        | `cppc_reg_id` is a read-only register.
113/// | `SbiRet::failed()`        | The write operation request failed for unspecified or unknown other reasons.
114///
115/// This function is defined in RISC-V SBI Specification chapter 14.4.
116#[inline]
117#[doc(alias = "sbi_cppc_write")]
118pub fn cppc_write(cppc_reg_id: u32, value: u64) -> SbiRet {
119    match () {
120        #[cfg(target_pointer_width = "32")]
121        () => sbi_call_3(
122            EID_CPPC,
123            WRITE,
124            cppc_reg_id as _,
125            value as _,
126            (value >> 32) as _,
127        ),
128        #[cfg(target_pointer_width = "64")]
129        () => sbi_call_2(EID_CPPC, WRITE, cppc_reg_id as _, value as _),
130    }
131}