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