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//
23UINTN         mEfiAcpiMaxNumTables = EFI_ACPI_MAX_NUM_TABLES;
24
25//
26// Allocation strategy to use for AllocatePages ().
27// Runtime value depends on PcdExposedAcpiTableVersions.
28//
29STATIC 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**/
47EFI_STATUS
48AddTableToList (
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**/
68EFI_STATUS
69RemoveTableFromList (
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**/
84EFI_STATUS
85AcpiPlatformChecksum (
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**/
99EFI_STATUS
100ChecksumCommonTables (
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**/
120EFI_STATUS
121EFIAPI
122PublishTables (
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**/
208EFI_STATUS
209EFIAPI
210InstallAcpiTable (
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**/
284EFI_STATUS
285EFIAPI
286UninstallAcpiTable (
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**/
330EFI_STATUS
331ReallocateAcpiTableBuffer (
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**/
450EFI_STATUS
451AddTableToList (
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**/
1028EFI_STATUS
1029FindTableByHandle (
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**/
1081EFI_STATUS
1082RemoveTableFromRsdt (
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**/
1198EFI_STATUS
1199DeleteTable (
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**/
1450EFI_STATUS
1451RemoveTableFromList (
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**/
1502EFI_STATUS
1503AcpiPlatformChecksum (
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**/
1547EFI_STATUS
1548ChecksumCommonTables (
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**/
1627EFI_STATUS
1628AcpiTableAcpiTableConstructor (
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