]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
MdeModulePkg: Acpi: enforce exclusion between FirmwareCtrl and XFirmwareCtrl
[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 ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));
625 } else {
626 Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;
627 CopyMem (
628 &AcpiTableInstance->Fadt3->XFirmwareCtrl,
629 &Buffer64,
630 sizeof (UINT64)
631 );
632 AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
633 }
634 AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;
635 Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;
636 CopyMem (
637 &AcpiTableInstance->Fadt3->XDsdt,
638 &Buffer64,
639 sizeof (UINT64)
640 );
641
642 //
643 // RSDP OEM information is updated to match the FADT OEM information
644 //
645 CopyMem (
646 &AcpiTableInstance->Rsdp3->OemId,
647 &AcpiTableInstance->Fadt3->Header.OemId,
648 6
649 );
650
651 //
652 // RSDT OEM information is updated to match FADT OEM information.
653 //
654 CopyMem (
655 &AcpiTableInstance->Rsdt3->OemId,
656 &AcpiTableInstance->Fadt3->Header.OemId,
657 6
658 );
659 CopyMem (
660 &AcpiTableInstance->Rsdt3->OemTableId,
661 &AcpiTableInstance->Fadt3->Header.OemTableId,
662 sizeof (UINT64)
663 );
664 AcpiTableInstance->Rsdt3->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;
665
666 //
667 // XSDT OEM information is updated to match FADT OEM information.
668 //
669 CopyMem (
670 &AcpiTableInstance->Xsdt->OemId,
671 &AcpiTableInstance->Fadt3->Header.OemId,
672 6
673 );
674 CopyMem (
675 &AcpiTableInstance->Xsdt->OemTableId,
676 &AcpiTableInstance->Fadt3->Header.OemTableId,
677 sizeof (UINT64)
678 );
679 AcpiTableInstance->Xsdt->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;
680 }
681 //
682 // Checksum the table
683 //
684 if (Checksum) {
685 AcpiPlatformChecksum (
686 CurrentTableList->Table,
687 CurrentTableList->Table->Length,
688 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
689 Checksum)
690 );
691 }
692 break;
693
694 case EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:
695 //
696 // Check that the table has not been previously added.
697 //
698 if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Facs1 != NULL) ||
699 ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 && AcpiTableInstance->Facs3 != NULL) ||
700 ((Version & EFI_ACPI_TABLE_VERSION_3_0) != 0 && AcpiTableInstance->Facs3 != NULL)
701 ) {
702 gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);
703 gBS->FreePool (CurrentTableList);
704 return EFI_ACCESS_DENIED;
705 }
706 //
707 // FACS is referenced by FADT and is not part of RSDT
708 //
709 AddToRsdt = FALSE;
710
711 //
712 // Add the table to the appropriate table version
713 //
714 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
715 //
716 // Save a pointer to the table
717 //
718 AcpiTableInstance->Facs1 = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) CurrentTableList->Table;
719
720 //
721 // If FADT already exists, update table pointers.
722 //
723 if (AcpiTableInstance->Fadt1 != NULL) {
724 AcpiTableInstance->Fadt1->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs1;
725
726 //
727 // Checksum FADT table
728 //
729 AcpiPlatformChecksum (
730 AcpiTableInstance->Fadt1,
731 AcpiTableInstance->Fadt1->Header.Length,
732 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
733 Checksum)
734 );
735 }
736 }
737
738 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
739 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
740 //
741 // Save a pointer to the table
742 //
743 AcpiTableInstance->Facs3 = (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) CurrentTableList->Table;
744
745 //
746 // If FADT already exists, update table pointers.
747 //
748 if (AcpiTableInstance->Fadt3 != NULL) {
749 //
750 // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
751 // vice-versa.
752 //
753 if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {
754 AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiTableInstance->Facs3;
755 ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));
756 } else {
757 Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Facs3;
758 CopyMem (
759 &AcpiTableInstance->Fadt3->XFirmwareCtrl,
760 &Buffer64,
761 sizeof (UINT64)
762 );
763 AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
764 }
765
766 //
767 // Checksum FADT table
768 //
769 AcpiPlatformChecksum (
770 AcpiTableInstance->Fadt3,
771 AcpiTableInstance->Fadt3->Header.Length,
772 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
773 Checksum)
774 );
775 }
776 }
777
778 break;
779
780 case EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
781 //
782 // Check that the table has not been previously added.
783 //
784 if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Dsdt1 != NULL) ||
785 ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 && AcpiTableInstance->Dsdt3 != NULL) ||
786 ((Version & EFI_ACPI_TABLE_VERSION_3_0) != 0 && AcpiTableInstance->Dsdt3 != NULL)
787 ) {
788 gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);
789 gBS->FreePool (CurrentTableList);
790 return EFI_ACCESS_DENIED;
791 }
792 //
793 // DSDT is referenced by FADT and is not part of RSDT
794 //
795 AddToRsdt = FALSE;
796
797 //
798 // Add the table to the appropriate table version
799 //
800 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
801 //
802 // Save a pointer to the table
803 //
804 AcpiTableInstance->Dsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTableList->Table;
805
806 //
807 // If FADT already exists, update table pointers.
808 //
809 if (AcpiTableInstance->Fadt1 != NULL) {
810 AcpiTableInstance->Fadt1->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt1;
811
812 //
813 // Checksum FADT table
814 //
815 AcpiPlatformChecksum (
816 AcpiTableInstance->Fadt1,
817 AcpiTableInstance->Fadt1->Header.Length,
818 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
819 Checksum)
820 );
821 }
822 }
823
824 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
825 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
826 //
827 // Save a pointer to the table
828 //
829 AcpiTableInstance->Dsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTableList->Table;
830
831 //
832 // If FADT already exists, update table pointers.
833 //
834 if (AcpiTableInstance->Fadt3 != NULL) {
835 AcpiTableInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiTableInstance->Dsdt3;
836 Buffer64 = (UINT64) (UINTN) AcpiTableInstance->Dsdt3;
837 CopyMem (
838 &AcpiTableInstance->Fadt3->XDsdt,
839 &Buffer64,
840 sizeof (UINT64)
841 );
842
843 //
844 // Checksum FADT table
845 //
846 AcpiPlatformChecksum (
847 AcpiTableInstance->Fadt3,
848 AcpiTableInstance->Fadt3->Header.Length,
849 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
850 Checksum)
851 );
852 }
853 }
854 //
855 // Checksum the table
856 //
857 if (Checksum) {
858 AcpiPlatformChecksum (
859 CurrentTableList->Table,
860 CurrentTableList->Table->Length,
861 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
862 Checksum)
863 );
864 }
865 break;
866
867 default:
868 //
869 // Checksum the table
870 //
871 if (Checksum) {
872 AcpiPlatformChecksum (
873 CurrentTableList->Table,
874 CurrentTableList->Table->Length,
875 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
876 Checksum)
877 );
878 }
879 break;
880 }
881 //
882 // Add the table to the current list of tables
883 //
884 InsertTailList (&AcpiTableInstance->TableList, &CurrentTableList->Link);
885
886 //
887 // Add the table to RSDT and/or XSDT table entry lists.
888 //
889 //
890 // Add to ACPI 1.0b table tree
891 //
892 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
893 if (AddToRsdt) {
894 //
895 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
896 //
897 if (AcpiTableInstance->NumberOfTableEntries1 >= mEfiAcpiMaxNumTables) {
898 Status = ReallocateAcpiTableBuffer (AcpiTableInstance);
899 ASSERT_EFI_ERROR (Status);
900 }
901 CurrentRsdtEntry = (UINT32 *)
902 (
903 (UINT8 *) AcpiTableInstance->Rsdt1 +
904 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
905 AcpiTableInstance->NumberOfTableEntries1 *
906 sizeof (UINT32)
907 );
908
909 //
910 // Add entry to the RSDT unless its the FACS or DSDT
911 //
912 *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;
913
914 //
915 // Update RSDT length
916 //
917 AcpiTableInstance->Rsdt1->Length = AcpiTableInstance->Rsdt1->Length + sizeof (UINT32);
918
919 AcpiTableInstance->NumberOfTableEntries1++;
920 }
921 }
922 //
923 // Add to ACPI 2.0/3.0 table tree
924 //
925 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
926 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
927 if (AddToRsdt) {
928 //
929 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
930 //
931 if (AcpiTableInstance->NumberOfTableEntries3 >= mEfiAcpiMaxNumTables) {
932 Status = ReallocateAcpiTableBuffer (AcpiTableInstance);
933 ASSERT_EFI_ERROR (Status);
934 }
935 //
936 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
937 // If it becomes necessary to maintain separate table lists, changes will be required.
938 //
939 CurrentRsdtEntry = (UINT32 *)
940 (
941 (UINT8 *) AcpiTableInstance->Rsdt3 +
942 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
943 AcpiTableInstance->NumberOfTableEntries3 *
944 sizeof (UINT32)
945 );
946
947 //
948 // This pointer must not be directly dereferenced as the XSDT entries may not
949 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
950 //
951 CurrentXsdtEntry = (VOID *)
952 (
953 (UINT8 *) AcpiTableInstance->Xsdt +
954 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
955 AcpiTableInstance->NumberOfTableEntries3 *
956 sizeof (UINT64)
957 );
958
959 //
960 // Add entry to the RSDT
961 //
962 *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;
963
964 //
965 // Update RSDT length
966 //
967 AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);
968
969 //
970 // Add entry to XSDT, XSDT expects 64 bit pointers, but
971 // the table pointers in XSDT are not aligned on 8 byte boundary.
972 //
973 Buffer64 = (UINT64) (UINTN) CurrentTableList->Table;
974 CopyMem (
975 CurrentXsdtEntry,
976 &Buffer64,
977 sizeof (UINT64)
978 );
979
980 //
981 // Update length
982 //
983 AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof (UINT64);
984
985 AcpiTableInstance->NumberOfTableEntries3++;
986 }
987 }
988
989 ChecksumCommonTables (AcpiTableInstance);
990 return EFI_SUCCESS;
991 }
992
993
994 /**
995 This function finds the table specified by the handle and returns a pointer to it.
996 If the handle is not found, EFI_NOT_FOUND is returned and the contents of Table are
997 undefined.
998
999 @param Handle Table to find.
1000 @param TableList Table list to search
1001 @param Table Pointer to table found.
1002
1003 @return EFI_SUCCESS The function completed successfully.
1004 @return EFI_NOT_FOUND No table found matching the handle specified.
1005
1006 **/
1007 EFI_STATUS
1008 FindTableByHandle (
1009 IN UINTN Handle,
1010 IN LIST_ENTRY *TableList,
1011 OUT EFI_ACPI_TABLE_LIST **Table
1012 )
1013 {
1014 LIST_ENTRY *CurrentLink;
1015 EFI_ACPI_TABLE_LIST *CurrentTable;
1016
1017 //
1018 // Check for invalid input parameters
1019 //
1020 ASSERT (Table);
1021
1022 //
1023 // Find the table
1024 //
1025 CurrentLink = TableList->ForwardLink;
1026
1027 while (CurrentLink != TableList) {
1028 CurrentTable = EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink);
1029 if (CurrentTable->Handle == Handle) {
1030 //
1031 // Found handle, so return this table.
1032 //
1033 *Table = CurrentTable;
1034 return EFI_SUCCESS;
1035 }
1036
1037 CurrentLink = CurrentLink->ForwardLink;
1038 }
1039 //
1040 // Table not found
1041 //
1042 return EFI_NOT_FOUND;
1043 }
1044
1045
1046 /**
1047 This function removes a basic table from the RSDT and/or XSDT.
1048 For Acpi 1.0 tables, pass in the Rsdt.
1049 For Acpi 2.0 tables, pass in both Rsdt and Xsdt.
1050
1051 @param Table Pointer to table found.
1052 @param NumberOfTableEntries Current number of table entries in the RSDT/XSDT
1053 @param Rsdt Pointer to the RSDT to remove from
1054 @param Xsdt Pointer to the Xsdt to remove from
1055
1056 @return EFI_SUCCESS The function completed successfully.
1057 @return EFI_INVALID_PARAMETER The table was not found in both Rsdt and Xsdt.
1058
1059 **/
1060 EFI_STATUS
1061 RemoveTableFromRsdt (
1062 IN OUT EFI_ACPI_TABLE_LIST * Table,
1063 IN OUT UINTN *NumberOfTableEntries,
1064 IN OUT EFI_ACPI_DESCRIPTION_HEADER * Rsdt,
1065 IN OUT EFI_ACPI_DESCRIPTION_HEADER * Xsdt OPTIONAL
1066 )
1067 {
1068 UINT32 *CurrentRsdtEntry;
1069 VOID *CurrentXsdtEntry;
1070 UINT64 CurrentTablePointer64;
1071 UINTN Index;
1072
1073 //
1074 // Check for invalid input parameters
1075 //
1076 ASSERT (Table);
1077 ASSERT (NumberOfTableEntries);
1078 ASSERT (Rsdt);
1079
1080 //
1081 // Find the table entry in the RSDT and XSDT
1082 //
1083 for (Index = 0; Index < *NumberOfTableEntries; Index++) {
1084 //
1085 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
1086 // If it becomes necessary to maintain separate table lists, changes will be required.
1087 //
1088 CurrentRsdtEntry = (UINT32 *) ((UINT8 *) Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT32));
1089 if (Xsdt != NULL) {
1090 //
1091 // This pointer must not be directly dereferenced as the XSDT entries may not
1092 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
1093 //
1094 CurrentXsdtEntry = (VOID *) ((UINT8 *) Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT64));
1095
1096 //
1097 // Read the entry value out of the XSDT
1098 //
1099 CopyMem (&CurrentTablePointer64, CurrentXsdtEntry, sizeof (UINT64));
1100 } else {
1101 //
1102 // Initialize to NULL
1103 //
1104 CurrentXsdtEntry = 0;
1105 CurrentTablePointer64 = 0;
1106 }
1107 //
1108 // Check if we have found the corresponding entry in both RSDT and XSDT
1109 //
1110 if (*CurrentRsdtEntry == (UINT32) (UINTN) Table->Table &&
1111 ((Xsdt == NULL) || CurrentTablePointer64 == (UINT64) (UINTN) Table->Table)
1112 ) {
1113 //
1114 // Found entry, so copy all following entries and shrink table
1115 // We actually copy all + 1 to copy the initialized value of memory over
1116 // the last entry.
1117 //
1118 CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index) * sizeof (UINT32));
1119 Rsdt->Length = Rsdt->Length - sizeof (UINT32);
1120 if (Xsdt != NULL) {
1121 CopyMem (CurrentXsdtEntry, ((UINT64 *) CurrentXsdtEntry) + 1, (*NumberOfTableEntries - Index) * sizeof (UINT64));
1122 Xsdt->Length = Xsdt->Length - sizeof (UINT64);
1123 }
1124 break;
1125 } else if (Index + 1 == *NumberOfTableEntries) {
1126 //
1127 // At the last entry, and table not found
1128 //
1129 return EFI_INVALID_PARAMETER;
1130 }
1131 }
1132 //
1133 // Checksum the tables
1134 //
1135 AcpiPlatformChecksum (
1136 Rsdt,
1137 Rsdt->Length,
1138 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1139 Checksum)
1140 );
1141
1142 if (Xsdt != NULL) {
1143 AcpiPlatformChecksum (
1144 Xsdt,
1145 Xsdt->Length,
1146 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1147 Checksum)
1148 );
1149 }
1150 //
1151 // Decrement the number of tables
1152 //
1153 (*NumberOfTableEntries)--;
1154
1155 return EFI_SUCCESS;
1156 }
1157
1158
1159 /**
1160 This function removes a table and frees any associated memory.
1161
1162 @param AcpiTableInstance Instance of the protocol.
1163 @param Version Version(s) to delete.
1164 @param Table Pointer to table found.
1165
1166 @return EFI_SUCCESS The function completed successfully.
1167
1168 **/
1169 EFI_STATUS
1170 DeleteTable (
1171 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
1172 IN EFI_ACPI_TABLE_VERSION Version,
1173 IN OUT EFI_ACPI_TABLE_LIST *Table
1174 )
1175 {
1176 UINT32 CurrentTableSignature;
1177 BOOLEAN RemoveFromRsdt;
1178
1179 //
1180 // Check for invalid input parameters
1181 //
1182 ASSERT (AcpiTableInstance);
1183 ASSERT (Table);
1184
1185 //
1186 // Init locals
1187 //
1188 RemoveFromRsdt = TRUE;
1189 //
1190 // Check for Table->Table
1191 //
1192 ASSERT (Table->Table != NULL);
1193 CurrentTableSignature = ((EFI_ACPI_COMMON_HEADER *) Table->Table)->Signature;
1194
1195 //
1196 // Basic tasks to accomplish delete are:
1197 // Determine removal requirements (in RSDT/XSDT or not)
1198 // Remove entry from RSDT/XSDT
1199 // Remove any table references to the table
1200 // If no one is using the table
1201 // Free the table (removing pointers from private data and tables)
1202 // Remove from list
1203 // Free list structure
1204 //
1205 //
1206 // Determine if this table is in the RSDT or XSDT
1207 //
1208 if ((CurrentTableSignature == EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||
1209 (CurrentTableSignature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) ||
1210 (CurrentTableSignature == EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)
1211 ) {
1212 RemoveFromRsdt = FALSE;
1213 }
1214 //
1215 // We don't remove the FADT in the standard way because some
1216 // OS expect the FADT to be early in the table list.
1217 // So we always put it as the first element in the list.
1218 //
1219 if (CurrentTableSignature == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
1220 RemoveFromRsdt = FALSE;
1221 }
1222
1223 //
1224 // Remove the table from RSDT and XSDT
1225 //
1226 if (Table->Table != NULL) {
1227 //
1228 // This is a basic table, remove it from any lists and the Rsdt and/or Xsdt
1229 //
1230 if (Version & EFI_ACPI_TABLE_VERSION_NONE & Table->Version) {
1231 //
1232 // Remove this version from the table
1233 //
1234 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_NONE;
1235 }
1236
1237 if (Version & EFI_ACPI_TABLE_VERSION_1_0B & Table->Version) {
1238 //
1239 // Remove this version from the table
1240 //
1241 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_1_0B;
1242
1243 //
1244 // Remove from Rsdt. We don't care about the return value because it is
1245 // acceptable for the table to not exist in Rsdt.
1246 // We didn't add some tables so we don't remove them.
1247 //
1248 if (RemoveFromRsdt) {
1249 RemoveTableFromRsdt (
1250 Table,
1251 &AcpiTableInstance->NumberOfTableEntries1,
1252 AcpiTableInstance->Rsdt1,
1253 NULL
1254 );
1255 }
1256 }
1257
1258 if ((Version & EFI_ACPI_TABLE_VERSION_2_0 & Table->Version) ||
1259 (Version & EFI_ACPI_TABLE_VERSION_3_0 & Table->Version)) {
1260 //
1261 // Remove this version from the table
1262 //
1263 if (Version & EFI_ACPI_TABLE_VERSION_2_0 & Table->Version) {
1264 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_2_0;
1265 }
1266 if (Version & EFI_ACPI_TABLE_VERSION_3_0 & Table->Version) {
1267 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_3_0;
1268 }
1269
1270 //
1271 // Remove from Rsdt and Xsdt. We don't care about the return value
1272 // because it is acceptable for the table to not exist in Rsdt/Xsdt.
1273 // We didn't add some tables so we don't remove them.
1274 //
1275 if (RemoveFromRsdt) {
1276 RemoveTableFromRsdt (
1277 Table,
1278 &AcpiTableInstance->NumberOfTableEntries3,
1279 AcpiTableInstance->Rsdt3,
1280 AcpiTableInstance->Xsdt
1281 );
1282 }
1283 }
1284 //
1285 // Free the table, clean up any dependent tables and our private data pointers.
1286 //
1287 switch (Table->Table->Signature) {
1288
1289 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
1290 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1291 AcpiTableInstance->Fadt1 = NULL;
1292 }
1293
1294 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
1295 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
1296 AcpiTableInstance->Fadt3 = NULL;
1297 }
1298 break;
1299
1300 case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:
1301 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1302 AcpiTableInstance->Facs1 = NULL;
1303
1304 //
1305 // Update FADT table pointers
1306 //
1307 if (AcpiTableInstance->Fadt1 != NULL) {
1308 AcpiTableInstance->Fadt1->FirmwareCtrl = 0;
1309
1310 //
1311 // Checksum table
1312 //
1313 AcpiPlatformChecksum (
1314 AcpiTableInstance->Fadt1,
1315 AcpiTableInstance->Fadt1->Header.Length,
1316 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1317 Checksum)
1318 );
1319 }
1320 }
1321
1322 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
1323 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
1324 AcpiTableInstance->Facs3 = NULL;
1325
1326 //
1327 // Update FADT table pointers
1328 //
1329 if (AcpiTableInstance->Fadt3 != NULL) {
1330 AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
1331 ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));
1332
1333 //
1334 // Checksum table
1335 //
1336 AcpiPlatformChecksum (
1337 AcpiTableInstance->Fadt3,
1338 AcpiTableInstance->Fadt3->Header.Length,
1339 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1340 Checksum)
1341 );
1342 }
1343 }
1344 break;
1345
1346 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
1347 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1348 AcpiTableInstance->Dsdt1 = NULL;
1349
1350 //
1351 // Update FADT table pointers
1352 //
1353 if (AcpiTableInstance->Fadt1 != NULL) {
1354 AcpiTableInstance->Fadt1->Dsdt = 0;
1355
1356 //
1357 // Checksum table
1358 //
1359 AcpiPlatformChecksum (
1360 AcpiTableInstance->Fadt1,
1361 AcpiTableInstance->Fadt1->Header.Length,
1362 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1363 Checksum)
1364 );
1365 }
1366 }
1367
1368
1369 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
1370 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
1371 AcpiTableInstance->Dsdt3 = NULL;
1372
1373 //
1374 // Update FADT table pointers
1375 //
1376 if (AcpiTableInstance->Fadt3 != NULL) {
1377 AcpiTableInstance->Fadt3->Dsdt = 0;
1378 ZeroMem (&AcpiTableInstance->Fadt3->XDsdt, sizeof (UINT64));
1379
1380 //
1381 // Checksum table
1382 //
1383 AcpiPlatformChecksum (
1384 AcpiTableInstance->Fadt3,
1385 AcpiTableInstance->Fadt3->Header.Length,
1386 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1387 Checksum)
1388 );
1389 }
1390 }
1391 break;
1392
1393 default:
1394 //
1395 // Do nothing
1396 //
1397 break;
1398 }
1399 }
1400 //
1401 // If no version is using this table anymore, remove and free list entry.
1402 //
1403 if (Table->Version == 0) {
1404 //
1405 // Free the Table
1406 //
1407 gBS->FreePages (Table->PageAddress, Table->NumberOfPages);
1408 RemoveEntryList (&(Table->Link));
1409 gBS->FreePool (Table);
1410 }
1411 //
1412 // Done
1413 //
1414 return EFI_SUCCESS;
1415 }
1416
1417
1418 /**
1419 This function finds and removes the table specified by the handle.
1420
1421 @param AcpiTableInstance Instance of the protocol.
1422 @param Version Bitmask of which versions to remove.
1423 @param Handle Table to remove.
1424
1425 @return EFI_SUCCESS The function completed successfully.
1426 @return EFI_ABORTED An error occurred.
1427 @return EFI_NOT_FOUND Handle not found in table list.
1428
1429 **/
1430 EFI_STATUS
1431 RemoveTableFromList (
1432 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
1433 IN EFI_ACPI_TABLE_VERSION Version,
1434 IN UINTN Handle
1435 )
1436 {
1437 EFI_ACPI_TABLE_LIST *Table;
1438 EFI_STATUS Status;
1439
1440 Table = (EFI_ACPI_TABLE_LIST*) NULL;
1441
1442 //
1443 // Check for invalid input parameters
1444 //
1445 ASSERT (AcpiTableInstance);
1446
1447 //
1448 // Find the table
1449 //
1450 Status = FindTableByHandle (
1451 Handle,
1452 &AcpiTableInstance->TableList,
1453 &Table
1454 );
1455 if (EFI_ERROR (Status)) {
1456 return EFI_NOT_FOUND;
1457 }
1458 //
1459 // Remove the table
1460 //
1461 Status = DeleteTable (AcpiTableInstance, Version, Table);
1462 if (EFI_ERROR (Status)) {
1463 return EFI_ABORTED;
1464 }
1465 //
1466 // Completed successfully
1467 //
1468 return EFI_SUCCESS;
1469 }
1470
1471
1472 /**
1473 This function calculates and updates an UINT8 checksum.
1474
1475 @param Buffer Pointer to buffer to checksum
1476 @param Size Number of bytes to checksum
1477 @param ChecksumOffset Offset to place the checksum result in
1478
1479 @return EFI_SUCCESS The function completed successfully.
1480
1481 **/
1482 EFI_STATUS
1483 AcpiPlatformChecksum (
1484 IN VOID *Buffer,
1485 IN UINTN Size,
1486 IN UINTN ChecksumOffset
1487 )
1488 {
1489 UINT8 Sum;
1490 UINT8 *Ptr;
1491
1492 Sum = 0;
1493 //
1494 // Initialize pointer
1495 //
1496 Ptr = Buffer;
1497
1498 //
1499 // set checksum to 0 first
1500 //
1501 Ptr[ChecksumOffset] = 0;
1502
1503 //
1504 // add all content of buffer
1505 //
1506 while ((Size--) != 0) {
1507 Sum = (UINT8) (Sum + (*Ptr++));
1508 }
1509 //
1510 // set checksum
1511 //
1512 Ptr = Buffer;
1513 Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
1514
1515 return EFI_SUCCESS;
1516 }
1517
1518
1519 /**
1520 Checksum all versions of the common tables, RSDP, RSDT, XSDT.
1521
1522 @param AcpiTableInstance Protocol instance private data.
1523
1524 @return EFI_SUCCESS The function completed successfully.
1525
1526 **/
1527 EFI_STATUS
1528 ChecksumCommonTables (
1529 IN OUT EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance
1530 )
1531 {
1532 //
1533 // RSDP ACPI 1.0 checksum for 1.0 table. This is only the first 20 bytes of the structure
1534 //
1535 AcpiPlatformChecksum (
1536 AcpiTableInstance->Rsdp1,
1537 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),
1538 OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
1539 Checksum)
1540 );
1541
1542 //
1543 // RSDP ACPI 1.0 checksum for 2.0/3.0 table. This is only the first 20 bytes of the structure
1544 //
1545 AcpiPlatformChecksum (
1546 AcpiTableInstance->Rsdp3,
1547 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),
1548 OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
1549 Checksum)
1550 );
1551
1552 //
1553 // RSDP ACPI 2.0/3.0 checksum, this is the entire table
1554 //
1555 AcpiPlatformChecksum (
1556 AcpiTableInstance->Rsdp3,
1557 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER),
1558 OFFSET_OF (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
1559 ExtendedChecksum)
1560 );
1561
1562 //
1563 // RSDT checksums
1564 //
1565 AcpiPlatformChecksum (
1566 AcpiTableInstance->Rsdt1,
1567 AcpiTableInstance->Rsdt1->Length,
1568 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1569 Checksum)
1570 );
1571
1572 AcpiPlatformChecksum (
1573 AcpiTableInstance->Rsdt3,
1574 AcpiTableInstance->Rsdt3->Length,
1575 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1576 Checksum)
1577 );
1578
1579 //
1580 // XSDT checksum
1581 //
1582 AcpiPlatformChecksum (
1583 AcpiTableInstance->Xsdt,
1584 AcpiTableInstance->Xsdt->Length,
1585 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1586 Checksum)
1587 );
1588
1589 return EFI_SUCCESS;
1590 }
1591
1592
1593 /**
1594 Constructor for the ACPI table protocol. Initializes instance
1595 data.
1596
1597 @param AcpiTableInstance Instance to construct
1598
1599 @return EFI_SUCCESS Instance initialized.
1600 @return EFI_OUT_OF_RESOURCES Unable to allocate required resources.
1601
1602 **/
1603 EFI_STATUS
1604 AcpiTableAcpiTableConstructor (
1605 EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance
1606 )
1607 {
1608 EFI_STATUS Status;
1609 UINT64 CurrentData;
1610 UINTN TotalSize;
1611 UINTN RsdpTableSize;
1612 UINT8 *Pointer;
1613 EFI_PHYSICAL_ADDRESS PageAddress;
1614
1615 //
1616 // Check for invalid input parameters
1617 //
1618 ASSERT (AcpiTableInstance);
1619
1620 InitializeListHead (&AcpiTableInstance->TableList);
1621 AcpiTableInstance->CurrentHandle = 1;
1622
1623 AcpiTableInstance->AcpiTableProtocol.InstallAcpiTable = InstallAcpiTable;
1624 AcpiTableInstance->AcpiTableProtocol.UninstallAcpiTable = UninstallAcpiTable;
1625
1626 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {
1627 SdtAcpiTableAcpiSdtConstructor (AcpiTableInstance);
1628 }
1629
1630 //
1631 // Create RSDP table
1632 //
1633 RsdpTableSize = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) +
1634 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
1635
1636 PageAddress = 0xFFFFFFFF;
1637 Status = gBS->AllocatePages (
1638 AllocateMaxAddress,
1639 EfiACPIReclaimMemory,
1640 EFI_SIZE_TO_PAGES (RsdpTableSize),
1641 &PageAddress
1642 );
1643
1644 if (EFI_ERROR (Status)) {
1645 return EFI_OUT_OF_RESOURCES;
1646 }
1647
1648 Pointer = (UINT8 *) (UINTN) PageAddress;
1649 ZeroMem (Pointer, RsdpTableSize);
1650
1651 AcpiTableInstance->Rsdp1 = (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;
1652 Pointer += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
1653 AcpiTableInstance->Rsdp3 = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;
1654
1655 //
1656 // Create RSDT, XSDT structures
1657 //
1658 TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT
1659 mEfiAcpiMaxNumTables * sizeof (UINT32) +
1660 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT
1661 mEfiAcpiMaxNumTables * sizeof (UINT32) +
1662 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT
1663 mEfiAcpiMaxNumTables * sizeof (UINT64);
1664
1665 //
1666 // Allocate memory in the lower 32 bit of address range for
1667 // compatibility with ACPI 1.0 OS.
1668 //
1669 // This is done because ACPI 1.0 pointers are 32 bit values.
1670 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
1671 // There is no architectural reason these should be below 4GB, it is purely
1672 // for convenience of implementation that we force memory below 4GB.
1673 //
1674 PageAddress = 0xFFFFFFFF;
1675 Status = gBS->AllocatePages (
1676 AllocateMaxAddress,
1677 EfiACPIReclaimMemory,
1678 EFI_SIZE_TO_PAGES (TotalSize),
1679 &PageAddress
1680 );
1681
1682 if (EFI_ERROR (Status)) {
1683 gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)AcpiTableInstance->Rsdp1, EFI_SIZE_TO_PAGES (RsdpTableSize));
1684 return EFI_OUT_OF_RESOURCES;
1685 }
1686
1687 Pointer = (UINT8 *) (UINTN) PageAddress;
1688 ZeroMem (Pointer, TotalSize);
1689
1690 AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
1691 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));
1692 AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
1693 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));
1694 AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
1695
1696 //
1697 // Initialize RSDP
1698 //
1699 CurrentData = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;
1700 CopyMem (&AcpiTableInstance->Rsdp1->Signature, &CurrentData, sizeof (UINT64));
1701 CopyMem (AcpiTableInstance->Rsdp1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdp1->OemId));
1702 AcpiTableInstance->Rsdp1->Reserved = EFI_ACPI_RESERVED_BYTE;
1703 AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt1;
1704
1705 CurrentData = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;
1706 CopyMem (&AcpiTableInstance->Rsdp3->Signature, &CurrentData, sizeof (UINT64));
1707 CopyMem (AcpiTableInstance->Rsdp3->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdp3->OemId));
1708 AcpiTableInstance->Rsdp3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION;
1709 AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiTableInstance->Rsdt3;
1710 AcpiTableInstance->Rsdp3->Length = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
1711 CurrentData = (UINT64) (UINTN) AcpiTableInstance->Xsdt;
1712 CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));
1713 SetMem (AcpiTableInstance->Rsdp3->Reserved, 3, EFI_ACPI_RESERVED_BYTE);
1714
1715 //
1716 // Initialize Rsdt
1717 //
1718 // Note that we "reserve" one entry for the FADT so it can always be
1719 // at the beginning of the list of tables. Some OS don't seem
1720 // to find it correctly if it is too far down the list.
1721 //
1722 AcpiTableInstance->Rsdt1->Signature = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
1723 AcpiTableInstance->Rsdt1->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
1724 AcpiTableInstance->Rsdt1->Revision = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;
1725 CopyMem (AcpiTableInstance->Rsdt1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt1->OemId));
1726 CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);
1727 CopyMem (&AcpiTableInstance->Rsdt1->OemTableId, &CurrentData, sizeof (UINT64));
1728 AcpiTableInstance->Rsdt1->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
1729 AcpiTableInstance->Rsdt1->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
1730 AcpiTableInstance->Rsdt1->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
1731 //
1732 // We always reserve first one for FADT
1733 //
1734 AcpiTableInstance->NumberOfTableEntries1 = 1;
1735 AcpiTableInstance->Rsdt1->Length = AcpiTableInstance->Rsdt1->Length + sizeof(UINT32);
1736
1737 AcpiTableInstance->Rsdt3->Signature = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
1738 AcpiTableInstance->Rsdt3->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
1739 AcpiTableInstance->Rsdt3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;
1740 CopyMem (AcpiTableInstance->Rsdt3->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt3->OemId));
1741 CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);
1742 CopyMem (&AcpiTableInstance->Rsdt3->OemTableId, &CurrentData, sizeof (UINT64));
1743 AcpiTableInstance->Rsdt3->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
1744 AcpiTableInstance->Rsdt3->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
1745 AcpiTableInstance->Rsdt3->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
1746 //
1747 // We always reserve first one for FADT
1748 //
1749 AcpiTableInstance->NumberOfTableEntries3 = 1;
1750 AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof(UINT32);
1751
1752 //
1753 // Initialize Xsdt
1754 //
1755 AcpiTableInstance->Xsdt->Signature = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
1756 AcpiTableInstance->Xsdt->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
1757 AcpiTableInstance->Xsdt->Revision = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION;
1758 CopyMem (AcpiTableInstance->Xsdt->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Xsdt->OemId));
1759 CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);
1760 CopyMem (&AcpiTableInstance->Xsdt->OemTableId, &CurrentData, sizeof (UINT64));
1761 AcpiTableInstance->Xsdt->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
1762 AcpiTableInstance->Xsdt->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
1763 AcpiTableInstance->Xsdt->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
1764 //
1765 // We always reserve first one for FADT
1766 //
1767 AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof(UINT64);
1768
1769 ChecksumCommonTables (AcpiTableInstance);
1770
1771 //
1772 // Completed successfully
1773 //
1774 return EFI_SUCCESS;
1775 }
1776