aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-06-10 15:55:54 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-08 04:35:38 -0400
commitab4a465e96adf2f3a8aaa95384bacfa9ab661e35 (patch)
treea4c72ba76c93ff362b404106f6a6ce756a2075cf
parentdf5f6c212cc049d1989b5ce71bb863a367c261e9 (diff)
x86: e820 merge parsing of the mem=/memmap= boot parameters
since we now have 32-bit support for e820_register_active_regions(), we can merge the parsing of the mem=/memmap= boot parameters. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/kernel/e820.c86
-rw-r--r--arch/x86/kernel/e820_32.c120
-rw-r--r--arch/x86/kernel/e820_64.c69
-rw-r--r--include/asm-x86/e820.h2
-rw-r--r--include/asm-x86/e820_32.h2
-rw-r--r--include/asm-x86/e820_64.h2
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
894static void early_panic(char *msg)
895{
896 early_printk(msg);
897 panic(msg);
898}
899
900/* "mem=nopentium" disables the 4MB page tables. */
901static 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}
919early_param("mem", parse_memopt);
920
921static int userdef __initdata;
922
923static 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}
964early_param("memmap", parse_memmap_opt);
965
966void __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
210void __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 */
241char * __init __attribute__((weak)) memory_setup(void) 211char * __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
252static 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 */
264static 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}
286early_param("mem", parse_mem);
287
288static 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}
332early_param("memmap", parse_memmap);
333
334void __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
99static 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}
107early_param("mem", parse_memopt);
108
109static int userdef __initdata;
110
111static 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}
152early_param("memmap", parse_memmap_opt);
153
154void __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
168int __init arch_get_ram_range(int slot, u64 *addr, u64 *size) 99int __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,
98extern void e820_register_active_regions(int nid, unsigned long start_pfn, 98extern void e820_register_active_regions(int nid, unsigned long start_pfn,
99 unsigned long end_pfn); 99 unsigned long end_pfn);
100extern u64 e820_hole_size(u64 start, u64 end); 100extern u64 e820_hole_size(u64 start, u64 end);
101extern 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
21extern void setup_memory_map(void); 21extern void setup_memory_map(void);
22extern void finish_e820_parsing(void);
23 22
24extern void limit_regions(unsigned long long size);
25extern void init_iomem_resources(struct resource *code_resource, 23extern 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);
22extern int e820_all_non_reserved(unsigned long start, unsigned long end); 22extern int e820_all_non_reserved(unsigned long start, unsigned long end);
23extern int is_memory_all_valid(unsigned long start, unsigned long end); 23extern int is_memory_all_valid(unsigned long start, unsigned long end);
24 24
25extern void finish_e820_parsing(void);
26
27#endif/*!__ASSEMBLY__*/ 25#endif/*!__ASSEMBLY__*/
28 26
29#endif/*__E820_HEADER*/ 27#endif/*__E820_HEADER*/