MiscOemType0x94Function.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177
  1. /*++
  2. Copyright (c) 1999 - 2019, Intel Corporation. All rights reserved.
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. Module Name:
  5. MiscOemType0x94Function.c
  6. Abstract:
  7. The function that processes the Smbios data type 0x94.
  8. --*/
  9. #include "CommonHeader.h"
  10. #include "MiscSubclassDriver.h"
  11. #include <Library/HiiLib.h>
  12. #include <Library/PrintLib.h>
  13. #include <Protocol/PciRootBridgeIo.h>
  14. #include <Protocol/SimpleNetwork.h>
  15. #include <Protocol/DevicePath.h>
  16. #include <Protocol/DiskInfo.h>
  17. #include <Protocol/IdeControllerInit.h>
  18. #include <Protocol/MpService.h>
  19. #include <Protocol/PchPlatformPolicy.h>
  20. #include <Protocol/I2cBus.h>
  21. #include <Library/IoLib.h>
  22. #include <Library/CpuIA32.h>
  23. #include <Library/UefiRuntimeServicesTableLib.h>
  24. #include <Guid/PlatformInfo.h>
  25. #include <Guid/SetupVariable.h>
  26. #include <Guid/Vlv2Variable.h>
  27. #include "Valleyview.h"
  28. #include "VlvAccess.h"
  29. #include "PchAccess.h"
  30. #include "SetupMode.h"
  31. #include "PchCommonDefinitions.h"
  32. #include <PlatformBaseAddresses.h>
  33. typedef struct {
  34. UINT8 RevId;
  35. CHAR8 String[16];
  36. } SB_REV;
  37. //
  38. // Silicon Steppings
  39. //
  40. SB_REV SBRevisionTable[] = {
  41. {V_PCH_LPC_RID_0, "(A0 Stepping)"},
  42. {V_PCH_LPC_RID_1, "(A0 Stepping)"},
  43. {V_PCH_LPC_RID_2, "(A1 Stepping)"},
  44. {V_PCH_LPC_RID_3, "(A1 Stepping)"},
  45. {V_PCH_LPC_RID_4, "(B0 Stepping)"},
  46. {V_PCH_LPC_RID_5, "(B0 Stepping)"},
  47. {V_PCH_LPC_RID_6, "(B1 Stepping)"},
  48. {V_PCH_LPC_RID_7, "(B1 Stepping)"},
  49. {V_PCH_LPC_RID_8, "(B2 Stepping)"},
  50. {V_PCH_LPC_RID_9, "(B2 Stepping)"},
  51. {V_PCH_LPC_RID_A, "(B3 Stepping)"},
  52. {V_PCH_LPC_RID_B, "(B3 Stepping)"}
  53. };
  54. #define LEFT_JUSTIFY 0x01
  55. #define PREFIX_SIGN 0x02
  56. #define PREFIX_BLANK 0x04
  57. #define COMMA_TYPE 0x08
  58. #define LONG_TYPE 0x10
  59. #define PREFIX_ZERO 0x20
  60. #define ICH_REG_REV 0x08
  61. #define MSR_IA32_PLATFORM_ID 0x17
  62. #define CHARACTER_NUMBER_FOR_VALUE 30
  63. UINT8 ReadBuffer[20]; //Version report length
  64. UINT8 WriteBuffer[22] = {0x40,0x01,0x14,0x00,0x06,0x51,0x02,0x07,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //Version request
  65. /**
  66. VSPrint worker function that prints a Value as a decimal number in Buffer
  67. @param Buffer Location to place ascii decimal number string of Value.
  68. @param Value Decimal value to convert to a string in Buffer.
  69. @param Flags Flags to use in printing decimal string, see file header for details.
  70. @param Width Width of hex value.
  71. @retval Number of characters printed.
  72. **/
  73. UINTN
  74. EfiValueToString (
  75. IN OUT CHAR16 *Buffer,
  76. IN INT64 Value,
  77. IN UINTN Flags,
  78. IN UINTN Width
  79. )
  80. {
  81. CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
  82. CHAR16 *TempStr;
  83. CHAR16 *BufferPtr;
  84. UINTN Count;
  85. UINTN ValueCharNum;
  86. UINTN Remainder;
  87. CHAR16 Prefix;
  88. UINTN Index;
  89. BOOLEAN ValueIsNegative;
  90. UINT64 TempValue;
  91. TempStr = TempBuffer;
  92. BufferPtr = Buffer;
  93. Count = 0;
  94. ValueCharNum = 0;
  95. ValueIsNegative = FALSE;
  96. if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
  97. Width = CHARACTER_NUMBER_FOR_VALUE - 1;
  98. }
  99. if (Value < 0) {
  100. Value = -Value;
  101. ValueIsNegative = TRUE;
  102. }
  103. do {
  104. TempValue = Value;
  105. Value = (INT64)DivU64x32 ((UINT64)Value, 10);
  106. Remainder = (UINTN)((UINT64)TempValue - 10 * Value);
  107. *(TempStr++) = (CHAR16)(Remainder + '0');
  108. ValueCharNum++;
  109. Count++;
  110. if ((Flags & COMMA_TYPE) == COMMA_TYPE) {
  111. if (ValueCharNum % 3 == 0 && Value != 0) {
  112. *(TempStr++) = ',';
  113. Count++;
  114. }
  115. }
  116. } while (Value != 0);
  117. if (ValueIsNegative) {
  118. *(TempStr++) = '-';
  119. Count++;
  120. }
  121. if ((Flags & PREFIX_ZERO) && !ValueIsNegative) {
  122. Prefix = '0';
  123. } else {
  124. Prefix = ' ';
  125. }
  126. Index = Count;
  127. if (!(Flags & LEFT_JUSTIFY)) {
  128. for (; Index < Width; Index++) {
  129. *(TempStr++) = Prefix;
  130. }
  131. }
  132. //
  133. // Reverse temp string into Buffer.
  134. //
  135. if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
  136. TempStr = TempBuffer + Width;
  137. }
  138. Index = 0;
  139. while (TempStr != TempBuffer) {
  140. *(BufferPtr++) = *(--TempStr);
  141. Index++;
  142. }
  143. *BufferPtr = 0;
  144. return Index;
  145. }
  146. static CHAR16 mHexStr[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
  147. L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
  148. /**
  149. VSPrint worker function that prints a Value as a hex number in Buffer
  150. @param Buffer Location to place ascii hex string of Value.
  151. @param Value Hex value to convert to a string in Buffer.
  152. @param Flags Flags to use in printing Hex string, see file header for details.
  153. @param Width Width of hex value.
  154. @retval Number of characters printed.
  155. **/
  156. UINTN
  157. EfiValueToHexStr (
  158. IN OUT CHAR16 *Buffer,
  159. IN UINT64 Value,
  160. IN UINTN Flags,
  161. IN UINTN Width
  162. )
  163. {
  164. CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
  165. CHAR16 *TempStr;
  166. CHAR16 Prefix;
  167. CHAR16 *BufferPtr;
  168. UINTN Count;
  169. UINTN Index;
  170. TempStr = TempBuffer;
  171. BufferPtr = Buffer;
  172. //
  173. // Count starts at one since we will null terminate. Each iteration of the
  174. // loop picks off one nibble. Oh yea TempStr ends up backwards
  175. //
  176. Count = 0;
  177. if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
  178. Width = CHARACTER_NUMBER_FOR_VALUE - 1;
  179. }
  180. do {
  181. Index = ((UINTN)Value & 0xf);
  182. *(TempStr++) = mHexStr[Index];
  183. Value = RShiftU64 (Value, 4);
  184. Count++;
  185. } while (Value != 0);
  186. if (Flags & PREFIX_ZERO) {
  187. Prefix = '0';
  188. } else {
  189. Prefix = ' ';
  190. }
  191. Index = Count;
  192. if (!(Flags & LEFT_JUSTIFY)) {
  193. for (; Index < Width; Index++) {
  194. *(TempStr++) = Prefix;
  195. }
  196. }
  197. //
  198. // Reverse temp string into Buffer.
  199. //
  200. if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
  201. TempStr = TempBuffer + Width;
  202. }
  203. Index = 0;
  204. while (TempStr != TempBuffer) {
  205. *(BufferPtr++) = *(--TempStr);
  206. Index++;
  207. }
  208. *BufferPtr = 0;
  209. return Index;
  210. }
  211. /**
  212. Converts MAC address to Unicode string.
  213. The value is 64-bit and the resulting string will be 12
  214. digit hex number in pairs of digits separated by dashes.
  215. @param String - string that will contain the value
  216. @param Val - value to convert
  217. **/
  218. CHAR16 *
  219. StrMacToString (
  220. OUT CHAR16 *String,
  221. IN EFI_MAC_ADDRESS *MacAddr,
  222. IN UINT32 AddrSize
  223. )
  224. {
  225. UINT32 i;
  226. for (i = 0; i < AddrSize; i++) {
  227. EfiValueToHexStr (
  228. &String[2 * i],
  229. MacAddr->Addr[i] & 0xFF,
  230. PREFIX_ZERO,
  231. 2
  232. );
  233. }
  234. //
  235. // Terminate the string.
  236. //
  237. String[2 * AddrSize] = L'\0';
  238. return String;
  239. }
  240. EFI_STATUS
  241. TJudgeHandleIsPCIDevice(
  242. EFI_HANDLE Handle,
  243. UINT8 Device,
  244. UINT8 Funs
  245. )
  246. {
  247. EFI_STATUS Status;
  248. EFI_DEVICE_PATH *DPath;
  249. EFI_DEVICE_PATH *DevicePath;
  250. Status = gBS->HandleProtocol (
  251. Handle,
  252. &gEfiDevicePathProtocolGuid,
  253. (VOID **) &DPath
  254. );
  255. if(!EFI_ERROR(Status))
  256. {
  257. DevicePath = DPath;
  258. while(!IsDevicePathEnd(DPath))
  259. {
  260. if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP))
  261. {
  262. PCI_DEVICE_PATH *PCIPath;
  263. PCIPath = (PCI_DEVICE_PATH*) DPath;
  264. DPath = NextDevicePathNode(DPath);
  265. if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs))
  266. {
  267. return EFI_SUCCESS;
  268. }
  269. }
  270. else
  271. {
  272. DPath = NextDevicePathNode(DPath);
  273. }
  274. }
  275. }
  276. return EFI_UNSUPPORTED;
  277. }
  278. EFI_STATUS
  279. TSearchChildHandle(
  280. EFI_HANDLE Father,
  281. EFI_HANDLE *Child
  282. )
  283. {
  284. EFI_STATUS Status;
  285. UINTN HandleIndex;
  286. EFI_GUID **ProtocolGuidArray = NULL;
  287. UINTN ArrayCount;
  288. UINTN ProtocolIndex;
  289. UINTN OpenInfoCount;
  290. UINTN OpenInfoIndex;
  291. EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo = NULL;
  292. UINTN mHandleCount;
  293. EFI_HANDLE *mHandleBuffer= NULL;
  294. //
  295. // Retrieve the list of all handles from the handle database
  296. //
  297. Status = gBS->LocateHandleBuffer (
  298. AllHandles,
  299. NULL,
  300. NULL,
  301. &mHandleCount,
  302. &mHandleBuffer
  303. );
  304. for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++)
  305. {
  306. //
  307. // Retrieve the list of all the protocols on each handle
  308. //
  309. Status = gBS->ProtocolsPerHandle (
  310. mHandleBuffer[HandleIndex],
  311. &ProtocolGuidArray,
  312. &ArrayCount
  313. );
  314. if (!EFI_ERROR (Status))
  315. {
  316. for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++)
  317. {
  318. Status = gBS->OpenProtocolInformation (
  319. mHandleBuffer[HandleIndex],
  320. ProtocolGuidArray[ProtocolIndex],
  321. &OpenInfo,
  322. &OpenInfoCount
  323. );
  324. if (!EFI_ERROR (Status))
  325. {
  326. for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++)
  327. {
  328. if(OpenInfo[OpenInfoIndex].AgentHandle == Father)
  329. {
  330. if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)
  331. {
  332. *Child = mHandleBuffer[HandleIndex];
  333. Status = EFI_SUCCESS;
  334. goto TryReturn;
  335. }
  336. }
  337. }
  338. Status = EFI_NOT_FOUND;
  339. }
  340. }
  341. if(OpenInfo != NULL)
  342. {
  343. FreePool(OpenInfo);
  344. OpenInfo = NULL;
  345. }
  346. }
  347. FreePool (ProtocolGuidArray);
  348. ProtocolGuidArray = NULL;
  349. }
  350. TryReturn:
  351. if(OpenInfo != NULL)
  352. {
  353. FreePool (OpenInfo);
  354. OpenInfo = NULL;
  355. }
  356. if(ProtocolGuidArray != NULL)
  357. {
  358. FreePool(ProtocolGuidArray);
  359. ProtocolGuidArray = NULL;
  360. }
  361. if(mHandleBuffer != NULL)
  362. {
  363. FreePool (mHandleBuffer);
  364. mHandleBuffer = NULL;
  365. }
  366. return Status;
  367. }
  368. EFI_STATUS
  369. TGetDriverName(
  370. EFI_HANDLE Handle,
  371. CHAR16 *Name
  372. )
  373. {
  374. EFI_DRIVER_BINDING_PROTOCOL *BindHandle = NULL;
  375. EFI_STATUS Status;
  376. UINT32 Version;
  377. UINT16 *Ptr;
  378. Status = gBS->OpenProtocol(
  379. Handle,
  380. &gEfiDriverBindingProtocolGuid,
  381. (VOID**)&BindHandle,
  382. NULL,
  383. NULL,
  384. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  385. );
  386. if (EFI_ERROR(Status))
  387. {
  388. return EFI_NOT_FOUND;
  389. }
  390. Version = BindHandle->Version;
  391. Ptr = (UINT16*)&Version;
  392. UnicodeSPrint(Name, 40, L"%d.%d.%d", Version >> 24 , (Version >>16)& 0x0f ,*(Ptr));
  393. return EFI_SUCCESS;
  394. }
  395. EFI_STATUS
  396. TGetGOPDriverName(
  397. CHAR16 *Name
  398. )
  399. {
  400. UINTN HandleCount;
  401. EFI_HANDLE *Handles= NULL;
  402. UINTN Index;
  403. EFI_STATUS Status;
  404. EFI_HANDLE Child = 0;
  405. Status = gBS->LocateHandleBuffer(
  406. ByProtocol,
  407. &gEfiDriverBindingProtocolGuid,
  408. NULL,
  409. &HandleCount,
  410. &Handles
  411. );
  412. for (Index = 0; Index < HandleCount ; Index++)
  413. {
  414. Status = TSearchChildHandle(Handles[Index], &Child);
  415. if(!EFI_ERROR(Status))
  416. {
  417. Status = TJudgeHandleIsPCIDevice(Child, 0x02, 0x00);
  418. if(!EFI_ERROR(Status))
  419. {
  420. return TGetDriverName(Handles[Index], Name);
  421. }
  422. }
  423. }
  424. return EFI_UNSUPPORTED;
  425. }
  426. EFI_STATUS
  427. TGetTouchFirmwareVersion(
  428. )
  429. {
  430. EFI_STATUS rc=EFI_SUCCESS;
  431. UINTN TouchVer = 0;
  432. UINTN Size = sizeof(UINTN);
  433. CHAR16 Buffer[40];
  434. rc = gRT->GetVariable(
  435. L"TouchVer",
  436. &gEfiVlv2VariableGuid,
  437. NULL,
  438. &Size,
  439. &TouchVer
  440. );
  441. if(!EFI_ERROR(rc)){
  442. UnicodeSPrint(Buffer, sizeof(Buffer), L"%02x.%02x", (TouchVer&0xFFFF)>>8,TouchVer&0xFF);
  443. HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_TOUCH_VERSION), Buffer, NULL);
  444. }
  445. return EFI_SUCCESS;
  446. }
  447. EFI_STATUS
  448. UpdatePlatformInformation (
  449. )
  450. {
  451. UINT32 MicroCodeVersion;
  452. CHAR16 Buffer[40];
  453. EFI_STATUS Status;
  454. UINT8 CpuFlavor=0;
  455. EFI_PEI_HOB_POINTERS GuidHob;
  456. EFI_PLATFORM_INFO_HOB *mPlatformInfo=NULL;
  457. UINTN NumHandles;
  458. EFI_HANDLE *HandleBuffer;
  459. UINTN Index;
  460. DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
  461. UINTN PciD31F0RegBase;
  462. UINT8 count;
  463. UINT8 Data8;
  464. UINT8 Data8_1;
  465. CHAR16 Name[40];
  466. UINT32 MrcVersion;
  467. UINT8 KscFwRevH =0;
  468. UINT8 KscFwRevL =0;
  469. //
  470. // Get the HOB list. If it is not present, then ASSERT.
  471. //
  472. GuidHob.Raw = GetHobList ();
  473. if (GuidHob.Raw != NULL) {
  474. if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) {
  475. mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid);
  476. }
  477. }
  478. Status = TGetGOPDriverName(Name);
  479. if(!EFI_ERROR(Status))
  480. {
  481. HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_GOP_VERSION), Name, NULL);
  482. }
  483. //
  484. //CpuFlavor
  485. //
  486. //VLV
  487. //VLV-DC Tablet 000
  488. //VLV-QC Notebook 001
  489. //VLV-QC Desktop 010
  490. //
  491. //CPU flavor
  492. //
  493. CpuFlavor = RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07;
  494. switch(CpuFlavor){
  495. case 0x0:
  496. UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-DC Tablet", CpuFlavor);
  497. break;
  498. case 0x01:
  499. UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor);
  500. break;
  501. case 0x02:
  502. UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Desktop", CpuFlavor);
  503. break;
  504. case 0x03:
  505. UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"VLV-QC Notebook", CpuFlavor);
  506. break;
  507. default:
  508. UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"Unknown CPU", CpuFlavor);
  509. break;
  510. }
  511. HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_CPU_FLAVOR_VALUE), Buffer, NULL);
  512. if ( NULL != mPlatformInfo) {
  513. //
  514. // Board Id
  515. //
  516. UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->BoardId);
  517. HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_BOARD_ID_VALUE), Buffer, NULL);
  518. //
  519. // FAB ID
  520. //
  521. UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->BoardRev);
  522. HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_FAB_ID_VALUE), Buffer, NULL);
  523. }
  524. //
  525. //Update MRC Version
  526. //
  527. MrcVersion = MmioRead32 (MmPciAddress (0, 0, 0, 0, 0xF0));
  528. MrcVersion &= 0xffff;
  529. Index = EfiValueToString (Buffer, MrcVersion/100, PREFIX_ZERO, 0);
  530. StrCat (Buffer, L".");
  531. EfiValueToString (Buffer + Index + 1, (MrcVersion%100)/10, PREFIX_ZERO, 0);
  532. EfiValueToString (Buffer + Index + 2, (MrcVersion%100)%10, PREFIX_ZERO, 0);
  533. HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_MRC_VERSION_VALUE), Buffer, NULL);
  534. //
  535. //Update Soc Version
  536. //
  537. //
  538. // Retrieve all instances of PCH Platform Policy protocol
  539. //
  540. Status = gBS->LocateHandleBuffer (
  541. ByProtocol,
  542. &gDxePchPlatformPolicyProtocolGuid,
  543. NULL,
  544. &NumHandles,
  545. &HandleBuffer
  546. );
  547. if (!EFI_ERROR (Status)) {
  548. //
  549. // Find the matching PCH Policy protocol
  550. //
  551. for (Index = 0; Index < NumHandles; Index++) {
  552. Status = gBS->HandleProtocol (
  553. HandleBuffer[Index],
  554. &gDxePchPlatformPolicyProtocolGuid,
  555. (VOID **) &PchPlatformPolicy
  556. );
  557. if (!EFI_ERROR (Status)) {
  558. PciD31F0RegBase = MmPciAddress (
  559. 0,
  560. PchPlatformPolicy->BusNumber,
  561. PCI_DEVICE_NUMBER_PCH_LPC,
  562. PCI_FUNCTION_NUMBER_PCH_LPC,
  563. 0
  564. );
  565. Data8 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_RID_CC);
  566. count = ARRAY_SIZE (SBRevisionTable);
  567. for (Index = 0; Index < count; Index++) {
  568. if(Data8 == SBRevisionTable[Index].RevId) {
  569. UnicodeSPrint (Buffer, sizeof (Buffer), L"%02x %a", Data8, SBRevisionTable[Index].String);
  570. HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SOC_VALUE), Buffer, NULL);
  571. break;
  572. }
  573. }
  574. break;
  575. }
  576. }
  577. }
  578. //
  579. // Microcode Revision
  580. //
  581. EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
  582. EfiCpuid (EFI_CPUID_VERSION_INFO, NULL);
  583. MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID), 32);
  584. UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion);
  585. HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PROCESSOR_MICROCODE_VALUE), Buffer, NULL);
  586. //
  587. //Secure boot
  588. //
  589. Data8 = SystemConfiguration.SecureBoot;
  590. UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
  591. HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_SECURE_BOOT), Buffer, NULL);
  592. //
  593. //Bootmode
  594. //
  595. BootMode = GetBootModeHob();
  596. UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", BootMode);
  597. HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_BOOT_MODE), Buffer, NULL);
  598. //
  599. //SpeedStep
  600. //
  601. Data8 = 1;
  602. UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
  603. HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_SPEED_STEP), Buffer, NULL);
  604. //
  605. //CPU Turbo
  606. //
  607. Data8 = 2;
  608. UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
  609. HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_CPU_TURBO), Buffer, NULL);
  610. //
  611. //CState
  612. //
  613. Data8 = 3;
  614. UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
  615. HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_CSTATE), Buffer, NULL);
  616. //
  617. //GFX Turbo
  618. //
  619. Data8 = SystemConfiguration.IgdTurboEnabled;
  620. UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
  621. HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_GFX_TURBO), Buffer, NULL);
  622. Data8 = 0;
  623. UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
  624. HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_S0IX_VALUE), Buffer, NULL);
  625. //
  626. //RC6
  627. //
  628. Data8 = 0;
  629. UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8);
  630. HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_RC6_VALUE), Buffer, NULL);
  631. //
  632. // Punit Version
  633. //
  634. Data8 = 0;
  635. UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%x", Data8);
  636. HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PUNIT_FW_VALUE), Buffer, NULL);
  637. //
  638. // PMC Version
  639. //
  640. Data8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>16)&0x00FF);
  641. Data8_1 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>24)&0x00FF);
  642. UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%X_%X", Data8_1, Data8);
  643. HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PMC_FW_VALUE), Buffer, NULL);
  644. //
  645. //PMIC Version
  646. //
  647. Status = ByteReadI2C(PMICI2cBus, PMICI2cAdd, PMICVendorOffset, 1, &Data8);
  648. if(!EFI_ERROR(Status)){
  649. Status = ByteReadI2C(PMICI2cBus, PMICI2cAdd, PMICRevOffset, 1, &Data8_1);
  650. if(!EFI_ERROR(Status)){
  651. UnicodeSPrint(Buffer, sizeof(Buffer), L"%02x.%02x", Data8, Data8_1);
  652. HiiSetString(mHiiHandle, STRING_TOKEN(STR_MISC_PMIC_VERSION), Buffer, NULL);
  653. }
  654. }
  655. TGetTouchFirmwareVersion();
  656. return EFI_SUCCESS;
  657. }
  658. /**
  659. Smbios OEM type 0x94 callback.
  660. @param Event Event whose notification function is being invoked.
  661. @param Context Pointer to the notification functions context, which is implementation dependent.
  662. @retval None
  663. **/
  664. VOID
  665. AddSmbiosT0x94Callback (
  666. IN EFI_EVENT Event,
  667. IN VOID *Context
  668. )
  669. {
  670. EFI_STATUS Status;
  671. UINTN SECVerStrLen = 0;
  672. UINTN uCodeVerStrLen = 0;
  673. UINTN GOPStrLen = 0;
  674. UINTN MRCVersionStrLen = 0;
  675. UINTN PMCVersionStrLen = 0;
  676. UINTN ULPMCVersionStrLen = 0;
  677. UINTN PUNITVersionStrLen = 0;
  678. UINTN SOCVersionStrLen = 0;
  679. UINTN BOARDVersionStrLen = 0;
  680. UINTN FABVersionStrLen = 0;
  681. UINTN CPUFLAVORStrLen = 0;
  682. UINTN BIOSVersionStrLen = 0;
  683. UINTN PMICVersionStrLen = 0;
  684. UINTN TOUCHVersionStrLen = 0;
  685. UINTN SecureBootModeLen = 0;
  686. UINTN BootModeLen = 0;
  687. UINTN SpeedStepModeLen = 0;
  688. UINTN MaxCStateLen = 0;
  689. UINTN CpuTurboLen = 0;
  690. UINTN GfxTurboLen = 0;
  691. UINTN IdleReserveLen = 0;
  692. UINTN RC6Len = 0;
  693. SMBIOS_TABLE_TYPE94 *SmbiosRecord;
  694. EFI_SMBIOS_HANDLE SmbiosHandle;
  695. EFI_MISC_OEM_TYPE_0x94 *ForType94InputData;
  696. CHAR16 *SECVer;
  697. CHAR16 *uCodeVer;
  698. CHAR16 *GOPVer;
  699. CHAR16 *MrcVer;
  700. CHAR16 *PmcVer;
  701. CHAR16 *UlpmcVer;
  702. CHAR16 *PunitVer;
  703. CHAR16 *SocVer;
  704. CHAR16 *BoardVer;
  705. CHAR16 *FabVer;
  706. CHAR16 *CpuFlavor;
  707. CHAR16 *BiosVer;
  708. CHAR16 *PmicVer;
  709. CHAR16 *TouchVer = L"15.16";
  710. CHAR16 *SecureBootMode;
  711. CHAR16 *BootMode;
  712. CHAR16 *SpeedStepMode;
  713. CHAR16 *MaxCState;
  714. CHAR16 *CpuTurbo;
  715. CHAR16 *GfxTurbo;
  716. CHAR16 *IdleReserve;
  717. CHAR16 *RC6;
  718. UINTN RecordLen = 0;
  719. UINTN StrIdx = 0;
  720. STRING_REF TokenToGet;
  721. CHAR8 *OptionalStrStart;
  722. EFI_SMBIOS_PROTOCOL *SmbiosProtocol;
  723. ForType94InputData = (EFI_MISC_OEM_TYPE_0x94 *)Context;
  724. DEBUG ((EFI_D_INFO, "Executing SMBIOS T0x94 callback.\n"));
  725. gBS->CloseEvent (Event); // Unload this event.
  726. //
  727. // First check for invalid parameters.
  728. //
  729. if (Context == NULL) {
  730. return;
  731. }
  732. UpdatePlatformInformation();
  733. Status = gBS->LocateProtocol (
  734. &gEfiSmbiosProtocolGuid,
  735. NULL,
  736. (VOID **) &SmbiosProtocol
  737. );
  738. ASSERT_EFI_ERROR (Status);
  739. TokenToGet = STRING_TOKEN (STR_MISC_SEC_VERSION);
  740. SECVer = SmbiosMiscGetString (TokenToGet);
  741. SECVerStrLen = StrLen(SECVer);
  742. if (SECVerStrLen > SMBIOS_STRING_MAX_LENGTH) {
  743. return;
  744. }
  745. TokenToGet = STRING_TOKEN (STR_MISC_UCODE_VERSION);
  746. uCodeVer = SmbiosMiscGetString (TokenToGet);
  747. uCodeVerStrLen = StrLen(uCodeVer);
  748. if (uCodeVerStrLen > SMBIOS_STRING_MAX_LENGTH) {
  749. return;
  750. }
  751. TokenToGet = STRING_TOKEN (STR_MISC_GOP_VERSION);
  752. GOPVer = SmbiosMiscGetString (TokenToGet);
  753. GOPStrLen = StrLen(GOPVer);
  754. if (GOPStrLen > SMBIOS_STRING_MAX_LENGTH) {
  755. return;
  756. }
  757. TokenToGet = STRING_TOKEN (STR_MISC_MRC_VERSION_VALUE);
  758. MrcVer = SmbiosMiscGetString (TokenToGet);
  759. MRCVersionStrLen = StrLen(MrcVer);
  760. if (MRCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
  761. return;
  762. }
  763. TokenToGet = STRING_TOKEN (STR_MISC_PMC_FW_VALUE);
  764. PmcVer = SmbiosMiscGetString (TokenToGet);
  765. PMCVersionStrLen = StrLen(PmcVer);
  766. if (PMCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
  767. return;
  768. }
  769. TokenToGet = STRING_TOKEN (STR_MISC_ULPMC_FW_VALUE);
  770. UlpmcVer = SmbiosMiscGetString (TokenToGet);
  771. ULPMCVersionStrLen = StrLen(UlpmcVer);
  772. if (ULPMCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
  773. return;
  774. }
  775. TokenToGet = STRING_TOKEN (STR_MISC_PUNIT_FW_VALUE);
  776. PunitVer = SmbiosMiscGetString (TokenToGet);
  777. PUNITVersionStrLen = StrLen(PunitVer);
  778. if (PUNITVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
  779. return;
  780. }
  781. TokenToGet = STRING_TOKEN (STR_MISC_SOC_VALUE);
  782. SocVer = SmbiosMiscGetString (TokenToGet);
  783. SOCVersionStrLen = StrLen(SocVer);
  784. if (SOCVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
  785. return;
  786. }
  787. TokenToGet = STRING_TOKEN (STR_MISC_BOARD_ID_VALUE);
  788. BoardVer = SmbiosMiscGetString (TokenToGet);
  789. BOARDVersionStrLen = StrLen(BoardVer);
  790. if (BOARDVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
  791. return;
  792. }
  793. TokenToGet = STRING_TOKEN (STR_MISC_FAB_ID_VALUE);
  794. FabVer = SmbiosMiscGetString (TokenToGet);
  795. FABVersionStrLen = StrLen(FabVer);
  796. if (FABVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
  797. return;
  798. }
  799. TokenToGet = STRING_TOKEN (STR_MISC_CPU_FLAVOR_VALUE);
  800. CpuFlavor = SmbiosMiscGetString (TokenToGet);
  801. CPUFLAVORStrLen = StrLen(CpuFlavor);
  802. if (CPUFLAVORStrLen > SMBIOS_STRING_MAX_LENGTH) {
  803. return;
  804. }
  805. TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION);
  806. BiosVer = SmbiosMiscGetString (TokenToGet);
  807. BIOSVersionStrLen = StrLen(BiosVer);
  808. if (BIOSVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
  809. return;
  810. }
  811. TokenToGet = STRING_TOKEN (STR_MISC_PMIC_VERSION);
  812. PmicVer = SmbiosMiscGetString (TokenToGet);
  813. PMICVersionStrLen = StrLen(PmicVer);
  814. if (PMICVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
  815. return;
  816. }
  817. TokenToGet = STRING_TOKEN (STR_MISC_TOUCH_VERSION);
  818. TouchVer = SmbiosMiscGetString (TokenToGet);
  819. TOUCHVersionStrLen = StrLen(TouchVer);
  820. if (TOUCHVersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
  821. return;
  822. }
  823. TokenToGet = STRING_TOKEN (STR_MISC_SECURE_BOOT);
  824. SecureBootMode = SmbiosMiscGetString(TokenToGet);
  825. SecureBootModeLen = StrLen(SecureBootMode);
  826. if (SecureBootModeLen > SMBIOS_STRING_MAX_LENGTH) {
  827. return;
  828. }
  829. TokenToGet = STRING_TOKEN (STR_MISC_BOOT_MODE);
  830. BootMode = SmbiosMiscGetString(TokenToGet);
  831. BootModeLen = StrLen(BootMode);
  832. if (BootModeLen > SMBIOS_STRING_MAX_LENGTH) {
  833. return;
  834. }
  835. TokenToGet = STRING_TOKEN (STR_MISC_SPEED_STEP);
  836. SpeedStepMode = SmbiosMiscGetString(TokenToGet);
  837. SpeedStepModeLen = StrLen(SpeedStepMode);
  838. if (SpeedStepModeLen > SMBIOS_STRING_MAX_LENGTH) {
  839. return;
  840. }
  841. TokenToGet = STRING_TOKEN (STR_MISC_CPU_TURBO);
  842. CpuTurbo = SmbiosMiscGetString(TokenToGet);
  843. CpuTurboLen = StrLen(CpuTurbo);
  844. if (CpuTurboLen > SMBIOS_STRING_MAX_LENGTH) {
  845. return;
  846. }
  847. TokenToGet = STRING_TOKEN (STR_MISC_CSTATE);
  848. MaxCState = SmbiosMiscGetString(TokenToGet);
  849. MaxCStateLen = StrLen(MaxCState);
  850. if (MaxCStateLen > SMBIOS_STRING_MAX_LENGTH) {
  851. return;
  852. }
  853. TokenToGet = STRING_TOKEN (STR_MISC_GFX_TURBO);
  854. GfxTurbo = SmbiosMiscGetString(TokenToGet);
  855. GfxTurboLen = StrLen(GfxTurbo);
  856. if (GfxTurboLen > SMBIOS_STRING_MAX_LENGTH) {
  857. return;
  858. }
  859. TokenToGet = STRING_TOKEN (STR_MISC_S0IX_VALUE);
  860. IdleReserve = SmbiosMiscGetString(TokenToGet);
  861. IdleReserveLen = StrLen(IdleReserve);
  862. if (S0ixLen > SMBIOS_STRING_MAX_LENGTH) {
  863. return;
  864. }
  865. TokenToGet = STRING_TOKEN (STR_MISC_RC6_VALUE);
  866. RC6 = SmbiosMiscGetString(TokenToGet);
  867. RC6Len = StrLen(RC6);
  868. if (RC6Len > SMBIOS_STRING_MAX_LENGTH) {
  869. return;
  870. }
  871. RecordLen = sizeof (SMBIOS_TABLE_TYPE94) + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1 + PMCVersionStrLen + 1 + \
  872. TOUCHVersionStrLen + 1 + PMICVersionStrLen + 1 + BIOSVersionStrLen + 1 + CPUFLAVORStrLen + 1 + \
  873. BOARDVersionStrLen + 1 + FABVersionStrLen + 1 + PUNITVersionStrLen+ 1 + ULPMCVersionStrLen + 1 + \
  874. MRCVersionStrLen + 1 + SOCVersionStrLen + 1 + SecureBootModeLen + 1 + BootModeLen + 1 + \
  875. SpeedStepModeLen + 1 + CpuTurboLen + 1 + MaxCStateLen + 1 + GfxTurboLen + 1 + + RC6Len + 1 + 1;
  876. SmbiosRecord = AllocatePool(RecordLen);
  877. ZeroMem(SmbiosRecord, RecordLen);
  878. SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_MISC_VERSION_INFO;
  879. SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE94);
  880. //
  881. // Make handle chosen by smbios protocol.add automatically.
  882. //
  883. SmbiosRecord->Hdr.Handle = 0;
  884. SmbiosRecord->GopVersion = 1;
  885. SmbiosRecord->SECVersion = 2;
  886. SmbiosRecord->MRCVersion = 3;
  887. SmbiosRecord->uCodeVersion = 4;
  888. SmbiosRecord->PUnitVersion = 5;
  889. SmbiosRecord->PMCVersion = 6;
  890. SmbiosRecord->ULPMCVersion = 7;
  891. SmbiosRecord->SoCVersion = 8;
  892. SmbiosRecord->BoardVersion = 9;
  893. SmbiosRecord->FabVersion = 10;
  894. SmbiosRecord->CPUFlavor = 11;
  895. SmbiosRecord->BiosVersion = 12;
  896. SmbiosRecord->PmicVersion = 13;
  897. SmbiosRecord->TouchVersion = 14;
  898. SmbiosRecord->SecureBoot = 15;
  899. SmbiosRecord->BootMode = 16;
  900. SmbiosRecord->SpeedStepMode= 17;
  901. SmbiosRecord->CPUTurboMode = 18;
  902. SmbiosRecord->MaxCState = 19;
  903. SmbiosRecord->GfxTurbo = 20;
  904. SmbiosRecord->IdleReserve = 21;
  905. SmbiosRecord->RC6 = 22;
  906. OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
  907. UnicodeStrToAsciiStr(GOPVer, OptionalStrStart);
  908. StrIdx += GOPStrLen + 1;
  909. UnicodeStrToAsciiStr(SECVer, OptionalStrStart + StrIdx);
  910. StrIdx += SECVerStrLen + 1;
  911. UnicodeStrToAsciiStr(MrcVer, OptionalStrStart + StrIdx);
  912. StrIdx += MRCVersionStrLen + 1;
  913. UnicodeStrToAsciiStr(uCodeVer, OptionalStrStart + StrIdx);
  914. StrIdx += uCodeVerStrLen + 1;
  915. UnicodeStrToAsciiStr(PunitVer, OptionalStrStart + StrIdx);
  916. StrIdx += PUNITVersionStrLen + 1;
  917. UnicodeStrToAsciiStr(PmcVer, OptionalStrStart + StrIdx);
  918. StrIdx += PMCVersionStrLen + 1;
  919. UnicodeStrToAsciiStr(UlpmcVer, OptionalStrStart + StrIdx);
  920. StrIdx += ULPMCVersionStrLen + 1;
  921. UnicodeStrToAsciiStr(SocVer, OptionalStrStart + StrIdx);
  922. StrIdx += SOCVersionStrLen +1;
  923. UnicodeStrToAsciiStr(BoardVer, OptionalStrStart + StrIdx);
  924. StrIdx += BOARDVersionStrLen + 1;
  925. UnicodeStrToAsciiStr(FabVer, OptionalStrStart + StrIdx);
  926. StrIdx += FABVersionStrLen + 1;
  927. UnicodeStrToAsciiStr(CpuFlavor, OptionalStrStart + StrIdx);
  928. StrIdx += CPUFLAVORStrLen + 1;
  929. UnicodeStrToAsciiStr(BiosVer, OptionalStrStart + StrIdx);
  930. StrIdx += BIOSVersionStrLen + 1;
  931. UnicodeStrToAsciiStr(PmicVer, OptionalStrStart + StrIdx);
  932. StrIdx += PMICVersionStrLen + 1;
  933. UnicodeStrToAsciiStr(TouchVer, OptionalStrStart + StrIdx);
  934. StrIdx += TOUCHVersionStrLen + 1;
  935. UnicodeStrToAsciiStr(SecureBootMode, OptionalStrStart + StrIdx);
  936. StrIdx += SecureBootModeLen + 1;
  937. UnicodeStrToAsciiStr(BootMode, OptionalStrStart + StrIdx);
  938. StrIdx += BootModeLen + 1;
  939. UnicodeStrToAsciiStr(SpeedStepMode, OptionalStrStart + StrIdx);
  940. StrIdx += SpeedStepModeLen + 1;
  941. UnicodeStrToAsciiStr(CpuTurbo, OptionalStrStart + StrIdx);
  942. StrIdx += CpuTurboLen + 1;
  943. UnicodeStrToAsciiStr(MaxCState, OptionalStrStart + StrIdx);
  944. StrIdx += MaxCStateLen + 1;
  945. UnicodeStrToAsciiStr(GfxTurbo, OptionalStrStart + StrIdx);
  946. StrIdx += GfxTurboLen + 1;
  947. UnicodeStrToAsciiStr(IdleReserve, OptionalStrStart + StrIdx);
  948. StrIdx += S0ixLen + 1;
  949. UnicodeStrToAsciiStr(RC6, OptionalStrStart + StrIdx);
  950. StrIdx += RC6Len + 1;
  951. //
  952. // Now we have got the full smbios record, call smbios protocol to add this record.
  953. //
  954. SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  955. Status = SmbiosProtocol-> Add (
  956. SmbiosProtocol,
  957. NULL,
  958. &SmbiosHandle,
  959. (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
  960. );
  961. FreePool(SmbiosRecord);
  962. return;
  963. }
  964. /**
  965. This function makes boot time changes to the contents of the
  966. MiscOemType0x94 (Type 0x94).
  967. @param RecordData Pointer to copy of RecordData from the Data Table.
  968. @retval EFI_SUCCESS All parameters were valid.
  969. @retval EFI_UNSUPPORTED Unexpected RecordType value.
  970. @retval EFI_INVALID_PARAMETER Invalid parameter was found.
  971. **/
  972. MISC_SMBIOS_TABLE_FUNCTION(MiscOemType0x94)
  973. {
  974. EFI_STATUS Status;
  975. EFI_EVENT AddSmbiosT0x94CallbackEvent;
  976. Status = EfiCreateEventReadyToBootEx (
  977. TPL_CALLBACK,
  978. AddSmbiosT0x94Callback,
  979. RecordData,
  980. &AddSmbiosT0x94CallbackEvent
  981. );
  982. ASSERT_EFI_ERROR (Status);
  983. return Status;
  984. }