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