1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <common.h>
25#include <command.h>
26#include <image.h>
27#include <u-boot/zlib.h>
28#include <asm/byteorder.h>
29
30DECLARE_GLOBAL_DATA_PTR;
31
32#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
33 defined (CONFIG_CMDLINE_TAG) || \
34 defined (CONFIG_INITRD_TAG) || \
35 defined (CONFIG_SERIAL_TAG) || \
36 defined (CONFIG_REVISION_TAG) || \
37 defined (CONFIG_VFD) || \
38 defined (CONFIG_LCD)
39static void setup_start_tag (bd_t *bd);
40
41# ifdef CONFIG_SETUP_MEMORY_TAGS
42static void setup_memory_tags (bd_t *bd);
43# endif
44static void setup_commandline_tag (bd_t *bd, char *commandline);
45
46# ifdef CONFIG_INITRD_TAG
47static void setup_initrd_tag (bd_t *bd, ulong initrd_start,
48 ulong initrd_end);
49# endif
50static void setup_end_tag (bd_t *bd);
51
52# if defined (CONFIG_VFD) || defined (CONFIG_LCD)
53static void setup_videolfb_tag (gd_t *gd);
54# endif
55
56static struct tag *params;
57#endif
58
59int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
60{
61 bd_t *bd = gd->bd;
62 char *s;
63 int machid = bd->bi_arch_number;
64 void (*theKernel)(int zero, int arch, uint params);
65
66#ifdef CONFIG_CMDLINE_TAG
67 char *commandline = getenv ("bootargs");
68#endif
69
70 if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
71 return 1;
72
73 theKernel = (void (*)(int, int, uint))images->ep;
74
75 s = getenv ("machid");
76 if (s) {
77 machid = simple_strtoul (s, NULL, 16);
78 printf ("Using machid 0x%x from environment\n", machid);
79 }
80
81 show_boot_progress (15);
82
83 debug ("## Transferring control to Linux (at address %08lx) ...\n",
84 (ulong) theKernel);
85
86#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
87 defined (CONFIG_CMDLINE_TAG) || \
88 defined (CONFIG_INITRD_TAG) || \
89 defined (CONFIG_SERIAL_TAG) || \
90 defined (CONFIG_REVISION_TAG) || \
91 defined (CONFIG_LCD) || \
92 defined (CONFIG_VFD)
93 setup_start_tag (bd);
94#ifdef CONFIG_SERIAL_TAG
95 setup_serial_tag (¶ms);
96#endif
97#ifdef CONFIG_REVISION_TAG
98 setup_revision_tag (¶ms);
99#endif
100#ifdef CONFIG_SETUP_MEMORY_TAGS
101 setup_memory_tags (bd);
102#endif
103#ifdef CONFIG_CMDLINE_TAG
104 setup_commandline_tag (bd, commandline);
105#endif
106#ifdef CONFIG_INITRD_TAG
107 if (images->rd_start && images->rd_end)
108 setup_initrd_tag (bd, images->rd_start, images->rd_end);
109#endif
110#if defined (CONFIG_VFD) || defined (CONFIG_LCD)
111 setup_videolfb_tag ((gd_t *) gd);
112#endif
113 setup_end_tag (bd);
114#endif
115
116
117 printf ("\nStarting kernel ...\n\n");
118
119#ifdef CONFIG_USB_DEVICE
120 {
121 extern void udc_disconnect (void);
122 udc_disconnect ();
123 }
124#endif
125
126 cleanup_before_linux ();
127
128 theKernel (0, machid, bd->bi_boot_params);
129
130
131 return 1;
132}
133
134
135#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
136 defined (CONFIG_CMDLINE_TAG) || \
137 defined (CONFIG_INITRD_TAG) || \
138 defined (CONFIG_SERIAL_TAG) || \
139 defined (CONFIG_REVISION_TAG) || \
140 defined (CONFIG_LCD) || \
141 defined (CONFIG_VFD)
142static void setup_start_tag (bd_t *bd)
143{
144 params = (struct tag *) bd->bi_boot_params;
145
146 params->hdr.tag = ATAG_CORE;
147 params->hdr.size = tag_size (tag_core);
148
149 params->u.core.flags = 0;
150 params->u.core.pagesize = 0;
151 params->u.core.rootdev = 0;
152
153 params = tag_next (params);
154}
155
156
157#ifdef CONFIG_SETUP_MEMORY_TAGS
158static void setup_memory_tags (bd_t *bd)
159{
160 int i;
161
162 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
163 params->hdr.tag = ATAG_MEM;
164 params->hdr.size = tag_size (tag_mem32);
165
166 params->u.mem.start = bd->bi_dram[i].start;
167 params->u.mem.size = bd->bi_dram[i].size;
168
169 params = tag_next (params);
170 }
171}
172#endif
173
174
175static void setup_commandline_tag (bd_t *bd, char *commandline)
176{
177 char *p;
178
179 if (!commandline)
180 return;
181
182
183 for (p = commandline; *p == ' '; p++);
184
185
186
187
188 if (*p == '\0')
189 return;
190
191 params->hdr.tag = ATAG_CMDLINE;
192 params->hdr.size =
193 (sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;
194
195 strcpy (params->u.cmdline.cmdline, p);
196
197 params = tag_next (params);
198}
199
200
201#ifdef CONFIG_INITRD_TAG
202static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
203{
204
205
206
207 params->hdr.tag = ATAG_INITRD2;
208 params->hdr.size = tag_size (tag_initrd);
209
210 params->u.initrd.start = initrd_start;
211 params->u.initrd.size = initrd_end - initrd_start;
212
213 params = tag_next (params);
214}
215#endif
216
217
218#if defined (CONFIG_VFD) || defined (CONFIG_LCD)
219extern ulong calc_fbsize (void);
220static void setup_videolfb_tag (gd_t *gd)
221{
222
223
224
225
226
227
228
229 params->hdr.tag = ATAG_VIDEOLFB;
230 params->hdr.size = tag_size (tag_videolfb);
231
232 params->u.videolfb.lfb_base = (u32) gd->fb_base;
233
234
235 params->u.videolfb.lfb_size = calc_fbsize();
236
237 params = tag_next (params);
238}
239#endif
240
241#ifdef CONFIG_SERIAL_TAG
242void setup_serial_tag (struct tag **tmp)
243{
244 struct tag *params = *tmp;
245 struct tag_serialnr serialnr;
246 void get_board_serial(struct tag_serialnr *serialnr);
247
248 get_board_serial(&serialnr);
249 params->hdr.tag = ATAG_SERIAL;
250 params->hdr.size = tag_size (tag_serialnr);
251 params->u.serialnr.low = serialnr.low;
252 params->u.serialnr.high= serialnr.high;
253 params = tag_next (params);
254 *tmp = params;
255}
256#endif
257
258#ifdef CONFIG_REVISION_TAG
259void setup_revision_tag(struct tag **in_params)
260{
261 u32 rev = 0;
262 u32 get_board_rev(void);
263
264 rev = get_board_rev();
265 params->hdr.tag = ATAG_REVISION;
266 params->hdr.size = tag_size (tag_revision);
267 params->u.revision.rev = rev;
268 params = tag_next (params);
269}
270#endif
271
272
273static void setup_end_tag (bd_t *bd)
274{
275 params->hdr.tag = ATAG_NONE;
276 params->hdr.size = 0;
277}
278
279#endif
280