Home | History | Annotate | Download | only in s390x
      1 #include <stdio.h>
      2 #include <assert.h>
      3 #include <stdint.h>
      4 #include <inttypes.h>
      5 #include "opcodes.h"
      6 
      7 uint64_t
      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
     19 get_level_info(uint64_t topology, unsigned level)
     20 {
     21    return (topology >> (56 - level * 8)) & 0xff;
     22 }
     23 
     24 int
     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