/*++

Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
                                                                                   
  This program and the accompanying materials are licensed and made available under
  the terms and conditions of the BSD License that accompanies this distribution.  
  The full text of the license may be found at                                     
  http://opensource.org/licenses/bsd-license.php.                                  
                                                                                   
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,            
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.    
                                                                                   


Module Name:

  MiscProcessorInformationFunction.c

Abstract:

  Onboard processor information boot time changes.
  SMBIOS type 4.

--*/

#include "CommonHeader.h"

#include "MiscSubclassDriver.h"

#include <Protocol/MpService.h>
#include <Protocol/DataHub.h>
#include <Guid/DataHubRecords.h>
#include <Library/CpuIA32.h>

#define EfiProcessorFamilyIntelAtomProcessor    0x2B

EFI_GUID                        mProcessorProducerGuid;


/**
  Get cache SMBIOS record handle.

  @param  Smbios        Pointer to SMBIOS protocol instance.
  @param  CacheLevel    Level of cache, starting from one.
  @param  Handle        Returned record handle.

**/

VOID
GetCacheHandle (
  IN  EFI_SMBIOS_PROTOCOL      *Smbios,
  IN  UINT8                    CacheLevel,
  OUT  EFI_SMBIOS_HANDLE       *Handle
  )
{
  UINT16                     CacheConfig;
  EFI_STATUS                 Status;
  EFI_SMBIOS_TYPE            RecordType;
  EFI_SMBIOS_TABLE_HEADER    *Buffer;

  *Handle = 0;
  RecordType = EFI_SMBIOS_TYPE_CACHE_INFORMATION;

  do {
    Status = Smbios->GetNext (
                       Smbios,
                       Handle,
                       &RecordType,
                       &Buffer,
                       NULL
                       );
    if (!EFI_ERROR(Status)) {
      CacheConfig = *(UINT16*)((UINT8*)Buffer + 5);
      if ((CacheConfig & 0x7) == (CacheLevel -1) ) {
        return;
      }
    }
  } while (!EFI_ERROR(Status));

  *Handle = 0xFFFF;
}


/**
  This function makes boot time changes to the contents of the
  MiscProcessorInformation (Type 4).

  @param  RecordData                 Pointer to copy of RecordData from the Data Table.

  @retval EFI_SUCCESS                All parameters were valid.
  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
  @retval EFI_INVALID_PARAMETER      Invalid parameter was found.

**/
UINT32
ConvertBase10ToRaw (
  IN  EFI_EXP_BASE10_DATA             *Data)
{
  UINTN         Index;
  UINT32        RawData;

  RawData = Data->Value;
  for (Index = 0; Index < (UINTN) Data->Exponent; Index++) {
     RawData *= 10;
  }

  return  RawData;
}

#define BSEL_CR_OVERCLOCK_CONTROL	0xCD
#define	FUSE_BSEL_MASK				0x03



UINT16 miFSBFrequencyTable[4] = {
  83,          	// 83.3MHz
  100,          // 100MHz
  133,          // 133MHz
  117           // 116.7MHz
};

/**
  Determine the processor core frequency

  @param None

  @retval Processor core frequency multiplied by 3


**/
UINT16
DetermineiFsbFromMsr (
  VOID
  )
{
  //
  // Determine the processor core frequency
  //
  UINT64	Temp;
  Temp = (EfiReadMsr (BSEL_CR_OVERCLOCK_CONTROL)) & FUSE_BSEL_MASK;
  return miFSBFrequencyTable[(UINT32)(Temp)];

}

MISC_SMBIOS_TABLE_FUNCTION (MiscProcessorInformation)
{
    CHAR8                           *OptionalStrStart;
    EFI_STRING                      SerialNumber;
    CHAR16                          *Version=NULL;
    CHAR16                          *Manufacturer=NULL;
    CHAR16                          *Socket=NULL;
    CHAR16                          *AssetTag=NULL;
    CHAR16                          *PartNumber=NULL;
    UINTN                           SerialNumberStrLen=0;
    UINTN                           VersionStrLen=0;
    UINTN                           ManufacturerStrLen=0;
    UINTN                           SocketStrLen=0;
    UINTN                           AssetTagStrLen=0;
    UINTN                           PartNumberStrLen=0;
    UINTN                           ProcessorVoltage=0xAE;
    UINT32                          Eax01;
    UINT32                          Ebx01;
    UINT32                          Ecx01;
    UINT32                          Edx01;
    STRING_REF                      TokenToGet;
    EFI_STATUS                      Status;
    EFI_SMBIOS_HANDLE               SmbiosHandle;
    SMBIOS_TABLE_TYPE4              *SmbiosRecord;
    EFI_CPU_DATA_RECORD             *ForType4InputData;
    UINT16                          L1CacheHandle=0;
    UINT16                          L2CacheHandle=0;
    UINT16                          L3CacheHandle=0;
    UINTN                           NumberOfEnabledProcessors=0 ;
    UINTN                           NumberOfProcessors=0;
    UINT64                          Frequency = 0;
    EFI_MP_SERVICES_PROTOCOL        *MpService;
    EFI_DATA_HUB_PROTOCOL           *DataHub;
    UINT64                          MonotonicCount;
    EFI_DATA_RECORD_HEADER          *Record;
    EFI_SUBCLASS_TYPE1_HEADER       *DataHeader;
    UINT8                           *SrcData;
    EFI_PROCESSOR_VERSION_DATA      *ProcessorVersion;
    CHAR16                          *NewStringToken;
    STRING_REF                      TokenToUpdate;
    PROCESSOR_ID_DATA               *ProcessorId = NULL;


    //
    // First check for invalid parameters.
    //
    if (RecordData == NULL) {
        return EFI_INVALID_PARAMETER;
    }

    ForType4InputData = (EFI_CPU_DATA_RECORD *)RecordData;

    ProcessorId = AllocateZeroPool(sizeof(PROCESSOR_ID_DATA));
    if (ProcessorId == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Get the Data Hub Protocol. Assume only one instance
    //
    Status = gBS->LocateProtocol (
                    &gEfiDataHubProtocolGuid,
                    NULL,
                    (VOID **)&DataHub
                    );
    ASSERT_EFI_ERROR(Status);

    MonotonicCount = 0;
    Record = NULL;

    do {
      Status = DataHub->GetNextRecord (
                          DataHub,
                          &MonotonicCount,
                          NULL,
                          &Record
                          );
       if (!EFI_ERROR(Status)) {
         if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {

            DataHeader  = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
            SrcData     = (UINT8  *)(DataHeader + 1);

            //
            // Processor
            //
            if (CompareGuid(&Record->DataRecordGuid, &gEfiProcessorSubClassGuid)) {
              CopyMem (&mProcessorProducerGuid, &Record->ProducerName, sizeof(EFI_GUID));
              switch (DataHeader->RecordType) {
                case ProcessorVoltageRecordType:
                  ProcessorVoltage = (((EFI_EXP_BASE10_DATA *)SrcData)->Value)/100 + 0x80;
                  break;
                case ProcessorCoreFrequencyRecordType:
                  DEBUG ((EFI_D_ERROR, "ProcessorCoreFrequencyRecordType SrcData1 =%d\n", ConvertBase10ToRaw((EFI_EXP_BASE10_DATA *)SrcData)/1000000));
                  Frequency = (ConvertBase10ToRaw((EFI_EXP_BASE10_DATA *)SrcData)/1000000);
                  break;
                case ProcessorVersionRecordType:
                  ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *)SrcData;
                  NewStringToken = HiiGetPackageString(&mProcessorProducerGuid, *ProcessorVersion, NULL);
                  TokenToUpdate = (STRING_REF)STR_MISC_PROCESSOR_VERSION;
                  HiiSetString(mHiiHandle, TokenToUpdate, NewStringToken, NULL);
                  break;
                default:
                  break;
              }
            }
          }
        }
    } while (!EFI_ERROR(Status) && (MonotonicCount != 0));

    //
    // Token to get for Socket Name
    //
    TokenToGet = STRING_TOKEN (STR_MISC_SOCKET_NAME);
    Socket = SmbiosMiscGetString (TokenToGet);
    SocketStrLen = StrLen(Socket);
    if (SocketStrLen > SMBIOS_STRING_MAX_LENGTH) {
         return EFI_UNSUPPORTED;
    }

    //
    // Token to get for Processor Manufacturer
    //
    TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_MAUFACTURER);
    Manufacturer = SmbiosMiscGetString (TokenToGet);
    ManufacturerStrLen = StrLen(Manufacturer);
    if (ManufacturerStrLen > SMBIOS_STRING_MAX_LENGTH) {
      return EFI_UNSUPPORTED;
    }

    //
    // Token to get for Processor Version
    //
    TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_VERSION);
    Version = SmbiosMiscGetString (TokenToGet);
    VersionStrLen = StrLen(Version);
    if (VersionStrLen > SMBIOS_STRING_MAX_LENGTH) {
        return EFI_UNSUPPORTED;
    }

    //
    // Token to get for Serial Number
    //
    TokenToGet = STRING_TOKEN (STR_MISC_PROCESSOR_SERIAL_NUMBER);
    SerialNumber = SmbiosMiscGetString (TokenToGet);
    SerialNumberStrLen = StrLen(SerialNumber);
    if (SerialNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
        return EFI_UNSUPPORTED;
    }

    //
    // Token to get for Assert Tag Information
    //
    TokenToGet = STRING_TOKEN (STR_MISC_ASSERT_TAG_DATA);
    AssetTag = SmbiosMiscGetString (TokenToGet);
    AssetTagStrLen = StrLen(AssetTag);
    if (AssetTagStrLen > SMBIOS_STRING_MAX_LENGTH) {
        return EFI_UNSUPPORTED;
    }

    //
    // Token to get for part number Information
    //
    TokenToGet = STRING_TOKEN (STR_MISC_PART_NUMBER);
    PartNumber = SmbiosMiscGetString (TokenToGet);
    PartNumberStrLen = StrLen(PartNumber);
    if (PartNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
         return EFI_UNSUPPORTED;
    }

    //
    // Two zeros following the last string.
    //
    SmbiosRecord = AllocateZeroPool(sizeof (SMBIOS_TABLE_TYPE4) + AssetTagStrLen + 1 + SocketStrLen + 1+ ManufacturerStrLen +1 + VersionStrLen+ 1+ SerialNumberStrLen + 1 + PartNumberStrLen+ 1 + 1);

    SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION;
    SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE4);

    //
    // Make handle chosen by smbios protocol.add automatically.
    //
    SmbiosRecord->Hdr.Handle = 0;

    SmbiosRecord-> Socket= 1;
    SmbiosRecord -> ProcessorManufacture = 2;
    SmbiosRecord -> ProcessorVersion = 3;
    SmbiosRecord ->SerialNumber =4;

    SmbiosRecord-> AssetTag= 5;
    SmbiosRecord-> PartNumber= 6;

    //
    // Processor Type
    //
    ForType4InputData-> VariableRecord.ProcessorType= EfiCentralProcessor;
    SmbiosRecord -> ProcessorType = ForType4InputData-> VariableRecord.ProcessorType;

    //
    // Processor Family
    //
    ForType4InputData-> VariableRecord.ProcessorFamily= EfiProcessorFamilyIntelAtomProcessor; //0x2B;;
    SmbiosRecord -> ProcessorFamily = ForType4InputData-> VariableRecord.ProcessorFamily;
    SmbiosRecord -> ExternalClock = DetermineiFsbFromMsr();

    //
    // Processor ID
    //
    AsmCpuid(0x001, &Eax01, &Ebx01, &Ecx01, &Edx01);
    ProcessorId->Signature = *(PROCESSOR_SIGNATURE *)&Eax01;
    ProcessorId->FeatureFlags = *(PROCESSOR_FEATURE_FLAGS *)&Edx01;
    SmbiosRecord -> ProcessorId = *(PROCESSOR_ID_DATA *)ProcessorId;

    //
    // Processor Voltage
    //
    ForType4InputData-> VariableRecord.ProcessorVoltage= *(EFI_PROCESSOR_VOLTAGE_DATA *)&ProcessorVoltage;
    SmbiosRecord -> Voltage = *(PROCESSOR_VOLTAGE *) &(ForType4InputData-> VariableRecord.ProcessorVoltage);

    //
    // Status
    //
    ForType4InputData-> VariableRecord.ProcessorHealthStatus= 0x41;//0x41;
    SmbiosRecord -> Status = ForType4InputData-> VariableRecord.ProcessorHealthStatus;

    //
    // Processor Upgrade
    //
    SmbiosRecord -> ProcessorUpgrade = 0x008;

    //
    // Processor Family 2
    //
    SmbiosRecord -> ProcessorFamily2 = ForType4InputData-> VariableRecord.ProcessorFamily;

    //
    // Processor speed
    //
    SmbiosRecord-> CurrentSpeed = *(UINT16*) & Frequency;
    SmbiosRecord-> MaxSpeed = *(UINT16*) & Frequency;

    //
    // Processor Characteristics
    //
    AsmCpuid(0x8000000, NULL, NULL, NULL, &Edx01);
    Edx01= Edx01 >> 28;
    Edx01 &= 0x01;
    SmbiosRecord-> ProcessorCharacteristics= (UINT16)Edx01;

    //
    // Processor Core Count and Enabled core count
    //
    Status = gBS->LocateProtocol (
                    &gEfiMpServiceProtocolGuid,
                    NULL,
                    (void **)&MpService
                    );
    if (!EFI_ERROR (Status)) {
    //
    // Determine the number of processors
    //
    MpService->GetNumberOfProcessors (
                 MpService,
                 &NumberOfProcessors,
                 &NumberOfEnabledProcessors
                 );
    }
    SmbiosRecord-> CoreCount= (UINT8)NumberOfProcessors;
    SmbiosRecord-> EnabledCoreCount= (UINT8)NumberOfEnabledProcessors;
    SmbiosRecord-> ThreadCount= (UINT8)NumberOfEnabledProcessors;
    SmbiosRecord-> ProcessorCharacteristics = 0x2; // Unknown

    //
    // Processor Cache Handle
    //
    GetCacheHandle( Smbios,1, &L1CacheHandle);
    GetCacheHandle( Smbios,2, &L2CacheHandle);
    GetCacheHandle( Smbios,3, &L3CacheHandle);

    //
    // Updating Cache Handle Information
    //
    SmbiosRecord->L1CacheHandle  = L1CacheHandle;
    SmbiosRecord->L2CacheHandle  = L2CacheHandle;
    SmbiosRecord->L3CacheHandle  = L3CacheHandle;

    OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
    UnicodeStrToAsciiStr(Socket, OptionalStrStart);
    UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart + SocketStrLen + 1);
    UnicodeStrToAsciiStr(Version, OptionalStrStart + SocketStrLen + 1 + ManufacturerStrLen+ 1);
    UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + SocketStrLen + 1 + VersionStrLen + 1 + ManufacturerStrLen + 1);
    UnicodeStrToAsciiStr(AssetTag, OptionalStrStart + SerialNumberStrLen + 1 + VersionStrLen + 1 + ManufacturerStrLen + 1 + SocketStrLen + 1);
    UnicodeStrToAsciiStr(PartNumber, OptionalStrStart + SerialNumberStrLen + 1 + VersionStrLen + 1 + ManufacturerStrLen + 1 + SocketStrLen + 1 + AssetTagStrLen + 1 );

    //
    // Now we have got the full Smbios record, call Smbios protocol to add this record.
    //
    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
    Status = Smbios-> Add(
                        Smbios,
                        NULL,
                        &SmbiosHandle,
                        (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
                        );
    if (EFI_ERROR (Status)) return Status;
    FreePool(SmbiosRecord);
    return Status;

}

