3 Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 MiscOemType0x88Function.c
22 The function that processes the Smbios data type 0x88 before they
23 are submitted to Data Hub
27 #include "CommonHeader.h"
29 #include "MiscSubclassDriver.h"
30 #include <Library/PrintLib.h>
31 #include <Library/CpuIA32.h>
32 #include <Protocol/DxeSmmReadyToLock.h>
46 EfiCpuVersion (&FamilyId
, &Model
, &SteppingId
, &ProcessorType
);
49 //we need raw Model data
56 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%d/%d/%d", FamilyId
, Model
, SteppingId
);
57 HiiSetString(mHiiHandle
,STRING_TOKEN(STR_MISC_PROCESSOR_STEPPING
), Buffer
, NULL
);
69 EFI_GUID
**ProtocolGuidArray
= NULL
;
74 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfo
= NULL
;
76 EFI_HANDLE
*mHandleBuffer
= NULL
;
79 // Retrieve the list of all handles from the handle database
81 Status
= gBS
->LocateHandleBuffer (
89 for (HandleIndex
= 0; HandleIndex
< mHandleCount
; HandleIndex
++) {
91 // Retrieve the list of all the protocols on each handle
93 Status
= gBS
->ProtocolsPerHandle (
94 mHandleBuffer
[HandleIndex
],
98 if (!EFI_ERROR (Status
)) {
99 for (ProtocolIndex
= 0; ProtocolIndex
< ArrayCount
; ProtocolIndex
++) {
100 Status
= gBS
->OpenProtocolInformation (
101 mHandleBuffer
[HandleIndex
],
102 ProtocolGuidArray
[ProtocolIndex
],
107 if (!EFI_ERROR (Status
)) {
108 for (OpenInfoIndex
= 0; OpenInfoIndex
< OpenInfoCount
; OpenInfoIndex
++) {
109 if(OpenInfo
[OpenInfoIndex
].AgentHandle
== Father
) {
110 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
111 *Child
= mHandleBuffer
[HandleIndex
];
112 Status
= EFI_SUCCESS
;
117 Status
= EFI_NOT_FOUND
;
120 if(OpenInfo
!= NULL
) {
125 if(ProtocolGuidArray
!= NULL
) {
126 FreePool (ProtocolGuidArray
);
127 ProtocolGuidArray
= NULL
;
131 if(OpenInfo
!= NULL
) {
135 if(ProtocolGuidArray
!= NULL
) {
136 FreePool(ProtocolGuidArray
);
137 ProtocolGuidArray
= NULL
;
139 if(mHandleBuffer
!= NULL
) {
140 FreePool (mHandleBuffer
);
141 mHandleBuffer
= NULL
;
147 JudgeHandleIsPCIDevice(
154 EFI_DEVICE_PATH
*DPath
;
155 EFI_DEVICE_PATH
*DevicePath
;
157 Status
= gBS
->HandleProtocol (
159 &gEfiDevicePathProtocolGuid
,
162 if(!EFI_ERROR(Status
)) {
164 while(!IsDevicePathEnd(DPath
)) {
165 if((DPath
->Type
== HARDWARE_DEVICE_PATH
) && (DPath
->SubType
== HW_PCI_DP
)) {
166 PCI_DEVICE_PATH
*PCIPath
;
167 PCIPath
= (PCI_DEVICE_PATH
*) DPath
;
168 DPath
= NextDevicePathNode(DPath
);
170 if(IsDevicePathEnd(DPath
) && (PCIPath
->Device
== Device
) && (PCIPath
->Function
== Funs
)) {
174 DPath
= NextDevicePathNode(DPath
);
178 return EFI_UNSUPPORTED
;
186 EFI_DRIVER_BINDING_PROTOCOL
*BindHandle
= NULL
;
191 STRING_REF TokenToUpdate
;
192 Status
= gBS
->OpenProtocol(
194 &gEfiDriverBindingProtocolGuid
,
198 EFI_OPEN_PROTOCOL_GET_PROTOCOL
201 if (EFI_ERROR(Status
)) {
202 return EFI_NOT_FOUND
;
205 Version
= BindHandle
->Version
;
206 Ptr
= (UINT16
*)&Version
;
207 UnicodeSPrint(Buffer
, sizeof (Buffer
), L
"%d.%d.%d", Version
>> 24 , (Version
>>16)& 0x0f ,*(Ptr
));
209 TokenToUpdate
= (STRING_REF
)STR_MISC_GOP_VERSION
;
210 HiiSetString(mHiiHandle
, TokenToUpdate
, Buffer
, NULL
);
219 EFI_HANDLE
*Handles
= NULL
;
222 EFI_HANDLE Child
= 0;
224 Status
= gBS
->LocateHandleBuffer(
226 &gEfiDriverBindingProtocolGuid
,
232 for (Index
= 0; Index
< HandleCount
; Index
++) {
233 Status
= SearchChildHandle(Handles
[Index
], &Child
);
234 if(!EFI_ERROR(Status
)) {
235 Status
= JudgeHandleIsPCIDevice(Child
, 0x02, 0x00);
236 if(!EFI_ERROR(Status
)) {
237 return GetDriverName(Handles
[Index
]);
241 return EFI_UNSUPPORTED
;
247 UINT32 MicroCodeVersion
;
251 // Microcode Revision
253 EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID
, 0);
254 EfiCpuid (EFI_CPUID_VERSION_INFO
, NULL
);
255 MicroCodeVersion
= (UINT32
) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID
), 32);
256 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%x", MicroCodeVersion
);
257 HiiSetString(mHiiHandle
,STRING_TOKEN(STR_MISC_UCODE_VERSION
), Buffer
, NULL
);
261 Publish the smbios OEM type 0x90.
263 @param Event - Event whose notification function is being invoked (gEfiDxeSmmReadyToLockProtocolGuid).
264 @param Context - Pointer to the notification functions context, which is implementation dependent.
271 AddSmbiosT0x90Callback (
277 UINTN SECVerStrLen
= 0;
278 UINTN uCodeVerStrLen
= 0;
280 UINTN SteppingStrLen
= 0;
281 SMBIOS_TABLE_TYPE90
*SmbiosRecord
;
282 EFI_SMBIOS_HANDLE SmbiosHandle
;
283 EFI_MISC_OEM_TYPE_0x90
*ForType90InputData
;
288 STRING_REF TokenToGet
;
289 CHAR8
*OptionalStrStart
;
290 EFI_SMBIOS_PROTOCOL
*SmbiosProtocol
;
292 ForType90InputData
= (EFI_MISC_OEM_TYPE_0x90
*)Context
;
294 DEBUG ((EFI_D_INFO
, "Executing SMBIOS T0x90 callback.\n"));
296 gBS
->CloseEvent (Event
); // Unload this event.
299 // First check for invalid parameters.
301 if (Context
== NULL
) {
302 return EFI_INVALID_PARAMETER
;
305 Status
= gBS
->LocateProtocol (
306 &gEfiSmbiosProtocolGuid
,
308 (VOID
*) &SmbiosProtocol
310 ASSERT_EFI_ERROR (Status
);
316 TokenToGet
= STRING_TOKEN (STR_MISC_SEC_VERSION
);
317 SECVer
= SmbiosMiscGetString (TokenToGet
);
318 SECVerStrLen
= StrLen(SECVer
);
319 if (SECVerStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
320 return EFI_UNSUPPORTED
;
323 TokenToGet
= STRING_TOKEN (STR_MISC_UCODE_VERSION
);
324 uCodeVer
= SmbiosMiscGetString (TokenToGet
);
325 uCodeVerStrLen
= StrLen(uCodeVer
);
326 if (uCodeVerStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
327 return EFI_UNSUPPORTED
;
330 TokenToGet
= STRING_TOKEN (STR_MISC_GOP_VERSION
);
331 GOPVer
= SmbiosMiscGetString (TokenToGet
);
332 GOPStrLen
= StrLen(GOPVer
);
333 if (GOPStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
334 return EFI_UNSUPPORTED
;
337 TokenToGet
= STRING_TOKEN (STR_MISC_PROCESSOR_STEPPING
);
338 Stepping
= SmbiosMiscGetString (TokenToGet
);
339 SteppingStrLen
= StrLen(Stepping
);
342 if (SteppingStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
343 return EFI_UNSUPPORTED
;
346 SmbiosRecord
= AllocatePool(sizeof (SMBIOS_TABLE_TYPE90
) + SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1 + GOPStrLen
+ 1 + SteppingStrLen
+ 1 + 1);
347 ZeroMem(SmbiosRecord
, sizeof (SMBIOS_TABLE_TYPE90
) + SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1 + GOPStrLen
+ 1 + SteppingStrLen
+ 1 + 1);
349 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_FIRMWARE_VERSION_INFO
;
350 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE90
);
353 // Make handle chosen by smbios protocol.add automatically.
355 SmbiosRecord
->Hdr
.Handle
= 0;
358 // SEC VERSION will be the 1st optional string following the formatted structure.
360 SmbiosRecord
->SECVersion
= 0;
363 // Microcode VERSION will be the 2nd optional string following the formatted structure.
365 SmbiosRecord
->uCodeVersion
= 2;
368 // GOP VERSION will be the 3rd optional string following the formatted structure.
370 SmbiosRecord
->GOPVersion
= 3;
373 // CPU Stepping will be the 4th optional string following the formatted structure.
375 SmbiosRecord
->CpuStepping
= 4;
377 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
378 UnicodeStrToAsciiStr(SECVer
, OptionalStrStart
);
379 UnicodeStrToAsciiStr(uCodeVer
, OptionalStrStart
+ SECVerStrLen
+ 1);
380 UnicodeStrToAsciiStr(GOPVer
, OptionalStrStart
+ SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1);
381 UnicodeStrToAsciiStr(Stepping
, OptionalStrStart
+ SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1 + GOPStrLen
+ 1);
384 // Now we have got the full smbios record, call smbios protocol to add this record.
386 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
387 Status
= SmbiosProtocol
-> Add(
391 (EFI_SMBIOS_TABLE_HEADER
*) SmbiosRecord
394 FreePool(SmbiosRecord
);
400 This function makes boot time changes to the contents of the
401 MiscOemType0x90 (Type 0x90).
403 @param RecordData Pointer to copy of RecordData from the Data Table.
405 @retval EFI_SUCCESS All parameters were valid.
406 @retval EFI_UNSUPPORTED Unexpected RecordType value.
407 @retval EFI_INVALID_PARAMETER Invalid parameter was found.
410 MISC_SMBIOS_TABLE_FUNCTION(MiscOemType0x90
)
413 static BOOLEAN CallbackIsInstalledT0x90
= FALSE
;
414 VOID
*AddSmbiosT0x90CallbackNotifyReg
;
415 EFI_EVENT AddSmbiosT0x90CallbackEvent
;
418 // This callback will create a OEM Type 0x90 record.
420 if (CallbackIsInstalledT0x90
== FALSE
) {
421 CallbackIsInstalledT0x90
= TRUE
; // Prevent more than 1 callback.
422 DEBUG ((EFI_D_INFO
, "Create Smbios T0x90 callback.\n"));
425 // gEfiDxeSmmReadyToLockProtocolGuid is ready
427 Status
= gBS
->CreateEvent (
430 (EFI_EVENT_NOTIFY
)AddSmbiosT0x90Callback
,
432 &AddSmbiosT0x90CallbackEvent
435 ASSERT_EFI_ERROR (Status
);
436 if (EFI_ERROR (Status
)) {
441 Status
= gBS
->RegisterProtocolNotify (
442 &gEfiDxeSmmReadyToLockProtocolGuid
,
443 AddSmbiosT0x90CallbackEvent
,
444 &AddSmbiosT0x90CallbackNotifyReg