mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-11-04 19:11:11 +00:00
arch: x86_64: acpi: Generate MADT aka APIC table
This provides important APIC configuration details for the CPU. Even though it duplicates some of the information already included in the mptable it is necessary when booting with ACPI as the mptable is not used. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
ee83c2d44e
commit
98f81c36ec
@ -7,7 +7,27 @@ use vm_memory::{GuestAddress, GuestMemoryMmap};
|
||||
|
||||
use vm_memory::{Address, ByteValued, Bytes};
|
||||
|
||||
pub fn create_acpi_tables(guest_mem: &GuestMemoryMmap) -> GuestAddress {
|
||||
#[repr(packed)]
|
||||
struct LocalAPIC {
|
||||
pub r#type: u8,
|
||||
pub length: u8,
|
||||
pub processor_id: u8,
|
||||
pub apic_id: u8,
|
||||
pub flags: u32,
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
#[derive(Default)]
|
||||
struct IOAPIC {
|
||||
pub r#type: u8,
|
||||
pub length: u8,
|
||||
pub ioapic_id: u8,
|
||||
_reserved: u8,
|
||||
pub apic_address: u32,
|
||||
pub gsi_base: u32,
|
||||
}
|
||||
|
||||
pub fn create_acpi_tables(guest_mem: &GuestMemoryMmap, num_cpus: u8) -> GuestAddress {
|
||||
// RSDP is at the EBDA
|
||||
let rsdp_offset = super::EBDA_START;
|
||||
let mut tables: Vec<u64> = Vec::new();
|
||||
@ -43,19 +63,44 @@ pub fn create_acpi_tables(guest_mem: &GuestMemoryMmap) -> GuestAddress {
|
||||
.expect("Error writing FACP table");
|
||||
tables.push(facp_offset.0);
|
||||
|
||||
// MADT
|
||||
let mut madt = SDT::new(*b"APIC", 44, 5, *b"CLOUDH", *b"CHMADT ", 1);
|
||||
madt.write(36, super::mptable::APIC_DEFAULT_PHYS_BASE);
|
||||
|
||||
for cpu in 0..num_cpus {
|
||||
let lapic = LocalAPIC {
|
||||
r#type: 0,
|
||||
length: 8,
|
||||
processor_id: cpu,
|
||||
apic_id: cpu,
|
||||
flags: 1,
|
||||
};
|
||||
madt.append(lapic);
|
||||
}
|
||||
|
||||
madt.append(IOAPIC {
|
||||
r#type: 1,
|
||||
length: 12,
|
||||
ioapic_id: 0,
|
||||
apic_address: super::mptable::IO_APIC_DEFAULT_PHYS_BASE,
|
||||
gsi_base: 0,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let madt_offset = facp_offset.checked_add(facp.len() as u64).unwrap();
|
||||
guest_mem
|
||||
.write_slice(madt.as_slice(), madt_offset)
|
||||
.expect("Error writing MADT table");
|
||||
tables.push(madt_offset.0);
|
||||
|
||||
// XSDT
|
||||
let mut xsdt = SDT::new(
|
||||
*b"XSDT",
|
||||
36 + 8 * tables.len() as u32,
|
||||
1,
|
||||
*b"CLOUDH",
|
||||
*b"CHXSDT ",
|
||||
1,
|
||||
);
|
||||
xsdt.write(36, tables[0]);
|
||||
let mut xsdt = SDT::new(*b"XSDT", 36, 1, *b"CLOUDH", *b"CHXSDT ", 1);
|
||||
for table in tables {
|
||||
xsdt.append(table);
|
||||
}
|
||||
xsdt.update_checksum();
|
||||
|
||||
let xsdt_offset = facp_offset.checked_add(facp.len() as u64).unwrap();
|
||||
let xsdt_offset = madt_offset.checked_add(madt.len() as u64).unwrap();
|
||||
guest_mem
|
||||
.write_slice(xsdt.as_slice(), xsdt_offset)
|
||||
.expect("Error writing XSDT table");
|
||||
|
@ -182,7 +182,7 @@ pub fn configure_system(
|
||||
}
|
||||
}
|
||||
|
||||
let rsdp_addr = acpi::create_acpi_tables(guest_mem);
|
||||
let rsdp_addr = acpi::create_acpi_tables(guest_mem, num_cpus);
|
||||
params.0.acpi_rsdp_addr = rsdp_addr.0;
|
||||
|
||||
let zero_page_addr = layout::ZERO_PAGE_START;
|
||||
|
@ -92,8 +92,8 @@ const MPC_SPEC: i8 = 4;
|
||||
const MPC_OEM: [c_char; 8] = char_array!(c_char; 'F', 'C', ' ', ' ', ' ', ' ', ' ', ' ');
|
||||
const MPC_PRODUCT_ID: [c_char; 12] = ['0' as c_char; 12];
|
||||
const BUS_TYPE_ISA: [u8; 6] = char_array!(u8; 'I', 'S', 'A', ' ', ' ', ' ');
|
||||
const IO_APIC_DEFAULT_PHYS_BASE: u32 = 0xfec00000; // source: linux/arch/x86/include/asm/apicdef.h
|
||||
const APIC_DEFAULT_PHYS_BASE: u32 = 0xfee00000; // source: linux/arch/x86/include/asm/apicdef.h
|
||||
pub const IO_APIC_DEFAULT_PHYS_BASE: u32 = 0xfec00000; // source: linux/arch/x86/include/asm/apicdef.h
|
||||
pub const APIC_DEFAULT_PHYS_BASE: u32 = 0xfee00000; // source: linux/arch/x86/include/asm/apicdef.h
|
||||
const APIC_VERSION: u8 = 0x14;
|
||||
const CPU_STEPPING: u32 = 0x600;
|
||||
const CPU_FEATURE_APIC: u32 = 0x200;
|
||||
|
Loading…
Reference in New Issue
Block a user