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