Skip to content

Commit b9350fe

Browse files
committed
Added support for reading multiple IRQs from a ResourceDescriptor
1 parent 0a850f7 commit b9350fe

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

aml/src/pci_routing.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
22
namespace::AmlName,
3-
resource::{self, InterruptPolarity, InterruptTrigger, Resource},
3+
resource::{self, InterruptPolarity, InterruptTrigger, Irq, Resource},
44
value::Args,
55
AmlContext,
66
AmlError,
@@ -169,7 +169,7 @@ impl PciRoutingTable {
169169
polarity: InterruptPolarity::ActiveLow,
170170
is_shared: true,
171171
is_wake_capable: false,
172-
irq: gsi,
172+
irq: Irq::Single(gsi),
173173
}),
174174
PciRouteType::LinkObject(ref name) => {
175175
let path = AmlName::from_str("_CRS").unwrap().resolve(name)?;

aml/src/resource.rs

+30-11
Original file line numberDiff line numberDiff line change
@@ -317,18 +317,20 @@ fn address_space_descriptor<T>(bytes: &[u8]) -> Result<Resource, AmlError> {
317317
}))
318318
}
319319

320+
#[derive(Debug, PartialEq, Eq, Clone)]
321+
pub enum Irq {
322+
Single(u32),
323+
Multiple(Vec<u32>)
324+
}
325+
320326
#[derive(Debug, PartialEq, Eq, Clone)]
321327
pub struct IrqDescriptor {
322328
pub is_consumer: bool,
323329
pub trigger: InterruptTrigger,
324330
pub polarity: InterruptPolarity,
325331
pub is_shared: bool,
326332
pub is_wake_capable: bool,
327-
/*
328-
* NOTE: We currently only support the cases where a descriptor only contains a single interrupt
329-
* number.
330-
*/
331-
pub irq: u32,
333+
pub irq: Irq,
332334
}
333335

334336
fn irq_format_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
@@ -369,7 +371,7 @@ fn irq_format_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
369371
let irq = LittleEndian::read_u16(&bytes[1..=2]);
370372

371373
Ok(Resource::Irq(IrqDescriptor {
372-
irq: irq as u32,
374+
irq: Irq::Single(irq as u32),
373375
is_wake_capable: false,
374376
is_shared: false,
375377
polarity: InterruptPolarity::ActiveHigh,
@@ -395,7 +397,7 @@ fn irq_format_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
395397
};
396398

397399
Ok(Resource::Irq(IrqDescriptor {
398-
irq: irq as u32,
400+
irq: Irq::Single(irq as u32),
399401
is_wake_capable,
400402
is_shared,
401403
polarity,
@@ -551,8 +553,25 @@ fn extended_interrupt_descriptor(bytes: &[u8]) -> Result<Resource, AmlError> {
551553
}
552554

553555
let number_of_interrupts = bytes[4] as usize;
554-
assert_eq!(number_of_interrupts, 1);
555-
let irq = LittleEndian::read_u32(&[bytes[5], bytes[6], bytes[7], bytes[8]]);
556+
557+
let irq = if number_of_interrupts == 1 {
558+
let irq = LittleEndian::read_u32( &bytes[5..9]);
559+
560+
Irq::Single(irq)
561+
} else {
562+
let mut irqs = Vec::with_capacity(number_of_interrupts);
563+
564+
for i in 0..number_of_interrupts {
565+
let start = 5 + i * size_of::<u32>();
566+
let end = start + 4;
567+
568+
let irq = LittleEndian::read_u32(&bytes[start..end]);
569+
570+
irqs.push(irq);
571+
}
572+
573+
Irq::Multiple(irqs)
574+
};
556575

557576
Ok(Resource::Irq(IrqDescriptor {
558577
is_consumer: bytes[3].get_bit(0),
@@ -625,7 +644,7 @@ mod tests {
625644
polarity: InterruptPolarity::ActiveHigh,
626645
is_shared: false,
627646
is_wake_capable: false,
628-
irq: (1 << 1)
647+
irq: Irq::Single(1 << 1)
629648
})
630649
])
631650
);
@@ -836,7 +855,7 @@ mod tests {
836855
polarity: InterruptPolarity::ActiveHigh,
837856
is_shared: false,
838857
is_wake_capable: false,
839-
irq: (1 << 6)
858+
irq: Irq::Single(1 << 6)
840859
}),
841860
Resource::Dma(DMADescriptor {
842861
channel_mask: 1 << 2,

0 commit comments

Comments
 (0)