cache_shape.c (2380B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright 2017, Michael Ellerman, IBM Corp. 4 */ 5 6#include <elf.h> 7#include <errno.h> 8#include <fcntl.h> 9#include <link.h> 10#include <stdio.h> 11#include <stdlib.h> 12#include <string.h> 13#include <sys/stat.h> 14#include <sys/types.h> 15#include <sys/wait.h> 16#include <unistd.h> 17 18#include "utils.h" 19 20#ifndef AT_L1I_CACHESIZE 21#define AT_L1I_CACHESIZE 40 22#define AT_L1I_CACHEGEOMETRY 41 23#define AT_L1D_CACHESIZE 42 24#define AT_L1D_CACHEGEOMETRY 43 25#define AT_L2_CACHESIZE 44 26#define AT_L2_CACHEGEOMETRY 45 27#define AT_L3_CACHESIZE 46 28#define AT_L3_CACHEGEOMETRY 47 29#endif 30 31static void print_size(const char *label, uint32_t val) 32{ 33 printf("%s cache size: %#10x %10dB %10dK\n", label, val, val, val / 1024); 34} 35 36static void print_geo(const char *label, uint32_t val) 37{ 38 uint16_t assoc; 39 40 printf("%s line size: %#10x ", label, val & 0xFFFF); 41 42 assoc = val >> 16; 43 if (assoc) 44 printf("%u-way", assoc); 45 else 46 printf("fully"); 47 48 printf(" associative\n"); 49} 50 51static int test_cache_shape() 52{ 53 static char buffer[4096]; 54 ElfW(auxv_t) *p; 55 int found; 56 57 FAIL_IF(read_auxv(buffer, sizeof(buffer))); 58 59 found = 0; 60 61 p = find_auxv_entry(AT_L1I_CACHESIZE, buffer); 62 if (p) { 63 found++; 64 print_size("L1I ", (uint32_t)p->a_un.a_val); 65 } 66 67 p = find_auxv_entry(AT_L1I_CACHEGEOMETRY, buffer); 68 if (p) { 69 found++; 70 print_geo("L1I ", (uint32_t)p->a_un.a_val); 71 } 72 73 p = find_auxv_entry(AT_L1D_CACHESIZE, buffer); 74 if (p) { 75 found++; 76 print_size("L1D ", (uint32_t)p->a_un.a_val); 77 } 78 79 p = find_auxv_entry(AT_L1D_CACHEGEOMETRY, buffer); 80 if (p) { 81 found++; 82 print_geo("L1D ", (uint32_t)p->a_un.a_val); 83 } 84 85 p = find_auxv_entry(AT_L2_CACHESIZE, buffer); 86 if (p) { 87 found++; 88 print_size("L2 ", (uint32_t)p->a_un.a_val); 89 } 90 91 p = find_auxv_entry(AT_L2_CACHEGEOMETRY, buffer); 92 if (p) { 93 found++; 94 print_geo("L2 ", (uint32_t)p->a_un.a_val); 95 } 96 97 p = find_auxv_entry(AT_L3_CACHESIZE, buffer); 98 if (p) { 99 found++; 100 print_size("L3 ", (uint32_t)p->a_un.a_val); 101 } 102 103 p = find_auxv_entry(AT_L3_CACHEGEOMETRY, buffer); 104 if (p) { 105 found++; 106 print_geo("L3 ", (uint32_t)p->a_un.a_val); 107 } 108 109 /* If we found none we're probably on a system where they don't exist */ 110 SKIP_IF(found == 0); 111 112 /* But if we found any, we expect to find them all */ 113 FAIL_IF(found != 8); 114 115 return 0; 116} 117 118int main(void) 119{ 120 return test_harness(test_cache_shape, "cache_shape"); 121}