UbaSmbiosUpdateLib.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. /** @file
  2. UbaSmbiosUpdateLib implementation.
  3. @copyright
  4. Copyright 2012 - 2017 Intel Corporation. <BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <Base.h>
  8. #include <Uefi.h>
  9. #include <IndustryStandard/SmBios.h>
  10. #include <Protocol/Smbios.h>
  11. #include <Library/BaseLib.h>
  12. #include <Library/BaseMemoryLib.h>
  13. #include <Library/MemoryAllocationLib.h>
  14. #include <Library/UefiBootServicesTableLib.h>
  15. #include <Library/DebugLib.h>
  16. #include <Library/UbaSmbiosUpdateLib.h>
  17. #include <Protocol/UbaCfgDb.h>
  18. #include <Guid/EventGroup.h>
  19. #define SMBIOS_TYPE_MAX_LENGTH 0x300
  20. /**
  21. Provide the RegData and register a callback for dynamic update SMBIOS data.
  22. @param RegData Callback register data.
  23. @retval EFI_NOT_FOUND Data log protocol not found.
  24. @retval EFI_OUT_OF_RESOURCES Data was not logged due to lack of system resources.
  25. @retval EFI_SUCCESS Data have been updated successfully.
  26. **/
  27. EFI_STATUS
  28. PlatformRegisterSmbiosUpdate (
  29. IN SMBIOS_UPDATE_DATA *RegData
  30. )
  31. {
  32. EFI_STATUS Status;
  33. STATIC UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol = NULL;
  34. if (UbaConfigProtocol == NULL) {
  35. Status = gBS->LocateProtocol (
  36. &gUbaConfigDatabaseProtocolGuid,
  37. NULL,
  38. &UbaConfigProtocol
  39. );
  40. if (EFI_ERROR (Status)) {
  41. return Status;
  42. }
  43. }
  44. RegData->Signature = PLATFORM_SMBIOS_UPDATE_SIGNATURE;
  45. RegData->Version = PLATFORM_SMBIOS_UPDATE_VERSION;
  46. Status = UbaConfigProtocol->AddData (
  47. UbaConfigProtocol,
  48. &gPlatformSmbiosConfigDataGuid,
  49. RegData,
  50. sizeof(SMBIOS_UPDATE_DATA)
  51. );
  52. return Status;
  53. }
  54. /**
  55. Update a String for a filled SMBIOS data structure, the structure must be filled
  56. before update string.
  57. This function update a string indicated by StringNumber to the tail of SMBIOS
  58. structure.
  59. @param Smbios SMBIOS structure data buffer pointer.
  60. @param BufferSize SMBIOS structure data buffer size.
  61. @param StringNumber The string index number of SMBIOS structure.
  62. @param String String want to update.
  63. @retval EFI_OUT_OF_RESOURCES No enough memory for this action.
  64. @retval EFI_SUCCESS String updated successfully.
  65. **/
  66. EFI_STATUS
  67. PlatformSmbiosUpdateString (
  68. IN OUT SMBIOS_STRUCTURE_POINTER Smbios,
  69. IN UINTN BufferSize,
  70. IN UINTN StringNumber,
  71. IN CHAR16 *String
  72. )
  73. {
  74. EFI_STATUS Status;
  75. CHAR8 *AsciiString = NULL;
  76. UINTN InputStrLen;
  77. UINTN TargetStrLen;
  78. UINTN StrIndex;
  79. UINTN TargetStrOffset;
  80. CHAR8 *StrStart;
  81. SMBIOS_STRUCTURE_POINTER NewSmbiosPtr;
  82. UINTN OrigSize = 0;
  83. UINTN NewSize = 0;
  84. UINTN StringSize = 0;
  85. StringSize = StrSize (String);
  86. AsciiString = AllocateZeroPool (StringSize);
  87. ASSERT (AsciiString != NULL);
  88. if (AsciiString == NULL) {
  89. return EFI_OUT_OF_RESOURCES;
  90. }
  91. UnicodeStrToAsciiStrS (String, AsciiString, StringSize);
  92. InputStrLen = AsciiStrLen (AsciiString);
  93. Status = PlatformSmbiosGetTypeLength (Smbios, &OrigSize);
  94. //
  95. // Point to unformed string section
  96. //
  97. StrStart = (CHAR8 *) Smbios.Hdr + Smbios.Hdr->Length;
  98. for (StrIndex = 1, TargetStrOffset = 0; StrIndex < StringNumber; StrStart++, TargetStrOffset++) {
  99. //
  100. // A string ends in 00h
  101. //
  102. if (*StrStart == 0) {
  103. StrIndex++;
  104. }
  105. }
  106. //
  107. // Now we get the string target
  108. //
  109. TargetStrLen = AsciiStrLen(StrStart);
  110. if (InputStrLen == TargetStrLen) {
  111. Status = AsciiStrCpyS(StrStart, TargetStrLen + 1, AsciiString);
  112. ASSERT_EFI_ERROR (Status);
  113. if (EFI_ERROR (Status)) {
  114. return Status;
  115. }
  116. return EFI_SUCCESS;
  117. }
  118. //
  119. // Original string buffer size is not exactly match input string length.
  120. // Re-allocate buffer is needed.
  121. //
  122. NewSmbiosPtr.Hdr = AllocateZeroPool (SMBIOS_TYPE_MAX_LENGTH);
  123. if (NewSmbiosPtr.Hdr == NULL) {
  124. return EFI_OUT_OF_RESOURCES;
  125. }
  126. //
  127. // Copy SMBIOS structure and optional strings.
  128. //
  129. CopyMem (NewSmbiosPtr.Hdr, Smbios.Hdr, Smbios.Hdr->Length + TargetStrOffset);
  130. CopyMem ((CHAR8*)NewSmbiosPtr.Hdr + Smbios.Hdr->Length + TargetStrOffset, AsciiString, InputStrLen + 1);
  131. CopyMem ((CHAR8*)NewSmbiosPtr.Hdr + Smbios.Hdr->Length + TargetStrOffset + InputStrLen + 1,
  132. (CHAR8*)Smbios.Hdr + Smbios.Hdr->Length + TargetStrOffset + TargetStrLen + 1,
  133. OrigSize - Smbios.Hdr->Length - TargetStrOffset - TargetStrLen - 1);
  134. Status = PlatformSmbiosGetTypeLength (NewSmbiosPtr, &NewSize);
  135. CopyMem (Smbios.Hdr, NewSmbiosPtr.Hdr, NewSize);
  136. FreePool (NewSmbiosPtr.Hdr);
  137. FreePool (AsciiString);
  138. return EFI_SUCCESS;
  139. }
  140. /**
  141. Get SMBIOS data structure length, include the string in tail.
  142. @param Smbios SMBIOS structure data buffer pointer.
  143. @param TypeSize SMBIOS structure size.
  144. @retval EFI_INVALID_PARAMETER Input paramter invalid.
  145. @retval EFI_SUCCESS Caculate data structure size successfully.
  146. **/
  147. EFI_STATUS
  148. PlatformSmbiosGetTypeLength (
  149. IN OUT SMBIOS_STRUCTURE_POINTER Smbios,
  150. IN OUT UINTN *TypeSize
  151. )
  152. {
  153. UINTN FullSize;
  154. UINTN StrLen;
  155. UINTN MaxLen;
  156. INT8* CharInStr;
  157. if (TypeSize == NULL) {
  158. return EFI_INVALID_PARAMETER;
  159. }
  160. FullSize = Smbios.Hdr->Length;
  161. CharInStr = (INT8*)Smbios.Hdr + Smbios.Hdr->Length;
  162. *TypeSize = FullSize;
  163. StrLen = 0;
  164. //
  165. // look for the two consecutive zeros, check the string limit by the way.
  166. //
  167. while (*CharInStr != 0 || *(CharInStr+1) != 0) {
  168. if (*CharInStr == 0) {
  169. *TypeSize += 1;
  170. CharInStr++;
  171. }
  172. MaxLen = SMBIOS_STRING_MAX_LENGTH;
  173. for (StrLen = 0 ; StrLen < MaxLen; StrLen++) {
  174. if (*(CharInStr+StrLen) == 0) {
  175. break;
  176. }
  177. }
  178. if (StrLen == MaxLen) {
  179. return EFI_INVALID_PARAMETER;
  180. }
  181. //
  182. // forward the pointer
  183. //
  184. CharInStr += StrLen;
  185. *TypeSize += StrLen;
  186. }
  187. //
  188. // count ending two zeros.
  189. //
  190. *TypeSize += 2;
  191. return EFI_SUCCESS;
  192. }
  193. /**
  194. Add a new SMBIOS structure into SMBIOS database.
  195. @param Smbios SMBIOS structure data buffer pointer.
  196. @retval EFI_NOT_FOUND SMBIOS protocol not installed.
  197. @retval EFI_SUCCESS Add data structure successfully.
  198. **/
  199. EFI_STATUS
  200. PlatformSmbiosAddNew (
  201. IN SMBIOS_STRUCTURE_POINTER SmbiosPtr
  202. )
  203. {
  204. EFI_STATUS Status;
  205. STATIC EFI_SMBIOS_PROTOCOL *Smbios = NULL;
  206. EFI_SMBIOS_HANDLE SmbiosHandle;
  207. if (Smbios == NULL) {
  208. Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
  209. if (EFI_ERROR (Status)) {
  210. return Status;
  211. }
  212. }
  213. SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  214. Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*)SmbiosPtr.Hdr);
  215. return EFI_SUCCESS;
  216. }
  217. /**
  218. Get the number of instance of SMBIOS type structure in SMBIOS database.
  219. return 0 means no instance for this type now.
  220. @param Type SMBIOS type.
  221. @retval Count Number of instance.
  222. **/
  223. UINTN
  224. PlatformSmbiosGetInstanceCount (
  225. IN UINT8 Type
  226. )
  227. {
  228. EFI_STATUS Status;
  229. STATIC EFI_SMBIOS_PROTOCOL *Smbios = NULL;
  230. EFI_SMBIOS_TABLE_HEADER *SmbiosRecord;
  231. EFI_SMBIOS_HANDLE SmbiosHandle;
  232. EFI_SMBIOS_TYPE SmbiosType;
  233. UINTN Count = 0;
  234. if (Smbios == NULL) {
  235. Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
  236. if (EFI_ERROR (Status)) {
  237. return Status;
  238. }
  239. }
  240. SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  241. SmbiosType = Type;
  242. do {
  243. Status = Smbios->GetNext (Smbios, &SmbiosHandle, &SmbiosType, &SmbiosRecord, NULL);
  244. if (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED)) {
  245. Count ++;
  246. }
  247. } while (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED));
  248. return Count;
  249. }
  250. /**
  251. Get SMBIOS type data structure in SMBIOS database.
  252. This function give you a pointer of SMBIOS structure directly in the database, you can update
  253. the value in formated structure area and it's take affect immediately, but never directly or
  254. call PlatformSmbiosUpdateString to edit the string in this buffer,
  255. use PlatformSmbiosGetEditCopy->PlatformSmbiosUpdateType instead.
  256. One of the SmbiosPtr or Handle must be valid value.
  257. @param Type SMBIOS type.
  258. @param Instance The instance of this type.
  259. @param SmbiosPtr Optional parameter, on input, pass a pointer of SMBIOS_STRUCTURE_POINTER
  260. to this function.
  261. On output, return the SMBIOS data pointer in SmbiosPtr.
  262. @param Handle Optional parameter, on input, pass a pointer of Handle.
  263. On output, return the SMBIOS data handle value
  264. @retval EFI_INVALID_PARAMETER Both the SmbiosPtr and Handle is NULL.
  265. @retval EFI_NOT_FOUND SMBIOS protocol not installed.
  266. @retval EFI_SUCCESS Get structure data successfully.
  267. **/
  268. EFI_STATUS
  269. PlatformSmbiosGetInstance (
  270. IN UINT8 Type,
  271. IN UINTN Instance,
  272. IN OUT SMBIOS_STRUCTURE_POINTER *SmbiosPtr,
  273. IN OUT UINT16 *Handle
  274. )
  275. {
  276. EFI_STATUS Status;
  277. STATIC EFI_SMBIOS_PROTOCOL *Smbios = NULL;
  278. EFI_SMBIOS_TABLE_HEADER *SmbiosRecord;
  279. EFI_SMBIOS_HANDLE SmbiosHandle;
  280. EFI_SMBIOS_TYPE SmbiosType;
  281. UINTN Count = 0;
  282. if ((SmbiosPtr == NULL) && (Handle == NULL)) {
  283. return EFI_INVALID_PARAMETER;
  284. }
  285. if (Smbios == NULL) {
  286. Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
  287. if (EFI_ERROR (Status)) {
  288. return Status;
  289. }
  290. }
  291. SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  292. SmbiosType = Type;
  293. do {
  294. Status = Smbios->GetNext (Smbios, &SmbiosHandle, &SmbiosType, &SmbiosRecord, NULL);
  295. if (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED)) {
  296. if (++Count == Instance) {
  297. if (SmbiosPtr != NULL) {
  298. (*SmbiosPtr).Hdr = (SMBIOS_STRUCTURE*)SmbiosRecord;
  299. }
  300. if (Handle != NULL) {
  301. *Handle = SmbiosHandle;
  302. }
  303. return EFI_SUCCESS;
  304. }
  305. }
  306. } while (!EFI_ERROR (Status) && (SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED));
  307. return EFI_NOT_FOUND;
  308. }
  309. /**
  310. Get a copy of SMBIOS type structure data in SMBIOS database.
  311. Must allocate memory large enough first, then call this function to get the copy.
  312. @param Type SMBIOS type.
  313. @param Instance The instance of this type.
  314. @param SmbiosPtr A valid buffer pointer which SMBIOS data will copy to this buffer.
  315. @retval EFI_NOT_FOUND SMBIOS protocol not installed.
  316. @retval EFI_SUCCESS Get structure data successfully.
  317. **/
  318. EFI_STATUS
  319. PlatformSmbiosGetEditCopy (
  320. IN UINT8 Type,
  321. IN UINTN Instance,
  322. IN OUT SMBIOS_STRUCTURE_POINTER SmbiosPtr
  323. )
  324. {
  325. EFI_STATUS Status;
  326. SMBIOS_STRUCTURE_POINTER NewSmbiosPtr;
  327. UINTN Size;
  328. Status = PlatformSmbiosGetInstance (Type, Instance, &NewSmbiosPtr, NULL);
  329. if (EFI_ERROR (Status)) {
  330. return Status;
  331. }
  332. Status = PlatformSmbiosGetTypeLength (NewSmbiosPtr, &Size);
  333. if (EFI_ERROR (Status)) {
  334. return Status;
  335. }
  336. CopyMem (SmbiosPtr.Hdr, NewSmbiosPtr.Hdr, Size);
  337. return EFI_SUCCESS;
  338. }
  339. /**
  340. Update a string which in SMBIOS database.
  341. The data structure which string belong to must installed before.
  342. @param Type SMBIOS type.
  343. @param Instance The instance of this type.
  344. @param StringNumber The string number.
  345. @param String The string want to update.
  346. @retval EFI_NOT_FOUND SMBIOS protocol not installed.
  347. @retval EFI_SUCCESS Update data successfully.
  348. **/
  349. EFI_STATUS
  350. PlatformSmbiosUpdateInstalledString (
  351. IN UINT8 Type,
  352. IN UINTN Instance,
  353. IN UINTN StringNumber,
  354. IN CHAR16 *String
  355. )
  356. {
  357. EFI_STATUS Status;
  358. STATIC EFI_SMBIOS_PROTOCOL *Smbios = NULL;
  359. EFI_SMBIOS_HANDLE SmbiosHandle;
  360. CHAR8 *AsciiStr = NULL;
  361. UINTN StringSize = 0;
  362. if (Smbios == NULL) {
  363. Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
  364. if (EFI_ERROR (Status)) {
  365. return Status;
  366. }
  367. }
  368. StringSize = StrSize (String);
  369. AsciiStr = AllocateZeroPool (StringSize);
  370. UnicodeStrToAsciiStrS (String, AsciiStr, StringSize);
  371. Status = PlatformSmbiosGetInstance (Type, Instance, NULL, &SmbiosHandle);
  372. if (!EFI_ERROR (Status)) {
  373. Status = Smbios->UpdateString (Smbios, &SmbiosHandle, &StringNumber, AsciiStr);
  374. }
  375. FreePool (AsciiStr);
  376. return Status;
  377. }
  378. /**
  379. Remove a SMBIOS instance in SMBIOS database.
  380. @param Type SMBIOS type.
  381. @param Instance The instance of this type.
  382. @retval EFI_NOT_FOUND SMBIOS protocol not installed.
  383. @retval EFI_SUCCESS Remove data successfully.
  384. **/
  385. EFI_STATUS
  386. PlatformSmbiosRemoveType (
  387. IN UINT8 Type,
  388. IN UINTN Instance
  389. )
  390. {
  391. EFI_STATUS Status;
  392. STATIC EFI_SMBIOS_PROTOCOL *Smbios = NULL;
  393. EFI_SMBIOS_HANDLE SmbiosHandle;
  394. if (Smbios == NULL) {
  395. Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
  396. if (EFI_ERROR (Status)) {
  397. return Status;
  398. }
  399. }
  400. Status = PlatformSmbiosGetInstance (Type, Instance, NULL, &SmbiosHandle);
  401. if (!EFI_ERROR (Status)) {
  402. Status = Smbios->Remove (Smbios, SmbiosHandle);
  403. }
  404. return Status;
  405. }
  406. /**
  407. Remove all the instance of specific SMBIOS type in SMBIOS database.
  408. @param Type SMBIOS type.
  409. @retval EFI_NOT_FOUND SMBIOS protocol not installed.
  410. @retval EFI_SUCCESS Remove data successfully.
  411. **/
  412. EFI_STATUS
  413. PlatformSmbiosRemoveAll (
  414. IN UINT8 Type
  415. )
  416. {
  417. EFI_STATUS Status;
  418. UINTN Count;
  419. UINTN Index;
  420. Count = PlatformSmbiosGetInstanceCount (Type);
  421. for (Index = 0; Index < Count; Index++) {
  422. Status = PlatformSmbiosRemoveType (Type, 1);
  423. if (EFI_ERROR (Status)) {
  424. return Status;
  425. }
  426. }
  427. return EFI_SUCCESS;
  428. }
  429. /**
  430. Update SMBIOS data structure in database with new structure data.
  431. @param Type SMBIOS type.
  432. @param Instance The instance of this type.
  433. @param SmbiosPtr A valid buffer pointer which new SMBIOS data stored.
  434. @retval EFI_NOT_FOUND SMBIOS protocol not installed.
  435. @retval EFI_SUCCESS Update data successfully.
  436. **/
  437. EFI_STATUS
  438. PlatformSmbiosUpdateType (
  439. IN UINT8 Type,
  440. IN UINTN Instance,
  441. IN SMBIOS_STRUCTURE_POINTER SmbiosPtr
  442. )
  443. {
  444. EFI_STATUS Status;
  445. STATIC EFI_SMBIOS_PROTOCOL *Smbios = NULL;
  446. EFI_SMBIOS_HANDLE SmbiosHandle;
  447. if (Smbios == NULL) {
  448. Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &Smbios);
  449. if (EFI_ERROR (Status)) {
  450. return Status;
  451. }
  452. }
  453. Status = PlatformSmbiosGetInstance (Type, Instance, NULL, &SmbiosHandle);
  454. if (EFI_ERROR (Status)) {
  455. return Status;
  456. }
  457. Status = PlatformSmbiosRemoveType (Type, Instance);
  458. if (EFI_ERROR (Status)) {
  459. return Status;
  460. }
  461. Status = PlatformSmbiosAddNew (SmbiosPtr);
  462. if (EFI_ERROR (Status)) {
  463. return Status;
  464. }
  465. return Status;
  466. }
  467. /**
  468. Implement the dynamic SMBIOS data update.
  469. @param UpdateType Immediately update or delay update at BDS.
  470. @retval EFI_SUCCESS Update successfully.
  471. **/
  472. EFI_STATUS
  473. DispatchSmbiosDynamicUpdate (
  474. IN SmbiosUpdateType UpdateType
  475. )
  476. {
  477. EFI_STATUS Status;
  478. UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol = NULL;
  479. UINTN DataLength = 0;
  480. SMBIOS_UPDATE_DATA RegData;
  481. Status = gBS->LocateProtocol (
  482. &gUbaConfigDatabaseProtocolGuid,
  483. NULL,
  484. &UbaConfigProtocol
  485. );
  486. if (EFI_ERROR (Status)) {
  487. return Status;
  488. }
  489. DataLength = sizeof (SMBIOS_UPDATE_DATA);
  490. Status = UbaConfigProtocol->GetData (
  491. UbaConfigProtocol,
  492. &gPlatformSmbiosConfigDataGuid,
  493. &RegData,
  494. &DataLength
  495. );
  496. if (EFI_ERROR (Status)) {
  497. return Status;
  498. }
  499. ASSERT (RegData.Signature == PLATFORM_SMBIOS_UPDATE_SIGNATURE);
  500. ASSERT (RegData.Version == PLATFORM_SMBIOS_UPDATE_VERSION);
  501. //
  502. // Check for updatetype match.
  503. //
  504. if ((RegData.UpdateType == UpdateType) && (RegData.CallUpdate != NULL)) {
  505. //
  506. // Invoke the callback and update every instance of this type
  507. //
  508. Status = RegData.CallUpdate ();
  509. }
  510. return EFI_SUCCESS;
  511. }
  512. /**
  513. Function provide to DXE driver, which initial the dynamic update.
  514. @param NULL
  515. @retval EFI_NOT_FOUND Required protocol not found.
  516. @retval EFI_SUCCESS Init successfully.
  517. **/
  518. EFI_STATUS
  519. PlatformInitSmbiosUpdate (
  520. VOID
  521. )
  522. {
  523. EFI_STATUS Status;
  524. DEBUG ((DEBUG_INFO, "UBA SMBIOS Update Library: PlatformInitSmbiosUpdate!\n"));
  525. Status = DispatchSmbiosDynamicUpdate (SmbiosDelayUpdate);
  526. return Status;
  527. }