diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/aarch64/cpu-features.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/aarch64/cpu-features.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c index ef6eecd17e..47c7d97185 100644 --- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c +++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c @@ -20,18 +20,53 @@ #include <sys/auxv.h> #include <elf/dl-hwcaps.h> +#if HAVE_TUNABLES +struct cpu_list +{ + const char *name; + uint64_t midr; +}; + +static struct cpu_list cpu_list[] = { + {"thunderxt88", 0x430F0A10}, + {"generic", 0x0} +}; + +static uint64_t +get_midr_from_mcpu (const char *mcpu) +{ + for (int i = 0; i < sizeof (cpu_list) / sizeof (struct cpu_list); i++) + if (tunable_is_name (mcpu, cpu_list[i].name) == 0) + return cpu_list[i].midr; + + return UINT64_MAX; +} +#endif + static inline void init_cpu_features (struct cpu_features *cpu_features) { uint64_t hwcap_mask = GET_HWCAP_MASK(); uint64_t hwcap = GLRO (dl_hwcap) & hwcap_mask; - if (hwcap & HWCAP_CPUID) + register uint64_t midr = UINT64_MAX; + +#if HAVE_TUNABLES + /* Get the tunable override. */ + const char *mcpu = TUNABLE_GET (glibc, tune, mcpu, const char *, NULL); + if (mcpu != NULL) + midr = get_midr_from_mcpu (mcpu); +#endif + + /* If there was no useful tunable override, query the MIDR if the kernel + allows it. */ + if (midr == UINT64_MAX) { - register uint64_t id = 0; - asm volatile ("mrs %0, midr_el1" : "=r"(id)); - cpu_features->midr_el1 = id; + if (hwcap & HWCAP_CPUID) + asm volatile ("mrs %0, midr_el1" : "=r"(midr)); + else + midr = 0; } - else - cpu_features->midr_el1 = 0; + + cpu_features->midr_el1 = midr; } |