4 Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
5 Copyright (c) 2015, Hisilicon Limited. All rights reserved.
6 Copyright (c) 2015, Linaro Limited. All rights reserved.
7 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <Protocol/Smbios.h>
13 #include <IndustryStandard/ArmCache.h>
14 #include <IndustryStandard/ArmStdSmc.h>
15 #include <IndustryStandard/SmBios.h>
16 #include <Library/ArmLib.h>
17 #include <Library/ArmSmcLib.h>
18 #include <Library/BaseLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/HiiLib.h>
22 #include <Library/IoLib.h>
23 #include <Library/MemoryAllocationLib.h>
24 #include <Library/OemMiscLib.h>
25 #include <Library/PcdLib.h>
26 #include <Library/PrintLib.h>
27 #include <Library/UefiBootServicesTableLib.h>
28 #include <Library/UefiLib.h>
30 #include "SmbiosProcessor.h"
32 extern UINT8 ProcessorSubClassStrings
[];
34 #define CACHE_SOCKETED_SHIFT 3
35 #define CACHE_LOCATION_SHIFT 5
36 #define CACHE_ENABLED_SHIFT 7
37 #define CACHE_OPERATION_MODE_SHIFT 8
40 CacheModeWriteThrough
= 0, ///< Cache is write-through
41 CacheModeWriteBack
, ///< Cache is write-back
42 CacheModeVariesWithAddress
, ///< Cache mode varies by address
43 CacheModeUnknown
, ///< Cache mode is unknown
45 } CACHE_OPERATION_MODE
;
48 CacheLocationInternal
= 0, ///< Cache is internal to the processor
49 CacheLocationExternal
, ///< Cache is external to the processor
50 CacheLocationReserved
, ///< Reserved
51 CacheLocationUnknown
, ///< Cache location is unknown
55 EFI_HII_HANDLE mHiiHandle
;
57 EFI_SMBIOS_PROTOCOL
*mSmbios
;
59 SMBIOS_TABLE_TYPE4 mSmbiosProcessorTableTemplate
= {
61 EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION
, // Type
62 sizeof (SMBIOS_TABLE_TYPE4
), // Length
66 CentralProcessor
, // ProcessorType
67 ProcessorFamilyIndicatorFamily2
, // ProcessorFamily
68 2, // ProcessorManufacture
77 3, // ProcessorVersion
85 ProcessorUpgradeUnknown
, // ProcessorUpgrade
86 0xFFFF, // L1CacheHandle
87 0xFFFF, // L2CacheHandle
88 0xFFFF, // L3CacheHandle
93 0, // EnabledCoreCount
95 0, // ProcessorCharacteristics
96 ProcessorFamilyARM
, // ProcessorFamily2
98 0, // EnabledCoreCount2
102 /** Sets the HII variable `StringId` is `Pcd` isn't empty.
104 @param Pcd The FixedAtBuild PCD that contains the string to fetch.
105 @param StringId The string identifier to set.
107 #define SET_HII_STRING_IF_PCD_NOT_EMPTY(Pcd, StringId) \
110 Str = (CHAR16*)PcdGetPtr (Pcd); \
111 if (StrLen (Str) > 0) { \
112 HiiSetString (mHiiHandle, StringId, Str, NULL); \
116 /** Fetches the specified processor's frequency in Hz.
118 @param ProcessorNumber The processor number
120 @return The clock frequency in MHz
125 IN UINT8 ProcessorNumber
128 return (UINT16
)(OemGetCpuFreq (ProcessorNumber
) / 1000 / 1000);
131 /** Gets a description of the specified cache.
133 @param[in] CacheLevel Zero-based cache level (e.g. L1 cache is 0).
134 @param[in] DataCache Cache is a data cache.
135 @param[in] UnifiedCache Cache is a unified cache.
136 @param[out] CacheSocketStr The description of the specified cache
138 @return The number of Unicode characters in CacheSocketStr not including the
144 IN BOOLEAN DataCache
,
145 IN BOOLEAN UnifiedCache
,
146 OUT CHAR16
*CacheSocketStr
149 UINTN CacheSocketStrLen
;
151 if ((CacheLevel
== CpuCacheL1
) && !DataCache
&& !UnifiedCache
) {
152 CacheSocketStrLen
= UnicodeSPrint (
154 SMBIOS_STRING_MAX_LENGTH
- 1,
155 L
"L%x Instruction Cache",
158 } else if ((CacheLevel
== CpuCacheL1
) && DataCache
) {
159 CacheSocketStrLen
= UnicodeSPrint (
161 SMBIOS_STRING_MAX_LENGTH
- 1,
166 CacheSocketStrLen
= UnicodeSPrint (
168 SMBIOS_STRING_MAX_LENGTH
- 1,
174 return CacheSocketStrLen
;
177 /** Fills in the Type 7 record with the cache architecture information
178 read from the CPU registers.
180 @param[in] CacheLevel Cache level (e.g. L1, L2).
181 @param[in] DataCache Cache is a data cache.
182 @param[in] UnifiedCache Cache is a unified cache.
183 @param[out] Type7Record The Type 7 record to fill in.
187 ConfigureCacheArchitectureInformation (
189 IN BOOLEAN DataCache
,
190 IN BOOLEAN UnifiedCache
,
191 OUT SMBIOS_TABLE_TYPE7
*Type7Record
199 if (!DataCache
&& !UnifiedCache
) {
200 Type7Record
->SystemCacheType
= CacheTypeInstruction
;
201 } else if (DataCache
) {
202 Type7Record
->SystemCacheType
= CacheTypeData
;
203 } else if (UnifiedCache
) {
204 Type7Record
->SystemCacheType
= CacheTypeUnified
;
209 CacheSize64
= SmbiosProcessorGetCacheSize (
215 Associativity
= SmbiosProcessorGetCacheAssociativity (
221 CacheSize64
/= 1024; // Minimum granularity is 1K
223 // Encode the cache size into the format SMBIOS wants
224 if (CacheSize64
< MAX_INT16
) {
225 CacheSize16
= CacheSize64
;
226 CacheSize32
= CacheSize16
;
227 } else if ((CacheSize64
/ 64) < MAX_INT16
) {
228 CacheSize16
= (1 << 15) | (CacheSize64
/ 64);
229 CacheSize32
= (1 << 31) | (CacheSize64
/ 64);
231 if ((CacheSize64
/ 1024) <= 2047) {
232 CacheSize32
= CacheSize64
;
234 CacheSize32
= (1 << 31) | (CacheSize64
/ 64);
240 Type7Record
->MaximumCacheSize
= CacheSize16
;
241 Type7Record
->InstalledSize
= CacheSize16
;
242 Type7Record
->MaximumCacheSize2
= CacheSize32
;
243 Type7Record
->InstalledSize2
= CacheSize32
;
245 switch (Associativity
) {
247 Type7Record
->Associativity
= CacheAssociativity2Way
;
250 Type7Record
->Associativity
= CacheAssociativity4Way
;
253 Type7Record
->Associativity
= CacheAssociativity8Way
;
256 Type7Record
->Associativity
= CacheAssociativity12Way
;
259 Type7Record
->Associativity
= CacheAssociativity16Way
;
262 Type7Record
->Associativity
= CacheAssociativity20Way
;
265 Type7Record
->Associativity
= CacheAssociativity24Way
;
268 Type7Record
->Associativity
= CacheAssociativity32Way
;
271 Type7Record
->Associativity
= CacheAssociativity48Way
;
274 Type7Record
->Associativity
= CacheAssociativity64Way
;
277 Type7Record
->Associativity
= CacheAssociativityOther
;
281 Type7Record
->CacheConfiguration
= (CacheModeUnknown
<< CACHE_OPERATION_MODE_SHIFT
) |
282 (1 << CACHE_ENABLED_SHIFT
) |
283 (CacheLocationUnknown
<< CACHE_LOCATION_SHIFT
) |
284 (0 << CACHE_SOCKETED_SHIFT
) |
288 /** Allocates and initializes an SMBIOS_TABLE_TYPE7 structure.
290 @param[in] CacheLevel The cache level (L1-L7).
291 @param[in] DataCache Cache is a data cache.
292 @param[in] UnifiedCache Cache is a unified cache.
294 @return A pointer to the Type 7 structure. Returns NULL on failure.
297 AllocateAndInitCacheInformation (
299 IN BOOLEAN DataCache
,
300 IN BOOLEAN UnifiedCache
303 SMBIOS_TABLE_TYPE7
*Type7Record
;
304 EFI_STRING CacheSocketStr
;
305 UINTN CacheSocketStrLen
;
306 UINTN StringBufferSize
;
307 CHAR8
*OptionalStrStart
;
310 // Allocate and fetch the cache description
311 StringBufferSize
= sizeof (CHAR16
) * SMBIOS_STRING_MAX_LENGTH
;
312 CacheSocketStr
= AllocateZeroPool (StringBufferSize
);
313 if (CacheSocketStr
== NULL
) {
317 CacheSocketStrLen
= GetCacheSocketStr (
324 TableSize
= sizeof (SMBIOS_TABLE_TYPE7
) + CacheSocketStrLen
+ 1 + 1;
325 Type7Record
= AllocateZeroPool (TableSize
);
326 if (Type7Record
== NULL
) {
327 FreePool (CacheSocketStr
);
331 Type7Record
->Hdr
.Type
= EFI_SMBIOS_TYPE_CACHE_INFORMATION
;
332 Type7Record
->Hdr
.Length
= sizeof (SMBIOS_TABLE_TYPE7
);
333 Type7Record
->Hdr
.Handle
= SMBIOS_HANDLE_PI_RESERVED
;
335 Type7Record
->SocketDesignation
= 1;
337 Type7Record
->SupportedSRAMType
.Unknown
= 1;
338 Type7Record
->CurrentSRAMType
.Unknown
= 1;
339 Type7Record
->CacheSpeed
= 0;
340 Type7Record
->ErrorCorrectionType
= CacheErrorUnknown
;
342 OptionalStrStart
= (CHAR8
*)(Type7Record
+ 1);
343 UnicodeStrToAsciiStrS (CacheSocketStr
, OptionalStrStart
, CacheSocketStrLen
+ 1);
344 FreePool (CacheSocketStr
);
350 Add Type 7 SMBIOS Record for Cache Information.
352 @param[in] ProcessorIndex Processor number of specified processor.
353 @param[out] L1CacheHandle Pointer to the handle of the L1 Cache SMBIOS record.
354 @param[out] L2CacheHandle Pointer to the handle of the L2 Cache SMBIOS record.
355 @param[out] L3CacheHandle Pointer to the handle of the L3 Cache SMBIOS record.
359 AddSmbiosCacheTypeTable (
360 IN UINTN ProcessorIndex
,
361 OUT EFI_SMBIOS_HANDLE
*L1CacheHandle
,
362 OUT EFI_SMBIOS_HANDLE
*L2CacheHandle
,
363 OUT EFI_SMBIOS_HANDLE
*L3CacheHandle
367 SMBIOS_TABLE_TYPE7
*Type7Record
;
368 EFI_SMBIOS_HANDLE SmbiosHandle
;
371 BOOLEAN DataCacheType
;
372 BOOLEAN SeparateCaches
;
374 Status
= EFI_SUCCESS
;
378 // See if there's an L1 cache present.
379 MaxCacheLevel
= SmbiosProcessorGetMaxCacheLevel ();
381 if (MaxCacheLevel
< 1) {
385 for (CacheLevel
= 1; CacheLevel
<= MaxCacheLevel
; CacheLevel
++) {
388 SeparateCaches
= SmbiosProcessorHasSeparateCaches (CacheLevel
);
390 // At each level of cache, we can have a single type (unified, instruction or data),
391 // or two types - separate data and instruction caches. If we have separate
392 // instruction and data caches, then on the first iteration (CacheSubLevel = 0)
393 // process the instruction cache.
394 for (DataCacheType
= 0; DataCacheType
<= 1; DataCacheType
++) {
395 // If there's no separate data/instruction cache, skip the second iteration
396 if ((DataCacheType
== 1) && !SeparateCaches
) {
400 Type7Record
= AllocateAndInitCacheInformation (
405 if (Type7Record
== NULL
) {
409 ConfigureCacheArchitectureInformation (
416 // Allow the platform to fill in other information such as speed, SRAM type etc.
417 if (!OemGetCacheInformation (
428 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
429 // Finally, install the table
430 Status
= mSmbios
->Add (
434 (EFI_SMBIOS_TABLE_HEADER
*)Type7Record
436 if (EFI_ERROR (Status
)) {
440 // Config L1/L2/L3 Cache Handle
441 switch (CacheLevel
) {
443 *L1CacheHandle
= SmbiosHandle
;
446 *L2CacheHandle
= SmbiosHandle
;
449 *L3CacheHandle
= SmbiosHandle
;
458 /** Allocates a Type 4 Processor Information structure and sets the
459 strings following the data fields.
461 @param[out] Type4Record The Type 4 structure to allocate and initialize
462 @param[in] ProcessorIndex The index of the processor
463 @param[in] Populated Whether the specified processor is
466 @retval EFI_SUCCESS The Type 4 structure was successfully
467 allocated and the strings initialized.
468 @retval EFI_OUT_OF_RESOURCES Could not allocate memory needed.
471 AllocateType4AndSetProcessorInformationStrings (
472 SMBIOS_TABLE_TYPE4
**Type4Record
,
473 UINT8 ProcessorIndex
,
478 EFI_STRING_ID ProcessorManu
;
479 EFI_STRING_ID ProcessorVersion
;
480 EFI_STRING_ID SerialNumber
;
481 EFI_STRING_ID AssetTag
;
482 EFI_STRING_ID PartNumber
;
483 EFI_STRING ProcessorStr
;
484 EFI_STRING ProcessorManuStr
;
485 EFI_STRING ProcessorVersionStr
;
486 EFI_STRING SerialNumberStr
;
487 EFI_STRING AssetTagStr
;
488 EFI_STRING PartNumberStr
;
489 CHAR8
*OptionalStrStart
;
491 UINTN ProcessorStrLen
;
492 UINTN ProcessorManuStrLen
;
493 UINTN ProcessorVersionStrLen
;
494 UINTN SerialNumberStrLen
;
495 UINTN AssetTagStrLen
;
496 UINTN PartNumberStrLen
;
498 UINTN StringBufferSize
;
500 Status
= EFI_SUCCESS
;
502 ProcessorManuStr
= NULL
;
503 ProcessorVersionStr
= NULL
;
504 SerialNumberStr
= NULL
;
506 PartNumberStr
= NULL
;
508 ProcessorManu
= STRING_TOKEN (STR_PROCESSOR_MANUFACTURE
);
509 ProcessorVersion
= STRING_TOKEN (STR_PROCESSOR_VERSION
);
510 SerialNumber
= STRING_TOKEN (STR_PROCESSOR_SERIAL_NUMBER
);
511 AssetTag
= STRING_TOKEN (STR_PROCESSOR_ASSET_TAG
);
512 PartNumber
= STRING_TOKEN (STR_PROCESSOR_PART_NUMBER
);
514 SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorManufacturer
, ProcessorManu
);
515 SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorVersion
, ProcessorVersion
);
516 SET_HII_STRING_IF_PCD_NOT_EMPTY (PcdProcessorAssetTag
, AssetTag
);
518 if (StrLen ((CHAR16
*)FixedPcdGetPtr (PcdProcessorSerialNumber
)) > 0) {
519 HiiSetString (mHiiHandle
, SerialNumber
, (CHAR16
*)FixedPcdGetPtr (PcdProcessorSerialNumber
), NULL
);
521 OemUpdateSmbiosInfo (mHiiHandle
, SerialNumber
, ProcessorSerialNumType04
);
524 if (StrLen ((CHAR16
*)FixedPcdGetPtr (PcdProcessorPartNumber
)) > 0) {
525 HiiSetString (mHiiHandle
, PartNumber
, (CHAR16
*)FixedPcdGetPtr (PcdProcessorPartNumber
), NULL
);
527 OemUpdateSmbiosInfo (mHiiHandle
, PartNumber
, ProcessorPartNumType04
);
530 // Processor Designation
531 StringBufferSize
= sizeof (CHAR16
) * SMBIOS_STRING_MAX_LENGTH
;
532 ProcessorStr
= AllocateZeroPool (StringBufferSize
);
533 if (ProcessorStr
== NULL
) {
534 return EFI_OUT_OF_RESOURCES
;
537 ProcessorStrLen
= UnicodeSPrint (
544 // Processor Manufacture
545 ProcessorManuStr
= HiiGetPackageString (&gEfiCallerIdGuid
, ProcessorManu
, NULL
);
546 ProcessorManuStrLen
= StrLen (ProcessorManuStr
);
549 ProcessorVersionStr
= HiiGetPackageString (&gEfiCallerIdGuid
, ProcessorVersion
, NULL
);
550 ProcessorVersionStrLen
= StrLen (ProcessorVersionStr
);
553 SerialNumberStr
= HiiGetPackageString (&gEfiCallerIdGuid
, SerialNumber
, NULL
);
554 SerialNumberStrLen
= StrLen (SerialNumberStr
);
557 AssetTagStr
= HiiGetPackageString (&gEfiCallerIdGuid
, AssetTag
, NULL
);
558 AssetTagStrLen
= StrLen (AssetTagStr
);
561 PartNumberStr
= HiiGetPackageString (&gEfiCallerIdGuid
, PartNumber
, NULL
);
562 PartNumberStrLen
= StrLen (PartNumberStr
);
564 TotalSize
= sizeof (SMBIOS_TABLE_TYPE4
) +
565 ProcessorStrLen
+ 1 +
566 ProcessorManuStrLen
+ 1 +
567 ProcessorVersionStrLen
+ 1 +
568 SerialNumberStrLen
+ 1 +
570 PartNumberStrLen
+ 1 + 1;
572 *Type4Record
= AllocateZeroPool (TotalSize
);
573 if (*Type4Record
== NULL
) {
574 Status
= EFI_OUT_OF_RESOURCES
;
578 CopyMem (*Type4Record
, &mSmbiosProcessorTableTemplate
, sizeof (SMBIOS_TABLE_TYPE4
));
580 OptionalStrStart
= (CHAR8
*)(*Type4Record
+ 1);
581 UnicodeStrToAsciiStrS (
587 StrStart
= OptionalStrStart
+ ProcessorStrLen
+ 1;
588 UnicodeStrToAsciiStrS (
591 ProcessorManuStrLen
+ 1
594 StrStart
+= ProcessorManuStrLen
+ 1;
595 UnicodeStrToAsciiStrS (
598 ProcessorVersionStrLen
+ 1
601 StrStart
+= ProcessorVersionStrLen
+ 1;
602 UnicodeStrToAsciiStrS (
605 SerialNumberStrLen
+ 1
608 StrStart
+= SerialNumberStrLen
+ 1;
609 UnicodeStrToAsciiStrS (
615 StrStart
+= AssetTagStrLen
+ 1;
616 UnicodeStrToAsciiStrS (
623 FreePool (ProcessorStr
);
624 FreePool (ProcessorManuStr
);
625 FreePool (ProcessorVersionStr
);
626 FreePool (SerialNumberStr
);
627 FreePool (AssetTagStr
);
628 FreePool (PartNumberStr
);
634 Add Type 4 SMBIOS Record for Processor Information.
636 @param[in] ProcessorIndex Processor index of specified processor.
640 AddSmbiosProcessorTypeTable (
641 IN UINTN ProcessorIndex
645 SMBIOS_TABLE_TYPE4
*Type4Record
;
646 EFI_SMBIOS_HANDLE SmbiosHandle
;
647 EFI_SMBIOS_HANDLE L1CacheHandle
;
648 EFI_SMBIOS_HANDLE L2CacheHandle
;
649 EFI_SMBIOS_HANDLE L3CacheHandle
;
650 UINT8
*LegacyVoltage
;
651 PROCESSOR_STATUS_DATA ProcessorStatus
;
653 PROCESSOR_CHARACTERISTIC_FLAGS ProcessorCharacteristics
;
654 OEM_MISC_PROCESSOR_DATA MiscProcessorData
;
655 BOOLEAN ProcessorPopulated
;
659 MiscProcessorData
.Voltage
= 0;
660 MiscProcessorData
.CurrentSpeed
= 0;
661 MiscProcessorData
.CoreCount
= 0;
662 MiscProcessorData
.CoresEnabled
= 0;
663 MiscProcessorData
.ThreadCount
= 0;
664 MiscProcessorData
.MaxSpeed
= 0;
665 L1CacheHandle
= 0xFFFF;
666 L2CacheHandle
= 0xFFFF;
667 L3CacheHandle
= 0xFFFF;
669 ProcessorPopulated
= OemIsProcessorPresent (ProcessorIndex
);
671 Status
= AllocateType4AndSetProcessorInformationStrings (
676 if (EFI_ERROR (Status
)) {
680 OemGetProcessorInformation (
683 (PROCESSOR_CHARACTERISTIC_FLAGS
*)
684 &Type4Record
->ProcessorCharacteristics
,
688 if (ProcessorPopulated
) {
689 AddSmbiosCacheTypeTable (
697 LegacyVoltage
= (UINT8
*)&Type4Record
->Voltage
;
699 *LegacyVoltage
= MiscProcessorData
.Voltage
;
700 Type4Record
->CurrentSpeed
= MiscProcessorData
.CurrentSpeed
;
701 Type4Record
->MaxSpeed
= MiscProcessorData
.MaxSpeed
;
702 Type4Record
->Status
= ProcessorStatus
.Data
;
703 Type4Record
->L1CacheHandle
= L1CacheHandle
;
704 Type4Record
->L2CacheHandle
= L2CacheHandle
;
705 Type4Record
->L3CacheHandle
= L3CacheHandle
;
706 Type4Record
->CoreCount
= MiscProcessorData
.CoreCount
;
707 Type4Record
->CoreCount2
= MiscProcessorData
.CoreCount
;
708 Type4Record
->EnabledCoreCount
= MiscProcessorData
.CoresEnabled
;
709 Type4Record
->EnabledCoreCount2
= MiscProcessorData
.CoresEnabled
;
710 Type4Record
->ThreadCount
= MiscProcessorData
.ThreadCount
;
711 Type4Record
->ThreadCount2
= MiscProcessorData
.ThreadCount
;
713 Type4Record
->CurrentSpeed
= GetCpuFrequency (ProcessorIndex
);
714 Type4Record
->ExternalClock
=
715 (UINT16
)(SmbiosGetExternalClockFrequency () / 1000 / 1000);
717 ProcessorId
= (UINT64
*)&Type4Record
->ProcessorId
;
718 *ProcessorId
= SmbiosGetProcessorId ();
720 ProcessorCharacteristics
= SmbiosGetProcessorCharacteristics ();
721 Type4Record
->ProcessorCharacteristics
|= *((UINT64
*)&ProcessorCharacteristics
);
723 Type4Record
->ProcessorFamily
= SmbiosGetProcessorFamily ();
724 Type4Record
->ProcessorFamily2
= SmbiosGetProcessorFamily2 ();
726 SmbiosHandle
= SMBIOS_HANDLE_PI_RESERVED
;
727 Status
= mSmbios
->Add (
731 (EFI_SMBIOS_TABLE_HEADER
*)Type4Record
734 if (EFI_ERROR (Status
)) {
737 "[%a]:[%dL] Smbios Type04 Table Log Failed! %r \n",
744 FreePool (Type4Record
);
750 Standard EFI driver point.
752 @param ImageHandle Handle for the image of this driver
753 @param SystemTable Pointer to the EFI System Table
755 @retval EFI_SUCCESS The data was successfully stored.
760 ProcessorSubClassEntryPoint (
761 IN EFI_HANDLE ImageHandle
,
762 IN EFI_SYSTEM_TABLE
*SystemTable
766 UINT32 ProcessorIndex
;
769 // Locate dependent protocols
771 Status
= gBS
->LocateProtocol (&gEfiSmbiosProtocolGuid
, NULL
, (VOID
**)&mSmbios
);
772 if (EFI_ERROR (Status
)) {
773 DEBUG ((DEBUG_ERROR
, "Could not locate SMBIOS protocol. %r\n", Status
));
778 // Add our default strings to the HII database. They will be modified later.
780 mHiiHandle
= HiiAddPackages (
783 ProcessorSubClassStrings
,
787 if (mHiiHandle
== NULL
) {
788 return EFI_OUT_OF_RESOURCES
;
792 // Add SMBIOS tables for populated sockets.
794 for (ProcessorIndex
= 0; ProcessorIndex
< OemGetMaxProcessors (); ProcessorIndex
++) {
795 Status
= AddSmbiosProcessorTypeTable (ProcessorIndex
);
796 if (EFI_ERROR (Status
)) {
797 DEBUG ((DEBUG_ERROR
, "Add Processor Type Table Failed! %r.\n", Status
));