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