From: Zhao Liu <zhao1.liu@xxxxxxxxx> The topology devices will be organized as a topology tree. Each topology device may have many topology children with lower topology level. Add the helpers to traverse the CPU topology tree. Signed-off-by: Zhao Liu <zhao1.liu@xxxxxxxxx> --- hw/core/cpu-topo.c | 41 ++++++++++++++++++++++++++++++++++++++ include/hw/core/cpu-topo.h | 13 ++++++++++++ 2 files changed, 54 insertions(+) diff --git a/hw/core/cpu-topo.c b/hw/core/cpu-topo.c index cba2dc747e74..687a4cc566ec 100644 --- a/hw/core/cpu-topo.c +++ b/hw/core/cpu-topo.c @@ -318,3 +318,44 @@ static void cpu_topo_register_types(void) } type_init(cpu_topo_register_types) + +static int do_cpu_topo_child_foreach(CPUTopoState *topo, + unsigned long *levels, + topo_fn fn, void *opaque, + bool recurse) +{ + CPUTopoState *child; + int ret = TOPO_FOREACH_CONTINUE; + + QTAILQ_FOREACH(child, &topo->children, sibling) { + if (!levels || (levels && test_bit(CPU_TOPO_LEVEL(child), levels))) { + ret = fn(child, opaque); + if (ret == TOPO_FOREACH_END || ret == TOPO_FOREACH_ERR) { + break; + } else if (ret == TOPO_FOREACH_SIBLING) { + continue; + } + } + + if (recurse) { + ret = do_cpu_topo_child_foreach(child, levels, fn, opaque, recurse); + if (ret != TOPO_FOREACH_CONTINUE) { + break; + } + } + } + return ret; +} + +int cpu_topo_child_foreach(CPUTopoState *topo, unsigned long *levels, + topo_fn fn, void *opaque) +{ + return do_cpu_topo_child_foreach(topo, levels, fn, opaque, false); +} + +int cpu_topo_child_foreach_recursive(CPUTopoState *topo, + unsigned long *levels, + topo_fn fn, void *opaque) +{ + return do_cpu_topo_child_foreach(topo, levels, fn, opaque, true); +} diff --git a/include/hw/core/cpu-topo.h b/include/hw/core/cpu-topo.h index 1ffdb0be6d38..453bacbb558b 100644 --- a/include/hw/core/cpu-topo.h +++ b/include/hw/core/cpu-topo.h @@ -90,4 +90,17 @@ struct CPUTopoState { #define CPU_TOPO_LEVEL(topo) (CPU_TOPO_GET_CLASS(topo)->level) +#define TOPO_FOREACH_SIBLING 2 +#define TOPO_FOREACH_END 1 +#define TOPO_FOREACH_CONTINUE 0 +#define TOPO_FOREACH_ERR -1 + +typedef int (*topo_fn)(CPUTopoState *topo, void *opaque); + +int cpu_topo_child_foreach(CPUTopoState *topo, unsigned long *levels, + topo_fn fn, void *opaque); +int cpu_topo_child_foreach_recursive(CPUTopoState *topo, + unsigned long *levels, + topo_fn fn, void *opaque); + #endif /* CPU_TOPO_H */ -- 2.34.1