[PATCH v4 11/16] target/i386: Load apicid model specific handlers from X86CPUDefinition

Babu Moger posted 16 patches 5 years, 12 months ago
There is a newer version of this series
[PATCH v4 11/16] target/i386: Load apicid model specific handlers from X86CPUDefinition
Posted by Babu Moger 5 years, 12 months ago
Load the model specific handlers if available or else default handlers
will be loaded. Add the model specific handlers if apicid decoding
differs from the standard sequential numbering.

Signed-off-by: Babu Moger <babu.moger@amd.com>
---
 target/i386/cpu.c |   38 ++++++++++++++++++++++++++++++++++++++
 target/i386/cpu.h |    1 +
 2 files changed, 39 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 19675eb696..389b68d765 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1614,6 +1614,16 @@ typedef struct X86CPUDefinition {
     FeatureWordArray features;
     const char *model_id;
     CPUCaches *cache_info;
+
+    /* Apic id specific handlers */
+    uint32_t (*apicid_from_cpu_idx)(X86CPUTopoInfo *topo_info,
+                                    unsigned cpu_index);
+    void (*topo_ids_from_apicid)(apic_id_t apicid, X86CPUTopoInfo *topo_info,
+                                 X86CPUTopoIDs *topo_ids);
+    apic_id_t (*apicid_from_topo_ids)(X86CPUTopoInfo *topo_info,
+                                      const X86CPUTopoIDs *topo_ids);
+    uint32_t (*apicid_pkg_offset)(X86CPUTopoInfo *topo_info);
+
     /*
      * Definitions for alternative versions of CPU model.
      * List is terminated by item with version == 0.
@@ -1654,6 +1664,34 @@ static const X86CPUVersionDefinition *x86_cpu_def_get_versions(X86CPUDefinition
     return def->versions ?: default_version_list;
 }
 
+void cpu_x86_init_apicid_fns(MachineState *machine)
+{
+    X86CPUClass *xcc = X86_CPU_CLASS(object_class_by_name(machine->cpu_type));
+    X86CPUModel *model = xcc->model;
+    X86CPUDefinition *def = model->cpudef;
+    X86MachineState *x86ms = X86_MACHINE(machine);
+
+    if (def) {
+        if (def->apicid_from_cpu_idx) {
+            x86ms->apicid_from_cpu_idx = def->apicid_from_cpu_idx;
+        }
+        if (def->topo_ids_from_apicid) {
+            x86ms->topo_ids_from_apicid = def->topo_ids_from_apicid;
+        }
+        if (def->apicid_from_topo_ids) {
+            x86ms->apicid_from_topo_ids = def->apicid_from_topo_ids;
+        }
+        if (def->apicid_pkg_offset) {
+            x86ms->apicid_pkg_offset = def->apicid_pkg_offset;
+        }
+    } else {
+            x86ms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx;
+            x86ms->topo_ids_from_apicid = x86_topo_ids_from_apicid;
+            x86ms->apicid_from_topo_ids = x86_apicid_from_topo_ids;
+            x86ms->apicid_pkg_offset = apicid_pkg_offset;
+    }
+}
+
 static CPUCaches epyc_cache_info = {
     .l1d_cache = &(CPUCacheInfo) {
         .type = DATA_CACHE,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 627a8cb9be..64a1cca690 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1889,6 +1889,7 @@ void cpu_clear_apic_feature(CPUX86State *env);
 void host_cpuid(uint32_t function, uint32_t count,
                 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
 void host_vendor_fms(char *vendor, int *family, int *model, int *stepping);
+void cpu_x86_init_apicid_fns(MachineState *machine);
 
 /* helper.c */
 bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,