]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/XenAcpiPlatformDxe/AcpiPlatform.c
OvmfPkg/XenAcpiPlatformDxe: remove the InstallAcpiTable() helper function
[mirror_edk2.git] / OvmfPkg / XenAcpiPlatformDxe / AcpiPlatform.c
1 /** @file
2 OVMF ACPI Platform Driver for Xen guests
3
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
7
8 **/
9
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...
14
15 #include "AcpiPlatform.h"
16
17 /**
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
20 storage file.
21
22 @param Instance Return pointer to the first instance of the protocol
23
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.
27
28 **/
29 EFI_STATUS
30 LocateFvInstanceWithTables (
31 OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance
32 )
33 {
34 EFI_STATUS Status;
35 EFI_HANDLE *HandleBuffer;
36 UINTN NumberOfHandles;
37 EFI_FV_FILETYPE FileType;
38 UINT32 FvStatus;
39 EFI_FV_FILE_ATTRIBUTES Attributes;
40 UINTN Size;
41 UINTN Index;
42 EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
43
44 FvStatus = 0;
45
46 //
47 // Locate protocol.
48 //
49 Status = gBS->LocateHandleBuffer (
50 ByProtocol,
51 &gEfiFirmwareVolume2ProtocolGuid,
52 NULL,
53 &NumberOfHandles,
54 &HandleBuffer
55 );
56 if (EFI_ERROR (Status)) {
57 //
58 // Defined errors at this time are not found and out of resources.
59 //
60 return Status;
61 }
62
63 //
64 // Looking for FV with ACPI storage file
65 //
66 for (Index = 0; Index < NumberOfHandles; Index++) {
67 //
68 // Get the protocol on this handle
69 // This should not fail because of LocateHandleBuffer
70 //
71 Status = gBS->HandleProtocol (
72 HandleBuffer[Index],
73 &gEfiFirmwareVolume2ProtocolGuid,
74 (VOID**) &FvInstance
75 );
76 ASSERT_EFI_ERROR (Status);
77
78 //
79 // See if it has the ACPI storage file
80 //
81 Status = FvInstance->ReadFile (
82 FvInstance,
83 (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
84 NULL,
85 &Size,
86 &FileType,
87 &Attributes,
88 &FvStatus
89 );
90
91 //
92 // If we found it, then we are done
93 //
94 if (Status == EFI_SUCCESS) {
95 *Instance = FvInstance;
96 break;
97 }
98 }
99
100 //
101 // Our exit status is determined by the success of the previous operations
102 // If the protocol was found, Instance already points to it.
103 //
104
105 //
106 // Free any allocated buffers
107 //
108 gBS->FreePool (HandleBuffer);
109
110 return Status;
111 }
112
113
114 /**
115 Find ACPI tables in an FV and install them.
116
117 This is now a fall-back path. Normally, we will search for tables provided
118 by the VMM first.
119
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.
122
123 @param AcpiTable Protocol instance pointer
124
125 **/
126 EFI_STATUS
127 EFIAPI
128 InstallOvmfFvTables (
129 IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable
130 )
131 {
132 EFI_STATUS Status;
133 EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
134 INTN Instance;
135 EFI_ACPI_COMMON_HEADER *CurrentTable;
136 UINTN TableHandle;
137 UINT32 FvStatus;
138 UINTN TableSize;
139 UINTN Size;
140
141 Instance = 0;
142 CurrentTable = NULL;
143 TableHandle = 0;
144
145 //
146 // set FwVol (and use an ASSERT() below) to suppress incorrect
147 // compiler/analyzer warnings
148 //
149 FwVol = NULL;
150 //
151 // Locate the firmware volume protocol
152 //
153 Status = LocateFvInstanceWithTables (&FwVol);
154 if (EFI_ERROR (Status)) {
155 return EFI_ABORTED;
156 }
157 ASSERT (FwVol != NULL);
158
159 //
160 // Read tables from the storage file.
161 //
162 while (Status == EFI_SUCCESS) {
163
164 Status = FwVol->ReadSection (
165 FwVol,
166 (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
167 EFI_SECTION_RAW,
168 Instance,
169 (VOID**) &CurrentTable,
170 &Size,
171 &FvStatus
172 );
173 if (!EFI_ERROR (Status)) {
174 //
175 // Add the table
176 //
177 TableHandle = 0;
178
179 TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
180 ASSERT (Size >= TableSize);
181
182 //
183 // Install ACPI table
184 //
185 Status = AcpiTable->InstallAcpiTable (
186 AcpiTable,
187 CurrentTable,
188 TableSize,
189 &TableHandle
190 );
191
192 //
193 // Free memory allocated by ReadSection
194 //
195 gBS->FreePool (CurrentTable);
196
197 if (EFI_ERROR (Status)) {
198 return EFI_ABORTED;
199 }
200
201 //
202 // Increment the instance
203 //
204 Instance++;
205 CurrentTable = NULL;
206 }
207 }
208
209 return EFI_SUCCESS;
210 }
211
212 /**
213 Effective entrypoint of Acpi Platform driver.
214
215 @param ImageHandle
216 @param SystemTable
217
218 @return EFI_SUCCESS
219 @return EFI_LOAD_ERROR
220 @return EFI_OUT_OF_RESOURCES
221
222 **/
223 EFI_STATUS
224 EFIAPI
225 InstallAcpiTables (
226 IN EFI_ACPI_TABLE_PROTOCOL *AcpiTable
227 )
228 {
229 EFI_STATUS Status;
230
231 if (XenDetected ()) {
232 Status = InstallXenTables (AcpiTable);
233 } else {
234 Status = EFI_UNSUPPORTED;
235 }
236
237 if (EFI_ERROR (Status)) {
238 Status = InstallOvmfFvTables (AcpiTable);
239 }
240
241 return Status;
242 }
243