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