From 255b4184154dd2f336c8c9f0c162a06a3655d8c6 Mon Sep 17 00:00:00 2001 From: jljusten Date: Wed, 30 May 2012 23:15:59 +0000 Subject: OvmfPkg/AcpiPlatformDxe: Dynamically add Local APIC entries in MADT Update MADT processing for QEMU to add additional Local APIC entries to the MADT. The MADT is still built with a single Local APIC entry. If the AcpiPlatformDxe driver determines that more processors are available, then additional Local APIC entries are added to the MADT at runtime. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jordan Justen Reviewed-by: Laszlo Ersek git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13387 6f19259b-4bc3-4df7-8a09-765794883524 --- OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf | 1 + OvmfPkg/AcpiPlatformDxe/Qemu.c | 83 ++++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 1 deletion(-) (limited to 'OvmfPkg/AcpiPlatformDxe') diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf index 57cdf3e28d..681567a762 100644 --- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf +++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -46,6 +46,7 @@ UefiDriverEntryPoint HobLib QemuFwCfgLib + MemoryAllocationLib [Protocols] gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED diff --git a/OvmfPkg/AcpiPlatformDxe/Qemu.c b/OvmfPkg/AcpiPlatformDxe/Qemu.c index f4e3269a8a..e483856dca 100644 --- a/OvmfPkg/AcpiPlatformDxe/Qemu.c +++ b/OvmfPkg/AcpiPlatformDxe/Qemu.c @@ -13,6 +13,8 @@ **/ #include "AcpiPlatform.h" +#include +#include #include @@ -29,6 +31,73 @@ QemuDetected ( } +STATIC +EFI_STATUS +EFIAPI +QemuInstallAcpiMadtTable ( + IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol, + IN VOID *AcpiTableBuffer, + IN UINTN AcpiTableBufferSize, + OUT UINTN *TableKey + ) +{ + EFI_STATUS Status; + UINTN Count; + UINTN Loop; + EFI_ACPI_DESCRIPTION_HEADER *Hdr; + UINTN NewBufferSize; + EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApic; + + QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount); + Count = (UINTN) QemuFwCfgRead16 (); + ASSERT (Count >= 1); + + if (Count == 1) { + // + // The pre-built MADT table covers the single CPU case + // + return InstallAcpiTable ( + AcpiProtocol, + AcpiTableBuffer, + AcpiTableBufferSize, + TableKey + ); + } + + // + // We need to add additional Local APIC entries to the MADT + // + NewBufferSize = AcpiTableBufferSize + ((Count - 1) * sizeof (*LocalApic)); + Hdr = (EFI_ACPI_DESCRIPTION_HEADER*) AllocatePool (NewBufferSize); + ASSERT (Hdr != NULL); + + CopyMem (Hdr, AcpiTableBuffer, AcpiTableBufferSize); + + LocalApic = (EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE*) + (((UINT8*) Hdr) + AcpiTableBufferSize); + + // + // Add Local APIC entries for the APs to the MADT + // + for (Loop = 1; Loop < Count; Loop++) { + LocalApic->Type = EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC; + LocalApic->Length = sizeof (*LocalApic); + LocalApic->AcpiProcessorId = Loop; + LocalApic->ApicId = Loop; + LocalApic->Flags = 1; + LocalApic++; + } + + Hdr->Length = NewBufferSize; + + Status = InstallAcpiTable (AcpiProtocol, Hdr, NewBufferSize, TableKey); + + FreePool (Hdr); + + return Status; +} + + EFI_STATUS EFIAPI QemuInstallAcpiTable ( @@ -38,7 +107,19 @@ QemuInstallAcpiTable ( OUT UINTN *TableKey ) { - return InstallAcpiTable( + EFI_ACPI_DESCRIPTION_HEADER *Hdr; + EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction; + + Hdr = (EFI_ACPI_DESCRIPTION_HEADER*) AcpiTableBuffer; + switch (Hdr->Signature) { + case EFI_ACPI_1_0_APIC_SIGNATURE: + TableInstallFunction = QemuInstallAcpiMadtTable; + break; + default: + TableInstallFunction = InstallAcpiTable; + } + + return TableInstallFunction ( AcpiProtocol, AcpiTableBuffer, AcpiTableBufferSize, -- cgit v1.2.3