diff options
Diffstat (limited to 'arch/x86/kernel/head64.c')
-rw-r--r-- | arch/x86/kernel/head64.c | 96 |
1 files changed, 24 insertions, 72 deletions
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index e25c57b8aa84..c97819829146 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -25,6 +25,20 @@ | |||
25 | #include <asm/e820.h> | 25 | #include <asm/e820.h> |
26 | #include <asm/bios_ebda.h> | 26 | #include <asm/bios_ebda.h> |
27 | 27 | ||
28 | /* boot cpu pda */ | ||
29 | static struct x8664_pda _boot_cpu_pda __read_mostly; | ||
30 | |||
31 | #ifdef CONFIG_SMP | ||
32 | /* | ||
33 | * We install an empty cpu_pda pointer table to indicate to early users | ||
34 | * (numa_set_node) that the cpu_pda pointer table for cpus other than | ||
35 | * the boot cpu is not yet setup. | ||
36 | */ | ||
37 | static struct x8664_pda *__cpu_pda[NR_CPUS] __initdata; | ||
38 | #else | ||
39 | static struct x8664_pda *__cpu_pda[NR_CPUS] __read_mostly; | ||
40 | #endif | ||
41 | |||
28 | static void __init zap_identity_mappings(void) | 42 | static void __init zap_identity_mappings(void) |
29 | { | 43 | { |
30 | pgd_t *pgd = pgd_offset_k(0UL); | 44 | pgd_t *pgd = pgd_offset_k(0UL); |
@@ -51,74 +65,6 @@ static void __init copy_bootdata(char *real_mode_data) | |||
51 | } | 65 | } |
52 | } | 66 | } |
53 | 67 | ||
54 | #define BIOS_LOWMEM_KILOBYTES 0x413 | ||
55 | |||
56 | /* | ||
57 | * The BIOS places the EBDA/XBDA at the top of conventional | ||
58 | * memory, and usually decreases the reported amount of | ||
59 | * conventional memory (int 0x12) too. This also contains a | ||
60 | * workaround for Dell systems that neglect to reserve EBDA. | ||
61 | * The same workaround also avoids a problem with the AMD768MPX | ||
62 | * chipset: reserve a page before VGA to prevent PCI prefetch | ||
63 | * into it (errata #56). Usually the page is reserved anyways, | ||
64 | * unless you have no PS/2 mouse plugged in. | ||
65 | */ | ||
66 | static void __init reserve_ebda_region(void) | ||
67 | { | ||
68 | unsigned int lowmem, ebda_addr; | ||
69 | |||
70 | /* To determine the position of the EBDA and the */ | ||
71 | /* end of conventional memory, we need to look at */ | ||
72 | /* the BIOS data area. In a paravirtual environment */ | ||
73 | /* that area is absent. We'll just have to assume */ | ||
74 | /* that the paravirt case can handle memory setup */ | ||
75 | /* correctly, without our help. */ | ||
76 | if (paravirt_enabled()) | ||
77 | return; | ||
78 | |||
79 | /* end of low (conventional) memory */ | ||
80 | lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES); | ||
81 | lowmem <<= 10; | ||
82 | |||
83 | /* start of EBDA area */ | ||
84 | ebda_addr = get_bios_ebda(); | ||
85 | |||
86 | /* Fixup: bios puts an EBDA in the top 64K segment */ | ||
87 | /* of conventional memory, but does not adjust lowmem. */ | ||
88 | if ((lowmem - ebda_addr) <= 0x10000) | ||
89 | lowmem = ebda_addr; | ||
90 | |||
91 | /* Fixup: bios does not report an EBDA at all. */ | ||
92 | /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */ | ||
93 | if ((ebda_addr == 0) && (lowmem >= 0x9f000)) | ||
94 | lowmem = 0x9f000; | ||
95 | |||
96 | /* Paranoia: should never happen, but... */ | ||
97 | if ((lowmem == 0) || (lowmem >= 0x100000)) | ||
98 | lowmem = 0x9f000; | ||
99 | |||
100 | /* reserve all memory between lowmem and the 1MB mark */ | ||
101 | reserve_early(lowmem, 0x100000, "BIOS reserved"); | ||
102 | } | ||
103 | |||
104 | static void __init reserve_setup_data(void) | ||
105 | { | ||
106 | struct setup_data *data; | ||
107 | unsigned long pa_data; | ||
108 | char buf[32]; | ||
109 | |||
110 | if (boot_params.hdr.version < 0x0209) | ||
111 | return; | ||
112 | pa_data = boot_params.hdr.setup_data; | ||
113 | while (pa_data) { | ||
114 | data = early_ioremap(pa_data, sizeof(*data)); | ||
115 | sprintf(buf, "setup data %x", data->type); | ||
116 | reserve_early(pa_data, pa_data+sizeof(*data)+data->len, buf); | ||
117 | pa_data = data->next; | ||
118 | early_iounmap(data, sizeof(*data)); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | void __init x86_64_start_kernel(char * real_mode_data) | 68 | void __init x86_64_start_kernel(char * real_mode_data) |
123 | { | 69 | { |
124 | int i; | 70 | int i; |
@@ -156,10 +102,17 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
156 | 102 | ||
157 | early_printk("Kernel alive\n"); | 103 | early_printk("Kernel alive\n"); |
158 | 104 | ||
159 | for (i = 0; i < NR_CPUS; i++) | 105 | _cpu_pda = __cpu_pda; |
160 | cpu_pda(i) = &boot_cpu_pda[i]; | 106 | cpu_pda(0) = &_boot_cpu_pda; |
161 | |||
162 | pda_init(0); | 107 | pda_init(0); |
108 | |||
109 | early_printk("Kernel really alive\n"); | ||
110 | |||
111 | x86_64_start_reservations(real_mode_data); | ||
112 | } | ||
113 | |||
114 | void __init x86_64_start_reservations(char *real_mode_data) | ||
115 | { | ||
163 | copy_bootdata(__va(real_mode_data)); | 116 | copy_bootdata(__va(real_mode_data)); |
164 | 117 | ||
165 | reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS"); | 118 | reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS"); |
@@ -175,7 +128,6 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
175 | #endif | 128 | #endif |
176 | 129 | ||
177 | reserve_ebda_region(); | 130 | reserve_ebda_region(); |
178 | reserve_setup_data(); | ||
179 | 131 | ||
180 | /* | 132 | /* |
181 | * At this point everything still needed from the boot loader | 133 | * At this point everything still needed from the boot loader |