@@ -103,6 +103,82 @@ inline void init_apicid_topo_info(X86ApicidTopoInfo *apicid_topo,
}
}
+/*
+ * Calculate thread/core/package IDs for a specific topology,
+ * based on (contiguous) CPU index
+ */
+static void x86_topo_ids_from_idx(X86MachineState *x86ms,
+ unsigned cpu_index,
+ X86CPUTopoIDs *topo_ids)
+{
+ MachineState *ms = MACHINE(x86ms);
+ unsigned nr_dies;
+ unsigned nr_modules;
+ unsigned nr_cores;
+ unsigned nr_threads;
+ unsigned cpus_per_pkg;
+ unsigned cpus_per_die;
+
+ nr_dies = machine_topo_get_dies(ms);
+ nr_modules = machine_topo_get_clusters(ms);
+ cpus_per_pkg = machine_topo_get_threads_per_socket(ms);
+ cpus_per_die = cpus_per_pkg / nr_dies;
+
+ topo_ids->pkg_id = cpu_index / cpus_per_pkg;
+ topo_ids->die_id = cpu_index / cpus_per_die % nr_dies;
+
+ if (machine_topo_is_smp(ms)) {
+ nr_cores = machine_topo_get_smp_cores(ms);
+ nr_threads = machine_topo_get_smp_threads(ms);
+
+ topo_ids->module_id = cpu_index / (nr_cores * nr_threads) %
+ nr_modules;
+ topo_ids->core_id = cpu_index / nr_threads % nr_cores;
+ topo_ids->smt_id = cpu_index % nr_threads;
+ } else {
+ /*
+ * Next we need to traverse in the die, so scale the cpu_index to
+ * the relative index in the die.
+ */
+ int idx = cpu_index % cpus_per_die;
+
+ topo_ids->module_id = 0;
+ topo_ids->core_id = 0;
+ topo_ids->smt_id = 0;
+
+ for (int i = 0; i < nr_modules; i++) {
+ nr_cores = machine_topo_get_cores(ms, i);
+
+ for (int j = 0; j < nr_cores; j++) {
+ nr_threads = machine_topo_get_threads(ms, i, j);
+
+ if (idx < nr_threads) {
+ topo_ids->module_id = i;
+ topo_ids->core_id = j;
+ topo_ids->smt_id = idx;
+ return;
+ } else {
+ idx -= nr_threads;
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Make APIC ID for the CPU 'cpu_index'
+ *
+ * 'cpu_index' is a sequential, contiguous ID for the CPU.
+ */
+static inline apic_id_t x86_apicid_from_cpu_idx(X86MachineState *x86ms,
+ X86ApicidTopoInfo *apicid_topo,
+ unsigned cpu_index)
+{
+ X86CPUTopoIDs topo_ids;
+ x86_topo_ids_from_idx(x86ms, cpu_index, &topo_ids);
+ return x86_apicid_from_topo_ids(apicid_topo, &topo_ids);
+}
+
/*
* Calculates initial APIC ID for a specific CPU index
*
@@ -118,7 +194,7 @@ uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms,
init_apicid_topo_info(&apicid_topo, x86ms);
- return x86_apicid_from_cpu_idx(&apicid_topo, cpu_index);
+ return x86_apicid_from_cpu_idx(x86ms, &apicid_topo, cpu_index);
}
@@ -153,29 +153,6 @@ static inline apic_id_t x86_apicid_from_topo_ids(X86ApicidTopoInfo *apicid_topo,
topo_ids->smt_id;
}
-/*
- * Calculate thread/core/package IDs for a specific topology,
- * based on (contiguous) CPU index
- */
-static inline void x86_topo_ids_from_idx(X86ApicidTopoInfo *apicid_topo,
- unsigned cpu_index,
- X86CPUTopoIDs *topo_ids)
-{
- unsigned nr_dies = apicid_topo->max_dies;
- unsigned nr_modules = apicid_topo->max_modules;
- unsigned nr_cores = apicid_topo->max_cores;
- unsigned nr_threads = apicid_topo->max_threads;
-
- topo_ids->pkg_id = cpu_index / (nr_dies * nr_modules *
- nr_cores * nr_threads);
- topo_ids->die_id = cpu_index / (nr_modules * nr_cores *
- nr_threads) % nr_dies;
- topo_ids->module_id = cpu_index / (nr_cores * nr_threads) %
- nr_modules;
- topo_ids->core_id = cpu_index / nr_threads % nr_cores;
- topo_ids->smt_id = cpu_index % nr_threads;
-}
-
/*
* Calculate thread/core/package IDs for a specific topology,
* based on APIC ID
@@ -198,17 +175,4 @@ static inline void x86_topo_ids_from_apicid(apic_id_t apicid,
topo_ids->pkg_id = apicid >> apicid_pkg_offset(apicid_topo);
}
-/*
- * Make APIC ID for the CPU 'cpu_index'
- *
- * 'cpu_index' is a sequential, contiguous ID for the CPU.
- */
-static inline apic_id_t x86_apicid_from_cpu_idx(X86ApicidTopoInfo *apicid_topo,
- unsigned cpu_index)
-{
- X86CPUTopoIDs topo_ids;
- x86_topo_ids_from_idx(apicid_topo, cpu_index, &topo_ids);
- return x86_apicid_from_topo_ids(apicid_topo, &topo_ids);
-}
-
#endif /* HW_I386_TOPOLOGY_H */
@@ -23,9 +23,36 @@
*/
#include "qemu/osdep.h"
-
+#include "hw/core/cpu.h"
#include "hw/i386/topology.h"
+static void x86_smp_test_topo_ids_from_idx(X86ApicidTopoInfo *apicid_topo,
+ unsigned cpu_index,
+ X86CPUTopoIDs *topo_ids)
+{
+ unsigned nr_dies = apicid_topo->max_dies;
+ unsigned nr_modules = apicid_topo->max_modules;
+ unsigned nr_cores = apicid_topo->max_cores;
+ unsigned nr_threads = apicid_topo->max_threads;
+
+ topo_ids->pkg_id = cpu_index / (nr_dies * nr_modules *
+ nr_cores * nr_threads);
+ topo_ids->die_id = cpu_index / (nr_modules * nr_cores
+ * nr_threads) % nr_dies;
+ topo_ids->module_id = cpu_index / (nr_cores * nr_threads) % nr_modules;
+ topo_ids->core_id = cpu_index / nr_threads % nr_cores;
+ topo_ids->smt_id = cpu_index % nr_threads;
+}
+
+static apic_id_t
+x86_smp_test_apicid_from_cpu_idx(X86ApicidTopoInfo *apicid_topo,
+ unsigned cpu_index)
+{
+ X86CPUTopoIDs topo_ids;
+ x86_smp_test_topo_ids_from_idx(apicid_topo, cpu_index, &topo_ids);
+ return x86_apicid_from_topo_ids(apicid_topo, &topo_ids);
+}
+
static void test_topo_bits(void)
{
X86ApicidTopoInfo apicid_topo = {0};
@@ -41,10 +68,10 @@ static void test_topo_bits(void)
g_assert_cmpuint(apicid_die_width(&apicid_topo), ==, 0);
apicid_topo = (X86ApicidTopoInfo) {1, 1, 1, 1};
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 0), ==, 0);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 1), ==, 1);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 2), ==, 2);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 3), ==, 3);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 0), ==, 0);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 1), ==, 1);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 2), ==, 2);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 3), ==, 3);
/* Test field width calculation for multiple values
@@ -106,37 +133,37 @@ static void test_topo_bits(void)
g_assert_cmpuint(apicid_pkg_offset(&apicid_topo), ==, 5);
apicid_topo = (X86ApicidTopoInfo) {1, 1, 6, 3};
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 0), ==, 0);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 1), ==, 1);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 2), ==, 2);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 0), ==, 0);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 1), ==, 1);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 2), ==, 2);
apicid_topo = (X86ApicidTopoInfo) {1, 1, 6, 3};
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 1 * 3 + 0), ==,
- (1 << 2) | 0);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 1 * 3 + 1), ==,
- (1 << 2) | 1);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 1 * 3 + 2), ==,
- (1 << 2) | 2);
-
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 2 * 3 + 0), ==,
- (2 << 2) | 0);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 2 * 3 + 1), ==,
- (2 << 2) | 1);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 2 * 3 + 2), ==,
- (2 << 2) | 2);
-
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 5 * 3 + 0), ==,
- (5 << 2) | 0);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 5 * 3 + 1), ==,
- (5 << 2) | 1);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo, 5 * 3 + 2), ==,
- (5 << 2) | 2);
-
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo,
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 1 * 3 + 0),
+ ==, (1 << 2) | 0);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 1 * 3 + 1),
+ ==, (1 << 2) | 1);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 1 * 3 + 2),
+ ==, (1 << 2) | 2);
+
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 2 * 3 + 0),
+ ==, (2 << 2) | 0);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 2 * 3 + 1),
+ ==, (2 << 2) | 1);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 2 * 3 + 2),
+ ==, (2 << 2) | 2);
+
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 5 * 3 + 0),
+ ==, (5 << 2) | 0);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 5 * 3 + 1),
+ ==, (5 << 2) | 1);
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo, 5 * 3 + 2),
+ ==, (5 << 2) | 2);
+
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo,
1 * 6 * 3 + 0 * 3 + 0), ==, (1 << 5));
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo,
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo,
1 * 6 * 3 + 1 * 3 + 1), ==, (1 << 5) | (1 << 2) | 1);
- g_assert_cmpuint(x86_apicid_from_cpu_idx(&apicid_topo,
+ g_assert_cmpuint(x86_smp_test_apicid_from_cpu_idx(&apicid_topo,
3 * 6 * 3 + 5 * 3 + 2), ==, (3 << 5) | (5 << 2) | 2);
}