diff options
Diffstat (limited to 'arch/s390/kernel/setup.c')
| -rw-r--r-- | arch/s390/kernel/setup.c | 139 |
1 files changed, 30 insertions, 109 deletions
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 577aa7dd660e..766c783bd7a7 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
| @@ -126,75 +126,6 @@ void __cpuinit cpu_init(void) | |||
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | /* | 128 | /* |
| 129 | * VM halt and poweroff setup routines | ||
| 130 | */ | ||
| 131 | char vmhalt_cmd[128] = ""; | ||
| 132 | char vmpoff_cmd[128] = ""; | ||
| 133 | static char vmpanic_cmd[128] = ""; | ||
| 134 | |||
| 135 | static void strncpy_skip_quote(char *dst, char *src, int n) | ||
| 136 | { | ||
| 137 | int sx, dx; | ||
| 138 | |||
| 139 | dx = 0; | ||
| 140 | for (sx = 0; src[sx] != 0; sx++) { | ||
| 141 | if (src[sx] == '"') continue; | ||
| 142 | dst[dx++] = src[sx]; | ||
| 143 | if (dx >= n) break; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | static int __init vmhalt_setup(char *str) | ||
| 148 | { | ||
| 149 | strncpy_skip_quote(vmhalt_cmd, str, 127); | ||
| 150 | vmhalt_cmd[127] = 0; | ||
| 151 | return 1; | ||
| 152 | } | ||
| 153 | |||
| 154 | __setup("vmhalt=", vmhalt_setup); | ||
| 155 | |||
| 156 | static int __init vmpoff_setup(char *str) | ||
| 157 | { | ||
| 158 | strncpy_skip_quote(vmpoff_cmd, str, 127); | ||
| 159 | vmpoff_cmd[127] = 0; | ||
| 160 | return 1; | ||
| 161 | } | ||
| 162 | |||
| 163 | __setup("vmpoff=", vmpoff_setup); | ||
| 164 | |||
| 165 | static int vmpanic_notify(struct notifier_block *self, unsigned long event, | ||
| 166 | void *data) | ||
| 167 | { | ||
| 168 | if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0) | ||
| 169 | cpcmd(vmpanic_cmd, NULL, 0, NULL); | ||
| 170 | |||
| 171 | return NOTIFY_OK; | ||
| 172 | } | ||
| 173 | |||
| 174 | #define PANIC_PRI_VMPANIC 0 | ||
| 175 | |||
| 176 | static struct notifier_block vmpanic_nb = { | ||
| 177 | .notifier_call = vmpanic_notify, | ||
| 178 | .priority = PANIC_PRI_VMPANIC | ||
| 179 | }; | ||
| 180 | |||
| 181 | static int __init vmpanic_setup(char *str) | ||
| 182 | { | ||
| 183 | static int register_done __initdata = 0; | ||
| 184 | |||
| 185 | strncpy_skip_quote(vmpanic_cmd, str, 127); | ||
| 186 | vmpanic_cmd[127] = 0; | ||
| 187 | if (!register_done) { | ||
| 188 | register_done = 1; | ||
| 189 | atomic_notifier_chain_register(&panic_notifier_list, | ||
| 190 | &vmpanic_nb); | ||
| 191 | } | ||
| 192 | return 1; | ||
| 193 | } | ||
| 194 | |||
| 195 | __setup("vmpanic=", vmpanic_setup); | ||
| 196 | |||
| 197 | /* | ||
| 198 | * condev= and conmode= setup parameter. | 129 | * condev= and conmode= setup parameter. |
| 199 | */ | 130 | */ |
| 200 | 131 | ||
| @@ -308,38 +239,6 @@ static void __init setup_zfcpdump(unsigned int console_devno) | |||
| 308 | static inline void setup_zfcpdump(unsigned int console_devno) {} | 239 | static inline void setup_zfcpdump(unsigned int console_devno) {} |
| 309 | #endif /* CONFIG_ZFCPDUMP */ | 240 | #endif /* CONFIG_ZFCPDUMP */ |
| 310 | 241 | ||
| 311 | #ifdef CONFIG_SMP | ||
| 312 | void (*_machine_restart)(char *command) = machine_restart_smp; | ||
| 313 | void (*_machine_halt)(void) = machine_halt_smp; | ||
| 314 | void (*_machine_power_off)(void) = machine_power_off_smp; | ||
| 315 | #else | ||
| 316 | /* | ||
| 317 | * Reboot, halt and power_off routines for non SMP. | ||
| 318 | */ | ||
| 319 | static void do_machine_restart_nonsmp(char * __unused) | ||
| 320 | { | ||
| 321 | do_reipl(); | ||
| 322 | } | ||
| 323 | |||
| 324 | static void do_machine_halt_nonsmp(void) | ||
| 325 | { | ||
| 326 | if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) | ||
| 327 | __cpcmd(vmhalt_cmd, NULL, 0, NULL); | ||
| 328 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); | ||
| 329 | } | ||
| 330 | |||
| 331 | static void do_machine_power_off_nonsmp(void) | ||
| 332 | { | ||
| 333 | if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) | ||
| 334 | __cpcmd(vmpoff_cmd, NULL, 0, NULL); | ||
| 335 | signal_processor(smp_processor_id(), sigp_stop_and_store_status); | ||
| 336 | } | ||
| 337 | |||
| 338 | void (*_machine_restart)(char *command) = do_machine_restart_nonsmp; | ||
| 339 | void (*_machine_halt)(void) = do_machine_halt_nonsmp; | ||
| 340 | void (*_machine_power_off)(void) = do_machine_power_off_nonsmp; | ||
| 341 | #endif | ||
| 342 | |||
| 343 | /* | 242 | /* |
| 344 | * Reboot, halt and power_off stubs. They just call _machine_restart, | 243 | * Reboot, halt and power_off stubs. They just call _machine_restart, |
| 345 | * _machine_halt or _machine_power_off. | 244 | * _machine_halt or _machine_power_off. |
| @@ -559,7 +458,9 @@ setup_resources(void) | |||
| 559 | data_resource.start = (unsigned long) &_etext; | 458 | data_resource.start = (unsigned long) &_etext; |
| 560 | data_resource.end = (unsigned long) &_edata - 1; | 459 | data_resource.end = (unsigned long) &_edata - 1; |
| 561 | 460 | ||
| 562 | for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { | 461 | for (i = 0; i < MEMORY_CHUNKS; i++) { |
| 462 | if (!memory_chunk[i].size) | ||
| 463 | continue; | ||
| 563 | res = alloc_bootmem_low(sizeof(struct resource)); | 464 | res = alloc_bootmem_low(sizeof(struct resource)); |
| 564 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; | 465 | res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; |
| 565 | switch (memory_chunk[i].type) { | 466 | switch (memory_chunk[i].type) { |
| @@ -617,7 +518,7 @@ EXPORT_SYMBOL_GPL(real_memory_size); | |||
| 617 | static void __init setup_memory_end(void) | 518 | static void __init setup_memory_end(void) |
| 618 | { | 519 | { |
| 619 | unsigned long memory_size; | 520 | unsigned long memory_size; |
| 620 | unsigned long max_mem, max_phys; | 521 | unsigned long max_mem; |
| 621 | int i; | 522 | int i; |
| 622 | 523 | ||
| 623 | #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) | 524 | #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE) |
| @@ -625,10 +526,31 @@ static void __init setup_memory_end(void) | |||
| 625 | memory_end = ZFCPDUMP_HSA_SIZE; | 526 | memory_end = ZFCPDUMP_HSA_SIZE; |
| 626 | #endif | 527 | #endif |
| 627 | memory_size = 0; | 528 | memory_size = 0; |
| 628 | max_phys = VMALLOC_END_INIT - VMALLOC_MIN_SIZE; | ||
| 629 | memory_end &= PAGE_MASK; | 529 | memory_end &= PAGE_MASK; |
| 630 | 530 | ||
| 631 | max_mem = memory_end ? min(max_phys, memory_end) : max_phys; | 531 | max_mem = memory_end ? min(VMALLOC_START, memory_end) : VMALLOC_START; |
| 532 | memory_end = min(max_mem, memory_end); | ||
| 533 | |||
| 534 | /* | ||
| 535 | * Make sure all chunks are MAX_ORDER aligned so we don't need the | ||
| 536 | * extra checks that HOLES_IN_ZONE would require. | ||
| 537 | */ | ||
| 538 | for (i = 0; i < MEMORY_CHUNKS; i++) { | ||
| 539 | unsigned long start, end; | ||
| 540 | struct mem_chunk *chunk; | ||
| 541 | unsigned long align; | ||
| 542 | |||
| 543 | chunk = &memory_chunk[i]; | ||
| 544 | align = 1UL << (MAX_ORDER + PAGE_SHIFT - 1); | ||
| 545 | start = (chunk->addr + align - 1) & ~(align - 1); | ||
| 546 | end = (chunk->addr + chunk->size) & ~(align - 1); | ||
| 547 | if (start >= end) | ||
| 548 | memset(chunk, 0, sizeof(*chunk)); | ||
| 549 | else { | ||
| 550 | chunk->addr = start; | ||
| 551 | chunk->size = end - start; | ||
| 552 | } | ||
| 553 | } | ||
| 632 | 554 | ||
| 633 | for (i = 0; i < MEMORY_CHUNKS; i++) { | 555 | for (i = 0; i < MEMORY_CHUNKS; i++) { |
| 634 | struct mem_chunk *chunk = &memory_chunk[i]; | 556 | struct mem_chunk *chunk = &memory_chunk[i]; |
| @@ -890,7 +812,7 @@ setup_arch(char **cmdline_p) | |||
| 890 | 812 | ||
| 891 | parse_early_param(); | 813 | parse_early_param(); |
| 892 | 814 | ||
| 893 | setup_ipl_info(); | 815 | setup_ipl(); |
| 894 | setup_memory_end(); | 816 | setup_memory_end(); |
| 895 | setup_addressing_mode(); | 817 | setup_addressing_mode(); |
| 896 | setup_memory(); | 818 | setup_memory(); |
| @@ -899,7 +821,6 @@ setup_arch(char **cmdline_p) | |||
| 899 | 821 | ||
| 900 | cpu_init(); | 822 | cpu_init(); |
| 901 | __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; | 823 | __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; |
| 902 | smp_setup_cpu_possible_map(); | ||
| 903 | 824 | ||
| 904 | /* | 825 | /* |
| 905 | * Setup capabilities (ELF_HWCAP & ELF_PLATFORM). | 826 | * Setup capabilities (ELF_HWCAP & ELF_PLATFORM). |
| @@ -920,7 +841,7 @@ setup_arch(char **cmdline_p) | |||
| 920 | 841 | ||
| 921 | void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo) | 842 | void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo) |
| 922 | { | 843 | { |
| 923 | printk("cpu %d " | 844 | printk(KERN_INFO "cpu %d " |
| 924 | #ifdef CONFIG_SMP | 845 | #ifdef CONFIG_SMP |
| 925 | "phys_idx=%d " | 846 | "phys_idx=%d " |
| 926 | #endif | 847 | #endif |
| @@ -996,7 +917,7 @@ static void *c_next(struct seq_file *m, void *v, loff_t *pos) | |||
| 996 | static void c_stop(struct seq_file *m, void *v) | 917 | static void c_stop(struct seq_file *m, void *v) |
| 997 | { | 918 | { |
| 998 | } | 919 | } |
| 999 | struct seq_operations cpuinfo_op = { | 920 | const struct seq_operations cpuinfo_op = { |
| 1000 | .start = c_start, | 921 | .start = c_start, |
| 1001 | .next = c_next, | 922 | .next = c_next, |
| 1002 | .stop = c_stop, | 923 | .stop = c_stop, |
