ecag.c revision 436e89c602e787e7a27dd6624b09beed41a0da8a
1#include <stdio.h>
2#include <assert.h>
3#include <stdint.h>
4#include <inttypes.h>
5#include "opcodes.h"
6
7uint64_t
8ecag(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
18static unsigned
19get_level_info(uint64_t topology, unsigned level)
20{
21   return (topology >> (56 - level * 8)) & 0xff;
22}
23
24int
25main(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