mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-14 08:35:18 +00:00
acpi_tables: aml: Add support for creating IO and interrupt resources
As per ACPI spec: "6.4.2.5 I/O Port Descriptor" and "6.4.3.6 Extended Interrupt Descriptor" Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
08aff4ed5a
commit
e1e0ac2ee3
@ -456,6 +456,83 @@ impl Aml for AddressSpace<u64> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct IO {
|
||||||
|
min: u16,
|
||||||
|
max: u16,
|
||||||
|
alignment: u8,
|
||||||
|
length: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IO {
|
||||||
|
pub fn new(min: u16, max: u16, alignment: u8, length: u8) -> Self {
|
||||||
|
IO {
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
alignment,
|
||||||
|
length,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Aml for IO {
|
||||||
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
|
||||||
|
bytes.push(0x47); /* IO Port Descriptor */
|
||||||
|
bytes.push(1); /* IODecode16 */
|
||||||
|
bytes.append(&mut self.min.to_le_bytes().to_vec());
|
||||||
|
bytes.append(&mut self.max.to_le_bytes().to_vec());
|
||||||
|
bytes.push(self.alignment);
|
||||||
|
bytes.push(self.length);
|
||||||
|
|
||||||
|
bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Interrupt {
|
||||||
|
consumer: bool,
|
||||||
|
edge_triggered: bool,
|
||||||
|
active_low: bool,
|
||||||
|
shared: bool,
|
||||||
|
number: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Interrupt {
|
||||||
|
pub fn new(
|
||||||
|
consumer: bool,
|
||||||
|
edge_triggered: bool,
|
||||||
|
active_low: bool,
|
||||||
|
shared: bool,
|
||||||
|
number: u32,
|
||||||
|
) -> Self {
|
||||||
|
Interrupt {
|
||||||
|
consumer,
|
||||||
|
edge_triggered,
|
||||||
|
active_low,
|
||||||
|
shared,
|
||||||
|
number,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Aml for Interrupt {
|
||||||
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
|
||||||
|
bytes.push(0x89); /* Extended IRQ Descriptor */
|
||||||
|
bytes.append(&mut 6u16.to_le_bytes().to_vec());
|
||||||
|
let flags = (self.shared as u8) << 3
|
||||||
|
| (self.active_low as u8) << 2
|
||||||
|
| (self.edge_triggered as u8) << 1
|
||||||
|
| self.consumer as u8;
|
||||||
|
bytes.push(flags);
|
||||||
|
bytes.push(1u8); /* count */
|
||||||
|
bytes.append(&mut self.number.to_le_bytes().to_vec());
|
||||||
|
|
||||||
|
bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -621,6 +698,39 @@ mod tests {
|
|||||||
.to_bytes(),
|
.to_bytes(),
|
||||||
&crs_qword_memory[..]
|
&crs_qword_memory[..]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
|
||||||
|
{
|
||||||
|
Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, )
|
||||||
|
{
|
||||||
|
0x00000004,
|
||||||
|
}
|
||||||
|
IO (Decode16,
|
||||||
|
0x03F8, // Range Minimum
|
||||||
|
0x03F8, // Range Maximum
|
||||||
|
0x00, // Alignment
|
||||||
|
0x08, // Length
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
*/
|
||||||
|
let interrupt_io_data = [
|
||||||
|
0x08, 0x5F, 0x43, 0x52, 0x53, 0x11, 0x16, 0x0A, 0x13, 0x89, 0x06, 0x00, 0x03, 0x01,
|
||||||
|
0x04, 0x00, 0x00, 0x00, 0x47, 0x01, 0xF8, 0x03, 0xF8, 0x03, 0x00, 0x08, 0x79, 0x00,
|
||||||
|
];
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Name::new(
|
||||||
|
"_CRS".into(),
|
||||||
|
&ResourceTemplate::new(vec![
|
||||||
|
&Interrupt::new(true, true, false, false, 4),
|
||||||
|
&IO::new(0x3f8, 0x3f8, 0, 0x8)
|
||||||
|
])
|
||||||
|
)
|
||||||
|
.to_bytes(),
|
||||||
|
&interrupt_io_data[..]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user