2 OVMF ACPI Platform Driver for Xen guests
4 Copyright (C) 2021, Red Hat, Inc.
5 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/DebugLib.h> // ASSERT_EFI_ERROR()
11 #include <Library/UefiBootServicesTableLib.h> // gBS
12 #include <Library/XenPlatformLib.h> // XenDetected()
13 #include <Protocol/FirmwareVolume2.h> // gEfiFirmwareVolume2Protocol...
15 #include "AcpiPlatform.h"
18 Locate the first instance of a protocol. If the protocol requested is an
19 FV protocol, then it will return the first FV that contains the ACPI table
22 @param Instance Return pointer to the first instance of the protocol
24 @return EFI_SUCCESS The function completed successfully.
25 @return EFI_NOT_FOUND The protocol could not be located.
26 @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
30 LocateFvInstanceWithTables (
31 OUT EFI_FIRMWARE_VOLUME2_PROTOCOL
**Instance
35 EFI_HANDLE
*HandleBuffer
;
36 UINTN NumberOfHandles
;
37 EFI_FV_FILETYPE FileType
;
39 EFI_FV_FILE_ATTRIBUTES Attributes
;
42 EFI_FIRMWARE_VOLUME2_PROTOCOL
*FvInstance
;
49 Status
= gBS
->LocateHandleBuffer (
51 &gEfiFirmwareVolume2ProtocolGuid
,
56 if (EFI_ERROR (Status
)) {
58 // Defined errors at this time are not found and out of resources.
64 // Looking for FV with ACPI storage file
66 for (Index
= 0; Index
< NumberOfHandles
; Index
++) {
68 // Get the protocol on this handle
69 // This should not fail because of LocateHandleBuffer
71 Status
= gBS
->HandleProtocol (
73 &gEfiFirmwareVolume2ProtocolGuid
,
76 ASSERT_EFI_ERROR (Status
);
79 // See if it has the ACPI storage file
81 Status
= FvInstance
->ReadFile (
83 (EFI_GUID
*)PcdGetPtr (PcdAcpiTableStorageFile
),
92 // If we found it, then we are done
94 if (Status
== EFI_SUCCESS
) {
95 *Instance
= FvInstance
;
101 // Our exit status is determined by the success of the previous operations
102 // If the protocol was found, Instance already points to it.
106 // Free any allocated buffers
108 gBS
->FreePool (HandleBuffer
);
115 Find ACPI tables in an FV and install them.
117 This is now a fall-back path. Normally, we will search for tables provided
120 If that fails, we use this function to load the ACPI tables from an FV. The
121 sources for the FV based tables is located under OvmfPkg/AcpiTables.
123 @param AcpiTable Protocol instance pointer
128 InstallOvmfFvTables (
129 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
133 EFI_FIRMWARE_VOLUME2_PROTOCOL
*FwVol
;
135 EFI_ACPI_COMMON_HEADER
*CurrentTable
;
146 // set FwVol (and use an ASSERT() below) to suppress incorrect
147 // compiler/analyzer warnings
151 // Locate the firmware volume protocol
153 Status
= LocateFvInstanceWithTables (&FwVol
);
154 if (EFI_ERROR (Status
)) {
157 ASSERT (FwVol
!= NULL
);
160 // Read tables from the storage file.
162 while (Status
== EFI_SUCCESS
) {
164 Status
= FwVol
->ReadSection (
166 (EFI_GUID
*)PcdGetPtr (PcdAcpiTableStorageFile
),
169 (VOID
**) &CurrentTable
,
173 if (!EFI_ERROR (Status
)) {
179 TableSize
= ((EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTable
)->Length
;
180 ASSERT (Size
>= TableSize
);
183 // Install ACPI table
185 Status
= AcpiTable
->InstallAcpiTable (
193 // Free memory allocated by ReadSection
195 gBS
->FreePool (CurrentTable
);
197 if (EFI_ERROR (Status
)) {
202 // Increment the instance
213 Effective entrypoint of Acpi Platform driver.
219 @return EFI_LOAD_ERROR
220 @return EFI_OUT_OF_RESOURCES
226 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
231 if (XenDetected ()) {
232 Status
= InstallXenTables (AcpiTable
);
234 Status
= EFI_UNSUPPORTED
;
237 if (EFI_ERROR (Status
)) {
238 Status
= InstallOvmfFvTables (AcpiTable
);