resource.rs 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. use core::mem;
  2. use crate::{
  3. value::{AmlType, AmlValue},
  4. AmlError,
  5. };
  6. use alloc::vec::Vec;
  7. use bit_field::BitField;
  8. use byteorder::{ByteOrder, LittleEndian};
  9. #[derive(Debug, PartialEq, Eq)]
  10. pub enum Resource {
  11. Irq(IrqDescriptor),
  12. AddressSpace(AddressSpaceDescriptor),
  13. MemoryRange(MemoryRangeDescriptor),
  14. IOPort(IOPortDescriptor),
  15. Dma(DMADescriptor),
  16. }
  17. /// Parse a `ResourceDescriptor` into a list of resources. Returns `AmlError::IncompatibleValueConversion` if the passed value is not a
  18. /// `Buffer`.
  19. pub fn resource_descriptor_list(descriptor: &AmlValue) -> Result<Vec<Resource>, AmlError> {
  20. if let AmlValue::Buffer(bytes) = descriptor {
  21. let mut descriptors = Vec::new();
  22. let mut bytes = bytes.as_slice();
  23. while bytes.len() > 0 {
  24. let (descriptor, remaining_bytes) = resource_descriptor(bytes)?;
  25. if let Some(descriptor) = descriptor {
  26. descriptors.push(descriptor);
  27. bytes = remaining_bytes;
  28. } else {
  29. break;
  30. }
  31. }
  32. Ok(descriptors)
  33. } else {
  34. Err(AmlError::IncompatibleValueConversion { current: descriptor.type_of(), target: AmlType::Buffer })
  35. }
  36. }
  37. /// Parse a `ResourceDescriptor`. Returns `AmlError::IncompatibleValueConversion` if the passed value is not a
  38. /// `Buffer`.
  39. fn resource_descriptor(bytes: &[u8]) -> Result<(Option<Resource>, &[u8]), AmlError> {
  40. /*
  41. * If bit 7 of Byte 0 is set, it's a large descriptor. If not, it's a small descriptor.
  42. */
  43. if bytes[0].get_bit(7) {
  44. /*
  45. * We're parsing a large item. The descriptor type is encoded in Bits 0-6 of Byte 0. Valid types:
  46. * 0x00: Reserved
  47. * 0x01: 24-bit Memory Range Descriptor
  48. * 0x02: Generic Register Descriptor
  49. * 0x03: Reserved
  50. * 0x04: Vendor-defined Descriptor
  51. * 0x05: 32-bit Memory Range Descriptor
  52. * 0x06: 32-bit Fixed Memory Range Descriptor
  53. * 0x07: Address Space Resource Descriptor
  54. * 0x08: Word Address Space Descriptor
  55. * 0x09: Extended Interrupt Descriptor
  56. * 0x0a: QWord Address Space Descriptor
  57. * 0x0b: Extended Address Space Descriptor
  58. * 0x0c: GPIO Connection Descriptor
  59. * 0x0d: Pin Function Descriptor
  60. * 0x0e: GenericSerialBus Connection Descriptor
  61. * 0x0f: Pin Configuration Descriptor
  62. * 0x10: Pin Group Descriptor
  63. * 0x11: Pin Group Function Descriptor
  64. * 0x12: Pin Group Configuration Descriptor
  65. * 0x13-0x7f: Reserved
  66. *
  67. * Byte 1 contains bits 0-7 of the length, and Byte 2 contains bits 8-15 of the length. Subsequent
  68. * bytes contain the actual data items.
  69. */
  70. let descriptor_type = bytes[0].get_bits(0..7);
  71. let length = LittleEndian::read_u16(&bytes[1..=2]) as usize;
  72. let (descriptor_bytes, remaining_bytes) = bytes.split_at(length + 3);
  73. let descriptor = match descriptor_type {
  74. 0x01 => unimplemented!("24-bit Memory Range Descriptor"),
  75. 0x02 => unimplemented!("Generic Register Descriptor"),
  76. 0x03 => unimplemented!("0x03 Reserved"),
  77. 0x04 => unimplemented!("Vendor-defined Descriptor"),
  78. 0x05 => unimplemented!("32-bit Memory Range Descriptor"),
  79. 0x06 => fixed_memory_descriptor(descriptor_bytes),
  80. 0x07 => address_space_descriptor::<u32>(descriptor_bytes),
  81. 0x08 => address_space_descriptor::<u16>(descriptor_bytes),
  82. 0x09 => extended_interrupt_descriptor(descriptor_bytes),
  83. 0x0a => address_space_descriptor::<u64>(descriptor_bytes),
  84. 0x0b => unimplemented!("Extended Address Space Descriptor"),
  85. 0x0c => unimplemented!("GPIO Connection Descriptor"),
  86. 0x0d => unimplemented!("Pin Function Descriptor"),
  87. 0x0e => unimplemented!("GenericSerialBus Connection Descriptor"),
  88. 0x0f => unimplemented!("Pin Configuration Descriptor"),
  89. 0x10 => unimplemented!("Pin Group Descriptor"),
  90. 0x11 => unimplemented!("Pin Group Function Descriptor"),
  91. 0x12 => unimplemented!("Pin Group Configuration Descriptor"),
  92. 0x00 | 0x13..=0x7f => Err(AmlError::ReservedResourceType),
  93. 0x80..=0xff => unreachable!(),
  94. }?;
  95. Ok((Some(descriptor), remaining_bytes))
  96. } else {
  97. /*
  98. * We're parsing a small descriptor. Byte 0 has the format:
  99. * | Bits | Field |
  100. * |-------------|-------------------|
  101. * | 0-2 | Length - n bytes |
  102. * | 3-6 | Small item type |
  103. * | 7 | 0 = small item |
  104. *
  105. * The valid types are:
  106. * 0x00-0x03: Reserved
  107. * 0x04: IRQ Format Descriptor
  108. * 0x05: DMA Format Descriptor
  109. * 0x06: Start Dependent Functions Descriptor
  110. * 0x07: End Dependent Functions Descriptor
  111. * 0x08: IO Port Descriptor
  112. * 0x09: Fixed Location IO Port Descriptor
  113. * 0x0A: Fixed DMA Descriptor
  114. * 0x0B-0x0D: Reserved
  115. * 0x0E: Vendor Defined Descriptor
  116. * 0x0F: End Tag Descriptor
  117. */
  118. let descriptor_type = bytes[0].get_bits(3..=6);
  119. let length: usize = bytes[0].get_bits(0..=2) as usize;
  120. let (descriptor_bytes, remaining_bytes) = bytes.split_at(length + 1);
  121. let descriptor = match descriptor_type {
  122. 0x00..=0x03 => Err(AmlError::ReservedResourceType),
  123. 0x04 => irq_format_descriptor(descriptor_bytes),
  124. 0x05 => dma_format_descriptor(descriptor_bytes),
  125. 0x06 => unimplemented!("Start Dependent Functions Descriptor"),
  126. 0x07 => unimplemented!("End Dependent Functions Descriptor"),
  127. 0x08 => io_port_descriptor(descriptor_bytes),
  128. 0x09 => unimplemented!("Fixed Location IO Port Descriptor"),
  129. 0x0A => unimplemented!("Fixed DMA Descriptor"),
  130. 0x0B..=0x0D => Err(AmlError::ReservedResourceType),
  131. 0x0E => unimplemented!("Vendor Defined Descriptor"),
  132. 0x0F => return Ok((None, &[])),
  133. 0x10..=0xFF => unreachable!(),
  134. }?;
  135. Ok((Some(descriptor), remaining_bytes))
  136. }
  137. }
  138. #[derive(Debug, PartialEq, Eq, Copy, Clone)]
  139. pub enum InterruptTrigger {
  140. Edge,
  141. Level,
  142. }
  143. #[derive(Debug, PartialEq, Eq, Copy, Clone)]
  144. pub enum InterruptPolarity {
  145. ActiveHigh,
  146. ActiveLow,
  147. }
  148. #[derive(Debug, PartialEq, Eq, Copy, Clone)]
  149. pub enum AddressSpaceResourceType {
  150. MemoryRange,
  151. IORange,
  152. BusNumberRange,
  153. }
  154. #[derive(Debug, PartialEq, Eq, Copy, Clone)]
  155. pub enum AddressSpaceDecodeType {
  156. Additive,
  157. Subtractive,
  158. }
  159. #[derive(Debug, PartialEq, Eq)]
  160. pub struct AddressSpaceDescriptor {
  161. resource_type: AddressSpaceResourceType,
  162. is_maximum_address_fixed: bool,
  163. is_minimum_address_fixed: bool,
  164. decode_type: AddressSpaceDecodeType,
  165. granularity: u64,
  166. address_range: (u64, u64),
  167. translation_offset: u64,
  168. length: u64,
  169. }
  170. #[derive(Debug, PartialEq, Eq)]
  171. pub enum MemoryRangeDescriptor {
  172. FixedLocation { is_writable: bool, base_address: u32, range_length: u32 },
  173. }
  174. fn fixed_memory_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
  175. /*
  176. * -- 32-bit Fixed Memory Descriptor ---
  177. * Offset Field Name Definition
  178. * Byte 0 32-bit Fixed Memory Range Descriptor Value = 0x86 (10000110B) – Type = 1, Large item name = 0x06
  179. * Byte 1 Length, bits [7:0] Value = 0x09 (9)
  180. * Byte 2 Length, bits [15:8] Value = 0x00
  181. * Byte 3 Information This field provides extra information about this memory.
  182. * Bit [7:1] Ignored
  183. * Bit [0] Write status, _RW
  184. * 1 writeable (read/write)
  185. * 0 non-writeable (read-only)
  186. * Byte 4 Range base address, _BAS bits [7:0] Address bits [7:0] of the base memory address for which the card may be configured.
  187. * Byte 5 Range base address, _BAS bits [15:8] Address bits [15:8] of the base memory address for which the card may be configured.
  188. * Byte 6 Range base address, _BAS bits [23:16] Address bits [23:16] of the base memory address for which the card may be configured.
  189. * Byte 7 Range base address, _BAS bits [31:24] Address bits [31:24] of the base memory address for which the card may be configured.
  190. * Byte 8 Range length, _LEN bits [7:0] This field contains bits [7:0] of the memory range length. The range length provides the length of the memory range in 1-byte blocks.
  191. * Byte 9 Range length, _LEN bits [15:8] This field contains bits [15:8] of the memory range length. The range length provides the length of the memory range in 1-byte blocks.
  192. * Byte 10 Range length, _LEN bits [23:16] This field contains bits [23:16] of the memory range length. The range length provides the length of the memory range in 1-byte blocks.
  193. * Byte 11 Range length, _LEN bits [31:24] This field contains bits [31:24] of the memory range length. The range length provides the length of the memory range in 1-byte blocks.
  194. */
  195. if bytes.len() < 12 {
  196. return Err(AmlError::ResourceDescriptorTooShort);
  197. }
  198. if bytes.len() > 12 {
  199. return Err(AmlError::ResourceDescriptorTooLong);
  200. }
  201. let information = bytes[3];
  202. let is_writable = information.get_bit(0);
  203. let base_address = LittleEndian::read_u32(&bytes[4..=7]);
  204. let range_length = LittleEndian::read_u32(&bytes[8..=11]);
  205. Ok(Resource::MemoryRange(MemoryRangeDescriptor::FixedLocation { is_writable, base_address, range_length }))
  206. }
  207. fn address_space_descriptor<T>(bytes: &[u8]) -> Result<Resource, AmlError> {
  208. /*
  209. * WORD Address Space Descriptor Definition
  210. * Note: The definitions for DWORD and QWORD are the same other than the width of the address fields.
  211. *
  212. * Offset Field Name Definition
  213. * Byte 0 WORD Address Space Descriptor Value = 0x88 (10001000B) – Type = 1, Large item name = 0x08
  214. * Byte 1 Length, bits [7:0] Variable length, minimum value = 0x0D (13)
  215. * Byte 2 Length, bits [15:8] Variable length, minimum value = 0x00
  216. * Byte 3 Resource Type Indicates which type of resource this descriptor describes. Defined values are:
  217. * 0 Memory range
  218. * 1 I/O range
  219. * 2 Bus number range
  220. * 3–191 Reserved
  221. * 192-255 Hardware Vendor Defined
  222. * Byte 4 General Flags Flags that are common to all resource types:
  223. * Bits [7:4] Reserved (must be 0)
  224. * Bit [3] Max Address Fixed, _MAF:
  225. * 1 The specified maximum address is fixed
  226. * 0 The specified maximum address is not fixed
  227. * and can be changed
  228. * Bit [2] Min Address Fixed,_MIF:
  229. * 1 The specified minimum address is fixed
  230. * 0 The specified minimum address is not fixed
  231. * and can be changed
  232. * Bit [1] Decode Type, _DEC:
  233. * 1 This bridge subtractively decodes this address (top level bridges only)
  234. * 0 This bridge positively decodes this address
  235. * Bit [0] Ignored
  236. * Byte 5 Type Specific Flags Flags that are specific to each resource type. The meaning of the flags in this field depends on the value of the Resource Type field (see above).
  237. * Byte 6 Address space granularity, _GRA bits[7:0] A set bit in this mask means that this bit is decoded. All bits less significant than the most significant set bit must be set. (In other words, the value of the full Address Space Granularity field (all 16 bits) must be a number (2n-1).
  238. * Byte 7 Address space granularity, _GRA bits[15:8]
  239. * Byte 8 Address range minimum, _MIN, bits [7:0] For bridges that translate addresses, this is the address space on the secondary side of the bridge.
  240. * Byte 9 Address range minimum, _MIN, bits [15:8]
  241. * Byte 10 Address range maximum, _MAX, bits [7:0] For bridges that translate addresses, this is the address space on the secondary side of the bridge.
  242. * Byte 11 Address range maximum, _MAX, bits [15:8]
  243. * Byte 12 Address Translation offset, _TRA, bits [7:0] For bridges that translate addresses across the bridge, this is the offset that must be added to the address on the secondary side to obtain the address on the primary side. Non-bridge devices must list 0 for all Address Translation offset bits.
  244. * Byte 13 Address Translation offset, _TRA, bits [15:8]
  245. * Byte 14 Address Length, _LEN, bits [7:0]
  246. * Byte 15 Address Length, _LEN, bits [15:8]
  247. * Byte 16 Resource Source Index (Optional) Only present if Resource Source (below) is present. This field gives an index to the specific resource descriptor that this device consumes from in the current resource template for the device object pointed to in Resource Source.
  248. * String Resource Source (Optional) If present, the device that uses this descriptor consumes its resources from the resources produced by the named device object. If not present, the device consumes its resources out of a global pool. If not present, the device consumes this resource from its hierarchical parent.
  249. */
  250. let size = mem::size_of::<T>();
  251. if bytes.len() < 6 + size * 5 {
  252. return Err(AmlError::ResourceDescriptorTooShort);
  253. }
  254. let resource_type = match bytes[3] {
  255. 0 => AddressSpaceResourceType::MemoryRange,
  256. 1 => AddressSpaceResourceType::IORange,
  257. 2 => AddressSpaceResourceType::BusNumberRange,
  258. 3..=191 => return Err(AmlError::ReservedResourceType),
  259. 192..=255 => unimplemented!(),
  260. };
  261. let general_flags = bytes[4];
  262. let is_maximum_address_fixed = general_flags.get_bit(3);
  263. let is_minimum_address_fixed = general_flags.get_bit(2);
  264. let decode_type = if general_flags.get_bit(1) {
  265. AddressSpaceDecodeType::Subtractive
  266. } else {
  267. AddressSpaceDecodeType::Additive
  268. };
  269. let mut address_fields = bytes[6..].chunks_exact(size);
  270. // it's safe to unwrap because we check the length at the top
  271. let granularity = LittleEndian::read_uint(address_fields.next().unwrap(), size);
  272. let address_range_min = LittleEndian::read_uint(address_fields.next().unwrap(), size);
  273. let address_range_max = LittleEndian::read_uint(address_fields.next().unwrap(), size);
  274. let translation_offset = LittleEndian::read_uint(address_fields.next().unwrap(), size);
  275. let length = LittleEndian::read_uint(address_fields.next().unwrap(), size);
  276. Ok(Resource::AddressSpace(AddressSpaceDescriptor {
  277. resource_type,
  278. is_maximum_address_fixed,
  279. is_minimum_address_fixed,
  280. decode_type,
  281. granularity,
  282. address_range: (address_range_min, address_range_max),
  283. translation_offset,
  284. length,
  285. }))
  286. }
  287. #[derive(Debug, PartialEq, Eq, Clone)]
  288. pub struct IrqDescriptor {
  289. pub is_consumer: bool,
  290. pub trigger: InterruptTrigger,
  291. pub polarity: InterruptPolarity,
  292. pub is_shared: bool,
  293. pub is_wake_capable: bool,
  294. /*
  295. * NOTE: We currently only support the cases where a descriptor only contains a single interrupt
  296. * number.
  297. */
  298. pub irq: u32,
  299. }
  300. fn irq_format_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
  301. /*
  302. * IRQ Descriptor Definition
  303. *
  304. * Offset Field Name
  305. * Byte 0 Value = 0x22 or 0x23 (0010001nB)– Type = 0, Small item name = 0x4, Length = 2 or 3
  306. * Byte 1 IRQ mask bits[7:0], _INT
  307. * Bit [0] represents IRQ0, bit[1] is IRQ1, and so on.
  308. * Byte 2 IRQ mask bits[15:8], _INT
  309. * Bit [0] represents IRQ8, bit[1] is IRQ9, and so on.
  310. * Byte 3 IRQ Information. Each bit, when set, indicates this device is capable of driving a certain type of interrupt.
  311. * (Optional—if not included then assume edge sensitive, high true interrupts.)
  312. * These bits can be used both for reporting and setting IRQ resources.
  313. * Note: This descriptor is meant for describing interrupts that are connected to PIC-compatible interrupt controllers, which can only be programmed for Active-High-Edge-Triggered or Active-Low-Level-Triggered interrupts. Any other combination is invalid. The Extended Interrupt Descriptor can be used to describe other combinations.
  314. * Bit [7:6] Reserved (must be 0)
  315. * Bit [5] Wake Capability, _WKC
  316. * 0x0 = Not Wake Capable: This interrupt is not capable of waking the system.
  317. * 0x1 = Wake Capable: This interrupt is capable of waking the system from a
  318. * low-power idle state or a system sleep state.
  319. * Bit [4] Interrupt Sharing, _SHR
  320. * 0x0 = Exclusive: This interrupt is not shared with other devices.
  321. * 0x1 = Shared: This interrupt is shared with other devices.
  322. * Bit [3] Interrupt Polarity, _LL
  323. * 0 Active-High – This interrupt is sampled when the signal is high, or true
  324. * 1 Active-Low – This interrupt is sampled when the signal is low, or false.
  325. * Bit [2:1] Ignored
  326. * Bit [0] Interrupt Mode, _HE
  327. * 0 Level-Triggered – Interrupt is triggered in response to signal in a low state.
  328. * 1 Edge-Triggered – Interrupt is triggered in response to a change in signal state from low to high.
  329. */
  330. match bytes.len() {
  331. 0..=2 => Err(AmlError::ResourceDescriptorTooShort),
  332. 3 => {
  333. // no IRQ information ("length 2" in spec)
  334. let irq = LittleEndian::read_u16(&bytes[1..=2]);
  335. Ok(Resource::Irq(IrqDescriptor {
  336. irq: irq as u32,
  337. is_wake_capable: false,
  338. is_shared: false,
  339. polarity: InterruptPolarity::ActiveHigh,
  340. trigger: InterruptTrigger::Edge,
  341. is_consumer: false, // assumed to be producer
  342. }))
  343. }
  344. 4 => {
  345. // with IRQ information ("length 3" in spec)
  346. let irq = LittleEndian::read_u16(&bytes[1..=2]);
  347. let information = bytes[3];
  348. let is_wake_capable = information.get_bit(5);
  349. let is_shared = information.get_bit(4);
  350. let polarity = match information.get_bit(3) {
  351. false => InterruptPolarity::ActiveHigh,
  352. true => InterruptPolarity::ActiveLow,
  353. };
  354. let trigger = match information.get_bit(0) {
  355. false => InterruptTrigger::Level,
  356. true => InterruptTrigger::Edge,
  357. };
  358. Ok(Resource::Irq(IrqDescriptor {
  359. irq: irq as u32,
  360. is_wake_capable,
  361. is_shared,
  362. polarity,
  363. trigger,
  364. is_consumer: false, // assumed to be producer
  365. }))
  366. }
  367. _ => Err(AmlError::ResourceDescriptorTooLong),
  368. }
  369. }
  370. #[derive(Debug, PartialEq, Eq)]
  371. pub enum DMASupportedSpeed {
  372. CompatibilityMode,
  373. TypeA, // as described by the EISA
  374. TypeB,
  375. TypeF,
  376. }
  377. #[derive(Debug, PartialEq, Eq)]
  378. pub enum DMATransferTypePreference {
  379. _8BitOnly,
  380. _8And16Bit,
  381. _16Bit,
  382. }
  383. #[derive(Debug, PartialEq, Eq)]
  384. pub struct DMADescriptor {
  385. channel_mask: u8,
  386. supported_speeds: DMASupportedSpeed,
  387. is_bus_master: bool,
  388. transfer_type_preference: DMATransferTypePreference,
  389. }
  390. pub fn dma_format_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
  391. /*
  392. * DMA Descriptor Definition
  393. * Offset Field Name
  394. * Byte 0 Value = 0x2A (00101010B) – Type = 0, Small item name = 0x5, Length = 2
  395. * Byte 1 DMA channel mask bits [7:0] (channels 0 – 7), _DMA
  396. * Bit [0] is channel 0, etc.
  397. * Byte 2 Bit [7] Reserved (must be 0)
  398. * Bits [6:5] DMA channel speed supported, _TYP
  399. * 00 Indicates compatibility mode
  400. * 01 Indicates Type A DMA as described in the EISA
  401. * 10 Indicates Type B DMA
  402. * 11 Indicates Type F
  403. * Bits [4:3] Ignored
  404. * Bit [2] Logical device bus master status, _BM
  405. * 0 Logical device is not a bus master
  406. * 1 Logical device is a bus master
  407. * Bits [1:0] DMA transfer type preference, _SIZ
  408. * 00 8-bit only
  409. * 01 8- and 16-bit
  410. * 10 16-bit only
  411. * 11 Reserved
  412. */
  413. if bytes.len() < 3 {
  414. return Err(AmlError::ResourceDescriptorTooShort);
  415. }
  416. if bytes.len() > 3 {
  417. return Err(AmlError::ResourceDescriptorTooLong);
  418. }
  419. let channel_mask = bytes[1];
  420. let options = bytes[2];
  421. let supported_speeds = match options.get_bits(5..=6) {
  422. 0 => DMASupportedSpeed::CompatibilityMode,
  423. 1 => DMASupportedSpeed::TypeA,
  424. 2 => DMASupportedSpeed::TypeB,
  425. 3 => DMASupportedSpeed::TypeF,
  426. _ => unreachable!(),
  427. };
  428. let is_bus_master = options.get_bit(2);
  429. let transfer_type_preference = match options.get_bits(0..=1) {
  430. 0 => DMATransferTypePreference::_8BitOnly,
  431. 1 => DMATransferTypePreference::_8And16Bit,
  432. 2 => DMATransferTypePreference::_16Bit,
  433. 3 => unimplemented!("Reserved DMA transfer type preference"),
  434. _ => unreachable!(),
  435. };
  436. Ok(Resource::Dma(DMADescriptor { channel_mask, supported_speeds, is_bus_master, transfer_type_preference }))
  437. }
  438. #[derive(Debug, PartialEq, Eq)]
  439. pub struct IOPortDescriptor {
  440. decodes_full_address: bool,
  441. memory_range: (u16, u16),
  442. base_alignment: u8,
  443. range_length: u8,
  444. }
  445. fn io_port_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
  446. /*
  447. * I/O Port Descriptor Definition
  448. * Offset Field Name Definition
  449. * Byte 0 I/O Port Descriptor Value = 0x47 (01000111B) –
  450. * Type = 0, Small item name = 0x8, Length = 7
  451. * Byte 1 Information Bits [7:1] Reserved and must be 0
  452. * Bit [0] (_DEC)
  453. * 1 The logical device decodes 16-bit addresses
  454. * 0 The logical device only decodes address bits[9:0]
  455. * Byte 2 Range minimum base address, _MIN bits[7:0] Address bits [7:0] of the minimum base I/O address that the card may be configured for.
  456. * Byte 3 Range minimum base address, _MIN bits[15:8] Address bits [15:8] of the minimum base I/O address that the card may be configured for.
  457. * Byte 4 Range maximum base address, _MAX bits[7:0] Address bits [7:0] of the maximum base I/O address that the card may be configured for.
  458. * Byte 5 Range maximum base address, _MAX bits[15:8] Address bits [15:8] of the maximum base I/O address that the card may be configured for.
  459. * Byte 6 Base alignment, _ALN Alignment for minimum base address, increment in 1-byte blocks.
  460. * Byte 7 Range length, _LEN The number of contiguous I/O ports requested.
  461. */
  462. if bytes.len() < 8 {
  463. return Err(AmlError::ResourceDescriptorTooShort);
  464. }
  465. if bytes.len() > 8 {
  466. return Err(AmlError::ResourceDescriptorTooLong);
  467. }
  468. let information = bytes[1];
  469. let decodes_full_address = information.get_bit(0);
  470. let memory_range_min = LittleEndian::read_u16(&bytes[2..=3]);
  471. let memory_range_max = LittleEndian::read_u16(&bytes[4..=5]);
  472. let memory_range = (memory_range_min, memory_range_max);
  473. let base_alignment = bytes[6];
  474. let range_length = bytes[7];
  475. Ok(Resource::IOPort(IOPortDescriptor { decodes_full_address, memory_range, base_alignment, range_length }))
  476. }
  477. fn extended_interrupt_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
  478. /*
  479. * --- Extended Interrupt Descriptor ---
  480. * Byte 3 contains the Interrupt Vector Flags:
  481. * Bit 0: 1 if device consumes the resource, 0 if it produces it
  482. * Bit 1: 1 if edge-triggered, 0 if level-triggered
  483. * Bit 2: 1 = active-high, 0 = active-low
  484. * Bit 3: 1 if interrupt is shared with other devices
  485. * Bit 4: 1 if this interrupt is capable of waking the system, 0 if it is not
  486. * Byte 4 contains the number of interrupt numbers that follow. When this descriptor is
  487. * returned from `_CRS` or send to `_SRS`, this field must be 1.
  488. *
  489. * From Byte 5 onwards, there are `n` interrupt numbers, each of which is encoded as a
  490. * 4-byte little-endian number.
  491. *
  492. * NOTE: We only support the case where there is a single interrupt number.
  493. */
  494. if bytes.len() < 9 {
  495. return Err(AmlError::ResourceDescriptorTooShort);
  496. }
  497. let number_of_interrupts = bytes[4] as usize;
  498. assert_eq!(number_of_interrupts, 1);
  499. let irq = LittleEndian::read_u32(&[bytes[5], bytes[6], bytes[7], bytes[8]]);
  500. Ok(Resource::Irq(IrqDescriptor {
  501. is_consumer: bytes[3].get_bit(0),
  502. trigger: if bytes[3].get_bit(1) { InterruptTrigger::Edge } else { InterruptTrigger::Level },
  503. polarity: if bytes[3].get_bit(2) { InterruptPolarity::ActiveLow } else { InterruptPolarity::ActiveHigh },
  504. is_shared: bytes[3].get_bit(3),
  505. is_wake_capable: bytes[3].get_bit(4),
  506. irq,
  507. }))
  508. }
  509. #[cfg(test)]
  510. mod tests {
  511. use super::*;
  512. #[test]
  513. fn test_parses_keyboard_crs() {
  514. let bytes: Vec<u8> = [
  515. // Generated from `iasl -l pc-bios_acpi-dsdt.asl`
  516. //
  517. // 315: IO (Decode16,
  518. // 316: 0x0060, // Range Minimum
  519. // 317: 0x0060, // Range Maximum
  520. // 318: 0x01, // Alignment
  521. // 319: 0x01, // Length
  522. // 320: )
  523. // 0000040A: 47 01 60 00 60 00 01 01 "G.`.`..."
  524. 0x47, 0x01, 0x60, 0x00, 0x60, 0x00, 0x01, 0x01,
  525. // 321: IO (Decode16,
  526. // 322: 0x0064, // Range Minimum
  527. // 323: 0x0064, // Range Maximum
  528. // 324: 0x01, // Alignment
  529. // 325: 0x01, // Length
  530. // 326: )
  531. // 00000412: 47 01 64 00 64 00 01 01 "G.d.d..."
  532. 0x47, 0x01, 0x64, 0x00, 0x64, 0x00, 0x01, 0x01,
  533. // 327: IRQNoFlags ()
  534. // 328: {1}
  535. // 0000041A: 22 02 00 ............... "".."
  536. 0x22, 0x02, 0x00, // 0000041D: 79 00 .................. "y."
  537. 0x79, 0x00,
  538. ]
  539. .to_vec();
  540. let value: AmlValue = AmlValue::Buffer(bytes);
  541. let resources = resource_descriptor_list(&value).unwrap();
  542. assert_eq!(
  543. resources,
  544. Vec::from([
  545. Resource::IOPort(IOPortDescriptor {
  546. decodes_full_address: true,
  547. memory_range: (0x60, 0x60),
  548. base_alignment: 1,
  549. range_length: 1
  550. }),
  551. Resource::IOPort(IOPortDescriptor {
  552. decodes_full_address: true,
  553. memory_range: (0x64, 0x64),
  554. base_alignment: 1,
  555. range_length: 1
  556. }),
  557. Resource::Irq(IrqDescriptor {
  558. is_consumer: false,
  559. trigger: InterruptTrigger::Edge,
  560. polarity: InterruptPolarity::ActiveHigh,
  561. is_shared: false,
  562. is_wake_capable: false,
  563. irq: (1 << 1)
  564. })
  565. ])
  566. );
  567. }
  568. #[test]
  569. fn test_pci_crs() {
  570. let bytes: Vec<u8> = [
  571. // Generated from `iasl -l pc-bios_acpi-dsdt.asl`
  572. //
  573. // 98: WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
  574. // 99: 0x0000, // Granularity
  575. // 100: 0x0000, // Range Minimum
  576. // 101: 0x00FF, // Range Maximum
  577. // 102: 0x0000, // Translation Offset
  578. // 103: 0x0100, // Length
  579. // 104: ,, )
  580. // 000000F3: 88 0D 00 02 0C 00 00 00 "........"
  581. // 000000FB: 00 00 FF 00 00 00 00 01 "........"
  582. 0x88, 0x0D, 0x00, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01,
  583. // 105: IO (Decode16,
  584. // 106: 0x0CF8, // Range Minimum
  585. // 107: 0x0CF8, // Range Maximum
  586. // 108: 0x01, // Alignment
  587. // 109: 0x08, // Length
  588. // 110: )
  589. // 00000103: 47 01 F8 0C F8 0C 01 08 "G......."
  590. 0x47, 0x01, 0xF8, 0x0C, 0xF8, 0x0C, 0x01, 0x08,
  591. // 111: WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
  592. // 112: 0x0000, // Granularity
  593. // 113: 0x0000, // Range Minimum
  594. // 114: 0x0CF7, // Range Maximum
  595. // 115: 0x0000, // Translation Offset
  596. // 116: 0x0CF8, // Length
  597. // 117: ,, , TypeStatic, DenseTranslation)
  598. // 0000010B: 88 0D 00 01 0C 03 00 00 "........"
  599. // 00000113: 00 00 F7 0C 00 00 F8 0C "........"
  600. 0x88, 0x0D, 0x00, 0x01, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x0C, 0x00, 0x00, 0xF8, 0x0C,
  601. // 118: WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
  602. // 119: 0x0000, // Granularity
  603. // 120: 0x0D00, // Range Minimum
  604. // 121: 0xFFFF, // Range Maximum
  605. // 122: 0x0000, // Translation Offset
  606. // 123: 0xF300, // Length
  607. // 124: ,, , TypeStatic, DenseTranslation)
  608. // 0000011B: 88 0D 00 01 0C 03 00 00 "........"
  609. // 00000123: 00 0D FF FF 00 00 00 F3 "........"
  610. 0x88, 0x0D, 0x00, 0x01, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x0D, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF3,
  611. // 125: DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
  612. // 126: 0x00000000, // Granularity
  613. // 127: 0x000A0000, // Range Minimum
  614. // 128: 0x000BFFFF, // Range Maximum
  615. // 129: 0x00000000, // Translation Offset
  616. // 130: 0x00020000, // Length
  617. // 131: ,, , AddressRangeMemory, TypeStatic)
  618. // 0000012B: 87 17 00 00 0C 03 00 00 "........"
  619. // 00000133: 00 00 00 00 0A 00 FF FF "........"
  620. // 0000013B: 0B 00 00 00 00 00 00 00 "........"
  621. // 00000143: 02 00 .................. ".."
  622. 0x87, 0x17, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xFF, 0xFF, 0x0B,
  623. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
  624. // 132: DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
  625. // 133: 0x00000000, // Granularity
  626. // 134: 0xE0000000, // Range Minimum
  627. // 135: 0xFEBFFFFF, // Range Maximum
  628. // 136: 0x00000000, // Translation Offset
  629. // 137: 0x1EC00000, // Length
  630. // 138: ,, _Y00, AddressRangeMemory, TypeStatic)
  631. // 00000145: 87 17 00 00 0C 01 00 00 "........"
  632. // 0000014D: 00 00 00 00 00 E0 FF FF "........"
  633. // 00000155: BF FE 00 00 00 00 00 00 "........"
  634. // 0000015D: C0 1E .................. ".."
  635. 0x87, 0x17, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0xBF,
  636. 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1E,
  637. // 0000015F: 79 00 .................. "y."
  638. 0x79, 0x00,
  639. ]
  640. .to_vec();
  641. let value: AmlValue = AmlValue::Buffer(bytes);
  642. let resources = resource_descriptor_list(&value).unwrap();
  643. assert_eq!(
  644. resources,
  645. Vec::from([
  646. Resource::AddressSpace(AddressSpaceDescriptor {
  647. resource_type: AddressSpaceResourceType::BusNumberRange,
  648. is_maximum_address_fixed: true,
  649. is_minimum_address_fixed: true,
  650. decode_type: AddressSpaceDecodeType::Additive,
  651. granularity: 0,
  652. address_range: (0x00, 0xFF),
  653. translation_offset: 0,
  654. length: 0x100
  655. }),
  656. Resource::IOPort(IOPortDescriptor {
  657. decodes_full_address: true,
  658. memory_range: (0xCF8, 0xCF8),
  659. base_alignment: 1,
  660. range_length: 8
  661. }),
  662. Resource::AddressSpace(AddressSpaceDescriptor {
  663. resource_type: AddressSpaceResourceType::IORange,
  664. is_maximum_address_fixed: true,
  665. is_minimum_address_fixed: true,
  666. decode_type: AddressSpaceDecodeType::Additive,
  667. granularity: 0,
  668. address_range: (0x0000, 0x0CF7),
  669. translation_offset: 0,
  670. length: 0xCF8
  671. }),
  672. Resource::AddressSpace(AddressSpaceDescriptor {
  673. resource_type: AddressSpaceResourceType::IORange,
  674. is_maximum_address_fixed: true,
  675. is_minimum_address_fixed: true,
  676. decode_type: AddressSpaceDecodeType::Additive,
  677. granularity: 0,
  678. address_range: (0x0D00, 0xFFFF),
  679. translation_offset: 0,
  680. length: 0xF300
  681. }),
  682. Resource::AddressSpace(AddressSpaceDescriptor {
  683. resource_type: AddressSpaceResourceType::MemoryRange,
  684. is_maximum_address_fixed: true,
  685. is_minimum_address_fixed: true,
  686. decode_type: AddressSpaceDecodeType::Additive,
  687. granularity: 0,
  688. address_range: (0xA0000, 0xBFFFF),
  689. translation_offset: 0,
  690. length: 0x20000
  691. }),
  692. Resource::AddressSpace(AddressSpaceDescriptor {
  693. resource_type: AddressSpaceResourceType::MemoryRange,
  694. is_maximum_address_fixed: true,
  695. is_minimum_address_fixed: true,
  696. decode_type: AddressSpaceDecodeType::Additive,
  697. granularity: 0,
  698. address_range: (0xE0000000, 0xFEBFFFFF),
  699. translation_offset: 0,
  700. length: 0x1EC00000
  701. }),
  702. ])
  703. );
  704. }
  705. #[test]
  706. fn test_fdc_crs() {
  707. let bytes: Vec<u8> = [
  708. // 365: IO (Decode16,
  709. // 366: 0x03F2, // Range Minimum
  710. // 367: 0x03F2, // Range Maximum
  711. // 368: 0x00, // Alignment
  712. // 369: 0x04, // Length
  713. // 370: )
  714. // 0000047C: 47 01 F2 03 F2 03 00 04 "G......."
  715. 0x47, 0x01, 0xF2, 0x03, 0xF2, 0x03, 0x00, 0x04,
  716. // 371: IO (Decode16,
  717. // 372: 0x03F7, // Range Minimum
  718. // 373: 0x03F7, // Range Maximum
  719. // 374: 0x00, // Alignment
  720. // 375: 0x01, // Length
  721. // 376: )
  722. // 00000484: 47 01 F7 03 F7 03 00 01 "G......."
  723. 0x47, 0x01, 0xF7, 0x03, 0xF7, 0x03, 0x00, 0x01,
  724. // 377: IRQNoFlags ()
  725. // 378: {6}
  726. // 0000048C: 22 40 00 ............... ""@."
  727. 0x22, 0x40, 0x00,
  728. // 379: DMA (Compatibility, NotBusMaster, Transfer8, )
  729. // 380: {2}
  730. // 0000048F: 2A 04 00 ............... "*.."
  731. 0x2A, 0x04, 0x00, // 00000492: 79 00 .................. "y."
  732. 0x79, 0x00,
  733. ]
  734. .to_vec();
  735. let value: AmlValue = AmlValue::Buffer(bytes);
  736. let resources = resource_descriptor_list(&value).unwrap();
  737. assert_eq!(
  738. resources,
  739. Vec::from([
  740. Resource::IOPort(IOPortDescriptor {
  741. decodes_full_address: true,
  742. memory_range: (0x03F2, 0x03F2),
  743. base_alignment: 0,
  744. range_length: 4
  745. }),
  746. Resource::IOPort(IOPortDescriptor {
  747. decodes_full_address: true,
  748. memory_range: (0x03F7, 0x03F7),
  749. base_alignment: 0,
  750. range_length: 1
  751. }),
  752. Resource::Irq(IrqDescriptor {
  753. is_consumer: false,
  754. trigger: InterruptTrigger::Edge,
  755. polarity: InterruptPolarity::ActiveHigh,
  756. is_shared: false,
  757. is_wake_capable: false,
  758. irq: (1 << 6)
  759. }),
  760. Resource::Dma(DMADescriptor {
  761. channel_mask: 1 << 2,
  762. supported_speeds: DMASupportedSpeed::CompatibilityMode,
  763. is_bus_master: false,
  764. transfer_type_preference: DMATransferTypePreference::_8BitOnly
  765. })
  766. ])
  767. );
  768. }
  769. }