x86: Fix a section mismatch in arch/x86/kernel/setup.c
[safe/jmp/linux-2.6] / arch / x86 / kernel / setup.c
index e894f36..e020b2d 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/screen_info.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
+#include <linux/sfi.h>
 #include <linux/apm_bios.h>
 #include <linux/initrd.h>
 #include <linux/bootmem.h>
@@ -66,6 +67,7 @@
 
 #include <linux/percpu.h>
 #include <linux/crash_dump.h>
+#include <linux/tboot.h>
 
 #include <video/edid.h>
 
 #include <asm/numa_64.h>
 #endif
 
-#ifndef ARCH_SETUP
-#define ARCH_SETUP
-#endif
+/*
+ * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
+ * The direct mapping extends to max_pfn_mapped, so that we can directly access
+ * apertures, ACPI and other tables without having to play with fixmaps.
+ */
+unsigned long max_low_pfn_mapped;
+unsigned long max_pfn_mapped;
+
+RESERVE_BRK(dmi_alloc, 65536);
 
 unsigned int boot_cpu_id __read_mostly;
 
@@ -123,9 +131,9 @@ int default_cpu_present_to_apicid(int mps_cpu)
        return __default_cpu_present_to_apicid(mps_cpu);
 }
 
-int default_check_phys_apicid_present(int boot_cpu_physical_apicid)
+int default_check_phys_apicid_present(int phys_apicid)
 {
-       return __default_check_phys_apicid_present(boot_cpu_physical_apicid);
+       return __default_check_phys_apicid_present(phys_apicid);
 }
 #endif
 
@@ -161,13 +169,6 @@ static struct resource bss_resource = {
 
 
 #ifdef CONFIG_X86_32
-static struct resource video_ram_resource = {
-       .name   = "Video RAM area",
-       .start  = 0xa0000,
-       .end    = 0xbffff,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
-};
-
 /* cpu data as detected by the assembly code in head.S */
 struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1};
 /* common cpu data for all cpus */
@@ -212,8 +213,8 @@ unsigned long mmu_cr4_features;
 unsigned long mmu_cr4_features = X86_CR4_PAE;
 #endif
 
-/* Boot loader ID as an integer, for the benefit of proc_dointvec */
-int bootloader_type;
+/* Boot loader ID and version as integers, for the benefit of proc_dointvec */
+int bootloader_type, bootloader_version;
 
 /*
  * Setup options
@@ -246,7 +247,7 @@ EXPORT_SYMBOL(edd);
  *              from boot_params into a safe place.
  *
  */
-static inline void copy_edd(void)
+static inline void __init copy_edd(void)
 {
      memcpy(edd.mbr_signature, boot_params.edd_mbr_sig_buffer,
            sizeof(edd.mbr_signature));
@@ -255,7 +256,7 @@ static inline void copy_edd(void)
      edd.edd_info_nr = boot_params.eddbuf_entries;
 }
 #else
-static inline void copy_edd(void)
+static inline void __init copy_edd(void)
 {
 }
 #endif
@@ -279,6 +280,20 @@ void * __init extend_brk(size_t size, size_t align)
        return ret;
 }
 
+#ifdef CONFIG_X86_64
+static void __init init_gbpages(void)
+{
+       if (direct_gbpages && cpu_has_gbpages)
+               printk(KERN_INFO "Using GB pages for direct mapping\n");
+       else
+               direct_gbpages = 0;
+}
+#else
+static inline void init_gbpages(void)
+{
+}
+#endif
+
 static void __init reserve_brk(void)
 {
        if (_brk_end > _brk_start)
@@ -291,15 +306,13 @@ static void __init reserve_brk(void)
 
 #ifdef CONFIG_BLK_DEV_INITRD
 
-#ifdef CONFIG_X86_32
-
 #define MAX_MAP_CHUNK  (NR_FIX_BTMAPS << PAGE_SHIFT)
 static void __init relocate_initrd(void)
 {
 
        u64 ramdisk_image = boot_params.hdr.ramdisk_image;
        u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
-       u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT;
+       u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
        u64 ramdisk_here;
        unsigned long slop, clen, mapaddr;
        char *p, *q;
@@ -355,14 +368,13 @@ static void __init relocate_initrd(void)
                ramdisk_image, ramdisk_image + ramdisk_size - 1,
                ramdisk_here, ramdisk_here + ramdisk_size - 1);
 }
-#endif
 
 static void __init reserve_initrd(void)
 {
        u64 ramdisk_image = boot_params.hdr.ramdisk_image;
        u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
        u64 ramdisk_end   = ramdisk_image + ramdisk_size;
-       u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT;
+       u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
 
        if (!boot_params.hdr.type_of_loader ||
            !ramdisk_image || !ramdisk_size)
@@ -392,14 +404,8 @@ static void __init reserve_initrd(void)
                return;
        }
 
-#ifdef CONFIG_X86_32
        relocate_initrd();
-#else
-       printk(KERN_ERR "initrd extends beyond end of memory "
-              "(0x%08llx > 0x%08llx)\ndisabling initrd\n",
-              ramdisk_end, end_of_lowmem);
-       initrd_start = 0;
-#endif
+
        free_early(ramdisk_image, ramdisk_end);
 }
 #else
@@ -590,7 +596,7 @@ static struct resource standard_io_resources[] = {
                .flags = IORESOURCE_BUSY | IORESOURCE_IO }
 };
 
-static void __init reserve_standard_io_resources(void)
+void __init reserve_standard_io_resources(void)
 {
        int i;
 
@@ -622,10 +628,6 @@ static int __init setup_elfcorehdr(char *arg)
 early_param("elfcorehdr", setup_elfcorehdr);
 #endif
 
-static struct x86_quirks default_x86_quirks __initdata;
-
-struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
-
 #ifdef CONFIG_X86_RESERVE_LOW_64K
 static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
 {
@@ -657,6 +659,19 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
                        DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies"),
                },
        },
+       {
+       /*
+        * AMI BIOS with low memory corruption was found on Intel DG45ID board.
+        * It hase different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
+        * match only DMI_BOARD_NAME and see if there is more bad products
+        * with this vendor.
+        */
+               .callback = dmi_low_memory_corruption,
+               .ident = "AMI BIOS",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "DG45ID"),
+               },
+       },
 #endif
        {}
 };
@@ -704,6 +719,12 @@ void __init setup_arch(char **cmdline_p)
 #endif
        saved_video_mode = boot_params.hdr.vid_mode;
        bootloader_type = boot_params.hdr.type_of_loader;
+       if ((bootloader_type >> 4) == 0xe) {
+               bootloader_type &= 0xf;
+               bootloader_type |= (boot_params.hdr.ext_loader_type+0x10) << 4;
+       }
+       bootloader_version  = bootloader_type & 0xf;
+       bootloader_version |= boot_params.hdr.ext_loader_ver << 4;
 
 #ifdef CONFIG_BLK_DEV_RAM
        rd_image_start = boot_params.hdr.ram_size & RAMDISK_IMAGE_START_MASK;
@@ -723,7 +744,7 @@ void __init setup_arch(char **cmdline_p)
        }
 #endif
 
-       ARCH_SETUP
+       x86_init.oem.arch_setup();
 
        setup_memory_map();
        parse_setup_data();
@@ -762,6 +783,16 @@ void __init setup_arch(char **cmdline_p)
        strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
        *cmdline_p = command_line;
 
+#ifdef CONFIG_X86_64
+       /*
+        * Must call this twice: Once just to detect whether hardware doesn't
+        * support NX (so that the early EHCI debug console setup can safely
+        * call set_fixmap(), and then again after parsing early parameters to
+        * honor the respective command line option.
+        */
+       check_efer();
+#endif
+
        parse_early_param();
 
 #ifdef CONFIG_X86_64
@@ -799,11 +830,9 @@ void __init setup_arch(char **cmdline_p)
         * VMware detection requires dmi to be available, so this
         * needs to be done after dmi_scan_machine, for the BP.
         */
-       init_hypervisor(&boot_cpu_data);
+       init_hypervisor_platform();
 
-#ifdef CONFIG_X86_32
-       probe_roms();
-#endif
+       x86_init.resources.probe_roms();
 
        /* after parse_early_param, so could debug it */
        insert_resource(&iomem_resource, &code_resource);
@@ -852,14 +881,20 @@ void __init setup_arch(char **cmdline_p)
                max_low_pfn = max_pfn;
 
        high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
+       max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
 #endif
 
 #ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
        setup_bios_corruption_check();
 #endif
 
+       printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
+                       max_pfn_mapped<<PAGE_SHIFT);
+
        reserve_brk();
 
+       init_gbpages();
+
        /* max_pfn_mapped is updated here */
        max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT);
        max_pfn_mapped = max_low_pfn_mapped;
@@ -932,10 +967,11 @@ void __init setup_arch(char **cmdline_p)
        kvmclock_init();
 #endif
 
-       paravirt_pagetable_setup_start(swapper_pg_dir);
+       x86_init.paging.pagetable_setup_start(swapper_pg_dir);
        paging_init();
-       paravirt_pagetable_setup_done(swapper_pg_dir);
-       paravirt_post_allocator_init();
+       x86_init.paging.pagetable_setup_done(swapper_pg_dir);
+
+       tboot_probe();
 
 #ifdef CONFIG_X86_64
        map_vsyscall();
@@ -950,13 +986,13 @@ void __init setup_arch(char **cmdline_p)
         */
        acpi_boot_init();
 
-#if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS)
+       sfi_init();
+
        /*
         * get boot-time SMP configuration:
         */
        if (smp_found_config)
                get_smp_config();
-#endif
 
        prefill_possible_map();
 
@@ -975,10 +1011,7 @@ void __init setup_arch(char **cmdline_p)
        e820_reserve_resources();
        e820_mark_nosave_regions(max_low_pfn);
 
-#ifdef CONFIG_X86_32
-       request_resource(&iomem_resource, &video_ram_resource);
-#endif
-       reserve_standard_io_resources();
+       x86_init.resources.reserve_resources();
 
        e820_setup_gap();
 
@@ -990,97 +1023,22 @@ void __init setup_arch(char **cmdline_p)
        conswitchp = &dummy_con;
 #endif
 #endif
+       x86_init.oem.banner();
 }
 
 #ifdef CONFIG_X86_32
 
-/**
- * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors
- *
- * Description:
- *     Perform any necessary interrupt initialisation prior to setting up
- *     the "ordinary" interrupt call gates.  For legacy reasons, the ISA
- *     interrupts should be initialised here if the machine emulates a PC
- *     in any way.
- **/
-void __init x86_quirk_pre_intr_init(void)
-{
-       if (x86_quirks->arch_pre_intr_init) {
-               if (x86_quirks->arch_pre_intr_init())
-                       return;
-       }
-       init_ISA_irqs();
-}
-
-/**
- * x86_quirk_intr_init - post gate setup interrupt initialisation
- *
- * Description:
- *     Fill in any interrupts that may have been left out by the general
- *     init_IRQ() routine.  interrupts having to do with the machine rather
- *     than the devices on the I/O bus (like APIC interrupts in intel MP
- *     systems) are started here.
- **/
-void __init x86_quirk_intr_init(void)
-{
-       if (x86_quirks->arch_intr_init) {
-               if (x86_quirks->arch_intr_init())
-                       return;
-       }
-}
-
-/**
- * x86_quirk_trap_init - initialise system specific traps
- *
- * Description:
- *     Called as the final act of trap_init().  Used in VISWS to initialise
- *     the various board specific APIC traps.
- **/
-void __init x86_quirk_trap_init(void)
-{
-       if (x86_quirks->arch_trap_init) {
-               if (x86_quirks->arch_trap_init())
-                       return;
-       }
-}
-
-static struct irqaction irq0  = {
-       .handler = timer_interrupt,
-       .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
-       .mask = CPU_MASK_NONE,
-       .name = "timer"
+static struct resource video_ram_resource = {
+       .name   = "Video RAM area",
+       .start  = 0xa0000,
+       .end    = 0xbffff,
+       .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
 };
 
-/**
- * x86_quirk_pre_time_init - do any specific initialisations before.
- *
- **/
-void __init x86_quirk_pre_time_init(void)
+void __init i386_reserve_resources(void)
 {
-       if (x86_quirks->arch_pre_time_init)
-               x86_quirks->arch_pre_time_init();
+       request_resource(&iomem_resource, &video_ram_resource);
+       reserve_standard_io_resources();
 }
 
-/**
- * x86_quirk_time_init - do any specific initialisations for the system timer.
- *
- * Description:
- *     Must plug the system timer interrupt source at HZ into the IRQ listed
- *     in irq_vectors.h:TIMER_IRQ
- **/
-void __init x86_quirk_time_init(void)
-{
-       if (x86_quirks->arch_time_init) {
-               /*
-                * A nonzero return code does not mean failure, it means
-                * that the architecture quirk does not want any
-                * generic (timer) setup to be performed after this:
-                */
-               if (x86_quirks->arch_time_init())
-                       return;
-       }
-
-       irq0.mask = cpumask_of_cpu(0);
-       setup_irq(0, &irq0);
-}
 #endif /* CONFIG_X86_32 */