]> git.proxmox.com Git - mirror_edk2.git/blob - ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c
ArmVirtPkg/Kvmtool: Add Configuration Manager
[mirror_edk2.git] / ArmVirtPkg / KvmtoolCfgMgrDxe / ConfigurationManager.c
1 /** @file
2 Configuration Manager Dxe
3
4 Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 @par Glossary:
9 - Cm or CM - Configuration Manager
10 - Obj or OBJ - Object
11 **/
12
13 #include <IndustryStandard/DebugPort2Table.h>
14 #include <IndustryStandard/IoRemappingTable.h>
15 #include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
16 #include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/DynamicPlatRepoLib.h>
20 #include <Library/HobLib.h>
21 #include <Library/HwInfoParserLib.h>
22 #include <Library/IoLib.h>
23 #include <Library/PcdLib.h>
24 #include <Library/TableHelperLib.h>
25 #include <Library/UefiBootServicesTableLib.h>
26 #include <Protocol/AcpiTable.h>
27 #include <Protocol/ConfigurationManagerProtocol.h>
28
29 #include "ConfigurationManager.h"
30
31 //
32 // The platform configuration repository information.
33 //
34 STATIC
35 EDKII_PLATFORM_REPOSITORY_INFO mKvmtoolPlatRepositoryInfo = {
36 //
37 // Configuration Manager information
38 //
39 { CONFIGURATION_MANAGER_REVISION, CFG_MGR_OEM_ID },
40
41 //
42 // ACPI Table List
43 //
44 {
45 //
46 // FADT Table
47 //
48 {
49 EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
50 EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
51 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt),
52 NULL
53 },
54 //
55 // GTDT Table
56 //
57 {
58 EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
59 EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION,
60 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdGtdt),
61 NULL
62 },
63 //
64 // MADT Table
65 //
66 {
67 EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
68 EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
69 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMadt),
70 NULL
71 },
72 //
73 // SPCR Table
74 //
75 {
76 EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
77 EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION,
78 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpcr),
79 NULL
80 },
81 //
82 // DSDT Table
83 //
84 {
85 EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
86 0, // Unused
87 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDsdt),
88 (EFI_ACPI_DESCRIPTION_HEADER *)dsdt_aml_code
89 },
90 //
91 // SSDT Cpu Hierarchy Table
92 //
93 {
94 EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
95 0, // Unused
96 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtCpuTopology),
97 NULL
98 },
99 //
100 // DBG2 Table
101 //
102 {
103 EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
104 EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,
105 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2),
106 NULL
107 },
108 //
109 // PCI MCFG Table
110 //
111 {
112 EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
113 EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,
114 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMcfg),
115 NULL
116 },
117 //
118 // SSDT table describing the PCI root complex
119 //
120 {
121 EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
122 0, // Unused
123 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtPciExpress),
124 NULL
125 },
126 //
127 // IORT Table
128 //
129 {
130 EFI_ACPI_6_3_IO_REMAPPING_TABLE_SIGNATURE,
131 EFI_ACPI_IO_REMAPPING_TABLE_REVISION,
132 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdIort),
133 NULL
134 },
135 },
136
137 //
138 // Power management profile information
139 //
140 { EFI_ACPI_6_3_PM_PROFILE_ENTERPRISE_SERVER }, // PowerManagement Profile
141
142 //
143 // ITS group node
144 //
145 {
146 //
147 // Reference token for this Iort node
148 //
149 REFERENCE_TOKEN (ItsGroupInfo),
150 //
151 // The number of ITS identifiers in the ITS node.
152 //
153 1,
154 //
155 // Reference token for the ITS identifier array
156 //
157 REFERENCE_TOKEN (ItsIdentifierArray)
158 },
159
160 //
161 // ITS identifier array
162 //
163 {
164 { 0 }, // The ITS Identifier
165 },
166
167 //
168 // Root Complex node info
169 //
170 {
171 //
172 // Reference token for this Iort node
173 //
174 REFERENCE_TOKEN (RootComplexInfo),
175 //
176 // Number of ID mappings
177 //
178 1,
179 //
180 // Reference token for the ID mapping array
181 //
182 REFERENCE_TOKEN (DeviceIdMapping[0]),
183 //
184 // Memory access properties : Cache coherent attributes
185 //
186 EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA,
187 //
188 // Memory access properties : Allocation hints
189 //
190 0,
191 //
192 // Memory access properties : Memory access flags
193 //
194 0,
195 //
196 // ATS attributes
197 //
198 EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED,
199 //
200 // PCI segment number
201 //
202 0,
203 ///
204 /// Memory address size limit
205 ///
206 MEMORY_ADDRESS_SIZE_LIMIT
207 },
208
209 //
210 // Array of Device ID mappings
211 //
212 {
213 //
214 // Device ID mapping for Root complex node
215 // RootComplex -> ITS Group
216 //
217 {
218 //
219 // Input base
220 //
221 0x0,
222 //
223 // Number of input IDs
224 //
225 0x0000FFFF,
226 //
227 // Output Base
228 //
229 0x0,
230 //
231 // Output reference
232 //
233 REFERENCE_TOKEN (ItsGroupInfo),
234 //
235 // Flags
236 //
237 0
238 },
239 },
240 };
241
242 /**
243 A helper function for returning the Configuration Manager Objects.
244
245 @param [in] CmObjectId The Configuration Manager Object ID.
246 @param [in] Object Pointer to the Object(s).
247 @param [in] ObjectSize Total size of the Object(s).
248 @param [in] ObjectCount Number of Objects.
249 @param [in, out] CmObjectDesc Pointer to the Configuration Manager Object
250 descriptor describing the requested Object.
251
252 @retval EFI_SUCCESS Success.
253 **/
254 STATIC
255 EFI_STATUS
256 EFIAPI
257 HandleCmObject (
258 IN CONST CM_OBJECT_ID CmObjectId,
259 IN VOID *Object,
260 IN CONST UINTN ObjectSize,
261 IN CONST UINTN ObjectCount,
262 IN OUT CM_OBJ_DESCRIPTOR *CONST CmObjectDesc
263 )
264 {
265 CmObjectDesc->ObjectId = CmObjectId;
266 CmObjectDesc->Size = ObjectSize;
267 CmObjectDesc->Data = Object;
268 CmObjectDesc->Count = ObjectCount;
269 DEBUG ((
270 DEBUG_INFO,
271 "INFO: CmObjectId = " FMT_CM_OBJECT_ID ", "
272 "Ptr = 0x%p, Size = %lu, Count = %lu\n",
273 CmObjectId,
274 CmObjectDesc->Data,
275 CmObjectDesc->Size,
276 CmObjectDesc->Count
277 ));
278 return EFI_SUCCESS;
279 }
280
281 /**
282 A helper function for returning the Configuration Manager Objects that
283 match the token.
284
285 @param [in] This Pointer to the Configuration Manager Protocol.
286 @param [in] CmObjectId The Configuration Manager Object ID.
287 @param [in] Object Pointer to the Object(s).
288 @param [in] ObjectSize Total size of the Object(s).
289 @param [in] ObjectCount Number of Objects.
290 @param [in] Token A token identifying the object.
291 @param [in] HandlerProc A handler function to search the object
292 referenced by the token.
293 @param [in, out] CmObjectDesc Pointer to the Configuration Manager Object
294 descriptor describing the requested Object.
295
296 @retval EFI_SUCCESS Success.
297 @retval EFI_INVALID_PARAMETER A parameter is invalid.
298 @retval EFI_NOT_FOUND The required object information is not found.
299 **/
300 STATIC
301 EFI_STATUS
302 EFIAPI
303 HandleCmObjectRefByToken (
304 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
305 IN CONST CM_OBJECT_ID CmObjectId,
306 IN VOID *Object,
307 IN CONST UINTN ObjectSize,
308 IN CONST UINTN ObjectCount,
309 IN CONST CM_OBJECT_TOKEN Token,
310 IN CONST CM_OBJECT_HANDLER_PROC HandlerProc,
311 IN OUT CM_OBJ_DESCRIPTOR *CONST CmObjectDesc
312 )
313 {
314 EFI_STATUS Status;
315
316 CmObjectDesc->ObjectId = CmObjectId;
317 if (Token == CM_NULL_TOKEN) {
318 CmObjectDesc->Size = ObjectSize;
319 CmObjectDesc->Data = Object;
320 CmObjectDesc->Count = ObjectCount;
321 Status = EFI_SUCCESS;
322 } else {
323 Status = HandlerProc (This, CmObjectId, Token, CmObjectDesc);
324 }
325
326 DEBUG ((
327 DEBUG_INFO,
328 "INFO: Token = 0x%p, CmObjectId = " FMT_CM_OBJECT_ID ", "
329 "Ptr = 0x%p, Size = %lu, Count = %lu\n",
330 (VOID *)Token,
331 CmObjectId,
332 CmObjectDesc->Data,
333 CmObjectDesc->Size,
334 CmObjectDesc->Count
335 ));
336 return Status;
337 }
338
339 /**
340 Return an ITS identifier array.
341
342 @param [in] This Pointer to the Configuration Manager Protocol.
343 @param [in] CmObjectId The Configuration Manager Object ID.
344 @param [in] Token A token for identifying the object
345 @param [out] CmObject Pointer to the Configuration Manager Object
346 descriptor describing the requested Object.
347
348 @retval EFI_SUCCESS Success.
349 @retval EFI_INVALID_PARAMETER A parameter is invalid.
350 @retval EFI_NOT_FOUND The required object information is not found.
351 **/
352 EFI_STATUS
353 EFIAPI
354 GetItsIdentifierArray (
355 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
356 IN CONST CM_OBJECT_ID CmObjectId,
357 IN CONST CM_OBJECT_TOKEN Token,
358 OUT CM_OBJ_DESCRIPTOR *CONST CmObject
359 )
360 {
361 EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo;
362
363 if ((This == NULL) || (CmObject == NULL)) {
364 ASSERT (This != NULL);
365 ASSERT (CmObject != NULL);
366 return EFI_INVALID_PARAMETER;
367 }
368
369 PlatformRepo = This->PlatRepoInfo;
370
371 if (Token != (CM_OBJECT_TOKEN)&PlatformRepo->ItsIdentifierArray) {
372 return EFI_NOT_FOUND;
373 }
374
375 CmObject->ObjectId = CmObjectId;
376 CmObject->Size = sizeof (PlatformRepo->ItsIdentifierArray);
377 CmObject->Data = (VOID *)&PlatformRepo->ItsIdentifierArray;
378 CmObject->Count = ARRAY_SIZE (PlatformRepo->ItsIdentifierArray);
379 return EFI_SUCCESS;
380 }
381
382 /**
383 Return a device Id mapping array.
384
385 @param [in] This Pointer to the Configuration Manager Protocol.
386 @param [in] CmObjectId The Configuration Manager Object ID.
387 @param [in] Token A token for identifying the object
388 @param [out] CmObject Pointer to the Configuration Manager Object
389 descriptor describing the requested Object.
390
391 @retval EFI_SUCCESS Success.
392 @retval EFI_INVALID_PARAMETER A parameter is invalid.
393 @retval EFI_NOT_FOUND The required object information is not found.
394 **/
395 EFI_STATUS
396 EFIAPI
397 GetDeviceIdMappingArray (
398 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
399 IN CONST CM_OBJECT_ID CmObjectId,
400 IN CONST CM_OBJECT_TOKEN Token,
401 OUT CM_OBJ_DESCRIPTOR *CONST CmObject
402 )
403 {
404 EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo;
405
406 if ((This == NULL) || (CmObject == NULL)) {
407 ASSERT (This != NULL);
408 ASSERT (CmObject != NULL);
409 return EFI_INVALID_PARAMETER;
410 }
411
412 PlatformRepo = This->PlatRepoInfo;
413
414 if (Token != (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[0]) {
415 return EFI_NOT_FOUND;
416 }
417
418 CmObject->ObjectId = CmObjectId;
419 CmObject->Size = sizeof (CM_ARM_ID_MAPPING);
420 CmObject->Data = (VOID *)Token;
421 CmObject->Count = 1;
422 return EFI_SUCCESS;
423 }
424
425 /**
426 Function pointer called by the parser to add information.
427
428 Callback function that the parser can use to add new
429 CmObj. This function must copy the CmObj data and not rely on
430 the parser preserving the CmObj memory.
431 This function is responsible of the Token allocation.
432
433 @param [in] ParserHandle A handle to the parser instance.
434 @param [in] Context A pointer to the caller's context provided in
435 HwInfoParserInit ().
436 @param [in] CmObjDesc CM_OBJ_DESCRIPTOR containing the CmObj(s) to add.
437 @param [out] Token If provided and success, contain the token
438 generated for the CmObj.
439
440 @retval EFI_SUCCESS The function completed successfully.
441 @retval EFI_INVALID_PARAMETER Invalid parameter.
442 **/
443 STATIC
444 EFI_STATUS
445 EFIAPI
446 HwInfoAdd (
447 IN HW_INFO_PARSER_HANDLE ParserHandle,
448 IN VOID *Context,
449 IN CONST CM_OBJ_DESCRIPTOR *CmObjDesc,
450 OUT CM_OBJECT_TOKEN *Token OPTIONAL
451 )
452 {
453 EFI_STATUS Status;
454 EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo;
455
456 if ((ParserHandle == NULL) ||
457 (Context == NULL) ||
458 (CmObjDesc == NULL))
459 {
460 ASSERT (ParserHandle != NULL);
461 ASSERT (Context != NULL);
462 ASSERT (CmObjDesc != NULL);
463 return EFI_INVALID_PARAMETER;
464 }
465
466 PlatformRepo = (EDKII_PLATFORM_REPOSITORY_INFO *)Context;
467
468 DEBUG_CODE_BEGIN ();
469 //
470 // Print the received objects.
471 //
472 ParseCmObjDesc (CmObjDesc);
473 DEBUG_CODE_END ();
474
475 Status = DynPlatRepoAddObject (
476 PlatformRepo->DynamicPlatformRepo,
477 CmObjDesc,
478 Token
479 );
480 if (EFI_ERROR (Status)) {
481 ASSERT_EFI_ERROR (Status);
482 }
483
484 return Status;
485 }
486
487 /**
488 Cleanup the platform configuration repository.
489
490 @param [in] This Pointer to the Configuration Manager Protocol.
491
492 @retval EFI_SUCCESS Success
493 @retval EFI_INVALID_PARAMETER A parameter is invalid.
494 **/
495 STATIC
496 EFI_STATUS
497 EFIAPI
498 CleanupPlatformRepository (
499 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This
500 )
501 {
502 EFI_STATUS Status;
503 EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo;
504
505 if (This == NULL) {
506 ASSERT (This != NULL);
507 return EFI_INVALID_PARAMETER;
508 }
509
510 PlatformRepo = This->PlatRepoInfo;
511
512 //
513 // Shutdown the dynamic repo and free all objects.
514 //
515 Status = DynamicPlatRepoShutdown (PlatformRepo->DynamicPlatformRepo);
516 if (EFI_ERROR (Status)) {
517 ASSERT_EFI_ERROR (Status);
518 return Status;
519 }
520
521 //
522 // Shutdown parser.
523 //
524 Status = HwInfoParserShutdown (PlatformRepo->FdtParserHandle);
525 if (EFI_ERROR (Status)) {
526 ASSERT_EFI_ERROR (Status);
527 }
528
529 return Status;
530 }
531
532 /**
533 Initialize the platform configuration repository.
534
535 @param [in] This Pointer to the Configuration Manager Protocol.
536
537 @retval EFI_SUCCESS Success
538 @retval EFI_INVALID_PARAMETER A parameter is invalid.
539 @retval EFI_OUT_OF_RESOURCES An allocation has failed.
540 **/
541 STATIC
542 EFI_STATUS
543 EFIAPI
544 InitializePlatformRepository (
545 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This
546 )
547 {
548 EFI_STATUS Status;
549 EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo;
550 VOID *Hob;
551
552 if (This == NULL) {
553 ASSERT (This != NULL);
554 return EFI_INVALID_PARAMETER;
555 }
556
557 Hob = GetFirstGuidHob (&gFdtHobGuid);
558 if ((Hob == NULL) || (GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64))) {
559 ASSERT (FALSE);
560 ASSERT (GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64));
561 return EFI_NOT_FOUND;
562 }
563
564 PlatformRepo = This->PlatRepoInfo;
565 PlatformRepo->FdtBase = (VOID *)*(UINTN *)GET_GUID_HOB_DATA (Hob);
566
567 //
568 // Initialise the dynamic platform repository.
569 //
570 Status = DynamicPlatRepoInit (&PlatformRepo->DynamicPlatformRepo);
571 if (EFI_ERROR (Status)) {
572 ASSERT_EFI_ERROR (Status);
573 return Status;
574 }
575
576 //
577 // Initialise the FDT parser
578 //
579 Status = HwInfoParserInit (
580 PlatformRepo->FdtBase,
581 PlatformRepo,
582 HwInfoAdd,
583 &PlatformRepo->FdtParserHandle
584 );
585 if (EFI_ERROR (Status)) {
586 ASSERT_EFI_ERROR (Status);
587 goto ErrorHandler;
588 }
589
590 Status = HwInfoParse (PlatformRepo->FdtParserHandle);
591 if (EFI_ERROR (Status)) {
592 ASSERT_EFI_ERROR (Status);
593 goto ErrorHandler;
594 }
595
596 Status = DynamicPlatRepoFinalise (PlatformRepo->DynamicPlatformRepo);
597 if (EFI_ERROR (Status)) {
598 ASSERT_EFI_ERROR (Status);
599 goto ErrorHandler;
600 }
601
602 return EFI_SUCCESS;
603
604 ErrorHandler:
605 CleanupPlatformRepository (This);
606 return Status;
607 }
608
609 /**
610 Return a standard namespace object.
611
612 @param [in] This Pointer to the Configuration Manager Protocol.
613 @param [in] CmObjectId The Configuration Manager Object ID.
614 @param [in] Token An optional token identifying the object. If
615 unused this must be CM_NULL_TOKEN.
616 @param [in, out] CmObject Pointer to the Configuration Manager Object
617 descriptor describing the requested Object.
618
619 @retval EFI_SUCCESS Success.
620 @retval EFI_INVALID_PARAMETER A parameter is invalid.
621 @retval EFI_NOT_FOUND The required object information is not found.
622 **/
623 EFI_STATUS
624 EFIAPI
625 GetStandardNameSpaceObject (
626 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
627 IN CONST CM_OBJECT_ID CmObjectId,
628 IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
629 IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
630 )
631 {
632 EFI_STATUS Status;
633 EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo;
634 UINTN AcpiTableCount;
635 CM_OBJ_DESCRIPTOR CmObjDesc;
636
637 if ((This == NULL) || (CmObject == NULL)) {
638 ASSERT (This != NULL);
639 ASSERT (CmObject != NULL);
640 return EFI_INVALID_PARAMETER;
641 }
642
643 Status = EFI_NOT_FOUND;
644 PlatformRepo = This->PlatRepoInfo;
645
646 switch (GET_CM_OBJECT_ID (CmObjectId)) {
647 case EStdObjCfgMgrInfo:
648 Status = HandleCmObject (
649 CmObjectId,
650 &PlatformRepo->CmInfo,
651 sizeof (PlatformRepo->CmInfo),
652 1,
653 CmObject
654 );
655 break;
656
657 case EStdObjAcpiTableList:
658 AcpiTableCount = ARRAY_SIZE (PlatformRepo->CmAcpiTableList);
659
660 //
661 // Get Pci config space information.
662 //
663 Status = DynamicPlatRepoGetObject (
664 PlatformRepo->DynamicPlatformRepo,
665 CREATE_CM_ARM_OBJECT_ID (EArmObjPciConfigSpaceInfo),
666 CM_NULL_TOKEN,
667 &CmObjDesc
668 );
669 if (Status == EFI_NOT_FOUND) {
670 //
671 // The last 3 tables are for PCIe. If PCIe information is not
672 // present, Kvmtool was launched without the PCIe option.
673 // Therefore, reduce the table count by 3.
674 //
675 AcpiTableCount -= 3;
676 } else if (EFI_ERROR (Status)) {
677 ASSERT_EFI_ERROR (Status);
678 return Status;
679 }
680
681 //
682 // Get the Gic version.
683 //
684 Status = DynamicPlatRepoGetObject (
685 PlatformRepo->DynamicPlatformRepo,
686 CREATE_CM_ARM_OBJECT_ID (EArmObjGicDInfo),
687 CM_NULL_TOKEN,
688 &CmObjDesc
689 );
690 if (EFI_ERROR (Status)) {
691 ASSERT_EFI_ERROR (Status);
692 return Status;
693 }
694
695 if (((CM_ARM_GICD_INFO *)CmObjDesc.Data)->GicVersion < 3) {
696 //
697 // IORT is only required for GicV3/4
698 //
699 AcpiTableCount -= 1;
700 }
701
702 Status = HandleCmObject (
703 CmObjectId,
704 PlatformRepo->CmAcpiTableList,
705 (sizeof (PlatformRepo->CmAcpiTableList[0]) * AcpiTableCount),
706 AcpiTableCount,
707 CmObject
708 );
709 break;
710
711 default:
712 Status = EFI_NOT_FOUND;
713 DEBUG ((
714 DEBUG_ERROR,
715 "ERROR: CmObjectId " FMT_CM_OBJECT_ID ". Status = %r\n",
716 CmObjectId,
717 Status
718 ));
719 break;
720 }
721
722 return Status;
723 }
724
725 /**
726 Return an ARM namespace object.
727
728 @param [in] This Pointer to the Configuration Manager Protocol.
729 @param [in] CmObjectId The Configuration Manager Object ID.
730 @param [in] Token An optional token identifying the object. If
731 unused this must be CM_NULL_TOKEN.
732 @param [in, out] CmObject Pointer to the Configuration Manager Object
733 descriptor describing the requested Object.
734
735 @retval EFI_SUCCESS Success.
736 @retval EFI_INVALID_PARAMETER A parameter is invalid.
737 @retval EFI_NOT_FOUND The required object information is not found.
738 **/
739 EFI_STATUS
740 EFIAPI
741 GetArmNameSpaceObject (
742 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
743 IN CONST CM_OBJECT_ID CmObjectId,
744 IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
745 IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
746 )
747 {
748 EFI_STATUS Status;
749 EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo;
750
751 if ((This == NULL) || (CmObject == NULL)) {
752 ASSERT (This != NULL);
753 ASSERT (CmObject != NULL);
754 return EFI_INVALID_PARAMETER;
755 }
756
757 Status = EFI_NOT_FOUND;
758 PlatformRepo = This->PlatRepoInfo;
759
760 //
761 // First check among the static objects.
762 //
763 switch (GET_CM_OBJECT_ID (CmObjectId)) {
764 case EArmObjPowerManagementProfileInfo:
765 Status = HandleCmObject (
766 CmObjectId,
767 &PlatformRepo->PmProfileInfo,
768 sizeof (PlatformRepo->PmProfileInfo),
769 1,
770 CmObject
771 );
772 break;
773
774 case EArmObjItsGroup:
775 Status = HandleCmObject (
776 CmObjectId,
777 &PlatformRepo->ItsGroupInfo,
778 sizeof (PlatformRepo->ItsGroupInfo),
779 1,
780 CmObject
781 );
782 break;
783
784 case EArmObjGicItsIdentifierArray:
785 Status = HandleCmObjectRefByToken (
786 This,
787 CmObjectId,
788 PlatformRepo->ItsIdentifierArray,
789 sizeof (PlatformRepo->ItsIdentifierArray),
790 ARRAY_SIZE (PlatformRepo->ItsIdentifierArray),
791 Token,
792 GetItsIdentifierArray,
793 CmObject
794 );
795 break;
796
797 case EArmObjRootComplex:
798 Status = HandleCmObject (
799 CmObjectId,
800 &PlatformRepo->RootComplexInfo,
801 sizeof (PlatformRepo->RootComplexInfo),
802 1,
803 CmObject
804 );
805 break;
806
807 case EArmObjIdMappingArray:
808 Status = HandleCmObjectRefByToken (
809 This,
810 CmObjectId,
811 PlatformRepo->DeviceIdMapping,
812 sizeof (PlatformRepo->DeviceIdMapping),
813 ARRAY_SIZE (PlatformRepo->DeviceIdMapping),
814 Token,
815 GetDeviceIdMappingArray,
816 CmObject
817 );
818 break;
819
820 default:
821 //
822 // No match found among the static objects.
823 // Check the dynamic objects.
824 //
825 Status = DynamicPlatRepoGetObject (
826 PlatformRepo->DynamicPlatformRepo,
827 CmObjectId,
828 Token,
829 CmObject
830 );
831 break;
832 } // switch
833
834 if (Status == EFI_NOT_FOUND) {
835 DEBUG ((
836 DEBUG_INFO,
837 "INFO: CmObjectId " FMT_CM_OBJECT_ID ". Status = %r\n",
838 CmObjectId,
839 Status
840 ));
841 } else {
842 ASSERT_EFI_ERROR (Status);
843 }
844
845 return Status;
846 }
847
848 /**
849 Return an OEM namespace object.
850
851 @param [in] This Pointer to the Configuration Manager Protocol.
852 @param [in] CmObjectId The Configuration Manager Object ID.
853 @param [in] Token An optional token identifying the object. If
854 unused this must be CM_NULL_TOKEN.
855 @param [in, out] CmObject Pointer to the Configuration Manager Object
856 descriptor describing the requested Object.
857
858 @retval EFI_SUCCESS Success.
859 @retval EFI_INVALID_PARAMETER A parameter is invalid.
860 @retval EFI_NOT_FOUND The required object information is not found.
861 **/
862 EFI_STATUS
863 EFIAPI
864 GetOemNameSpaceObject (
865 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
866 IN CONST CM_OBJECT_ID CmObjectId,
867 IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
868 IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
869 )
870 {
871 EFI_STATUS Status;
872
873 Status = EFI_SUCCESS;
874 if ((This == NULL) || (CmObject == NULL)) {
875 ASSERT (This != NULL);
876 ASSERT (CmObject != NULL);
877 return EFI_INVALID_PARAMETER;
878 }
879
880 switch (GET_CM_OBJECT_ID (CmObjectId)) {
881 default:
882 Status = EFI_NOT_FOUND;
883 DEBUG ((
884 DEBUG_ERROR,
885 "ERROR: CmObjectId " FMT_CM_OBJECT_ID ". Status = %r\n",
886 CmObjectId,
887 Status
888 ));
889 break;
890 }
891
892 return Status;
893 }
894
895 /**
896 The GetObject function defines the interface implemented by the
897 Configuration Manager Protocol for returning the Configuration
898 Manager Objects.
899
900 @param [in] This Pointer to the Configuration Manager Protocol.
901 @param [in] CmObjectId The Configuration Manager Object ID.
902 @param [in] Token An optional token identifying the object. If
903 unused this must be CM_NULL_TOKEN.
904 @param [in, out] CmObject Pointer to the Configuration Manager Object
905 descriptor describing the requested Object.
906
907 @retval EFI_SUCCESS Success.
908 @retval EFI_INVALID_PARAMETER A parameter is invalid.
909 @retval EFI_NOT_FOUND The required object information is not found.
910 **/
911 EFI_STATUS
912 EFIAPI
913 ArmKvmtoolPlatformGetObject (
914 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
915 IN CONST CM_OBJECT_ID CmObjectId,
916 IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
917 IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
918 )
919 {
920 EFI_STATUS Status;
921
922 if ((This == NULL) || (CmObject == NULL)) {
923 ASSERT (This != NULL);
924 ASSERT (CmObject != NULL);
925 return EFI_INVALID_PARAMETER;
926 }
927
928 switch (GET_CM_NAMESPACE_ID (CmObjectId)) {
929 case EObjNameSpaceStandard:
930 Status = GetStandardNameSpaceObject (This, CmObjectId, Token, CmObject);
931 break;
932 case EObjNameSpaceArm:
933 Status = GetArmNameSpaceObject (This, CmObjectId, Token, CmObject);
934 break;
935 case EObjNameSpaceOem:
936 Status = GetOemNameSpaceObject (This, CmObjectId, Token, CmObject);
937 break;
938 default:
939 Status = EFI_INVALID_PARAMETER;
940 DEBUG ((
941 DEBUG_ERROR,
942 "ERROR: Unknown Namespace CmObjectId " FMT_CM_OBJECT_ID ". "
943 "Status = %r\n",
944 CmObjectId,
945 Status
946 ));
947 break;
948 }
949
950 return Status;
951 }
952
953 /**
954 The SetObject function defines the interface implemented by the
955 Configuration Manager Protocol for updating the Configuration
956 Manager Objects.
957
958 @param [in] This Pointer to the Configuration Manager Protocol.
959 @param [in] CmObjectId The Configuration Manager Object ID.
960 @param [in] Token An optional token identifying the object. If
961 unused this must be CM_NULL_TOKEN.
962 @param [in] CmObject Pointer to the Configuration Manager Object
963 descriptor describing the Object.
964
965 @retval EFI_UNSUPPORTED This operation is not supported.
966 **/
967 EFI_STATUS
968 EFIAPI
969 ArmKvmtoolPlatformSetObject (
970 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
971 IN CONST CM_OBJECT_ID CmObjectId,
972 IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
973 IN CM_OBJ_DESCRIPTOR *CONST CmObject
974 )
975 {
976 return EFI_UNSUPPORTED;
977 }
978
979 //
980 // A structure describing the configuration manager protocol interface.
981 //
982 STATIC
983 CONST
984 EDKII_CONFIGURATION_MANAGER_PROTOCOL mKvmtoolPlatformConfigManagerProtocol = {
985 CREATE_REVISION (1, 0),
986 ArmKvmtoolPlatformGetObject,
987 ArmKvmtoolPlatformSetObject,
988 &mKvmtoolPlatRepositoryInfo
989 };
990
991 /**
992 Entrypoint of Configuration Manager Dxe.
993
994 @param ImageHandle
995 @param SystemTable
996
997 @retval EFI_SUCCESS
998 @retval EFI_LOAD_ERROR
999 @retval EFI_OUT_OF_RESOURCES
1000 **/
1001 EFI_STATUS
1002 EFIAPI
1003 ConfigurationManagerDxeInitialize (
1004 IN EFI_HANDLE ImageHandle,
1005 IN EFI_SYSTEM_TABLE *SystemTable
1006 )
1007 {
1008 EFI_STATUS Status;
1009
1010 Status = gBS->InstallProtocolInterface (
1011 &ImageHandle,
1012 &gEdkiiConfigurationManagerProtocolGuid,
1013 EFI_NATIVE_INTERFACE,
1014 (VOID *)&mKvmtoolPlatformConfigManagerProtocol
1015 );
1016 if (EFI_ERROR (Status)) {
1017 DEBUG ((
1018 DEBUG_ERROR,
1019 "ERROR: Failed to get Install Configuration Manager Protocol." \
1020 " Status = %r\n",
1021 Status
1022 ));
1023 return Status;
1024 }
1025
1026 Status = InitializePlatformRepository (
1027 &mKvmtoolPlatformConfigManagerProtocol
1028 );
1029 if (EFI_ERROR (Status)) {
1030 DEBUG ((
1031 DEBUG_ERROR,
1032 "ERROR: Failed to initialize the Platform Configuration Repository." \
1033 " Status = %r\n",
1034 Status
1035 ));
1036 goto ErrorHandler;
1037 }
1038
1039 return Status;
1040
1041 ErrorHandler:
1042 gBS->UninstallProtocolInterface (
1043 &ImageHandle,
1044 &gEdkiiConfigurationManagerProtocolGuid,
1045 (VOID *)&mKvmtoolPlatformConfigManagerProtocol
1046 );
1047 return Status;
1048 }
1049
1050 /**
1051 Unload function for this image.
1052
1053 @param ImageHandle Handle for the image of this driver.
1054
1055 @retval EFI_SUCCESS Driver unloaded successfully.
1056 @retval other Driver can not unloaded.
1057 **/
1058 EFI_STATUS
1059 EFIAPI
1060 ConfigurationManagerDxeUnloadImage (
1061 IN EFI_HANDLE ImageHandle
1062 )
1063 {
1064 return CleanupPlatformRepository (&mKvmtoolPlatformConfigManagerProtocol);
1065 }