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