CfgDbDxe.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. /** @file
  2. UbaConfigDatabaseDxe Driver.
  3. @copyright
  4. Copyright 2013 - 2021 Intel Corporation. <BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include "CfgDbDxe.h"
  8. #include <PiDxe.h> // For Hob
  9. #include <Library/BaseLib.h>
  10. #include <Library/DebugLib.h>
  11. #include <Library/BaseMemoryLib.h>
  12. #include <Library/MemoryAllocationLib.h>
  13. #include <Library/HobLib.h>
  14. #include <Library/UefiDriverEntryPoint.h>
  15. #include <Library/UefiBootServicesTableLib.h>
  16. /**
  17. Internal function for getting the platform record node in the database.
  18. @param This uba Protocol instance.
  19. @param SkuNode The pointer to pointer of Platform record node.
  20. @retval EFI_NOT_FOUND Platform record not found.
  21. @retval EFI_SUCCESS Platform found.
  22. **/
  23. EFI_STATUS
  24. InternalGetSkuNode (
  25. IN UBA_CONFIG_DATABASE_PROTOCOL *This,
  26. OUT UBA_BOARD_NODE **SkuNode
  27. )
  28. {
  29. UBA_DXE_PRIVATE_DATA *UbaDxePrivate;
  30. UbaDxePrivate = NULL;
  31. UbaDxePrivate = PRIVATE_DATA_FROM_PROTOCOL (This);
  32. *SkuNode = UbaDxePrivate->CurrentSku;
  33. return EFI_SUCCESS;
  34. }
  35. /**
  36. Internal function for init the platform record to database.
  37. Create the connections between UBA_BOARD_NODE and UBA_DXE_PRIVATE_DATA
  38. @param This UBA Protocol instance.
  39. @param BoardId The platform type.
  40. @param BoardGuid The platform GUID.
  41. @param BoardName The platform user friendly name.
  42. @param SkuNode The pointer to pointer of Platform record node.
  43. @retval EFI_ALREADY_STARTED Platform record already exist.
  44. @retval EFI_OUT_OF_RESOURCES No enough resource.
  45. @retval EFI_SUCCESS Operation success.
  46. **/
  47. EFI_STATUS
  48. InternalInitSkuDxe (
  49. IN UBA_CONFIG_DATABASE_PROTOCOL *This,
  50. IN UINT32 BoardId,
  51. IN EFI_GUID *BoardGuid, OPTIONAL
  52. IN CHAR8 *BoardName, OPTIONAL
  53. OUT UBA_BOARD_NODE **SkuNode OPTIONAL
  54. )
  55. {
  56. UBA_DXE_PRIVATE_DATA *UbaDxePrivate;
  57. UBA_BOARD_NODE *NewSkuNode;
  58. UbaDxePrivate = NULL;
  59. NewSkuNode = NULL;
  60. UbaDxePrivate = PRIVATE_DATA_FROM_PROTOCOL (This);
  61. NewSkuNode = AllocateZeroPool (sizeof (UBA_BOARD_NODE));
  62. if (NewSkuNode == NULL) {
  63. return EFI_OUT_OF_RESOURCES;
  64. }
  65. NewSkuNode->Signature = UBA_BOARD_SIGNATURE;
  66. NewSkuNode->Version = UBA_BOARD_VERSION;
  67. NewSkuNode->BoardId = BoardId;
  68. if (BoardName != NULL) {
  69. AsciiStrnCpyS (NewSkuNode->BoardName, AsciiStrSize (BoardName) / sizeof (CHAR8), BoardName, sizeof (NewSkuNode->BoardName) - 1);
  70. }
  71. if (BoardGuid != NULL) {
  72. CopyMem (&NewSkuNode->BoardGuid, BoardGuid, sizeof (EFI_GUID));
  73. }
  74. // Initialize the list head for Datalink.
  75. InitializeListHead (&NewSkuNode->DataLinkHead);
  76. if (SkuNode != NULL) {
  77. // Output the point of sku node.
  78. *SkuNode = NewSkuNode;
  79. // Pass the point to CurrentSku in UbaDxePrivate.
  80. UbaDxePrivate->CurrentSku = NewSkuNode;
  81. }
  82. return EFI_SUCCESS;
  83. }
  84. /**
  85. Internal function for adding new configuration data record to database.
  86. @param This uba Protocol instance.
  87. @param ResId The resource ID.
  88. @param Data Data pointer.
  89. @param DataSize Data size.
  90. @retval EFI_INVALID_PARAMETER Parameter invalid.
  91. @retval EFI_OUT_OF_RESOURCES No enough resource.
  92. @retval EFI_SUCCESS Operation success.
  93. **/
  94. EFI_STATUS
  95. InternalAddNewConfigData (
  96. IN UBA_CONFIG_DATABASE_PROTOCOL *This,
  97. IN EFI_GUID *ResId,
  98. IN VOID *Data,
  99. IN UINTN DataSize
  100. )
  101. {
  102. EFI_STATUS Status;
  103. EFI_HANDLE Handle;
  104. UBA_DXE_PRIVATE_DATA *UbaDxePrivate;
  105. UBA_CONFIG_NODE *NewDataNode;
  106. UBA_BOARD_NODE *SkuNode;
  107. UbaDxePrivate = NULL;
  108. NewDataNode = NULL;
  109. SkuNode = NULL;
  110. if ((ResId == NULL) || (Data == NULL) || (DataSize <= 0)) {
  111. return EFI_INVALID_PARAMETER;
  112. }
  113. UbaDxePrivate = PRIVATE_DATA_FROM_PROTOCOL (This);
  114. Status = InternalGetSkuNode (This, &SkuNode);
  115. if (EFI_ERROR (Status)) {
  116. return Status;
  117. }
  118. NewDataNode = AllocateZeroPool (sizeof (UBA_CONFIG_NODE));
  119. if (NewDataNode == NULL) {
  120. return EFI_OUT_OF_RESOURCES;
  121. }
  122. NewDataNode->Signature = UBA_BOARD_SIGNATURE;
  123. NewDataNode->Version = UBA_BOARD_VERSION;
  124. NewDataNode->Handle = (EFI_HANDLE) (UINTN) UbaDxePrivate->HandleCount;
  125. NewDataNode->Data = AllocateCopyPool (DataSize, Data);
  126. NewDataNode->Size = (UINT32) DataSize;
  127. CopyMem (&NewDataNode->ResId, ResId, sizeof (EFI_GUID));
  128. InsertTailList (&SkuNode->DataLinkHead, &NewDataNode->DataLink);
  129. SkuNode->DataCount ++;
  130. UbaDxePrivate->ConfigDataCount ++;
  131. UbaDxePrivate->HandleCount ++;
  132. //
  133. // This Protocol just install for Protocol notify
  134. // The Protocol instance UbaCfgDbProtocol should not used
  135. //
  136. Handle = NULL;
  137. Status = gBS->InstallProtocolInterface (
  138. &Handle,
  139. &NewDataNode->ResId,
  140. EFI_NATIVE_INTERFACE,
  141. &UbaDxePrivate->UbaCfgDbProtocol
  142. );
  143. ASSERT_EFI_ERROR (Status);
  144. if (Status != EFI_SUCCESS) {
  145. return Status;
  146. }
  147. return EFI_SUCCESS;
  148. }
  149. /**
  150. Internal function for Getting configuration data from database.
  151. @param This uba Protocol instance.
  152. @param SkuNode The platform node record.
  153. @param ResId The resource ID.
  154. @param Data Data pointer.
  155. @param DataSize Data size pointer.
  156. @retval EFI_INVALID_PARAMETER Parameter invalid.
  157. @retval EFI_NOT_FOUND Resource not found.
  158. @retval EFI_BUFFER_TOO_SMALL The buffer is too small to copy the data.
  159. @retval EFI_SUCCESS Operation success.
  160. **/
  161. EFI_STATUS
  162. InternalGetConfigData (
  163. IN UBA_CONFIG_DATABASE_PROTOCOL *This,
  164. IN UBA_BOARD_NODE *SkuNode,
  165. IN EFI_GUID *ResId,
  166. OUT VOID *Data, OPTIONAL
  167. OUT UINTN *DataSize OPTIONAL
  168. )
  169. {
  170. LIST_ENTRY *ListHead;
  171. LIST_ENTRY *Link;
  172. UBA_CONFIG_NODE *DataNode;
  173. ListHead = NULL;
  174. Link = NULL;
  175. DataNode = NULL;
  176. if ((SkuNode == NULL) || (ResId == NULL)) {
  177. return EFI_INVALID_PARAMETER;
  178. }
  179. ListHead = &SkuNode->DataLinkHead;
  180. if (IsListEmpty (ListHead)) {
  181. return EFI_NOT_FOUND;
  182. }
  183. for (Link = GetFirstNode (ListHead); !IsNull (ListHead, Link); Link = GetNextNode (ListHead, Link)) {
  184. DataNode = CONFIG_NODE_INSTANCE_FROM_THIS (Link);
  185. ASSERT (DataNode != NULL);
  186. if (DataNode == NULL) {
  187. return EFI_UNSUPPORTED;
  188. }
  189. if (CompareGuid (ResId, &DataNode->ResId)) {
  190. if (DataSize != NULL) {
  191. if (*DataSize < DataNode->Size) {
  192. *DataSize = DataNode->Size;
  193. return EFI_BUFFER_TOO_SMALL;
  194. }
  195. *DataSize = DataNode->Size;
  196. if (Data != NULL) {
  197. CopyMem (Data, DataNode->Data, DataNode->Size);
  198. }
  199. }
  200. return EFI_SUCCESS;
  201. }
  202. }
  203. return EFI_NOT_FOUND;
  204. }
  205. /**
  206. Get platform's GUID and user friendly name by BoardId.
  207. This is used when you need a BoardGuid to Add/Get platform data
  208. Core will create a new platform for you if the BoardId is not
  209. recorded in database, and assgin a unique GUID for this platform.
  210. @param This uba Protocol instance.
  211. @param BoardId The platform type, same define as Platform.h.
  212. @param BoardGuid The GUID for this platform.
  213. @param BoardName The user friendly name for this platform.
  214. @retval EFI_ALREADY_STARTED Create new for an exist platform.
  215. @retval EFI_OUT_OF_RESOURCES Resource not enough.
  216. @retval EFI_NOT_FOUND Platform not found.
  217. @retval EFI_SUCCESS Operation success.
  218. **/
  219. EFI_STATUS
  220. EFIAPI
  221. DxeUbaGetPlatformSku (
  222. IN UBA_CONFIG_DATABASE_PROTOCOL *This,
  223. OUT UINT32 *BoardId,
  224. OUT EFI_GUID *BoardGuid, OPTIONAL
  225. OUT CHAR8 *BoardName OPTIONAL
  226. )
  227. {
  228. EFI_STATUS Status;
  229. UBA_BOARD_NODE *SkuNode;
  230. SkuNode = NULL;
  231. Status = InternalGetSkuNode (This, &SkuNode);
  232. if (!EFI_ERROR (Status)) {
  233. if (BoardId != NULL) {
  234. *BoardId = SkuNode->BoardId;
  235. }
  236. if (BoardName != NULL) {
  237. AsciiStrCpyS (BoardName, AsciiStrSize (SkuNode->BoardName) / sizeof (CHAR8) , SkuNode->BoardName);
  238. }
  239. if (BoardGuid != NULL) {
  240. CopyMem (BoardGuid, &SkuNode->BoardGuid, sizeof (EFI_GUID));
  241. }
  242. return EFI_SUCCESS;
  243. }
  244. return Status;
  245. }
  246. /**
  247. Add configuration data to uba configuration database.
  248. @param This uba Protocol instance.
  249. @param ResId The configuration data resource id.
  250. @param Data The data buffer pointer.
  251. @param DataSize Size of data want to add into database.
  252. @retval EFI_INVALID_PARAMETER Required parameters not correct.
  253. @retval EFI_OUT_OF_RESOURCES Resource not enough.
  254. @retval EFI_NOT_FOUND Platform not found.
  255. @retval EFI_SUCCESS Operation success.
  256. **/
  257. EFI_STATUS
  258. EFIAPI
  259. DxeUbaAddData (
  260. IN UBA_CONFIG_DATABASE_PROTOCOL *This,
  261. IN EFI_GUID *ResId,
  262. IN VOID *Data,
  263. IN UINTN DataSize
  264. )
  265. {
  266. EFI_STATUS Status;
  267. UBA_BOARD_NODE *SkuNode;
  268. SkuNode = NULL;
  269. Status = InternalGetSkuNode (This, &SkuNode);
  270. if (EFI_ERROR (Status)) {
  271. return Status;
  272. }
  273. Status = InternalAddNewConfigData (This, ResId, Data, DataSize);
  274. return Status;
  275. }
  276. /**
  277. Get configuration data from uba configuration database.
  278. @param This uba Protocol instance.
  279. @param ResId The configuration data resource id.
  280. @param Data The data buffer pointer.
  281. @param DataSize IN:Size of data want to get, OUT: Size of data in database.
  282. @retval EFI_INVALID_PARAMETER Required parameters not correct.
  283. @retval EFI_BUFFER_TOO_SMALL The DataSize of Data buffer is too small to get this configuration data
  284. @retval EFI_OUT_OF_RESOURCES Resource not enough.
  285. @retval EFI_NOT_FOUND Platform or data not found.
  286. @retval EFI_SUCCESS Operation success.
  287. **/
  288. EFI_STATUS
  289. EFIAPI
  290. DxeUbaGetData (
  291. IN UBA_CONFIG_DATABASE_PROTOCOL *This,
  292. IN EFI_GUID *ResId,
  293. OUT VOID *Data,
  294. OUT UINTN *DataSize
  295. )
  296. {
  297. EFI_STATUS Status;
  298. UBA_BOARD_NODE *SkuNode;
  299. SkuNode = NULL;
  300. if ((ResId == NULL) || (Data == NULL) || (DataSize == NULL)) {
  301. return EFI_INVALID_PARAMETER;
  302. }
  303. Status = InternalGetSkuNode (This, &SkuNode);
  304. if (EFI_ERROR (Status)) {
  305. return Status;
  306. }
  307. Status = InternalGetConfigData (This, SkuNode, ResId, Data, DataSize);
  308. if (!EFI_ERROR (Status)) {
  309. return EFI_SUCCESS;
  310. }
  311. return EFI_NOT_FOUND;
  312. }
  313. /**
  314. Internal function for getting current platform's configuration data from HOB, which passed by PEIM.
  315. @param This uba Protocol instance.
  316. @retval EFI_INVALID_PARAMETER Required parameters not correct.
  317. @retval EFI_OUT_OF_RESOURCES Resource not enough.
  318. @retval EFI_NOT_FOUND Platform or data not found.
  319. @retval EFI_SUCCESS Operation success.
  320. **/
  321. EFI_STATUS
  322. InternalGetConfigDataFromHob (
  323. IN UBA_CONFIG_DATABASE_PROTOCOL *This
  324. )
  325. {
  326. EFI_STATUS Status;
  327. EFI_PEI_HOB_POINTERS Hob;
  328. UINT8 *HobDataStart;
  329. UBA_CONFIG_HOB_HEADER *HobHeader;
  330. UBA_CONFIG_HOB_FIELD *HobDataFieldStart;
  331. UINTN Index;
  332. UBA_BOARD_NODE *SkuNode;
  333. HobHeader = NULL;
  334. HobDataFieldStart = NULL;
  335. SkuNode = NULL;
  336. Hob.Raw = GetFirstGuidHob (&gUbaCurrentConfigHobGuid);
  337. ASSERT (Hob.Raw != NULL);
  338. if (Hob.Raw == NULL) {
  339. return EFI_UNSUPPORTED;
  340. }
  341. DEBUG ((DEBUG_INFO, "UbaConfigDatabasedxeEntry: get first hob!\n"));
  342. HobDataStart = GET_GUID_HOB_DATA (Hob);
  343. HobHeader = (UBA_CONFIG_HOB_HEADER *) HobDataStart;
  344. HobDataFieldStart = HobHeader->HobField;
  345. //Call internal function for SKU init, accroding to hob data.
  346. Status = InternalInitSkuDxe (This, HobHeader->BoardId, &HobHeader->BoardGuid, HobHeader->BoardName, &SkuNode);
  347. if (EFI_ERROR (Status)) {
  348. return Status;
  349. }
  350. // Obtain all data stored in the hob from PEI phase.
  351. for (Index = 0; Index < HobHeader->DataCount; Index ++) {
  352. Status = This->AddData (
  353. This,
  354. &HobDataFieldStart[Index].ResId,
  355. (VOID *) ((UINTN) HobDataFieldStart[Index].DataOffset + (UINTN) HobHeader),
  356. HobDataFieldStart[Index].Size
  357. );
  358. ASSERT_EFI_ERROR (Status);
  359. if (Status != EFI_SUCCESS) {
  360. return Status;
  361. }
  362. }
  363. return EFI_SUCCESS;
  364. }
  365. /**
  366. The Driver Entry Point.
  367. The function is the driver Entry point.
  368. @param ImageHandle A handle for the image that is initializing this driver
  369. @param SystemTable A pointer to the EFI system table
  370. @retval EFI_SUCCESS: Driver initialized successfully
  371. @retval EFI_LOAD_ERROR: Failed to Initialize or has been loaded
  372. @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources
  373. **/
  374. EFI_STATUS
  375. EFIAPI
  376. UbaConfigDatabaseEntry (
  377. IN EFI_HANDLE ImageHandle,
  378. IN EFI_SYSTEM_TABLE *SystemTable
  379. )
  380. {
  381. EFI_STATUS Status;
  382. UBA_DXE_PRIVATE_DATA *UbaDxePrivate;
  383. EFI_HANDLE Handle;
  384. UbaDxePrivate = NULL;
  385. UbaDxePrivate = AllocateZeroPool (sizeof (UBA_DXE_PRIVATE_DATA));
  386. ASSERT (UbaDxePrivate != NULL);
  387. if (UbaDxePrivate == NULL) {
  388. return EFI_OUT_OF_RESOURCES;
  389. }
  390. DEBUG ((DEBUG_INFO, "UbaConfigDatabasedxeEntry: after allocate Memory!\n"));
  391. UbaDxePrivate->Signature = UBA_BOARD_SIGNATURE;
  392. UbaDxePrivate->Version = UBA_BOARD_VERSION;
  393. UbaDxePrivate->ConfigDataCount = 0;
  394. UbaDxePrivate->HandleCount = 0;
  395. UbaDxePrivate->UbaCfgDbProtocol.Signature = UBA_CONFIG_PROTOCOL_SIGNATURE;
  396. UbaDxePrivate->UbaCfgDbProtocol.Version = UBA_CONFIG_PROTOCOL_VERSION;
  397. UbaDxePrivate->UbaCfgDbProtocol.GetSku = DxeUbaGetPlatformSku;
  398. UbaDxePrivate->UbaCfgDbProtocol.AddData = DxeUbaAddData;
  399. UbaDxePrivate->UbaCfgDbProtocol.GetData = DxeUbaGetData;
  400. //
  401. // Just produce our Protocol
  402. //
  403. Handle = NULL;
  404. Status = gBS->InstallProtocolInterface (
  405. &Handle,
  406. &gUbaConfigDatabaseProtocolGuid,
  407. EFI_NATIVE_INTERFACE,
  408. &UbaDxePrivate->UbaCfgDbProtocol
  409. );
  410. if (EFI_ERROR (Status)) {
  411. return Status;
  412. }
  413. DEBUG ((DEBUG_INFO, "UbaConfigDatabasedxeEntry: before get data from hob!\n"));
  414. // Init sku dxe and get configuration data from hob passed by PEIM.
  415. Status = InternalGetConfigDataFromHob (&UbaDxePrivate->UbaCfgDbProtocol);
  416. ASSERT_EFI_ERROR (Status);
  417. return Status;
  418. }