aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/kernel/setup.c172
1 files changed, 60 insertions, 112 deletions
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 804b93dc3c5a..fdbb508661c5 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -135,138 +135,54 @@ static void __init print_memory_map(void)
135 } 135 }
136} 136}
137 137
138static void __init parse_cmdline_early(void)
139{
140 char c = ' ', *to = command_line, *from = saved_command_line;
141 unsigned long start_at, mem_size;
142 int len = 0;
143 int usermem = 0;
144
145 printk("Determined physical RAM map:\n");
146 print_memory_map();
147
148 for (;;) {
149 /*
150 * "mem=XXX[kKmM]" defines a memory region from
151 * 0 to <XXX>, overriding the determined size.
152 * "mem=XXX[KkmM]@YYY[KkmM]" defines a memory region from
153 * <YYY> to <YYY>+<XXX>, overriding the determined size.
154 */
155 if (c == ' ' && !memcmp(from, "mem=", 4)) {
156 if (to != command_line)
157 to--;
158 /*
159 * If a user specifies memory size, we
160 * blow away any automatically generated
161 * size.
162 */
163 if (usermem == 0) {
164 boot_mem_map.nr_map = 0;
165 usermem = 1;
166 }
167 mem_size = memparse(from + 4, &from);
168 if (*from == '@')
169 start_at = memparse(from + 1, &from);
170 else
171 start_at = 0;
172 add_memory_region(start_at, mem_size, BOOT_MEM_RAM);
173 }
174 c = *(from++);
175 if (!c)
176 break;
177 if (CL_SIZE <= ++len)
178 break;
179 *(to++) = c;
180 }
181 *to = '\0';
182
183 if (usermem) {
184 printk("User-defined physical RAM map:\n");
185 print_memory_map();
186 }
187}
188
189/* 138/*
190 * Manage initrd 139 * Manage initrd
191 */ 140 */
192#ifdef CONFIG_BLK_DEV_INITRD 141#ifdef CONFIG_BLK_DEV_INITRD
193 142
194static int __init parse_rd_cmdline(unsigned long *rd_start, unsigned long *rd_end) 143static int __init rd_start_early(char *p)
195{ 144{
196 /* 145 unsigned long start = memparse(p, &p);
197 * "rd_start=0xNNNNNNNN" defines the memory address of an initrd
198 * "rd_size=0xNN" it's size
199 */
200 unsigned long start = 0;
201 unsigned long size = 0;
202 unsigned long end;
203 char cmd_line[CL_SIZE];
204 char *start_str;
205 char *size_str;
206 char *tmp;
207
208 strcpy(cmd_line, command_line);
209 *command_line = 0;
210 tmp = cmd_line;
211 /* Ignore "rd_start=" strings in other parameters. */
212 start_str = strstr(cmd_line, "rd_start=");
213 if (start_str && start_str != cmd_line && *(start_str - 1) != ' ')
214 start_str = strstr(start_str, " rd_start=");
215 while (start_str) {
216 if (start_str != cmd_line)
217 strncat(command_line, tmp, start_str - tmp);
218 start = memparse(start_str + 9, &start_str);
219 tmp = start_str + 1;
220 start_str = strstr(start_str, " rd_start=");
221 }
222 if (*tmp)
223 strcat(command_line, tmp);
224
225 strcpy(cmd_line, command_line);
226 *command_line = 0;
227 tmp = cmd_line;
228 /* Ignore "rd_size" strings in other parameters. */
229 size_str = strstr(cmd_line, "rd_size=");
230 if (size_str && size_str != cmd_line && *(size_str - 1) != ' ')
231 size_str = strstr(size_str, " rd_size=");
232 while (size_str) {
233 if (size_str != cmd_line)
234 strncat(command_line, tmp, size_str - tmp);
235 size = memparse(size_str + 8, &size_str);
236 tmp = size_str + 1;
237 size_str = strstr(size_str, " rd_size=");
238 }
239 if (*tmp)
240 strcat(command_line, tmp);
241 146
242#ifdef CONFIG_64BIT 147#ifdef CONFIG_64BIT
243 /* HACK: Guess if the sign extension was forgotten */ 148 /* HACK: Guess if the sign extension was forgotten */
244 if (start > 0x0000000080000000 && start < 0x00000000ffffffff) 149 if (start > 0x0000000080000000 && start < 0x00000000ffffffff)
245 start |= 0xffffffff00000000UL; 150 start |= 0xffffffff00000000UL;
246#endif 151#endif
152 initrd_start = start;
153 initrd_end += start;
154
155 return 0;
156}
157early_param("rd_start", rd_start_early);
158
159static int __init rd_size_early(char *p)
160{
161 initrd_end += memparse(p, &p);
247 162
248 end = start + size;
249 if (start && end) {
250 *rd_start = start;
251 *rd_end = end;
252 return 1;
253 }
254 return 0; 163 return 0;
255} 164}
165early_param("rd_size", rd_size_early);
256 166
257static unsigned long __init init_initrd(void) 167static unsigned long __init init_initrd(void)
258{ 168{
259 unsigned long tmp, end; 169 unsigned long tmp, end, size;
260 u32 *initrd_header; 170 u32 *initrd_header;
261 171
262 ROOT_DEV = Root_RAM0; 172 ROOT_DEV = Root_RAM0;
263 173
264 if (parse_rd_cmdline(&initrd_start, &initrd_end))
265 return initrd_end;
266 /* 174 /*
267 * Board specific code should have set up initrd_start 175 * Board specific code or command line parser should have
268 * and initrd_end... 176 * already set up initrd_start and initrd_end. In these cases
177 * perfom sanity checks and use them if all looks good.
269 */ 178 */
179 size = initrd_end - initrd_start;
180 if (initrd_end == 0 || size == 0) {
181 initrd_start = 0;
182 initrd_end = 0;
183 } else
184 return initrd_end;
185
270 end = (unsigned long)&_end; 186 end = (unsigned long)&_end;
271 tmp = PAGE_ALIGN(end) - sizeof(u32) * 2; 187 tmp = PAGE_ALIGN(end) - sizeof(u32) * 2;
272 if (tmp < end) 188 if (tmp < end)
@@ -436,8 +352,6 @@ static void __init bootmem_init(void)
436 * 352 *
437 * o plat_mem_setup() detects the memory configuration and will record detected 353 * o plat_mem_setup() detects the memory configuration and will record detected
438 * memory areas using add_memory_region. 354 * memory areas using add_memory_region.
439 * o parse_cmdline_early() parses the command line for mem= options which,
440 * iff detected, will override the results of the automatic detection.
441 * 355 *
442 * At this stage the memory configuration of the system is known to the 356 * At this stage the memory configuration of the system is known to the
443 * kernel but generic memory managment system is still entirely uninitialized. 357 * kernel but generic memory managment system is still entirely uninitialized.
@@ -455,19 +369,53 @@ static void __init bootmem_init(void)
455 * initialization hook for anything else was introduced. 369 * initialization hook for anything else was introduced.
456 */ 370 */
457 371
458extern void plat_mem_setup(void); 372static int usermem __initdata = 0;
373
374static int __init early_parse_mem(char *p)
375{
376 unsigned long start, size;
377
378 /*
379 * If a user specifies memory size, we
380 * blow away any automatically generated
381 * size.
382 */
383 if (usermem == 0) {
384 boot_mem_map.nr_map = 0;
385 usermem = 1;
386 }
387 start = 0;
388 size = memparse(p, &p);
389 if (*p == '@')
390 start = memparse(p + 1, &p);
391
392 add_memory_region(start, size, BOOT_MEM_RAM);
393 return 0;
394}
395early_param("mem", early_parse_mem);
459 396
460static void __init arch_mem_init(char **cmdline_p) 397static void __init arch_mem_init(char **cmdline_p)
461{ 398{
399 extern void plat_mem_setup(void);
400
462 /* call board setup routine */ 401 /* call board setup routine */
463 plat_mem_setup(); 402 plat_mem_setup();
464 403
404 printk("Determined physical RAM map:\n");
405 print_memory_map();
406
465 strlcpy(command_line, arcs_cmdline, sizeof(command_line)); 407 strlcpy(command_line, arcs_cmdline, sizeof(command_line));
466 strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); 408 strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
467 409
468 *cmdline_p = command_line; 410 *cmdline_p = command_line;
469 411
470 parse_cmdline_early(); 412 parse_early_param();
413
414 if (usermem) {
415 printk("User-defined physical RAM map:\n");
416 print_memory_map();
417 }
418
471 bootmem_init(); 419 bootmem_init();
472 sparse_init(); 420 sparse_init();
473 paging_init(); 421 paging_init();