summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRaul E Rangel <rrangel@chromium.org>2020-04-27 15:38:58 -0600
committerAaron Durbin <adurbin@chromium.org>2020-05-01 15:42:01 +0000
commit3e42ee05d86c1de3ed23dddf08fd8e6451bdea92 (patch)
tree2b6941b396b30cbbb20ab2865cf738b6576a1320 /src
parente4c81bcca59e94c71f7acf48c060da827afeb15a (diff)
cpu/x86/mtrr/earlymtrr: Validate MTRR arguments
The AMD64 Architecture Programmer's Manual, Volume 2: Systems Programming says the following about variable MTRRs: Variable Range Size and Alignment. The size and alignment of variable memory-ranges (MTRRs) and I/O ranges (IORRs) are restricted as follows: * The boundary on which a variable range is aligned must be equal to the range size. For example, a memory range of 16 Mbytes must be aligned on a 16-Mbyte boundary (i.e., naturally aligned). * The range size must be a power of 2 (2^n , 52 > n > 11), with a minimum allowable size of 4 Kbytes. For example, 4 Mbytes and 8 Mbytes are allowable memory range sizes, but 6 Mbytes is not allowable. Print out errors if these conditions are violated. I didn't assert since `set_var_mtrr` can be used in boot block before the serial console is enabled. BUG=b:147042464 TEST=Boot trembyle and see MTRR errors: MTRR Error: base 0xcc800000 must be aligned to size 0x1000000 Signed-off-by: Raul E Rangel <rrangel@chromium.org> Change-Id: I8b8c734c7599bd89cf9f212ed43c2dd5b2c8ba7b Reviewed-on: https://review.coreboot.org/c/coreboot/+/40762 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src')
-rw-r--r--src/cpu/x86/mtrr/earlymtrr.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/cpu/x86/mtrr/earlymtrr.c b/src/cpu/x86/mtrr/earlymtrr.c
index e8608fd9cc..f96b05061f 100644
--- a/src/cpu/x86/mtrr/earlymtrr.c
+++ b/src/cpu/x86/mtrr/earlymtrr.c
@@ -4,6 +4,8 @@
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
+#include <console/console.h>
+#include <commonlib/bsd/helpers.h>
/* Get first available variable MTRR.
* Returns var# if available, else returns -1.
@@ -34,6 +36,15 @@ void set_var_mtrr(
/* Bit 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);