]> git.proxmox.com Git - mirror_edk2.git/blame - Vlv2TbltDevicePkg/SmBiosMiscDxe/MiscOemType0x90Function.c
MdeModulePkg/CapsuleApp: Center bitmap at bottom of screen
[mirror_edk2.git] / Vlv2TbltDevicePkg / SmBiosMiscDxe / MiscOemType0x90Function.c
CommitLineData
3cbfba02
DW
1/*++\r
2\r
3Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.\r
4 \r\r
5 This program and the accompanying materials are licensed and made available under\r\r
6 the terms and conditions of the BSD License that accompanies this distribution. \r\r
7 The full text of the license may be found at \r\r
8 http://opensource.org/licenses/bsd-license.php. \r\r
9 \r\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r\r
12 \r\r
13\r
14\r
15\r
16Module Name:\r
17\r
18 MiscOemType0x88Function.c\r
19\r
20Abstract:\r
21\r
22 The function that processes the Smbios data type 0x88 before they\r
23 are submitted to Data Hub\r
24\r
25--*/\r
26\r
27#include "CommonHeader.h"\r
28\r
29#include "MiscSubclassDriver.h"\r
30#include <Library/PrintLib.h>\r
31#include <Library/CpuIA32.h>\r
32#include <Protocol/DxeSmmReadyToLock.h>\r
33\r
34\r
35VOID\r
36GetCPUStepping ( )\r
37{\r
38 CHAR16 Buffer[40];\r
39\r
40 UINT16 FamilyId;\r
41 UINT8 Model;\r
42 UINT8 SteppingId;\r
43 UINT8 ProcessorType;\r
44\r
45\r
46 EfiCpuVersion (&FamilyId, &Model, &SteppingId, &ProcessorType);\r
47\r
48 //\r
49 //we need raw Model data\r
50 //\r
51 Model = Model & 0xf;\r
52\r
53 //\r
54 //Family/Model/Step\r
55 //\r
56 UnicodeSPrint (Buffer, sizeof (Buffer), L"%d/%d/%d", FamilyId, Model, SteppingId);\r
57 HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_PROCESSOR_STEPPING), Buffer, NULL);\r
58\r
59}\r
60\r
61EFI_STATUS\r
62SearchChildHandle(\r
63 EFI_HANDLE Father,\r
64 EFI_HANDLE *Child\r
65 )\r
66{\r
67 EFI_STATUS Status;\r
68 UINTN HandleIndex;\r
69 EFI_GUID **ProtocolGuidArray = NULL;\r
70 UINTN ArrayCount;\r
71 UINTN ProtocolIndex;\r
72 UINTN OpenInfoCount;\r
73 UINTN OpenInfoIndex;\r
74 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo = NULL;\r
75 UINTN mHandleCount;\r
76 EFI_HANDLE *mHandleBuffer= NULL;\r
77\r
78 //\r
79 // Retrieve the list of all handles from the handle database\r
80 //\r
81 Status = gBS->LocateHandleBuffer (\r
82 AllHandles,\r
83 NULL,\r
84 NULL,\r
85 &mHandleCount,\r
86 &mHandleBuffer\r
87 );\r
88\r
89 for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++) {\r
90 //\r
91 // Retrieve the list of all the protocols on each handle\r
92 //\r
93 Status = gBS->ProtocolsPerHandle (\r
94 mHandleBuffer[HandleIndex],\r
95 &ProtocolGuidArray,\r
96 &ArrayCount\r
97 );\r
98 if (!EFI_ERROR (Status)) {\r
99 for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
100 Status = gBS->OpenProtocolInformation (\r
101 mHandleBuffer[HandleIndex],\r
102 ProtocolGuidArray[ProtocolIndex],\r
103 &OpenInfo,\r
104 &OpenInfoCount\r
105 );\r
106\r
107 if (!EFI_ERROR (Status)) {\r
108 for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
109 if(OpenInfo[OpenInfoIndex].AgentHandle == Father) {\r
110 if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {\r
111 *Child = mHandleBuffer[HandleIndex];\r
112 Status = EFI_SUCCESS;\r
113 goto TryReturn;\r
114 }\r
115 }\r
116 }\r
117 Status = EFI_NOT_FOUND;\r
118 }\r
119 }\r
120 if(OpenInfo != NULL) {\r
121 FreePool(OpenInfo);\r
122 OpenInfo = NULL;\r
123 }\r
124 }\r
125 if(ProtocolGuidArray != NULL) {\r
126 FreePool (ProtocolGuidArray);\r
127 ProtocolGuidArray = NULL;\r
128 }\r
129 }\r
130TryReturn:\r
131 if(OpenInfo != NULL) {\r
132 FreePool (OpenInfo);\r
133 OpenInfo = NULL;\r
134 }\r
135 if(ProtocolGuidArray != NULL) {\r
136 FreePool(ProtocolGuidArray);\r
137 ProtocolGuidArray = NULL;\r
138 }\r
139 if(mHandleBuffer != NULL) {\r
140 FreePool (mHandleBuffer);\r
141 mHandleBuffer = NULL;\r
142 }\r
143 return Status;\r
144}\r
145\r
146EFI_STATUS\r
147JudgeHandleIsPCIDevice(\r
148 EFI_HANDLE Handle,\r
149 UINT8 Device,\r
150 UINT8 Funs\r
151 )\r
152{\r
153 EFI_STATUS Status;\r
154 EFI_DEVICE_PATH *DPath;\r
3cbfba02
DW
155\r
156 Status = gBS->HandleProtocol (\r
157 Handle,\r
158 &gEfiDevicePathProtocolGuid,\r
159 (VOID **) &DPath\r
160 );\r
161 if(!EFI_ERROR(Status)) {\r
3cbfba02
DW
162 while(!IsDevicePathEnd(DPath)) {\r
163 if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP)) {\r
164 PCI_DEVICE_PATH *PCIPath;\r
165 PCIPath = (PCI_DEVICE_PATH*) DPath;\r
166 DPath = NextDevicePathNode(DPath);\r
167\r
168 if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs)) {\r
169 return EFI_SUCCESS;\r
170 }\r
171 } else {\r
172 DPath = NextDevicePathNode(DPath);\r
173 }\r
174 }\r
175 }\r
176 return EFI_UNSUPPORTED;\r
177}\r
178\r
179EFI_STATUS\r
180GetDriverName(\r
181 EFI_HANDLE Handle\r
182)\r
183{\r
184 EFI_DRIVER_BINDING_PROTOCOL *BindHandle = NULL;\r
185 EFI_STATUS Status;\r
186 UINT32 Version;\r
187 UINT16 *Ptr;\r
188 CHAR16 Buffer[40];\r
189 STRING_REF TokenToUpdate;\r
190 Status = gBS->OpenProtocol(\r
191 Handle,\r
192 &gEfiDriverBindingProtocolGuid,\r
193 (VOID**)&BindHandle,\r
194 NULL,\r
195 NULL,\r
196 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
197 );\r
198\r
199 if (EFI_ERROR(Status)) {\r
200 return EFI_NOT_FOUND;\r
201 }\r
202\r
203 Version = BindHandle->Version;\r
204 Ptr = (UINT16*)&Version;\r
205 UnicodeSPrint(Buffer, sizeof (Buffer), L"%d.%d.%d", Version >> 24 , (Version >>16)& 0x0f ,*(Ptr));\r
206\r
207 TokenToUpdate = (STRING_REF)STR_MISC_GOP_VERSION;\r
208 HiiSetString(mHiiHandle, TokenToUpdate, Buffer, NULL);\r
209\r
210 return EFI_SUCCESS;\r
211}\r
212\r
213EFI_STATUS\r
214GetGOPDriverName()\r
215{\r
216 UINTN HandleCount;\r
217 EFI_HANDLE *Handles= NULL;\r
218 UINTN Index;\r
219 EFI_STATUS Status;\r
220 EFI_HANDLE Child = 0;\r
221\r
222 Status = gBS->LocateHandleBuffer(\r
223 ByProtocol,\r
224 &gEfiDriverBindingProtocolGuid,\r
225 NULL,\r
226 &HandleCount,\r
227 &Handles\r
228 );\r
229\r
230 for (Index = 0; Index < HandleCount ; Index++) {\r
231 Status = SearchChildHandle(Handles[Index], &Child);\r
232 if(!EFI_ERROR(Status)) {\r
233 Status = JudgeHandleIsPCIDevice(Child, 0x02, 0x00);\r
234 if(!EFI_ERROR(Status)) {\r
235 return GetDriverName(Handles[Index]);\r
236 }\r
237 }\r
238 }\r
239 return EFI_UNSUPPORTED;\r
240}\r
241\r
242VOID\r
243GetUcodeVersion()\r
244{\r
245 UINT32 MicroCodeVersion;\r
246 CHAR16 Buffer[40];\r
247\r
248 //\r
249 // Microcode Revision\r
250 //\r
251 EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0);\r
252 EfiCpuid (EFI_CPUID_VERSION_INFO, NULL);\r
253 MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID), 32);\r
254 UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion);\r
255 HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_UCODE_VERSION), Buffer, NULL);\r
256}\r
257\r
258/**\r
259 Publish the smbios OEM type 0x90.\r
260\r
261 @param Event - Event whose notification function is being invoked (gEfiDxeSmmReadyToLockProtocolGuid).\r
262 @param Context - Pointer to the notification functions context, which is implementation dependent.\r
263\r
264 @retval None\r
265\r
266**/\r
267EFI_STATUS\r
268EFIAPI\r
269AddSmbiosT0x90Callback (\r
270 IN EFI_EVENT Event,\r
271 IN VOID *Context\r
272 )\r
273{\r
274 EFI_STATUS Status;\r
275 UINTN SECVerStrLen = 0;\r
276 UINTN uCodeVerStrLen = 0;\r
277 UINTN GOPStrLen = 0;\r
278 UINTN SteppingStrLen = 0;\r
279 SMBIOS_TABLE_TYPE90 *SmbiosRecord;\r
280 EFI_SMBIOS_HANDLE SmbiosHandle;\r
3cbfba02
DW
281 CHAR16 *SECVer;\r
282 CHAR16 *uCodeVer;\r
283 CHAR16 *GOPVer;\r
284 CHAR16 *Stepping;\r
285 STRING_REF TokenToGet;\r
286 CHAR8 *OptionalStrStart;\r
287 EFI_SMBIOS_PROTOCOL *SmbiosProtocol;\r
288\r
3cbfba02
DW
289 DEBUG ((EFI_D_INFO, "Executing SMBIOS T0x90 callback.\n"));\r
290\r
291 gBS->CloseEvent (Event); // Unload this event.\r
292\r
293 //\r
294 // First check for invalid parameters.\r
295 //\r
296 if (Context == NULL) {\r
297 return EFI_INVALID_PARAMETER;\r
298 }\r
299\r
300 Status = gBS->LocateProtocol (\r
301 &gEfiSmbiosProtocolGuid,\r
302 NULL,\r
303 (VOID *) &SmbiosProtocol\r
304 );\r
305 ASSERT_EFI_ERROR (Status);\r
306\r
307 GetUcodeVersion();\r
308 GetGOPDriverName();\r
309 GetCPUStepping();\r
310\r
311 TokenToGet = STRING_TOKEN (STR_MISC_SEC_VERSION);\r
312 SECVer = SmbiosMiscGetString (TokenToGet);\r
313 SECVerStrLen = StrLen(SECVer);\r
314 if (SECVerStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
315 return EFI_UNSUPPORTED;\r
316 }\r
317\r
318 TokenToGet = STRING_TOKEN (STR_MISC_UCODE_VERSION);\r
319 uCodeVer = SmbiosMiscGetString (TokenToGet);\r
320 uCodeVerStrLen = StrLen(uCodeVer);\r
321 if (uCodeVerStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
322 return EFI_UNSUPPORTED;\r
323 }\r
324\r
325 TokenToGet = STRING_TOKEN (STR_MISC_GOP_VERSION);\r
326 GOPVer = SmbiosMiscGetString (TokenToGet);\r
327 GOPStrLen = StrLen(GOPVer);\r
328 if (GOPStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
329 return EFI_UNSUPPORTED;\r
330 }\r
331\r
332 TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_STEPPING);\r
333 Stepping = SmbiosMiscGetString (TokenToGet);\r
334 SteppingStrLen = StrLen(Stepping);\r
335\r
336\r
337 if (SteppingStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
338 return EFI_UNSUPPORTED;\r
339 }\r
340\r
341 SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE90) + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1 + SteppingStrLen + 1 + 1);\r
342 ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE90) + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1 + SteppingStrLen + 1 + 1);\r
343\r
344 SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_FIRMWARE_VERSION_INFO;\r
345 SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE90);\r
346\r
347 //\r
348 // Make handle chosen by smbios protocol.add automatically.\r
349 //\r
350 SmbiosRecord->Hdr.Handle = 0;\r
351\r
352 //\r
353 // SEC VERSION will be the 1st optional string following the formatted structure.\r
354 //\r
355 SmbiosRecord->SECVersion = 0;\r
356\r
357 //\r
358 // Microcode VERSION will be the 2nd optional string following the formatted structure.\r
359 //\r
360 SmbiosRecord->uCodeVersion = 2;\r
361\r
362 //\r
363 // GOP VERSION will be the 3rd optional string following the formatted structure.\r
364 //\r
365 SmbiosRecord->GOPVersion = 3;\r
366\r
367 //\r
368 // CPU Stepping will be the 4th optional string following the formatted structure.\r
369 //\r
370 SmbiosRecord->CpuStepping = 4;\r
371\r
372 OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);\r
373 UnicodeStrToAsciiStr(SECVer, OptionalStrStart);\r
374 UnicodeStrToAsciiStr(uCodeVer, OptionalStrStart + SECVerStrLen + 1);\r
375 UnicodeStrToAsciiStr(GOPVer, OptionalStrStart + SECVerStrLen + 1 + uCodeVerStrLen + 1);\r
376 UnicodeStrToAsciiStr(Stepping, OptionalStrStart + SECVerStrLen + 1 + uCodeVerStrLen + 1 + GOPStrLen + 1);\r
377\r
378 //\r
379 // Now we have got the full smbios record, call smbios protocol to add this record.\r
380 //\r
381 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
382 Status = SmbiosProtocol-> Add(\r
383 SmbiosProtocol,\r
384 NULL,\r
385 &SmbiosHandle,\r
386 (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord\r
387 );\r
388\r
389 FreePool(SmbiosRecord);\r
390 return Status;\r
391}\r
392\r
393\r
394/**\r
395 This function makes boot time changes to the contents of the\r
396 MiscOemType0x90 (Type 0x90).\r
397\r
398 @param RecordData Pointer to copy of RecordData from the Data Table.\r
399\r
400 @retval EFI_SUCCESS All parameters were valid.\r
401 @retval EFI_UNSUPPORTED Unexpected RecordType value.\r
402 @retval EFI_INVALID_PARAMETER Invalid parameter was found.\r
403\r
404**/\r
405MISC_SMBIOS_TABLE_FUNCTION(MiscOemType0x90)\r
406{\r
407 EFI_STATUS Status;\r
408 static BOOLEAN CallbackIsInstalledT0x90 = FALSE;\r
409 VOID *AddSmbiosT0x90CallbackNotifyReg;\r
410 EFI_EVENT AddSmbiosT0x90CallbackEvent;\r
411\r
412 //\r
413 // This callback will create a OEM Type 0x90 record.\r
414 //\r
415 if (CallbackIsInstalledT0x90 == FALSE) {\r
416 CallbackIsInstalledT0x90 = TRUE; // Prevent more than 1 callback.\r
417 DEBUG ((EFI_D_INFO, "Create Smbios T0x90 callback.\n"));\r
418\r
419 //\r
420 // gEfiDxeSmmReadyToLockProtocolGuid is ready\r
421 //\r
422 Status = gBS->CreateEvent (\r
423 EVT_NOTIFY_SIGNAL,\r
424 TPL_CALLBACK,\r
425 (EFI_EVENT_NOTIFY)AddSmbiosT0x90Callback,\r
426 RecordData,\r
427 &AddSmbiosT0x90CallbackEvent\r
428 );\r
429\r
430 ASSERT_EFI_ERROR (Status);\r
431 if (EFI_ERROR (Status)) {\r
432 return Status;\r
433\r
434 }\r
435\r
436 Status = gBS->RegisterProtocolNotify (\r
437 &gEfiDxeSmmReadyToLockProtocolGuid,\r
438 AddSmbiosT0x90CallbackEvent,\r
439 &AddSmbiosT0x90CallbackNotifyReg\r
440 );\r
441\r
442 return Status;\r
443 }\r
444\r
445 return EFI_SUCCESS;\r
446\r
447}\r