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