summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/x86/mtrr/Makefile.inc2
-rw-r--r--src/cpu/x86/mtrr/earlymtrr.c39
2 files changed, 25 insertions, 16 deletions
diff --git a/src/cpu/x86/mtrr/Makefile.inc b/src/cpu/x86/mtrr/Makefile.inc
index ac6502608b..87e61b21e4 100644
--- a/src/cpu/x86/mtrr/Makefile.inc
+++ b/src/cpu/x86/mtrr/Makefile.inc
@@ -1,6 +1,7 @@
ramstage-y += mtrr.c
ramstage-y += mtrrlib.c
+postcar-y += mtrrlib.c
romstage-y += mtrrlib.c
bootblock-y += mtrrlib.c
verstage_x86-y += mtrrlib.c
@@ -8,6 +9,7 @@ verstage_x86-y += mtrrlib.c
romstage-y += earlymtrr.c
bootblock-y += earlymtrr.c
verstage_x86-y += earlymtrr.c
+postcar-y += earlymtrr.c
bootblock-y += debug.c
romstage-y += debug.c
diff --git a/src/cpu/x86/mtrr/earlymtrr.c b/src/cpu/x86/mtrr/earlymtrr.c
index a2d6e11d5f..8ea1216384 100644
--- a/src/cpu/x86/mtrr/earlymtrr.c
+++ b/src/cpu/x86/mtrr/earlymtrr.c
@@ -5,20 +5,17 @@
#include <cpu/x86/msr.h>
#include <console/console.h>
#include <commonlib/bsd/helpers.h>
+#include <stdint.h>
-void var_mtrr_context_init(struct var_mtrr_context *ctx, void *arg)
+void var_mtrr_context_init(struct var_mtrr_context *ctx)
{
- ctx->upper_mask = (1U << (cpu_phys_address_size() - 32)) - 1;
ctx->max_var_mtrrs = get_var_mtrr_count();
ctx->used_var_mtrrs = 0;
- ctx->arg = arg;
}
-int var_mtrr_set_with_cb(struct var_mtrr_context *ctx, uintptr_t addr, size_t size,
- int type, void (*callback)(const struct var_mtrr_context *ctx,
- uintptr_t base_addr, size_t size,
- msr_t base, msr_t mask))
+int var_mtrr_set(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type)
{
+ const uint32_t upper_mask = (1U << (cpu_phys_address_size() - 32)) - 1;
/* Utilize additional MTRRs if the specified size is greater than the
base address alignment. */
while (size != 0) {
@@ -47,9 +44,10 @@ int var_mtrr_set_with_cb(struct var_mtrr_context *ctx, uintptr_t addr, size_t si
base.hi = (uint64_t)addr >> 32;
base.lo = addr | type;
- mask.hi = ctx->upper_mask;
+ mask.hi = upper_mask;
mask.lo = ~(mtrr_size - 1) | MTRR_PHYS_MASK_VALID;
- callback(ctx, addr, mtrr_size, base, mask);
+ ctx->mtrr[ctx->used_var_mtrrs].base = base;
+ ctx->mtrr[ctx->used_var_mtrrs].mask = mask;
ctx->used_var_mtrrs++;
size -= mtrr_size;
@@ -59,16 +57,25 @@ int var_mtrr_set_with_cb(struct var_mtrr_context *ctx, uintptr_t addr, size_t si
return 0;
}
-static void set_mtrr(const struct var_mtrr_context *ctx, uintptr_t base_addr, size_t size,
- msr_t base, msr_t mask)
+/* Romstage sets up a MTRR context in cbmem and sets up this pointer in postcar stage. */
+__attribute__((used, __section__(".module_parameters"))) const volatile uintptr_t post_car_mtrrs;
+
+void commit_mtrr_setup(const struct var_mtrr_context *ctx)
{
- int i = var_mtrr_context_current_mtrr(ctx);
+ clear_all_var_mtrr();
- wrmsr(MTRR_PHYS_BASE(i), base);
- wrmsr(MTRR_PHYS_MASK(i), mask);
+ for (int i = 0; i < ctx->used_var_mtrrs; i++) {
+ wrmsr(MTRR_PHYS_BASE(i), ctx->mtrr[i].base);
+ wrmsr(MTRR_PHYS_MASK(i), ctx->mtrr[i].mask);
+ }
+ /* Enable MTRR */
+ msr_t mtrr_def_type = rdmsr(MTRR_DEF_TYPE_MSR);
+ mtrr_def_type.lo &= MTRR_DEF_TYPE_MASK;
+ mtrr_def_type.lo |= MTRR_DEF_TYPE_EN;
+ wrmsr(MTRR_DEF_TYPE_MSR, mtrr_def_type);
}
-int var_mtrr_set(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type)
+void postcar_mtrr_setup(void)
{
- return var_mtrr_set_with_cb(ctx, addr, size, type, set_mtrr);
+ commit_mtrr_setup((const struct var_mtrr_context *)post_car_mtrrs);
}