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