linux/tools/testing/selftests/powerpc/cache_shape/cache_shape.c
<<
>>
Prefs
   1/*
   2 * Copyright 2017, Michael Ellerman, IBM Corp.
   3 *
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU General Public License
   6 * as published by the Free Software Foundation; either version
   7 * 2 of the License, or (at your option) any later version.
   8 */
   9
  10#include <elf.h>
  11#include <errno.h>
  12#include <fcntl.h>
  13#include <link.h>
  14#include <stdio.h>
  15#include <stdlib.h>
  16#include <string.h>
  17#include <sys/stat.h>
  18#include <sys/types.h>
  19#include <sys/wait.h>
  20#include <unistd.h>
  21
  22#include "utils.h"
  23
  24#ifndef AT_L1I_CACHESIZE
  25#define AT_L1I_CACHESIZE        40
  26#define AT_L1I_CACHEGEOMETRY    41
  27#define AT_L1D_CACHESIZE        42
  28#define AT_L1D_CACHEGEOMETRY    43
  29#define AT_L2_CACHESIZE         44
  30#define AT_L2_CACHEGEOMETRY     45
  31#define AT_L3_CACHESIZE         46
  32#define AT_L3_CACHEGEOMETRY     47
  33#endif
  34
  35static void print_size(const char *label, uint32_t val)
  36{
  37        printf("%s cache size: %#10x %10dB %10dK\n", label, val, val, val / 1024);
  38}
  39
  40static void print_geo(const char *label, uint32_t val)
  41{
  42        uint16_t assoc;
  43
  44        printf("%s line size:  %#10x       ", label, val & 0xFFFF);
  45
  46        assoc = val >> 16;
  47        if (assoc)
  48                printf("%u-way", assoc);
  49        else
  50                printf("fully");
  51
  52        printf(" associative\n");
  53}
  54
  55static int test_cache_shape()
  56{
  57        static char buffer[4096];
  58        ElfW(auxv_t) *p;
  59        int found;
  60
  61        FAIL_IF(read_auxv(buffer, sizeof(buffer)));
  62
  63        found = 0;
  64
  65        p = find_auxv_entry(AT_L1I_CACHESIZE, buffer);
  66        if (p) {
  67                found++;
  68                print_size("L1I ", (uint32_t)p->a_un.a_val);
  69        }
  70
  71        p = find_auxv_entry(AT_L1I_CACHEGEOMETRY, buffer);
  72        if (p) {
  73                found++;
  74                print_geo("L1I ", (uint32_t)p->a_un.a_val);
  75        }
  76
  77        p = find_auxv_entry(AT_L1D_CACHESIZE, buffer);
  78        if (p) {
  79                found++;
  80                print_size("L1D ", (uint32_t)p->a_un.a_val);
  81        }
  82
  83        p = find_auxv_entry(AT_L1D_CACHEGEOMETRY, buffer);
  84        if (p) {
  85                found++;
  86                print_geo("L1D ", (uint32_t)p->a_un.a_val);
  87        }
  88
  89        p = find_auxv_entry(AT_L2_CACHESIZE, buffer);
  90        if (p) {
  91                found++;
  92                print_size("L2  ", (uint32_t)p->a_un.a_val);
  93        }
  94
  95        p = find_auxv_entry(AT_L2_CACHEGEOMETRY, buffer);
  96        if (p) {
  97                found++;
  98                print_geo("L2  ", (uint32_t)p->a_un.a_val);
  99        }
 100
 101        p = find_auxv_entry(AT_L3_CACHESIZE, buffer);
 102        if (p) {
 103                found++;
 104                print_size("L3  ", (uint32_t)p->a_un.a_val);
 105        }
 106
 107        p = find_auxv_entry(AT_L3_CACHEGEOMETRY, buffer);
 108        if (p) {
 109                found++;
 110                print_geo("L3  ", (uint32_t)p->a_un.a_val);
 111        }
 112
 113        /* If we found none we're probably on a system where they don't exist */
 114        SKIP_IF(found == 0);
 115
 116        /* But if we found any, we expect to find them all */
 117        FAIL_IF(found != 8);
 118
 119        return 0;
 120}
 121
 122int main(void)
 123{
 124        return test_harness(test_cache_shape, "cache_shape");
 125}
 126