xref: /dpdk/lib/eal/loongarch/rte_cpuflags.c (revision 48c33e8ceeaf323976b0d26ee976f43829acfb43)
1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * Copyright(c) 2022 Loongson Technology Corporation Limited
4  */
5 
6 #include "rte_cpuflags.h"
7 
8 #include <elf.h>
9 #include <fcntl.h>
10 #include <assert.h>
11 #include <unistd.h>
12 #include <string.h>
13 
14 /* Symbolic values for the entries in the auxiliary table */
15 #define AT_HWCAP  16
16 
17 /* software based registers */
18 enum cpu_register_t {
19 	REG_NONE = 0,
20 	REG_HWCAP,
21 	REG_MAX
22 };
23 
24 typedef uint32_t hwcap_registers_t[REG_MAX];
25 
26 struct feature_entry {
27 	uint32_t reg;
28 	uint32_t bit;
29 #define CPU_FLAG_NAME_MAX_LEN 64
30 	char name[CPU_FLAG_NAME_MAX_LEN];
31 };
32 
33 #define FEAT_DEF(name, reg, bit) \
34 	[RTE_CPUFLAG_##name] = {reg, bit, #name},
35 
36 const struct feature_entry rte_cpu_feature_table[] = {
37 	FEAT_DEF(CPUCFG,             REG_HWCAP,   0)
38 	FEAT_DEF(LAM,                REG_HWCAP,   1)
39 	FEAT_DEF(UAL,                REG_HWCAP,   2)
40 	FEAT_DEF(FPU,                REG_HWCAP,   3)
41 	FEAT_DEF(LSX,                REG_HWCAP,   4)
42 	FEAT_DEF(LASX,               REG_HWCAP,   5)
43 	FEAT_DEF(CRC32,              REG_HWCAP,   6)
44 	FEAT_DEF(COMPLEX,            REG_HWCAP,   7)
45 	FEAT_DEF(CRYPTO,             REG_HWCAP,   8)
46 	FEAT_DEF(LVZ,                REG_HWCAP,   9)
47 	FEAT_DEF(LBT_X86,            REG_HWCAP,  10)
48 	FEAT_DEF(LBT_ARM,            REG_HWCAP,  11)
49 	FEAT_DEF(LBT_MIPS,           REG_HWCAP,  12)
50 };
51 
52 /*
53  * Read AUXV software register and get cpu features for LoongArch
54  */
55 static void
rte_cpu_get_features(hwcap_registers_t out)56 rte_cpu_get_features(hwcap_registers_t out)
57 {
58 	out[REG_HWCAP] = rte_cpu_getauxval(AT_HWCAP);
59 }
60 
61 /*
62  * Checks if a particular flag is available on current machine.
63  */
64 int
rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)65 rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
66 {
67 	const struct feature_entry *feat;
68 	hwcap_registers_t regs = {0};
69 
70 	if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table))
71 		return -ENOENT;
72 
73 	feat = &rte_cpu_feature_table[feature];
74 	if (feat->reg == REG_NONE)
75 		return -EFAULT;
76 
77 	rte_cpu_get_features(regs);
78 	return (regs[feat->reg] >> feat->bit) & 1;
79 }
80 
81 const char *
rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)82 rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
83 {
84 	if ((unsigned int)feature >= RTE_DIM(rte_cpu_feature_table))
85 		return NULL;
86 	return rte_cpu_feature_table[feature].name;
87 }
88 
89 void
rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics * intrinsics)90 rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics)
91 {
92 	memset(intrinsics, 0, sizeof(*intrinsics));
93 }
94