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