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