Blame view
cmd/fpga.c
8.96 KB
4a9cbbe83 Initial revision |
1 2 3 4 |
/* * (C) Copyright 2000, 2001 * Rich Ireland, Enterasys Networks, rireland@enterasys.com. * |
1a4596601 Add GPL-2.0+ SPDX... |
5 |
* SPDX-License-Identifier: GPL-2.0+ |
4a9cbbe83 Initial revision |
6 7 8 9 10 11 12 |
*/ /* * FPGA support */ #include <common.h> #include <command.h> |
8bde7f776 * Code cleanup: |
13 |
#include <fpga.h> |
1a897668a fpga: Added suppo... |
14 |
#include <fs.h> |
c3d2b4b48 Code cleanup. |
15 |
#include <malloc.h> |
4a9cbbe83 Initial revision |
16 |
|
4a9cbbe83 Initial revision |
17 |
/* Local functions */ |
fc598412c cmd: fpga: Clean ... |
18 |
static int fpga_get_op(char *opstr); |
4a9cbbe83 Initial revision |
19 20 |
/* Local defines */ |
5cf22289a fpga: Use enum fo... |
21 22 23 24 25 26 27 28 29 30 31 |
enum { FPGA_NONE = -1, FPGA_INFO, FPGA_LOAD, FPGA_LOADB, FPGA_DUMP, FPGA_LOADMK, FPGA_LOADP, FPGA_LOADBP, FPGA_LOADFS, }; |
4a9cbbe83 Initial revision |
32 33 34 35 36 37 38 39 40 |
/* ------------------------------------------------------------------------- */ /* command form: * fpga <op> <device number> <data addr> <datasize> * where op is 'load', 'dump', or 'info' * If there is no device number field, the fpga environment variable is used. * If there is no data addr field, the fpgadata environment variable is used. * The info command requires no data address field. */ |
fc598412c cmd: fpga: Clean ... |
41 |
int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) |
4a9cbbe83 Initial revision |
42 |
{ |
d4ca31c40 * Cleanup lowboot... |
43 44 45 |
int op, dev = FPGA_INVALID_DEVICE; size_t data_size = 0; void *fpga_data = NULL; |
00caae6d4 env: Rename geten... |
46 47 |
char *devstr = env_get("fpga"); char *datastr = env_get("fpgadata"); |
d4ca31c40 * Cleanup lowboot... |
48 |
int rc = FPGA_FAIL; |
a790b5b23 cmd_fpga: cleanup... |
49 |
int wrong_parms = 0; |
fc598412c cmd: fpga: Clean ... |
50 |
#if defined(CONFIG_FIT) |
c28c4d193 [new uImage] Add ... |
51 52 53 |
const char *fit_uname = NULL; ulong fit_addr; #endif |
1a897668a fpga: Added suppo... |
54 55 56 57 |
#if defined(CONFIG_CMD_FPGA_LOADFS) fpga_fs_info fpga_fsinfo; fpga_fsinfo.fstype = FS_TYPE_ANY; #endif |
d4ca31c40 * Cleanup lowboot... |
58 59 |
if (devstr) |
fc598412c cmd: fpga: Clean ... |
60 |
dev = (int) simple_strtoul(devstr, NULL, 16); |
d4ca31c40 * Cleanup lowboot... |
61 |
if (datastr) |
fc598412c cmd: fpga: Clean ... |
62 |
fpga_data = (void *)simple_strtoul(datastr, NULL, 16); |
d4ca31c40 * Cleanup lowboot... |
63 64 |
switch (argc) { |
1a897668a fpga: Added suppo... |
65 66 67 68 69 70 71 72 |
#if defined(CONFIG_CMD_FPGA_LOADFS) case 9: fpga_fsinfo.blocksize = (unsigned int) simple_strtoul(argv[5], NULL, 16); fpga_fsinfo.interface = argv[6]; fpga_fsinfo.dev_part = argv[7]; fpga_fsinfo.filename = argv[8]; #endif |
d4ca31c40 * Cleanup lowboot... |
73 |
case 5: /* fpga <op> <dev> <data> <datasize> */ |
fc598412c cmd: fpga: Clean ... |
74 |
data_size = simple_strtoul(argv[4], NULL, 16); |
c28c4d193 [new uImage] Add ... |
75 |
|
d4ca31c40 * Cleanup lowboot... |
76 |
case 4: /* fpga <op> <dev> <data> */ |
c28c4d193 [new uImage] Add ... |
77 |
#if defined(CONFIG_FIT) |
fc598412c cmd: fpga: Clean ... |
78 79 |
if (fit_parse_subimage(argv[3], (ulong)fpga_data, &fit_addr, &fit_uname)) { |
c28c4d193 [new uImage] Add ... |
80 |
fpga_data = (void *)fit_addr; |
fc598412c cmd: fpga: Clean ... |
81 82 83 84 |
debug("* fpga: subimage '%s' from FIT image ", fit_uname); debug("at 0x%08lx ", fit_addr); |
c28c4d193 [new uImage] Add ... |
85 86 87 |
} else #endif { |
fc598412c cmd: fpga: Clean ... |
88 |
fpga_data = (void *)simple_strtoul(argv[3], NULL, 16); |
06297db06 FPGA: use debug()... |
89 90 |
debug("* fpga: cmdline image address = 0x%08lx ", |
fc598412c cmd: fpga: Clean ... |
91 |
(ulong)fpga_data); |
c28c4d193 [new uImage] Add ... |
92 |
} |
455ad585e fpga: Fix compila... |
93 94 |
debug("%s: fpga_data = 0x%lx ", __func__, (ulong)fpga_data); |
c28c4d193 [new uImage] Add ... |
95 |
|
d4ca31c40 * Cleanup lowboot... |
96 |
case 3: /* fpga <op> <dev | data addr> */ |
fc598412c cmd: fpga: Clean ... |
97 |
dev = (int)simple_strtoul(argv[2], NULL, 16); |
06297db06 FPGA: use debug()... |
98 99 |
debug("%s: device = %d ", __func__, dev); |
d4ca31c40 * Cleanup lowboot... |
100 |
/* FIXME - this is a really weak test */ |
fc598412c cmd: fpga: Clean ... |
101 102 |
if ((argc == 3) && (dev > fpga_count())) { /* must be buffer ptr */ |
06297db06 FPGA: use debug()... |
103 104 |
debug("%s: Assuming buffer pointer in arg 3 ", |
fc598412c cmd: fpga: Clean ... |
105 |
__func__); |
c28c4d193 [new uImage] Add ... |
106 107 |
#if defined(CONFIG_FIT) |
fc598412c cmd: fpga: Clean ... |
108 109 |
if (fit_parse_subimage(argv[2], (ulong)fpga_data, &fit_addr, &fit_uname)) { |
c28c4d193 [new uImage] Add ... |
110 |
fpga_data = (void *)fit_addr; |
fc598412c cmd: fpga: Clean ... |
111 112 113 114 |
debug("* fpga: subimage '%s' from FIT image ", fit_uname); debug("at 0x%08lx ", fit_addr); |
c28c4d193 [new uImage] Add ... |
115 116 117 |
} else #endif { |
455ad585e fpga: Fix compila... |
118 |
fpga_data = (void *)(uintptr_t)dev; |
fc598412c cmd: fpga: Clean ... |
119 120 121 |
debug("* fpga: cmdline image addr = 0x%08lx ", (ulong)fpga_data); |
c28c4d193 [new uImage] Add ... |
122 |
} |
455ad585e fpga: Fix compila... |
123 124 125 |
debug("%s: fpga_data = 0x%lx ", __func__, (ulong)fpga_data); |
d4ca31c40 * Cleanup lowboot... |
126 127 |
dev = FPGA_INVALID_DEVICE; /* reset device num */ } |
c28c4d193 [new uImage] Add ... |
128 |
|
d4ca31c40 * Cleanup lowboot... |
129 |
case 2: /* fpga <op> */ |
fc598412c cmd: fpga: Clean ... |
130 |
op = (int)fpga_get_op(argv[1]); |
d4ca31c40 * Cleanup lowboot... |
131 |
break; |
c28c4d193 [new uImage] Add ... |
132 |
|
d4ca31c40 * Cleanup lowboot... |
133 |
default: |
fc598412c cmd: fpga: Clean ... |
134 135 |
debug("%s: Too many or too few args (%d) ", __func__, argc); |
d4ca31c40 * Cleanup lowboot... |
136 137 138 |
op = FPGA_NONE; /* force usage display */ break; } |
a790b5b23 cmd_fpga: cleanup... |
139 140 141 142 143 144 145 146 147 148 |
if (dev == FPGA_INVALID_DEVICE) { puts("FPGA device not specified "); op = FPGA_NONE; } switch (op) { case FPGA_NONE: case FPGA_INFO: break; |
1a897668a fpga: Added suppo... |
149 150 151 152 153 154 155 |
#if defined(CONFIG_CMD_FPGA_LOADFS) case FPGA_LOADFS: /* Blocksize can be zero */ if (!fpga_fsinfo.interface || !fpga_fsinfo.dev_part || !fpga_fsinfo.filename) wrong_parms = 1; #endif |
a790b5b23 cmd_fpga: cleanup... |
156 |
case FPGA_LOAD: |
67193864b fpga: Add support... |
157 |
case FPGA_LOADP: |
a790b5b23 cmd_fpga: cleanup... |
158 |
case FPGA_LOADB: |
67193864b fpga: Add support... |
159 |
case FPGA_LOADBP: |
a790b5b23 cmd_fpga: cleanup... |
160 161 162 163 |
case FPGA_DUMP: if (!fpga_data || !data_size) wrong_parms = 1; break; |
64e809afe fpga: Guard the L... |
164 |
#if defined(CONFIG_CMD_FPGA_LOADMK) |
a790b5b23 cmd_fpga: cleanup... |
165 166 167 168 |
case FPGA_LOADMK: if (!fpga_data) wrong_parms = 1; break; |
64e809afe fpga: Guard the L... |
169 |
#endif |
a790b5b23 cmd_fpga: cleanup... |
170 171 172 173 174 175 176 |
} if (wrong_parms) { puts("Wrong parameters for FPGA request "); op = FPGA_NONE; } |
d4ca31c40 * Cleanup lowboot... |
177 178 |
switch (op) { case FPGA_NONE: |
4c12eeb8b Convert cmd_usage... |
179 |
return CMD_RET_USAGE; |
d4ca31c40 * Cleanup lowboot... |
180 181 |
case FPGA_INFO: |
fc598412c cmd: fpga: Clean ... |
182 |
rc = fpga_info(dev); |
d4ca31c40 * Cleanup lowboot... |
183 184 185 |
break; case FPGA_LOAD: |
7a78bd267 fpga: Define bits... |
186 |
rc = fpga_load(dev, fpga_data, data_size, BIT_FULL); |
d4ca31c40 * Cleanup lowboot... |
187 |
break; |
67193864b fpga: Add support... |
188 189 190 191 192 |
#if defined(CONFIG_CMD_FPGA_LOADP) case FPGA_LOADP: rc = fpga_load(dev, fpga_data, data_size, BIT_PARTIAL); break; #endif |
30ce5ab04 * Patch by Gleb N... |
193 |
case FPGA_LOADB: |
7a78bd267 fpga: Define bits... |
194 |
rc = fpga_loadbitstream(dev, fpga_data, data_size, BIT_FULL); |
30ce5ab04 * Patch by Gleb N... |
195 |
break; |
67193864b fpga: Add support... |
196 197 198 199 200 |
#if defined(CONFIG_CMD_FPGA_LOADBP) case FPGA_LOADBP: rc = fpga_loadbitstream(dev, fpga_data, data_size, BIT_PARTIAL); break; #endif |
1a897668a fpga: Added suppo... |
201 202 203 204 205 |
#if defined(CONFIG_CMD_FPGA_LOADFS) case FPGA_LOADFS: rc = fpga_fsload(dev, fpga_data, data_size, &fpga_fsinfo); break; #endif |
64e809afe fpga: Guard the L... |
206 |
#if defined(CONFIG_CMD_FPGA_LOADMK) |
f0ff4692f Add FPGA Altera C... |
207 |
case FPGA_LOADMK: |
fc598412c cmd: fpga: Clean ... |
208 |
switch (genimg_get_format(fpga_data)) { |
21d29f7f9 bootm: make use o... |
209 |
#if defined(CONFIG_IMAGE_FORMAT_LEGACY) |
d5934ad77 [new uImage] Add ... |
210 211 |
case IMAGE_FORMAT_LEGACY: { |
fc598412c cmd: fpga: Clean ... |
212 213 214 |
image_header_t *hdr = (image_header_t *)fpga_data; ulong data; |
32d7cdd36 fpga: Add support... |
215 216 217 218 |
uint8_t comp; comp = image_get_comp(hdr); if (comp == IH_COMP_GZIP) { |
1b63aaa58 fpga: Protect GZI... |
219 |
#if defined(CONFIG_GZIP) |
32d7cdd36 fpga: Add support... |
220 221 222 223 224 225 226 227 228 229 230 231 |
ulong image_buf = image_get_data(hdr); data = image_get_load(hdr); ulong image_size = ~0UL; if (gunzip((void *)data, ~0UL, (void *)image_buf, &image_size) != 0) { puts("GUNZIP: error "); return 1; } data_size = image_size; |
1b63aaa58 fpga: Protect GZI... |
232 233 234 235 236 |
#else puts("Gunzip image is not supported "); return 1; #endif |
32d7cdd36 fpga: Add support... |
237 238 239 240 |
} else { data = (ulong)image_get_data(hdr); data_size = image_get_data_size(hdr); } |
7a78bd267 fpga: Define bits... |
241 242 |
rc = fpga_load(dev, (void *)data, data_size, BIT_FULL); |
f0ff4692f Add FPGA Altera C... |
243 |
} |
d5934ad77 [new uImage] Add ... |
244 |
break; |
21d29f7f9 bootm: make use o... |
245 |
#endif |
d5934ad77 [new uImage] Add ... |
246 247 |
#if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: |
c28c4d193 [new uImage] Add ... |
248 249 250 |
{ const void *fit_hdr = (const void *)fpga_data; int noffset; |
e6a857da7 fpga: constify to... |
251 |
const void *fit_data; |
c28c4d193 [new uImage] Add ... |
252 253 |
if (fit_uname == NULL) { |
fc598412c cmd: fpga: Clean ... |
254 255 |
puts("No FIT subimage unit name "); |
c28c4d193 [new uImage] Add ... |
256 257 |
return 1; } |
fc598412c cmd: fpga: Clean ... |
258 259 260 |
if (!fit_check_format(fit_hdr)) { puts("Bad FIT image format "); |
c28c4d193 [new uImage] Add ... |
261 262 263 264 |
return 1; } /* get fpga component image node offset */ |
fc598412c cmd: fpga: Clean ... |
265 266 |
noffset = fit_image_get_node(fit_hdr, fit_uname); |
c28c4d193 [new uImage] Add ... |
267 |
if (noffset < 0) { |
fc598412c cmd: fpga: Clean ... |
268 269 270 |
printf("Can't find '%s' FIT subimage ", fit_uname); |
c28c4d193 [new uImage] Add ... |
271 272 273 274 |
return 1; } /* verify integrity */ |
b8da83665 image: Rename fit... |
275 |
if (!fit_image_verify(fit_hdr, noffset)) { |
c28c4d193 [new uImage] Add ... |
276 277 278 279 280 281 |
puts ("Bad Data Hash "); return 1; } /* get fpga subimage data address and length */ |
fc598412c cmd: fpga: Clean ... |
282 283 284 285 |
if (fit_image_get_data(fit_hdr, noffset, &fit_data, &data_size)) { puts("Fpga subimage data not found "); |
c28c4d193 [new uImage] Add ... |
286 287 |
return 1; } |
7a78bd267 fpga: Define bits... |
288 289 |
rc = fpga_load(dev, fit_data, data_size, BIT_FULL); |
c28c4d193 [new uImage] Add ... |
290 |
} |
d5934ad77 [new uImage] Add ... |
291 292 293 |
break; #endif default: |
fc598412c cmd: fpga: Clean ... |
294 295 |
puts("** Unknown image type "); |
d5934ad77 [new uImage] Add ... |
296 297 |
rc = FPGA_FAIL; break; |
f0ff4692f Add FPGA Altera C... |
298 299 |
} break; |
64e809afe fpga: Guard the L... |
300 |
#endif |
f0ff4692f Add FPGA Altera C... |
301 |
|
d4ca31c40 * Cleanup lowboot... |
302 |
case FPGA_DUMP: |
fc598412c cmd: fpga: Clean ... |
303 |
rc = fpga_dump(dev, fpga_data, data_size); |
d4ca31c40 * Cleanup lowboot... |
304 305 306 |
break; default: |
fc598412c cmd: fpga: Clean ... |
307 308 |
printf("Unknown operation "); |
4c12eeb8b Convert cmd_usage... |
309 |
return CMD_RET_USAGE; |
d4ca31c40 * Cleanup lowboot... |
310 |
} |
fc598412c cmd: fpga: Clean ... |
311 |
return rc; |
4a9cbbe83 Initial revision |
312 |
} |
4a9cbbe83 Initial revision |
313 314 315 316 |
/* * Map op to supported operations. We don't use a table since we * would just have to relocate it from flash anyway. */ |
fc598412c cmd: fpga: Clean ... |
317 |
static int fpga_get_op(char *opstr) |
4a9cbbe83 Initial revision |
318 319 |
{ int op = FPGA_NONE; |
fc598412c cmd: fpga: Clean ... |
320 |
if (!strcmp("info", opstr)) |
4a9cbbe83 Initial revision |
321 |
op = FPGA_INFO; |
fc598412c cmd: fpga: Clean ... |
322 |
else if (!strcmp("loadb", opstr)) |
30ce5ab04 * Patch by Gleb N... |
323 |
op = FPGA_LOADB; |
fc598412c cmd: fpga: Clean ... |
324 |
else if (!strcmp("load", opstr)) |
4a9cbbe83 Initial revision |
325 |
op = FPGA_LOAD; |
67193864b fpga: Add support... |
326 327 328 329 330 331 332 333 |
#if defined(CONFIG_CMD_FPGA_LOADP) else if (!strcmp("loadp", opstr)) op = FPGA_LOADP; #endif #if defined(CONFIG_CMD_FPGA_LOADBP) else if (!strcmp("loadbp", opstr)) op = FPGA_LOADBP; #endif |
1a897668a fpga: Added suppo... |
334 335 336 337 |
#if defined(CONFIG_CMD_FPGA_LOADFS) else if (!strcmp("loadfs", opstr)) op = FPGA_LOADFS; #endif |
64e809afe fpga: Guard the L... |
338 |
#if defined(CONFIG_CMD_FPGA_LOADMK) |
fc598412c cmd: fpga: Clean ... |
339 |
else if (!strcmp("loadmk", opstr)) |
f0ff4692f Add FPGA Altera C... |
340 |
op = FPGA_LOADMK; |
64e809afe fpga: Guard the L... |
341 |
#endif |
fc598412c cmd: fpga: Clean ... |
342 |
else if (!strcmp("dump", opstr)) |
4a9cbbe83 Initial revision |
343 |
op = FPGA_DUMP; |
4a9cbbe83 Initial revision |
344 |
|
fc598412c cmd: fpga: Clean ... |
345 346 347 |
if (op == FPGA_NONE) printf("Unknown fpga operation \"%s\" ", opstr); |
4a9cbbe83 Initial revision |
348 349 |
return op; } |
1a897668a fpga: Added suppo... |
350 351 352 |
#if defined(CONFIG_CMD_FPGA_LOADFS) U_BOOT_CMD(fpga, 9, 1, do_fpga, #else |
fc598412c cmd: fpga: Clean ... |
353 |
U_BOOT_CMD(fpga, 6, 1, do_fpga, |
1a897668a fpga: Added suppo... |
354 |
#endif |
fc598412c cmd: fpga: Clean ... |
355 356 357 358 359 |
"loadable FPGA image support", "[operation type] [device number] [image address] [image size] " "fpga operations: " |
2d73f0d6c fpga: Extend dump... |
360 361 |
" dump\t[dev] [address] [size]\tLoad device to memory buffer " |
fc598412c cmd: fpga: Clean ... |
362 363 364 365 |
" info\t[dev]\t\t\tlist known device information " " load\t[dev] [address] [size]\tLoad device from memory buffer " |
67193864b fpga: Add support... |
366 367 368 369 370 |
#if defined(CONFIG_CMD_FPGA_LOADP) " loadp\t[dev] [address] [size]\t" "Load device from memory buffer with partial bitstream " #endif |
fc598412c cmd: fpga: Clean ... |
371 372 373 |
" loadb\t[dev] [address] [size]\t" "Load device from bitstream buffer (Xilinx only) " |
67193864b fpga: Add support... |
374 375 376 377 378 379 |
#if defined(CONFIG_CMD_FPGA_LOADBP) " loadbp\t[dev] [address] [size]\t" "Load device from bitstream buffer with partial bitstream" "(Xilinx only) " #endif |
1a897668a fpga: Added suppo... |
380 381 382 383 384 385 386 387 |
#if defined(CONFIG_CMD_FPGA_LOADFS) "Load device from filesystem (FAT by default) (Xilinx only) " " loadfs [dev] [address] [image size] [blocksize] <interface> " " [<dev[:part]>] <filename> " #endif |
64e809afe fpga: Guard the L... |
388 |
#if defined(CONFIG_CMD_FPGA_LOADMK) |
fc598412c cmd: fpga: Clean ... |
389 |
" loadmk [dev] [address]\tLoad device generated with mkimage" |
c28c4d193 [new uImage] Add ... |
390 |
#if defined(CONFIG_FIT) |
fc598412c cmd: fpga: Clean ... |
391 392 393 394 395 |
" " "\tFor loadmk operating on FIT format uImage address must include " "\tsubimage unit name in the form of addr:<subimg_uname>" |
c28c4d193 [new uImage] Add ... |
396 |
#endif |
64e809afe fpga: Guard the L... |
397 |
#endif |
c28c4d193 [new uImage] Add ... |
398 |
); |