]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/nds32/lib/bootm.c
nds32: Support AG101P serial DM.
[people/ms/u-boot.git] / arch / nds32 / lib / bootm.c
CommitLineData
463d47f6
ML
1/*
2 * Copyright (C) 2011 Andes Technology Corporation
3 * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
4 * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
5 *
1a459660 6 * SPDX-License-Identifier: GPL-2.0+
463d47f6
ML
7 */
8
9#include <common.h>
10#include <command.h>
11#include <image.h>
12#include <u-boot/zlib.h>
13#include <asm/byteorder.h>
14
15DECLARE_GLOBAL_DATA_PTR;
16
86132af7 17int arch_fixup_fdt(void *blob)
18{
19 return 0;
20}
21
22
463d47f6
ML
23#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
24 defined(CONFIG_CMDLINE_TAG) || \
25 defined(CONFIG_INITRD_TAG) || \
26 defined(CONFIG_SERIAL_TAG) || \
27 defined(CONFIG_REVISION_TAG)
28static void setup_start_tag(bd_t *bd);
29
30# ifdef CONFIG_SETUP_MEMORY_TAGS
31static void setup_memory_tags(bd_t *bd);
32# endif
33static void setup_commandline_tag(bd_t *bd, char *commandline);
34
35# ifdef CONFIG_INITRD_TAG
36static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end);
37# endif
38static void setup_end_tag(bd_t *bd);
39
40static struct tag *params;
41#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
42
43int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
44{
45 bd_t *bd = gd->bd;
46 char *s;
47 int machid = bd->bi_arch_number;
48 void (*theKernel)(int zero, int arch, uint params);
49
50#ifdef CONFIG_CMDLINE_TAG
51 char *commandline = getenv("bootargs");
52#endif
53
2cb0e55a
AB
54 /*
55 * allow the PREP bootm subcommand, it is required for bootm to work
56 */
57 if (flag & BOOTM_STATE_OS_PREP)
58 return 0;
59
463d47f6
ML
60 if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
61 return 1;
62
63 theKernel = (void (*)(int, int, uint))images->ep;
64
65 s = getenv("machid");
66 if (s) {
67 machid = simple_strtoul(s, NULL, 16);
68 printf("Using machid 0x%x from environment\n", machid);
69 }
70
770605e4 71 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
463d47f6
ML
72
73 debug("## Transferring control to Linux (at address %08lx) ...\n",
74 (ulong)theKernel);
75
76#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
77 defined(CONFIG_CMDLINE_TAG) || \
78 defined(CONFIG_INITRD_TAG) || \
79 defined(CONFIG_SERIAL_TAG) || \
80 defined(CONFIG_REVISION_TAG)
81 setup_start_tag(bd);
82#ifdef CONFIG_SERIAL_TAG
83 setup_serial_tag(&params);
84#endif
85#ifdef CONFIG_REVISION_TAG
86 setup_revision_tag(&params);
87#endif
88#ifdef CONFIG_SETUP_MEMORY_TAGS
89 setup_memory_tags(bd);
90#endif
91#ifdef CONFIG_CMDLINE_TAG
92 setup_commandline_tag(bd, commandline);
93#endif
94#ifdef CONFIG_INITRD_TAG
95 if (images->rd_start && images->rd_end)
96 setup_initrd_tag(bd, images->rd_start, images->rd_end);
97#endif
98 setup_end_tag(bd);
99#endif
100
101 /* we assume that the kernel is in place */
102 printf("\nStarting kernel ...\n\n");
103
104#ifdef CONFIG_USB_DEVICE
105 {
106 extern void udc_disconnect(void);
107 udc_disconnect();
108 }
109#endif
110
111 cleanup_before_linux();
112
113 theKernel(0, machid, bd->bi_boot_params);
114 /* does not return */
115
116 return 1;
117}
118
119
120#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
121 defined(CONFIG_CMDLINE_TAG) || \
122 defined(CONFIG_INITRD_TAG) || \
123 defined(CONFIG_SERIAL_TAG) || \
124 defined(CONFIG_REVISION_TAG)
125static void setup_start_tag(bd_t *bd)
126{
127 params = (struct tag *)bd->bi_boot_params;
128
129 params->hdr.tag = ATAG_CORE;
130 params->hdr.size = tag_size(tag_core);
131
132 params->u.core.flags = 0;
133 params->u.core.pagesize = 0;
134 params->u.core.rootdev = 0;
135
136 params = tag_next(params);
137}
138
139
140#ifdef CONFIG_SETUP_MEMORY_TAGS
141static void setup_memory_tags(bd_t *bd)
142{
143 int i;
144
145 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
146 params->hdr.tag = ATAG_MEM;
147 params->hdr.size = tag_size(tag_mem32);
148
149 params->u.mem.start = bd->bi_dram[i].start;
150 params->u.mem.size = bd->bi_dram[i].size;
151
152 params = tag_next(params);
153 }
154}
155#endif /* CONFIG_SETUP_MEMORY_TAGS */
156
157
158static void setup_commandline_tag(bd_t *bd, char *commandline)
159{
160 char *p;
161
162 if (!commandline)
163 return;
164
165 /* eat leading white space */
166 for (p = commandline; *p == ' '; p++)
167 ;
168
169 /* skip non-existent command lines so the kernel will still
170 * use its default command line.
171 */
172 if (*p == '\0')
173 return;
174
175 params->hdr.tag = ATAG_CMDLINE;
176 params->hdr.size =
177 (sizeof(struct tag_header) + strlen(p) + 1 + 4) >> 2;
178
179 strcpy(params->u.cmdline.cmdline, p)
180 ;
181
182 params = tag_next(params);
183}
184
185
186#ifdef CONFIG_INITRD_TAG
187static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end)
188{
189 /* an ATAG_INITRD node tells the kernel where the compressed
190 * ramdisk can be found. ATAG_RDIMG is a better name, actually.
191 */
192 params->hdr.tag = ATAG_INITRD2;
193 params->hdr.size = tag_size(tag_initrd);
194
195 params->u.initrd.start = initrd_start;
196 params->u.initrd.size = initrd_end - initrd_start;
197
198 params = tag_next(params);
199}
200#endif /* CONFIG_INITRD_TAG */
201
202#ifdef CONFIG_SERIAL_TAG
203void setup_serial_tag(struct tag **tmp)
204{
205 struct tag *params = *tmp;
206 struct tag_serialnr serialnr;
207 void get_board_serial(struct tag_serialnr *serialnr);
208
209 get_board_serial(&serialnr);
210 params->hdr.tag = ATAG_SERIAL;
211 params->hdr.size = tag_size(tag_serialnr);
212 params->u.serialnr.low = serialnr.low;
213 params->u.serialnr.high = serialnr.high;
214 params = tag_next(params);
215 *tmp = params;
216}
217#endif
218
219#ifdef CONFIG_REVISION_TAG
220void setup_revision_tag(struct tag **in_params)
221{
222 u32 rev = 0;
223 u32 get_board_rev(void);
224
225 rev = get_board_rev();
226 params->hdr.tag = ATAG_REVISION;
227 params->hdr.size = tag_size(tag_revision);
228 params->u.revision.rev = rev;
229 params = tag_next(params);
230}
231#endif /* CONFIG_REVISION_TAG */
232
233
234static void setup_end_tag(bd_t *bd)
235{
236 params->hdr.tag = ATAG_NONE;
237 params->hdr.size = 0;
238}
239
240#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */