/*++ Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
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 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; }