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]
34pub fn cppc_probe(cppc_reg_id: u32) -> SbiRet {
35 sbi_call_1(EID_CPPC, PROBE, cppc_reg_id as _)
36}
37
38/// Read the CPPC register identified by given `cppc_reg_id`.
39///
40/// # Parameters
41///
42/// The `cppc_reg_id` parameter specifies the CPPC register ID.
43///
44/// # Return value
45///
46/// `SbiRet.value` will contain the register value. When supervisor mode XLEN is 32, the `SbiRet.value`
47/// will only contain the lower 32 bits of the CPPC register value.
48///
49/// The possible error codes returned in `SbiRet.error` are shown in the table below:
50///
51/// | Return code | Description
52/// |:--------------------------|:----------------------------------------------
53/// | `SbiRet::success()` | Read completed successfully.
54/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved.
55/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform.
56/// | `SbiRet::denied()` | `cppc_reg_id` is a write-only register.
57/// | `SbiRet::failed()` | The read request failed for unspecified or unknown other reasons.
58///
59/// This function is defined in RISC-V SBI Specification chapter 14.2.
60#[inline]
61pub fn cppc_read(cppc_reg_id: u32) -> SbiRet {
62 sbi_call_1(EID_CPPC, READ, cppc_reg_id as _)
63}
64
65/// Read the upper 32-bit value of the CPPC register identified by `cppc_reg_id`.
66///
67/// # Parameters
68///
69/// The `cppc_reg_id` parameter specifies the CPPC register ID.
70///
71/// # Return value
72///
73/// `SbiRet.value` will contain the upper 32 bits of the register value. This function always
74/// returns zero in `SbiRet.value` when supervisor mode XLEN is 64 or higher.
75///
76/// The possible error codes returned in `SbiRet.error` are shown in the table below:
77///
78/// | Return code | Description
79/// |:--------------------------|:----------------------------------------------
80/// | `SbiRet::success()` | Read completed successfully.
81/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved.
82/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform.
83/// | `SbiRet::denied()` | `cppc_reg_id` is a write-only register.
84/// | `SbiRet::failed()` | The read operation request failed for unspecified or unknown other reasons.
85///
86/// This function is defined in RISC-V SBI Specification chapter 14.3.
87#[inline]
88pub fn cppc_read_hi(cppc_reg_id: u32) -> SbiRet {
89 sbi_call_1(EID_CPPC, READ_HI, cppc_reg_id as _)
90}
91
92/// Write 64-bit value to the CPPC register identified by given `cppc_reg_id`.
93///
94/// # Parameters
95///
96/// The `cppc_reg_id` parameter specifies the CPPC register ID.
97///
98/// The `value` parameter specifies the value to be written to the register.
99///
100/// # Return value
101///
102/// The possible error codes returned in `SbiRet.error` are shown in the table below:
103///
104/// | Return code | Description
105/// |:--------------------------|:----------------------------------------------
106/// | `SbiRet::success()` | Write completed successfully.
107/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved.
108/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform.
109/// | `SbiRet::denied()` | `cppc_reg_id` is a read-only register.
110/// | `SbiRet::failed()` | The write operation request failed for unspecified or unknown other reasons.
111///
112/// This function is defined in RISC-V SBI Specification chapter 14.4.
113#[inline]
114pub fn cppc_write(cppc_reg_id: u32, value: u64) -> SbiRet {
115 match () {
116 #[cfg(target_pointer_width = "32")]
117 () => sbi_call_3(
118 EID_CPPC,
119 WRITE,
120 cppc_reg_id as _,
121 value as _,
122 (value >> 32) as _,
123 ),
124 #[cfg(target_pointer_width = "64")]
125 () => sbi_call_2(EID_CPPC, WRITE, cppc_reg_id as _, value as _),
126 }
127}