ConfigurationManager.c 30 KB

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