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
;
156 Status
= gBS
->HandleProtocol (
158 &gEfiDevicePathProtocolGuid
,
161 if(!EFI_ERROR(Status
)) {
162 while(!IsDevicePathEnd(DPath
)) {
163 if((DPath
->Type
== HARDWARE_DEVICE_PATH
) && (DPath
->SubType
== HW_PCI_DP
)) {
164 PCI_DEVICE_PATH
*PCIPath
;
165 PCIPath
= (PCI_DEVICE_PATH
*) DPath
;
166 DPath
= NextDevicePathNode(DPath
);
168 if(IsDevicePathEnd(DPath
) && (PCIPath
->Device
== Device
) && (PCIPath
->Function
== Funs
)) {
172 DPath
= NextDevicePathNode(DPath
);
176 return EFI_UNSUPPORTED
;
184 EFI_DRIVER_BINDING_PROTOCOL
*BindHandle
= NULL
;
189 STRING_REF TokenToUpdate
;
190 Status
= gBS
->OpenProtocol(
192 &gEfiDriverBindingProtocolGuid
,
196 EFI_OPEN_PROTOCOL_GET_PROTOCOL
199 if (EFI_ERROR(Status
)) {
200 return EFI_NOT_FOUND
;
203 Version
= BindHandle
->Version
;
204 Ptr
= (UINT16
*)&Version
;
205 UnicodeSPrint(Buffer
, sizeof (Buffer
), L
"%d.%d.%d", Version
>> 24 , (Version
>>16)& 0x0f ,*(Ptr
));
207 TokenToUpdate
= (STRING_REF
)STR_MISC_GOP_VERSION
;
208 HiiSetString(mHiiHandle
, TokenToUpdate
, Buffer
, NULL
);
217 EFI_HANDLE
*Handles
= NULL
;
220 EFI_HANDLE Child
= 0;
222 Status
= gBS
->LocateHandleBuffer(
224 &gEfiDriverBindingProtocolGuid
,
230 for (Index
= 0; Index
< HandleCount
; Index
++) {
231 Status
= SearchChildHandle(Handles
[Index
], &Child
);
232 if(!EFI_ERROR(Status
)) {
233 Status
= JudgeHandleIsPCIDevice(Child
, 0x02, 0x00);
234 if(!EFI_ERROR(Status
)) {
235 return GetDriverName(Handles
[Index
]);
239 return EFI_UNSUPPORTED
;
245 UINT32 MicroCodeVersion
;
249 // Microcode Revision
251 EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID
, 0);
252 EfiCpuid (EFI_CPUID_VERSION_INFO
, NULL
);
253 MicroCodeVersion
= (UINT32
) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID
), 32);
254 UnicodeSPrint (Buffer
, sizeof (Buffer
), L
"%x", MicroCodeVersion
);
255 HiiSetString(mHiiHandle
,STRING_TOKEN(STR_MISC_UCODE_VERSION
), Buffer
, NULL
);
259 Publish the smbios OEM type 0x90.
261 @param Event - Event whose notification function is being invoked (gEfiDxeSmmReadyToLockProtocolGuid).
262 @param Context - Pointer to the notification functions context, which is implementation dependent.
269 AddSmbiosT0x90Callback (
275 UINTN SECVerStrLen
= 0;
276 UINTN uCodeVerStrLen
= 0;
278 UINTN SteppingStrLen
= 0;
279 SMBIOS_TABLE_TYPE90
*SmbiosRecord
;
280 EFI_SMBIOS_HANDLE SmbiosHandle
;
285 STRING_REF TokenToGet
;
286 CHAR8
*OptionalStrStart
;
287 EFI_SMBIOS_PROTOCOL
*SmbiosProtocol
;
289 DEBUG ((EFI_D_INFO
, "Executing SMBIOS T0x90 callback.\n"));
291 gBS
->CloseEvent (Event
); // Unload this event.
294 // First check for invalid parameters.
296 if (Context
== NULL
) {
297 return EFI_INVALID_PARAMETER
;
300 Status
= gBS
->LocateProtocol (
301 &gEfiSmbiosProtocolGuid
,
303 (VOID
*) &SmbiosProtocol
305 ASSERT_EFI_ERROR (Status
);
311 TokenToGet
= STRING_TOKEN (STR_MISC_SEC_VERSION
);
312 SECVer
= SmbiosMiscGetString (TokenToGet
);
313 SECVerStrLen
= StrLen(SECVer
);
314 if (SECVerStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
315 return EFI_UNSUPPORTED
;
318 TokenToGet
= STRING_TOKEN (STR_MISC_UCODE_VERSION
);
319 uCodeVer
= SmbiosMiscGetString (TokenToGet
);
320 uCodeVerStrLen
= StrLen(uCodeVer
);
321 if (uCodeVerStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
322 return EFI_UNSUPPORTED
;
325 TokenToGet
= STRING_TOKEN (STR_MISC_GOP_VERSION
);
326 GOPVer
= SmbiosMiscGetString (TokenToGet
);
327 GOPStrLen
= StrLen(GOPVer
);
328 if (GOPStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
329 return EFI_UNSUPPORTED
;
332 TokenToGet
= STRING_TOKEN (STR_MISC_PROCESSOR_STEPPING
);
333 Stepping
= SmbiosMiscGetString (TokenToGet
);
334 SteppingStrLen
= StrLen(Stepping
);
337 if (SteppingStrLen
> SMBIOS_STRING_MAX_LENGTH
) {
338 return EFI_UNSUPPORTED
;
341 SmbiosRecord
= AllocatePool(sizeof (SMBIOS_TABLE_TYPE90
) + SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1 + GOPStrLen
+ 1 + SteppingStrLen
+ 1 + 1);
342 ZeroMem(SmbiosRecord
, sizeof (SMBIOS_TABLE_TYPE90
) + SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1 + GOPStrLen
+ 1 + SteppingStrLen
+ 1 + 1);
344 SmbiosRecord
->Hdr
.Type
= EFI_SMBIOS_TYPE_FIRMWARE_VERSION_INFO
;
345 SmbiosRecord
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE90
);
348 // Make handle chosen by smbios protocol.add automatically.
350 SmbiosRecord
->Hdr
.Handle
= 0;
353 // SEC VERSION will be the 1st optional string following the formatted structure.
355 SmbiosRecord
->SECVersion
= 0;
358 // Microcode VERSION will be the 2nd optional string following the formatted structure.
360 SmbiosRecord
->uCodeVersion
= 2;
363 // GOP VERSION will be the 3rd optional string following the formatted structure.
365 SmbiosRecord
->GOPVersion
= 3;
368 // CPU Stepping will be the 4th optional string following the formatted structure.
370 SmbiosRecord
->CpuStepping
= 4;
372 OptionalStrStart
= (CHAR8
*)(SmbiosRecord
+ 1);
373 UnicodeStrToAsciiStr(SECVer
, OptionalStrStart
);
374 UnicodeStrToAsciiStr(uCodeVer
, OptionalStrStart
+ SECVerStrLen
+ 1);
375 UnicodeStrToAsciiStr(GOPVer
, OptionalStrStart
+ SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1);
376 UnicodeStrToAsciiStr(Stepping
, OptionalStrStart
+ SECVerStrLen
+ 1 + uCodeVerStrLen
+ 1 + GOPStrLen
+ 1);
379 // Now we have got the full smbios record, call smbios protocol to add this record.
381 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
382 Status
= SmbiosProtocol
-> Add(
386 (EFI_SMBIOS_TABLE_HEADER
*) SmbiosRecord
389 FreePool(SmbiosRecord
);
395 This function makes boot time changes to the contents of the
396 MiscOemType0x90 (Type 0x90).
398 @param RecordData Pointer to copy of RecordData from the Data Table.
400 @retval EFI_SUCCESS All parameters were valid.
401 @retval EFI_UNSUPPORTED Unexpected RecordType value.
402 @retval EFI_INVALID_PARAMETER Invalid parameter was found.
405 MISC_SMBIOS_TABLE_FUNCTION(MiscOemType0x90
)
408 static BOOLEAN CallbackIsInstalledT0x90
= FALSE
;
409 VOID
*AddSmbiosT0x90CallbackNotifyReg
;
410 EFI_EVENT AddSmbiosT0x90CallbackEvent
;
413 // This callback will create a OEM Type 0x90 record.
415 if (CallbackIsInstalledT0x90
== FALSE
) {
416 CallbackIsInstalledT0x90
= TRUE
; // Prevent more than 1 callback.
417 DEBUG ((EFI_D_INFO
, "Create Smbios T0x90 callback.\n"));
420 // gEfiDxeSmmReadyToLockProtocolGuid is ready
422 Status
= gBS
->CreateEvent (
425 (EFI_EVENT_NOTIFY
)AddSmbiosT0x90Callback
,
427 &AddSmbiosT0x90CallbackEvent
430 ASSERT_EFI_ERROR (Status
);
431 if (EFI_ERROR (Status
)) {
436 Status
= gBS
->RegisterProtocolNotify (
437 &gEfiDxeSmmReadyToLockProtocolGuid
,
438 AddSmbiosT0x90CallbackEvent
,
439 &AddSmbiosT0x90CallbackNotifyReg