Commit 5644369450635fa5c2967bee55b1ac41f6e988d0

Authored by Tom Rini

Merge branch 'agust@denx.de' of git://git.denx.de/u-boot-staging

Showing 10 changed files Inline Diff

board/ait/cam_enc_4xx/cam_enc_4xx.c
1 /* 1 /*
2 * Copyright (C) 2009 Texas Instruments Incorporated 2 * Copyright (C) 2009 Texas Instruments Incorporated
3 * 3 *
4 * Copyright (C) 2011 4 * Copyright (C) 2011
5 * Heiko Schocher, DENX Software Engineering, hs@denx.de. 5 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or 9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version. 10 * (at your option) any later version.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */ 20 */
21 21
22 #include <common.h> 22 #include <common.h>
23 #include <errno.h> 23 #include <errno.h>
24 #include <hush.h> 24 #include <hush.h>
25 #include <linux/mtd/nand.h> 25 #include <linux/mtd/nand.h>
26 #include <nand.h> 26 #include <nand.h>
27 #include <miiphy.h> 27 #include <miiphy.h>
28 #include <netdev.h> 28 #include <netdev.h>
29 #include <asm/io.h> 29 #include <asm/io.h>
30 #include <asm/arch/hardware.h> 30 #include <asm/arch/hardware.h>
31 #include <asm/arch/nand_defs.h> 31 #include <asm/arch/nand_defs.h>
32 #include <asm/arch/davinci_misc.h> 32 #include <asm/arch/davinci_misc.h>
33 #ifdef CONFIG_DAVINCI_MMC 33 #ifdef CONFIG_DAVINCI_MMC
34 #include <mmc.h> 34 #include <mmc.h>
35 #include <asm/arch/sdmmc_defs.h> 35 #include <asm/arch/sdmmc_defs.h>
36 #endif 36 #endif
37 37
38 DECLARE_GLOBAL_DATA_PTR; 38 DECLARE_GLOBAL_DATA_PTR;
39 39
40 #ifndef CONFIG_SPL_BUILD 40 #ifndef CONFIG_SPL_BUILD
41 static struct davinci_timer *timer = 41 static struct davinci_timer *timer =
42 (struct davinci_timer *)DAVINCI_TIMER3_BASE; 42 (struct davinci_timer *)DAVINCI_TIMER3_BASE;
43 43
44 static unsigned long get_timer_val(void) 44 static unsigned long get_timer_val(void)
45 { 45 {
46 unsigned long now = readl(&timer->tim34); 46 unsigned long now = readl(&timer->tim34);
47 47
48 return now; 48 return now;
49 } 49 }
50 50
51 static int timer_running(void) 51 static int timer_running(void)
52 { 52 {
53 return readl(&timer->tcr) & 53 return readl(&timer->tcr) &
54 (DV_TIMER_TCR_ENAMODE_MASK << DV_TIMER_TCR_ENAMODE34_SHIFT); 54 (DV_TIMER_TCR_ENAMODE_MASK << DV_TIMER_TCR_ENAMODE34_SHIFT);
55 } 55 }
56 56
57 static void stop_timer(void) 57 static void stop_timer(void)
58 { 58 {
59 writel(0x0, &timer->tcr); 59 writel(0x0, &timer->tcr);
60 return; 60 return;
61 } 61 }
62 62
63 int checkboard(void) 63 int checkboard(void)
64 { 64 {
65 printf("Board: AIT CAM ENC 4XX\n"); 65 printf("Board: AIT CAM ENC 4XX\n");
66 return 0; 66 return 0;
67 } 67 }
68 68
69 int board_init(void) 69 int board_init(void)
70 { 70 {
71 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; 71 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
72 72
73 return 0; 73 return 0;
74 } 74 }
75 75
76 #ifdef CONFIG_DRIVER_TI_EMAC 76 #ifdef CONFIG_DRIVER_TI_EMAC
77 static int cam_enc_4xx_check_network(void) 77 static int cam_enc_4xx_check_network(void)
78 { 78 {
79 char *s; 79 char *s;
80 80
81 s = getenv("ethaddr"); 81 s = getenv("ethaddr");
82 if (!s) 82 if (!s)
83 return -EINVAL; 83 return -EINVAL;
84 84
85 if (!is_valid_ether_addr((const u8 *)s)) 85 if (!is_valid_ether_addr((const u8 *)s))
86 return -EINVAL; 86 return -EINVAL;
87 87
88 s = getenv("ipaddr"); 88 s = getenv("ipaddr");
89 if (!s) 89 if (!s)
90 return -EINVAL; 90 return -EINVAL;
91 91
92 s = getenv("netmask"); 92 s = getenv("netmask");
93 if (!s) 93 if (!s)
94 return -EINVAL; 94 return -EINVAL;
95 95
96 s = getenv("serverip"); 96 s = getenv("serverip");
97 if (!s) 97 if (!s)
98 return -EINVAL; 98 return -EINVAL;
99 99
100 s = getenv("gatewayip"); 100 s = getenv("gatewayip");
101 if (!s) 101 if (!s)
102 return -EINVAL; 102 return -EINVAL;
103 103
104 return 0; 104 return 0;
105 } 105 }
106 int board_eth_init(bd_t *bis) 106 int board_eth_init(bd_t *bis)
107 { 107 {
108 int ret; 108 int ret;
109 109
110 ret = cam_enc_4xx_check_network(); 110 ret = cam_enc_4xx_check_network();
111 if (ret) 111 if (ret)
112 return ret; 112 return ret;
113 113
114 davinci_emac_initialize(); 114 davinci_emac_initialize();
115 115
116 return 0; 116 return 0;
117 } 117 }
118 #endif 118 #endif
119 119
120 #ifdef CONFIG_NAND_DAVINCI 120 #ifdef CONFIG_NAND_DAVINCI
121 static int 121 static int
122 davinci_std_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, 122 davinci_std_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
123 uint8_t *buf, int page) 123 uint8_t *buf, int page)
124 { 124 {
125 struct nand_chip *this = mtd->priv; 125 struct nand_chip *this = mtd->priv;
126 int i, eccsize = chip->ecc.size; 126 int i, eccsize = chip->ecc.size;
127 int eccbytes = chip->ecc.bytes; 127 int eccbytes = chip->ecc.bytes;
128 int eccsteps = chip->ecc.steps; 128 int eccsteps = chip->ecc.steps;
129 uint8_t *p = buf; 129 uint8_t *p = buf;
130 uint8_t *oob = chip->oob_poi; 130 uint8_t *oob = chip->oob_poi;
131 131
132 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); 132 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
133 133
134 chip->read_buf(mtd, oob, mtd->oobsize); 134 chip->read_buf(mtd, oob, mtd->oobsize);
135 135
136 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x0, page & this->pagemask); 136 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x0, page & this->pagemask);
137 137
138 138
139 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 139 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
140 int stat; 140 int stat;
141 141
142 chip->ecc.hwctl(mtd, NAND_ECC_READ); 142 chip->ecc.hwctl(mtd, NAND_ECC_READ);
143 chip->read_buf(mtd, p, eccsize); 143 chip->read_buf(mtd, p, eccsize);
144 chip->ecc.hwctl(mtd, NAND_ECC_READSYN); 144 chip->ecc.hwctl(mtd, NAND_ECC_READSYN);
145 145
146 if (chip->ecc.prepad) 146 if (chip->ecc.prepad)
147 oob += chip->ecc.prepad; 147 oob += chip->ecc.prepad;
148 148
149 stat = chip->ecc.correct(mtd, p, oob, NULL); 149 stat = chip->ecc.correct(mtd, p, oob, NULL);
150 150
151 if (stat == -1) 151 if (stat == -1)
152 mtd->ecc_stats.failed++; 152 mtd->ecc_stats.failed++;
153 else 153 else
154 mtd->ecc_stats.corrected += stat; 154 mtd->ecc_stats.corrected += stat;
155 155
156 oob += eccbytes; 156 oob += eccbytes;
157 157
158 if (chip->ecc.postpad) 158 if (chip->ecc.postpad)
159 oob += chip->ecc.postpad; 159 oob += chip->ecc.postpad;
160 } 160 }
161 161
162 /* Calculate remaining oob bytes */ 162 /* Calculate remaining oob bytes */
163 i = mtd->oobsize - (oob - chip->oob_poi); 163 i = mtd->oobsize - (oob - chip->oob_poi);
164 if (i) 164 if (i)
165 chip->read_buf(mtd, oob, i); 165 chip->read_buf(mtd, oob, i);
166 166
167 return 0; 167 return 0;
168 } 168 }
169 169
170 static void davinci_std_write_page_syndrome(struct mtd_info *mtd, 170 static void davinci_std_write_page_syndrome(struct mtd_info *mtd,
171 struct nand_chip *chip, const uint8_t *buf) 171 struct nand_chip *chip, const uint8_t *buf)
172 { 172 {
173 unsigned char davinci_ecc_buf[NAND_MAX_OOBSIZE]; 173 unsigned char davinci_ecc_buf[NAND_MAX_OOBSIZE];
174 struct nand_chip *this = mtd->priv; 174 struct nand_chip *this = mtd->priv;
175 int i, eccsize = chip->ecc.size; 175 int i, eccsize = chip->ecc.size;
176 int eccbytes = chip->ecc.bytes; 176 int eccbytes = chip->ecc.bytes;
177 int eccsteps = chip->ecc.steps; 177 int eccsteps = chip->ecc.steps;
178 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; 178 int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
179 int offset = 0; 179 int offset = 0;
180 const uint8_t *p = buf; 180 const uint8_t *p = buf;
181 uint8_t *oob = chip->oob_poi; 181 uint8_t *oob = chip->oob_poi;
182 182
183 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 183 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
184 chip->ecc.hwctl(mtd, NAND_ECC_WRITE); 184 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
185 chip->write_buf(mtd, p, eccsize); 185 chip->write_buf(mtd, p, eccsize);
186 186
187 /* Calculate ECC without prepad */ 187 /* Calculate ECC without prepad */
188 chip->ecc.calculate(mtd, p, oob + chip->ecc.prepad); 188 chip->ecc.calculate(mtd, p, oob + chip->ecc.prepad);
189 189
190 if (chip->ecc.prepad) { 190 if (chip->ecc.prepad) {
191 offset = (chip->ecc.steps - eccsteps) * chunk; 191 offset = (chip->ecc.steps - eccsteps) * chunk;
192 memcpy(&davinci_ecc_buf[offset], oob, chip->ecc.prepad); 192 memcpy(&davinci_ecc_buf[offset], oob, chip->ecc.prepad);
193 oob += chip->ecc.prepad; 193 oob += chip->ecc.prepad;
194 } 194 }
195 195
196 offset = ((chip->ecc.steps - eccsteps) * chunk) + 196 offset = ((chip->ecc.steps - eccsteps) * chunk) +
197 chip->ecc.prepad; 197 chip->ecc.prepad;
198 memcpy(&davinci_ecc_buf[offset], oob, eccbytes); 198 memcpy(&davinci_ecc_buf[offset], oob, eccbytes);
199 oob += eccbytes; 199 oob += eccbytes;
200 200
201 if (chip->ecc.postpad) { 201 if (chip->ecc.postpad) {
202 offset = ((chip->ecc.steps - eccsteps) * chunk) + 202 offset = ((chip->ecc.steps - eccsteps) * chunk) +
203 chip->ecc.prepad + eccbytes; 203 chip->ecc.prepad + eccbytes;
204 memcpy(&davinci_ecc_buf[offset], oob, 204 memcpy(&davinci_ecc_buf[offset], oob,
205 chip->ecc.postpad); 205 chip->ecc.postpad);
206 oob += chip->ecc.postpad; 206 oob += chip->ecc.postpad;
207 } 207 }
208 } 208 }
209 209
210 /* 210 /*
211 * Write the sparebytes into the page once 211 * Write the sparebytes into the page once
212 * all eccsteps have been covered 212 * all eccsteps have been covered
213 */ 213 */
214 for (i = 0; i < mtd->oobsize; i++) 214 for (i = 0; i < mtd->oobsize; i++)
215 writeb(davinci_ecc_buf[i], this->IO_ADDR_W); 215 writeb(davinci_ecc_buf[i], this->IO_ADDR_W);
216 216
217 /* Calculate remaining oob bytes */ 217 /* Calculate remaining oob bytes */
218 i = mtd->oobsize - (oob - chip->oob_poi); 218 i = mtd->oobsize - (oob - chip->oob_poi);
219 if (i) 219 if (i)
220 chip->write_buf(mtd, oob, i); 220 chip->write_buf(mtd, oob, i);
221 } 221 }
222 222
223 static int davinci_std_write_oob_syndrome(struct mtd_info *mtd, 223 static int davinci_std_write_oob_syndrome(struct mtd_info *mtd,
224 struct nand_chip *chip, int page) 224 struct nand_chip *chip, int page)
225 { 225 {
226 int pos, status = 0; 226 int pos, status = 0;
227 const uint8_t *bufpoi = chip->oob_poi; 227 const uint8_t *bufpoi = chip->oob_poi;
228 228
229 pos = mtd->writesize; 229 pos = mtd->writesize;
230 230
231 chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page); 231 chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page);
232 232
233 chip->write_buf(mtd, bufpoi, mtd->oobsize); 233 chip->write_buf(mtd, bufpoi, mtd->oobsize);
234 234
235 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); 235 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
236 status = chip->waitfunc(mtd, chip); 236 status = chip->waitfunc(mtd, chip);
237 237
238 return status & NAND_STATUS_FAIL ? -1 : 0; 238 return status & NAND_STATUS_FAIL ? -1 : 0;
239 } 239 }
240 240
241 static int davinci_std_read_oob_syndrome(struct mtd_info *mtd, 241 static int davinci_std_read_oob_syndrome(struct mtd_info *mtd,
242 struct nand_chip *chip, int page, int sndcmd) 242 struct nand_chip *chip, int page, int sndcmd)
243 { 243 {
244 struct nand_chip *this = mtd->priv; 244 struct nand_chip *this = mtd->priv;
245 uint8_t *buf = chip->oob_poi; 245 uint8_t *buf = chip->oob_poi;
246 uint8_t *bufpoi = buf; 246 uint8_t *bufpoi = buf;
247 247
248 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); 248 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
249 249
250 chip->read_buf(mtd, bufpoi, mtd->oobsize); 250 chip->read_buf(mtd, bufpoi, mtd->oobsize);
251 251
252 return 1; 252 return 1;
253 } 253 }
254 254
255 static void nand_dm365evm_select_chip(struct mtd_info *mtd, int chip) 255 static void nand_dm365evm_select_chip(struct mtd_info *mtd, int chip)
256 { 256 {
257 struct nand_chip *this = mtd->priv; 257 struct nand_chip *this = mtd->priv;
258 unsigned long wbase = (unsigned long) this->IO_ADDR_W; 258 unsigned long wbase = (unsigned long) this->IO_ADDR_W;
259 unsigned long rbase = (unsigned long) this->IO_ADDR_R; 259 unsigned long rbase = (unsigned long) this->IO_ADDR_R;
260 260
261 if (chip == 1) { 261 if (chip == 1) {
262 __set_bit(14, &wbase); 262 __set_bit(14, &wbase);
263 __set_bit(14, &rbase); 263 __set_bit(14, &rbase);
264 } else { 264 } else {
265 __clear_bit(14, &wbase); 265 __clear_bit(14, &wbase);
266 __clear_bit(14, &rbase); 266 __clear_bit(14, &rbase);
267 } 267 }
268 this->IO_ADDR_W = (void *)wbase; 268 this->IO_ADDR_W = (void *)wbase;
269 this->IO_ADDR_R = (void *)rbase; 269 this->IO_ADDR_R = (void *)rbase;
270 } 270 }
271 271
272 int board_nand_init(struct nand_chip *nand) 272 int board_nand_init(struct nand_chip *nand)
273 { 273 {
274 davinci_nand_init(nand); 274 davinci_nand_init(nand);
275 nand->select_chip = nand_dm365evm_select_chip; 275 nand->select_chip = nand_dm365evm_select_chip;
276 276
277 return 0; 277 return 0;
278 } 278 }
279 279
280 struct nand_ecc_ctrl org_ecc; 280 struct nand_ecc_ctrl org_ecc;
281 static int notsaved = 1; 281 static int notsaved = 1;
282 282
283 static int nand_switch_hw_func(int mode) 283 static int nand_switch_hw_func(int mode)
284 { 284 {
285 struct nand_chip *nand; 285 struct nand_chip *nand;
286 struct mtd_info *mtd; 286 struct mtd_info *mtd;
287 287
288 if (nand_curr_device < 0 || 288 if (nand_curr_device < 0 ||
289 nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE || 289 nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
290 !nand_info[nand_curr_device].name) { 290 !nand_info[nand_curr_device].name) {
291 printf("Error: Can't switch hw functions," \ 291 printf("Error: Can't switch hw functions," \
292 " no devices available\n"); 292 " no devices available\n");
293 return -1; 293 return -1;
294 } 294 }
295 295
296 mtd = &nand_info[nand_curr_device]; 296 mtd = &nand_info[nand_curr_device];
297 nand = mtd->priv; 297 nand = mtd->priv;
298 298
299 if (mode == 0) { 299 if (mode == 0) {
300 if (notsaved == 0) { 300 if (notsaved == 0) {
301 printf("switching to uboot hw functions.\n"); 301 printf("switching to uboot hw functions.\n");
302 memcpy(&nand->ecc, &org_ecc, 302 memcpy(&nand->ecc, &org_ecc,
303 sizeof(struct nand_ecc_ctrl)); 303 sizeof(struct nand_ecc_ctrl));
304 } 304 }
305 } else { 305 } else {
306 /* RBL */ 306 /* RBL */
307 printf("switching to RBL hw functions.\n"); 307 printf("switching to RBL hw functions.\n");
308 if (notsaved == 1) { 308 if (notsaved == 1) {
309 memcpy(&org_ecc, &nand->ecc, 309 memcpy(&org_ecc, &nand->ecc,
310 sizeof(struct nand_ecc_ctrl)); 310 sizeof(struct nand_ecc_ctrl));
311 notsaved = 0; 311 notsaved = 0;
312 } 312 }
313 nand->ecc.mode = NAND_ECC_HW_SYNDROME; 313 nand->ecc.mode = NAND_ECC_HW_SYNDROME;
314 nand->ecc.prepad = 6; 314 nand->ecc.prepad = 6;
315 nand->ecc.read_page = davinci_std_read_page_syndrome; 315 nand->ecc.read_page = davinci_std_read_page_syndrome;
316 nand->ecc.write_page = davinci_std_write_page_syndrome; 316 nand->ecc.write_page = davinci_std_write_page_syndrome;
317 nand->ecc.read_oob = davinci_std_read_oob_syndrome; 317 nand->ecc.read_oob = davinci_std_read_oob_syndrome;
318 nand->ecc.write_oob = davinci_std_write_oob_syndrome; 318 nand->ecc.write_oob = davinci_std_write_oob_syndrome;
319 } 319 }
320 return mode; 320 return mode;
321 } 321 }
322 322
323 static int hwmode; 323 static int hwmode;
324 324
325 static int do_switch_ecc(cmd_tbl_t *cmdtp, int flag, int argc, 325 static int do_switch_ecc(cmd_tbl_t *cmdtp, int flag, int argc,
326 char *const argv[]) 326 char *const argv[])
327 { 327 {
328 if (argc != 2) 328 if (argc != 2)
329 goto usage; 329 goto usage;
330 if (strncmp(argv[1], "rbl", 2) == 0) 330 if (strncmp(argv[1], "rbl", 2) == 0)
331 hwmode = nand_switch_hw_func(1); 331 hwmode = nand_switch_hw_func(1);
332 else if (strncmp(argv[1], "uboot", 2) == 0) 332 else if (strncmp(argv[1], "uboot", 2) == 0)
333 hwmode = nand_switch_hw_func(0); 333 hwmode = nand_switch_hw_func(0);
334 else 334 else
335 goto usage; 335 goto usage;
336 336
337 return 0; 337 return 0;
338 338
339 usage: 339 usage:
340 printf("Usage: nandrbl %s\n", cmdtp->usage); 340 printf("Usage: nandrbl %s\n", cmdtp->usage);
341 return 1; 341 return 1;
342 } 342 }
343 343
344 U_BOOT_CMD( 344 U_BOOT_CMD(
345 nandrbl, 2, 1, do_switch_ecc, 345 nandrbl, 2, 1, do_switch_ecc,
346 "switch between rbl/uboot NAND ECC calculation algorithm", 346 "switch between rbl/uboot NAND ECC calculation algorithm",
347 "[rbl/uboot] - Switch between rbl/uboot NAND ECC algorithm" 347 "[rbl/uboot] - Switch between rbl/uboot NAND ECC algorithm"
348 ); 348 );
349 349
350 350
351 #endif /* #ifdef CONFIG_NAND_DAVINCI */ 351 #endif /* #ifdef CONFIG_NAND_DAVINCI */
352 352
353 #ifdef CONFIG_DAVINCI_MMC 353 #ifdef CONFIG_DAVINCI_MMC
354 static struct davinci_mmc mmc_sd0 = { 354 static struct davinci_mmc mmc_sd0 = {
355 .reg_base = (struct davinci_mmc_regs *)DAVINCI_MMC_SD0_BASE, 355 .reg_base = (struct davinci_mmc_regs *)DAVINCI_MMC_SD0_BASE,
356 .input_clk = 121500000, 356 .input_clk = 121500000,
357 .host_caps = MMC_MODE_4BIT, 357 .host_caps = MMC_MODE_4BIT,
358 .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, 358 .voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
359 .version = MMC_CTLR_VERSION_2, 359 .version = MMC_CTLR_VERSION_2,
360 }; 360 };
361 361
362 int board_mmc_init(bd_t *bis) 362 int board_mmc_init(bd_t *bis)
363 { 363 {
364 int err; 364 int err;
365 365
366 /* Add slot-0 to mmc subsystem */ 366 /* Add slot-0 to mmc subsystem */
367 err = davinci_mmc_init(bis, &mmc_sd0); 367 err = davinci_mmc_init(bis, &mmc_sd0);
368 368
369 return err; 369 return err;
370 } 370 }
371 #endif 371 #endif
372 372
373 int board_late_init(void) 373 int board_late_init(void)
374 { 374 {
375 struct davinci_gpio *gpio = davinci_gpio_bank45; 375 struct davinci_gpio *gpio = davinci_gpio_bank45;
376 376
377 /* 24MHz InputClock / 15 prediv -> 1.6 MHz timer running */ 377 /* 24MHz InputClock / 15 prediv -> 1.6 MHz timer running */
378 while ((get_timer_val() < CONFIG_AIT_TIMER_TIMEOUT) && 378 while ((get_timer_val() < CONFIG_AIT_TIMER_TIMEOUT) &&
379 timer_running()) 379 timer_running())
380 ; 380 ;
381 381
382 /* 1 sec reached -> stop timer, clear all LED */ 382 /* 1 sec reached -> stop timer, clear all LED */
383 stop_timer(); 383 stop_timer();
384 clrbits_le32(&gpio->out_data, CONFIG_CAM_ENC_LED_MASK); 384 clrbits_le32(&gpio->out_data, CONFIG_CAM_ENC_LED_MASK);
385 return 0; 385 return 0;
386 } 386 }
387 387
388 void reset_phy(void) 388 void reset_phy(void)
389 { 389 {
390 char *name = "GENERIC @ 0x00"; 390 char *name = "GENERIC @ 0x00";
391 391
392 /* reset the phy */ 392 /* reset the phy */
393 miiphy_reset(name, 0x0); 393 miiphy_reset(name, 0x0);
394 } 394 }
395 395
396 #else /* #ifndef CONFIG_SPL_BUILD */ 396 #else /* #ifndef CONFIG_SPL_BUILD */
397 static void cam_enc_4xx_set_all_led(void) 397 static void cam_enc_4xx_set_all_led(void)
398 { 398 {
399 struct davinci_gpio *gpio = davinci_gpio_bank45; 399 struct davinci_gpio *gpio = davinci_gpio_bank45;
400 400
401 setbits_le32(&gpio->out_data, CONFIG_CAM_ENC_LED_MASK); 401 setbits_le32(&gpio->out_data, CONFIG_CAM_ENC_LED_MASK);
402 } 402 }
403 403
404 /* 404 /*
405 * TIMER 0 is used for tick 405 * TIMER 0 is used for tick
406 */ 406 */
407 static struct davinci_timer *timer = 407 static struct davinci_timer *timer =
408 (struct davinci_timer *)DAVINCI_TIMER3_BASE; 408 (struct davinci_timer *)DAVINCI_TIMER3_BASE;
409 409
410 #define TIMER_LOAD_VAL 0xffffffff 410 #define TIMER_LOAD_VAL 0xffffffff
411 #define TIM_CLK_DIV 16 411 #define TIM_CLK_DIV 16
412 412
413 static int cam_enc_4xx_timer_init(void) 413 static int cam_enc_4xx_timer_init(void)
414 { 414 {
415 /* We are using timer34 in unchained 32-bit mode, full speed */ 415 /* We are using timer34 in unchained 32-bit mode, full speed */
416 writel(0x0, &timer->tcr); 416 writel(0x0, &timer->tcr);
417 writel(0x0, &timer->tgcr); 417 writel(0x0, &timer->tgcr);
418 writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr); 418 writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr);
419 writel(0x0, &timer->tim34); 419 writel(0x0, &timer->tim34);
420 writel(TIMER_LOAD_VAL, &timer->prd34); 420 writel(TIMER_LOAD_VAL, &timer->prd34);
421 writel(2 << 22, &timer->tcr); 421 writel(2 << 22, &timer->tcr);
422 return 0; 422 return 0;
423 } 423 }
424 424
425 void board_gpio_init(void) 425 void board_gpio_init(void)
426 { 426 {
427 struct davinci_gpio *gpio; 427 struct davinci_gpio *gpio;
428 428
429 cam_enc_4xx_set_all_led(); 429 cam_enc_4xx_set_all_led();
430 cam_enc_4xx_timer_init(); 430 cam_enc_4xx_timer_init();
431 gpio = davinci_gpio_bank01; 431 gpio = davinci_gpio_bank01;
432 clrbits_le32(&gpio->dir, ~0xfdfffffe); 432 clrbits_le32(&gpio->dir, ~0xfdfffffe);
433 /* clear LED D14 = GPIO25 */ 433 /* clear LED D14 = GPIO25 */
434 clrbits_le32(&gpio->out_data, 0x02000000); 434 clrbits_le32(&gpio->out_data, 0x02000000);
435 gpio = davinci_gpio_bank23; 435 gpio = davinci_gpio_bank23;
436 clrbits_le32(&gpio->dir, ~0x5ff0afef); 436 clrbits_le32(&gpio->dir, ~0x5ff0afef);
437 /* set GPIO61 to 1 -> intern UART0 as Console */ 437 /* set GPIO61 to 1 -> intern UART0 as Console */
438 setbits_le32(&gpio->out_data, 0x20000000); 438 setbits_le32(&gpio->out_data, 0x20000000);
439 /* 439 /*
440 * PHY out of reset GIO 50 = 1 440 * PHY out of reset GIO 50 = 1
441 * NAND WP off GIO 51 = 1 441 * NAND WP off GIO 51 = 1
442 */ 442 */
443 setbits_le32(&gpio->out_data, 0x000c0004); 443 setbits_le32(&gpio->out_data, 0x000c0004);
444 gpio = davinci_gpio_bank45; 444 gpio = davinci_gpio_bank45;
445 clrbits_le32(&gpio->dir, ~(0xdb2fffff) | CONFIG_CAM_ENC_LED_MASK); 445 clrbits_le32(&gpio->dir, ~(0xdb2fffff) | CONFIG_CAM_ENC_LED_MASK);
446 /* 446 /*
447 * clear LED: 447 * clear LED:
448 * D17 = GPIO86 448 * D17 = GPIO86
449 * D11 = GPIO87 449 * D11 = GPIO87
450 * GPIO88 450 * GPIO88
451 * GPIO89 451 * GPIO89
452 * D13 = GPIO90 452 * D13 = GPIO90
453 * GPIO91 453 * GPIO91
454 */ 454 */
455 clrbits_le32(&gpio->out_data, CONFIG_CAM_ENC_LED_MASK); 455 clrbits_le32(&gpio->out_data, CONFIG_CAM_ENC_LED_MASK);
456 gpio = davinci_gpio_bank67; 456 gpio = davinci_gpio_bank67;
457 clrbits_le32(&gpio->dir, ~0x000007ff); 457 clrbits_le32(&gpio->dir, ~0x000007ff);
458 } 458 }
459 459
460 /* 460 /*
461 * functions for the post memory test. 461 * functions for the post memory test.
462 */ 462 */
463 int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset) 463 int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
464 { 464 {
465 *vstart = CONFIG_SYS_SDRAM_BASE; 465 *vstart = CONFIG_SYS_SDRAM_BASE;
466 *size = PHYS_SDRAM_1_SIZE; 466 *size = PHYS_SDRAM_1_SIZE;
467 *phys_offset = 0; 467 *phys_offset = 0;
468 return 0; 468 return 0;
469 } 469 }
470 470
471 void arch_memory_failure_handle(void) 471 void arch_memory_failure_handle(void)
472 { 472 {
473 cam_enc_4xx_set_all_led(); 473 cam_enc_4xx_set_all_led();
474 puts("mem failure\n"); 474 puts("mem failure\n");
475 while (1) 475 while (1)
476 ; 476 ;
477 } 477 }
478 #endif 478 #endif
479 #if defined(CONFIG_MENU) 479 #if defined(CONFIG_MENU)
480 #include "menu.h" 480 #include "menu.h"
481 481
482 #define MENU_EXIT -1 482 #define MENU_EXIT -1
483 #define MENU_EXIT_BOOTCMD -2 483 #define MENU_EXIT_BOOTCMD -2
484 #define MENU_STAY 0 484 #define MENU_STAY 0
485 #define MENU_MAIN 1 485 #define MENU_MAIN 1
486 #define MENU_UPDATE 2 486 #define MENU_UPDATE 2
487 #define MENU_NETWORK 3 487 #define MENU_NETWORK 3
488 #define MENU_LOAD 4 488 #define MENU_LOAD 4
489 489
490 static int menu_start; 490 static int menu_start;
491 491
492 #define FIT_SUBTYPE_UNKNOWN 0 492 #define FIT_SUBTYPE_UNKNOWN 0
493 #define FIT_SUBTYPE_UBL_HEADER 1 493 #define FIT_SUBTYPE_UBL_HEADER 1
494 #define FIT_SUBTYPE_SPL_IMAGE 2 494 #define FIT_SUBTYPE_SPL_IMAGE 2
495 #define FIT_SUBTYPE_UBOOT_IMAGE 3 495 #define FIT_SUBTYPE_UBOOT_IMAGE 3
496 #define FIT_SUBTYPE_DF_ENV_IMAGE 4 496 #define FIT_SUBTYPE_DF_ENV_IMAGE 4
497 #define FIT_SUBTYPE_RAMDISK_IMAGE 5 497 #define FIT_SUBTYPE_RAMDISK_IMAGE 5
498 498
499 struct fit_images_info { 499 struct fit_images_info {
500 u_int8_t type; 500 u_int8_t type;
501 int subtype; 501 int subtype;
502 char desc[200]; 502 char desc[200];
503 const void *data; 503 const void *data;
504 size_t size; 504 size_t size;
505 }; 505 };
506 506
507 static struct fit_images_info imgs[10]; 507 static struct fit_images_info imgs[10];
508 508
509 struct menu_display { 509 struct menu_display {
510 char title[50]; 510 char title[50];
511 int timeout; /* in sec */ 511 int timeout; /* in sec */
512 int id; /* MENU_* */ 512 int id; /* MENU_* */
513 char **menulist; 513 char **menulist;
514 int (*menu_evaluate)(char *choice); 514 int (*menu_evaluate)(char *choice);
515 }; 515 };
516 516
517 char *menu_main[] = { 517 char *menu_main[] = {
518 "(1) Boot", 518 "(1) Boot",
519 "(2) Update Software", 519 "(2) Update Software",
520 "(3) Reset to default setting and boot", 520 "(3) Reset to default setting and boot",
521 "(4) Enter U-Boot console", 521 "(4) Enter U-Boot console",
522 NULL 522 NULL
523 }; 523 };
524 524
525 char *menu_update[] = { 525 char *menu_update[] = {
526 "(1) Network settings", 526 "(1) Network settings",
527 "(2) load image", 527 "(2) load image",
528 "(3) back to main", 528 "(3) back to main",
529 NULL 529 NULL
530 }; 530 };
531 531
532 char *menu_load[] = { 532 char *menu_load[] = {
533 "(1) install image", 533 "(1) install image",
534 "(2) cancel", 534 "(2) cancel",
535 NULL 535 NULL
536 }; 536 };
537 537
538 char *menu_network[] = { 538 char *menu_network[] = {
539 "(1) ipaddr ", 539 "(1) ipaddr ",
540 "(2) netmask ", 540 "(2) netmask ",
541 "(3) serverip ", 541 "(3) serverip ",
542 "(4) gatewayip", 542 "(4) gatewayip",
543 "(5) tftp image name", 543 "(5) tftp image name",
544 "(6) back to update software", 544 "(6) back to update software",
545 NULL 545 NULL
546 }; 546 };
547 547
548 static void ait_menu_print(void *data) 548 static void ait_menu_print(void *data)
549 { 549 {
550 printf("%s\n", (char *)data); 550 printf("%s\n", (char *)data);
551 return; 551 return;
552 } 552 }
553 553
554 static char *menu_handle(struct menu_display *display) 554 static char *menu_handle(struct menu_display *display)
555 { 555 {
556 struct menu *m; 556 struct menu *m;
557 int i; 557 int i;
558 void *choice = NULL; 558 void *choice = NULL;
559 char key[2]; 559 char key[2];
560 int ret; 560 int ret;
561 char *s; 561 char *s;
562 char temp[6][200]; 562 char temp[6][200];
563 563
564 m = menu_create(display->title, display->timeout, 1, ait_menu_print); 564 m = menu_create(display->title, display->timeout, 1, ait_menu_print,
565 NULL, NULL);
565 566
566 for (i = 0; display->menulist[i]; i++) { 567 for (i = 0; display->menulist[i]; i++) {
567 sprintf(key, "%d", i + 1); 568 sprintf(key, "%d", i + 1);
568 if (display->id == MENU_NETWORK) { 569 if (display->id == MENU_NETWORK) {
569 switch (i) { 570 switch (i) {
570 case 0: 571 case 0:
571 s = getenv("ipaddr"); 572 s = getenv("ipaddr");
572 break; 573 break;
573 case 1: 574 case 1:
574 s = getenv("netmask"); 575 s = getenv("netmask");
575 break; 576 break;
576 case 2: 577 case 2:
577 s = getenv("serverip"); 578 s = getenv("serverip");
578 break; 579 break;
579 case 3: 580 case 3:
580 s = getenv("gatewayip"); 581 s = getenv("gatewayip");
581 break; 582 break;
582 case 4: 583 case 4:
583 s = getenv("img_file"); 584 s = getenv("img_file");
584 break; 585 break;
585 default: 586 default:
586 s = NULL; 587 s = NULL;
587 break; 588 break;
588 } 589 }
589 if (s) { 590 if (s) {
590 sprintf(temp[i], "%s: %s", 591 sprintf(temp[i], "%s: %s",
591 display->menulist[i], s); 592 display->menulist[i], s);
592 ret = menu_item_add(m, key, temp[i]); 593 ret = menu_item_add(m, key, temp[i]);
593 } else { 594 } else {
594 ret = menu_item_add(m, key, 595 ret = menu_item_add(m, key,
595 display->menulist[i]); 596 display->menulist[i]);
596 } 597 }
597 } else { 598 } else {
598 ret = menu_item_add(m, key, display->menulist[i]); 599 ret = menu_item_add(m, key, display->menulist[i]);
599 } 600 }
600 601
601 if (ret != 1) { 602 if (ret != 1) {
602 printf("failed to add item!"); 603 printf("failed to add item!");
603 menu_destroy(m); 604 menu_destroy(m);
604 return NULL; 605 return NULL;
605 } 606 }
606 } 607 }
607 sprintf(key, "%d", 1); 608 sprintf(key, "%d", 1);
608 menu_default_set(m, key); 609 menu_default_set(m, key);
609 610
610 if (menu_get_choice(m, &choice) != 1) 611 if (menu_get_choice(m, &choice) != 1)
611 debug("Problem picking a choice!\n"); 612 debug("Problem picking a choice!\n");
612 613
613 menu_destroy(m); 614 menu_destroy(m);
614 615
615 return choice; 616 return choice;
616 } 617 }
617 618
618 static int ait_menu_show(struct menu_display *display, int bootdelay) 619 static int ait_menu_show(struct menu_display *display, int bootdelay)
619 { 620 {
620 int end = MENU_STAY; 621 int end = MENU_STAY;
621 char *choice; 622 char *choice;
622 623
623 if ((menu_start == 0) && (display->id == MENU_MAIN)) 624 if ((menu_start == 0) && (display->id == MENU_MAIN))
624 display->timeout = bootdelay; 625 display->timeout = bootdelay;
625 else 626 else
626 display->timeout = 0; 627 display->timeout = 0;
627 628
628 while (end == MENU_STAY) { 629 while (end == MENU_STAY) {
629 choice = menu_handle(display); 630 choice = menu_handle(display);
630 if (choice) 631 if (choice)
631 end = display->menu_evaluate(choice); 632 end = display->menu_evaluate(choice);
632 633
633 if (end == display->id) 634 if (end == display->id)
634 end = MENU_STAY; 635 end = MENU_STAY;
635 if (display->id == MENU_MAIN) { 636 if (display->id == MENU_MAIN) {
636 if (menu_start == 0) 637 if (menu_start == 0)
637 end = MENU_EXIT_BOOTCMD; 638 end = MENU_EXIT_BOOTCMD;
638 else 639 else
639 display->timeout = 0; 640 display->timeout = 0;
640 } 641 }
641 } 642 }
642 return end; 643 return end;
643 } 644 }
644 645
645 static int ait_writeublheader(void) 646 static int ait_writeublheader(void)
646 { 647 {
647 char s[20]; 648 char s[20];
648 unsigned long i; 649 unsigned long i;
649 int ret; 650 int ret;
650 651
651 for (i = CONFIG_SYS_NAND_BLOCK_SIZE; 652 for (i = CONFIG_SYS_NAND_BLOCK_SIZE;
652 i < CONFIG_SYS_NAND_U_BOOT_OFFS; 653 i < CONFIG_SYS_NAND_U_BOOT_OFFS;
653 i += CONFIG_SYS_NAND_BLOCK_SIZE) { 654 i += CONFIG_SYS_NAND_BLOCK_SIZE) {
654 sprintf(s, "%lx", i); 655 sprintf(s, "%lx", i);
655 ret = setenv("header_addr", s); 656 ret = setenv("header_addr", s);
656 if (ret == 0) 657 if (ret == 0)
657 ret = run_command("run img_writeheader", 0); 658 ret = run_command("run img_writeheader", 0);
658 if (ret != 0) 659 if (ret != 0)
659 break; 660 break;
660 } 661 }
661 return ret; 662 return ret;
662 } 663 }
663 664
664 static int ait_menu_install_images(void) 665 static int ait_menu_install_images(void)
665 { 666 {
666 int ret = 0; 667 int ret = 0;
667 int count = 0; 668 int count = 0;
668 char s[100]; 669 char s[100];
669 char *t; 670 char *t;
670 671
671 /* 672 /*
672 * possible image types: 673 * possible image types:
673 * FIT_SUBTYPE_UNKNOWN 674 * FIT_SUBTYPE_UNKNOWN
674 * FIT_SUBTYPE_UBL_HEADER 675 * FIT_SUBTYPE_UBL_HEADER
675 * FIT_SUBTYPE_SPL_IMAGE 676 * FIT_SUBTYPE_SPL_IMAGE
676 * FIT_SUBTYPE_UBOOT_IMAGE 677 * FIT_SUBTYPE_UBOOT_IMAGE
677 * FIT_SUBTYPE_DF_ENV_IMAGE 678 * FIT_SUBTYPE_DF_ENV_IMAGE
678 * FIT_SUBTYPE_RAMDISK_IMAGE 679 * FIT_SUBTYPE_RAMDISK_IMAGE
679 * 680 *
680 * use Envvariables: 681 * use Envvariables:
681 * img_addr_r: image start addr 682 * img_addr_r: image start addr
682 * header_addr: addr where to write to UBL header 683 * header_addr: addr where to write to UBL header
683 * img_writeheader: write ubl header to nand 684 * img_writeheader: write ubl header to nand
684 * img_writespl: write spl to nand 685 * img_writespl: write spl to nand
685 * img_writeuboot: write uboot to nand 686 * img_writeuboot: write uboot to nand
686 * img_writedfenv: write default environment to ubi volume 687 * img_writedfenv: write default environment to ubi volume
687 * img_volume: which ubi volume should be updated with img_writeramdisk 688 * img_volume: which ubi volume should be updated with img_writeramdisk
688 * filesize: size of data for updating ubi volume 689 * filesize: size of data for updating ubi volume
689 * img_writeramdisk: write ramdisk to ubi volume 690 * img_writeramdisk: write ramdisk to ubi volume
690 */ 691 */
691 692
692 while (imgs[count].type != IH_TYPE_INVALID) { 693 while (imgs[count].type != IH_TYPE_INVALID) {
693 printf("Installing %s\n", 694 printf("Installing %s\n",
694 genimg_get_type_name(imgs[count].type)); 695 genimg_get_type_name(imgs[count].type));
695 sprintf(s, "%p", imgs[count].data); 696 sprintf(s, "%p", imgs[count].data);
696 setenv("img_addr_r", s); 697 setenv("img_addr_r", s);
697 sprintf(s, "%lx", (unsigned long)imgs[count].size); 698 sprintf(s, "%lx", (unsigned long)imgs[count].size);
698 setenv("filesize", s); 699 setenv("filesize", s);
699 switch (imgs[count].subtype) { 700 switch (imgs[count].subtype) {
700 case FIT_SUBTYPE_DF_ENV_IMAGE: 701 case FIT_SUBTYPE_DF_ENV_IMAGE:
701 ret = run_command("run img_writedfenv", 0); 702 ret = run_command("run img_writedfenv", 0);
702 break; 703 break;
703 case FIT_SUBTYPE_RAMDISK_IMAGE: 704 case FIT_SUBTYPE_RAMDISK_IMAGE:
704 t = getenv("img_volume"); 705 t = getenv("img_volume");
705 if (!t) { 706 if (!t) {
706 ret = setenv("img_volume", "rootfs1"); 707 ret = setenv("img_volume", "rootfs1");
707 } else { 708 } else {
708 /* switch to other volume */ 709 /* switch to other volume */
709 if (strncmp(t, "rootfs1", 7) == 0) 710 if (strncmp(t, "rootfs1", 7) == 0)
710 ret = setenv("img_volume", "rootfs2"); 711 ret = setenv("img_volume", "rootfs2");
711 else 712 else
712 ret = setenv("img_volume", "rootfs1"); 713 ret = setenv("img_volume", "rootfs1");
713 } 714 }
714 if (ret != 0) 715 if (ret != 0)
715 break; 716 break;
716 717
717 ret = run_command("run img_writeramdisk", 0); 718 ret = run_command("run img_writeramdisk", 0);
718 break; 719 break;
719 case FIT_SUBTYPE_SPL_IMAGE: 720 case FIT_SUBTYPE_SPL_IMAGE:
720 ret = run_command("run img_writespl", 0); 721 ret = run_command("run img_writespl", 0);
721 break; 722 break;
722 case FIT_SUBTYPE_UBL_HEADER: 723 case FIT_SUBTYPE_UBL_HEADER:
723 ret = ait_writeublheader(); 724 ret = ait_writeublheader();
724 break; 725 break;
725 case FIT_SUBTYPE_UBOOT_IMAGE: 726 case FIT_SUBTYPE_UBOOT_IMAGE:
726 ret = run_command("run img_writeuboot", 0); 727 ret = run_command("run img_writeuboot", 0);
727 break; 728 break;
728 default: 729 default:
729 /* not supported type */ 730 /* not supported type */
730 break; 731 break;
731 } 732 }
732 count++; 733 count++;
733 } 734 }
734 /* now save dvn_* and img_volume env vars to new values */ 735 /* now save dvn_* and img_volume env vars to new values */
735 if (ret == 0) { 736 if (ret == 0) {
736 t = getenv("x_dvn_boot_vers"); 737 t = getenv("x_dvn_boot_vers");
737 if (t) 738 if (t)
738 setenv("dvn_boot_vers", t); 739 setenv("dvn_boot_vers", t);
739 740
740 t = getenv("x_dvn_app_vers"); 741 t = getenv("x_dvn_app_vers");
741 if (t) 742 if (t)
742 setenv("dvn_boot_vers", t); 743 setenv("dvn_boot_vers", t);
743 744
744 setenv("x_dvn_boot_vers", NULL); 745 setenv("x_dvn_boot_vers", NULL);
745 setenv("x_dvn_app_vers", NULL); 746 setenv("x_dvn_app_vers", NULL);
746 ret = run_command("run savenewvers", 0); 747 ret = run_command("run savenewvers", 0);
747 } 748 }
748 749
749 return ret; 750 return ret;
750 } 751 }
751 752
752 static int ait_menu_evaluate_load(char *choice) 753 static int ait_menu_evaluate_load(char *choice)
753 { 754 {
754 if (!choice) 755 if (!choice)
755 return -1; 756 return -1;
756 757
757 switch (choice[1]) { 758 switch (choice[1]) {
758 case '1': 759 case '1':
759 /* install image */ 760 /* install image */
760 ait_menu_install_images(); 761 ait_menu_install_images();
761 break; 762 break;
762 case '2': 763 case '2':
763 /* cancel, back to main */ 764 /* cancel, back to main */
764 setenv("x_dvn_boot_vers", NULL); 765 setenv("x_dvn_boot_vers", NULL);
765 setenv("x_dvn_app_vers", NULL); 766 setenv("x_dvn_app_vers", NULL);
766 break; 767 break;
767 } 768 }
768 769
769 return MENU_MAIN; 770 return MENU_MAIN;
770 } 771 }
771 772
772 struct menu_display ait_load = { 773 struct menu_display ait_load = {
773 .title = "AIT load image", 774 .title = "AIT load image",
774 .timeout = 0, 775 .timeout = 0,
775 .id = MENU_LOAD, 776 .id = MENU_LOAD,
776 .menulist = menu_load, 777 .menulist = menu_load,
777 .menu_evaluate = ait_menu_evaluate_load, 778 .menu_evaluate = ait_menu_evaluate_load,
778 }; 779 };
779 780
780 static void ait_menu_read_env(char *name) 781 static void ait_menu_read_env(char *name)
781 { 782 {
782 char output[CONFIG_SYS_CBSIZE]; 783 char output[CONFIG_SYS_CBSIZE];
783 char cbuf[CONFIG_SYS_CBSIZE]; 784 char cbuf[CONFIG_SYS_CBSIZE];
784 int readret; 785 int readret;
785 int ret; 786 int ret;
786 787
787 sprintf(output, "%s old: %s value: ", name, getenv(name)); 788 sprintf(output, "%s old: %s value: ", name, getenv(name));
788 memset(cbuf, 0, CONFIG_SYS_CBSIZE); 789 memset(cbuf, 0, CONFIG_SYS_CBSIZE);
789 readret = readline_into_buffer(output, cbuf, 0); 790 readret = readline_into_buffer(output, cbuf, 0);
790 791
791 if (readret >= 0) { 792 if (readret >= 0) {
792 ret = setenv(name, cbuf); 793 ret = setenv(name, cbuf);
793 if (ret) { 794 if (ret) {
794 printf("Error setting %s\n", name); 795 printf("Error setting %s\n", name);
795 return; 796 return;
796 } 797 }
797 } 798 }
798 return; 799 return;
799 } 800 }
800 801
801 static int ait_menu_evaluate_network(char *choice) 802 static int ait_menu_evaluate_network(char *choice)
802 { 803 {
803 if (!choice) 804 if (!choice)
804 return MENU_MAIN; 805 return MENU_MAIN;
805 806
806 switch (choice[1]) { 807 switch (choice[1]) {
807 case '1': 808 case '1':
808 ait_menu_read_env("ipaddr"); 809 ait_menu_read_env("ipaddr");
809 break; 810 break;
810 case '2': 811 case '2':
811 ait_menu_read_env("netmask"); 812 ait_menu_read_env("netmask");
812 break; 813 break;
813 case '3': 814 case '3':
814 ait_menu_read_env("serverip"); 815 ait_menu_read_env("serverip");
815 break; 816 break;
816 case '4': 817 case '4':
817 ait_menu_read_env("gatewayip"); 818 ait_menu_read_env("gatewayip");
818 break; 819 break;
819 case '5': 820 case '5':
820 ait_menu_read_env("img_file"); 821 ait_menu_read_env("img_file");
821 break; 822 break;
822 case '6': 823 case '6':
823 return MENU_UPDATE; 824 return MENU_UPDATE;
824 break; 825 break;
825 } 826 }
826 827
827 return MENU_STAY; 828 return MENU_STAY;
828 } 829 }
829 830
830 struct menu_display ait_network = { 831 struct menu_display ait_network = {
831 .title = "AIT network settings", 832 .title = "AIT network settings",
832 .timeout = 0, 833 .timeout = 0,
833 .id = MENU_NETWORK, 834 .id = MENU_NETWORK,
834 .menulist = menu_network, 835 .menulist = menu_network,
835 .menu_evaluate = ait_menu_evaluate_network, 836 .menu_evaluate = ait_menu_evaluate_network,
836 }; 837 };
837 838
838 static int fit_get_subtype(const void *fit, int noffset, char **subtype) 839 static int fit_get_subtype(const void *fit, int noffset, char **subtype)
839 { 840 {
840 int len; 841 int len;
841 842
842 *subtype = (char *)fdt_getprop(fit, noffset, "subtype", &len); 843 *subtype = (char *)fdt_getprop(fit, noffset, "subtype", &len);
843 if (*subtype == NULL) 844 if (*subtype == NULL)
844 return -1; 845 return -1;
845 846
846 return 0; 847 return 0;
847 } 848 }
848 849
849 static int ait_subtype_nr(char *subtype) 850 static int ait_subtype_nr(char *subtype)
850 { 851 {
851 int ret = FIT_SUBTYPE_UNKNOWN; 852 int ret = FIT_SUBTYPE_UNKNOWN;
852 853
853 if (!strncmp("ublheader", subtype, strlen("ublheader"))) 854 if (!strncmp("ublheader", subtype, strlen("ublheader")))
854 return FIT_SUBTYPE_UBL_HEADER; 855 return FIT_SUBTYPE_UBL_HEADER;
855 if (!strncmp("splimage", subtype, strlen("splimage"))) 856 if (!strncmp("splimage", subtype, strlen("splimage")))
856 return FIT_SUBTYPE_SPL_IMAGE; 857 return FIT_SUBTYPE_SPL_IMAGE;
857 if (!strncmp("ubootimage", subtype, strlen("ubootimage"))) 858 if (!strncmp("ubootimage", subtype, strlen("ubootimage")))
858 return FIT_SUBTYPE_UBOOT_IMAGE; 859 return FIT_SUBTYPE_UBOOT_IMAGE;
859 if (!strncmp("dfenvimage", subtype, strlen("dfenvimage"))) 860 if (!strncmp("dfenvimage", subtype, strlen("dfenvimage")))
860 return FIT_SUBTYPE_DF_ENV_IMAGE; 861 return FIT_SUBTYPE_DF_ENV_IMAGE;
861 862
862 return ret; 863 return ret;
863 } 864 }
864 865
865 static int ait_menu_check_image(void) 866 static int ait_menu_check_image(void)
866 { 867 {
867 char *s; 868 char *s;
868 unsigned long fit_addr; 869 unsigned long fit_addr;
869 void *addr; 870 void *addr;
870 int format; 871 int format;
871 char *desc; 872 char *desc;
872 char *subtype; 873 char *subtype;
873 int images_noffset; 874 int images_noffset;
874 int noffset; 875 int noffset;
875 int ndepth; 876 int ndepth;
876 int count = 0; 877 int count = 0;
877 int ret; 878 int ret;
878 int i; 879 int i;
879 int found_uboot = -1; 880 int found_uboot = -1;
880 int found_ramdisk = -1; 881 int found_ramdisk = -1;
881 882
882 memset(imgs, 0, sizeof(imgs)); 883 memset(imgs, 0, sizeof(imgs));
883 s = getenv("fit_addr_r"); 884 s = getenv("fit_addr_r");
884 fit_addr = s ? (unsigned long)simple_strtol(s, NULL, 16) : \ 885 fit_addr = s ? (unsigned long)simple_strtol(s, NULL, 16) : \
885 CONFIG_BOARD_IMG_ADDR_R; 886 CONFIG_BOARD_IMG_ADDR_R;
886 887
887 addr = (void *)fit_addr; 888 addr = (void *)fit_addr;
888 /* check if it is a FIT image */ 889 /* check if it is a FIT image */
889 format = genimg_get_format(addr); 890 format = genimg_get_format(addr);
890 if (format != IMAGE_FORMAT_FIT) 891 if (format != IMAGE_FORMAT_FIT)
891 return -EINVAL; 892 return -EINVAL;
892 893
893 if (!fit_check_format(addr)) 894 if (!fit_check_format(addr))
894 return -EINVAL; 895 return -EINVAL;
895 896
896 /* print the FIT description */ 897 /* print the FIT description */
897 ret = fit_get_desc(addr, 0, &desc); 898 ret = fit_get_desc(addr, 0, &desc);
898 printf("FIT description: "); 899 printf("FIT description: ");
899 if (ret) 900 if (ret)
900 printf("unavailable\n"); 901 printf("unavailable\n");
901 else 902 else
902 printf("%s\n", desc); 903 printf("%s\n", desc);
903 904
904 /* find images */ 905 /* find images */
905 images_noffset = fdt_path_offset(addr, FIT_IMAGES_PATH); 906 images_noffset = fdt_path_offset(addr, FIT_IMAGES_PATH);
906 if (images_noffset < 0) { 907 if (images_noffset < 0) {
907 printf("Can't find images parent node '%s' (%s)\n", 908 printf("Can't find images parent node '%s' (%s)\n",
908 FIT_IMAGES_PATH, fdt_strerror(images_noffset)); 909 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
909 return -EINVAL; 910 return -EINVAL;
910 } 911 }
911 912
912 /* Process its subnodes, print out component images details */ 913 /* Process its subnodes, print out component images details */
913 for (ndepth = 0, count = 0, 914 for (ndepth = 0, count = 0,
914 noffset = fdt_next_node(addr, images_noffset, &ndepth); 915 noffset = fdt_next_node(addr, images_noffset, &ndepth);
915 (noffset >= 0) && (ndepth > 0); 916 (noffset >= 0) && (ndepth > 0);
916 noffset = fdt_next_node(addr, noffset, &ndepth)) { 917 noffset = fdt_next_node(addr, noffset, &ndepth)) {
917 if (ndepth == 1) { 918 if (ndepth == 1) {
918 /* 919 /*
919 * Direct child node of the images parent node, 920 * Direct child node of the images parent node,
920 * i.e. component image node. 921 * i.e. component image node.
921 */ 922 */
922 printf("Image %u (%s)\n", count, 923 printf("Image %u (%s)\n", count,
923 fit_get_name(addr, noffset, NULL)); 924 fit_get_name(addr, noffset, NULL));
924 925
925 fit_image_print(addr, noffset, ""); 926 fit_image_print(addr, noffset, "");
926 927
927 fit_image_get_type(addr, noffset, 928 fit_image_get_type(addr, noffset,
928 &imgs[count].type); 929 &imgs[count].type);
929 /* Mandatory properties */ 930 /* Mandatory properties */
930 ret = fit_get_desc(addr, noffset, &desc); 931 ret = fit_get_desc(addr, noffset, &desc);
931 printf("Description: "); 932 printf("Description: ");
932 if (ret) 933 if (ret)
933 printf("unavailable\n"); 934 printf("unavailable\n");
934 else 935 else
935 printf("%s\n", desc); 936 printf("%s\n", desc);
936 937
937 ret = fit_get_subtype(addr, noffset, &subtype); 938 ret = fit_get_subtype(addr, noffset, &subtype);
938 printf("Subtype: "); 939 printf("Subtype: ");
939 if (ret) { 940 if (ret) {
940 printf("unavailable\n"); 941 printf("unavailable\n");
941 } else { 942 } else {
942 imgs[count].subtype = ait_subtype_nr(subtype); 943 imgs[count].subtype = ait_subtype_nr(subtype);
943 printf("%s %d\n", subtype, 944 printf("%s %d\n", subtype,
944 imgs[count].subtype); 945 imgs[count].subtype);
945 } 946 }
946 947
947 sprintf(imgs[count].desc, "%s", desc); 948 sprintf(imgs[count].desc, "%s", desc);
948 949
949 ret = fit_image_get_data(addr, noffset, 950 ret = fit_image_get_data(addr, noffset,
950 &imgs[count].data, 951 &imgs[count].data,
951 &imgs[count].size); 952 &imgs[count].size);
952 953
953 printf("Data Size: "); 954 printf("Data Size: ");
954 if (ret) 955 if (ret)
955 printf("unavailable\n"); 956 printf("unavailable\n");
956 else 957 else
957 genimg_print_size(imgs[count].size); 958 genimg_print_size(imgs[count].size);
958 printf("Data @ %p\n", imgs[count].data); 959 printf("Data @ %p\n", imgs[count].data);
959 count++; 960 count++;
960 } 961 }
961 } 962 }
962 963
963 for (i = 0; i < count; i++) { 964 for (i = 0; i < count; i++) {
964 if (imgs[i].subtype == FIT_SUBTYPE_UBOOT_IMAGE) 965 if (imgs[i].subtype == FIT_SUBTYPE_UBOOT_IMAGE)
965 found_uboot = i; 966 found_uboot = i;
966 if (imgs[i].type == IH_TYPE_RAMDISK) { 967 if (imgs[i].type == IH_TYPE_RAMDISK) {
967 found_ramdisk = i; 968 found_ramdisk = i;
968 imgs[i].subtype = FIT_SUBTYPE_RAMDISK_IMAGE; 969 imgs[i].subtype = FIT_SUBTYPE_RAMDISK_IMAGE;
969 } 970 }
970 } 971 }
971 972
972 /* dvn_* env var update, if the FIT descriptors are different */ 973 /* dvn_* env var update, if the FIT descriptors are different */
973 if (found_uboot >= 0) { 974 if (found_uboot >= 0) {
974 s = getenv("dvn_boot_vers"); 975 s = getenv("dvn_boot_vers");
975 if (s) { 976 if (s) {
976 ret = strcmp(s, imgs[found_uboot].desc); 977 ret = strcmp(s, imgs[found_uboot].desc);
977 if (ret != 0) { 978 if (ret != 0) {
978 setenv("x_dvn_boot_vers", 979 setenv("x_dvn_boot_vers",
979 imgs[found_uboot].desc); 980 imgs[found_uboot].desc);
980 } else { 981 } else {
981 found_uboot = -1; 982 found_uboot = -1;
982 printf("no new uboot version\n"); 983 printf("no new uboot version\n");
983 } 984 }
984 } else { 985 } else {
985 setenv("dvn_boot_vers", imgs[found_uboot].desc); 986 setenv("dvn_boot_vers", imgs[found_uboot].desc);
986 } 987 }
987 } 988 }
988 if (found_ramdisk >= 0) { 989 if (found_ramdisk >= 0) {
989 s = getenv("dvn_app_vers"); 990 s = getenv("dvn_app_vers");
990 if (s) { 991 if (s) {
991 ret = strcmp(s, imgs[found_ramdisk].desc); 992 ret = strcmp(s, imgs[found_ramdisk].desc);
992 if (ret != 0) { 993 if (ret != 0) {
993 setenv("x_dvn_app_vers", 994 setenv("x_dvn_app_vers",
994 imgs[found_ramdisk].desc); 995 imgs[found_ramdisk].desc);
995 } else { 996 } else {
996 found_ramdisk = -1; 997 found_ramdisk = -1;
997 printf("no new ramdisk version\n"); 998 printf("no new ramdisk version\n");
998 } 999 }
999 } else { 1000 } else {
1000 setenv("dvn_app_vers", imgs[found_ramdisk].desc); 1001 setenv("dvn_app_vers", imgs[found_ramdisk].desc);
1001 } 1002 }
1002 } 1003 }
1003 if ((found_uboot == -1) && (found_ramdisk == -1)) 1004 if ((found_uboot == -1) && (found_ramdisk == -1))
1004 return -EINVAL; 1005 return -EINVAL;
1005 1006
1006 return 0; 1007 return 0;
1007 } 1008 }
1008 1009
1009 static int ait_menu_evaluate_update(char *choice) 1010 static int ait_menu_evaluate_update(char *choice)
1010 { 1011 {
1011 int ret; 1012 int ret;
1012 1013
1013 if (!choice) 1014 if (!choice)
1014 return MENU_MAIN; 1015 return MENU_MAIN;
1015 1016
1016 switch (choice[1]) { 1017 switch (choice[1]) {
1017 case '1': 1018 case '1':
1018 return ait_menu_show(&ait_network, 0); 1019 return ait_menu_show(&ait_network, 0);
1019 break; 1020 break;
1020 case '2': 1021 case '2':
1021 /* load image */ 1022 /* load image */
1022 ret = run_command("run load_img", 0); 1023 ret = run_command("run load_img", 0);
1023 printf("ret: %d\n", ret); 1024 printf("ret: %d\n", ret);
1024 if (ret) 1025 if (ret)
1025 return MENU_UPDATE; 1026 return MENU_UPDATE;
1026 1027
1027 ret = ait_menu_check_image(); 1028 ret = ait_menu_check_image();
1028 if (ret) 1029 if (ret)
1029 return MENU_UPDATE; 1030 return MENU_UPDATE;
1030 1031
1031 return ait_menu_show(&ait_load, 0); 1032 return ait_menu_show(&ait_load, 0);
1032 break; 1033 break;
1033 case '3': 1034 case '3':
1034 return MENU_MAIN; 1035 return MENU_MAIN;
1035 break; 1036 break;
1036 1037
1037 } 1038 }
1038 1039
1039 return MENU_MAIN; 1040 return MENU_MAIN;
1040 } 1041 }
1041 1042
1042 struct menu_display ait_update = { 1043 struct menu_display ait_update = {
1043 .title = "AIT Update Software", 1044 .title = "AIT Update Software",
1044 .timeout = 0, 1045 .timeout = 0,
1045 .id = MENU_UPDATE, 1046 .id = MENU_UPDATE,
1046 .menulist = menu_update, 1047 .menulist = menu_update,
1047 .menu_evaluate = ait_menu_evaluate_update, 1048 .menu_evaluate = ait_menu_evaluate_update,
1048 }; 1049 };
1049 1050
1050 static int ait_menu_evaluate_main(char *choice) 1051 static int ait_menu_evaluate_main(char *choice)
1051 { 1052 {
1052 if (!choice) 1053 if (!choice)
1053 return MENU_STAY; 1054 return MENU_STAY;
1054 1055
1055 menu_start = 1; 1056 menu_start = 1;
1056 switch (choice[1]) { 1057 switch (choice[1]) {
1057 case '1': 1058 case '1':
1058 /* run bootcmd */ 1059 /* run bootcmd */
1059 return MENU_EXIT_BOOTCMD; 1060 return MENU_EXIT_BOOTCMD;
1060 break; 1061 break;
1061 case '2': 1062 case '2':
1062 return ait_menu_show(&ait_update, 0); 1063 return ait_menu_show(&ait_update, 0);
1063 break; 1064 break;
1064 case '3': 1065 case '3':
1065 /* reset to default settings */ 1066 /* reset to default settings */
1066 setenv("app_reset", "yes"); 1067 setenv("app_reset", "yes");
1067 return MENU_EXIT_BOOTCMD; 1068 return MENU_EXIT_BOOTCMD;
1068 break; 1069 break;
1069 case '4': 1070 case '4':
1070 /* u-boot shell */ 1071 /* u-boot shell */
1071 return MENU_EXIT; 1072 return MENU_EXIT;
1072 break; 1073 break;
1073 } 1074 }
1074 1075
1075 return MENU_EXIT; 1076 return MENU_EXIT;
1076 } 1077 }
1077 1078
1078 struct menu_display ait_main = { 1079 struct menu_display ait_main = {
1079 .title = "AIT Main", 1080 .title = "AIT Main",
1080 .timeout = CONFIG_BOOTDELAY, 1081 .timeout = CONFIG_BOOTDELAY,
1081 .id = MENU_MAIN, 1082 .id = MENU_MAIN,
1082 .menulist = menu_main, 1083 .menulist = menu_main,
1083 .menu_evaluate = ait_menu_evaluate_main, 1084 .menu_evaluate = ait_menu_evaluate_main,
1084 }; 1085 };
1085 1086
1086 int menu_show(int bootdelay) 1087 int menu_show(int bootdelay)
1087 { 1088 {
1088 int ret; 1089 int ret;
1089 1090
1090 run_command("run saveparms", 0); 1091 run_command("run saveparms", 0);
1091 ret = ait_menu_show(&ait_main, bootdelay); 1092 ret = ait_menu_show(&ait_main, bootdelay);
1092 run_command("run restoreparms", 0); 1093 run_command("run restoreparms", 0);
1093 1094
1094 if (ret == MENU_EXIT_BOOTCMD) 1095 if (ret == MENU_EXIT_BOOTCMD)
1095 return 0; 1096 return 0;
1096 1097
1097 return MENU_EXIT; 1098 return MENU_EXIT;
1098 } 1099 }
1099 1100
1100 void menu_display_statusline(struct menu *m) 1101 void menu_display_statusline(struct menu *m)
1101 { 1102 {
1102 char *s1, *s2; 1103 char *s1, *s2;
1103 1104
1104 s1 = getenv("x_dvn_boot_vers"); 1105 s1 = getenv("x_dvn_boot_vers");
1105 if (!s1) 1106 if (!s1)
1106 s1 = getenv("dvn_boot_vers"); 1107 s1 = getenv("dvn_boot_vers");
1107 1108
1108 s2 = getenv("x_dvn_app_vers"); 1109 s2 = getenv("x_dvn_app_vers");
1109 if (!s2) 1110 if (!s2)
1110 s2 = getenv("dvn_app_vers"); 1111 s2 = getenv("dvn_app_vers");
1111 1112
1112 printf("State: dvn_boot_vers: %s dvn_app_vers: %s\n", s1, s2); 1113 printf("State: dvn_boot_vers: %s dvn_app_vers: %s\n", s1, s2);
1113 return; 1114 return;
1114 } 1115 }
1115 #endif 1116 #endif
1116 1117
1 # 1 #
2 # (C) Copyright 2004-2006 2 # (C) Copyright 2004-2006
3 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. 3 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 # 4 #
5 # See file CREDITS for list of people who contributed to this 5 # See file CREDITS for list of people who contributed to this
6 # project. 6 # project.
7 # 7 #
8 # This program is free software; you can redistribute it and/or 8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License as 9 # modify it under the terms of the GNU General Public License as
10 # published by the Free Software Foundation; either version 2 of 10 # published by the Free Software Foundation; either version 2 of
11 # the License, or (at your option) any later version. 11 # the License, or (at your option) any later version.
12 # 12 #
13 # This program is distributed in the hope that it will be useful, 13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details. 16 # GNU General Public License for more details.
17 # 17 #
18 # You should have received a copy of the GNU General Public License 18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software 19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 # MA 02111-1307 USA 21 # MA 02111-1307 USA
22 # 22 #
23 23
24 include $(TOPDIR)/config.mk 24 include $(TOPDIR)/config.mk
25 25
26 LIB = $(obj)libcommon.o 26 LIB = $(obj)libcommon.o
27 27
28 # core 28 # core
29 ifndef CONFIG_SPL_BUILD 29 ifndef CONFIG_SPL_BUILD
30 COBJS-y += main.o 30 COBJS-y += main.o
31 COBJS-y += command.o 31 COBJS-y += command.o
32 COBJS-y += exports.o 32 COBJS-y += exports.o
33 COBJS-y += hash.o 33 COBJS-y += hash.o
34 COBJS-$(CONFIG_SYS_HUSH_PARSER) += hush.o 34 COBJS-$(CONFIG_SYS_HUSH_PARSER) += hush.o
35 COBJS-y += s_record.o 35 COBJS-y += s_record.o
36 COBJS-y += xyzModem.o 36 COBJS-y += xyzModem.o
37 COBJS-y += cmd_disk.o 37 COBJS-y += cmd_disk.o
38 38
39 # boards 39 # boards
40 COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o 40 COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o
41 COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o 41 COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o
42 42
43 # core command 43 # core command
44 COBJS-y += cmd_boot.o 44 COBJS-y += cmd_boot.o
45 COBJS-$(CONFIG_CMD_BOOTM) += cmd_bootm.o 45 COBJS-$(CONFIG_CMD_BOOTM) += cmd_bootm.o
46 COBJS-y += cmd_help.o 46 COBJS-y += cmd_help.o
47 COBJS-y += cmd_nvedit.o 47 COBJS-y += cmd_nvedit.o
48 COBJS-y += cmd_version.o 48 COBJS-y += cmd_version.o
49 49
50 # environment 50 # environment
51 COBJS-y += env_attr.o 51 COBJS-y += env_attr.o
52 COBJS-y += env_callback.o 52 COBJS-y += env_callback.o
53 COBJS-y += env_common.o 53 COBJS-y += env_common.o
54 COBJS-y += env_flags.o 54 COBJS-y += env_flags.o
55 COBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o 55 COBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o
56 COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_eeprom.o 56 COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_eeprom.o
57 XCOBJS-$(CONFIG_ENV_IS_EMBEDDED) += env_embedded.o 57 XCOBJS-$(CONFIG_ENV_IS_EMBEDDED) += env_embedded.o
58 COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_embedded.o 58 COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_embedded.o
59 XCOBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_embedded.o 59 XCOBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_embedded.o
60 COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o 60 COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o
61 COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o 61 COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
62 COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o 62 COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o
63 COBJS-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o 63 COBJS-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o
64 COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o 64 COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
65 COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o 65 COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o
66 COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o 66 COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o
67 COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o 67 COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
68 COBJS-$(CONFIG_ENV_IS_IN_REMOTE) += env_remote.o 68 COBJS-$(CONFIG_ENV_IS_IN_REMOTE) += env_remote.o
69 COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o 69 COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
70 70
71 # command 71 # command
72 COBJS-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.o 72 COBJS-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.o
73 COBJS-$(CONFIG_SOURCE) += cmd_source.o 73 COBJS-$(CONFIG_SOURCE) += cmd_source.o
74 COBJS-$(CONFIG_CMD_SOURCE) += cmd_source.o 74 COBJS-$(CONFIG_CMD_SOURCE) += cmd_source.o
75 COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o 75 COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
76 COBJS-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o 76 COBJS-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
77 COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o 77 COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
78 COBJS-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
78 COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o 79 COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
79 COBJS-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o 80 COBJS-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o
80 COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o 81 COBJS-$(CONFIG_CMD_CACHE) += cmd_cache.o
81 COBJS-$(CONFIG_CMD_CBFS) += cmd_cbfs.o 82 COBJS-$(CONFIG_CMD_CBFS) += cmd_cbfs.o
82 COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o 83 COBJS-$(CONFIG_CMD_CONSOLE) += cmd_console.o
83 COBJS-$(CONFIG_CMD_CPLBINFO) += cmd_cplbinfo.o 84 COBJS-$(CONFIG_CMD_CPLBINFO) += cmd_cplbinfo.o
84 COBJS-$(CONFIG_DATAFLASH_MMC_SELECT) += cmd_dataflash_mmc_mux.o 85 COBJS-$(CONFIG_DATAFLASH_MMC_SELECT) += cmd_dataflash_mmc_mux.o
85 COBJS-$(CONFIG_CMD_DATE) += cmd_date.o 86 COBJS-$(CONFIG_CMD_DATE) += cmd_date.o
86 COBJS-$(CONFIG_CMD_SOUND) += cmd_sound.o 87 COBJS-$(CONFIG_CMD_SOUND) += cmd_sound.o
87 ifdef CONFIG_4xx 88 ifdef CONFIG_4xx
88 COBJS-$(CONFIG_CMD_SETGETDCR) += cmd_dcr.o 89 COBJS-$(CONFIG_CMD_SETGETDCR) += cmd_dcr.o
89 endif 90 endif
90 ifdef CONFIG_POST 91 ifdef CONFIG_POST
91 COBJS-$(CONFIG_CMD_DIAG) += cmd_diag.o 92 COBJS-$(CONFIG_CMD_DIAG) += cmd_diag.o
92 endif 93 endif
93 COBJS-$(CONFIG_CMD_DISPLAY) += cmd_display.o 94 COBJS-$(CONFIG_CMD_DISPLAY) += cmd_display.o
94 COBJS-$(CONFIG_CMD_DTT) += cmd_dtt.o 95 COBJS-$(CONFIG_CMD_DTT) += cmd_dtt.o
95 COBJS-$(CONFIG_CMD_ECHO) += cmd_echo.o 96 COBJS-$(CONFIG_CMD_ECHO) += cmd_echo.o
96 COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o 97 COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o
97 COBJS-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o 98 COBJS-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o
98 COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o 99 COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o
99 COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o 100 COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o
100 COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o 101 COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o
101 COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o 102 COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o
102 COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o 103 COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o
103 COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o 104 COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o
104 COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o 105 COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o
105 COBJS-$(CONFIG_CMD_FDOS) += cmd_fdos.o 106 COBJS-$(CONFIG_CMD_FDOS) += cmd_fdos.o
106 COBJS-$(CONFIG_CMD_FITUPD) += cmd_fitupd.o 107 COBJS-$(CONFIG_CMD_FITUPD) += cmd_fitupd.o
107 COBJS-$(CONFIG_CMD_FLASH) += cmd_flash.o 108 COBJS-$(CONFIG_CMD_FLASH) += cmd_flash.o
108 ifdef CONFIG_FPGA 109 ifdef CONFIG_FPGA
109 COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o 110 COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o
110 endif 111 endif
111 COBJS-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o 112 COBJS-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o
112 COBJS-$(CONFIG_CMD_GETTIME) += cmd_gettime.o 113 COBJS-$(CONFIG_CMD_GETTIME) += cmd_gettime.o
113 COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o 114 COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o
114 COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o 115 COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o
115 COBJS-$(CONFIG_CMD_HASH) += cmd_hash.o 116 COBJS-$(CONFIG_CMD_HASH) += cmd_hash.o
116 COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o 117 COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o
117 COBJS-$(CONFIG_CMD_IMMAP) += cmd_immap.o 118 COBJS-$(CONFIG_CMD_IMMAP) += cmd_immap.o
118 COBJS-$(CONFIG_CMD_INI) += cmd_ini.o 119 COBJS-$(CONFIG_CMD_INI) += cmd_ini.o
119 COBJS-$(CONFIG_CMD_IRQ) += cmd_irq.o 120 COBJS-$(CONFIG_CMD_IRQ) += cmd_irq.o
120 COBJS-$(CONFIG_CMD_ITEST) += cmd_itest.o 121 COBJS-$(CONFIG_CMD_ITEST) += cmd_itest.o
121 COBJS-$(CONFIG_CMD_JFFS2) += cmd_jffs2.o 122 COBJS-$(CONFIG_CMD_JFFS2) += cmd_jffs2.o
122 COBJS-$(CONFIG_CMD_CRAMFS) += cmd_cramfs.o 123 COBJS-$(CONFIG_CMD_CRAMFS) += cmd_cramfs.o
123 COBJS-$(CONFIG_CMD_LDRINFO) += cmd_ldrinfo.o 124 COBJS-$(CONFIG_CMD_LDRINFO) += cmd_ldrinfo.o
124 COBJS-$(CONFIG_CMD_LED) += cmd_led.o 125 COBJS-$(CONFIG_CMD_LED) += cmd_led.o
125 COBJS-$(CONFIG_CMD_LICENSE) += cmd_license.o 126 COBJS-$(CONFIG_CMD_LICENSE) += cmd_license.o
126 COBJS-y += cmd_load.o 127 COBJS-y += cmd_load.o
127 COBJS-$(CONFIG_LOGBUFFER) += cmd_log.o 128 COBJS-$(CONFIG_LOGBUFFER) += cmd_log.o
128 COBJS-$(CONFIG_ID_EEPROM) += cmd_mac.o 129 COBJS-$(CONFIG_ID_EEPROM) += cmd_mac.o
129 COBJS-$(CONFIG_CMD_MD5SUM) += cmd_md5sum.o 130 COBJS-$(CONFIG_CMD_MD5SUM) += cmd_md5sum.o
130 COBJS-$(CONFIG_CMD_MEMORY) += cmd_mem.o 131 COBJS-$(CONFIG_CMD_MEMORY) += cmd_mem.o
131 COBJS-$(CONFIG_CMD_IO) += cmd_io.o 132 COBJS-$(CONFIG_CMD_IO) += cmd_io.o
132 COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o 133 COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
133 COBJS-$(CONFIG_MII) += miiphyutil.o 134 COBJS-$(CONFIG_MII) += miiphyutil.o
134 COBJS-$(CONFIG_CMD_MII) += miiphyutil.o 135 COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
135 COBJS-$(CONFIG_PHYLIB) += miiphyutil.o 136 COBJS-$(CONFIG_PHYLIB) += miiphyutil.o
136 COBJS-$(CONFIG_CMD_MII) += cmd_mii.o 137 COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
137 ifdef CONFIG_PHYLIB 138 ifdef CONFIG_PHYLIB
138 COBJS-$(CONFIG_CMD_MII) += cmd_mdio.o 139 COBJS-$(CONFIG_CMD_MII) += cmd_mdio.o
139 endif 140 endif
140 COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o 141 COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
141 COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o 142 COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
142 COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o 143 COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
143 COBJS-$(CONFIG_MP) += cmd_mp.o 144 COBJS-$(CONFIG_MP) += cmd_mp.o
144 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o 145 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
145 COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o 146 COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o
146 COBJS-$(CONFIG_CMD_NET) += cmd_net.o 147 COBJS-$(CONFIG_CMD_NET) += cmd_net.o
147 COBJS-$(CONFIG_CMD_ONENAND) += cmd_onenand.o 148 COBJS-$(CONFIG_CMD_ONENAND) += cmd_onenand.o
148 COBJS-$(CONFIG_CMD_OTP) += cmd_otp.o 149 COBJS-$(CONFIG_CMD_OTP) += cmd_otp.o
149 COBJS-$(CONFIG_CMD_PART) += cmd_part.o 150 COBJS-$(CONFIG_CMD_PART) += cmd_part.o
150 ifdef CONFIG_PCI 151 ifdef CONFIG_PCI
151 COBJS-$(CONFIG_CMD_PCI) += cmd_pci.o 152 COBJS-$(CONFIG_CMD_PCI) += cmd_pci.o
152 endif 153 endif
153 COBJS-y += cmd_pcmcia.o 154 COBJS-y += cmd_pcmcia.o
154 COBJS-$(CONFIG_CMD_PORTIO) += cmd_portio.o 155 COBJS-$(CONFIG_CMD_PORTIO) += cmd_portio.o
155 COBJS-$(CONFIG_CMD_PXE) += cmd_pxe.o 156 COBJS-$(CONFIG_CMD_PXE) += cmd_pxe.o
156 COBJS-$(CONFIG_CMD_READ) += cmd_read.o 157 COBJS-$(CONFIG_CMD_READ) += cmd_read.o
157 COBJS-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o 158 COBJS-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o
158 COBJS-$(CONFIG_CMD_REISER) += cmd_reiser.o 159 COBJS-$(CONFIG_CMD_REISER) += cmd_reiser.o
159 COBJS-$(CONFIG_SANDBOX) += cmd_sandbox.o 160 COBJS-$(CONFIG_SANDBOX) += cmd_sandbox.o
160 COBJS-$(CONFIG_CMD_SATA) += cmd_sata.o 161 COBJS-$(CONFIG_CMD_SATA) += cmd_sata.o
161 COBJS-$(CONFIG_CMD_SF) += cmd_sf.o 162 COBJS-$(CONFIG_CMD_SF) += cmd_sf.o
162 COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o 163 COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o
163 COBJS-$(CONFIG_CMD_SHA1SUM) += cmd_sha1sum.o 164 COBJS-$(CONFIG_CMD_SHA1SUM) += cmd_sha1sum.o
164 COBJS-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o 165 COBJS-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o
165 COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o 166 COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o
166 COBJS-$(CONFIG_CMD_SPIBOOTLDR) += cmd_spibootldr.o 167 COBJS-$(CONFIG_CMD_SPIBOOTLDR) += cmd_spibootldr.o
167 COBJS-$(CONFIG_CMD_STRINGS) += cmd_strings.o 168 COBJS-$(CONFIG_CMD_STRINGS) += cmd_strings.o
168 COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o 169 COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o
169 COBJS-$(CONFIG_CMD_TIME) += cmd_time.o 170 COBJS-$(CONFIG_CMD_TIME) += cmd_time.o
170 COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_test.o 171 COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_test.o
171 COBJS-$(CONFIG_CMD_TPM) += cmd_tpm.o 172 COBJS-$(CONFIG_CMD_TPM) += cmd_tpm.o
172 COBJS-$(CONFIG_CMD_TSI148) += cmd_tsi148.o 173 COBJS-$(CONFIG_CMD_TSI148) += cmd_tsi148.o
173 COBJS-$(CONFIG_CMD_UBI) += cmd_ubi.o 174 COBJS-$(CONFIG_CMD_UBI) += cmd_ubi.o
174 COBJS-$(CONFIG_CMD_UBIFS) += cmd_ubifs.o 175 COBJS-$(CONFIG_CMD_UBIFS) += cmd_ubifs.o
175 COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o 176 COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o
176 COBJS-$(CONFIG_CMD_UNZIP) += cmd_unzip.o 177 COBJS-$(CONFIG_CMD_UNZIP) += cmd_unzip.o
177 ifdef CONFIG_CMD_USB 178 ifdef CONFIG_CMD_USB
178 COBJS-y += cmd_usb.o 179 COBJS-y += cmd_usb.o
179 COBJS-y += usb.o usb_hub.o 180 COBJS-y += usb.o usb_hub.o
180 COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o 181 COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o
181 endif 182 endif
182 COBJS-$(CONFIG_CMD_USB_MASS_STORAGE) += cmd_usb_mass_storage.o 183 COBJS-$(CONFIG_CMD_USB_MASS_STORAGE) += cmd_usb_mass_storage.o
183 COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o 184 COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
184 COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o 185 COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
185 COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o 186 COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
186 COBJS-$(CONFIG_CMD_ZIP) += cmd_zip.o 187 COBJS-$(CONFIG_CMD_ZIP) += cmd_zip.o
187 COBJS-$(CONFIG_CMD_ZFS) += cmd_zfs.o 188 COBJS-$(CONFIG_CMD_ZFS) += cmd_zfs.o
188 189
189 # others 190 # others
190 ifdef CONFIG_DDR_SPD 191 ifdef CONFIG_DDR_SPD
191 SPD := y 192 SPD := y
192 endif 193 endif
193 ifdef CONFIG_SPD_EEPROM 194 ifdef CONFIG_SPD_EEPROM
194 SPD := y 195 SPD := y
195 endif 196 endif
196 COBJS-$(SPD) += ddr_spd.o 197 COBJS-$(SPD) += ddr_spd.o
197 COBJS-$(CONFIG_HWCONFIG) += hwconfig.o 198 COBJS-$(CONFIG_HWCONFIG) += hwconfig.o
198 COBJS-$(CONFIG_BOOTSTAGE) += bootstage.o 199 COBJS-$(CONFIG_BOOTSTAGE) += bootstage.o
199 COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o 200 COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o
200 COBJS-y += flash.o 201 COBJS-y += flash.o
201 COBJS-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o 202 COBJS-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o
202 COBJS-$(CONFIG_I2C_EDID) += edid.o 203 COBJS-$(CONFIG_I2C_EDID) += edid.o
203 COBJS-$(CONFIG_KALLSYMS) += kallsyms.o 204 COBJS-$(CONFIG_KALLSYMS) += kallsyms.o
204 COBJS-$(CONFIG_LCD) += lcd.o 205 COBJS-$(CONFIG_LCD) += lcd.o
205 COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o 206 COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
206 COBJS-$(CONFIG_MENU) += menu.o 207 COBJS-$(CONFIG_MENU) += menu.o
207 COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o 208 COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
208 COBJS-$(CONFIG_UPDATE_TFTP) += update.o 209 COBJS-$(CONFIG_UPDATE_TFTP) += update.o
209 COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o 210 COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
210 COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o 211 COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o
211 COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o 212 COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o
212 endif 213 endif
213 214
214 ifdef CONFIG_SPL_BUILD 215 ifdef CONFIG_SPL_BUILD
215 COBJS-y += cmd_nvedit.o 216 COBJS-y += cmd_nvedit.o
216 COBJS-y += env_common.o 217 COBJS-y += env_common.o
217 COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o 218 COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
218 COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o 219 COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
219 COBJS-$(CONFIG_SPL_NET_SUPPORT) += cmd_nvedit.o 220 COBJS-$(CONFIG_SPL_NET_SUPPORT) += cmd_nvedit.o
220 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_attr.o 221 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_attr.o
221 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_callback.o 222 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_callback.o
222 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_common.o 223 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_common.o
223 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_flags.o 224 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_flags.o
224 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_nowhere.o 225 COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_nowhere.o
225 COBJS-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o 226 COBJS-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o
226 endif 227 endif
227 COBJS-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o 228 COBJS-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o
228 COBJS-y += console.o 229 COBJS-y += console.o
229 COBJS-y += dlmalloc.o 230 COBJS-y += dlmalloc.o
230 COBJS-y += image.o 231 COBJS-y += image.o
231 COBJS-y += memsize.o 232 COBJS-y += memsize.o
232 COBJS-y += stdio.o 233 COBJS-y += stdio.o
233 234
234 235
235 COBJS := $(sort $(COBJS-y)) 236 COBJS := $(sort $(COBJS-y))
236 XCOBJS := $(sort $(XCOBJS-y)) 237 XCOBJS := $(sort $(XCOBJS-y))
237 SRCS := $(COBJS:.o=.c) $(XCOBJS:.o=.c) 238 SRCS := $(COBJS:.o=.c) $(XCOBJS:.o=.c)
238 OBJS := $(addprefix $(obj),$(COBJS)) 239 OBJS := $(addprefix $(obj),$(COBJS))
239 XOBJS := $(addprefix $(obj),$(XCOBJS)) 240 XOBJS := $(addprefix $(obj),$(XCOBJS))
240 241
241 CPPFLAGS += -I.. 242 CPPFLAGS += -I..
242 243
243 all: $(LIB) $(XOBJS) 244 all: $(LIB) $(XOBJS)
244 245
245 $(LIB): $(obj).depend $(OBJS) 246 $(LIB): $(obj).depend $(OBJS)
246 $(call cmd_link_o_target, $(OBJS)) 247 $(call cmd_link_o_target, $(OBJS))
247 248
248 $(obj)env_embedded.o: $(src)env_embedded.c $(obj)../tools/envcrc 249 $(obj)env_embedded.o: $(src)env_embedded.c $(obj)../tools/envcrc
249 $(CC) $(AFLAGS) -Wa,--no-warn \ 250 $(CC) $(AFLAGS) -Wa,--no-warn \
250 -DENV_CRC=$(shell $(obj)../tools/envcrc) \ 251 -DENV_CRC=$(shell $(obj)../tools/envcrc) \
251 -c -o $@ $(src)env_embedded.c 252 -c -o $@ $(src)env_embedded.c
252 253
253 $(obj)../tools/envcrc: 254 $(obj)../tools/envcrc:
254 $(MAKE) -C ../tools 255 $(MAKE) -C ../tools
255 256
256 # SEE README.arm-unaligned-accesses 257 # SEE README.arm-unaligned-accesses
257 $(obj)hush.o: CFLAGS += $(PLATFORM_NO_UNALIGNED) 258 $(obj)hush.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
258 $(obj)fdt_support.o: CFLAGS += $(PLATFORM_NO_UNALIGNED) 259 $(obj)fdt_support.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
259 260
260 ######################################################################### 261 #########################################################################
261 262
262 # defines $(obj).depend target 263 # defines $(obj).depend target
263 include $(SRCTREE)/rules.mk 264 include $(SRCTREE)/rules.mk
264 265
265 sinclude $(obj).depend 266 sinclude $(obj).depend
266 267
267 ######################################################################### 268 #########################################################################
268 269
common/cmd_bootmenu.c
File was created 1 /*
2 * (C) Copyright 2011-2013 Pali Rohรกr <pali.rohar@gmail.com>
3 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23 #include <common.h>
24 #include <command.h>
25 #include <ansi.h>
26 #include <menu.h>
27 #include <hush.h>
28 #include <watchdog.h>
29 #include <malloc.h>
30 #include <linux/string.h>
31
32 /* maximum bootmenu entries */
33 #define MAX_COUNT 99
34
35 /* maximal size of bootmenu env
36 * 9 = strlen("bootmenu_")
37 * 2 = strlen(MAX_COUNT)
38 * 1 = NULL term
39 */
40 #define MAX_ENV_SIZE (9 + 2 + 1)
41
42 struct bootmenu_entry {
43 unsigned short int num; /* unique number 0 .. MAX_COUNT */
44 char key[3]; /* key identifier of number */
45 char *title; /* title of entry */
46 char *command; /* hush command of entry */
47 struct bootmenu_data *menu; /* this bootmenu */
48 struct bootmenu_entry *next; /* next menu entry (num+1) */
49 };
50
51 struct bootmenu_data {
52 int delay; /* delay for autoboot */
53 int active; /* active menu entry */
54 int count; /* total count of menu entries */
55 struct bootmenu_entry *first; /* first menu entry */
56 };
57
58 enum bootmenu_key {
59 KEY_NONE = 0,
60 KEY_UP,
61 KEY_DOWN,
62 KEY_SELECT,
63 };
64
65 static char *bootmenu_getoption(unsigned short int n)
66 {
67 char name[MAX_ENV_SIZE] = "bootmenu_";
68
69 if (n > MAX_COUNT)
70 return NULL;
71
72 sprintf(name + 9, "%d", n);
73 return getenv(name);
74 }
75
76 static void bootmenu_print_entry(void *data)
77 {
78 struct bootmenu_entry *entry = data;
79 int reverse = (entry->menu->active == entry->num);
80
81 /*
82 * Move cursor to line where the entry will be drown (entry->num)
83 * First 3 lines contain bootmenu header + 1 empty line
84 */
85 printf(ANSI_CURSOR_POSITION, entry->num + 4, 1);
86
87 puts(" ");
88
89 if (reverse)
90 puts(ANSI_COLOR_REVERSE);
91
92 puts(entry->title);
93
94 if (reverse)
95 puts(ANSI_COLOR_RESET);
96 }
97
98 static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
99 enum bootmenu_key *key, int *esc)
100 {
101 int i, c;
102
103 if (menu->delay > 0) {
104 printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
105 printf(" Hit any key to stop autoboot: %2d ", menu->delay);
106 }
107
108 while (menu->delay > 0) {
109 for (i = 0; i < 100; ++i) {
110 if (!tstc()) {
111 WATCHDOG_RESET();
112 mdelay(10);
113 continue;
114 }
115
116 menu->delay = -1;
117 c = getc();
118
119 switch (c) {
120 case '\e':
121 *esc = 1;
122 *key = KEY_NONE;
123 break;
124 case '\r':
125 *key = KEY_SELECT;
126 break;
127 default:
128 *key = KEY_NONE;
129 break;
130 }
131
132 break;
133 }
134
135 if (menu->delay < 0)
136 break;
137
138 --menu->delay;
139 printf("\b\b\b%2d ", menu->delay);
140 }
141
142 printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
143 puts(ANSI_CLEAR_LINE);
144
145 if (menu->delay == 0)
146 *key = KEY_SELECT;
147 }
148
149 static void bootmenu_loop(struct bootmenu_data *menu,
150 enum bootmenu_key *key, int *esc)
151 {
152 int c;
153
154 while (!tstc()) {
155 WATCHDOG_RESET();
156 mdelay(10);
157 }
158
159 c = getc();
160
161 switch (*esc) {
162 case 0:
163 /* First char of ANSI escape sequence '\e' */
164 if (c == '\e') {
165 *esc = 1;
166 *key = KEY_NONE;
167 }
168 break;
169 case 1:
170 /* Second char of ANSI '[' */
171 if (c == '[') {
172 *esc = 2;
173 *key = KEY_NONE;
174 } else {
175 *esc = 0;
176 }
177 break;
178 case 2:
179 case 3:
180 /* Third char of ANSI (number '1') - optional */
181 if (*esc == 2 && c == '1') {
182 *esc = 3;
183 *key = KEY_NONE;
184 break;
185 }
186
187 *esc = 0;
188
189 /* ANSI 'A' - key up was pressed */
190 if (c == 'A')
191 *key = KEY_UP;
192 /* ANSI 'B' - key down was pressed */
193 else if (c == 'B')
194 *key = KEY_DOWN;
195 /* other key was pressed */
196 else
197 *key = KEY_NONE;
198
199 break;
200 }
201
202 /* enter key was pressed */
203 if (c == '\r')
204 *key = KEY_SELECT;
205 }
206
207 static char *bootmenu_choice_entry(void *data)
208 {
209 struct bootmenu_data *menu = data;
210 struct bootmenu_entry *iter;
211 enum bootmenu_key key = KEY_NONE;
212 int esc = 0;
213 int i;
214
215 while (1) {
216 if (menu->delay >= 0) {
217 /* Autoboot was not stopped */
218 bootmenu_autoboot_loop(menu, &key, &esc);
219 } else {
220 /* Some key was pressed, so autoboot was stopped */
221 bootmenu_loop(menu, &key, &esc);
222 }
223
224 switch (key) {
225 case KEY_UP:
226 if (menu->active > 0)
227 --menu->active;
228 /* no menu key selected, regenerate menu */
229 return NULL;
230 case KEY_DOWN:
231 if (menu->active < menu->count - 1)
232 ++menu->active;
233 /* no menu key selected, regenerate menu */
234 return NULL;
235 case KEY_SELECT:
236 iter = menu->first;
237 for (i = 0; i < menu->active; ++i)
238 iter = iter->next;
239 return iter->key;
240 default:
241 break;
242 }
243 }
244
245 /* never happens */
246 debug("bootmenu: this should not happen");
247 return NULL;
248 }
249
250 static void bootmenu_destroy(struct bootmenu_data *menu)
251 {
252 struct bootmenu_entry *iter = menu->first;
253 struct bootmenu_entry *next;
254
255 while (iter) {
256 next = iter->next;
257 free(iter->title);
258 free(iter->command);
259 free(iter);
260 iter = next;
261 }
262 free(menu);
263 }
264
265 static struct bootmenu_data *bootmenu_create(int delay)
266 {
267 unsigned short int i = 0;
268 const char *option;
269 struct bootmenu_data *menu;
270 struct bootmenu_entry *iter = NULL;
271
272 int len;
273 char *sep;
274 struct bootmenu_entry *entry;
275
276 menu = malloc(sizeof(struct bootmenu_data));
277 if (!menu)
278 return NULL;
279
280 menu->delay = delay;
281 menu->active = 0;
282 menu->first = NULL;
283
284 while ((option = bootmenu_getoption(i))) {
285 sep = strchr(option, '=');
286 if (!sep) {
287 printf("Invalid bootmenu entry: %s\n", option);
288 break;
289 }
290
291 entry = malloc(sizeof(struct bootmenu_entry));
292 if (!entry)
293 goto cleanup;
294
295 len = sep-option;
296 entry->title = malloc(len + 1);
297 if (!entry->title) {
298 free(entry);
299 goto cleanup;
300 }
301 memcpy(entry->title, option, len);
302 entry->title[len] = 0;
303
304 len = strlen(sep + 1);
305 entry->command = malloc(len + 1);
306 if (!entry->command) {
307 free(entry->title);
308 free(entry);
309 goto cleanup;
310 }
311 memcpy(entry->command, sep + 1, len);
312 entry->command[len] = 0;
313
314 sprintf(entry->key, "%d", i);
315
316 entry->num = i;
317 entry->menu = menu;
318 entry->next = NULL;
319
320 if (!iter)
321 menu->first = entry;
322 else
323 iter->next = entry;
324
325 iter = entry;
326 ++i;
327
328 if (i == MAX_COUNT - 1)
329 break;
330 }
331
332 /* Add U-Boot console entry at the end */
333 if (i <= MAX_COUNT - 1) {
334 entry = malloc(sizeof(struct bootmenu_entry));
335 if (!entry)
336 goto cleanup;
337
338 entry->title = strdup("U-Boot console");
339 if (!entry->title) {
340 free(entry);
341 goto cleanup;
342 }
343
344 entry->command = strdup("");
345 if (!entry->command) {
346 free(entry->title);
347 free(entry);
348 goto cleanup;
349 }
350
351 sprintf(entry->key, "%d", i);
352
353 entry->num = i;
354 entry->menu = menu;
355 entry->next = NULL;
356
357 if (!iter)
358 menu->first = entry;
359 else
360 iter->next = entry;
361
362 iter = entry;
363 ++i;
364 }
365
366 menu->count = i;
367 return menu;
368
369 cleanup:
370 bootmenu_destroy(menu);
371 return NULL;
372 }
373
374 static void bootmenu_show(int delay)
375 {
376 int init = 0;
377 void *choice = NULL;
378 char *title = NULL;
379 char *command = NULL;
380 struct menu *menu;
381 struct bootmenu_data *bootmenu;
382 struct bootmenu_entry *iter;
383 char *option, *sep;
384
385 /* If delay is 0 do not create menu, just run first entry */
386 if (delay == 0) {
387 option = bootmenu_getoption(0);
388 if (!option) {
389 puts("bootmenu option 0 was not found\n");
390 return;
391 }
392 sep = strchr(option, '=');
393 if (!sep) {
394 puts("bootmenu option 0 is invalid\n");
395 return;
396 }
397 run_command(sep+1, 0);
398 return;
399 }
400
401 bootmenu = bootmenu_create(delay);
402 if (!bootmenu)
403 return;
404
405 menu = menu_create(NULL, bootmenu->delay, 1, bootmenu_print_entry,
406 bootmenu_choice_entry, bootmenu);
407 if (!menu) {
408 bootmenu_destroy(bootmenu);
409 return;
410 }
411
412 for (iter = bootmenu->first; iter; iter = iter->next) {
413 if (!menu_item_add(menu, iter->key, iter))
414 goto cleanup;
415 }
416
417 /* Default menu entry is always first */
418 menu_default_set(menu, "0");
419
420 puts(ANSI_CURSOR_HIDE);
421 puts(ANSI_CLEAR_CONSOLE);
422 printf(ANSI_CURSOR_POSITION, 1, 1);
423
424 init = 1;
425
426 if (menu_get_choice(menu, &choice)) {
427 iter = choice;
428 title = strdup(iter->title);
429 command = strdup(iter->command);
430 }
431
432 cleanup:
433 menu_destroy(menu);
434 bootmenu_destroy(bootmenu);
435
436 if (init) {
437 puts(ANSI_CURSOR_SHOW);
438 puts(ANSI_CLEAR_CONSOLE);
439 printf(ANSI_CURSOR_POSITION, 1, 1);
440 }
441
442 if (title && command) {
443 debug("Starting entry '%s'\n", title);
444 free(title);
445 run_command(command, 0);
446 free(command);
447 }
448
449 #ifdef CONFIG_POSTBOOTMENU
450 run_command(CONFIG_POSTBOOTMENU, 0);
451 #endif
452 }
453
454 void menu_display_statusline(struct menu *m)
455 {
456 struct bootmenu_entry *entry;
457 struct bootmenu_data *menu;
458
459 if (menu_default_choice(m, (void *)&entry) < 0)
460 return;
461
462 menu = entry->menu;
463
464 printf(ANSI_CURSOR_POSITION, 1, 1);
465 puts(ANSI_CLEAR_LINE);
466 printf(ANSI_CURSOR_POSITION, 2, 1);
467 puts(" *** U-Boot Boot Menu ***");
468 puts(ANSI_CLEAR_LINE_TO_END);
469 printf(ANSI_CURSOR_POSITION, 3, 1);
470 puts(ANSI_CLEAR_LINE);
471
472 /* First 3 lines are bootmenu header + 2 empty lines between entries */
473 printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
474 puts(ANSI_CLEAR_LINE);
475 printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
476 puts(" Press UP/DOWN to move, ENTER to select");
477 puts(ANSI_CLEAR_LINE_TO_END);
478 printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
479 puts(ANSI_CLEAR_LINE);
480 }
481
482 #ifdef CONFIG_MENU_SHOW
483 int menu_show(int bootdelay)
484 {
485 bootmenu_show(bootdelay);
486 return -1; /* -1 - abort boot and run monitor code */
487 }
488 #endif
489
490 int do_bootmenu(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
491 {
492 char *delay_str = NULL;
493 int delay = 10;
494
495 #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
496 delay = CONFIG_BOOTDELAY;
497 #endif
498
499 if (argc >= 2)
500 delay_str = argv[1];
501
502 if (!delay_str)
503 delay_str = getenv("bootmenu_delay");
504
505 if (delay_str)
506 delay = (int)simple_strtol(delay_str, NULL, 10);
507
508 bootmenu_show(delay);
509 return 0;
510 }
511
512 U_BOOT_CMD(
513 bootmenu, 2, 1, do_bootmenu,
514 "ANSI terminal bootmenu",
515 "[delay]\n"
516 " - show ANSI terminal bootmenu with autoboot delay"
517 );
518
1 /* 1 /*
2 * Copyright 2010-2011 Calxeda, Inc. 2 * Copyright 2010-2011 Calxeda, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free 5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option) 6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version. 7 * any later version.
8 * 8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT 9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details. 12 * more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License along with 14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>. 15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 #include <common.h> 17 #include <common.h>
18 #include <command.h> 18 #include <command.h>
19 #include <malloc.h> 19 #include <malloc.h>
20 #include <linux/string.h> 20 #include <linux/string.h>
21 #include <linux/ctype.h> 21 #include <linux/ctype.h>
22 #include <errno.h> 22 #include <errno.h>
23 #include <linux/list.h> 23 #include <linux/list.h>
24 24
25 #include "menu.h" 25 #include "menu.h"
26 26
27 #define MAX_TFTP_PATH_LEN 127 27 #define MAX_TFTP_PATH_LEN 127
28 28
29 /* 29 /*
30 * Like getenv, but prints an error if envvar isn't defined in the 30 * Like getenv, but prints an error if envvar isn't defined in the
31 * environment. It always returns what getenv does, so it can be used in 31 * environment. It always returns what getenv does, so it can be used in
32 * place of getenv without changing error handling otherwise. 32 * place of getenv without changing error handling otherwise.
33 */ 33 */
34 static char *from_env(char *envvar) 34 static char *from_env(char *envvar)
35 { 35 {
36 char *ret; 36 char *ret;
37 37
38 ret = getenv(envvar); 38 ret = getenv(envvar);
39 39
40 if (!ret) 40 if (!ret)
41 printf("missing environment variable: %s\n", envvar); 41 printf("missing environment variable: %s\n", envvar);
42 42
43 return ret; 43 return ret;
44 } 44 }
45 45
46 /* 46 /*
47 * Convert an ethaddr from the environment to the format used by pxelinux 47 * Convert an ethaddr from the environment to the format used by pxelinux
48 * filenames based on mac addresses. Convert's ':' to '-', and adds "01-" to 48 * filenames based on mac addresses. Convert's ':' to '-', and adds "01-" to
49 * the beginning of the ethernet address to indicate a hardware type of 49 * the beginning of the ethernet address to indicate a hardware type of
50 * Ethernet. Also converts uppercase hex characters into lowercase, to match 50 * Ethernet. Also converts uppercase hex characters into lowercase, to match
51 * pxelinux's behavior. 51 * pxelinux's behavior.
52 * 52 *
53 * Returns 1 for success, -ENOENT if 'ethaddr' is undefined in the 53 * Returns 1 for success, -ENOENT if 'ethaddr' is undefined in the
54 * environment, or some other value < 0 on error. 54 * environment, or some other value < 0 on error.
55 */ 55 */
56 static int format_mac_pxe(char *outbuf, size_t outbuf_len) 56 static int format_mac_pxe(char *outbuf, size_t outbuf_len)
57 { 57 {
58 size_t ethaddr_len; 58 size_t ethaddr_len;
59 char *p, *ethaddr; 59 char *p, *ethaddr;
60 60
61 ethaddr = from_env("ethaddr"); 61 ethaddr = from_env("ethaddr");
62 62
63 if (!ethaddr) 63 if (!ethaddr)
64 return -ENOENT; 64 return -ENOENT;
65 65
66 ethaddr_len = strlen(ethaddr); 66 ethaddr_len = strlen(ethaddr);
67 67
68 /* 68 /*
69 * ethaddr_len + 4 gives room for "01-", ethaddr, and a NUL byte at 69 * ethaddr_len + 4 gives room for "01-", ethaddr, and a NUL byte at
70 * the end. 70 * the end.
71 */ 71 */
72 if (outbuf_len < ethaddr_len + 4) { 72 if (outbuf_len < ethaddr_len + 4) {
73 printf("outbuf is too small (%d < %d)\n", 73 printf("outbuf is too small (%d < %d)\n",
74 outbuf_len, ethaddr_len + 4); 74 outbuf_len, ethaddr_len + 4);
75 75
76 return -EINVAL; 76 return -EINVAL;
77 } 77 }
78 78
79 strcpy(outbuf, "01-"); 79 strcpy(outbuf, "01-");
80 80
81 for (p = outbuf + 3; *ethaddr; ethaddr++, p++) { 81 for (p = outbuf + 3; *ethaddr; ethaddr++, p++) {
82 if (*ethaddr == ':') 82 if (*ethaddr == ':')
83 *p = '-'; 83 *p = '-';
84 else 84 else
85 *p = tolower(*ethaddr); 85 *p = tolower(*ethaddr);
86 } 86 }
87 87
88 *p = '\0'; 88 *p = '\0';
89 89
90 return 1; 90 return 1;
91 } 91 }
92 92
93 /* 93 /*
94 * Returns the directory the file specified in the bootfile env variable is 94 * Returns the directory the file specified in the bootfile env variable is
95 * in. If bootfile isn't defined in the environment, return NULL, which should 95 * in. If bootfile isn't defined in the environment, return NULL, which should
96 * be interpreted as "don't prepend anything to paths". 96 * be interpreted as "don't prepend anything to paths".
97 */ 97 */
98 static int get_bootfile_path(const char *file_path, char *bootfile_path, 98 static int get_bootfile_path(const char *file_path, char *bootfile_path,
99 size_t bootfile_path_size) 99 size_t bootfile_path_size)
100 { 100 {
101 char *bootfile, *last_slash; 101 char *bootfile, *last_slash;
102 size_t path_len = 0; 102 size_t path_len = 0;
103 103
104 if (file_path[0] == '/') 104 if (file_path[0] == '/')
105 goto ret; 105 goto ret;
106 106
107 bootfile = from_env("bootfile"); 107 bootfile = from_env("bootfile");
108 108
109 if (!bootfile) 109 if (!bootfile)
110 goto ret; 110 goto ret;
111 111
112 last_slash = strrchr(bootfile, '/'); 112 last_slash = strrchr(bootfile, '/');
113 113
114 if (last_slash == NULL) 114 if (last_slash == NULL)
115 goto ret; 115 goto ret;
116 116
117 path_len = (last_slash - bootfile) + 1; 117 path_len = (last_slash - bootfile) + 1;
118 118
119 if (bootfile_path_size < path_len) { 119 if (bootfile_path_size < path_len) {
120 printf("bootfile_path too small. (%d < %d)\n", 120 printf("bootfile_path too small. (%d < %d)\n",
121 bootfile_path_size, path_len); 121 bootfile_path_size, path_len);
122 122
123 return -1; 123 return -1;
124 } 124 }
125 125
126 strncpy(bootfile_path, bootfile, path_len); 126 strncpy(bootfile_path, bootfile, path_len);
127 127
128 ret: 128 ret:
129 bootfile_path[path_len] = '\0'; 129 bootfile_path[path_len] = '\0';
130 130
131 return 1; 131 return 1;
132 } 132 }
133 133
134 static int (*do_getfile)(char *file_path, char *file_addr); 134 static int (*do_getfile)(char *file_path, char *file_addr);
135 135
136 static int do_get_tftp(char *file_path, char *file_addr) 136 static int do_get_tftp(char *file_path, char *file_addr)
137 { 137 {
138 char *tftp_argv[] = {"tftp", NULL, NULL, NULL}; 138 char *tftp_argv[] = {"tftp", NULL, NULL, NULL};
139 139
140 tftp_argv[1] = file_addr; 140 tftp_argv[1] = file_addr;
141 tftp_argv[2] = file_path; 141 tftp_argv[2] = file_path;
142 142
143 if (do_tftpb(NULL, 0, 3, tftp_argv)) 143 if (do_tftpb(NULL, 0, 3, tftp_argv))
144 return -ENOENT; 144 return -ENOENT;
145 145
146 return 1; 146 return 1;
147 } 147 }
148 148
149 static char *fs_argv[5]; 149 static char *fs_argv[5];
150 150
151 static int do_get_ext2(char *file_path, char *file_addr) 151 static int do_get_ext2(char *file_path, char *file_addr)
152 { 152 {
153 #ifdef CONFIG_CMD_EXT2 153 #ifdef CONFIG_CMD_EXT2
154 fs_argv[0] = "ext2load"; 154 fs_argv[0] = "ext2load";
155 fs_argv[3] = file_addr; 155 fs_argv[3] = file_addr;
156 fs_argv[4] = file_path; 156 fs_argv[4] = file_path;
157 157
158 if (!do_ext2load(NULL, 0, 5, fs_argv)) 158 if (!do_ext2load(NULL, 0, 5, fs_argv))
159 return 1; 159 return 1;
160 #endif 160 #endif
161 return -ENOENT; 161 return -ENOENT;
162 } 162 }
163 163
164 static int do_get_fat(char *file_path, char *file_addr) 164 static int do_get_fat(char *file_path, char *file_addr)
165 { 165 {
166 #ifdef CONFIG_CMD_FAT 166 #ifdef CONFIG_CMD_FAT
167 fs_argv[0] = "fatload"; 167 fs_argv[0] = "fatload";
168 fs_argv[3] = file_addr; 168 fs_argv[3] = file_addr;
169 fs_argv[4] = file_path; 169 fs_argv[4] = file_path;
170 170
171 if (!do_fat_fsload(NULL, 0, 5, fs_argv)) 171 if (!do_fat_fsload(NULL, 0, 5, fs_argv))
172 return 1; 172 return 1;
173 #endif 173 #endif
174 return -ENOENT; 174 return -ENOENT;
175 } 175 }
176 176
177 /* 177 /*
178 * As in pxelinux, paths to files referenced from files we retrieve are 178 * As in pxelinux, paths to files referenced from files we retrieve are
179 * relative to the location of bootfile. get_relfile takes such a path and 179 * relative to the location of bootfile. get_relfile takes such a path and
180 * joins it with the bootfile path to get the full path to the target file. If 180 * joins it with the bootfile path to get the full path to the target file. If
181 * the bootfile path is NULL, we use file_path as is. 181 * the bootfile path is NULL, we use file_path as is.
182 * 182 *
183 * Returns 1 for success, or < 0 on error. 183 * Returns 1 for success, or < 0 on error.
184 */ 184 */
185 static int get_relfile(char *file_path, void *file_addr) 185 static int get_relfile(char *file_path, void *file_addr)
186 { 186 {
187 size_t path_len; 187 size_t path_len;
188 char relfile[MAX_TFTP_PATH_LEN+1]; 188 char relfile[MAX_TFTP_PATH_LEN+1];
189 char addr_buf[10]; 189 char addr_buf[10];
190 int err; 190 int err;
191 191
192 err = get_bootfile_path(file_path, relfile, sizeof(relfile)); 192 err = get_bootfile_path(file_path, relfile, sizeof(relfile));
193 193
194 if (err < 0) 194 if (err < 0)
195 return err; 195 return err;
196 196
197 path_len = strlen(file_path); 197 path_len = strlen(file_path);
198 path_len += strlen(relfile); 198 path_len += strlen(relfile);
199 199
200 if (path_len > MAX_TFTP_PATH_LEN) { 200 if (path_len > MAX_TFTP_PATH_LEN) {
201 printf("Base path too long (%s%s)\n", 201 printf("Base path too long (%s%s)\n",
202 relfile, 202 relfile,
203 file_path); 203 file_path);
204 204
205 return -ENAMETOOLONG; 205 return -ENAMETOOLONG;
206 } 206 }
207 207
208 strcat(relfile, file_path); 208 strcat(relfile, file_path);
209 209
210 printf("Retrieving file: %s\n", relfile); 210 printf("Retrieving file: %s\n", relfile);
211 211
212 sprintf(addr_buf, "%p", file_addr); 212 sprintf(addr_buf, "%p", file_addr);
213 213
214 return do_getfile(relfile, addr_buf); 214 return do_getfile(relfile, addr_buf);
215 } 215 }
216 216
217 /* 217 /*
218 * Retrieve the file at 'file_path' to the locate given by 'file_addr'. If 218 * Retrieve the file at 'file_path' to the locate given by 'file_addr'. If
219 * 'bootfile' was specified in the environment, the path to bootfile will be 219 * 'bootfile' was specified in the environment, the path to bootfile will be
220 * prepended to 'file_path' and the resulting path will be used. 220 * prepended to 'file_path' and the resulting path will be used.
221 * 221 *
222 * Returns 1 on success, or < 0 for error. 222 * Returns 1 on success, or < 0 for error.
223 */ 223 */
224 static int get_pxe_file(char *file_path, void *file_addr) 224 static int get_pxe_file(char *file_path, void *file_addr)
225 { 225 {
226 unsigned long config_file_size; 226 unsigned long config_file_size;
227 char *tftp_filesize; 227 char *tftp_filesize;
228 int err; 228 int err;
229 229
230 err = get_relfile(file_path, file_addr); 230 err = get_relfile(file_path, file_addr);
231 231
232 if (err < 0) 232 if (err < 0)
233 return err; 233 return err;
234 234
235 /* 235 /*
236 * the file comes without a NUL byte at the end, so find out its size 236 * the file comes without a NUL byte at the end, so find out its size
237 * and add the NUL byte. 237 * and add the NUL byte.
238 */ 238 */
239 tftp_filesize = from_env("filesize"); 239 tftp_filesize = from_env("filesize");
240 240
241 if (!tftp_filesize) 241 if (!tftp_filesize)
242 return -ENOENT; 242 return -ENOENT;
243 243
244 if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0) 244 if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0)
245 return -EINVAL; 245 return -EINVAL;
246 246
247 *(char *)(file_addr + config_file_size) = '\0'; 247 *(char *)(file_addr + config_file_size) = '\0';
248 248
249 return 1; 249 return 1;
250 } 250 }
251 251
252 #define PXELINUX_DIR "pxelinux.cfg/" 252 #define PXELINUX_DIR "pxelinux.cfg/"
253 253
254 /* 254 /*
255 * Retrieves a file in the 'pxelinux.cfg' folder. Since this uses get_pxe_file 255 * Retrieves a file in the 'pxelinux.cfg' folder. Since this uses get_pxe_file
256 * to do the hard work, the location of the 'pxelinux.cfg' folder is generated 256 * to do the hard work, the location of the 'pxelinux.cfg' folder is generated
257 * from the bootfile path, as described above. 257 * from the bootfile path, as described above.
258 * 258 *
259 * Returns 1 on success or < 0 on error. 259 * Returns 1 on success or < 0 on error.
260 */ 260 */
261 static int get_pxelinux_path(char *file, void *pxefile_addr_r) 261 static int get_pxelinux_path(char *file, void *pxefile_addr_r)
262 { 262 {
263 size_t base_len = strlen(PXELINUX_DIR); 263 size_t base_len = strlen(PXELINUX_DIR);
264 char path[MAX_TFTP_PATH_LEN+1]; 264 char path[MAX_TFTP_PATH_LEN+1];
265 265
266 if (base_len + strlen(file) > MAX_TFTP_PATH_LEN) { 266 if (base_len + strlen(file) > MAX_TFTP_PATH_LEN) {
267 printf("path (%s%s) too long, skipping\n", 267 printf("path (%s%s) too long, skipping\n",
268 PXELINUX_DIR, file); 268 PXELINUX_DIR, file);
269 return -ENAMETOOLONG; 269 return -ENAMETOOLONG;
270 } 270 }
271 271
272 sprintf(path, PXELINUX_DIR "%s", file); 272 sprintf(path, PXELINUX_DIR "%s", file);
273 273
274 return get_pxe_file(path, pxefile_addr_r); 274 return get_pxe_file(path, pxefile_addr_r);
275 } 275 }
276 276
277 /* 277 /*
278 * Looks for a pxe file with a name based on the pxeuuid environment variable. 278 * Looks for a pxe file with a name based on the pxeuuid environment variable.
279 * 279 *
280 * Returns 1 on success or < 0 on error. 280 * Returns 1 on success or < 0 on error.
281 */ 281 */
282 static int pxe_uuid_path(void *pxefile_addr_r) 282 static int pxe_uuid_path(void *pxefile_addr_r)
283 { 283 {
284 char *uuid_str; 284 char *uuid_str;
285 285
286 uuid_str = from_env("pxeuuid"); 286 uuid_str = from_env("pxeuuid");
287 287
288 if (!uuid_str) 288 if (!uuid_str)
289 return -ENOENT; 289 return -ENOENT;
290 290
291 return get_pxelinux_path(uuid_str, pxefile_addr_r); 291 return get_pxelinux_path(uuid_str, pxefile_addr_r);
292 } 292 }
293 293
294 /* 294 /*
295 * Looks for a pxe file with a name based on the 'ethaddr' environment 295 * Looks for a pxe file with a name based on the 'ethaddr' environment
296 * variable. 296 * variable.
297 * 297 *
298 * Returns 1 on success or < 0 on error. 298 * Returns 1 on success or < 0 on error.
299 */ 299 */
300 static int pxe_mac_path(void *pxefile_addr_r) 300 static int pxe_mac_path(void *pxefile_addr_r)
301 { 301 {
302 char mac_str[21]; 302 char mac_str[21];
303 int err; 303 int err;
304 304
305 err = format_mac_pxe(mac_str, sizeof(mac_str)); 305 err = format_mac_pxe(mac_str, sizeof(mac_str));
306 306
307 if (err < 0) 307 if (err < 0)
308 return err; 308 return err;
309 309
310 return get_pxelinux_path(mac_str, pxefile_addr_r); 310 return get_pxelinux_path(mac_str, pxefile_addr_r);
311 } 311 }
312 312
313 /* 313 /*
314 * Looks for pxe files with names based on our IP address. See pxelinux 314 * Looks for pxe files with names based on our IP address. See pxelinux
315 * documentation for details on what these file names look like. We match 315 * documentation for details on what these file names look like. We match
316 * that exactly. 316 * that exactly.
317 * 317 *
318 * Returns 1 on success or < 0 on error. 318 * Returns 1 on success or < 0 on error.
319 */ 319 */
320 static int pxe_ipaddr_paths(void *pxefile_addr_r) 320 static int pxe_ipaddr_paths(void *pxefile_addr_r)
321 { 321 {
322 char ip_addr[9]; 322 char ip_addr[9];
323 int mask_pos, err; 323 int mask_pos, err;
324 324
325 sprintf(ip_addr, "%08X", ntohl(NetOurIP)); 325 sprintf(ip_addr, "%08X", ntohl(NetOurIP));
326 326
327 for (mask_pos = 7; mask_pos >= 0; mask_pos--) { 327 for (mask_pos = 7; mask_pos >= 0; mask_pos--) {
328 err = get_pxelinux_path(ip_addr, pxefile_addr_r); 328 err = get_pxelinux_path(ip_addr, pxefile_addr_r);
329 329
330 if (err > 0) 330 if (err > 0)
331 return err; 331 return err;
332 332
333 ip_addr[mask_pos] = '\0'; 333 ip_addr[mask_pos] = '\0';
334 } 334 }
335 335
336 return -ENOENT; 336 return -ENOENT;
337 } 337 }
338 338
339 /* 339 /*
340 * Entry point for the 'pxe get' command. 340 * Entry point for the 'pxe get' command.
341 * This Follows pxelinux's rules to download a config file from a tftp server. 341 * This Follows pxelinux's rules to download a config file from a tftp server.
342 * The file is stored at the location given by the pxefile_addr_r environment 342 * The file is stored at the location given by the pxefile_addr_r environment
343 * variable, which must be set. 343 * variable, which must be set.
344 * 344 *
345 * UUID comes from pxeuuid env variable, if defined 345 * UUID comes from pxeuuid env variable, if defined
346 * MAC addr comes from ethaddr env variable, if defined 346 * MAC addr comes from ethaddr env variable, if defined
347 * IP 347 * IP
348 * 348 *
349 * see http://syslinux.zytor.com/wiki/index.php/PXELINUX 349 * see http://syslinux.zytor.com/wiki/index.php/PXELINUX
350 * 350 *
351 * Returns 0 on success or 1 on error. 351 * Returns 0 on success or 1 on error.
352 */ 352 */
353 static int 353 static int
354 do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 354 do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
355 { 355 {
356 char *pxefile_addr_str; 356 char *pxefile_addr_str;
357 unsigned long pxefile_addr_r; 357 unsigned long pxefile_addr_r;
358 int err; 358 int err;
359 359
360 do_getfile = do_get_tftp; 360 do_getfile = do_get_tftp;
361 361
362 if (argc != 1) 362 if (argc != 1)
363 return CMD_RET_USAGE; 363 return CMD_RET_USAGE;
364 364
365 pxefile_addr_str = from_env("pxefile_addr_r"); 365 pxefile_addr_str = from_env("pxefile_addr_r");
366 366
367 if (!pxefile_addr_str) 367 if (!pxefile_addr_str)
368 return 1; 368 return 1;
369 369
370 err = strict_strtoul(pxefile_addr_str, 16, 370 err = strict_strtoul(pxefile_addr_str, 16,
371 (unsigned long *)&pxefile_addr_r); 371 (unsigned long *)&pxefile_addr_r);
372 if (err < 0) 372 if (err < 0)
373 return 1; 373 return 1;
374 374
375 /* 375 /*
376 * Keep trying paths until we successfully get a file we're looking 376 * Keep trying paths until we successfully get a file we're looking
377 * for. 377 * for.
378 */ 378 */
379 if (pxe_uuid_path((void *)pxefile_addr_r) > 0 379 if (pxe_uuid_path((void *)pxefile_addr_r) > 0
380 || pxe_mac_path((void *)pxefile_addr_r) > 0 380 || pxe_mac_path((void *)pxefile_addr_r) > 0
381 || pxe_ipaddr_paths((void *)pxefile_addr_r) > 0 381 || pxe_ipaddr_paths((void *)pxefile_addr_r) > 0
382 || get_pxelinux_path("default", (void *)pxefile_addr_r) > 0) { 382 || get_pxelinux_path("default", (void *)pxefile_addr_r) > 0) {
383 383
384 printf("Config file found\n"); 384 printf("Config file found\n");
385 385
386 return 0; 386 return 0;
387 } 387 }
388 388
389 printf("Config file not found\n"); 389 printf("Config file not found\n");
390 390
391 return 1; 391 return 1;
392 } 392 }
393 393
394 /* 394 /*
395 * Wrapper to make it easier to store the file at file_path in the location 395 * Wrapper to make it easier to store the file at file_path in the location
396 * specified by envaddr_name. file_path will be joined to the bootfile path, 396 * specified by envaddr_name. file_path will be joined to the bootfile path,
397 * if any is specified. 397 * if any is specified.
398 * 398 *
399 * Returns 1 on success or < 0 on error. 399 * Returns 1 on success or < 0 on error.
400 */ 400 */
401 static int get_relfile_envaddr(char *file_path, char *envaddr_name) 401 static int get_relfile_envaddr(char *file_path, char *envaddr_name)
402 { 402 {
403 unsigned long file_addr; 403 unsigned long file_addr;
404 char *envaddr; 404 char *envaddr;
405 405
406 envaddr = from_env(envaddr_name); 406 envaddr = from_env(envaddr_name);
407 407
408 if (!envaddr) 408 if (!envaddr)
409 return -ENOENT; 409 return -ENOENT;
410 410
411 if (strict_strtoul(envaddr, 16, &file_addr) < 0) 411 if (strict_strtoul(envaddr, 16, &file_addr) < 0)
412 return -EINVAL; 412 return -EINVAL;
413 413
414 return get_relfile(file_path, (void *)file_addr); 414 return get_relfile(file_path, (void *)file_addr);
415 } 415 }
416 416
417 /* 417 /*
418 * A note on the pxe file parser. 418 * A note on the pxe file parser.
419 * 419 *
420 * We're parsing files that use syslinux grammar, which has a few quirks. 420 * We're parsing files that use syslinux grammar, which has a few quirks.
421 * String literals must be recognized based on context - there is no 421 * String literals must be recognized based on context - there is no
422 * quoting or escaping support. There's also nothing to explicitly indicate 422 * quoting or escaping support. There's also nothing to explicitly indicate
423 * when a label section completes. We deal with that by ending a label 423 * when a label section completes. We deal with that by ending a label
424 * section whenever we see a line that doesn't include. 424 * section whenever we see a line that doesn't include.
425 * 425 *
426 * As with the syslinux family, this same file format could be reused in the 426 * As with the syslinux family, this same file format could be reused in the
427 * future for non pxe purposes. The only action it takes during parsing that 427 * future for non pxe purposes. The only action it takes during parsing that
428 * would throw this off is handling of include files. It assumes we're using 428 * would throw this off is handling of include files. It assumes we're using
429 * pxe, and does a tftp download of a file listed as an include file in the 429 * pxe, and does a tftp download of a file listed as an include file in the
430 * middle of the parsing operation. That could be handled by refactoring it to 430 * middle of the parsing operation. That could be handled by refactoring it to
431 * take a 'include file getter' function. 431 * take a 'include file getter' function.
432 */ 432 */
433 433
434 /* 434 /*
435 * Describes a single label given in a pxe file. 435 * Describes a single label given in a pxe file.
436 * 436 *
437 * Create these with the 'label_create' function given below. 437 * Create these with the 'label_create' function given below.
438 * 438 *
439 * name - the name of the menu as given on the 'menu label' line. 439 * name - the name of the menu as given on the 'menu label' line.
440 * kernel - the path to the kernel file to use for this label. 440 * kernel - the path to the kernel file to use for this label.
441 * append - kernel command line to use when booting this label 441 * append - kernel command line to use when booting this label
442 * initrd - path to the initrd to use for this label. 442 * initrd - path to the initrd to use for this label.
443 * attempted - 0 if we haven't tried to boot this label, 1 if we have. 443 * attempted - 0 if we haven't tried to boot this label, 1 if we have.
444 * localboot - 1 if this label specified 'localboot', 0 otherwise. 444 * localboot - 1 if this label specified 'localboot', 0 otherwise.
445 * list - lets these form a list, which a pxe_menu struct will hold. 445 * list - lets these form a list, which a pxe_menu struct will hold.
446 */ 446 */
447 struct pxe_label { 447 struct pxe_label {
448 char *name; 448 char *name;
449 char *menu; 449 char *menu;
450 char *kernel; 450 char *kernel;
451 char *append; 451 char *append;
452 char *initrd; 452 char *initrd;
453 char *fdt; 453 char *fdt;
454 int attempted; 454 int attempted;
455 int localboot; 455 int localboot;
456 struct list_head list; 456 struct list_head list;
457 }; 457 };
458 458
459 /* 459 /*
460 * Describes a pxe menu as given via pxe files. 460 * Describes a pxe menu as given via pxe files.
461 * 461 *
462 * title - the name of the menu as given by a 'menu title' line. 462 * title - the name of the menu as given by a 'menu title' line.
463 * default_label - the name of the default label, if any. 463 * default_label - the name of the default label, if any.
464 * timeout - time in tenths of a second to wait for a user key-press before 464 * timeout - time in tenths of a second to wait for a user key-press before
465 * booting the default label. 465 * booting the default label.
466 * prompt - if 0, don't prompt for a choice unless the timeout period is 466 * prompt - if 0, don't prompt for a choice unless the timeout period is
467 * interrupted. If 1, always prompt for a choice regardless of 467 * interrupted. If 1, always prompt for a choice regardless of
468 * timeout. 468 * timeout.
469 * labels - a list of labels defined for the menu. 469 * labels - a list of labels defined for the menu.
470 */ 470 */
471 struct pxe_menu { 471 struct pxe_menu {
472 char *title; 472 char *title;
473 char *default_label; 473 char *default_label;
474 int timeout; 474 int timeout;
475 int prompt; 475 int prompt;
476 struct list_head labels; 476 struct list_head labels;
477 }; 477 };
478 478
479 /* 479 /*
480 * Allocates memory for and initializes a pxe_label. This uses malloc, so the 480 * Allocates memory for and initializes a pxe_label. This uses malloc, so the
481 * result must be free()'d to reclaim the memory. 481 * result must be free()'d to reclaim the memory.
482 * 482 *
483 * Returns NULL if malloc fails. 483 * Returns NULL if malloc fails.
484 */ 484 */
485 static struct pxe_label *label_create(void) 485 static struct pxe_label *label_create(void)
486 { 486 {
487 struct pxe_label *label; 487 struct pxe_label *label;
488 488
489 label = malloc(sizeof(struct pxe_label)); 489 label = malloc(sizeof(struct pxe_label));
490 490
491 if (!label) 491 if (!label)
492 return NULL; 492 return NULL;
493 493
494 memset(label, 0, sizeof(struct pxe_label)); 494 memset(label, 0, sizeof(struct pxe_label));
495 495
496 return label; 496 return label;
497 } 497 }
498 498
499 /* 499 /*
500 * Free the memory used by a pxe_label, including that used by its name, 500 * Free the memory used by a pxe_label, including that used by its name,
501 * kernel, append and initrd members, if they're non NULL. 501 * kernel, append and initrd members, if they're non NULL.
502 * 502 *
503 * So - be sure to only use dynamically allocated memory for the members of 503 * So - be sure to only use dynamically allocated memory for the members of
504 * the pxe_label struct, unless you want to clean it up first. These are 504 * the pxe_label struct, unless you want to clean it up first. These are
505 * currently only created by the pxe file parsing code. 505 * currently only created by the pxe file parsing code.
506 */ 506 */
507 static void label_destroy(struct pxe_label *label) 507 static void label_destroy(struct pxe_label *label)
508 { 508 {
509 if (label->name) 509 if (label->name)
510 free(label->name); 510 free(label->name);
511 511
512 if (label->kernel) 512 if (label->kernel)
513 free(label->kernel); 513 free(label->kernel);
514 514
515 if (label->append) 515 if (label->append)
516 free(label->append); 516 free(label->append);
517 517
518 if (label->initrd) 518 if (label->initrd)
519 free(label->initrd); 519 free(label->initrd);
520 520
521 if (label->fdt) 521 if (label->fdt)
522 free(label->fdt); 522 free(label->fdt);
523 523
524 free(label); 524 free(label);
525 } 525 }
526 526
527 /* 527 /*
528 * Print a label and its string members if they're defined. 528 * Print a label and its string members if they're defined.
529 * 529 *
530 * This is passed as a callback to the menu code for displaying each 530 * This is passed as a callback to the menu code for displaying each
531 * menu entry. 531 * menu entry.
532 */ 532 */
533 static void label_print(void *data) 533 static void label_print(void *data)
534 { 534 {
535 struct pxe_label *label = data; 535 struct pxe_label *label = data;
536 const char *c = label->menu ? label->menu : label->kernel; 536 const char *c = label->menu ? label->menu : label->kernel;
537 537
538 printf("%s:\t%s\n", label->name, c); 538 printf("%s:\t%s\n", label->name, c);
539 539
540 if (label->kernel) 540 if (label->kernel)
541 printf("\t\tkernel: %s\n", label->kernel); 541 printf("\t\tkernel: %s\n", label->kernel);
542 542
543 if (label->append) 543 if (label->append)
544 printf("\t\tappend: %s\n", label->append); 544 printf("\t\tappend: %s\n", label->append);
545 545
546 if (label->initrd) 546 if (label->initrd)
547 printf("\t\tinitrd: %s\n", label->initrd); 547 printf("\t\tinitrd: %s\n", label->initrd);
548 548
549 if (label->fdt) 549 if (label->fdt)
550 printf("\tfdt: %s\n", label->fdt); 550 printf("\tfdt: %s\n", label->fdt);
551 } 551 }
552 552
553 /* 553 /*
554 * Boot a label that specified 'localboot'. This requires that the 'localcmd' 554 * Boot a label that specified 'localboot'. This requires that the 'localcmd'
555 * environment variable is defined. Its contents will be executed as U-boot 555 * environment variable is defined. Its contents will be executed as U-boot
556 * command. If the label specified an 'append' line, its contents will be 556 * command. If the label specified an 'append' line, its contents will be
557 * used to overwrite the contents of the 'bootargs' environment variable prior 557 * used to overwrite the contents of the 'bootargs' environment variable prior
558 * to running 'localcmd'. 558 * to running 'localcmd'.
559 * 559 *
560 * Returns 1 on success or < 0 on error. 560 * Returns 1 on success or < 0 on error.
561 */ 561 */
562 static int label_localboot(struct pxe_label *label) 562 static int label_localboot(struct pxe_label *label)
563 { 563 {
564 char *localcmd; 564 char *localcmd;
565 565
566 localcmd = from_env("localcmd"); 566 localcmd = from_env("localcmd");
567 567
568 if (!localcmd) 568 if (!localcmd)
569 return -ENOENT; 569 return -ENOENT;
570 570
571 if (label->append) 571 if (label->append)
572 setenv("bootargs", label->append); 572 setenv("bootargs", label->append);
573 573
574 debug("running: %s\n", localcmd); 574 debug("running: %s\n", localcmd);
575 575
576 return run_command_list(localcmd, strlen(localcmd), 0); 576 return run_command_list(localcmd, strlen(localcmd), 0);
577 } 577 }
578 578
579 /* 579 /*
580 * Boot according to the contents of a pxe_label. 580 * Boot according to the contents of a pxe_label.
581 * 581 *
582 * If we can't boot for any reason, we return. A successful boot never 582 * If we can't boot for any reason, we return. A successful boot never
583 * returns. 583 * returns.
584 * 584 *
585 * The kernel will be stored in the location given by the 'kernel_addr_r' 585 * The kernel will be stored in the location given by the 'kernel_addr_r'
586 * environment variable. 586 * environment variable.
587 * 587 *
588 * If the label specifies an initrd file, it will be stored in the location 588 * If the label specifies an initrd file, it will be stored in the location
589 * given by the 'ramdisk_addr_r' environment variable. 589 * given by the 'ramdisk_addr_r' environment variable.
590 * 590 *
591 * If the label specifies an 'append' line, its contents will overwrite that 591 * If the label specifies an 'append' line, its contents will overwrite that
592 * of the 'bootargs' environment variable. 592 * of the 'bootargs' environment variable.
593 */ 593 */
594 static void label_boot(struct pxe_label *label) 594 static void label_boot(struct pxe_label *label)
595 { 595 {
596 char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL }; 596 char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
597 int bootm_argc = 3; 597 int bootm_argc = 3;
598 598
599 label_print(label); 599 label_print(label);
600 600
601 label->attempted = 1; 601 label->attempted = 1;
602 602
603 if (label->localboot) { 603 if (label->localboot) {
604 label_localboot(label); 604 label_localboot(label);
605 return; 605 return;
606 } 606 }
607 607
608 if (label->kernel == NULL) { 608 if (label->kernel == NULL) {
609 printf("No kernel given, skipping %s\n", 609 printf("No kernel given, skipping %s\n",
610 label->name); 610 label->name);
611 return; 611 return;
612 } 612 }
613 613
614 if (label->initrd) { 614 if (label->initrd) {
615 if (get_relfile_envaddr(label->initrd, "ramdisk_addr_r") < 0) { 615 if (get_relfile_envaddr(label->initrd, "ramdisk_addr_r") < 0) {
616 printf("Skipping %s for failure retrieving initrd\n", 616 printf("Skipping %s for failure retrieving initrd\n",
617 label->name); 617 label->name);
618 return; 618 return;
619 } 619 }
620 620
621 bootm_argv[2] = getenv("ramdisk_addr_r"); 621 bootm_argv[2] = getenv("ramdisk_addr_r");
622 } else { 622 } else {
623 bootm_argv[2] = "-"; 623 bootm_argv[2] = "-";
624 } 624 }
625 625
626 if (get_relfile_envaddr(label->kernel, "kernel_addr_r") < 0) { 626 if (get_relfile_envaddr(label->kernel, "kernel_addr_r") < 0) {
627 printf("Skipping %s for failure retrieving kernel\n", 627 printf("Skipping %s for failure retrieving kernel\n",
628 label->name); 628 label->name);
629 return; 629 return;
630 } 630 }
631 631
632 if (label->append) 632 if (label->append)
633 setenv("bootargs", label->append); 633 setenv("bootargs", label->append);
634 634
635 bootm_argv[1] = getenv("kernel_addr_r"); 635 bootm_argv[1] = getenv("kernel_addr_r");
636 636
637 /* 637 /*
638 * fdt usage is optional: 638 * fdt usage is optional:
639 * It handles the following scenarios. All scenarios are exclusive 639 * It handles the following scenarios. All scenarios are exclusive
640 * 640 *
641 * Scenario 1: If fdt_addr_r specified and "fdt" label is defined in 641 * Scenario 1: If fdt_addr_r specified and "fdt" label is defined in
642 * pxe file, retrieve fdt blob from server. Pass fdt_addr_r to bootm, 642 * pxe file, retrieve fdt blob from server. Pass fdt_addr_r to bootm,
643 * and adjust argc appropriately. 643 * and adjust argc appropriately.
644 * 644 *
645 * Scenario 2: If there is an fdt_addr specified, pass it along to 645 * Scenario 2: If there is an fdt_addr specified, pass it along to
646 * bootm, and adjust argc appropriately. 646 * bootm, and adjust argc appropriately.
647 * 647 *
648 * Scenario 3: fdt blob is not available. 648 * Scenario 3: fdt blob is not available.
649 */ 649 */
650 bootm_argv[3] = getenv("fdt_addr_r"); 650 bootm_argv[3] = getenv("fdt_addr_r");
651 651
652 /* if fdt label is defined then get fdt from server */ 652 /* if fdt label is defined then get fdt from server */
653 if (bootm_argv[3] && label->fdt) { 653 if (bootm_argv[3] && label->fdt) {
654 if (get_relfile_envaddr(label->fdt, "fdt_addr_r") < 0) { 654 if (get_relfile_envaddr(label->fdt, "fdt_addr_r") < 0) {
655 printf("Skipping %s for failure retrieving fdt\n", 655 printf("Skipping %s for failure retrieving fdt\n",
656 label->name); 656 label->name);
657 return; 657 return;
658 } 658 }
659 } else 659 } else
660 bootm_argv[3] = getenv("fdt_addr"); 660 bootm_argv[3] = getenv("fdt_addr");
661 661
662 if (bootm_argv[3]) 662 if (bootm_argv[3])
663 bootm_argc = 4; 663 bootm_argc = 4;
664 664
665 do_bootm(NULL, 0, bootm_argc, bootm_argv); 665 do_bootm(NULL, 0, bootm_argc, bootm_argv);
666 } 666 }
667 667
668 /* 668 /*
669 * Tokens for the pxe file parser. 669 * Tokens for the pxe file parser.
670 */ 670 */
671 enum token_type { 671 enum token_type {
672 T_EOL, 672 T_EOL,
673 T_STRING, 673 T_STRING,
674 T_EOF, 674 T_EOF,
675 T_MENU, 675 T_MENU,
676 T_TITLE, 676 T_TITLE,
677 T_TIMEOUT, 677 T_TIMEOUT,
678 T_LABEL, 678 T_LABEL,
679 T_KERNEL, 679 T_KERNEL,
680 T_LINUX, 680 T_LINUX,
681 T_APPEND, 681 T_APPEND,
682 T_INITRD, 682 T_INITRD,
683 T_LOCALBOOT, 683 T_LOCALBOOT,
684 T_DEFAULT, 684 T_DEFAULT,
685 T_PROMPT, 685 T_PROMPT,
686 T_INCLUDE, 686 T_INCLUDE,
687 T_FDT, 687 T_FDT,
688 T_INVALID 688 T_INVALID
689 }; 689 };
690 690
691 /* 691 /*
692 * A token - given by a value and a type. 692 * A token - given by a value and a type.
693 */ 693 */
694 struct token { 694 struct token {
695 char *val; 695 char *val;
696 enum token_type type; 696 enum token_type type;
697 }; 697 };
698 698
699 /* 699 /*
700 * Keywords recognized. 700 * Keywords recognized.
701 */ 701 */
702 static const struct token keywords[] = { 702 static const struct token keywords[] = {
703 {"menu", T_MENU}, 703 {"menu", T_MENU},
704 {"title", T_TITLE}, 704 {"title", T_TITLE},
705 {"timeout", T_TIMEOUT}, 705 {"timeout", T_TIMEOUT},
706 {"default", T_DEFAULT}, 706 {"default", T_DEFAULT},
707 {"prompt", T_PROMPT}, 707 {"prompt", T_PROMPT},
708 {"label", T_LABEL}, 708 {"label", T_LABEL},
709 {"kernel", T_KERNEL}, 709 {"kernel", T_KERNEL},
710 {"linux", T_LINUX}, 710 {"linux", T_LINUX},
711 {"localboot", T_LOCALBOOT}, 711 {"localboot", T_LOCALBOOT},
712 {"append", T_APPEND}, 712 {"append", T_APPEND},
713 {"initrd", T_INITRD}, 713 {"initrd", T_INITRD},
714 {"include", T_INCLUDE}, 714 {"include", T_INCLUDE},
715 {"fdt", T_FDT}, 715 {"fdt", T_FDT},
716 {NULL, T_INVALID} 716 {NULL, T_INVALID}
717 }; 717 };
718 718
719 /* 719 /*
720 * Since pxe(linux) files don't have a token to identify the start of a 720 * Since pxe(linux) files don't have a token to identify the start of a
721 * literal, we have to keep track of when we're in a state where a literal is 721 * literal, we have to keep track of when we're in a state where a literal is
722 * expected vs when we're in a state a keyword is expected. 722 * expected vs when we're in a state a keyword is expected.
723 */ 723 */
724 enum lex_state { 724 enum lex_state {
725 L_NORMAL = 0, 725 L_NORMAL = 0,
726 L_KEYWORD, 726 L_KEYWORD,
727 L_SLITERAL 727 L_SLITERAL
728 }; 728 };
729 729
730 /* 730 /*
731 * get_string retrieves a string from *p and stores it as a token in 731 * get_string retrieves a string from *p and stores it as a token in
732 * *t. 732 * *t.
733 * 733 *
734 * get_string used for scanning both string literals and keywords. 734 * get_string used for scanning both string literals and keywords.
735 * 735 *
736 * Characters from *p are copied into t-val until a character equal to 736 * Characters from *p are copied into t-val until a character equal to
737 * delim is found, or a NUL byte is reached. If delim has the special value of 737 * delim is found, or a NUL byte is reached. If delim has the special value of
738 * ' ', any whitespace character will be used as a delimiter. 738 * ' ', any whitespace character will be used as a delimiter.
739 * 739 *
740 * If lower is unequal to 0, uppercase characters will be converted to 740 * If lower is unequal to 0, uppercase characters will be converted to
741 * lowercase in the result. This is useful to make keywords case 741 * lowercase in the result. This is useful to make keywords case
742 * insensitive. 742 * insensitive.
743 * 743 *
744 * The location of *p is updated to point to the first character after the end 744 * The location of *p is updated to point to the first character after the end
745 * of the token - the ending delimiter. 745 * of the token - the ending delimiter.
746 * 746 *
747 * On success, the new value of t->val is returned. Memory for t->val is 747 * On success, the new value of t->val is returned. Memory for t->val is
748 * allocated using malloc and must be free()'d to reclaim it. If insufficient 748 * allocated using malloc and must be free()'d to reclaim it. If insufficient
749 * memory is available, NULL is returned. 749 * memory is available, NULL is returned.
750 */ 750 */
751 static char *get_string(char **p, struct token *t, char delim, int lower) 751 static char *get_string(char **p, struct token *t, char delim, int lower)
752 { 752 {
753 char *b, *e; 753 char *b, *e;
754 size_t len, i; 754 size_t len, i;
755 755
756 /* 756 /*
757 * b and e both start at the beginning of the input stream. 757 * b and e both start at the beginning of the input stream.
758 * 758 *
759 * e is incremented until we find the ending delimiter, or a NUL byte 759 * e is incremented until we find the ending delimiter, or a NUL byte
760 * is reached. Then, we take e - b to find the length of the token. 760 * is reached. Then, we take e - b to find the length of the token.
761 */ 761 */
762 b = e = *p; 762 b = e = *p;
763 763
764 while (*e) { 764 while (*e) {
765 if ((delim == ' ' && isspace(*e)) || delim == *e) 765 if ((delim == ' ' && isspace(*e)) || delim == *e)
766 break; 766 break;
767 e++; 767 e++;
768 } 768 }
769 769
770 len = e - b; 770 len = e - b;
771 771
772 /* 772 /*
773 * Allocate memory to hold the string, and copy it in, converting 773 * Allocate memory to hold the string, and copy it in, converting
774 * characters to lowercase if lower is != 0. 774 * characters to lowercase if lower is != 0.
775 */ 775 */
776 t->val = malloc(len + 1); 776 t->val = malloc(len + 1);
777 if (!t->val) 777 if (!t->val)
778 return NULL; 778 return NULL;
779 779
780 for (i = 0; i < len; i++, b++) { 780 for (i = 0; i < len; i++, b++) {
781 if (lower) 781 if (lower)
782 t->val[i] = tolower(*b); 782 t->val[i] = tolower(*b);
783 else 783 else
784 t->val[i] = *b; 784 t->val[i] = *b;
785 } 785 }
786 786
787 t->val[len] = '\0'; 787 t->val[len] = '\0';
788 788
789 /* 789 /*
790 * Update *p so the caller knows where to continue scanning. 790 * Update *p so the caller knows where to continue scanning.
791 */ 791 */
792 *p = e; 792 *p = e;
793 793
794 t->type = T_STRING; 794 t->type = T_STRING;
795 795
796 return t->val; 796 return t->val;
797 } 797 }
798 798
799 /* 799 /*
800 * Populate a keyword token with a type and value. 800 * Populate a keyword token with a type and value.
801 */ 801 */
802 static void get_keyword(struct token *t) 802 static void get_keyword(struct token *t)
803 { 803 {
804 int i; 804 int i;
805 805
806 for (i = 0; keywords[i].val; i++) { 806 for (i = 0; keywords[i].val; i++) {
807 if (!strcmp(t->val, keywords[i].val)) { 807 if (!strcmp(t->val, keywords[i].val)) {
808 t->type = keywords[i].type; 808 t->type = keywords[i].type;
809 break; 809 break;
810 } 810 }
811 } 811 }
812 } 812 }
813 813
814 /* 814 /*
815 * Get the next token. We have to keep track of which state we're in to know 815 * Get the next token. We have to keep track of which state we're in to know
816 * if we're looking to get a string literal or a keyword. 816 * if we're looking to get a string literal or a keyword.
817 * 817 *
818 * *p is updated to point at the first character after the current token. 818 * *p is updated to point at the first character after the current token.
819 */ 819 */
820 static void get_token(char **p, struct token *t, enum lex_state state) 820 static void get_token(char **p, struct token *t, enum lex_state state)
821 { 821 {
822 char *c = *p; 822 char *c = *p;
823 823
824 t->type = T_INVALID; 824 t->type = T_INVALID;
825 825
826 /* eat non EOL whitespace */ 826 /* eat non EOL whitespace */
827 while (isblank(*c)) 827 while (isblank(*c))
828 c++; 828 c++;
829 829
830 /* 830 /*
831 * eat comments. note that string literals can't begin with #, but 831 * eat comments. note that string literals can't begin with #, but
832 * can contain a # after their first character. 832 * can contain a # after their first character.
833 */ 833 */
834 if (*c == '#') { 834 if (*c == '#') {
835 while (*c && *c != '\n') 835 while (*c && *c != '\n')
836 c++; 836 c++;
837 } 837 }
838 838
839 if (*c == '\n') { 839 if (*c == '\n') {
840 t->type = T_EOL; 840 t->type = T_EOL;
841 c++; 841 c++;
842 } else if (*c == '\0') { 842 } else if (*c == '\0') {
843 t->type = T_EOF; 843 t->type = T_EOF;
844 c++; 844 c++;
845 } else if (state == L_SLITERAL) { 845 } else if (state == L_SLITERAL) {
846 get_string(&c, t, '\n', 0); 846 get_string(&c, t, '\n', 0);
847 } else if (state == L_KEYWORD) { 847 } else if (state == L_KEYWORD) {
848 /* 848 /*
849 * when we expect a keyword, we first get the next string 849 * when we expect a keyword, we first get the next string
850 * token delimited by whitespace, and then check if it 850 * token delimited by whitespace, and then check if it
851 * matches a keyword in our keyword list. if it does, it's 851 * matches a keyword in our keyword list. if it does, it's
852 * converted to a keyword token of the appropriate type, and 852 * converted to a keyword token of the appropriate type, and
853 * if not, it remains a string token. 853 * if not, it remains a string token.
854 */ 854 */
855 get_string(&c, t, ' ', 1); 855 get_string(&c, t, ' ', 1);
856 get_keyword(t); 856 get_keyword(t);
857 } 857 }
858 858
859 *p = c; 859 *p = c;
860 } 860 }
861 861
862 /* 862 /*
863 * Increment *c until we get to the end of the current line, or EOF. 863 * Increment *c until we get to the end of the current line, or EOF.
864 */ 864 */
865 static void eol_or_eof(char **c) 865 static void eol_or_eof(char **c)
866 { 866 {
867 while (**c && **c != '\n') 867 while (**c && **c != '\n')
868 (*c)++; 868 (*c)++;
869 } 869 }
870 870
871 /* 871 /*
872 * All of these parse_* functions share some common behavior. 872 * All of these parse_* functions share some common behavior.
873 * 873 *
874 * They finish with *c pointing after the token they parse, and return 1 on 874 * They finish with *c pointing after the token they parse, and return 1 on
875 * success, or < 0 on error. 875 * success, or < 0 on error.
876 */ 876 */
877 877
878 /* 878 /*
879 * Parse a string literal and store a pointer it at *dst. String literals 879 * Parse a string literal and store a pointer it at *dst. String literals
880 * terminate at the end of the line. 880 * terminate at the end of the line.
881 */ 881 */
882 static int parse_sliteral(char **c, char **dst) 882 static int parse_sliteral(char **c, char **dst)
883 { 883 {
884 struct token t; 884 struct token t;
885 char *s = *c; 885 char *s = *c;
886 886
887 get_token(c, &t, L_SLITERAL); 887 get_token(c, &t, L_SLITERAL);
888 888
889 if (t.type != T_STRING) { 889 if (t.type != T_STRING) {
890 printf("Expected string literal: %.*s\n", (int)(*c - s), s); 890 printf("Expected string literal: %.*s\n", (int)(*c - s), s);
891 return -EINVAL; 891 return -EINVAL;
892 } 892 }
893 893
894 *dst = t.val; 894 *dst = t.val;
895 895
896 return 1; 896 return 1;
897 } 897 }
898 898
899 /* 899 /*
900 * Parse a base 10 (unsigned) integer and store it at *dst. 900 * Parse a base 10 (unsigned) integer and store it at *dst.
901 */ 901 */
902 static int parse_integer(char **c, int *dst) 902 static int parse_integer(char **c, int *dst)
903 { 903 {
904 struct token t; 904 struct token t;
905 char *s = *c; 905 char *s = *c;
906 unsigned long temp; 906 unsigned long temp;
907 907
908 get_token(c, &t, L_SLITERAL); 908 get_token(c, &t, L_SLITERAL);
909 909
910 if (t.type != T_STRING) { 910 if (t.type != T_STRING) {
911 printf("Expected string: %.*s\n", (int)(*c - s), s); 911 printf("Expected string: %.*s\n", (int)(*c - s), s);
912 return -EINVAL; 912 return -EINVAL;
913 } 913 }
914 914
915 if (strict_strtoul(t.val, 10, &temp) < 0) { 915 if (strict_strtoul(t.val, 10, &temp) < 0) {
916 printf("Expected unsigned integer: %s\n", t.val); 916 printf("Expected unsigned integer: %s\n", t.val);
917 return -EINVAL; 917 return -EINVAL;
918 } 918 }
919 919
920 *dst = (int)temp; 920 *dst = (int)temp;
921 921
922 free(t.val); 922 free(t.val);
923 923
924 return 1; 924 return 1;
925 } 925 }
926 926
927 static int parse_pxefile_top(char *p, struct pxe_menu *cfg, int nest_level); 927 static int parse_pxefile_top(char *p, struct pxe_menu *cfg, int nest_level);
928 928
929 /* 929 /*
930 * Parse an include statement, and retrieve and parse the file it mentions. 930 * Parse an include statement, and retrieve and parse the file it mentions.
931 * 931 *
932 * base should point to a location where it's safe to store the file, and 932 * base should point to a location where it's safe to store the file, and
933 * nest_level should indicate how many nested includes have occurred. For this 933 * nest_level should indicate how many nested includes have occurred. For this
934 * include, nest_level has already been incremented and doesn't need to be 934 * include, nest_level has already been incremented and doesn't need to be
935 * incremented here. 935 * incremented here.
936 */ 936 */
937 static int handle_include(char **c, char *base, 937 static int handle_include(char **c, char *base,
938 struct pxe_menu *cfg, int nest_level) 938 struct pxe_menu *cfg, int nest_level)
939 { 939 {
940 char *include_path; 940 char *include_path;
941 char *s = *c; 941 char *s = *c;
942 int err; 942 int err;
943 943
944 err = parse_sliteral(c, &include_path); 944 err = parse_sliteral(c, &include_path);
945 945
946 if (err < 0) { 946 if (err < 0) {
947 printf("Expected include path: %.*s\n", 947 printf("Expected include path: %.*s\n",
948 (int)(*c - s), s); 948 (int)(*c - s), s);
949 return err; 949 return err;
950 } 950 }
951 951
952 err = get_pxe_file(include_path, base); 952 err = get_pxe_file(include_path, base);
953 953
954 if (err < 0) { 954 if (err < 0) {
955 printf("Couldn't retrieve %s\n", include_path); 955 printf("Couldn't retrieve %s\n", include_path);
956 return err; 956 return err;
957 } 957 }
958 958
959 return parse_pxefile_top(base, cfg, nest_level); 959 return parse_pxefile_top(base, cfg, nest_level);
960 } 960 }
961 961
962 /* 962 /*
963 * Parse lines that begin with 'menu'. 963 * Parse lines that begin with 'menu'.
964 * 964 *
965 * b and nest are provided to handle the 'menu include' case. 965 * b and nest are provided to handle the 'menu include' case.
966 * 966 *
967 * b should be the address where the file currently being parsed is stored. 967 * b should be the address where the file currently being parsed is stored.
968 * 968 *
969 * nest_level should be 1 when parsing the top level pxe file, 2 when parsing 969 * nest_level should be 1 when parsing the top level pxe file, 2 when parsing
970 * a file it includes, 3 when parsing a file included by that file, and so on. 970 * a file it includes, 3 when parsing a file included by that file, and so on.
971 */ 971 */
972 static int parse_menu(char **c, struct pxe_menu *cfg, char *b, int nest_level) 972 static int parse_menu(char **c, struct pxe_menu *cfg, char *b, int nest_level)
973 { 973 {
974 struct token t; 974 struct token t;
975 char *s = *c; 975 char *s = *c;
976 int err = 0; 976 int err = 0;
977 977
978 get_token(c, &t, L_KEYWORD); 978 get_token(c, &t, L_KEYWORD);
979 979
980 switch (t.type) { 980 switch (t.type) {
981 case T_TITLE: 981 case T_TITLE:
982 err = parse_sliteral(c, &cfg->title); 982 err = parse_sliteral(c, &cfg->title);
983 983
984 break; 984 break;
985 985
986 case T_INCLUDE: 986 case T_INCLUDE:
987 err = handle_include(c, b + strlen(b) + 1, cfg, 987 err = handle_include(c, b + strlen(b) + 1, cfg,
988 nest_level + 1); 988 nest_level + 1);
989 break; 989 break;
990 990
991 default: 991 default:
992 printf("Ignoring malformed menu command: %.*s\n", 992 printf("Ignoring malformed menu command: %.*s\n",
993 (int)(*c - s), s); 993 (int)(*c - s), s);
994 } 994 }
995 995
996 if (err < 0) 996 if (err < 0)
997 return err; 997 return err;
998 998
999 eol_or_eof(c); 999 eol_or_eof(c);
1000 1000
1001 return 1; 1001 return 1;
1002 } 1002 }
1003 1003
1004 /* 1004 /*
1005 * Handles parsing a 'menu line' when we're parsing a label. 1005 * Handles parsing a 'menu line' when we're parsing a label.
1006 */ 1006 */
1007 static int parse_label_menu(char **c, struct pxe_menu *cfg, 1007 static int parse_label_menu(char **c, struct pxe_menu *cfg,
1008 struct pxe_label *label) 1008 struct pxe_label *label)
1009 { 1009 {
1010 struct token t; 1010 struct token t;
1011 char *s; 1011 char *s;
1012 1012
1013 s = *c; 1013 s = *c;
1014 1014
1015 get_token(c, &t, L_KEYWORD); 1015 get_token(c, &t, L_KEYWORD);
1016 1016
1017 switch (t.type) { 1017 switch (t.type) {
1018 case T_DEFAULT: 1018 case T_DEFAULT:
1019 if (cfg->default_label) 1019 if (cfg->default_label)
1020 free(cfg->default_label); 1020 free(cfg->default_label);
1021 1021
1022 cfg->default_label = strdup(label->name); 1022 cfg->default_label = strdup(label->name);
1023 1023
1024 if (!cfg->default_label) 1024 if (!cfg->default_label)
1025 return -ENOMEM; 1025 return -ENOMEM;
1026 1026
1027 break; 1027 break;
1028 case T_LABEL: 1028 case T_LABEL:
1029 parse_sliteral(c, &label->menu); 1029 parse_sliteral(c, &label->menu);
1030 break; 1030 break;
1031 default: 1031 default:
1032 printf("Ignoring malformed menu command: %.*s\n", 1032 printf("Ignoring malformed menu command: %.*s\n",
1033 (int)(*c - s), s); 1033 (int)(*c - s), s);
1034 } 1034 }
1035 1035
1036 eol_or_eof(c); 1036 eol_or_eof(c);
1037 1037
1038 return 0; 1038 return 0;
1039 } 1039 }
1040 1040
1041 /* 1041 /*
1042 * Parses a label and adds it to the list of labels for a menu. 1042 * Parses a label and adds it to the list of labels for a menu.
1043 * 1043 *
1044 * A label ends when we either get to the end of a file, or 1044 * A label ends when we either get to the end of a file, or
1045 * get some input we otherwise don't have a handler defined 1045 * get some input we otherwise don't have a handler defined
1046 * for. 1046 * for.
1047 * 1047 *
1048 */ 1048 */
1049 static int parse_label(char **c, struct pxe_menu *cfg) 1049 static int parse_label(char **c, struct pxe_menu *cfg)
1050 { 1050 {
1051 struct token t; 1051 struct token t;
1052 int len; 1052 int len;
1053 char *s = *c; 1053 char *s = *c;
1054 struct pxe_label *label; 1054 struct pxe_label *label;
1055 int err; 1055 int err;
1056 1056
1057 label = label_create(); 1057 label = label_create();
1058 if (!label) 1058 if (!label)
1059 return -ENOMEM; 1059 return -ENOMEM;
1060 1060
1061 err = parse_sliteral(c, &label->name); 1061 err = parse_sliteral(c, &label->name);
1062 if (err < 0) { 1062 if (err < 0) {
1063 printf("Expected label name: %.*s\n", (int)(*c - s), s); 1063 printf("Expected label name: %.*s\n", (int)(*c - s), s);
1064 label_destroy(label); 1064 label_destroy(label);
1065 return -EINVAL; 1065 return -EINVAL;
1066 } 1066 }
1067 1067
1068 list_add_tail(&label->list, &cfg->labels); 1068 list_add_tail(&label->list, &cfg->labels);
1069 1069
1070 while (1) { 1070 while (1) {
1071 s = *c; 1071 s = *c;
1072 get_token(c, &t, L_KEYWORD); 1072 get_token(c, &t, L_KEYWORD);
1073 1073
1074 err = 0; 1074 err = 0;
1075 switch (t.type) { 1075 switch (t.type) {
1076 case T_MENU: 1076 case T_MENU:
1077 err = parse_label_menu(c, cfg, label); 1077 err = parse_label_menu(c, cfg, label);
1078 break; 1078 break;
1079 1079
1080 case T_KERNEL: 1080 case T_KERNEL:
1081 case T_LINUX: 1081 case T_LINUX:
1082 err = parse_sliteral(c, &label->kernel); 1082 err = parse_sliteral(c, &label->kernel);
1083 break; 1083 break;
1084 1084
1085 case T_APPEND: 1085 case T_APPEND:
1086 err = parse_sliteral(c, &label->append); 1086 err = parse_sliteral(c, &label->append);
1087 if (label->initrd) 1087 if (label->initrd)
1088 break; 1088 break;
1089 s = strstr(label->append, "initrd="); 1089 s = strstr(label->append, "initrd=");
1090 if (!s) 1090 if (!s)
1091 break; 1091 break;
1092 s += 7; 1092 s += 7;
1093 len = (int)(strchr(s, ' ') - s); 1093 len = (int)(strchr(s, ' ') - s);
1094 label->initrd = malloc(len + 1); 1094 label->initrd = malloc(len + 1);
1095 strncpy(label->initrd, s, len); 1095 strncpy(label->initrd, s, len);
1096 label->initrd[len] = '\0'; 1096 label->initrd[len] = '\0';
1097 1097
1098 break; 1098 break;
1099 1099
1100 case T_INITRD: 1100 case T_INITRD:
1101 if (!label->initrd) 1101 if (!label->initrd)
1102 err = parse_sliteral(c, &label->initrd); 1102 err = parse_sliteral(c, &label->initrd);
1103 break; 1103 break;
1104 1104
1105 case T_FDT: 1105 case T_FDT:
1106 if (!label->fdt) 1106 if (!label->fdt)
1107 err = parse_sliteral(c, &label->fdt); 1107 err = parse_sliteral(c, &label->fdt);
1108 break; 1108 break;
1109 1109
1110 case T_LOCALBOOT: 1110 case T_LOCALBOOT:
1111 err = parse_integer(c, &label->localboot); 1111 err = parse_integer(c, &label->localboot);
1112 break; 1112 break;
1113 1113
1114 case T_EOL: 1114 case T_EOL:
1115 break; 1115 break;
1116 1116
1117 default: 1117 default:
1118 /* 1118 /*
1119 * put the token back! we don't want it - it's the end 1119 * put the token back! we don't want it - it's the end
1120 * of a label and whatever token this is, it's 1120 * of a label and whatever token this is, it's
1121 * something for the menu level context to handle. 1121 * something for the menu level context to handle.
1122 */ 1122 */
1123 *c = s; 1123 *c = s;
1124 return 1; 1124 return 1;
1125 } 1125 }
1126 1126
1127 if (err < 0) 1127 if (err < 0)
1128 return err; 1128 return err;
1129 } 1129 }
1130 } 1130 }
1131 1131
1132 /* 1132 /*
1133 * This 16 comes from the limit pxelinux imposes on nested includes. 1133 * This 16 comes from the limit pxelinux imposes on nested includes.
1134 * 1134 *
1135 * There is no reason at all we couldn't do more, but some limit helps prevent 1135 * There is no reason at all we couldn't do more, but some limit helps prevent
1136 * infinite (until crash occurs) recursion if a file tries to include itself. 1136 * infinite (until crash occurs) recursion if a file tries to include itself.
1137 */ 1137 */
1138 #define MAX_NEST_LEVEL 16 1138 #define MAX_NEST_LEVEL 16
1139 1139
1140 /* 1140 /*
1141 * Entry point for parsing a menu file. nest_level indicates how many times 1141 * Entry point for parsing a menu file. nest_level indicates how many times
1142 * we've nested in includes. It will be 1 for the top level menu file. 1142 * we've nested in includes. It will be 1 for the top level menu file.
1143 * 1143 *
1144 * Returns 1 on success, < 0 on error. 1144 * Returns 1 on success, < 0 on error.
1145 */ 1145 */
1146 static int parse_pxefile_top(char *p, struct pxe_menu *cfg, int nest_level) 1146 static int parse_pxefile_top(char *p, struct pxe_menu *cfg, int nest_level)
1147 { 1147 {
1148 struct token t; 1148 struct token t;
1149 char *s, *b, *label_name; 1149 char *s, *b, *label_name;
1150 int err; 1150 int err;
1151 1151
1152 b = p; 1152 b = p;
1153 1153
1154 if (nest_level > MAX_NEST_LEVEL) { 1154 if (nest_level > MAX_NEST_LEVEL) {
1155 printf("Maximum nesting (%d) exceeded\n", MAX_NEST_LEVEL); 1155 printf("Maximum nesting (%d) exceeded\n", MAX_NEST_LEVEL);
1156 return -EMLINK; 1156 return -EMLINK;
1157 } 1157 }
1158 1158
1159 while (1) { 1159 while (1) {
1160 s = p; 1160 s = p;
1161 1161
1162 get_token(&p, &t, L_KEYWORD); 1162 get_token(&p, &t, L_KEYWORD);
1163 1163
1164 err = 0; 1164 err = 0;
1165 switch (t.type) { 1165 switch (t.type) {
1166 case T_MENU: 1166 case T_MENU:
1167 err = parse_menu(&p, cfg, b, nest_level); 1167 err = parse_menu(&p, cfg, b, nest_level);
1168 break; 1168 break;
1169 1169
1170 case T_TIMEOUT: 1170 case T_TIMEOUT:
1171 err = parse_integer(&p, &cfg->timeout); 1171 err = parse_integer(&p, &cfg->timeout);
1172 break; 1172 break;
1173 1173
1174 case T_LABEL: 1174 case T_LABEL:
1175 err = parse_label(&p, cfg); 1175 err = parse_label(&p, cfg);
1176 break; 1176 break;
1177 1177
1178 case T_DEFAULT: 1178 case T_DEFAULT:
1179 err = parse_sliteral(&p, &label_name); 1179 err = parse_sliteral(&p, &label_name);
1180 1180
1181 if (label_name) { 1181 if (label_name) {
1182 if (cfg->default_label) 1182 if (cfg->default_label)
1183 free(cfg->default_label); 1183 free(cfg->default_label);
1184 1184
1185 cfg->default_label = label_name; 1185 cfg->default_label = label_name;
1186 } 1186 }
1187 1187
1188 break; 1188 break;
1189 1189
1190 case T_INCLUDE: 1190 case T_INCLUDE:
1191 err = handle_include(&p, b + ALIGN(strlen(b), 4), cfg, 1191 err = handle_include(&p, b + ALIGN(strlen(b), 4), cfg,
1192 nest_level + 1); 1192 nest_level + 1);
1193 break; 1193 break;
1194 1194
1195 case T_PROMPT: 1195 case T_PROMPT:
1196 err = parse_integer(&p, &cfg->prompt); 1196 err = parse_integer(&p, &cfg->prompt);
1197 break; 1197 break;
1198 1198
1199 case T_EOL: 1199 case T_EOL:
1200 break; 1200 break;
1201 1201
1202 case T_EOF: 1202 case T_EOF:
1203 return 1; 1203 return 1;
1204 1204
1205 default: 1205 default:
1206 printf("Ignoring unknown command: %.*s\n", 1206 printf("Ignoring unknown command: %.*s\n",
1207 (int)(p - s), s); 1207 (int)(p - s), s);
1208 eol_or_eof(&p); 1208 eol_or_eof(&p);
1209 } 1209 }
1210 1210
1211 if (err < 0) 1211 if (err < 0)
1212 return err; 1212 return err;
1213 } 1213 }
1214 } 1214 }
1215 1215
1216 /* 1216 /*
1217 * Free the memory used by a pxe_menu and its labels. 1217 * Free the memory used by a pxe_menu and its labels.
1218 */ 1218 */
1219 static void destroy_pxe_menu(struct pxe_menu *cfg) 1219 static void destroy_pxe_menu(struct pxe_menu *cfg)
1220 { 1220 {
1221 struct list_head *pos, *n; 1221 struct list_head *pos, *n;
1222 struct pxe_label *label; 1222 struct pxe_label *label;
1223 1223
1224 if (cfg->title) 1224 if (cfg->title)
1225 free(cfg->title); 1225 free(cfg->title);
1226 1226
1227 if (cfg->default_label) 1227 if (cfg->default_label)
1228 free(cfg->default_label); 1228 free(cfg->default_label);
1229 1229
1230 list_for_each_safe(pos, n, &cfg->labels) { 1230 list_for_each_safe(pos, n, &cfg->labels) {
1231 label = list_entry(pos, struct pxe_label, list); 1231 label = list_entry(pos, struct pxe_label, list);
1232 1232
1233 label_destroy(label); 1233 label_destroy(label);
1234 } 1234 }
1235 1235
1236 free(cfg); 1236 free(cfg);
1237 } 1237 }
1238 1238
1239 /* 1239 /*
1240 * Entry point for parsing a pxe file. This is only used for the top level 1240 * Entry point for parsing a pxe file. This is only used for the top level
1241 * file. 1241 * file.
1242 * 1242 *
1243 * Returns NULL if there is an error, otherwise, returns a pointer to a 1243 * Returns NULL if there is an error, otherwise, returns a pointer to a
1244 * pxe_menu struct populated with the results of parsing the pxe file (and any 1244 * pxe_menu struct populated with the results of parsing the pxe file (and any
1245 * files it includes). The resulting pxe_menu struct can be free()'d by using 1245 * files it includes). The resulting pxe_menu struct can be free()'d by using
1246 * the destroy_pxe_menu() function. 1246 * the destroy_pxe_menu() function.
1247 */ 1247 */
1248 static struct pxe_menu *parse_pxefile(char *menucfg) 1248 static struct pxe_menu *parse_pxefile(char *menucfg)
1249 { 1249 {
1250 struct pxe_menu *cfg; 1250 struct pxe_menu *cfg;
1251 1251
1252 cfg = malloc(sizeof(struct pxe_menu)); 1252 cfg = malloc(sizeof(struct pxe_menu));
1253 1253
1254 if (!cfg) 1254 if (!cfg)
1255 return NULL; 1255 return NULL;
1256 1256
1257 memset(cfg, 0, sizeof(struct pxe_menu)); 1257 memset(cfg, 0, sizeof(struct pxe_menu));
1258 1258
1259 INIT_LIST_HEAD(&cfg->labels); 1259 INIT_LIST_HEAD(&cfg->labels);
1260 1260
1261 if (parse_pxefile_top(menucfg, cfg, 1) < 0) { 1261 if (parse_pxefile_top(menucfg, cfg, 1) < 0) {
1262 destroy_pxe_menu(cfg); 1262 destroy_pxe_menu(cfg);
1263 return NULL; 1263 return NULL;
1264 } 1264 }
1265 1265
1266 return cfg; 1266 return cfg;
1267 } 1267 }
1268 1268
1269 /* 1269 /*
1270 * Converts a pxe_menu struct into a menu struct for use with U-boot's generic 1270 * Converts a pxe_menu struct into a menu struct for use with U-boot's generic
1271 * menu code. 1271 * menu code.
1272 */ 1272 */
1273 static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg) 1273 static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
1274 { 1274 {
1275 struct pxe_label *label; 1275 struct pxe_label *label;
1276 struct list_head *pos; 1276 struct list_head *pos;
1277 struct menu *m; 1277 struct menu *m;
1278 int err; 1278 int err;
1279 1279
1280 /* 1280 /*
1281 * Create a menu and add items for all the labels. 1281 * Create a menu and add items for all the labels.
1282 */ 1282 */
1283 m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print); 1283 m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print,
1284 NULL, NULL);
1284 1285
1285 if (!m) 1286 if (!m)
1286 return NULL; 1287 return NULL;
1287 1288
1288 list_for_each(pos, &cfg->labels) { 1289 list_for_each(pos, &cfg->labels) {
1289 label = list_entry(pos, struct pxe_label, list); 1290 label = list_entry(pos, struct pxe_label, list);
1290 1291
1291 if (menu_item_add(m, label->name, label) != 1) { 1292 if (menu_item_add(m, label->name, label) != 1) {
1292 menu_destroy(m); 1293 menu_destroy(m);
1293 return NULL; 1294 return NULL;
1294 } 1295 }
1295 } 1296 }
1296 1297
1297 /* 1298 /*
1298 * After we've created items for each label in the menu, set the 1299 * After we've created items for each label in the menu, set the
1299 * menu's default label if one was specified. 1300 * menu's default label if one was specified.
1300 */ 1301 */
1301 if (cfg->default_label) { 1302 if (cfg->default_label) {
1302 err = menu_default_set(m, cfg->default_label); 1303 err = menu_default_set(m, cfg->default_label);
1303 if (err != 1) { 1304 if (err != 1) {
1304 if (err != -ENOENT) { 1305 if (err != -ENOENT) {
1305 menu_destroy(m); 1306 menu_destroy(m);
1306 return NULL; 1307 return NULL;
1307 } 1308 }
1308 1309
1309 printf("Missing default: %s\n", cfg->default_label); 1310 printf("Missing default: %s\n", cfg->default_label);
1310 } 1311 }
1311 } 1312 }
1312 1313
1313 return m; 1314 return m;
1314 } 1315 }
1315 1316
1316 /* 1317 /*
1317 * Try to boot any labels we have yet to attempt to boot. 1318 * Try to boot any labels we have yet to attempt to boot.
1318 */ 1319 */
1319 static void boot_unattempted_labels(struct pxe_menu *cfg) 1320 static void boot_unattempted_labels(struct pxe_menu *cfg)
1320 { 1321 {
1321 struct list_head *pos; 1322 struct list_head *pos;
1322 struct pxe_label *label; 1323 struct pxe_label *label;
1323 1324
1324 list_for_each(pos, &cfg->labels) { 1325 list_for_each(pos, &cfg->labels) {
1325 label = list_entry(pos, struct pxe_label, list); 1326 label = list_entry(pos, struct pxe_label, list);
1326 1327
1327 if (!label->attempted) 1328 if (!label->attempted)
1328 label_boot(label); 1329 label_boot(label);
1329 } 1330 }
1330 } 1331 }
1331 1332
1332 /* 1333 /*
1333 * Boot the system as prescribed by a pxe_menu. 1334 * Boot the system as prescribed by a pxe_menu.
1334 * 1335 *
1335 * Use the menu system to either get the user's choice or the default, based 1336 * Use the menu system to either get the user's choice or the default, based
1336 * on config or user input. If there is no default or user's choice, 1337 * on config or user input. If there is no default or user's choice,
1337 * attempted to boot labels in the order they were given in pxe files. 1338 * attempted to boot labels in the order they were given in pxe files.
1338 * If the default or user's choice fails to boot, attempt to boot other 1339 * If the default or user's choice fails to boot, attempt to boot other
1339 * labels in the order they were given in pxe files. 1340 * labels in the order they were given in pxe files.
1340 * 1341 *
1341 * If this function returns, there weren't any labels that successfully 1342 * If this function returns, there weren't any labels that successfully
1342 * booted, or the user interrupted the menu selection via ctrl+c. 1343 * booted, or the user interrupted the menu selection via ctrl+c.
1343 */ 1344 */
1344 static void handle_pxe_menu(struct pxe_menu *cfg) 1345 static void handle_pxe_menu(struct pxe_menu *cfg)
1345 { 1346 {
1346 void *choice; 1347 void *choice;
1347 struct menu *m; 1348 struct menu *m;
1348 int err; 1349 int err;
1349 1350
1350 m = pxe_menu_to_menu(cfg); 1351 m = pxe_menu_to_menu(cfg);
1351 if (!m) 1352 if (!m)
1352 return; 1353 return;
1353 1354
1354 err = menu_get_choice(m, &choice); 1355 err = menu_get_choice(m, &choice);
1355 1356
1356 menu_destroy(m); 1357 menu_destroy(m);
1357 1358
1358 /* 1359 /*
1359 * err == 1 means we got a choice back from menu_get_choice. 1360 * err == 1 means we got a choice back from menu_get_choice.
1360 * 1361 *
1361 * err == -ENOENT if the menu was setup to select the default but no 1362 * err == -ENOENT if the menu was setup to select the default but no
1362 * default was set. in that case, we should continue trying to boot 1363 * default was set. in that case, we should continue trying to boot
1363 * labels that haven't been attempted yet. 1364 * labels that haven't been attempted yet.
1364 * 1365 *
1365 * otherwise, the user interrupted or there was some other error and 1366 * otherwise, the user interrupted or there was some other error and
1366 * we give up. 1367 * we give up.
1367 */ 1368 */
1368 1369
1369 if (err == 1) 1370 if (err == 1)
1370 label_boot(choice); 1371 label_boot(choice);
1371 else if (err != -ENOENT) 1372 else if (err != -ENOENT)
1372 return; 1373 return;
1373 1374
1374 boot_unattempted_labels(cfg); 1375 boot_unattempted_labels(cfg);
1375 } 1376 }
1376 1377
1377 /* 1378 /*
1378 * Boots a system using a pxe file 1379 * Boots a system using a pxe file
1379 * 1380 *
1380 * Returns 0 on success, 1 on error. 1381 * Returns 0 on success, 1 on error.
1381 */ 1382 */
1382 static int 1383 static int
1383 do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1384 do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1384 { 1385 {
1385 unsigned long pxefile_addr_r; 1386 unsigned long pxefile_addr_r;
1386 struct pxe_menu *cfg; 1387 struct pxe_menu *cfg;
1387 char *pxefile_addr_str; 1388 char *pxefile_addr_str;
1388 1389
1389 do_getfile = do_get_tftp; 1390 do_getfile = do_get_tftp;
1390 1391
1391 if (argc == 1) { 1392 if (argc == 1) {
1392 pxefile_addr_str = from_env("pxefile_addr_r"); 1393 pxefile_addr_str = from_env("pxefile_addr_r");
1393 if (!pxefile_addr_str) 1394 if (!pxefile_addr_str)
1394 return 1; 1395 return 1;
1395 1396
1396 } else if (argc == 2) { 1397 } else if (argc == 2) {
1397 pxefile_addr_str = argv[1]; 1398 pxefile_addr_str = argv[1];
1398 } else { 1399 } else {
1399 return CMD_RET_USAGE; 1400 return CMD_RET_USAGE;
1400 } 1401 }
1401 1402
1402 if (strict_strtoul(pxefile_addr_str, 16, &pxefile_addr_r) < 0) { 1403 if (strict_strtoul(pxefile_addr_str, 16, &pxefile_addr_r) < 0) {
1403 printf("Invalid pxefile address: %s\n", pxefile_addr_str); 1404 printf("Invalid pxefile address: %s\n", pxefile_addr_str);
1404 return 1; 1405 return 1;
1405 } 1406 }
1406 1407
1407 cfg = parse_pxefile((char *)(pxefile_addr_r)); 1408 cfg = parse_pxefile((char *)(pxefile_addr_r));
1408 1409
1409 if (cfg == NULL) { 1410 if (cfg == NULL) {
1410 printf("Error parsing config file\n"); 1411 printf("Error parsing config file\n");
1411 return 1; 1412 return 1;
1412 } 1413 }
1413 1414
1414 handle_pxe_menu(cfg); 1415 handle_pxe_menu(cfg);
1415 1416
1416 destroy_pxe_menu(cfg); 1417 destroy_pxe_menu(cfg);
1417 1418
1418 return 0; 1419 return 0;
1419 } 1420 }
1420 1421
1421 static cmd_tbl_t cmd_pxe_sub[] = { 1422 static cmd_tbl_t cmd_pxe_sub[] = {
1422 U_BOOT_CMD_MKENT(get, 1, 1, do_pxe_get, "", ""), 1423 U_BOOT_CMD_MKENT(get, 1, 1, do_pxe_get, "", ""),
1423 U_BOOT_CMD_MKENT(boot, 2, 1, do_pxe_boot, "", "") 1424 U_BOOT_CMD_MKENT(boot, 2, 1, do_pxe_boot, "", "")
1424 }; 1425 };
1425 1426
1426 int do_pxe(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1427 int do_pxe(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1427 { 1428 {
1428 cmd_tbl_t *cp; 1429 cmd_tbl_t *cp;
1429 1430
1430 if (argc < 2) 1431 if (argc < 2)
1431 return CMD_RET_USAGE; 1432 return CMD_RET_USAGE;
1432 1433
1433 /* drop initial "pxe" arg */ 1434 /* drop initial "pxe" arg */
1434 argc--; 1435 argc--;
1435 argv++; 1436 argv++;
1436 1437
1437 cp = find_cmd_tbl(argv[0], cmd_pxe_sub, ARRAY_SIZE(cmd_pxe_sub)); 1438 cp = find_cmd_tbl(argv[0], cmd_pxe_sub, ARRAY_SIZE(cmd_pxe_sub));
1438 1439
1439 if (cp) 1440 if (cp)
1440 return cp->cmd(cmdtp, flag, argc, argv); 1441 return cp->cmd(cmdtp, flag, argc, argv);
1441 1442
1442 return CMD_RET_USAGE; 1443 return CMD_RET_USAGE;
1443 } 1444 }
1444 1445
1445 U_BOOT_CMD( 1446 U_BOOT_CMD(
1446 pxe, 3, 1, do_pxe, 1447 pxe, 3, 1, do_pxe,
1447 "commands to get and boot from pxe files", 1448 "commands to get and boot from pxe files",
1448 "get - try to retrieve a pxe file using tftp\npxe " 1449 "get - try to retrieve a pxe file using tftp\npxe "
1449 "boot [pxefile_addr_r] - boot from the pxe file at pxefile_addr_r\n" 1450 "boot [pxefile_addr_r] - boot from the pxe file at pxefile_addr_r\n"
1450 ); 1451 );
1451 1452
1452 /* 1453 /*
1453 * Boots a system using a local disk syslinux/extlinux file 1454 * Boots a system using a local disk syslinux/extlinux file
1454 * 1455 *
1455 * Returns 0 on success, 1 on error. 1456 * Returns 0 on success, 1 on error.
1456 */ 1457 */
1457 int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1458 int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1458 { 1459 {
1459 unsigned long pxefile_addr_r; 1460 unsigned long pxefile_addr_r;
1460 struct pxe_menu *cfg; 1461 struct pxe_menu *cfg;
1461 char *pxefile_addr_str; 1462 char *pxefile_addr_str;
1462 char *filename; 1463 char *filename;
1463 int prompt = 0; 1464 int prompt = 0;
1464 1465
1465 if (strstr(argv[1], "-p")) { 1466 if (strstr(argv[1], "-p")) {
1466 prompt = 1; 1467 prompt = 1;
1467 argc--; 1468 argc--;
1468 argv++; 1469 argv++;
1469 } 1470 }
1470 1471
1471 if (argc < 4) 1472 if (argc < 4)
1472 return cmd_usage(cmdtp); 1473 return cmd_usage(cmdtp);
1473 1474
1474 if (argc < 5) { 1475 if (argc < 5) {
1475 pxefile_addr_str = from_env("pxefile_addr_r"); 1476 pxefile_addr_str = from_env("pxefile_addr_r");
1476 if (!pxefile_addr_str) 1477 if (!pxefile_addr_str)
1477 return 1; 1478 return 1;
1478 } else { 1479 } else {
1479 pxefile_addr_str = argv[4]; 1480 pxefile_addr_str = argv[4];
1480 } 1481 }
1481 1482
1482 if (argc < 6) 1483 if (argc < 6)
1483 filename = getenv("bootfile"); 1484 filename = getenv("bootfile");
1484 else { 1485 else {
1485 filename = argv[5]; 1486 filename = argv[5];
1486 setenv("bootfile", filename); 1487 setenv("bootfile", filename);
1487 } 1488 }
1488 1489
1489 if (strstr(argv[3], "ext2")) 1490 if (strstr(argv[3], "ext2"))
1490 do_getfile = do_get_ext2; 1491 do_getfile = do_get_ext2;
1491 else if (strstr(argv[3], "fat")) 1492 else if (strstr(argv[3], "fat"))
1492 do_getfile = do_get_fat; 1493 do_getfile = do_get_fat;
1493 else { 1494 else {
1494 printf("Invalid filesystem: %s\n", argv[3]); 1495 printf("Invalid filesystem: %s\n", argv[3]);
1495 return 1; 1496 return 1;
1496 } 1497 }
1497 fs_argv[1] = argv[1]; 1498 fs_argv[1] = argv[1];
1498 fs_argv[2] = argv[2]; 1499 fs_argv[2] = argv[2];
1499 1500
1500 if (strict_strtoul(pxefile_addr_str, 16, &pxefile_addr_r) < 0) { 1501 if (strict_strtoul(pxefile_addr_str, 16, &pxefile_addr_r) < 0) {
1501 printf("Invalid pxefile address: %s\n", pxefile_addr_str); 1502 printf("Invalid pxefile address: %s\n", pxefile_addr_str);
1502 return 1; 1503 return 1;
1503 } 1504 }
1504 1505
1505 if (get_pxe_file(filename, (void *)pxefile_addr_r) < 0) { 1506 if (get_pxe_file(filename, (void *)pxefile_addr_r) < 0) {
1506 printf("Error reading config file\n"); 1507 printf("Error reading config file\n");
1507 return 1; 1508 return 1;
1508 } 1509 }
1509 1510
1510 cfg = parse_pxefile((char *)(pxefile_addr_r)); 1511 cfg = parse_pxefile((char *)(pxefile_addr_r));
1511 1512
1512 if (cfg == NULL) { 1513 if (cfg == NULL) {
1513 printf("Error parsing config file\n"); 1514 printf("Error parsing config file\n");
1514 return 1; 1515 return 1;
1515 } 1516 }
1516 1517
1517 if (prompt) 1518 if (prompt)
1518 cfg->prompt = 1; 1519 cfg->prompt = 1;
1519 1520
1520 handle_pxe_menu(cfg); 1521 handle_pxe_menu(cfg);
1521 1522
1522 destroy_pxe_menu(cfg); 1523 destroy_pxe_menu(cfg);
1523 1524
1524 return 0; 1525 return 0;
1525 } 1526 }
1526 1527
1527 U_BOOT_CMD( 1528 U_BOOT_CMD(
1528 sysboot, 7, 1, do_sysboot, 1529 sysboot, 7, 1, do_sysboot,
1529 "command to get and boot from syslinux files", 1530 "command to get and boot from syslinux files",
1530 "[-p] <interface> <dev[:part]> <ext2|fat> [addr] [filename]\n" 1531 "[-p] <interface> <dev[:part]> <ext2|fat> [addr] [filename]\n"
1531 " - load and parse syslinux menu file 'filename' from ext2 or fat\n" 1532 " - load and parse syslinux menu file 'filename' from ext2 or fat\n"
1532 " filesystem on 'dev' on 'interface' to address 'addr'" 1533 " filesystem on 'dev' on 'interface' to address 'addr'"
1533 ); 1534 );
1534 1535
1 /* 1 /*
2 * Copyright 2010-2011 Calxeda, Inc. 2 * Copyright 2010-2011 Calxeda, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free 5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option) 6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version. 7 * any later version.
8 * 8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT 9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details. 12 * more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License along with 14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>. 15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include <common.h> 18 #include <common.h>
19 #include <malloc.h> 19 #include <malloc.h>
20 #include <errno.h> 20 #include <errno.h>
21 #include <linux/list.h> 21 #include <linux/list.h>
22 22
23 #include "menu.h" 23 #include "menu.h"
24 24
25 /* 25 /*
26 * Internally, each item in a menu is represented by a struct menu_item. 26 * Internally, each item in a menu is represented by a struct menu_item.
27 * 27 *
28 * These items will be alloc'd and initialized by menu_item_add and destroyed 28 * These items will be alloc'd and initialized by menu_item_add and destroyed
29 * by menu_item_destroy, and the consumer of the interface never sees that 29 * by menu_item_destroy, and the consumer of the interface never sees that
30 * this struct is used at all. 30 * this struct is used at all.
31 */ 31 */
32 struct menu_item { 32 struct menu_item {
33 char *key; 33 char *key;
34 void *data; 34 void *data;
35 struct list_head list; 35 struct list_head list;
36 }; 36 };
37 37
38 /* 38 /*
39 * The menu is composed of a list of items along with settings and callbacks 39 * The menu is composed of a list of items along with settings and callbacks
40 * provided by the user. An incomplete definition of this struct is available 40 * provided by the user. An incomplete definition of this struct is available
41 * in menu.h, but the full definition is here to prevent consumers from 41 * in menu.h, but the full definition is here to prevent consumers from
42 * relying on its contents. 42 * relying on its contents.
43 */ 43 */
44 struct menu { 44 struct menu {
45 struct menu_item *default_item; 45 struct menu_item *default_item;
46 int timeout; 46 int timeout;
47 char *title; 47 char *title;
48 int prompt; 48 int prompt;
49 void (*item_data_print)(void *); 49 void (*item_data_print)(void *);
50 char *(*item_choice)(void *);
51 void *item_choice_data;
50 struct list_head items; 52 struct list_head items;
51 }; 53 };
52 54
53 /* 55 /*
54 * An iterator function for menu items. callback will be called for each item 56 * An iterator function for menu items. callback will be called for each item
55 * in m, with m, a pointer to the item, and extra being passed to callback. If 57 * in m, with m, a pointer to the item, and extra being passed to callback. If
56 * callback returns a value other than NULL, iteration stops and the value 58 * callback returns a value other than NULL, iteration stops and the value
57 * return by callback is returned from menu_items_iter. This allows it to be 59 * return by callback is returned from menu_items_iter. This allows it to be
58 * used for search type operations. It is also safe for callback to remove the 60 * used for search type operations. It is also safe for callback to remove the
59 * item from the list of items. 61 * item from the list of items.
60 */ 62 */
61 static inline void *menu_items_iter(struct menu *m, 63 static inline void *menu_items_iter(struct menu *m,
62 void *(*callback)(struct menu *, struct menu_item *, void *), 64 void *(*callback)(struct menu *, struct menu_item *, void *),
63 void *extra) 65 void *extra)
64 { 66 {
65 struct list_head *pos, *n; 67 struct list_head *pos, *n;
66 struct menu_item *item; 68 struct menu_item *item;
67 void *ret; 69 void *ret;
68 70
69 list_for_each_safe(pos, n, &m->items) { 71 list_for_each_safe(pos, n, &m->items) {
70 item = list_entry(pos, struct menu_item, list); 72 item = list_entry(pos, struct menu_item, list);
71 73
72 ret = callback(m, item, extra); 74 ret = callback(m, item, extra);
73 75
74 if (ret) 76 if (ret)
75 return ret; 77 return ret;
76 } 78 }
77 79
78 return NULL; 80 return NULL;
79 } 81 }
80 82
81 /* 83 /*
82 * Print a menu_item. If the consumer provided an item_data_print function 84 * Print a menu_item. If the consumer provided an item_data_print function
83 * when creating the menu, call it with a pointer to the item's private data. 85 * when creating the menu, call it with a pointer to the item's private data.
84 * Otherwise, print the key of the item. 86 * Otherwise, print the key of the item.
85 */ 87 */
86 static inline void *menu_item_print(struct menu *m, 88 static inline void *menu_item_print(struct menu *m,
87 struct menu_item *item, 89 struct menu_item *item,
88 void *extra) 90 void *extra)
89 { 91 {
90 if (!m->item_data_print) { 92 if (!m->item_data_print) {
91 puts(item->key); 93 puts(item->key);
92 putc('\n'); 94 putc('\n');
93 } else { 95 } else {
94 m->item_data_print(item->data); 96 m->item_data_print(item->data);
95 } 97 }
96 98
97 return NULL; 99 return NULL;
98 } 100 }
99 101
100 /* 102 /*
101 * Free the memory used by a menu item. This includes the memory used by its 103 * Free the memory used by a menu item. This includes the memory used by its
102 * key. 104 * key.
103 */ 105 */
104 static inline void *menu_item_destroy(struct menu *m, 106 static inline void *menu_item_destroy(struct menu *m,
105 struct menu_item *item, 107 struct menu_item *item,
106 void *extra) 108 void *extra)
107 { 109 {
108 if (item->key) 110 if (item->key)
109 free(item->key); 111 free(item->key);
110 112
111 free(item); 113 free(item);
112 114
113 return NULL; 115 return NULL;
114 } 116 }
115 117
116 void __menu_display_statusline(struct menu *m) 118 void __menu_display_statusline(struct menu *m)
117 { 119 {
118 return; 120 return;
119 } 121 }
120 void menu_display_statusline(struct menu *m) 122 void menu_display_statusline(struct menu *m)
121 __attribute__ ((weak, alias("__menu_display_statusline"))); 123 __attribute__ ((weak, alias("__menu_display_statusline")));
122 124
123 /* 125 /*
124 * Display a menu so the user can make a choice of an item. First display its 126 * Display a menu so the user can make a choice of an item. First display its
125 * title, if any, and then each item in the menu. 127 * title, if any, and then each item in the menu.
126 */ 128 */
127 static inline void menu_display(struct menu *m) 129 static inline void menu_display(struct menu *m)
128 { 130 {
129 if (m->title) { 131 if (m->title) {
130 puts(m->title); 132 puts(m->title);
131 putc('\n'); 133 putc('\n');
132 } 134 }
133 menu_display_statusline(m); 135 menu_display_statusline(m);
134 136
135 menu_items_iter(m, menu_item_print, NULL); 137 menu_items_iter(m, menu_item_print, NULL);
136 } 138 }
137 139
138 /* 140 /*
139 * Check if an item's key matches a provided string, pointed to by extra. If 141 * Check if an item's key matches a provided string, pointed to by extra. If
140 * extra is NULL, an item with a NULL key will match. Otherwise, the item's 142 * extra is NULL, an item with a NULL key will match. Otherwise, the item's
141 * key has to match according to strcmp. 143 * key has to match according to strcmp.
142 * 144 *
143 * This is called via menu_items_iter, so it returns a pointer to the item if 145 * This is called via menu_items_iter, so it returns a pointer to the item if
144 * the key matches, and returns NULL otherwise. 146 * the key matches, and returns NULL otherwise.
145 */ 147 */
146 static inline void *menu_item_key_match(struct menu *m, 148 static inline void *menu_item_key_match(struct menu *m,
147 struct menu_item *item, void *extra) 149 struct menu_item *item, void *extra)
148 { 150 {
149 char *item_key = extra; 151 char *item_key = extra;
150 152
151 if (!item_key || !item->key) { 153 if (!item_key || !item->key) {
152 if (item_key == item->key) 154 if (item_key == item->key)
153 return item; 155 return item;
154 156
155 return NULL; 157 return NULL;
156 } 158 }
157 159
158 if (strcmp(item->key, item_key) == 0) 160 if (strcmp(item->key, item_key) == 0)
159 return item; 161 return item;
160 162
161 return NULL; 163 return NULL;
162 } 164 }
163 165
164 /* 166 /*
165 * Find the first item with a key matching item_key, if any exists. 167 * Find the first item with a key matching item_key, if any exists.
166 */ 168 */
167 static inline struct menu_item *menu_item_by_key(struct menu *m, 169 static inline struct menu_item *menu_item_by_key(struct menu *m,
168 char *item_key) 170 char *item_key)
169 { 171 {
170 return menu_items_iter(m, menu_item_key_match, item_key); 172 return menu_items_iter(m, menu_item_key_match, item_key);
171 } 173 }
172 174
173 /* 175 /*
174 * Set *choice to point to the default item's data, if any default item was 176 * Set *choice to point to the default item's data, if any default item was
175 * set, and returns 1. If no default item was set, returns -ENOENT. 177 * set, and returns 1. If no default item was set, returns -ENOENT.
176 */ 178 */
177 static inline int menu_default_choice(struct menu *m, void **choice) 179 int menu_default_choice(struct menu *m, void **choice)
178 { 180 {
179 if (m->default_item) { 181 if (m->default_item) {
180 *choice = m->default_item->data; 182 *choice = m->default_item->data;
181 return 1; 183 return 1;
182 } 184 }
183 185
184 return -ENOENT; 186 return -ENOENT;
185 } 187 }
186 188
187 /* 189 /*
188 * Displays the menu and asks the user to choose an item. *choice will point 190 * Displays the menu and asks the user to choose an item. *choice will point
189 * to the private data of the item the user chooses. The user makes a choice 191 * to the private data of the item the user chooses. The user makes a choice
190 * by inputting a string matching the key of an item. Invalid choices will 192 * by inputting a string matching the key of an item. Invalid choices will
191 * cause the user to be prompted again, repeatedly, until the user makes a 193 * cause the user to be prompted again, repeatedly, until the user makes a
192 * valid choice. The user can exit the menu without making a choice via ^c. 194 * valid choice. The user can exit the menu without making a choice via ^c.
193 * 195 *
194 * Returns 1 if the user made a choice, or -EINTR if they bail via ^c. 196 * Returns 1 if the user made a choice, or -EINTR if they bail via ^c.
195 */ 197 */
196 static inline int menu_interactive_choice(struct menu *m, void **choice) 198 static inline int menu_interactive_choice(struct menu *m, void **choice)
197 { 199 {
198 char cbuf[CONFIG_SYS_CBSIZE]; 200 char cbuf[CONFIG_SYS_CBSIZE];
199 struct menu_item *choice_item = NULL; 201 struct menu_item *choice_item = NULL;
200 int readret; 202 int readret;
201 203
202 while (!choice_item) { 204 while (!choice_item) {
203 cbuf[0] = '\0'; 205 cbuf[0] = '\0';
204 206
205 menu_display(m); 207 menu_display(m);
206 208
207 readret = readline_into_buffer("Enter choice: ", cbuf, 209 if (!m->item_choice) {
208 m->timeout / 10); 210 readret = readline_into_buffer("Enter choice: ", cbuf,
211 m->timeout / 10);
209 212
210 if (readret >= 0) { 213 if (readret >= 0) {
211 choice_item = menu_item_by_key(m, cbuf); 214 choice_item = menu_item_by_key(m, cbuf);
212 215 if (!choice_item)
213 if (!choice_item) { 216 printf("%s not found\n", cbuf);
214 printf("%s not found\n", cbuf); 217 } else {
215 m->timeout = 0; 218 return menu_default_choice(m, choice);
216 } 219 }
217 } else 220 } else {
218 return menu_default_choice(m, choice); 221 char *key = m->item_choice(m->item_choice_data);
222
223 if (key)
224 choice_item = menu_item_by_key(m, key);
225 }
226
227 if (!choice_item)
228 m->timeout = 0;
219 } 229 }
220 230
221 *choice = choice_item->data; 231 *choice = choice_item->data;
222 232
223 return 1; 233 return 1;
224 } 234 }
225 235
226 /* 236 /*
227 * menu_default_set() - Sets the default choice for the menu. This is safe to 237 * menu_default_set() - Sets the default choice for the menu. This is safe to
228 * call more than once on a menu. 238 * call more than once on a menu.
229 * 239 *
230 * m - Points to a menu created by menu_create(). 240 * m - Points to a menu created by menu_create().
231 * 241 *
232 * item_key - Points to a string that, when compared using strcmp, matches the 242 * item_key - Points to a string that, when compared using strcmp, matches the
233 * key for an existing item in the menu. 243 * key for an existing item in the menu.
234 * 244 *
235 * Returns 1 if successful, -EINVAL if m is NULL, or -ENOENT if no item with a 245 * Returns 1 if successful, -EINVAL if m is NULL, or -ENOENT if no item with a
236 * key matching item_key is found. 246 * key matching item_key is found.
237 */ 247 */
238 int menu_default_set(struct menu *m, char *item_key) 248 int menu_default_set(struct menu *m, char *item_key)
239 { 249 {
240 struct menu_item *item; 250 struct menu_item *item;
241 251
242 if (!m) 252 if (!m)
243 return -EINVAL; 253 return -EINVAL;
244 254
245 item = menu_item_by_key(m, item_key); 255 item = menu_item_by_key(m, item_key);
246 256
247 if (!item) 257 if (!item)
248 return -ENOENT; 258 return -ENOENT;
249 259
250 m->default_item = item; 260 m->default_item = item;
251 261
252 return 1; 262 return 1;
253 } 263 }
254 264
255 /* 265 /*
256 * menu_get_choice() - Returns the user's selected menu entry, or the default 266 * menu_get_choice() - Returns the user's selected menu entry, or the default
257 * if the menu is set to not prompt or the timeout expires. This is safe to 267 * if the menu is set to not prompt or the timeout expires. This is safe to
258 * call more than once. 268 * call more than once.
259 * 269 *
260 * m - Points to a menu created by menu_create(). 270 * m - Points to a menu created by menu_create().
261 * 271 *
262 * choice - Points to a location that will store a pointer to the selected 272 * choice - Points to a location that will store a pointer to the selected
263 * menu item. If no item is selected or there is an error, no value will be 273 * menu item. If no item is selected or there is an error, no value will be
264 * written at the location it points to. 274 * written at the location it points to.
265 * 275 *
266 * Returns 1 if successful, -EINVAL if m or choice is NULL, -ENOENT if no 276 * Returns 1 if successful, -EINVAL if m or choice is NULL, -ENOENT if no
267 * default has been set and the menu is set to not prompt or the timeout 277 * default has been set and the menu is set to not prompt or the timeout
268 * expires, or -EINTR if the user exits the menu via ^c. 278 * expires, or -EINTR if the user exits the menu via ^c.
269 */ 279 */
270 int menu_get_choice(struct menu *m, void **choice) 280 int menu_get_choice(struct menu *m, void **choice)
271 { 281 {
272 if (!m || !choice) 282 if (!m || !choice)
273 return -EINVAL; 283 return -EINVAL;
274 284
275 if (!m->prompt) 285 if (!m->prompt)
276 return menu_default_choice(m, choice); 286 return menu_default_choice(m, choice);
277 287
278 return menu_interactive_choice(m, choice); 288 return menu_interactive_choice(m, choice);
279 } 289 }
280 290
281 /* 291 /*
282 * menu_item_add() - Adds or replaces a menu item. Note that this replaces the 292 * menu_item_add() - Adds or replaces a menu item. Note that this replaces the
283 * data of an item if it already exists, but doesn't change the order of the 293 * data of an item if it already exists, but doesn't change the order of the
284 * item. 294 * item.
285 * 295 *
286 * m - Points to a menu created by menu_create(). 296 * m - Points to a menu created by menu_create().
287 * 297 *
288 * item_key - Points to a string that will uniquely identify the item. The 298 * item_key - Points to a string that will uniquely identify the item. The
289 * string will be copied to internal storage, and is safe to discard after 299 * string will be copied to internal storage, and is safe to discard after
290 * passing to menu_item_add. 300 * passing to menu_item_add.
291 * 301 *
292 * item_data - An opaque pointer associated with an item. It is never 302 * item_data - An opaque pointer associated with an item. It is never
293 * dereferenced internally, but will be passed to the item_data_print, and 303 * dereferenced internally, but will be passed to the item_data_print, and
294 * will be returned from menu_get_choice if the menu item is selected. 304 * will be returned from menu_get_choice if the menu item is selected.
295 * 305 *
296 * Returns 1 if successful, -EINVAL if m is NULL, or -ENOMEM if there is 306 * Returns 1 if successful, -EINVAL if m is NULL, or -ENOMEM if there is
297 * insufficient memory to add the menu item. 307 * insufficient memory to add the menu item.
298 */ 308 */
299 int menu_item_add(struct menu *m, char *item_key, void *item_data) 309 int menu_item_add(struct menu *m, char *item_key, void *item_data)
300 { 310 {
301 struct menu_item *item; 311 struct menu_item *item;
302 312
303 if (!m) 313 if (!m)
304 return -EINVAL; 314 return -EINVAL;
305 315
306 item = menu_item_by_key(m, item_key); 316 item = menu_item_by_key(m, item_key);
307 317
308 if (item) { 318 if (item) {
309 item->data = item_data; 319 item->data = item_data;
310 return 1; 320 return 1;
311 } 321 }
312 322
313 item = malloc(sizeof *item); 323 item = malloc(sizeof *item);
314 if (!item) 324 if (!item)
315 return -ENOMEM; 325 return -ENOMEM;
316 326
317 item->key = strdup(item_key); 327 item->key = strdup(item_key);
318 328
319 if (!item->key) { 329 if (!item->key) {
320 free(item); 330 free(item);
321 return -ENOMEM; 331 return -ENOMEM;
322 } 332 }
323 333
324 item->data = item_data; 334 item->data = item_data;
325 335
326 list_add_tail(&item->list, &m->items); 336 list_add_tail(&item->list, &m->items);
327 337
328 return 1; 338 return 1;
329 } 339 }
330 340
331 /* 341 /*
332 * menu_create() - Creates a menu handle with default settings 342 * menu_create() - Creates a menu handle with default settings
333 * 343 *
334 * title - If not NULL, points to a string that will be displayed before the 344 * title - If not NULL, points to a string that will be displayed before the
335 * list of menu items. It will be copied to internal storage, and is safe to 345 * list of menu items. It will be copied to internal storage, and is safe to
336 * discard after passing to menu_create(). 346 * discard after passing to menu_create().
337 * 347 *
338 * timeout - A delay in seconds to wait for user input. If 0, timeout is 348 * timeout - A delay in seconds to wait for user input. If 0, timeout is
339 * disabled, and the default choice will be returned unless prompt is 1. 349 * disabled, and the default choice will be returned unless prompt is 1.
340 * 350 *
341 * prompt - If 0, don't ask for user input unless there is an interrupted 351 * prompt - If 0, don't ask for user input unless there is an interrupted
342 * timeout. If 1, the user will be prompted for input regardless of the value 352 * timeout. If 1, the user will be prompted for input regardless of the value
343 * of timeout. 353 * of timeout.
344 * 354 *
345 * item_data_print - If not NULL, will be called for each item when the menu 355 * item_data_print - If not NULL, will be called for each item when the menu
346 * is displayed, with the pointer to the item's data passed as the argument. 356 * is displayed, with the pointer to the item's data passed as the argument.
347 * If NULL, each item's key will be printed instead. Since an item's key is 357 * If NULL, each item's key will be printed instead. Since an item's key is
348 * what must be entered to select an item, the item_data_print function should 358 * what must be entered to select an item, the item_data_print function should
349 * make it obvious what the key for each entry is. 359 * make it obvious what the key for each entry is.
350 * 360 *
361 * item_choice - If not NULL, will be called when asking the user to choose an
362 * item. Returns a key string corresponding to the choosen item or NULL if
363 * no item has been selected.
364 *
365 * item_choice_data - Will be passed as the argument to the item_choice function
366 *
351 * Returns a pointer to the menu if successful, or NULL if there is 367 * Returns a pointer to the menu if successful, or NULL if there is
352 * insufficient memory available to create the menu. 368 * insufficient memory available to create the menu.
353 */ 369 */
354 struct menu *menu_create(char *title, int timeout, int prompt, 370 struct menu *menu_create(char *title, int timeout, int prompt,
355 void (*item_data_print)(void *)) 371 void (*item_data_print)(void *),
372 char *(*item_choice)(void *),
373 void *item_choice_data)
356 { 374 {
357 struct menu *m; 375 struct menu *m;
358 376
359 m = malloc(sizeof *m); 377 m = malloc(sizeof *m);
360 378
361 if (!m) 379 if (!m)
362 return NULL; 380 return NULL;
363 381
364 m->default_item = NULL; 382 m->default_item = NULL;
365 m->prompt = prompt; 383 m->prompt = prompt;
366 m->timeout = timeout; 384 m->timeout = timeout;
367 m->item_data_print = item_data_print; 385 m->item_data_print = item_data_print;
386 m->item_choice = item_choice;
387 m->item_choice_data = item_choice_data;
368 388
369 if (title) { 389 if (title) {
370 m->title = strdup(title); 390 m->title = strdup(title);
371 if (!m->title) { 391 if (!m->title) {
372 free(m); 392 free(m);
373 return NULL; 393 return NULL;
374 } 394 }
375 } else 395 } else
376 m->title = NULL; 396 m->title = NULL;
377 397
378 398
379 INIT_LIST_HEAD(&m->items); 399 INIT_LIST_HEAD(&m->items);
380 400
381 return m; 401 return m;
382 } 402 }
383 403
384 /* 404 /*
385 * menu_destroy() - frees the memory used by a menu and its items. 405 * menu_destroy() - frees the memory used by a menu and its items.
386 * 406 *
387 * m - Points to a menu created by menu_create(). 407 * m - Points to a menu created by menu_create().
388 * 408 *
389 * Returns 1 if successful, or -EINVAL if m is NULL. 409 * Returns 1 if successful, or -EINVAL if m is NULL.
390 */ 410 */
391 int menu_destroy(struct menu *m) 411 int menu_destroy(struct menu *m)
392 { 412 {
393 if (!m) 413 if (!m)
394 return -EINVAL; 414 return -EINVAL;
395 415
396 menu_items_iter(m, menu_item_destroy, NULL); 416 menu_items_iter(m, menu_item_destroy, NULL);
397 417
398 if (m->title) 418 if (m->title)
399 free(m->title); 419 free(m->title);
400 420
401 free(m); 421 free(m);
402 422
403 return 1; 423 return 1;
404 } 424 }
405 425
File was created 1 /*
2 * (C) Copyright 2011-2012 Pali Rohรกr <pali.rohar@gmail.com>
3 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23 ANSI terminal bootmenu command
24
25 The "bootmenu" command uses U-Boot menu interfaces and provides
26 a simple mechanism for creating menus with different boot items.
27 The cursor keys "Up" and "Down" are used for navigation through
28 the items. Current active menu item is highlighted and can be
29 selected using the "Enter" key. The selection of the highlighted
30 menu entry invokes an U-Boot command (or a list of commands)
31 associated with this menu entry.
32
33 The "bootmenu" command interprets ANSI escape sequencies, so
34 an ANSI terminal is required for proper menu rendering and item
35 selection.
36
37 The assembling of the menu is done via a set of environment variables
38 "bootmenu_<num>" and "bootmenu_delay", i.e.:
39
40 bootmenu_delay=<delay>
41 bootmenu_<num>="<title>=<commands>"
42
43 <delay> is the autoboot delay in seconds, after which the first
44 menu entry will be selected automatically
45
46 <num> is the boot menu entry number, starting from zero
47
48 <title> is the text of the menu entry shown on the console
49 or on the boot screen
50
51 <commands> are commands which will be executed when a menu
52 entry is selected
53
54 (title and commands are separated by first appearance of '='
55 character in the environment variable)
56
57 First (optional) argument of the "bootmenu" command is a delay specifier
58 and it overrides the delay value defined by "bootmenu_delay" environment
59 variable. If the environment variable "bootmenu_delay" is not set or if
60 the argument of the "bootmenu" command is not specified, the default delay
61 will be CONFIG_BOOTDELAY. If delay is 0, no menu entries will be shown on
62 the console (or on the screen) and the command of the first menu entry will
63 be called immediately. If delay is less then 0, bootmenu will be shown and
64 autoboot will be disabled.
65
66 Bootmenu always adds menu entry "U-Boot console" at the end of all menu
67 entries specified by environment variables. When selecting this entry
68 the bootmenu terminates and the usual U-Boot command prompt is presented
69 to the user.
70
71 Example environment:
72
73 setenv bootmenu_0 Boot 1. kernel=bootm 0x82000000 # Set first menu entry
74 setenv bootmenu_1 Boot 2. kernel=bootm 0x83000000 # Set second menu entry
75 setenv bootmenu_2 Reset board=reset # Set third menu entry
76 setenv bootmenu_3 U-Boot boot order=boot # Set fourth menu entry
77 bootmenu 20 # Run bootmenu with autoboot delay 20s
78
79
80 The above example will be rendered as below
81 (without decorating rectangle):
82
83 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
84 โ”‚ โ”‚
85 โ”‚ *** U-Boot Boot Menu *** โ”‚
86 โ”‚ โ”‚
87 โ”‚ Boot 1. kernel โ”‚
88 โ”‚ Boot 2. kernel โ”‚
89 โ”‚ Reset board โ”‚
90 โ”‚ U-Boot boot order โ”‚
91 โ”‚ U-Boot console โ”‚
92 โ”‚ โ”‚
93 โ”‚ Hit any key to stop autoboot: 20 โ”‚
94 โ”‚ Press UP/DOWN to move, ENTER to select โ”‚
95 โ”‚ โ”‚
96 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
97
98 Selected menu entry will be highlighted - it will have inverted
99 background and text colors.
100
101 To enable the "bootmenu" command add following definitions to the
102 board config file:
103
104 #define CONFIG_CMD_BOOTMENU
105 #define CONFIG_MENU
106
107 To run the bootmenu at startup add these additional definitions:
108
109 #define CONFIG_AUTOBOOT_KEYED
110 #define CONFIG_BOOTDELAY 30
111 #define CONFIG_MENU_SHOW
112
113 When you intend to use the bootmenu on color frame buffer console,
114 make sure to additionally define CONFIG_CFB_CONSOLE_ANSI in the
115 board config file.
116
1 /* 1 /*
2 * Copyright 2010-2011 Calxeda, Inc. 2 * Copyright 2010-2011 Calxeda, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free 5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option) 6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version. 7 * any later version.
8 * 8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT 9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details. 12 * more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License along with 14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>. 15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 U-boot provides a set of interfaces for creating and using simple, text 18 U-boot provides a set of interfaces for creating and using simple, text
19 based menus. Menus are displayed as lists of labeled entries on the 19 based menus. Menus are displayed as lists of labeled entries on the
20 console, and an entry can be selected by entering its label. 20 console, and an entry can be selected by entering its label.
21 21
22 To use the menu code, enable CONFIG_MENU, and include "menu.h" where 22 To use the menu code, enable CONFIG_MENU, and include "menu.h" where
23 the interfaces should be available. 23 the interfaces should be available.
24 24
25 Menus are composed of items. Each item has a key used to identify it in 25 Menus are composed of items. Each item has a key used to identify it in
26 the menu, and an opaque pointer to data controlled by the consumer. 26 the menu, and an opaque pointer to data controlled by the consumer.
27 27
28 If you want to show a menu, instead starting the shell, define 28 If you want to show a menu, instead starting the shell, define
29 CONFIG_MENU_SHOW. You have to code the int menu_show(int bootdelay) 29 CONFIG_MENU_SHOW. You have to code the int menu_show(int bootdelay)
30 function, which handle your menu. This function returns the remaining 30 function, which handle your menu. This function returns the remaining
31 bootdelay. 31 bootdelay.
32 32
33 Interfaces 33 Interfaces
34 ---------- 34 ----------
35 #include "menu.h" 35 #include "menu.h"
36 36
37 /* 37 /*
38 * Consumers of the menu interfaces will use a struct menu * as the 38 * Consumers of the menu interfaces will use a struct menu * as the
39 * handle for a menu. struct menu is only fully defined in menu.c, 39 * handle for a menu. struct menu is only fully defined in menu.c,
40 * preventing consumers of the menu interfaces from accessing its 40 * preventing consumers of the menu interfaces from accessing its
41 * contents directly. 41 * contents directly.
42 */ 42 */
43 struct menu; 43 struct menu;
44 44
45 /* 45 /*
46 * NOTE: See comments in common/menu.c for more detailed documentation on 46 * NOTE: See comments in common/menu.c for more detailed documentation on
47 * these interfaces. 47 * these interfaces.
48 */ 48 */
49 49
50 /* 50 /*
51 * menu_create() - Creates a menu handle with default settings 51 * menu_create() - Creates a menu handle with default settings
52 */ 52 */
53 struct menu *menu_create(char *title, int timeout, int prompt, 53 struct menu *menu_create(char *title, int timeout, int prompt,
54 void (*item_data_print)(void *)); 54 void (*item_data_print)(void *),
55 char *(*item_choice)(void *),
56 void *item_choice_data);
55 57
56 /* 58 /*
57 * menu_item_add() - Adds or replaces a menu item 59 * menu_item_add() - Adds or replaces a menu item
58 */ 60 */
59 int menu_item_add(struct menu *m, char *item_key, void *item_data); 61 int menu_item_add(struct menu *m, char *item_key, void *item_data);
60 62
61 /* 63 /*
62 * menu_default_set() - Sets the default choice for the menu 64 * menu_default_set() - Sets the default choice for the menu
63 */ 65 */
64 int menu_default_set(struct menu *m, char *item_key); 66 int menu_default_set(struct menu *m, char *item_key);
67
68 /*
69 * menu_default_choice() - Set *choice to point to the default item's data
70 */
71 int menu_default_choice(struct menu *m, void **choice);
65 72
66 /* 73 /*
67 * menu_get_choice() - Returns the user's selected menu entry, or the 74 * menu_get_choice() - Returns the user's selected menu entry, or the
68 * default if the menu is set to not prompt or the timeout expires. 75 * default if the menu is set to not prompt or the timeout expires.
69 */ 76 */
70 int menu_get_choice(struct menu *m, void **choice); 77 int menu_get_choice(struct menu *m, void **choice);
71 78
72 /* 79 /*
73 * menu_destroy() - frees the memory used by a menu and its items. 80 * menu_destroy() - frees the memory used by a menu and its items.
74 */ 81 */
75 int menu_destroy(struct menu *m); 82 int menu_destroy(struct menu *m);
76 83
77 /* 84 /*
78 * menu_display_statusline(struct menu *m); 85 * menu_display_statusline(struct menu *m);
79 * shows a statusline for every menu_display call. 86 * shows a statusline for every menu_display call.
80 */ 87 */
81 void menu_display_statusline(struct menu *m); 88 void menu_display_statusline(struct menu *m);
82 89
83 Example Code 90 Example Code
84 ------------ 91 ------------
85 This example creates a menu that always prompts, and allows the user 92 This example creates a menu that always prompts, and allows the user
86 to pick from a list of tools. The item key and data are the same. 93 to pick from a list of tools. The item key and data are the same.
87 94
88 #include "menu.h" 95 #include "menu.h"
89 96
90 char *tools[] = { 97 char *tools[] = {
91 "Hammer", 98 "Hammer",
92 "Screwdriver", 99 "Screwdriver",
93 "Nail gun", 100 "Nail gun",
94 NULL 101 NULL
95 }; 102 };
96 103
97 char *pick_a_tool(void) 104 char *pick_a_tool(void)
98 { 105 {
99 struct menu *m; 106 struct menu *m;
100 int i; 107 int i;
101 char *tool = NULL; 108 char *tool = NULL;
102 109
103 m = menu_create("Tools", 0, 1, NULL); 110 m = menu_create("Tools", 0, 1, NULL);
104 111
105 for(i = 0; tools[i]; i++) { 112 for(i = 0; tools[i]; i++) {
106 if (menu_item_add(m, tools[i], tools[i]) != 1) { 113 if (menu_item_add(m, tools[i], tools[i]) != 1) {
107 printf("failed to add item!"); 114 printf("failed to add item!");
108 menu_destroy(m); 115 menu_destroy(m);
109 return NULL; 116 return NULL;
110 } 117 }
111 } 118 }
112 119
113 if (menu_get_choice(m, (void **)&tool) != 1) 120 if (menu_get_choice(m, (void **)&tool) != 1)
114 printf("Problem picking tool!\n"); 121 printf("Problem picking tool!\n");
115 122
116 menu_destroy(m); 123 menu_destroy(m);
117 124
118 return tool; 125 return tool;
119 } 126 }
120 127
121 void caller(void) 128 void caller(void)
122 { 129 {
123 char *tool = pick_a_tool(); 130 char *tool = pick_a_tool();
124 131
125 if (tool) { 132 if (tool) {
126 printf("picked a tool: %s\n", tool); 133 printf("picked a tool: %s\n", tool);
127 use_tool(tool); 134 use_tool(tool);
128 } 135 }
129 } 136 }
130 137
File was created 1 /*
2 * (C) Copyright 2012
3 * Pali Rohรกr <pali.rohar@gmail.com>
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24 /*
25 * ANSI terminal
26 */
27
28 #define ANSI_CURSOR_UP "\e[%dA"
29 #define ANSI_CURSOR_DOWN "\e[%dB"
30 #define ANSI_CURSOR_FORWARD "\e[%dC"
31 #define ANSI_CURSOR_BACK "\e[%dD"
32 #define ANSI_CURSOR_NEXTLINE "\e[%dE"
33 #define ANSI_CURSOR_PREVIOUSLINE "\e[%dF"
34 #define ANSI_CURSOR_COLUMN "\e[%dG"
35 #define ANSI_CURSOR_POSITION "\e[%d;%dH"
36 #define ANSI_CURSOR_SHOW "\e[?25h"
37 #define ANSI_CURSOR_HIDE "\e[?25l"
38 #define ANSI_CLEAR_CONSOLE "\e[2J"
39 #define ANSI_CLEAR_LINE_TO_END "\e[0K"
40 #define ANSI_CLEAR_LINE "\e[2K"
41 #define ANSI_COLOR_RESET "\e[0m"
42 #define ANSI_COLOR_REVERSE "\e[7m"
43
include/configs/nokia_rx51.h
1 /* 1 /*
2 * (C) Copyright 2011-2012 2 * (C) Copyright 2011-2012
3 * Pali Rohรกr <pali.rohar@gmail.com> 3 * Pali Rohรกr <pali.rohar@gmail.com>
4 * 4 *
5 * (C) Copyright 2010 5 * (C) Copyright 2010
6 * Alistair Buxton <a.j.buxton@gmail.com> 6 * Alistair Buxton <a.j.buxton@gmail.com>
7 * 7 *
8 * Derived from Beagle Board code: 8 * Derived from Beagle Board code:
9 * (C) Copyright 2006-2008 9 * (C) Copyright 2006-2008
10 * Texas Instruments. 10 * Texas Instruments.
11 * Richard Woodruff <r-woodruff2@ti.com> 11 * Richard Woodruff <r-woodruff2@ti.com>
12 * Syed Mohammed Khasim <x0khasim@ti.com> 12 * Syed Mohammed Khasim <x0khasim@ti.com>
13 * 13 *
14 * Configuration settings for the Nokia RX-51 aka N900. 14 * Configuration settings for the Nokia RX-51 aka N900.
15 * 15 *
16 * See file CREDITS for list of people who contributed to this 16 * See file CREDITS for list of people who contributed to this
17 * project. 17 * project.
18 * 18 *
19 * This program is free software; you can redistribute it and/or 19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License as 20 * modify it under the terms of the GNU General Public License as
21 * published by the Free Software Foundation; either version 2 of 21 * published by the Free Software Foundation; either version 2 of
22 * the License, or (at your option) any later version. 22 * the License, or (at your option) any later version.
23 * 23 *
24 * This program is distributed in the hope that it will be useful, 24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details. 27 * GNU General Public License for more details.
28 * 28 *
29 * You should have received a copy of the GNU General Public License 29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software 30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 * MA 02111-1307 USA 32 * MA 02111-1307 USA
33 */ 33 */
34 34
35 #ifndef __CONFIG_H 35 #ifndef __CONFIG_H
36 #define __CONFIG_H 36 #define __CONFIG_H
37 37
38 /* 38 /*
39 * High Level Configuration Options 39 * High Level Configuration Options
40 */ 40 */
41 41
42 #define CONFIG_OMAP /* in a TI OMAP core */ 42 #define CONFIG_OMAP /* in a TI OMAP core */
43 #define CONFIG_OMAP34XX /* which is a 34XX */ 43 #define CONFIG_OMAP34XX /* which is a 34XX */
44 #define CONFIG_OMAP3430 /* which is in a 3430 */ 44 #define CONFIG_OMAP3430 /* which is in a 3430 */
45 #define CONFIG_OMAP3_RX51 /* working with RX51 */ 45 #define CONFIG_OMAP3_RX51 /* working with RX51 */
46 #define CONFIG_SYS_L2CACHE_OFF /* pretend there is no L2 CACHE */ 46 #define CONFIG_SYS_L2CACHE_OFF /* pretend there is no L2 CACHE */
47 47
48 #define CONFIG_MACH_TYPE MACH_TYPE_NOKIA_RX51 48 #define CONFIG_MACH_TYPE MACH_TYPE_NOKIA_RX51
49 49
50 /* 50 /*
51 * Nokia X-Loader loading secondary image to address 0x80400000 51 * Nokia X-Loader loading secondary image to address 0x80400000
52 * NOLO loading boot image to random place, so it doesn't really 52 * NOLO loading boot image to random place, so it doesn't really
53 * matter what we set this to. We have to copy u-boot to this address 53 * matter what we set this to. We have to copy u-boot to this address
54 */ 54 */
55 #define CONFIG_SYS_TEXT_BASE 0x80008000 55 #define CONFIG_SYS_TEXT_BASE 0x80008000
56 56
57 #define CONFIG_SDRC /* The chip has SDRC controller */ 57 #define CONFIG_SDRC /* The chip has SDRC controller */
58 58
59 #include <asm/arch/cpu.h> /* get chip and board defs */ 59 #include <asm/arch/cpu.h> /* get chip and board defs */
60 #include <asm/arch/omap3.h> 60 #include <asm/arch/omap3.h>
61 #include <asm/arch/mem.h> 61 #include <asm/arch/mem.h>
62 #include <linux/stringify.h> 62 #include <linux/stringify.h>
63 63
64 /* 64 /*
65 * Display CPU and Board information 65 * Display CPU and Board information
66 */ 66 */
67 #define CONFIG_DISPLAY_CPUINFO 67 #define CONFIG_DISPLAY_CPUINFO
68 #define CONFIG_DISPLAY_BOARDINFO 68 #define CONFIG_DISPLAY_BOARDINFO
69 69
70 /* Clock Defines */ 70 /* Clock Defines */
71 #define V_OSCK 26000000 /* Clock output from T2 */ 71 #define V_OSCK 26000000 /* Clock output from T2 */
72 #define V_SCLK (V_OSCK >> 1) 72 #define V_SCLK (V_OSCK >> 1)
73 73
74 #undef CONFIG_USE_IRQ /* no support for IRQs */ 74 #undef CONFIG_USE_IRQ /* no support for IRQs */
75 #define CONFIG_MISC_INIT_R 75 #define CONFIG_MISC_INIT_R
76 #define CONFIG_SKIP_LOWLEVEL_INIT /* X-Loader set everything up */ 76 #define CONFIG_SKIP_LOWLEVEL_INIT /* X-Loader set everything up */
77 77
78 #define CONFIG_CMDLINE_TAG /* enable passing kernel command line string */ 78 #define CONFIG_CMDLINE_TAG /* enable passing kernel command line string */
79 #define CONFIG_INITRD_TAG /* enable passing initrd */ 79 #define CONFIG_INITRD_TAG /* enable passing initrd */
80 #define CONFIG_REVISION_TAG /* enable passing revision tag*/ 80 #define CONFIG_REVISION_TAG /* enable passing revision tag*/
81 #define CONFIG_SETUP_MEMORY_TAGS /* enable memory tag */ 81 #define CONFIG_SETUP_MEMORY_TAGS /* enable memory tag */
82 82
83 /* 83 /*
84 * Size of malloc() pool 84 * Size of malloc() pool
85 */ 85 */
86 #define CONFIG_ENV_SIZE (128 << 10) 86 #define CONFIG_ENV_SIZE (128 << 10)
87 #define CONFIG_UBI_SIZE (512 << 10) 87 #define CONFIG_UBI_SIZE (512 << 10)
88 #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + CONFIG_UBI_SIZE + \ 88 #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + CONFIG_UBI_SIZE + \
89 (128 << 10)) 89 (128 << 10))
90 90
91 /* 91 /*
92 * Hardware drivers 92 * Hardware drivers
93 */ 93 */
94 94
95 /* 95 /*
96 * NS16550 Configuration 96 * NS16550 Configuration
97 */ 97 */
98 #define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */ 98 #define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */
99 99
100 #define CONFIG_SYS_NS16550 100 #define CONFIG_SYS_NS16550
101 #define CONFIG_SYS_NS16550_SERIAL 101 #define CONFIG_SYS_NS16550_SERIAL
102 #define CONFIG_SYS_NS16550_REG_SIZE (-4) 102 #define CONFIG_SYS_NS16550_REG_SIZE (-4)
103 #define CONFIG_SYS_NS16550_CLK V_NS16550_CLK 103 #define CONFIG_SYS_NS16550_CLK V_NS16550_CLK
104 104
105 /* 105 /*
106 * select serial console configuration 106 * select serial console configuration
107 */ 107 */
108 #define CONFIG_CONS_INDEX 3 108 #define CONFIG_CONS_INDEX 3
109 #define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3 109 #define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3
110 #define CONFIG_SERIAL3 3 /* UART3 on RX-51 */ 110 #define CONFIG_SERIAL3 3 /* UART3 on RX-51 */
111 111
112 /* allow to overwrite serial and ethaddr */ 112 /* allow to overwrite serial and ethaddr */
113 #define CONFIG_ENV_OVERWRITE 113 #define CONFIG_ENV_OVERWRITE
114 #define CONFIG_BAUDRATE 115200 114 #define CONFIG_BAUDRATE 115200
115 #define CONFIG_SYS_BAUDRATE_TABLE { 4800, 9600, 19200, 38400, 57600, 115200 } 115 #define CONFIG_SYS_BAUDRATE_TABLE { 4800, 9600, 19200, 38400, 57600, 115200 }
116 #define CONFIG_MMC 116 #define CONFIG_MMC
117 #define CONFIG_GENERIC_MMC 117 #define CONFIG_GENERIC_MMC
118 #define CONFIG_OMAP_HSMMC 118 #define CONFIG_OMAP_HSMMC
119 #define CONFIG_DOS_PARTITION 119 #define CONFIG_DOS_PARTITION
120 120
121 /* USB */ 121 /* USB */
122 #define CONFIG_MUSB_UDC 122 #define CONFIG_MUSB_UDC
123 #define CONFIG_MUSB_HDC 123 #define CONFIG_MUSB_HDC
124 #define CONFIG_USB_OMAP3 124 #define CONFIG_USB_OMAP3
125 #define CONFIG_TWL4030_USB 125 #define CONFIG_TWL4030_USB
126 126
127 /* USB device configuration */ 127 /* USB device configuration */
128 #define CONFIG_USB_DEVICE 128 #define CONFIG_USB_DEVICE
129 #define CONFIG_USBD_VENDORID 0x0421 129 #define CONFIG_USBD_VENDORID 0x0421
130 #define CONFIG_USBD_PRODUCTID 0x01c8 130 #define CONFIG_USBD_PRODUCTID 0x01c8
131 #define CONFIG_USBD_MANUFACTURER "Nokia" 131 #define CONFIG_USBD_MANUFACTURER "Nokia"
132 #define CONFIG_USBD_PRODUCT_NAME "N900" 132 #define CONFIG_USBD_PRODUCT_NAME "N900"
133 133
134 #define CONFIG_SYS_CONSOLE_IS_IN_ENV 134 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
135 #define CONFIG_SYS_NO_FLASH 135 #define CONFIG_SYS_NO_FLASH
136 136
137 /* commands to include */ 137 /* commands to include */
138 #include <config_cmd_default.h> 138 #include <config_cmd_default.h>
139 139
140 #define CONFIG_CMD_EXT2 /* EXT2 Support */ 140 #define CONFIG_CMD_EXT2 /* EXT2 Support */
141 #define CONFIG_CMD_EXT4 /* EXT4 Support */ 141 #define CONFIG_CMD_EXT4 /* EXT4 Support */
142 #define CONFIG_CMD_FAT /* FAT support */ 142 #define CONFIG_CMD_FAT /* FAT support */
143 143
144 #define CONFIG_CMD_I2C /* I2C serial bus support */ 144 #define CONFIG_CMD_I2C /* I2C serial bus support */
145 #define CONFIG_CMD_MMC /* MMC support */ 145 #define CONFIG_CMD_MMC /* MMC support */
146 #define CONFIG_CMD_GPIO /* Enable gpio command */ 146 #define CONFIG_CMD_GPIO /* Enable gpio command */
147 147
148 #define CONFIG_CMDLINE_EDITING /* add command line history */ 148 #define CONFIG_CMDLINE_EDITING /* add command line history */
149 #define CONFIG_AUTO_COMPLETE /* add autocompletion support */ 149 #define CONFIG_AUTO_COMPLETE /* add autocompletion support */
150 150
151 #define CONFIG_CMD_BOOTMENU /* ANSI terminal Boot Menu */
151 #define CONFIG_CMD_CLEAR /* ANSI terminal clear screen command */ 152 #define CONFIG_CMD_CLEAR /* ANSI terminal clear screen command */
152 153
153 #ifdef ONENAND_SUPPORT 154 #ifdef ONENAND_SUPPORT
154 155
155 #define CONFIG_CMD_ONENAND /* ONENAND support */ 156 #define CONFIG_CMD_ONENAND /* ONENAND support */
156 #define CONFIG_CMD_MTDPARTS /* mtd parts support */ 157 #define CONFIG_CMD_MTDPARTS /* mtd parts support */
157 158
158 #ifdef UBIFS_SUPPORT 159 #ifdef UBIFS_SUPPORT
159 #define CONFIG_CMD_UBI /* UBI Support */ 160 #define CONFIG_CMD_UBI /* UBI Support */
160 #define CONFIG_CMD_UBIFS /* UBIFS Support */ 161 #define CONFIG_CMD_UBIFS /* UBIFS Support */
161 #endif 162 #endif
162 163
163 #endif 164 #endif
164 165
165 /* commands not needed from config_cmd_default.h */ 166 /* commands not needed from config_cmd_default.h */
166 #undef CONFIG_CMD_FPGA /* FPGA configuration Support */ 167 #undef CONFIG_CMD_FPGA /* FPGA configuration Support */
167 #undef CONFIG_CMD_IMI /* iminfo */ 168 #undef CONFIG_CMD_IMI /* iminfo */
168 #undef CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */ 169 #undef CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */
169 #undef CONFIG_CMD_NFS /* NFS support */ 170 #undef CONFIG_CMD_NFS /* NFS support */
170 #undef CONFIG_CMD_SAVEENV /* saveenv */ 171 #undef CONFIG_CMD_SAVEENV /* saveenv */
171 #undef CONFIG_CMD_SETGETDCR /* DCR support on 4xx */ 172 #undef CONFIG_CMD_SETGETDCR /* DCR support on 4xx */
172 173
173 #define CONFIG_OMAP3_SPI 174 #define CONFIG_OMAP3_SPI
174 #define CONFIG_HARD_I2C 175 #define CONFIG_HARD_I2C
175 #define CONFIG_SYS_I2C_SPEED 100000 176 #define CONFIG_SYS_I2C_SPEED 100000
176 #define CONFIG_SYS_I2C_SLAVE 1 177 #define CONFIG_SYS_I2C_SLAVE 1
177 #define CONFIG_DRIVER_OMAP34XX_I2C 178 #define CONFIG_DRIVER_OMAP34XX_I2C
178 179
179 /* 180 /*
180 * TWL4030 181 * TWL4030
181 */ 182 */
182 #define CONFIG_TWL4030_POWER 183 #define CONFIG_TWL4030_POWER
183 #define CONFIG_TWL4030_LED 184 #define CONFIG_TWL4030_LED
184 #define CONFIG_TWL4030_KEYPAD 185 #define CONFIG_TWL4030_KEYPAD
185 186
186 #define CONFIG_OMAP_GPIO 187 #define CONFIG_OMAP_GPIO
187 #define GPIO_SLIDE 71 188 #define GPIO_SLIDE 71
188 189
189 /* 190 /*
190 * Board ONENAND Info. 191 * Board ONENAND Info.
191 */ 192 */
192 193
193 #define PART1_NAME "bootloader" 194 #define PART1_NAME "bootloader"
194 #define PART1_SIZE 128 195 #define PART1_SIZE 128
195 #define PART1_MULL 1024 196 #define PART1_MULL 1024
196 #define PART1_SUFF "k" 197 #define PART1_SUFF "k"
197 #define PART1_OFFS 0x00000000 198 #define PART1_OFFS 0x00000000
198 #define PART1_MASK 0x00000003 199 #define PART1_MASK 0x00000003
199 200
200 #define PART2_NAME "config" 201 #define PART2_NAME "config"
201 #define PART2_SIZE 384 202 #define PART2_SIZE 384
202 #define PART2_MULL 1024 203 #define PART2_MULL 1024
203 #define PART2_SUFF "k" 204 #define PART2_SUFF "k"
204 #define PART2_OFFS 0x00020000 205 #define PART2_OFFS 0x00020000
205 #define PART2_MASK 0x00000000 206 #define PART2_MASK 0x00000000
206 207
207 #define PART3_NAME "log" 208 #define PART3_NAME "log"
208 #define PART3_SIZE 256 209 #define PART3_SIZE 256
209 #define PART3_MULL 1024 210 #define PART3_MULL 1024
210 #define PART3_SUFF "k" 211 #define PART3_SUFF "k"
211 #define PART3_OFFS 0x00080000 212 #define PART3_OFFS 0x00080000
212 #define PART3_MASK 0x00000000 213 #define PART3_MASK 0x00000000
213 214
214 #define PART4_NAME "kernel" 215 #define PART4_NAME "kernel"
215 #define PART4_SIZE 2 216 #define PART4_SIZE 2
216 #define PART4_MULL 1024*1024 217 #define PART4_MULL 1024*1024
217 #define PART4_SUFF "m" 218 #define PART4_SUFF "m"
218 #define PART4_OFFS 0x000c0000 219 #define PART4_OFFS 0x000c0000
219 #define PART4_MASK 0x00000000 220 #define PART4_MASK 0x00000000
220 221
221 #define PART5_NAME "initfs" 222 #define PART5_NAME "initfs"
222 #define PART5_SIZE 2 223 #define PART5_SIZE 2
223 #define PART5_MULL 1024*1024 224 #define PART5_MULL 1024*1024
224 #define PART5_SUFF "m" 225 #define PART5_SUFF "m"
225 #define PART5_OFFS 0x002c0000 226 #define PART5_OFFS 0x002c0000
226 #define PART5_MASK 0x00000000 227 #define PART5_MASK 0x00000000
227 228
228 #define PART6_NAME "rootfs" 229 #define PART6_NAME "rootfs"
229 #define PART6_SIZE 257280 230 #define PART6_SIZE 257280
230 #define PART6_MULL 1024 231 #define PART6_MULL 1024
231 #define PART6_SUFF "k" 232 #define PART6_SUFF "k"
232 #define PART6_OFFS 0x004c0000 233 #define PART6_OFFS 0x004c0000
233 #define PART6_MASK 0x00000000 234 #define PART6_MASK 0x00000000
234 235
235 #ifdef ONENAND_SUPPORT 236 #ifdef ONENAND_SUPPORT
236 237
237 #define PISMO1_NAND_SIZE GPMC_SIZE_128M 238 #define PISMO1_NAND_SIZE GPMC_SIZE_128M
238 #define PISMO1_ONEN_SIZE GPMC_SIZE_128M 239 #define PISMO1_ONEN_SIZE GPMC_SIZE_128M
239 #define CONFIG_SYS_ONENAND_BASE ONENAND_MAP 240 #define CONFIG_SYS_ONENAND_BASE ONENAND_MAP
240 #define CONFIG_MTD_DEVICE 241 #define CONFIG_MTD_DEVICE
241 #define CONFIG_MTD_PARTITIONS 242 #define CONFIG_MTD_PARTITIONS
242 243
243 #ifdef UBIFS_SUPPORT 244 #ifdef UBIFS_SUPPORT
244 #define CONFIG_RBTREE 245 #define CONFIG_RBTREE
245 #define CONFIG_LZO 246 #define CONFIG_LZO
246 #endif 247 #endif
247 248
248 #define MTDIDS_DEFAULT "onenand0=onenand" 249 #define MTDIDS_DEFAULT "onenand0=onenand"
249 #define MTDPARTS_DEFAULT "mtdparts=onenand:" \ 250 #define MTDPARTS_DEFAULT "mtdparts=onenand:" \
250 __stringify(PART1_SIZE) PART1_SUFF "(" PART1_NAME ")ro," \ 251 __stringify(PART1_SIZE) PART1_SUFF "(" PART1_NAME ")ro," \
251 __stringify(PART2_SIZE) PART2_SUFF "(" PART2_NAME ")," \ 252 __stringify(PART2_SIZE) PART2_SUFF "(" PART2_NAME ")," \
252 __stringify(PART3_SIZE) PART3_SUFF "(" PART3_NAME ")," \ 253 __stringify(PART3_SIZE) PART3_SUFF "(" PART3_NAME ")," \
253 __stringify(PART4_SIZE) PART4_SUFF "(" PART4_NAME ")," \ 254 __stringify(PART4_SIZE) PART4_SUFF "(" PART4_NAME ")," \
254 __stringify(PART5_SIZE) PART5_SUFF "(" PART5_NAME ")," \ 255 __stringify(PART5_SIZE) PART5_SUFF "(" PART5_NAME ")," \
255 "-(" PART6_NAME ")" 256 "-(" PART6_NAME ")"
256 257
257 #endif 258 #endif
258 259
259 /* Watchdog support */ 260 /* Watchdog support */
260 #define CONFIG_HW_WATCHDOG 261 #define CONFIG_HW_WATCHDOG
261 262
262 /* 263 /*
263 * Framebuffer 264 * Framebuffer
264 */ 265 */
265 /* Video console */ 266 /* Video console */
266 #define CONFIG_VIDEO 267 #define CONFIG_VIDEO
267 #define CONFIG_CFB_CONSOLE 268 #define CONFIG_CFB_CONSOLE
268 #define CONFIG_CFB_CONSOLE_ANSI /* Enable ANSI escape codes in framebuffer */ 269 #define CONFIG_CFB_CONSOLE_ANSI /* Enable ANSI escape codes in framebuffer */
269 #define CONFIG_VIDEO_LOGO 270 #define CONFIG_VIDEO_LOGO
270 #define VIDEO_FB_16BPP_PIXEL_SWAP 271 #define VIDEO_FB_16BPP_PIXEL_SWAP
271 #define VIDEO_FB_16BPP_WORD_SWAP 272 #define VIDEO_FB_16BPP_WORD_SWAP
272 #define CONFIG_VIDEO_SW_CURSOR 273 #define CONFIG_VIDEO_SW_CURSOR
273 #define CONFIG_SPLASH_SCREEN 274 #define CONFIG_SPLASH_SCREEN
274 275
275 /* functions for cfb_console */ 276 /* functions for cfb_console */
276 #define VIDEO_KBD_INIT_FCT rx51_kp_init() 277 #define VIDEO_KBD_INIT_FCT rx51_kp_init()
277 #define VIDEO_TSTC_FCT rx51_kp_tstc 278 #define VIDEO_TSTC_FCT rx51_kp_tstc
278 #define VIDEO_GETC_FCT rx51_kp_getc 279 #define VIDEO_GETC_FCT rx51_kp_getc
279 #ifndef __ASSEMBLY__ 280 #ifndef __ASSEMBLY__
280 int rx51_kp_init(void); 281 int rx51_kp_init(void);
281 int rx51_kp_tstc(void); 282 int rx51_kp_tstc(void);
282 int rx51_kp_getc(void); 283 int rx51_kp_getc(void);
283 #endif 284 #endif
284 285
285 #ifndef MTDPARTS_DEFAULT 286 #ifndef MTDPARTS_DEFAULT
286 #define MTDPARTS_DEFAULT 287 #define MTDPARTS_DEFAULT
287 #endif 288 #endif
288 289
289 /* Environment information */ 290 /* Environment information */
290 #define CONFIG_BOOTDELAY 3
291
292 #define CONFIG_EXTRA_ENV_SETTINGS \ 291 #define CONFIG_EXTRA_ENV_SETTINGS \
293 "mtdparts=" MTDPARTS_DEFAULT "\0" \ 292 "mtdparts=" MTDPARTS_DEFAULT "\0" \
294 "usbtty=cdc_acm\0" \ 293 "usbtty=cdc_acm\0" \
295 "stdin=vga\0" \ 294 "stdin=vga\0" \
296 "stdout=vga\0" \ 295 "stdout=vga\0" \
297 "stderr=vga\0" \ 296 "stderr=vga\0" \
298 "setcon=setenv stdin ${con};" \ 297 "setcon=setenv stdin ${con};" \
299 "setenv stdout ${con};" \ 298 "setenv stdout ${con};" \
300 "setenv stderr ${con}\0" \ 299 "setenv stderr ${con}\0" \
301 "sercon=setenv con serial; run setcon\0" \ 300 "sercon=setenv con serial; run setcon\0" \
302 "usbcon=setenv con usbtty; run setcon\0" \ 301 "usbcon=setenv con usbtty; run setcon\0" \
303 "vgacon=setenv con vga; run setcon\0" \ 302 "vgacon=setenv con vga; run setcon\0" \
304 "slide=gpio input " __stringify(GPIO_SLIDE) "\0" \ 303 "slide=gpio input " __stringify(GPIO_SLIDE) "\0" \
305 "switchmmc=mmc dev ${mmcnum}\0" \ 304 "switchmmc=mmc dev ${mmcnum}\0" \
306 "kernaddr=0x82008000\0" \ 305 "kernaddr=0x82008000\0" \
307 "initrdaddr=0x84008000\0" \ 306 "initrdaddr=0x84008000\0" \
308 "scriptaddr=0x86008000\0" \ 307 "scriptaddr=0x86008000\0" \
309 "fileload=${mmctype}load mmc ${mmcnum}:${mmcpart} " \ 308 "fileload=${mmctype}load mmc ${mmcnum}:${mmcpart} " \
310 "${loadaddr} ${mmcfile}\0" \ 309 "${loadaddr} ${mmcfile}\0" \
311 "kernload=setenv loadaddr ${kernaddr};" \ 310 "kernload=setenv loadaddr ${kernaddr};" \
312 "setenv mmcfile ${mmckernfile};" \ 311 "setenv mmcfile ${mmckernfile};" \
313 "run fileload\0" \ 312 "run fileload\0" \
314 "initrdload=setenv loadaddr ${initrdaddr};" \ 313 "initrdload=setenv loadaddr ${initrdaddr};" \
315 "setenv mmcfile ${mmcinitrdfile};" \ 314 "setenv mmcfile ${mmcinitrdfile};" \
316 "run fileload\0" \ 315 "run fileload\0" \
317 "scriptload=setenv loadaddr ${scriptaddr};" \ 316 "scriptload=setenv loadaddr ${scriptaddr};" \
318 "setenv mmcfile ${mmcscriptfile};" \ 317 "setenv mmcfile ${mmcscriptfile};" \
319 "run fileload\0" \ 318 "run fileload\0" \
320 "scriptboot=echo Running ${mmcscriptfile} from mmc " \ 319 "scriptboot=echo Running ${mmcscriptfile} from mmc " \
321 "${mmcnum}:${mmcpart} ...; source ${scriptaddr}\0" \ 320 "${mmcnum}:${mmcpart} ...; source ${scriptaddr}\0" \
322 "kernboot=echo Booting ${mmckernfile} from mmc " \ 321 "kernboot=echo Booting ${mmckernfile} from mmc " \
323 "${mmcnum}:${mmcpart} ...; bootm ${kernaddr}\0" \ 322 "${mmcnum}:${mmcpart} ...; bootm ${kernaddr}\0" \
324 "kerninitrdboot=echo Booting ${mmckernfile} ${mmcinitrdfile} from mmc "\ 323 "kerninitrdboot=echo Booting ${mmckernfile} ${mmcinitrdfile} from mmc "\
325 "${mmcnum}:${mmcpart} ...; bootm ${kernaddr} ${initrdaddr}\0" \ 324 "${mmcnum}:${mmcpart} ...; bootm ${kernaddr} ${initrdaddr}\0" \
326 "attachboot=echo Booting attached kernel image ...;" \ 325 "attachboot=echo Booting attached kernel image ...;" \
327 "setenv setup_omap_atag 1;" \ 326 "setenv setup_omap_atag 1;" \
328 "bootm ${attkernaddr};" \ 327 "bootm ${attkernaddr};" \
329 "setenv setup_omap_atag\0" \ 328 "setenv setup_omap_atag\0" \
330 "trymmcscriptboot=if run switchmmc; then " \ 329 "trymmcscriptboot=if run switchmmc; then " \
331 "if run scriptload; then " \ 330 "if run scriptload; then " \
332 "run scriptboot;" \ 331 "run scriptboot;" \
333 "fi;" \ 332 "fi;" \
334 "fi\0" \ 333 "fi\0" \
335 "trymmckernboot=if run switchmmc; then " \ 334 "trymmckernboot=if run switchmmc; then " \
336 "if run kernload; then " \ 335 "if run kernload; then " \
337 "run kernboot;" \ 336 "run kernboot;" \
338 "fi;" \ 337 "fi;" \
339 "fi\0" \ 338 "fi\0" \
340 "trymmckerninitrdboot=if run switchmmc; then " \ 339 "trymmckerninitrdboot=if run switchmmc; then " \
341 "if run initrdload; then " \ 340 "if run initrdload; then " \
342 "if run kernload; then " \ 341 "if run kernload; then " \
343 "run kerninitrdboot;" \ 342 "run kerninitrdboot;" \
344 "fi;" \ 343 "fi;" \
345 "fi; " \ 344 "fi; " \
346 "fi\0" \ 345 "fi\0" \
347 "trymmcpartboot=setenv mmcscriptfile boot.scr; run trymmcscriptboot;" \ 346 "trymmcpartboot=setenv mmcscriptfile boot.scr; run trymmcscriptboot;" \
348 "setenv mmckernfile uImage; run trymmckernboot\0" \ 347 "setenv mmckernfile uImage; run trymmckernboot\0" \
349 "trymmcallpartboot=setenv mmcpart 1; run trymmcpartboot;" \ 348 "trymmcallpartboot=setenv mmcpart 1; run trymmcpartboot;" \
350 "setenv mmcpart 2; run trymmcpartboot;" \ 349 "setenv mmcpart 2; run trymmcpartboot;" \
351 "setenv mmcpart 3; run trymmcpartboot;" \ 350 "setenv mmcpart 3; run trymmcpartboot;" \
352 "setenv mmcpart 4; run trymmcpartboot\0" \ 351 "setenv mmcpart 4; run trymmcpartboot\0" \
353 "trymmcboot=if run switchmmc; then " \ 352 "trymmcboot=if run switchmmc; then " \
354 "setenv mmctype fat;" \ 353 "setenv mmctype fat;" \
355 "run trymmcallpartboot;" \ 354 "run trymmcallpartboot;" \
356 "setenv mmctype ext2;" \ 355 "setenv mmctype ext2;" \
357 "run trymmcallpartboot;" \ 356 "run trymmcallpartboot;" \
358 "setenv mmctype ext4;" \ 357 "setenv mmctype ext4;" \
359 "run trymmcallpartboot;" \ 358 "run trymmcallpartboot;" \
360 "fi\0" \ 359 "fi\0" \
361 "emmcboot=setenv mmcnum 1; run trymmcboot\0" \ 360 "emmcboot=setenv mmcnum 1; run trymmcboot\0" \
362 "sdboot=setenv mmcnum 0; run trymmcboot\0" \ 361 "sdboot=setenv mmcnum 0; run trymmcboot\0" \
362 "menucmd=bootmenu\0" \
363 "bootmenu_0=Attached kernel=run attachboot\0" \
364 "bootmenu_1=Internal eMMC=run emmcboot\0" \
365 "bootmenu_2=External SD card=run sdboot\0" \
366 "bootmenu_3=U-Boot boot order=boot\0" \
367 "bootmenu_delay=30\0" \
363 "" 368 ""
364 369
365 #define CONFIG_PREBOOT \ 370 #define CONFIG_PREBOOT \
366 "if run slide; then true; else run attachboot; fi;" \ 371 "setenv mmcnum 1; setenv mmcpart 1;" \
372 "setenv mmcscriptfile bootmenu.scr;" \
373 "if run switchmmc; then " \
374 "setenv mmcdone true;" \
375 "setenv mmctype fat;" \
376 "if run scriptload; then true; else " \
377 "setenv mmctype ext2;" \
378 "if run scriptload; then true; else " \
379 "setenv mmctype ext4;" \
380 "if run scriptload; then true; else " \
381 "setenv mmcdone false;" \
382 "fi;" \
383 "fi;" \
384 "fi;" \
385 "if ${mmcdone}; then " \
386 "run scriptboot;" \
387 "fi;" \
388 "fi;" \
389 "if run slide; then true; else " \
390 "setenv bootmenu_delay 0;" \
391 "setenv bootdelay 0;" \
392 "fi"
393
394 #define CONFIG_POSTBOOTMENU \
395 "echo;" \
367 "echo Extra commands:;" \ 396 "echo Extra commands:;" \
368 "echo run sercon - Use serial port for control.;" \ 397 "echo run sercon - Use serial port for control.;" \
369 "echo run usbcon - Use usbtty for control.;" \ 398 "echo run usbcon - Use usbtty for control.;" \
370 "echo run vgacon - Use framebuffer/keyboard.;" \ 399 "echo run vgacon - Use framebuffer/keyboard.;" \
371 "echo run sdboot - Boot from SD card slot.;" \ 400 "echo run sdboot - Boot from SD card slot.;" \
372 "echo run emmcboot - Boot internal eMMC memory.;" \ 401 "echo run emmcboot - Boot internal eMMC memory.;" \
373 "echo run attachboot - Boot attached kernel image.;" \ 402 "echo run attachboot - Boot attached kernel image.;" \
374 "echo" 403 "echo"
375 404
376 #define CONFIG_BOOTCOMMAND \ 405 #define CONFIG_BOOTCOMMAND \
377 "run sdboot;" \ 406 "run sdboot;" \
378 "run emmcboot;" \ 407 "run emmcboot;" \
379 "run attachboot;" \ 408 "run attachboot;" \
380 "echo" 409 "echo"
410
411 #define CONFIG_BOOTDELAY 30
412 #define CONFIG_AUTOBOOT_KEYED
413 #define CONFIG_MENU
414 #define CONFIG_MENU_SHOW
381 415
382 /* 416 /*
383 * Miscellaneous configurable options 417 * Miscellaneous configurable options
384 */ 418 */
385 #define CONFIG_SYS_LONGHELP /* undef to save memory */ 419 #define CONFIG_SYS_LONGHELP /* undef to save memory */
386 #define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ 420 #define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */
387 #define CONFIG_SYS_PROMPT_HUSH_PS2 "> " 421 #define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
388 #define CONFIG_SYS_PROMPT "Nokia RX-51 # " 422 #define CONFIG_SYS_PROMPT "Nokia RX-51 # "
389 #define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ 423 #define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
390 /* Print Buffer Size */ 424 /* Print Buffer Size */
391 #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ 425 #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
392 sizeof(CONFIG_SYS_PROMPT) + 16) 426 sizeof(CONFIG_SYS_PROMPT) + 16)
393 #define CONFIG_SYS_MAXARGS 16 /* max number of command args */ 427 #define CONFIG_SYS_MAXARGS 16 /* max number of command args */
394 /* Boot Argument Buffer Size */ 428 /* Boot Argument Buffer Size */
395 #define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE) 429 #define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE)
396 430
397 #define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0) 431 #define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0)
398 #define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + 0x01F00000)/*31MB*/ 432 #define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + 0x01F00000)/*31MB*/
399 433
400 /* default load address */ 434 /* default load address */
401 #define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) 435 #define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0)
402 436
403 /* 437 /*
404 * OMAP3 has 12 GP timers, they can be driven by the system clock 438 * OMAP3 has 12 GP timers, they can be driven by the system clock
405 * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). 439 * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK).
406 * This rate is divided by a local divisor. 440 * This rate is divided by a local divisor.
407 */ 441 */
408 #define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) 442 #define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2)
409 #define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */ 443 #define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */
410 #define CONFIG_SYS_HZ 1000 444 #define CONFIG_SYS_HZ 1000
411 445
412 /* 446 /*
413 * Stack sizes 447 * Stack sizes
414 * 448 *
415 * The stack sizes are set up in start.S using the settings below 449 * The stack sizes are set up in start.S using the settings below
416 */ 450 */
417 #define CONFIG_STACKSIZE (128 << 10) /* regular stack 128 KiB */ 451 #define CONFIG_STACKSIZE (128 << 10) /* regular stack 128 KiB */
418 452
419 /* 453 /*
420 * Physical Memory Map 454 * Physical Memory Map
421 */ 455 */
422 #define CONFIG_NR_DRAM_BANKS 2 456 #define CONFIG_NR_DRAM_BANKS 2
423 #define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 457 #define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0
424 458
425 /* 459 /*
426 * FLASH and environment organization 460 * FLASH and environment organization
427 */ 461 */
428 462
429 #define CONFIG_ENV_IS_NOWHERE 463 #define CONFIG_ENV_IS_NOWHERE
430 464
431 #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 465 #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
432 #define CONFIG_SYS_INIT_RAM_ADDR 0x4020f800 466 #define CONFIG_SYS_INIT_RAM_ADDR 0x4020f800
433 #define CONFIG_SYS_INIT_RAM_SIZE 0x800 467 #define CONFIG_SYS_INIT_RAM_SIZE 0x800
434 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ 468 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
435 CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) 469 CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
436 470
437 /* 471 /*
438 * Attached kernel image 472 * Attached kernel image
439 */ 473 */
440 474
441 #define SDRAM_SIZE 0x10000000 /* 256 MB */ 475 #define SDRAM_SIZE 0x10000000 /* 256 MB */
442 #define SDRAM_END (CONFIG_SYS_SDRAM_BASE + SDRAM_SIZE) 476 #define SDRAM_END (CONFIG_SYS_SDRAM_BASE + SDRAM_SIZE)
443 477
444 #define IMAGE_MAXSIZE 0x1FF800 /* 2 MB - 2 kB */ 478 #define IMAGE_MAXSIZE 0x1FF800 /* 2 MB - 2 kB */
445 #define KERNEL_OFFSET 0x40000 /* 256 kB */ 479 #define KERNEL_OFFSET 0x40000 /* 256 kB */
446 #define KERNEL_MAXSIZE (IMAGE_MAXSIZE-KERNEL_OFFSET) 480 #define KERNEL_MAXSIZE (IMAGE_MAXSIZE-KERNEL_OFFSET)
447 #define KERNEL_ADDRESS (SDRAM_END-KERNEL_MAXSIZE) 481 #define KERNEL_ADDRESS (SDRAM_END-KERNEL_MAXSIZE)
448 482
449 /* Reserve protected RAM for attached kernel */ 483 /* Reserve protected RAM for attached kernel */
450 #define CONFIG_PRAM ((KERNEL_MAXSIZE >> 10)+1) 484 #define CONFIG_PRAM ((KERNEL_MAXSIZE >> 10)+1)
451 485
1 /* 1 /*
2 * Copyright 2010-2011 Calxeda, Inc. 2 * Copyright 2010-2011 Calxeda, Inc.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free 5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option) 6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version. 7 * any later version.
8 * 8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT 9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details. 12 * more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License along with 14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>. 15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #ifndef __MENU_H__ 18 #ifndef __MENU_H__
19 #define __MENU_H__ 19 #define __MENU_H__
20 20
21 struct menu; 21 struct menu;
22 22
23 struct menu *menu_create(char *title, int timeout, int prompt, 23 struct menu *menu_create(char *title, int timeout, int prompt,
24 void (*item_data_print)(void *)); 24 void (*item_data_print)(void *),
25 char *(*item_choice)(void *),
26 void *item_choice_data);
25 int menu_default_set(struct menu *m, char *item_key); 27 int menu_default_set(struct menu *m, char *item_key);
26 int menu_get_choice(struct menu *m, void **choice); 28 int menu_get_choice(struct menu *m, void **choice);
27 int menu_item_add(struct menu *m, char *item_key, void *item_data); 29 int menu_item_add(struct menu *m, char *item_key, void *item_data);
28 int menu_destroy(struct menu *m); 30 int menu_destroy(struct menu *m);
29 void menu_display_statusline(struct menu *m); 31 void menu_display_statusline(struct menu *m);
32 int menu_default_choice(struct menu *m, void **choice);
30 33
31 #if defined(CONFIG_MENU_SHOW) 34 #if defined(CONFIG_MENU_SHOW)
32 int menu_show(int bootdelay); 35 int menu_show(int bootdelay);
33 #endif 36 #endif
34 #endif /* __MENU_H__ */ 37 #endif /* __MENU_H__ */
35 38