cppc.rs 4.9 KB

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