summaryrefslogtreecommitdiffstats
path: root/src/detection/cpucache/cpucache_shared.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/detection/cpucache/cpucache_shared.c')
-rw-r--r--src/detection/cpucache/cpucache_shared.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/detection/cpucache/cpucache_shared.c b/src/detection/cpucache/cpucache_shared.c
new file mode 100644
index 0000000..c13e351
--- /dev/null
+++ b/src/detection/cpucache/cpucache_shared.c
@@ -0,0 +1,82 @@
+#include "cpucache.h"
+#include "common/smbios.h"
+#include "common/strutil.h"
+
+typedef struct FFSmbiosCacheInfo {
+ FFSmbiosHeader Header;
+
+ uint8_t SocketDesignation; // string
+ uint16_t CacheConfiguration; // varies
+ uint16_t MaximumCacheSize; // varies
+ uint16_t InstalledSize; // varies
+ uint16_t SupportedSramType; // bit field
+ uint16_t CurrentSramType; // bit field
+
+ // 2.1+
+ uint8_t CacheSpeed; // varies
+ uint8_t ErrorCorrectionType; // enum
+ uint8_t SystemCacheType; // enum
+ uint8_t Associativity; // enum
+
+ // 3.1+
+ uint32_t MaximumCacheSize2; // bit field
+ uint32_t InstalledCacheSize2; // bit field
+} FF_A_PACKED FFSmbiosCacheInfo;
+
+static_assert(offsetof(FFSmbiosCacheInfo, InstalledCacheSize2) == 0x17,
+ "FFSmbiosCacheInfo: Wrong struct alignment");
+
+const char* ffDetectCPUCache(FFCPUCacheResult* result) {
+ const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
+ if (!smbiosTable) {
+ return "Failed to get SMBIOS data";
+ }
+
+ const FFSmbiosCacheInfo* data = (const FFSmbiosCacheInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_CACHE_INFO];
+ if (!data) {
+ return "Cache information is not found in SMBIOS data";
+ }
+
+ const FFSmbiosCacheInfo* endOfTable = (const FFSmbiosCacheInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_END_OF_TABLE];
+ for (; data != endOfTable; data = (const FFSmbiosCacheInfo*) ffSmbiosNextEntry(&data->Header)) {
+ if (data->Header.Type != FF_SMBIOS_TYPE_CACHE_INFO) {
+ continue;
+ }
+
+ bool enabled = !!(data->CacheConfiguration & (1 << 7));
+ if (!enabled) {
+ continue;
+ }
+
+ uint32_t size = data->InstalledSize;
+ if (size == 0) {
+ continue;
+ }
+
+ if (data->InstalledSize != 0xFFFF) {
+ size *= (size >> 15 ? 64 : 1) * 1024u;
+ } else if (data->Header.Length > offsetof(FFSmbiosCacheInfo, InstalledCacheSize2)) {
+ size = data->InstalledCacheSize2;
+ size *= (size >> 31 ? 64 : 1) * 1024u;
+ }
+
+ uint32_t level = (data->CacheConfiguration & 0b111u) + 1;
+
+ FFCPUCacheType type;
+ switch (data->SystemCacheType) {
+ case 3:
+ type = FF_CPU_CACHE_TYPE_INSTRUCTION;
+ break;
+ case 4:
+ type = FF_CPU_CACHE_TYPE_DATA;
+ break;
+ default:
+ type = FF_CPU_CACHE_TYPE_UNIFIED;
+ break;
+ }
+
+ ffCPUCacheAddItem(result, level, size, 0, type);
+ }
+
+ return NULL;
+}