diff options
-rw-r--r-- | arch/x86/kernel/e820.c | 86 | ||||
-rw-r--r-- | arch/x86/kernel/e820_32.c | 120 | ||||
-rw-r--r-- | arch/x86/kernel/e820_64.c | 69 | ||||
-rw-r--r-- | include/asm-x86/e820.h | 2 | ||||
-rw-r--r-- | include/asm-x86/e820_32.h | 2 | ||||
-rw-r--r-- | include/asm-x86/e820_64.h | 2 |
6 files changed, 88 insertions, 193 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 68aba413d403..4f2cd5d179e2 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -890,3 +890,89 @@ u64 __init e820_hole_size(u64 start, u64 end) | |||
890 | } | 890 | } |
891 | return end - start - ((u64)ram << PAGE_SHIFT); | 891 | return end - start - ((u64)ram << PAGE_SHIFT); |
892 | } | 892 | } |
893 | |||
894 | static void early_panic(char *msg) | ||
895 | { | ||
896 | early_printk(msg); | ||
897 | panic(msg); | ||
898 | } | ||
899 | |||
900 | /* "mem=nopentium" disables the 4MB page tables. */ | ||
901 | static int __init parse_memopt(char *p) | ||
902 | { | ||
903 | u64 mem_size; | ||
904 | |||
905 | if (!p) | ||
906 | return -EINVAL; | ||
907 | |||
908 | #ifdef CONFIG_X86_32 | ||
909 | if (!strcmp(p, "nopentium")) { | ||
910 | setup_clear_cpu_cap(X86_FEATURE_PSE); | ||
911 | return 0; | ||
912 | } | ||
913 | #endif | ||
914 | |||
915 | mem_size = memparse(p, &p); | ||
916 | end_user_pfn = mem_size>>PAGE_SHIFT; | ||
917 | return 0; | ||
918 | } | ||
919 | early_param("mem", parse_memopt); | ||
920 | |||
921 | static int userdef __initdata; | ||
922 | |||
923 | static int __init parse_memmap_opt(char *p) | ||
924 | { | ||
925 | char *oldp; | ||
926 | u64 start_at, mem_size; | ||
927 | |||
928 | if (!strcmp(p, "exactmap")) { | ||
929 | #ifdef CONFIG_CRASH_DUMP | ||
930 | /* | ||
931 | * If we are doing a crash dump, we still need to know | ||
932 | * the real mem size before original memory map is | ||
933 | * reset. | ||
934 | */ | ||
935 | e820_register_active_regions(0, 0, -1UL); | ||
936 | saved_max_pfn = e820_end_of_ram(); | ||
937 | remove_all_active_ranges(); | ||
938 | #endif | ||
939 | e820.nr_map = 0; | ||
940 | userdef = 1; | ||
941 | return 0; | ||
942 | } | ||
943 | |||
944 | oldp = p; | ||
945 | mem_size = memparse(p, &p); | ||
946 | if (p == oldp) | ||
947 | return -EINVAL; | ||
948 | |||
949 | userdef = 1; | ||
950 | if (*p == '@') { | ||
951 | start_at = memparse(p+1, &p); | ||
952 | add_memory_region(start_at, mem_size, E820_RAM); | ||
953 | } else if (*p == '#') { | ||
954 | start_at = memparse(p+1, &p); | ||
955 | add_memory_region(start_at, mem_size, E820_ACPI); | ||
956 | } else if (*p == '$') { | ||
957 | start_at = memparse(p+1, &p); | ||
958 | add_memory_region(start_at, mem_size, E820_RESERVED); | ||
959 | } else { | ||
960 | end_user_pfn = (mem_size >> PAGE_SHIFT); | ||
961 | } | ||
962 | return *p == '\0' ? 0 : -EINVAL; | ||
963 | } | ||
964 | early_param("memmap", parse_memmap_opt); | ||
965 | |||
966 | void __init finish_e820_parsing(void) | ||
967 | { | ||
968 | if (userdef) { | ||
969 | int nr = e820.nr_map; | ||
970 | |||
971 | if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0) | ||
972 | early_panic("Invalid user supplied memory map"); | ||
973 | e820.nr_map = nr; | ||
974 | |||
975 | printk(KERN_INFO "user-defined physical RAM map:\n"); | ||
976 | e820_print_map("user"); | ||
977 | } | ||
978 | } | ||
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c index e8a3b968c9fa..8de3df9548db 100644 --- a/arch/x86/kernel/e820_32.c +++ b/arch/x86/kernel/e820_32.c | |||
@@ -207,36 +207,6 @@ void __init init_iomem_resources(struct resource *code_resource, | |||
207 | } | 207 | } |
208 | } | 208 | } |
209 | 209 | ||
210 | void __init limit_regions(unsigned long long size) | ||
211 | { | ||
212 | unsigned long long current_addr; | ||
213 | int i; | ||
214 | |||
215 | e820_print_map("limit_regions start"); | ||
216 | for (i = 0; i < e820.nr_map; i++) { | ||
217 | current_addr = e820.map[i].addr + e820.map[i].size; | ||
218 | if (current_addr < size) | ||
219 | continue; | ||
220 | |||
221 | if (e820.map[i].type != E820_RAM) | ||
222 | continue; | ||
223 | |||
224 | if (e820.map[i].addr >= size) { | ||
225 | /* | ||
226 | * This region starts past the end of the | ||
227 | * requested size, skip it completely. | ||
228 | */ | ||
229 | e820.nr_map = i; | ||
230 | } else { | ||
231 | e820.nr_map = i + 1; | ||
232 | e820.map[i].size -= current_addr - size; | ||
233 | } | ||
234 | e820_print_map("limit_regions endfor"); | ||
235 | return; | ||
236 | } | ||
237 | e820_print_map("limit_regions endfunc"); | ||
238 | } | ||
239 | |||
240 | /* Overridden in paravirt.c if CONFIG_PARAVIRT */ | 210 | /* Overridden in paravirt.c if CONFIG_PARAVIRT */ |
241 | char * __init __attribute__((weak)) memory_setup(void) | 211 | char * __init __attribute__((weak)) memory_setup(void) |
242 | { | 212 | { |
@@ -249,93 +219,3 @@ void __init setup_memory_map(void) | |||
249 | e820_print_map(memory_setup()); | 219 | e820_print_map(memory_setup()); |
250 | } | 220 | } |
251 | 221 | ||
252 | static int __initdata user_defined_memmap; | ||
253 | |||
254 | /* | ||
255 | * "mem=nopentium" disables the 4MB page tables. | ||
256 | * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM | ||
257 | * to <mem>, overriding the bios size. | ||
258 | * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from | ||
259 | * <start> to <start>+<mem>, overriding the bios size. | ||
260 | * | ||
261 | * HPA tells me bootloaders need to parse mem=, so no new | ||
262 | * option should be mem= [also see Documentation/i386/boot.txt] | ||
263 | */ | ||
264 | static int __init parse_mem(char *arg) | ||
265 | { | ||
266 | if (!arg) | ||
267 | return -EINVAL; | ||
268 | |||
269 | if (strcmp(arg, "nopentium") == 0) { | ||
270 | setup_clear_cpu_cap(X86_FEATURE_PSE); | ||
271 | } else { | ||
272 | /* If the user specifies memory size, we | ||
273 | * limit the BIOS-provided memory map to | ||
274 | * that size. exactmap can be used to specify | ||
275 | * the exact map. mem=number can be used to | ||
276 | * trim the existing memory map. | ||
277 | */ | ||
278 | unsigned long long mem_size; | ||
279 | |||
280 | mem_size = memparse(arg, &arg); | ||
281 | limit_regions(mem_size); | ||
282 | user_defined_memmap = 1; | ||
283 | } | ||
284 | return 0; | ||
285 | } | ||
286 | early_param("mem", parse_mem); | ||
287 | |||
288 | static int __init parse_memmap(char *arg) | ||
289 | { | ||
290 | if (!arg) | ||
291 | return -EINVAL; | ||
292 | |||
293 | if (strcmp(arg, "exactmap") == 0) { | ||
294 | #ifdef CONFIG_CRASH_DUMP | ||
295 | /* If we are doing a crash dump, we | ||
296 | * still need to know the real mem | ||
297 | * size before original memory map is | ||
298 | * reset. | ||
299 | */ | ||
300 | e820_register_active_regions(0, 0, -1UL); | ||
301 | saved_max_pfn = e820_end_of_ram(); | ||
302 | remove_all_active_ranges(); | ||
303 | #endif | ||
304 | e820.nr_map = 0; | ||
305 | user_defined_memmap = 1; | ||
306 | } else { | ||
307 | /* If the user specifies memory size, we | ||
308 | * limit the BIOS-provided memory map to | ||
309 | * that size. exactmap can be used to specify | ||
310 | * the exact map. mem=number can be used to | ||
311 | * trim the existing memory map. | ||
312 | */ | ||
313 | unsigned long long start_at, mem_size; | ||
314 | |||
315 | mem_size = memparse(arg, &arg); | ||
316 | if (*arg == '@') { | ||
317 | start_at = memparse(arg+1, &arg); | ||
318 | add_memory_region(start_at, mem_size, E820_RAM); | ||
319 | } else if (*arg == '#') { | ||
320 | start_at = memparse(arg+1, &arg); | ||
321 | add_memory_region(start_at, mem_size, E820_ACPI); | ||
322 | } else if (*arg == '$') { | ||
323 | start_at = memparse(arg+1, &arg); | ||
324 | add_memory_region(start_at, mem_size, E820_RESERVED); | ||
325 | } else { | ||
326 | limit_regions(mem_size); | ||
327 | user_defined_memmap = 1; | ||
328 | } | ||
329 | } | ||
330 | return 0; | ||
331 | } | ||
332 | early_param("memmap", parse_memmap); | ||
333 | |||
334 | void __init finish_e820_parsing(void) | ||
335 | { | ||
336 | if (user_defined_memmap) { | ||
337 | printk(KERN_INFO "user-defined physical RAM map:\n"); | ||
338 | e820_print_map("user"); | ||
339 | } | ||
340 | } | ||
341 | |||
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c index 0afee2ca0bf8..47952b1690b6 100644 --- a/arch/x86/kernel/e820_64.c +++ b/arch/x86/kernel/e820_64.c | |||
@@ -96,75 +96,6 @@ char *__init machine_specific_memory_setup(void) | |||
96 | return who; | 96 | return who; |
97 | } | 97 | } |
98 | 98 | ||
99 | static int __init parse_memopt(char *p) | ||
100 | { | ||
101 | if (!p) | ||
102 | return -EINVAL; | ||
103 | end_user_pfn = memparse(p, &p); | ||
104 | end_user_pfn >>= PAGE_SHIFT; | ||
105 | return 0; | ||
106 | } | ||
107 | early_param("mem", parse_memopt); | ||
108 | |||
109 | static int userdef __initdata; | ||
110 | |||
111 | static int __init parse_memmap_opt(char *p) | ||
112 | { | ||
113 | char *oldp; | ||
114 | unsigned long long start_at, mem_size; | ||
115 | |||
116 | if (!strcmp(p, "exactmap")) { | ||
117 | #ifdef CONFIG_CRASH_DUMP | ||
118 | /* | ||
119 | * If we are doing a crash dump, we still need to know | ||
120 | * the real mem size before original memory map is | ||
121 | * reset. | ||
122 | */ | ||
123 | e820_register_active_regions(0, 0, -1UL); | ||
124 | saved_max_pfn = e820_end_of_ram(); | ||
125 | remove_all_active_ranges(); | ||
126 | #endif | ||
127 | e820.nr_map = 0; | ||
128 | userdef = 1; | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | oldp = p; | ||
133 | mem_size = memparse(p, &p); | ||
134 | if (p == oldp) | ||
135 | return -EINVAL; | ||
136 | |||
137 | userdef = 1; | ||
138 | if (*p == '@') { | ||
139 | start_at = memparse(p+1, &p); | ||
140 | add_memory_region(start_at, mem_size, E820_RAM); | ||
141 | } else if (*p == '#') { | ||
142 | start_at = memparse(p+1, &p); | ||
143 | add_memory_region(start_at, mem_size, E820_ACPI); | ||
144 | } else if (*p == '$') { | ||
145 | start_at = memparse(p+1, &p); | ||
146 | add_memory_region(start_at, mem_size, E820_RESERVED); | ||
147 | } else { | ||
148 | end_user_pfn = (mem_size >> PAGE_SHIFT); | ||
149 | } | ||
150 | return *p == '\0' ? 0 : -EINVAL; | ||
151 | } | ||
152 | early_param("memmap", parse_memmap_opt); | ||
153 | |||
154 | void __init finish_e820_parsing(void) | ||
155 | { | ||
156 | if (userdef) { | ||
157 | int nr = e820.nr_map; | ||
158 | |||
159 | if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0) | ||
160 | early_panic("Invalid user supplied memory map"); | ||
161 | e820.nr_map = nr; | ||
162 | |||
163 | printk(KERN_INFO "user-defined physical RAM map:\n"); | ||
164 | e820_print_map("user"); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | int __init arch_get_ram_range(int slot, u64 *addr, u64 *size) | 99 | int __init arch_get_ram_range(int slot, u64 *addr, u64 *size) |
169 | { | 100 | { |
170 | int i; | 101 | int i; |
diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h index 8aa32323a182..a5959e3a5626 100644 --- a/include/asm-x86/e820.h +++ b/include/asm-x86/e820.h | |||
@@ -98,6 +98,8 @@ extern int e820_find_active_region(const struct e820entry *ei, | |||
98 | extern void e820_register_active_regions(int nid, unsigned long start_pfn, | 98 | extern void e820_register_active_regions(int nid, unsigned long start_pfn, |
99 | unsigned long end_pfn); | 99 | unsigned long end_pfn); |
100 | extern u64 e820_hole_size(u64 start, u64 end); | 100 | extern u64 e820_hole_size(u64 start, u64 end); |
101 | extern void finish_e820_parsing(void); | ||
102 | |||
101 | #endif /* __ASSEMBLY__ */ | 103 | #endif /* __ASSEMBLY__ */ |
102 | 104 | ||
103 | #define ISA_START_ADDRESS 0xa0000 | 105 | #define ISA_START_ADDRESS 0xa0000 |
diff --git a/include/asm-x86/e820_32.h b/include/asm-x86/e820_32.h index 212b74c10efc..9135ce6e617e 100644 --- a/include/asm-x86/e820_32.h +++ b/include/asm-x86/e820_32.h | |||
@@ -19,9 +19,7 @@ | |||
19 | #ifndef __ASSEMBLY__ | 19 | #ifndef __ASSEMBLY__ |
20 | 20 | ||
21 | extern void setup_memory_map(void); | 21 | extern void setup_memory_map(void); |
22 | extern void finish_e820_parsing(void); | ||
23 | 22 | ||
24 | extern void limit_regions(unsigned long long size); | ||
25 | extern void init_iomem_resources(struct resource *code_resource, | 23 | extern void init_iomem_resources(struct resource *code_resource, |
26 | struct resource *data_resource, | 24 | struct resource *data_resource, |
27 | struct resource *bss_resource); | 25 | struct resource *bss_resource); |
diff --git a/include/asm-x86/e820_64.h b/include/asm-x86/e820_64.h index 368585daaa42..478547c63222 100644 --- a/include/asm-x86/e820_64.h +++ b/include/asm-x86/e820_64.h | |||
@@ -22,8 +22,6 @@ extern int is_memory_any_valid(unsigned long start, unsigned long end); | |||
22 | extern int e820_all_non_reserved(unsigned long start, unsigned long end); | 22 | extern int e820_all_non_reserved(unsigned long start, unsigned long end); |
23 | extern int is_memory_all_valid(unsigned long start, unsigned long end); | 23 | extern int is_memory_all_valid(unsigned long start, unsigned long end); |
24 | 24 | ||
25 | extern void finish_e820_parsing(void); | ||
26 | |||
27 | #endif/*!__ASSEMBLY__*/ | 25 | #endif/*!__ASSEMBLY__*/ |
28 | 26 | ||
29 | #endif/*__E820_HEADER*/ | 27 | #endif/*__E820_HEADER*/ |