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