Home | History | Annotate | Download | only in ProcessorSubClassDxe
      1 /** @file
      2 *
      3 *  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
      4 *  Copyright (c) 2015, Linaro Limited. All rights reserved.
      5 *
      6 *  This program and the accompanying materials
      7 *  are licensed and made available under the terms and conditions of the BSD License
      8 *  which accompanies this distribution.  The full text of the license may be found at
      9 *  http://opensource.org/licenses/bsd-license.php
     10 *
     11 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 *
     14 **/
     15 
     16 #include "ProcessorSubClass.h"
     17 
     18 #include <FrameworkDxe.h>
     19 
     20 EFI_HII_HANDLE                  mHiiHandle;
     21 
     22 EFI_SMBIOS_PROTOCOL             *mSmbios;
     23 
     24 SMBIOS_TABLE_TYPE7   mSmbiosCacheTable[] = {
     25     //L1 Instruction Cache
     26     {
     27         {                                               //Header
     28             EFI_SMBIOS_TYPE_CACHE_INFORMATION,              //Type
     29             sizeof(SMBIOS_TABLE_TYPE7),                     //Length
     30             0                                               //Handle
     31         },
     32         1,                                              //SocketDesignation
     33         0,                                              //CacheConfiguration
     34         0,                                              //MaximumCacheSize
     35         48,                                             //InstalledSize
     36         {                                               //SupportedSRAMType
     37             0
     38         },
     39         {                                               //CurrentSRAMType
     40             0
     41         },
     42         0,                                              //CacheSpeed
     43         CacheErrorParity,                               //ErrorCorrectionType
     44         CacheTypeInstruction,                           //SystemCacheType
     45         CacheAssociativity8Way                          //Associativity
     46     },
     47 
     48     //L1 Data Cache
     49     {
     50         {                                               //Header
     51             EFI_SMBIOS_TYPE_CACHE_INFORMATION,              //Type
     52             sizeof(SMBIOS_TABLE_TYPE7),                     //Length
     53             0                                               //Handle
     54         },
     55         1,                                              //SocketDesignation
     56         0,                                              //CacheConfiguration
     57         0,                                              //MaximumCacheSize
     58         32,                                              //InstalledSize
     59         {                                               //SupportedSRAMType
     60             0
     61         },
     62         {                                               //CurrentSRAMType
     63             0
     64         },
     65         0,                                              //CacheSpeed
     66         CacheErrorSingleBit,                            //ErrorCorrectionType
     67         CacheTypeData,                                  //SystemCacheType
     68         CacheAssociativity8Way                          //Associativity
     69     },
     70 
     71     //L2 Cache
     72     {
     73         {                                               //Header
     74             EFI_SMBIOS_TYPE_CACHE_INFORMATION,              //Type
     75             sizeof(SMBIOS_TABLE_TYPE7),                     //Length
     76             0                                               //Handle
     77         },
     78         1,                                              //SocketDesignation
     79         0,                                              //CacheConfiguration
     80         0,                                              //MaximumCacheSize
     81         4096,                                           //InstalledSize
     82         {                                               //SupportedSRAMType
     83             0
     84         },
     85         {                                               //CurrentSRAMType
     86             0
     87         },
     88         0,                                              //CacheSpeed
     89         CacheErrorSingleBit,                            //ErrorCorrectionType
     90         CacheTypeUnified,                               //SystemCacheType
     91         CacheAssociativity8Way                          //Associativity
     92     },
     93 
     94     //L3 Cache
     95     {
     96         {                                               //Header
     97             EFI_SMBIOS_TYPE_CACHE_INFORMATION,              //Type
     98             sizeof(SMBIOS_TABLE_TYPE7),                     //Length
     99             0                                               //Handle
    100         },
    101         1,                                              //SocketDesignation
    102         0,                                              //CacheConfiguration
    103         0,                                              //MaximumCacheSize
    104         16384,                                          //InstalledSize
    105         {                                               //SupportedSRAMType
    106             0
    107         },
    108         {                                               //CurrentSRAMType
    109             0
    110         },
    111         0,                                              //CacheSpeed
    112         CacheErrorSingleBit,                            //ErrorCorrectionType
    113         CacheTypeUnified,                               //SystemCacheType
    114         CacheAssociativity16Way                         //Associativity
    115     }
    116 };
    117 
    118 SMBIOS_TABLE_TYPE4   mSmbiosProcessorTable[] = {
    119     //CPU0
    120     {
    121         {                                               //Header
    122             EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,          //Type
    123             sizeof(SMBIOS_TABLE_TYPE4),                     //Length
    124             0                                               //Handle
    125         },
    126         1,                                              //Socket
    127         CentralProcessor,                               //ProcessorType
    128         ProcessorFamilyOther,                           //ProcessorFamily
    129         2,                                              //ProcessorManufacture
    130         {                                               //ProcessorId
    131             {                                               //Signature
    132                 0
    133             },
    134             {                                               //FeatureFlags
    135                 0
    136             }
    137         },
    138         3,                                              //ProcessorVersion
    139         {                                               //Voltage
    140             0
    141         },
    142         EXTERNAL_CLOCK,                                 //ExternalClock
    143         CPU_MAX_SPEED,                                  //MaxSpeed
    144         0,                                              //CurrentSpeed
    145         0,                                              //Status
    146         ProcessorUpgradeUnknown,                        //ProcessorUpgrade
    147         0xFFFF,                                         //L1CacheHandle
    148         0xFFFF,                                         //L2CacheHandle
    149         0xFFFF,                                         //L3CacheHandle
    150         4,                                              //SerialNumber
    151         5,                                              //AssetTag
    152         6,                                              //PartNumber
    153 
    154         0,                                              //CoreCount
    155         0,                                              //EnabledCoreCount
    156         0,                                              //ThreadCount
    157         0,                                              //ProcessorCharacteristics
    158 
    159         ProcessorFamilyARM,                             //ProcessorFamily2
    160 
    161         0,                                              //CoreCount2
    162         0,                                              //EnabledCoreCount2
    163         0                                               //ThreadCount2
    164     },
    165 
    166     //CPU1
    167     {
    168         {                                               //Header
    169             EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,          //Type
    170             sizeof(SMBIOS_TABLE_TYPE4),                     //Length
    171             0                                               //Handle
    172         },
    173         1,                                              //Socket
    174         CentralProcessor,                               //ProcessorType
    175         ProcessorFamilyOther,                           //ProcessorFamily
    176         2,                                              //ProcessorManufacture
    177         {                                               //ProcessorId
    178             {                                               //Signature
    179                 0
    180             },
    181             {                                               //FeatureFlags
    182                 0
    183             }
    184         },
    185         3,                                              //ProcessorVersion
    186         {                                               //Voltage
    187             0
    188         },
    189         EXTERNAL_CLOCK,                                 //ExternalClock
    190         CPU_MAX_SPEED,                                  //MaxSpeed
    191         0,                                              //CurrentSpeed
    192         0,                                              //Status
    193         ProcessorUpgradeUnknown,                        //ProcessorUpgrade
    194         0xFFFF,                                         //L1CacheHandle
    195         0xFFFF,                                         //L2CacheHandle
    196         0xFFFF,                                         //L3CacheHandle
    197         4,                                              //SerialNumber
    198         5,                                              //AssetTag
    199         6,                                              //PartNumber
    200 
    201         0,                                              //CoreCount
    202         0,                                              //EnabledCoreCount
    203         0,                                              //ThreadCount
    204         0,                                              //ProcessorCharacteristics
    205 
    206         ProcessorFamilyARM,                             //ProcessorFamily2
    207 
    208         0,                                              //CoreCount2
    209         0,                                              //EnabledCoreCount2
    210         0                                               //ThreadCount2
    211     }
    212 };
    213 
    214 
    215 UINT16
    216 GetCpuFrequency (
    217   IN  UINT8 ProcessorNumber
    218 )
    219 {
    220     return (UINT16)(PlatformGetCpuFreq(ProcessorNumber)/1000/1000);
    221 }
    222 
    223 UINTN
    224 GetCacheSocketStr (
    225   IN  UINT8     CacheLevel,
    226   OUT CHAR16    *CacheSocketStr
    227   )
    228 {
    229     UINTN CacheSocketStrLen;
    230 
    231     if(CacheLevel == CPU_CACHE_L1_Instruction)
    232     {
    233         CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Instruction Cache", CacheLevel + 1);
    234     }
    235     else if(CacheLevel == CPU_CACHE_L1_Data)
    236     {
    237         CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Data Cache", CacheLevel);
    238     }
    239     else
    240     {
    241         CacheSocketStrLen = UnicodeSPrint (CacheSocketStr, SMBIOS_STRING_MAX_LENGTH - 1, L"L%x Cache", CacheLevel);
    242     }
    243 
    244     return CacheSocketStrLen;
    245 }
    246 
    247 VOID
    248 UpdateSmbiosCacheTable (
    249   IN UINT8  CacheLevel
    250   )
    251 {
    252     UINT16                      CoreCount;
    253     UINT32                      TotalSize;
    254     UINT32                      CacheSize;
    255     UINT16                      MaximumCacheSize;
    256     UINT16                      InstalledSize;
    257     CACHE_CONFIGURATION         CacheConfig;
    258     CACHE_SRAM_TYPE_DATA        CacheSramType = {0};
    259 
    260     CoreCount = 16;     // Default value is 16 Core
    261 
    262     //
    263     // Set Cache Configuration
    264     //
    265     CacheConfig.Bits.Socketed                = 0;    // Not Socketed
    266     CacheConfig.Bits.Reserved1               = 0;    //
    267     CacheConfig.Bits.Location                = 0;    // Internal
    268     CacheConfig.Bits.Enable                  = 1;    // Enabled
    269     CacheConfig.Bits.Reserved2               = 0;
    270     if(CacheLevel == CPU_CACHE_L1_Instruction || CacheLevel == CPU_CACHE_L1_Data)
    271     {
    272         CacheConfig.Bits.Level               = 0;
    273         CacheConfig.Bits.OperationalMode     = 1;        // Write Back
    274     }
    275     else
    276     {
    277         CacheConfig.Bits.Level               = CacheLevel - 1;
    278         CacheConfig.Bits.OperationalMode     = 2;        // Varies with Memory Address
    279     }
    280 
    281     mSmbiosCacheTable[CacheLevel].CacheConfiguration = CacheConfig.Data;
    282 
    283     //
    284     // Set Cache Size
    285     //
    286     CacheSize = mSmbiosCacheTable[CacheLevel].InstalledSize;
    287     if (PACKAGE_16CORE != PlatformGetPackageType())  // 32 Core
    288     {
    289         CoreCount = CoreCount * 2;
    290 
    291         if (CacheLevel > 1)
    292         {
    293             CacheSize = CacheSize * 2;
    294         }
    295     }
    296 
    297     if(CacheLevel <= 1)
    298     {
    299         TotalSize = CacheSize * CoreCount;
    300     }
    301     else
    302     {
    303         TotalSize = CacheSize;
    304     }
    305 
    306     if((TotalSize >> 15) == 0)  // 1K granularity
    307     {
    308         MaximumCacheSize   = (UINT16)TotalSize;
    309         InstalledSize      = (UINT16)TotalSize;
    310     }
    311     else    // 64K granularity
    312     {
    313         MaximumCacheSize   = (UINT16)(TotalSize >> 6);
    314         InstalledSize      = (UINT16)(TotalSize >> 6);
    315 
    316         // Set BIT15 to 1
    317         MaximumCacheSize   |= BIT15;
    318         InstalledSize      |= BIT15;
    319     }
    320 
    321     mSmbiosCacheTable[CacheLevel].MaximumCacheSize = MaximumCacheSize;
    322     mSmbiosCacheTable[CacheLevel].InstalledSize = InstalledSize;
    323 
    324     //
    325     // Set SRAM Type
    326     //
    327     CacheSramType.Synchronous = 1;
    328     (VOID)CopyMem(&mSmbiosCacheTable[CacheLevel].SupportedSRAMType, &CacheSramType, sizeof(CACHE_SRAM_TYPE_DATA));
    329     (VOID)CopyMem(&mSmbiosCacheTable[CacheLevel].CurrentSRAMType, &CacheSramType, sizeof(CACHE_SRAM_TYPE_DATA));
    330 }
    331 
    332 /**
    333   Add Type 7 SMBIOS Record for Cache Information.
    334 
    335   @param[in]    ProcessorNumber     Processor number of specified processor.
    336   @param[out]   L1CacheHandle       Pointer to the handle of the L1 Cache SMBIOS record.
    337   @param[out]   L2CacheHandle       Pointer to the handle of the L2 Cache SMBIOS record.
    338   @param[out]   L3CacheHandle       Pointer to the handle of the L3 Cache SMBIOS record.
    339 
    340 **/
    341 EFI_STATUS
    342 AddSmbiosCacheTypeTable (
    343   IN UINTN                  ProcessorNumber,
    344   OUT EFI_SMBIOS_HANDLE     *L1CacheHandle,
    345   OUT EFI_SMBIOS_HANDLE     *L2CacheHandle,
    346   OUT EFI_SMBIOS_HANDLE     *L3CacheHandle
    347   )
    348 {
    349     EFI_STATUS                  Status;
    350     SMBIOS_TABLE_TYPE7          *Type7Record;
    351     EFI_SMBIOS_HANDLE           SmbiosHandle;
    352     UINTN                       TableSize;
    353     UINT8                       CacheLevel;
    354     CHAR8                       *OptionalStrStart;
    355     EFI_STRING                  CacheSocketStr;
    356     UINTN                       CacheSocketStrLen;
    357     UINTN                       StringBufferSize;
    358 
    359     Status = EFI_SUCCESS;
    360 
    361     //
    362     // Get Cache information
    363     //
    364     for(CacheLevel = 0; CacheLevel < MAX_CACHE_LEVEL; CacheLevel++)
    365     {
    366         Type7Record = NULL;
    367 
    368         if(mSmbiosCacheTable[CacheLevel].InstalledSize == 0)
    369         {
    370             continue;
    371         }
    372 
    373         //
    374         // Update Cache information
    375         //
    376         if (mSmbiosCacheTable[CacheLevel].MaximumCacheSize == 0)
    377         {
    378             UpdateSmbiosCacheTable (CacheLevel);
    379         }
    380 
    381         StringBufferSize = sizeof(CHAR16) * SMBIOS_STRING_MAX_LENGTH;
    382         CacheSocketStr = AllocateZeroPool(StringBufferSize);
    383         if (CacheSocketStr == NULL)
    384         {
    385             Status = EFI_OUT_OF_RESOURCES;
    386             goto Exit;
    387         }
    388 
    389         CacheSocketStrLen = GetCacheSocketStr (CacheLevel, CacheSocketStr);
    390 
    391         TableSize = sizeof(SMBIOS_TABLE_TYPE7) + CacheSocketStrLen + 1 + 1;
    392         Type7Record = AllocateZeroPool (TableSize);
    393         if (Type7Record == NULL)
    394         {
    395             Status = EFI_OUT_OF_RESOURCES;
    396             goto Exit;
    397         }
    398 
    399         (VOID)CopyMem(Type7Record, &mSmbiosCacheTable[CacheLevel], sizeof (SMBIOS_TABLE_TYPE7));
    400 
    401         OptionalStrStart = (CHAR8 *) (Type7Record + 1);
    402         UnicodeStrToAsciiStr (CacheSocketStr, OptionalStrStart);
    403 
    404         SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
    405         Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type7Record);
    406         if (EFI_ERROR (Status))
    407         {
    408             goto Exit;
    409         }
    410 
    411         // Config L1/L2/L3 Cache Handle
    412         switch(CacheLevel)
    413         {
    414             case CPU_CACHE_L1_Instruction:
    415             case CPU_CACHE_L1_Data:
    416                 *L1CacheHandle = SmbiosHandle;
    417                 break;
    418             case CPU_CACHE_L2:
    419                 *L2CacheHandle = SmbiosHandle;
    420                 break;
    421             case CPU_CACHE_L3:
    422                 *L3CacheHandle = SmbiosHandle;
    423                 break;
    424             default :
    425                 break;
    426         }
    427 Exit:
    428         if(Type7Record != NULL)
    429         {
    430             FreePool (Type7Record);
    431         }
    432         if(CacheSocketStr != NULL)
    433         {
    434             FreePool (CacheSocketStr);
    435             CacheSocketStr = NULL;
    436         }
    437     }
    438 
    439     return Status;
    440 }
    441 
    442 /**
    443   Add Type 4 SMBIOS Record for Processor Information.
    444 
    445   @param[in]    ProcessorNumber     Processor number of specified processor.
    446 
    447 **/
    448 EFI_STATUS
    449 AddSmbiosProcessorTypeTable (
    450   IN UINTN                  ProcessorNumber
    451   )
    452 {
    453     EFI_STATUS                  Status;
    454     SMBIOS_TABLE_TYPE4          *Type4Record;
    455     EFI_SMBIOS_HANDLE           SmbiosHandle;
    456     EFI_SMBIOS_HANDLE           L1CacheHandle;
    457     EFI_SMBIOS_HANDLE           L2CacheHandle;
    458     EFI_SMBIOS_HANDLE           L3CacheHandle;
    459 
    460     CHAR8                       *OptionalStrStart;
    461     EFI_STRING_ID               ProcessorManu;
    462     EFI_STRING_ID               ProcessorVersion;
    463     EFI_STRING_ID               SerialNumber;
    464     EFI_STRING_ID               AssetTag;
    465     EFI_STRING_ID               PartNumber;
    466     EFI_STRING                  ProcessorSocketStr;
    467     EFI_STRING                  ProcessorManuStr;
    468     EFI_STRING                  ProcessorVersionStr;
    469     EFI_STRING                  SerialNumberStr;
    470     EFI_STRING                  AssetTagStr;
    471     EFI_STRING                  PartNumberStr;
    472     UINTN                       ProcessorSocketStrLen;
    473     UINTN                       ProcessorManuStrLen;
    474     UINTN                       ProcessorVersionStrLen;
    475     UINTN                       SerialNumberStrLen;
    476     UINTN                       AssetTagStrLen;
    477     UINTN                       PartNumberStrLen;
    478     UINTN                       StringBufferSize;
    479     UINTN                       TotalSize;
    480 
    481     UINT8                       Voltage;
    482     UINT16                      CoreCount;
    483     UINT16                      CoreEnabled;
    484     UINT16                      ThreadCount;
    485     UINT16                      CurrentSpeed;
    486     PROCESSOR_STATUS_DATA       ProcessorStatus = {{0}};
    487     PROCESSOR_CHARACTERISTICS_DATA  ProcessorCharacteristics = {{0}};
    488 
    489     CHAR16                      *CpuVersion;
    490     STRING_REF                  TokenToUpdate;
    491 
    492     UINT64                      *ProcessorId;
    493     Type4Record         = NULL;
    494     ProcessorManuStr    = NULL;
    495     ProcessorVersionStr = NULL;
    496     SerialNumberStr     = NULL;
    497     AssetTagStr         = NULL;
    498     PartNumberStr       = NULL;
    499 
    500     if(OemIsSocketPresent(ProcessorNumber))  //CPU is present
    501     {
    502         Voltage         = BIT7 | 9;          // 0.9V
    503 
    504         Status = AddSmbiosCacheTypeTable (ProcessorNumber, &L1CacheHandle, &L2CacheHandle, &L3CacheHandle);
    505         if(EFI_ERROR(Status))
    506         {
    507             return Status;
    508         }
    509 
    510         CurrentSpeed        = GetCpuFrequency(ProcessorNumber);
    511 
    512         CoreCount       = PlatformGetCoreCount();
    513         CoreEnabled     = CoreCount;
    514         ThreadCount     = CoreCount;
    515 
    516         CpuVersion = (CHAR16 *) PcdGetPtr (PcdCPUInfo);
    517         if (StrLen(CpuVersion) > 0)
    518         {
    519             TokenToUpdate = STRING_TOKEN (STR_PROCESSOR_VERSION);
    520             HiiSetString (mHiiHandle, TokenToUpdate, CpuVersion, NULL);
    521         }
    522 
    523         ProcessorManu       = STRING_TOKEN (STR_PROCESSOR_MANUFACTURE);
    524         ProcessorVersion    = STRING_TOKEN (STR_PROCESSOR_VERSION);
    525         SerialNumber        = STRING_TOKEN (STR_PROCESSOR_SERIAL_NUMBER);
    526         AssetTag            = STRING_TOKEN (STR_PROCESSOR_ASSET_TAG);
    527         PartNumber          = STRING_TOKEN (STR_PROCESSOR_PART_NUMBER);
    528 
    529         // Processor Status
    530         ProcessorStatus.Bits.CpuStatus           = 1;        // CPU Enabled
    531         ProcessorStatus.Bits.Reserved1           = 0;
    532         ProcessorStatus.Bits.SocketPopulated     = 1;        // CPU Socket Populated
    533         ProcessorStatus.Bits.Reserved2           = 0;
    534 
    535         // Processor Characteristics
    536         ProcessorCharacteristics.Bits.Reserved       = 0;
    537         ProcessorCharacteristics.Bits.Capable64Bit   = 1;        // 64-bit Capable
    538         ProcessorCharacteristics.Bits.Unknown        = 0;
    539         ProcessorCharacteristics.Bits.EnhancedVirtualization     = 1;
    540         ProcessorCharacteristics.Bits.HardwareThread = 0;
    541         ProcessorCharacteristics.Bits.MultiCore      = 1;
    542         ProcessorCharacteristics.Bits.ExecuteProtection          = 1;
    543         ProcessorCharacteristics.Bits.PowerPerformanceControl    = 1;
    544         ProcessorCharacteristics.Bits.Reserved2      = 0;
    545     }
    546     else
    547     {
    548         Voltage             = 0;
    549         CurrentSpeed        = 0;
    550         CoreCount           = 0;
    551         CoreEnabled         = 0;
    552         ThreadCount         = 0;
    553         L1CacheHandle       = 0xFFFF;
    554         L2CacheHandle       = 0xFFFF;
    555         L3CacheHandle       = 0xFFFF;
    556 
    557         ProcessorManu       = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
    558         ProcessorVersion    = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
    559         SerialNumber        = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
    560         AssetTag            = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
    561         PartNumber          = STRING_TOKEN (STR_PROCESSOR_UNKNOWN);
    562     }
    563 
    564     // Processor Socket Designation
    565     StringBufferSize = sizeof(CHAR16) * SMBIOS_STRING_MAX_LENGTH;
    566     ProcessorSocketStr = AllocateZeroPool(StringBufferSize);
    567     if (ProcessorSocketStr == NULL)
    568     {
    569         Status = EFI_OUT_OF_RESOURCES;
    570         goto Exit;
    571     }
    572 
    573     ProcessorSocketStrLen = UnicodeSPrint (ProcessorSocketStr, StringBufferSize, L"CPU%02d", ProcessorNumber + 1);
    574 
    575     // Processor Manufacture
    576     ProcessorManuStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorManu, NULL);
    577     ProcessorManuStrLen = StrLen (ProcessorManuStr);
    578 
    579     // Processor Version
    580     ProcessorVersionStr = HiiGetPackageString (&gEfiCallerIdGuid, ProcessorVersion, NULL);
    581     ProcessorVersionStrLen = StrLen (ProcessorVersionStr);
    582 
    583     // Serial Number
    584     SerialNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, SerialNumber, NULL);
    585     SerialNumberStrLen = StrLen (SerialNumberStr);
    586 
    587     // Asset Tag
    588     AssetTagStr = HiiGetPackageString (&gEfiCallerIdGuid, AssetTag, NULL);
    589     AssetTagStrLen = StrLen (AssetTagStr);
    590 
    591     // Part Number
    592     PartNumberStr = HiiGetPackageString (&gEfiCallerIdGuid, PartNumber, NULL);
    593     PartNumberStrLen = StrLen (PartNumberStr);
    594 
    595     TotalSize = sizeof (SMBIOS_TABLE_TYPE4) + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1 + AssetTagStrLen + 1 + PartNumberStrLen + 1 + 1;
    596     Type4Record = AllocateZeroPool (TotalSize);
    597     if (Type4Record == NULL)
    598     {
    599         Status = EFI_OUT_OF_RESOURCES;
    600         goto Exit;
    601     }
    602 
    603     (VOID)CopyMem(Type4Record, &mSmbiosProcessorTable[ProcessorNumber], sizeof (SMBIOS_TABLE_TYPE4));
    604 
    605     *(UINT8 *) &Type4Record->Voltage        = Voltage;
    606     Type4Record->CurrentSpeed               = CurrentSpeed;
    607     Type4Record->Status                     = ProcessorStatus.Data;
    608     Type4Record->L1CacheHandle              = L1CacheHandle;
    609     Type4Record->L2CacheHandle              = L2CacheHandle;
    610     Type4Record->L3CacheHandle              = L3CacheHandle;
    611     Type4Record->CoreCount                  = CoreCount;
    612     Type4Record->EnabledCoreCount           = CoreEnabled;
    613     Type4Record->ThreadCount                = ThreadCount;
    614     Type4Record->ProcessorCharacteristics   = ProcessorCharacteristics.Data;
    615 
    616     Type4Record->ExternalClock              = (UINT16)(ArmReadCntFrq() / 1000 / 1000);
    617     ProcessorId = (UINT64 *)&(Type4Record->ProcessorId);
    618     *ProcessorId = ArmReadMidr();
    619 
    620     OptionalStrStart = (CHAR8 *) (Type4Record + 1);
    621     UnicodeStrToAsciiStr (ProcessorSocketStr, OptionalStrStart);
    622     UnicodeStrToAsciiStr (ProcessorManuStr, OptionalStrStart + ProcessorSocketStrLen + 1);
    623     UnicodeStrToAsciiStr (ProcessorVersionStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1);
    624     UnicodeStrToAsciiStr (SerialNumberStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1);
    625     UnicodeStrToAsciiStr (AssetTagStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1);
    626     UnicodeStrToAsciiStr (PartNumberStr, OptionalStrStart + ProcessorSocketStrLen + 1 + ProcessorManuStrLen + 1 + ProcessorVersionStrLen + 1 + SerialNumberStrLen + 1 + AssetTagStrLen + 1);
    627 
    628     SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
    629     Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type4Record);
    630     if (EFI_ERROR (Status))
    631     {
    632         DEBUG((EFI_D_ERROR, "[%a]:[%dL] Smbios Type04 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
    633     }
    634     FreePool (Type4Record);
    635 
    636 Exit:
    637     if(ProcessorSocketStr != NULL)
    638     {
    639         FreePool (ProcessorSocketStr);
    640     }
    641     if(ProcessorManuStr != NULL)
    642     {
    643         FreePool (ProcessorManuStr);
    644     }
    645     if(ProcessorVersionStr != NULL)
    646     {
    647         FreePool (ProcessorVersionStr);
    648     }
    649     if(SerialNumberStr != NULL)
    650     {
    651         FreePool (SerialNumberStr);
    652     }
    653     if(AssetTagStr != NULL)
    654     {
    655         FreePool (AssetTagStr);
    656     }
    657     if(PartNumberStr != NULL)
    658     {
    659         FreePool (PartNumberStr);
    660     }
    661 
    662     return Status;
    663 }
    664 
    665 /**
    666   Standard EFI driver point.  This driver locates the ProcessorConfigurationData Variable,
    667   if it exists, add the related SMBIOS tables by PI SMBIOS protocol.
    668 
    669   @param  ImageHandle     Handle for the image of this driver
    670   @param  SystemTable     Pointer to the EFI System Table
    671 
    672   @retval  EFI_SUCCESS    The data was successfully stored.
    673 
    674 **/
    675 EFI_STATUS
    676 EFIAPI
    677 ProcessorSubClassEntryPoint(
    678   IN EFI_HANDLE         ImageHandle,
    679   IN EFI_SYSTEM_TABLE   *SystemTable
    680   )
    681 {
    682     EFI_STATUS                      Status;
    683     UINT32                          SocketIndex;
    684 
    685     //
    686     // Locate dependent protocols
    687     //
    688     Status = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID**)&mSmbios);
    689     if (EFI_ERROR(Status))
    690     {
    691         DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol.  %r\n", Status));
    692         return Status;
    693     }
    694 
    695     //
    696     // Add our default strings to the HII database. They will be modified later.
    697     //
    698     mHiiHandle = HiiAddPackages (
    699                 &gEfiCallerIdGuid,
    700                 NULL,
    701                 ProcessorSubClassStrings,
    702                 NULL,
    703                 NULL
    704                 );
    705     if (mHiiHandle == NULL)
    706     {
    707         return EFI_OUT_OF_RESOURCES;
    708     }
    709 
    710     //
    711     // Add SMBIOS tables for populated sockets.
    712     //
    713     for (SocketIndex = 0; SocketIndex < MAX_SOCKET; SocketIndex++)
    714     {
    715         if((SocketIndex == 1) && !OemIsMpBoot())
    716         {
    717             break;
    718         }
    719         Status = AddSmbiosProcessorTypeTable (SocketIndex);
    720         if(EFI_ERROR(Status))
    721         {
    722             DEBUG((EFI_D_ERROR, "Add Processor Type Table Failed!  %r.\n", Status));
    723             return Status;
    724         }
    725     }
    726 
    727     return Status;
    728 }
    729