Re: MTRR initialization

From: Howard Chu
Date: Sun Sep 16 2007 - 12:10:36 EST


Yinghai Lu wrote:
On 9/14/07, Howard Chu <hyc@xxxxxxxxx> wrote:
Hi, was wondering if anyone else has been tripped up by this... I've got 4GB of
RAM in my Asus A8V Deluxe and memory hole mapping enabled in the BIOS. By
default, my system boots up with these MTRR settings:

reg00: base=0x00000000 ( 0MB), size=4096MB: write-back, count=1
reg01: base=0x100000000 (4096MB), size=1024MB: write-back, count=1
reg02: base=0xc0000000 (3072MB), size=1024MB: uncachable, count=1
reg03: base=0xc0000000 (3072MB), size= 256MB: write-combining, count=1

BIOS should have another setup option about MTRR (continous?)
then you could get

reg00: base=0x00000000 ( 0MB), size=2048MB: write-back, count=1
reg01: base=0x100000000 (2048MB), size=1024MB: write-back, count=1
reg02: base=0x100000000 (4096MB), size=1024MB: write-back, count=1
===> if you have rev E...instead of rev F.

Thanks for the reply. Unfortunately this BIOS doesn't seem to have any other options related to the MTRRs. I guess I'll just live with this hack.
--
-- Howard Chu
Chief Architect, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/ --- generic.c.O 2007-08-30 23:21:01.000000000 -0700
+++ generic.c 2007-09-16 09:09:34.000000000 -0700
@@ -78,6 +78,8 @@
base, base + step - 1, mtrr_attrib_to_str(*types));
}

+static int set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr);
+
/* Grab all of the MTRR state for this CPU into *state */
void get_mtrr_state(void)
{
@@ -105,6 +107,21 @@
mtrr_state.def_type = (lo & 0xff);
mtrr_state.enabled = (lo & 0xc00) >> 10;

+ /* Check for initial 4GB range, it should only be 3GB */
+ if (!mtrr_state.var_ranges[0].base_hi && !(mtrr_state.var_ranges[0].base_lo & 0xffffff00) &&
+ !(mtrr_state.var_ranges[0].mask_lo & 0x80000000)) {
+ /* split initial 4GB range into 2GB and 1GB */
+ for (i = num_var_ranges-1; i>0; i--)
+ mtrr_state.var_ranges[i] = mtrr_state.var_ranges[i-1];
+ mtrr_state.var_ranges[0].mask_lo |= 0x80000000;
+ mtrr_state.var_ranges[1].base_hi = 0;
+ mtrr_state.var_ranges[1].base_lo = 0x80000000 | MTRR_TYPE_WRBACK ;
+ mtrr_state.var_ranges[1].mask_hi = mtrr_state.var_ranges[2].mask_hi;
+ mtrr_state.var_ranges[1].mask_lo = mtrr_state.var_ranges[2].mask_lo;
+ for (i = 0; i < num_var_ranges; i++)
+ set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i]);
+ }
+
if (mtrr_show) {
int high_width;