]> git.proxmox.com Git - mirror_edk2.git/blob - DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
33f26a2115e0eb7019fcba680ffe57633b69091c
[mirror_edk2.git] / DynamicTablesPkg / Drivers / DynamicTableManagerDxe / DynamicTableManagerDxe.c
1 /** @file
2 Dynamic Table Manager Dxe
3
4 Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
5
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 #include <Library/DebugLib.h>
17 #include <Library/PcdLib.h>
18 #include <Library/UefiBootServicesTableLib.h>
19 #include <Protocol/AcpiTable.h>
20
21 // Module specific include files.
22 #include <AcpiTableGenerator.h>
23 #include <ConfigurationManagerObject.h>
24 #include <ConfigurationManagerHelper.h>
25 #include <DeviceTreeTableGenerator.h>
26 #include <Library/TableHelperLib.h>
27 #include <Protocol/ConfigurationManagerProtocol.h>
28 #include <Protocol/DynamicTableFactoryProtocol.h>
29 #include <SmbiosTableGenerator.h>
30
31 /** This macro expands to a function that retrieves the ACPI Table
32 List from the Configuration Manager.
33 */
34 GET_OBJECT_LIST (
35 EObjNameSpaceStandard,
36 EStdObjAcpiTableList,
37 CM_STD_OBJ_ACPI_TABLE_INFO
38 )
39
40 /** A helper function to build and install a single ACPI table.
41
42 This is a helper function that invokes the Table generator interface
43 for building an ACPI table. It uses the AcpiTableProtocol to install the
44 table, then frees the resources allocated for generating it.
45
46 @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
47 interface.
48 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
49 Protocol Interface.
50 @param [in] Generator Pointer to the AcpiTable generator.
51 @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol.
52 @param [in] AcpiTableInfo Pointer to the ACPI table Info.
53
54 @retval EFI_SUCCESS Success.
55 @retval EFI_INVALID_PARAMETER A parameter is invalid.
56 @retval EFI_NOT_FOUND Required object is not found.
57 @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
58 is less than the Object size for the
59 requested object.
60 **/
61 STATIC
62 EFI_STATUS
63 EFIAPI
64 BuildAndInstallSingleAcpiTable (
65 IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol,
66 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
67 IN CONST ACPI_TABLE_GENERATOR * CONST Generator,
68 IN EFI_ACPI_TABLE_PROTOCOL * AcpiTableProtocol,
69 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo
70 )
71 {
72 EFI_STATUS Status;
73 EFI_STATUS Status1;
74 EFI_ACPI_DESCRIPTION_HEADER * AcpiTable;
75 UINTN TableHandle;
76
77 AcpiTable = NULL;
78 Status = Generator->BuildAcpiTable (
79 Generator,
80 AcpiTableInfo,
81 CfgMgrProtocol,
82 &AcpiTable
83 );
84 if (EFI_ERROR (Status)) {
85 DEBUG ((
86 DEBUG_ERROR,
87 "ERROR: Failed to Build Table." \
88 " TableGeneratorId = 0x%x. Status = %r\n",
89 AcpiTableInfo->TableGeneratorId,
90 Status
91 ));
92 // Free any allocated resources.
93 goto exit_handler;
94 }
95
96 if (AcpiTable == NULL) {
97 Status = EFI_NOT_FOUND;
98 goto exit_handler;
99 }
100
101 // Dump ACPI Table Header
102 DUMP_ACPI_TABLE_HEADER (AcpiTable);
103
104 // Install ACPI table
105 Status = AcpiTableProtocol->InstallAcpiTable (
106 AcpiTableProtocol,
107 AcpiTable,
108 AcpiTable->Length,
109 &TableHandle
110 );
111 if (EFI_ERROR (Status)) {
112 DEBUG ((
113 DEBUG_ERROR,
114 "ERROR: Failed to Install ACPI Table. Status = %r\n",
115 Status
116 ));
117 // Free any allocated resources.
118 goto exit_handler;
119 }
120
121 DEBUG ((
122 DEBUG_INFO,
123 "INFO: ACPI Table installed. Status = %r\n",
124 Status
125 ));
126
127 exit_handler:
128 // Free any resources allocated for generating the tables.
129 if (Generator->FreeTableResources != NULL) {
130 Status1 = Generator->FreeTableResources (
131 Generator,
132 AcpiTableInfo,
133 CfgMgrProtocol,
134 &AcpiTable
135 );
136 if (EFI_ERROR (Status1)) {
137 DEBUG ((
138 DEBUG_ERROR,
139 "ERROR: Failed to Free Table Resources." \
140 "TableGeneratorId = 0x%x. Status = %r\n",
141 AcpiTableInfo->TableGeneratorId,
142 Status1
143 ));
144 }
145
146 // Return the first error status in case of failure
147 if (!EFI_ERROR (Status)) {
148 Status = Status1;
149 }
150 }
151 return Status;
152 }
153
154 /** A helper function to build and install multiple ACPI tables.
155
156 This is a helper function that invokes the Table generator interface
157 for building an ACPI table. It uses the AcpiTableProtocol to install the
158 table, then frees the resources allocated for generating it.
159
160 @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
161 interface.
162 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
163 Protocol Interface.
164 @param [in] Generator Pointer to the AcpiTable generator.
165 @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol.
166 @param [in] AcpiTableInfo Pointer to the ACPI table Info.
167
168 @retval EFI_SUCCESS Success.
169 @retval EFI_INVALID_PARAMETER A parameter is invalid.
170 @retval EFI_NOT_FOUND Required object is not found.
171 @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
172 is less than the Object size for the
173 requested object.
174 **/
175 STATIC
176 EFI_STATUS
177 EFIAPI
178 BuildAndInstallMultipleAcpiTable (
179 IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol,
180 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
181 IN CONST ACPI_TABLE_GENERATOR * CONST Generator,
182 IN EFI_ACPI_TABLE_PROTOCOL * AcpiTableProtocol,
183 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo
184 )
185 {
186 EFI_STATUS Status;
187 EFI_STATUS Status1;
188 EFI_ACPI_DESCRIPTION_HEADER ** AcpiTable;
189 UINTN TableCount;
190 UINTN TableHandle;
191 UINTN Index;
192
193 AcpiTable = NULL;
194 TableCount = 0;
195 Status = Generator->BuildAcpiTableEx (
196 Generator,
197 AcpiTableInfo,
198 CfgMgrProtocol,
199 &AcpiTable,
200 &TableCount
201 );
202 if (EFI_ERROR (Status)) {
203 DEBUG ((
204 DEBUG_ERROR,
205 "ERROR: Failed to Build Table." \
206 " TableGeneratorId = 0x%x. Status = %r\n",
207 AcpiTableInfo->TableGeneratorId,
208 Status
209 ));
210 // Free any allocated resources.
211 goto exit_handler;
212 }
213
214 if ((AcpiTable == NULL) || (TableCount == 0)) {
215 Status = EFI_NOT_FOUND;
216 goto exit_handler;
217 }
218
219 for (Index = 0; Index < TableCount; Index++) {
220 // Dump ACPI Table Header
221 DUMP_ACPI_TABLE_HEADER (AcpiTable[Index]);
222 // Install ACPI table
223 Status = AcpiTableProtocol->InstallAcpiTable (
224 AcpiTableProtocol,
225 AcpiTable[Index],
226 AcpiTable[Index]->Length,
227 &TableHandle
228 );
229 if (EFI_ERROR (Status)) {
230 DEBUG ((
231 DEBUG_ERROR,
232 "ERROR: Failed to Install ACPI Table. Status = %r\n",
233 Status
234 ));
235 // Free any allocated resources.
236 goto exit_handler;
237 }
238
239 DEBUG ((
240 DEBUG_INFO,
241 "INFO: ACPI Table installed. Status = %r\n",
242 Status
243 ));
244 }
245
246 exit_handler:
247 // Free any resources allocated for generating the tables.
248 if (Generator->FreeTableResourcesEx != NULL) {
249 Status1 = Generator->FreeTableResourcesEx (
250 Generator,
251 AcpiTableInfo,
252 CfgMgrProtocol,
253 &AcpiTable,
254 TableCount
255 );
256 if (EFI_ERROR (Status1)) {
257 DEBUG ((
258 DEBUG_ERROR,
259 "ERROR: Failed to Free Table Resources." \
260 "TableGeneratorId = 0x%x. Status = %r\n",
261 AcpiTableInfo->TableGeneratorId,
262 Status1
263 ));
264 }
265
266 // Return the first error status in case of failure
267 if (!EFI_ERROR (Status)) {
268 Status = Status1;
269 }
270 }
271 return Status;
272 }
273
274 /** A helper function to invoke a Table generator
275
276 This is a helper function that invokes the Table generator interface
277 for building an ACPI table. It uses the AcpiTableProtocol to install the
278 table, then frees the resources allocated for generating it.
279
280 @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
281 interface.
282 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
283 Protocol Interface.
284 @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol.
285 @param [in] AcpiTableInfo Pointer to the ACPI table Info.
286
287 @retval EFI_SUCCESS Success.
288 @retval EFI_INVALID_PARAMETER A parameter is invalid.
289 @retval EFI_NOT_FOUND Required object is not found.
290 @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager
291 is less than the Object size for the
292 requested object.
293 **/
294 STATIC
295 EFI_STATUS
296 EFIAPI
297 BuildAndInstallAcpiTable (
298 IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol,
299 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
300 IN EFI_ACPI_TABLE_PROTOCOL * AcpiTableProtocol,
301 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo
302 )
303 {
304 EFI_STATUS Status;
305 CONST ACPI_TABLE_GENERATOR * Generator;
306
307 ASSERT (TableFactoryProtocol != NULL);
308 ASSERT (CfgMgrProtocol != NULL);
309 ASSERT (AcpiTableProtocol != NULL);
310 ASSERT (AcpiTableInfo != NULL);
311
312 DEBUG ((
313 DEBUG_INFO,
314 "INFO: EStdObjAcpiTableList: Address = 0x%p," \
315 " TableGeneratorId = 0x%x\n",
316 AcpiTableInfo,
317 AcpiTableInfo->TableGeneratorId
318 ));
319
320 Generator = NULL;
321 Status = TableFactoryProtocol->GetAcpiTableGenerator (
322 TableFactoryProtocol,
323 AcpiTableInfo->TableGeneratorId,
324 &Generator
325 );
326 if (EFI_ERROR (Status)) {
327 DEBUG ((
328 DEBUG_ERROR,
329 "ERROR: Table Generator not found." \
330 " TableGeneratorId = 0x%x. Status = %r\n",
331 AcpiTableInfo->TableGeneratorId,
332 Status
333 ));
334 return Status;
335 }
336
337 if (Generator == NULL) {
338 return EFI_NOT_FOUND;
339 }
340
341 DEBUG ((
342 DEBUG_INFO,
343 "INFO: Generator found : %s\n",
344 Generator->Description
345 ));
346
347 if (Generator->BuildAcpiTableEx != NULL) {
348 Status = BuildAndInstallMultipleAcpiTable (
349 TableFactoryProtocol,
350 CfgMgrProtocol,
351 Generator,
352 AcpiTableProtocol,
353 AcpiTableInfo
354 );
355 if (EFI_ERROR (Status)) {
356 DEBUG ((
357 DEBUG_ERROR,
358 "ERROR: Failed to find build and install ACPI Table." \
359 " Status = %r\n",
360 Status
361 ));
362 }
363 } else if (Generator->BuildAcpiTable != NULL) {
364 Status = BuildAndInstallSingleAcpiTable (
365 TableFactoryProtocol,
366 CfgMgrProtocol,
367 Generator,
368 AcpiTableProtocol,
369 AcpiTableInfo
370 );
371 if (EFI_ERROR (Status)) {
372 DEBUG ((
373 DEBUG_ERROR,
374 "ERROR: Failed to find build and install ACPI Table." \
375 " Status = %r\n",
376 Status
377 ));
378 }
379 } else {
380 Status = EFI_INVALID_PARAMETER;
381 DEBUG ((
382 DEBUG_ERROR,
383 "ERROR: Table Generator does not implement the" \
384 " ACPI_TABLE_GENERATOR_BUILD_TABLE interface." \
385 " TableGeneratorId = 0x%x. Status = %r\n",
386 AcpiTableInfo->TableGeneratorId,
387 Status
388 ));
389 }
390
391 return Status;
392 }
393
394 /** The function checks if the Configuration Manager has provided the
395 mandatory ACPI tables for installation.
396
397 @param [in] AcpiTableInfo Pointer to the ACPI Table Info list.
398 @param [in] AcpiTableCount Count of ACPI Table Info.
399
400 @retval EFI_SUCCESS Success.
401 @retval EFI_NOT_FOUND If mandatory table is not found.
402 **/
403 STATIC
404 EFI_STATUS
405 EFIAPI
406 VerifyMandatoryTablesArePresent (
407 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
408 IN UINT32 AcpiTableCount
409 )
410 {
411 EFI_STATUS Status;
412 BOOLEAN FadtFound;
413 BOOLEAN MadtFound;
414 BOOLEAN GtdtFound;
415 BOOLEAN DsdtFound;
416 BOOLEAN Dbg2Found;
417 BOOLEAN SpcrFound;
418
419 Status = EFI_SUCCESS;
420 FadtFound = FALSE;
421 MadtFound = FALSE;
422 GtdtFound = FALSE;
423 DsdtFound = FALSE;
424 Dbg2Found = FALSE;
425 SpcrFound = FALSE;
426 ASSERT (AcpiTableInfo != NULL);
427
428 while (AcpiTableCount-- != 0) {
429 switch (AcpiTableInfo[AcpiTableCount].AcpiTableSignature) {
430 case EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
431 FadtFound = TRUE;
432 break;
433 case EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
434 MadtFound = TRUE;
435 break;
436 case EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE:
437 GtdtFound = TRUE;
438 break;
439 case EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
440 DsdtFound = TRUE;
441 break;
442 case EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE:
443 Dbg2Found = TRUE;
444 break;
445 case EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE:
446 SpcrFound = TRUE;
447 break;
448 default:
449 break;
450 }
451 }
452
453 // We need at least the FADT, MADT, GTDT and the DSDT tables to boot
454 if (!FadtFound) {
455 DEBUG ((DEBUG_ERROR,"ERROR: FADT Table not found\n"));
456 Status = EFI_NOT_FOUND;
457 }
458 if (!MadtFound) {
459 DEBUG ((DEBUG_ERROR, "ERROR: MADT Table not found.\n"));
460 Status = EFI_NOT_FOUND;
461 }
462 if (!GtdtFound) {
463 DEBUG ((DEBUG_ERROR, "ERROR: GTDT Table not found.\n"));
464 Status = EFI_NOT_FOUND;
465 }
466 if (!DsdtFound) {
467 DEBUG ((DEBUG_ERROR, "ERROR: DSDT Table not found.\n"));
468 Status = EFI_NOT_FOUND;
469 }
470 if (!Dbg2Found) {
471 DEBUG ((DEBUG_WARN, "WARNING: DBG2 Table not found.\n"));
472 }
473 if (!SpcrFound) {
474 DEBUG ((DEBUG_WARN, "WARNING: SPCR Table not found.\n"));
475 }
476 return Status;
477 }
478
479 /** Generate and install ACPI tables.
480
481 The function gathers the information necessary for installing the
482 ACPI tables from the Configuration Manager, invokes the generators
483 and installs them (via BuildAndInstallAcpiTable).
484
485 @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol
486 interface.
487 @param [in] CfgMgrProtocol Pointer to the Configuration Manager
488 Protocol Interface.
489
490 @retval EFI_SUCCESS Success.
491 @retval EFI_NOT_FOUND If a mandatory table or a generator is not found.
492 **/
493 STATIC
494 EFI_STATUS
495 EFIAPI
496 ProcessAcpiTables (
497 IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol,
498 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol
499 )
500 {
501 EFI_STATUS Status;
502 EFI_ACPI_TABLE_PROTOCOL * AcpiTableProtocol;
503 CM_STD_OBJ_ACPI_TABLE_INFO * AcpiTableInfo;
504 UINT32 AcpiTableCount;
505 UINT32 Idx;
506
507 ASSERT (TableFactoryProtocol != NULL);
508 ASSERT (CfgMgrProtocol != NULL);
509
510 // Find the AcpiTable protocol
511 Status = gBS->LocateProtocol (
512 &gEfiAcpiTableProtocolGuid,
513 NULL,
514 (VOID**)&AcpiTableProtocol
515 );
516 if (EFI_ERROR (Status)) {
517 DEBUG ((
518 DEBUG_ERROR,
519 "ERROR: Failed to find AcpiTable protocol. Status = %r\n",
520 Status
521 ));
522 return Status;
523 }
524
525 Status = GetEStdObjAcpiTableList (
526 CfgMgrProtocol,
527 CM_NULL_TOKEN,
528 &AcpiTableInfo,
529 &AcpiTableCount
530 );
531 if (EFI_ERROR (Status)) {
532 DEBUG ((
533 DEBUG_ERROR,
534 "ERROR: Failed to get ACPI Table List. Status = %r\n",
535 Status
536 ));
537 return Status;
538 }
539
540 if (0 == AcpiTableCount) {
541 DEBUG ((
542 DEBUG_ERROR,
543 "ERROR: EStdObjAcpiTableList: AcpiTableCount = %d\n",
544 AcpiTableCount
545 ));
546 return EFI_NOT_FOUND;
547 }
548
549 DEBUG ((
550 DEBUG_INFO,
551 "INFO: EStdObjAcpiTableList: AcpiTableCount = %d\n",
552 AcpiTableCount
553 ));
554
555 // Check if mandatory ACPI tables are present.
556 Status = VerifyMandatoryTablesArePresent (
557 AcpiTableInfo,
558 AcpiTableCount
559 );
560 if (EFI_ERROR (Status)) {
561 DEBUG ((
562 DEBUG_ERROR,
563 "ERROR: Failed to find mandatory ACPI Table(s)."
564 " Status = %r\n",
565 Status
566 ));
567 return Status;
568 }
569
570 // Add the FADT Table first.
571 for (Idx = 0; Idx < AcpiTableCount; Idx++) {
572 if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) ==
573 AcpiTableInfo[Idx].TableGeneratorId) {
574 Status = BuildAndInstallAcpiTable (
575 TableFactoryProtocol,
576 CfgMgrProtocol,
577 AcpiTableProtocol,
578 &AcpiTableInfo[Idx]
579 );
580 if (EFI_ERROR (Status)) {
581 DEBUG ((
582 DEBUG_ERROR,
583 "ERROR: Failed to find build and install ACPI FADT Table." \
584 " Status = %r\n",
585 Status
586 ));
587 return Status;
588 }
589 break;
590 }
591 } // for
592
593 // Add remaining ACPI Tables
594 for (Idx = 0; Idx < AcpiTableCount; Idx++) {
595 DEBUG ((
596 DEBUG_INFO,
597 "INFO: AcpiTableInfo[%d].TableGeneratorId = 0x%x\n",
598 Idx,
599 AcpiTableInfo[Idx].TableGeneratorId
600 ));
601
602 // Skip FADT Table since we have already added
603 if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) ==
604 AcpiTableInfo[Idx].TableGeneratorId) {
605 continue;
606 }
607
608 // Skip the Reserved table Generator ID for standard generators
609 if ((IS_GENERATOR_NAMESPACE_STD (AcpiTableInfo[Idx].TableGeneratorId)) &&
610 ((CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdReserved) >=
611 AcpiTableInfo[Idx].TableGeneratorId) ||
612 (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMax) <=
613 AcpiTableInfo[Idx].TableGeneratorId))) {
614 DEBUG ((
615 DEBUG_WARN,
616 "WARNING: Invalid ACPI Generator table ID = 0x%x, Skipping...\n",
617 AcpiTableInfo[Idx].TableGeneratorId
618 ));
619 continue;
620 }
621
622 Status = BuildAndInstallAcpiTable (
623 TableFactoryProtocol,
624 CfgMgrProtocol,
625 AcpiTableProtocol,
626 &AcpiTableInfo[Idx]
627 );
628 if (EFI_ERROR (Status)) {
629 DEBUG ((
630 DEBUG_ERROR,
631 "ERROR: Failed to find, build, and install ACPI Table." \
632 " Status = %r\n",
633 Status
634 ));
635 return Status;
636 }
637 } // for
638
639 return Status;
640 }
641
642 /** Entrypoint of Dynamic Table Manager Dxe.
643
644 The Dynamic Table Manager uses the Configuration Manager Protocol
645 to get the list of ACPI and SMBIOS tables to install. For each table
646 in the list it requests the corresponding ACPI/SMBIOS table factory for
647 a generator capable of building the ACPI/SMBIOS table.
648 If a suitable table generator is found, it invokes the generator interface
649 to build the table. The Dynamic Table Manager then installs the
650 table and invokes another generator interface to free any resources
651 allocated for building the table.
652
653 @param ImageHandle
654 @param SystemTable
655
656 @retval EFI_SUCCESS Success.
657 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
658 @retval EFI_NOT_FOUND Required interface/object was not found.
659 @retval EFI_INVALID_PARAMETER Some parameter is incorrect/invalid.
660 **/
661 EFI_STATUS
662 EFIAPI
663 DynamicTableManagerDxeInitialize (
664 IN CONST EFI_HANDLE ImageHandle,
665 IN EFI_SYSTEM_TABLE * CONST SystemTable
666 )
667 {
668 EFI_STATUS Status;
669 EDKII_CONFIGURATION_MANAGER_PROTOCOL * CfgMgrProtocol;
670 CM_STD_OBJ_CONFIGURATION_MANAGER_INFO * CfgMfrInfo;
671 EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * TableFactoryProtocol;
672
673 // Locate the Dynamic Table Factory
674 Status = gBS->LocateProtocol (
675 &gEdkiiDynamicTableFactoryProtocolGuid,
676 NULL,
677 (VOID**)&TableFactoryProtocol
678 );
679 if (EFI_ERROR (Status)) {
680 DEBUG ((
681 DEBUG_ERROR,
682 "ERROR: Failed to find Dynamic Table Factory protocol." \
683 " Status = %r\n",
684 Status
685 ));
686 return Status;
687 }
688
689 // Locate the Configuration Manager for the Platform
690 Status = gBS->LocateProtocol (
691 &gEdkiiConfigurationManagerProtocolGuid,
692 NULL,
693 (VOID**)&CfgMgrProtocol
694 );
695 if (EFI_ERROR (Status)) {
696 DEBUG ((
697 DEBUG_ERROR,
698 "ERROR: Failed to find Configuration Manager protocol. Status = %r\n",
699 Status
700 ));
701 return Status;
702 }
703
704 Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo);
705 if (EFI_ERROR (Status)) {
706 DEBUG ((
707 DEBUG_ERROR,
708 "ERROR: Failed to get Configuration Manager info. Status = %r\n",
709 Status
710 ));
711 return Status;
712 }
713
714 DEBUG ((
715 DEBUG_INFO,
716 "INFO: Configuration Manager Version = 0x%x, OemID = %c%c%c%c%c%c\n",
717 CfgMfrInfo->Revision,
718 CfgMfrInfo->OemId[0],
719 CfgMfrInfo->OemId[1],
720 CfgMfrInfo->OemId[2],
721 CfgMfrInfo->OemId[3],
722 CfgMfrInfo->OemId[4],
723 CfgMfrInfo->OemId[5]
724 ));
725
726 Status = ProcessAcpiTables (TableFactoryProtocol, CfgMgrProtocol);
727 if (EFI_ERROR (Status)) {
728 DEBUG ((
729 DEBUG_ERROR,
730 "ERROR: ACPI Table processing failure. Status = %r\n",
731 Status
732 ));
733 }
734 return Status;
735 }