diff --git a/OvmfPkg/AcpiPlatformDxe/Qemu.c b/OvmfPkg/AcpiPlatformDxe/Qemu.c index f7736c2b71..7088733905 100644 --- a/OvmfPkg/AcpiPlatformDxe/Qemu.c +++ b/OvmfPkg/AcpiPlatformDxe/Qemu.c @@ -10,7 +10,7 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ +**/ #include "AcpiPlatform.h" #include @@ -98,6 +98,107 @@ QemuInstallAcpiMadtTable ( } +#pragma pack(1) + +typedef struct { + UINT64 Base; + UINT64 End; + UINT64 Length; +} PCI_WINDOW; + +typedef struct { + PCI_WINDOW PciWindow32; + PCI_WINDOW PciWindow64; +} FIRMWARE_DATA; + +#pragma pack() + + +STATIC +EFI_STATUS +EFIAPI +PopulateFwData( + OUT FIRMWARE_DATA *FwData + ) +{ + return EFI_SUCCESS; +} + + +STATIC +EFI_STATUS +EFIAPI +QemuInstallAcpiSsdtTable ( + IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol, + IN VOID *AcpiTableBuffer, + IN UINTN AcpiTableBufferSize, + OUT UINTN *TableKey + ) +{ + EFI_STATUS Status; + FIRMWARE_DATA *FwData; + + Status = EFI_OUT_OF_RESOURCES; + + FwData = AllocateReservedPool (sizeof (*FwData)); + if (FwData != NULL) { + UINTN SsdtSize; + UINT8 *Ssdt; + + SsdtSize = AcpiTableBufferSize + 17; + Ssdt = AllocatePool (SsdtSize); + + if (Ssdt != NULL) { + Status = PopulateFwData (FwData); + + if (Status == EFI_SUCCESS) { + UINT8 *SsdtPtr; + + SsdtPtr = Ssdt; + + CopyMem (SsdtPtr, AcpiTableBuffer, AcpiTableBufferSize); + SsdtPtr += AcpiTableBufferSize; + + // + // build "OperationRegion(FWDT, SystemMemory, 0x12345678, 0x87654321)" + // + *(SsdtPtr++) = 0x5B; // ExtOpPrefix + *(SsdtPtr++) = 0x80; // OpRegionOp + *(SsdtPtr++) = 'F'; + *(SsdtPtr++) = 'W'; + *(SsdtPtr++) = 'D'; + *(SsdtPtr++) = 'T'; + *(SsdtPtr++) = 0x00; // SystemMemory + *(SsdtPtr++) = 0x0C; // DWordPrefix + + // + // no virtual addressing yet, take the four least significant bytes + // + CopyMem(SsdtPtr, &FwData, 4); + SsdtPtr += 4; + + *(SsdtPtr++) = 0x0C; // DWordPrefix + + *(UINT32*) SsdtPtr = sizeof (*FwData); + SsdtPtr += 4; + + ASSERT(SsdtPtr - Ssdt == SsdtSize); + ((EFI_ACPI_DESCRIPTION_HEADER *) Ssdt)->Length = SsdtSize; + Status = InstallAcpiTable (AcpiProtocol, Ssdt, SsdtSize, TableKey); + } + + FreePool(Ssdt); + } + + if (Status != EFI_SUCCESS) { + FreePool(FwData); + } + } + + return Status; +} + + EFI_STATUS EFIAPI QemuInstallAcpiTable ( @@ -115,6 +216,9 @@ QemuInstallAcpiTable ( case EFI_ACPI_1_0_APIC_SIGNATURE: TableInstallFunction = QemuInstallAcpiMadtTable; break; + case EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: + TableInstallFunction = QemuInstallAcpiSsdtTable; + break; default: TableInstallFunction = InstallAcpiTable; } diff --git a/OvmfPkg/AcpiTables/AcpiTables.inf b/OvmfPkg/AcpiTables/AcpiTables.inf index 0f61df45b7..1187a145e5 100644 --- a/OvmfPkg/AcpiTables/AcpiTables.inf +++ b/OvmfPkg/AcpiTables/AcpiTables.inf @@ -33,6 +33,7 @@ Facp.aslc Facs.aslc Dsdt.asl + Ssdt.asl [Packages] MdePkg/MdePkg.dec diff --git a/OvmfPkg/AcpiTables/Ssdt.asl b/OvmfPkg/AcpiTables/Ssdt.asl new file mode 100644 index 0000000000..67c5fdb3a4 --- /dev/null +++ b/OvmfPkg/AcpiTables/Ssdt.asl @@ -0,0 +1,19 @@ +/** @file + Placeholder for runtime-generated objects. + + This empty table provides only a header for dynamic copying and extension, + and a trigger for QemuInstallAcpiSsdtTable(). + + Copyright (C) 2012 Red Hat, Inc. + + This program and the accompanying materials are licensed and made available + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT + WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +DefinitionBlock ("Ssdt.aml", "SSDT", 1, "REDHAT", "OVMF ", 1) { +}