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