b43: Add LP-PHY firmware loading support
[safe/jmp/linux-2.6] / arch / x86 / kernel / setup.c
index 4c54bc0..63f32d2 100644 (file)
 #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;
 
+static __initdata unsigned long _brk_start = (unsigned long)__brk_base;
+unsigned long _brk_end = (unsigned long)__brk_base;
+
 #ifdef CONFIG_X86_64
 int default_cpu_present_to_apicid(int mps_cpu)
 {
@@ -158,12 +171,6 @@ static struct resource bss_resource = {
 
 
 #ifdef CONFIG_X86_32
-/* This value is set up by the early boot code to point to the value
-   immediately after the boot time page tables.  It contains a *physical*
-   address, and must not be in the .bss segment! */
-unsigned long init_pg_tables_start __initdata = ~0UL;
-unsigned long init_pg_tables_end __initdata = ~0UL;
-
 static struct resource video_ram_resource = {
        .name   = "Video RAM area",
        .start  = 0xa0000,
@@ -202,7 +209,9 @@ struct ist_info ist_info;
 #endif
 
 #else
-struct cpuinfo_x86 boot_cpu_data __read_mostly;
+struct cpuinfo_x86 boot_cpu_data __read_mostly = {
+       .x86_phys_bits = MAX_PHYSMEM_BITS,
+};
 EXPORT_SYMBOL(boot_cpu_data);
 #endif
 
@@ -213,14 +222,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;
-
-/*
- * Early DMI memory
- */
-int dmi_alloc_index;
-char dmi_alloc_data[DMI_MAX_DATA];
+/* Boot loader ID and version as integers, for the benefit of proc_dointvec */
+int bootloader_type, bootloader_version;
 
 /*
  * Setup options
@@ -267,9 +270,50 @@ static inline void copy_edd(void)
 }
 #endif
 
-#ifdef CONFIG_BLK_DEV_INITRD
+void * __init extend_brk(size_t size, size_t align)
+{
+       size_t mask = align - 1;
+       void *ret;
 
-#ifdef CONFIG_X86_32
+       BUG_ON(_brk_start == 0);
+       BUG_ON(align & mask);
+
+       _brk_end = (_brk_end + mask) & ~mask;
+       BUG_ON((char *)(_brk_end + size) > __brk_limit);
+
+       ret = (void *)_brk_end;
+       _brk_end += size;
+
+       memset(ret, 0, size);
+
+       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)
+               reserve_early(__pa(_brk_start), __pa(_brk_end), "BRK");
+
+       /* Mark brk area as locked down and no longer taking any
+          new allocations */
+       _brk_start = 0;
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
 
 #define MAX_MAP_CHUNK  (NR_FIX_BTMAPS << PAGE_SHIFT)
 static void __init relocate_initrd(void)
@@ -277,7 +321,7 @@ 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;
@@ -333,14 +377,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)
@@ -370,14 +413,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
@@ -635,6 +672,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
        {}
 };
@@ -682,6 +732,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;
@@ -715,11 +771,7 @@ void __init setup_arch(char **cmdline_p)
        init_mm.start_code = (unsigned long) _text;
        init_mm.end_code = (unsigned long) _etext;
        init_mm.end_data = (unsigned long) _edata;
-#ifdef CONFIG_X86_32
-       init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
-#else
-       init_mm.brk = (unsigned long) &_end;
-#endif
+       init_mm.brk = _brk_end;
 
        code_resource.start = virt_to_phys(_text);
        code_resource.end = virt_to_phys(_etext)-1;
@@ -770,6 +822,9 @@ void __init setup_arch(char **cmdline_p)
 
        finish_e820_parsing();
 
+       if (efi_enabled)
+               efi_init();
+
        dmi_scan_machine();
 
        dmi_check_system(bad_bios_dmi_table);
@@ -789,8 +844,6 @@ void __init setup_arch(char **cmdline_p)
        insert_resource(&iomem_resource, &data_resource);
        insert_resource(&iomem_resource, &bss_resource);
 
-       if (efi_enabled)
-               efi_init();
 
 #ifdef CONFIG_X86_32
        if (ppro_with_ram_bug()) {
@@ -833,12 +886,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;
@@ -974,24 +1035,6 @@ void __init setup_arch(char **cmdline_p)
 #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:
@@ -1026,7 +1069,6 @@ void __init x86_quirk_trap_init(void)
 static struct irqaction irq0  = {
        .handler = timer_interrupt,
        .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
-       .mask = CPU_MASK_NONE,
        .name = "timer"
 };