refactor: move x86_64 ACPI to board/x86_64

Module ACPI should only include helpers for individual tables.
Putting tables together is architecture dependent.

Signed-off-by: Changyuan Lyu <changyuanl@google.com>
This commit is contained in:
Changyuan Lyu 2024-07-04 10:56:02 -07:00 committed by Lencerf
parent 79ec0077b4
commit 3d3d6df856
3 changed files with 94 additions and 92 deletions

View file

@ -15,7 +15,7 @@
use std::arch::x86_64::__cpuid;
use std::iter::zip;
use std::marker::PhantomData;
use std::mem::size_of;
use std::mem::{offset_of, size_of, size_of_val};
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
@ -27,8 +27,10 @@ use crate::arch::layout::{BIOS_DATA_END, EBDA_END, EBDA_START, MEM_64_START, RAM
use crate::arch::reg::{Reg, SegAccess, SegReg, SegRegVal};
use crate::arch::sev::SnpPageType;
use crate::board::{Board, BoardConfig, Result, VcpuGuard};
use crate::firmware::acpi::bindings::AcpiTableRsdp;
use crate::firmware::acpi::create_acpi;
use crate::firmware::acpi::bindings::{AcpiTableFadt, AcpiTableRsdp, AcpiTableXsdt};
use crate::firmware::acpi::{
create_fadt, create_madt, create_mcfg, create_rsdp, create_xsdt, AcpiTable,
};
use crate::hv::{Coco, Hypervisor, Vcpu, Vm};
use crate::loader::InitState;
use crate::mem::mapped::ArcMemPages;
@ -318,8 +320,61 @@ where
Ok(())
}
fn create_acpi(&self) -> AcpiTable {
let mut table_bytes = Vec::new();
let mut pointers = vec![];
let mut checksums = vec![];
let mut xsdt: AcpiTableXsdt<3> = FromZeroes::new_zeroed();
let offset_xsdt = 0;
table_bytes.extend(xsdt.as_bytes());
let offset_dsdt = offset_xsdt + size_of_val(&xsdt);
table_bytes.extend(DSDT_DSDTTBL_HEADER);
let offset_fadt = offset_dsdt + size_of_val(&DSDT_DSDTTBL_HEADER);
debug_assert_eq!(offset_fadt % 4, 0);
let fadt = create_fadt(offset_dsdt as u64);
let pointer_fadt_to_dsdt = offset_fadt + offset_of!(AcpiTableFadt, xdsdt);
table_bytes.extend(fadt.as_bytes());
pointers.push(pointer_fadt_to_dsdt);
checksums.push((offset_fadt, size_of_val(&fadt)));
let offset_madt = offset_fadt + size_of_val(&fadt);
debug_assert_eq!(offset_madt % 4, 0);
let (madt, madt_ioapic, madt_apics) = create_madt(self.config.num_cpu);
table_bytes.extend(madt.as_bytes());
table_bytes.extend(madt_ioapic.as_bytes());
for apic in madt_apics {
table_bytes.extend(apic.as_bytes());
}
let offset_mcfg = offset_madt + madt.header.length as usize;
debug_assert_eq!(offset_mcfg % 4, 0);
let mcfg = create_mcfg();
table_bytes.extend(mcfg.as_bytes());
debug_assert_eq!(offset_xsdt % 4, 0);
let xsdt_entries = [offset_fadt as u64, offset_madt as u64, offset_mcfg as u64];
xsdt = create_xsdt(xsdt_entries);
xsdt.write_to_prefix(&mut table_bytes);
for index in 0..xsdt_entries.len() {
pointers.push(offset_xsdt + offset_of!(AcpiTableXsdt<3>, entries) + index * 8);
}
checksums.push((offset_xsdt, size_of_val(&xsdt)));
let rsdp = create_rsdp(offset_xsdt as u64);
AcpiTable {
rsdp,
tables: table_bytes,
table_checksums: checksums,
table_pointers: pointers,
}
}
pub fn create_firmware_data(&self, _init_state: &InitState) -> Result<()> {
let mut acpi_table = create_acpi(self.config.num_cpu);
let mut acpi_table = self.create_acpi();
if self.config.coco.is_none() {
let ram = self.memory.ram_bus();
acpi_table.relocate(EBDA_START + size_of::<AcpiTableRsdp>() as u64);
@ -348,6 +403,30 @@ where
}
}
const DSDT_DSDTTBL_HEADER: [u8; 324] = [
0x44, 0x53, 0x44, 0x54, 0x43, 0x01, 0x00, 0x00, 0x02, 0x37, 0x41, 0x4c, 0x49, 0x4f, 0x54, 0x48,
0x41, 0x4c, 0x49, 0x4f, 0x54, 0x48, 0x56, 0x4d, 0x01, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x54, 0x4c,
0x25, 0x09, 0x20, 0x20, 0x5b, 0x82, 0x37, 0x2e, 0x5f, 0x53, 0x42, 0x5f, 0x43, 0x4f, 0x4d, 0x31,
0x08, 0x5f, 0x48, 0x49, 0x44, 0x0c, 0x41, 0xd0, 0x05, 0x01, 0x08, 0x5f, 0x55, 0x49, 0x44, 0x01,
0x08, 0x5f, 0x53, 0x54, 0x41, 0x0a, 0x0f, 0x08, 0x5f, 0x43, 0x52, 0x53, 0x11, 0x10, 0x0a, 0x0d,
0x47, 0x01, 0xf8, 0x03, 0xf8, 0x03, 0x00, 0x08, 0x22, 0x10, 0x00, 0x79, 0x00, 0x08, 0x5f, 0x53,
0x35, 0x5f, 0x12, 0x04, 0x01, 0x0a, 0x05, 0x5b, 0x82, 0x4a, 0x0d, 0x2e, 0x5f, 0x53, 0x42, 0x5f,
0x50, 0x43, 0x49, 0x30, 0x08, 0x5f, 0x48, 0x49, 0x44, 0x0c, 0x41, 0xd0, 0x0a, 0x08, 0x08, 0x5f,
0x43, 0x49, 0x44, 0x0c, 0x41, 0xd0, 0x0a, 0x03, 0x08, 0x5f, 0x53, 0x45, 0x47, 0x00, 0x08, 0x5f,
0x55, 0x49, 0x44, 0x00, 0x14, 0x32, 0x5f, 0x44, 0x53, 0x4d, 0x04, 0xa0, 0x29, 0x93, 0x68, 0x11,
0x13, 0x0a, 0x10, 0xd0, 0x37, 0xc9, 0xe5, 0x53, 0x35, 0x7a, 0x4d, 0x91, 0x17, 0xea, 0x4d, 0x19,
0xc3, 0x43, 0x4d, 0xa0, 0x09, 0x93, 0x6a, 0x00, 0xa4, 0x11, 0x03, 0x01, 0x21, 0xa0, 0x07, 0x93,
0x6a, 0x0a, 0x05, 0xa4, 0x00, 0xa4, 0x00, 0x08, 0x5f, 0x43, 0x52, 0x53, 0x11, 0x46, 0x07, 0x0a,
0x72, 0x88, 0x0d, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x47, 0x01, 0xf8, 0x0c, 0xf8, 0x0c, 0x01, 0x08, 0x87, 0x17, 0x00, 0x00, 0x0c, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x60, 0x8a, 0x2b, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00,
0x00, 0x88, 0x0d, 0x00, 0x01, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0x00, 0x00, 0x00,
0xf0, 0x79, 0x00, 0x00,
];
const GUID_TABLE_FOOTER_R_OFFSET: usize = 48;
const GUID_SIZE: usize = 16;

View file

@ -14,9 +14,9 @@
pub mod bindings;
use std::mem::{offset_of, size_of, size_of_val};
use std::mem::{offset_of, size_of};
use zerocopy::{transmute, AsBytes, FromBytes, FromZeroes};
use zerocopy::{transmute, AsBytes, FromBytes};
use crate::arch::layout::PCIE_CONFIG_START;
#[cfg(target_arch = "x86_64")]
@ -34,30 +34,6 @@ use bindings::{
unsafe_impl_zerocopy!(AcpiTableMcfg<1>, FromBytes, FromZeroes, AsBytes);
unsafe_impl_zerocopy!(AcpiTableXsdt<3>, FromBytes, FromZeroes, AsBytes);
const DSDT_DSDTTBL_HEADER: [u8; 324] = [
0x44, 0x53, 0x44, 0x54, 0x43, 0x01, 0x00, 0x00, 0x02, 0x37, 0x41, 0x4c, 0x49, 0x4f, 0x54, 0x48,
0x41, 0x4c, 0x49, 0x4f, 0x54, 0x48, 0x56, 0x4d, 0x01, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x54, 0x4c,
0x25, 0x09, 0x20, 0x20, 0x5b, 0x82, 0x37, 0x2e, 0x5f, 0x53, 0x42, 0x5f, 0x43, 0x4f, 0x4d, 0x31,
0x08, 0x5f, 0x48, 0x49, 0x44, 0x0c, 0x41, 0xd0, 0x05, 0x01, 0x08, 0x5f, 0x55, 0x49, 0x44, 0x01,
0x08, 0x5f, 0x53, 0x54, 0x41, 0x0a, 0x0f, 0x08, 0x5f, 0x43, 0x52, 0x53, 0x11, 0x10, 0x0a, 0x0d,
0x47, 0x01, 0xf8, 0x03, 0xf8, 0x03, 0x00, 0x08, 0x22, 0x10, 0x00, 0x79, 0x00, 0x08, 0x5f, 0x53,
0x35, 0x5f, 0x12, 0x04, 0x01, 0x0a, 0x05, 0x5b, 0x82, 0x4a, 0x0d, 0x2e, 0x5f, 0x53, 0x42, 0x5f,
0x50, 0x43, 0x49, 0x30, 0x08, 0x5f, 0x48, 0x49, 0x44, 0x0c, 0x41, 0xd0, 0x0a, 0x08, 0x08, 0x5f,
0x43, 0x49, 0x44, 0x0c, 0x41, 0xd0, 0x0a, 0x03, 0x08, 0x5f, 0x53, 0x45, 0x47, 0x00, 0x08, 0x5f,
0x55, 0x49, 0x44, 0x00, 0x14, 0x32, 0x5f, 0x44, 0x53, 0x4d, 0x04, 0xa0, 0x29, 0x93, 0x68, 0x11,
0x13, 0x0a, 0x10, 0xd0, 0x37, 0xc9, 0xe5, 0x53, 0x35, 0x7a, 0x4d, 0x91, 0x17, 0xea, 0x4d, 0x19,
0xc3, 0x43, 0x4d, 0xa0, 0x09, 0x93, 0x6a, 0x00, 0xa4, 0x11, 0x03, 0x01, 0x21, 0xa0, 0x07, 0x93,
0x6a, 0x0a, 0x05, 0xa4, 0x00, 0xa4, 0x00, 0x08, 0x5f, 0x43, 0x52, 0x53, 0x11, 0x46, 0x07, 0x0a,
0x72, 0x88, 0x0d, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x47, 0x01, 0xf8, 0x0c, 0xf8, 0x0c, 0x01, 0x08, 0x87, 0x17, 0x00, 0x00, 0x0c, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x60, 0x8a, 0x2b, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00,
0x00, 0x88, 0x0d, 0x00, 0x01, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0x00, 0x00, 0x00,
0xf0, 0x79, 0x00, 0x00,
];
#[inline]
fn wrapping_sum<'a, T>(data: T) -> u8
where
@ -81,7 +57,7 @@ fn default_header() -> AcpiTableHeader {
}
// https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#root-system-description-pointer-rsdp-structure
fn create_rsdp(xsdt_addr: u64) -> AcpiTableRsdp {
pub fn create_rsdp(xsdt_addr: u64) -> AcpiTableRsdp {
AcpiTableRsdp {
signature: SIG_RSDP,
oem_id: OEM_ID,
@ -93,7 +69,7 @@ fn create_rsdp(xsdt_addr: u64) -> AcpiTableRsdp {
}
// https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#extended-system-description-table-fields-xsdt
fn create_xsdt<const N: usize>(entries: [u64; N]) -> AcpiTableXsdt<N> {
pub fn create_xsdt<const N: usize>(entries: [u64; N]) -> AcpiTableXsdt<N> {
let total_length = size_of::<AcpiTableHeader>() + size_of::<u64>() * N;
let entries = entries.map(|e| transmute!(e));
AcpiTableXsdt {
@ -108,7 +84,7 @@ fn create_xsdt<const N: usize>(entries: [u64; N]) -> AcpiTableXsdt<N> {
}
// https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#fadt-format
fn create_fadt(dsdt_addr: u64) -> AcpiTableFadt {
pub fn create_fadt(dsdt_addr: u64) -> AcpiTableFadt {
AcpiTableFadt {
header: AcpiTableHeader {
signature: SIG_FADT,
@ -148,7 +124,7 @@ fn create_fadt(dsdt_addr: u64) -> AcpiTableFadt {
// https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#multiple-apic-description-table-madt
#[cfg(target_arch = "x86_64")]
fn create_madt(num_cpu: u32) -> (AcpiTableMadt, AcpiMadtIoApic, Vec<AcpiMadtLocalX2apic>) {
pub fn create_madt(num_cpu: u32) -> (AcpiTableMadt, AcpiMadtIoApic, Vec<AcpiMadtLocalX2apic>) {
let total_length = size_of::<AcpiTableMadt>()
+ size_of::<AcpiMadtIoApic>()
+ num_cpu as usize * size_of::<AcpiMadtLocalX2apic>();
@ -198,7 +174,7 @@ fn create_madt(num_cpu: u32) -> (AcpiTableMadt, AcpiMadtIoApic, Vec<AcpiMadtLoca
(madt, io_apic, x2apics)
}
fn create_mcfg() -> AcpiTableMcfg<1> {
pub fn create_mcfg() -> AcpiTableMcfg<1> {
let mut mcfg = AcpiTableMcfg {
header: AcpiTableHeader {
signature: SIG_MCFG,
@ -220,10 +196,10 @@ fn create_mcfg() -> AcpiTableMcfg<1> {
}
pub struct AcpiTable {
rsdp: AcpiTableRsdp,
tables: Vec<u8>,
table_pointers: Vec<usize>,
table_checksums: Vec<(usize, usize)>,
pub(crate) rsdp: AcpiTableRsdp,
pub(crate) tables: Vec<u8>,
pub(crate) table_pointers: Vec<usize>,
pub(crate) table_checksums: Vec<(usize, usize)>,
}
impl AcpiTable {
@ -269,56 +245,3 @@ impl AcpiTable {
(self.rsdp, self.tables)
}
}
pub fn create_acpi(num_cpu: u32) -> AcpiTable {
let mut table_bytes = Vec::new();
let mut pointers = vec![];
let mut checksums = vec![];
let mut xsdt: AcpiTableXsdt<3> = FromZeroes::new_zeroed();
let offset_xsdt = 0;
table_bytes.extend(xsdt.as_bytes());
let offset_dsdt = offset_xsdt + size_of_val(&xsdt);
table_bytes.extend(DSDT_DSDTTBL_HEADER);
let offset_fadt = offset_dsdt + size_of_val(&DSDT_DSDTTBL_HEADER);
debug_assert_eq!(offset_fadt % 4, 0);
let fadt = create_fadt(offset_dsdt as u64);
let pointer_fadt_to_dsdt = offset_fadt + offset_of!(AcpiTableFadt, xdsdt);
table_bytes.extend(fadt.as_bytes());
pointers.push(pointer_fadt_to_dsdt);
checksums.push((offset_fadt, size_of_val(&fadt)));
let offset_madt = offset_fadt + size_of_val(&fadt);
debug_assert_eq!(offset_madt % 4, 0);
let (madt, madt_ioapic, madt_apics) = create_madt(num_cpu);
table_bytes.extend(madt.as_bytes());
table_bytes.extend(madt_ioapic.as_bytes());
for apic in madt_apics {
table_bytes.extend(apic.as_bytes());
}
let offset_mcfg = offset_madt + madt.header.length as usize;
debug_assert_eq!(offset_mcfg % 4, 0);
let mcfg = create_mcfg();
table_bytes.extend(mcfg.as_bytes());
debug_assert_eq!(offset_xsdt % 4, 0);
let xsdt_entries = [offset_fadt as u64, offset_madt as u64, offset_mcfg as u64];
xsdt = create_xsdt(xsdt_entries);
xsdt.write_to_prefix(&mut table_bytes);
for index in 0..xsdt_entries.len() {
pointers.push(offset_xsdt + offset_of!(AcpiTableXsdt<3>, entries) + index * 8);
}
checksums.push((offset_xsdt, size_of_val(&xsdt)));
let rsdp = create_rsdp(offset_xsdt as u64);
AcpiTable {
rsdp,
tables: table_bytes,
table_checksums: checksums,
table_pointers: pointers,
}
}