Merge branch '2022-08-04-Kconfig-migrations'
[platform/kernel/u-boot.git] / arch / sh / lib / bootm.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2003
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  *
6  * (c) Copyright 2008 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
7  * (c) Copyright 2008 Renesas Solutions Corp.
8  */
9
10 #include <common.h>
11 #include <command.h>
12 #include <env.h>
13 #include <image.h>
14 #include <asm/byteorder.h>
15 #include <asm/global_data.h>
16 #include <asm/zimage.h>
17
18 DECLARE_GLOBAL_DATA_PTR;
19
20 #ifdef CONFIG_SH_SDRAM_OFFSET
21 #define GET_INITRD_START(initrd, linux) (initrd - linux + CONFIG_SH_SDRAM_OFFSET)
22 #else
23 #define GET_INITRD_START(initrd, linux) (initrd - linux)
24 #endif
25
26 static void set_sh_linux_param(unsigned long param_addr, unsigned long data)
27 {
28         *(unsigned long *)(param_addr) = data;
29 }
30
31 static unsigned long sh_check_cmd_arg(char *cmdline, char *key, int base)
32 {
33         unsigned long val = 0;
34         char *p = strstr(cmdline, key);
35         if (p) {
36                 p += strlen(key);
37                 val = simple_strtol(p, NULL, base);
38         }
39         return val;
40 }
41
42 int do_bootm_linux(int flag, int argc, char *const argv[],
43                    bootm_headers_t *images)
44 {
45         /* Linux kernel load address */
46         void (*kernel) (void) = (void (*)(void))images->ep;
47         /* empty_zero_page */
48         unsigned char *param
49                 = (unsigned char *)image_get_load(images->legacy_hdr_os);
50         /* Linux kernel command line */
51         char *cmdline = (char *)param + COMMAND_LINE;
52         /* PAGE_SIZE */
53         unsigned long size = images->ep - (unsigned long)param;
54         char *bootargs = env_get("bootargs");
55
56         /*
57          * allow the PREP bootm subcommand, it is required for bootm to work
58          */
59         if (flag & BOOTM_STATE_OS_PREP)
60                 return 0;
61
62         if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
63                 return 1;
64
65         /* Clear zero page */
66         memset(param, 0, size);
67
68         /* Set commandline */
69         strcpy(cmdline, bootargs);
70
71         /* Initrd */
72         if (images->rd_start || images->rd_end) {
73                 unsigned long ramdisk_flags = 0;
74                 int val = sh_check_cmd_arg(bootargs, CMD_ARG_RD_PROMPT, 10);
75                 if (val == 1)
76                                 ramdisk_flags |= RD_PROMPT;
77                 else
78                                 ramdisk_flags &= ~RD_PROMPT;
79
80                 val = sh_check_cmd_arg(bootargs, CMD_ARG_RD_DOLOAD, 10);
81                 if (val == 1)
82                                 ramdisk_flags |= RD_DOLOAD;
83                 else
84                                 ramdisk_flags &= ~RD_DOLOAD;
85
86                 set_sh_linux_param((unsigned long)param + MOUNT_ROOT_RDONLY, 0x0001);
87                 set_sh_linux_param((unsigned long)param + RAMDISK_FLAGS, ramdisk_flags);
88                 set_sh_linux_param((unsigned long)param + ORIG_ROOT_DEV, 0x0200);
89                 set_sh_linux_param((unsigned long)param + LOADER_TYPE, 0x0001);
90                 set_sh_linux_param((unsigned long)param + INITRD_START,
91                         GET_INITRD_START(images->rd_start, CONFIG_SYS_SDRAM_BASE));
92                 set_sh_linux_param((unsigned long)param + INITRD_SIZE,
93                         images->rd_end - images->rd_start);
94         }
95
96         /* Boot kernel */
97         kernel();
98
99         /* does not return */
100         return 1;
101 }
102
103 static ulong get_sp(void)
104 {
105         ulong ret;
106
107         asm("mov r15, %0" : "=r"(ret) : );
108         return ret;
109 }
110
111 void arch_lmb_reserve(struct lmb *lmb)
112 {
113         arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096);
114 }