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