[v5,01/15] x86/cpu: Create Hygon Dhyana architecture support file
diff mbox series

Message ID 0d6839a65753c60f4fd1738560a551ca7df7b1e8.1554382869.git.puwen@hygon.cn
State New, archived
Headers show
Series
  • Add support for Hygon Dhyana Family 18h processor
Related show

Commit Message

Pu Wen April 4, 2019, 1:45 p.m. UTC
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
and vendor ID "HygonGenuine" for system recognition, and fit the new
x86 vendor lookup mechanism.

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

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@hygon.cn>
---
 xen/arch/x86/cpu/Makefile         |   1 +
 xen/arch/x86/cpu/amd.c            |   2 +-
 xen/arch/x86/cpu/common.c         |   1 +
 xen/arch/x86/cpu/cpu.h            |   3 +
 xen/arch/x86/cpu/hygon.c          | 114 ++++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/x86-vendors.h |   7 ++-
 xen/lib/x86/cpuid.c               |   6 ++
 7 files changed, 132 insertions(+), 2 deletions(-)
 create mode 100644 xen/arch/x86/cpu/hygon.c

Comments

Andrew Cooper April 4, 2019, 2:02 p.m. UTC | #1
On 04/04/2019 14:45, Pu Wen wrote:
> index 774ceac..75fefcf 100644
> --- a/xen/include/asm-x86/x86-vendors.h
> +++ b/xen/include/asm-x86/x86-vendors.h
> @@ -30,6 +30,11 @@
>  #define X86_VENDOR_SHANGHAI_ECX 0x20206961U
>  #define X86_VENDOR_SHANGHAI_EDX 0x68676e61U
>  
> -#define X86_VENDOR_NUM 5
> +#define X86_VENDOR_HYGON 5
> +#define X86_VENDOR_HYGON_EBX 0x6f677948 /* "HygonGenuine" */
> +#define X86_VENDOR_HYGON_ECX 0x656e6975
> +#define X86_VENDOR_HYGON_EDX 0x6e65476e
> +
> +#define X86_VENDOR_NUM 6
>  
>  #endif	/* __XEN_X86_VENDORS_H__ */
> diff --git a/xen/lib/x86/cpuid.c b/xen/lib/x86/cpuid.c
> index 311d19e..d0b3ff7 100644
> --- a/xen/lib/x86/cpuid.c
> +++ b/xen/lib/x86/cpuid.c
> @@ -29,6 +29,12 @@ unsigned int x86_cpuid_lookup_vendor(uint32_t ebx, uint32_t ecx, uint32_t edx)
>               edx == X86_VENDOR_SHANGHAI_EDX )
>              return X86_VENDOR_SHANGHAI;
>          break;
> +
> +    case X86_VENDOR_HYGON_EBX:
> +        if ( ecx == X86_VENDOR_HYGON_ECX &&
> +             edx == X86_VENDOR_HYGON_EDX )
> +            return X86_VENDOR_HYGON;
> +        break;
>      }
>  
>      return X86_VENDOR_UNKNOWN;

This needs the following hunk folding in

diff --git a/tools/tests/cpu-policy/test-cpu-policy.c
b/tools/tests/cpu-policy/test-cpu-policy.c
index beced5e..88f5121 100644
--- a/tools/tests/cpu-policy/test-cpu-policy.c
+++ b/tools/tests/cpu-policy/test-cpu-policy.c
@@ -35,6 +35,7 @@ static void test_vendor_identification(void)
         { { "AuthenticAMD" }, X86_VENDOR_AMD },
         { { "CentaurHauls" }, X86_VENDOR_CENTAUR },
         { { "  Shanghai  " }, X86_VENDOR_SHANGHAI },
+        { { "HygonGenuine" }, X86_VENDOR_HYGON },
 
         { { ""             }, X86_VENDOR_UNKNOWN },
         { { "            " }, X86_VENDOR_UNKNOWN },

which can be done on commit to avoid sending yet another version.

~Andrew
Pu Wen April 4, 2019, 4:39 p.m. UTC | #2
On 2019/4/4 22:07, Andrew Cooper wrote:
> On 04/04/2019 14:45, Pu Wen wrote:
>> index 774ceac..75fefcf 100644
>> --- a/xen/include/asm-x86/x86-vendors.h
>> +++ b/xen/include/asm-x86/x86-vendors.h
>> @@ -30,6 +30,11 @@
>>   #define X86_VENDOR_SHANGHAI_ECX 0x20206961U
>>   #define X86_VENDOR_SHANGHAI_EDX 0x68676e61U
>>   
>> -#define X86_VENDOR_NUM 5
>> +#define X86_VENDOR_HYGON 5
>> +#define X86_VENDOR_HYGON_EBX 0x6f677948 /* "HygonGenuine" */
>> +#define X86_VENDOR_HYGON_ECX 0x656e6975
>> +#define X86_VENDOR_HYGON_EDX 0x6e65476e
>> +
>> +#define X86_VENDOR_NUM 6
>>   
>>   #endif	/* __XEN_X86_VENDORS_H__ */
>> diff --git a/xen/lib/x86/cpuid.c b/xen/lib/x86/cpuid.c
>> index 311d19e..d0b3ff7 100644
>> --- a/xen/lib/x86/cpuid.c
>> +++ b/xen/lib/x86/cpuid.c
>> @@ -29,6 +29,12 @@ unsigned int x86_cpuid_lookup_vendor(uint32_t ebx, uint32_t ecx, uint32_t edx)
>>                edx == X86_VENDOR_SHANGHAI_EDX )
>>               return X86_VENDOR_SHANGHAI;
>>           break;
>> +
>> +    case X86_VENDOR_HYGON_EBX:
>> +        if ( ecx == X86_VENDOR_HYGON_ECX &&
>> +             edx == X86_VENDOR_HYGON_EDX )
>> +            return X86_VENDOR_HYGON;
>> +        break;
>>       }
>>   
>>       return X86_VENDOR_UNKNOWN;
> 
> This needs the following hunk folding in
> 
> diff --git a/tools/tests/cpu-policy/test-cpu-policy.c
> b/tools/tests/cpu-policy/test-cpu-policy.c
> index beced5e..88f5121 100644
> --- a/tools/tests/cpu-policy/test-cpu-policy.c
> +++ b/tools/tests/cpu-policy/test-cpu-policy.c
> @@ -35,6 +35,7 @@ static void test_vendor_identification(void)
>           { { "AuthenticAMD" }, X86_VENDOR_AMD },
>           { { "CentaurHauls" }, X86_VENDOR_CENTAUR },
>           { { "  Shanghai  " }, X86_VENDOR_SHANGHAI },
> +        { { "HygonGenuine" }, X86_VENDOR_HYGON },
>   
>           { { ""             }, X86_VENDOR_UNKNOWN },
>           { { "            " }, X86_VENDOR_UNKNOWN },

I'm sorry for missing this file.

> which can be done on commit to avoid sending yet another version.

Do you mean I need to send a individual patch for this file instead of 
reworking the whole series?
Jan Beulich April 5, 2019, 7:49 a.m. UTC | #3
>>> On 04.04.19 at 18:39, <puwen@hygon.cn> wrote:
> On 2019/4/4 22:07, Andrew Cooper wrote:
>> This needs the following hunk folding in
>> 
>> diff --git a/tools/tests/cpu-policy/test-cpu-policy.c
>> b/tools/tests/cpu-policy/test-cpu-policy.c
>> index beced5e..88f5121 100644
>> --- a/tools/tests/cpu-policy/test-cpu-policy.c
>> +++ b/tools/tests/cpu-policy/test-cpu-policy.c
>> @@ -35,6 +35,7 @@ static void test_vendor_identification(void)
>>           { { "AuthenticAMD" }, X86_VENDOR_AMD },
>>           { { "CentaurHauls" }, X86_VENDOR_CENTAUR },
>>           { { "  Shanghai  " }, X86_VENDOR_SHANGHAI },
>> +        { { "HygonGenuine" }, X86_VENDOR_HYGON },
>>   
>>           { { ""             }, X86_VENDOR_UNKNOWN },
>>           { { "            " }, X86_VENDOR_UNKNOWN },
> 
> I'm sorry for missing this file.
> 
>> which can be done on commit to avoid sending yet another version.
> 
> Do you mean I need to send a individual patch for this file instead of 
> reworking the whole series?

I don't think that's necessary, unless other reasons arise for there
to be yet another round necessary. As Andrew says - this can easily
be done while committing.

Jan
Pu Wen April 12, 2019, 4:14 p.m. UTC | #4
On 2019/4/5 15:50, Jan Beulich wrote:
> On 04.04.19 at 18:39, <puwen@hygon.cn> wrote:
>> On 2019/4/4 22:07, Andrew Cooper wrote:
>>> This needs the following hunk folding in
>>> which can be done on commit to avoid sending yet another version.
>>
>> Do you mean I need to send a individual patch for this file instead of
>> reworking the whole series?
> 
> I don't think that's necessary, unless other reasons arise for there
> to be yet another round necessary. As Andrew says - this can easily
> be done while committing.

Hi Jan and Andrew,

How about the patches till now? Are they acceptable to commit?

Thx.
Wei Liu April 17, 2019, 3:03 p.m. UTC | #5
On Sat, Apr 13, 2019 at 12:14:14AM +0800, Pu Wen wrote:
> On 2019/4/5 15:50, Jan Beulich wrote:
> > On 04.04.19 at 18:39, <puwen@hygon.cn> wrote:
> > > On 2019/4/4 22:07, Andrew Cooper wrote:
> > > > This needs the following hunk folding in
> > > > which can be done on commit to avoid sending yet another version.
> > > 
> > > Do you mean I need to send a individual patch for this file instead of
> > > reworking the whole series?
> > 
> > I don't think that's necessary, unless other reasons arise for there
> > to be yet another round necessary. As Andrew says - this can easily
> > be done while committing.
> 
> Hi Jan and Andrew,
> 
> How about the patches till now? Are they acceptable to commit?

FYI we're trying to sort out issues with upstream CI system, so
committing these patches need to wait a bit. But don't worry, they will
eventually be committed (assuming all the acks and Rbs are in place).

Wei.

> 
> Thx.
> 
> -- 
> Regards,
> Pu Wen
Pu Wen April 18, 2019, 2:15 a.m. UTC | #6
On 2019/4/17 23:04, Wei Liu wrote:
> On Sat, Apr 13, 2019 at 12:14:14AM +0800, Pu Wen wrote:
>> On 2019/4/5 15:50, Jan Beulich wrote:
>>> On 04.04.19 at 18:39, <puwen@hygon.cn> wrote:
>>>> On 2019/4/4 22:07, Andrew Cooper wrote:
>>>>> This needs the following hunk folding in
>>>>> which can be done on commit to avoid sending yet another version.
>>>>
>>>> Do you mean I need to send a individual patch for this file instead of
>>>> reworking the whole series?
>>>
>>> I don't think that's necessary, unless other reasons arise for there
>>> to be yet another round necessary. As Andrew says - this can easily
>>> be done while committing.
>>
>> Hi Jan and Andrew,
>>
>> How about the patches till now? Are they acceptable to commit?
> 
> FYI we're trying to sort out issues with upstream CI system, so
> committing these patches need to wait a bit. But don't worry, they will
> eventually be committed (assuming all the acks and Rbs are in place).

Okay, thanks! But there's still no acks for this patch of the whole 
series, so I just worry about it. Could someone offer Acked-by tag for it?
Wei Liu April 18, 2019, 9:14 a.m. UTC | #7
On Thu, Apr 18, 2019 at 10:15:05AM +0800, Pu Wen wrote:
> On 2019/4/17 23:04, Wei Liu wrote:
> > On Sat, Apr 13, 2019 at 12:14:14AM +0800, Pu Wen wrote:
> > > On 2019/4/5 15:50, Jan Beulich wrote:
> > > > On 04.04.19 at 18:39, <puwen@hygon.cn> wrote:
> > > > > On 2019/4/4 22:07, Andrew Cooper wrote:
> > > > > > This needs the following hunk folding in
> > > > > > which can be done on commit to avoid sending yet another version.
> > > > > 
> > > > > Do you mean I need to send a individual patch for this file instead of
> > > > > reworking the whole series?
> > > > 
> > > > I don't think that's necessary, unless other reasons arise for there
> > > > to be yet another round necessary. As Andrew says - this can easily
> > > > be done while committing.
> > > 
> > > Hi Jan and Andrew,
> > > 
> > > How about the patches till now? Are they acceptable to commit?
> > 
> > FYI we're trying to sort out issues with upstream CI system, so
> > committing these patches need to wait a bit. But don't worry, they will
> > eventually be committed (assuming all the acks and Rbs are in place).
> 
> Okay, thanks! But there's still no acks for this patch of the whole series,
> so I just worry about it. Could someone offer Acked-by tag for it?

It would be either Jan or Andrew who needs to ack this patch.  Jan is
away at the moment. And a lot of us in Europe have a long Easter weekend
this week.

From my reading of their comments, you don't need to worry about getting
an ack.

Wei.

> 
> -- 
> Regards,
> Pu Wen

Patch
diff mbox series

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 7a73d62..6554d5d 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -526,7 +526,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 b2249b5..74c9426 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -691,6 +691,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 edc88b1..c3ae2ee 100644
--- a/xen/arch/x86/cpu/cpu.h
+++ b/xen/arch/x86/cpu/cpu.h
@@ -16,7 +16,10 @@  extern unsigned int opt_cpuid_mask_ext_ecx, opt_cpuid_mask_ext_edx;
 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..912849c
--- /dev/null
+++ b/xen/arch/x86/cpu/hygon.c
@@ -0,0 +1,114 @@ 
+#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)
+{
+	unsigned int 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 init_hygon(struct cpuinfo_x86 *c)
+{
+	unsigned long long value;
+
+	/*
+	 * Attempt to set lfence to be Dispatch Serialising.  This MSR almost
+	 * certainly isn't virtualised (and Xen at least will leak the real
+	 * value in but silently discard writes), as well as being per-core
+	 * rather than per-thread, so do a full safe read/write/readback cycle
+	 * in the worst case.
+	 */
+	if (rdmsr_safe(MSR_AMD64_DE_CFG, value))
+		/* Unable to read.  Assume the safer default. */
+		__clear_bit(X86_FEATURE_LFENCE_DISPATCH,
+			    c->x86_capability);
+	else if (value & AMD64_DE_CFG_LFENCE_SERIALISE)
+		/* Already dispatch serialising. */
+		__set_bit(X86_FEATURE_LFENCE_DISPATCH,
+			  c->x86_capability);
+	else if (wrmsr_safe(MSR_AMD64_DE_CFG,
+			    value | AMD64_DE_CFG_LFENCE_SERIALISE) ||
+		 rdmsr_safe(MSR_AMD64_DE_CFG, value) ||
+		 !(value & AMD64_DE_CFG_LFENCE_SERIALISE))
+		/* Attempt to set failed.  Assume the safer default. */
+		__clear_bit(X86_FEATURE_LFENCE_DISPATCH,
+			    c->x86_capability);
+	else
+		/* Successfully enabled! */
+		__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);
+	}
+
+	/* MFENCE stops RDTSC speculation */
+	if (!cpu_has_lfence_dispatch)
+		__set_bit(X86_FEATURE_MFENCE_RDTSC, c->x86_capability);
+
+	display_cacheinfo(c);
+
+	if (c->extended_cpuid_level >= 0x80000008)
+		c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
+
+	if (c->extended_cpuid_level >= 0x80000007) {
+		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);
+		}
+	}
+
+	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)) {
+		rdmsrl(MSR_K7_HWCR, value);
+		value |= (1 << 27); /* Enable read-only APERF/MPERF bit */
+		wrmsrl(MSR_K7_HWCR, value);
+	}
+}
+
+static const struct cpu_dev hygon_cpu_dev = {
+	.c_vendor	= "Hygon",
+	.c_early_init	= early_init_amd,
+	.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 774ceac..75fefcf 100644
--- a/xen/include/asm-x86/x86-vendors.h
+++ b/xen/include/asm-x86/x86-vendors.h
@@ -30,6 +30,11 @@ 
 #define X86_VENDOR_SHANGHAI_ECX 0x20206961U
 #define X86_VENDOR_SHANGHAI_EDX 0x68676e61U
 
-#define X86_VENDOR_NUM 5
+#define X86_VENDOR_HYGON 5
+#define X86_VENDOR_HYGON_EBX 0x6f677948 /* "HygonGenuine" */
+#define X86_VENDOR_HYGON_ECX 0x656e6975
+#define X86_VENDOR_HYGON_EDX 0x6e65476e
+
+#define X86_VENDOR_NUM 6
 
 #endif	/* __XEN_X86_VENDORS_H__ */
diff --git a/xen/lib/x86/cpuid.c b/xen/lib/x86/cpuid.c
index 311d19e..d0b3ff7 100644
--- a/xen/lib/x86/cpuid.c
+++ b/xen/lib/x86/cpuid.c
@@ -29,6 +29,12 @@  unsigned int x86_cpuid_lookup_vendor(uint32_t ebx, uint32_t ecx, uint32_t edx)
              edx == X86_VENDOR_SHANGHAI_EDX )
             return X86_VENDOR_SHANGHAI;
         break;
+
+    case X86_VENDOR_HYGON_EBX:
+        if ( ecx == X86_VENDOR_HYGON_ECX &&
+             edx == X86_VENDOR_HYGON_EDX )
+            return X86_VENDOR_HYGON;
+        break;
     }
 
     return X86_VENDOR_UNKNOWN;