Merge tag 'xfs-4.20-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
[linux-2.6-microblaze.git] / arch / s390 / boot / startup.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/string.h>
3 #include <asm/setup.h>
4 #include <asm/sclp.h>
5 #include "compressed/decompressor.h"
6 #include "boot.h"
7
8 extern char __boot_data_start[], __boot_data_end[];
9
10 void error(char *x)
11 {
12         sclp_early_printk("\n\n");
13         sclp_early_printk(x);
14         sclp_early_printk("\n\n -- System halted");
15
16         disabled_wait(0xdeadbeef);
17 }
18
19 #ifdef CONFIG_KERNEL_UNCOMPRESSED
20 unsigned long mem_safe_offset(void)
21 {
22         return vmlinux.default_lma + vmlinux.image_size + vmlinux.bss_size;
23 }
24 #endif
25
26 static void rescue_initrd(void)
27 {
28         unsigned long min_initrd_addr;
29
30         if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD))
31                 return;
32         if (!INITRD_START || !INITRD_SIZE)
33                 return;
34         min_initrd_addr = mem_safe_offset();
35         if (min_initrd_addr <= INITRD_START)
36                 return;
37         memmove((void *)min_initrd_addr, (void *)INITRD_START, INITRD_SIZE);
38         INITRD_START = min_initrd_addr;
39 }
40
41 static void copy_bootdata(void)
42 {
43         if (__boot_data_end - __boot_data_start != vmlinux.bootdata_size)
44                 error(".boot.data section size mismatch");
45         memcpy((void *)vmlinux.bootdata_off, __boot_data_start, vmlinux.bootdata_size);
46 }
47
48 void startup_kernel(void)
49 {
50         void *img;
51
52         rescue_initrd();
53         sclp_early_read_info();
54         store_ipl_parmblock();
55         setup_boot_command_line();
56         setup_memory_end();
57         detect_memory();
58         if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) {
59                 img = decompress_kernel();
60                 memmove((void *)vmlinux.default_lma, img, vmlinux.image_size);
61         }
62         copy_bootdata();
63         vmlinux.entry();
64 }