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