Skip to content

Commit

Permalink
acpi_tables: fix the access_size of GenericAddress
Browse files Browse the repository at this point in the history
Without the fix, the code gives
    1 for Byte access
    2 for Word access
    4 for Dword access
    8 for QWord access.

However, As per ACPI 6.4 spec Sec.5.2.3.2 [1], the access_size should
be
    1 for Byte access
    2 for Word access
    3 for Dword access
    4 for QWord access.

[1] https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#generic-address-structure-gas

Signed-off-by: Changyuan Lyu <changyuanl@google.com>
  • Loading branch information
Lencerf committed Jun 26, 2024
1 parent 0ec1948 commit e017b19
Showing 1 changed file with 26 additions and 3 deletions.
29 changes: 26 additions & 3 deletions src/sdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,23 @@ pub struct GenericAddress {
}

impl GenericAddress {
fn access_size_of<T>() -> u8 {
// https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#generic-address-structure-gas
match core::mem::size_of::<T>() {
1 => 1,
2 => 2,
4 => 3,
8 => 4,
_ => unreachable!(),
}
}

pub fn io_port_address<T>(address: u16) -> Self {
GenericAddress {
address_space_id: 1,
register_bit_width: 8 * core::mem::size_of::<T>() as u8,
register_bit_offset: 0,
access_size: core::mem::size_of::<T>() as u8,
access_size: Self::access_size_of::<T>(),
address: u64::from(address),
}
}
Expand All @@ -34,7 +45,7 @@ impl GenericAddress {
address_space_id: 0,
register_bit_width: 8 * core::mem::size_of::<T>() as u8,
register_bit_offset: 0,
access_size: core::mem::size_of::<T>() as u8,
access_size: Self::access_size_of::<T>(),
address,
}
}
Expand Down Expand Up @@ -151,7 +162,7 @@ impl Aml for Sdt {

#[cfg(test)]
mod tests {
use super::Sdt;
use super::{GenericAddress, Sdt};

#[test]
fn test_sdt() {
Expand All @@ -168,4 +179,16 @@ mod tests {
.fold(0u8, |acc, x| acc.wrapping_add(*x));
assert_eq!(sum, 0);
}

#[test]
fn test_generic_address_access_size() {
let byte_mmio = GenericAddress::mmio_address::<u8>(0x1000);
assert_eq!(byte_mmio.access_size, 1);
let word_mmio = GenericAddress::mmio_address::<u16>(0x1000);
assert_eq!(word_mmio.access_size, 2);
let dword_mmio = GenericAddress::mmio_address::<u32>(0x1000);
assert_eq!(dword_mmio.access_size, 3);
let qword_mmio = GenericAddress::mmio_address::<u64>(0x1000);
assert_eq!(qword_mmio.access_size, 4);
}
}

0 comments on commit e017b19

Please sign in to comment.