ia64/xen-unstable

changeset 19583:ea068394ec12

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>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Apr 29 11:52:14 2009 +0100 (2009-04-29)
parents 648d7de355dd
children 86f659545f17
files xen/arch/x86/e820.c
line diff
     1.1 --- a/xen/arch/x86/e820.c	Tue Apr 28 13:45:08 2009 +0100
     1.2 +++ b/xen/arch/x86/e820.c	Wed Apr 29 11:52:14 2009 +0100
     1.3 @@ -15,6 +15,14 @@ unsigned long long opt_mem;
     1.4  static void parse_mem(char *s) { opt_mem = parse_size_and_unit(s, NULL); }
     1.5  custom_param("mem", parse_mem);
     1.6  
     1.7 +/* opt_nomtrr_check: Don't clip ram to highest cacheable MTRR. */
     1.8 +static int __initdata e820_mtrr_clip = -1;
     1.9 +boolean_param("e820-mtrr-clip", e820_mtrr_clip);
    1.10 +
    1.11 +/* opt_e820_verbose: Be verbose about clipping, the original e820, &c */
    1.12 +static int __initdata e820_verbose;
    1.13 +boolean_param("e820-verbose", e820_verbose);
    1.14 +
    1.15  struct e820map e820;
    1.16  
    1.17  static void __init add_memory_region(unsigned long long start,
    1.18 @@ -324,27 +332,35 @@ static void __init clip_to_limit(uint64_
    1.19  {
    1.20      int i;
    1.21      char _warnmsg[160];
    1.22 +    uint64_t old_limit = 0;
    1.23  
    1.24      for ( i = 0; i < e820.nr_map; i++ )
    1.25      {
    1.26 -        if ( (e820.map[i].addr + e820.map[i].size) <= limit )
    1.27 +        if ( (e820.map[i].type != E820_RAM) ||
    1.28 +             ((e820.map[i].addr + e820.map[i].size) <= limit) )
    1.29              continue;
    1.30 +        old_limit = e820.map[i].addr + e820.map[i].size;
    1.31 +        if ( e820.map[i].addr < limit )
    1.32 +        {
    1.33 +            e820.map[i].size = limit - e820.map[i].addr;
    1.34 +        }
    1.35 +        else
    1.36 +        {
    1.37 +            memmove(&e820.map[i], &e820.map[i+1],
    1.38 +                    (e820.nr_map - i - 1) * sizeof(struct e820entry));
    1.39 +            e820.nr_map--;
    1.40 +        }
    1.41 +    }
    1.42 +
    1.43 +    if ( old_limit )
    1.44 +    {
    1.45          if ( warnmsg )
    1.46          {
    1.47              snprintf(_warnmsg, sizeof(_warnmsg), warnmsg, (long)(limit>>30));
    1.48              printk("WARNING: %s\n", _warnmsg);
    1.49          }
    1.50 -        printk("Truncating memory map to %lukB\n",
    1.51 -               (unsigned long)(limit >> 10));
    1.52 -        if ( e820.map[i].addr >= limit )
    1.53 -        {
    1.54 -            e820.nr_map = i;
    1.55 -        }
    1.56 -        else
    1.57 -        {
    1.58 -            e820.map[i].size = limit - e820.map[i].addr;
    1.59 -            e820.nr_map = i + 1;                
    1.60 -        }            
    1.61 +        printk("Truncating RAM from %lukB to %lukB\n",
    1.62 +               (unsigned long)(old_limit >> 10), (unsigned long)(limit >> 10));
    1.63      }
    1.64  }
    1.65  
    1.66 @@ -357,6 +373,24 @@ static uint64_t mtrr_top_of_ram(void)
    1.67      uint64_t mtrr_cap, mtrr_def, addr_mask, base, mask, top;
    1.68      unsigned int i, phys_bits = 36;
    1.69  
    1.70 +    /* By default we check only Intel systems. */
    1.71 +    if ( e820_mtrr_clip == -1 )
    1.72 +    {
    1.73 +        char vendor[13];
    1.74 +        cpuid(0x00000000, &eax,
    1.75 +              (uint32_t *)&vendor[0],
    1.76 +              (uint32_t *)&vendor[8],
    1.77 +              (uint32_t *)&vendor[4]);
    1.78 +        vendor[12] = '\0';
    1.79 +        e820_mtrr_clip = !strcmp(vendor, "GenuineIntel");
    1.80 +    }
    1.81 +
    1.82 +    if ( !e820_mtrr_clip )
    1.83 +        return 0;
    1.84 +
    1.85 +    if ( e820_verbose )
    1.86 +        printk("Checking MTRR ranges...\n");
    1.87 +
    1.88      /* Does the CPU support architectural MTRRs? */
    1.89      cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
    1.90      if ( !test_bit(X86_FEATURE_MTRR & 31, &edx) )
    1.91 @@ -374,6 +408,9 @@ static uint64_t mtrr_top_of_ram(void)
    1.92      rdmsrl(MSR_MTRRcap, mtrr_cap);
    1.93      rdmsrl(MSR_MTRRdefType, mtrr_def);
    1.94  
    1.95 +    if ( e820_verbose )
    1.96 +        printk(" MTRR cap: %lx type: %lx\n", mtrr_cap, mtrr_def);
    1.97 +
    1.98      /* MTRRs enabled, and default memory type is not writeback? */
    1.99      if ( !test_bit(11, &mtrr_def) || ((uint8_t)mtrr_def == MTRR_TYPE_WRBACK) )
   1.100          return 0;
   1.101 @@ -387,6 +424,10 @@ static uint64_t mtrr_top_of_ram(void)
   1.102      {
   1.103          rdmsrl(MSR_MTRRphysBase(i), base);
   1.104          rdmsrl(MSR_MTRRphysMask(i), mask);
   1.105 +
   1.106 +        if ( e820_verbose )
   1.107 +            printk(" MTRR[%d]: base %lx mask %lx\n", i, base, mask);
   1.108 +
   1.109          if ( !test_bit(11, &mask) || ((uint8_t)base != MTRR_TYPE_WRBACK) )
   1.110              continue;
   1.111          base &= addr_mask;
   1.112 @@ -543,8 +584,16 @@ int __init reserve_e820_ram(struct e820m
   1.113  unsigned long __init init_e820(
   1.114      const char *str, struct e820entry *raw, int *raw_nr)
   1.115  {
   1.116 +    if ( e820_verbose )
   1.117 +    {
   1.118 +        printk("Initial %s RAM map:\n", str);
   1.119 +        print_e820_memory_map(raw, *raw_nr);
   1.120 +    }
   1.121 +
   1.122      machine_specific_memory_setup(raw, raw_nr);
   1.123 +
   1.124      printk("%s RAM map:\n", str);
   1.125      print_e820_memory_map(e820.map, e820.nr_map);
   1.126 +
   1.127      return find_max_pfn();
   1.128  }