]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - arch/x86/kernel/setup.c
x86: add brk allocation for very, very early allocations
[linux-2.6.git] / arch / x86 / kernel / setup.c
index 08e02e8453c9a147d838daab9c21421708d22350..e6b742d2a3f503e0d83707c477811cf430868b4a 100644 (file)
 #include <asm/e820.h>
 #include <asm/mpspec.h>
 #include <asm/setup.h>
-#include <asm/arch_hooks.h>
 #include <asm/efi.h>
+#include <asm/timer.h>
+#include <asm/i8259.h>
 #include <asm/sections.h>
 #include <asm/dmi.h>
 #include <asm/io_apic.h>
 #include <asm/ist.h>
 #include <asm/vmi.h>
-#include <setup_arch.h>
+#include <asm/setup_arch.h>
 #include <asm/bios_ebda.h>
 #include <asm/cacheflush.h>
 #include <asm/processor.h>
@@ -89,7 +90,7 @@
 
 #include <asm/system.h>
 #include <asm/vsyscall.h>
-#include <asm/smp.h>
+#include <asm/cpu.h>
 #include <asm/desc.h>
 #include <asm/dma.h>
 #include <asm/iommu.h>
@@ -97,7 +98,6 @@
 #include <asm/mmu_context.h>
 #include <asm/proto.h>
 
-#include <mach_apic.h>
 #include <asm/paravirt.h>
 #include <asm/hypervisor.h>
 
 #define ARCH_SETUP
 #endif
 
+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)
+{
+       return __default_cpu_present_to_apicid(mps_cpu);
+}
+
+int default_check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+       return __default_check_phys_apicid_present(boot_cpu_physical_apicid);
+}
+#endif
+
 #ifndef CONFIG_DEBUG_BOOT_PARAMS
 struct boot_params __initdata boot_params;
 #else
@@ -188,7 +205,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
 
@@ -321,6 +340,34 @@ static void __init relocate_initrd(void)
 }
 #endif
 
+void * __init extend_brk(size_t size, size_t align)
+{
+       size_t mask = align - 1;
+       void *ret;
+
+       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;
+}
+
+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;
+}
+
 static void __init reserve_initrd(void)
 {
        u64 ramdisk_image = boot_params.hdr.ramdisk_image;
@@ -586,20 +633,7 @@ static int __init setup_elfcorehdr(char *arg)
 early_param("elfcorehdr", setup_elfcorehdr);
 #endif
 
-static int __init default_update_genapic(void)
-{
-#ifdef CONFIG_X86_SMP
-# if defined(CONFIG_X86_GENERICARCH) || defined(CONFIG_X86_64)
-       genapic->wakeup_cpu = wakeup_secondary_cpu_via_init;
-# endif
-#endif
-
-       return 0;
-}
-
-static struct x86_quirks default_x86_quirks __initdata = {
-       .update_genapic         = default_update_genapic,
-};
+static struct x86_quirks default_x86_quirks __initdata;
 
 struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
 
@@ -607,7 +641,7 @@ struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
 static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
 {
        printk(KERN_NOTICE
-               "%s detected: BIOS may corrupt low RAM, working it around.\n",
+               "%s detected: BIOS may corrupt low RAM, working around it.\n",
                d->ident);
 
        e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED);
@@ -656,7 +690,6 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_X86_32
        memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
        visws_early_detect();
-       pre_setup_arch_hook();
 #else
        printk(KERN_INFO "Command line: %s\n", boot_command_line);
 #endif
@@ -715,11 +748,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 +799,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 +821,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()) {
@@ -823,8 +853,7 @@ void __init setup_arch(char **cmdline_p)
 #else
        num_physpages = max_pfn;
 
-       if (cpu_has_x2apic)
-               check_x2apic();
+       check_x2apic();
 
        /* How many end-of-memory variables you have, grandma! */
        /* need this before calling reserve_initrd */
@@ -840,6 +869,8 @@ void __init setup_arch(char **cmdline_p)
        setup_bios_corruption_check();
 #endif
 
+       reserve_brk();
+
        /* 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;
@@ -864,9 +895,7 @@ void __init setup_arch(char **cmdline_p)
 
        reserve_initrd();
 
-#ifdef CONFIG_X86_64
        vsmp_init();
-#endif
 
        io_delay_init();
 
@@ -892,12 +921,11 @@ void __init setup_arch(char **cmdline_p)
         */
        acpi_reserve_bootmem();
 #endif
-#ifdef CONFIG_X86_FIND_SMP_CONFIG
        /*
         * Find and reserve possible boot-time SMP configuration:
         */
        find_smp_config();
-#endif
+
        reserve_crashkernel();
 
 #ifdef CONFIG_X86_64
@@ -924,9 +952,7 @@ void __init setup_arch(char **cmdline_p)
        map_vsyscall();
 #endif
 
-#ifdef CONFIG_X86_GENERICARCH
        generic_apic_probe();
-#endif
 
        early_quirks();
 
@@ -953,7 +979,7 @@ void __init setup_arch(char **cmdline_p)
        ioapic_init_mappings();
 
        /* need to wait for io_apic is mapped */
-       nr_irqs = probe_nr_irqs();
+       probe_nr_irqs_gsi();
 
        kvm_guest_init();
 
@@ -977,4 +1003,95 @@ void __init setup_arch(char **cmdline_p)
 #endif
 }
 
+#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"
+};
+
+/**
+ * x86_quirk_pre_time_init - do any specific initialisations before.
+ *
+ **/
+void __init x86_quirk_pre_time_init(void)
+{
+       if (x86_quirks->arch_pre_time_init)
+               x86_quirks->arch_pre_time_init();
+}
+
+/**
+ * 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 */