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