Advertisement
vtlmks

cpuid cache query 2

Jun 2nd, 2021 (edited)
306
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.74 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <stdint.h>
  4.  
  5. typedef uint8_t u8;
  6. typedef uint32_t u32;
  7. typedef uint64_t u64;
  8. typedef u32 b32;
  9.  
  10. typedef float r32;
  11.  
  12. struct cpuid_data {
  13.     u32 eax;
  14.     u32 ebx;
  15.     u32 ecx;
  16.     u32 edx;
  17. };
  18.  
  19. char *cache_types[] = {
  20.     "",
  21.     "Data",
  22.     "Instr",
  23.     "Shared",
  24. };
  25.  
  26.  
  27. #if 1
  28. #include <intrin.h>
  29.  
  30. struct cpuid_data get_cpuid(u32 leaf) {
  31.     struct cpuid_data result = {0};
  32.  
  33.     __cpuid((u32*)&result, leaf);
  34.  
  35.     return result;
  36. }
  37.  
  38. struct cpuid_data get_cpuid_count(u32 leaf, u32 count) {
  39.     struct cpuid_data result = {0};
  40.  
  41.     __cpuidex((u32*)&result, leaf, count);
  42.  
  43.     return result;
  44. }
  45.  
  46. #else
  47.  
  48. #include <cpuid.h>
  49. struct cpuid_data get_cpuid(u32 leaf) {
  50.     struct cpuid_data result = {0};
  51.  
  52.     __cpuid(leaf, result.eax, result.ebx, result.ecx, result.edx);
  53.  
  54.     return result;
  55. }
  56.  
  57. struct cpuid_data get_cpuid_count(u32 leaf, u32 count) {
  58.     struct cpuid_data result = {0};
  59.  
  60.     __cpuid_count(leaf, count, result.eax, result.ebx, result.ecx, result.edx);
  61.  
  62.     return result;
  63. }
  64.  
  65. #endif
  66.  
  67.  
  68.  
  69.  
  70. int main(int argc, char **argv) {
  71.     (void)argc;
  72.     (void)argv;
  73.  
  74.     struct cpuid_data maximum_supported = get_cpuid(0x0);
  75.  
  76.     if(maximum_supported.eax > 0x4) {
  77.         u32 index = 0;
  78.         while(1) {
  79.             struct cpuid_data cpuid_cache_configuration_04 = get_cpuid_count(0x4, index);
  80.  
  81.             // NOTE(peter): When cache type is zero we exit.
  82.             if((cpuid_cache_configuration_04.eax & 0x1f) == 0) {
  83.                 break;
  84.             }
  85.  
  86.             u32 max_cores_per_package = (cpuid_cache_configuration_04.eax >> 26) + 1;
  87.             u32 max_threads_per_cache = (cpuid_cache_configuration_04.eax >> 14 & 0xfff) + 1;
  88.             // note(peter): bits 13...10 reserved
  89.             u32 fully_associative     = cpuid_cache_configuration_04.eax >> 9 & 0x1;
  90.             u32 self_initializing     = cpuid_cache_configuration_04.eax >> 8 & 0x1;
  91.             u32 cache_level           = cpuid_cache_configuration_04.eax >> 5 & 0x7;
  92.             u32 cache_type            = cpuid_cache_configuration_04.eax & 0x1f;
  93.  
  94.             u32 ways_of_associativity      = (cpuid_cache_configuration_04.ebx >> 22) + 1;
  95.             u32 physical_line_partitions   = (cpuid_cache_configuration_04.ebx >> 12 & 0x3ff) + 1;
  96.             u32 system_coherency_line_size = (cpuid_cache_configuration_04.ebx  & 0xfff) + 1;
  97.  
  98.             u32 sets = (cpuid_cache_configuration_04.ecx) + 1;
  99.  
  100.             u32 complex_cache_indexing = (cpuid_cache_configuration_04.edx >> 2) & 0x1;
  101.             u32 cache_inclusiveness    = (cpuid_cache_configuration_04.edx >> 1) & 0x1;
  102.             u32 write_back_invalidate  = (cpuid_cache_configuration_04.edx) & 0x1;
  103.  
  104.             u64 cache_size_ = ways_of_associativity * physical_line_partitions * system_coherency_line_size * sets;
  105.             b32 cache_size_kb = (cache_size_ < (1024*1024));
  106.             r32 cache_size = (cache_size_kb) ? cache_size_ / 1024.f : (cache_size_ / (1024.f*1024.f));
  107.  
  108.             printf("Cache index: %d\n", index);
  109.             printf("  Package max cores: %d\n", max_cores_per_package);
  110.             printf("  Cache max threads: %d\n", max_threads_per_cache);
  111.             printf("  Self initializing: %d\n", self_initializing);
  112.             printf("  %s\n", fully_associative ? "Fully associative" : "Not fully associative");
  113.             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);
  114.             printf("  Physical line partitions: %d\n", physical_line_partitions);
  115.             printf("  System coherency line size: %d\n", system_coherency_line_size);
  116.             printf("  Sets: %d\n", sets);
  117.             printf("  Cache indexing: %s\n", complex_cache_indexing ? "A complex function is used to index the cache, potentially using all address bits." : "Direct mapped");
  118.             printf("  Inclusive to lower caches: %s\n", cache_inclusiveness ? "True" : "False");
  119.             printf("  WBINVD/INVD on lower caches: %s\n", write_back_invalidate ? "True" : "False");
  120.             printf("\n");
  121.             index++;
  122.         }
  123.     }
  124.  
  125.     return 0;
  126. }
  127.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement