CfgDbPei.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. /** @file
  2. UbaConfigDatabase Peim.
  3. @copyright
  4. Copyright 2013 - 2021 Intel Corporation. <BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include "CfgDbPei.h"
  8. #include <Ppi/EndOfPeiPhase.h>
  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/PeimEntryPoint.h>
  15. #include <Library/PeiServicesLib.h>
  16. #include <Library/PeiServicesTablePointerLib.h>
  17. /**
  18. Internal function for getting the platform record node in the database.
  19. @param This uba Ppi instance.
  20. @param SkuNode The pointer to pointer of Platform record node.
  21. @retval EFI_NOT_FOUND Platform record not found.
  22. @retval EFI_SUCCESS Platform found.
  23. **/
  24. EFI_STATUS
  25. InternalGetSkuNode (
  26. IN UBA_CONFIG_DATABASE_PPI *This,
  27. OUT UBA_BOARD_NODE **SkuNode
  28. )
  29. {
  30. UBA_PEIM_PRIVATE_DATA *UbaPeimPrivate;
  31. UbaPeimPrivate = NULL;
  32. UbaPeimPrivate = PRIVATE_DATA_FROM_PPI (This);
  33. *SkuNode = UbaPeimPrivate->CurrentSku;
  34. return EFI_SUCCESS;
  35. }
  36. /**
  37. Internal function for init the platform record to database.
  38. Create the connections between UBA_BOARD_NODE and UBA_PEIM_PRIVATE_DATA
  39. @param This uba Ppi instance.
  40. @param BoardId The platform type.
  41. @param BoardGuid The platform GUID.
  42. @param BoardName The platform user friendly name.
  43. @param SkuNode The pointer to pointer of Platform record node.
  44. @retval EFI_ALREADY_STARTED Platform record already exist.
  45. @retval EFI_OUT_OF_RESOURCES No enough resource.
  46. @retval EFI_SUCCESS Operation success.
  47. **/
  48. EFI_STATUS
  49. InternalInitSku (
  50. IN UBA_CONFIG_DATABASE_PPI *This,
  51. IN UINT32 BoardId,
  52. IN EFI_GUID *BoardGuid, OPTIONAL
  53. IN CHAR8 *BoardName, OPTIONAL
  54. OUT UBA_BOARD_NODE **SkuNode OPTIONAL
  55. )
  56. {
  57. UBA_PEIM_PRIVATE_DATA *UbaPeimPrivate;
  58. UBA_BOARD_NODE *NewSkuNode;
  59. UbaPeimPrivate = NULL;
  60. NewSkuNode = NULL;
  61. UbaPeimPrivate = PRIVATE_DATA_FROM_PPI (This);
  62. NewSkuNode = AllocateZeroPool (sizeof (UBA_BOARD_NODE));
  63. if (NewSkuNode == NULL) {
  64. return EFI_OUT_OF_RESOURCES;
  65. }
  66. NewSkuNode->Signature = UBA_BOARD_SIGNATURE;
  67. NewSkuNode->Version = UBA_BOARD_VERSION;
  68. NewSkuNode->BoardId = BoardId;
  69. if (BoardName != NULL) {
  70. AsciiStrnCpyS (NewSkuNode->BoardName, sizeof (NewSkuNode->BoardName), BoardName, sizeof (NewSkuNode->BoardName) - 1);
  71. }
  72. if (BoardGuid != NULL) {
  73. CopyMem (&NewSkuNode->BoardGuid, BoardGuid, sizeof (EFI_GUID));
  74. }
  75. //Initialize the list head for Datalink.
  76. InitializeListHead (&NewSkuNode->DataLinkHead);
  77. if (SkuNode != NULL) {
  78. *SkuNode = NewSkuNode;
  79. UbaPeimPrivate->CurrentSku = NewSkuNode;
  80. }
  81. return EFI_SUCCESS;
  82. }
  83. /**
  84. Internal function for adding new configuration data record to database.
  85. @param This uba Ppi instance.
  86. @param ResId The resource ID.
  87. @param Data Data pointer.
  88. @param DataSize Data size.
  89. @retval EFI_INVALID_PARAMETER Parameter invalid.
  90. @retval EFI_OUT_OF_RESOURCES No enough resource.
  91. @retval EFI_SUCCESS Operation success.
  92. **/
  93. EFI_STATUS
  94. InternalAddNewConfigData (
  95. IN UBA_CONFIG_DATABASE_PPI *This,
  96. IN EFI_GUID *ResId,
  97. IN VOID *Data,
  98. IN UINTN DataSize
  99. )
  100. {
  101. EFI_STATUS Status;
  102. UBA_PEIM_PRIVATE_DATA *UbaPeimPrivate;
  103. UBA_CONFIG_NODE *NewDataNode;
  104. UBA_BOARD_NODE *SkuNode;
  105. EFI_PEI_PPI_DESCRIPTOR *ConfigDataPpi;
  106. UbaPeimPrivate = NULL;
  107. NewDataNode = NULL;
  108. SkuNode = NULL;
  109. ConfigDataPpi = NULL;
  110. if ((ResId == NULL) || (Data == NULL) || (DataSize <= 0)) {
  111. return EFI_INVALID_PARAMETER;
  112. }
  113. UbaPeimPrivate = PRIVATE_DATA_FROM_PPI (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) UbaPeimPrivate->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. UbaPeimPrivate->ConfigDataCount ++;
  131. UbaPeimPrivate->HandleCount ++;
  132. //
  133. // This PPI just install for NotifyPpi
  134. // The PPI instance UbaCfgDbPpi should not used
  135. //
  136. ConfigDataPpi = AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
  137. if (ConfigDataPpi == NULL) {
  138. return EFI_OUT_OF_RESOURCES;
  139. }
  140. ConfigDataPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
  141. ConfigDataPpi->Guid = &NewDataNode->ResId;
  142. ConfigDataPpi->Ppi = &UbaPeimPrivate->UbaCfgDbPpi;
  143. Status = PeiServicesInstallPpi (ConfigDataPpi);
  144. ASSERT_EFI_ERROR (Status);
  145. if (Status != EFI_SUCCESS) {
  146. return Status;
  147. }
  148. return EFI_SUCCESS;
  149. }
  150. /**
  151. Internal function for Getting configuration data from database.
  152. @param This uba Ppi instance.
  153. @param SkuNode The platform node record.
  154. @param ResId The resource ID.
  155. @param Data Data pointer.
  156. @param DataSize Data size pointer.
  157. @retval EFI_INVALID_PARAMETER Parameter invalid.
  158. @retval EFI_NOT_FOUND Resource not found.
  159. @retval EFI_BUFFER_TOO_SMALL The buffer is too small to copy the data.
  160. @retval EFI_SUCCESS Operation success.
  161. **/
  162. EFI_STATUS
  163. InternalGetConfigData (
  164. IN UBA_CONFIG_DATABASE_PPI *This,
  165. IN UBA_BOARD_NODE *SkuNode,
  166. IN EFI_GUID *ResId,
  167. OUT VOID *Data, OPTIONAL
  168. OUT UINTN *DataSize OPTIONAL
  169. )
  170. {
  171. LIST_ENTRY *ListHead;
  172. LIST_ENTRY *Link;
  173. UBA_CONFIG_NODE *DataNode;
  174. ListHead = NULL;
  175. Link = NULL;
  176. DataNode = NULL;
  177. if ((SkuNode == NULL) || (ResId == NULL)) {
  178. return EFI_INVALID_PARAMETER;
  179. }
  180. ListHead = &SkuNode->DataLinkHead;
  181. if (IsListEmpty (ListHead)) {
  182. return EFI_NOT_FOUND;
  183. }
  184. for (Link = GetFirstNode (ListHead); !IsNull (ListHead, Link); Link = GetNextNode (ListHead, Link)) {
  185. DataNode = CONFIG_NODE_INSTANCE_FROM_THIS (Link);
  186. ASSERT (DataNode != NULL);
  187. if (DataNode == NULL) {
  188. return EFI_UNSUPPORTED;
  189. }
  190. if (CompareGuid (ResId, &DataNode->ResId)) {
  191. if (DataSize != NULL) {
  192. if (*DataSize < DataNode->Size) {
  193. *DataSize = DataNode->Size;
  194. return EFI_BUFFER_TOO_SMALL;
  195. }
  196. *DataSize = DataNode->Size;
  197. if (Data != NULL) {
  198. CopyMem (Data, DataNode->Data, DataNode->Size);
  199. }
  200. }
  201. return EFI_SUCCESS;
  202. }
  203. }
  204. return EFI_NOT_FOUND;
  205. }
  206. /**
  207. Covert the LIST_ENTRY pointer from CAR to RAM after memory init.
  208. @param Link The LIST_ENTRY pointer want to convert.
  209. @param PtrPositive The pointer need positive fix.
  210. @param PtrDelta The pointer delta value after memory init.
  211. @retval EFI_SUCCESS Operation success.
  212. **/
  213. EFI_STATUS
  214. PeiConvertListPointer (
  215. IN LIST_ENTRY *Link,
  216. IN BOOLEAN PtrPositive,
  217. IN UINTN PtrDelta
  218. )
  219. {
  220. if (PtrPositive) {
  221. Link->ForwardLink = (LIST_ENTRY *) ((UINTN) Link->ForwardLink + PtrDelta);
  222. Link->BackLink = (LIST_ENTRY *) ((UINTN) Link->BackLink + PtrDelta);
  223. } else {
  224. Link->ForwardLink = (LIST_ENTRY *) ((UINTN) Link->ForwardLink - PtrDelta);
  225. Link->BackLink = (LIST_ENTRY *) ((UINTN) Link->BackLink - PtrDelta);
  226. }
  227. return EFI_SUCCESS;
  228. }
  229. /**
  230. Covert general pointer from CAR to RAM after memory init.
  231. @param Ptr The VOID pointer want to convert.
  232. @param PtrPositive The pointer need positive fix.
  233. @param PtrDelta The pointer delta value after memory init.
  234. @retval EFI_SUCCESS Operation success.
  235. **/
  236. EFI_STATUS
  237. PeiConvertVoidPointer (
  238. IN VOID **Ptr,
  239. IN BOOLEAN PtrPositive,
  240. IN UINTN PtrDelta
  241. )
  242. {
  243. if (PtrPositive) {
  244. *Ptr = (VOID *) ((UINTN)*Ptr + PtrDelta);
  245. } else {
  246. *Ptr = (VOID *) ((UINTN)*Ptr - PtrDelta);
  247. }
  248. return EFI_SUCCESS;
  249. }
  250. /**
  251. Covert all pointers from CAR to RAM after memory init.
  252. @param This The uba Ppi pointer.
  253. @param PtrPositive The pointer need positive fix.
  254. @param PtrDelta The pointer delta value after memory init.
  255. @retval EFI_SUCCESS Operation success.
  256. **/
  257. EFI_STATUS
  258. PeiConvertDataPointer (
  259. IN UBA_CONFIG_DATABASE_PPI *This,
  260. IN BOOLEAN PtrPositive,
  261. IN UINTN PtrDelta
  262. )
  263. {
  264. UBA_PEIM_PRIVATE_DATA *UbaPeimPrivate;
  265. UBA_BOARD_NODE *SkuNode;
  266. UBA_CONFIG_NODE *DataNode;
  267. LIST_ENTRY *DataListHead;
  268. LIST_ENTRY *DataLink;
  269. UbaPeimPrivate = NULL;
  270. SkuNode = NULL;
  271. DataNode = NULL;
  272. DataListHead = NULL;
  273. DataLink = NULL;
  274. UbaPeimPrivate = PRIVATE_DATA_FROM_PPI (This);
  275. if (UbaPeimPrivate->ThisAddress == (UINTN) This) {
  276. return EFI_SUCCESS;
  277. }
  278. PeiConvertVoidPointer ((VOID**) &UbaPeimPrivate->CurrentSku, PtrPositive, PtrDelta);
  279. SkuNode = UbaPeimPrivate->CurrentSku;
  280. DataListHead = &SkuNode->DataLinkHead;
  281. PeiConvertListPointer (DataListHead, PtrPositive, PtrDelta);
  282. DataLink = DataListHead->ForwardLink;
  283. while (DataListHead != DataLink) {
  284. PeiConvertListPointer (DataLink, PtrPositive, PtrDelta);
  285. DataNode = CONFIG_NODE_INSTANCE_FROM_THIS (DataLink);
  286. PeiConvertVoidPointer (&DataNode->Data, PtrPositive, PtrDelta);
  287. DataLink = DataLink->ForwardLink;
  288. }
  289. UbaPeimPrivate->ThisAddress = (UINTN) This;
  290. return EFI_SUCCESS;
  291. }
  292. /**
  293. Check whether the This pointer have been relocated after memory init,
  294. if true, we need also relocate our own pointers in the heap, because core won't
  295. do it for us.
  296. @param This The uba Ppi pointer.
  297. @retval EFI_SUCCESS Operation success.
  298. **/
  299. EFI_STATUS
  300. PeiCheckPointerRelocated (
  301. IN UBA_CONFIG_DATABASE_PPI *This
  302. )
  303. {
  304. EFI_STATUS Status;
  305. UBA_PEIM_PRIVATE_DATA *UbaPeimPrivate;
  306. BOOLEAN PtrPositive;
  307. UINTN PtrDelta;
  308. Status = EFI_SUCCESS;
  309. UbaPeimPrivate = NULL;
  310. PtrPositive = FALSE;
  311. PtrDelta = 0;
  312. UbaPeimPrivate = PRIVATE_DATA_FROM_PPI (This);
  313. if (UbaPeimPrivate->ThisAddress != (UINTN) This) {
  314. if ((UINTN) This > UbaPeimPrivate->ThisAddress) {
  315. PtrPositive = TRUE;
  316. PtrDelta = (UINTN) This - UbaPeimPrivate->ThisAddress;
  317. } else {
  318. PtrPositive = FALSE;
  319. PtrDelta = UbaPeimPrivate->ThisAddress - (UINTN) This;
  320. }
  321. Status = PeiConvertDataPointer (This, PtrPositive, PtrDelta);
  322. }
  323. return Status;
  324. }
  325. /**
  326. Set platform's GUID and user friendly name by BoardId.
  327. If the BoardId is not exist in database, it will create a new platform.
  328. @param This UBA Ppi instance.
  329. @param BoardId The platform type, same define as Platform.h.
  330. @param BoardGuid The GUID for this platform.
  331. @param BoardName The user friendly name for this platform.
  332. @retval EFI_ALREADY_STARTED Create new for an exist platform.
  333. @retval EFI_OUT_OF_RESOURCES Resource not enough.
  334. @retval EFI_NOT_FOUND Platform not found.
  335. @retval EFI_SUCCESS Operation success.
  336. **/
  337. EFI_STATUS
  338. EFIAPI
  339. PeiUbaInit (
  340. IN UBA_CONFIG_DATABASE_PPI *This,
  341. IN UINT32 BoardId,
  342. IN EFI_GUID *BoardGuid, OPTIONAL
  343. IN CHAR8 *BoardName OPTIONAL
  344. )
  345. {
  346. EFI_STATUS Status;
  347. UBA_BOARD_NODE *SkuNode;
  348. Status = EFI_SUCCESS;
  349. SkuNode = NULL;
  350. PeiCheckPointerRelocated (This);
  351. Status = InternalInitSku (This, BoardId, BoardGuid, BoardName, &SkuNode);
  352. return Status;
  353. }
  354. /**
  355. Get platform's GUID and user friendly name by BoardId.
  356. This is used when you need a BoardGuid to Add/Get platform data
  357. Core will create a new platform for you if the BoardId is not
  358. recorded in database, and assgin a unique GUID for this platform.
  359. @param This uba Ppi instance.
  360. @param BoardId The platform type, same define as Platform.h.
  361. @param BoardGuid The GUID for this platform.
  362. @param BoardName The user friendly name for this platform.
  363. @retval EFI_ALREADY_STARTED Create new for an exist platform.
  364. @retval EFI_OUT_OF_RESOURCES Resource not enough.
  365. @retval EFI_NOT_FOUND Platform not found.
  366. @retval EFI_SUCCESS Operation success.
  367. **/
  368. EFI_STATUS
  369. EFIAPI
  370. PeiUbaGetSku (
  371. IN UBA_CONFIG_DATABASE_PPI *This,
  372. OUT UINT32 *BoardId,
  373. OUT EFI_GUID *BoardGuid, OPTIONAL
  374. OUT CHAR8 *BoardName OPTIONAL
  375. )
  376. {
  377. EFI_STATUS Status;
  378. UBA_BOARD_NODE *SkuNode;
  379. SkuNode = NULL;
  380. PeiCheckPointerRelocated (This);
  381. Status = InternalGetSkuNode (This, &SkuNode);
  382. if (!EFI_ERROR (Status)) {
  383. if (BoardId != NULL) {
  384. *BoardId = SkuNode->BoardId;
  385. }
  386. if (BoardName != NULL) {
  387. AsciiStrCpyS (BoardName, AsciiStrSize (SkuNode->BoardName) / sizeof (CHAR8), SkuNode->BoardName);
  388. }
  389. if (BoardGuid != NULL) {
  390. CopyMem (BoardGuid, &SkuNode->BoardGuid, sizeof (EFI_GUID));
  391. }
  392. return EFI_SUCCESS;
  393. }
  394. return Status;
  395. }
  396. /**
  397. Add configuration data to uba configuration database.
  398. @param This uba Ppi instance.
  399. @param ResId The configuration data resource id.
  400. @param Data The data buffer pointer.
  401. @param DataSize Size of data want to add into database.
  402. @retval EFI_INVALID_PARAMETER Required parameters not correct.
  403. @retval EFI_OUT_OF_RESOURCES Resource not enough.
  404. @retval EFI_NOT_FOUND Platform not found.
  405. @retval EFI_SUCCESS Operation success.
  406. **/
  407. EFI_STATUS
  408. EFIAPI
  409. PeiUbaAddData (
  410. IN UBA_CONFIG_DATABASE_PPI *This,
  411. IN EFI_GUID *ResId,
  412. IN VOID *Data,
  413. IN UINTN DataSize
  414. )
  415. {
  416. EFI_STATUS Status;
  417. UBA_BOARD_NODE *SkuNode;
  418. SkuNode = NULL;
  419. PeiCheckPointerRelocated (This);
  420. Status = InternalGetSkuNode (This, &SkuNode);
  421. if (EFI_ERROR (Status)) {
  422. return Status;
  423. }
  424. Status = InternalAddNewConfigData (This, ResId, Data, DataSize);
  425. return Status;
  426. }
  427. /**
  428. Get configuration data from uba configuration database.
  429. @param This uba Ppi instance.
  430. @param ResId The configuration data resource id.
  431. @param Data The data buffer pointer.
  432. @param DataSize IN:Size of data want to get, OUT: Size of data in database.
  433. @retval EFI_INVALID_PARAMETER Required parameters not correct.
  434. @retval EFI_BUFFER_TOO_SMALL The DataSize of Data buffer is too small to get this configuration data
  435. @retval EFI_OUT_OF_RESOURCES Resource not enough.
  436. @retval EFI_NOT_FOUND Platform or data not found.
  437. @retval EFI_SUCCESS Operation success.
  438. **/
  439. EFI_STATUS
  440. EFIAPI
  441. PeiUbaGetData (
  442. IN UBA_CONFIG_DATABASE_PPI *This,
  443. IN EFI_GUID *ResId,
  444. OUT VOID *Data,
  445. OUT UINTN *DataSize
  446. )
  447. {
  448. EFI_STATUS Status;
  449. UBA_BOARD_NODE *SkuNode;
  450. SkuNode = NULL;
  451. if ((ResId == NULL) || (Data == NULL) || (DataSize == NULL)) {
  452. return EFI_INVALID_PARAMETER;
  453. }
  454. PeiCheckPointerRelocated (This);
  455. Status = InternalGetSkuNode (This, &SkuNode);
  456. if (EFI_ERROR (Status)) {
  457. return Status;
  458. }
  459. Status = InternalGetConfigData (This, SkuNode, ResId, Data, DataSize);
  460. if (!EFI_ERROR (Status)) {
  461. return EFI_SUCCESS;
  462. }
  463. return EFI_NOT_FOUND;
  464. }
  465. /**
  466. Internal function for creating a HOB for platform data,
  467. and copy all the platform information and configuration data to the HOB,
  468. it will be passed to DXE driver.
  469. @param SkuNode The platform node in database.
  470. @param HobGuid The Hob GUID want to build.
  471. @retval EFI_OUT_OF_RESOURCES No enough resource.
  472. @retval EFI_SUCCESS Operation success.
  473. **/
  474. EFI_STATUS
  475. InternalCreateHobForSkuNode (
  476. IN UBA_BOARD_NODE *SkuNode,
  477. IN EFI_GUID *HobGuid
  478. )
  479. {
  480. UINT8 *HobData;
  481. UBA_CONFIG_HOB_HEADER *HobHeader;
  482. UBA_CONFIG_HOB_FIELD *HobDataFieldStart;
  483. UINT8 *ConfigDataHobPtr;
  484. UINTN DataLength;
  485. UINTN Index;
  486. LIST_ENTRY *ListHead;
  487. LIST_ENTRY *Link;
  488. UBA_CONFIG_NODE *DataNode;
  489. HobData = NULL;
  490. HobHeader = NULL;
  491. HobDataFieldStart = NULL;
  492. ConfigDataHobPtr = NULL;
  493. DataLength = 0;
  494. ListHead = NULL;
  495. Link = NULL;
  496. DataNode = NULL;
  497. if (SkuNode->DataCount != 0) {
  498. DataLength = sizeof (UBA_CONFIG_HOB_HEADER) +
  499. sizeof (UBA_CONFIG_HOB_FIELD) * (SkuNode->DataCount - 1);
  500. //
  501. // Get config data size
  502. //
  503. ListHead = &SkuNode->DataLinkHead;
  504. for (Link = GetFirstNode (ListHead); !IsNull (ListHead, Link); Link = GetNextNode (ListHead, Link)) {
  505. DataNode = CONFIG_NODE_INSTANCE_FROM_THIS (Link);
  506. DataLength += DataNode->Size;
  507. }
  508. HobData = BuildGuidHob (HobGuid, DataLength);
  509. ASSERT (HobData != NULL);
  510. if (HobData == NULL) {
  511. return EFI_OUT_OF_RESOURCES;
  512. }
  513. HobHeader = (UBA_CONFIG_HOB_HEADER *) HobData;
  514. HobDataFieldStart = HobHeader->HobField;
  515. ConfigDataHobPtr = (UINT8 *) HobDataFieldStart + (sizeof (UBA_CONFIG_HOB_FIELD) * SkuNode->DataCount);
  516. //
  517. // Copy our HOB header
  518. //
  519. HobHeader->Signature = UBA_CONFIG_HOB_SIGNATURE;
  520. HobHeader->Version = UBA_CONFIG_HOB_VERSION;
  521. HobHeader->HobLength = DataLength;
  522. CopyGuid (&HobHeader->DataGuid, HobGuid);
  523. HobHeader->BoardId = SkuNode->BoardId;
  524. HobHeader->DataCount = SkuNode->DataCount;
  525. CopyGuid (&HobHeader->BoardGuid, &SkuNode->BoardGuid);
  526. CopyMem (HobHeader->BoardName, SkuNode->BoardName, AsciiStrSize (SkuNode->BoardName));
  527. //
  528. // Copy N * (UBA_CONFIG_HOB_NODE & UBA_CONFIG_HOB_NODE->Data)
  529. //
  530. Index = 0;
  531. ListHead = &SkuNode->DataLinkHead;
  532. for (Link = GetFirstNode (ListHead); !IsNull (ListHead, Link); Link = GetNextNode (ListHead, Link)) {
  533. DataNode = CONFIG_NODE_INSTANCE_FROM_THIS (Link);
  534. ASSERT (DataNode != NULL);
  535. if (DataNode == NULL) {
  536. return EFI_UNSUPPORTED;
  537. }
  538. HobDataFieldStart[Index].Size = DataNode->Size;
  539. HobDataFieldStart[Index].Signature = DataNode->Signature;
  540. HobDataFieldStart[Index].Version = DataNode->Version;
  541. CopyGuid (&HobDataFieldStart[Index].ResId, &DataNode->ResId);
  542. CopyMem (ConfigDataHobPtr, DataNode->Data, DataNode->Size);
  543. //
  544. // Fix the config data pointer after memory copy
  545. // Set the pointer address into memory in HOB
  546. //
  547. HobDataFieldStart[Index].DataOffset = ((UINTN) ConfigDataHobPtr - (UINTN) HobHeader);
  548. Index ++;
  549. ConfigDataHobPtr += DataNode->Size;
  550. }
  551. }
  552. return EFI_SUCCESS;
  553. }
  554. /**
  555. End of PEI phase callback, we need build configuration data HOB in this callback,
  556. it will pass to DXE driver.
  557. @param PeiServices The PEI service pointer.
  558. @param NotifyDescriptor The notify descriptor.
  559. @param Ppi The PPI was notified.
  560. @retval EFI_OUT_OF_RESOURCES No enough resource.
  561. @retval EFI_NOT_FOUND Platform/data not found.
  562. @retval EFI_SUCCESS Operation success.
  563. **/
  564. EFI_STATUS
  565. EndOfPeiPpiNotifyCallback (
  566. IN EFI_PEI_SERVICES **PeiServices,
  567. IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
  568. IN VOID *Ppi
  569. )
  570. {
  571. EFI_STATUS Status;
  572. UBA_CONFIG_DATABASE_PPI *UbaConfigPpi;
  573. UBA_PEIM_PRIVATE_DATA *UbaPeimPrivate;
  574. UBA_BOARD_NODE *SkuNode;
  575. UbaPeimPrivate = NULL;
  576. SkuNode = NULL;
  577. Status = PeiServicesLocatePpi (
  578. &gUbaConfigDatabasePpiGuid,
  579. 0,
  580. NULL,
  581. (VOID**) &UbaConfigPpi
  582. );
  583. ASSERT_EFI_ERROR (Status);
  584. if (Status != EFI_SUCCESS) {
  585. return Status;
  586. }
  587. PeiCheckPointerRelocated (UbaConfigPpi);
  588. //
  589. // Build GUID data HOB for current platform configuration data
  590. //
  591. UbaPeimPrivate = PRIVATE_DATA_FROM_PPI (UbaConfigPpi);
  592. if (UbaPeimPrivate->CurrentSku != NULL) {
  593. SkuNode = UbaPeimPrivate->CurrentSku;
  594. Status = InternalCreateHobForSkuNode (SkuNode, &gUbaCurrentConfigHobGuid);
  595. ASSERT_EFI_ERROR (Status);
  596. if (Status != EFI_SUCCESS) {
  597. return Status;
  598. }
  599. }
  600. //
  601. // Other will not pass to DXE because it's useless
  602. //
  603. return EFI_SUCCESS;
  604. }
  605. EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
  606. {
  607. EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
  608. &gEfiEndOfPeiSignalPpiGuid,
  609. EndOfPeiPpiNotifyCallback
  610. }
  611. };
  612. /**
  613. Entry point function for the PEIM
  614. @param FileHandle Handle of the file being invoked.
  615. @param PeiServices Describes the list of possible PEI Services.
  616. @return EFI_SUCCESS If we installed our PPI
  617. **/
  618. EFI_STATUS
  619. EFIAPI
  620. UbaConfigDatabasePeimEntry (
  621. IN EFI_PEI_FILE_HANDLE FileHandle,
  622. IN CONST EFI_PEI_SERVICES **PeiServices
  623. )
  624. {
  625. EFI_STATUS Status;
  626. UBA_PEIM_PRIVATE_DATA *UbaPeimPrivate;
  627. UbaPeimPrivate = NULL;
  628. UbaPeimPrivate = AllocateZeroPool (sizeof (UBA_PEIM_PRIVATE_DATA));
  629. if (UbaPeimPrivate == NULL) {
  630. return EFI_OUT_OF_RESOURCES;
  631. }
  632. DEBUG ((DEBUG_INFO, "UbaConfigDatabasePeimEntry!\n"));
  633. UbaPeimPrivate->Signature = UBA_BOARD_SIGNATURE;
  634. UbaPeimPrivate->Version = UBA_BOARD_VERSION;
  635. UbaPeimPrivate->ConfigDataCount = 0;
  636. UbaPeimPrivate->HandleCount = 0;
  637. UbaPeimPrivate->ThisAddress = (UINTN) &UbaPeimPrivate->UbaCfgDbPpi;
  638. UbaPeimPrivate->UbaPeimPpiList.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
  639. UbaPeimPrivate->UbaPeimPpiList.Guid = &gUbaConfigDatabasePpiGuid;
  640. UbaPeimPrivate->UbaPeimPpiList.Ppi = &UbaPeimPrivate->UbaCfgDbPpi;
  641. UbaPeimPrivate->UbaCfgDbPpi.Signature = UBA_CONFIG_PPI_SIGNATURE;
  642. UbaPeimPrivate->UbaCfgDbPpi.Version = UBA_CONFIG_PPI_VERSION;
  643. UbaPeimPrivate->UbaCfgDbPpi.InitSku = PeiUbaInit;
  644. UbaPeimPrivate->UbaCfgDbPpi.GetSku = PeiUbaGetSku;
  645. UbaPeimPrivate->UbaCfgDbPpi.AddData = PeiUbaAddData;
  646. UbaPeimPrivate->UbaCfgDbPpi.GetData = PeiUbaGetData;
  647. //
  648. // Just produce our PPI
  649. //
  650. Status = PeiServicesInstallPpi (&UbaPeimPrivate->UbaPeimPpiList);
  651. if (EFI_ERROR (Status)) {
  652. return Status;
  653. }
  654. Status = PeiServicesNotifyPpi (&mNotifyList[0]);
  655. ASSERT_EFI_ERROR (Status);
  656. return Status;
  657. }