|
@@ -392,7 +392,49 @@ static int __init cad_init(void)
|
|
|
}
|
|
|
early_initcall(cad_init);
|
|
|
|
|
|
-static __init void rescue_initrd(void)
|
|
|
+static __init void memmove_early(void *dst, const void *src, size_t n)
|
|
|
+{
|
|
|
+ unsigned long addr;
|
|
|
+ long incr;
|
|
|
+ psw_t old;
|
|
|
+
|
|
|
+ if (!n)
|
|
|
+ return;
|
|
|
+ incr = 1;
|
|
|
+ if (dst > src) {
|
|
|
+ incr = -incr;
|
|
|
+ dst += n - 1;
|
|
|
+ src += n - 1;
|
|
|
+ }
|
|
|
+ old = S390_lowcore.program_new_psw;
|
|
|
+ S390_lowcore.program_new_psw.mask = __extract_psw();
|
|
|
+ asm volatile(
|
|
|
+ " larl %[addr],1f\n"
|
|
|
+ " stg %[addr],%[psw_pgm_addr]\n"
|
|
|
+ "0: mvc 0(1,%[dst]),0(%[src])\n"
|
|
|
+ " agr %[dst],%[incr]\n"
|
|
|
+ " agr %[src],%[incr]\n"
|
|
|
+ " brctg %[n],0b\n"
|
|
|
+ "1:\n"
|
|
|
+ : [addr] "=&d" (addr),
|
|
|
+ [psw_pgm_addr] "=&Q" (S390_lowcore.program_new_psw.addr),
|
|
|
+ [dst] "+&a" (dst), [src] "+&a" (src), [n] "+d" (n)
|
|
|
+ : [incr] "d" (incr)
|
|
|
+ : "cc", "memory");
|
|
|
+ S390_lowcore.program_new_psw = old;
|
|
|
+}
|
|
|
+
|
|
|
+static __init noinline void ipl_save_parameters(void)
|
|
|
+{
|
|
|
+ void *src, *dst;
|
|
|
+
|
|
|
+ src = (void *)(unsigned long) S390_lowcore.ipl_parmblock_ptr;
|
|
|
+ dst = (void *) IPL_PARMBLOCK_ORIGIN;
|
|
|
+ memmove_early(dst, src, PAGE_SIZE);
|
|
|
+ S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
|
|
|
+}
|
|
|
+
|
|
|
+static __init noinline void rescue_initrd(void)
|
|
|
{
|
|
|
#ifdef CONFIG_BLK_DEV_INITRD
|
|
|
unsigned long min_initrd_addr = (unsigned long) _end + (4UL << 20);
|
|
@@ -406,7 +448,7 @@ static __init void rescue_initrd(void)
|
|
|
return;
|
|
|
if (INITRD_START >= min_initrd_addr)
|
|
|
return;
|
|
|
- memmove((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE);
|
|
|
+ memmove_early((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE);
|
|
|
INITRD_START = min_initrd_addr;
|
|
|
#endif
|
|
|
}
|
|
@@ -468,6 +510,7 @@ void __init startup_init(void)
|
|
|
ipl_save_parameters();
|
|
|
rescue_initrd();
|
|
|
clear_bss_section();
|
|
|
+ ipl_verify_parameters();
|
|
|
time_early_init();
|
|
|
init_kernel_storage_key();
|
|
|
lockdep_off();
|