cache_shape.c 2.5 KB

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