199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright (C) Cavium, Inc. 2015. 399a2dd95SBruce Richardson * Copyright(c) 2015 RehiveTech. All rights reserved. 499a2dd95SBruce Richardson */ 599a2dd95SBruce Richardson 699a2dd95SBruce Richardson #include "rte_cpuflags.h" 799a2dd95SBruce Richardson 899a2dd95SBruce Richardson #include <elf.h> 999a2dd95SBruce Richardson #include <fcntl.h> 1099a2dd95SBruce Richardson #include <assert.h> 1199a2dd95SBruce Richardson #include <unistd.h> 1299a2dd95SBruce Richardson #include <string.h> 1399a2dd95SBruce Richardson 1499a2dd95SBruce Richardson #ifndef AT_HWCAP 1599a2dd95SBruce Richardson #define AT_HWCAP 16 1699a2dd95SBruce Richardson #endif 1799a2dd95SBruce Richardson 1899a2dd95SBruce Richardson #ifndef AT_HWCAP2 1999a2dd95SBruce Richardson #define AT_HWCAP2 26 2099a2dd95SBruce Richardson #endif 2199a2dd95SBruce Richardson 2299a2dd95SBruce Richardson #ifndef AT_PLATFORM 2399a2dd95SBruce Richardson #define AT_PLATFORM 15 2499a2dd95SBruce Richardson #endif 2599a2dd95SBruce Richardson 2699a2dd95SBruce Richardson enum cpu_register_t { 2799a2dd95SBruce Richardson REG_NONE = 0, 2899a2dd95SBruce Richardson REG_HWCAP, 2999a2dd95SBruce Richardson REG_HWCAP2, 3099a2dd95SBruce Richardson REG_PLATFORM, 3199a2dd95SBruce Richardson REG_MAX 3299a2dd95SBruce Richardson }; 3399a2dd95SBruce Richardson 3499a2dd95SBruce Richardson typedef uint32_t hwcap_registers_t[REG_MAX]; 3599a2dd95SBruce Richardson 3699a2dd95SBruce Richardson /** 3799a2dd95SBruce Richardson * Struct to hold a processor feature entry 3899a2dd95SBruce Richardson */ 3999a2dd95SBruce Richardson struct feature_entry { 4099a2dd95SBruce Richardson uint32_t reg; 4199a2dd95SBruce Richardson uint32_t bit; 4299a2dd95SBruce Richardson #define CPU_FLAG_NAME_MAX_LEN 64 4399a2dd95SBruce Richardson char name[CPU_FLAG_NAME_MAX_LEN]; 4499a2dd95SBruce Richardson }; 4599a2dd95SBruce Richardson 4699a2dd95SBruce Richardson #define FEAT_DEF(name, reg, bit) \ 4799a2dd95SBruce Richardson [RTE_CPUFLAG_##name] = {reg, bit, #name}, 4899a2dd95SBruce Richardson 49845048c5SJuraj Linkeš #ifdef RTE_ARCH_32 5099a2dd95SBruce Richardson #ifdef RTE_ARCH_ARMv7 5199a2dd95SBruce Richardson #define PLATFORM_STR "v7l" 52845048c5SJuraj Linkeš #elif defined RTE_ARCH_ARMv8_AARCH32 53845048c5SJuraj Linkeš #define PLATFORM_STR "v8l" 54845048c5SJuraj Linkeš #endif 55845048c5SJuraj Linkeš typedef Elf32_auxv_t _Elfx_auxv_t; 5699a2dd95SBruce Richardson 5799a2dd95SBruce Richardson const struct feature_entry rte_cpu_feature_table[] = { 5899a2dd95SBruce Richardson FEAT_DEF(SWP, REG_HWCAP, 0) 5999a2dd95SBruce Richardson FEAT_DEF(HALF, REG_HWCAP, 1) 6099a2dd95SBruce Richardson FEAT_DEF(THUMB, REG_HWCAP, 2) 6199a2dd95SBruce Richardson FEAT_DEF(A26BIT, REG_HWCAP, 3) 6299a2dd95SBruce Richardson FEAT_DEF(FAST_MULT, REG_HWCAP, 4) 6399a2dd95SBruce Richardson FEAT_DEF(FPA, REG_HWCAP, 5) 6499a2dd95SBruce Richardson FEAT_DEF(VFP, REG_HWCAP, 6) 6599a2dd95SBruce Richardson FEAT_DEF(EDSP, REG_HWCAP, 7) 6699a2dd95SBruce Richardson FEAT_DEF(JAVA, REG_HWCAP, 8) 6799a2dd95SBruce Richardson FEAT_DEF(IWMMXT, REG_HWCAP, 9) 6899a2dd95SBruce Richardson FEAT_DEF(CRUNCH, REG_HWCAP, 10) 6999a2dd95SBruce Richardson FEAT_DEF(THUMBEE, REG_HWCAP, 11) 7099a2dd95SBruce Richardson FEAT_DEF(NEON, REG_HWCAP, 12) 7199a2dd95SBruce Richardson FEAT_DEF(VFPv3, REG_HWCAP, 13) 7299a2dd95SBruce Richardson FEAT_DEF(VFPv3D16, REG_HWCAP, 14) 7399a2dd95SBruce Richardson FEAT_DEF(TLS, REG_HWCAP, 15) 7499a2dd95SBruce Richardson FEAT_DEF(VFPv4, REG_HWCAP, 16) 7599a2dd95SBruce Richardson FEAT_DEF(IDIVA, REG_HWCAP, 17) 7699a2dd95SBruce Richardson FEAT_DEF(IDIVT, REG_HWCAP, 18) 7799a2dd95SBruce Richardson FEAT_DEF(VFPD32, REG_HWCAP, 19) 7899a2dd95SBruce Richardson FEAT_DEF(LPAE, REG_HWCAP, 20) 7999a2dd95SBruce Richardson FEAT_DEF(EVTSTRM, REG_HWCAP, 21) 8099a2dd95SBruce Richardson FEAT_DEF(AES, REG_HWCAP2, 0) 8199a2dd95SBruce Richardson FEAT_DEF(PMULL, REG_HWCAP2, 1) 8299a2dd95SBruce Richardson FEAT_DEF(SHA1, REG_HWCAP2, 2) 8399a2dd95SBruce Richardson FEAT_DEF(SHA2, REG_HWCAP2, 3) 8499a2dd95SBruce Richardson FEAT_DEF(CRC32, REG_HWCAP2, 4) 85845048c5SJuraj Linkeš #ifdef RTE_ARCH_ARMv7 8699a2dd95SBruce Richardson FEAT_DEF(V7L, REG_PLATFORM, 0) 87845048c5SJuraj Linkeš #elif defined RTE_ARCH_ARMv8_AARCH32 88845048c5SJuraj Linkeš FEAT_DEF(V8L, REG_PLATFORM, 0) 89845048c5SJuraj Linkeš #endif 9099a2dd95SBruce Richardson }; 9199a2dd95SBruce Richardson 92845048c5SJuraj Linkeš #elif defined RTE_ARCH_64 9399a2dd95SBruce Richardson #define PLATFORM_STR "aarch64" 9499a2dd95SBruce Richardson 9599a2dd95SBruce Richardson const struct feature_entry rte_cpu_feature_table[] = { 9699a2dd95SBruce Richardson FEAT_DEF(FP, REG_HWCAP, 0) 9799a2dd95SBruce Richardson FEAT_DEF(NEON, REG_HWCAP, 1) 9899a2dd95SBruce Richardson FEAT_DEF(EVTSTRM, REG_HWCAP, 2) 9999a2dd95SBruce Richardson FEAT_DEF(AES, REG_HWCAP, 3) 10099a2dd95SBruce Richardson FEAT_DEF(PMULL, REG_HWCAP, 4) 10199a2dd95SBruce Richardson FEAT_DEF(SHA1, REG_HWCAP, 5) 10299a2dd95SBruce Richardson FEAT_DEF(SHA2, REG_HWCAP, 6) 10399a2dd95SBruce Richardson FEAT_DEF(CRC32, REG_HWCAP, 7) 10499a2dd95SBruce Richardson FEAT_DEF(ATOMICS, REG_HWCAP, 8) 10599a2dd95SBruce Richardson FEAT_DEF(SVE, REG_HWCAP, 22) 10699a2dd95SBruce Richardson FEAT_DEF(SVE2, REG_HWCAP2, 1) 10799a2dd95SBruce Richardson FEAT_DEF(SVEAES, REG_HWCAP2, 2) 10899a2dd95SBruce Richardson FEAT_DEF(SVEPMULL, REG_HWCAP2, 3) 10999a2dd95SBruce Richardson FEAT_DEF(SVEBITPERM, REG_HWCAP2, 4) 11099a2dd95SBruce Richardson FEAT_DEF(SVESHA3, REG_HWCAP2, 5) 11199a2dd95SBruce Richardson FEAT_DEF(SVESM4, REG_HWCAP2, 6) 11299a2dd95SBruce Richardson FEAT_DEF(FLAGM2, REG_HWCAP2, 7) 11399a2dd95SBruce Richardson FEAT_DEF(FRINT, REG_HWCAP2, 8) 11499a2dd95SBruce Richardson FEAT_DEF(SVEI8MM, REG_HWCAP2, 9) 11599a2dd95SBruce Richardson FEAT_DEF(SVEF32MM, REG_HWCAP2, 10) 11699a2dd95SBruce Richardson FEAT_DEF(SVEF64MM, REG_HWCAP2, 11) 11799a2dd95SBruce Richardson FEAT_DEF(SVEBF16, REG_HWCAP2, 12) 118*2f1a90f0SWathsala Vithanage FEAT_DEF(WFXT, REG_HWCAP2, 31) 11920c7744fSJuraj Linkeš FEAT_DEF(AARCH64, REG_PLATFORM, 0) 12099a2dd95SBruce Richardson }; 12199a2dd95SBruce Richardson #endif /* RTE_ARCH */ 12299a2dd95SBruce Richardson 12399a2dd95SBruce Richardson /* 12499a2dd95SBruce Richardson * Read AUXV software register and get cpu features for ARM 12599a2dd95SBruce Richardson */ 12699a2dd95SBruce Richardson static void 12799a2dd95SBruce Richardson rte_cpu_get_features(hwcap_registers_t out) 12899a2dd95SBruce Richardson { 12999a2dd95SBruce Richardson out[REG_HWCAP] = rte_cpu_getauxval(AT_HWCAP); 13099a2dd95SBruce Richardson out[REG_HWCAP2] = rte_cpu_getauxval(AT_HWCAP2); 13199a2dd95SBruce Richardson if (!rte_cpu_strcmp_auxval(AT_PLATFORM, PLATFORM_STR)) 13299a2dd95SBruce Richardson out[REG_PLATFORM] = 0x0001; 13399a2dd95SBruce Richardson } 13499a2dd95SBruce Richardson 13599a2dd95SBruce Richardson /* 13699a2dd95SBruce Richardson * Checks if a particular flag is available on current machine. 13799a2dd95SBruce Richardson */ 13899a2dd95SBruce Richardson int 13999a2dd95SBruce Richardson rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature) 14099a2dd95SBruce Richardson { 14199a2dd95SBruce Richardson const struct feature_entry *feat; 14299a2dd95SBruce Richardson hwcap_registers_t regs = {0}; 14399a2dd95SBruce Richardson 14448c33e8cSSivaprasad Tummala if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table)) 14599a2dd95SBruce Richardson return -ENOENT; 14699a2dd95SBruce Richardson 14799a2dd95SBruce Richardson feat = &rte_cpu_feature_table[feature]; 14899a2dd95SBruce Richardson if (feat->reg == REG_NONE) 14999a2dd95SBruce Richardson return -EFAULT; 15099a2dd95SBruce Richardson 15199a2dd95SBruce Richardson rte_cpu_get_features(regs); 15299a2dd95SBruce Richardson return (regs[feat->reg] >> feat->bit) & 1; 15399a2dd95SBruce Richardson } 15499a2dd95SBruce Richardson 15599a2dd95SBruce Richardson const char * 15699a2dd95SBruce Richardson rte_cpu_get_flag_name(enum rte_cpu_flag_t feature) 15799a2dd95SBruce Richardson { 15848c33e8cSSivaprasad Tummala if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table)) 15999a2dd95SBruce Richardson return NULL; 16099a2dd95SBruce Richardson return rte_cpu_feature_table[feature].name; 16199a2dd95SBruce Richardson } 16299a2dd95SBruce Richardson 16399a2dd95SBruce Richardson void 16499a2dd95SBruce Richardson rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics) 16599a2dd95SBruce Richardson { 16699a2dd95SBruce Richardson memset(intrinsics, 0, sizeof(*intrinsics)); 167990b065fSWathsala Vithanage #ifdef RTE_ARCH_64 168ac114da6SFeifei Wang intrinsics->power_monitor = 1; 169990b065fSWathsala Vithanage #endif /* RTE_ARCH_64 */ 17099a2dd95SBruce Richardson } 171