122 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*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_CACHESIZE21#define AT_L1I_CACHESIZE 4022#define AT_L1I_CACHEGEOMETRY 4123#define AT_L1D_CACHESIZE 4224#define AT_L1D_CACHEGEOMETRY 4325#define AT_L2_CACHESIZE 4426#define AT_L2_CACHEGEOMETRY 4527#define AT_L3_CACHESIZE 4628#define AT_L3_CACHEGEOMETRY 4729#endif30 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 else46 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