Merge branch 'x86/mpparse' into x86/devel
authorIngo Molnar <mingo@elte.hu>
Tue, 8 Jul 2008 09:14:58 +0000 (11:14 +0200)
committerIngo Molnar <mingo@elte.hu>
Tue, 8 Jul 2008 09:14:58 +0000 (11:14 +0200)
Conflicts:

arch/x86/Kconfig
arch/x86/kernel/io_apic_32.c
arch/x86/kernel/setup_64.c
arch/x86/mm/init_32.c

Signed-off-by: Ingo Molnar <mingo@elte.hu>
26 files changed:
1  2 
Documentation/kernel-parameters.txt
arch/x86/Kconfig
arch/x86/Kconfig.debug
arch/x86/Makefile
arch/x86/boot/compressed/misc.c
arch/x86/kernel/Makefile
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/aperture_64.c
arch/x86/kernel/apic_32.c
arch/x86/kernel/apic_64.c
arch/x86/kernel/io_apic_32.c
arch/x86/kernel/io_apic_64.c
arch/x86/kernel/setup_64.c
arch/x86/kernel/smpboot.c
arch/x86/mm/discontig_32.c
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c
arch/x86/mm/k8topology_64.c
arch/x86/pci/Makefile_32
arch/x86/pci/amd_bus.c
arch/x86/xen/enlighten.c
arch/x86/xen/setup.c
include/asm-x86/bootparam.h
include/asm-x86/e820.h
include/asm-x86/io_apic.h
include/asm-x86/system.h

Simple merge
index 7dc46ba26fbf56c8ab0bb152ab42f126d8f62bfb,23c352e408af8319d393817a1466b922e92f7d81..640dc62a7fa039974af21696b1a1f6f65aaa8cc1
@@@ -261,39 -282,9 +282,9 @@@ config X86_VOYAGE
          If you do not specifically know you have a Voyager based machine,
          say N here, otherwise the kernel you build will not be bootable.
  
- config X86_NUMAQ
-       bool "NUMAQ (IBM/Sequent)"
-       depends on SMP && X86_32 && PCI
-       select NUMA
-       help
-         This option is used for getting Linux to run on a (IBM/Sequent) NUMA
-         multiquad box. This changes the way that processors are bootstrapped,
-         and uses Clustered Logical APIC addressing mode instead of Flat Logical.
-         You will need a new lynxer.elf file to flash your firmware with - send
-         email to <Martin.Bligh@us.ibm.com>.
- config X86_SUMMIT
-       bool "Summit/EXA (IBM x440)"
-       depends on X86_32 && SMP
-       help
-         This option is needed for IBM systems that use the Summit/EXA chipset.
-         In particular, it is needed for the x440.
-         If you don't have one of these computers, you should say N here.
-         If you want to build a NUMA kernel, you must select ACPI.
- config X86_BIGSMP
-       bool "Support for other sub-arch SMP systems with more than 8 CPUs"
-       depends on X86_32 && SMP
-       help
-         This option is needed for the systems that have more than 8 CPUs
-         and if the system is not of any sub-arch type above.
-         If you don't have such a system, you should say N here.
  config X86_VISWS
        bool "SGI 320/540 (Visual Workstation)"
 -      depends on X86_32
 +      depends on X86_32 && !PCI
        help
          The SGI Visual Workstation series is an IA32-based workstation
          based on SGI systems chips with some legacy PC hardware attached.
          and vice versa. See <file:Documentation/sgi-visws.txt> for details.
  
  config X86_GENERICARCH
-        bool "Generic architecture (Summit, bigsmp, ES7000, default)"
+        bool "Generic architecture"
        depends on X86_32
         help
-           This option compiles in the Summit, bigsmp, ES7000, default subarchitectures.
-         It is intended for a generic binary kernel.
-         If you want a NUMA kernel, select ACPI.   We need SRAT for NUMA.
+           This option compiles in the NUMAQ, Summit, bigsmp, ES7000, default
+         subarchitectures.  It is intended for a generic binary kernel.
+         if you select them all, kernel will probe it one by one. and will
+         fallback to default.
+ if X86_GENERICARCH
+ config X86_NUMAQ
+       bool "NUMAQ (IBM/Sequent)"
 -      depends on SMP && X86_32 && X86_MPPARSE
++      depends on SMP && X86_32 && PCI && X86_MPPARSE
+       select NUMA
+       help
+         This option is used for getting Linux to run on a NUMAQ (IBM/Sequent)
+         NUMA multiquad box. This changes the way that processors are
+         bootstrapped, and uses Clustered Logical APIC addressing mode instead
+         of Flat Logical.  You will need a new lynxer.elf file to flash your
+         firmware with - send email to <Martin.Bligh@us.ibm.com>.
+ config X86_SUMMIT
+       bool "Summit/EXA (IBM x440)"
+       depends on X86_32 && SMP
+       help
+         This option is needed for IBM systems that use the Summit/EXA chipset.
+         In particular, it is needed for the x440.
  
  config X86_ES7000
        bool "Support for Unisys ES7000 IA32 series"
@@@ -423,16 -442,32 +442,16 @@@ config MEMTES
        default y
        help
          This option adds a kernel parameter 'memtest', which allows memtest
 -        to be disabled at boot.  If this option is selected, memtest
 -        functionality can be disabled with memtest=0 on the kernel
 -        command line.  The purpose of this option is to allow a single
 -        kernel image to be distributed with memtest built in, but not
 -        necessarily enabled.
 -
 +        to be set.
 +              memtest=0, mean disabled; -- default
 +              memtest=1, mean do 1 test pattern;
 +              ...
 +              memtest=4, mean do 4 test patterns.
          If you are unsure how to answer this question, answer Y.
  
 -config MEMTEST_BOOTPARAM_VALUE
 -      int "Memtest boot parameter default value (0-4)"
 -      depends on MEMTEST_BOOTPARAM
 -      range 0 4
 -      default 0
 -      help
 -        This option sets the default value for the kernel parameter
 -        'memtest', which allows memtest to be disabled at boot.  If this
 -        option is set to 0 (zero), the memtest kernel parameter will
 -        default to 0, disabling memtest at bootup.  If this option is
 -        set to 4, the memtest kernel parameter will default to 4,
 -        enabling memtest at bootup, and use that as pattern number.
 -
 -        If you are unsure how to answer this question, answer 0.
 -
  config ACPI_SRAT
        def_bool y
-       depends on X86_32 && ACPI && NUMA && (X86_SUMMIT || X86_GENERICARCH)
+       depends on X86_32 && ACPI && NUMA && X86_GENERICARCH
        select ACPI_NUMA
  
  config HAVE_ARCH_PARSE_SRAT
Simple merge
Simple merge
Simple merge
index 53557cbe4bfae3d757433bbda23c72a74de7ac3b,bcc2b123dabf1733825509f7cb754ab806e15ab3..d1d4ee895270cf06a0dd57f9d9e167968b4c0071
@@@ -22,9 -22,10 +22,9 @@@ obj-y                        += setup_$(BITS).o i8259.o irqi
  obj-$(CONFIG_X86_32)  += sys_i386_32.o i386_ksyms_32.o
  obj-$(CONFIG_X86_64)  += sys_x86_64.o x8664_ksyms_64.o
  obj-$(CONFIG_X86_64)  += syscall_64.o vsyscall_64.o setup64.o
- obj-y                 += bootflag.o e820_$(BITS).o
+ obj-y                 += bootflag.o e820.o
  obj-y                 += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
  obj-y                 += alternative.o i8253.o pci-nommu.o
 -obj-$(CONFIG_X86_64)  += bugs_64.o
  obj-y                 += tsc_$(BITS).o io_delay.o rtc.o
  
  obj-$(CONFIG_X86_TRAMPOLINE)  += trampoline.o
Simple merge
index e819362c706853aab48b103be16f6b0e109ecccb,66b140932b23e2cad0c33601c265b53ffcdf47e6..600470d464faeb6291e562b6e1172be42f59988e
@@@ -326,33 -290,22 +326,33 @@@ void __init early_gart_iommu_check(void
        if (gart_fix_e820 && !fix && aper_enabled) {
                if (e820_any_mapped(aper_base, aper_base + aper_size,
                                    E820_RAM)) {
 -                      /* reserved it, so we can resuse it in second kernel */
 +                      /* reserve it, so we can reuse it in second kernel */
                        printk(KERN_INFO "update e820 for GART\n");
-                       add_memory_region(aper_base, aper_size, E820_RESERVED);
+                       e820_add_region(aper_base, aper_size, E820_RESERVED);
                        update_e820();
                }
 -              return;
        }
  
 +      if (!fix)
 +              return;
 +
        /* different nodes have different setting, disable them all at first*/
 -      for (num = 24; num < 32; num++) {
 -              if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00)))
 -                      continue;
 +      for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
 +              int bus;
 +              int dev_base, dev_limit;
 +
 +              bus = bus_dev_ranges[i].bus;
 +              dev_base = bus_dev_ranges[i].dev_base;
 +              dev_limit = bus_dev_ranges[i].dev_limit;
 +
 +              for (slot = dev_base; slot < dev_limit; slot++) {
 +                      if (!early_is_k8_nb(read_pci_config(bus, slot, 3, 0x00)))
 +                              continue;
  
 -              ctl = read_pci_config(0, num, 3, 0x90);
 -              ctl &= ~1;
 -              write_pci_config(0, num, 3, 0x90, ctl);
 +                      ctl = read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL);
 +                      ctl &= ~AMD64_GARTEN;
 +                      write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
 +              }
        }
  
  }
Simple merge
Simple merge
index dac47d61d2be9866e28c3ded5f9c4ea2232c277d,0662817d61bfdd61f189fb7576ada934fdbfbedb..fedb3b113acee3ac9fb80f12ee235c83402e6f5a
@@@ -844,8 -849,8 +850,8 @@@ static int __init find_isa_irq_apic(in
        }
        if (i < mp_irq_entries) {
                int apic;
 -              for(apic = 0; apic < nr_ioapics; apic++) {
 +              for (apic = 0; apic < nr_ioapics; apic++) {
-                       if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
+                       if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic)
                                return apic;
                }
        }
@@@ -878,10 -883,10 +884,10 @@@ int IO_APIC_get_PCI_irq_vector(int bus
                                break;
  
                if (!test_bit(lbus, mp_bus_not_pci) &&
-                   !mp_irqs[i].mpc_irqtype &&
+                   !mp_irqs[i].mp_irqtype &&
                    (bus == lbus) &&
-                   (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) {
-                       int irq = pin_2_irq(i, apic, mp_irqs[i].mpc_dstirq);
+                   (slot == ((mp_irqs[i].mp_srcbusirq >> 2) & 0x1f))) {
 -                      int irq = pin_2_irq(i,apic,mp_irqs[i].mp_dstirq);
++                      int irq = pin_2_irq(i, apic, mp_irqs[i].mp_dstirq);
  
                        if (!(apic || IO_APIC_IRQ(irq)))
                                continue;
@@@ -976,36 -981,37 +982,36 @@@ static int MPBIOS_polarity(int idx
        /*
         * Determine IRQ line polarity (high active or low active):
         */
-       switch (mp_irqs[idx].mpc_irqflag & 3) {
 -      switch (mp_irqs[idx].mp_irqflag & 3)
++      switch (mp_irqs[idx].mp_irqflag & 3) {
 +      case 0: /* conforms, ie. bus-type dependent polarity */
        {
 -              case 0: /* conforms, ie. bus-type dependent polarity */
 -              {
 -                      polarity = test_bit(bus, mp_bus_not_pci)?
 -                              default_ISA_polarity(idx):
 -                              default_PCI_polarity(idx);
 -                      break;
 -              }
 -              case 1: /* high active */
 -              {
 -                      polarity = 0;
 -                      break;
 -              }
 -              case 2: /* reserved */
 -              {
 -                      printk(KERN_WARNING "broken BIOS!!\n");
 -                      polarity = 1;
 -                      break;
 -              }
 -              case 3: /* low active */
 -              {
 -                      polarity = 1;
 -                      break;
 -              }
 -              default: /* invalid */
 -              {
 -                      printk(KERN_WARNING "broken BIOS!!\n");
 -                      polarity = 1;
 -                      break;
 -              }
 +              polarity = test_bit(bus, mp_bus_not_pci)?
 +                      default_ISA_polarity(idx):
 +                      default_PCI_polarity(idx);
 +              break;
 +      }
 +      case 1: /* high active */
 +      {
 +              polarity = 0;
 +              break;
 +      }
 +      case 2: /* reserved */
 +      {
 +              printk(KERN_WARNING "broken BIOS!!\n");
 +              polarity = 1;
 +              break;
 +      }
 +      case 3: /* low active */
 +      {
 +              polarity = 1;
 +              break;
 +      }
 +      default: /* invalid */
 +      {
 +              printk(KERN_WARNING "broken BIOS!!\n");
 +              polarity = 1;
 +              break;
 +      }
        }
        return polarity;
  }
@@@ -1018,38 -1024,66 +1024,38 @@@ static int MPBIOS_trigger(int idx
        /*
         * Determine IRQ trigger mode (edge or level sensitive):
         */
-       switch ((mp_irqs[idx].mpc_irqflag>>2) & 3) {
 -      switch ((mp_irqs[idx].mp_irqflag>>2) & 3)
++      switch ((mp_irqs[idx].mp_irqflag>>2) & 3) {
 +      case 0: /* conforms, ie. bus-type dependent */
        {
 -              case 0: /* conforms, ie. bus-type dependent */
 -              {
 -                      trigger = test_bit(bus, mp_bus_not_pci)?
 -                                      default_ISA_trigger(idx):
 -                                      default_PCI_trigger(idx);
 +              trigger = test_bit(bus, mp_bus_not_pci)?
 +                              default_ISA_trigger(idx):
 +                              default_PCI_trigger(idx);
  #if defined(CONFIG_EISA) || defined(CONFIG_MCA)
 -                      switch (mp_bus_id_to_type[bus])
 -                      {
 -                              case MP_BUS_ISA: /* ISA pin */
 -                              {
 -                                      /* set before the switch */
 -                                      break;
 -                              }
 -                              case MP_BUS_EISA: /* EISA pin */
 -                              {
 -                                      trigger = default_EISA_trigger(idx);
 -                                      break;
 -                              }
 -                              case MP_BUS_PCI: /* PCI pin */
 -                              {
 -                                      /* set before the switch */
 -                                      break;
 -                              }
 -                              case MP_BUS_MCA: /* MCA pin */
 -                              {
 -                                      trigger = default_MCA_trigger(idx);
 -                                      break;
 -                              }
 -                              default:
 -                              {
 -                                      printk(KERN_WARNING "broken BIOS!!\n");
 -                                      trigger = 1;
 -                                      break;
 -                              }
 -                      }
 -#endif
 +              switch (mp_bus_id_to_type[bus]) {
 +              case MP_BUS_ISA: /* ISA pin */
 +              {
 +                      /* set before the switch */
                        break;
                }
 -              case 1: /* edge */
 +              case MP_BUS_EISA: /* EISA pin */
                {
 -                      trigger = 0;
 +                      trigger = default_EISA_trigger(idx);
                        break;
                }
 -              case 2: /* reserved */
 +              case MP_BUS_PCI: /* PCI pin */
                {
 -                      printk(KERN_WARNING "broken BIOS!!\n");
 -                      trigger = 1;
 +                      /* set before the switch */
                        break;
                }
 -              case 3: /* level */
 +              case MP_BUS_MCA: /* MCA pin */
                {
 -                      trigger = 1;
 +                      trigger = default_MCA_trigger(idx);
                        break;
                }
 -              default: /* invalid */
 +              default:
                {
                        printk(KERN_WARNING "broken BIOS!!\n");
 -                      trigger = 0;
 +                      trigger = 1;
                        break;
                }
        }
@@@ -1345,10 -1360,10 +1351,10 @@@ void __init print_IO_APIC(void
        if (apic_verbosity == APIC_QUIET)
                return;
  
 -      printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
 +      printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
        for (i = 0; i < nr_ioapics; i++)
                printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
-                      mp_ioapics[i].mpc_apicid, nr_ioapic_registers[i]);
+                      mp_ioapics[i].mp_apicid, nr_ioapic_registers[i]);
  
        /*
         * We are a bit conservative about what we expect.  We have to
@@@ -1740,15 -1758,15 +1750,15 @@@ static void __init setup_ioapic_ids_fro
                spin_lock_irqsave(&ioapic_lock, flags);
                reg_00.raw = io_apic_read(apic, 0);
                spin_unlock_irqrestore(&ioapic_lock, flags);
 -              
 +
-               old_id = mp_ioapics[apic].mpc_apicid;
+               old_id = mp_ioapics[apic].mp_apicid;
  
-               if (mp_ioapics[apic].mpc_apicid >= get_physical_broadcast()) {
+               if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) {
                        printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
-                               apic, mp_ioapics[apic].mpc_apicid);
+                               apic, mp_ioapics[apic].mp_apicid);
                        printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
                                reg_00.bits.ID);
-                       mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
+                       mp_ioapics[apic].mp_apicid = reg_00.bits.ID;
                }
  
                /*
                /*
                 * Read the right value from the MPC table and
                 * write it into the ID register.
 -               */
 +               */
                apic_printk(APIC_VERBOSE, KERN_INFO
                        "...changing IO-APIC physical APIC ID to %d ...",
-                       mp_ioapics[apic].mpc_apicid);
+                       mp_ioapics[apic].mp_apicid);
  
-               reg_00.bits.ID = mp_ioapics[apic].mpc_apicid;
+               reg_00.bits.ID = mp_ioapics[apic].mp_apicid;
                spin_lock_irqsave(&ioapic_lock, flags);
                io_apic_write(apic, 0, reg_00.raw);
                spin_unlock_irqrestore(&ioapic_lock, flags);
Simple merge
index 545440e471b2f0e412fbf93f607e172a412bf0b5,3220c7b56eb3f1eb9029abb8871a299d5629b50b..9a87113ba996a9bf5583c236900d9294212dba00
@@@ -267,34 -266,18 +268,6 @@@ static inline void __init reserve_crash
  {}
  #endif
  
- /* Overridden in paravirt.c if CONFIG_PARAVIRT */
- void __attribute__((weak)) __init memory_setup(void)
 -#ifdef CONFIG_PCI_MMCONFIG
 -extern void __cpuinit fam10h_check_enable_mmcfg(void);
 -extern void __init check_enable_amd_mmconf_dmi(void);
 -#else
 -void __cpuinit fam10h_check_enable_mmcfg(void)
--{
-        machine_specific_memory_setup();
--}
- static void __init parse_setup_data(void)
 -void __init check_enable_amd_mmconf_dmi(void)
--{
-       struct setup_data *data;
-       unsigned long pa_data;
-       if (boot_params.hdr.version < 0x0209)
-               return;
-       pa_data = boot_params.hdr.setup_data;
-       while (pa_data) {
-               data = early_ioremap(pa_data, PAGE_SIZE);
-               switch (data->type) {
-               default:
-                       break;
-               }
- #ifndef CONFIG_DEBUG_BOOT_PARAMS
-               free_early(pa_data, pa_data+sizeof(*data)+data->len);
- #endif
-               pa_data = data->next;
-               early_iounmap(data, PAGE_SIZE);
-       }
--}
 -#endif
--
  /*
   * setup_arch - architecture-specific boot-time initializations
   *
Simple merge
index 8b4eac0ca07d8265314e0b2551daef03933f6ae2,6216e43b6e95c71e1cabaa11b3c591998563390a..a2f73ba42b8bcbe6bf1eddc18e2052644d2b0882
@@@ -156,21 -156,32 +156,29 @@@ static void __init propagate_e820_map_n
   */
  static void __init allocate_pgdat(int nid)
  {
 -      if (nid && node_has_online_mem(nid))
 +      if (nid && node_has_online_mem(nid) && node_remap_start_vaddr[nid])
                NODE_DATA(nid) = (pg_data_t *)node_remap_start_vaddr[nid];
        else {
-               NODE_DATA(nid) = (pg_data_t *)(pfn_to_kaddr(min_low_pfn));
-               min_low_pfn += PFN_UP(sizeof(pg_data_t));
+               unsigned long pgdat_phys;
+               pgdat_phys = find_e820_area(min_low_pfn<<PAGE_SHIFT,
+                                (nid ? max_low_pfn:max_pfn_mapped)<<PAGE_SHIFT,
+                                sizeof(pg_data_t),
+                                PAGE_SIZE);
+               NODE_DATA(nid) = (pg_data_t *)(pfn_to_kaddr(pgdat_phys>>PAGE_SHIFT));
+               reserve_early(pgdat_phys, pgdat_phys + sizeof(pg_data_t),
+                             "NODE_DATA");
        }
+       printk(KERN_DEBUG "allocate_pgdat: node %d NODE_DATA %08lx\n",
+               nid, (unsigned long)NODE_DATA(nid));
  }
  
 -#ifdef CONFIG_DISCONTIGMEM
  /*
 - * In the discontig memory model, a portion of the kernel virtual area (KVA)
 - * is reserved and portions of nodes are mapped using it. This is to allow
 - * node-local memory to be allocated for structures that would normally require
 - * ZONE_NORMAL. The memory is allocated with alloc_remap() and callers
 - * should be prepared to allocate from the bootmem allocator instead. This KVA
 - * mechanism is incompatible with SPARSEMEM as it makes assumptions about the
 - * layout of memory that are broken if alloc_remap() succeeds for some of the
 - * map and fails for others
 + * In the DISCONTIGMEM and SPARSEMEM memory model, a portion of the kernel
 + * virtual address space (KVA) is reserved and portions of nodes are mapped
 + * using it. This is to allow node-local memory to be allocated for
 + * structures that would normally require ZONE_NORMAL. The memory is
 + * allocated with alloc_remap() and callers should be prepared to allocate
 + * from the bootmem allocator instead.
   */
  static unsigned long node_remap_start_pfn[MAX_NUMNODES];
  static void *node_remap_end_vaddr[MAX_NUMNODES];
@@@ -284,9 -309,27 +306,8 @@@ static void init_remap_allocator(int ni
  
        printk ("node %d will remap to vaddr %08lx - %08lx\n", nid,
                (ulong) node_remap_start_vaddr[nid],
-               (ulong) pfn_to_kaddr(highstart_pfn
-                  + node_remap_offset[nid] + node_remap_size[nid]));
+               (ulong) node_remap_end_vaddr[nid]);
  }
 -#else
 -void *alloc_remap(int nid, unsigned long size)
 -{
 -      return NULL;
 -}
 -
 -static unsigned long calculate_numa_remap_pages(void)
 -{
 -      return 0;
 -}
 -
 -static void init_remap_allocator(int nid)
 -{
 -}
 -
 -void __init remap_numa_kva(void)
 -{
 -}
 -#endif /* CONFIG_DISCONTIGMEM */
  
  extern void setup_bootmem_allocator(void);
  unsigned long __init setup_memory(void)
index d71be0eb0130ec0bf6cc9838db5be69493826c5d,fb5694d788bfda1274b6647b8824d76f3cce9cff..65d55056b6e781c72b1740dad18747682a2985eb
@@@ -221,17 -218,8 +221,10 @@@ static void __init kernel_physical_mapp
                        max_pfn_mapped = pfn;
                }
        }
 +      update_page_count(PG_LEVEL_2M, pages_2m);
 +      update_page_count(PG_LEVEL_4K, pages_4k);
  }
  
- static inline int page_kills_ppro(unsigned long pagenr)
- {
-       if (pagenr >= 0x70000 && pagenr <= 0x7003F)
-               return 1;
-       return 0;
- }
  /*
   * devmem_is_allowed() checks to see if /dev/mem access to a certain address
   * is valid. The argument is a physical page number.
@@@ -573,9 -592,18 +597,7 @@@ void __init mem_init(void
  
  #ifdef CONFIG_FLATMEM
        BUG_ON(!mem_map);
 -#endif
 -#ifdef CONFIG_HIGHMEM
 -      /* check that fixmap and pkmap do not overlap */
 -      if (PKMAP_BASE + LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
 -              printk(KERN_ERR
 -                      "fixmap and kmap areas overlap - this will crash\n");
 -              printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n",
 -                              PKMAP_BASE, PKMAP_BASE + LAST_PKMAP*PAGE_SIZE,
 -                              FIXADDR_START);
 -              BUG();
 -      }
  #endif
-       bad_ppro = ppro_with_ram_bug();
        /* this will put all low memory onto the freelists */
        totalram_pages += free_all_bootmem();
  
Simple merge
Simple merge
Simple merge
index 15f505d3a78ef99b3591d1ca7fb24d0d2c278688,0000000000000000000000000000000000000000..d02c598451ec91dadd346b54d91d7d296b291a81
mode 100644,000000..100644
--- /dev/null
@@@ -1,560 -1,0 +1,560 @@@
-       end = (val & 0xffffff8000000ULL);
 +#include <linux/init.h>
 +#include <linux/pci.h>
 +#include "pci.h"
 +
 +#ifdef CONFIG_X86_64
 +
 +#include <asm/pci-direct.h>
 +#include <asm/mpspec.h>
 +#include <linux/cpumask.h>
 +#include <linux/topology.h>
 +
 +/*
 + * This discovers the pcibus <-> node mapping on AMD K8.
 + * also get peer root bus resource for io,mmio
 + */
 +
 +
 +/*
 + * sub bus (transparent) will use entres from 3 to store extra from root,
 + * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES?
 + */
 +#define RES_NUM 16
 +struct pci_root_info {
 +      char name[12];
 +      unsigned int res_num;
 +      struct resource res[RES_NUM];
 +      int bus_min;
 +      int bus_max;
 +      int node;
 +      int link;
 +};
 +
 +/* 4 at this time, it may become to 32 */
 +#define PCI_ROOT_NR 4
 +static int pci_root_num;
 +static struct pci_root_info pci_root_info[PCI_ROOT_NR];
 +
 +#ifdef CONFIG_NUMA
 +
 +#define BUS_NR 256
 +
 +static int mp_bus_to_node[BUS_NR];
 +
 +void set_mp_bus_to_node(int busnum, int node)
 +{
 +      if (busnum >= 0 &&  busnum < BUS_NR)
 +              mp_bus_to_node[busnum] = node;
 +}
 +
 +int get_mp_bus_to_node(int busnum)
 +{
 +      int node = -1;
 +
 +      if (busnum < 0 || busnum > (BUS_NR - 1))
 +              return node;
 +
 +      node = mp_bus_to_node[busnum];
 +
 +      /*
 +       * let numa_node_id to decide it later in dma_alloc_pages
 +       * if there is no ram on that node
 +       */
 +      if (node != -1 && !node_online(node))
 +              node = -1;
 +
 +      return node;
 +}
 +#endif
 +
 +void set_pci_bus_resources_arch_default(struct pci_bus *b)
 +{
 +      int i;
 +      int j;
 +      struct pci_root_info *info;
 +
 +      /* if only one root bus, don't need to anything */
 +      if (pci_root_num < 2)
 +              return;
 +
 +      for (i = 0; i < pci_root_num; i++) {
 +              if (pci_root_info[i].bus_min == b->number)
 +                      break;
 +      }
 +
 +      if (i == pci_root_num)
 +              return;
 +
 +      info = &pci_root_info[i];
 +      for (j = 0; j < info->res_num; j++) {
 +              struct resource *res;
 +              struct resource *root;
 +
 +              res = &info->res[j];
 +              b->resource[j] = res;
 +              if (res->flags & IORESOURCE_IO)
 +                      root = &ioport_resource;
 +              else
 +                      root = &iomem_resource;
 +              insert_resource(root, res);
 +      }
 +}
 +
 +#define RANGE_NUM 16
 +
 +struct res_range {
 +      size_t start;
 +      size_t end;
 +};
 +
 +static void __init update_range(struct res_range *range, size_t start,
 +                              size_t end)
 +{
 +      int i;
 +      int j;
 +
 +      for (j = 0; j < RANGE_NUM; j++) {
 +              if (!range[j].end)
 +                      continue;
 +
 +              if (start <= range[j].start && end >= range[j].end) {
 +                      range[j].start = 0;
 +                      range[j].end = 0;
 +                      continue;
 +              }
 +
 +              if (start <= range[j].start && end < range[j].end && range[j].start < end + 1) {
 +                      range[j].start = end + 1;
 +                      continue;
 +              }
 +
 +
 +              if (start > range[j].start && end >= range[j].end && range[j].end > start - 1) {
 +                      range[j].end = start - 1;
 +                      continue;
 +              }
 +
 +              if (start > range[j].start && end < range[j].end) {
 +                      /* find the new spare */
 +                      for (i = 0; i < RANGE_NUM; i++) {
 +                              if (range[i].end == 0)
 +                                      break;
 +                      }
 +                      if (i < RANGE_NUM) {
 +                              range[i].end = range[j].end;
 +                              range[i].start = end + 1;
 +                      } else {
 +                              printk(KERN_ERR "run of slot in ranges\n");
 +                      }
 +                      range[j].end = start - 1;
 +                      continue;
 +              }
 +      }
 +}
 +
 +static void __init update_res(struct pci_root_info *info, size_t start,
 +                            size_t end, unsigned long flags, int merge)
 +{
 +      int i;
 +      struct resource *res;
 +
 +      if (!merge)
 +              goto addit;
 +
 +      /* try to merge it with old one */
 +      for (i = 0; i < info->res_num; i++) {
 +              size_t final_start, final_end;
 +              size_t common_start, common_end;
 +
 +              res = &info->res[i];
 +              if (res->flags != flags)
 +                      continue;
 +
 +              common_start = max((size_t)res->start, start);
 +              common_end = min((size_t)res->end, end);
 +              if (common_start > common_end + 1)
 +                      continue;
 +
 +              final_start = min((size_t)res->start, start);
 +              final_end = max((size_t)res->end, end);
 +
 +              res->start = final_start;
 +              res->end = final_end;
 +              return;
 +      }
 +
 +addit:
 +
 +      /* need to add that */
 +      if (info->res_num >= RES_NUM)
 +              return;
 +
 +      res = &info->res[info->res_num];
 +      res->name = info->name;
 +      res->flags = flags;
 +      res->start = start;
 +      res->end = end;
 +      res->child = NULL;
 +      info->res_num++;
 +}
 +
 +struct pci_hostbridge_probe {
 +      u32 bus;
 +      u32 slot;
 +      u32 vendor;
 +      u32 device;
 +};
 +
 +static struct pci_hostbridge_probe pci_probes[] __initdata = {
 +      { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1100 },
 +      { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 },
 +      { 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 },
 +      { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1300 },
 +};
 +
 +static u64 __initdata fam10h_mmconf_start;
 +static u64 __initdata fam10h_mmconf_end;
 +static void __init get_pci_mmcfg_amd_fam10h_range(void)
 +{
 +      u32 address;
 +      u64 base, msr;
 +      unsigned segn_busn_bits;
 +
 +      /* assume all cpus from fam10h have mmconf */
 +        if (boot_cpu_data.x86 < 0x10)
 +              return;
 +
 +      address = MSR_FAM10H_MMIO_CONF_BASE;
 +      rdmsrl(address, msr);
 +
 +      /* mmconfig is not enable */
 +      if (!(msr & FAM10H_MMIO_CONF_ENABLE))
 +              return;
 +
 +      base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
 +
 +      segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
 +                       FAM10H_MMIO_CONF_BUSRANGE_MASK;
 +
 +      fam10h_mmconf_start = base;
 +      fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
 +}
 +
 +/**
 + * early_fill_mp_bus_to_node()
 + * called before pcibios_scan_root and pci_scan_bus
 + * fills the mp_bus_to_cpumask array based according to the LDT Bus Number
 + * Registers found in the K8 northbridge
 + */
 +static int __init early_fill_mp_bus_info(void)
 +{
 +      int i;
 +      int j;
 +      unsigned bus;
 +      unsigned slot;
 +      int found;
 +      int node;
 +      int link;
 +      int def_node;
 +      int def_link;
 +      struct pci_root_info *info;
 +      u32 reg;
 +      struct resource *res;
 +      size_t start;
 +      size_t end;
 +      struct res_range range[RANGE_NUM];
 +      u64 val;
 +      u32 address;
 +
 +#ifdef CONFIG_NUMA
 +      for (i = 0; i < BUS_NR; i++)
 +              mp_bus_to_node[i] = -1;
 +#endif
 +
 +      if (!early_pci_allowed())
 +              return -1;
 +
 +      found = 0;
 +      for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
 +              u32 id;
 +              u16 device;
 +              u16 vendor;
 +
 +              bus = pci_probes[i].bus;
 +              slot = pci_probes[i].slot;
 +              id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID);
 +
 +              vendor = id & 0xffff;
 +              device = (id>>16) & 0xffff;
 +              if (pci_probes[i].vendor == vendor &&
 +                  pci_probes[i].device == device) {
 +                      found = 1;
 +                      break;
 +              }
 +      }
 +
 +      if (!found)
 +              return 0;
 +
 +      pci_root_num = 0;
 +      for (i = 0; i < 4; i++) {
 +              int min_bus;
 +              int max_bus;
 +              reg = read_pci_config(bus, slot, 1, 0xe0 + (i << 2));
 +
 +              /* Check if that register is enabled for bus range */
 +              if ((reg & 7) != 3)
 +                      continue;
 +
 +              min_bus = (reg >> 16) & 0xff;
 +              max_bus = (reg >> 24) & 0xff;
 +              node = (reg >> 4) & 0x07;
 +#ifdef CONFIG_NUMA
 +              for (j = min_bus; j <= max_bus; j++)
 +                      mp_bus_to_node[j] = (unsigned char) node;
 +#endif
 +              link = (reg >> 8) & 0x03;
 +
 +              info = &pci_root_info[pci_root_num];
 +              info->bus_min = min_bus;
 +              info->bus_max = max_bus;
 +              info->node = node;
 +              info->link = link;
 +              sprintf(info->name, "PCI Bus #%02x", min_bus);
 +              pci_root_num++;
 +      }
 +
 +      /* get the default node and link for left over res */
 +      reg = read_pci_config(bus, slot, 0, 0x60);
 +      def_node = (reg >> 8) & 0x07;
 +      reg = read_pci_config(bus, slot, 0, 0x64);
 +      def_link = (reg >> 8) & 0x03;
 +
 +      memset(range, 0, sizeof(range));
 +      range[0].end = 0xffff;
 +      /* io port resource */
 +      for (i = 0; i < 4; i++) {
 +              reg = read_pci_config(bus, slot, 1, 0xc0 + (i << 3));
 +              if (!(reg & 3))
 +                      continue;
 +
 +              start = reg & 0xfff000;
 +              reg = read_pci_config(bus, slot, 1, 0xc4 + (i << 3));
 +              node = reg & 0x07;
 +              link = (reg >> 4) & 0x03;
 +              end = (reg & 0xfff000) | 0xfff;
 +
 +              /* find the position */
 +              for (j = 0; j < pci_root_num; j++) {
 +                      info = &pci_root_info[j];
 +                      if (info->node == node && info->link == link)
 +                              break;
 +              }
 +              if (j == pci_root_num)
 +                      continue; /* not found */
 +
 +              info = &pci_root_info[j];
 +              printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n",
 +                     node, link, (u64)start, (u64)end);
 +
 +              /* kernel only handle 16 bit only */
 +              if (end > 0xffff)
 +                      end = 0xffff;
 +              update_res(info, start, end, IORESOURCE_IO, 1);
 +              update_range(range, start, end);
 +      }
 +      /* add left over io port range to def node/link, [0, 0xffff] */
 +      /* find the position */
 +      for (j = 0; j < pci_root_num; j++) {
 +              info = &pci_root_info[j];
 +              if (info->node == def_node && info->link == def_link)
 +                      break;
 +      }
 +      if (j < pci_root_num) {
 +              info = &pci_root_info[j];
 +              for (i = 0; i < RANGE_NUM; i++) {
 +                      if (!range[i].end)
 +                              continue;
 +
 +                      update_res(info, range[i].start, range[i].end,
 +                                 IORESOURCE_IO, 1);
 +              }
 +      }
 +
 +      memset(range, 0, sizeof(range));
 +      /* 0xfd00000000-0xffffffffff for HT */
 +      range[0].end = (0xfdULL<<32) - 1;
 +
 +      /* need to take out [0, TOM) for RAM*/
 +      address = MSR_K8_TOP_MEM1;
 +      rdmsrl(address, val);
-               end = (val & 0xffffff8000000ULL);
++      end = (val & 0xffffff800000ULL);
 +      printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20);
 +      if (end < (1ULL<<32))
 +              update_range(range, 0, end - 1);
 +
 +      /* get mmconfig */
 +      get_pci_mmcfg_amd_fam10h_range();
 +      /* need to take out mmconf range */
 +      if (fam10h_mmconf_end) {
 +              printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
 +              update_range(range, fam10h_mmconf_start, fam10h_mmconf_end);
 +      }
 +
 +      /* mmio resource */
 +      for (i = 0; i < 8; i++) {
 +              reg = read_pci_config(bus, slot, 1, 0x80 + (i << 3));
 +              if (!(reg & 3))
 +                      continue;
 +
 +              start = reg & 0xffffff00; /* 39:16 on 31:8*/
 +              start <<= 8;
 +              reg = read_pci_config(bus, slot, 1, 0x84 + (i << 3));
 +              node = reg & 0x07;
 +              link = (reg >> 4) & 0x03;
 +              end = (reg & 0xffffff00);
 +              end <<= 8;
 +              end |= 0xffff;
 +
 +              /* find the position */
 +              for (j = 0; j < pci_root_num; j++) {
 +                      info = &pci_root_info[j];
 +                      if (info->node == node && info->link == link)
 +                              break;
 +              }
 +              if (j == pci_root_num)
 +                      continue; /* not found */
 +
 +              info = &pci_root_info[j];
 +
 +              printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]",
 +                     node, link, (u64)start, (u64)end);
 +              /*
 +               * some sick allocation would have range overlap with fam10h
 +               * mmconf range, so need to update start and end.
 +               */
 +              if (fam10h_mmconf_end) {
 +                      int changed = 0;
 +                      u64 endx = 0;
 +                      if (start >= fam10h_mmconf_start &&
 +                          start <= fam10h_mmconf_end) {
 +                              start = fam10h_mmconf_end + 1;
 +                              changed = 1;
 +                      }
 +
 +                      if (end >= fam10h_mmconf_start &&
 +                          end <= fam10h_mmconf_end) {
 +                              end = fam10h_mmconf_start - 1;
 +                              changed = 1;
 +                      }
 +
 +                      if (start < fam10h_mmconf_start &&
 +                          end > fam10h_mmconf_end) {
 +                              /* we got a hole */
 +                              endx = fam10h_mmconf_start - 1;
 +                              update_res(info, start, endx, IORESOURCE_MEM, 0);
 +                              update_range(range, start, endx);
 +                              printk(KERN_CONT " ==> [%llx, %llx]", (u64)start, endx);
 +                              start = fam10h_mmconf_end + 1;
 +                              changed = 1;
 +                      }
 +                      if (changed) {
 +                              if (start <= end) {
 +                                      printk(KERN_CONT " %s [%llx, %llx]", endx?"and":"==>", (u64)start, (u64)end);
 +                              } else {
 +                                      printk(KERN_CONT "%s\n", endx?"":" ==> none");
 +                                      continue;
 +                              }
 +                      }
 +              }
 +
 +              update_res(info, start, end, IORESOURCE_MEM, 1);
 +              update_range(range, start, end);
 +              printk(KERN_CONT "\n");
 +      }
 +
 +      /* need to take out [4G, TOM2) for RAM*/
 +      /* SYS_CFG */
 +      address = MSR_K8_SYSCFG;
 +      rdmsrl(address, val);
 +      /* TOP_MEM2 is enabled? */
 +      if (val & (1<<21)) {
 +              /* TOP_MEM2 */
 +              address = MSR_K8_TOP_MEM2;
 +              rdmsrl(address, val);
++              end = (val & 0xffffff800000ULL);
 +              printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20);
 +              update_range(range, 1ULL<<32, end - 1);
 +      }
 +
 +      /*
 +       * add left over mmio range to def node/link ?
 +       * that is tricky, just record range in from start_min to 4G
 +       */
 +      for (j = 0; j < pci_root_num; j++) {
 +              info = &pci_root_info[j];
 +              if (info->node == def_node && info->link == def_link)
 +                      break;
 +      }
 +      if (j < pci_root_num) {
 +              info = &pci_root_info[j];
 +
 +              for (i = 0; i < RANGE_NUM; i++) {
 +                      if (!range[i].end)
 +                              continue;
 +
 +                      update_res(info, range[i].start, range[i].end,
 +                                 IORESOURCE_MEM, 1);
 +              }
 +      }
 +
 +      for (i = 0; i < pci_root_num; i++) {
 +              int res_num;
 +              int busnum;
 +
 +              info = &pci_root_info[i];
 +              res_num = info->res_num;
 +              busnum = info->bus_min;
 +              printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n",
 +                     info->bus_min, info->bus_max, info->node, info->link);
 +              for (j = 0; j < res_num; j++) {
 +                      res = &info->res[j];
 +                      printk(KERN_DEBUG "bus: %02x index %x %s: [%llx, %llx]\n",
 +                             busnum, j,
 +                             (res->flags & IORESOURCE_IO)?"io port":"mmio",
 +                             res->start, res->end);
 +              }
 +      }
 +
 +      return 0;
 +}
 +
 +postcore_initcall(early_fill_mp_bus_info);
 +
 +#endif
 +
 +/* common 32/64 bit code */
 +
 +#define ENABLE_CF8_EXT_CFG      (1ULL << 46)
 +
 +static void enable_pci_io_ecs_per_cpu(void *unused)
 +{
 +      u64 reg;
 +      rdmsrl(MSR_AMD64_NB_CFG, reg);
 +      if (!(reg & ENABLE_CF8_EXT_CFG)) {
 +              reg |= ENABLE_CF8_EXT_CFG;
 +              wrmsrl(MSR_AMD64_NB_CFG, reg);
 +      }
 +}
 +
 +static int __init enable_pci_io_ecs(void)
 +{
 +      /* assume all cpus from fam10h have IO ECS */
 +        if (boot_cpu_data.x86 < 0x10)
 +              return 0;
 +      on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1, 1);
 +      pci_probe |= PCI_HAS_IO_ECS;
 +      return 0;
 +}
 +
 +postcore_initcall(enable_pci_io_ecs);
index bd74229081c3c4614f80319449cfb74f423e9ccc,275163f81464d452dc75f3f9a5af5d3a7b51a38b..fe60aa9fed0a6a73fbed57b1fc63dcfeec39a761
@@@ -1309,12 -1233,9 +1310,12 @@@ asmlinkage void __init xen_start_kernel
                ? __pa(xen_start_info->mod_start) : 0;
        boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
  
 -      if (!is_initial_xendomain())
 +      if (!is_initial_xendomain()) {
 +              add_preferred_console("xenboot", 0, NULL);
 +              add_preferred_console("tty", 0, NULL);
                add_preferred_console("hvc", 0, NULL);
 +      }
  
        /* Start the world */
-       start_kernel();
+       i386_start_kernel();
  }
index 488447878a9df059ccc9cf87c9c37d18f034df2a,9001c9df04d82a7027408633244c868b25ea2944..a29575803204b87301d457dbdc05a6805b252a3b
@@@ -37,11 -38,9 +37,11 @@@ char * __init xen_memory_setup(void
  {
        unsigned long max_pfn = xen_start_info->nr_pages;
  
 +      max_pfn = min(MAX_DOMAIN_PAGES, max_pfn);
 +
        e820.nr_map = 0;
-       add_memory_region(0, LOWMEMSIZE(), E820_RAM);
-       add_memory_region(HIGH_MEMORY, PFN_PHYS(max_pfn)-HIGH_MEMORY, E820_RAM);
+       e820_add_region(0, LOWMEMSIZE(), E820_RAM);
+       e820_add_region(HIGH_MEMORY, PFN_PHYS(max_pfn)-HIGH_MEMORY, E820_RAM);
  
        return "Xen";
  }
Simple merge
Simple merge
Simple merge
Simple merge