sta.rs 4.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. //! Chapter 16. Steal-time Accounting Extension (EID #0x535441 "STA")
  2. use crate::binary::sbi_call_3;
  3. use sbi_spec::{
  4. binary::{SbiRet, SharedPtr},
  5. sta::{EID_STA, SET_SHMEM},
  6. };
  7. /// Prepare shared memory for steal-time accounting feature.
  8. ///
  9. /// Set the shared memory physical base address for steal-time accounting of the calling virtual hart and
  10. /// enable the SBI implementation’s steal-time information reporting.
  11. ///
  12. /// It is not expected for the shared memory to be written by the supervisor-mode software
  13. /// while it is in use for steal-time accounting. However, the SBI implementation MUST not misbehave
  14. /// if a write operation from supervisor-mode software occurs, however, in that case,
  15. /// it MAY leave the shared memory filled with inconsistent data.
  16. ///
  17. /// *NOTE:* Not writing to the shared memory when the supervisor-mode software is not runnable
  18. /// avoids unnecessary work and supports repeatable capture of a system image
  19. /// while the supervisor-mode software is suspended.
  20. ///
  21. /// # STA Shared Memory Structure
  22. ///
  23. /// | Name | Offset | Size | Description
  24. /// |:----------|:-------|:-----|:------------
  25. /// | `sequence` | 0 | 4 | The SBI implementation MUST increment this field to an odd value before writing the `steal` field, and increment it again to an even value after writing `steal` (i.e. an odd sequence number indicates an in-progress update). The SBI implementation SHOULD ensure that the sequence field remains odd for only very short periods of time. <br><br> The supervisor-mode software MUST check this field before and after reading the `steal` field, and repeat the read if it is different or odd. <br><br> This sequence field enables the value of the steal field to be read by supervisor-mode software executed in a 32-bit environment.
  26. /// | `flags` | 4 | 4 | Always zero. <br><br> Future extensions of the SBI call might allow the supervisor-mode software to write to some fields of the shared memory. Such extensions will not be enabled as long as a zero value is used for the flags argument to the SBI call.
  27. /// | `steal` | 8 | 8 | The amount of time in which this virtual hart was not idle and scheduled out, in nanoseconds. The time during which the virtual hart is idle will not be reported as steal-time.
  28. /// | `preempted` | 16 | 1 | An advisory flag indicating whether the virtual hart which registered this structure is running or not. A non-zero value MAY be written by the SBI implementation if the virtual hart has been preempted (i.e., while the `steal` field is increasing), while a zero value MUST be written before the virtual hart starts to run again. <br><br> This preempted field can, for example, be used by the supervisor-mode software to check if a lock holder has been preempted, and, in that case, disable optimistic spinning.
  29. /// | `pad` | 17 | 47 | Pad with zeros to a 64-byte boundary.
  30. ///
  31. /// # Parameters
  32. ///
  33. /// If `shmem` address is not all-ones bitwise, then `shmem` specifies the shared memory
  34. /// physical base address. `shmem` MUST be 64-byte aligned. The size of the shared memory
  35. /// must be 64 bytes. All bytes MUST be set to zero by the SBI implementation before returning
  36. /// from the SBI call.
  37. ///
  38. /// If `shmem` address is all-ones bitwise, the SBI implementation will stop reporting
  39. /// steal-time information for the virtual hart.
  40. ///
  41. /// The `flags` parameter is reserved for future use and MUST be zero.
  42. ///
  43. /// # Return value
  44. ///
  45. /// `SbiRet.value` is set to zero, and the possible error codes returned in `SbiRet.error` are shown in the table below:
  46. ///
  47. /// | Error code | Description
  48. /// |:----------------------------|:---------------------------------
  49. /// | `SbiRet::success()` | The steal-time shared memory physical base address was set or cleared successfully.
  50. /// | `SbiRet::invalid_param()` | The `flags` parameter is not zero or the shmem_phys_lo is not 64-byte aligned.
  51. /// | `SbiRet::invalid_address()` | The shared memory pointed to by the `shmem` parameter is not writable or does not satisfy other requirements of STA Shared Memory Structure.
  52. /// | `SbiRet::failed()` | The request failed for unspecified or unknown other reasons.
  53. ///
  54. /// This function is defined in RISC-V SBI Specification chapter 16.1.
  55. #[inline]
  56. pub fn sta_set_shmem(shmem: SharedPtr<[u8; 64]>, flags: usize) -> SbiRet {
  57. sbi_call_3(
  58. EID_STA,
  59. SET_SHMEM,
  60. shmem.phys_addr_lo(),
  61. shmem.phys_addr_hi(),
  62. flags,
  63. )
  64. }