xref: /dpdk/lib/eal/riscv/rte_cpuflags.c (revision 48c33e8ceeaf323976b0d26ee976f43829acfb43)
1f22e705eSMichal Mazurek /* SPDX-License-Identifier: BSD-3-Clause
2f22e705eSMichal Mazurek  * Copyright(c) 2022 StarFive
3f22e705eSMichal Mazurek  * Copyright(c) 2022 SiFive
4f22e705eSMichal Mazurek  * Copyright(c) 2022 Semihalf
5f22e705eSMichal Mazurek  */
6f22e705eSMichal Mazurek 
7f22e705eSMichal Mazurek #include "rte_cpuflags.h"
8f22e705eSMichal Mazurek 
9f22e705eSMichal Mazurek #include <elf.h>
10f22e705eSMichal Mazurek #include <fcntl.h>
11f22e705eSMichal Mazurek #include <assert.h>
12f22e705eSMichal Mazurek #include <unistd.h>
13f22e705eSMichal Mazurek #include <string.h>
14f22e705eSMichal Mazurek 
15f22e705eSMichal Mazurek #ifndef AT_HWCAP
16f22e705eSMichal Mazurek #define AT_HWCAP 16
17f22e705eSMichal Mazurek #endif
18f22e705eSMichal Mazurek 
19f22e705eSMichal Mazurek #ifndef AT_HWCAP2
20f22e705eSMichal Mazurek #define AT_HWCAP2 26
21f22e705eSMichal Mazurek #endif
22f22e705eSMichal Mazurek 
23f22e705eSMichal Mazurek #ifndef AT_PLATFORM
24f22e705eSMichal Mazurek #define AT_PLATFORM 15
25f22e705eSMichal Mazurek #endif
26f22e705eSMichal Mazurek 
27f22e705eSMichal Mazurek enum cpu_register_t {
28f22e705eSMichal Mazurek 	REG_NONE = 0,
29f22e705eSMichal Mazurek 	REG_HWCAP,
30f22e705eSMichal Mazurek 	REG_HWCAP2,
31f22e705eSMichal Mazurek 	REG_PLATFORM,
32f22e705eSMichal Mazurek 	REG_MAX
33f22e705eSMichal Mazurek };
34f22e705eSMichal Mazurek 
35f22e705eSMichal Mazurek typedef uint32_t hwcap_registers_t[REG_MAX];
36f22e705eSMichal Mazurek 
37f22e705eSMichal Mazurek /**
38f22e705eSMichal Mazurek  * Struct to hold a processor feature entry
39f22e705eSMichal Mazurek  */
40f22e705eSMichal Mazurek struct feature_entry {
41f22e705eSMichal Mazurek 	uint32_t reg;
42f22e705eSMichal Mazurek 	uint32_t bit;
43f22e705eSMichal Mazurek #define CPU_FLAG_NAME_MAX_LEN 64
44f22e705eSMichal Mazurek 	char name[CPU_FLAG_NAME_MAX_LEN];
45f22e705eSMichal Mazurek };
46f22e705eSMichal Mazurek 
47f22e705eSMichal Mazurek #define FEAT_DEF(name, reg, bit) \
48f22e705eSMichal Mazurek 	[RTE_CPUFLAG_##name] = {reg, bit, #name},
49f22e705eSMichal Mazurek 
50f22e705eSMichal Mazurek typedef Elf64_auxv_t _Elfx_auxv_t;
51f22e705eSMichal Mazurek 
52f22e705eSMichal Mazurek const struct feature_entry rte_cpu_feature_table[] = {
53f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_A, REG_HWCAP,    0)
54f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_B, REG_HWCAP,    1)
55f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_C, REG_HWCAP,    2)
56f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_D, REG_HWCAP,    3)
57f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_E, REG_HWCAP,    4)
58f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_F, REG_HWCAP,    5)
59f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_G, REG_HWCAP,    6)
60f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_H, REG_HWCAP,    7)
61f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_I, REG_HWCAP,    8)
62f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_J, REG_HWCAP,    9)
63f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_K, REG_HWCAP,   10)
64f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_L, REG_HWCAP,   11)
65f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_M, REG_HWCAP,   12)
66f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_N, REG_HWCAP,   13)
67f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_O, REG_HWCAP,   14)
68f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_P, REG_HWCAP,   15)
69f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_Q, REG_HWCAP,   16)
70f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_R, REG_HWCAP,   17)
71f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_S, REG_HWCAP,   18)
72f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_T, REG_HWCAP,   19)
73f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_U, REG_HWCAP,   20)
74f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_V, REG_HWCAP,   21)
75f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_W, REG_HWCAP,   22)
76f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_X, REG_HWCAP,   23)
77f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_Y, REG_HWCAP,   24)
78f22e705eSMichal Mazurek 	FEAT_DEF(RISCV_ISA_Z, REG_HWCAP,   25)
79f22e705eSMichal Mazurek };
80f22e705eSMichal Mazurek /*
81f22e705eSMichal Mazurek  * Read AUXV software register and get cpu features for ARM
82f22e705eSMichal Mazurek  */
83f22e705eSMichal Mazurek static void
rte_cpu_get_features(hwcap_registers_t out)84f22e705eSMichal Mazurek rte_cpu_get_features(hwcap_registers_t out)
85f22e705eSMichal Mazurek {
86f22e705eSMichal Mazurek 	out[REG_HWCAP] = rte_cpu_getauxval(AT_HWCAP);
87f22e705eSMichal Mazurek 	out[REG_HWCAP2] = rte_cpu_getauxval(AT_HWCAP2);
88f22e705eSMichal Mazurek }
89f22e705eSMichal Mazurek 
90f22e705eSMichal Mazurek /*
91f22e705eSMichal Mazurek  * Checks if a particular flag is available on current machine.
92f22e705eSMichal Mazurek  */
93f22e705eSMichal Mazurek int
rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)94f22e705eSMichal Mazurek rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
95f22e705eSMichal Mazurek {
96f22e705eSMichal Mazurek 	const struct feature_entry *feat;
97f22e705eSMichal Mazurek 	hwcap_registers_t regs = {0};
98f22e705eSMichal Mazurek 
99*48c33e8cSSivaprasad Tummala 	if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table))
100f22e705eSMichal Mazurek 		return -ENOENT;
101f22e705eSMichal Mazurek 
102f22e705eSMichal Mazurek 	feat = &rte_cpu_feature_table[feature];
103f22e705eSMichal Mazurek 	if (feat->reg == REG_NONE)
104f22e705eSMichal Mazurek 		return -EFAULT;
105f22e705eSMichal Mazurek 
106f22e705eSMichal Mazurek 	rte_cpu_get_features(regs);
107f22e705eSMichal Mazurek 	return (regs[feat->reg] >> feat->bit) & 1;
108f22e705eSMichal Mazurek }
109f22e705eSMichal Mazurek 
110f22e705eSMichal Mazurek const char *
rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)111f22e705eSMichal Mazurek rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
112f22e705eSMichal Mazurek {
113*48c33e8cSSivaprasad Tummala 	if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table))
114f22e705eSMichal Mazurek 		return NULL;
115f22e705eSMichal Mazurek 	return rte_cpu_feature_table[feature].name;
116f22e705eSMichal Mazurek }
117f22e705eSMichal Mazurek 
118f22e705eSMichal Mazurek void
rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics * intrinsics)119f22e705eSMichal Mazurek rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics)
120f22e705eSMichal Mazurek {
121f22e705eSMichal Mazurek 	memset(intrinsics, 0, sizeof(*intrinsics));
122f22e705eSMichal Mazurek }
123