]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
Fixed the GCC build failure.
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / AcpiTableDxe / AcpiTableProtocol.c
CommitLineData
5f55c700 1/** @file\r
2 ACPI Table Protocol Implementation\r
3\r
5966402e 4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5 This program and the accompanying materials\r
5f55c700 6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15//\r
16// Includes\r
17//\r
18#include "AcpiTable.h"\r
da935a5c 19//\r
20// The maximum number of tables that pre-allocated. \r
21//\r
22UINTN mEfiAcpiMaxNumTables = EFI_ACPI_MAX_NUM_TABLES; \r
5f55c700 23\r
24/**\r
25 This function adds an ACPI table to the table list. It will detect FACS and\r
26 allocate the correct type of memory and properly align the table.\r
27\r
28 @param AcpiTableInstance Instance of the protocol.\r
29 @param Table Table to add.\r
30 @param Checksum Does the table require checksumming.\r
31 @param Version The version of the list to add the table to.\r
32 @param Handle Pointer for returning the handle.\r
33\r
34 @return EFI_SUCCESS The function completed successfully.\r
35 @return EFI_OUT_OF_RESOURCES Could not allocate a required resource.\r
36 @return EFI_ABORTED The table is a duplicate of a table that is required\r
37 to be unique.\r
38\r
39**/\r
40EFI_STATUS\r
41AddTableToList (\r
42 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,\r
43 IN VOID *Table,\r
44 IN BOOLEAN Checksum,\r
45 IN EFI_ACPI_TABLE_VERSION Version,\r
46 OUT UINTN *Handle\r
47 );\r
48\r
49/**\r
50 This function finds and removes the table specified by the handle.\r
51\r
52 @param AcpiTableInstance Instance of the protocol.\r
53 @param Version Bitmask of which versions to remove.\r
54 @param Handle Table to remove.\r
55\r
56 @return EFI_SUCCESS The function completed successfully.\r
57 @return EFI_ABORTED An error occurred.\r
58 @return EFI_NOT_FOUND Handle not found in table list.\r
59\r
60**/\r
61EFI_STATUS\r
62RemoveTableFromList (\r
63 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,\r
64 IN EFI_ACPI_TABLE_VERSION Version,\r
65 IN UINTN Handle\r
66 );\r
67\r
68/**\r
69 This function calculates and updates an UINT8 checksum.\r
70\r
71 @param Buffer Pointer to buffer to checksum\r
72 @param Size Number of bytes to checksum\r
73 @param ChecksumOffset Offset to place the checksum result in\r
74\r
75 @return EFI_SUCCESS The function completed successfully.\r
5f55c700 76**/\r
77EFI_STATUS\r
78AcpiPlatformChecksum (\r
79 IN VOID *Buffer,\r
80 IN UINTN Size,\r
81 IN UINTN ChecksumOffset\r
82 );\r
83\r
84/**\r
85 Checksum all versions of the common tables, RSDP, RSDT, XSDT.\r
86\r
87 @param AcpiTableInstance Protocol instance private data.\r
88\r
89 @return EFI_SUCCESS The function completed successfully.\r
90\r
91**/\r
92EFI_STATUS\r
93ChecksumCommonTables (\r
94 IN OUT EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance\r
95 );\r
96\r
97//\r
98// Protocol function implementations.\r
99//\r
100\r
5f55c700 101/**\r
102 This function publishes the specified versions of the ACPI tables by\r
103 installing EFI configuration table entries for them. Any combination of\r
104 table versions can be published.\r
105\r
106 @param AcpiTableInstance Instance of the protocol.\r
107 @param Version Version(s) to publish.\r
108\r
109 @return EFI_SUCCESS The function completed successfully.\r
110 @return EFI_ABORTED The function could not complete successfully.\r
111\r
112**/\r
113EFI_STATUS\r
114EFIAPI\r
115PublishTables (\r
116 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,\r
117 IN EFI_ACPI_TABLE_VERSION Version\r
118 )\r
119{\r
120 EFI_STATUS Status;\r
121 UINT32 *CurrentRsdtEntry;\r
122 VOID *CurrentXsdtEntry;\r
123 UINT64 Buffer64;\r
124\r
125 //\r
126 // Reorder tables as some operating systems don't seem to find the\r
127 // FADT correctly if it is not in the first few entries\r
128 //\r
129\r
130 //\r
131 // Add FADT as the first entry\r
132 //\r
133 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
134 CurrentRsdtEntry = (UINT32 *) ((UINT8 *) AcpiTableInstance->Rsdt1 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
135 *CurrentRsdtEntry = (UINT32) (UINTN) AcpiTableInstance->Fadt1;\r
136 }\r
137 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
138 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
139 CurrentRsdtEntry = (UINT32 *) ((UINT8 *) AcpiTableInstance->Rsdt3 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
140 *CurrentRsdtEntry = (UINT32) (UINTN) AcpiTableInstance->Fadt3;\r
141 CurrentXsdtEntry = (VOID *) ((UINT8 *) AcpiTableInstance->Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
142 //\r
143 // Add entry to XSDT, XSDT expects 64 bit pointers, but\r
144 // the table pointers in XSDT are not aligned on 8 byte boundary.\r
145 //\r
146 Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Fadt3;\r
147 CopyMem (\r
148 CurrentXsdtEntry,\r
149 &Buffer64,\r
150 sizeof (UINT64)\r
151 );\r
152 }\r
153\r
154 //\r
155 // Do checksum again because Dsdt/Xsdt is updated.\r
156 //\r
157 ChecksumCommonTables (AcpiTableInstance);\r
158\r
159 //\r
160 // Add the RSD_PTR to the system table and store that we have installed the\r
161 // tables.\r
162 //\r
163 if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) &&\r
164 !AcpiTableInstance->TablesInstalled1) {\r
165 Status = gBS->InstallConfigurationTable (&gEfiAcpi10TableGuid, AcpiTableInstance->Rsdp1);\r
166 if (EFI_ERROR (Status)) {\r
167 return EFI_ABORTED;\r
168 }\r
169\r
170 AcpiTableInstance->TablesInstalled1 = TRUE;\r
171 }\r
172\r
173 if (((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
174 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) &&\r
175 !AcpiTableInstance->TablesInstalled3) {\r
176 Status = gBS->InstallConfigurationTable (&gEfiAcpiTableGuid, AcpiTableInstance->Rsdp3);\r
177 if (EFI_ERROR (Status)) {\r
178 return EFI_ABORTED;\r
179 }\r
180\r
181 AcpiTableInstance->TablesInstalled3= TRUE;\r
182 }\r
183\r
184 return EFI_SUCCESS;\r
185}\r
186\r
187\r
188/**\r
189 Installs an ACPI table into the RSDT/XSDT.\r
2fd3009f 190 Note that the ACPI table should be checksumed before installing it.\r
191 Otherwise it will assert.\r
5f55c700 192\r
193 @param This Protocol instance pointer.\r
194 @param AcpiTableBuffer A pointer to a buffer containing the ACPI table to be installed.\r
195 @param AcpiTableBufferSize Specifies the size, in bytes, of the AcpiTableBuffer buffer.\r
196 @param TableKey Reurns a key to refer to the ACPI table.\r
197\r
198 @return EFI_SUCCESS The table was successfully inserted.\r
199 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize \r
200 and the size field embedded in the ACPI table pointed to by AcpiTableBuffer\r
201 are not in sync.\r
202 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.\r
5966402e
SZ
203 @retval EFI_ACCESS_DENIED The table signature matches a table already\r
204 present in the system and platform policy\r
205 does not allow duplicate tables of this type.\r
5f55c700 206\r
207**/\r
208EFI_STATUS\r
209EFIAPI\r
210InstallAcpiTable (\r
db0f0d3c 211 IN EFI_ACPI_TABLE_PROTOCOL *This,\r
212 IN VOID *AcpiTableBuffer,\r
213 IN UINTN AcpiTableBufferSize,\r
214 OUT UINTN *TableKey\r
5f55c700 215 )\r
216{\r
217 EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;\r
218 EFI_STATUS Status;\r
219 VOID *AcpiTableBufferConst;\r
220\r
221 //\r
222 // Check for invalid input parameters\r
223 //\r
224 if ((AcpiTableBuffer == NULL) || (TableKey == NULL)\r
225 || (((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTableBuffer)->Length != AcpiTableBufferSize)) {\r
226 return EFI_INVALID_PARAMETER;\r
227 }\r
228\r
229 //\r
230 // Get the instance of the ACPI table protocol\r
231 //\r
232 AcpiTableInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This);\r
233\r
234 //\r
235 // Install the ACPI table\r
236 //\r
237 AcpiTableBufferConst = AllocateCopyPool (AcpiTableBufferSize,AcpiTableBuffer);\r
238 *TableKey = 0;\r
5966402e 239 Status = AddTableToList (\r
5f55c700 240 AcpiTableInstance,\r
241 AcpiTableBufferConst,\r
71824dd8 242 TRUE,\r
46a989f7 243 EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0,\r
5f55c700 244 TableKey\r
245 );\r
246 if (!EFI_ERROR (Status)) {\r
247 Status = PublishTables (\r
248 AcpiTableInstance,\r
46a989f7 249 EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0\r
5f55c700 250 );\r
251 }\r
252 FreePool (AcpiTableBufferConst);\r
253 \r
3dc8585e
JY
254 //\r
255 // Add a new table successfully, notify registed callback\r
256 //\r
257 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {\r
258 if (!EFI_ERROR (Status)) {\r
259 SdtNotifyAcpiList (\r
260 AcpiTableInstance,\r
261 EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0,\r
262 *TableKey\r
263 );\r
264 }\r
265 }\r
266\r
5f55c700 267 return Status;\r
268}\r
269\r
270\r
271/**\r
272 Removes an ACPI table from the RSDT/XSDT.\r
273\r
274 @param This Protocol instance pointer.\r
275 @param TableKey Specifies the table to uninstall. The key was returned from InstallAcpiTable().\r
276\r
277 @return EFI_SUCCESS The table was successfully uninstalled.\r
278 @return EFI_NOT_FOUND TableKey does not refer to a valid key for a table entry.\r
279\r
280**/\r
281EFI_STATUS\r
282EFIAPI\r
283UninstallAcpiTable (\r
db0f0d3c 284 IN EFI_ACPI_TABLE_PROTOCOL *This,\r
285 IN UINTN TableKey\r
5f55c700 286 )\r
287{\r
288 EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;\r
289 EFI_STATUS Status;\r
290\r
291 //\r
292 // Get the instance of the ACPI table protocol\r
293 //\r
294 AcpiTableInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This);\r
295\r
296 //\r
297 // Uninstall the ACPI table\r
298 //\r
5966402e 299 Status = RemoveTableFromList (\r
5f55c700 300 AcpiTableInstance,\r
46a989f7 301 EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0,\r
5966402e 302 TableKey\r
5f55c700 303 );\r
304 if (!EFI_ERROR (Status)) {\r
305 Status = PublishTables (\r
306 AcpiTableInstance,\r
46a989f7 307 EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0\r
5f55c700 308 );\r
309 }\r
310\r
311 if (EFI_ERROR (Status)) {\r
312 return EFI_NOT_FOUND;\r
313 } else {\r
314 return EFI_SUCCESS;\r
315 }\r
316}\r
317\r
da935a5c 318/**\r
319 If the number of APCI tables exceeds the preallocated max table number, enlarge the table buffer.\r
320\r
321 @param AcpiTableInstance ACPI table protocol instance data structure.\r
322\r
323 @return EFI_SUCCESS reallocate the table beffer successfully.\r
324 @return EFI_OUT_OF_RESOURCES Unable to allocate required resources.\r
325\r
326**/\r
327EFI_STATUS\r
328ReallocateAcpiTableBuffer (\r
329 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance\r
330 )\r
331{\r
332 UINTN NewMaxTableNumber;\r
333 UINTN TotalSize;\r
334 UINT8 *Pointer;\r
335 EFI_PHYSICAL_ADDRESS PageAddress;\r
336 EFI_ACPI_TABLE_INSTANCE TempPrivateData;\r
337 EFI_STATUS Status;\r
338 UINT64 CurrentData;\r
339 \r
340 CopyMem (&TempPrivateData, AcpiTableInstance, sizeof (EFI_ACPI_TABLE_INSTANCE)); \r
341 //\r
342 // Enlarge the max table number from mEfiAcpiMaxNumTables to mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES\r
343 //\r
344 NewMaxTableNumber = mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES;\r
345 //\r
37abfb7e 346 // Create RSDT, XSDT structures and allocate buffers.\r
da935a5c 347 //\r
37abfb7e
LG
348 TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT\r
349 NewMaxTableNumber * sizeof (UINT32) +\r
350 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT\r
351 NewMaxTableNumber * sizeof (UINT32) +\r
352 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT\r
353 NewMaxTableNumber * sizeof (UINT64);\r
da935a5c 354\r
355 //\r
356 // Allocate memory in the lower 32 bit of address range for\r
357 // compatibility with ACPI 1.0 OS.\r
358 //\r
359 // This is done because ACPI 1.0 pointers are 32 bit values.\r
360 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.\r
361 // There is no architectural reason these should be below 4GB, it is purely\r
362 // for convenience of implementation that we force memory below 4GB.\r
363 //\r
364 PageAddress = 0xFFFFFFFF;\r
365 Status = gBS->AllocatePages (\r
366 AllocateMaxAddress,\r
367 EfiACPIReclaimMemory,\r
368 EFI_SIZE_TO_PAGES (TotalSize),\r
369 &PageAddress\r
370 );\r
371\r
372 if (EFI_ERROR (Status)) {\r
373 return EFI_OUT_OF_RESOURCES;\r
374 }\r
375\r
376 Pointer = (UINT8 *) (UINTN) PageAddress;\r
377 ZeroMem (Pointer, TotalSize);\r
378 \r
da935a5c 379 AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
380 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));\r
381 AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
382 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));\r
da935a5c 383 AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
5f55c700 384\r
da935a5c 385 //\r
37abfb7e 386 // Update RSDP to point to the new Rsdt and Xsdt address.\r
da935a5c 387 //\r
da935a5c 388 AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt1;\r
da935a5c 389 AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;\r
390 CurrentData = (UINT64) (UINTN) AcpiTableInstance->Xsdt;\r
391 CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));\r
392\r
393 //\r
394 // copy the original Rsdt1, Rsdt3 and Xsdt structure to new buffer \r
395 //\r
396 CopyMem (AcpiTableInstance->Rsdt1, TempPrivateData.Rsdt1, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32))); \r
397 CopyMem (AcpiTableInstance->Rsdt3, TempPrivateData.Rsdt3, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32))); \r
398 CopyMem (AcpiTableInstance->Xsdt, TempPrivateData.Xsdt, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT64)));\r
399 \r
400 //\r
401 // Calculate orignal ACPI table buffer size\r
402 //\r
37abfb7e
LG
403 TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT\r
404 mEfiAcpiMaxNumTables * sizeof (UINT32) +\r
405 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT\r
406 mEfiAcpiMaxNumTables * sizeof (UINT32) +\r
407 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT\r
408 mEfiAcpiMaxNumTables * sizeof (UINT64);\r
409 gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)TempPrivateData.Rsdt1, EFI_SIZE_TO_PAGES (TotalSize));\r
da935a5c 410 \r
411 //\r
412 // Update the Max ACPI table number\r
413 // \r
414 mEfiAcpiMaxNumTables = NewMaxTableNumber;\r
415 return EFI_SUCCESS;\r
416}\r
5f55c700 417/**\r
418 This function adds an ACPI table to the table list. It will detect FACS and\r
419 allocate the correct type of memory and properly align the table.\r
420\r
421 @param AcpiTableInstance Instance of the protocol.\r
422 @param Table Table to add.\r
423 @param Checksum Does the table require checksumming.\r
424 @param Version The version of the list to add the table to.\r
425 @param Handle Pointer for returning the handle.\r
426\r
427 @return EFI_SUCCESS The function completed successfully.\r
428 @return EFI_OUT_OF_RESOURCES Could not allocate a required resource.\r
5966402e
SZ
429 @retval EFI_ACCESS_DENIED The table signature matches a table already\r
430 present in the system and platform policy\r
431 does not allow duplicate tables of this type.\r
5f55c700 432\r
433**/\r
434EFI_STATUS\r
435AddTableToList (\r
436 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,\r
437 IN VOID *Table,\r
438 IN BOOLEAN Checksum,\r
439 IN EFI_ACPI_TABLE_VERSION Version,\r
440 OUT UINTN *Handle\r
441 )\r
442{\r
443 EFI_STATUS Status;\r
444 EFI_ACPI_TABLE_LIST *CurrentTableList;\r
445 UINT32 CurrentTableSignature;\r
446 UINT32 CurrentTableSize;\r
447 UINT32 *CurrentRsdtEntry;\r
448 VOID *CurrentXsdtEntry;\r
449 UINT64 Buffer64;\r
450 BOOLEAN AddToRsdt;\r
451\r
452 //\r
453 // Check for invalid input parameters\r
454 //\r
455 ASSERT (AcpiTableInstance);\r
456 ASSERT (Table);\r
457 ASSERT (Handle);\r
458\r
459 //\r
460 // Init locals\r
461 //\r
462 AddToRsdt = TRUE;\r
463\r
464 //\r
465 // Create a new list entry\r
466 //\r
467 CurrentTableList = AllocatePool (sizeof (EFI_ACPI_TABLE_LIST));\r
468 ASSERT (CurrentTableList);\r
469\r
470 //\r
471 // Determine table type and size\r
472 //\r
473 CurrentTableSignature = ((EFI_ACPI_COMMON_HEADER *) Table)->Signature;\r
474 CurrentTableSize = ((EFI_ACPI_COMMON_HEADER *) Table)->Length;\r
475\r
476 //\r
477 // Allocate a buffer for the table. All tables are allocated in the lower 32 bits of address space\r
478 // for backwards compatibility with ACPI 1.0 OS.\r
479 //\r
480 // This is done because ACPI 1.0 pointers are 32 bit values.\r
481 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.\r
482 // There is no architectural reason these should be below 4GB, it is purely\r
483 // for convenience of implementation that we force memory below 4GB.\r
484 //\r
485 CurrentTableList->PageAddress = 0xFFFFFFFF;\r
486 CurrentTableList->NumberOfPages = EFI_SIZE_TO_PAGES (CurrentTableSize);\r
487\r
488 //\r
489 // Allocation memory type depends on the type of the table\r
490 //\r
36d58153
JY
491 if ((CurrentTableSignature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) || \r
492 (CurrentTableSignature == EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE)) {\r
5f55c700 493 //\r
494 // Allocate memory for the FACS. This structure must be aligned\r
495 // on a 64 byte boundary and must be ACPI NVS memory.\r
496 // Using AllocatePages should ensure that it is always aligned.\r
36d58153
JY
497 // Do not change signature for new ACPI version because they are same.\r
498 //\r
499 // UEFI table also need to be in ACPI NVS memory, because some data field\r
500 // could be updated by OS present agent. For example, BufferPtrAddress in\r
501 // SMM communication ACPI table.\r
5f55c700 502 //\r
503 ASSERT ((EFI_PAGE_SIZE % 64) == 0);\r
504 Status = gBS->AllocatePages (\r
505 AllocateMaxAddress,\r
506 EfiACPIMemoryNVS,\r
507 CurrentTableList->NumberOfPages,\r
508 &CurrentTableList->PageAddress\r
509 );\r
510 } else {\r
511 //\r
512 // All other tables are ACPI reclaim memory, no alignment requirements.\r
513 //\r
514 Status = gBS->AllocatePages (\r
515 AllocateMaxAddress,\r
516 EfiACPIReclaimMemory,\r
517 CurrentTableList->NumberOfPages,\r
518 &CurrentTableList->PageAddress\r
519 );\r
520 }\r
521 //\r
522 // Check return value from memory alloc.\r
523 //\r
524 if (EFI_ERROR (Status)) {\r
525 gBS->FreePool (CurrentTableList);\r
526 return EFI_OUT_OF_RESOURCES;\r
527 }\r
528 //\r
529 // Update the table pointer with the allocated memory start\r
530 //\r
531 CurrentTableList->Table = (EFI_ACPI_COMMON_HEADER *) (UINTN) CurrentTableList->PageAddress;\r
532\r
533 //\r
534 // Initialize the table contents\r
535 //\r
536 CurrentTableList->Signature = EFI_ACPI_TABLE_LIST_SIGNATURE;\r
537 CopyMem (CurrentTableList->Table, Table, CurrentTableSize);\r
538 CurrentTableList->Handle = AcpiTableInstance->CurrentHandle++;\r
539 *Handle = CurrentTableList->Handle;\r
540 CurrentTableList->Version = Version;\r
541\r
542 //\r
543 // Update internal pointers if this is a required table. If it is a required\r
544 // table and a table of that type already exists, return an error.\r
545 //\r
546 // Calculate the checksum if the table is not FACS.\r
547 //\r
548 switch (CurrentTableSignature) {\r
549\r
550 case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:\r
551 //\r
552 // We don't add the FADT in the standard way because some\r
553 // OS expect the FADT to be early in the table list.\r
554 // So we always add it as the first element in the list.\r
555 //\r
556 AddToRsdt = FALSE;\r
557\r
558 //\r
559 // Check that the table has not been previously added.\r
560 //\r
561 if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Fadt1 != NULL) ||\r
562 ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 && AcpiTableInstance->Fadt3 != NULL) ||\r
563 ((Version & EFI_ACPI_TABLE_VERSION_3_0) != 0 && AcpiTableInstance->Fadt3 != NULL)\r
564 ) {\r
565 gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
566 gBS->FreePool (CurrentTableList);\r
5966402e 567 return EFI_ACCESS_DENIED;\r
5f55c700 568 }\r
569 //\r
570 // Add the table to the appropriate table version\r
571 //\r
572 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
573 //\r
574 // Save a pointer to the table\r
575 //\r
576 AcpiTableInstance->Fadt1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *) CurrentTableList->Table;\r
577\r
578 //\r
579 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.\r
580 //\r
581 AcpiTableInstance->Fadt1->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs1;\r
582 AcpiTableInstance->Fadt1->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt1;\r
583\r
584 //\r
585 // RSDP OEM information is updated to match the FADT OEM information\r
586 //\r
587 CopyMem (\r
588 &AcpiTableInstance->Rsdp1->OemId,\r
589 &AcpiTableInstance->Fadt1->Header.OemId,\r
590 6\r
591 );\r
592\r
593 //\r
594 // RSDT OEM information is updated to match the FADT OEM information.\r
595 //\r
596 CopyMem (\r
597 &AcpiTableInstance->Rsdt1->OemId,\r
598 &AcpiTableInstance->Fadt1->Header.OemId,\r
599 6\r
600 );\r
601\r
602 CopyMem (\r
603 &AcpiTableInstance->Rsdt1->OemTableId,\r
604 &AcpiTableInstance->Fadt1->Header.OemTableId,\r
605 sizeof (UINT64)\r
606 );\r
607 AcpiTableInstance->Rsdt1->OemRevision = AcpiTableInstance->Fadt1->Header.OemRevision;\r
608 }\r
609\r
610 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
611 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
612 //\r
613 // Save a pointer to the table\r
614 //\r
615 AcpiTableInstance->Fadt3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) CurrentTableList->Table;\r
616\r
617 //\r
618 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.\r
c93776c2
JY
619 // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and \r
620 // vice-versa.\r
5f55c700 621 //\r
10342a64 622 if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {\r
c93776c2
JY
623 AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs3;\r
624 } else {\r
625 Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;\r
626 CopyMem (\r
627 &AcpiTableInstance->Fadt3->XFirmwareCtrl,\r
628 &Buffer64,\r
629 sizeof (UINT64)\r
630 );\r
631 }\r
f0c855b2 632 AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\r
633 Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
634 CopyMem (\r
635 &AcpiTableInstance->Fadt3->XDsdt,\r
636 &Buffer64,\r
637 sizeof (UINT64)\r
638 );\r
5f55c700 639\r
f0c855b2 640 //\r
641 // RSDP OEM information is updated to match the FADT OEM information\r
642 //\r
643 CopyMem (\r
644 &AcpiTableInstance->Rsdp3->OemId,\r
645 &AcpiTableInstance->Fadt3->Header.OemId,\r
646 6\r
647 );\r
648 \r
649 //\r
650 // RSDT OEM information is updated to match FADT OEM information.\r
651 //\r
652 CopyMem (\r
653 &AcpiTableInstance->Rsdt3->OemId,\r
654 &AcpiTableInstance->Fadt3->Header.OemId,\r
655 6\r
656 );\r
657 CopyMem (\r
658 &AcpiTableInstance->Rsdt3->OemTableId,\r
659 &AcpiTableInstance->Fadt3->Header.OemTableId,\r
660 sizeof (UINT64)\r
661 );\r
662 AcpiTableInstance->Rsdt3->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;\r
663 \r
664 //\r
665 // XSDT OEM information is updated to match FADT OEM information.\r
666 //\r
667 CopyMem (\r
668 &AcpiTableInstance->Xsdt->OemId,\r
669 &AcpiTableInstance->Fadt3->Header.OemId,\r
670 6\r
671 );\r
672 CopyMem (\r
673 &AcpiTableInstance->Xsdt->OemTableId,\r
674 &AcpiTableInstance->Fadt3->Header.OemTableId,\r
675 sizeof (UINT64)\r
676 );\r
677 AcpiTableInstance->Xsdt->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;\r
5f55c700 678 } \r
679 //\r
680 // Checksum the table\r
681 //\r
682 if (Checksum) {\r
683 AcpiPlatformChecksum (\r
684 CurrentTableList->Table,\r
685 CurrentTableList->Table->Length,\r
686 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
687 Checksum)\r
688 );\r
689 }\r
690 break;\r
691\r
692 case EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:\r
693 //\r
694 // Check that the table has not been previously added.\r
695 //\r
696 if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Facs1 != NULL) ||\r
697 ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 && AcpiTableInstance->Facs3 != NULL) ||\r
698 ((Version & EFI_ACPI_TABLE_VERSION_3_0) != 0 && AcpiTableInstance->Facs3 != NULL)\r
699 ) {\r
700 gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
701 gBS->FreePool (CurrentTableList);\r
5966402e 702 return EFI_ACCESS_DENIED;\r
5f55c700 703 }\r
704 //\r
705 // FACS is referenced by FADT and is not part of RSDT\r
706 //\r
707 AddToRsdt = FALSE;\r
708\r
709 //\r
710 // Add the table to the appropriate table version\r
711 //\r
712 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
713 //\r
714 // Save a pointer to the table\r
715 //\r
716 AcpiTableInstance->Facs1 = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) CurrentTableList->Table;\r
717\r
718 //\r
719 // If FADT already exists, update table pointers.\r
720 //\r
721 if (AcpiTableInstance->Fadt1 != NULL) {\r
722 AcpiTableInstance->Fadt1->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs1;\r
723\r
724 //\r
725 // Checksum FADT table\r
726 //\r
727 AcpiPlatformChecksum (\r
728 AcpiTableInstance->Fadt1,\r
729 AcpiTableInstance->Fadt1->Header.Length,\r
730 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
731 Checksum)\r
732 );\r
733 }\r
734 }\r
735\r
736 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
737 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
738 //\r
739 // Save a pointer to the table\r
740 //\r
741 AcpiTableInstance->Facs3 = (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) CurrentTableList->Table;\r
742\r
743 //\r
744 // If FADT already exists, update table pointers.\r
745 //\r
746 if (AcpiTableInstance->Fadt3 != NULL) {\r
c93776c2
JY
747 //\r
748 // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and \r
749 // vice-versa.\r
750 //\r
10342a64 751 if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {\r
c93776c2
JY
752 AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs3;\r
753 } else {\r
754 Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;\r
755 CopyMem (\r
756 &AcpiTableInstance->Fadt3->XFirmwareCtrl,\r
757 &Buffer64,\r
758 sizeof (UINT64)\r
759 );\r
760 }\r
5f55c700 761\r
762 //\r
763 // Checksum FADT table\r
764 //\r
765 AcpiPlatformChecksum (\r
766 AcpiTableInstance->Fadt3,\r
767 AcpiTableInstance->Fadt3->Header.Length,\r
768 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
769 Checksum)\r
770 );\r
771 }\r
772 }\r
773\r
774 break;\r
775\r
776 case EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
777 //\r
778 // Check that the table has not been previously added.\r
779 //\r
780 if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Dsdt1 != NULL) ||\r
781 ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 && AcpiTableInstance->Dsdt3 != NULL) ||\r
782 ((Version & EFI_ACPI_TABLE_VERSION_3_0) != 0 && AcpiTableInstance->Dsdt3 != NULL)\r
783 ) {\r
784 gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
785 gBS->FreePool (CurrentTableList);\r
5966402e 786 return EFI_ACCESS_DENIED;\r
5f55c700 787 }\r
788 //\r
789 // DSDT is referenced by FADT and is not part of RSDT\r
790 //\r
791 AddToRsdt = FALSE;\r
792\r
793 //\r
794 // Add the table to the appropriate table version\r
795 //\r
796 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
797 //\r
798 // Save a pointer to the table\r
799 //\r
800 AcpiTableInstance->Dsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTableList->Table;\r
801\r
802 //\r
803 // If FADT already exists, update table pointers.\r
804 //\r
805 if (AcpiTableInstance->Fadt1 != NULL) {\r
806 AcpiTableInstance->Fadt1->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt1;\r
807\r
808 //\r
809 // Checksum FADT table\r
810 //\r
811 AcpiPlatformChecksum (\r
812 AcpiTableInstance->Fadt1,\r
813 AcpiTableInstance->Fadt1->Header.Length,\r
814 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
815 Checksum)\r
816 );\r
817 }\r
818 }\r
819 \r
820 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
821 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
822 //\r
823 // Save a pointer to the table\r
824 //\r
825 AcpiTableInstance->Dsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTableList->Table;\r
826\r
827 //\r
828 // If FADT already exists, update table pointers.\r
829 //\r
830 if (AcpiTableInstance->Fadt3 != NULL) {\r
831 AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;\r
832 Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;\r
833 CopyMem (\r
834 &AcpiTableInstance->Fadt3->XDsdt,\r
835 &Buffer64,\r
836 sizeof (UINT64)\r
837 );\r
838\r
839 //\r
840 // Checksum FADT table\r
841 //\r
842 AcpiPlatformChecksum (\r
843 AcpiTableInstance->Fadt3,\r
844 AcpiTableInstance->Fadt3->Header.Length,\r
845 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
846 Checksum)\r
847 );\r
848 }\r
849 } \r
850 //\r
851 // Checksum the table\r
852 //\r
853 if (Checksum) {\r
854 AcpiPlatformChecksum (\r
855 CurrentTableList->Table,\r
856 CurrentTableList->Table->Length,\r
857 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
858 Checksum)\r
859 );\r
860 }\r
861 break;\r
862\r
863 default:\r
864 //\r
865 // Checksum the table\r
866 //\r
867 if (Checksum) {\r
868 AcpiPlatformChecksum (\r
869 CurrentTableList->Table,\r
870 CurrentTableList->Table->Length,\r
871 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
872 Checksum)\r
873 );\r
874 }\r
875 break;\r
876 }\r
877 //\r
878 // Add the table to the current list of tables\r
879 //\r
880 InsertTailList (&AcpiTableInstance->TableList, &CurrentTableList->Link);\r
881\r
882 //\r
883 // Add the table to RSDT and/or XSDT table entry lists.\r
884 //\r
885 //\r
886 // Add to ACPI 1.0b table tree\r
887 //\r
888 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
5f55c700 889 if (AddToRsdt) {\r
890 //\r
da935a5c 891 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer\r
5f55c700 892 //\r
da935a5c 893 if (AcpiTableInstance->NumberOfTableEntries1 >= mEfiAcpiMaxNumTables) {\r
894 Status = ReallocateAcpiTableBuffer (AcpiTableInstance);\r
895 ASSERT_EFI_ERROR (Status);\r
896 }\r
5f55c700 897 CurrentRsdtEntry = (UINT32 *)\r
898 (\r
da935a5c 899 (UINT8 *) AcpiTableInstance->Rsdt1 +\r
5f55c700 900 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
da935a5c 901 AcpiTableInstance->NumberOfTableEntries1 *\r
5f55c700 902 sizeof (UINT32)\r
903 );\r
904\r
905 //\r
da935a5c 906 // Add entry to the RSDT unless its the FACS or DSDT\r
5f55c700 907 //\r
908 *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;\r
909\r
910 //\r
911 // Update RSDT length\r
912 //\r
da935a5c 913 AcpiTableInstance->Rsdt1->Length = AcpiTableInstance->Rsdt1->Length + sizeof (UINT32);\r
5f55c700 914\r
da935a5c 915 AcpiTableInstance->NumberOfTableEntries1++;\r
916 }\r
917 }\r
918 //\r
919 // Add to ACPI 2.0/3.0 table tree\r
920 //\r
921 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
922 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
923 if (AddToRsdt) {\r
924 //\r
925 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer\r
926 //\r
927 if (AcpiTableInstance->NumberOfTableEntries3 >= mEfiAcpiMaxNumTables) {\r
928 Status = ReallocateAcpiTableBuffer (AcpiTableInstance);\r
929 ASSERT_EFI_ERROR (Status);\r
930 }\r
931 //\r
932 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.\r
933 // If it becomes necessary to maintain separate table lists, changes will be required.\r
934 //\r
935 CurrentRsdtEntry = (UINT32 *)\r
936 (\r
937 (UINT8 *) AcpiTableInstance->Rsdt3 +\r
938 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
939 AcpiTableInstance->NumberOfTableEntries3 *\r
940 sizeof (UINT32)\r
941 );\r
942\r
943 //\r
944 // This pointer must not be directly dereferenced as the XSDT entries may not\r
945 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.\r
946 //\r
947 CurrentXsdtEntry = (VOID *)\r
948 (\r
949 (UINT8 *) AcpiTableInstance->Xsdt +\r
950 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +\r
951 AcpiTableInstance->NumberOfTableEntries3 *\r
952 sizeof (UINT64)\r
953 );\r
954\r
955 //\r
956 // Add entry to the RSDT\r
957 //\r
958 *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;\r
959\r
960 //\r
961 // Update RSDT length\r
962 //\r
963 AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);\r
964\r
965 //\r
966 // Add entry to XSDT, XSDT expects 64 bit pointers, but\r
967 // the table pointers in XSDT are not aligned on 8 byte boundary.\r
968 //\r
969 Buffer64 = (UINT64) (UINTN) CurrentTableList->Table;\r
970 CopyMem (\r
971 CurrentXsdtEntry,\r
972 &Buffer64,\r
973 sizeof (UINT64)\r
974 );\r
975\r
976 //\r
977 // Update length\r
978 //\r
979 AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof (UINT64);\r
980\r
981 AcpiTableInstance->NumberOfTableEntries3++;\r
5f55c700 982 }\r
5f55c700 983 }\r
984\r
985 ChecksumCommonTables (AcpiTableInstance);\r
986 return EFI_SUCCESS;\r
987}\r
988\r
989\r
990/**\r
991 This function finds the table specified by the handle and returns a pointer to it.\r
992 If the handle is not found, EFI_NOT_FOUND is returned and the contents of Table are\r
993 undefined.\r
994\r
995 @param Handle Table to find.\r
996 @param TableList Table list to search\r
997 @param Table Pointer to table found. \r
998\r
999 @return EFI_SUCCESS The function completed successfully.\r
1000 @return EFI_NOT_FOUND No table found matching the handle specified.\r
1001\r
1002**/\r
1003EFI_STATUS\r
1004FindTableByHandle (\r
1005 IN UINTN Handle,\r
1006 IN LIST_ENTRY *TableList,\r
1007 OUT EFI_ACPI_TABLE_LIST **Table\r
1008 )\r
1009{\r
1010 LIST_ENTRY *CurrentLink;\r
1011 EFI_ACPI_TABLE_LIST *CurrentTable;\r
1012\r
1013 //\r
1014 // Check for invalid input parameters\r
1015 //\r
1016 ASSERT (Table);\r
1017\r
1018 //\r
1019 // Find the table\r
1020 //\r
1021 CurrentLink = TableList->ForwardLink;\r
1022\r
1023 while (CurrentLink != TableList) {\r
1024 CurrentTable = EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink);\r
1025 if (CurrentTable->Handle == Handle) {\r
1026 //\r
1027 // Found handle, so return this table.\r
1028 //\r
1029 *Table = CurrentTable;\r
1030 return EFI_SUCCESS;\r
1031 }\r
1032\r
1033 CurrentLink = CurrentLink->ForwardLink;\r
1034 }\r
1035 //\r
1036 // Table not found\r
1037 //\r
1038 return EFI_NOT_FOUND;\r
1039}\r
1040\r
1041\r
1042/**\r
1043 This function removes a basic table from the RSDT and/or XSDT.\r
1044 For Acpi 1.0 tables, pass in the Rsdt.\r
1045 For Acpi 2.0 tables, pass in both Rsdt and Xsdt.\r
1046\r
1047 @param Table Pointer to table found. \r
1048 @param NumberOfTableEntries Current number of table entries in the RSDT/XSDT\r
1049 @param Rsdt Pointer to the RSDT to remove from\r
1050 @param Xsdt Pointer to the Xsdt to remove from\r
1051\r
1052 @return EFI_SUCCESS The function completed successfully.\r
1053 @return EFI_INVALID_PARAMETER The table was not found in both Rsdt and Xsdt.\r
1054\r
1055**/\r
1056EFI_STATUS\r
1057RemoveTableFromRsdt (\r
1058 IN OUT EFI_ACPI_TABLE_LIST * Table,\r
1059 IN OUT UINTN *NumberOfTableEntries,\r
1060 IN OUT EFI_ACPI_DESCRIPTION_HEADER * Rsdt,\r
1061 IN OUT EFI_ACPI_DESCRIPTION_HEADER * Xsdt OPTIONAL\r
1062 )\r
1063{\r
1064 UINT32 *CurrentRsdtEntry;\r
1065 VOID *CurrentXsdtEntry;\r
1066 UINT64 CurrentTablePointer64;\r
1067 UINTN Index;\r
1068\r
1069 //\r
1070 // Check for invalid input parameters\r
1071 //\r
1072 ASSERT (Table);\r
1073 ASSERT (NumberOfTableEntries);\r
1074 ASSERT (Rsdt);\r
1075\r
1076 //\r
1077 // Find the table entry in the RSDT and XSDT\r
1078 //\r
1079 for (Index = 0; Index < *NumberOfTableEntries; Index++) {\r
1080 //\r
1081 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.\r
1082 // If it becomes necessary to maintain separate table lists, changes will be required.\r
1083 //\r
1084 CurrentRsdtEntry = (UINT32 *) ((UINT8 *) Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT32));\r
1085 if (Xsdt != NULL) {\r
1086 //\r
1087 // This pointer must not be directly dereferenced as the XSDT entries may not\r
1088 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.\r
1089 //\r
1090 CurrentXsdtEntry = (VOID *) ((UINT8 *) Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT64));\r
1091\r
1092 //\r
1093 // Read the entry value out of the XSDT\r
1094 //\r
1095 CopyMem (&CurrentTablePointer64, CurrentXsdtEntry, sizeof (UINT64));\r
1096 } else {\r
1097 //\r
1098 // Initialize to NULL\r
1099 //\r
1100 CurrentXsdtEntry = 0;\r
1101 CurrentTablePointer64 = 0;\r
1102 }\r
1103 //\r
1104 // Check if we have found the corresponding entry in both RSDT and XSDT\r
1105 //\r
1106 if (*CurrentRsdtEntry == (UINT32) (UINTN) Table->Table &&\r
1107 ((Xsdt == NULL) || CurrentTablePointer64 == (UINT64) (UINTN) Table->Table)\r
1108 ) {\r
1109 //\r
1110 // Found entry, so copy all following entries and shrink table\r
1111 // We actually copy all + 1 to copy the initialized value of memory over\r
1112 // the last entry.\r
1113 //\r
1114 CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index) * sizeof (UINT32));\r
1115 Rsdt->Length = Rsdt->Length - sizeof (UINT32);\r
1116 if (Xsdt != NULL) {\r
1117 CopyMem (CurrentXsdtEntry, ((UINT64 *) CurrentXsdtEntry) + 1, (*NumberOfTableEntries - Index) * sizeof (UINT64));\r
1118 Xsdt->Length = Xsdt->Length - sizeof (UINT64);\r
1119 }\r
1120 break;\r
1121 } else if (Index + 1 == *NumberOfTableEntries) {\r
1122 //\r
1123 // At the last entry, and table not found\r
1124 //\r
1125 return EFI_INVALID_PARAMETER;\r
1126 }\r
1127 }\r
1128 //\r
1129 // Checksum the tables\r
1130 //\r
1131 AcpiPlatformChecksum (\r
1132 Rsdt,\r
1133 Rsdt->Length,\r
1134 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
1135 Checksum)\r
1136 );\r
1137\r
1138 if (Xsdt != NULL) {\r
1139 AcpiPlatformChecksum (\r
1140 Xsdt,\r
1141 Xsdt->Length,\r
1142 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
1143 Checksum)\r
1144 );\r
1145 }\r
1146 //\r
1147 // Decrement the number of tables\r
1148 //\r
1149 (*NumberOfTableEntries)--;\r
1150\r
1151 return EFI_SUCCESS;\r
1152}\r
1153\r
1154\r
1155/**\r
1156 This function removes a table and frees any associated memory.\r
1157\r
1158 @param AcpiTableInstance Instance of the protocol.\r
1159 @param Version Version(s) to delete.\r
1160 @param Table Pointer to table found.\r
1161\r
1162 @return EFI_SUCCESS The function completed successfully.\r
1163\r
1164**/\r
1165EFI_STATUS\r
1166DeleteTable (\r
1167 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,\r
1168 IN EFI_ACPI_TABLE_VERSION Version,\r
1169 IN OUT EFI_ACPI_TABLE_LIST *Table\r
1170 )\r
1171{\r
1172 UINT32 CurrentTableSignature;\r
1173 BOOLEAN RemoveFromRsdt;\r
1174\r
1175 //\r
1176 // Check for invalid input parameters\r
1177 //\r
1178 ASSERT (AcpiTableInstance);\r
1179 ASSERT (Table);\r
1180\r
1181 //\r
1182 // Init locals\r
1183 //\r
1184 RemoveFromRsdt = TRUE;\r
6198c346 1185 //\r
1186 // Check for Table->Table\r
1187 //\r
1188 ASSERT (Table->Table != NULL);\r
5f55c700 1189 CurrentTableSignature = ((EFI_ACPI_COMMON_HEADER *) Table->Table)->Signature;\r
1190\r
1191 //\r
1192 // Basic tasks to accomplish delete are:\r
1193 // Determine removal requirements (in RSDT/XSDT or not)\r
1194 // Remove entry from RSDT/XSDT\r
1195 // Remove any table references to the table\r
1196 // If no one is using the table\r
1197 // Free the table (removing pointers from private data and tables)\r
1198 // Remove from list\r
1199 // Free list structure\r
1200 //\r
1201 //\r
1202 // Determine if this table is in the RSDT or XSDT\r
1203 //\r
1204 if ((CurrentTableSignature == EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||\r
1205 (CurrentTableSignature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) ||\r
1206 (CurrentTableSignature == EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)\r
1207 ) {\r
1208 RemoveFromRsdt = FALSE;\r
1209 }\r
1210 //\r
1211 // We don't remove the FADT in the standard way because some\r
1212 // OS expect the FADT to be early in the table list.\r
1213 // So we always put it as the first element in the list.\r
1214 //\r
1215 if (CurrentTableSignature == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {\r
1216 RemoveFromRsdt = FALSE;\r
1217 }\r
1218\r
1219 //\r
1220 // Remove the table from RSDT and XSDT\r
1221 //\r
1222 if (Table->Table != NULL) {\r
1223 //\r
1224 // This is a basic table, remove it from any lists and the Rsdt and/or Xsdt\r
1225 //\r
1226 if (Version & EFI_ACPI_TABLE_VERSION_NONE & Table->Version) {\r
1227 //\r
1228 // Remove this version from the table\r
1229 //\r
1230 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_NONE;\r
1231 }\r
1232\r
1233 if (Version & EFI_ACPI_TABLE_VERSION_1_0B & Table->Version) {\r
1234 //\r
1235 // Remove this version from the table\r
1236 //\r
1237 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_1_0B;\r
1238\r
1239 //\r
1240 // Remove from Rsdt. We don't care about the return value because it is\r
1241 // acceptable for the table to not exist in Rsdt.\r
1242 // We didn't add some tables so we don't remove them.\r
1243 //\r
1244 if (RemoveFromRsdt) {\r
1245 RemoveTableFromRsdt (\r
1246 Table,\r
1247 &AcpiTableInstance->NumberOfTableEntries1,\r
1248 AcpiTableInstance->Rsdt1,\r
1249 NULL\r
1250 );\r
1251 }\r
1252 }\r
1253\r
1254 if ((Version & EFI_ACPI_TABLE_VERSION_2_0 & Table->Version) ||\r
1255 (Version & EFI_ACPI_TABLE_VERSION_3_0 & Table->Version)) {\r
1256 //\r
1257 // Remove this version from the table\r
1258 //\r
1259 if (Version & EFI_ACPI_TABLE_VERSION_2_0 & Table->Version) {\r
1260 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_2_0;\r
1261 } \r
1262 if (Version & EFI_ACPI_TABLE_VERSION_3_0 & Table->Version) {\r
1263 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_3_0;\r
1264 }\r
1265 \r
1266 //\r
1267 // Remove from Rsdt and Xsdt. We don't care about the return value\r
1268 // because it is acceptable for the table to not exist in Rsdt/Xsdt.\r
1269 // We didn't add some tables so we don't remove them.\r
1270 //\r
1271 if (RemoveFromRsdt) {\r
1272 RemoveTableFromRsdt (\r
1273 Table,\r
1274 &AcpiTableInstance->NumberOfTableEntries3,\r
1275 AcpiTableInstance->Rsdt3,\r
1276 AcpiTableInstance->Xsdt\r
1277 );\r
1278 }\r
1279 } \r
1280 //\r
1281 // Free the table, clean up any dependent tables and our private data pointers.\r
1282 //\r
1283 switch (Table->Table->Signature) {\r
1284\r
1285 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:\r
1286 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
1287 AcpiTableInstance->Fadt1 = NULL;\r
1288 }\r
1289\r
1290 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
1291 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
1292 AcpiTableInstance->Fadt3 = NULL;\r
1293 }\r
1294 break;\r
1295\r
1296 case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:\r
1297 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
1298 AcpiTableInstance->Facs1 = NULL;\r
1299\r
1300 //\r
1301 // Update FADT table pointers\r
1302 //\r
1303 if (AcpiTableInstance->Fadt1 != NULL) {\r
1304 AcpiTableInstance->Fadt1->FirmwareCtrl = 0;\r
1305\r
1306 //\r
1307 // Checksum table\r
1308 //\r
1309 AcpiPlatformChecksum (\r
1310 AcpiTableInstance->Fadt1,\r
1311 AcpiTableInstance->Fadt1->Header.Length,\r
1312 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
1313 Checksum)\r
1314 );\r
1315 }\r
1316 }\r
1317\r
1318 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
1319 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
1320 AcpiTableInstance->Facs3 = NULL;\r
1321\r
1322 //\r
1323 // Update FADT table pointers\r
1324 //\r
1325 if (AcpiTableInstance->Fadt3 != NULL) {\r
1326 AcpiTableInstance->Fadt3->FirmwareCtrl = 0;\r
1327 ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));\r
1328\r
1329 //\r
1330 // Checksum table\r
1331 //\r
1332 AcpiPlatformChecksum (\r
1333 AcpiTableInstance->Fadt3,\r
1334 AcpiTableInstance->Fadt3->Header.Length,\r
1335 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
1336 Checksum)\r
1337 );\r
1338 }\r
1339 } \r
1340 break;\r
1341\r
1342 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
1343 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {\r
1344 AcpiTableInstance->Dsdt1 = NULL;\r
1345\r
1346 //\r
1347 // Update FADT table pointers\r
1348 //\r
1349 if (AcpiTableInstance->Fadt1 != NULL) {\r
1350 AcpiTableInstance->Fadt1->Dsdt = 0;\r
1351\r
1352 //\r
1353 // Checksum table\r
1354 //\r
1355 AcpiPlatformChecksum (\r
1356 AcpiTableInstance->Fadt1,\r
1357 AcpiTableInstance->Fadt1->Header.Length,\r
1358 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
1359 Checksum)\r
1360 );\r
1361 }\r
1362 }\r
1363\r
1364 \r
1365 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||\r
1366 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {\r
1367 AcpiTableInstance->Dsdt3 = NULL;\r
1368\r
1369 //\r
1370 // Update FADT table pointers\r
1371 //\r
1372 if (AcpiTableInstance->Fadt3 != NULL) {\r
1373 AcpiTableInstance->Fadt3->Dsdt = 0;\r
1374 ZeroMem (&AcpiTableInstance->Fadt3->XDsdt, sizeof (UINT64));\r
1375\r
1376 //\r
1377 // Checksum table\r
1378 //\r
1379 AcpiPlatformChecksum (\r
1380 AcpiTableInstance->Fadt3,\r
1381 AcpiTableInstance->Fadt3->Header.Length,\r
1382 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
1383 Checksum)\r
1384 );\r
1385 }\r
1386 }\r
1387 break;\r
1388\r
1389 default:\r
1390 //\r
1391 // Do nothing\r
1392 //\r
1393 break;\r
1394 }\r
1395 }\r
1396 //\r
1397 // If no version is using this table anymore, remove and free list entry.\r
1398 //\r
1399 if (Table->Version == 0) {\r
1400 //\r
1401 // Free the Table\r
1402 //\r
1403 gBS->FreePages (Table->PageAddress, Table->NumberOfPages);\r
1404 RemoveEntryList (&(Table->Link));\r
1405 gBS->FreePool (Table);\r
1406 }\r
1407 //\r
1408 // Done\r
1409 //\r
1410 return EFI_SUCCESS;\r
1411}\r
1412\r
1413\r
1414/**\r
1415 This function finds and removes the table specified by the handle.\r
1416\r
1417 @param AcpiTableInstance Instance of the protocol.\r
1418 @param Version Bitmask of which versions to remove.\r
1419 @param Handle Table to remove.\r
1420\r
1421 @return EFI_SUCCESS The function completed successfully.\r
1422 @return EFI_ABORTED An error occurred.\r
1423 @return EFI_NOT_FOUND Handle not found in table list.\r
1424\r
1425**/\r
1426EFI_STATUS\r
1427RemoveTableFromList (\r
1428 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,\r
1429 IN EFI_ACPI_TABLE_VERSION Version,\r
1430 IN UINTN Handle\r
1431 )\r
1432{\r
1433 EFI_ACPI_TABLE_LIST *Table;\r
1434 EFI_STATUS Status;\r
1435\r
b474ed49 1436 Table = (EFI_ACPI_TABLE_LIST*) NULL;\r
1437\r
5f55c700 1438 //\r
1439 // Check for invalid input parameters\r
1440 //\r
1441 ASSERT (AcpiTableInstance);\r
1442\r
1443 //\r
1444 // Find the table\r
1445 //\r
1446 Status = FindTableByHandle (\r
1447 Handle,\r
1448 &AcpiTableInstance->TableList,\r
1449 &Table\r
1450 );\r
1451 if (EFI_ERROR (Status)) {\r
1452 return EFI_NOT_FOUND;\r
1453 }\r
1454 //\r
1455 // Remove the table\r
1456 //\r
1457 Status = DeleteTable (AcpiTableInstance, Version, Table);\r
1458 if (EFI_ERROR (Status)) {\r
1459 return EFI_ABORTED;\r
1460 }\r
1461 //\r
1462 // Completed successfully\r
1463 //\r
1464 return EFI_SUCCESS;\r
1465}\r
1466\r
1467\r
1468/**\r
1469 This function calculates and updates an UINT8 checksum.\r
1470\r
1471 @param Buffer Pointer to buffer to checksum\r
1472 @param Size Number of bytes to checksum\r
1473 @param ChecksumOffset Offset to place the checksum result in\r
1474\r
1475 @return EFI_SUCCESS The function completed successfully.\r
1476\r
1477**/\r
1478EFI_STATUS\r
1479AcpiPlatformChecksum (\r
1480 IN VOID *Buffer,\r
1481 IN UINTN Size,\r
1482 IN UINTN ChecksumOffset\r
1483 )\r
1484{\r
1485 UINT8 Sum;\r
1486 UINT8 *Ptr;\r
1487\r
1488 Sum = 0;\r
1489 //\r
1490 // Initialize pointer\r
1491 //\r
1492 Ptr = Buffer;\r
1493\r
1494 //\r
1495 // set checksum to 0 first\r
1496 //\r
1497 Ptr[ChecksumOffset] = 0;\r
1498\r
1499 //\r
1500 // add all content of buffer\r
1501 //\r
1502 while ((Size--) != 0) {\r
1503 Sum = (UINT8) (Sum + (*Ptr++));\r
1504 }\r
1505 //\r
1506 // set checksum\r
1507 //\r
1508 Ptr = Buffer;\r
1509 Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);\r
1510\r
1511 return EFI_SUCCESS;\r
1512}\r
1513\r
1514\r
1515/**\r
1516 Checksum all versions of the common tables, RSDP, RSDT, XSDT.\r
1517\r
1518 @param AcpiTableInstance Protocol instance private data.\r
1519\r
1520 @return EFI_SUCCESS The function completed successfully.\r
1521\r
1522**/\r
1523EFI_STATUS\r
1524ChecksumCommonTables (\r
1525 IN OUT EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance\r
1526 )\r
1527{\r
1528 //\r
1529 // RSDP ACPI 1.0 checksum for 1.0 table. This is only the first 20 bytes of the structure\r
1530 //\r
1531 AcpiPlatformChecksum (\r
1532 AcpiTableInstance->Rsdp1,\r
1533 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),\r
1534 OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,\r
1535 Checksum)\r
1536 );\r
1537\r
1538 //\r
1539 // RSDP ACPI 1.0 checksum for 2.0/3.0 table. This is only the first 20 bytes of the structure\r
1540 //\r
1541 AcpiPlatformChecksum (\r
1542 AcpiTableInstance->Rsdp3,\r
1543 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),\r
1544 OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,\r
1545 Checksum)\r
1546 );\r
1547\r
1548 //\r
1549 // RSDP ACPI 2.0/3.0 checksum, this is the entire table\r
1550 //\r
1551 AcpiPlatformChecksum (\r
1552 AcpiTableInstance->Rsdp3,\r
1553 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER),\r
1554 OFFSET_OF (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER,\r
1555 ExtendedChecksum)\r
1556 );\r
1557\r
1558 //\r
1559 // RSDT checksums\r
1560 //\r
1561 AcpiPlatformChecksum (\r
1562 AcpiTableInstance->Rsdt1,\r
1563 AcpiTableInstance->Rsdt1->Length,\r
1564 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
1565 Checksum)\r
1566 );\r
1567\r
1568 AcpiPlatformChecksum (\r
1569 AcpiTableInstance->Rsdt3,\r
1570 AcpiTableInstance->Rsdt3->Length,\r
1571 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
1572 Checksum)\r
1573 );\r
1574\r
1575 //\r
1576 // XSDT checksum\r
1577 //\r
1578 AcpiPlatformChecksum (\r
1579 AcpiTableInstance->Xsdt,\r
1580 AcpiTableInstance->Xsdt->Length,\r
1581 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,\r
1582 Checksum)\r
1583 );\r
1584 \r
1585 return EFI_SUCCESS;\r
1586}\r
1587\r
1588\r
1589/**\r
1590 Constructor for the ACPI table protocol. Initializes instance\r
1591 data.\r
1592\r
1593 @param AcpiTableInstance Instance to construct\r
1594\r
1595 @return EFI_SUCCESS Instance initialized.\r
1596 @return EFI_OUT_OF_RESOURCES Unable to allocate required resources.\r
1597\r
1598**/\r
1599EFI_STATUS\r
1600AcpiTableAcpiTableConstructor (\r
1601 EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance\r
1602 )\r
1603{\r
1604 EFI_STATUS Status;\r
1605 UINT64 CurrentData;\r
1606 UINTN TotalSize;\r
37abfb7e 1607 UINTN RsdpTableSize;\r
5f55c700 1608 UINT8 *Pointer;\r
1609 EFI_PHYSICAL_ADDRESS PageAddress;\r
1610\r
1611 //\r
1612 // Check for invalid input parameters\r
1613 //\r
1614 ASSERT (AcpiTableInstance);\r
1615\r
1616 InitializeListHead (&AcpiTableInstance->TableList);\r
1617 AcpiTableInstance->CurrentHandle = 1;\r
1618\r
1619 AcpiTableInstance->AcpiTableProtocol.InstallAcpiTable = InstallAcpiTable;\r
1620 AcpiTableInstance->AcpiTableProtocol.UninstallAcpiTable = UninstallAcpiTable;\r
3dc8585e
JY
1621\r
1622 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {\r
1623 SdtAcpiTableAcpiSdtConstructor (AcpiTableInstance);\r
1624 }\r
1625\r
5f55c700 1626 //\r
37abfb7e
LG
1627 // Create RSDP table\r
1628 //\r
1629 RsdpTableSize = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) +\r
1630 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
1631\r
1632 PageAddress = 0xFFFFFFFF;\r
1633 Status = gBS->AllocatePages (\r
1634 AllocateMaxAddress,\r
1635 EfiACPIReclaimMemory,\r
1636 EFI_SIZE_TO_PAGES (RsdpTableSize),\r
1637 &PageAddress\r
1638 );\r
1639\r
1640 if (EFI_ERROR (Status)) {\r
1641 return EFI_OUT_OF_RESOURCES;\r
1642 }\r
1643\r
1644 Pointer = (UINT8 *) (UINTN) PageAddress;\r
1645 ZeroMem (Pointer, RsdpTableSize);\r
1646\r
1647 AcpiTableInstance->Rsdp1 = (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;\r
1648 Pointer += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
1649 AcpiTableInstance->Rsdp3 = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;\r
1650\r
1651 //\r
1652 // Create RSDT, XSDT structures\r
5f55c700 1653 //\r
37abfb7e
LG
1654 TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT\r
1655 mEfiAcpiMaxNumTables * sizeof (UINT32) +\r
1656 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT\r
1657 mEfiAcpiMaxNumTables * sizeof (UINT32) +\r
1658 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT\r
1659 mEfiAcpiMaxNumTables * sizeof (UINT64);\r
5f55c700 1660\r
1661 //\r
1662 // Allocate memory in the lower 32 bit of address range for\r
1663 // compatibility with ACPI 1.0 OS.\r
1664 //\r
1665 // This is done because ACPI 1.0 pointers are 32 bit values.\r
1666 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.\r
1667 // There is no architectural reason these should be below 4GB, it is purely\r
1668 // for convenience of implementation that we force memory below 4GB.\r
1669 //\r
1670 PageAddress = 0xFFFFFFFF;\r
1671 Status = gBS->AllocatePages (\r
1672 AllocateMaxAddress,\r
1673 EfiACPIReclaimMemory,\r
1674 EFI_SIZE_TO_PAGES (TotalSize),\r
1675 &PageAddress\r
1676 );\r
1677\r
1678 if (EFI_ERROR (Status)) {\r
37abfb7e 1679 gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)AcpiTableInstance->Rsdp1, EFI_SIZE_TO_PAGES (RsdpTableSize));\r
5f55c700 1680 return EFI_OUT_OF_RESOURCES;\r
1681 }\r
1682\r
1683 Pointer = (UINT8 *) (UINTN) PageAddress;\r
1684 ZeroMem (Pointer, TotalSize);\r
1685\r
5f55c700 1686 AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
1687 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));\r
1688 AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
1689 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));\r
5f55c700 1690 AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;\r
1691\r
1692 //\r
1693 // Initialize RSDP\r
1694 //\r
1695 CurrentData = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;\r
1696 CopyMem (&AcpiTableInstance->Rsdp1->Signature, &CurrentData, sizeof (UINT64));\r
e84f07b5 1697 CopyMem (AcpiTableInstance->Rsdp1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdp1->OemId));\r
5f55c700 1698 AcpiTableInstance->Rsdp1->Reserved = EFI_ACPI_RESERVED_BYTE;\r
1699 AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt1;\r
1700\r
1701 CurrentData = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;\r
1702 CopyMem (&AcpiTableInstance->Rsdp3->Signature, &CurrentData, sizeof (UINT64));\r
e84f07b5 1703 CopyMem (AcpiTableInstance->Rsdp3->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdp3->OemId));\r
5f55c700 1704 AcpiTableInstance->Rsdp3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION;\r
1705 AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;\r
1706 AcpiTableInstance->Rsdp3->Length = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
1707 CurrentData = (UINT64) (UINTN) AcpiTableInstance->Xsdt;\r
1708 CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));\r
1709 SetMem (AcpiTableInstance->Rsdp3->Reserved, 3, EFI_ACPI_RESERVED_BYTE);\r
1710\r
1711 //\r
1712 // Initialize Rsdt\r
1713 //\r
1714 // Note that we "reserve" one entry for the FADT so it can always be\r
1715 // at the beginning of the list of tables. Some OS don't seem\r
1716 // to find it correctly if it is too far down the list.\r
1717 //\r
1718 AcpiTableInstance->Rsdt1->Signature = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;\r
1719 AcpiTableInstance->Rsdt1->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
1720 AcpiTableInstance->Rsdt1->Revision = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;\r
e84f07b5
SZ
1721 CopyMem (AcpiTableInstance->Rsdt1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt1->OemId));\r
1722 CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);\r
5f55c700 1723 CopyMem (&AcpiTableInstance->Rsdt1->OemTableId, &CurrentData, sizeof (UINT64));\r
e84f07b5
SZ
1724 AcpiTableInstance->Rsdt1->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
1725 AcpiTableInstance->Rsdt1->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
1726 AcpiTableInstance->Rsdt1->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
5f55c700 1727 //\r
1728 // We always reserve first one for FADT\r
1729 //\r
1730 AcpiTableInstance->NumberOfTableEntries1 = 1;\r
1731 AcpiTableInstance->Rsdt1->Length = AcpiTableInstance->Rsdt1->Length + sizeof(UINT32);\r
1732\r
1733 AcpiTableInstance->Rsdt3->Signature = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;\r
1734 AcpiTableInstance->Rsdt3->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
1735 AcpiTableInstance->Rsdt3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;\r
e84f07b5
SZ
1736 CopyMem (AcpiTableInstance->Rsdt3->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt3->OemId));\r
1737 CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);\r
5f55c700 1738 CopyMem (&AcpiTableInstance->Rsdt3->OemTableId, &CurrentData, sizeof (UINT64));\r
e84f07b5
SZ
1739 AcpiTableInstance->Rsdt3->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
1740 AcpiTableInstance->Rsdt3->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
1741 AcpiTableInstance->Rsdt3->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
5f55c700 1742 //\r
1743 // We always reserve first one for FADT\r
1744 //\r
1745 AcpiTableInstance->NumberOfTableEntries3 = 1;\r
1746 AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof(UINT32);\r
1747\r
1748 //\r
1749 // Initialize Xsdt\r
1750 //\r
1751 AcpiTableInstance->Xsdt->Signature = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;\r
1752 AcpiTableInstance->Xsdt->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
1753 AcpiTableInstance->Xsdt->Revision = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION;\r
e84f07b5
SZ
1754 CopyMem (AcpiTableInstance->Xsdt->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Xsdt->OemId));\r
1755 CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);\r
5f55c700 1756 CopyMem (&AcpiTableInstance->Xsdt->OemTableId, &CurrentData, sizeof (UINT64));\r
e84f07b5
SZ
1757 AcpiTableInstance->Xsdt->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
1758 AcpiTableInstance->Xsdt->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
1759 AcpiTableInstance->Xsdt->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
5f55c700 1760 //\r
1761 // We always reserve first one for FADT\r
1762 //\r
1763 AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof(UINT64);\r
1764\r
1765 ChecksumCommonTables (AcpiTableInstance);\r
1766\r
1767 //\r
1768 // Completed successfully\r
1769 //\r
1770 return EFI_SUCCESS;\r
1771}\r
1772\r