aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-04-29 11:52:14 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-04-29 11:52:14 +0100
commit9d85142e675142191f64d73aa40791a03a9f7389 (patch)
tree70dc0be442a9fadebe4f699ac6043676b42f2986
parent1e906caa0aa6f6f57bd5088e8faf19dc89900552 (diff)
downloadxen-9d85142e675142191f64d73aa40791a03a9f7389.tar.gz
xen-9d85142e675142191f64d73aa40791a03a9f7389.tar.bz2
xen-9d85142e675142191f64d73aa40791a03a9f7389.zip
x86: Add boot options regarding e820 parsinga nd clipping.
[no-]e820-mtrr-clip: Clip e820 RAM areas to top-of-memory according to MTRRs. Prefix no- to disable the clip. e820-verbose: Extra e820 info printed during boot. Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com> Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r--xen/arch/x86/e820.c73
1 files changed, 61 insertions, 12 deletions
diff --git a/xen/arch/x86/e820.c b/xen/arch/x86/e820.c
index d402faa6e1..b5d8690d7a 100644
--- a/xen/arch/x86/e820.c
+++ b/xen/arch/x86/e820.c
@@ -15,6 +15,14 @@ unsigned long long opt_mem;
static void parse_mem(char *s) { opt_mem = parse_size_and_unit(s, NULL); }
custom_param("mem", parse_mem);
+/* opt_nomtrr_check: Don't clip ram to highest cacheable MTRR. */
+static int __initdata e820_mtrr_clip = -1;
+boolean_param("e820-mtrr-clip", e820_mtrr_clip);
+
+/* opt_e820_verbose: Be verbose about clipping, the original e820, &c */
+static int __initdata e820_verbose;
+boolean_param("e820-verbose", e820_verbose);
+
struct e820map e820;
static void __init add_memory_region(unsigned long long start,
@@ -324,27 +332,35 @@ static void __init clip_to_limit(uint64_t limit, char *warnmsg)
{
int i;
char _warnmsg[160];
+ uint64_t old_limit = 0;
for ( i = 0; i < e820.nr_map; i++ )
{
- if ( (e820.map[i].addr + e820.map[i].size) <= limit )
+ if ( (e820.map[i].type != E820_RAM) ||
+ ((e820.map[i].addr + e820.map[i].size) <= limit) )
continue;
- if ( warnmsg )
+ old_limit = e820.map[i].addr + e820.map[i].size;
+ if ( e820.map[i].addr < limit )
{
- snprintf(_warnmsg, sizeof(_warnmsg), warnmsg, (long)(limit>>30));
- printk("WARNING: %s\n", _warnmsg);
+ e820.map[i].size = limit - e820.map[i].addr;
}
- printk("Truncating memory map to %lukB\n",
- (unsigned long)(limit >> 10));
- if ( e820.map[i].addr >= limit )
+ else
{
- e820.nr_map = i;
+ memmove(&e820.map[i], &e820.map[i+1],
+ (e820.nr_map - i - 1) * sizeof(struct e820entry));
+ e820.nr_map--;
}
- else
+ }
+
+ if ( old_limit )
+ {
+ if ( warnmsg )
{
- e820.map[i].size = limit - e820.map[i].addr;
- e820.nr_map = i + 1;
- }
+ snprintf(_warnmsg, sizeof(_warnmsg), warnmsg, (long)(limit>>30));
+ printk("WARNING: %s\n", _warnmsg);
+ }
+ printk("Truncating RAM from %lukB to %lukB\n",
+ (unsigned long)(old_limit >> 10), (unsigned long)(limit >> 10));
}
}
@@ -357,6 +373,24 @@ static uint64_t mtrr_top_of_ram(void)
uint64_t mtrr_cap, mtrr_def, addr_mask, base, mask, top;
unsigned int i, phys_bits = 36;
+ /* By default we check only Intel systems. */
+ if ( e820_mtrr_clip == -1 )
+ {
+ char vendor[13];
+ cpuid(0x00000000, &eax,
+ (uint32_t *)&vendor[0],
+ (uint32_t *)&vendor[8],
+ (uint32_t *)&vendor[4]);
+ vendor[12] = '\0';
+ e820_mtrr_clip = !strcmp(vendor, "GenuineIntel");
+ }
+
+ if ( !e820_mtrr_clip )
+ return 0;
+
+ if ( e820_verbose )
+ printk("Checking MTRR ranges...\n");
+
/* Does the CPU support architectural MTRRs? */
cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
if ( !test_bit(X86_FEATURE_MTRR & 31, &edx) )
@@ -374,6 +408,9 @@ static uint64_t mtrr_top_of_ram(void)
rdmsrl(MSR_MTRRcap, mtrr_cap);
rdmsrl(MSR_MTRRdefType, mtrr_def);
+ if ( e820_verbose )
+ printk(" MTRR cap: %lx type: %lx\n", mtrr_cap, mtrr_def);
+
/* MTRRs enabled, and default memory type is not writeback? */
if ( !test_bit(11, &mtrr_def) || ((uint8_t)mtrr_def == MTRR_TYPE_WRBACK) )
return 0;
@@ -387,6 +424,10 @@ static uint64_t mtrr_top_of_ram(void)
{
rdmsrl(MSR_MTRRphysBase(i), base);
rdmsrl(MSR_MTRRphysMask(i), mask);
+
+ if ( e820_verbose )
+ printk(" MTRR[%d]: base %lx mask %lx\n", i, base, mask);
+
if ( !test_bit(11, &mask) || ((uint8_t)base != MTRR_TYPE_WRBACK) )
continue;
base &= addr_mask;
@@ -543,8 +584,16 @@ int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e)
unsigned long __init init_e820(
const char *str, struct e820entry *raw, int *raw_nr)
{
+ if ( e820_verbose )
+ {
+ printk("Initial %s RAM map:\n", str);
+ print_e820_memory_map(raw, *raw_nr);
+ }
+
machine_specific_memory_setup(raw, raw_nr);
+
printk("%s RAM map:\n", str);
print_e820_memory_map(e820.map, e820.nr_map);
+
return find_max_pfn();
}