aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/setup.c')
-rw-r--r--arch/i386/kernel/setup.c111
1 files changed, 92 insertions, 19 deletions
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 2bfbddebdbf8..af4de58cab54 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -23,8 +23,10 @@
23 * This file handles the architecture-dependent parts of initialization 23 * This file handles the architecture-dependent parts of initialization
24 */ 24 */
25 25
26#include <linux/config.h>
26#include <linux/sched.h> 27#include <linux/sched.h>
27#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/mmzone.h>
28#include <linux/tty.h> 30#include <linux/tty.h>
29#include <linux/ioport.h> 31#include <linux/ioport.h>
30#include <linux/acpi.h> 32#include <linux/acpi.h>
@@ -41,7 +43,12 @@
41#include <linux/init.h> 43#include <linux/init.h>
42#include <linux/edd.h> 44#include <linux/edd.h>
43#include <linux/nodemask.h> 45#include <linux/nodemask.h>
46#include <linux/kexec.h>
47#include <linux/crash_dump.h>
48
44#include <video/edid.h> 49#include <video/edid.h>
50
51#include <asm/apic.h>
45#include <asm/e820.h> 52#include <asm/e820.h>
46#include <asm/mpspec.h> 53#include <asm/mpspec.h>
47#include <asm/setup.h> 54#include <asm/setup.h>
@@ -53,12 +60,15 @@
53#include "setup_arch_pre.h" 60#include "setup_arch_pre.h"
54#include <bios_ebda.h> 61#include <bios_ebda.h>
55 62
63/* Forward Declaration. */
64void __init find_max_pfn(void);
65
56/* This value is set up by the early boot code to point to the value 66/* This value is set up by the early boot code to point to the value
57 immediately after the boot time page tables. It contains a *physical* 67 immediately after the boot time page tables. It contains a *physical*
58 address, and must not be in the .bss segment! */ 68 address, and must not be in the .bss segment! */
59unsigned long init_pg_tables_end __initdata = ~0UL; 69unsigned long init_pg_tables_end __initdata = ~0UL;
60 70
61int disable_pse __initdata = 0; 71int disable_pse __devinitdata = 0;
62 72
63/* 73/*
64 * Machine setup.. 74 * Machine setup..
@@ -73,6 +83,7 @@ EXPORT_SYMBOL(efi_enabled);
73struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; 83struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
74/* common cpu data for all cpus */ 84/* common cpu data for all cpus */
75struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; 85struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
86EXPORT_SYMBOL(boot_cpu_data);
76 87
77unsigned long mmu_cr4_features; 88unsigned long mmu_cr4_features;
78 89
@@ -90,12 +101,18 @@ extern acpi_interrupt_flags acpi_sci_flags;
90 101
91/* for MCA, but anyone else can use it if they want */ 102/* for MCA, but anyone else can use it if they want */
92unsigned int machine_id; 103unsigned int machine_id;
104#ifdef CONFIG_MCA
105EXPORT_SYMBOL(machine_id);
106#endif
93unsigned int machine_submodel_id; 107unsigned int machine_submodel_id;
94unsigned int BIOS_revision; 108unsigned int BIOS_revision;
95unsigned int mca_pentium_flag; 109unsigned int mca_pentium_flag;
96 110
97/* For PCI or other memory-mapped resources */ 111/* For PCI or other memory-mapped resources */
98unsigned long pci_mem_start = 0x10000000; 112unsigned long pci_mem_start = 0x10000000;
113#ifdef CONFIG_PCI
114EXPORT_SYMBOL(pci_mem_start);
115#endif
99 116
100/* Boot loader ID as an integer, for the benefit of proc_dointvec */ 117/* Boot loader ID as an integer, for the benefit of proc_dointvec */
101int bootloader_type; 118int bootloader_type;
@@ -107,14 +124,26 @@ static unsigned int highmem_pages = -1;
107 * Setup options 124 * Setup options
108 */ 125 */
109struct drive_info_struct { char dummy[32]; } drive_info; 126struct drive_info_struct { char dummy[32]; } drive_info;
127#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
128 defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
129EXPORT_SYMBOL(drive_info);
130#endif
110struct screen_info screen_info; 131struct screen_info screen_info;
132#ifdef CONFIG_VT
133EXPORT_SYMBOL(screen_info);
134#endif
111struct apm_info apm_info; 135struct apm_info apm_info;
136EXPORT_SYMBOL(apm_info);
112struct sys_desc_table_struct { 137struct sys_desc_table_struct {
113 unsigned short length; 138 unsigned short length;
114 unsigned char table[0]; 139 unsigned char table[0];
115}; 140};
116struct edid_info edid_info; 141struct edid_info edid_info;
117struct ist_info ist_info; 142struct ist_info ist_info;
143#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \
144 defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
145EXPORT_SYMBOL(ist_info);
146#endif
118struct e820map e820; 147struct e820map e820;
119 148
120extern void early_cpu_init(void); 149extern void early_cpu_init(void);
@@ -711,6 +740,15 @@ static void __init parse_cmdline_early (char ** cmdline_p)
711 if (to != command_line) 740 if (to != command_line)
712 to--; 741 to--;
713 if (!memcmp(from+7, "exactmap", 8)) { 742 if (!memcmp(from+7, "exactmap", 8)) {
743#ifdef CONFIG_CRASH_DUMP
744 /* If we are doing a crash dump, we
745 * still need to know the real mem
746 * size before original memory map is
747 * reset.
748 */
749 find_max_pfn();
750 saved_max_pfn = max_pfn;
751#endif
714 from += 8+7; 752 from += 8+7;
715 e820.nr_map = 0; 753 e820.nr_map = 0;
716 userdef = 1; 754 userdef = 1;
@@ -814,6 +852,44 @@ static void __init parse_cmdline_early (char ** cmdline_p)
814#endif /* CONFIG_X86_LOCAL_APIC */ 852#endif /* CONFIG_X86_LOCAL_APIC */
815#endif /* CONFIG_ACPI_BOOT */ 853#endif /* CONFIG_ACPI_BOOT */
816 854
855#ifdef CONFIG_X86_LOCAL_APIC
856 /* enable local APIC */
857 else if (!memcmp(from, "lapic", 5))
858 lapic_enable();
859
860 /* disable local APIC */
861 else if (!memcmp(from, "nolapic", 6))
862 lapic_disable();
863#endif /* CONFIG_X86_LOCAL_APIC */
864
865#ifdef CONFIG_KEXEC
866 /* crashkernel=size@addr specifies the location to reserve for
867 * a crash kernel. By reserving this memory we guarantee
868 * that linux never set's it up as a DMA target.
869 * Useful for holding code to do something appropriate
870 * after a kernel panic.
871 */
872 else if (!memcmp(from, "crashkernel=", 12)) {
873 unsigned long size, base;
874 size = memparse(from+12, &from);
875 if (*from == '@') {
876 base = memparse(from+1, &from);
877 /* FIXME: Do I want a sanity check
878 * to validate the memory range?
879 */
880 crashk_res.start = base;
881 crashk_res.end = base + size - 1;
882 }
883 }
884#endif
885#ifdef CONFIG_CRASH_DUMP
886 /* elfcorehdr= specifies the location of elf core header
887 * stored by the crashed kernel.
888 */
889 else if (!memcmp(from, "elfcorehdr=", 11))
890 elfcorehdr_addr = memparse(from+11, &from);
891#endif
892
817 /* 893 /*
818 * highmem=size forces highmem to be exactly 'size' bytes. 894 * highmem=size forces highmem to be exactly 'size' bytes.
819 * This works even on boxes that have no highmem otherwise. 895 * This works even on boxes that have no highmem otherwise.
@@ -1022,7 +1098,7 @@ static void __init reserve_ebda_region(void)
1022 reserve_bootmem(addr, PAGE_SIZE); 1098 reserve_bootmem(addr, PAGE_SIZE);
1023} 1099}
1024 1100
1025#ifndef CONFIG_DISCONTIGMEM 1101#ifndef CONFIG_NEED_MULTIPLE_NODES
1026void __init setup_bootmem_allocator(void); 1102void __init setup_bootmem_allocator(void);
1027static unsigned long __init setup_memory(void) 1103static unsigned long __init setup_memory(void)
1028{ 1104{
@@ -1072,9 +1148,9 @@ void __init zone_sizes_init(void)
1072 free_area_init(zones_size); 1148 free_area_init(zones_size);
1073} 1149}
1074#else 1150#else
1075extern unsigned long setup_memory(void); 1151extern unsigned long __init setup_memory(void);
1076extern void zone_sizes_init(void); 1152extern void zone_sizes_init(void);
1077#endif /* !CONFIG_DISCONTIGMEM */ 1153#endif /* !CONFIG_NEED_MULTIPLE_NODES */
1078 1154
1079void __init setup_bootmem_allocator(void) 1155void __init setup_bootmem_allocator(void)
1080{ 1156{
@@ -1092,8 +1168,8 @@ void __init setup_bootmem_allocator(void)
1092 * the (very unlikely) case of us accidentally initializing the 1168 * the (very unlikely) case of us accidentally initializing the
1093 * bootmem allocator with an invalid RAM area. 1169 * bootmem allocator with an invalid RAM area.
1094 */ 1170 */
1095 reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(min_low_pfn) + 1171 reserve_bootmem(__PHYSICAL_START, (PFN_PHYS(min_low_pfn) +
1096 bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY)); 1172 bootmap_size + PAGE_SIZE-1) - (__PHYSICAL_START));
1097 1173
1098 /* 1174 /*
1099 * reserve physical page 0 - it's a special BIOS page on many boxes, 1175 * reserve physical page 0 - it's a special BIOS page on many boxes,
@@ -1149,6 +1225,11 @@ void __init setup_bootmem_allocator(void)
1149 } 1225 }
1150 } 1226 }
1151#endif 1227#endif
1228#ifdef CONFIG_KEXEC
1229 if (crashk_res.start != crashk_res.end)
1230 reserve_bootmem(crashk_res.start,
1231 crashk_res.end - crashk_res.start + 1);
1232#endif
1152} 1233}
1153 1234
1154/* 1235/*
@@ -1202,6 +1283,9 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
1202 */ 1283 */
1203 request_resource(res, code_resource); 1284 request_resource(res, code_resource);
1204 request_resource(res, data_resource); 1285 request_resource(res, data_resource);
1286#ifdef CONFIG_KEXEC
1287 request_resource(res, &crashk_res);
1288#endif
1205 } 1289 }
1206 } 1290 }
1207} 1291}
@@ -1330,7 +1414,7 @@ static struct nop {
1330 This runs before SMP is initialized to avoid SMP problems with 1414 This runs before SMP is initialized to avoid SMP problems with
1331 self modifying code. This implies that assymetric systems where 1415 self modifying code. This implies that assymetric systems where
1332 APs have less capabilities than the boot processor are not handled. 1416 APs have less capabilities than the boot processor are not handled.
1333 In this case boot with "noreplacement". */ 1417 Tough. Make sure you disable such features by hand. */
1334void apply_alternatives(void *start, void *end) 1418void apply_alternatives(void *start, void *end)
1335{ 1419{
1336 struct alt_instr *a; 1420 struct alt_instr *a;
@@ -1358,24 +1442,12 @@ void apply_alternatives(void *start, void *end)
1358 } 1442 }
1359} 1443}
1360 1444
1361static int no_replacement __initdata = 0;
1362
1363void __init alternative_instructions(void) 1445void __init alternative_instructions(void)
1364{ 1446{
1365 extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; 1447 extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
1366 if (no_replacement)
1367 return;
1368 apply_alternatives(__alt_instructions, __alt_instructions_end); 1448 apply_alternatives(__alt_instructions, __alt_instructions_end);
1369} 1449}
1370 1450
1371static int __init noreplacement_setup(char *s)
1372{
1373 no_replacement = 1;
1374 return 0;
1375}
1376
1377__setup("noreplacement", noreplacement_setup);
1378
1379static char * __init machine_specific_memory_setup(void); 1451static char * __init machine_specific_memory_setup(void);
1380 1452
1381#ifdef CONFIG_MCA 1453#ifdef CONFIG_MCA
@@ -1475,6 +1547,7 @@ void __init setup_arch(char **cmdline_p)
1475#endif 1547#endif
1476 paging_init(); 1548 paging_init();
1477 remapped_pgdat_init(); 1549 remapped_pgdat_init();
1550 sparse_init();
1478 zone_sizes_init(); 1551 zone_sizes_init();
1479 1552
1480 /* 1553 /*