[U-Boot-Users] [PATCH] add: fpga loadi <dev> <src> sub command.

Adds the capability to load an image packaged with mkimage either in compressed form or not. (raw gzip & bzip2 images packed with mkimage)
fpga loadi <device number> <address of image>
Signed-off-by: Eran Liberty eran.liberty@gmail.com
Index: common/cmd_fpga.c =================================================================== --- common/cmd_fpga.c (.../tags/trunk/20070620_2_merge_to_exsw6000) (revision 69) +++ common/cmd_fpga.c (.../branches/exsw6000) (revision 69) @@ -32,6 +32,7 @@ #endif #include <fpga.h> #include <malloc.h> +#include <bzlib.h>
#if 0 #define FPGA_DEBUG @@ -45,6 +46,9 @@
#if defined (CONFIG_FPGA) && ( CONFIG_COMMANDS & CFG_CMD_FPGA )
+extern int gunzip (void *dst, int dstlen, unsigned char *src, + unsigned long *lenp); + /* Local functions */ static void fpga_usage (cmd_tbl_t * cmdtp); static int fpga_get_op (char *opstr); @@ -56,7 +60,92 @@ #define FPGA_LOADB 2 #define FPGA_DUMP 3 #define FPGA_LOADMK 4 +#define FPGA_LOADI 5
+/* Load an image */ +int fpga_loadi (int devnum, void *buf) +{ + ulong addr = (ulong) (buf); + ulong data, len, checksum; + image_header_t hdr; + unsigned int unc_len; + unsigned int *punc_len = &unc_len; + int i; + + /* Copy header so we can blank CRC field for re-calculation */ +#ifdef CONFIG_HAS_DATAFLASH + if (addr_dataflash (addr)) { + read_dataflash (addr, sizeof (image_header_t), (char *)&hdr); + } else +#endif + memmove (&hdr, (char *)addr, sizeof (image_header_t)); + if (ntohl (hdr.ih_magic) != IH_MAGIC) { + puts ("Bad Magic Number\n"); + return 1; + } + data = (ulong) & hdr; + len = sizeof (image_header_t); + + checksum = ntohl (hdr.ih_hcrc); + hdr.ih_hcrc = 0; + + if (crc32 (0, (uchar *) data, len) != checksum) { + puts ("Bad Header Checksum\n"); + return 1; + } +#ifdef CONFIG_HAS_DATAFLASH + if (addr_dataflash (addr)) { + len = ntohl (hdr.ih_size) + sizeof (image_header_t); + read_dataflash (addr, len, (char *)CFG_LOAD_ADDR); + addr = CFG_LOAD_ADDR; + } +#endif + + print_image_hdr ((image_header_t *) addr); + + data = addr + sizeof (image_header_t); + len = ntohl (hdr.ih_size); + + puts (" Verifying Checksum ... "); + if (crc32 (0, (uchar *) data, len) != ntohl (hdr.ih_dcrc)) { + printf ("Bad Data CRC\n"); + return 1; + } + puts ("OK\n"); + + switch (hdr.ih_comp) { + case IH_COMP_NONE: + memmove ((char *)CFG_LOAD_ADDR, (void *)data, len); + break; + case IH_COMP_GZIP: + if (gunzip + ((char *)CFG_LOAD_ADDR, unc_len, (uchar *) data, &len) + != 0) { + puts ("GUNZIP ERROR - FPGA not loaded\n"); + return 1; + } + len = unc_len; + break; + +#ifdef CONFIG_BZIP2 + case IH_COMP_BZIP2: + i = BZ2_bzBuffToBuffDecompress ((char *)CFG_LOAD_ADDR, punc_len, + (char *)data, len, 1, 0); + if (i != BZ_OK) { + printf ("BUNZIP2 ERROR %d - FPGA not loaded!\n", i); + return 1; + } + len = unc_len; + break; +#endif /* CONFIG_BZIP2 */ + default: + printf ("Unimplemented compression type %d\n", hdr.ih_comp); + return 1; + } + + return fpga_load(devnum,(char *)CFG_LOAD_ADDR,len); +} + /* Convert bitstream data and load into the fpga */ int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size) { @@ -248,6 +337,10 @@ rc = fpga_load (dev, fpga_data, data_size); break;
+ case FPGA_LOADI: + rc = fpga_loadi (dev, fpga_data); + break; + case FPGA_LOADB: rc = fpga_loadbitstream(dev, fpga_data, data_size); break; @@ -298,6 +391,8 @@ op = FPGA_INFO; } else if (!strcmp ("loadb", opstr)) { op = FPGA_LOADB; + } else if (!strcmp ("loadi", opstr)) { + op = FPGA_LOADI; } else if (!strcmp ("load", opstr)) { op = FPGA_LOAD; } else if (!strcmp ("loadmk", opstr)) { @@ -317,6 +412,7 @@ "fpga [operation type] [device number] [image address] [image size]\n" "fpga operations:\n" "\tinfo\tlist known device information\n" + "\tloadi\tLoad device from u-boot image\n" "\tload\tLoad device from memory buffer\n" "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n" "\tloadmk\tLoad device generated with mkimage\n"

On 7/3/07, eran.liberty@gmail.com eran.liberty@gmail.com wrote:
Adds the capability to load an image packaged with mkimage either in compressed form or not. (raw gzip & bzip2 images packed with mkimage)
fpga loadi <device number> <address of image>
I might be missing something here; wouldn't it be better to extend the loadmk command? It looks to me that loadmk currently only handles uncompressed images, but that it could be fixed to do compressed ones too. Correct me if I'm wrong.
Signed-off-by: Eran Liberty eran.liberty@gmail.com
Index: common/cmd_fpga.c
--- common/cmd_fpga.c (.../tags/trunk/20070620_2_merge_to_exsw6000) (revision 69) +++ common/cmd_fpga.c (.../branches/exsw6000) (revision 69) @@ -32,6 +32,7 @@ #endif #include <fpga.h> #include <malloc.h> +#include <bzlib.h>
#if 0 #define FPGA_DEBUG @@ -45,6 +46,9 @@
#if defined (CONFIG_FPGA) && ( CONFIG_COMMANDS & CFG_CMD_FPGA )
+extern int gunzip (void *dst, int dstlen, unsigned char *src,
unsigned long *lenp);
Very bad; please don't do this (even if it is done elsewhere). Please fix/create the appropriate gzip header file instead.
/* Local functions */ static void fpga_usage (cmd_tbl_t * cmdtp); static int fpga_get_op (char *opstr); @@ -56,7 +60,92 @@ #define FPGA_LOADB 2 #define FPGA_DUMP 3 #define FPGA_LOADMK 4 +#define FPGA_LOADI 5
+/* Load an image */ +int fpga_loadi (int devnum, void *buf) +{
ulong addr = (ulong) (buf);
ulong data, len, checksum;
image_header_t hdr;
unsigned int unc_len;
unsigned int *punc_len = &unc_len;
int i;
/* Copy header so we can blank CRC field for re-calculation */
+#ifdef CONFIG_HAS_DATAFLASH
if (addr_dataflash (addr)) {
read_dataflash (addr, sizeof (image_header_t), (char *)&hdr);
} else
+#endif
The Dataflash-as-memory concept is depreciated. You shouldn't add the dataflash hooks to new code.
memmove (&hdr, (char *)addr, sizeof (image_header_t));
if (ntohl (hdr.ih_magic) != IH_MAGIC) {
puts ("Bad Magic Number\n");
return 1;
}
data = (ulong) & hdr;
len = sizeof (image_header_t);
checksum = ntohl (hdr.ih_hcrc);
hdr.ih_hcrc = 0;
if (crc32 (0, (uchar *) data, len) != checksum) {
puts ("Bad Header Checksum\n");
return 1;
}
+#ifdef CONFIG_HAS_DATAFLASH
if (addr_dataflash (addr)) {
len = ntohl (hdr.ih_size) + sizeof (image_header_t);
read_dataflash (addr, len, (char *)CFG_LOAD_ADDR);
addr = CFG_LOAD_ADDR;
}
+#endif
Ditto
print_image_hdr ((image_header_t *) addr);
data = addr + sizeof (image_header_t);
len = ntohl (hdr.ih_size);
puts (" Verifying Checksum ... ");
if (crc32 (0, (uchar *) data, len) != ntohl (hdr.ih_dcrc)) {
printf ("Bad Data CRC\n");
return 1;
}
puts ("OK\n");
switch (hdr.ih_comp) {
case IH_COMP_NONE:
memmove ((char *)CFG_LOAD_ADDR, (void *)data, len);
Can you use (void*) instead of (char*)?
break;
case IH_COMP_GZIP:
if (gunzip
((char *)CFG_LOAD_ADDR, unc_len, (uchar *) data, &len)
!= 0) {
nit: a little ugly; can you split the gunzip call and if() into separate lines for easy readability?
puts ("GUNZIP ERROR - FPGA not loaded\n");
return 1;
}
len = unc_len;
break;
+#ifdef CONFIG_BZIP2
case IH_COMP_BZIP2:
i = BZ2_bzBuffToBuffDecompress ((char *)CFG_LOAD_ADDR, punc_len,
(char *)data, len, 1, 0);
if (i != BZ_OK) {
printf ("BUNZIP2 ERROR %d - FPGA not loaded!\n", i);
return 1;
}
len = unc_len;
break;
+#endif /* CONFIG_BZIP2 */
Aside: I really hate these #defs; is it feasable to make it table driven instead to keep things clean? But maybe it's not worth it since there are only 3 paths including the default.
default:
printf ("Unimplemented compression type %d\n", hdr.ih_comp);
return 1;
}
return fpga_load(devnum,(char *)CFG_LOAD_ADDR,len);
+}
/* Convert bitstream data and load into the fpga */ int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size) { @@ -248,6 +337,10 @@ rc = fpga_load (dev, fpga_data, data_size); break;
case FPGA_LOADI:
rc = fpga_loadi (dev, fpga_data);
break;
case FPGA_LOADB: rc = fpga_loadbitstream(dev, fpga_data, data_size); break;
@@ -298,6 +391,8 @@ op = FPGA_INFO; } else if (!strcmp ("loadb", opstr)) { op = FPGA_LOADB;
} else if (!strcmp ("loadi", opstr)) {
op = FPGA_LOADI; } else if (!strcmp ("load", opstr)) { op = FPGA_LOAD; } else if (!strcmp ("loadmk", opstr)) {
@@ -317,6 +412,7 @@ "fpga [operation type] [device number] [image address] [image size]\n" "fpga operations:\n" "\tinfo\tlist known device information\n"
"\tloadi\tLoad device from u-boot image\n" "\tload\tLoad device from memory buffer\n" "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n" "\tloadmk\tLoad device generated with mkimage\n"
This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users

On 7/3/07, Grant Likely grant.likely@secretlab.ca wrote:
On 7/3/07, eran.liberty@gmail.com eran.liberty@gmail.com wrote:
Adds the capability to load an image packaged with mkimage either in compressed form or not. (raw gzip & bzip2 images packed with mkimage)
fpga loadi <device number> <address of image>
I might be missing something here; wouldn't it be better to extend the loadmk command? It looks to me that loadmk currently only handles uncompressed images, but that it could be fixed to do compressed ones too. Correct me if I'm wrong.
You are not wrong. Still I would like to argue 4 points
1. To start with, when i wrote this functionality, loadmk was not patched in yet... (not a very strong point :) )
2. If we take a closer look at loadmk, its 10 lines long and this same functionality is within my loadi under the "IH_COMP_NONE" case. (some what stornger)
3. with the addition of the decompression functionality, loadmk will be too long to be inlined in the the switch - case as it is right now. It would be exported to a function loadmk_func() and it will be called from the switch case. That is what loadi does. So you can either trash the original loadmk or rename my function to loadmk function and call it from loadmk... the out come is the same, only syntactical change. (Even stronger)
4. I prefer the name loadi over loadmk. (The best argue in the world :) )
Signed-off-by: Eran Liberty eran.liberty@gmail.com
Index: common/cmd_fpga.c
--- common/cmd_fpga.c (.../tags/trunk/20070620_2_merge_to_exsw6000) (revision 69) +++ common/cmd_fpga.c (.../branches/exsw6000) (revision 69) @@ -32,6 +32,7 @@ #endif #include <fpga.h> #include <malloc.h> +#include <bzlib.h>
#if 0 #define FPGA_DEBUG @@ -45,6 +46,9 @@
#if defined (CONFIG_FPGA) && ( CONFIG_COMMANDS & CFG_CMD_FPGA )
+extern int gunzip (void *dst, int dstlen, unsigned char *src,
unsigned long *lenp);
Very bad; please don't do this (even if it is done elsewhere). Please fix/create the appropriate gzip header file instead.
Agree! the gunzip function is not exported (defined in the header file) I wanted not to change any files I had no direct need to. should I add gunzip declaration to a header file?
/* Local functions */ static void fpga_usage (cmd_tbl_t * cmdtp); static int fpga_get_op (char *opstr); @@ -56,7 +60,92 @@ #define FPGA_LOADB 2 #define FPGA_DUMP 3 #define FPGA_LOADMK 4 +#define FPGA_LOADI 5
+/* Load an image */ +int fpga_loadi (int devnum, void *buf) +{
ulong addr = (ulong) (buf);
ulong data, len, checksum;
image_header_t hdr;
unsigned int unc_len;
unsigned int *punc_len = &unc_len;
int i;
/* Copy header so we can blank CRC field for re-calculation */
+#ifdef CONFIG_HAS_DATAFLASH
if (addr_dataflash (addr)) {
read_dataflash (addr, sizeof (image_header_t), (char *)&hdr);
} else
+#endif
The Dataflash-as-memory concept is depreciated. You shouldn't add the dataflash hooks to new code.
OK,
memmove (&hdr, (char *)addr, sizeof (image_header_t));
if (ntohl (hdr.ih_magic) != IH_MAGIC) {
puts ("Bad Magic Number\n");
return 1;
}
data = (ulong) & hdr;
len = sizeof (image_header_t);
checksum = ntohl (hdr.ih_hcrc);
hdr.ih_hcrc = 0;
if (crc32 (0, (uchar *) data, len) != checksum) {
puts ("Bad Header Checksum\n");
return 1;
}
+#ifdef CONFIG_HAS_DATAFLASH
if (addr_dataflash (addr)) {
len = ntohl (hdr.ih_size) + sizeof (image_header_t);
read_dataflash (addr, len, (char *)CFG_LOAD_ADDR);
addr = CFG_LOAD_ADDR;
}
+#endif
Ditto
OK again,
print_image_hdr ((image_header_t *) addr);
data = addr + sizeof (image_header_t);
len = ntohl (hdr.ih_size);
puts (" Verifying Checksum ... ");
if (crc32 (0, (uchar *) data, len) != ntohl (hdr.ih_dcrc)) {
printf ("Bad Data CRC\n");
return 1;
}
puts ("OK\n");
switch (hdr.ih_comp) {
case IH_COMP_NONE:
memmove ((char *)CFG_LOAD_ADDR, (void *)data, len);
Can you use (void*) instead of (char*)?
sure!
break;
case IH_COMP_GZIP:
if (gunzip
((char *)CFG_LOAD_ADDR, unc_len, (uchar *) data, &len)
!= 0) {
nit: a little ugly; can you split the gunzip call and if() into separate lines for easy readability?
not ugly in my book, but can do. :)
puts ("GUNZIP ERROR - FPGA not loaded\n");
return 1;
}
len = unc_len;
break;
+#ifdef CONFIG_BZIP2
case IH_COMP_BZIP2:
i = BZ2_bzBuffToBuffDecompress ((char *)CFG_LOAD_ADDR, punc_len,
(char *)data, len, 1, 0);
if (i != BZ_OK) {
printf ("BUNZIP2 ERROR %d - FPGA not loaded!\n", i);
return 1;
}
len = unc_len;
break;
+#endif /* CONFIG_BZIP2 */
Aside: I really hate these #defs; is it feasable to make it table driven instead to keep things clean? But maybe it's not worth it since there are only 3 paths including the default.
Lets leave this one alone...
default:
printf ("Unimplemented compression type %d\n", hdr.ih_comp);
return 1;
}
return fpga_load(devnum,(char *)CFG_LOAD_ADDR,len);
+}
/* Convert bitstream data and load into the fpga */ int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size) { @@ -248,6 +337,10 @@ rc = fpga_load (dev, fpga_data, data_size); break;
case FPGA_LOADI:
rc = fpga_loadi (dev, fpga_data);
break;
case FPGA_LOADB: rc = fpga_loadbitstream(dev, fpga_data, data_size); break;
@@ -298,6 +391,8 @@ op = FPGA_INFO; } else if (!strcmp ("loadb", opstr)) { op = FPGA_LOADB;
} else if (!strcmp ("loadi", opstr)) {
op = FPGA_LOADI; } else if (!strcmp ("load", opstr)) { op = FPGA_LOAD; } else if (!strcmp ("loadmk", opstr)) {
@@ -317,6 +412,7 @@ "fpga [operation type] [device number] [image address] [image size]\n" "fpga operations:\n" "\tinfo\tlist known device information\n"
"\tloadi\tLoad device from u-boot image\n" "\tload\tLoad device from memory buffer\n" "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n" "\tloadmk\tLoad device generated with mkimage\n"
This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users
-- Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd. grant.likely@secretlab.ca (403) 399-0195

On 7/4/07, eran liberty eran.liberty@gmail.com wrote:
On 7/3/07, Grant Likely grant.likely@secretlab.ca wrote:
I might be missing something here; wouldn't it be better to extend the loadmk command? It looks to me that loadmk currently only handles uncompressed images, but that it could be fixed to do compressed ones too. Correct me if I'm wrong.
You are not wrong. Still I would like to argue 4 points
- To start with, when i wrote this functionality, loadmk was not
patched in yet... (not a very strong point :) )
- If we take a closer look at loadmk, its 10 lines long and this same
functionality is within my loadi under the "IH_COMP_NONE" case. (some what stornger)
- with the addition of the decompression functionality, loadmk will
be too long to be inlined in the the switch - case as it is right now. It would be exported to a function loadmk_func() and it will be called from the switch case. That is what loadi does. So you can either trash the original loadmk or rename my function to loadmk function and call it from loadmk... the out come is the same, only syntactical change. (Even stronger)
- I prefer the name loadi over loadmk. (The best argue in the world :) )
Heh; I also hate it when things change underneath me. :-) Regardless, you should consolidate. The name doesn't matter much, and loadmk was in first; so you should stick with loadmk. It's probably fine if you swap in your implementation, but make sure you cc the author of loadmk when you submit the patch.
+extern int gunzip (void *dst, int dstlen, unsigned char *src,
unsigned long *lenp);
Very bad; please don't do this (even if it is done elsewhere). Please fix/create the appropriate gzip header file instead.
Agree! the gunzip function is not exported (defined in the header file) I wanted not to change any files I had no direct need to. should I add gunzip declaration to a header file?
Add the gunzip decl to the header please. Submit as a separate patch. For extra credit; include a patch to remove all the spurious extern gunzip() decls scattered about the various .c files. :-)
break;
case IH_COMP_GZIP:
if (gunzip
((char *)CFG_LOAD_ADDR, unc_len, (uchar *) data, &len)
!= 0) {
nit: a little ugly; can you split the gunzip call and if() into separate lines for easy readability?
not ugly in my book, but can do. :)
Heh; only ugly because the if() is longer than 80chars and spills over 3 lines. :-)
Cheers, g.
participants (3)
-
eran liberty
-
eran.liberty@gmail.com
-
Grant Likely