1 #include <stdio.h>
2 #include <assert.h>
3 #include <stdint.h>
4 #include <inttypes.h>
5 #include "opcodes.h"
6
7 uint64_t
ecag(int ai,int li,int ti)8 ecag(int ai, int li, int ti)
9 {
10 register uint64_t result asm("2") = 0;
11 register uint64_t input asm("3") = (ai << 4) | (li << 1) | ti;
12
13 asm volatile( ECAG(2,0,3,000,00)
14 : "=d" (result) : "d" (input));
15 return result;
16 }
17
18 static unsigned
get_level_info(uint64_t topology,unsigned level)19 get_level_info(uint64_t topology, unsigned level)
20 {
21 return (topology >> (56 - level * 8)) & 0xff;
22 }
23
24 int
main(void)25 main(void)
26 {
27 unsigned level;
28 uint64_t topology;
29
30 topology = ecag(0, 0, 0); // get summary
31
32 /* ECAG supports at most 8 levels of cache. Iterate over all of them
33 ignoring those not present. */
34 for (level = 0; level < 8; level++) {
35 unsigned info = get_level_info(topology, level);
36
37 if ((info & 0xc) == 0) continue; // cache does not exist at this level
38
39 unsigned cache_type = info & 0x3;
40 unsigned cache_scope = (info & 0xc) >> 2;
41 char *type, *scope;
42
43 switch (cache_type) {
44 case 0: type = "separate data and instruction"; break;
45 case 1: type = "instruction"; break;
46 case 2: type = "data"; break;
47 case 3: type = "unified data and instruction"; break;
48 }
49
50 switch (cache_scope) {
51 case 0: assert(0); // should never occur because cache exists
52 case 1: scope = "private"; break;
53 case 2: scope = "shared"; break;
54 case 3: scope = "reserved"; break;
55 }
56
57 printf("L%u topology: %s; %s\n", level+1, type, scope);
58 printf("L%u cache line size data: %"PRId64"\n", level+1,
59 ecag(1, level, 0));
60 printf("L%u cache line size insn: %"PRId64"\n", level+1,
61 ecag(1, level, 1));
62 printf("L%u total cachesize data: %"PRId64"\n", level+1,
63 ecag(2, level, 0));
64 printf("L%u total cachesize insn: %"PRId64"\n", level+1,
65 ecag(2, level, 1));
66 printf("L%u set. assoc. data: %"PRId64"\n", level+1,
67 ecag(3, level, 0));
68 printf("L%u set. assoc. insn: %"PRId64"\n", level+1,
69 ecag(3, level, 1));
70 }
71
72 return 0;
73 }
74