summaryrefslogtreecommitdiff
path: root/src/cpu/x86/mtrr
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2016-07-21 14:26:34 -0500
committerAaron Durbin <adurbin@chromium.org>2016-07-22 21:38:54 +0200
commita38677b6646fae7284d08fef706a77478c38c547 (patch)
tree432ee948647d7dea624e068f42e12e451c2c250b /src/cpu/x86/mtrr
parent9d29c3cc3182c8e8f38b3a2b1e0d445cdbd448bc (diff)
cpu/x86/mtrr: correct variable MTRR calculation around 1MiB boundary
The fixed MTRRs cover the range [0:1MiB). While calculating the variable MTRR usage the 1MiB boundary is checked such that an excessive number of MTRRs aren't used because of unnatural alignment at the low end of the physical address space. Howevever, those checks weren't inclusive of the 1MiB boundary. As such a variable MTRR could be used for a range which is actually covered by the fixed MTRRs when the end address is equal to 1MiB. Likewise, if the starting address of the range lands on the 1MiB boundary then more variable MTRRs are calculated in order to meet natural alignment requirements. Before: MTRR: Physical address space: 0x0000000000000000 - 0x00000000000a0000 size 0x000a0000 type 6 0x00000000000a0000 - 0x0000000000100000 size 0x00060000 type 0 0x0000000000100000 - 0x000000007b800000 size 0x7b700000 type 6 0x000000007b800000 - 0x00000000b0000000 size 0x34800000 type 0 0x00000000b0000000 - 0x00000000c0000000 size 0x10000000 type 1 0x00000000c0000000 - 0x0000000100000000 size 0x40000000 type 0 0x0000000100000000 - 0x0000000180000000 size 0x80000000 type 6 CPU physical address size: 39 bits MTRR: default type WB/UC MTRR counts: 7/17. MTRR: WB selected as default type. MTRR: 0 base 0x0000000000000000 mask 0x0000007ffff00000 type 0 MTRR: 1 base 0x000000007b800000 mask 0x0000007fff800000 type 0 MTRR: 2 base 0x000000007c000000 mask 0x0000007ffc000000 type 0 MTRR: 3 base 0x0000000080000000 mask 0x0000007fe0000000 type 0 MTRR: 4 base 0x00000000a0000000 mask 0x0000007ff0000000 type 0 MTRR: 5 base 0x00000000b0000000 mask 0x0000007ff0000000 type 1 MTRR: 6 base 0x00000000c0000000 mask 0x0000007fc0000000 type 0 After: MTRR: Physical address space: 0x0000000000000000 - 0x00000000000a0000 size 0x000a0000 type 6 0x00000000000a0000 - 0x0000000000100000 size 0x00060000 type 0 0x0000000000100000 - 0x000000007b800000 size 0x7b700000 type 6 0x000000007b800000 - 0x00000000b0000000 size 0x34800000 type 0 0x00000000b0000000 - 0x00000000c0000000 size 0x10000000 type 1 0x00000000c0000000 - 0x0000000100000000 size 0x40000000 type 0 0x0000000100000000 - 0x0000000180000000 size 0x80000000 type 6 CPU physical address size: 39 bits MTRR: default type WB/UC MTRR counts: 6/8. MTRR: WB selected as default type. MTRR: 0 base 0x000000007b800000 mask 0x0000007fff800000 type 0 MTRR: 1 base 0x000000007c000000 mask 0x0000007ffc000000 type 0 MTRR: 2 base 0x0000000080000000 mask 0x0000007fe0000000 type 0 MTRR: 3 base 0x00000000a0000000 mask 0x0000007ff0000000 type 0 MTRR: 4 base 0x00000000b0000000 mask 0x0000007ff0000000 type 1 MTRR: 5 base 0x00000000c0000000 mask 0x0000007fc0000000 type 0 BUG=chrome-os-partner:55504 Change-Id: I7feab38dfe135f5e596c9e67520378a406aa6866 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/15780 Reviewed-by: Furquan Shaikh <furquan@google.com> Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Diffstat (limited to 'src/cpu/x86/mtrr')
-rw-r--r--src/cpu/x86/mtrr/mtrr.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c
index 794df9922b..8bdc511fd5 100644
--- a/src/cpu/x86/mtrr/mtrr.c
+++ b/src/cpu/x86/mtrr/mtrr.c
@@ -505,15 +505,15 @@ static void calc_var_mtrrs_with_hole(struct var_mtrr_state *var_state,
a1 = range_entry_base_mtrr_addr(r);
a2 = range_entry_end_mtrr_addr(r);
- /* The end address is under 1MiB. The fixed MTRRs take
+ /* The end address is within the first 1MiB. The fixed MTRRs take
* precedence over the variable ones. Therefore this range
* can be ignored. */
- if (a2 < RANGE_1MB)
+ if (a2 <= RANGE_1MB)
return;
/* Again, the fixed MTRRs take precedence so the beginning
- * of the range can be set to 0 if it starts below 1MiB. */
- if (a1 < RANGE_1MB)
+ * of the range can be set to 0 if it starts at or below 1MiB. */
+ if (a1 <= RANGE_1MB)
a1 = 0;
/* If the range starts above 4GiB the processing is done. */
@@ -585,15 +585,15 @@ static void calc_var_mtrrs_without_hole(struct var_mtrr_state *var_state,
a1 = range_entry_base_mtrr_addr(r);
c2 = range_entry_end_mtrr_addr(r);
- /* The end address is under 1MiB. The fixed MTRRs take
+ /* The end address is within the first 1MiB. The fixed MTRRs take
* precedence over the variable ones. Therefore this range
* can be ignored. */
- if (c2 < RANGE_1MB)
+ if (c2 <= RANGE_1MB)
return;
/* Again, the fixed MTRRs take precedence so the beginning
- * of the range can be set to 0 if it starts below 1MiB. */
- if (a1 < RANGE_1MB)
+ * of the range can be set to 0 if it starts at or below 1MiB. */
+ if (a1 <= RANGE_1MB)
a1 = 0;
/* If the range starts above 4GiB the processing is done. */