]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c
OvmfPkg/AcpiPlatformDxe: Assert if AcpiTable protocol is not found
[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 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "AcpiPlatform.h"
16
17 EFI_STATUS
18 EFIAPI
19 InstallAcpiTable (
20 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
21 IN VOID *AcpiTableBuffer,
22 IN UINTN AcpiTableBufferSize,
23 OUT UINTN *TableKey
24 )
25 {
26 return AcpiProtocol->InstallAcpiTable (
27 AcpiProtocol,
28 AcpiTableBuffer,
29 AcpiTableBufferSize,
30 TableKey
31 );
32 }
33
34
35 /**
36 Locate the first instance of a protocol. If the protocol requested is an
37 FV protocol, then it will return the first FV that contains the ACPI table
38 storage file.
39
40 @param Instance Return pointer to the first instance of the protocol
41
42 @return EFI_SUCCESS The function completed successfully.
43 @return EFI_NOT_FOUND The protocol could not be located.
44 @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
45
46 **/
47 EFI_STATUS
48 LocateFvInstanceWithTables (
49 OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance
50 )
51 {
52 EFI_STATUS Status;
53 EFI_HANDLE *HandleBuffer;
54 UINTN NumberOfHandles;
55 EFI_FV_FILETYPE FileType;
56 UINT32 FvStatus;
57 EFI_FV_FILE_ATTRIBUTES Attributes;
58 UINTN Size;
59 UINTN Index;
60 EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
61
62 FvStatus = 0;
63
64 //
65 // Locate protocol.
66 //
67 Status = gBS->LocateHandleBuffer (
68 ByProtocol,
69 &gEfiFirmwareVolume2ProtocolGuid,
70 NULL,
71 &NumberOfHandles,
72 &HandleBuffer
73 );
74 if (EFI_ERROR (Status)) {
75 //
76 // Defined errors at this time are not found and out of resources.
77 //
78 return Status;
79 }
80
81 //
82 // Looking for FV with ACPI storage file
83 //
84 for (Index = 0; Index < NumberOfHandles; Index++) {
85 //
86 // Get the protocol on this handle
87 // This should not fail because of LocateHandleBuffer
88 //
89 Status = gBS->HandleProtocol (
90 HandleBuffer[Index],
91 &gEfiFirmwareVolume2ProtocolGuid,
92 (VOID**) &FvInstance
93 );
94 ASSERT_EFI_ERROR (Status);
95
96 //
97 // See if it has the ACPI storage file
98 //
99 Status = FvInstance->ReadFile (
100 FvInstance,
101 (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
102 NULL,
103 &Size,
104 &FileType,
105 &Attributes,
106 &FvStatus
107 );
108
109 //
110 // If we found it, then we are done
111 //
112 if (Status == EFI_SUCCESS) {
113 *Instance = FvInstance;
114 break;
115 }
116 }
117
118 //
119 // Our exit status is determined by the success of the previous operations
120 // If the protocol was found, Instance already points to it.
121 //
122
123 //
124 // Free any allocated buffers
125 //
126 gBS->FreePool (HandleBuffer);
127
128 return Status;
129 }
130
131
132 /**
133 Find ACPI tables in an FV and parses them. This function is useful for QEMU and KVM.
134
135 @param AcpiTable Protocol instance pointer
136
137 **/
138 EFI_STATUS
139 EFIAPI
140 FindAcpiTablesInFv (
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 // Locate the firmware volume protocol
166 //
167 Status = LocateFvInstanceWithTables (&FwVol);
168 if (EFI_ERROR (Status)) {
169 return EFI_ABORTED;
170 }
171 //
172 // Read tables from the storage file.
173 //
174 while (Status == EFI_SUCCESS) {
175
176 Status = FwVol->ReadSection (
177 FwVol,
178 (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
179 EFI_SECTION_RAW,
180 Instance,
181 (VOID**) &CurrentTable,
182 &Size,
183 &FvStatus
184 );
185 if (!EFI_ERROR (Status)) {
186 //
187 // Add the table
188 //
189 TableHandle = 0;
190
191 TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
192 ASSERT (Size >= TableSize);
193
194 //
195 // Install ACPI table
196 //
197 Status = TableInstallFunction (
198 AcpiTable,
199 CurrentTable,
200 TableSize,
201 &TableHandle
202 );
203
204 //
205 // Free memory allocated by ReadSection
206 //
207 gBS->FreePool (CurrentTable);
208
209 if (EFI_ERROR (Status)) {
210 return EFI_ABORTED;
211 }
212
213 //
214 // Increment the instance
215 //
216 Instance++;
217 CurrentTable = NULL;
218 }
219 }
220
221 return EFI_SUCCESS;
222 }
223
224 /**
225 Entrypoint of Acpi Platform driver.
226
227 @param ImageHandle
228 @param SystemTable
229
230 @return EFI_SUCCESS
231 @return EFI_LOAD_ERROR
232 @return EFI_OUT_OF_RESOURCES
233
234 **/
235 EFI_STATUS
236 EFIAPI
237 AcpiPlatformEntryPoint (
238 IN EFI_HANDLE ImageHandle,
239 IN EFI_SYSTEM_TABLE *SystemTable
240 )
241 {
242 EFI_STATUS Status;
243 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
244
245 //
246 // Find the AcpiTable protocol
247 //
248 Status = gBS->LocateProtocol (
249 &gEfiAcpiTableProtocolGuid,
250 NULL,
251 (VOID**)&AcpiTable
252 );
253 ASSERT_EFI_ERROR (Status);
254
255 if (XenDetected ()) {
256 Status = InstallXenTables (AcpiTable);
257 } else {
258 Status = InstallAllQemuLinkedTables (AcpiTable);
259 }
260
261 if (EFI_ERROR (Status)) {
262 Status = FindAcpiTablesInFv (AcpiTable);
263 }
264
265 return Status;
266 }
267