Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdint.h>
- typedef uint8_t u8;
- typedef uint32_t u32;
- typedef uint64_t u64;
- typedef u32 b32;
- typedef float r32;
- struct cpuid_data {
- u32 eax;
- u32 ebx;
- u32 ecx;
- u32 edx;
- };
- char *cache_types[] = {
- "",
- "Data",
- "Instr",
- "Shared",
- };
- #if 1
- #include <intrin.h>
- struct cpuid_data get_cpuid(u32 leaf) {
- struct cpuid_data result = {0};
- __cpuid((u32*)&result, leaf);
- return result;
- }
- struct cpuid_data get_cpuid_count(u32 leaf, u32 count) {
- struct cpuid_data result = {0};
- __cpuidex((u32*)&result, leaf, count);
- return result;
- }
- #else
- #include <cpuid.h>
- struct cpuid_data get_cpuid(u32 leaf) {
- struct cpuid_data result = {0};
- __cpuid(leaf, result.eax, result.ebx, result.ecx, result.edx);
- return result;
- }
- struct cpuid_data get_cpuid_count(u32 leaf, u32 count) {
- struct cpuid_data result = {0};
- __cpuid_count(leaf, count, result.eax, result.ebx, result.ecx, result.edx);
- return result;
- }
- #endif
- int main(int argc, char **argv) {
- (void)argc;
- (void)argv;
- struct cpuid_data maximum_supported = get_cpuid(0x0);
- if(maximum_supported.eax > 0x4) {
- u32 index = 0;
- while(1) {
- struct cpuid_data cpuid_cache_configuration_04 = get_cpuid_count(0x4, index);
- // NOTE(peter): When cache type is zero we exit.
- if((cpuid_cache_configuration_04.eax & 0x1f) == 0) {
- break;
- }
- u32 max_cores_per_package = (cpuid_cache_configuration_04.eax >> 26) + 1;
- u32 max_threads_per_cache = (cpuid_cache_configuration_04.eax >> 14 & 0xfff) + 1;
- // note(peter): bits 13...10 reserved
- u32 fully_associative = cpuid_cache_configuration_04.eax >> 9 & 0x1;
- u32 self_initializing = cpuid_cache_configuration_04.eax >> 8 & 0x1;
- u32 cache_level = cpuid_cache_configuration_04.eax >> 5 & 0x7;
- u32 cache_type = cpuid_cache_configuration_04.eax & 0x1f;
- u32 ways_of_associativity = (cpuid_cache_configuration_04.ebx >> 22) + 1;
- u32 physical_line_partitions = (cpuid_cache_configuration_04.ebx >> 12 & 0x3ff) + 1;
- u32 system_coherency_line_size = (cpuid_cache_configuration_04.ebx & 0xfff) + 1;
- u32 sets = (cpuid_cache_configuration_04.ecx) + 1;
- u32 complex_cache_indexing = (cpuid_cache_configuration_04.edx >> 2) & 0x1;
- u32 cache_inclusiveness = (cpuid_cache_configuration_04.edx >> 1) & 0x1;
- u32 write_back_invalidate = (cpuid_cache_configuration_04.edx) & 0x1;
- u64 cache_size_ = ways_of_associativity * physical_line_partitions * system_coherency_line_size * sets;
- b32 cache_size_kb = (cache_size_ < (1024*1024));
- r32 cache_size = (cache_size_kb) ? cache_size_ / 1024.f : (cache_size_ / (1024.f*1024.f));
- printf("Cache index: %d\n", index);
- printf(" Package max cores: %d\n", max_cores_per_package);
- printf(" Cache max threads: %d\n", max_threads_per_cache);
- printf(" Self initializing: %d\n", self_initializing);
- printf(" %s\n", fully_associative ? "Fully associative" : "Not fully associative");
- printf(" Cache: L%d %s (%.2f %s) %d-way set associative\n", cache_level, cache_types[cache_type], cache_size, cache_size_kb ? "KB" : "MB", ways_of_associativity);
- printf(" Physical line partitions: %d\n", physical_line_partitions);
- printf(" System coherency line size: %d\n", system_coherency_line_size);
- printf(" Sets: %d\n", sets);
- printf(" Cache indexing: %s\n", complex_cache_indexing ? "A complex function is used to index the cache, potentially using all address bits." : "Direct mapped");
- printf(" Inclusive to lower caches: %s\n", cache_inclusiveness ? "True" : "False");
- printf(" WBINVD/INVD on lower caches: %s\n", write_back_invalidate ? "True" : "False");
- printf("\n");
- index++;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement