TianoCore EDK2 master
Loading...
Searching...
No Matches
DynamicTableManagerDxe.c
Go to the documentation of this file.
1
10#include <Library/DebugLib.h>
11#include <Library/PcdLib.h>
14#include <Protocol/AcpiTable.h>
15
16// Module specific include files.
17#include <AcpiTableGenerator.h>
25
27
33STATIC UINT32 mAcpiVerifyTablesCount;
34STATIC INT32 mAcpiVerifyTablesFadtIndex;
35
43 )
44
45
68EFIAPI
69BuildAndInstallSingleAcpiTable (
73 IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol,
75 )
76{
77 EFI_STATUS Status;
78 EFI_STATUS Status1;
80 UINTN TableHandle;
81
82 AcpiTable = NULL;
83 Status = Generator->BuildAcpiTable (
85 AcpiTableInfo,
86 CfgMgrProtocol,
87 &AcpiTable
88 );
89 if (EFI_ERROR (Status)) {
90 DEBUG ((
91 DEBUG_ERROR,
92 "ERROR: Failed to Build Table." \
93 " TableGeneratorId = 0x%x. Status = %r\n",
94 AcpiTableInfo->TableGeneratorId,
95 Status
96 ));
97 // Free any allocated resources.
98 goto exit_handler;
99 }
100
101 if (AcpiTable == NULL) {
102 Status = EFI_NOT_FOUND;
103 goto exit_handler;
104 }
105
106 // Dump ACPI Table Header
107 DUMP_ACPI_TABLE_HEADER (AcpiTable);
108
109 // Install ACPI table
110 Status = AcpiTableProtocol->InstallAcpiTable (
111 AcpiTableProtocol,
112 AcpiTable,
113 AcpiTable->Length,
114 &TableHandle
115 );
116 if (EFI_ERROR (Status)) {
117 DEBUG ((
118 DEBUG_ERROR,
119 "ERROR: Failed to Install ACPI Table. Status = %r\n",
120 Status
121 ));
122 // Free any allocated resources.
123 goto exit_handler;
124 }
125
126 DEBUG ((
127 DEBUG_INFO,
128 "INFO: ACPI Table installed. Status = %r\n",
129 Status
130 ));
131
132exit_handler:
133 // Free any resources allocated for generating the tables.
134 if (Generator->FreeTableResources != NULL) {
135 Status1 = Generator->FreeTableResources (
136 Generator,
137 AcpiTableInfo,
138 CfgMgrProtocol,
139 &AcpiTable
140 );
141 if (EFI_ERROR (Status1)) {
142 DEBUG ((
143 DEBUG_ERROR,
144 "ERROR: Failed to Free Table Resources." \
145 "TableGeneratorId = 0x%x. Status = %r\n",
146 AcpiTableInfo->TableGeneratorId,
147 Status1
148 ));
149 }
150
151 // Return the first error status in case of failure
152 if (!EFI_ERROR (Status)) {
153 Status = Status1;
154 }
155 }
156
157 return Status;
158}
159
181STATIC
183EFIAPI
188 IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol,
190 )
191{
192 EFI_STATUS Status;
193 EFI_STATUS Status1;
194 EFI_ACPI_DESCRIPTION_HEADER **AcpiTable;
195 UINTN TableCount;
196 UINTN TableHandle;
197 UINTN Index;
198
199 AcpiTable = NULL;
200 TableCount = 0;
201 Status = Generator->BuildAcpiTableEx (
202 Generator,
203 AcpiTableInfo,
204 CfgMgrProtocol,
205 &AcpiTable,
206 &TableCount
207 );
208 if (EFI_ERROR (Status)) {
209 DEBUG ((
210 DEBUG_ERROR,
211 "ERROR: Failed to Build Table." \
212 " TableGeneratorId = 0x%x. Status = %r\n",
213 AcpiTableInfo->TableGeneratorId,
214 Status
215 ));
216 // Free any allocated resources.
217 goto exit_handler;
218 }
219
220 if ((AcpiTable == NULL) || (TableCount == 0)) {
221 Status = EFI_NOT_FOUND;
222 goto exit_handler;
223 }
224
225 for (Index = 0; Index < TableCount; Index++) {
226 // Dump ACPI Table Header
227 DUMP_ACPI_TABLE_HEADER (AcpiTable[Index]);
228 // Install ACPI table
229 Status = AcpiTableProtocol->InstallAcpiTable (
230 AcpiTableProtocol,
231 AcpiTable[Index],
232 AcpiTable[Index]->Length,
233 &TableHandle
234 );
235 if (EFI_ERROR (Status)) {
236 DEBUG ((
237 DEBUG_ERROR,
238 "ERROR: Failed to Install ACPI Table. Status = %r\n",
239 Status
240 ));
241 // Free any allocated resources.
242 goto exit_handler;
243 }
244
245 DEBUG ((
246 DEBUG_INFO,
247 "INFO: ACPI Table installed. Status = %r\n",
248 Status
249 ));
250 }
251
252exit_handler:
253 // Free any resources allocated for generating the tables.
254 if (Generator->FreeTableResourcesEx != NULL) {
255 Status1 = Generator->FreeTableResourcesEx (
256 Generator,
257 AcpiTableInfo,
258 CfgMgrProtocol,
259 &AcpiTable,
260 TableCount
261 );
262 if (EFI_ERROR (Status1)) {
263 DEBUG ((
264 DEBUG_ERROR,
265 "ERROR: Failed to Free Table Resources." \
266 "TableGeneratorId = 0x%x. Status = %r\n",
267 AcpiTableInfo->TableGeneratorId,
268 Status1
269 ));
270 }
271
272 // Return the first error status in case of failure
273 if (!EFI_ERROR (Status)) {
274 Status = Status1;
275 }
276 }
277
278 return Status;
279}
280
301STATIC
303EFIAPI
307 IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol,
309 )
310{
311 EFI_STATUS Status;
313
314 ASSERT (TableFactoryProtocol != NULL);
315 ASSERT (CfgMgrProtocol != NULL);
316 ASSERT (AcpiTableProtocol != NULL);
317 ASSERT (AcpiTableInfo != NULL);
318
319 DEBUG ((
320 DEBUG_INFO,
321 "INFO: EStdObjAcpiTableList: Address = 0x%p," \
322 " TableGeneratorId = 0x%x\n",
323 AcpiTableInfo,
324 AcpiTableInfo->TableGeneratorId
325 ));
326
327 Generator = NULL;
328 Status = TableFactoryProtocol->GetAcpiTableGenerator (
329 TableFactoryProtocol,
330 AcpiTableInfo->TableGeneratorId,
331 &Generator
332 );
333 if (EFI_ERROR (Status)) {
334 DEBUG ((
335 DEBUG_ERROR,
336 "ERROR: Table Generator not found." \
337 " TableGeneratorId = 0x%x. Status = %r\n",
338 AcpiTableInfo->TableGeneratorId,
339 Status
340 ));
341 return Status;
342 }
343
344 if (Generator == NULL) {
345 return EFI_NOT_FOUND;
346 }
347
348 DEBUG ((
349 DEBUG_INFO,
350 "INFO: Generator found : %s\n",
351 Generator->Description
352 ));
353
354 if (Generator->BuildAcpiTableEx != NULL) {
356 TableFactoryProtocol,
357 CfgMgrProtocol,
358 Generator,
359 AcpiTableProtocol,
360 AcpiTableInfo
361 );
362 if (EFI_ERROR (Status)) {
363 DEBUG ((
364 DEBUG_ERROR,
365 "ERROR: Failed to find build and install ACPI Table." \
366 " Status = %r\n",
367 Status
368 ));
369 }
370 } else if (Generator->BuildAcpiTable != NULL) {
371 Status = BuildAndInstallSingleAcpiTable (
372 TableFactoryProtocol,
373 CfgMgrProtocol,
374 Generator,
375 AcpiTableProtocol,
376 AcpiTableInfo
377 );
378 if (EFI_ERROR (Status)) {
379 DEBUG ((
380 DEBUG_ERROR,
381 "ERROR: Failed to find build and install ACPI Table." \
382 " Status = %r\n",
383 Status
384 ));
385 }
386 } else {
387 Status = EFI_INVALID_PARAMETER;
388 DEBUG ((
389 DEBUG_ERROR,
390 "ERROR: Table Generator does not implement the" \
391 " ACPI_TABLE_GENERATOR_BUILD_TABLE interface." \
392 " TableGeneratorId = 0x%x. Status = %r\n",
393 AcpiTableInfo->TableGeneratorId,
394 Status
395 ));
396 }
397
398 return Status;
399}
400
411STATIC
413EFIAPI
416 IN UINT32 AcpiTableCount
417 )
418{
419 EFI_STATUS Status;
420 UINTN Handle;
421 UINTN Index;
422 UINTN InstalledTableIndex;
423 EFI_ACPI_DESCRIPTION_HEADER *DescHeader;
424 EFI_ACPI_TABLE_VERSION Version;
425 EFI_ACPI_SDT_PROTOCOL *AcpiSdt;
426
427 ASSERT (AcpiTableInfo != NULL);
428
429 Status = EFI_SUCCESS;
430
431 // Check against the statically initialized ACPI tables to see if they are in ACPI info list
432 while (AcpiTableCount-- != 0) {
433 for (Index = 0; Index < mAcpiVerifyTablesCount; Index++) {
434 if (AcpiTableInfo[AcpiTableCount].AcpiTableSignature == mAcpiVerifyTables[Index].AcpiTableSignature) {
436 // Found this table, skip the rest.
437 break;
438 }
439 }
440 }
441
442 // They also might be published already, so we can search from there
443 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {
444 AcpiSdt = NULL;
445 Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiSdt);
446
447 if (EFI_ERROR (Status) || (AcpiSdt == NULL)) {
448 DEBUG ((DEBUG_ERROR, "ERROR: Failed to locate ACPI SDT protocol (0x%p) - %r\n", AcpiSdt, Status));
449 return Status;
450 }
451
452 for (Index = 0; Index < mAcpiVerifyTablesCount; Index++) {
453 Handle = 0;
454 InstalledTableIndex = 0;
455 do {
456 Status = AcpiSdt->GetAcpiTable (InstalledTableIndex, (EFI_ACPI_SDT_HEADER **)&DescHeader, &Version, &Handle);
457 if (EFI_ERROR (Status)) {
458 break;
459 }
460
461 InstalledTableIndex++;
462 } while (DescHeader->Signature != mAcpiVerifyTables[Index].AcpiTableSignature);
463
464 if (!EFI_ERROR (Status)) {
465 mAcpiVerifyTables[Index].Presence |= ACPI_TABLE_PRESENT_INSTALLED;
466 }
467 }
468 }
469
470 // Reset the return Status value to EFI_SUCCESS. We do not fully care if the table look up has failed.
471 Status = EFI_SUCCESS;
472 for (Index = 0; Index < mAcpiVerifyTablesCount; Index++) {
473 if (mAcpiVerifyTables[Index].Presence == 0) {
474 if (mAcpiVerifyTables[Index].IsMandatory) {
475 DEBUG ((DEBUG_ERROR, "ERROR: %a Table not found.\n", mAcpiVerifyTables[Index].AcpiTableName));
476 Status = EFI_NOT_FOUND;
477 } else {
478 DEBUG ((DEBUG_WARN, "WARNING: %a Table not found.\n", mAcpiVerifyTables[Index].AcpiTableName));
479 }
480 } else if (mAcpiVerifyTables[Index].Presence ==
481 (ACPI_TABLE_PRESENT_INFO_LIST | ACPI_TABLE_PRESENT_INSTALLED))
482 {
483 DEBUG ((DEBUG_ERROR, "ERROR: %a Table found while already published.\n", mAcpiVerifyTables[Index].AcpiTableName));
484 Status = EFI_ALREADY_STARTED;
485 }
486 }
487
488 return Status;
489}
490
506STATIC
508EFIAPI
512 )
513{
514 EFI_STATUS Status;
515 EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
516 CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo;
517 UINT32 AcpiTableCount;
518 UINT32 Idx;
519
520 ASSERT (TableFactoryProtocol != NULL);
521 ASSERT (CfgMgrProtocol != NULL);
522
523 // Find the AcpiTable protocol
524 Status = gBS->LocateProtocol (
525 &gEfiAcpiTableProtocolGuid,
526 NULL,
527 (VOID **)&AcpiTableProtocol
528 );
529 if (EFI_ERROR (Status)) {
530 DEBUG ((
531 DEBUG_ERROR,
532 "ERROR: Failed to find AcpiTable protocol. Status = %r\n",
533 Status
534 ));
535 return Status;
536 }
537
538 Status = GetEStdObjAcpiTableList (
539 CfgMgrProtocol,
541 &AcpiTableInfo,
542 &AcpiTableCount
543 );
544 if (EFI_ERROR (Status)) {
545 DEBUG ((
546 DEBUG_ERROR,
547 "ERROR: Failed to get ACPI Table List. Status = %r\n",
548 Status
549 ));
550 return Status;
551 }
552
553 if (0 == AcpiTableCount) {
554 DEBUG ((
555 DEBUG_ERROR,
556 "ERROR: EStdObjAcpiTableList: AcpiTableCount = %d\n",
557 AcpiTableCount
558 ));
559 return EFI_NOT_FOUND;
560 }
561
562 DEBUG ((
563 DEBUG_INFO,
564 "INFO: EStdObjAcpiTableList: AcpiTableCount = %d\n",
565 AcpiTableCount
566 ));
567
568 // Check if mandatory ACPI tables are present.
570 AcpiTableInfo,
571 AcpiTableCount
572 );
573 if (EFI_ERROR (Status)) {
574 DEBUG ((
575 DEBUG_ERROR,
576 "ERROR: Failed to verify mandatory ACPI Table(s) presence."
577 " Status = %r\n",
578 Status
579 ));
580 return Status;
581 }
582
583 // Add the FADT Table first.
584 if ((mAcpiVerifyTablesFadtIndex >= 0) &&
585 ((mAcpiVerifyTables[mAcpiVerifyTablesFadtIndex].Presence & ACPI_TABLE_PRESENT_INSTALLED) == 0))
586 {
587 // FADT is not yet installed
588 for (Idx = 0; Idx < AcpiTableCount; Idx++) {
590 AcpiTableInfo[Idx].TableGeneratorId)
591 {
592 Status = BuildAndInstallAcpiTable (
593 TableFactoryProtocol,
594 CfgMgrProtocol,
595 AcpiTableProtocol,
596 &AcpiTableInfo[Idx]
597 );
598 if (EFI_ERROR (Status)) {
599 DEBUG ((
600 DEBUG_ERROR,
601 "ERROR: Failed to find build and install ACPI FADT Table." \
602 " Status = %r\n",
603 Status
604 ));
605 return Status;
606 }
607
608 break;
609 }
610 } // for
611 }
612
613 // Add remaining ACPI Tables
614 for (Idx = 0; Idx < AcpiTableCount; Idx++) {
615 DEBUG ((
616 DEBUG_INFO,
617 "INFO: AcpiTableInfo[%d].TableGeneratorId = 0x%x\n",
618 Idx,
619 AcpiTableInfo[Idx].TableGeneratorId
620 ));
621
622 // Skip FADT Table since we have already added
624 AcpiTableInfo[Idx].TableGeneratorId)
625 {
626 continue;
627 }
628
629 // Skip the Reserved table Generator ID for standard generators
630 if ((IS_GENERATOR_NAMESPACE_STD (AcpiTableInfo[Idx].TableGeneratorId)) &&
632 AcpiTableInfo[Idx].TableGeneratorId) ||
633 (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMax) <=
634 AcpiTableInfo[Idx].TableGeneratorId)))
635 {
636 DEBUG ((
637 DEBUG_WARN,
638 "WARNING: Invalid ACPI Generator table ID = 0x%x, Skipping...\n",
639 AcpiTableInfo[Idx].TableGeneratorId
640 ));
641 continue;
642 }
643
644 Status = BuildAndInstallAcpiTable (
645 TableFactoryProtocol,
646 CfgMgrProtocol,
647 AcpiTableProtocol,
648 &AcpiTableInfo[Idx]
649 );
650 if (EFI_ERROR (Status)) {
651 DEBUG ((
652 DEBUG_ERROR,
653 "ERROR: Failed to find, build, and install ACPI Table." \
654 " Status = %r\n",
655 Status
656 ));
657 return Status;
658 }
659 } // for
660
661 return Status;
662}
663
684EFIAPI
686 IN EFI_HANDLE ImageHandle,
687 IN EFI_SYSTEM_TABLE *SystemTable
688 )
689{
690 EFI_STATUS Status;
693 EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *TableFactoryProtocol;
694
695 // Locate the Dynamic Table Factory
696 Status = gBS->LocateProtocol (
698 NULL,
699 (VOID **)&TableFactoryProtocol
700 );
701 if (EFI_ERROR (Status)) {
702 DEBUG ((
703 DEBUG_ERROR,
704 "ERROR: Failed to find Dynamic Table Factory protocol." \
705 " Status = %r\n",
706 Status
707 ));
708 return Status;
709 }
710
711 // Locate the Configuration Manager for the Platform
712 Status = gBS->LocateProtocol (
714 NULL,
715 (VOID **)&CfgMgrProtocol
716 );
717 if (EFI_ERROR (Status)) {
718 DEBUG ((
719 DEBUG_ERROR,
720 "ERROR: Failed to find Configuration Manager protocol. Status = %r\n",
721 Status
722 ));
723 return Status;
724 }
725
726 Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo);
727 if (EFI_ERROR (Status)) {
728 DEBUG ((
729 DEBUG_ERROR,
730 "ERROR: Failed to get Configuration Manager info. Status = %r\n",
731 Status
732 ));
733 return Status;
734 }
735
736 DEBUG ((
737 DEBUG_INFO,
738 "INFO: Configuration Manager Version = 0x%x, OemID = %c%c%c%c%c%c\n",
739 CfgMfrInfo->Revision,
740 CfgMfrInfo->OemId[0],
741 CfgMfrInfo->OemId[1],
742 CfgMfrInfo->OemId[2],
743 CfgMfrInfo->OemId[3],
744 CfgMfrInfo->OemId[4],
745 CfgMfrInfo->OemId[5]
746 ));
747
748 Status = GetAcpiTablePresenceInfo (
750 &mAcpiVerifyTablesCount,
751 &mAcpiVerifyTablesFadtIndex
752 );
753 if (EFI_ERROR (Status)) {
754 ASSERT_EFI_ERROR (Status);
755 return Status;
756 }
757
758 Status = ProcessAcpiTables (TableFactoryProtocol, CfgMgrProtocol);
759 if (EFI_ERROR (Status)) {
760 DEBUG ((
761 DEBUG_ERROR,
762 "ERROR: ACPI Table processing failure. Status = %r\n",
763 Status
764 ));
765 }
766
767 return Status;
768}
UINT64 UINTN
#define DUMP_ACPI_TABLE_HEADER(AcpiHeader)
#define CREATE_STD_ACPI_TABLE_GEN_ID(TableId)
@ EStdAcpiTableIdFadt
FADT Generator.
@ EStdAcpiTableIdReserved
Reserved.
EFI_STATUS EFIAPI GetAcpiTablePresenceInfo(OUT ACPI_TABLE_PRESENCE_INFO **PresenceArray, OUT UINT32 *PresenceArrayCount, OUT INT32 *FadtIndex)
#define GET_OBJECT_LIST(CmObjectNameSpace, CmObjectId, Type)
@ EObjNameSpaceStandard
Standard Objects Namespace.
EFI_GUID gEdkiiConfigurationManagerProtocolGuid
EFI_GUID gEdkiiDynamicTableFactoryProtocolGuid
STATIC EFI_STATUS EFIAPI BuildAndInstallAcpiTable(IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo)
STATIC EFI_STATUS EFIAPI VerifyMandatoryTablesArePresent(IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN UINT32 AcpiTableCount)
STATIC ACPI_TABLE_PRESENCE_INFO * mAcpiVerifyTables
STATIC EFI_STATUS EFIAPI BuildAndInstallMultipleAcpiTable(IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CONST ACPI_TABLE_GENERATOR *CONST Generator, IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo)
STATIC EFI_STATUS EFIAPI ProcessAcpiTables(IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol)
EFI_STATUS EFIAPI DynamicTableManagerDxeInitialize(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
#define ACPI_TABLE_PRESENT_INFO_LIST
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
@ EStdObjAcpiTableList
1 - ACPI table Info List
#define CM_NULL_TOKEN
#define IS_GENERATOR_NAMESPACE_STD(TableGeneratorId)
EFI_STATUS EFIAPI GetCgfMgrInfo(IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, OUT CM_STD_OBJ_CONFIGURATION_MANAGER_INFO **CfgMfrInfo)
Definition: TableHelper.c:38
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
UINT32 AcpiTableSignature
Standard UINT32 ACPI signature.
UINT32 Revision
The Configuration Manager Revision.