Index: u-boot/README =================================================================== RCS file: /cvsroot/u-boot/u-boot/README,v retrieving revision 1.126 diff -p -u -r1.126 README --- u-boot/README 3 May 2005 14:12:25 -0000 1.126 +++ u-boot/README 10 Jun 2005 17:24:55 -0000 @@ -1310,6 +1310,12 @@ The following options need to be configu Time to wait after FPGA configuration. The default is 200 mS. + CONFIG_FPGA_IMAGE + + Enables checking fpga data for a valid U-Boot image header. + If needed, CRC is checked and data uncompressed before doing + the desired fpga operation like load, loadb, dump (see mkimage) + - Configuration Management: CONFIG_IDENT_STRING Index: u-boot/common/cmd_fpga.c =================================================================== RCS file: /cvsroot/u-boot/u-boot/common/cmd_fpga.c,v retrieving revision 1.10 diff -p -u -r1.10 cmd_fpga.c --- u-boot/common/cmd_fpga.c 22 Jan 2005 18:13:05 -0000 1.10 +++ u-boot/common/cmd_fpga.c 10 Jun 2005 17:24:55 -0000 @@ -56,6 +56,143 @@ static int fpga_get_op (char *opstr); #define FPGA_LOADB 2 #define FPGA_DUMP 3 +#ifdef CONFIG_FPGA_IMAGE +/* + * Some systems (for example LWMON) have very short watchdog periods; + * we must make sure to split long operations like memmove() or + * crc32() into reasonable chunks. + */ +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) +# define CHUNKSZ (64 * 1024) +#endif + +int gunzip (void *, int, unsigned char *, unsigned long *); + +static image_header_t header; + +/* + * Checking for a valid Firmware/Standalone Image, uncompress/copy data + * and update pointer and size + */ +static int +fpga_check_image(void **fpga_data, size_t *data_size) +{ + unsigned long len, checksum; + uchar *data; + image_header_t *hdr = &header; + int rc = 0; + uint unc_len = 0x400000; + char *name, *s; + int verify; + + /* Copy header so we can blank CRC field for re-calculation */ + memcpy (&header, *fpga_data, sizeof(image_header_t)); + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + /* That's ok. Maybe it's raw data. */ + PRINTF("No Magic Number (%08x != %08x) -> Raw data.\n", ntohl(hdr->ih_magic), IH_MAGIC); + return 0; + } + + print_image_hdr(hdr); + + if (hdr->ih_os != IH_OS_U_BOOT) { + puts("No U-Boot Image\n"); + return 1; + } + + if ((hdr->ih_type != IH_TYPE_FIRMWARE) && (hdr->ih_type != IH_TYPE_STANDALONE)) { + puts("No Firmware/Standalone Image\n"); + return 1; + } + + name = "Firmware/Standalone Image"; + + data = (uchar *)&header; + len = sizeof(image_header_t); + + checksum = ntohl(hdr->ih_hcrc); + hdr->ih_hcrc = 0; + + if (crc32 (0, (char *)data, len) != checksum) { + puts("Bad Header Checksum\n"); + return 1; + } + + data = *fpga_data + sizeof(image_header_t); + len = ntohl(hdr->ih_size); + + s = getenv ("verify"); + verify = (s && (*s == 'n')) ? 0 : 1; + if (verify) { + puts(" Verifying Checksum ... "); + if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) { + puts("Bad Data CRC\n"); + return 1; + } + puts("OK\n"); + } + + switch (hdr->ih_comp) { + case IH_COMP_NONE: + printf (" Loading %s ... ", name); +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + size_t l = len; + void *to = (void *)ntohl(hdr->ih_load); + void *from = (void *)data; + + while (l > 0) { + size_t tail = (l > CHUNKSZ) ? CHUNKSZ : l; + WATCHDOG_RESET(); + memmove (to, from, tail); + to += tail; + from += tail; + l -= tail; + } +#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ + memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len); +#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ + break; + case IH_COMP_GZIP: + printf (" Uncompressing %s ... ", name); + if (gunzip ((void *)ntohl(hdr->ih_load), unc_len, + (uchar *)data, &len) != 0) { + puts ("GUNZIP ERROR - must RESET board to recover\n"); + return 1; + } + break; +#ifdef CONFIG_BZIP2 + case IH_COMP_BZIP2: + printf (" Uncompressing %s ... ", name); + /* + * If we've got less than 4 MB of malloc() space, + * use slower decompression algorithm which requires + * at most 2300 KB of memory. + */ + i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load), + &unc_len, (char *)data, len, + CFG_MALLOC_LEN < (4096 * 1024), 0); + if (i != BZ_OK) { + printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i); + return 1; + } + break; +#endif /* CONFIG_BZIP2 */ + default: + printf ("Unimplemented compression type %d\n", hdr->ih_comp); + return 1; + } + puts ("OK\n"); + + /* update the value for fpga operations */ + *fpga_data = (void *) data; + *data_size = len; + + return(rc); +} +#else /* ! CONFIG_FPGA_IMAGE */ +#define fpga_check_image(fpga_data, data_size) 0 +#endif /* CONFIG_FPGA_IMAGE */ + /* Convert bitstream data and load into the fpga */ int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size) { @@ -229,14 +366,23 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag break; case FPGA_LOAD: + rc = fpga_check_image(&fpga_data, &data_size); + if (rc) + break; rc = fpga_load (dev, fpga_data, data_size); break; case FPGA_LOADB: + rc = fpga_check_image(&fpga_data, &data_size); + if (rc) + break; rc = fpga_loadbitstream(dev, fpga_data, data_size); break; case FPGA_DUMP: + rc = fpga_check_image(&fpga_data, &data_size); + if (rc) + break; rc = fpga_dump (dev, fpga_data, data_size); break;