resource.rs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. use crate::{value::AmlValue, AmlError};
  2. use bit_field::BitField;
  3. use byteorder::{ByteOrder, LittleEndian};
  4. #[derive(Debug)]
  5. pub enum Resource {
  6. Irq(IrqDescriptor),
  7. }
  8. /// Parse a `ResourceDescriptor`. Returns `AmlError::IncompatibleValueConversion` if the passed value is not a
  9. /// `Buffer`.
  10. pub(crate) fn resource_descriptor(descriptor: &AmlValue) -> Result<Resource, AmlError> {
  11. if let AmlValue::Buffer { bytes, size } = descriptor {
  12. /*
  13. * If bit 7 of Byte 0 is set, it's a large descriptor. If not, it's a small descriptor.
  14. */
  15. if bytes[0].get_bit(7) {
  16. /*
  17. * We're parsing a large item. The descriptor type is encoded in Bits 0-6 of Byte 0. Valid types:
  18. * 0x00: Reserved
  19. * 0x01: 24-bit Memory Range Descriptor
  20. * 0x02: Generic Register Descriptor
  21. * 0x03: Reserved
  22. * 0x04: Vendor-defined Descriptor
  23. * 0x05: 32-bit Memory Range Descriptor
  24. * 0x06: 32-bit Fixed Memory Range Descriptor
  25. * 0x07: Address Space Resource Descriptor
  26. * 0x08: Word Address Space Descriptor
  27. * 0x09: Extended Interrupt Descriptor
  28. * 0x0a: QWord Address Space Descriptor
  29. * 0x0b: Extended Address Space Descriptor
  30. * 0x0c: GPIO Connection Descriptor
  31. * 0x0d: Pin Function Descriptor
  32. * 0x0e: GenericSerialBus Connection Descriptor
  33. * 0x0f: Pin Configuration Descriptor
  34. * 0x10: Pin Group Descriptor
  35. * 0x11: Pin Group Function Descriptor
  36. * 0x12: Pin Group Configuration Descriptor
  37. * 0x13-0x7f: Reserved
  38. *
  39. * Byte 1 contains bits 0-7 of the length, and Byte 2 contains bits 8-15 of the length. Subsequent
  40. * bytes contain the actual data items.
  41. */
  42. let descriptor_type = bytes[0].get_bits(0..7);
  43. let length = LittleEndian::read_u16(&[bytes[1], bytes[2]]);
  44. match descriptor_type {
  45. 0x01 => unimplemented!(),
  46. 0x02 => unimplemented!(),
  47. 0x03 => unimplemented!(),
  48. 0x04 => unimplemented!(),
  49. 0x05 => unimplemented!(),
  50. 0x06 => unimplemented!(),
  51. 0x07 => unimplemented!(),
  52. 0x08 => unimplemented!(),
  53. 0x09 => extended_interrupt_descriptor(bytes),
  54. 0x0a => unimplemented!(),
  55. 0x0b => unimplemented!(),
  56. 0x0c => unimplemented!(),
  57. 0x0d => unimplemented!(),
  58. 0x0e => unimplemented!(),
  59. 0x0f => unimplemented!(),
  60. 0x10 => unimplemented!(),
  61. 0x11 => unimplemented!(),
  62. 0x12 => unimplemented!(),
  63. 0x00 | 0x13..=0x7f => Err(AmlError::ReservedResourceType),
  64. 0x80..=0xff => unreachable!(),
  65. }
  66. } else {
  67. /*
  68. * We're parsing a small descriptor. Byte 0 has the format:
  69. * | Bits | Field |
  70. * |-------------|-------------------|
  71. * | 0-2 | Length - n bytes |
  72. * | 3-6 | Small item type |
  73. * | 7 | 0 = small item |
  74. *
  75. * The valid types are:
  76. * 0x00-0x03: Reserved
  77. * 0x04: IRQ Format Descriptor
  78. * 0x05: DMA Format Descriptor
  79. * 0x06: Start Dependent Functions Descriptor
  80. * 0x07: End Dependent Functions Descriptor
  81. * 0x08: IO Port Descriptor
  82. * 0x09: Fixed Location IO Port Descriptor
  83. * 0x0A: Fixed DMA Descriptor
  84. * 0x0B-0x0D: Reserved
  85. * 0x0E: Vendor Defined Descriptor
  86. * 0x0F: End Tag Descriptor
  87. */
  88. unimplemented!()
  89. }
  90. } else {
  91. Err(AmlError::IncompatibleValueConversion)
  92. }
  93. }
  94. #[derive(Debug)]
  95. pub enum InterruptTrigger {
  96. Edge,
  97. Level,
  98. }
  99. #[derive(Debug)]
  100. pub enum InterruptPolarity {
  101. ActiveHigh,
  102. ActiveLow,
  103. }
  104. #[derive(Debug)]
  105. pub struct IrqDescriptor {
  106. pub is_consumer: bool,
  107. pub trigger: InterruptTrigger,
  108. pub polarity: InterruptPolarity,
  109. pub is_shared: bool,
  110. pub is_wake_capable: bool,
  111. /*
  112. * NOTE: We currently only support the cases where a descriptor only contains a single interrupt
  113. * number.
  114. */
  115. pub irq: u32,
  116. }
  117. fn extended_interrupt_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
  118. /*
  119. * --- Extended Interrupt Descriptor ---
  120. * Byte 3 contains the Interrupt Vector Flags:
  121. * Bit 0: 1 if device consumes the resource, 0 if it produces it
  122. * Bit 1: 1 if edge-triggered, 0 if level-triggered
  123. * Bit 2: 1 = active-high, 0 = active-low
  124. * Bit 3: 1 if interrupt is shared with other devices
  125. * Bit 4: 1 if this interrupt is capable of waking the system, 0 if it is not
  126. * Byte 4 contains the number of interrupt numbers that follow. When this descriptor is
  127. * returned from `_CRS` or send to `_SRS`, this field must be 1.
  128. *
  129. * From Byte 5 onwards, there are `n` interrupt numbers, each of which is encoded as a
  130. * 4-byte little-endian number.
  131. *
  132. * NOTE: We only support the case where there is a single interrupt number.
  133. */
  134. if bytes.len() < 9 {
  135. return Err(AmlError::ResourceDescriptorTooShort);
  136. }
  137. let number_of_interrupts = bytes[4] as usize;
  138. assert_eq!(number_of_interrupts, 1);
  139. let irq = LittleEndian::read_u32(&[bytes[5], bytes[6], bytes[7], bytes[8]]);
  140. Ok(Resource::Irq(IrqDescriptor {
  141. is_consumer: bytes[3].get_bit(0),
  142. trigger: if bytes[3].get_bit(1) { InterruptTrigger::Edge } else { InterruptTrigger::Level },
  143. polarity: if bytes[3].get_bit(2) { InterruptPolarity::ActiveLow } else { InterruptPolarity::ActiveHigh },
  144. is_shared: bytes[3].get_bit(3),
  145. is_wake_capable: bytes[3].get_bit(4),
  146. irq,
  147. }))
  148. }