diff options
Diffstat (limited to 'arch/s390/kernel/early.c')
-rw-r--r-- | arch/s390/kernel/early.c | 80 |
1 files changed, 72 insertions, 8 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index b2226e41f067..e22473993dc9 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/pfn.h> | 15 | #include <linux/pfn.h> |
16 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
17 | #include <asm/ebcdic.h> | ||
17 | #include <asm/ipl.h> | 18 | #include <asm/ipl.h> |
18 | #include <asm/lowcore.h> | 19 | #include <asm/lowcore.h> |
19 | #include <asm/processor.h> | 20 | #include <asm/processor.h> |
@@ -26,12 +27,40 @@ | |||
26 | /* | 27 | /* |
27 | * Create a Kernel NSS if the SAVESYS= parameter is defined | 28 | * Create a Kernel NSS if the SAVESYS= parameter is defined |
28 | */ | 29 | */ |
29 | #define DEFSYS_CMD_SIZE 96 | 30 | #define DEFSYS_CMD_SIZE 128 |
30 | #define SAVESYS_CMD_SIZE 32 | 31 | #define SAVESYS_CMD_SIZE 32 |
31 | 32 | ||
32 | char kernel_nss_name[NSS_NAME_SIZE + 1]; | 33 | char kernel_nss_name[NSS_NAME_SIZE + 1]; |
33 | 34 | ||
35 | static void __init setup_boot_command_line(void); | ||
36 | |||
37 | |||
34 | #ifdef CONFIG_SHARED_KERNEL | 38 | #ifdef CONFIG_SHARED_KERNEL |
39 | int __init savesys_ipl_nss(char *cmd, const int cmdlen); | ||
40 | |||
41 | asm( | ||
42 | " .section .init.text,\"ax\",@progbits\n" | ||
43 | " .align 4\n" | ||
44 | " .type savesys_ipl_nss, @function\n" | ||
45 | "savesys_ipl_nss:\n" | ||
46 | #ifdef CONFIG_64BIT | ||
47 | " stmg 6,15,48(15)\n" | ||
48 | " lgr 14,3\n" | ||
49 | " sam31\n" | ||
50 | " diag 2,14,0x8\n" | ||
51 | " sam64\n" | ||
52 | " lgr 2,14\n" | ||
53 | " lmg 6,15,48(15)\n" | ||
54 | #else | ||
55 | " stm 6,15,24(15)\n" | ||
56 | " lr 14,3\n" | ||
57 | " diag 2,14,0x8\n" | ||
58 | " lr 2,14\n" | ||
59 | " lm 6,15,24(15)\n" | ||
60 | #endif | ||
61 | " br 14\n" | ||
62 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); | ||
63 | |||
35 | static noinline __init void create_kernel_nss(void) | 64 | static noinline __init void create_kernel_nss(void) |
36 | { | 65 | { |
37 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; | 66 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; |
@@ -39,6 +68,7 @@ static noinline __init void create_kernel_nss(void) | |||
39 | unsigned int sinitrd_pfn, einitrd_pfn; | 68 | unsigned int sinitrd_pfn, einitrd_pfn; |
40 | #endif | 69 | #endif |
41 | int response; | 70 | int response; |
71 | size_t len; | ||
42 | char *savesys_ptr; | 72 | char *savesys_ptr; |
43 | char upper_command_line[COMMAND_LINE_SIZE]; | 73 | char upper_command_line[COMMAND_LINE_SIZE]; |
44 | char defsys_cmd[DEFSYS_CMD_SIZE]; | 74 | char defsys_cmd[DEFSYS_CMD_SIZE]; |
@@ -49,8 +79,8 @@ static noinline __init void create_kernel_nss(void) | |||
49 | return; | 79 | return; |
50 | 80 | ||
51 | /* Convert COMMAND_LINE to upper case */ | 81 | /* Convert COMMAND_LINE to upper case */ |
52 | for (i = 0; i < strlen(COMMAND_LINE); i++) | 82 | for (i = 0; i < strlen(boot_command_line); i++) |
53 | upper_command_line[i] = toupper(COMMAND_LINE[i]); | 83 | upper_command_line[i] = toupper(boot_command_line[i]); |
54 | 84 | ||
55 | savesys_ptr = strstr(upper_command_line, "SAVESYS="); | 85 | savesys_ptr = strstr(upper_command_line, "SAVESYS="); |
56 | 86 | ||
@@ -83,7 +113,8 @@ static noinline __init void create_kernel_nss(void) | |||
83 | } | 113 | } |
84 | #endif | 114 | #endif |
85 | 115 | ||
86 | sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK", defsys_cmd, min_size); | 116 | sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK PARMREGS=0-13", |
117 | defsys_cmd, min_size); | ||
87 | sprintf(savesys_cmd, "SAVESYS %s \n IPL %s", | 118 | sprintf(savesys_cmd, "SAVESYS %s \n IPL %s", |
88 | kernel_nss_name, kernel_nss_name); | 119 | kernel_nss_name, kernel_nss_name); |
89 | 120 | ||
@@ -94,13 +125,24 @@ static noinline __init void create_kernel_nss(void) | |||
94 | return; | 125 | return; |
95 | } | 126 | } |
96 | 127 | ||
97 | __cpcmd(savesys_cmd, NULL, 0, &response); | 128 | len = strlen(savesys_cmd); |
129 | ASCEBC(savesys_cmd, len); | ||
130 | response = savesys_ipl_nss(savesys_cmd, len); | ||
98 | 131 | ||
99 | if (response != strlen(savesys_cmd)) { | 132 | /* On success: response is equal to the command size, |
133 | * max SAVESYS_CMD_SIZE | ||
134 | * On error: response contains the numeric portion of cp error message. | ||
135 | * for SAVESYS it will be >= 263 | ||
136 | */ | ||
137 | if (response > SAVESYS_CMD_SIZE) { | ||
100 | kernel_nss_name[0] = '\0'; | 138 | kernel_nss_name[0] = '\0'; |
101 | return; | 139 | return; |
102 | } | 140 | } |
103 | 141 | ||
142 | /* re-setup boot command line with new ipl vm parms */ | ||
143 | ipl_update_parameters(); | ||
144 | setup_boot_command_line(); | ||
145 | |||
104 | ipl_flags = IPL_NSS_VALID; | 146 | ipl_flags = IPL_NSS_VALID; |
105 | } | 147 | } |
106 | 148 | ||
@@ -397,6 +439,26 @@ static __init void rescue_initrd(void) | |||
397 | #endif | 439 | #endif |
398 | } | 440 | } |
399 | 441 | ||
442 | /* Set up boot command line */ | ||
443 | static void __init setup_boot_command_line(void) | ||
444 | { | ||
445 | char *parm = NULL; | ||
446 | |||
447 | /* copy arch command line */ | ||
448 | strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); | ||
449 | boot_command_line[ARCH_COMMAND_LINE_SIZE - 1] = 0; | ||
450 | |||
451 | /* append IPL PARM data to the boot command line */ | ||
452 | if (MACHINE_IS_VM) { | ||
453 | parm = boot_command_line + strlen(boot_command_line); | ||
454 | *parm++ = ' '; | ||
455 | get_ipl_vmparm(parm); | ||
456 | if (parm[0] == '=') | ||
457 | memmove(boot_command_line, parm + 1, strlen(parm)); | ||
458 | } | ||
459 | } | ||
460 | |||
461 | |||
400 | /* | 462 | /* |
401 | * Save ipl parameters, clear bss memory, initialize storage keys | 463 | * Save ipl parameters, clear bss memory, initialize storage keys |
402 | * and create a kernel NSS at startup if the SAVESYS= parm is defined | 464 | * and create a kernel NSS at startup if the SAVESYS= parm is defined |
@@ -411,10 +473,12 @@ void __init startup_init(void) | |||
411 | init_kernel_storage_key(); | 473 | init_kernel_storage_key(); |
412 | lockdep_init(); | 474 | lockdep_init(); |
413 | lockdep_off(); | 475 | lockdep_off(); |
414 | detect_machine_type(); | ||
415 | create_kernel_nss(); | ||
416 | sort_main_extable(); | 476 | sort_main_extable(); |
417 | setup_lowcore_early(); | 477 | setup_lowcore_early(); |
478 | detect_machine_type(); | ||
479 | ipl_update_parameters(); | ||
480 | setup_boot_command_line(); | ||
481 | create_kernel_nss(); | ||
418 | detect_mvpg(); | 482 | detect_mvpg(); |
419 | detect_ieee(); | 483 | detect_ieee(); |
420 | detect_csp(); | 484 | detect_csp(); |