R: Stefan Berger <stefanb@linux.ibm.com>\r
\r
OvmfPkg: Xen-related modules\r
-F: OvmfPkg/AcpiPlatformDxe/Xen.c\r
F: OvmfPkg/Include/Guid/XenBusRootDevice.h\r
F: OvmfPkg/Include/Guid/XenInfo.h\r
F: OvmfPkg/Include/IndustryStandard/Xen/\r
+++ /dev/null
-/** @file\r
- OVMF ACPI Platform Driver\r
-\r
- Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <Library/DebugLib.h> // ASSERT_EFI_ERROR()\r
-#include <Library/UefiBootServicesTableLib.h> // gBS\r
-#include <Library/XenPlatformLib.h> // XenDetected()\r
-#include <Protocol/FirmwareVolume2.h> // gEfiFirmwareVolume2Protocol...\r
-\r
-#include "AcpiPlatform.h"\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-InstallAcpiTable (\r
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,\r
- IN VOID *AcpiTableBuffer,\r
- IN UINTN AcpiTableBufferSize,\r
- OUT UINTN *TableKey\r
- )\r
-{\r
- return AcpiProtocol->InstallAcpiTable (\r
- AcpiProtocol,\r
- AcpiTableBuffer,\r
- AcpiTableBufferSize,\r
- TableKey\r
- );\r
-}\r
-\r
-\r
-/**\r
- Locate the first instance of a protocol. If the protocol requested is an\r
- FV protocol, then it will return the first FV that contains the ACPI table\r
- storage file.\r
-\r
- @param Instance Return pointer to the first instance of the protocol\r
-\r
- @return EFI_SUCCESS The function completed successfully.\r
- @return EFI_NOT_FOUND The protocol could not be located.\r
- @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.\r
-\r
-**/\r
-EFI_STATUS\r
-LocateFvInstanceWithTables (\r
- OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN NumberOfHandles;\r
- EFI_FV_FILETYPE FileType;\r
- UINT32 FvStatus;\r
- EFI_FV_FILE_ATTRIBUTES Attributes;\r
- UINTN Size;\r
- UINTN Index;\r
- EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;\r
-\r
- FvStatus = 0;\r
-\r
- //\r
- // Locate protocol.\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- NULL,\r
- &NumberOfHandles,\r
- &HandleBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Defined errors at this time are not found and out of resources.\r
- //\r
- return Status;\r
- }\r
-\r
- //\r
- // Looking for FV with ACPI storage file\r
- //\r
- for (Index = 0; Index < NumberOfHandles; Index++) {\r
- //\r
- // Get the protocol on this handle\r
- // This should not fail because of LocateHandleBuffer\r
- //\r
- Status = gBS->HandleProtocol (\r
- HandleBuffer[Index],\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- (VOID**) &FvInstance\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // See if it has the ACPI storage file\r
- //\r
- Status = FvInstance->ReadFile (\r
- FvInstance,\r
- (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),\r
- NULL,\r
- &Size,\r
- &FileType,\r
- &Attributes,\r
- &FvStatus\r
- );\r
-\r
- //\r
- // If we found it, then we are done\r
- //\r
- if (Status == EFI_SUCCESS) {\r
- *Instance = FvInstance;\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // Our exit status is determined by the success of the previous operations\r
- // If the protocol was found, Instance already points to it.\r
- //\r
-\r
- //\r
- // Free any allocated buffers\r
- //\r
- gBS->FreePool (HandleBuffer);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Find ACPI tables in an FV and install them.\r
-\r
- This is now a fall-back path. Normally, we will search for tables provided\r
- by the VMM first.\r
-\r
- If that fails, we use this function to load the ACPI tables from an FV. The\r
- sources for the FV based tables is located under OvmfPkg/AcpiTables.\r
-\r
- @param AcpiTable Protocol instance pointer\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InstallOvmfFvTables (\r
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;\r
- INTN Instance;\r
- EFI_ACPI_COMMON_HEADER *CurrentTable;\r
- UINTN TableHandle;\r
- UINT32 FvStatus;\r
- UINTN TableSize;\r
- UINTN Size;\r
- EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction;\r
-\r
- Instance = 0;\r
- CurrentTable = NULL;\r
- TableHandle = 0;\r
-\r
- if (QemuDetected ()) {\r
- TableInstallFunction = QemuInstallAcpiTable;\r
- } else {\r
- TableInstallFunction = InstallAcpiTable;\r
- }\r
-\r
- //\r
- // set FwVol (and use an ASSERT() below) to suppress incorrect\r
- // compiler/analyzer warnings\r
- //\r
- FwVol = NULL;\r
- //\r
- // Locate the firmware volume protocol\r
- //\r
- Status = LocateFvInstanceWithTables (&FwVol);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
- ASSERT (FwVol != NULL);\r
-\r
- //\r
- // Read tables from the storage file.\r
- //\r
- while (Status == EFI_SUCCESS) {\r
-\r
- Status = FwVol->ReadSection (\r
- FwVol,\r
- (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),\r
- EFI_SECTION_RAW,\r
- Instance,\r
- (VOID**) &CurrentTable,\r
- &Size,\r
- &FvStatus\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Add the table\r
- //\r
- TableHandle = 0;\r
-\r
- TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;\r
- ASSERT (Size >= TableSize);\r
-\r
- //\r
- // Install ACPI table\r
- //\r
- Status = TableInstallFunction (\r
- AcpiTable,\r
- CurrentTable,\r
- TableSize,\r
- &TableHandle\r
- );\r
-\r
- //\r
- // Free memory allocated by ReadSection\r
- //\r
- gBS->FreePool (CurrentTable);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- //\r
- // Increment the instance\r
- //\r
- Instance++;\r
- CurrentTable = NULL;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Effective entrypoint of Acpi Platform driver.\r
-\r
- @param ImageHandle\r
- @param SystemTable\r
-\r
- @return EFI_SUCCESS\r
- @return EFI_LOAD_ERROR\r
- @return EFI_OUT_OF_RESOURCES\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InstallAcpiTables (\r
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if (XenDetected ()) {\r
- Status = InstallXenTables (AcpiTable);\r
- } else {\r
- Status = InstallQemuFwCfgTables (AcpiTable);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- Status = InstallOvmfFvTables (AcpiTable);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
\r
typedef struct S3_CONTEXT S3_CONTEXT;\r
\r
-EFI_STATUS\r
-EFIAPI\r
-InstallAcpiTable (\r
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,\r
- IN VOID *AcpiTableBuffer,\r
- IN UINTN AcpiTableBufferSize,\r
- OUT UINTN *TableKey\r
- );\r
-\r
-BOOLEAN\r
-QemuDetected (\r
- VOID\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-QemuInstallAcpiTable (\r
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,\r
- IN VOID *AcpiTableBuffer,\r
- IN UINTN AcpiTableBufferSize,\r
- OUT UINTN *TableKey\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-InstallXenTables (\r
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol\r
- );\r
-\r
EFI_STATUS\r
EFIAPI\r
InstallQemuFwCfgTables (\r
+++ /dev/null
-## @file\r
-# OVMF ACPI Platform Driver\r
-#\r
-# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>\r
-# SPDX-License-Identifier: BSD-2-Clause-Patent\r
-#\r
-##\r
-\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = AcpiPlatform\r
- FILE_GUID = 49970331-E3FA-4637-9ABC-3B7868676970\r
- MODULE_TYPE = DXE_DRIVER\r
- VERSION_STRING = 1.0\r
- ENTRY_POINT = AcpiPlatformEntryPoint\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-# VALID_ARCHITECTURES = IA32 X64 EBC\r
-#\r
-\r
-[Sources]\r
- AcpiPlatform.c\r
- AcpiPlatform.h\r
- BootScript.c\r
- EntryPoint.c\r
- PciDecoding.c\r
- Qemu.c\r
- QemuFwCfgAcpi.c\r
- Xen.c\r
-\r
-[Packages]\r
- MdeModulePkg/MdeModulePkg.dec\r
- MdePkg/MdePkg.dec\r
- OvmfPkg/OvmfPkg.dec\r
- UefiCpuPkg/UefiCpuPkg.dec\r
-\r
-[LibraryClasses]\r
- BaseLib\r
- BaseMemoryLib\r
- DebugLib\r
- DxeServicesTableLib\r
- MemoryAllocationLib\r
- OrderedCollectionLib\r
- PcdLib\r
- QemuFwCfgLib\r
- QemuFwCfgS3Lib\r
- UefiBootServicesTableLib\r
- UefiDriverEntryPoint\r
- XenPlatformLib\r
-\r
-[Protocols]\r
- gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED\r
- gEfiFirmwareVolume2ProtocolGuid # PROTOCOL SOMETIMES_CONSUMED\r
- gEfiPciIoProtocolGuid # PROTOCOL SOMETIMES_CONSUMED\r
-\r
-[Guids]\r
- gRootBridgesConnectedEventGroupGuid\r
-\r
-[Pcd]\r
- gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile\r
- gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration\r
- gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress\r
- gUefiOvmfPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel\r
- gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress\r
-\r
-[Depex]\r
- gEfiAcpiTableProtocolGuid\r
+++ /dev/null
-/** @file\r
- OVMF ACPI QEMU support\r
-\r
- Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
-\r
- Copyright (C) 2012-2014, Red Hat, Inc.\r
-\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <IndustryStandard/Acpi.h> // EFI_ACPI_1_0_IO_APIC_STRUCTURE\r
-#include <Library/BaseMemoryLib.h> // CopyMem()\r
-#include <Library/DebugLib.h> // DEBUG()\r
-#include <Library/DxeServicesTableLib.h> // gDS\r
-#include <Library/MemoryAllocationLib.h> // AllocatePool()\r
-#include <Library/PcdLib.h> // PcdGet16()\r
-#include <Library/QemuFwCfgLib.h> // QemuFwCfgIsAvailable()\r
-\r
-#include "AcpiPlatform.h"\r
-\r
-BOOLEAN\r
-QemuDetected (\r
- VOID\r
- )\r
-{\r
- if (!QemuFwCfgIsAvailable ()) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-STATIC\r
-UINTN\r
-CountBits16 (\r
- UINT16 Mask\r
- )\r
-{\r
- //\r
- // For all N >= 1, N bits are enough to represent the number of bits set\r
- // among N bits. It's true for N == 1. When adding a new bit (N := N+1),\r
- // the maximum number of possibly set bits increases by one, while the\r
- // representable maximum doubles.\r
- //\r
- Mask = ((Mask & 0xAAAA) >> 1) + (Mask & 0x5555);\r
- Mask = ((Mask & 0xCCCC) >> 2) + (Mask & 0x3333);\r
- Mask = ((Mask & 0xF0F0) >> 4) + (Mask & 0x0F0F);\r
- Mask = ((Mask & 0xFF00) >> 8) + (Mask & 0x00FF);\r
-\r
- return Mask;\r
-}\r
-\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-QemuInstallAcpiMadtTable (\r
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,\r
- IN VOID *AcpiTableBuffer,\r
- IN UINTN AcpiTableBufferSize,\r
- OUT UINTN *TableKey\r
- )\r
-{\r
- UINTN CpuCount;\r
- UINTN PciLinkIsoCount;\r
- UINTN NewBufferSize;\r
- EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt;\r
- EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE *LocalApic;\r
- EFI_ACPI_1_0_IO_APIC_STRUCTURE *IoApic;\r
- EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *Iso;\r
- EFI_ACPI_1_0_LOCAL_APIC_NMI_STRUCTURE *LocalApicNmi;\r
- VOID *Ptr;\r
- UINTN Loop;\r
- EFI_STATUS Status;\r
-\r
- ASSERT (AcpiTableBufferSize >= sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
-\r
- QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount);\r
- CpuCount = QemuFwCfgRead16 ();\r
- ASSERT (CpuCount >= 1);\r
-\r
- //\r
- // Set Level-tiggered, Active High for these identity mapped IRQs. The bitset\r
- // corresponds to the union of all possible interrupt assignments for the LNKA,\r
- // LNKB, LNKC, LNKD PCI interrupt lines. See the DSDT.\r
- //\r
- PciLinkIsoCount = CountBits16 (PcdGet16 (Pcd8259LegacyModeEdgeLevel));\r
-\r
- NewBufferSize = 1 * sizeof (*Madt) +\r
- CpuCount * sizeof (*LocalApic) +\r
- 1 * sizeof (*IoApic) +\r
- (1 + PciLinkIsoCount) * sizeof (*Iso) +\r
- 1 * sizeof (*LocalApicNmi);\r
-\r
- Madt = AllocatePool (NewBufferSize);\r
- if (Madt == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- CopyMem (&(Madt->Header), AcpiTableBuffer, sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
- Madt->Header.Length = (UINT32) NewBufferSize;\r
- Madt->LocalApicAddress = PcdGet32 (PcdCpuLocalApicBaseAddress);\r
- Madt->Flags = EFI_ACPI_1_0_PCAT_COMPAT;\r
- Ptr = Madt + 1;\r
-\r
- LocalApic = Ptr;\r
- for (Loop = 0; Loop < CpuCount; ++Loop) {\r
- LocalApic->Type = EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC;\r
- LocalApic->Length = sizeof (*LocalApic);\r
- LocalApic->AcpiProcessorId = (UINT8) Loop;\r
- LocalApic->ApicId = (UINT8) Loop;\r
- LocalApic->Flags = 1; // enabled\r
- ++LocalApic;\r
- }\r
- Ptr = LocalApic;\r
-\r
- IoApic = Ptr;\r
- IoApic->Type = EFI_ACPI_1_0_IO_APIC;\r
- IoApic->Length = sizeof (*IoApic);\r
- IoApic->IoApicId = (UINT8) CpuCount;\r
- IoApic->Reserved = EFI_ACPI_RESERVED_BYTE;\r
- IoApic->IoApicAddress = 0xFEC00000;\r
- IoApic->SystemVectorBase = 0x00000000;\r
- Ptr = IoApic + 1;\r
-\r
- //\r
- // IRQ0 (8254 Timer) => IRQ2 (PIC) Interrupt Source Override Structure\r
- //\r
- Iso = Ptr;\r
- Iso->Type = EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE;\r
- Iso->Length = sizeof (*Iso);\r
- Iso->Bus = 0x00; // ISA\r
- Iso->Source = 0x00; // IRQ0\r
- Iso->GlobalSystemInterruptVector = 0x00000002;\r
- Iso->Flags = 0x0000; // Conforms to specs of the bus\r
- ++Iso;\r
-\r
- //\r
- // Set Level-triggered, Active High for all possible PCI link targets.\r
- //\r
- for (Loop = 0; Loop < 16; ++Loop) {\r
- if ((PcdGet16 (Pcd8259LegacyModeEdgeLevel) & (1 << Loop)) == 0) {\r
- continue;\r
- }\r
- Iso->Type = EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE;\r
- Iso->Length = sizeof (*Iso);\r
- Iso->Bus = 0x00; // ISA\r
- Iso->Source = (UINT8) Loop;\r
- Iso->GlobalSystemInterruptVector = (UINT32) Loop;\r
- Iso->Flags = 0x000D; // Level-triggered, Active High\r
- ++Iso;\r
- }\r
- ASSERT (\r
- (UINTN) (Iso - (EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE *)Ptr) ==\r
- 1 + PciLinkIsoCount\r
- );\r
- Ptr = Iso;\r
-\r
- LocalApicNmi = Ptr;\r
- LocalApicNmi->Type = EFI_ACPI_1_0_LOCAL_APIC_NMI;\r
- LocalApicNmi->Length = sizeof (*LocalApicNmi);\r
- LocalApicNmi->AcpiProcessorId = 0xFF; // applies to all processors\r
- //\r
- // polarity and trigger mode of the APIC I/O input signals conform to the\r
- // specifications of the bus\r
- //\r
- LocalApicNmi->Flags = 0x0000;\r
- //\r
- // Local APIC interrupt input LINTn to which NMI is connected.\r
- //\r
- LocalApicNmi->LocalApicInti = 0x01;\r
- Ptr = LocalApicNmi + 1;\r
-\r
- ASSERT ((UINTN) ((UINT8 *)Ptr - (UINT8 *)Madt) == NewBufferSize);\r
- Status = InstallAcpiTable (AcpiProtocol, Madt, NewBufferSize, TableKey);\r
-\r
- FreePool (Madt);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-#pragma pack(1)\r
-\r
-typedef struct {\r
- UINT64 Base;\r
- UINT64 End;\r
- UINT64 Length;\r
-} PCI_WINDOW;\r
-\r
-typedef struct {\r
- PCI_WINDOW PciWindow32;\r
- PCI_WINDOW PciWindow64;\r
-} FIRMWARE_DATA;\r
-\r
-typedef struct {\r
- UINT8 BytePrefix;\r
- UINT8 ByteValue;\r
-} AML_BYTE;\r
-\r
-typedef struct {\r
- UINT8 NameOp;\r
- UINT8 RootChar;\r
- UINT8 NameChar[4];\r
- UINT8 PackageOp;\r
- UINT8 PkgLength;\r
- UINT8 NumElements;\r
- AML_BYTE Pm1aCntSlpTyp;\r
- AML_BYTE Pm1bCntSlpTyp;\r
- AML_BYTE Reserved[2];\r
-} SYSTEM_STATE_PACKAGE;\r
-\r
-#pragma pack()\r
-\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-PopulateFwData(\r
- OUT FIRMWARE_DATA *FwData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN NumDesc;\r
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR *AllDesc;\r
-\r
- Status = gDS->GetMemorySpaceMap (&NumDesc, &AllDesc);\r
- if (Status == EFI_SUCCESS) {\r
- UINT64 NonMmio32MaxExclTop;\r
- UINT64 Mmio32MinBase;\r
- UINT64 Mmio32MaxExclTop;\r
- UINTN CurDesc;\r
-\r
- Status = EFI_UNSUPPORTED;\r
-\r
- NonMmio32MaxExclTop = 0;\r
- Mmio32MinBase = BASE_4GB;\r
- Mmio32MaxExclTop = 0;\r
-\r
- for (CurDesc = 0; CurDesc < NumDesc; ++CurDesc) {\r
- CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Desc;\r
- UINT64 ExclTop;\r
-\r
- Desc = &AllDesc[CurDesc];\r
- ExclTop = Desc->BaseAddress + Desc->Length;\r
-\r
- if (ExclTop <= (UINT64) PcdGet32 (PcdOvmfFdBaseAddress)) {\r
- switch (Desc->GcdMemoryType) {\r
- case EfiGcdMemoryTypeNonExistent:\r
- break;\r
-\r
- case EfiGcdMemoryTypeReserved:\r
- case EfiGcdMemoryTypeSystemMemory:\r
- if (NonMmio32MaxExclTop < ExclTop) {\r
- NonMmio32MaxExclTop = ExclTop;\r
- }\r
- break;\r
-\r
- case EfiGcdMemoryTypeMemoryMappedIo:\r
- if (Mmio32MinBase > Desc->BaseAddress) {\r
- Mmio32MinBase = Desc->BaseAddress;\r
- }\r
- if (Mmio32MaxExclTop < ExclTop) {\r
- Mmio32MaxExclTop = ExclTop;\r
- }\r
- break;\r
-\r
- default:\r
- ASSERT(0);\r
- }\r
- }\r
- }\r
-\r
- if (Mmio32MinBase < NonMmio32MaxExclTop) {\r
- Mmio32MinBase = NonMmio32MaxExclTop;\r
- }\r
-\r
- if (Mmio32MinBase < Mmio32MaxExclTop) {\r
- FwData->PciWindow32.Base = Mmio32MinBase;\r
- FwData->PciWindow32.End = Mmio32MaxExclTop - 1;\r
- FwData->PciWindow32.Length = Mmio32MaxExclTop - Mmio32MinBase;\r
-\r
- FwData->PciWindow64.Base = 0;\r
- FwData->PciWindow64.End = 0;\r
- FwData->PciWindow64.Length = 0;\r
-\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
- FreePool (AllDesc);\r
- }\r
-\r
- DEBUG ((\r
- DEBUG_INFO,\r
- "ACPI PciWindow32: Base=0x%08lx End=0x%08lx Length=0x%08lx\n",\r
- FwData->PciWindow32.Base,\r
- FwData->PciWindow32.End,\r
- FwData->PciWindow32.Length\r
- ));\r
- DEBUG ((\r
- DEBUG_INFO,\r
- "ACPI PciWindow64: Base=0x%08lx End=0x%08lx Length=0x%08lx\n",\r
- FwData->PciWindow64.Base,\r
- FwData->PciWindow64.End,\r
- FwData->PciWindow64.Length\r
- ));\r
-\r
- return Status;\r
-}\r
-\r
-\r
-STATIC\r
-VOID\r
-EFIAPI\r
-GetSuspendStates (\r
- UINTN *SuspendToRamSize,\r
- SYSTEM_STATE_PACKAGE *SuspendToRam,\r
- UINTN *SuspendToDiskSize,\r
- SYSTEM_STATE_PACKAGE *SuspendToDisk\r
- )\r
-{\r
- STATIC CONST SYSTEM_STATE_PACKAGE Template = {\r
- 0x08, // NameOp\r
- '\\', // RootChar\r
- { '_', 'S', 'x', '_' }, // NameChar[4]\r
- 0x12, // PackageOp\r
- 0x0A, // PkgLength\r
- 0x04, // NumElements\r
- { 0x0A, 0x00 }, // Pm1aCntSlpTyp\r
- { 0x0A, 0x00 }, // Pm1bCntSlpTyp -- we don't support it\r
- { // Reserved[2]\r
- { 0x0A, 0x00 },\r
- { 0x0A, 0x00 }\r
- }\r
- };\r
- RETURN_STATUS Status;\r
- FIRMWARE_CONFIG_ITEM FwCfgItem;\r
- UINTN FwCfgSize;\r
- UINT8 SystemStates[6];\r
-\r
- //\r
- // configure defaults\r
- //\r
- *SuspendToRamSize = sizeof Template;\r
- CopyMem (SuspendToRam, &Template, sizeof Template);\r
- SuspendToRam->NameChar[2] = '3'; // S3\r
- SuspendToRam->Pm1aCntSlpTyp.ByteValue = 1; // PIIX4: STR\r
-\r
- *SuspendToDiskSize = sizeof Template;\r
- CopyMem (SuspendToDisk, &Template, sizeof Template);\r
- SuspendToDisk->NameChar[2] = '4'; // S4\r
- SuspendToDisk->Pm1aCntSlpTyp.ByteValue = 2; // PIIX4: POSCL\r
-\r
- //\r
- // check for overrides\r
- //\r
- Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize);\r
- if (Status != RETURN_SUCCESS || FwCfgSize != sizeof SystemStates) {\r
- DEBUG ((DEBUG_INFO, "ACPI using S3/S4 defaults\n"));\r
- return;\r
- }\r
- QemuFwCfgSelectItem (FwCfgItem);\r
- QemuFwCfgReadBytes (sizeof SystemStates, SystemStates);\r
-\r
- //\r
- // Each byte corresponds to a system state. In each byte, the MSB tells us\r
- // whether the given state is enabled. If so, the three LSBs specify the\r
- // value to be written to the PM control register's SUS_TYP bits.\r
- //\r
- if (SystemStates[3] & BIT7) {\r
- SuspendToRam->Pm1aCntSlpTyp.ByteValue =\r
- SystemStates[3] & (BIT2 | BIT1 | BIT0);\r
- DEBUG ((DEBUG_INFO, "ACPI S3 value: %d\n",\r
- SuspendToRam->Pm1aCntSlpTyp.ByteValue));\r
- } else {\r
- *SuspendToRamSize = 0;\r
- DEBUG ((DEBUG_INFO, "ACPI S3 disabled\n"));\r
- }\r
-\r
- if (SystemStates[4] & BIT7) {\r
- SuspendToDisk->Pm1aCntSlpTyp.ByteValue =\r
- SystemStates[4] & (BIT2 | BIT1 | BIT0);\r
- DEBUG ((DEBUG_INFO, "ACPI S4 value: %d\n",\r
- SuspendToDisk->Pm1aCntSlpTyp.ByteValue));\r
- } else {\r
- *SuspendToDiskSize = 0;\r
- DEBUG ((DEBUG_INFO, "ACPI S4 disabled\n"));\r
- }\r
-}\r
-\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-QemuInstallAcpiSsdtTable (\r
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,\r
- IN VOID *AcpiTableBuffer,\r
- IN UINTN AcpiTableBufferSize,\r
- OUT UINTN *TableKey\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FIRMWARE_DATA *FwData;\r
-\r
- Status = EFI_OUT_OF_RESOURCES;\r
-\r
- FwData = AllocateReservedPool (sizeof (*FwData));\r
- if (FwData != NULL) {\r
- UINTN SuspendToRamSize;\r
- SYSTEM_STATE_PACKAGE SuspendToRam;\r
- UINTN SuspendToDiskSize;\r
- SYSTEM_STATE_PACKAGE SuspendToDisk;\r
- UINTN SsdtSize;\r
- UINT8 *Ssdt;\r
-\r
- GetSuspendStates (&SuspendToRamSize, &SuspendToRam,\r
- &SuspendToDiskSize, &SuspendToDisk);\r
- SsdtSize = AcpiTableBufferSize + 17 + SuspendToRamSize + SuspendToDiskSize;\r
- Ssdt = AllocatePool (SsdtSize);\r
-\r
- if (Ssdt != NULL) {\r
- Status = PopulateFwData (FwData);\r
-\r
- if (Status == EFI_SUCCESS) {\r
- UINT8 *SsdtPtr;\r
-\r
- SsdtPtr = Ssdt;\r
-\r
- CopyMem (SsdtPtr, AcpiTableBuffer, AcpiTableBufferSize);\r
- SsdtPtr += AcpiTableBufferSize;\r
-\r
- //\r
- // build "OperationRegion(FWDT, SystemMemory, 0x12345678, 0x87654321)"\r
- //\r
- *(SsdtPtr++) = 0x5B; // ExtOpPrefix\r
- *(SsdtPtr++) = 0x80; // OpRegionOp\r
- *(SsdtPtr++) = 'F';\r
- *(SsdtPtr++) = 'W';\r
- *(SsdtPtr++) = 'D';\r
- *(SsdtPtr++) = 'T';\r
- *(SsdtPtr++) = 0x00; // SystemMemory\r
- *(SsdtPtr++) = 0x0C; // DWordPrefix\r
-\r
- //\r
- // no virtual addressing yet, take the four least significant bytes\r
- //\r
- CopyMem(SsdtPtr, &FwData, 4);\r
- SsdtPtr += 4;\r
-\r
- *(SsdtPtr++) = 0x0C; // DWordPrefix\r
-\r
- *(UINT32*) SsdtPtr = sizeof (*FwData);\r
- SsdtPtr += 4;\r
-\r
- //\r
- // add suspend system states\r
- //\r
- CopyMem (SsdtPtr, &SuspendToRam, SuspendToRamSize);\r
- SsdtPtr += SuspendToRamSize;\r
- CopyMem (SsdtPtr, &SuspendToDisk, SuspendToDiskSize);\r
- SsdtPtr += SuspendToDiskSize;\r
-\r
- ASSERT((UINTN) (SsdtPtr - Ssdt) == SsdtSize);\r
- ((EFI_ACPI_DESCRIPTION_HEADER *) Ssdt)->Length = (UINT32) SsdtSize;\r
- Status = InstallAcpiTable (AcpiProtocol, Ssdt, SsdtSize, TableKey);\r
- }\r
-\r
- FreePool(Ssdt);\r
- }\r
-\r
- if (Status != EFI_SUCCESS) {\r
- FreePool(FwData);\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-QemuInstallAcpiTable (\r
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,\r
- IN VOID *AcpiTableBuffer,\r
- IN UINTN AcpiTableBufferSize,\r
- OUT UINTN *TableKey\r
- )\r
-{\r
- EFI_ACPI_DESCRIPTION_HEADER *Hdr;\r
- EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction;\r
-\r
- Hdr = (EFI_ACPI_DESCRIPTION_HEADER*) AcpiTableBuffer;\r
- switch (Hdr->Signature) {\r
- case EFI_ACPI_1_0_APIC_SIGNATURE:\r
- TableInstallFunction = QemuInstallAcpiMadtTable;\r
- break;\r
- case EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
- TableInstallFunction = QemuInstallAcpiSsdtTable;\r
- break;\r
- default:\r
- TableInstallFunction = InstallAcpiTable;\r
- }\r
-\r
- return TableInstallFunction (\r
- AcpiProtocol,\r
- AcpiTableBuffer,\r
- AcpiTableBufferSize,\r
- TableKey\r
- );\r
-}\r
+++ /dev/null
-/** @file\r
- OVMF ACPI Xen support\r
-\r
- Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
- Copyright (c) 2012, Bei Guan <gbtju85@gmail.com>\r
-\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <Library/BaseLib.h> // CpuDeadLoop()\r
-#include <Library/DebugLib.h> // DEBUG()\r
-#include <Library/XenPlatformLib.h> // XenGetInfoHOB()\r
-\r
-#include "AcpiPlatform.h"\r
-\r
-#define XEN_ACPI_PHYSICAL_ADDRESS 0x000EA020\r
-#define XEN_BIOS_PHYSICAL_END 0x000FFFFF\r
-\r
-EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *XenAcpiRsdpStructurePtr = NULL;\r
-\r
-/**\r
- Get the address of Xen ACPI Root System Description Pointer (RSDP)\r
- structure.\r
-\r
- @param RsdpStructurePtr Return pointer to RSDP structure\r
-\r
- @return EFI_SUCCESS Find Xen RSDP structure successfully.\r
- @return EFI_NOT_FOUND Don't find Xen RSDP structure.\r
- @return EFI_ABORTED Find Xen RSDP structure, but it's not integrated.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetXenAcpiRsdp (\r
- OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr\r
- )\r
-{\r
- EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;\r
- UINT8 *XenAcpiPtr;\r
- UINT8 Sum;\r
- EFI_XEN_INFO *XenInfo;\r
-\r
- //\r
- // Detect the RSDP structure\r
- //\r
-\r
- //\r
- // First look for PVH one\r
- //\r
- XenInfo = XenGetInfoHOB ();\r
- ASSERT (XenInfo != NULL);\r
- if (XenInfo->RsdpPvh != NULL) {\r
- DEBUG ((DEBUG_INFO, "%a: Use ACPI RSDP table at 0x%p\n",\r
- gEfiCallerBaseName, XenInfo->RsdpPvh));\r
- *RsdpPtr = XenInfo->RsdpPvh;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Otherwise, look for the HVM one\r
- //\r
- for (XenAcpiPtr = (UINT8*)(UINTN) XEN_ACPI_PHYSICAL_ADDRESS;\r
- XenAcpiPtr < (UINT8*)(UINTN) XEN_BIOS_PHYSICAL_END;\r
- XenAcpiPtr += 0x10) {\r
-\r
- RsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)\r
- (UINTN) XenAcpiPtr;\r
-\r
- if (!AsciiStrnCmp ((CHAR8 *) &RsdpStructurePtr->Signature, "RSD PTR ", 8)) {\r
- //\r
- // RSDP ACPI 1.0 checksum for 1.0/2.0/3.0 table.\r
- // This is only the first 20 bytes of the structure\r
- //\r
- Sum = CalculateSum8 (\r
- (CONST UINT8 *)RsdpStructurePtr,\r
- sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)\r
- );\r
- if (Sum != 0) {\r
- return EFI_ABORTED;\r
- }\r
-\r
- if (RsdpStructurePtr->Revision >= 2) {\r
- //\r
- // RSDP ACPI 2.0/3.0 checksum, this is the entire table\r
- //\r
- Sum = CalculateSum8 (\r
- (CONST UINT8 *)RsdpStructurePtr,\r
- sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)\r
- );\r
- if (Sum != 0) {\r
- return EFI_ABORTED;\r
- }\r
- }\r
- *RsdpPtr = RsdpStructurePtr;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables\r
- into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed\r
- ACPI tables are: FACP, APIC, HPET, WAET, SSDT, FACS, DSDT.\r
-\r
- @param AcpiProtocol Protocol instance pointer.\r
-\r
- @return EFI_SUCCESS The table was successfully inserted.\r
- @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is\r
- NULL, or AcpiTableBufferSize and the size\r
- field embedded in the ACPI table pointed to\r
- by AcpiTableBuffer are not in sync.\r
- @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InstallXenTables (\r
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN TableHandle;\r
-\r
- EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
- EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
- VOID *CurrentTableEntry;\r
- UINTN CurrentTablePointer;\r
- EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;\r
- UINTN Index;\r
- UINTN NumberOfTableEntries;\r
- EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table;\r
- EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt1Table;\r
- EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs2Table;\r
- EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs1Table;\r
- EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;\r
-\r
- Fadt2Table = NULL;\r
- Fadt1Table = NULL;\r
- Facs2Table = NULL;\r
- Facs1Table = NULL;\r
- DsdtTable = NULL;\r
- TableHandle = 0;\r
- NumberOfTableEntries = 0;\r
-\r
- //\r
- // Try to find Xen ACPI tables\r
- //\r
- Status = GetXenAcpiRsdp (&XenAcpiRsdpStructurePtr);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // If XSDT table is find, just install its tables.\r
- // Otherwise, try to find and install the RSDT tables.\r
- //\r
- if (XenAcpiRsdpStructurePtr->XsdtAddress) {\r
- //\r
- // Retrieve the addresses of XSDT and\r
- // calculate the number of its table entries.\r
- //\r
- Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)\r
- XenAcpiRsdpStructurePtr->XsdtAddress;\r
- NumberOfTableEntries = (Xsdt->Length -\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /\r
- sizeof (UINT64);\r
-\r
- //\r
- // Install ACPI tables found in XSDT.\r
- //\r
- for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
- //\r
- // Get the table entry from XSDT\r
- //\r
- CurrentTableEntry = (VOID *) ((UINT8 *) Xsdt +\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
- Index * sizeof (UINT64));\r
- CurrentTablePointer = (UINTN) *(UINT64 *)CurrentTableEntry;\r
- CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;\r
-\r
- //\r
- // Install the XSDT tables\r
- //\r
- Status = InstallAcpiTable (\r
- AcpiProtocol,\r
- CurrentTable,\r
- CurrentTable->Length,\r
- &TableHandle\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the FACS and DSDT table address from the table FADT\r
- //\r
- if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {\r
- Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)\r
- (UINTN) CurrentTablePointer;\r
- Facs2Table = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)\r
- (UINTN) Fadt2Table->FirmwareCtrl;\r
- DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Fadt2Table->Dsdt;\r
- }\r
- }\r
- }\r
- else if (XenAcpiRsdpStructurePtr->RsdtAddress) {\r
- //\r
- // Retrieve the addresses of RSDT and\r
- // calculate the number of its table entries.\r
- //\r
- Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)\r
- XenAcpiRsdpStructurePtr->RsdtAddress;\r
- NumberOfTableEntries = (Rsdt->Length -\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /\r
- sizeof (UINT32);\r
-\r
- //\r
- // Install ACPI tables found in XSDT.\r
- //\r
- for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
- //\r
- // Get the table entry from RSDT\r
- //\r
- CurrentTableEntry = (UINT32 *) ((UINT8 *) Rsdt +\r
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
- Index * sizeof (UINT32));\r
- CurrentTablePointer = *(UINT32 *)CurrentTableEntry;\r
- CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTablePointer;\r
-\r
- //\r
- // Install the RSDT tables\r
- //\r
- Status = InstallAcpiTable (\r
- AcpiProtocol,\r
- CurrentTable,\r
- CurrentTable->Length,\r
- &TableHandle\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Get the FACS and DSDT table address from the table FADT\r
- //\r
- if (!AsciiStrnCmp ((CHAR8 *) &CurrentTable->Signature, "FACP", 4)) {\r
- Fadt1Table = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *)\r
- (UINTN) CurrentTablePointer;\r
- Facs1Table = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)\r
- (UINTN) Fadt1Table->FirmwareCtrl;\r
- DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Fadt1Table->Dsdt;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Install the FACS table.\r
- //\r
- if (Fadt2Table) {\r
- //\r
- // FACS 2.0\r
- //\r
- Status = InstallAcpiTable (\r
- AcpiProtocol,\r
- Facs2Table,\r
- Facs2Table->Length,\r
- &TableHandle\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
- else if (Fadt1Table) {\r
- //\r
- // FACS 1.0\r
- //\r
- Status = InstallAcpiTable (\r
- AcpiProtocol,\r
- Facs1Table,\r
- Facs1Table->Length,\r
- &TableHandle\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Install DSDT table. If we reached this point without finding the DSDT,\r
- // then we're out of sync with the hypervisor, and cannot continue.\r
- //\r
- if (DsdtTable == NULL) {\r
- DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __FUNCTION__));\r
- ASSERT (FALSE);\r
- CpuDeadLoop ();\r
- }\r
-\r
- Status = InstallAcpiTable (\r
- AcpiProtocol,\r
- DsdtTable,\r
- DsdtTable->Length,\r
- &TableHandle\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r