cache_shape.c 2.3 KB

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