linux/arch/i386/kernel/setup.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/i386/kernel/setup.c
   3 *
   4 *  Copyright (C) 1995  Linus Torvalds
   5 *
   6 *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
   7 *
   8 *  Memory region support
   9 *      David Parsons <orc@pell.chi.il.us>, July-August 1999
  10 *
  11 *  Added E820 sanitization routine (removes overlapping memory regions);
  12 *  Brian Moyle <bmoyle@mvista.com>, February 2001
  13 *
  14 * Moved CPU detection code to cpu/${cpu}.c
  15 *    Patrick Mochel <mochel@osdl.org>, March 2002
  16 *
  17 *  Provisions for empty E820 memory regions (reported by certain BIOSes).
  18 *  Alex Achenbach <xela@slit.de>, December 2002.
  19 *
  20 */
  21
  22/*
  23 * This file handles the architecture-dependent parts of initialization
  24 */
  25
  26#include <linux/sched.h>
  27#include <linux/mm.h>
  28#include <linux/mmzone.h>
  29#include <linux/screen_info.h>
  30#include <linux/ioport.h>
  31#include <linux/acpi.h>
  32#include <linux/apm_bios.h>
  33#include <linux/initrd.h>
  34#include <linux/bootmem.h>
  35#include <linux/seq_file.h>
  36#include <linux/console.h>
  37#include <linux/mca.h>
  38#include <linux/root_dev.h>
  39#include <linux/highmem.h>
  40#include <linux/module.h>
  41#include <linux/efi.h>
  42#include <linux/init.h>
  43#include <linux/edd.h>
  44#include <linux/nodemask.h>
  45#include <linux/kexec.h>
  46#include <linux/crash_dump.h>
  47#include <linux/dmi.h>
  48#include <linux/pfn.h>
  49
  50#include <video/edid.h>
  51
  52#include <asm/apic.h>
  53#include <asm/e820.h>
  54#include <asm/mpspec.h>
  55#include <asm/mmzone.h>
  56#include <asm/setup.h>
  57#include <asm/arch_hooks.h>
  58#include <asm/sections.h>
  59#include <asm/io_apic.h>
  60#include <asm/ist.h>
  61#include <asm/io.h>
  62#include <asm/vmi.h>
  63#include <setup_arch.h>
  64#include <bios_ebda.h>
  65
  66/* This value is set up by the early boot code to point to the value
  67   immediately after the boot time page tables.  It contains a *physical*
  68   address, and must not be in the .bss segment! */
  69unsigned long init_pg_tables_end __initdata = ~0UL;
  70
  71int disable_pse __devinitdata = 0;
  72
  73/*
  74 * Machine setup..
  75 */
  76extern struct resource code_resource;
  77extern struct resource data_resource;
  78
  79/* cpu data as detected by the assembly code in head.S */
  80struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
  81/* common cpu data for all cpus */
  82struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
  83EXPORT_SYMBOL(boot_cpu_data);
  84
  85unsigned long mmu_cr4_features;
  86
  87/* for MCA, but anyone else can use it if they want */
  88unsigned int machine_id;
  89#ifdef CONFIG_MCA
  90EXPORT_SYMBOL(machine_id);
  91#endif
  92unsigned int machine_submodel_id;
  93unsigned int BIOS_revision;
  94unsigned int mca_pentium_flag;
  95
  96/* Boot loader ID as an integer, for the benefit of proc_dointvec */
  97int bootloader_type;
  98
  99/* user-defined highmem size */
 100static unsigned int highmem_pages = -1;
 101
 102/*
 103 * Setup options
 104 */
 105struct drive_info_struct { char dummy[32]; } drive_info;
 106#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
 107    defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
 108EXPORT_SYMBOL(drive_info);
 109#endif
 110struct screen_info screen_info;
 111EXPORT_SYMBOL(screen_info);
 112struct apm_info apm_info;
 113EXPORT_SYMBOL(apm_info);
 114struct sys_desc_table_struct {
 115        unsigned short length;
 116        unsigned char table[0];
 117};
 118struct edid_info edid_info;
 119EXPORT_SYMBOL_GPL(edid_info);
 120struct ist_info ist_info;
 121#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \
 122        defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
 123EXPORT_SYMBOL(ist_info);
 124#endif
 125
 126extern void early_cpu_init(void);
 127extern int root_mountflags;
 128
 129unsigned long saved_videomode;
 130
 131#define RAMDISK_IMAGE_START_MASK        0x07FF
 132#define RAMDISK_PROMPT_FLAG             0x8000
 133#define RAMDISK_LOAD_FLAG               0x4000  
 134
 135static char __initdata command_line[COMMAND_LINE_SIZE];
 136
 137unsigned char __initdata boot_params[PARAM_SIZE];
 138
 139#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
 140struct edd edd;
 141#ifdef CONFIG_EDD_MODULE
 142EXPORT_SYMBOL(edd);
 143#endif
 144/**
 145 * copy_edd() - Copy the BIOS EDD information
 146 *              from boot_params into a safe place.
 147 *
 148 */
 149static inline void copy_edd(void)
 150{
 151     memcpy(edd.mbr_signature, EDD_MBR_SIGNATURE, sizeof(edd.mbr_signature));
 152     memcpy(edd.edd_info, EDD_BUF, sizeof(edd.edd_info));
 153     edd.mbr_signature_nr = EDD_MBR_SIG_NR;
 154     edd.edd_info_nr = EDD_NR;
 155}
 156#else
 157static inline void copy_edd(void)
 158{
 159}
 160#endif
 161
 162int __initdata user_defined_memmap = 0;
 163
 164/*
 165 * "mem=nopentium" disables the 4MB page tables.
 166 * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
 167 * to <mem>, overriding the bios size.
 168 * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from
 169 * <start> to <start>+<mem>, overriding the bios size.
 170 *
 171 * HPA tells me bootloaders need to parse mem=, so no new
 172 * option should be mem=  [also see Documentation/i386/boot.txt]
 173 */
 174static int __init parse_mem(char *arg)
 175{
 176        if (!arg)
 177                return -EINVAL;
 178
 179        if (strcmp(arg, "nopentium") == 0) {
 180                clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
 181                disable_pse = 1;
 182        } else {
 183                /* If the user specifies memory size, we
 184                 * limit the BIOS-provided memory map to
 185                 * that size. exactmap can be used to specify
 186                 * the exact map. mem=number can be used to
 187                 * trim the existing memory map.
 188                 */
 189                unsigned long long mem_size;
 190 
 191                mem_size = memparse(arg, &arg);
 192                limit_regions(mem_size);
 193                user_defined_memmap = 1;
 194        }
 195        return 0;
 196}
 197early_param("mem", parse_mem);
 198
 199#ifdef CONFIG_PROC_VMCORE
 200/* elfcorehdr= specifies the location of elf core header
 201 * stored by the crashed kernel.
 202 */
 203static int __init parse_elfcorehdr(char *arg)
 204{
 205        if (!arg)
 206                return -EINVAL;
 207
 208        elfcorehdr_addr = memparse(arg, &arg);
 209        return 0;
 210}
 211early_param("elfcorehdr", parse_elfcorehdr);
 212#endif /* CONFIG_PROC_VMCORE */
 213
 214/*
 215 * highmem=size forces highmem to be exactly 'size' bytes.
 216 * This works even on boxes that have no highmem otherwise.
 217 * This also works to reduce highmem size on bigger boxes.
 218 */
 219static int __init parse_highmem(char *arg)
 220{
 221        if (!arg)
 222                return -EINVAL;
 223
 224        highmem_pages = memparse(arg, &arg) >> PAGE_SHIFT;
 225        return 0;
 226}
 227early_param("highmem", parse_highmem);
 228
 229/*
 230 * vmalloc=size forces the vmalloc area to be exactly 'size'
 231 * bytes. This can be used to increase (or decrease) the
 232 * vmalloc area - the default is 128m.
 233 */
 234static int __init parse_vmalloc(char *arg)
 235{
 236        if (!arg)
 237                return -EINVAL;
 238
 239        __VMALLOC_RESERVE = memparse(arg, &arg);
 240        return 0;
 241}
 242early_param("vmalloc", parse_vmalloc);
 243
 244/*
 245 * reservetop=size reserves a hole at the top of the kernel address space which
 246 * a hypervisor can load into later.  Needed for dynamically loaded hypervisors,
 247 * so relocating the fixmap can be done before paging initialization.
 248 */
 249static int __init parse_reservetop(char *arg)
 250{
 251        unsigned long address;
 252
 253        if (!arg)
 254                return -EINVAL;
 255
 256        address = memparse(arg, &arg);
 257        reserve_top_address(address);
 258        return 0;
 259}
 260early_param("reservetop", parse_reservetop);
 261
 262/*
 263 * Determine low and high memory ranges:
 264 */
 265unsigned long __init find_max_low_pfn(void)
 266{
 267        unsigned long max_low_pfn;
 268
 269        max_low_pfn = max_pfn;
 270        if (max_low_pfn > MAXMEM_PFN) {
 271                if (highmem_pages == -1)
 272                        highmem_pages = max_pfn - MAXMEM_PFN;
 273                if (highmem_pages + MAXMEM_PFN < max_pfn)
 274                        max_pfn = MAXMEM_PFN + highmem_pages;
 275                if (highmem_pages + MAXMEM_PFN > max_pfn) {
 276                        printk("only %luMB highmem pages available, ignoring highmem size of %uMB.\n", pages_to_mb(max_pfn - MAXMEM_PFN), pages_to_mb(highmem_pages));
 277                        highmem_pages = 0;
 278                }
 279                max_low_pfn = MAXMEM_PFN;
 280#ifndef CONFIG_HIGHMEM
 281                /* Maximum memory usable is what is directly addressable */
 282                printk(KERN_WARNING "Warning only %ldMB will be used.\n",
 283                                        MAXMEM>>20);
 284                if (max_pfn > MAX_NONPAE_PFN)
 285                        printk(KERN_WARNING "Use a PAE enabled kernel.\n");
 286                else
 287                        printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
 288                max_pfn = MAXMEM_PFN;
 289#else /* !CONFIG_HIGHMEM */
 290#ifndef CONFIG_X86_PAE
 291                if (max_pfn > MAX_NONPAE_PFN) {
 292                        max_pfn = MAX_NONPAE_PFN;
 293                        printk(KERN_WARNING "Warning only 4GB will be used.\n");
 294                        printk(KERN_WARNING "Use a PAE enabled kernel.\n");
 295                }
 296#endif /* !CONFIG_X86_PAE */
 297#endif /* !CONFIG_HIGHMEM */
 298        } else {
 299                if (highmem_pages == -1)
 300                        highmem_pages = 0;
 301#ifdef CONFIG_HIGHMEM
 302                if (highmem_pages >= max_pfn) {
 303                        printk(KERN_ERR "highmem size specified (%uMB) is bigger than pages available (%luMB)!.\n", pages_to_mb(highmem_pages), pages_to_mb(max_pfn));
 304                        highmem_pages = 0;
 305                }
 306                if (highmem_pages) {
 307                        if (max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){
 308                                printk(KERN_ERR "highmem size %uMB results in smaller than 64MB lowmem, ignoring it.\n", pages_to_mb(highmem_pages));
 309                                highmem_pages = 0;
 310                        }
 311                        max_low_pfn -= highmem_pages;
 312                }
 313#else
 314                if (highmem_pages)
 315                        printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
 316#endif
 317        }
 318        return max_low_pfn;
 319}
 320
 321/*
 322 * workaround for Dell systems that neglect to reserve EBDA
 323 */
 324static void __init reserve_ebda_region(void)
 325{
 326        unsigned int addr;
 327        addr = get_bios_ebda();
 328        if (addr)
 329                reserve_bootmem(addr, PAGE_SIZE);       
 330}
 331
 332#ifndef CONFIG_NEED_MULTIPLE_NODES
 333void __init setup_bootmem_allocator(void);
 334static unsigned long __init setup_memory(void)
 335{
 336        /*
 337         * partially used pages are not usable - thus
 338         * we are rounding upwards:
 339         */
 340        min_low_pfn = PFN_UP(init_pg_tables_end);
 341
 342        find_max_pfn();
 343
 344        max_low_pfn = find_max_low_pfn();
 345
 346#ifdef CONFIG_HIGHMEM
 347        highstart_pfn = highend_pfn = max_pfn;
 348        if (max_pfn > max_low_pfn) {
 349                highstart_pfn = max_low_pfn;
 350        }
 351        printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
 352                pages_to_mb(highend_pfn - highstart_pfn));
 353        num_physpages = highend_pfn;
 354        high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
 355#else
 356        num_physpages = max_low_pfn;
 357        high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
 358#endif
 359#ifdef CONFIG_FLATMEM
 360        max_mapnr = num_physpages;
 361#endif
 362        printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
 363                        pages_to_mb(max_low_pfn));
 364
 365        setup_bootmem_allocator();
 366
 367        return max_low_pfn;
 368}
 369
 370void __init zone_sizes_init(void)
 371{
 372        unsigned long max_zone_pfns[MAX_NR_ZONES];
 373        memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
 374        max_zone_pfns[ZONE_DMA] =
 375                virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 376        max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
 377#ifdef CONFIG_HIGHMEM
 378        max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
 379        add_active_range(0, 0, highend_pfn);
 380#else
 381        add_active_range(0, 0, max_low_pfn);
 382#endif
 383
 384        free_area_init_nodes(max_zone_pfns);
 385}
 386#else
 387extern unsigned long __init setup_memory(void);
 388extern void zone_sizes_init(void);
 389#endif /* !CONFIG_NEED_MULTIPLE_NODES */
 390
 391void __init setup_bootmem_allocator(void)
 392{
 393        unsigned long bootmap_size;
 394        /*
 395         * Initialize the boot-time allocator (with low memory only):
 396         */
 397        bootmap_size = init_bootmem(min_low_pfn, max_low_pfn);
 398
 399        register_bootmem_low_pages(max_low_pfn);
 400
 401        /*
 402         * Reserve the bootmem bitmap itself as well. We do this in two
 403         * steps (first step was init_bootmem()) because this catches
 404         * the (very unlikely) case of us accidentally initializing the
 405         * bootmem allocator with an invalid RAM area.
 406         */
 407        reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
 408                         bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text));
 409
 410        /*
 411         * reserve physical page 0 - it's a special BIOS page on many boxes,
 412         * enabling clean reboots, SMP operation, laptop functions.
 413         */
 414        reserve_bootmem(0, PAGE_SIZE);
 415
 416        /* reserve EBDA region, it's a 4K region */
 417        reserve_ebda_region();
 418
 419    /* could be an AMD 768MPX chipset. Reserve a page  before VGA to prevent
 420       PCI prefetch into it (errata #56). Usually the page is reserved anyways,
 421       unless you have no PS/2 mouse plugged in. */
 422        if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
 423            boot_cpu_data.x86 == 6)
 424             reserve_bootmem(0xa0000 - 4096, 4096);
 425
 426#ifdef CONFIG_SMP
 427        /*
 428         * But first pinch a few for the stack/trampoline stuff
 429         * FIXME: Don't need the extra page at 4K, but need to fix
 430         * trampoline before removing it. (see the GDT stuff)
 431         */
 432        reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
 433#endif
 434#ifdef CONFIG_ACPI_SLEEP
 435        /*
 436         * Reserve low memory region for sleep support.
 437         */
 438        acpi_reserve_bootmem();
 439#endif
 440#ifdef CONFIG_X86_FIND_SMP_CONFIG
 441        /*
 442         * Find and reserve possible boot-time SMP configuration:
 443         */
 444        find_smp_config();
 445#endif
 446        numa_kva_reserve();
 447#ifdef CONFIG_BLK_DEV_INITRD
 448        if (LOADER_TYPE && INITRD_START) {
 449                if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
 450                        reserve_bootmem(INITRD_START, INITRD_SIZE);
 451                        initrd_start = INITRD_START + PAGE_OFFSET;
 452                        initrd_end = initrd_start+INITRD_SIZE;
 453                }
 454                else {
 455                        printk(KERN_ERR "initrd extends beyond end of memory "
 456                            "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
 457                            INITRD_START + INITRD_SIZE,
 458                            max_low_pfn << PAGE_SHIFT);
 459                        initrd_start = 0;
 460                }
 461        }
 462#endif
 463#ifdef CONFIG_KEXEC
 464        if (crashk_res.start != crashk_res.end)
 465                reserve_bootmem(crashk_res.start,
 466                        crashk_res.end - crashk_res.start + 1);
 467#endif
 468}
 469
 470/*
 471 * The node 0 pgdat is initialized before all of these because
 472 * it's needed for bootmem.  node>0 pgdats have their virtual
 473 * space allocated before the pagetables are in place to access
 474 * them, so they can't be cleared then.
 475 *
 476 * This should all compile down to nothing when NUMA is off.
 477 */
 478void __init remapped_pgdat_init(void)
 479{
 480        int nid;
 481
 482        for_each_online_node(nid) {
 483                if (nid != 0)
 484                        memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
 485        }
 486}
 487
 488#ifdef CONFIG_MCA
 489static void set_mca_bus(int x)
 490{
 491        MCA_bus = x;
 492}
 493#else
 494static void set_mca_bus(int x) { }
 495#endif
 496
 497/* Overridden in paravirt.c if CONFIG_PARAVIRT */
 498char * __init __attribute__((weak)) memory_setup(void)
 499{
 500        return machine_specific_memory_setup();
 501}
 502
 503/*
 504 * Determine if we were loaded by an EFI loader.  If so, then we have also been
 505 * passed the efi memmap, systab, etc., so we should use these data structures
 506 * for initialization.  Note, the efi init code path is determined by the
 507 * global efi_enabled. This allows the same kernel image to be used on existing
 508 * systems (with a traditional BIOS) as well as on EFI systems.
 509 */
 510void __init setup_arch(char **cmdline_p)
 511{
 512        unsigned long max_low_pfn;
 513
 514        memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
 515        pre_setup_arch_hook();
 516        early_cpu_init();
 517
 518        /*
 519         * FIXME: This isn't an official loader_type right
 520         * now but does currently work with elilo.
 521         * If we were configured as an EFI kernel, check to make
 522         * sure that we were loaded correctly from elilo and that
 523         * the system table is valid.  If not, then initialize normally.
 524         */
 525#ifdef CONFIG_EFI
 526        if ((LOADER_TYPE == 0x50) && EFI_SYSTAB)
 527                efi_enabled = 1;
 528#endif
 529
 530        ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
 531        drive_info = DRIVE_INFO;
 532        screen_info = SCREEN_INFO;
 533        edid_info = EDID_INFO;
 534        apm_info.bios = APM_BIOS_INFO;
 535        ist_info = IST_INFO;
 536        saved_videomode = VIDEO_MODE;
 537        if( SYS_DESC_TABLE.length != 0 ) {
 538                set_mca_bus(SYS_DESC_TABLE.table[3] & 0x2);
 539                machine_id = SYS_DESC_TABLE.table[0];
 540                machine_submodel_id = SYS_DESC_TABLE.table[1];
 541                BIOS_revision = SYS_DESC_TABLE.table[2];
 542        }
 543        bootloader_type = LOADER_TYPE;
 544
 545#ifdef CONFIG_BLK_DEV_RAM
 546        rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
 547        rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
 548        rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
 549#endif
 550        ARCH_SETUP
 551        if (efi_enabled)
 552                efi_init();
 553        else {
 554                printk(KERN_INFO "BIOS-provided physical RAM map:\n");
 555                print_memory_map(memory_setup());
 556        }
 557
 558        copy_edd();
 559
 560        if (!MOUNT_ROOT_RDONLY)
 561                root_mountflags &= ~MS_RDONLY;
 562        init_mm.start_code = (unsigned long) _text;
 563        init_mm.end_code = (unsigned long) _etext;
 564        init_mm.end_data = (unsigned long) _edata;
 565        init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
 566
 567        code_resource.start = virt_to_phys(_text);
 568        code_resource.end = virt_to_phys(_etext)-1;
 569        data_resource.start = virt_to_phys(_etext);
 570        data_resource.end = virt_to_phys(_edata)-1;
 571
 572        parse_early_param();
 573
 574        if (user_defined_memmap) {
 575                printk(KERN_INFO "user-defined physical RAM map:\n");
 576                print_memory_map("user");
 577        }
 578
 579        strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
 580        *cmdline_p = command_line;
 581
 582        max_low_pfn = setup_memory();
 583
 584#ifdef CONFIG_VMI
 585        /*
 586         * Must be after max_low_pfn is determined, and before kernel
 587         * pagetables are setup.
 588         */
 589        vmi_init();
 590#endif
 591
 592        /*
 593         * NOTE: before this point _nobody_ is allowed to allocate
 594         * any memory using the bootmem allocator.  Although the
 595         * alloctor is now initialised only the first 8Mb of the kernel
 596         * virtual address space has been mapped.  All allocations before
 597         * paging_init() has completed must use the alloc_bootmem_low_pages()
 598         * variant (which allocates DMA'able memory) and care must be taken
 599         * not to exceed the 8Mb limit.
 600         */
 601
 602#ifdef CONFIG_SMP
 603        smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
 604#endif
 605        paging_init();
 606        remapped_pgdat_init();
 607        sparse_init();
 608        zone_sizes_init();
 609
 610        /*
 611         * NOTE: at this point the bootmem allocator is fully available.
 612         */
 613
 614        dmi_scan_machine();
 615
 616#ifdef CONFIG_X86_GENERICARCH
 617        generic_apic_probe();
 618#endif  
 619        if (efi_enabled)
 620                efi_map_memmap();
 621
 622#ifdef CONFIG_ACPI
 623        /*
 624         * Parse the ACPI tables for possible boot-time SMP configuration.
 625         */
 626        acpi_boot_table_init();
 627#endif
 628
 629#ifdef CONFIG_PCI
 630#ifdef CONFIG_X86_IO_APIC
 631        check_acpi_pci();       /* Checks more than just ACPI actually */
 632#endif
 633#endif
 634
 635#ifdef CONFIG_ACPI
 636        acpi_boot_init();
 637
 638#if defined(CONFIG_SMP) && defined(CONFIG_X86_PC)
 639        if (def_to_bigsmp)
 640                printk(KERN_WARNING "More than 8 CPUs detected and "
 641                        "CONFIG_X86_PC cannot handle it.\nUse "
 642                        "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n");
 643#endif
 644#endif
 645#ifdef CONFIG_X86_LOCAL_APIC
 646        if (smp_found_config)
 647                get_smp_config();
 648#endif
 649
 650        e820_register_memory();
 651
 652#ifdef CONFIG_VT
 653#if defined(CONFIG_VGA_CONSOLE)
 654        if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
 655                conswitchp = &vga_con;
 656#elif defined(CONFIG_DUMMY_CONSOLE)
 657        conswitchp = &dummy_con;
 658#endif
 659#endif
 660}
 661
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.