resource.rs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. use core::mem;
  2. use crate::{value::AmlValue, AmlError};
  3. use alloc::vec::Vec;
  4. use bit_field::BitField;
  5. use byteorder::{ByteOrder, LittleEndian};
  6. #[derive(Debug, PartialEq, Eq)]
  7. pub enum Resource {
  8. Irq(IrqDescriptor),
  9. WordAddressSpace(AddressSpaceDescriptor),
  10. MemoryRange(MemoryRangeDescriptor),
  11. IOPort(IOPortDescriptor),
  12. Dma(DMADescriptor)
  13. }
  14. /// Parse a `ResourceDescriptor` into a list of resources. Returns `AmlError::IncompatibleValueConversion` if the passed value is not a
  15. /// `Buffer`.
  16. pub fn resource_descriptor_list(descriptor: &AmlValue) -> Result<Vec<Resource>, AmlError> {
  17. if let AmlValue::Buffer { bytes, size: _ } = descriptor {
  18. let mut descriptors = Vec::new();
  19. let mut bytes = bytes.as_slice();
  20. while bytes.len() > 0 {
  21. let (descriptor, remaining_bytes) = resource_descriptor(bytes)?;
  22. if let Some(descriptor) = descriptor {
  23. descriptors.push(descriptor);
  24. bytes = remaining_bytes;
  25. } else {
  26. break;
  27. }
  28. }
  29. Ok(descriptors)
  30. } else {
  31. Err(AmlError::IncompatibleValueConversion)
  32. }
  33. }
  34. /// Parse a `ResourceDescriptor`. Returns `AmlError::IncompatibleValueConversion` if the passed value is not a
  35. /// `Buffer`.
  36. fn resource_descriptor(bytes: &[u8]) -> Result<(Option<Resource>, &[u8]), AmlError> {
  37. /*
  38. * If bit 7 of Byte 0 is set, it's a large descriptor. If not, it's a small descriptor.
  39. */
  40. if bytes[0].get_bit(7) {
  41. /*
  42. * We're parsing a large item. The descriptor type is encoded in Bits 0-6 of Byte 0. Valid types:
  43. * 0x00: Reserved
  44. * 0x01: 24-bit Memory Range Descriptor
  45. * 0x02: Generic Register Descriptor
  46. * 0x03: Reserved
  47. * 0x04: Vendor-defined Descriptor
  48. * 0x05: 32-bit Memory Range Descriptor
  49. * 0x06: 32-bit Fixed Memory Range Descriptor
  50. * 0x07: Address Space Resource Descriptor
  51. * 0x08: Word Address Space Descriptor
  52. * 0x09: Extended Interrupt Descriptor
  53. * 0x0a: QWord Address Space Descriptor
  54. * 0x0b: Extended Address Space Descriptor
  55. * 0x0c: GPIO Connection Descriptor
  56. * 0x0d: Pin Function Descriptor
  57. * 0x0e: GenericSerialBus Connection Descriptor
  58. * 0x0f: Pin Configuration Descriptor
  59. * 0x10: Pin Group Descriptor
  60. * 0x11: Pin Group Function Descriptor
  61. * 0x12: Pin Group Configuration Descriptor
  62. * 0x13-0x7f: Reserved
  63. *
  64. * Byte 1 contains bits 0-7 of the length, and Byte 2 contains bits 8-15 of the length. Subsequent
  65. * bytes contain the actual data items.
  66. */
  67. let descriptor_type = bytes[0].get_bits(0..7);
  68. let length = LittleEndian::read_u16(&bytes[1..=2]) as usize + 2;
  69. let descriptor = match descriptor_type {
  70. 0x01 => unimplemented!("24-bit Memory Range Descriptor"),
  71. 0x02 => unimplemented!("Generic Register Descriptor"),
  72. 0x03 => unimplemented!("0x03 Reserved"),
  73. 0x04 => unimplemented!("Vendor-defined Descriptor"),
  74. 0x05 => unimplemented!("32-bit Memory Range Descriptor"),
  75. 0x06 => fixed_memory_descriptor(&bytes[0..length+2]),
  76. 0x07 => address_space_descriptor::<u32>(&bytes[0..length+2]),
  77. 0x08 => address_space_descriptor::<u16>(&bytes[0..length+2]),
  78. 0x09 => extended_interrupt_descriptor(&bytes[0..length+2]),
  79. 0x0a => address_space_descriptor::<u64>(&bytes[0..length+2]),
  80. 0x0b => unimplemented!("Extended Address Space Descriptor"),
  81. 0x0c => unimplemented!("GPIO Connection Descriptor"),
  82. 0x0d => unimplemented!("Pin Function Descriptor"),
  83. 0x0e => unimplemented!("GenericSerialBus Connection Descriptor"),
  84. 0x0f => unimplemented!("Pin Configuration Descriptor"),
  85. 0x10 => unimplemented!("Pin Group Descriptor"),
  86. 0x11 => unimplemented!("Pin Group Function Descriptor"),
  87. 0x12 => unimplemented!("Pin Group Configuration Descriptor"),
  88. 0x00 | 0x13..=0x7f => Err(AmlError::ReservedResourceType),
  89. 0x80..=0xff => unreachable!(),
  90. }?;
  91. Ok((Some(descriptor), &bytes[length+1..]))
  92. } else {
  93. /*
  94. * We're parsing a small descriptor. Byte 0 has the format:
  95. * | Bits | Field |
  96. * |-------------|-------------------|
  97. * | 0-2 | Length - n bytes |
  98. * | 3-6 | Small item type |
  99. * | 7 | 0 = small item |
  100. *
  101. * The valid types are:
  102. * 0x00-0x03: Reserved
  103. * 0x04: IRQ Format Descriptor
  104. * 0x05: DMA Format Descriptor
  105. * 0x06: Start Dependent Functions Descriptor
  106. * 0x07: End Dependent Functions Descriptor
  107. * 0x08: IO Port Descriptor
  108. * 0x09: Fixed Location IO Port Descriptor
  109. * 0x0A: Fixed DMA Descriptor
  110. * 0x0B-0x0D: Reserved
  111. * 0x0E: Vendor Defined Descriptor
  112. * 0x0F: End Tag Descriptor
  113. */
  114. let descriptor_type = bytes[0].get_bits(3..=6);
  115. let length: usize = bytes[0].get_bits(0..=2) as usize;
  116. let descriptor = match descriptor_type {
  117. 0x00..=0x03 => Err(AmlError::ReservedResourceType),
  118. 0x04 => irq_format_descriptor(&bytes[0..=length]),
  119. 0x05 => dma_format_descriptor(&bytes[0..=length]),
  120. 0x06 => unimplemented!("Start Dependent Functions Descriptor"),
  121. 0x07 => unimplemented!("End Dependent Functions Descriptor"),
  122. 0x08 => io_port_descriptor(&bytes[0..=length]),
  123. 0x09 => unimplemented!("Fixed Location IO Port Descriptor"),
  124. 0x0A => unimplemented!("Fixed DMA Descriptor"),
  125. 0x0B..=0x0D => Err(AmlError::ReservedResourceType),
  126. 0x0E => unimplemented!("Vendor Defined Descriptor"),
  127. 0x0F => return Ok((None, &[])),
  128. 0x10..=0xFF => unreachable!()
  129. }?;
  130. Ok((Some(descriptor), &bytes[length+1..]))
  131. }
  132. }
  133. #[derive(Debug, PartialEq, Eq, Copy, Clone)]
  134. pub enum InterruptTrigger {
  135. Edge,
  136. Level,
  137. }
  138. #[derive(Debug, PartialEq, Eq, Copy, Clone)]
  139. pub enum InterruptPolarity {
  140. ActiveHigh,
  141. ActiveLow,
  142. }
  143. #[derive(Debug, PartialEq, Eq, Copy, Clone)]
  144. pub enum AddressSpaceResourceType {
  145. MemoryRange,
  146. IORange,
  147. BusNumberRange
  148. }
  149. #[derive(Debug, PartialEq, Eq, Copy, Clone)]
  150. pub enum AddressSpaceDecodeType {
  151. Additive,
  152. Subtractive
  153. }
  154. #[derive(Debug, PartialEq, Eq)]
  155. pub struct AddressSpaceDescriptor {
  156. resource_type: AddressSpaceResourceType,
  157. is_maximum_address_fixed: bool,
  158. is_minimum_address_fixed: bool,
  159. decode_type: AddressSpaceDecodeType,
  160. granularity: u64,
  161. address_range: (u64, u64),
  162. translation_offset: u64,
  163. length: u64
  164. }
  165. #[derive(Debug, PartialEq, Eq)]
  166. pub enum MemoryRangeDescriptor {
  167. FixedLocation {
  168. is_writable: bool,
  169. base_address: u32,
  170. range_length: u32
  171. }
  172. }
  173. fn fixed_memory_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
  174. /*
  175. * -- 32-bit Fixed Memory Descriptor ---
  176. * Offset Field Name Definition
  177. * Byte 0 32-bit Fixed Memory Range Descriptor Value = 0x86 (10000110B) – Type = 1, Large item name = 0x06
  178. * Byte 1 Length, bits [7:0] Value = 0x09 (9)
  179. * Byte 2 Length, bits [15:8] Value = 0x00
  180. * Byte 3 Information This field provides extra information about this memory.
  181. * Bit [7:1] Ignored
  182. * Bit [0] Write status, _RW
  183. * 1 writeable (read/write)
  184. * 0 non-writeable (read-only))
  185. * 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.
  186. * Byte 5 Range base address, _BASbits [15:8] Address bits [15:8] of the base memory address for which the card may be configured.
  187. * Byte 6 Range base address, _BASbits [23:16] Address bits [23:16] of the base memory address for which the card may be configured.
  188. * Byte 7 Range base address, _BASbits [31:24] Address bits [31:24] of the base memory address for which the card may be configured.
  189. * 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.
  190. * 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.
  191. * 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.
  192. * 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.
  193. */
  194. if bytes.len() < 12 {
  195. return Err(AmlError::ResourceDescriptorTooShort);
  196. }
  197. let information = bytes[3];
  198. let is_writable = information.get_bit(0);
  199. let base_address = LittleEndian::read_u32(&bytes[4..8]);
  200. let range_length = LittleEndian::read_u32(&bytes[8..12]);
  201. Ok(Resource::MemoryRange(MemoryRangeDescriptor::FixedLocation {
  202. is_writable,
  203. base_address,
  204. range_length
  205. }))
  206. }
  207. fn address_space_descriptor<T>(bytes: &[u8]) -> Result<Resource, AmlError> {
  208. let size = mem::size_of::<T>();
  209. if bytes.len() < 6 + size*5 {
  210. return Err(AmlError::ResourceDescriptorTooShort);
  211. }
  212. let resource_type = match bytes[3] {
  213. 0 => AddressSpaceResourceType::MemoryRange,
  214. 1 => AddressSpaceResourceType::IORange,
  215. 2 => AddressSpaceResourceType::BusNumberRange,
  216. 3..=191 => return Err(AmlError::ReservedResourceType),
  217. 192..=255 => unimplemented!()
  218. };
  219. let general_flags = bytes[4];
  220. let is_maximum_address_fixed = general_flags.get_bit(3);
  221. let is_minimum_address_fixed = general_flags.get_bit(2);
  222. let decode_type = if general_flags.get_bit(1) {
  223. AddressSpaceDecodeType::Subtractive
  224. } else {
  225. AddressSpaceDecodeType::Additive
  226. };
  227. const START: usize = 6;
  228. let granularity = LittleEndian::read_uint(&bytes[START+(0*size)..], size);
  229. let address_range_min = LittleEndian::read_uint(&bytes[START+(1*size)..], size);
  230. let address_range_max = LittleEndian::read_uint(&bytes[START+(2*size)..], size);
  231. let translation_offset = LittleEndian::read_uint(&bytes[START+(3*size)..], size);
  232. let length = LittleEndian::read_uint(&bytes[START+(4*size)..], size);
  233. Ok(Resource::WordAddressSpace(AddressSpaceDescriptor {
  234. resource_type,
  235. is_maximum_address_fixed,
  236. is_minimum_address_fixed,
  237. decode_type,
  238. granularity,
  239. address_range: (address_range_min, address_range_max),
  240. translation_offset,
  241. length
  242. }))
  243. }
  244. #[derive(Debug, PartialEq, Eq, Clone)]
  245. pub struct IrqDescriptor {
  246. pub is_consumer: bool,
  247. pub trigger: InterruptTrigger,
  248. pub polarity: InterruptPolarity,
  249. pub is_shared: bool,
  250. pub is_wake_capable: bool,
  251. /*
  252. * NOTE: We currently only support the cases where a descriptor only contains a single interrupt
  253. * number.
  254. */
  255. pub irq: u32,
  256. }
  257. fn irq_format_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
  258. match bytes.len() {
  259. 0..=2 => Err(AmlError::ResourceDescriptorTooShort),
  260. 3 => { // 2 in spec
  261. let irq = LittleEndian::read_u16(&bytes[1..=2]);
  262. Ok(Resource::Irq(IrqDescriptor {
  263. irq: irq as u32,
  264. is_wake_capable: false,
  265. is_shared: false,
  266. polarity: InterruptPolarity::ActiveHigh,
  267. trigger: InterruptTrigger::Edge,
  268. is_consumer: false // Is this correct?
  269. }))
  270. },
  271. 4 => { // 3 in spec
  272. let irq = LittleEndian::read_u16(&bytes[1..=2]);
  273. let information = bytes[3];
  274. let is_wake_capable = information.get_bit(5);
  275. let is_shared = information.get_bit(4);
  276. let polarity = match information.get_bit(3) {
  277. false => InterruptPolarity::ActiveHigh,
  278. true => InterruptPolarity::ActiveLow
  279. };
  280. let trigger = match information.get_bit(0) {
  281. false => InterruptTrigger::Level,
  282. true => InterruptTrigger::Edge
  283. };
  284. Ok(Resource::Irq(IrqDescriptor {
  285. irq: irq as u32,
  286. is_wake_capable,
  287. is_shared,
  288. polarity,
  289. trigger,
  290. is_consumer: false // Is this correct?
  291. }))
  292. },
  293. _ => Err(AmlError::ResourceDescriptorTooLong)
  294. }
  295. }
  296. #[derive(Debug, PartialEq, Eq)]
  297. pub enum DMASupportedSpeed {
  298. CompatibilityMode,
  299. TypeA, // as described by the EISA
  300. TypeB,
  301. TypeF
  302. }
  303. #[derive(Debug, PartialEq, Eq)]
  304. pub enum DMATransferTypePreference {
  305. _8BitOnly,
  306. _8And16Bit,
  307. _16Bit
  308. }
  309. #[derive(Debug, PartialEq, Eq)]
  310. pub struct DMADescriptor {
  311. channel_mask: u8,
  312. supported_speeds: DMASupportedSpeed,
  313. is_bus_master: bool,
  314. transfer_type_preference: DMATransferTypePreference
  315. }
  316. pub fn dma_format_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
  317. if bytes.len() < 3 {
  318. return Err(AmlError::ResourceDescriptorTooShort);
  319. }
  320. if bytes.len() > 3 {
  321. return Err(AmlError::ResourceDescriptorTooLong);
  322. }
  323. let channel_mask = bytes[1];
  324. let options = bytes[2];
  325. let supported_speeds = match options.get_bits(5..=6) {
  326. 0 => DMASupportedSpeed::CompatibilityMode,
  327. 1 => DMASupportedSpeed::TypeA,
  328. 2 => DMASupportedSpeed::TypeB,
  329. 3 => DMASupportedSpeed::TypeF,
  330. _ => unreachable!()
  331. };
  332. let is_bus_master = options.get_bit(2);
  333. let transfer_type_preference = match options.get_bits(0..=1) {
  334. 0 => DMATransferTypePreference::_8BitOnly,
  335. 1 => DMATransferTypePreference::_8And16Bit,
  336. 2 => DMATransferTypePreference::_16Bit,
  337. 3 => unimplemented!("Reserved DMA transfer type preference"),
  338. _ => unreachable!()
  339. };
  340. Ok(Resource::Dma(DMADescriptor {
  341. channel_mask,
  342. supported_speeds,
  343. is_bus_master,
  344. transfer_type_preference
  345. }))
  346. }
  347. #[derive(Debug, PartialEq, Eq)]
  348. pub struct IOPortDescriptor {
  349. decodes_full_address: bool,
  350. memory_range: (u16, u16),
  351. base_alignment: u8,
  352. range_length: u8
  353. }
  354. fn io_port_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
  355. if bytes.len() < 8 {
  356. return Err(AmlError::ResourceDescriptorTooShort);
  357. }
  358. if bytes.len() > 8 {
  359. return Err(AmlError::ResourceDescriptorTooLong);
  360. }
  361. let information = bytes[1];
  362. let decodes_full_address = information.get_bit(0);
  363. let memory_range_min = LittleEndian::read_u16(&bytes[2..=3]);
  364. let memory_range_max = LittleEndian::read_u16(&bytes[4..=5]);
  365. let memory_range = (memory_range_min, memory_range_max);
  366. let base_alignment = bytes[6];
  367. let range_length = bytes[7];
  368. Ok(Resource::IOPort(IOPortDescriptor {
  369. decodes_full_address,
  370. memory_range,
  371. base_alignment,
  372. range_length
  373. }))
  374. }
  375. fn extended_interrupt_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
  376. /*
  377. * --- Extended Interrupt Descriptor ---
  378. * Byte 3 contains the Interrupt Vector Flags:
  379. * Bit 0: 1 if device consumes the resource, 0 if it produces it
  380. * Bit 1: 1 if edge-triggered, 0 if level-triggered
  381. * Bit 2: 1 = active-high, 0 = active-low
  382. * Bit 3: 1 if interrupt is shared with other devices
  383. * Bit 4: 1 if this interrupt is capable of waking the system, 0 if it is not
  384. * Byte 4 contains the number of interrupt numbers that follow. When this descriptor is
  385. * returned from `_CRS` or send to `_SRS`, this field must be 1.
  386. *
  387. * From Byte 5 onwards, there are `n` interrupt numbers, each of which is encoded as a
  388. * 4-byte little-endian number.
  389. *
  390. * NOTE: We only support the case where there is a single interrupt number.
  391. */
  392. if bytes.len() < 9 {
  393. return Err(AmlError::ResourceDescriptorTooShort);
  394. }
  395. let number_of_interrupts = bytes[4] as usize;
  396. assert_eq!(number_of_interrupts, 1);
  397. let irq = LittleEndian::read_u32(&[bytes[5], bytes[6], bytes[7], bytes[8]]);
  398. Ok(Resource::Irq(IrqDescriptor {
  399. is_consumer: bytes[3].get_bit(0),
  400. trigger: if bytes[3].get_bit(1) { InterruptTrigger::Edge } else { InterruptTrigger::Level },
  401. polarity: if bytes[3].get_bit(2) { InterruptPolarity::ActiveLow } else { InterruptPolarity::ActiveHigh },
  402. is_shared: bytes[3].get_bit(3),
  403. is_wake_capable: bytes[3].get_bit(4),
  404. irq,
  405. }))
  406. }
  407. #[cfg(test)]
  408. mod tests {
  409. use super::*;
  410. #[test]
  411. fn test_parses_keyboard_crs() {
  412. let bytes: Vec<u8> = [
  413. // Generated from `iasl -l pc-bios_acpi-dsdt.asl`
  414. //
  415. // 315: IO (Decode16,
  416. // 316: 0x0060, // Range Minimum
  417. // 317: 0x0060, // Range Maximum
  418. // 318: 0x01, // Alignment
  419. // 319: 0x01, // Length
  420. // 320: )
  421. // 0000040A: 47 01 60 00 60 00 01 01 "G.`.`..."
  422. 0x47, 0x01, 0x60, 0x00, 0x60, 0x00, 0x01, 0x01,
  423. // 321: IO (Decode16,
  424. // 322: 0x0064, // Range Minimum
  425. // 323: 0x0064, // Range Maximum
  426. // 324: 0x01, // Alignment
  427. // 325: 0x01, // Length
  428. // 326: )
  429. // 00000412: 47 01 64 00 64 00 01 01 "G.d.d..."
  430. 0x47, 0x01, 0x64, 0x00, 0x64, 0x00, 0x01, 0x01,
  431. // 327: IRQNoFlags ()
  432. // 328: {1}
  433. // 0000041A: 22 02 00 ............... "".."
  434. 0x22, 0x02, 0x00,
  435. // 0000041D: 79 00 .................. "y."
  436. 0x79, 0x00,
  437. ].to_vec();
  438. let size: u64 = bytes.len() as u64;
  439. let value: AmlValue = AmlValue::Buffer { bytes, size };
  440. let resources = resource_descriptor_list(&value).unwrap();
  441. assert_eq!(resources, Vec::from([
  442. Resource::IOPort(IOPortDescriptor { decodes_full_address: true, memory_range: (0x60, 0x60), base_alignment: 1, range_length: 1 }),
  443. Resource::IOPort(IOPortDescriptor { decodes_full_address: true, memory_range: (0x64, 0x64), base_alignment: 1, range_length: 1 }),
  444. Resource::Irq(IrqDescriptor { is_consumer: false, trigger: InterruptTrigger::Edge, polarity: InterruptPolarity::ActiveHigh, is_shared: false, is_wake_capable: false, irq: (1<<1) })
  445. ]));
  446. }
  447. #[test]
  448. fn test_pci_crs() {
  449. let bytes: Vec<u8> = [
  450. // Generated from `iasl -l pc-bios_acpi-dsdt.asl`
  451. //
  452. // 98: WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
  453. // 99: 0x0000, // Granularity
  454. // 100: 0x0000, // Range Minimum
  455. // 101: 0x00FF, // Range Maximum
  456. // 102: 0x0000, // Translation Offset
  457. // 103: 0x0100, // Length
  458. // 104: ,, )
  459. // 000000F3: 88 0D 00 02 0C 00 00 00 "........"
  460. // 000000FB: 00 00 FF 00 00 00 00 01 "........"
  461. 0x88, 0x0D, 0x00, 0x02, 0x0C, 0x00, 0x00, 0x00,
  462. 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01,
  463. // 105: IO (Decode16,
  464. // 106: 0x0CF8, // Range Minimum
  465. // 107: 0x0CF8, // Range Maximum
  466. // 108: 0x01, // Alignment
  467. // 109: 0x08, // Length
  468. // 110: )
  469. // 00000103: 47 01 F8 0C F8 0C 01 08 "G......."
  470. 0x47, 0x01, 0xF8, 0x0C, 0xF8, 0x0C, 0x01, 0x08,
  471. // 111: WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
  472. // 112: 0x0000, // Granularity
  473. // 113: 0x0000, // Range Minimum
  474. // 114: 0x0CF7, // Range Maximum
  475. // 115: 0x0000, // Translation Offset
  476. // 116: 0x0CF8, // Length
  477. // 117: ,, , TypeStatic, DenseTranslation)
  478. // 0000010B: 88 0D 00 01 0C 03 00 00 "........"
  479. // 00000113: 00 00 F7 0C 00 00 F8 0C "........"
  480. 0x88, 0x0D, 0x00, 0x01, 0x0C, 0x03, 0x00, 0x00,
  481. 0x00, 0x00, 0xF7, 0x0C, 0x00, 0x00, 0xF8, 0x0C,
  482. // 118: WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
  483. // 119: 0x0000, // Granularity
  484. // 120: 0x0D00, // Range Minimum
  485. // 121: 0xFFFF, // Range Maximum
  486. // 122: 0x0000, // Translation Offset
  487. // 123: 0xF300, // Length
  488. // 124: ,, , TypeStatic, DenseTranslation)
  489. // 0000011B: 88 0D 00 01 0C 03 00 00 "........"
  490. // 00000123: 00 0D FF FF 00 00 00 F3 "........"
  491. 0x88, 0x0D, 0x00, 0x01, 0x0C, 0x03, 0x00, 0x00,
  492. 0x00, 0x0D, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xF3,
  493. // 125: DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
  494. // 126: 0x00000000, // Granularity
  495. // 127: 0x000A0000, // Range Minimum
  496. // 128: 0x000BFFFF, // Range Maximum
  497. // 129: 0x00000000, // Translation Offset
  498. // 130: 0x00020000, // Length
  499. // 131: ,, , AddressRangeMemory, TypeStatic)
  500. // 0000012B: 87 17 00 00 0C 03 00 00 "........"
  501. // 00000133: 00 00 00 00 0A 00 FF FF "........"
  502. // 0000013B: 0B 00 00 00 00 00 00 00 "........"
  503. // 00000143: 02 00 .................. ".."
  504. 0x87, 0x17, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00,
  505. 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xFF, 0xFF,
  506. 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  507. 0x02, 0x00,
  508. // 132: DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
  509. // 133: 0x00000000, // Granularity
  510. // 134: 0xE0000000, // Range Minimum
  511. // 135: 0xFEBFFFFF, // Range Maximum
  512. // 136: 0x00000000, // Translation Offset
  513. // 137: 0x1EC00000, // Length
  514. // 138: ,, _Y00, AddressRangeMemory, TypeStatic)
  515. // 00000145: 87 17 00 00 0C 01 00 00 "........"
  516. // 0000014D: 00 00 00 00 00 E0 FF FF "........"
  517. // 00000155: BF FE 00 00 00 00 00 00 "........"
  518. // 0000015D: C0 1E .................. ".."
  519. 0x87, 0x17, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00,
  520. 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF,
  521. 0xBF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  522. 0xC0, 0x1E,
  523. // 0000015F: 79 00 .................. "y."
  524. 0x79, 0x00,
  525. ].to_vec();
  526. let size: u64 = bytes.len() as u64;
  527. let value: AmlValue = AmlValue::Buffer { bytes, size };
  528. let resources = resource_descriptor_list(&value).unwrap();
  529. assert_eq!(resources, Vec::from([
  530. Resource::WordAddressSpace(AddressSpaceDescriptor { resource_type: AddressSpaceResourceType::BusNumberRange, is_maximum_address_fixed: true, is_minimum_address_fixed: true, decode_type: AddressSpaceDecodeType::Additive, granularity: 0, address_range: (0x00, 0xFF), translation_offset: 0, length: 0x100 }),
  531. Resource::IOPort(IOPortDescriptor { decodes_full_address: true, memory_range: (0xCF8, 0xCF8), base_alignment: 1, range_length: 8 }),
  532. Resource::WordAddressSpace(AddressSpaceDescriptor { resource_type: AddressSpaceResourceType::IORange, is_maximum_address_fixed: true, is_minimum_address_fixed: true, decode_type: AddressSpaceDecodeType::Additive, granularity: 0, address_range: (0x0000, 0x0CF7), translation_offset: 0, length: 0xCF8 }),
  533. Resource::WordAddressSpace(AddressSpaceDescriptor { resource_type: AddressSpaceResourceType::IORange, is_maximum_address_fixed: true, is_minimum_address_fixed: true, decode_type: AddressSpaceDecodeType::Additive, granularity: 0, address_range: (0x0D00, 0xFFFF), translation_offset: 0, length: 0xF300 }),
  534. Resource::WordAddressSpace(AddressSpaceDescriptor { resource_type: AddressSpaceResourceType::MemoryRange, is_maximum_address_fixed: true, is_minimum_address_fixed: true, decode_type: AddressSpaceDecodeType::Additive, granularity: 0, address_range: (0xA0000, 0xBFFFF), translation_offset: 0, length: 0x20000 }),
  535. Resource::WordAddressSpace(AddressSpaceDescriptor { resource_type: AddressSpaceResourceType::MemoryRange, is_maximum_address_fixed: true, is_minimum_address_fixed: true, decode_type: AddressSpaceDecodeType::Additive, granularity: 0, address_range: (0xE0000000, 0xFEBFFFFF), translation_offset: 0, length: 0x1EC00000 }),
  536. ]));
  537. }
  538. #[test]
  539. fn test_fdc_crs() {
  540. let bytes: Vec<u8> = [
  541. // 365: IO (Decode16,
  542. // 366: 0x03F2, // Range Minimum
  543. // 367: 0x03F2, // Range Maximum
  544. // 368: 0x00, // Alignment
  545. // 369: 0x04, // Length
  546. // 370: )
  547. // 0000047C: 47 01 F2 03 F2 03 00 04 "G......."
  548. 0x47, 0x01, 0xF2, 0x03, 0xF2, 0x03, 0x00, 0x04,
  549. // 371: IO (Decode16,
  550. // 372: 0x03F7, // Range Minimum
  551. // 373: 0x03F7, // Range Maximum
  552. // 374: 0x00, // Alignment
  553. // 375: 0x01, // Length
  554. // 376: )
  555. // 00000484: 47 01 F7 03 F7 03 00 01 "G......."
  556. 0x47, 0x01, 0xF7, 0x03, 0xF7, 0x03, 0x00, 0x01,
  557. // 377: IRQNoFlags ()
  558. // 378: {6}
  559. // 0000048C: 22 40 00 ............... ""@."
  560. 0x22, 0x40, 0x00,
  561. // 379: DMA (Compatibility, NotBusMaster, Transfer8, )
  562. // 380: {2}
  563. // 0000048F: 2A 04 00 ............... "*.."
  564. 0x2A, 0x04, 0x00,
  565. // 00000492: 79 00 .................. "y."
  566. 0x79, 0x00,
  567. ].to_vec();
  568. let size: u64 = bytes.len() as u64;
  569. let value: AmlValue = AmlValue::Buffer { bytes, size };
  570. let resources = resource_descriptor_list(&value).unwrap();
  571. assert_eq!(resources, Vec::from([
  572. Resource::IOPort(IOPortDescriptor { decodes_full_address: true, memory_range: (0x03F2, 0x03F2), base_alignment: 0, range_length: 4 }),
  573. Resource::IOPort(IOPortDescriptor { decodes_full_address: true, memory_range: (0x03F7, 0x03F7), base_alignment: 0, range_length: 1 }),
  574. Resource::Irq(IrqDescriptor { is_consumer: false, trigger: InterruptTrigger::Edge, polarity: InterruptPolarity::ActiveHigh, is_shared: false, is_wake_capable: false, irq: (1<<6) }),
  575. Resource::Dma(DMADescriptor { channel_mask: 1<<2, supported_speeds: DMASupportedSpeed::CompatibilityMode, is_bus_master: false, transfer_type_preference: DMATransferTypePreference::_8BitOnly })
  576. ]));
  577. }
  578. }