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