xref: /dpdk/lib/eal/include/generic/rte_power_intrinsics.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2020 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #ifndef _RTE_POWER_INTRINSIC_H_
699a2dd95SBruce Richardson #define _RTE_POWER_INTRINSIC_H_
799a2dd95SBruce Richardson 
899a2dd95SBruce Richardson #include <inttypes.h>
999a2dd95SBruce Richardson 
1099a2dd95SBruce Richardson #include <rte_spinlock.h>
1199a2dd95SBruce Richardson 
12*719834a6SMattias Rönnblom #ifdef __cplusplus
13*719834a6SMattias Rönnblom extern "C" {
14*719834a6SMattias Rönnblom #endif
15*719834a6SMattias Rönnblom 
1699a2dd95SBruce Richardson /**
1799a2dd95SBruce Richardson  * @file
1899a2dd95SBruce Richardson  * Advanced power management operations.
1999a2dd95SBruce Richardson  *
2099a2dd95SBruce Richardson  * This file define APIs for advanced power management,
2199a2dd95SBruce Richardson  * which are architecture-dependent.
2299a2dd95SBruce Richardson  */
2399a2dd95SBruce Richardson 
246afc4bafSAnatoly Burakov /** Size of the opaque data in monitor condition */
256afc4bafSAnatoly Burakov #define RTE_POWER_MONITOR_OPAQUE_SZ 4
266afc4bafSAnatoly Burakov 
276afc4bafSAnatoly Burakov /**
286afc4bafSAnatoly Burakov  * Callback definition for monitoring conditions. Callbacks with this signature
296afc4bafSAnatoly Burakov  * will be used by `rte_power_monitor()` to check if the entering of power
306afc4bafSAnatoly Burakov  * optimized state should be aborted.
316afc4bafSAnatoly Burakov  *
326afc4bafSAnatoly Burakov  * @param val
336afc4bafSAnatoly Burakov  *   The value read from memory.
346afc4bafSAnatoly Burakov  * @param opaque
356afc4bafSAnatoly Burakov  *   Callback-specific data.
366afc4bafSAnatoly Burakov  *
376afc4bafSAnatoly Burakov  * @return
386afc4bafSAnatoly Burakov  *   0 if entering of power optimized state should proceed
396afc4bafSAnatoly Burakov  *   -1 if entering of power optimized state should be aborted
406afc4bafSAnatoly Burakov  */
416afc4bafSAnatoly Burakov typedef int (*rte_power_monitor_clb_t)(const uint64_t val,
426afc4bafSAnatoly Burakov 		const uint64_t opaque[RTE_POWER_MONITOR_OPAQUE_SZ]);
436afc4bafSAnatoly Burakov 
4499a2dd95SBruce Richardson struct rte_power_monitor_cond {
4599a2dd95SBruce Richardson 	volatile void *addr;  /**< Address to monitor for changes */
466afc4bafSAnatoly Burakov 	uint8_t size;    /**< Data size (in bytes) that will be read from the
4799a2dd95SBruce Richardson 	                  *   monitored memory location (`addr`). Can be 1, 2,
4899a2dd95SBruce Richardson 	                  *   4, or 8. Supplying any other value will result in
4999a2dd95SBruce Richardson 	                  *   an error.
5099a2dd95SBruce Richardson 	                  */
516afc4bafSAnatoly Burakov 	rte_power_monitor_clb_t fn; /**< Callback to be used to check if
526afc4bafSAnatoly Burakov 	                             *   entering power optimized state should
536afc4bafSAnatoly Burakov 	                             *   be aborted.
546afc4bafSAnatoly Burakov 	                             */
556afc4bafSAnatoly Burakov 	uint64_t opaque[RTE_POWER_MONITOR_OPAQUE_SZ];
566afc4bafSAnatoly Burakov 	/**< Callback-specific data */
5799a2dd95SBruce Richardson };
5899a2dd95SBruce Richardson 
5999a2dd95SBruce Richardson /**
6099a2dd95SBruce Richardson  * Monitor specific address for changes. This will cause the CPU to enter an
6199a2dd95SBruce Richardson  * architecture-defined optimized power state until either the specified
6299a2dd95SBruce Richardson  * memory address is written to, a certain TSC timestamp is reached, or other
6399a2dd95SBruce Richardson  * reasons cause the CPU to wake up.
6499a2dd95SBruce Richardson  *
6599a2dd95SBruce Richardson  * Additionally, an expected value (`pmc->val`), mask (`pmc->mask`), and data
6699a2dd95SBruce Richardson  * size (`pmc->size`) are provided in the `pmc` power monitoring condition. If
6799a2dd95SBruce Richardson  * the mask is non-zero, the current value pointed to by the `pmc->addr` pointer
6899a2dd95SBruce Richardson  * will be read and compared against the expected value, and if they match, the
6999a2dd95SBruce Richardson  * entering of optimized power state will be aborted. This is intended to
7099a2dd95SBruce Richardson  * prevent the CPU from entering optimized power state and waiting on a write
7199a2dd95SBruce Richardson  * that has already happened by the time this API is called.
7299a2dd95SBruce Richardson  *
7399a2dd95SBruce Richardson  * @warning It is responsibility of the user to check if this function is
7499a2dd95SBruce Richardson  *   supported at runtime using `rte_cpu_get_intrinsics_support()` API call.
7599a2dd95SBruce Richardson  *
7699a2dd95SBruce Richardson  * @param pmc
7799a2dd95SBruce Richardson  *   The monitoring condition structure.
7899a2dd95SBruce Richardson  * @param tsc_timestamp
7999a2dd95SBruce Richardson  *   Maximum TSC timestamp to wait for. Note that the wait behavior is
8099a2dd95SBruce Richardson  *   architecture-dependent.
8199a2dd95SBruce Richardson  *
8299a2dd95SBruce Richardson  * @return
8399a2dd95SBruce Richardson  *   0 on success
8499a2dd95SBruce Richardson  *   -EINVAL on invalid parameters
8599a2dd95SBruce Richardson  *   -ENOTSUP if unsupported
8699a2dd95SBruce Richardson  */
8799a2dd95SBruce Richardson int rte_power_monitor(const struct rte_power_monitor_cond *pmc,
8899a2dd95SBruce Richardson 		const uint64_t tsc_timestamp);
8999a2dd95SBruce Richardson 
9099a2dd95SBruce Richardson /**
9199a2dd95SBruce Richardson  * Wake up a specific lcore that is in a power optimized state and is monitoring
9299a2dd95SBruce Richardson  * an address.
9399a2dd95SBruce Richardson  *
9499a2dd95SBruce Richardson  * @note It is safe to call this function if the lcore in question is not
9599a2dd95SBruce Richardson  *   sleeping. The function will have no effect.
9699a2dd95SBruce Richardson  *
9799a2dd95SBruce Richardson  * @note This function will *not* wake up a core that is in a power optimized
9899a2dd95SBruce Richardson  *   state due to calling `rte_power_pause`.
9999a2dd95SBruce Richardson  *
10099a2dd95SBruce Richardson  * @param lcore_id
10199a2dd95SBruce Richardson  *   Lcore ID of a sleeping thread.
10299a2dd95SBruce Richardson  */
10399a2dd95SBruce Richardson int rte_power_monitor_wakeup(const unsigned int lcore_id);
10499a2dd95SBruce Richardson 
10599a2dd95SBruce Richardson /**
10699a2dd95SBruce Richardson  * Enter an architecture-defined optimized power state until a certain TSC
10799a2dd95SBruce Richardson  * timestamp is reached.
10899a2dd95SBruce Richardson  *
10999a2dd95SBruce Richardson  * @warning It is responsibility of the user to check if this function is
11099a2dd95SBruce Richardson  *   supported at runtime using `rte_cpu_get_intrinsics_support()` API call.
11199a2dd95SBruce Richardson  *
11299a2dd95SBruce Richardson  * @param tsc_timestamp
11399a2dd95SBruce Richardson  *   Maximum TSC timestamp to wait for. Note that the wait behavior is
11499a2dd95SBruce Richardson  *   architecture-dependent.
11599a2dd95SBruce Richardson  *
11699a2dd95SBruce Richardson  * @return
11799a2dd95SBruce Richardson  *   0 on success
11899a2dd95SBruce Richardson  *   -EINVAL on invalid parameters
11999a2dd95SBruce Richardson  *   -ENOTSUP if unsupported
12099a2dd95SBruce Richardson  */
12199a2dd95SBruce Richardson int rte_power_pause(const uint64_t tsc_timestamp);
12299a2dd95SBruce Richardson 
12366834f29SAnatoly Burakov /**
12466834f29SAnatoly Burakov  * Monitor a set of addresses for changes. This will cause the CPU to enter an
12566834f29SAnatoly Burakov  * architecture-defined optimized power state until either one of the specified
12666834f29SAnatoly Burakov  * memory addresses is written to, a certain TSC timestamp is reached, or other
12766834f29SAnatoly Burakov  * reasons cause the CPU to wake up.
12866834f29SAnatoly Burakov  *
12966834f29SAnatoly Burakov  * Additionally, `expected` 64-bit values and 64-bit masks are provided. If
13066834f29SAnatoly Burakov  * mask is non-zero, the current value pointed to by the `p` pointer will be
13166834f29SAnatoly Burakov  * checked against the expected value, and if they do not match, the entering of
13266834f29SAnatoly Burakov  * optimized power state may be aborted.
13366834f29SAnatoly Burakov  *
13466834f29SAnatoly Burakov  * @warning It is responsibility of the user to check if this function is
13566834f29SAnatoly Burakov  *   supported at runtime using `rte_cpu_get_intrinsics_support()` API call.
13666834f29SAnatoly Burakov  *   Failing to do so may result in an illegal CPU instruction error.
13766834f29SAnatoly Burakov  *
13866834f29SAnatoly Burakov  * @param pmc
13966834f29SAnatoly Burakov  *   An array of monitoring condition structures.
14066834f29SAnatoly Burakov  * @param num
14166834f29SAnatoly Burakov  *   Length of the `pmc` array.
14266834f29SAnatoly Burakov  * @param tsc_timestamp
14366834f29SAnatoly Burakov  *   Maximum TSC timestamp to wait for. Note that the wait behavior is
14466834f29SAnatoly Burakov  *   architecture-dependent.
14566834f29SAnatoly Burakov  *
14666834f29SAnatoly Burakov  * @return
14766834f29SAnatoly Burakov  *   0 on success
14866834f29SAnatoly Burakov  *   -EINVAL on invalid parameters
14966834f29SAnatoly Burakov  *   -ENOTSUP if unsupported
15066834f29SAnatoly Burakov  */
15166834f29SAnatoly Burakov int rte_power_monitor_multi(const struct rte_power_monitor_cond pmc[],
15266834f29SAnatoly Burakov 		const uint32_t num, const uint64_t tsc_timestamp);
15366834f29SAnatoly Burakov 
154*719834a6SMattias Rönnblom #ifdef __cplusplus
155*719834a6SMattias Rönnblom }
156*719834a6SMattias Rönnblom #endif
157*719834a6SMattias Rönnblom 
15899a2dd95SBruce Richardson #endif /* _RTE_POWER_INTRINSIC_H_ */
159