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