diff mbox series

mtrr: refine memory type above 4GB on AMD platforms

Message ID 20201117033847.365918-1-alex.hung@canonical.com
State Superseded
Headers show
Series mtrr: refine memory type above 4GB on AMD platforms | expand

Commit Message

Alex Hung Nov. 17, 2020, 3:38 a.m. UTC
Buglink: https://bugs.launchpad.net/bugs/1901146

1. amd_Tom2ForceMemTypeWB only works from 4GB and top of memory 2 (TOM2)
2. amd_Tom2ForceMemTypeWB can be overridden by MTRR
3. amd_Tom2ForceMemTypeWB overrides MTRR_DEF_TYPE

Signed-off-by: Alex Hung <alex.hung@canonical.com>
---
 src/bios/mtrr/mtrr.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

Comments

Colin Ian King Nov. 17, 2020, 11:29 a.m. UTC | #1
On 17/11/2020 03:38, Alex Hung wrote:
> Buglink: https://bugs.launchpad.net/bugs/1901146
> 
> 1. amd_Tom2ForceMemTypeWB only works from 4GB and top of memory 2 (TOM2)
> 2. amd_Tom2ForceMemTypeWB can be overridden by MTRR
> 3. amd_Tom2ForceMemTypeWB overrides MTRR_DEF_TYPE
> 
> Signed-off-by: Alex Hung <alex.hung@canonical.com>
> ---
>  src/bios/mtrr/mtrr.c | 16 ++++++++++------
>  1 file changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/src/bios/mtrr/mtrr.c b/src/bios/mtrr/mtrr.c
> index e064f9c4..c9b77941 100644
> --- a/src/bios/mtrr/mtrr.c
> +++ b/src/bios/mtrr/mtrr.c
> @@ -51,8 +51,10 @@ static fwts_cpuinfo_x86 *fwts_cpuinfo;
>  
>  #define MTRR_DEF_TYPE_MSR	0x2FF
>  #define AMD_SYS_CFG_MSR		0xC0010010
> +#define AMD_TOM2_MSR		0xC001001D
>  
>  static	uint64_t mtrr_default;
> +static	uint64_t amd_tom2_addr;
>  static	bool amd_Tom2ForceMemTypeWB = false;
>  
>  struct mtrr_entry {
> @@ -195,6 +197,9 @@ static int get_default_mtrr(fwts_framework *fw)
>  		if (fwts_cpu_readmsr(fw, 0, AMD_SYS_CFG_MSR, &amd_sys_conf) == FWTS_OK)
>  			if (amd_sys_conf & 0x200000)
>  				amd_Tom2ForceMemTypeWB = true;
> +
> +		if (fwts_cpu_readmsr(fw, 0, AMD_TOM2_MSR, &amd_tom2_addr) != FWTS_OK)
> +			amd_tom2_addr = 0x100000000;	// this should above 4G

I'd rather not have // style comments in fwts if that's OK.

>  	}
>  
>  	if (fwts_cpu_readmsr(fw, 0, MTRR_DEF_TYPE_MSR, &mtrr_default) == FWTS_OK) {
> @@ -229,12 +234,6 @@ static int cache_types(uint64_t start, uint64_t end)
>  	struct mtrr_entry *entry;
>  	int type = 0;
>  
> -	/* On AMD platforms, Tom2ForceMemTypeWB overwrites other memory types */
> -	if (amd_Tom2ForceMemTypeWB && start >= 0x100000000) {
> -		type = WRITE_BACK;
> -		return type;
> -	}
> -
>  	fwts_list_foreach(item, mtrr_list) {
>  		entry = fwts_list_data(struct mtrr_entry*, item);
>  
> @@ -242,6 +241,11 @@ static int cache_types(uint64_t start, uint64_t end)
>  			type |= entry->type;
>  	}
>  
> +	/* On AMD platforms, Tom2ForceMemTypeWB overwrites MTRRdefType */
> +	if (type == 0 && (strstr(fwts_cpuinfo->vendor_id, "AMD") || strstr(fwts_cpuinfo->vendor_id, "Hygon")))
> +		if (amd_Tom2ForceMemTypeWB && start >= 0x100000000 && start <= amd_tom2_addr)
> +			return WRITE_BACK;
> +

The second if statement could be replaced with a further && clause,
something like:

	if ((type == 0) &&
            (strstr(fwts_cpuinfo->vendor_id, "AMD") ||
strstr(fwts_cpuinfo->vendor_id, "Hygon")) &&
            (amd_Tom2ForceMemTypeWB && (start >= 0x100000000) && (start
<= amd_tom2_addr)))
		return WRITE_BACK;



>  	/*
>  	 * now to see if there is any part of the range that isn't
>  	 * covered by an mtrr, since it's UNCACHED if so
>
Alex Hung Nov. 17, 2020, 7:10 p.m. UTC | #2
On 2020-11-17 4:29 a.m., Colin Ian King wrote:
> On 17/11/2020 03:38, Alex Hung wrote:
>> Buglink: https://bugs.launchpad.net/bugs/1901146
>>
>> 1. amd_Tom2ForceMemTypeWB only works from 4GB and top of memory 2 (TOM2)
>> 2. amd_Tom2ForceMemTypeWB can be overridden by MTRR
>> 3. amd_Tom2ForceMemTypeWB overrides MTRR_DEF_TYPE
>>
>> Signed-off-by: Alex Hung <alex.hung@canonical.com>
>> ---
>>  src/bios/mtrr/mtrr.c | 16 ++++++++++------
>>  1 file changed, 10 insertions(+), 6 deletions(-)
>>
>> diff --git a/src/bios/mtrr/mtrr.c b/src/bios/mtrr/mtrr.c
>> index e064f9c4..c9b77941 100644
>> --- a/src/bios/mtrr/mtrr.c
>> +++ b/src/bios/mtrr/mtrr.c
>> @@ -51,8 +51,10 @@ static fwts_cpuinfo_x86 *fwts_cpuinfo;
>>  
>>  #define MTRR_DEF_TYPE_MSR	0x2FF
>>  #define AMD_SYS_CFG_MSR		0xC0010010
>> +#define AMD_TOM2_MSR		0xC001001D
>>  
>>  static	uint64_t mtrr_default;
>> +static	uint64_t amd_tom2_addr;
>>  static	bool amd_Tom2ForceMemTypeWB = false;
>>  
>>  struct mtrr_entry {
>> @@ -195,6 +197,9 @@ static int get_default_mtrr(fwts_framework *fw)
>>  		if (fwts_cpu_readmsr(fw, 0, AMD_SYS_CFG_MSR, &amd_sys_conf) == FWTS_OK)
>>  			if (amd_sys_conf & 0x200000)
>>  				amd_Tom2ForceMemTypeWB = true;
>> +
>> +		if (fwts_cpu_readmsr(fw, 0, AMD_TOM2_MSR, &amd_tom2_addr) != FWTS_OK)
>> +			amd_tom2_addr = 0x100000000;	// this should above 4G
> 
> I'd rather not have // style comments in fwts if that's OK.

Thanks for pointing this out.

> 
>>  	}
>>  
>>  	if (fwts_cpu_readmsr(fw, 0, MTRR_DEF_TYPE_MSR, &mtrr_default) == FWTS_OK) {
>> @@ -229,12 +234,6 @@ static int cache_types(uint64_t start, uint64_t end)
>>  	struct mtrr_entry *entry;
>>  	int type = 0;
>>  
>> -	/* On AMD platforms, Tom2ForceMemTypeWB overwrites other memory types */
>> -	if (amd_Tom2ForceMemTypeWB && start >= 0x100000000) {
>> -		type = WRITE_BACK;
>> -		return type;
>> -	}
>> -
>>  	fwts_list_foreach(item, mtrr_list) {
>>  		entry = fwts_list_data(struct mtrr_entry*, item);
>>  
>> @@ -242,6 +241,11 @@ static int cache_types(uint64_t start, uint64_t end)
>>  			type |= entry->type;
>>  	}
>>  
>> +	/* On AMD platforms, Tom2ForceMemTypeWB overwrites MTRRdefType */
>> +	if (type == 0 && (strstr(fwts_cpuinfo->vendor_id, "AMD") || strstr(fwts_cpuinfo->vendor_id, "Hygon")))
>> +		if (amd_Tom2ForceMemTypeWB && start >= 0x100000000 && start <= amd_tom2_addr)
>> +			return WRITE_BACK;
>> +
> 
> The second if statement could be replaced with a further && clause,
> something like:
> 
> 	if ((type == 0) &&
>             (strstr(fwts_cpuinfo->vendor_id, "AMD") ||
> strstr(fwts_cpuinfo->vendor_id, "Hygon")) &&
>             (amd_Tom2ForceMemTypeWB && (start >= 0x100000000) && (start
> <= amd_tom2_addr)))

I just realized that CPU vendor IDs aren't necessary because
amd_Tom2ForceMemTypeWB will never be set without them in the first
place, and the variable name is also clear about this too.

Therefore, the following condition will be sufficient:

if (type == 0 && amd_Tom2ForceMemTypeWB && start >= 0x100000000 && start
<= amd_tom2_addr)


> 		return WRITE_BACK;
> 
> 
> 
>>  	/*
>>  	 * now to see if there is any part of the range that isn't
>>  	 * covered by an mtrr, since it's UNCACHED if so
>>
>
diff mbox series

Patch

diff --git a/src/bios/mtrr/mtrr.c b/src/bios/mtrr/mtrr.c
index e064f9c4..c9b77941 100644
--- a/src/bios/mtrr/mtrr.c
+++ b/src/bios/mtrr/mtrr.c
@@ -51,8 +51,10 @@  static fwts_cpuinfo_x86 *fwts_cpuinfo;
 
 #define MTRR_DEF_TYPE_MSR	0x2FF
 #define AMD_SYS_CFG_MSR		0xC0010010
+#define AMD_TOM2_MSR		0xC001001D
 
 static	uint64_t mtrr_default;
+static	uint64_t amd_tom2_addr;
 static	bool amd_Tom2ForceMemTypeWB = false;
 
 struct mtrr_entry {
@@ -195,6 +197,9 @@  static int get_default_mtrr(fwts_framework *fw)
 		if (fwts_cpu_readmsr(fw, 0, AMD_SYS_CFG_MSR, &amd_sys_conf) == FWTS_OK)
 			if (amd_sys_conf & 0x200000)
 				amd_Tom2ForceMemTypeWB = true;
+
+		if (fwts_cpu_readmsr(fw, 0, AMD_TOM2_MSR, &amd_tom2_addr) != FWTS_OK)
+			amd_tom2_addr = 0x100000000;	// this should above 4G
 	}
 
 	if (fwts_cpu_readmsr(fw, 0, MTRR_DEF_TYPE_MSR, &mtrr_default) == FWTS_OK) {
@@ -229,12 +234,6 @@  static int cache_types(uint64_t start, uint64_t end)
 	struct mtrr_entry *entry;
 	int type = 0;
 
-	/* On AMD platforms, Tom2ForceMemTypeWB overwrites other memory types */
-	if (amd_Tom2ForceMemTypeWB && start >= 0x100000000) {
-		type = WRITE_BACK;
-		return type;
-	}
-
 	fwts_list_foreach(item, mtrr_list) {
 		entry = fwts_list_data(struct mtrr_entry*, item);
 
@@ -242,6 +241,11 @@  static int cache_types(uint64_t start, uint64_t end)
 			type |= entry->type;
 	}
 
+	/* On AMD platforms, Tom2ForceMemTypeWB overwrites MTRRdefType */
+	if (type == 0 && (strstr(fwts_cpuinfo->vendor_id, "AMD") || strstr(fwts_cpuinfo->vendor_id, "Hygon")))
+		if (amd_Tom2ForceMemTypeWB && start >= 0x100000000 && start <= amd_tom2_addr)
+			return WRITE_BACK;
+
 	/*
 	 * now to see if there is any part of the range that isn't
 	 * covered by an mtrr, since it's UNCACHED if so