similarity index 95%
rename from lib/power/power_intel_uncore.c
rename to drivers/power/intel_uncore/intel_uncore.c
@@ -8,7 +8,7 @@
#include <rte_memcpy.h>
-#include "power_intel_uncore.h"
+#include "intel_uncore.h"
#include "power_common.h"
#define MAX_UNCORE_FREQS 32
@@ -476,3 +476,19 @@ power_intel_uncore_get_num_dies(unsigned int pkg)
return count;
}
+
+static struct rte_power_uncore_ops intel_uncore_ops = {
+ .name = "intel-uncore",
+ .init = power_intel_uncore_init,
+ .exit = power_intel_uncore_exit,
+ .get_avail_freqs = power_intel_uncore_freqs,
+ .get_num_pkgs = power_intel_uncore_get_num_pkgs,
+ .get_num_dies = power_intel_uncore_get_num_dies,
+ .get_num_freqs = power_intel_uncore_get_num_freqs,
+ .get_freq = power_get_intel_uncore_freq,
+ .set_freq = power_set_intel_uncore_freq,
+ .freq_max = power_intel_uncore_freq_max,
+ .freq_min = power_intel_uncore_freq_min,
+};
+
+RTE_POWER_REGISTER_UNCORE_OPS(intel_uncore_ops);
similarity index 97%
rename from lib/power/power_intel_uncore.h
rename to drivers/power/intel_uncore/intel_uncore.h
@@ -2,8 +2,8 @@
* Copyright(c) 2022 Intel Corporation
*/
-#ifndef POWER_INTEL_UNCORE_H
-#define POWER_INTEL_UNCORE_H
+#ifndef INTEL_UNCORE_H
+#define INTEL_UNCORE_H
/**
* @file
@@ -11,7 +11,7 @@
*/
#include "rte_power.h"
-#include "rte_power_uncore.h"
+#include "rte_power_uncore_ops.h"
#ifdef __cplusplus
extern "C" {
@@ -223,4 +223,4 @@ power_intel_uncore_get_num_dies(unsigned int pkg);
}
#endif
-#endif /* POWER_INTEL_UNCORE_H */
+#endif /* INTEL_UNCORE_H */
new file mode 100644
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2017 Intel Corporation
+# Copyright(c) 2024 Advanced Micro Devices, Inc.
+
+sources = files('intel_uncore.c')
+
+deps += ['power']
@@ -6,7 +6,8 @@ drivers = [
'amd_pstate',
'cppc',
'kvm_vm',
- 'pstate'
+ 'pstate',
+ 'intel_uncore'
]
std_deps = ['power']
@@ -13,7 +13,6 @@ if not is_linux
endif
sources = files(
'power_common.c',
- 'power_intel_uncore.c',
'rte_power.c',
'rte_power_uncore.c',
'rte_power_pmd_mgmt.c',
@@ -24,6 +23,7 @@ headers = files(
'rte_power_guest_channel.h',
'rte_power_pmd_mgmt.h',
'rte_power_uncore.h',
+ 'rte_power_uncore_ops.h',
)
if cc.has_argument('-Wno-cast-qual')
cflags += '-Wno-cast-qual'
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2014 Intel Corporation
- * Copyright(c) 2023 AMD Corporation
+ * Copyright(c) 2024 Advanced Micro Devices, Inc.
*/
#include <errno.h>
@@ -10,100 +10,52 @@
#include "power_common.h"
#include "rte_power_uncore.h"
-#include "power_intel_uncore.h"
-enum rte_uncore_power_mgmt_env default_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET;
+static enum rte_uncore_power_mgmt_env global_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET;
+static struct rte_power_uncore_ops *global_uncore_ops;
static rte_spinlock_t global_env_cfg_lock = RTE_SPINLOCK_INITIALIZER;
+static RTE_TAILQ_HEAD(, rte_power_uncore_ops) uncore_ops_list =
+ TAILQ_HEAD_INITIALIZER(uncore_ops_list);
-static uint32_t
-power_get_dummy_uncore_freq(unsigned int pkg __rte_unused,
- unsigned int die __rte_unused)
-{
- return 0;
-}
-
-static int
-power_set_dummy_uncore_freq(unsigned int pkg __rte_unused,
- unsigned int die __rte_unused, uint32_t index __rte_unused)
-{
- return 0;
-}
+const char *uncore_env_str[] = {
+ "not set",
+ "auto-detect",
+ "intel-uncore",
+ "amd-hsmp"
+};
-static int
-power_dummy_uncore_freq_max(unsigned int pkg __rte_unused,
- unsigned int die __rte_unused)
-{
- return 0;
-}
-
-static int
-power_dummy_uncore_freq_min(unsigned int pkg __rte_unused,
- unsigned int die __rte_unused)
-{
- return 0;
-}
-
-static int
-power_dummy_uncore_freqs(unsigned int pkg __rte_unused, unsigned int die __rte_unused,
- uint32_t *freqs __rte_unused, uint32_t num __rte_unused)
-{
- return 0;
-}
-
-static int
-power_dummy_uncore_get_num_freqs(unsigned int pkg __rte_unused,
- unsigned int die __rte_unused)
+/* register the ops struct in rte_power_uncore_ops, return 0 on success. */
+int
+rte_power_register_uncore_ops(struct rte_power_uncore_ops *driver_ops)
{
- return 0;
-}
+ if (!driver_ops->init || !driver_ops->exit || !driver_ops->get_num_pkgs ||
+ !driver_ops->get_num_dies || !driver_ops->get_num_freqs ||
+ !driver_ops->get_avail_freqs || !driver_ops->get_freq ||
+ !driver_ops->set_freq || !driver_ops->freq_max ||
+ !driver_ops->freq_min) {
+ POWER_LOG(ERR, "Missing callbacks while registering power ops");
+ return -1;
+ }
+ if (driver_ops->cb)
+ driver_ops->cb();
-static unsigned int
-power_dummy_uncore_get_num_pkgs(void)
-{
- return 0;
-}
+ TAILQ_INSERT_TAIL(&uncore_ops_list, driver_ops, next);
-static unsigned int
-power_dummy_uncore_get_num_dies(unsigned int pkg __rte_unused)
-{
return 0;
}
-/* function pointers */
-rte_power_get_uncore_freq_t rte_power_get_uncore_freq = power_get_dummy_uncore_freq;
-rte_power_set_uncore_freq_t rte_power_set_uncore_freq = power_set_dummy_uncore_freq;
-rte_power_uncore_freq_change_t rte_power_uncore_freq_max = power_dummy_uncore_freq_max;
-rte_power_uncore_freq_change_t rte_power_uncore_freq_min = power_dummy_uncore_freq_min;
-rte_power_uncore_freqs_t rte_power_uncore_freqs = power_dummy_uncore_freqs;
-rte_power_uncore_get_num_freqs_t rte_power_uncore_get_num_freqs = power_dummy_uncore_get_num_freqs;
-rte_power_uncore_get_num_pkgs_t rte_power_uncore_get_num_pkgs = power_dummy_uncore_get_num_pkgs;
-rte_power_uncore_get_num_dies_t rte_power_uncore_get_num_dies = power_dummy_uncore_get_num_dies;
-
-static void
-reset_power_uncore_function_ptrs(void)
-{
- rte_power_get_uncore_freq = power_get_dummy_uncore_freq;
- rte_power_set_uncore_freq = power_set_dummy_uncore_freq;
- rte_power_uncore_freq_max = power_dummy_uncore_freq_max;
- rte_power_uncore_freq_min = power_dummy_uncore_freq_min;
- rte_power_uncore_freqs = power_dummy_uncore_freqs;
- rte_power_uncore_get_num_freqs = power_dummy_uncore_get_num_freqs;
- rte_power_uncore_get_num_pkgs = power_dummy_uncore_get_num_pkgs;
- rte_power_uncore_get_num_dies = power_dummy_uncore_get_num_dies;
-}
-
int
rte_power_set_uncore_env(enum rte_uncore_power_mgmt_env env)
{
- int ret;
+ int ret = -1;
+ struct rte_power_uncore_ops *ops;
rte_spinlock_lock(&global_env_cfg_lock);
- if (default_uncore_env != RTE_UNCORE_PM_ENV_NOT_SET) {
+ if (global_uncore_env != RTE_UNCORE_PM_ENV_NOT_SET) {
POWER_LOG(ERR, "Uncore Power Management Env already set.");
- rte_spinlock_unlock(&global_env_cfg_lock);
- return -1;
+ goto out;
}
if (env == RTE_UNCORE_PM_ENV_AUTO_DETECT)
@@ -113,25 +65,23 @@ rte_power_set_uncore_env(enum rte_uncore_power_mgmt_env env)
*/
env = RTE_UNCORE_PM_ENV_INTEL_UNCORE;
- ret = 0;
- if (env == RTE_UNCORE_PM_ENV_INTEL_UNCORE) {
- rte_power_get_uncore_freq = power_get_intel_uncore_freq;
- rte_power_set_uncore_freq = power_set_intel_uncore_freq;
- rte_power_uncore_freq_min = power_intel_uncore_freq_min;
- rte_power_uncore_freq_max = power_intel_uncore_freq_max;
- rte_power_uncore_freqs = power_intel_uncore_freqs;
- rte_power_uncore_get_num_freqs = power_intel_uncore_get_num_freqs;
- rte_power_uncore_get_num_pkgs = power_intel_uncore_get_num_pkgs;
- rte_power_uncore_get_num_dies = power_intel_uncore_get_num_dies;
- } else {
- POWER_LOG(ERR, "Invalid Power Management Environment(%d) set", env);
- ret = -1;
- goto out;
- }
+ if (env <= RTE_DIM(uncore_env_str)) {
+ RTE_TAILQ_FOREACH(ops, &uncore_ops_list, next)
+ if (strncmp(ops->name, uncore_env_str[env],
+ RTE_POWER_UNCORE_DRIVER_NAMESZ) == 0) {
+ global_uncore_env = env;
+ global_uncore_ops = ops;
+ ret = 0;
+ goto out;
+ }
+ POWER_LOG(ERR, "Power Management (%s) not supported",
+ uncore_env_str[env]);
+ } else
+ POWER_LOG(ERR, "Invalid Power Management Environment");
- default_uncore_env = env;
out:
rte_spinlock_unlock(&global_env_cfg_lock);
+
return ret;
}
@@ -139,42 +89,50 @@ void
rte_power_unset_uncore_env(void)
{
rte_spinlock_lock(&global_env_cfg_lock);
- default_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET;
- reset_power_uncore_function_ptrs();
+ global_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET;
rte_spinlock_unlock(&global_env_cfg_lock);
}
enum rte_uncore_power_mgmt_env
rte_power_get_uncore_env(void)
{
- return default_uncore_env;
+ return global_uncore_env;
+}
+
+struct rte_power_uncore_ops *
+rte_power_get_uncore_ops(void)
+{
+ RTE_ASSERT(global_uncore_ops != NULL);
+
+ return global_uncore_ops;
}
int
rte_power_uncore_init(unsigned int pkg, unsigned int die)
{
int ret = -1;
-
- switch (default_uncore_env) {
- case RTE_UNCORE_PM_ENV_INTEL_UNCORE:
- return power_intel_uncore_init(pkg, die);
- default:
- POWER_LOG(INFO, "Uncore Env isn't set yet!");
- break;
- }
-
- /* Auto detect Environment */
- POWER_LOG(INFO, "Attempting to initialise Intel Uncore power mgmt...");
- ret = power_intel_uncore_init(pkg, die);
- if (ret == 0) {
- rte_power_set_uncore_env(RTE_UNCORE_PM_ENV_INTEL_UNCORE);
- goto out;
- }
-
- if (default_uncore_env == RTE_UNCORE_PM_ENV_NOT_SET) {
- POWER_LOG(ERR, "Unable to set Power Management Environment "
- "for package %u Die %u", pkg, die);
- ret = 0;
+ struct rte_power_uncore_ops *ops;
+ uint8_t env;
+
+ if ((global_uncore_env != RTE_UNCORE_PM_ENV_NOT_SET) &&
+ (global_uncore_env != RTE_UNCORE_PM_ENV_AUTO_DETECT))
+ return global_uncore_ops->init(pkg, die);
+
+ /* Auto Detect Environment */
+ RTE_TAILQ_FOREACH(ops, &uncore_ops_list, next)
+ if (ops) {
+ POWER_LOG(INFO,
+ "Attempting to initialise %s power management...",
+ ops->name);
+ ret = ops->init(pkg, die);
+ if (ret == 0) {
+ for (env = 0; env < RTE_DIM(uncore_env_str); env++)
+ if (strncmp(ops->name, uncore_env_str[env],
+ RTE_POWER_UNCORE_DRIVER_NAMESZ) == 0) {
+ rte_power_set_uncore_env(env);
+ goto out;
+ }
+ }
}
out:
return ret;
@@ -183,12 +141,12 @@ rte_power_uncore_init(unsigned int pkg, unsigned int die)
int
rte_power_uncore_exit(unsigned int pkg, unsigned int die)
{
- switch (default_uncore_env) {
- case RTE_UNCORE_PM_ENV_INTEL_UNCORE:
- return power_intel_uncore_exit(pkg, die);
- default:
- POWER_LOG(ERR, "Uncore Env has not been set, unable to exit gracefully");
- break;
- }
+ if ((global_uncore_env != RTE_UNCORE_PM_ENV_NOT_SET) &&
+ global_uncore_ops)
+ return global_uncore_ops->exit(pkg, die);
+
+ POWER_LOG(ERR,
+ "Uncore Env has not been set, unable to exit gracefully");
+
return -1;
}
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2022 Intel Corporation
- * Copyright(c) 2023 AMD Corporation
+ * Copyright(c) 2024 Advanced Micro Devices, Inc.
*/
#ifndef RTE_POWER_UNCORE_H
@@ -10,9 +10,7 @@
* @file
* RTE Uncore Frequency Management
*/
-
-#include <rte_compat.h>
-#include "rte_power.h"
+#include "rte_power_uncore_ops.h"
#ifdef __cplusplus
extern "C" {
@@ -116,9 +114,13 @@ rte_power_uncore_exit(unsigned int pkg, unsigned int die);
* The current index of available frequencies.
* If error, it will return 'RTE_POWER_INVALID_FREQ_INDEX = (~0)'.
*/
-typedef uint32_t (*rte_power_get_uncore_freq_t)(unsigned int pkg, unsigned int die);
+static inline uint32_t
+rte_power_get_uncore_freq(unsigned int pkg, unsigned int die)
+{
+ struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops();
-extern rte_power_get_uncore_freq_t rte_power_get_uncore_freq;
+ return ops->get_freq(pkg, die);
+}
/**
* Set minimum and maximum uncore frequency for specified die on a package
@@ -141,26 +143,13 @@ extern rte_power_get_uncore_freq_t rte_power_get_uncore_freq;
* - 0 on success without frequency changed.
* - Negative on error.
*/
-typedef int (*rte_power_set_uncore_freq_t)(unsigned int pkg, unsigned int die, uint32_t index);
+static inline uint32_t
+rte_power_set_uncore_freq(unsigned int pkg, unsigned int die, uint32_t index)
+{
+ struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops();
-extern rte_power_set_uncore_freq_t rte_power_set_uncore_freq;
-
-/**
- * Function pointer definition for generic frequency change functions.
- *
- * @param pkg
- * Package number.
- * Each physical CPU in a system is referred to as a package.
- * @param die
- * Die number.
- * Each package can have several dies connected together via the uncore mesh.
- *
- * @return
- * - 1 on success with frequency changed.
- * - 0 on success without frequency changed.
- * - Negative on error.
- */
-typedef int (*rte_power_uncore_freq_change_t)(unsigned int pkg, unsigned int die);
+ return ops->set_freq(pkg, die, index);
+}
/**
* Set minimum and maximum uncore frequency for specified die on a package
@@ -169,7 +158,13 @@ typedef int (*rte_power_uncore_freq_change_t)(unsigned int pkg, unsigned int die
*
* This function should NOT be called in the fast path.
*/
-extern rte_power_uncore_freq_change_t rte_power_uncore_freq_max;
+static inline uint32_t
+rte_power_uncore_freq_max(unsigned int pkg, unsigned int die)
+{
+ struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops();
+
+ return ops->freq_max(pkg, die);
+}
/**
* Set minimum and maximum uncore frequency for specified die on a package
@@ -178,7 +173,13 @@ extern rte_power_uncore_freq_change_t rte_power_uncore_freq_max;
*
* This function should NOT be called in the fast path.
*/
-extern rte_power_uncore_freq_change_t rte_power_uncore_freq_min;
+static inline uint32_t
+rte_power_uncore_freq_min(unsigned int pkg, unsigned int die)
+{
+ struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops();
+
+ return ops->freq_min(pkg, die);
+}
/**
* Return the list of available frequencies in the index array.
@@ -200,10 +201,14 @@ extern rte_power_uncore_freq_change_t rte_power_uncore_freq_min;
* - The number of available index's in frequency array.
* - Negative on error.
*/
-typedef int (*rte_power_uncore_freqs_t)(unsigned int pkg, unsigned int die,
- uint32_t *freqs, uint32_t num);
+static inline uint32_t
+rte_power_uncore_freqs(unsigned int pkg, unsigned int die,
+ uint32_t *freqs, uint32_t num)
+{
+ struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops();
-extern rte_power_uncore_freqs_t rte_power_uncore_freqs;
+ return ops->get_avail_freqs(pkg, die, freqs, num);
+}
/**
* Return the list length of available frequencies in the index array.
@@ -221,10 +226,13 @@ extern rte_power_uncore_freqs_t rte_power_uncore_freqs;
* - The number of available index's in frequency array.
* - Negative on error.
*/
-typedef int (*rte_power_uncore_get_num_freqs_t)(unsigned int pkg, unsigned int die);
-
-extern rte_power_uncore_get_num_freqs_t rte_power_uncore_get_num_freqs;
+static inline int
+rte_power_uncore_get_num_freqs(unsigned int pkg, unsigned int die)
+{
+ struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops();
+ return ops->get_num_freqs(pkg, die);
+}
/**
* Return the number of packages (CPUs) on a system
* by parsing the uncore sysfs directory.
@@ -235,10 +243,13 @@ extern rte_power_uncore_get_num_freqs_t rte_power_uncore_get_num_freqs;
* - Zero on error.
* - Number of package on system on success.
*/
-typedef unsigned int (*rte_power_uncore_get_num_pkgs_t)(void);
-
-extern rte_power_uncore_get_num_pkgs_t rte_power_uncore_get_num_pkgs;
+static inline unsigned int
+rte_power_uncore_get_num_pkgs(void)
+{
+ struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops();
+ return ops->get_num_pkgs();
+}
/**
* Return the number of dies for pakckages (CPUs) specified
* from parsing the uncore sysfs directory.
@@ -253,9 +264,13 @@ extern rte_power_uncore_get_num_pkgs_t rte_power_uncore_get_num_pkgs;
* - Zero on error.
* - Number of dies for package on sucecss.
*/
-typedef unsigned int (*rte_power_uncore_get_num_dies_t)(unsigned int pkg);
+static inline unsigned int
+rte_power_uncore_get_num_dies(unsigned int pkg)
+{
+ struct rte_power_uncore_ops *ops = rte_power_get_uncore_ops();
-extern rte_power_uncore_get_num_dies_t rte_power_uncore_get_num_dies;
+ return ops->get_num_dies(pkg);
+}
#ifdef __cplusplus
}
new file mode 100644
@@ -0,0 +1,239 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 Intel Corporation
+ * Copyright(c) 2024 Advanced Micro Devices, Inc.
+ */
+
+#ifndef RTE_POWER_UNCORE_OPS_H
+#define RTE_POWER_UNCORE_OPS_H
+
+/**
+ * @file
+ * RTE Uncore Frequency Management
+ */
+
+#include <rte_compat.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RTE_POWER_UNCORE_DRIVER_NAMESZ 24
+
+/**
+ * Initialize uncore frequency management for specific die on a package.
+ * It will get the available frequencies and prepare to set new die frequencies.
+ *
+ * This function should NOT be called in the fast path.
+ *
+ * @param pkg
+ * Package number.
+ * Each physical CPU in a system is referred to as a package.
+ * @param die
+ * Die number.
+ * Each package can have several dies connected together via the uncore mesh.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+typedef int (*rte_power_uncore_init_t)(unsigned int pkg, unsigned int die);
+
+/**
+ * Exit uncore frequency management on a specific die on a package.
+ * It will restore uncore min and* max values to previous values
+ * before initialization of API.
+ *
+ * This function should NOT be called in the fast path.
+ *
+ * @param pkg
+ * Package number.
+ * Each physical CPU in a system is referred to as a package.
+ * @param die
+ * Die number.
+ * Each package can have several dies connected together via the uncore mesh.
+ *
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+typedef int (*rte_power_uncore_exit_t)(unsigned int pkg, unsigned int die);
+
+/**
+ * Return the current index of available frequencies of a specific die on a package.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * This function should NOT be called in the fast path.
+ *
+ * @param pkg
+ * Package number.
+ * Each physical CPU in a system is referred to as a package.
+ * @param die
+ * Die number.
+ * Each package can have several dies connected together via the uncore mesh.
+ *
+ * @return
+ * The current index of available frequencies.
+ * If error, it will return 'RTE_POWER_INVALID_FREQ_INDEX = (~0)'.
+ */
+typedef uint32_t (*rte_power_get_uncore_freq_t)(unsigned int pkg, unsigned int die);
+
+/**
+ * Set minimum and maximum uncore frequency for specified die on a package
+ * to specified index value.
+ * It should be protected outside of this function for threadsafe.
+ *
+ * This function should NOT be called in the fast path.
+ *
+ * @param pkg
+ * Package number.
+ * Each physical CPU in a system is referred to as a package.
+ * @param die
+ * Die number.
+ * Each package can have several dies connected together via the uncore mesh.
+ * @param index
+ * The index of available frequencies.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+typedef int (*rte_power_set_uncore_freq_t)(unsigned int pkg, unsigned int die, uint32_t index);
+
+/**
+ * Return the list length of available frequencies in the index array.
+ *
+ * This function should NOT be called in the fast path.
+ *
+ * @param pkg
+ * Package number.
+ * Each physical CPU in a system is referred to as a package.
+ * @param die
+ * Die number.
+ * Each package can have several dies connected together via the uncore mesh.
+ *
+ * @return
+ * - The number of available index's in frequency array.
+ * - Negative on error.
+ */
+typedef int (*rte_power_uncore_get_num_freqs_t)(unsigned int pkg, unsigned int die);
+
+/**
+ * Return the list of available frequencies in the index array.
+ *
+ * This function should NOT be called in the fast path.
+ *
+ * @param pkg
+ * Package number.
+ * Each physical CPU in a system is referred to as a package.
+ * @param die
+ * Die number.
+ * Each package can have several dies connected together via the uncore mesh.
+ * @param freqs
+ * The buffer array to save the frequencies.
+ * @param num
+ * The number of frequencies to get.
+ *
+ * @return
+ * - The number of available index's in frequency array.
+ * - Negative on error.
+ */
+typedef int (*rte_power_uncore_freqs_t)(unsigned int pkg, unsigned int die,
+ uint32_t *freqs, uint32_t num);
+/**
+ * Function pointers for generic frequency change functions.
+ *
+ * @param pkg
+ * Package number.
+ * Each physical CPU in a system is referred to as a package.
+ * @param die
+ * Die number.
+ * Each package can have several dies connected together via the uncore mesh.
+ *
+ * @return
+ * - 1 on success with frequency changed.
+ * - 0 on success without frequency changed.
+ * - Negative on error.
+ */
+typedef int (*rte_power_uncore_freq_change_t)(unsigned int pkg, unsigned int die);
+
+/**
+ * Return the number of packages (CPUs) on a system
+ * by parsing the uncore sysfs directory.
+ *
+ * This function should NOT be called in the fast path.
+ *
+ * @return
+ * - Zero on error.
+ * - Number of package on system on success.
+ */
+typedef unsigned int (*rte_power_uncore_get_num_pkgs_t)(void);
+
+/**
+ * Return the number of dies for pakckages (CPUs) specified
+ * from parsing the uncore sysfs directory.
+ *
+ * This function should NOT be called in the fast path.
+ *
+ * @param pkg
+ * Package number.
+ * Each physical CPU in a system is referred to as a package.
+ *
+ * @return
+ * - Zero on error.
+ * - Number of dies for package on sucecss.
+ */
+typedef unsigned int (*rte_power_uncore_get_num_dies_t)(unsigned int pkg);
+typedef void (*rte_power_uncore_driver_cb_t)(void);
+
+/** Structure defining uncore power operations structure */
+struct rte_power_uncore_ops {
+ RTE_TAILQ_ENTRY(rte_power_uncore_ops) next; /**< Next in list. */
+ char name[RTE_POWER_UNCORE_DRIVER_NAMESZ]; /**< power mgmt driver. */
+ rte_power_uncore_driver_cb_t cb; /**< Driver specific callbacks. */
+ rte_power_uncore_init_t init; /**< Initialize power management. */
+ rte_power_uncore_exit_t exit; /**< Exit power management. */
+ rte_power_uncore_get_num_pkgs_t get_num_pkgs;
+ rte_power_uncore_get_num_dies_t get_num_dies;
+ rte_power_uncore_get_num_freqs_t get_num_freqs; /**< Number of available frequencies. */
+ rte_power_uncore_freqs_t get_avail_freqs; /**< Get the available frequencies. */
+ rte_power_get_uncore_freq_t get_freq; /**< Get frequency index. */
+ rte_power_set_uncore_freq_t set_freq; /**< Set frequency index. */
+ rte_power_uncore_freq_change_t freq_max; /**< Scale up frequency to highest. */
+ rte_power_uncore_freq_change_t freq_min; /**< Scale up frequency to lowest. */
+};
+
+/**
+ * Register power uncore frequency operations.
+ * @param ops
+ * Pointer to an ops structure to register.
+ * @return
+ * - >=0: Success; return the index of the ops struct in the table.
+ * - -EINVAL - error while registering ops struct.
+ */
+__rte_internal
+int rte_power_register_uncore_ops(struct rte_power_uncore_ops *ops);
+
+/**
+ * Macro to statically register the ops of an uncore driver.
+ */
+#define RTE_POWER_REGISTER_UNCORE_OPS(ops) \
+ RTE_INIT(power_hdlr_init_uncore_##ops) \
+ { \
+ rte_power_register_uncore_ops(&ops); \
+ }
+
+/**
+ * @internal Get the power uncore ops struct from its index.
+ *
+ * @return
+ * The pointer to the ops struct in the table if registered.
+ */
+struct rte_power_uncore_ops *
+rte_power_get_uncore_ops(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RTE_POWER_UNCORE_H */
@@ -59,6 +59,7 @@ INTERNAL {
global:
rte_power_register_ops;
+ rte_power_register_uncore_ops;
cpufreq_check_scaling_driver;
power_set_governor;
open_core_sysfs_file;