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.

The fix takes QEMU's implementation[2] as a reference. A related
patch[3] has been merged into crosvm.

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

[2] https://github.com/qemu/qemu/blob/6a4180af9686830d88c387baab6d79563ce42a15/hw/acpi/erst.c#L218

[3] https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5394229

Signed-off-by: Changyuan Lyu <changyuanl@google.com>
  • Loading branch information
Lencerf committed Jun 26, 2024
1 parent 0ec1948 commit 9f02e6f
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/sdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl 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: core::mem::size_of::<T>().trailing_zeros() as u8 + 1,
address: u64::from(address),
}
}
Expand All @@ -34,7 +34,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: core::mem::size_of::<T>().trailing_zeros() as u8 + 1,
address,
}
}
Expand Down Expand Up @@ -151,7 +151,7 @@ impl Aml for Sdt {

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

#[test]
fn test_sdt() {
Expand All @@ -168,4 +168,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 9f02e6f

Please sign in to comment.