14d14968f6d322633d3977e76981a337983cc66e3florian#include <stdio.h> 24d14968f6d322633d3977e76981a337983cc66e3florian#include <assert.h> 34d14968f6d322633d3977e76981a337983cc66e3florian#include <stdint.h> 44d14968f6d322633d3977e76981a337983cc66e3florian#include <inttypes.h> 54d14968f6d322633d3977e76981a337983cc66e3florian#include "opcodes.h" 64d14968f6d322633d3977e76981a337983cc66e3florian 74d14968f6d322633d3977e76981a337983cc66e3florianuint64_t 84d14968f6d322633d3977e76981a337983cc66e3florianecag(int ai, int li, int ti) 94d14968f6d322633d3977e76981a337983cc66e3florian{ 104d14968f6d322633d3977e76981a337983cc66e3florian register uint64_t result asm("2") = 0; 114d14968f6d322633d3977e76981a337983cc66e3florian register uint64_t input asm("3") = (ai << 4) | (li << 1) | ti; 124d14968f6d322633d3977e76981a337983cc66e3florian 134d14968f6d322633d3977e76981a337983cc66e3florian asm volatile( ECAG(2,0,3,000,00) 144d14968f6d322633d3977e76981a337983cc66e3florian : "=d" (result) : "d" (input)); 154d14968f6d322633d3977e76981a337983cc66e3florian return result; 164d14968f6d322633d3977e76981a337983cc66e3florian} 174d14968f6d322633d3977e76981a337983cc66e3florian 184d14968f6d322633d3977e76981a337983cc66e3florianstatic unsigned 194d14968f6d322633d3977e76981a337983cc66e3florianget_level_info(uint64_t topology, unsigned level) 204d14968f6d322633d3977e76981a337983cc66e3florian{ 214d14968f6d322633d3977e76981a337983cc66e3florian return (topology >> (56 - level * 8)) & 0xff; 224d14968f6d322633d3977e76981a337983cc66e3florian} 234d14968f6d322633d3977e76981a337983cc66e3florian 244d14968f6d322633d3977e76981a337983cc66e3florianint 254d14968f6d322633d3977e76981a337983cc66e3florianmain(void) 264d14968f6d322633d3977e76981a337983cc66e3florian{ 274d14968f6d322633d3977e76981a337983cc66e3florian unsigned level; 284d14968f6d322633d3977e76981a337983cc66e3florian uint64_t topology; 294d14968f6d322633d3977e76981a337983cc66e3florian 304d14968f6d322633d3977e76981a337983cc66e3florian topology = ecag(0, 0, 0); // get summary 314d14968f6d322633d3977e76981a337983cc66e3florian 324d14968f6d322633d3977e76981a337983cc66e3florian /* ECAG supports at most 8 levels of cache. Iterate over all of them 334d14968f6d322633d3977e76981a337983cc66e3florian ignoring those not present. */ 344d14968f6d322633d3977e76981a337983cc66e3florian for (level = 0; level < 8; level++) { 354d14968f6d322633d3977e76981a337983cc66e3florian unsigned info = get_level_info(topology, level); 364d14968f6d322633d3977e76981a337983cc66e3florian 374d14968f6d322633d3977e76981a337983cc66e3florian if ((info & 0xc) == 0) continue; // cache does not exist at this level 384d14968f6d322633d3977e76981a337983cc66e3florian 394d14968f6d322633d3977e76981a337983cc66e3florian unsigned cache_type = info & 0x3; 404d14968f6d322633d3977e76981a337983cc66e3florian unsigned cache_scope = (info & 0xc) >> 2; 414d14968f6d322633d3977e76981a337983cc66e3florian char *type, *scope; 424d14968f6d322633d3977e76981a337983cc66e3florian 434d14968f6d322633d3977e76981a337983cc66e3florian switch (cache_type) { 444d14968f6d322633d3977e76981a337983cc66e3florian case 0: type = "separate data and instruction"; break; 454d14968f6d322633d3977e76981a337983cc66e3florian case 1: type = "instruction"; break; 464d14968f6d322633d3977e76981a337983cc66e3florian case 2: type = "data"; break; 474d14968f6d322633d3977e76981a337983cc66e3florian case 3: type = "unified data and instruction"; break; 484d14968f6d322633d3977e76981a337983cc66e3florian } 494d14968f6d322633d3977e76981a337983cc66e3florian 504d14968f6d322633d3977e76981a337983cc66e3florian switch (cache_scope) { 514d14968f6d322633d3977e76981a337983cc66e3florian case 0: assert(0); // should never occur because cache exists 524d14968f6d322633d3977e76981a337983cc66e3florian case 1: scope = "private"; break; 534d14968f6d322633d3977e76981a337983cc66e3florian case 2: scope = "shared"; break; 544d14968f6d322633d3977e76981a337983cc66e3florian case 3: scope = "reserved"; break; 554d14968f6d322633d3977e76981a337983cc66e3florian } 564d14968f6d322633d3977e76981a337983cc66e3florian 574d14968f6d322633d3977e76981a337983cc66e3florian printf("L%u topology: %s; %s\n", level+1, type, scope); 584d14968f6d322633d3977e76981a337983cc66e3florian printf("L%u cache line size data: %"PRId64"\n", level+1, 594d14968f6d322633d3977e76981a337983cc66e3florian ecag(1, level, 0)); 604d14968f6d322633d3977e76981a337983cc66e3florian printf("L%u cache line size insn: %"PRId64"\n", level+1, 614d14968f6d322633d3977e76981a337983cc66e3florian ecag(1, level, 1)); 624d14968f6d322633d3977e76981a337983cc66e3florian printf("L%u total cachesize data: %"PRId64"\n", level+1, 634d14968f6d322633d3977e76981a337983cc66e3florian ecag(2, level, 0)); 644d14968f6d322633d3977e76981a337983cc66e3florian printf("L%u total cachesize insn: %"PRId64"\n", level+1, 654d14968f6d322633d3977e76981a337983cc66e3florian ecag(2, level, 1)); 664d14968f6d322633d3977e76981a337983cc66e3florian printf("L%u set. assoc. data: %"PRId64"\n", level+1, 674d14968f6d322633d3977e76981a337983cc66e3florian ecag(3, level, 0)); 684d14968f6d322633d3977e76981a337983cc66e3florian printf("L%u set. assoc. insn: %"PRId64"\n", level+1, 694d14968f6d322633d3977e76981a337983cc66e3florian ecag(3, level, 1)); 704d14968f6d322633d3977e76981a337983cc66e3florian } 714d14968f6d322633d3977e76981a337983cc66e3florian 724d14968f6d322633d3977e76981a337983cc66e3florian return 0; 734d14968f6d322633d3977e76981a337983cc66e3florian} 74