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