summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2012-05-30 23:15:59 +0000
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2012-05-30 23:15:59 +0000
commit255b4184154dd2f336c8c9f0c162a06a3655d8c6 (patch)
treed7d002853f63f5c61b4a4d1acb3c304d2c3c2791
parent54235984ee6a9d0abe0797ee00d358a0ed6df861 (diff)
downloadedk2-platforms-255b4184154dd2f336c8c9f0c162a06a3655d8c6.tar.xz
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 <jordan.l.justen@intel.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13387 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf1
-rw-r--r--OvmfPkg/AcpiPlatformDxe/Qemu.c83
2 files changed, 83 insertions, 1 deletions
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 <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
#include <Library/QemuFwCfgLib.h>
@@ -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,