| #include <stdio.h> |
| #include <assert.h> |
| #include <stdint.h> |
| #include <inttypes.h> |
| #include "opcodes.h" |
| |
| uint64_t |
| ecag(int ai, int li, int ti) |
| { |
| register uint64_t result asm("2") = 0; |
| register uint64_t input asm("3") = (ai << 4) | (li << 1) | ti; |
| |
| asm volatile( ECAG(2,0,3,000,00) |
| : "=d" (result) : "d" (input)); |
| return result; |
| } |
| |
| static unsigned |
| get_level_info(uint64_t topology, unsigned level) |
| { |
| return (topology >> (56 - level * 8)) & 0xff; |
| } |
| |
| int |
| main(void) |
| { |
| unsigned level; |
| uint64_t topology; |
| |
| topology = ecag(0, 0, 0); // get summary |
| |
| /* ECAG supports at most 8 levels of cache. Iterate over all of them |
| ignoring those not present. */ |
| for (level = 0; level < 8; level++) { |
| unsigned info = get_level_info(topology, level); |
| |
| if ((info & 0xc) == 0) continue; // cache does not exist at this level |
| |
| unsigned cache_type = info & 0x3; |
| unsigned cache_scope = (info & 0xc) >> 2; |
| char *type, *scope; |
| |
| switch (cache_type) { |
| case 0: type = "separate data and instruction"; break; |
| case 1: type = "instruction"; break; |
| case 2: type = "data"; break; |
| case 3: type = "unified data and instruction"; break; |
| } |
| |
| switch (cache_scope) { |
| case 0: assert(0); // should never occur because cache exists |
| case 1: scope = "private"; break; |
| case 2: scope = "shared"; break; |
| case 3: scope = "reserved"; break; |
| } |
| |
| printf("L%u topology: %s; %s\n", level+1, type, scope); |
| printf("L%u cache line size data: %"PRId64"\n", level+1, |
| ecag(1, level, 0)); |
| printf("L%u cache line size insn: %"PRId64"\n", level+1, |
| ecag(1, level, 1)); |
| printf("L%u total cachesize data: %"PRId64"\n", level+1, |
| ecag(2, level, 0)); |
| printf("L%u total cachesize insn: %"PRId64"\n", level+1, |
| ecag(2, level, 1)); |
| printf("L%u set. assoc. data: %"PRId64"\n", level+1, |
| ecag(3, level, 0)); |
| printf("L%u set. assoc. insn: %"PRId64"\n", level+1, |
| ecag(3, level, 1)); |
| } |
| |
| return 0; |
| } |