diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cpu/x86/mtrr/Makefile.inc | 5 | ||||
-rw-r--r-- | src/cpu/x86/mtrr/earlymtrr.c | 60 | ||||
-rw-r--r-- | src/cpu/x86/mtrr/mtrrlib.c | 65 |
3 files changed, 70 insertions, 60 deletions
diff --git a/src/cpu/x86/mtrr/Makefile.inc b/src/cpu/x86/mtrr/Makefile.inc index 3f33e31379..ac6502608b 100644 --- a/src/cpu/x86/mtrr/Makefile.inc +++ b/src/cpu/x86/mtrr/Makefile.inc @@ -1,5 +1,10 @@ ramstage-y += mtrr.c +ramstage-y += mtrrlib.c +romstage-y += mtrrlib.c +bootblock-y += mtrrlib.c +verstage_x86-y += mtrrlib.c + romstage-y += earlymtrr.c bootblock-y += earlymtrr.c verstage_x86-y += earlymtrr.c diff --git a/src/cpu/x86/mtrr/earlymtrr.c b/src/cpu/x86/mtrr/earlymtrr.c index aa301d0fe5..a2d6e11d5f 100644 --- a/src/cpu/x86/mtrr/earlymtrr.c +++ b/src/cpu/x86/mtrr/earlymtrr.c @@ -6,66 +6,6 @@ #include <console/console.h> #include <commonlib/bsd/helpers.h> -/* Get first available variable MTRR. - * Returns var# if available, else returns -1. - */ -int get_free_var_mtrr(void) -{ - msr_t maskm; - int vcnt; - int i; - - vcnt = get_var_mtrr_count(); - - /* Identify the first var mtrr which is not valid. */ - for (i = 0; i < vcnt; i++) { - maskm = rdmsr(MTRR_PHYS_MASK(i)); - if ((maskm.lo & MTRR_PHYS_MASK_VALID) == 0) - return i; - } - - /* No free var mtrr. */ - return -1; -} - -void set_var_mtrr( - unsigned int reg, unsigned int base, unsigned int size, - unsigned int type) -{ - /* Bit 32-35 of MTRRphysMask should be set to 1 */ - /* FIXME: It only support 4G less range */ - msr_t basem, maskm; - - if (!IS_POWER_OF_2(size)) - printk(BIOS_ERR, "MTRR Error: size %#x is not a power of two\n", size); - if (size < 4 * KiB) - printk(BIOS_ERR, "MTRR Error: size %#x smaller than 4KiB\n", size); - if (base % size != 0) - printk(BIOS_ERR, "MTRR Error: base %#x must be aligned to size %#x\n", base, - size); - - basem.lo = base | type; - basem.hi = 0; - wrmsr(MTRR_PHYS_BASE(reg), basem); - maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID; - maskm.hi = (1 << (cpu_phys_address_size() - 32)) - 1; - wrmsr(MTRR_PHYS_MASK(reg), maskm); -} - -void clear_all_var_mtrr(void) -{ - msr_t mtrr = {0, 0}; - int vcnt; - int i; - - vcnt = get_var_mtrr_count(); - - for (i = 0; i < vcnt; i++) { - wrmsr(MTRR_PHYS_MASK(i), mtrr); - wrmsr(MTRR_PHYS_BASE(i), mtrr); - } -} - void var_mtrr_context_init(struct var_mtrr_context *ctx, void *arg) { ctx->upper_mask = (1U << (cpu_phys_address_size() - 32)) - 1; diff --git a/src/cpu/x86/mtrr/mtrrlib.c b/src/cpu/x86/mtrr/mtrrlib.c new file mode 100644 index 0000000000..71921de9e3 --- /dev/null +++ b/src/cpu/x86/mtrr/mtrrlib.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <cpu/cpu.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/msr.h> +#include <console/console.h> + +/* Get first available variable MTRR. + * Returns var# if available, else returns -1. + */ +int get_free_var_mtrr(void) +{ + msr_t maskm; + int vcnt; + int i; + + vcnt = get_var_mtrr_count(); + + /* Identify the first var mtrr which is not valid. */ + for (i = 0; i < vcnt; i++) { + maskm = rdmsr(MTRR_PHYS_MASK(i)); + if ((maskm.lo & MTRR_PHYS_MASK_VALID) == 0) + return i; + } + + /* No free var mtrr. */ + return -1; +} + +void set_var_mtrr( + unsigned int reg, unsigned int base, unsigned int size, unsigned int type) +{ + /* Bit 32-35 of MTRRphysMask should be set to 1 */ + /* FIXME: It only support 4G less range */ + msr_t basem, maskm; + + if (!IS_POWER_OF_2(size)) + printk(BIOS_ERR, "MTRR Error: size %#x is not a power of two\n", size); + if (size < 4 * KiB) + printk(BIOS_ERR, "MTRR Error: size %#x smaller than 4KiB\n", size); + if (base % size != 0) + printk(BIOS_ERR, "MTRR Error: base %#x must be aligned to size %#x\n", base, + size); + + basem.lo = base | type; + basem.hi = 0; + wrmsr(MTRR_PHYS_BASE(reg), basem); + maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID; + maskm.hi = (1 << (cpu_phys_address_size() - 32)) - 1; + wrmsr(MTRR_PHYS_MASK(reg), maskm); +} + +void clear_all_var_mtrr(void) +{ + msr_t mtrr = {0, 0}; + int vcnt; + int i; + + vcnt = get_var_mtrr_count(); + + for (i = 0; i < vcnt; i++) { + wrmsr(MTRR_PHYS_MASK(i), mtrr); + wrmsr(MTRR_PHYS_BASE(i), mtrr); + } +} |