address.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. //! ACPI defines a Generic Address Structure (GAS), which provides a versatile way to describe register locations
  2. //! in a wide range of address spaces.
  3. use crate::AcpiError;
  4. use core::convert::TryFrom;
  5. /// This is the raw form of a Generic Address Structure, and follows the layout found in the ACPI tables. It does
  6. /// not form part of the public API, and should be turned into a `GenericAddress` for most use-cases.
  7. #[derive(Clone, Copy, Debug)]
  8. #[repr(C, packed)]
  9. pub(crate) struct RawGenericAddress {
  10. pub address_space: u8,
  11. pub bit_width: u8,
  12. pub bit_offset: u8,
  13. pub access_size: u8,
  14. pub address: u64,
  15. }
  16. #[derive(PartialEq, Eq, Clone, Copy, Debug)]
  17. pub enum AddressSpace {
  18. SystemMemory,
  19. SystemIo,
  20. /// Describes a register in the configuration space of a PCI device in segment `0`, on bus `0`. The `address`
  21. /// field is of the format:
  22. /// ```ignore
  23. /// 64 48 32 16 0
  24. /// +---------------+---------------+---------------+---------------+
  25. /// | reserved (0) | device | function | offset |
  26. /// +---------------+---------------+---------------+---------------+
  27. /// ```
  28. PciConfigSpace,
  29. EmbeddedController,
  30. SMBus,
  31. SystemCmos,
  32. PciBarTarget,
  33. Ipmi,
  34. GeneralIo,
  35. GenericSerialBus,
  36. PlatformCommunicationsChannel,
  37. FunctionalFixedHardware,
  38. OemDefined(u8),
  39. }
  40. #[derive(PartialEq, Eq, Clone, Copy, Debug)]
  41. pub enum AccessSize {
  42. Undefined,
  43. ByteAccess,
  44. WordAccess,
  45. DWordAccess,
  46. QWordAccess,
  47. }
  48. impl TryFrom<u8> for AccessSize {
  49. type Error = AcpiError;
  50. fn try_from(size: u8) -> Result<Self, Self::Error> {
  51. match size {
  52. 0 => Ok(AccessSize::Undefined),
  53. 1 => Ok(AccessSize::ByteAccess),
  54. 2 => Ok(AccessSize::WordAccess),
  55. 3 => Ok(AccessSize::DWordAccess),
  56. 4 => Ok(AccessSize::QWordAccess),
  57. _ => Err(AcpiError::InvalidGenericAddress),
  58. }
  59. }
  60. }
  61. #[derive(PartialEq, Eq, Clone, Copy, Debug)]
  62. pub struct GenericAddress {
  63. pub address_space: AddressSpace,
  64. pub bit_width: u8,
  65. pub bit_offset: u8,
  66. pub access_size: AccessSize,
  67. pub address: u64,
  68. }
  69. impl GenericAddress {
  70. pub(crate) fn from_raw(raw: RawGenericAddress) -> crate::AcpiResult<GenericAddress> {
  71. let address_space = match raw.address_space {
  72. 0x00 => AddressSpace::SystemMemory,
  73. 0x01 => AddressSpace::SystemIo,
  74. 0x02 => AddressSpace::PciConfigSpace,
  75. 0x03 => AddressSpace::EmbeddedController,
  76. 0x04 => AddressSpace::SMBus,
  77. 0x05 => AddressSpace::SystemCmos,
  78. 0x06 => AddressSpace::PciBarTarget,
  79. 0x07 => AddressSpace::Ipmi,
  80. 0x08 => AddressSpace::GeneralIo,
  81. 0x09 => AddressSpace::GenericSerialBus,
  82. 0x0a => AddressSpace::PlatformCommunicationsChannel,
  83. 0x0b..=0x7e => return Err(AcpiError::InvalidGenericAddress),
  84. 0x7f => AddressSpace::FunctionalFixedHardware,
  85. 0x80..=0xbf => return Err(AcpiError::InvalidGenericAddress),
  86. 0xc0..=0xff => AddressSpace::OemDefined(raw.address_space),
  87. };
  88. Ok(GenericAddress {
  89. address_space,
  90. bit_width: raw.bit_width,
  91. bit_offset: raw.bit_offset,
  92. access_size: AccessSize::try_from(raw.access_size)?,
  93. address: raw.address,
  94. })
  95. }
  96. }