[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v3 01/14] x86/cpu: Create Hygon Dhyana architecture support file



Add x86 architecture support for a new processor: Hygon Dhyana Family
18h. To make Hygon initialization flow more clear, carve out code from
amd.c into a separate file hygon.c, and remove unnecessary code for
Hygon Dhyana.

To identify Hygon Dhyana CPU, add a new vendor type X86_VENDOR_HYGON
for system recognition.

Hygon can fully use the function early_init_amd(), so make this common
function non-static and direct call it from Hygon code.

As opt_cpuid_mask_l7s0_eax and opt_cpuid_mask_l7s0_ebx are used by both
AMD and Hygon, so move them to common.c.

Hygon Dhyana has no CPUID faulting, so directly return false in the
function probe_cpuid_faulting().

Add a separate hygon_get_topology(), which calculate phys_proc_id from
AcpiId[6](see reference [1]).

Reference:
[1] https://git.kernel.org/tip/e0ceeae708cebf22c990c3d703a4ca187dc837f5

Signed-off-by: Pu Wen <puwen@xxxxxxxx>
---
 xen/arch/x86/cpu/Makefile         |  1 +
 xen/arch/x86/cpu/amd.c            |  7 +--
 xen/arch/x86/cpu/common.c         |  9 ++++
 xen/arch/x86/cpu/cpu.h            |  4 ++
 xen/arch/x86/cpu/hygon.c          | 95 +++++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/x86-vendors.h |  3 +-
 6 files changed, 112 insertions(+), 7 deletions(-)
 create mode 100644 xen/arch/x86/cpu/hygon.c

diff --git a/xen/arch/x86/cpu/Makefile b/xen/arch/x86/cpu/Makefile
index 34a01ca..466acc8 100644
--- a/xen/arch/x86/cpu/Makefile
+++ b/xen/arch/x86/cpu/Makefile
@@ -4,6 +4,7 @@ subdir-y += mtrr
 obj-y += amd.o
 obj-y += centaur.o
 obj-y += common.o
+obj-y += hygon.o
 obj-y += intel.o
 obj-y += intel_cacheinfo.o
 obj-y += mwait-idle.o
diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index c790416..812d54d 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -32,11 +32,6 @@
 static char __initdata opt_famrev[14];
 string_param("cpuid_mask_cpu", opt_famrev);
 
-static unsigned int __initdata opt_cpuid_mask_l7s0_eax = ~0u;
-integer_param("cpuid_mask_l7s0_eax", opt_cpuid_mask_l7s0_eax);
-static unsigned int __initdata opt_cpuid_mask_l7s0_ebx = ~0u;
-integer_param("cpuid_mask_l7s0_ebx", opt_cpuid_mask_l7s0_ebx);
-
 static unsigned int __initdata opt_cpuid_mask_thermal_ecx = ~0u;
 integer_param("cpuid_mask_thermal_ecx", opt_cpuid_mask_thermal_ecx);
 
@@ -526,7 +521,7 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
                                                           : c->cpu_core_id);
 }
 
-static void early_init_amd(struct cpuinfo_x86 *c)
+void early_init_amd(struct cpuinfo_x86 *c)
 {
        if (c == &boot_cpu_data)
                amd_init_levelling();
diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 53bb0a9..9fb75dd 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -36,6 +36,11 @@ integer_param("cpuid_mask_ext_ecx", opt_cpuid_mask_ext_ecx);
 unsigned int opt_cpuid_mask_ext_edx = ~0u;
 integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx);
 
+unsigned int  opt_cpuid_mask_l7s0_eax = ~0u;
+integer_param("cpuid_mask_l7s0_eax", opt_cpuid_mask_l7s0_eax);
+unsigned int  opt_cpuid_mask_l7s0_ebx = ~0u;
+integer_param("cpuid_mask_l7s0_ebx", opt_cpuid_mask_l7s0_ebx);
+
 unsigned int __initdata expected_levelling_cap;
 unsigned int __read_mostly levelling_caps;
 
@@ -116,6 +121,9 @@ bool __init probe_cpuid_faulting(void)
        uint64_t val;
        int rc;
 
+       if(boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
+               return false;
+
        if ((rc = rdmsr_safe(MSR_INTEL_PLATFORM_INFO, val)) == 0)
                raw_msr_policy.plaform_info.cpuid_faulting =
                        val & MSR_PLATFORM_INFO_CPUID_FAULTING;
@@ -710,6 +718,7 @@ void __init early_cpu_init(void)
        amd_init_cpu();
        centaur_init_cpu();
        shanghai_init_cpu();
+       hygon_init_cpu();
        early_cpu_detect();
 }
 
diff --git a/xen/arch/x86/cpu/cpu.h b/xen/arch/x86/cpu/cpu.h
index 2fcb931..971077a 100644
--- a/xen/arch/x86/cpu/cpu.h
+++ b/xen/arch/x86/cpu/cpu.h
@@ -13,11 +13,15 @@ extern bool_t opt_arat;
 extern unsigned int opt_cpuid_mask_ecx, opt_cpuid_mask_edx;
 extern unsigned int opt_cpuid_mask_xsave_eax;
 extern unsigned int opt_cpuid_mask_ext_ecx, opt_cpuid_mask_ext_edx;
+extern unsigned int opt_cpuid_mask_l7s0_eax, opt_cpuid_mask_l7s0_ebx;
 
 extern int get_model_name(struct cpuinfo_x86 *c);
 extern void display_cacheinfo(struct cpuinfo_x86 *c);
 
+void early_init_amd(struct cpuinfo_x86 *c);
+
 int intel_cpu_init(void);
 int amd_init_cpu(void);
 int centaur_init_cpu(void);
 int shanghai_init_cpu(void);
+int hygon_init_cpu(void);
diff --git a/xen/arch/x86/cpu/hygon.c b/xen/arch/x86/cpu/hygon.c
new file mode 100644
index 0000000..bbe13c5
--- /dev/null
+++ b/xen/arch/x86/cpu/hygon.c
@@ -0,0 +1,95 @@
+#include <xen/init.h>
+#include <asm/processor.h>
+#include <asm/hvm/support.h>
+#include <asm/spec_ctrl.h>
+
+#include "cpu.h"
+
+#define APICID_SOCKET_ID_BIT 6
+
+static void hygon_get_topology(struct cpuinfo_x86 *c)
+{
+       u32 ebx;
+
+       if (c->x86_max_cores <= 1)
+               return;
+
+       /* Socket ID is ApicId[6] for Hygon processors. */
+       c->phys_proc_id >>= APICID_SOCKET_ID_BIT;
+
+       ebx = cpuid_ebx(0x8000001e);
+       c->x86_num_siblings = ((ebx >> 8) & 0x3) + 1;
+       c->x86_max_cores /= c->x86_num_siblings;
+       c->cpu_core_id = ebx & 0xff;
+
+       if (opt_cpu_info)
+               printk("CPU %d(%d) -> Processor %d, Core %d\n",
+                       smp_processor_id(), c->x86_max_cores,
+                               c->phys_proc_id, c->cpu_core_id);
+}
+
+static void early_init_hygon(struct cpuinfo_x86 *c)
+{
+       early_init_amd(c);
+}
+
+static void init_hygon(struct cpuinfo_x86 *c)
+{
+       u32 l, h;
+       unsigned long long value;
+
+       /* Attempt to set LFENCE to be Dispatch Serialising. */
+       if (rdmsr_safe(MSR_AMD64_DE_CFG, value))
+               /* Unable to read.  Assume the safer default. */
+               __clear_bit(X86_FEATURE_LFENCE_DISPATCH, c->x86_capability);
+       if (value & AMD64_DE_CFG_LFENCE_SERIALISE)
+               /* Dispatch Serialising. */
+               __set_bit(X86_FEATURE_LFENCE_DISPATCH, c->x86_capability);
+
+       /*
+        * If the user has explicitly chosen to disable Memory Disambiguation
+        * to mitigiate Speculative Store Bypass, poke the appropriate MSR.
+        */
+       if (opt_ssbd && !rdmsr_safe(MSR_AMD64_LS_CFG, value)) {
+               value |= 1ull << 10;
+               wrmsr_safe(MSR_AMD64_LS_CFG, value);
+       }
+
+       display_cacheinfo(c);
+
+       if (cpu_has(c, X86_FEATURE_ITSC)) {
+               __set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
+               __set_bit(X86_FEATURE_NONSTOP_TSC, c->x86_capability);
+               __set_bit(X86_FEATURE_TSC_RELIABLE, c->x86_capability);
+       }
+
+       c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
+
+       hygon_get_topology(c);
+
+       /* Hygon CPUs do not support SYSENTER outside of legacy mode. */
+       __clear_bit(X86_FEATURE_SEP, c->x86_capability);
+
+       /* Hygon processors have APIC timer running in deep C states. */
+       if (opt_arat)
+               __set_bit(X86_FEATURE_ARAT, c->x86_capability);
+
+       if (cpu_has(c, X86_FEATURE_EFRO)) {
+               rdmsr(MSR_K7_HWCR, l, h);
+               l |= (1 << 27); /* Enable read-only APERF/MPERF bit */
+               wrmsr(MSR_K7_HWCR, l, h);
+       }
+}
+
+static const struct cpu_dev hygon_cpu_dev = {
+       .c_vendor       = "Hygon",
+       .c_ident        = { "HygonGenuine" },
+       .c_early_init   = early_init_hygon,
+       .c_init         = init_hygon,
+};
+
+int __init hygon_init_cpu(void)
+{
+       cpu_devs[X86_VENDOR_HYGON] = &hygon_cpu_dev;
+       return 0;
+}
diff --git a/xen/include/asm-x86/x86-vendors.h 
b/xen/include/asm-x86/x86-vendors.h
index 38a81c3..fa1cbb4 100644
--- a/xen/include/asm-x86/x86-vendors.h
+++ b/xen/include/asm-x86/x86-vendors.h
@@ -9,6 +9,7 @@
 #define X86_VENDOR_AMD 2
 #define X86_VENDOR_CENTAUR 3
 #define X86_VENDOR_SHANGHAI 4
-#define X86_VENDOR_NUM 5
+#define X86_VENDOR_HYGON 5
+#define X86_VENDOR_NUM 6
 
 #endif /* __XEN_X86_VENDORS_H__ */
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.