diff options
Diffstat (limited to 'arch/s390/kernel/setup.c')
-rw-r--r-- | arch/s390/kernel/setup.c | 68 |
1 files changed, 40 insertions, 28 deletions
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 49f2b68e32b1..49ef206ec880 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -62,13 +62,9 @@ EXPORT_SYMBOL_GPL(uaccess); | |||
62 | unsigned int console_mode = 0; | 62 | unsigned int console_mode = 0; |
63 | unsigned int console_devno = -1; | 63 | unsigned int console_devno = -1; |
64 | unsigned int console_irq = -1; | 64 | unsigned int console_irq = -1; |
65 | unsigned long memory_size = 0; | ||
66 | unsigned long machine_flags = 0; | 65 | unsigned long machine_flags = 0; |
67 | struct { | 66 | |
68 | unsigned long addr, size, type; | 67 | struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; |
69 | } memory_chunk[MEMORY_CHUNKS] = { { 0 } }; | ||
70 | #define CHUNK_READ_WRITE 0 | ||
71 | #define CHUNK_READ_ONLY 1 | ||
72 | volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ | 68 | volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ |
73 | static unsigned long __initdata memory_end; | 69 | static unsigned long __initdata memory_end; |
74 | 70 | ||
@@ -228,11 +224,11 @@ static void __init conmode_default(void) | |||
228 | char *ptr; | 224 | char *ptr; |
229 | 225 | ||
230 | if (MACHINE_IS_VM) { | 226 | if (MACHINE_IS_VM) { |
231 | __cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL); | 227 | cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL); |
232 | console_devno = simple_strtoul(query_buffer + 5, NULL, 16); | 228 | console_devno = simple_strtoul(query_buffer + 5, NULL, 16); |
233 | ptr = strstr(query_buffer, "SUBCHANNEL ="); | 229 | ptr = strstr(query_buffer, "SUBCHANNEL ="); |
234 | console_irq = simple_strtoul(ptr + 13, NULL, 16); | 230 | console_irq = simple_strtoul(ptr + 13, NULL, 16); |
235 | __cpcmd("QUERY TERM", query_buffer, 1024, NULL); | 231 | cpcmd("QUERY TERM", query_buffer, 1024, NULL); |
236 | ptr = strstr(query_buffer, "CONMODE"); | 232 | ptr = strstr(query_buffer, "CONMODE"); |
237 | /* | 233 | /* |
238 | * Set the conmode to 3215 so that the device recognition | 234 | * Set the conmode to 3215 so that the device recognition |
@@ -241,7 +237,7 @@ static void __init conmode_default(void) | |||
241 | * 3215 and the 3270 driver will try to access the console | 237 | * 3215 and the 3270 driver will try to access the console |
242 | * device (3215 as console and 3270 as normal tty). | 238 | * device (3215 as console and 3270 as normal tty). |
243 | */ | 239 | */ |
244 | __cpcmd("TERM CONMODE 3215", NULL, 0, NULL); | 240 | cpcmd("TERM CONMODE 3215", NULL, 0, NULL); |
245 | if (ptr == NULL) { | 241 | if (ptr == NULL) { |
246 | #if defined(CONFIG_SCLP_CONSOLE) | 242 | #if defined(CONFIG_SCLP_CONSOLE) |
247 | SET_CONSOLE_SCLP; | 243 | SET_CONSOLE_SCLP; |
@@ -298,14 +294,14 @@ static void do_machine_restart_nonsmp(char * __unused) | |||
298 | static void do_machine_halt_nonsmp(void) | 294 | static void do_machine_halt_nonsmp(void) |
299 | { | 295 | { |
300 | if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) | 296 | if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) |
301 | cpcmd(vmhalt_cmd, NULL, 0, NULL); | 297 | __cpcmd(vmhalt_cmd, NULL, 0, NULL); |
302 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); | 298 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); |
303 | } | 299 | } |
304 | 300 | ||
305 | static void do_machine_power_off_nonsmp(void) | 301 | static void do_machine_power_off_nonsmp(void) |
306 | { | 302 | { |
307 | if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) | 303 | if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) |
308 | cpcmd(vmpoff_cmd, NULL, 0, NULL); | 304 | __cpcmd(vmpoff_cmd, NULL, 0, NULL); |
309 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); | 305 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); |
310 | } | 306 | } |
311 | 307 | ||
@@ -434,7 +430,7 @@ setup_lowcore(void) | |||
434 | lc->extended_save_area_addr = (__u32) | 430 | lc->extended_save_area_addr = (__u32) |
435 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); | 431 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); |
436 | /* enable extended save area */ | 432 | /* enable extended save area */ |
437 | ctl_set_bit(14, 29); | 433 | __ctl_set_bit(14, 29); |
438 | } | 434 | } |
439 | #endif | 435 | #endif |
440 | set_prefix((u32)(unsigned long) lc); | 436 | set_prefix((u32)(unsigned long) lc); |
@@ -473,6 +469,37 @@ setup_resources(void) | |||
473 | } | 469 | } |
474 | } | 470 | } |
475 | 471 | ||
472 | static void __init setup_memory_end(void) | ||
473 | { | ||
474 | unsigned long real_size, memory_size; | ||
475 | unsigned long max_mem, max_phys; | ||
476 | int i; | ||
477 | |||
478 | memory_size = real_size = 0; | ||
479 | max_phys = VMALLOC_END - VMALLOC_MIN_SIZE; | ||
480 | memory_end &= PAGE_MASK; | ||
481 | |||
482 | max_mem = memory_end ? min(max_phys, memory_end) : max_phys; | ||
483 | |||
484 | for (i = 0; i < MEMORY_CHUNKS; i++) { | ||
485 | struct mem_chunk *chunk = &memory_chunk[i]; | ||
486 | |||
487 | real_size = max(real_size, chunk->addr + chunk->size); | ||
488 | if (chunk->addr >= max_mem) { | ||
489 | memset(chunk, 0, sizeof(*chunk)); | ||
490 | continue; | ||
491 | } | ||
492 | if (chunk->addr + chunk->size > max_mem) | ||
493 | chunk->size = max_mem - chunk->addr; | ||
494 | memory_size = max(memory_size, chunk->addr + chunk->size); | ||
495 | } | ||
496 | if (!memory_end) | ||
497 | memory_end = memory_size; | ||
498 | if (real_size > memory_end) | ||
499 | printk("More memory detected than supported. Unused: %luk\n", | ||
500 | (real_size - memory_end) >> 10); | ||
501 | } | ||
502 | |||
476 | static void __init | 503 | static void __init |
477 | setup_memory(void) | 504 | setup_memory(void) |
478 | { | 505 | { |
@@ -616,8 +643,6 @@ setup_arch(char **cmdline_p) | |||
616 | init_mm.end_data = (unsigned long) &_edata; | 643 | init_mm.end_data = (unsigned long) &_edata; |
617 | init_mm.brk = (unsigned long) &_end; | 644 | init_mm.brk = (unsigned long) &_end; |
618 | 645 | ||
619 | memory_end = memory_size; | ||
620 | |||
621 | if (MACHINE_HAS_MVCOS) | 646 | if (MACHINE_HAS_MVCOS) |
622 | memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess)); | 647 | memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess)); |
623 | else | 648 | else |
@@ -625,20 +650,7 @@ setup_arch(char **cmdline_p) | |||
625 | 650 | ||
626 | parse_early_param(); | 651 | parse_early_param(); |
627 | 652 | ||
628 | #ifndef CONFIG_64BIT | 653 | setup_memory_end(); |
629 | memory_end &= ~0x400000UL; | ||
630 | |||
631 | /* | ||
632 | * We need some free virtual space to be able to do vmalloc. | ||
633 | * On a machine with 2GB memory we make sure that we have at | ||
634 | * least 128 MB free space for vmalloc. | ||
635 | */ | ||
636 | if (memory_end > 1920*1024*1024) | ||
637 | memory_end = 1920*1024*1024; | ||
638 | #else /* CONFIG_64BIT */ | ||
639 | memory_end &= ~0x200000UL; | ||
640 | #endif /* CONFIG_64BIT */ | ||
641 | |||
642 | setup_memory(); | 654 | setup_memory(); |
643 | setup_resources(); | 655 | setup_resources(); |
644 | setup_lowcore(); | 656 | setup_lowcore(); |