resource.rs 30 KB

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