cpu-features.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /* Initialize CPU feature data. AArch64 version.
  2. This file is part of the GNU C Library.
  3. Copyright (C) 2017-2019 Free Software Foundation, Inc.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <cpu-features.h>
  16. #include <sys/auxv.h>
  17. #include <elf/dl-hwcaps.h>
  18. #define DCZID_DZP_MASK (1 << 4)
  19. #define DCZID_BS_MASK (0xf)
  20. #if HAVE_TUNABLES
  21. struct cpu_list
  22. {
  23. const char *name;
  24. uint64_t midr;
  25. };
  26. static struct cpu_list cpu_list[] = {
  27. {"falkor", 0x510FC000},
  28. {"thunderxt88", 0x430F0A10},
  29. {"thunderx2t99", 0x431F0AF0},
  30. {"thunderx2t99p1", 0x420F5160},
  31. {"phecda", 0x680F0000},
  32. {"ares", 0x411FD0C0},
  33. {"generic", 0x0}
  34. };
  35. static uint64_t
  36. get_midr_from_mcpu (const char *mcpu)
  37. {
  38. for (int i = 0; i < sizeof (cpu_list) / sizeof (struct cpu_list); i++)
  39. if (strcmp (mcpu, cpu_list[i].name) == 0)
  40. return cpu_list[i].midr;
  41. return UINT64_MAX;
  42. }
  43. #endif
  44. static inline void
  45. init_cpu_features (struct cpu_features *cpu_features)
  46. {
  47. register uint64_t midr = UINT64_MAX;
  48. #if HAVE_TUNABLES
  49. /* Get the tunable override. */
  50. const char *mcpu = TUNABLE_GET (glibc, cpu, name, const char *, NULL);
  51. if (mcpu != NULL)
  52. midr = get_midr_from_mcpu (mcpu);
  53. #endif
  54. /* If there was no useful tunable override, query the MIDR if the kernel
  55. allows it. */
  56. if (midr == UINT64_MAX)
  57. {
  58. if (GLRO (dl_hwcap) & HWCAP_CPUID)
  59. asm volatile ("mrs %0, midr_el1" : "=r"(midr));
  60. else
  61. midr = 0;
  62. }
  63. cpu_features->midr_el1 = midr;
  64. /* Check if ZVA is enabled. */
  65. unsigned dczid;
  66. asm volatile ("mrs %0, dczid_el0" : "=r"(dczid));
  67. if ((dczid & DCZID_DZP_MASK) == 0)
  68. cpu_features->zva_size = 4 << (dczid & DCZID_BS_MASK);
  69. }