3 Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
13 MiscOemType0x88Function.c
17 The function that processes the Smbios data type 0x88 before they
18 are submitted to Data Hub
22 #include "CommonHeader.h"
24 #include "MiscSubclassDriver.h"
25 #include <Library/PrintLib.h>
26 #include <Library/CpuIA32.h>
27 #include <Protocol/DxeSmmReadyToLock.h>
41 EfiCpuVersion (&FamilyId
, &Model
, &SteppingId
, &ProcessorType
);
44 //we need raw Model data
51 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%d/%d/%d", FamilyId
, Model
, SteppingId
);
52 HiiSetString(mHiiHandle
,STRING_TOKEN(STR_MISC_PROCESSOR_STEPPING
), Buffer
, NULL
);
64 EFI_GUID
**ProtocolGuidArray
= NULL
;
69 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfo
= NULL
;
71 EFI_HANDLE
*mHandleBuffer
= NULL
;
74 // Retrieve the list of all handles from the handle database
76 Status
= gBS
->LocateHandleBuffer (
84 for (HandleIndex
= 0; HandleIndex
< mHandleCount
; HandleIndex
++) {
86 // Retrieve the list of all the protocols on each handle
88 Status
= gBS
->ProtocolsPerHandle (
89 mHandleBuffer
[HandleIndex
],
93 if (!EFI_ERROR (Status
)) {
94 for (ProtocolIndex
= 0; ProtocolIndex
< ArrayCount
; ProtocolIndex
++) {
95 Status
= gBS
->OpenProtocolInformation (
96 mHandleBuffer
[HandleIndex
],
97 ProtocolGuidArray
[ProtocolIndex
],
102 if (!EFI_ERROR (Status
)) {
103 for (OpenInfoIndex
= 0; OpenInfoIndex
< OpenInfoCount
; OpenInfoIndex
++) {
104 if(OpenInfo
[OpenInfoIndex
].AgentHandle
== Father
) {
105 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
106 *Child
= mHandleBuffer
[HandleIndex
];
107 Status
= EFI_SUCCESS
;
112 Status
= EFI_NOT_FOUND
;
115 if(OpenInfo
!= NULL
) {
120 if(ProtocolGuidArray
!= NULL
) {
121 FreePool (ProtocolGuidArray
);
122 ProtocolGuidArray
= NULL
;
126 if(OpenInfo
!= NULL
) {
130 if(ProtocolGuidArray
!= NULL
) {
131 FreePool(ProtocolGuidArray
);
132 ProtocolGuidArray
= NULL
;
134 if(mHandleBuffer
!= NULL
) {
135 FreePool (mHandleBuffer
);
136 mHandleBuffer
= NULL
;
142 JudgeHandleIsPCIDevice(
149 EFI_DEVICE_PATH
*DPath
;
151 Status
= gBS
->HandleProtocol (
153 &gEfiDevicePathProtocolGuid
,
156 if(!EFI_ERROR(Status
)) {
157 while(!IsDevicePathEnd(DPath
)) {
158 if((DPath
->Type
== HARDWARE_DEVICE_PATH
) && (DPath
->SubType
== HW_PCI_DP
)) {
159 PCI_DEVICE_PATH
*PCIPath
;
160 PCIPath
= (PCI_DEVICE_PATH
*) DPath
;
161 DPath
= NextDevicePathNode(DPath
);
163 if(IsDevicePathEnd(DPath
) && (PCIPath
->Device
== Device
) && (PCIPath
->Function
== Funs
)) {
167 DPath
= NextDevicePathNode(DPath
);
171 return EFI_UNSUPPORTED
;
179 EFI_DRIVER_BINDING_PROTOCOL
*BindHandle
= NULL
;
184 STRING_REF TokenToUpdate
;
185 Status
= gBS
->OpenProtocol(
187 &gEfiDriverBindingProtocolGuid
,
191 EFI_OPEN_PROTOCOL_GET_PROTOCOL
194 if (EFI_ERROR(Status
)) {
195 return EFI_NOT_FOUND
;
198 Version
= BindHandle
->Version
;
199 Ptr
= (UINT16
*)&Version
;
200 UnicodeSPrint(Buffer
, sizeof (Buffer
), L
"%d.%d.%d", Version
>> 24 , (Version
>>16)& 0x0f ,*(Ptr
));
202 TokenToUpdate
= (STRING_REF
)STR_MISC_GOP_VERSION
;
203 HiiSetString(mHiiHandle
, TokenToUpdate
, Buffer
, NULL
);
212 EFI_HANDLE
*Handles
= NULL
;
215 EFI_HANDLE Child
= 0;
217 Status
= gBS
->LocateHandleBuffer(
219 &gEfiDriverBindingProtocolGuid
,
225 for (Index
= 0; Index
< HandleCount
; Index
++) {
226 Status
= SearchChildHandle(Handles
[Index
], &Child
);
227 if(!EFI_ERROR(Status
)) {
228 Status
= JudgeHandleIsPCIDevice(Child
, 0x02, 0x00);
229 if(!EFI_ERROR(Status
)) {
230 return GetDriverName(Handles
[Index
]);
234 return EFI_UNSUPPORTED
;
240 UINT32 MicroCodeVersion
;
244 // Microcode Revision
246 EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID
, 0);
247 EfiCpuid (EFI_CPUID_VERSION_INFO
, NULL
);
248 MicroCodeVersion
= (UINT32
) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID
), 32);
249 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%x", MicroCodeVersion
);
250 HiiSetString(mHiiHandle
,STRING_TOKEN(STR_MISC_UCODE_VERSION
), Buffer
, NULL
);
254 Publish the smbios OEM type 0x90.
256 @param Event - Event whose notification function is being invoked (gEfiDxeSmmReadyToLockProtocolGuid).
257 @param Context - Pointer to the notification functions context, which is implementation dependent.
264 AddSmbiosT0x90Callback (
270 UINTN SECVerStrLen
= 0;
271 UINTN uCodeVerStrLen
= 0;
273 UINTN SteppingStrLen
= 0;
274 SMBIOS_TABLE_TYPE90
*SmbiosRecord
;
275 EFI_SMBIOS_HANDLE SmbiosHandle
;
280 STRING_REF TokenToGet
;
281 CHAR8
*OptionalStrStart
;
282 EFI_SMBIOS_PROTOCOL
*SmbiosProtocol
;
284 DEBUG ((EFI_D_INFO
, "Executing SMBIOS T0x90 callback.\n"));
286 gBS
->CloseEvent (Event
); // Unload this event.
289 // First check for invalid parameters.
291 if (Context
== NULL
) {
292 return EFI_INVALID_PARAMETER
;
295 Status
= gBS
->LocateProtocol (
296 &gEfiSmbiosProtocolGuid
,
298 (VOID
*) &SmbiosProtocol
300 ASSERT_EFI_ERROR (Status
);
306 TokenToGet
= STRING_TOKEN (STR_MISC_SEC_VERSION
);
307 SECVer
= SmbiosMiscGetString (TokenToGet
);
308 SECVerStrLen
= StrLen(SECVer
);
309 if (SECVerStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
310 return EFI_UNSUPPORTED
;
313 TokenToGet
= STRING_TOKEN (STR_MISC_UCODE_VERSION
);
314 uCodeVer
= SmbiosMiscGetString (TokenToGet
);
315 uCodeVerStrLen
= StrLen(uCodeVer
);
316 if (uCodeVerStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
317 return EFI_UNSUPPORTED
;
320 TokenToGet
= STRING_TOKEN (STR_MISC_GOP_VERSION
);
321 GOPVer
= SmbiosMiscGetString (TokenToGet
);
322 GOPStrLen
= StrLen(GOPVer
);
323 if (GOPStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
324 return EFI_UNSUPPORTED
;
327 TokenToGet
= STRING_TOKEN (STR_MISC_PROCESSOR_STEPPING
);
328 Stepping
= SmbiosMiscGetString (TokenToGet
);
329 SteppingStrLen
= StrLen(Stepping
);
332 if (SteppingStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
333 return EFI_UNSUPPORTED
;
336 SmbiosRecord
= AllocatePool(sizeof (SMBIOS_TABLE_TYPE90
) + SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1 + GOPStrLen
+ 1 + SteppingStrLen
+ 1 + 1);
337 ZeroMem(SmbiosRecord
, sizeof (SMBIOS_TABLE_TYPE90
) + SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1 + GOPStrLen
+ 1 + SteppingStrLen
+ 1 + 1);
339 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_FIRMWARE_VERSION_INFO
;
340 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE90
);
343 // Make handle chosen by smbios protocol.add automatically.
345 SmbiosRecord
->Hdr
.Handle
= 0;
348 // SEC VERSION will be the 1st optional string following the formatted structure.
350 SmbiosRecord
->SECVersion
= 0;
353 // Microcode VERSION will be the 2nd optional string following the formatted structure.
355 SmbiosRecord
->uCodeVersion
= 2;
358 // GOP VERSION will be the 3rd optional string following the formatted structure.
360 SmbiosRecord
->GOPVersion
= 3;
363 // CPU Stepping will be the 4th optional string following the formatted structure.
365 SmbiosRecord
->CpuStepping
= 4;
367 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
368 UnicodeStrToAsciiStr(SECVer
, OptionalStrStart
);
369 UnicodeStrToAsciiStr(uCodeVer
, OptionalStrStart
+ SECVerStrLen
+ 1);
370 UnicodeStrToAsciiStr(GOPVer
, OptionalStrStart
+ SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1);
371 UnicodeStrToAsciiStr(Stepping
, OptionalStrStart
+ SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1 + GOPStrLen
+ 1);
374 // Now we have got the full smbios record, call smbios protocol to add this record.
376 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
377 Status
= SmbiosProtocol
-> Add(
381 (EFI_SMBIOS_TABLE_HEADER
*) SmbiosRecord
384 FreePool(SmbiosRecord
);
390 This function makes boot time changes to the contents of the
391 MiscOemType0x90 (Type 0x90).
393 @param RecordData Pointer to copy of RecordData from the Data Table.
395 @retval EFI_SUCCESS All parameters were valid.
396 @retval EFI_UNSUPPORTED Unexpected RecordType value.
397 @retval EFI_INVALID_PARAMETER Invalid parameter was found.
400 MISC_SMBIOS_TABLE_FUNCTION(MiscOemType0x90
)
403 static BOOLEAN CallbackIsInstalledT0x90
= FALSE
;
404 VOID
*AddSmbiosT0x90CallbackNotifyReg
;
405 EFI_EVENT AddSmbiosT0x90CallbackEvent
;
408 // This callback will create a OEM Type 0x90 record.
410 if (CallbackIsInstalledT0x90
== FALSE
) {
411 CallbackIsInstalledT0x90
= TRUE
; // Prevent more than 1 callback.
412 DEBUG ((EFI_D_INFO
, "Create Smbios T0x90 callback.\n"));
415 // gEfiDxeSmmReadyToLockProtocolGuid is ready
417 Status
= gBS
->CreateEvent (
420 (EFI_EVENT_NOTIFY
)AddSmbiosT0x90Callback
,
422 &AddSmbiosT0x90CallbackEvent
425 ASSERT_EFI_ERROR (Status
);
426 if (EFI_ERROR (Status
)) {
431 Status
= gBS
->RegisterProtocolNotify (
432 &gEfiDxeSmmReadyToLockProtocolGuid
,
433 AddSmbiosT0x90CallbackEvent
,
434 &AddSmbiosT0x90CallbackNotifyReg