xref: /openbmc/linux/tools/testing/selftests/powerpc/cache_shape/cache_shape.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
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