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