Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/36382 )
Change subject: cpu/x86/mtrr: Add function to set MTRR with CR0.CD set ......................................................................
cpu/x86/mtrr: Add function to set MTRR with CR0.CD set
MTRRs should only be changed when CR0.CD is set. In a CAR environment this is a rather fragile thing to do. This is why it is best to implement this in assembly.
Change-Id: I4ff59d35ade125f60ed0002a386f41fd8ad54073 Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/cpu/x86/mtrr/Makefile.inc M src/cpu/x86/mtrr/earlymtrr.c A src/cpu/x86/mtrr/set_mtrr.S M src/include/cpu/x86/mtrr.h 4 files changed, 88 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/82/36382/1
diff --git a/src/cpu/x86/mtrr/Makefile.inc b/src/cpu/x86/mtrr/Makefile.inc index caa6e9c..4052c52 100644 --- a/src/cpu/x86/mtrr/Makefile.inc +++ b/src/cpu/x86/mtrr/Makefile.inc @@ -3,6 +3,9 @@ romstage-y += earlymtrr.c bootblock-y += earlymtrr.c
+bootblock-y += set_mtrr.S +verstage-y += set_mtrr.S + bootblock-y += debug.c romstage-y += debug.c postcar-y += debug.c diff --git a/src/cpu/x86/mtrr/earlymtrr.c b/src/cpu/x86/mtrr/earlymtrr.c index 02dfbdc..2f6a64d 100644 --- a/src/cpu/x86/mtrr/earlymtrr.c +++ b/src/cpu/x86/mtrr/earlymtrr.c @@ -52,3 +52,17 @@ maskm.hi = (1 << (cpu_phys_address_size() - 32)) - 1; wrmsr(MTRR_PHYS_MASK(reg), maskm); } + +void set_var_mtrr_uncached( + unsigned int reg, unsigned int base, unsigned int size, + unsigned int type) +{ + /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */ + /* FIXME: It only support 4G less range */ + msr_t basem, maskm; + basem.lo = base | type; + basem.hi = 0; + maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID; + maskm.hi = (1 << (cpu_phys_address_size() - 32)) - 1; + set_var_mtrr_uncached_asm(reg, basem, maskm); +} diff --git a/src/cpu/x86/mtrr/set_mtrr.S b/src/cpu/x86/mtrr/set_mtrr.S new file mode 100644 index 0000000..43c19f7 --- /dev/null +++ b/src/cpu/x86/mtrr/set_mtrr.S @@ -0,0 +1,67 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <cpu/x86/mtrr.h> +#include <cpu/x86/cache.h> +#include <cpu/x86/post_code.h> +.global set_var_mtrr_uncached_asm + /* ARG0: mtrr_num + * ARG1: mtrr_base.lo + * ARG2: mtrr_base.hi + * ARG3: mtrr_mask.lo + * ARG4: mtrr_mask.hi + */ +.code32 +set_var_mtrr_uncached_asm: + /* Callee saved registers */ + pushl %ebp + movl %esp, %ebp + addl $8, %ebp + pushl %ebx + pushl %edx + pushl %esi + pushl %edi + + movl 0(%ebp), %ecx + movl 4(%ebp), %ebx + movl 8(%ebp), %edx + movl 12(%ebp), %esi + movl 16(%ebp), %edi + + /* Disable caching before setting MTRR */ + movl %cr0, %eax + orl $CR0_CacheDisable, %eax + movl %eax, %cr0 + + /* MTRR_PHYS_BASE */ + imul $2, %ecx, %ecx + addl $MTRR_PHYS_BASE(0), %ecx + movl %ebx, %eax + wrmsr + /* MTRR_PHYS_MASK */ + addl $1, %ecx + movl %esi, %eax + movl %edi, %edx + wrmsr + + /* Enable cache again. */ + movl %cr0, %eax + andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax + movl %eax, %cr0 + + /* Restore Callee saved registers */ + popl %edi + popl %esi + popl %edx + popl %ebx + popl %ebp + ret diff --git a/src/include/cpu/x86/mtrr.h b/src/include/cpu/x86/mtrr.h index 29256c8..103388f 100644 --- a/src/include/cpu/x86/mtrr.h +++ b/src/include/cpu/x86/mtrr.h @@ -107,6 +107,10 @@ void set_var_mtrr(unsigned int reg, unsigned int base, unsigned int size, unsigned int type); int get_free_var_mtrr(void); +void set_var_mtrr_uncached(unsigned int reg, unsigned int base, + unsigned int size, unsigned int type); +__attribute__((cdecl)) void set_var_mtrr_uncached_asm(unsigned int reg, + msr_t base, msr_t mask);
asmlinkage void display_mtrrs(void);