diff options
author | Subrata Banik <subratabanik@google.com> | 2022-03-30 23:44:52 +0530 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2022-04-02 14:53:00 +0000 |
commit | 3ad00d0c89c9e7a8e9ef13b6dc65bb338a191ec8 (patch) | |
tree | 548509dc474d9d3acace756af3eb441fe4135f50 | |
parent | 6de1d9ff4ecfd1b550a99270e7431ab9e0cf5406 (diff) |
cpu/x86/mtrr: Make useful MTRR functions available for all boot stages
This patch migrates a few useful MTRR functions as below from
`earlymtrr.c` file to newly created common stage file `mtrrlib.c`.
1. get_free_var_mtrr
2. set_var_mtrr
3. clear_all_var_mtrr
These functions can be used to perform the MTRR programming from IA
common code SPI driver as `fast_spi.c` without requiring two separate
implementations for early boot stage (till romstage) and for ramstage
onwards.
BUG=b:225766934
TEST=Able to build and boot google/redrix board to ChromeOS.
Signed-off-by: Subrata Banik <subratabanik@google.com>
Change-Id: I2c62a04a36d3169545c3128b4231992ad9b3699d
Reviewed-on: https://review.coreboot.org/c/coreboot/+/63218
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
-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); + } +} |