diff options
Diffstat (limited to 'arch/s390/kernel/early.c')
-rw-r--r-- | arch/s390/kernel/early.c | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index c00856ad4e5a..068f8465c4ee 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -94,6 +94,7 @@ static noinline __init void create_kernel_nss(void) | |||
94 | unsigned int sinitrd_pfn, einitrd_pfn; | 94 | unsigned int sinitrd_pfn, einitrd_pfn; |
95 | #endif | 95 | #endif |
96 | int response; | 96 | int response; |
97 | int hlen; | ||
97 | size_t len; | 98 | size_t len; |
98 | char *savesys_ptr; | 99 | char *savesys_ptr; |
99 | char defsys_cmd[DEFSYS_CMD_SIZE]; | 100 | char defsys_cmd[DEFSYS_CMD_SIZE]; |
@@ -124,24 +125,27 @@ static noinline __init void create_kernel_nss(void) | |||
124 | end_pfn = PFN_UP(__pa(&_end)); | 125 | end_pfn = PFN_UP(__pa(&_end)); |
125 | min_size = end_pfn << 2; | 126 | min_size = end_pfn << 2; |
126 | 127 | ||
127 | sprintf(defsys_cmd, "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X", | 128 | hlen = snprintf(defsys_cmd, DEFSYS_CMD_SIZE, |
128 | kernel_nss_name, stext_pfn - 1, stext_pfn, eshared_pfn - 1, | 129 | "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X", |
129 | eshared_pfn, end_pfn); | 130 | kernel_nss_name, stext_pfn - 1, stext_pfn, |
131 | eshared_pfn - 1, eshared_pfn, end_pfn); | ||
130 | 132 | ||
131 | #ifdef CONFIG_BLK_DEV_INITRD | 133 | #ifdef CONFIG_BLK_DEV_INITRD |
132 | if (INITRD_START && INITRD_SIZE) { | 134 | if (INITRD_START && INITRD_SIZE) { |
133 | sinitrd_pfn = PFN_DOWN(__pa(INITRD_START)); | 135 | sinitrd_pfn = PFN_DOWN(__pa(INITRD_START)); |
134 | einitrd_pfn = PFN_UP(__pa(INITRD_START + INITRD_SIZE)); | 136 | einitrd_pfn = PFN_UP(__pa(INITRD_START + INITRD_SIZE)); |
135 | min_size = einitrd_pfn << 2; | 137 | min_size = einitrd_pfn << 2; |
136 | sprintf(defsys_cmd, "%s EW %.5X-%.5X", defsys_cmd, | 138 | hlen += snprintf(defsys_cmd + hlen, DEFSYS_CMD_SIZE - hlen, |
137 | sinitrd_pfn, einitrd_pfn); | 139 | " EW %.5X-%.5X", sinitrd_pfn, einitrd_pfn); |
138 | } | 140 | } |
139 | #endif | 141 | #endif |
140 | 142 | ||
141 | sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK PARMREGS=0-13", | 143 | snprintf(defsys_cmd + hlen, DEFSYS_CMD_SIZE - hlen, |
142 | defsys_cmd, min_size); | 144 | " EW MINSIZE=%.7iK PARMREGS=0-13", min_size); |
143 | sprintf(savesys_cmd, "SAVESYS %s \n IPL %s", | 145 | defsys_cmd[DEFSYS_CMD_SIZE - 1] = '\0'; |
144 | kernel_nss_name, kernel_nss_name); | 146 | snprintf(savesys_cmd, SAVESYS_CMD_SIZE, "SAVESYS %s \n IPL %s", |
147 | kernel_nss_name, kernel_nss_name); | ||
148 | savesys_cmd[SAVESYS_CMD_SIZE - 1] = '\0'; | ||
145 | 149 | ||
146 | __cpcmd(defsys_cmd, NULL, 0, &response); | 150 | __cpcmd(defsys_cmd, NULL, 0, &response); |
147 | 151 | ||
@@ -208,7 +212,8 @@ static noinline __init void init_kernel_storage_key(void) | |||
208 | end_pfn = PFN_UP(__pa(&_end)); | 212 | end_pfn = PFN_UP(__pa(&_end)); |
209 | 213 | ||
210 | for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++) | 214 | for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++) |
211 | page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); | 215 | page_set_storage_key(init_pfn << PAGE_SHIFT, |
216 | PAGE_DEFAULT_KEY, 0); | ||
212 | } | 217 | } |
213 | 218 | ||
214 | static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE); | 219 | static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE); |
@@ -255,13 +260,33 @@ static noinline __init void setup_lowcore_early(void) | |||
255 | s390_base_pgm_handler_fn = early_pgm_check_handler; | 260 | s390_base_pgm_handler_fn = early_pgm_check_handler; |
256 | } | 261 | } |
257 | 262 | ||
263 | static noinline __init void setup_facility_list(void) | ||
264 | { | ||
265 | unsigned long nr; | ||
266 | |||
267 | S390_lowcore.stfl_fac_list = 0; | ||
268 | asm volatile( | ||
269 | " .insn s,0xb2b10000,0(0)\n" /* stfl */ | ||
270 | "0:\n" | ||
271 | EX_TABLE(0b,0b) : "=m" (S390_lowcore.stfl_fac_list)); | ||
272 | memcpy(&S390_lowcore.stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); | ||
273 | nr = 4; /* # bytes stored by stfl */ | ||
274 | if (test_facility(7)) { | ||
275 | /* More facility bits available with stfle */ | ||
276 | register unsigned long reg0 asm("0") = MAX_FACILITY_BIT/64 - 1; | ||
277 | asm volatile(".insn s,0xb2b00000,%0" /* stfle */ | ||
278 | : "=m" (S390_lowcore.stfle_fac_list), "+d" (reg0) | ||
279 | : : "cc"); | ||
280 | nr = (reg0 + 1) * 8; /* # bytes stored by stfle */ | ||
281 | } | ||
282 | memset((char *) S390_lowcore.stfle_fac_list + nr, 0, | ||
283 | MAX_FACILITY_BIT/8 - nr); | ||
284 | } | ||
285 | |||
258 | static noinline __init void setup_hpage(void) | 286 | static noinline __init void setup_hpage(void) |
259 | { | 287 | { |
260 | #ifndef CONFIG_DEBUG_PAGEALLOC | 288 | #ifndef CONFIG_DEBUG_PAGEALLOC |
261 | unsigned int facilities; | 289 | if (!test_facility(2) || !test_facility(8)) |
262 | |||
263 | facilities = stfl(); | ||
264 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) | ||
265 | return; | 290 | return; |
266 | S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE; | 291 | S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE; |
267 | __ctl_set_bit(0, 23); | 292 | __ctl_set_bit(0, 23); |
@@ -355,18 +380,15 @@ static __init void detect_diag44(void) | |||
355 | static __init void detect_machine_facilities(void) | 380 | static __init void detect_machine_facilities(void) |
356 | { | 381 | { |
357 | #ifdef CONFIG_64BIT | 382 | #ifdef CONFIG_64BIT |
358 | unsigned int facilities; | 383 | if (test_facility(3)) |
359 | unsigned long long facility_bits; | ||
360 | |||
361 | facilities = stfl(); | ||
362 | if (facilities & (1 << 28)) | ||
363 | S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; | 384 | S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; |
364 | if (facilities & (1 << 23)) | 385 | if (test_facility(8)) |
365 | S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; | 386 | S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; |
366 | if (facilities & (1 << 4)) | 387 | if (test_facility(11)) |
388 | S390_lowcore.machine_flags |= MACHINE_FLAG_TOPOLOGY; | ||
389 | if (test_facility(27)) | ||
367 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; | 390 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; |
368 | if ((stfle(&facility_bits, 1) > 0) && | 391 | if (test_facility(40)) |
369 | (facility_bits & (1ULL << (63 - 40)))) | ||
370 | S390_lowcore.machine_flags |= MACHINE_FLAG_SPP; | 392 | S390_lowcore.machine_flags |= MACHINE_FLAG_SPP; |
371 | #endif | 393 | #endif |
372 | } | 394 | } |
@@ -447,6 +469,7 @@ void __init startup_init(void) | |||
447 | lockdep_off(); | 469 | lockdep_off(); |
448 | sort_main_extable(); | 470 | sort_main_extable(); |
449 | setup_lowcore_early(); | 471 | setup_lowcore_early(); |
472 | setup_facility_list(); | ||
450 | detect_machine_type(); | 473 | detect_machine_type(); |
451 | ipl_update_parameters(); | 474 | ipl_update_parameters(); |
452 | setup_boot_command_line(); | 475 | setup_boot_command_line(); |