/*++
|
|
Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
Module Name:
|
|
MiscProcessorCacheFunction.c
|
|
Abstract:
|
|
BIOS processor cache details.
|
Misc. subclass type 7.
|
SMBIOS type 7.
|
|
--*/
|
#include "CommonHeader.h"
|
#include "MiscSubclassDriver.h"
|
#include <Register/Cpuid.h>
|
|
MISC_SMBIOS_TABLE_FUNCTION(MiscProcessorCache)
|
{
|
EFI_SMBIOS_HANDLE SmbiosHandle;
|
SMBIOS_TABLE_TYPE7 *SmbiosRecord;
|
|
EFI_CACHE_SRAM_TYPE_DATA CacheSramType;
|
CHAR16 *SocketDesignation;
|
CHAR8 *OptionalStrStart;
|
UINTN SocketStrLen;
|
STRING_REF TokenToGet;
|
UINT32 SubIndex;
|
CPUID_CACHE_PARAMS_EAX CacheParamsEax;
|
CPUID_CACHE_PARAMS_EBX CacheParamsEbx;
|
UINT32 RegisterEcx;
|
CPUID_CACHE_PARAMS_EDX CacheParamsEdx;
|
UINT8 SystemCacheType;
|
UINTN Size;
|
|
//
|
// Memory Device Locator
|
//
|
TokenToGet = STRING_TOKEN (STR_SOCKET_DESIGNATION);
|
SocketDesignation = SmbiosMiscGetString (TokenToGet);
|
SocketStrLen = StrLen(SocketDesignation);
|
if (SocketStrLen > SMBIOS_STRING_MAX_LENGTH) {
|
return EFI_UNSUPPORTED;
|
}
|
|
//
|
// Retrieve cache level information using CPUID
|
//
|
for (SubIndex = 0; ; SubIndex++) {
|
AsmCpuidEx (
|
CPUID_CACHE_PARAMS,
|
SubIndex,
|
&CacheParamsEax.Uint32,
|
&CacheParamsEbx.Uint32,
|
&RegisterEcx,
|
&CacheParamsEdx.Uint32
|
);
|
//
|
// Terminate loop when CacheType is CPUID_CACHE_PARAMS_CACHE_TYPE_NULL
|
//
|
if (CacheParamsEax.Bits.CacheType == CPUID_CACHE_PARAMS_CACHE_TYPE_NULL) {
|
break;
|
}
|
|
//
|
// Allocate and zero SMBIOS TYPE 7 Record
|
//
|
SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE7) + 7 + 1 + 1);
|
ASSERT (SmbiosRecord != NULL);
|
|
//
|
// Compute cache size in bytes
|
//
|
Size = (CacheParamsEbx.Bits.Ways + 1) *
|
(CacheParamsEbx.Bits.LinePartitions + 1) *
|
(CacheParamsEbx.Bits.LineSize + 1) *
|
(RegisterEcx + 1);
|
DEBUG ((DEBUG_INFO, "MiscProcessorCache(): Cache Type = %d Cache Level = %d Size = %x\n", CacheParamsEax.Bits.CacheType, CacheParamsEax.Bits.CacheLevel, Size));
|
|
//
|
// Determine SMBIOS SystemCacheType
|
//
|
switch (CacheParamsEax.Bits.CacheType) {
|
case 1:
|
SystemCacheType = CacheTypeData;
|
break;
|
case 2:
|
SystemCacheType = CacheTypeInstruction;
|
break;
|
case 3:
|
SystemCacheType = CacheTypeUnified;
|
break;
|
default:
|
SystemCacheType = CacheTypeUnknown;
|
}
|
|
//
|
// Update cache sizes in KB
|
//
|
switch (CacheParamsEax.Bits.CacheLevel) {
|
case 1:
|
SmbiosRecord->InstalledSize = (UINT16)(Size >> 10);
|
SmbiosRecord->MaximumCacheSize = SmbiosRecord->InstalledSize;
|
SmbiosRecord->SystemCacheType = SystemCacheType;
|
SmbiosRecord->Associativity = CacheAssociativity8Way;
|
SmbiosRecord->CacheConfiguration = 0x0180;
|
break;
|
case 2:
|
SmbiosRecord->InstalledSize = (UINT16)(Size >> 10);
|
SmbiosRecord->MaximumCacheSize = SmbiosRecord->InstalledSize;
|
SmbiosRecord->SystemCacheType = SystemCacheType;
|
SmbiosRecord->Associativity = CacheAssociativity16Way;
|
SmbiosRecord->CacheConfiguration = 0x0281;
|
//
|
//VLV2 incorporates two SLM modules (quad cores) in the SoC.
|
// 2 cores share BIU/L2 cache
|
//
|
SmbiosRecord->InstalledSize = SmbiosRecord->InstalledSize / 2;
|
SmbiosRecord->MaximumCacheSize = SmbiosRecord->InstalledSize;
|
break;
|
default:
|
DEBUG ((DEBUG_ERROR, "MiscProcessorCache(): Unexpected cache level %d\n", CacheParamsEax.Bits.CacheLevel));
|
break;
|
}
|
|
//
|
//Filling SMBIOS type 7 information for different cache levels.
|
//
|
SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
|
SmbiosRecord->Hdr.Length = (UINT8) sizeof (SMBIOS_TABLE_TYPE7);
|
SmbiosRecord->Hdr.Handle = 0;
|
|
SmbiosRecord->SocketDesignation = 0x01;
|
SmbiosRecord->CacheSpeed = 0;
|
ZeroMem (&CacheSramType, sizeof (EFI_CACHE_SRAM_TYPE_DATA));
|
CacheSramType.Synchronous = 1;
|
CopyMem(&SmbiosRecord->SupportedSRAMType, &CacheSramType, 2);
|
CopyMem(&SmbiosRecord->CurrentSRAMType, &CacheSramType, 2);
|
SmbiosRecord->ErrorCorrectionType = EfiCacheErrorSingleBit;
|
|
//
|
// Adding SMBIOS type 7 records to SMBIOS table.
|
//
|
SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
|
OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
|
UnicodeStrToAsciiStrS (SocketDesignation, OptionalStrStart, + 7 + 1 + 1);
|
|
Smbios->Add(
|
Smbios,
|
NULL,
|
&SmbiosHandle,
|
(EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
|
);
|
}
|
return EFI_SUCCESS;
|
}
|