xref: /dpdk/lib/eal/arm/rte_power_intrinsics.c (revision 665b49c51639a10c553433bc2bcd85c7331c631e)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2021 Intel Corporation
3  */
4 
5 #include <errno.h>
6 
7 #include "rte_power_intrinsics.h"
8 
9 /**
10  * This function uses WFE instruction to make lcore suspend
11  * execution on ARM.
12  * Note that timestamp based timeout is not supported yet.
13  */
14 int
15 rte_power_monitor(const struct rte_power_monitor_cond *pmc,
16 		const uint64_t tsc_timestamp)
17 {
18 	RTE_SET_USED(tsc_timestamp);
19 
20 #ifdef RTE_ARM_USE_WFE
21 	const unsigned int lcore_id = rte_lcore_id();
22 	uint64_t cur_value;
23 
24 	/* prevent non-EAL thread from using this API */
25 	if (lcore_id >= RTE_MAX_LCORE)
26 		return -EINVAL;
27 
28 	if (pmc == NULL)
29 		return -EINVAL;
30 
31 	if (pmc->fn == NULL)
32 		return -EINVAL;
33 
34 	switch (pmc->size) {
35 	case sizeof(uint8_t):
36 		__RTE_ARM_LOAD_EXC_8(pmc->addr, cur_value, __ATOMIC_RELAXED)
37 		__RTE_ARM_WFE()
38 		break;
39 	case sizeof(uint16_t):
40 		__RTE_ARM_LOAD_EXC_16(pmc->addr, cur_value, __ATOMIC_RELAXED)
41 		__RTE_ARM_WFE()
42 		break;
43 	case sizeof(uint32_t):
44 		__RTE_ARM_LOAD_EXC_32(pmc->addr, cur_value, __ATOMIC_RELAXED)
45 		__RTE_ARM_WFE()
46 		break;
47 	case sizeof(uint64_t):
48 		__RTE_ARM_LOAD_EXC_64(pmc->addr, cur_value, __ATOMIC_RELAXED)
49 		__RTE_ARM_WFE()
50 		break;
51 	default:
52 		return -EINVAL; /* unexpected size */
53 	}
54 
55 	return 0;
56 #else
57 	RTE_SET_USED(pmc);
58 
59 	return -ENOTSUP;
60 #endif
61 }
62 
63 /**
64  * This function is not supported on ARM.
65  */
66 int
67 rte_power_pause(const uint64_t tsc_timestamp)
68 {
69 	RTE_SET_USED(tsc_timestamp);
70 
71 	return -ENOTSUP;
72 }
73 
74 /**
75  * This function uses SEV instruction to wake up all cores
76  * on ARM.
77  * Note that lcore_id is not used here.
78  */
79 int
80 rte_power_monitor_wakeup(const unsigned int lcore_id)
81 {
82 	RTE_SET_USED(lcore_id);
83 
84 #ifdef RTE_ARM_USE_WFE
85 	__RTE_ARM_SEV()
86 
87 	return 0;
88 #else
89 	return -ENOTSUP;
90 #endif
91 }
92 
93 int
94 rte_power_monitor_multi(const struct rte_power_monitor_cond pmc[],
95 		const uint32_t num, const uint64_t tsc_timestamp)
96 {
97 	RTE_SET_USED(pmc);
98 	RTE_SET_USED(num);
99 	RTE_SET_USED(tsc_timestamp);
100 
101 	return -ENOTSUP;
102 }
103