OvmfPkg/AcpiPlatformDxe: Add Xen ACPI tables support
This patch adds Xen ACPI tables support to OVMF. Use EFI_ACPI_TABLE_PROTOCOL to publish all Xen ACPI tables in OVMF, while keeping the Qemu and KVM support. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bei Guan <gbtju85@gmail.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13541 6f19259b-4bc3-4df7-8a09-765794883524 MU SOURCE COMMIT:377e758c3f10216c2638a3ae4bc75fd4d70fbfef
This commit is contained in:
Родитель
5329c3c043
Коммит
ab41f1fbda
|
@ -78,12 +78,9 @@ LocateFvInstanceWithTables (
|
|||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Looking for FV with ACPI storage file
|
||||
//
|
||||
|
||||
for (Index = 0; Index < NumberOfHandles; Index++) {
|
||||
//
|
||||
// Get the protocol on this handle
|
||||
|
@ -160,52 +157,34 @@ AcpiPlatformChecksum (
|
|||
Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Entrypoint of Acpi Platform driver.
|
||||
Find ACPI tables in an FV and parses them. This function is useful for QEMU and KVM.
|
||||
|
||||
@param ImageHandle
|
||||
@param SystemTable
|
||||
|
||||
@return EFI_SUCCESS
|
||||
@return EFI_LOAD_ERROR
|
||||
@return EFI_OUT_OF_RESOURCES
|
||||
@param AcpiTable Protocol instance pointer
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
AcpiPlatformEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
FindAcpiTablesInFv (
|
||||
IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
|
||||
INTN Instance;
|
||||
EFI_ACPI_COMMON_HEADER *CurrentTable;
|
||||
UINTN TableHandle;
|
||||
UINT32 FvStatus;
|
||||
UINTN TableSize;
|
||||
UINTN Size;
|
||||
EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction;
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
|
||||
INTN Instance;
|
||||
EFI_ACPI_COMMON_HEADER *CurrentTable;
|
||||
UINTN TableHandle;
|
||||
UINT32 FvStatus;
|
||||
UINTN TableSize;
|
||||
UINTN Size;
|
||||
EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction;
|
||||
|
||||
Instance = 0;
|
||||
CurrentTable = NULL;
|
||||
TableHandle = 0;
|
||||
|
||||
//
|
||||
// Find the AcpiTable protocol
|
||||
//
|
||||
Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
if (QemuDetected ()) {
|
||||
TableInstallFunction = QemuInstallAcpiTable;
|
||||
} else if (XenDetected ()) {
|
||||
TableInstallFunction = XenInstallAcpiTable;
|
||||
} else {
|
||||
TableInstallFunction = InstallAcpiTable;
|
||||
}
|
||||
|
@ -231,7 +210,7 @@ AcpiPlatformEntryPoint (
|
|||
&Size,
|
||||
&FvStatus
|
||||
);
|
||||
if (!EFI_ERROR(Status)) {
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Add the table
|
||||
//
|
||||
|
@ -275,3 +254,51 @@ AcpiPlatformEntryPoint (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Entrypoint of Acpi Platform driver.
|
||||
|
||||
@param ImageHandle
|
||||
@param SystemTable
|
||||
|
||||
@return EFI_SUCCESS
|
||||
@return EFI_LOAD_ERROR
|
||||
@return EFI_OUT_OF_RESOURCES
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
AcpiPlatformEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
|
||||
|
||||
//
|
||||
// Find the AcpiTable protocol
|
||||
//
|
||||
Status = gBS->LocateProtocol (
|
||||
&gEfiAcpiTableProtocolGuid,
|
||||
NULL,
|
||||
(VOID**)&AcpiTable
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
if (XenDetected ()) {
|
||||
Status = InstallXenTables (AcpiTable);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = FindAcpiTablesInFv (AcpiTable);
|
||||
}
|
||||
} else {
|
||||
Status = FindAcpiTablesInFv (AcpiTable);
|
||||
}
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,11 +57,8 @@ XenDetected (
|
|||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
XenInstallAcpiTable (
|
||||
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
|
||||
IN VOID *AcpiTableBuffer,
|
||||
IN UINTN AcpiTableBufferSize,
|
||||
OUT UINTN *TableKey
|
||||
InstallXenTables (
|
||||
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/** @file
|
||||
OVMF ACPI QEMU support
|
||||
OVMF ACPI Xen support
|
||||
|
||||
Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2012, Bei Guan <gbtju85@gmail.com>
|
||||
|
||||
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
|
||||
|
@ -16,7 +18,47 @@
|
|||
#include <Library/HobLib.h>
|
||||
#include <Guid/XenInfo.h>
|
||||
|
||||
#define XEN_ACPI_PHYSICAL_ADDRESS 0x000EA020
|
||||
#define XEN_BIOS_PHYSICAL_END 0x000FFFFF
|
||||
|
||||
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *XenAcpiRsdpStructurePtr = NULL;
|
||||
|
||||
/**
|
||||
Calculates the checksum of the ACPI tables.
|
||||
|
||||
@param Buffer Address of the ACPI table.
|
||||
@param Size Size of the ACPI table need to check.
|
||||
|
||||
**/
|
||||
UINT8
|
||||
CalculateTableChecksum (
|
||||
IN VOID *Buffer,
|
||||
IN UINTN Size
|
||||
)
|
||||
{
|
||||
UINT8 Sum;
|
||||
UINT8 *Ptr;
|
||||
|
||||
Sum = 0;
|
||||
//
|
||||
// Initialize pointer
|
||||
//
|
||||
Ptr = Buffer;
|
||||
|
||||
//
|
||||
// Add all content of buffer
|
||||
//
|
||||
while ((Size--) != 0) {
|
||||
Sum = (UINT8) (Sum + (*Ptr++));
|
||||
}
|
||||
|
||||
return Sum;
|
||||
}
|
||||
|
||||
/**
|
||||
This function detects if OVMF is running on Xen.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
XenDetected (
|
||||
VOID
|
||||
|
@ -35,21 +77,273 @@ XenDetected (
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the address of Xen ACPI Root System Description Pointer (RSDP)
|
||||
structure.
|
||||
|
||||
@param RsdpStructurePtr Return pointer to RSDP structure
|
||||
|
||||
@return EFI_SUCCESS Find Xen RSDP structure successfully.
|
||||
@return EFI_NOT_FOUND Don't find Xen RSDP structure.
|
||||
@return EFI_ABORTED Find Xen RSDP structure, but it's not integrated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
XenInstallAcpiTable (
|
||||
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
|
||||
IN VOID *AcpiTableBuffer,
|
||||
IN UINTN AcpiTableBufferSize,
|
||||
OUT UINTN *TableKey
|
||||
GetXenAcpiRsdp (
|
||||
OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr
|
||||
)
|
||||
{
|
||||
return InstallAcpiTable(
|
||||
AcpiProtocol,
|
||||
AcpiTableBuffer,
|
||||
AcpiTableBufferSize,
|
||||
TableKey
|
||||
);
|
||||
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;
|
||||
UINT8 *XenAcpiPtr;
|
||||
UINT8 Sum;
|
||||
|
||||
//
|
||||
// Detect the RSDP structure
|
||||
//
|
||||
for (XenAcpiPtr = (UINT8*)(UINTN) XEN_ACPI_PHYSICAL_ADDRESS;
|
||||
XenAcpiPtr < (UINT8*)(UINTN) XEN_BIOS_PHYSICAL_END;
|
||||
XenAcpiPtr += 0x10) {
|
||||
|
||||
RsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)
|
||||
(UINTN) XenAcpiPtr;
|
||||
|
||||
if (!AsciiStrnCmp ((CHAR8 *) &RsdpStructurePtr->Signature, "RSD PTR ", 8)) {
|
||||
//
|
||||
// RSDP ACPI 1.0 checksum for 1.0/2.0/3.0 table.
|
||||
// This is only the first 20 bytes of the structure
|
||||
//
|
||||
Sum = CalculateTableChecksum (
|
||||
RsdpStructurePtr,
|
||||
sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)
|
||||
);
|
||||
if (Sum != 0) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
if (RsdpStructurePtr->Revision >= 2) {
|
||||
//
|
||||
// RSDP ACPI 2.0/3.0 checksum, this is the entire table
|
||||
//
|
||||
Sum = CalculateTableChecksum (
|
||||
RsdpStructurePtr,
|
||||
sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)
|
||||
);
|
||||
if (Sum != 0) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
}
|
||||
*RsdpPtr = RsdpStructurePtr;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables
|
||||
into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed
|
||||
ACPI tables are: FACP, APIC, HPET, WAET, SSDT, FACS, DSDT.
|
||||
|
||||
@param AcpiProtocol Protocol instance pointer.
|
||||
|
||||
@return EFI_SUCCESS The table was successfully inserted.
|
||||
@return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is
|
||||
NULL, or AcpiTableBufferSize and the size
|
||||
field embedded in the ACPI table pointed to
|
||||
by AcpiTableBuffer are not in sync.
|
||||
@return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InstallXenTables (
|
||||
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN TableHandle;
|
||||
|
||||
EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
|
||||
EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
|
||||
VOID *CurrentTableEntry;
|
||||
UINTN CurrentTablePointer;
|
||||
EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;
|
||||
UINTN Index;
|
||||
UINTN NumberOfTableEntries;
|
||||
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table;
|
||||
EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt1Table;
|
||||
EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs2Table;
|
||||
EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs1Table;
|
||||
EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;
|
||||
|
||||
Fadt2Table = NULL;
|
||||
Fadt1Table = NULL;
|
||||
Facs2Table = NULL;
|
||||
Facs1Table = NULL;
|
||||
DsdtTable = NULL;
|
||||
TableHandle = 0;
|
||||
NumberOfTableEntries = 0;
|
||||
|
||||
//
|
||||
// Try to find Xen ACPI tables
|
||||
//
|
||||
Status = GetXenAcpiRsdp (&XenAcpiRsdpStructurePtr);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// If XSDT table is find, just install its tables.
|
||||
// Otherwise, try to find and install the RSDT tables.
|
||||
//
|
||||
if (XenAcpiRsdpStructurePtr->XsdtAddress) {
|
||||
//
|
||||
// Retrieve the addresses of XSDT and
|
||||
// calculate the number of its table entries.
|
||||
//
|
||||
Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)
|
||||
XenAcpiRsdpStructurePtr->XsdtAddress;
|
||||
NumberOfTableEntries = (Xsdt->Length -
|
||||
sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /
|
||||
sizeof (UINT64);
|
||||
|
||||
//
|
||||
// Install ACPI tables found in XSDT.
|
||||
//
|
||||
for (Index = 0; Index < NumberOfTableEntries; Index++) {
|
||||
//
|
||||
// Get the table entry from XSDT
|
||||
//
|
||||
CurrentTableEntry = (VOID *) ((UINT8 *) Xsdt +
|
||||
sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
|
||||
Index * sizeof (UINT64));
|
||||
CurrentTablePointer = *(UINT64 *)CurrentTableEntry;
|
||||
CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;
|
||||
|
||||
//
|
||||
// Install the XSDT tables
|
||||
//
|
||||
Status = InstallAcpiTable (
|
||||
AcpiProtocol,
|
||||
CurrentTable,
|
||||
CurrentTable->Length,
|
||||
&TableHandle
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the FACS and DSDT table address from the table FADT
|
||||
//
|
||||
if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {
|
||||
Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)
|
||||
(UINTN) CurrentTablePointer;
|
||||
Facs2Table = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)
|
||||
(UINTN) Fadt2Table->FirmwareCtrl;
|
||||
DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Fadt2Table->Dsdt;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (XenAcpiRsdpStructurePtr->RsdtAddress) {
|
||||
//
|
||||
// Retrieve the addresses of RSDT and
|
||||
// calculate the number of its table entries.
|
||||
//
|
||||
Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)
|
||||
XenAcpiRsdpStructurePtr->RsdtAddress;
|
||||
NumberOfTableEntries = (Rsdt->Length -
|
||||
sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /
|
||||
sizeof (UINT32);
|
||||
|
||||
//
|
||||
// Install ACPI tables found in XSDT.
|
||||
//
|
||||
for (Index = 0; Index < NumberOfTableEntries; Index++) {
|
||||
//
|
||||
// Get the table entry from RSDT
|
||||
//
|
||||
CurrentTableEntry = (UINT32 *) ((UINT8 *) Rsdt +
|
||||
sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
|
||||
Index * sizeof (UINT32));
|
||||
CurrentTablePointer = *(UINT32 *)CurrentTableEntry;
|
||||
CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;
|
||||
|
||||
//
|
||||
// Install the RSDT tables
|
||||
//
|
||||
Status = InstallAcpiTable (
|
||||
AcpiProtocol,
|
||||
CurrentTable,
|
||||
CurrentTable->Length,
|
||||
&TableHandle
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the FACS and DSDT table address from the table FADT
|
||||
//
|
||||
if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {
|
||||
Fadt1Table = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *)
|
||||
(UINTN) CurrentTablePointer;
|
||||
Facs1Table = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)
|
||||
(UINTN) Fadt1Table->FirmwareCtrl;
|
||||
DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Fadt1Table->Dsdt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Install the FACS table.
|
||||
//
|
||||
if (Fadt2Table) {
|
||||
//
|
||||
// FACS 2.0
|
||||
//
|
||||
Status = InstallAcpiTable (
|
||||
AcpiProtocol,
|
||||
Facs2Table,
|
||||
Facs2Table->Length,
|
||||
&TableHandle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else if (Fadt1Table) {
|
||||
//
|
||||
// FACS 1.0
|
||||
//
|
||||
Status = InstallAcpiTable (
|
||||
AcpiProtocol,
|
||||
Facs1Table,
|
||||
Facs1Table->Length,
|
||||
&TableHandle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Install DSDT table.
|
||||
//
|
||||
Status = InstallAcpiTable (
|
||||
AcpiProtocol,
|
||||
DsdtTable,
|
||||
DsdtTable->Length,
|
||||
&TableHandle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче