diff options
Diffstat (limited to 'common')
48 files changed, 2282 insertions, 297 deletions
diff --git a/common/Makefile b/common/Makefile index 9bfc11a..7e45a7c 100644 --- a/common/Makefile +++ b/common/Makefile @@ -31,7 +31,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o \ cmd_ace.o cmd_autoscript.o \ cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o \ cmd_cache.o cmd_console.o \ - cmd_date.o cmd_dcr.o cmd_diag.o cmd_doc.o cmd_dtt.o \ + cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \ cmd_eeprom.o cmd_elf.o cmd_ext2.o \ cmd_fat.o cmd_fdc.o cmd_fdos.o cmd_flash.o cmd_fpga.o \ cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \ @@ -39,14 +39,17 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o \ cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \ cmd_nand.o cmd_nand_new.o cmd_net.o cmd_nvedit.o \ cmd_pci.o cmd_pcmcia.o cmd_portio.o \ - cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o cmd_usb.o cmd_vfd.o \ + cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \ + cmd_usb.o cmd_vfd.o \ command.o console.o devices.o dlmalloc.o docecc.o \ environment.o env_common.o \ - env_nand.o env_dataflash.o env_flash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \ - flash.o fpga.o \ + env_nand.o env_dataflash.o env_flash.o env_eeprom.o \ + env_nvram.o env_nowhere.o \ + exports.o \ + flash.o fpga.o ft_build.o \ hush.o kgdb.o lcd.o lists.o lynxkdi.o \ memsize.o miiphybb.o miiphyutil.o \ - s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o \ + s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \ usb.o usb_kbd.o usb_storage.o \ virtex2.o xilinx.o diff --git a/common/cmd_ace.c b/common/cmd_ace.c index fb4d358..b6d6105 100644 --- a/common/cmd_ace.c +++ b/common/cmd_ace.c @@ -131,6 +131,7 @@ block_dev_desc_t * systemace_get_dev(int dev) not yet initialized. In that case, fill it in. */ if (systemace_dev.blksz == 0) { systemace_dev.if_type = IF_TYPE_UNKNOWN; + systemace_dev.dev = 0; systemace_dev.part_type = PART_TYPE_UNKNOWN; systemace_dev.type = DEV_TYPE_HARDDISK; systemace_dev.blksz = 512; diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index 2d1f431..e325302 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -76,7 +76,7 @@ autoscript (ulong addr) hdr->ih_hcrc = 0; len = sizeof (image_header_t); data = (ulong)hdr; - if (crc32(0, (char *)data, len) != crc) { + if (crc32(0, (uchar *)data, len) != crc) { puts ("Bad header crc\n"); return 1; } @@ -85,7 +85,7 @@ autoscript (ulong addr) len = ntohl(hdr->ih_size); if (verify) { - if (crc32(0, (char *)data, len) != ntohl(hdr->ih_dcrc)) { + if (crc32(0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { puts ("Bad data crc\n"); return 1; } diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c index daa54e7..ad412c8 100644 --- a/common/cmd_bmp.c +++ b/common/cmd_bmp.c @@ -29,12 +29,15 @@ #include <bmp_layout.h> #include <command.h> #include <asm/byteorder.h> +#include <malloc.h> #if (CONFIG_COMMANDS & CFG_CMD_BMP) static int bmp_info (ulong addr); static int bmp_display (ulong addr, int x, int y); +int gunzip(void *, int, unsigned char *, unsigned long *); + /* * Subroutine: do_bmp * @@ -100,15 +103,64 @@ U_BOOT_CMD( static int bmp_info(ulong addr) { bmp_image_t *bmp=(bmp_image_t *)addr; +#ifdef CONFIG_VIDEO_BMP_GZIP + unsigned char *dst = NULL; + ulong len; +#endif /* CONFIG_VIDEO_BMP_GZIP */ + if (!((bmp->header.signature[0]=='B') && (bmp->header.signature[1]=='M'))) { + +#ifdef CONFIG_VIDEO_BMP_GZIP + /* + * Decompress bmp image + */ + len = CFG_VIDEO_LOGO_MAX_SIZE; + dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE); + if (dst == NULL) { + printf("Error: malloc in gunzip failed!\n"); + return(1); + } + if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)addr, &len) != 0) { + printf("There is no valid bmp file at the given address\n"); + return(1); + } + if (len == CFG_VIDEO_LOGO_MAX_SIZE) { + printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n"); + } + + /* + * Set addr to decompressed image + */ + bmp = (bmp_image_t *)dst; + + /* + * Check for bmp mark 'BM' + */ + if (!((bmp->header.signature[0] == 'B') && + (bmp->header.signature[1] == 'M'))) { + printf("There is no valid bmp file at the given address\n"); + free(dst); + return(1); + } + + printf("Gzipped BMP image detected!\n"); +#else /* CONFIG_VIDEO_BMP_GZIP */ printf("There is no valid bmp file at the given address\n"); return(1); +#endif /* CONFIG_VIDEO_BMP_GZIP */ } printf("Image size : %d x %d\n", le32_to_cpu(bmp->header.width), le32_to_cpu(bmp->header.height)); printf("Bits per pixel: %d\n", le16_to_cpu(bmp->header.bit_count)); printf("Compression : %d\n", le32_to_cpu(bmp->header.compression)); + +#ifdef CONFIG_VIDEO_BMP_GZIP + if (dst) { + free(dst); + } +#endif /* CONFIG_VIDEO_BMP_GZIP */ + return(0); } diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index c200fd8..8599a49 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -34,6 +34,10 @@ #include <environment.h> #include <asm/byteorder.h> +#ifdef CONFIG_OF_FLAT_TREE +#include <ft_build.h> +#endif + /*cmd_boot.c*/ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); @@ -84,7 +88,7 @@ static int image_info (unsigned long addr); #if (CONFIG_COMMANDS & CFG_CMD_IMLS) #include <flash.h> -extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ +extern flash_info_t flash_info[]; /* info for FLASH chips */ static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif @@ -197,29 +201,31 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; - if (crc32 (0, (char *)data, len) != checksum) { + if (crc32 (0, (uchar *)data, len) != checksum) { puts ("Bad Header Checksum\n"); SHOW_BOOT_PROGRESS (-2); return 1; } SHOW_BOOT_PROGRESS (3); +#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 + + /* for multi-file images we need the data part, too */ print_image_hdr ((image_header_t *)addr); data = addr + sizeof(image_header_t); len = ntohl(hdr->ih_size); -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash(addr)){ - read_dataflash(data, len, (char *)CFG_LOAD_ADDR); - data = CFG_LOAD_ADDR; - } -#endif - if (verify) { puts (" Verifying Checksum ... "); - if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) { + if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { printf ("Bad Data CRC\n"); SHOW_BOOT_PROGRESS (-3); return 1; @@ -487,6 +493,11 @@ fixup_silent_linux () } #endif /* CONFIG_SILENT_CONSOLE */ +#ifdef CONFIG_OF_FLAT_TREE +extern const unsigned char oftree_dtb[]; +extern const unsigned int oftree_dtb_len; +#endif + #ifdef CONFIG_PPC static void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, @@ -509,6 +520,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, bd_t *kbd; void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); image_header_t *hdr = &header; +#ifdef CONFIG_OF_FLAT_TREE + char *of_flat_tree; +#endif if ((s = getenv ("initrd_high")) != NULL) { /* a value of "no" or a similar string will act like 0, @@ -619,7 +633,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, checksum = hdr->ih_hcrc; hdr->ih_hcrc = 0; - if (crc32 (0, (char *)data, len) != checksum) { + if (crc32 (0, (uchar *)data, len) != checksum) { puts ("Bad Header Checksum\n"); SHOW_BOOT_PROGRESS (-11); do_reset (cmdtp, flag, argc, argv); @@ -647,13 +661,13 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, if (chunk > CHUNKSZ) chunk = CHUNKSZ; - csum = crc32 (csum, (char *)cdata, chunk); + csum = crc32 (csum, (uchar *)cdata, chunk); cdata += chunk; WATCHDOG_RESET(); } #else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - csum = crc32 (0, (char *)data, len); + csum = crc32 (0, (uchar *)data, len); #endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ if (csum != hdr->ih_dcrc) { @@ -774,15 +788,26 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, initrd_end = 0; } +#ifdef CONFIG_OF_FLAT_TREE + if (initrd_start == 0) + of_flat_tree = (char *)(((ulong)kbd - OF_FLAT_TREE_MAX_SIZE - + sizeof(bd_t)) & ~0xF); + else + of_flat_tree = (char *)((initrd_start - OF_FLAT_TREE_MAX_SIZE - + sizeof(bd_t)) & ~0xF); +#endif debug ("## Transferring control to Linux (at address %08lx) ...\n", (ulong)kernel); SHOW_BOOT_PROGRESS (15); +#ifndef CONFIG_OF_FLAT_TREE + #if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) unlock_ram_in_cache(); #endif + /* * Linux Kernel Parameters: * r3: ptr to board info data @@ -792,6 +817,25 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, * r7: End of command line string */ (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); + +#else + ft_setup(of_flat_tree, OF_FLAT_TREE_MAX_SIZE, kbd); + /* ft_dump_blob(of_flat_tree); */ + +#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) + unlock_ram_in_cache(); +#endif + /* + * Linux Kernel Parameters: + * r3: ptr to OF flat tree, followed by the board info data + * r4: initrd_start or 0 if no initrd + * r5: initrd_end - unused if r4 is 0 + * r6: Start of command line string + * r7: End of command line string + */ + (*kernel) ((bd_t *)of_flat_tree, initrd_start, initrd_end, cmd_start, cmd_end); + +#endif } #endif /* CONFIG_PPC */ @@ -1035,7 +1079,7 @@ static int image_info (ulong addr) checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; - if (crc32 (0, (char *)data, len) != checksum) { + if (crc32 (0, (uchar *)data, len) != checksum) { puts (" Bad Header Checksum\n"); return 1; } @@ -1047,7 +1091,7 @@ static int image_info (ulong addr) len = ntohl(hdr->ih_size); puts (" Verifying Checksum ... "); - if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) { + if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { puts (" Bad Data CRC\n"); return 1; } @@ -1080,7 +1124,7 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) { if (info->flash_id == FLASH_UNKNOWN) goto next_bank; - for (j=0; j<CFG_MAX_FLASH_SECT; ++j) { + for (j=0; j<info->sector_count; ++j) { if (!(hdr=(image_header_t *)info->start[j]) || (ntohl(hdr->ih_magic) != IH_MAGIC)) @@ -1092,7 +1136,7 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) checksum = ntohl(header.ih_hcrc); header.ih_hcrc = 0; - if (crc32 (0, (char *)&header, sizeof(image_header_t)) + if (crc32 (0, (uchar *)&header, sizeof(image_header_t)) != checksum) goto next_sector; @@ -1103,7 +1147,7 @@ int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) len = ntohl(hdr->ih_size); puts (" Verifying Checksum ... "); - if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) { + if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { puts (" Bad Data CRC\n"); } puts ("OK\n"); diff --git a/common/cmd_dcr.c b/common/cmd_dcr.c index 3e4e08f..5842471 100644 --- a/common/cmd_dcr.c +++ b/common/cmd_dcr.c @@ -22,7 +22,7 @@ */ /* - * IBM 4XX DCR Functions + * AMCC 4XX DCR Functions */ #include <common.h> @@ -31,89 +31,91 @@ #if defined(CONFIG_4xx) && (CONFIG_COMMANDS & CFG_CMD_SETGETDCR) -/* ====================================================================== - * Interpreter command to retrieve an IBM PPC 4xx Device Control Register - * ====================================================================== +/* ======================================================================= + * Interpreter command to retrieve an AMCC PPC 4xx Device Control Register + * ======================================================================= */ int do_getdcr ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ) { - unsigned short dcrn; /* Device Control Register Num */ - unsigned long value; /* DCR's value */ + unsigned short dcrn; /* Device Control Register Num */ + unsigned long value; /* DCR's value */ - unsigned long get_dcr(unsigned short); + unsigned long get_dcr (unsigned short); - /* Validate arguments */ - if (argc < 2) { - printf("Usage:\n%s\n", cmdtp->usage); - return 1; - } + /* Validate arguments */ + if (argc < 2) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } - /* Get a DCR */ - dcrn = (unsigned short)simple_strtoul(argv[ 1 ], NULL, 16); - value = get_dcr(dcrn); + /* Get a DCR */ + dcrn = (unsigned short) simple_strtoul (argv[1], NULL, 16); + value = get_dcr (dcrn); - printf("%04x: %08lx\n", dcrn, value); + printf ("%04x: %08lx\n", dcrn, value); - return 0; -} /* do_getdcr */ + return 0; +} /* ====================================================================== - * Interpreter command to set an IBM PPC 4xx Device Control Register + * Interpreter command to set an AMCC PPC 4xx Device Control Register * ====================================================================== */ -int do_setdcr ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_setdcr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - unsigned long get_dcr(unsigned short ); - unsigned long set_dcr(unsigned short , unsigned long ); - unsigned short dcrn; /* Device Control Register Num */ - unsigned long value; - /* DCR's value */ - int nbytes; - extern char console_buffer[]; - - /* Validate arguments */ - if (argc < 2) { - printf("Usage:\n%s\n", cmdtp->usage); - return 1; - } - - /* Set a DCR */ - dcrn = (unsigned short)simple_strtoul(argv[1], NULL, 16); - do { - value = get_dcr(dcrn); - printf("%04x: %08lx", dcrn, value); - nbytes = readline(" ? "); - if (nbytes == 0) { - /* - * <CR> pressed as only input, don't modify current - * location and exit command. - */ - nbytes = 1; - return 0; - } else { - unsigned long i; - char *endp; - i = simple_strtoul(console_buffer, &endp, 16); - nbytes = endp - console_buffer; - if (nbytes) - set_dcr(dcrn, i); + unsigned long get_dcr (unsigned short); + unsigned long set_dcr (unsigned short, unsigned long); + unsigned short dcrn; /* Device Control Register Num */ + unsigned long value; + + /* DCR's value */ + int nbytes; + extern char console_buffer[]; + + /* Validate arguments */ + if (argc < 2) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; } - } while (nbytes); - return 0; -} /* do_setdcr */ + /* Set a DCR */ + dcrn = (unsigned short) simple_strtoul (argv[1], NULL, 16); + do { + value = get_dcr (dcrn); + printf ("%04x: %08lx", dcrn, value); + nbytes = readline (" ? "); + if (nbytes == 0) { + /* + * <CR> pressed as only input, don't modify current + * location and exit command. + */ + nbytes = 1; + return 0; + } else { + unsigned long i; + char *endp; + + i = simple_strtoul (console_buffer, &endp, 16); + nbytes = endp - console_buffer; + if (nbytes) + set_dcr (dcrn, i); + } + } while (nbytes); + + return 0; +} /***************************************************/ U_BOOT_CMD( getdcr, 2, 1, do_getdcr, - "getdcr - Get an IBM PPC 4xx DCR's value\n", + "getdcr - Get an AMCC PPC 4xx DCR's value\n", "dcrn - return a DCR's value.\n" ); U_BOOT_CMD( setdcr, 2, 1, do_setdcr, - "setdcr - Set an IBM PPC 4xx DCR's value\n", + "setdcr - Set an AMCC PPC 4xx DCR's value\n", "dcrn - set a DCR's value.\n" ); diff --git a/common/cmd_display.c b/common/cmd_display.c new file mode 100644 index 0000000..abee844 --- /dev/null +++ b/common/cmd_display.c @@ -0,0 +1,82 @@ +/* + * (C) Copyright 2005 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> + +#if (CONFIG_COMMANDS & CFG_CMD_DISPLAY) + +#undef DEBUG_DISP + +#define DISP_SIZE 8 +#define CWORD_CLEAR 0x80 +#define CLEAR_DELAY (110 * 2) + +int do_display (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int i; + int pos; + + /* Clear display */ + *((volatile char*)(CFG_DISP_CWORD)) = CWORD_CLEAR; + udelay(1000 * CLEAR_DELAY); + + if (argc < 2) + return (0); + + for (pos = 0, i = 1; i < argc && pos < DISP_SIZE; i++) { + char *p = argv[i], c; + + if (i > 1) { + *((volatile uchar *) (CFG_DISP_CHR_RAM + pos++)) = ' '; +#ifdef DEBUG_DISP + putc(' '); +#endif + } + + while ((c = *p++) != '\0' && pos < DISP_SIZE) { + *((volatile uchar *) (CFG_DISP_CHR_RAM + pos++)) = c; +#ifdef DEBUG_DISP + putc(c); +#endif + } + } + +#ifdef DEBUG_DISP + putc('\n'); +#endif + + return (0); +} + +/***************************************************/ + +U_BOOT_CMD( + display, CFG_MAXARGS, 1, do_display, + "display- display string on dot matrix display\n", + "[<string>]\n" + " - with <string> argument: display <string> on dot matrix display\n" + " - without arguments: clear dot matrix display\n" +); + +#endif /* CFG_CMD_DISPLAY */ diff --git a/common/cmd_doc.c b/common/cmd_doc.c index e5db1bc..5e9bea3 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -143,7 +143,7 @@ int do_doc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) cmd ? "read" : "write", curr_device, off, size); ret = doc_rw(doc_dev_desc + curr_device, cmd, off, size, - &total, (u_char*)addr); + (size_t *)&total, (u_char*)addr); printf ("%d bytes %s: %s\n", total, cmd ? "read" : "write", ret ? "ERROR" : "OK"); @@ -304,12 +304,12 @@ int doc_rw (struct DiskOnChip* this, int cmd, if (cmd) ret = doc_read_ecc(this, from, len, - &n, (u_char*)buf, - noecc ? NULL : eccbuf); + (size_t *)&n, (u_char*)buf, + noecc ? (uchar *)NULL : (uchar *)eccbuf); else ret = doc_write_ecc(this, from, len, - &n, (u_char*)buf, - noecc ? NULL : eccbuf); + (size_t *)&n, (u_char*)buf, + noecc ? (uchar *)NULL : (uchar *)eccbuf); if (ret) break; @@ -804,7 +804,7 @@ static int find_boot_record(struct NFTLrecord *nftl) /* Check for ANAND header first. Then can whinge if it's found but later checks fail */ if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, - &retlen, buf, NULL))) { + (size_t *)&retlen, buf, NULL))) { static int warncount = 5; if (warncount) { @@ -829,7 +829,7 @@ static int find_boot_record(struct NFTLrecord *nftl) /* To be safer with BIOS, also use erase mark as discriminant */ if ((ret = doc_read_oob(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, - 8, &retlen, (char *)&h1) < 0)) { + 8, (size_t *)&retlen, (uchar *)&h1) < 0)) { #ifdef NFTL_DEBUG printf("ANAND header found at 0x%x, but OOB data read failed\n", block * nftl->EraseSize); @@ -902,7 +902,7 @@ static int find_boot_record(struct NFTLrecord *nftl) /* read one sector for every SECTORSIZE of blocks */ if ((ret = doc_read_ecc(nftl->mtd, block * nftl->EraseSize + i + SECTORSIZE, SECTORSIZE, - &retlen, buf, (char *)&oob)) < 0) { + (size_t *)&retlen, buf, (uchar *)&oob)) < 0) { puts ("Read of bad sector table failed\n"); return -1; } diff --git a/common/cmd_eeprom.c b/common/cmd_eeprom.c index 80b8ccc..d15a412 100644 --- a/common/cmd_eeprom.c +++ b/common/cmd_eeprom.c @@ -22,6 +22,21 @@ * */ +/* + * Support for read and write access to EEPROM like memory devices. This + * includes regular EEPROM as well as FRAM (ferroelectic nonvolaile RAM). + * FRAM devices read and write data at bus speed. In particular, there is no + * write delay. Also, there is no limit imposed on the numer of bytes that can + * be transferred with a single read or write. + * + * Use the following configuration options to ensure no unneeded performance + * degradation (typical for EEPROM) is incured for FRAM memory: + * + * #define CFG_I2C_FRAM + * #undef CFG_EEPROM_PAGE_WRITE_DELAY_MS + * + */ + #include <common.h> #include <config.h> #include <command.h> @@ -34,6 +49,9 @@ extern int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt); extern int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt); +#if defined(CFG_EEPROM_WREN) +extern int eeprom_write_enable (unsigned dev_addr, int state); +#endif #endif @@ -122,7 +140,11 @@ int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt * because the next page may be in a different device. */ while (offset < end) { - unsigned alen, len, maxlen; + unsigned alen, len; +#if !defined(CFG_I2C_FRAM) + unsigned maxlen; +#endif + #if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X) uchar addr[2]; @@ -144,12 +166,21 @@ int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt addr[0] |= dev_addr; /* insert device address */ + len = end - offset; + + /* + * For a FRAM device there is no limit on the number of the + * bytes that can be ccessed with the single read or write + * operation. + */ +#if !defined(CFG_I2C_FRAM) maxlen = 0x100 - blk_off; if (maxlen > I2C_RXTX_LEN) maxlen = I2C_RXTX_LEN; - len = end - offset; if (len > maxlen) len = maxlen; +#endif + #ifdef CONFIG_SPI spi_read (addr, alen, buffer, len); #else @@ -159,6 +190,7 @@ int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt buffer += len; offset += len; } + return rcode; } @@ -185,13 +217,20 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn int i; #endif +#if defined(CFG_EEPROM_WREN) + eeprom_write_enable (dev_addr,1); +#endif /* Write data until done or would cross a write page boundary. * We must write the address again when changing pages * because the address counter only increments within a page. */ while (offset < end) { - unsigned alen, len, maxlen; + unsigned alen, len; +#if !defined(CFG_I2C_FRAM) + unsigned maxlen; +#endif + #if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X) uchar addr[2]; @@ -213,6 +252,15 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn addr[0] |= dev_addr; /* insert device address */ + len = end - offset; + + /* + * For a FRAM device there is no limit on the number of the + * bytes that can be ccessed with the single read or write + * operation. + */ +#if !defined(CFG_I2C_FRAM) + #if defined(CFG_EEPROM_PAGE_WRITE_BITS) #define EEPROM_PAGE_SIZE (1 << CFG_EEPROM_PAGE_WRITE_BITS) @@ -225,9 +273,10 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn if (maxlen > I2C_RXTX_LEN) maxlen = I2C_RXTX_LEN; - len = end - offset; if (len > maxlen) len = maxlen; +#endif + #ifdef CONFIG_SPI spi_write (addr, alen, buffer, len); #else @@ -324,6 +373,9 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000); #endif } +#if defined(CFG_EEPROM_WREN) + eeprom_write_enable (dev_addr,0); +#endif return rcode; } diff --git a/common/cmd_ext2.c b/common/cmd_ext2.c index af836cd..5db42f2 100644 --- a/common/cmd_ext2.c +++ b/common/cmd_ext2.c @@ -152,7 +152,7 @@ int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD( ext2ls, 4, 1, do_ext2ls, - "ext2ls- list files in a directory (default /)\n", + "ext2ls - list files in a directory (default /)\n", "<interface> <dev[:part]> [directory]\n" " - list files from 'dev' on 'interface' in a 'directory'\n" ); @@ -231,7 +231,7 @@ int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return(1); } - if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) { + if (strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) { printf ("\n** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info.type); diff --git a/common/cmd_flash.c b/common/cmd_flash.c index d5be30c..0aa4783 100644 --- a/common/cmd_flash.c +++ b/common/cmd_flash.c @@ -404,7 +404,11 @@ int flash_sect_erase (ulong addr_first, ulong addr_last) { flash_info_t *info; ulong bank; +#ifdef CFG_MAX_FLASH_BANKS_DETECT + int s_first[CFG_MAX_FLASH_BANKS_DETECT], s_last[CFG_MAX_FLASH_BANKS_DETECT]; +#else int s_first[CFG_MAX_FLASH_BANKS], s_last[CFG_MAX_FLASH_BANKS]; +#endif int erased = 0; int planned; int rcode = 0; @@ -617,7 +621,11 @@ int flash_sect_protect (int p, ulong addr_first, ulong addr_last) { flash_info_t *info; ulong bank; +#ifdef CFG_MAX_FLASH_BANKS_DETECT + int s_first[CFG_MAX_FLASH_BANKS_DETECT], s_last[CFG_MAX_FLASH_BANKS_DETECT]; +#else int s_first[CFG_MAX_FLASH_BANKS], s_last[CFG_MAX_FLASH_BANKS]; +#endif int protected, i; int planned; int rcode; diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index c4b7392..9a01e7d 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -69,7 +69,7 @@ int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size) unsigned int i; int rc; - dataptr = fpgadata; + dataptr = (unsigned char *)fpgadata; #if CFG_FPGA_XILINX /* skip the first bytes of the bitsteam, their meaning is unknown */ diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 9c02ceb..c543bb5 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -295,7 +295,13 @@ int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * chip doesn't respond. This apparently isn't a * universal feature so we don't take advantage of it. */ +/* + * No write delay with FRAM devices. + */ +#if !defined(CFG_I2C_FRAM) udelay(11000); +#endif + #if 0 for(timeout = 0; timeout < 10; timeout++) { udelay(2000); @@ -455,7 +461,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) */ do { printf("%08lx:", addr); - if(i2c_read(chip, addr, alen, (char *)&data, size) != 0) { + if(i2c_read(chip, addr, alen, (uchar *)&data, size) != 0) { puts ("\nError reading the chip,\n"); } else { data = cpu_to_be32(data); @@ -504,7 +510,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) */ reset_cmd_timeout(); #endif - if(i2c_write(chip, addr, alen, (char *)&data, size) != 0) { + if(i2c_write(chip, addr, alen, (uchar *)&data, size) != 0) { puts ("Error writing the chip.\n"); } #ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 1adfe2b..b67d35a 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -49,7 +49,7 @@ #include <asm/io.h> #ifdef __MIPS__ /* Macros depend on this variable */ -static unsigned long mips_io_port_base = 0; +unsigned long mips_io_port_base = 0; #endif #endif @@ -417,8 +417,8 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) SHOW_BOOT_PROGRESS (-1); return 1; } - if ((strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) && - (strncmp(info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) { + if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) && + (strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) { printf ("\n** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info.type); @@ -450,7 +450,7 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; - if (crc32 (0, (char *)hdr, sizeof(image_header_t)) != checksum) { + if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { puts ("\n** Bad Header Checksum **\n"); SHOW_BOOT_PROGRESS (-2); return 1; diff --git a/common/cmd_immap.c b/common/cmd_immap.c index abf5590..559d7b4 100644 --- a/common/cmd_immap.c +++ b/common/cmd_immap.c @@ -34,6 +34,7 @@ #if defined(CONFIG_8xx) #include <asm/8xx_immap.h> #include <commproc.h> +#include <asm/iopin_8xx.h> #elif defined(CONFIG_8260) #include <asm/immap_8260.h> #include <asm/cpm_8260.h> @@ -316,13 +317,21 @@ do_iopinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { -#if defined(CONFIG_8260) uint rcode = 0; + iopin_t iopin; static uint port = 0; static uint pin = 0; static uint value = 0; - static enum { DIR, PAR, SOR, ODR, DAT } cmd = DAT; - iopin_t iopin; + static enum { + DIR, + PAR, + SOR, + ODR, + DAT, +#if defined(CONFIG_8xx) + INT +#endif + } cmd = DAT; if (argc != 5) { puts ("iopset PORT PIN CMD VALUE\n"); @@ -356,6 +365,11 @@ do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) case 's': cmd = SOR; break; +#if defined(CONFIG_8xx) + case 'i': + cmd = INT; + break; +#endif default: printf ("iopset: unknown command %s\n", argv[3]); rcode = 1; @@ -369,6 +383,7 @@ do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (rcode == 0) { iopin.port = port; iopin.pin = pin; + iopin.flag = 0; switch (cmd) { case DIR: if (value) @@ -400,14 +415,18 @@ do_iopset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) else iopin_set_low (&iopin); break; +#if defined(CONFIG_8xx) + case INT: + if (value) + iopin_set_falledge (&iopin); + else + iopin_set_anyedge (&iopin); + break; +#endif } } return rcode; -#else - unimplemented (cmdtp, flag, argc, argv); - return 0; -#endif } int diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index bc63f0c..ecadb79 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -104,10 +104,10 @@ #endif /* enable/disable debugging messages */ -#define DEBUG -#undef DEBUG +#define DEBUG_JFFS +#undef DEBUG_JFFS -#ifdef DEBUG +#ifdef DEBUG_JFFS # define DEBUGF(fmt, args...) printf(fmt ,##args) #else # define DEBUGF(fmt, args...) @@ -127,7 +127,7 @@ /* this flag needs to be set in part_info struct mask_flags * field for read-only partitions */ -#define MTD_WRITEABLE 1 +#define MTD_WRITEABLE_CMD 1 #ifdef CONFIG_JFFS2_CMDLINE /* default values for mtdids and mtdparts variables */ @@ -242,6 +242,46 @@ static void memsize_format(char *buf, u32 size) } /** + * This routine does global indexing of all partitions. Resulting index for + * current partition is saved in 'mtddevnum'. Current partition name in + * 'mtddevname'. + */ +static void index_partitions(void) +{ + char buf[16]; + u16 mtddevnum; + struct part_info *part; + struct list_head *dentry; + struct mtd_device *dev; + + DEBUGF("--- index partitions ---\n"); + + if (current_dev) { + mtddevnum = 0; + list_for_each(dentry, &devices) { + dev = list_entry(dentry, struct mtd_device, link); + if (dev == current_dev) { + mtddevnum += current_partnum; + sprintf(buf, "%d", mtddevnum); + setenv("mtddevnum", buf); + break; + } + mtddevnum += dev->num_parts; + } + + part = jffs2_part_info(current_dev, current_partnum); + setenv("mtddevname", part->name); + + DEBUGF("=> mtddevnum %d,\n=> mtddevname %s\n", mtddevnum, part->name); + } else { + setenv("mtddevnum", NULL); + setenv("mtddevname", NULL); + + DEBUGF("=> mtddevnum NULL\n=> mtddevname NULL\n"); + } +} + +/** * Save current device and partition in environment variable 'partition'. */ static void current_save(void) @@ -264,6 +304,7 @@ static void current_save(void) DEBUGF("=> partition NULL\n"); } + index_partitions(); } /** @@ -279,7 +320,7 @@ static int part_validate_nor(struct mtdids *id, struct part_info *part) { #if (CONFIG_COMMANDS & CFG_CMD_FLASH) /* info for FLASH chips */ - extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + extern flash_info_t flash_info[]; flash_info_t *flash; int offset_aligned; u32 end_offset; @@ -401,6 +442,8 @@ static int part_validate(struct mtdids *id, struct part_info *part) */ static int part_del(struct mtd_device *dev, struct part_info *part) { + u8 current_save_needed = 0; + /* if there is only one partition, remove whole device */ if (dev->num_parts == 1) return device_del(dev); @@ -417,11 +460,10 @@ static int part_del(struct mtd_device *dev, struct part_info *part) if (curr_pi == part) { printf("current partition deleted, resetting current to 0\n"); current_partnum = 0; - current_save(); } else if (part->offset <= curr_pi->offset) { current_partnum--; - current_save(); } + current_save_needed = 1; } } @@ -432,6 +474,11 @@ static int part_del(struct mtd_device *dev, struct part_info *part) free(part); dev->num_parts--; + if (current_save_needed > 0) + current_save(); + else + index_partitions(); + return 0; } @@ -475,6 +522,8 @@ static int part_sort_add(struct mtd_device *dev, struct part_info *part) if (list_empty(&dev->parts)) { DEBUGF("part_sort_add: list empty\n"); list_add(&part->link, &dev->parts); + dev->num_parts++; + index_partitions(); return 0; } @@ -498,18 +547,23 @@ static int part_sort_add(struct mtd_device *dev, struct part_info *part) if (new_pi->offset <= pi->offset) { list_add_tail(&part->link, entry); + dev->num_parts++; if (curr_pi && (pi->offset <= curr_pi->offset)) { /* we are modyfing partitions for the current * device, update current */ current_partnum++; current_save(); + } else { + index_partitions(); } - return 0; } } + list_add_tail(&part->link, &dev->parts); + dev->num_parts++; + index_partitions(); return 0; } @@ -530,7 +584,6 @@ static int part_add(struct mtd_device *dev, struct part_info *part) if (part_sort_add(dev, part) != 0) return 1; - dev->num_parts++; return 0; } @@ -600,7 +653,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i /* test for options */ mask_flags = 0; if (strncmp(p, "ro", 2) == 0) { - mask_flags |= MTD_WRITEABLE; + mask_flags |= MTD_WRITEABLE_CMD; p += 2; } @@ -665,7 +718,7 @@ static int device_validate(u8 type, u8 num, u32 *size) if (type == MTD_DEV_TYPE_NOR) { #if (CONFIG_COMMANDS & CFG_CMD_FLASH) if (num < CFG_MAX_FLASH_BANKS) { - extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + extern flash_info_t flash_info[]; *size = flash_info[num].size; return 0; @@ -746,9 +799,10 @@ static int device_del(struct mtd_device *dev) current_partnum = 0; } current_save(); + return 0; } - + index_partitions(); return 0; } @@ -782,13 +836,20 @@ static struct mtd_device* device_find(u8 type, u8 num) */ static void device_add(struct mtd_device *dev) { + u8 current_save_needed = 0; + if (list_empty(&devices)) { current_dev = dev; current_partnum = 0; - current_save(); + current_save_needed = 1; } list_add_tail(&dev->link, &devices); + + if (current_save_needed > 0) + current_save(); + else + index_partitions(); } /** @@ -907,7 +968,7 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_ } memset(dev, 0, sizeof(struct mtd_device)); dev->id = id; - dev->num_parts = num_parts; + dev->num_parts = 0; /* part_sort_add increments num_parts */ INIT_LIST_HEAD(&dev->parts); INIT_LIST_HEAD(&dev->link); @@ -1120,7 +1181,7 @@ static int generate_mtdparts(char *buf, u32 buflen) } /* ro mask flag */ - if (part->mask_flags && MTD_WRITEABLE) { + if (part->mask_flags && MTD_WRITEABLE_CMD) { len = 2; if (len > maxlen) goto cleanup; @@ -1559,7 +1620,7 @@ int mtdparts_init(void) ids_changed = 1; if (parse_mtdids(ids) != 0) { - device_delall(&devices); + devices_init(); return 1; } diff --git a/common/cmd_load.c b/common/cmd_load.c index b85db69..7498497 100644 --- a/common/cmd_load.c +++ b/common/cmd_load.c @@ -166,7 +166,7 @@ load_serial (ulong offset) if (addr2info(store_addr)) { int rc; - rc = flash_write((uchar *)binbuf,store_addr,binlen); + rc = flash_write((char *)binbuf,store_addr,binlen); if (rc != 0) { flash_perror (rc); return (~0); diff --git a/common/cmd_log.c b/common/cmd_log.c index 57ef484..efc9689 100644 --- a/common/cmd_log.c +++ b/common/cmd_log.c @@ -179,7 +179,7 @@ int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) case 2: if (strcmp(argv[1],"show") == 0) { for (i=0; i < (log_size&LOGBUFF_MASK); i++) { - s = log_buf+((log_start+i)&LOGBUFF_MASK); + s = (char *)log_buf+((log_start+i)&LOGBUFF_MASK); putc (*s); } return 0; diff --git a/common/cmd_mem.c b/common/cmd_mem.c index bafb1d6..0f4f9b7 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -179,7 +179,7 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } #endif puts (" "); - cp = linebuf; + cp = (u_char *)linebuf; for (i=0; i<linebytes; i++) { if ((*cp < 0x20) || (*cp > 0x7e)) putc ('.'); @@ -430,7 +430,7 @@ int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) puts ("Copy to Flash... "); - rc = flash_write ((uchar *)addr, dest, count*size); + rc = flash_write ((char *)addr, dest, count*size); if (rc != 0) { flash_perror (rc); return (1); diff --git a/common/cmd_mii.c b/common/cmd_mii.c index 3d260ab..48a4e77 100644 --- a/common/cmd_mii.c +++ b/common/cmd_mii.c @@ -41,19 +41,21 @@ uint last_data; uint last_reg; /* - * MII read/write + * MII device/info/read/write * * Syntax: - * mii read {addr} {reg} - * mii write {addr} {reg} {data} + * mii device {devname} + * mii info {addr} + * mii read {addr} {reg} + * mii write {addr} {reg} {data} */ - int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { char op; unsigned char addr, reg; unsigned short data; int rcode = 0; + char *devname; #if defined(CONFIG_8xx) || defined(CONFIG_MCF52x2) mii_init (); @@ -78,8 +80,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) data = simple_strtoul (argv[4], NULL, 16); } + /* use current device */ + devname = miiphy_get_current_dev(); + /* - * check info/read/write. + * check device/read/write/list. */ if (op == 'i') { unsigned char j, start, end; @@ -93,32 +98,41 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (argc >= 3) { start = addr; end = addr + 1; } else { - start = 0; end = 32; + start = 0; end = 31; } for (j = start; j < end; j++) { - if (miiphy_info (j, &oui, &model, &rev) == 0) { + if (miiphy_info (devname, j, &oui, &model, &rev) == 0) { printf ("PHY 0x%02X: " "OUI = 0x%04X, " "Model = 0x%02X, " "Rev = 0x%02X, " "%3dbaseT, %s\n", j, oui, model, rev, - miiphy_speed (j), - miiphy_duplex (j) == FULL ? "FDX" : "HDX"); + miiphy_speed (devname, j), + (miiphy_duplex (devname, j) == FULL) + ? "FDX" : "HDX"); + } else { + puts ("Error reading info from the PHY\n"); } } } else if (op == 'r') { - if (miiphy_read (addr, reg, &data) != 0) { + if (miiphy_read (devname, addr, reg, &data) != 0) { puts ("Error reading from the PHY\n"); rcode = 1; + } else { + printf ("%04X\n", data & 0x0000FFFF); } - printf ("%04X\n", data & 0x0000FFFF); } else if (op == 'w') { - if (miiphy_write (addr, reg, data) != 0) { + if (miiphy_write (devname, addr, reg, data) != 0) { puts ("Error writing to the PHY\n"); rcode = 1; } + } else if (op == 'd') { + if (argc == 2) + miiphy_listdev (); + else + miiphy_set_current_dev (argv[2]); } else { printf ("Usage:\n%s\n", cmdtp->usage); return 1; @@ -140,9 +154,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD( mii, 5, 1, do_mii, "mii - MII utility commands\n", - "info <addr> - display MII PHY info\n" - "mii read <addr> <reg> - read MII PHY <addr> register <reg>\n" - "mii write <addr> <reg> <data> - write MII PHY <addr> register <reg>\n" + "device - list available devices\n" + "mii device <devname> - set current device\n" + "mii info <addr> - display MII PHY info\n" + "mii read <addr> <reg> - read MII PHY <addr> register <reg>\n" + "mii write <addr> <reg> <data> - write MII PHY <addr> register <reg>\n" ); #else /* ! CONFIG_TERSE_MII ================================================= */ @@ -386,7 +402,7 @@ static int special_field( return 0; } -uint last_op; +char last_op[2]; uint last_data; uint last_addr_lo; uint last_addr_hi; @@ -412,11 +428,12 @@ static void extract_range( /* ---------------------------------------------------------------- */ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - char op; + char op[2]; unsigned char addrlo, addrhi, reglo, reghi; - unsigned char addr = 0, reg = 0; + unsigned char addr, reg; unsigned short data; int rcode = 0; + char *devname; #ifdef CONFIG_8xx mii_init (); @@ -426,7 +443,8 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) * We use the last specified parameters, unless new ones are * entered. */ - op = last_op; + op[0] = last_op[0]; + op[1] = last_op[1]; addrlo = last_addr_lo; addrhi = last_addr_hi; reglo = last_reg_lo; @@ -434,7 +452,12 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) data = last_data; if ((flag & CMD_FLAG_REPEAT) == 0) { - op = argv[1][0]; + op[0] = argv[1][0]; + if (strlen(argv[1]) > 1) + op[1] = argv[1][1]; + else + op[1] = '\0'; + if (argc >= 3) extract_range(argv[2], &addrlo, &addrhi); if (argc >= 4) @@ -443,10 +466,13 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) data = simple_strtoul (argv[4], NULL, 16); } + /* use current device */ + devname = miiphy_get_current_dev(); + /* * check info/read/write. */ - if (op == 'i') { + if (op[0] == 'i') { unsigned char j, start, end; unsigned int oui; unsigned char model; @@ -456,34 +482,36 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) * Look for any and all PHYs. Valid addresses are 0..31. */ if (argc >= 3) { - start = addr; end = addr + 1; + start = addrlo; end = addrhi; } else { - start = 0; end = 32; + start = 0; end = 31; } - for (j = start; j < end; j++) { - if (miiphy_info (j, &oui, &model, &rev) == 0) { + for (j = start; j <= end; j++) { + if (miiphy_info (devname, j, &oui, &model, &rev) == 0) { printf("PHY 0x%02X: " "OUI = 0x%04X, " "Model = 0x%02X, " "Rev = 0x%02X, " "%3dbaseT, %s\n", j, oui, model, rev, - miiphy_speed (j), - miiphy_duplex (j) == FULL ? "FDX" : "HDX"); + miiphy_speed (devname, j), + (miiphy_duplex (devname, j) == FULL) + ? "FDX" : "HDX"); + } else { + puts ("Error reading info from the PHY\n"); } } - } else if (op == 'r') { + } else if (op[0] == 'r') { for (addr = addrlo; addr <= addrhi; addr++) { for (reg = reglo; reg <= reghi; reg++) { data = 0xffff; - if (miiphy_read (addr, reg, &data) != 0) { + if (miiphy_read (devname, addr, reg, &data) != 0) { printf( "Error reading from the PHY addr=%02x reg=%02x\n", addr, reg); rcode = 1; - } - else { + } else { if ((addrlo != addrhi) || (reglo != reghi)) printf("addr=%02x reg=%02x data=", (uint)addr, (uint)reg); @@ -493,17 +521,17 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if ((addrlo != addrhi) && (reglo != reghi)) printf("\n"); } - } else if (op == 'w') { + } else if (op[0] == 'w') { for (addr = addrlo; addr <= addrhi; addr++) { for (reg = reglo; reg <= reghi; reg++) { - if (miiphy_write (addr, reg, data) != 0) { + if (miiphy_write (devname, addr, reg, data) != 0) { printf("Error writing to the PHY addr=%02x reg=%02x\n", addr, reg); rcode = 1; } } } - } else if (op == 'd') { + } else if (strncmp(op, "du", 2) == 0) { ushort regs[6]; int ok = 1; if ((reglo > 5) || (reghi > 5)) { @@ -513,8 +541,8 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 1; } for (addr = addrlo; addr <= addrhi; addr++) { - for (reg = 0; reg < 6; reg++) { - if (miiphy_read(addr, reg, ®s[reg]) != 0) { + for (reg = reglo; reg < reghi + 1; reg++) { + if (miiphy_read(devname, addr, reg, ®s[reg]) != 0) { ok = 0; printf( "Error reading from the PHY addr=%02x reg=%02x\n", @@ -526,6 +554,11 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) MII_dump_0_to_5(regs, reglo, reghi); printf("\n"); } + } else if (strncmp(op, "de", 2) == 0) { + if (argc == 2) + miiphy_listdev (); + else + miiphy_set_current_dev (argv[2]); } else { printf("Usage:\n%s\n", cmdtp->usage); return 1; @@ -534,7 +567,8 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* * Save the parameters for repeats. */ - last_op = op; + last_op[0] = op[0]; + last_op[1] = op[1]; last_addr_lo = addrlo; last_addr_hi = addrhi; last_reg_lo = reglo; @@ -549,10 +583,12 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD( mii, 5, 1, do_mii, "mii - MII utility commands\n", - "info <addr> - display MII PHY info\n" - "mii read <addr> <reg> - read MII PHY <addr> register <reg>\n" - "mii write <addr> <reg> <data> - write MII PHY <addr> register <reg>\n" - "mii dump <addr> <reg> - pretty-print <addr> <reg> (0-5 only)\n" + "device - list available devices\n" + "mii device <devname> - set current device\n" + "mii info <addr> - display MII PHY info\n" + "mii read <addr> <reg> - read MII PHY <addr> register <reg>\n" + "mii write <addr> <reg> <data> - write MII PHY <addr> register <reg>\n" + "mii dump <addr> <reg> - pretty-print <addr> <reg> (0-5 only)\n" "Addr and/or reg may be ranges, e.g. 2-7.\n" ); diff --git a/common/cmd_misc.c b/common/cmd_misc.c index 674eafc..67ee9e8 100644 --- a/common/cmd_misc.c +++ b/common/cmd_misc.c @@ -31,6 +31,7 @@ int do_sleep (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { + ulong start = get_timer(0); ulong delay; if (argc != 2) { @@ -38,20 +39,18 @@ int do_sleep (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - delay = simple_strtoul(argv[1], NULL, 10); + delay = simple_strtoul(argv[1], NULL, 10) * CFG_HZ; - while (delay) { - int i; - for (i=0; i<1000; ++i) { - if (ctrlc ()) { - return (-1); - } - udelay (1000); + while (get_timer(start) < delay) { + if (ctrlc ()) { + return (-1); } - --delay; + udelay (100); } + return 0; } + /* Implemented in $(CPU)/interrupts.c */ #if (CONFIG_COMMANDS & CFG_CMD_IRQ) int do_irqinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 0c05255..152873f 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -21,7 +21,7 @@ # define SHOW_BOOT_PROGRESS(arg) #endif -#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined CONFIG_NEW_NAND_CODE +#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CONFIG_NEW_NAND_CODE) #include <linux/mtd/nand.h> #include <linux/mtd/nand_ids.h> @@ -200,12 +200,12 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* read out-of-band data */ if (cmd & NANDRW_READ) { ret = nand_read_oob(nand_dev_desc + curr_device, - off, size, &total, + off, size, (size_t *)&total, (u_char*)addr); } else { ret = nand_write_oob(nand_dev_desc + curr_device, - off, size, &total, + off, size, (size_t *)&total, (u_char*)addr); } return ret; @@ -241,7 +241,7 @@ int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) curr_device, off, size); ret = nand_rw(nand_dev_desc + curr_device, cmd, off, size, - &total, (u_char*)addr); + (size_t *)&total, (u_char*)addr); printf (" %d bytes %s: %s\n", total, (cmd & NANDRW_READ) ? "read" : "written", @@ -401,7 +401,7 @@ U_BOOT_CMD( */ int check_block (struct nand_chip *nand, unsigned long pos) { - int retlen; + size_t retlen; uint8_t oob_data; uint16_t oob_data16[6]; int page0 = pos & (-nand->erasesize); @@ -423,9 +423,9 @@ int check_block (struct nand_chip *nand, unsigned long pos) return 1; } else { /* Note - bad block marker can be on first or second page */ - if (nand_read_oob(nand, page0 + badpos, 1, &retlen, &oob_data) + if (nand_read_oob(nand, page0 + badpos, 1, &retlen, (unsigned char *)&oob_data) || oob_data != 0xff - || nand_read_oob (nand, page1 + badpos, 1, &retlen, &oob_data) + || nand_read_oob (nand, page1 + badpos, 1, &retlen, (unsigned char *)&oob_data) || oob_data != 0xff) return 1; } @@ -501,11 +501,11 @@ int nand_rw (struct nand_chip* nand, int cmd, if (cmd & NANDRW_READ) { ret = nand_read_ecc(nand, start, min(len, eblk + erasesize - start), - &n, (u_char*)buf, eccbuf); + (size_t *)&n, (u_char*)buf, (u_char *)eccbuf); } else { ret = nand_write_ecc(nand, start, min(len, eblk + erasesize - start), - &n, (u_char*)buf, eccbuf); + (size_t *)&n, (u_char*)buf, (u_char *)eccbuf); } if (ret) @@ -1591,7 +1591,7 @@ int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean) l = NAND_JFFS2_OOB16_FSDALEN; } - ret = nand_write_oob(nand, ofs + p, l, &n, + ret = nand_write_oob(nand, ofs + p, l, (size_t *)&n, (u_char *)&clean_marker); /* quit here if write failed */ if (ret) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 578b0ca..1babffe 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -124,7 +124,7 @@ int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) for (nxt=j; env_get_char(nxt) != '\0'; ++nxt) ; - k = envmatch(name, j); + k = envmatch((uchar *)name, j); if (k < 0) { continue; } @@ -157,7 +157,7 @@ int _do_setenv (int flag, int argc, char *argv[]) int i, len, oldval; int console = -1; uchar *env, *nxt = NULL; - uchar *name; + char *name; bd_t *bd = gd->bd; uchar *env_data = env_get_addr(0); @@ -174,7 +174,7 @@ int _do_setenv (int flag, int argc, char *argv[]) for (env=env_data; *env; env=nxt+1) { for (nxt=env; *nxt; ++nxt) ; - if ((oldval = envmatch(name, env-env_data)) >= 0) + if ((oldval = envmatch((uchar *)name, env-env_data)) >= 0) break; } @@ -191,7 +191,7 @@ int _do_setenv (int flag, int argc, char *argv[]) if ( (strcmp (name, "serial#") == 0) || ((strcmp (name, "ethaddr") == 0) #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR) - && (strcmp (env_get_addr(oldval),MK_STR(CONFIG_ETHADDR)) != 0) + && (strcmp ((char *)env_get_addr(oldval),MK_STR(CONFIG_ETHADDR)) != 0) #endif /* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */ ) ) { printf ("Can't overwrite \"%s\"\n", name); @@ -483,7 +483,7 @@ int do_askenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) * or NULL if not found */ -char *getenv (uchar *name) +char *getenv (char *name) { int i, nxt; @@ -497,15 +497,15 @@ char *getenv (uchar *name) return (NULL); } } - if ((val=envmatch(name, i)) < 0) + if ((val=envmatch((uchar *)name, i)) < 0) continue; - return (env_get_addr(val)); + return ((char *)env_get_addr(val)); } return (NULL); } -int getenv_r (uchar *name, uchar *buf, unsigned len) +int getenv_r (char *name, char *buf, unsigned len) { int i, nxt; @@ -517,7 +517,7 @@ int getenv_r (uchar *name, uchar *buf, unsigned len) return (-1); } } - if ((val=envmatch(name, i)) < 0) + if ((val=envmatch((uchar *)name, i)) < 0) continue; /* found; copy out */ n = 0; diff --git a/common/cmd_pcmcia.c b/common/cmd_pcmcia.c index 31f2ba2..62446d4 100644 --- a/common/cmd_pcmcia.c +++ b/common/cmd_pcmcia.c @@ -2681,7 +2681,7 @@ static void print_fixed (volatile uchar *p) #define MAX_IDENT_FIELDS 4 static uchar *known_cards[] = { - "ARGOSY PnPIDE D5", + (uchar *)"ARGOSY PnPIDE D5", NULL }; @@ -2722,12 +2722,12 @@ static int identify (volatile uchar *p) else break; } - puts (id_str); + puts ((char *)id_str); putc ('\n'); for (card=known_cards; *card; ++card) { debug ("## Compare against \"%s\"\n", *card); - if (strcmp(*card, id_str) == 0) { /* found! */ + if (strcmp((char *)*card, (char *)id_str) == 0) { /* found! */ debug ("## CARD FOUND ##\n"); return (1); } diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index ec53790..e804861 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -247,8 +247,8 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("error reading partinfo\n"); return 1; } - if ((strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) && - (strncmp(info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) { + if ((strncmp((char *)(info.type), BOOT_PART_TYPE, sizeof(info.type)) != 0) && + (strncmp((char *)(info.type), BOOT_PART_COMP, sizeof(info.type)) != 0)) { printf ("\n** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info.type); @@ -277,7 +277,7 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; - if (crc32 (0, (char *)hdr, sizeof(image_header_t)) != checksum) { + if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { puts ("\n** Bad Header Checksum **\n"); return 1; } diff --git a/common/cmd_spi.c b/common/cmd_spi.c index 7b6faf7..a6fdf7f 100644 --- a/common/cmd_spi.c +++ b/common/cmd_spi.c @@ -119,7 +119,7 @@ int do_spi (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("Error with the SPI transaction.\n"); rcode = 1; } else { - cp = din; + cp = (char *)din; for(j = 0; j < ((bitlen + 7) / 8); j++) { printf("%02X", *cp++); } diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 0738f55..fdfd042 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -362,15 +362,15 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (get_partition_info (stor_dev, part, &info)) { /* try to boot raw .... */ - strncpy(&info.type[0], BOOT_PART_TYPE, sizeof(BOOT_PART_TYPE)); - strncpy(&info.name[0], "Raw", 4); + strncpy((char *)&info.type[0], BOOT_PART_TYPE, sizeof(BOOT_PART_TYPE)); + strncpy((char *)&info.name[0], "Raw", 4); info.start=0; info.blksz=0x200; info.size=2880; printf("error reading partinfo...try to boot raw\n"); } - if ((strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) && - (strncmp(info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) { + if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) && + (strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) { printf ("\n** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info.type); @@ -398,7 +398,7 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; - if (crc32 (0, (char *)hdr, sizeof(image_header_t)) != checksum) { + if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { puts ("\n** Bad Header Checksum **\n"); return 1; } diff --git a/common/env_common.c b/common/env_common.c index 9be4cc1..3201135 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -283,7 +283,7 @@ int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf) for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) ; - lval = env_get_addr(i); + lval = (char *)env_get_addr(i); rval = strchr(lval, '='); if (rval != NULL) { vallen = rval - lval; diff --git a/common/env_dataflash.c b/common/env_dataflash.c index 8bfbbc9..8834da0 100644 --- a/common/env_dataflash.c +++ b/common/env_dataflash.c @@ -24,7 +24,6 @@ #include <command.h> #include <environment.h> #include <linux/stddef.h> -#include <malloc.h> #include <dataflash.h> env_t *env_ptr = NULL; diff --git a/common/env_eeprom.c b/common/env_eeprom.c index 300af6f..50c623e 100644 --- a/common/env_eeprom.c +++ b/common/env_eeprom.c @@ -31,7 +31,6 @@ #include <command.h> #include <environment.h> #include <linux/stddef.h> -#include <malloc.h> env_t *env_ptr = NULL; diff --git a/common/env_flash.c b/common/env_flash.c index d6257d0..a2ea9c4 100644 --- a/common/env_flash.c +++ b/common/env_flash.c @@ -202,7 +202,7 @@ int saveenv(void) debug (" %08lX ... %08lX ...", (ulong)&(flash_addr_new->data), sizeof(env_ptr->data)+(ulong)&(flash_addr_new->data)); - if ((rc = flash_write(env_ptr->data, + if ((rc = flash_write((char *)env_ptr->data, (ulong)&(flash_addr_new->data), sizeof(env_ptr->data))) || (rc = flash_write((char *)&(env_ptr->crc), @@ -291,7 +291,7 @@ int saveenv(void) ulong flash_offset; uchar env_buffer[CFG_ENV_SECT_SIZE]; #else - uchar *env_buffer = (char *)env_ptr; + uchar *env_buffer = (uchar *)env_ptr; #endif /* CFG_ENV_SECT_SIZE */ int rcode = 0; @@ -337,7 +337,7 @@ int saveenv(void) return 1; puts ("Writing to Flash... "); - rc = flash_write(env_buffer, flash_sect_addr, len); + rc = flash_write((char *)env_buffer, flash_sect_addr, len); if (rc != 0) { flash_perror (rc); rcode = 1; diff --git a/common/env_nand.c b/common/env_nand.c index 516aed7..60aba1e 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -36,7 +36,6 @@ #include <command.h> #include <environment.h> #include <linux/stddef.h> -#include <malloc.h> #include <linux/mtd/nand.h> #if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_NAND)) == (CFG_CMD_ENV|CFG_CMD_NAND)) diff --git a/common/env_nowhere.c b/common/env_nowhere.c index b274c03..ee4237c 100644 --- a/common/env_nowhere.c +++ b/common/env_nowhere.c @@ -31,7 +31,6 @@ #include <command.h> #include <environment.h> #include <linux/stddef.h> -#include <malloc.h> env_t *env_ptr = NULL; diff --git a/common/env_nvram.c b/common/env_nvram.c index 2c831d1..a406e42 100644 --- a/common/env_nvram.c +++ b/common/env_nvram.c @@ -47,7 +47,6 @@ #include <command.h> #include <environment.h> #include <linux/stddef.h> -#include <malloc.h> #ifdef CFG_NVRAM_ACCESS_ROUTINE extern void *nvram_read(void *dest, const long src, size_t count); diff --git a/common/flash.c b/common/flash.c index b308413..a64bc98 100644 --- a/common/flash.c +++ b/common/flash.c @@ -28,7 +28,7 @@ #if !defined(CFG_NO_FLASH) -extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ +extern flash_info_t flash_info[]; /* info for FLASH chips */ /*----------------------------------------------------------------------- * Functions @@ -135,7 +135,7 @@ addr2info (ulong addr) * (only some targets require alignment) */ int -flash_write (uchar *src, ulong addr, ulong cnt) +flash_write (char *src, ulong addr, ulong cnt) { #ifdef CONFIG_SPD823TS return (ERR_TIMOUT); /* any other error codes are possible as well */ @@ -174,7 +174,7 @@ flash_write (uchar *src, ulong addr, ulong cnt) len = info->start[0] + info->size - addr; if (len > cnt) len = cnt; - if ((i = write_buff(info, src, addr, len)) != 0) { + if ((i = write_buff(info, (uchar *)src, addr, len)) != 0) { return (i); } cnt -= len; diff --git a/common/fpga.c b/common/fpga.c index c41c6f8..02d3e42 100644 --- a/common/fpga.c +++ b/common/fpga.c @@ -53,8 +53,8 @@ static int next_desc = FPGA_INVALID_DEVICE; static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES]; /* Local static functions */ -static const fpga_desc * const fpga_get_desc( int devnum ); -static const fpga_desc * const fpga_validate( int devnum, void *buf, +static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum ); +static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf, size_t bsize, char *fn ); static int fpga_dev_info( int devnum ); @@ -82,7 +82,7 @@ static void fpga_no_sup( char *fn, char *msg ) /* fpga_get_desc * map a device number to a descriptor */ -static const fpga_desc * const fpga_get_desc( int devnum ) +static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum ) { fpga_desc *desc = (fpga_desc * )NULL; @@ -99,10 +99,10 @@ static const fpga_desc * const fpga_get_desc( int devnum ) /* fpga_validate * generic parameter checking code */ -static const fpga_desc * const fpga_validate( int devnum, void *buf, +static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf, size_t bsize, char *fn ) { - const fpga_desc * const desc = fpga_get_desc( devnum ); + fpga_desc * desc = fpga_get_desc( devnum ); if ( !desc ) { printf( "%s: Invalid device number %d\n", fn, devnum ); @@ -147,7 +147,7 @@ static int fpga_dev_info( int devnum ) printf( "Altera Device\nDescriptor @ 0x%p\n", desc ); ret_val = altera_info( desc->devdesc ); #else - fpga_no_sup( __FUNCTION__, "Altera devices" ); + fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); #endif break; default: @@ -185,7 +185,7 @@ int fpga_reloc( fpga_type devtype, void *desc, ulong reloc_off ) #if CONFIG_FPGA & CFG_FPGA_ALTERA ret_val = altera_reloc( desc, reloc_off ); #else - fpga_no_sup( __FUNCTION__, "Altera devices" ); + fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); #endif break; default: @@ -216,7 +216,7 @@ void fpga_init( ulong reloc_off ) /* fpga_count * Basic interface function to get the current number of devices available. */ -const int fpga_count( void ) +int fpga_count( void ) { return next_desc; } @@ -263,7 +263,7 @@ int fpga_add( fpga_type devtype, void *desc ) int fpga_load( int devnum, void *buf, size_t bsize ) { int ret_val = FPGA_FAIL; /* assume failure */ - const fpga_desc * const desc = fpga_validate( devnum, buf, bsize, __FUNCTION__ ); + fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ ); if ( desc ) { switch ( desc->devtype ) { @@ -278,7 +278,7 @@ int fpga_load( int devnum, void *buf, size_t bsize ) #if CONFIG_FPGA & CFG_FPGA_ALTERA ret_val = altera_load( desc->devdesc, buf, bsize ); #else - fpga_no_sup( __FUNCTION__, "Altera devices" ); + fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); #endif break; default: @@ -296,7 +296,7 @@ int fpga_load( int devnum, void *buf, size_t bsize ) int fpga_dump( int devnum, void *buf, size_t bsize ) { int ret_val = FPGA_FAIL; /* assume failure */ - const fpga_desc * const desc = fpga_validate( devnum, buf, bsize, __FUNCTION__ ); + fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ ); if ( desc ) { switch ( desc->devtype ) { @@ -311,7 +311,7 @@ int fpga_dump( int devnum, void *buf, size_t bsize ) #if CONFIG_FPGA & CFG_FPGA_ALTERA ret_val = altera_dump( desc->devdesc, buf, bsize ); #else - fpga_no_sup( __FUNCTION__, "Altera devices" ); + fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); #endif break; default: diff --git a/common/ft_build.c b/common/ft_build.c new file mode 100644 index 0000000..65a274f --- /dev/null +++ b/common/ft_build.c @@ -0,0 +1,695 @@ +/* + * OF flat tree builder + */ + +#include <common.h> +#include <malloc.h> +#include <environment.h> + +#ifdef CONFIG_OF_FLAT_TREE + +#include <asm/errno.h> +#include <stddef.h> + +#include <ft_build.h> + +/* align addr on a size boundary - adjust address up if needed -- Cort */ +#define _ALIGN(addr,size) (((addr)+(size)-1)&(~((size)-1))) + +static void ft_put_word(struct ft_cxt *cxt, u32 v) +{ + if (cxt->overflow) /* do nothing */ + return; + + /* check for overflow */ + if (cxt->p + 4 > cxt->pstr) { + cxt->overflow = 1; + return; + } + + *(u32 *) cxt->p = cpu_to_be32(v); + cxt->p += 4; +} + +static inline void ft_put_bin(struct ft_cxt *cxt, const void *data, int sz) +{ + u8 *p; + + if (cxt->overflow) /* do nothing */ + return; + + /* next pointer pos */ + p = (u8 *) _ALIGN((unsigned long)cxt->p + sz, 4); + + /* check for overflow */ + if (p > cxt->pstr) { + cxt->overflow = 1; + return; + } + + memcpy(cxt->p, data, sz); + if ((sz & 3) != 0) + memset(cxt->p + sz, 0, 4 - (sz & 3)); + cxt->p = p; +} + +void ft_begin_node(struct ft_cxt *cxt, const char *name) +{ + ft_put_word(cxt, OF_DT_BEGIN_NODE); + ft_put_bin(cxt, name, strlen(name) + 1); +} + +void ft_end_node(struct ft_cxt *cxt) +{ + ft_put_word(cxt, OF_DT_END_NODE); +} + +void ft_nop(struct ft_cxt *cxt) +{ + ft_put_word(cxt, OF_DT_NOP); +} + +static int lookup_string(struct ft_cxt *cxt, const char *name) +{ + u8 *p; + + p = cxt->pstr; + while (p < cxt->pstr_begin) { + if (strcmp(p, name) == 0) + return p - cxt->p_begin; + p += strlen(p) + 1; + } + + return -1; +} + +void ft_prop(struct ft_cxt *cxt, const char *name, const void *data, int sz) +{ + int len, off; + + if (cxt->overflow) + return; + + len = strlen(name) + 1; + + off = lookup_string(cxt, name); + if (off == -1) { + /* check if we have space */ + if (cxt->p + 12 + sz + len > cxt->pstr) { + cxt->overflow = 1; + return; + } + + cxt->pstr -= len; + memcpy(cxt->pstr, name, len); + off = cxt->pstr - cxt->p_begin; + } + + /* now put offset from beginning of *STRUCTURE* */ + /* will be fixed up at the end */ + ft_put_word(cxt, OF_DT_PROP); + ft_put_word(cxt, sz); + ft_put_word(cxt, off); + ft_put_bin(cxt, data, sz); +} + +void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str) +{ + ft_prop(cxt, name, str, strlen(str) + 1); +} + +void ft_prop_int(struct ft_cxt *cxt, const char *name, int val) +{ + u32 v = cpu_to_be32((u32) val); + + ft_prop(cxt, name, &v, 4); +} + +/* start construction of the flat OF tree */ +void ft_begin(struct ft_cxt *cxt, void *blob, int max_size) +{ + struct boot_param_header *bph = blob; + u32 off; + + /* clear the cxt */ + memset(cxt, 0, sizeof(*cxt)); + + cxt->bph = bph; + cxt->max_size = max_size; + + /* zero everything in the header area */ + memset(bph, 0, sizeof(*bph)); + + bph->magic = cpu_to_be32(OF_DT_HEADER); + bph->version = cpu_to_be32(0x10); + bph->last_comp_version = cpu_to_be32(0x10); + + /* start pointers */ + cxt->pres_begin = (u8 *) _ALIGN((unsigned long)(bph + 1), 8); + cxt->pres = cxt->pres_begin; + + off = (unsigned long)cxt->pres_begin - (unsigned long)bph; + bph->off_mem_rsvmap = cpu_to_be32(off); + + ((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */ + ((u64 *) cxt->pres)[1] = 0; + + cxt->p_anchor = cxt->pres + 16; /* over the terminator */ +} + +/* add a reserver physical area to the rsvmap */ +void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size) +{ + ((u64 *) cxt->pres)[0] = cpu_to_be64(physaddr); /* phys = 0, size = 0, terminate */ + ((u64 *) cxt->pres)[1] = cpu_to_be64(size); + + cxt->pres += 18; /* advance */ + + ((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */ + ((u64 *) cxt->pres)[1] = 0; + + /* keep track of size */ + cxt->res_size = cxt->pres + 16 - cxt->pres_begin; + + cxt->p_anchor = cxt->pres + 16; /* over the terminator */ +} + +void ft_begin_tree(struct ft_cxt *cxt) +{ + cxt->p_begin = cxt->p_anchor; + cxt->pstr_begin = (char *)cxt->bph + cxt->max_size; /* point at the end */ + + cxt->p = cxt->p_begin; + cxt->pstr = cxt->pstr_begin; +} + +int ft_end_tree(struct ft_cxt *cxt) +{ + struct boot_param_header *bph = cxt->bph; + int off, sz, sz1; + u32 tag, v; + u8 *p; + + ft_put_word(cxt, OF_DT_END); + + if (cxt->overflow) + return -ENOMEM; + + /* size of the areas */ + cxt->struct_size = cxt->p - cxt->p_begin; + cxt->strings_size = cxt->pstr_begin - cxt->pstr; + + /* the offset we must move */ + off = (cxt->pstr_begin - cxt->p_begin) - cxt->strings_size; + + /* the new strings start */ + cxt->pstr_begin = cxt->p_begin + cxt->struct_size; + + /* move the whole string area */ + memmove(cxt->pstr_begin, cxt->pstr, cxt->strings_size); + + /* now perform the fixup of the strings */ + p = cxt->p_begin; + while ((tag = be32_to_cpu(*(u32 *) p)) != OF_DT_END) { + p += 4; + + if (tag == OF_DT_BEGIN_NODE) { + p = (u8 *) _ALIGN((unsigned long)p + strlen(p) + 1, 4); + continue; + } + + if (tag == OF_DT_END_NODE || tag == OF_DT_NOP) + continue; + + if (tag != OF_DT_PROP) + return -EINVAL; + + sz = be32_to_cpu(*(u32 *) p); + p += 4; + + v = be32_to_cpu(*(u32 *) p); + v -= off; + *(u32 *) p = cpu_to_be32(v); /* move down */ + p += 4; + + p = (u8 *) _ALIGN((unsigned long)p + sz, 4); + } + + /* fix sizes */ + p = (char *)cxt->bph; + sz = (cxt->pstr_begin + cxt->strings_size) - p; + sz1 = _ALIGN(sz, 16); /* align at 16 bytes */ + if (sz != sz1) + memset(p + sz, 0, sz1 - sz); + bph->totalsize = cpu_to_be32(sz1); + bph->off_dt_struct = cpu_to_be32(cxt->p_begin - p); + bph->off_dt_strings = cpu_to_be32(cxt->pstr_begin - p); + + /* the new strings start */ + cxt->pstr_begin = cxt->p_begin + cxt->struct_size; + cxt->pstr = cxt->pstr_begin + cxt->strings_size; + + return 0; +} + +/**********************************************************************/ + +static inline int isprint(int c) +{ + return c >= 0x20 && c <= 0x7e; +} + +static int is_printable_string(const void *data, int len) +{ + const char *s = data; + const char *ss; + + /* zero length is not */ + if (len == 0) + return 0; + + /* must terminate with zero */ + if (s[len - 1] != '\0') + return 0; + + ss = s; + while (*s && isprint(*s)) + s++; + + /* not zero, or not done yet */ + if (*s != '\0' || (s + 1 - ss) < len) + return 0; + + return 1; +} + +static void print_data(const void *data, int len) +{ + int i; + const u8 *s; + + /* no data, don't print */ + if (len == 0) + return; + + if (is_printable_string(data, len)) { + printf(" = \"%s\"", (char *)data); + return; + } + + switch (len) { + case 1: /* byte */ + printf(" = <0x%02x>", (*(u8 *) data) & 0xff); + break; + case 2: /* half-word */ + printf(" = <0x%04x>", be16_to_cpu(*(u16 *) data) & 0xffff); + break; + case 4: /* word */ + printf(" = <0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU); + break; + case 8: /* double-word */ + printf(" = <0x%16llx>", be64_to_cpu(*(uint64_t *) data)); + break; + default: /* anything else... hexdump */ + printf(" = ["); + for (i = 0, s = data; i < len; i++) + printf("%02x%s", s[i], i < len - 1 ? " " : ""); + printf("]"); + + break; + } +} + +void ft_dump_blob(const void *bphp) +{ + const struct boot_param_header *bph = bphp; + const uint64_t *p_rsvmap = (const uint64_t *) + ((const char *)bph + be32_to_cpu(bph->off_mem_rsvmap)); + const u32 *p_struct = (const u32 *) + ((const char *)bph + be32_to_cpu(bph->off_dt_struct)); + const u32 *p_strings = (const u32 *) + ((const char *)bph + be32_to_cpu(bph->off_dt_strings)); + u32 tag; + const u32 *p; + const char *s, *t; + int depth, sz, shift; + int i; + uint64_t addr, size; + + if (be32_to_cpu(bph->magic) != OF_DT_HEADER) { + /* not valid tree */ + return; + } + + depth = 0; + shift = 4; + + for (i = 0;; i++) { + addr = be64_to_cpu(p_rsvmap[i * 2]); + size = be64_to_cpu(p_rsvmap[i * 2 + 1]); + if (addr == 0 && size == 0) + break; + + printf("/memreserve/ 0x%llx 0x%llx;\n", addr, size); + } + + p = p_struct; + while ((tag = be32_to_cpu(*p++)) != OF_DT_END) { + + /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */ + + if (tag == OF_DT_BEGIN_NODE) { + s = (const char *)p; + p = (u32 *) _ALIGN((unsigned long)p + strlen(s) + 1, 4); + + printf("%*s%s {\n", depth * shift, "", s); + + depth++; + continue; + } + + if (tag == OF_DT_END_NODE) { + depth--; + + printf("%*s};\n", depth * shift, ""); + continue; + } + + if (tag == OF_DT_NOP) { + printf("%*s[NOP]\n", depth * shift, ""); + continue; + } + + if (tag != OF_DT_PROP) { + fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", + depth * shift, "", tag); + break; + } + sz = be32_to_cpu(*p++); + s = (const char *)p_strings + be32_to_cpu(*p++); + t = (const char *)p; + p = (const u32 *)_ALIGN((unsigned long)p + sz, 4); + printf("%*s%s", depth * shift, "", s); + print_data(t, sz); + printf(";\n"); + } +} + +void ft_backtrack_node(struct ft_cxt *cxt) +{ + if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE) + return; /* XXX only for node */ + + cxt->p -= 4; +} + +/* note that the root node of the blob is "peeled" off */ +void ft_merge_blob(struct ft_cxt *cxt, void *blob) +{ + struct boot_param_header *bph = (struct boot_param_header *)blob; + u32 *p_struct = (u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_struct)); + u32 *p_strings = + (u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_strings)); + u32 tag, *p; + char *s, *t; + int depth, sz; + + if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE) + return; /* XXX only for node */ + + cxt->p -= 4; + + depth = 0; + p = p_struct; + while ((tag = be32_to_cpu(*p++)) != OF_DT_END) { + + /* printf("tag: 0x%08x (%d) - %d\n", tag, p - p_struct, depth); */ + + if (tag == OF_DT_BEGIN_NODE) { + s = (char *)p; + p = (u32 *) _ALIGN((unsigned long)p + strlen(s) + 1, 4); + + if (depth++ > 0) + ft_begin_node(cxt, s); + + continue; + } + + if (tag == OF_DT_END_NODE) { + ft_end_node(cxt); + if (--depth == 0) + break; + continue; + } + + if (tag == OF_DT_NOP) + continue; + + if (tag != OF_DT_PROP) + break; + + sz = be32_to_cpu(*p++); + s = (char *)p_strings + be32_to_cpu(*p++); + t = (char *)p; + p = (u32 *) _ALIGN((unsigned long)p + sz, 4); + + ft_prop(cxt, s, t, sz); + } +} + +void *ft_get_prop(void *bphp, const char *propname, int *szp) +{ + struct boot_param_header *bph = bphp; + uint32_t *p_struct = + (uint32_t *) ((char *)bph + be32_to_cpu(bph->off_dt_struct)); + uint32_t *p_strings = + (uint32_t *) ((char *)bph + be32_to_cpu(bph->off_dt_strings)); + uint32_t version = be32_to_cpu(bph->version); + uint32_t tag; + uint32_t *p; + char *s, *t; + char *ss; + int sz; + static char path[256], prop[256]; + + path[0] = '\0'; + + p = p_struct; + while ((tag = be32_to_cpu(*p++)) != OF_DT_END) { + + if (tag == OF_DT_BEGIN_NODE) { + s = (char *)p; + p = (uint32_t *) _ALIGN((unsigned long)p + strlen(s) + + 1, 4); + strcat(path, s); + strcat(path, "/"); + continue; + } + + if (tag == OF_DT_END_NODE) { + path[strlen(path) - 1] = '\0'; + ss = strrchr(path, '/'); + if (ss != NULL) + ss[1] = '\0'; + continue; + } + + if (tag == OF_DT_NOP) + continue; + + if (tag != OF_DT_PROP) + break; + + sz = be32_to_cpu(*p++); + s = (char *)p_strings + be32_to_cpu(*p++); + if (version < 0x10 && sz >= 8) + p = (uint32_t *) _ALIGN((unsigned long)p, 8); + t = (char *)p; + p = (uint32_t *) _ALIGN((unsigned long)p + sz, 4); + + strcpy(prop, path); + strcat(prop, s); + + if (strcmp(prop, propname) == 0) { + *szp = sz; + return t; + } + } + + return NULL; +} + +/********************************************************************/ + +extern unsigned char oftree_dtb[]; +extern unsigned int oftree_dtb_len; + +/* Function that returns a character from the environment */ +extern uchar(*env_get_char) (int); + +#define BDM(x) { .name = #x, .offset = offsetof(bd_t, bi_ ##x ) } + +static const struct { + const char *name; + int offset; +} bd_map[] = { + BDM(memstart), + BDM(memsize), + BDM(flashstart), + BDM(flashsize), + BDM(flashoffset), + BDM(sramstart), + BDM(sramsize), +#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ + || defined(CONFIG_E500) + BDM(immr_base), +#endif +#if defined(CONFIG_MPC5xxx) + BDM(mbar_base), +#endif +#if defined(CONFIG_MPC83XX) + BDM(immrbar), +#endif +#if defined(CONFIG_MPC8220) + BDM(mbar_base), + BDM(inpfreq), + BDM(pcifreq), + BDM(pevfreq), + BDM(flbfreq), + BDM(vcofreq), +#endif + BDM(bootflags), + BDM(ip_addr), + BDM(intfreq), + BDM(busfreq), +#ifdef CONFIG_CPM2 + BDM(cpmfreq), + BDM(brgfreq), + BDM(sccfreq), + BDM(vco), +#endif +#if defined(CONFIG_MPC5xxx) + BDM(ipbfreq), + BDM(pcifreq), +#endif + BDM(baudrate), +}; + +void ft_setup(void *blob, int size, bd_t * bd) +{ + DECLARE_GLOBAL_DATA_PTR; + u8 *end; + u32 *p; + int len; + struct ft_cxt cxt; + int i, k, nxt; + static char tmpenv[256]; + char *s, *lval, *rval; + ulong clock; + uint32_t v; + + /* disable OF tree; booting old kernel */ + if (getenv("disable_of") != NULL) { + memcpy(blob, bd, sizeof(*bd)); + return; + } + + ft_begin(&cxt, blob, size); + + /* fs_add_rsvmap not used */ + + ft_begin_tree(&cxt); + + ft_begin_node(&cxt, ""); + + ft_end_node(&cxt); + + /* copy RO tree */ + ft_merge_blob(&cxt, oftree_dtb); + + /* back into root */ + ft_backtrack_node(&cxt); + + ft_begin_node(&cxt, "u-boot-env"); + + for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { + for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) ; + s = tmpenv; + for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k) + *s++ = env_get_char(k); + *s++ = '\0'; + lval = tmpenv; + s = strchr(tmpenv, '='); + if (s != NULL) { + *s++ = '\0'; + rval = s; + } else + continue; + ft_prop_str(&cxt, lval, rval); + } + + ft_end_node(&cxt); + + ft_begin_node(&cxt, "chosen"); + + ft_prop_str(&cxt, "name", "chosen"); + ft_prop_str(&cxt, "bootargs", getenv("bootargs")); + ft_prop_int(&cxt, "linux,platform", 0x600); /* what is this? */ + + ft_end_node(&cxt); + + ft_end_node(&cxt); /* end root */ + + ft_end_tree(&cxt); + + /* + printf("merged OF-tree\n"); + ft_dump_blob(blob); + */ + + /* paste the bd_t at the end of the flat tree */ + end = (char *)blob + + be32_to_cpu(((struct boot_param_header *)blob)->totalsize); + memcpy(end, bd, sizeof(*bd)); + +#ifdef CONFIG_PPC + + for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) { + sprintf(tmpenv, "/bd_t/%s", bd_map[i].name); + v = *(uint32_t *)((char *)bd + bd_map[i].offset); + + p = ft_get_prop(blob, tmpenv, &len); + if (p != NULL) + *p = cpu_to_be32(v); + } + + p = ft_get_prop(blob, "/bd_t/enetaddr", &len); + if (p != NULL) + memcpy(p, bd->bi_enetaddr, 6); + + p = ft_get_prop(blob, "/bd_t/ethspeed", &len); + if (p != NULL) + *p = cpu_to_be32((uint32_t) bd->bi_ethspeed); + + clock = bd->bi_intfreq; + p = ft_get_prop(blob, "/cpus/" OF_CPU "/clock-frequency", &len); + if (p != NULL) + *p = cpu_to_be32(clock); + +#ifdef OF_TBCLK + clock = OF_TBCLK; + p = ft_get_prop(blob, "/cpus/" OF_CPU "/timebase-frequency", &len); + if (p != NULL) + *p = cpu_to_be32(OF_TBCLK); +#endif + +#endif /* __powerpc__ */ + + /* + printf("final OF-tree\n"); + ft_dump_blob(blob); + */ + +} + +#endif diff --git a/common/hush.c b/common/hush.c index eb7f7f1..bb5041a 100644 --- a/common/hush.c +++ b/common/hush.c @@ -296,7 +296,7 @@ extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */ #endif /* "globals" within this file */ -static char *ifs; +static uchar *ifs; static char map[256]; #ifndef __U_BOOT__ static int fake_mode; @@ -2389,6 +2389,7 @@ struct pipe *new_pipe(void) { pi->progs = NULL; pi->next = NULL; pi->followup = 0; /* invalid */ + pi->r_mode = RES_NONE; return pi; } @@ -3133,8 +3134,8 @@ void mapset(const unsigned char *set, int code) void update_ifs_map(void) { /* char *ifs and char map[256] are both globals. */ - ifs = getenv("IFS"); - if (ifs == NULL) ifs=" \t\n"; + ifs = (uchar *)getenv("IFS"); + if (ifs == NULL) ifs=(uchar *)" \t\n"; /* Precompute a list of 'flow through' behavior so it can be treated * quickly up front. Computation is necessary because of IFS. * Special case handling of IFS == " \t\n" is not implemented. @@ -3143,11 +3144,11 @@ void update_ifs_map(void) */ memset(map,0,sizeof(map)); /* most characters flow through always */ #ifndef __U_BOOT__ - mapset("\\$'\"`", 3); /* never flow through */ - mapset("<>;&|(){}#", 1); /* flow through if quoted */ + mapset((uchar *)"\\$'\"`", 3); /* never flow through */ + mapset((uchar *)"<>;&|(){}#", 1); /* flow through if quoted */ #else - mapset("\\$'\"", 3); /* never flow through */ - mapset(";&|#", 1); /* flow through if quoted */ + mapset((uchar *)"\\$'\"", 3); /* never flow through */ + mapset((uchar *)";&|#", 1); /* flow through if quoted */ #endif mapset(ifs, 2); /* also flow through if quoted */ } @@ -3167,7 +3168,7 @@ int parse_stream_outer(struct in_str *inp, int flag) ctx.type = flag; initialize_context(&ctx); update_ifs_map(); - if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset(";$&|", 0); + if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset((uchar *)";$&|", 0); inp->promptmode=1; rcode = parse_stream(&temp, &ctx, inp, '\n'); #ifdef __U_BOOT__ diff --git a/common/kgdb.c b/common/kgdb.c index 06adb3e..6de6ec9 100644 --- a/common/kgdb.c +++ b/common/kgdb.c @@ -144,7 +144,7 @@ mem2hex(char *mem, char *buf, int count) } *buf = 0; longjmp_on_fault = 0; - return buf; + return (unsigned char *)buf; } /* convert the hex array pointed to by buf into binary to be placed in mem @@ -353,7 +353,7 @@ handle_exception (struct pt_regs *regs) *ptr++ = hexchars[rp->num >> 4]; *ptr++ = hexchars[rp->num & 0xf]; *ptr++ = ':'; - ptr = mem2hex((char *)&rp->val, ptr, 4); + ptr = (char *)mem2hex((char *)&rp->val, ptr, 4); *ptr++ = ';'; } @@ -364,7 +364,7 @@ handle_exception (struct pt_regs *regs) printf("kgdb: remcomOutBuffer: %s\n", remcomOutBuffer); #endif - putpacket(remcomOutBuffer); + putpacket((unsigned char *)&remcomOutBuffer); while (1) { volatile int errnum; @@ -508,7 +508,7 @@ handle_exception (struct pt_regs *regs) #endif /* reply to the request */ - putpacket(remcomOutBuffer); + putpacket((unsigned char *)&remcomOutBuffer); } /* while(1) */ } @@ -548,7 +548,7 @@ kgdb_output_string (const char* s, unsigned int count) buffer[0] = 'O'; mem2hex ((char *)s, &buffer[1], count); - putpacket(buffer); + putpacket((unsigned char *)&buffer); return 1; } diff --git a/common/lcd.c b/common/lcd.c index a85599d..e64972f 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -279,9 +279,9 @@ static void lcd_drawchars (ushort x, ushort y, uchar *str, int count) static inline void lcd_puts_xy (ushort x, ushort y, uchar *s) { #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) - lcd_drawchars (x, y+BMP_LOGO_HEIGHT, s, strlen (s)); + lcd_drawchars (x, y+BMP_LOGO_HEIGHT, s, strlen ((char *)s)); #else - lcd_drawchars (x, y, s, strlen (s)); + lcd_drawchars (x, y, s, strlen ((char *)s)); #endif } @@ -526,7 +526,7 @@ void bitmap_plot (int x, int y) sizeof(bmp_logo_palette)/(sizeof(ushort))); bmap = &bmp_logo_bitmap[0]; - fb = (char *)(lcd_base + y * lcd_line_length + x); + fb = (uchar *)(lcd_base + y * lcd_line_length + x); if (NBITS(panel_info.vl_bpix) < 12) { /* Leave room for default color map */ @@ -638,9 +638,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) bmp_color_table_entry_t cte = bmp->color_table[i]; ushort colreg = ( ((cte.red) << 8) & 0xf800) | - ( ((cte.green) << 4) & 0x07e0) | - ( (cte.blue) & 0x001f) ; - + ( ((cte.green) << 3) & 0x07e0) | + ( ((cte.blue) >> 3) & 0x001f) ; #ifdef CFG_INVERT_COLORS *cmap = 0xffff - colreg; #else @@ -711,15 +710,15 @@ static void *lcd_logo (void) #ifdef CONFIG_MPC823 # ifdef CONFIG_LCD_INFO sprintf (info, "%s (%s - %s) ", U_BOOT_VERSION, __DATE__, __TIME__); - lcd_drawchars (LCD_INFO_X, LCD_INFO_Y, info, strlen(info)); + lcd_drawchars (LCD_INFO_X, LCD_INFO_Y, (uchar *)info, strlen(info)); sprintf (info, "(C) 2004 DENX Software Engineering"); lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT, - info, strlen(info)); + (uchar *)info, strlen(info)); sprintf (info, " Wolfgang DENK, wd@denx.de"); lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 2, - info, strlen(info)); + (uchar *)info, strlen(info)); # ifdef CONFIG_LCD_INFO_BELOW_LOGO sprintf (info, "MPC823 CPU at %s MHz", strmhz(temp, gd->cpu_clk)); @@ -738,7 +737,7 @@ static void *lcd_logo (void) gd->ram_size >> 20, gd->bd->bi_flashsize >> 20 ); lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 4, - info, strlen(info)); + (uchar *)info, strlen(info)); # endif /* CONFIG_LCD_INFO_BELOW_LOGO */ # endif /* CONFIG_LCD_INFO */ diff --git a/common/main.c b/common/main.c index 9f649db..f042f3a 100644 --- a/common/main.c +++ b/common/main.c @@ -26,7 +26,9 @@ #include <common.h> #include <watchdog.h> #include <command.h> -#include <malloc.h> +#ifdef CONFIG_MODEM_SUPPORT +#include <malloc.h> /* for free() prototype */ +#endif #ifdef CFG_HUSH_PARSER #include <hush.h> @@ -345,7 +347,7 @@ void main_loop (void) #ifdef CONFIG_MODEM_SUPPORT debug ("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init); if (do_mdm_init) { - uchar *str = strdup(getenv("mdm_cmd")); + char *str = strdup(getenv("mdm_cmd")); setenv ("preboot", str); /* set or delete definition */ if (str != NULL) free (str); diff --git a/common/miiphybb.c b/common/miiphybb.c index b6af88f..adb697c 100644 --- a/common/miiphybb.c +++ b/common/miiphybb.c @@ -121,7 +121,8 @@ static void miiphy_pre (char read, unsigned char addr, unsigned char reg) * Returns: * 0 on success */ -int miiphy_read (unsigned char addr, unsigned char reg, unsigned short *value) +int bb_miiphy_read (char *devname, unsigned char addr, + unsigned char reg, unsigned short *value) { short rdreg; /* register working value */ int j; /* counter */ @@ -188,7 +189,8 @@ int miiphy_read (unsigned char addr, unsigned char reg, unsigned short *value) * Returns: * 0 on success */ -int miiphy_write (unsigned char addr, unsigned char reg, unsigned short value) +int bb_miiphy_write (char *devname, unsigned char addr, + unsigned char reg, unsigned short value) { int j; /* counter */ #ifndef CONFIG_EP8248 diff --git a/common/miiphyutil.c b/common/miiphyutil.c index 13b9c65..e411e57 100644 --- a/common/miiphyutil.c +++ b/common/miiphyutil.c @@ -30,6 +30,218 @@ #include <miiphy.h> #if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) +#include <asm/types.h> +#include <linux/list.h> +#include <malloc.h> +#include <net.h> + +/* local debug macro */ +#define MII_DEBUG +#undef MII_DEBUG + +#undef debug +#ifdef MII_DEBUG +#define debug(fmt,args...) printf (fmt ,##args) +#else +#define debug(fmt,args...) +#endif /* MII_DEBUG */ + +struct mii_dev { + struct list_head link; + char *name; + int (* read)(char *devname, unsigned char addr, + unsigned char reg, unsigned short *value); + int (* write)(char *devname, unsigned char addr, + unsigned char reg, unsigned short value); +}; + +static struct list_head mii_devs; +static struct mii_dev *current_mii; + +/***************************************************************************** + * + * Initialize global data. Need to be called before any other miiphy routine. + */ +void miiphy_init() +{ + INIT_LIST_HEAD(&mii_devs); + current_mii = NULL; +} + +/***************************************************************************** + * + * Register read and write MII access routines for the device <name>. + */ +void miiphy_register(char *name, + int (* read)(char *devname, unsigned char addr, + unsigned char reg, unsigned short *value), + int (* write)(char *devname, unsigned char addr, + unsigned char reg, unsigned short value)) +{ + struct list_head *entry; + struct mii_dev *new_dev; + struct mii_dev *miidev; + unsigned int name_len; + + /* check if we have unique name */ + list_for_each(entry, &mii_devs) { + miidev = list_entry(entry, struct mii_dev, link); + if (strcmp(miidev->name, name) == 0) { + printf("miiphy_register: non unique device name '%s'\n", + name); + return; + } + } + + /* allocate memory */ + name_len = strlen(name); + new_dev = (struct mii_dev *)malloc(sizeof(struct mii_dev) + name_len + 1); + + if(new_dev == NULL) { + printf("miiphy_register: cannot allocate memory for '%s'\n", + name); + return; + } + memset(new_dev, 0, sizeof(struct mii_dev) + name_len); + + /* initalize mii_dev struct fields */ + INIT_LIST_HEAD(&new_dev->link); + new_dev->read = read; + new_dev->write = write; + new_dev->name = (char *)(new_dev + 1); + strncpy(new_dev->name, name, name_len); + new_dev->name[name_len] = '\0'; + + debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n", + new_dev->name, new_dev->read, new_dev->write); + + /* add it to the list */ + list_add_tail(&new_dev->link, &mii_devs); + + if (!current_mii) + current_mii = new_dev; +} + +int miiphy_set_current_dev(char *devname) +{ + struct list_head *entry; + struct mii_dev *dev; + + list_for_each(entry, &mii_devs) { + dev = list_entry(entry, struct mii_dev, link); + + if (strcmp(devname, dev->name) == 0) { + current_mii = dev; + return 0; + } + } + + printf("No such device: %s\n", devname); + return 1; +} + +char *miiphy_get_current_dev() +{ + if (current_mii) + return current_mii->name; + + return NULL; +} + +/***************************************************************************** + * + * Read to variable <value> from the PHY attached to device <devname>, + * use PHY address <addr> and register <reg>. + * + * Returns: + * 0 on success + */ +int miiphy_read(char *devname, unsigned char addr, unsigned char reg, + unsigned short *value) +{ + struct list_head *entry; + struct mii_dev *dev; + int found_dev = 0; + int read_ret = 0; + + if (!devname) { + printf("NULL device name!\n"); + return 1; + } + + list_for_each(entry, &mii_devs) { + dev = list_entry(entry, struct mii_dev, link); + + if (strcmp(devname, dev->name) == 0) { + found_dev = 1; + read_ret = dev->read(devname, addr, reg, value); + break; + } + } + + if (found_dev == 0) + printf("No such device: %s\n", devname); + + return ((found_dev) ? read_ret : 1); +} + +/***************************************************************************** + * + * Write <value> to the PHY attached to device <devname>, + * use PHY address <addr> and register <reg>. + * + * Returns: + * 0 on success + */ +int miiphy_write(char *devname, unsigned char addr, unsigned char reg, + unsigned short value) +{ + struct list_head *entry; + struct mii_dev *dev; + int found_dev = 0; + int write_ret = 0; + + if (!devname) { + printf("NULL device name!\n"); + return 1; + } + + list_for_each(entry, &mii_devs) { + dev = list_entry(entry, struct mii_dev, link); + + if (strcmp(devname, dev->name) == 0) { + found_dev = 1; + write_ret = dev->write(devname, addr, reg, value); + break; + } + } + + if (found_dev == 0) + printf("No such device: %s\n", devname); + + return ((found_dev) ? write_ret : 1); +} + +/***************************************************************************** + * + * Print out list of registered MII capable devices. + */ +void miiphy_listdev(void) +{ + struct list_head *entry; + struct mii_dev *dev; + + puts("MII devices: "); + list_for_each(entry, &mii_devs) { + dev = list_entry(entry, struct mii_dev, link); + printf("'%s' ", dev->name); + } + puts("\n"); + + if (current_mii) + printf("Current device: '%s'\n", current_mii->name); +} + /***************************************************************************** * @@ -42,14 +254,15 @@ * Returns: * 0 on success */ -int miiphy_info (unsigned char addr, +int miiphy_info (char *devname, + unsigned char addr, unsigned int *oui, unsigned char *model, unsigned char *rev) { unsigned int reg = 0; unsigned short tmp; - if (miiphy_read (addr, PHY_PHYIDR2, &tmp) != 0) { + if (miiphy_read (devname, addr, PHY_PHYIDR2, &tmp) != 0) { #ifdef DEBUG puts ("PHY ID register 2 read failed\n"); #endif @@ -65,7 +278,7 @@ int miiphy_info (unsigned char addr, return (-1); } - if (miiphy_read (addr, PHY_PHYIDR1, &tmp) != 0) { + if (miiphy_read (devname, addr, PHY_PHYIDR1, &tmp) != 0) { #ifdef DEBUG puts ("PHY ID register 1 read failed\n"); #endif @@ -88,18 +301,18 @@ int miiphy_info (unsigned char addr, * Returns: * 0 on success */ -int miiphy_reset (unsigned char addr) +int miiphy_reset (char *devname, unsigned char addr) { unsigned short reg; int loop_cnt; - if (miiphy_read (addr, PHY_BMCR, ®) != 0) { + if (miiphy_read (devname, addr, PHY_BMCR, ®) != 0) { #ifdef DEBUG printf ("PHY status read failed\n"); #endif return (-1); } - if (miiphy_write (addr, PHY_BMCR, reg | 0x8000) != 0) { + if (miiphy_write (devname, addr, PHY_BMCR, reg | 0x8000) != 0) { #ifdef DEBUG puts ("PHY reset failed\n"); #endif @@ -116,7 +329,7 @@ int miiphy_reset (unsigned char addr) loop_cnt = 0; reg = 0x8000; while (((reg & 0x8000) != 0) && (loop_cnt++ < 1000000)) { - if (miiphy_read (addr, PHY_BMCR, ®) != 0) { + if (miiphy_read (devname, addr, PHY_BMCR, ®) != 0) { # ifdef DEBUG puts ("PHY status read failed\n"); # endif @@ -137,12 +350,12 @@ int miiphy_reset (unsigned char addr) * * Determine the ethernet speed (10/100). */ -int miiphy_speed (unsigned char addr) +int miiphy_speed (char *devname, unsigned char addr) { unsigned short reg; #if defined(CONFIG_PHY_GIGE) - if (miiphy_read (addr, PHY_1000BTSR, ®)) { + if (miiphy_read (devname, addr, PHY_1000BTSR, ®)) { printf ("PHY 1000BT Status read failed\n"); } else { if (reg != 0xFFFF) { @@ -154,14 +367,14 @@ int miiphy_speed (unsigned char addr) #endif /* CONFIG_PHY_GIGE */ /* Check Basic Management Control Register first. */ - if (miiphy_read (addr, PHY_BMCR, ®)) { + if (miiphy_read (devname, addr, PHY_BMCR, ®)) { puts ("PHY speed read failed, assuming 10bT\n"); return (_10BASET); } /* Check if auto-negotiation is on. */ if ((reg & PHY_BMCR_AUTON) != 0) { /* Get auto-negotiation results. */ - if (miiphy_read (addr, PHY_ANLPAR, ®)) { + if (miiphy_read (devname, addr, PHY_ANLPAR, ®)) { puts ("PHY AN speed read failed, assuming 10bT\n"); return (_10BASET); } @@ -185,12 +398,12 @@ int miiphy_speed (unsigned char addr) * * Determine full/half duplex. */ -int miiphy_duplex (unsigned char addr) +int miiphy_duplex (char *devname, unsigned char addr) { unsigned short reg; #if defined(CONFIG_PHY_GIGE) - if (miiphy_read (addr, PHY_1000BTSR, ®)) { + if (miiphy_read (devname, addr, PHY_1000BTSR, ®)) { printf ("PHY 1000BT Status read failed\n"); } else { if ( (reg != 0xFFFF) && @@ -205,14 +418,14 @@ int miiphy_duplex (unsigned char addr) #endif /* CONFIG_PHY_GIGE */ /* Check Basic Management Control Register first. */ - if (miiphy_read (addr, PHY_BMCR, ®)) { + if (miiphy_read (devname, addr, PHY_BMCR, ®)) { puts ("PHY duplex read failed, assuming half duplex\n"); return (HALF); } /* Check if auto-negotiation is on. */ if ((reg & PHY_BMCR_AUTON) != 0) { /* Get auto-negotiation results. */ - if (miiphy_read (addr, PHY_ANLPAR, ®)) { + if (miiphy_read (devname, addr, PHY_ANLPAR, ®)) { puts ("PHY AN duplex read failed, assuming half duplex\n"); return (HALF); } @@ -237,13 +450,13 @@ int miiphy_duplex (unsigned char addr) * * Determine link status */ -int miiphy_link (unsigned char addr) +int miiphy_link (char *devname, unsigned char addr) { unsigned short reg; /* dummy read; needed to latch some phys */ - (void)miiphy_read(addr, PHY_BMSR, ®); - if (miiphy_read (addr, PHY_BMSR, ®)) { + (void)miiphy_read(devname, addr, PHY_BMSR, ®); + if (miiphy_read (devname, addr, PHY_BMSR, ®)) { puts ("PHY_BMSR read failed, assuming no link\n"); return (0); } diff --git a/common/soft_i2c.c b/common/soft_i2c.c index f7ca498..3d0e08c 100644 --- a/common/soft_i2c.c +++ b/common/soft_i2c.c @@ -399,7 +399,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) */ uchar i2c_reg_read(uchar i2c_addr, uchar reg) { - char buf; + uchar buf; i2c_read(i2c_addr, reg, 1, &buf, 1); diff --git a/common/spartan3.c b/common/spartan3.c new file mode 100644 index 0000000..c0f2b05 --- /dev/null +++ b/common/spartan3.c @@ -0,0 +1,658 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* + * Configuration support for Xilinx Spartan3 devices. Based + * on spartan2.c (Rich Ireland, rireland@enterasys.com). + */ + +#include <common.h> /* core U-Boot definitions */ +#include <spartan3.h> /* Spartan-II device family */ + +#if (CONFIG_FPGA & (CFG_XILINX | CFG_SPARTAN3)) + +/* Define FPGA_DEBUG to get debug printf's */ +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#undef CFG_FPGA_CHECK_BUSY +#undef CFG_FPGA_PROG_FEEDBACK + +/* Note: The assumption is that we cannot possibly run fast enough to + * overrun the device (the Slave Parallel mode can free run at 50MHz). + * If there is a need to operate slower, define CONFIG_FPGA_DELAY in + * the board config file to slow things down. + */ +#ifndef CONFIG_FPGA_DELAY +#define CONFIG_FPGA_DELAY() +#endif + +#ifndef CFG_FPGA_WAIT +#define CFG_FPGA_WAIT CFG_HZ/100 /* 10 ms */ +#endif + +static int Spartan3_sp_load( Xilinx_desc *desc, void *buf, size_t bsize ); +static int Spartan3_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize ); +/* static int Spartan3_sp_info( Xilinx_desc *desc ); */ +static int Spartan3_sp_reloc( Xilinx_desc *desc, ulong reloc_offset ); + +static int Spartan3_ss_load( Xilinx_desc *desc, void *buf, size_t bsize ); +static int Spartan3_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize ); +/* static int Spartan3_ss_info( Xilinx_desc *desc ); */ +static int Spartan3_ss_reloc( Xilinx_desc *desc, ulong reloc_offset ); + +/* ------------------------------------------------------------------------- */ +/* Spartan-II Generic Implementation */ +int Spartan3_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); + ret_val = Spartan3_ss_load (desc, buf, bsize); + break; + + case slave_parallel: + PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); + ret_val = Spartan3_sp_load (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int Spartan3_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); + ret_val = Spartan3_ss_dump (desc, buf, bsize); + break; + + case slave_parallel: + PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); + ret_val = Spartan3_sp_dump (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int Spartan3_info( Xilinx_desc *desc ) +{ + return FPGA_SUCCESS; +} + + +int Spartan3_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (desc->family != Xilinx_Spartan3) { + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + return FPGA_FAIL; + } else + switch (desc->iface) { + case slave_serial: + ret_val = Spartan3_ss_reloc (desc, reloc_offset); + break; + + case slave_parallel: + ret_val = Spartan3_sp_reloc (desc, reloc_offset); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + + +/* ------------------------------------------------------------------------- */ +/* Spartan-II Slave Parallel Generic Implementation */ + +static int Spartan3_sp_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns; + + PRINTF ("%s: start with interface functions @ 0x%p\n", + __FUNCTION__, fn); + + if (fn) { + size_t bytecount = 0; + unsigned char *data = (unsigned char *) buf; + int cookie = desc->cookie; /* make a local copy */ + unsigned long ts; /* timestamp */ + + PRINTF ("%s: Function Table:\n" + "ptr:\t0x%p\n" + "struct: 0x%p\n" + "pre: 0x%p\n" + "pgm:\t0x%p\n" + "init:\t0x%p\n" + "err:\t0x%p\n" + "clk:\t0x%p\n" + "cs:\t0x%p\n" + "wr:\t0x%p\n" + "read data:\t0x%p\n" + "write data:\t0x%p\n" + "busy:\t0x%p\n" + "abort:\t0x%p\n", + "post:\t0x%p\n\n", + __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err, + fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy, + fn->abort, fn->post); + + /* + * This code is designed to emulate the "Express Style" + * Continuous Data Loading in Slave Parallel Mode for + * the Spartan-II Family. + */ +#ifdef CFG_FPGA_PROG_FEEDBACK + printf ("Loading FPGA Device %d...\n", cookie); +#endif + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) { + (*fn->pre) (cookie); + } + + /* Establish the initial state */ + (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ + + /* Get ready for the burn */ + CONFIG_FPGA_DELAY (); + (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ + + ts = get_timer (0); /* get current time */ + /* Now wait for INIT and BUSY to go high */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for INIT to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + return FPGA_FAIL; + } + } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); + + (*fn->wr) (TRUE, TRUE, cookie); /* Assert write, commit */ + (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + /* Load the data */ + while (bytecount < bsize) { + /* XXX - do we check for an Ctrl-C press in here ??? */ + /* XXX - Check the error bit? */ + + (*fn->wdata) (data[bytecount++], TRUE, cookie); /* write the data */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + +#ifdef CFG_FPGA_CHECK_BUSY + ts = get_timer (0); /* get current time */ + while ((*fn->busy) (cookie)) { + /* XXX - we should have a check in here somewhere to + * make sure we aren't busy forever... */ + + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for BUSY to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + return FPGA_FAIL; + } + } +#endif + +#ifdef CFG_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + CONFIG_FPGA_DELAY (); + (*fn->cs) (FALSE, TRUE, cookie); /* Deassert the chip select */ + (*fn->wr) (FALSE, TRUE, cookie); /* Deassert the write pin */ + +#ifdef CFG_FPGA_PROG_FEEDBACK + putc ('\n'); /* terminate the dotted line */ +#endif + + /* now check for done signal */ + ts = get_timer (0); /* get current time */ + ret_val = FPGA_SUCCESS; + while ((*fn->done) (cookie) == FPGA_FAIL) { + /* XXX - we should have a check in here somewhere to + * make sure we aren't busy forever... */ + + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for DONE to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + ret_val = FPGA_FAIL; + break; + } + } + + if (ret_val == FPGA_SUCCESS) { +#ifdef CFG_FPGA_PROG_FEEDBACK + puts ("Done.\n"); +#endif + } + /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + + else { +#ifdef CFG_FPGA_PROG_FEEDBACK + puts ("Fail.\n"); +#endif + } + + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + +static int Spartan3_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns; + + if (fn) { + unsigned char *data = (unsigned char *) buf; + size_t bytecount = 0; + int cookie = desc->cookie; /* make a local copy */ + + printf ("Starting Dump of FPGA Device %d...\n", cookie); + + (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + /* dump the data */ + while (bytecount < bsize) { + /* XXX - do we check for an Ctrl-C press in here ??? */ + + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */ +#ifdef CFG_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + (*fn->cs) (FALSE, FALSE, cookie); /* Deassert the chip select */ + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + +#ifdef CFG_FPGA_PROG_FEEDBACK + putc ('\n'); /* terminate the dotted line */ +#endif + puts ("Done.\n"); + + /* XXX - checksum the data? */ + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + + +static int Spartan3_sp_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan3_Slave_Parallel_fns *fn_r, *fn = + (Xilinx_Spartan3_Slave_Parallel_fns *) (desc->iface_fns); + + if (fn) { + ulong addr; + + /* Get the relocated table address */ + addr = (ulong) fn + reloc_offset; + fn_r = (Xilinx_Spartan3_Slave_Parallel_fns *) addr; + + if (!fn_r->relocated) { + + if (memcmp (fn_r, fn, + sizeof (Xilinx_Spartan3_Slave_Parallel_fns)) + == 0) { + /* good copy of the table, fix the descriptor pointer */ + desc->iface_fns = fn_r; + } else { + PRINTF ("%s: Invalid function table at 0x%p\n", + __FUNCTION__, fn_r); + return FPGA_FAIL; + } + + PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, + desc); + + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + + addr = (ulong) (fn->pgm) + reloc_offset; + fn_r->pgm = (Xilinx_pgm_fn) addr; + + addr = (ulong) (fn->init) + reloc_offset; + fn_r->init = (Xilinx_init_fn) addr; + + addr = (ulong) (fn->done) + reloc_offset; + fn_r->done = (Xilinx_done_fn) addr; + + addr = (ulong) (fn->clk) + reloc_offset; + fn_r->clk = (Xilinx_clk_fn) addr; + + addr = (ulong) (fn->err) + reloc_offset; + fn_r->err = (Xilinx_err_fn) addr; + + addr = (ulong) (fn->cs) + reloc_offset; + fn_r->cs = (Xilinx_cs_fn) addr; + + addr = (ulong) (fn->wr) + reloc_offset; + fn_r->wr = (Xilinx_wr_fn) addr; + + addr = (ulong) (fn->rdata) + reloc_offset; + fn_r->rdata = (Xilinx_rdata_fn) addr; + + addr = (ulong) (fn->wdata) + reloc_offset; + fn_r->wdata = (Xilinx_wdata_fn) addr; + + addr = (ulong) (fn->busy) + reloc_offset; + fn_r->busy = (Xilinx_busy_fn) addr; + + addr = (ulong) (fn->abort) + reloc_offset; + fn_r->abort = (Xilinx_abort_fn) addr; + + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + + fn_r->relocated = TRUE; + + } else { + /* this table has already been moved */ + /* XXX - should check to see if the descriptor is correct */ + desc->iface_fns = fn_r; + } + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; + +} + +/* ------------------------------------------------------------------------- */ + +static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan3_Slave_Serial_fns *fn = desc->iface_fns; + int i; + char val; + + PRINTF ("%s: start with interface functions @ 0x%p\n", + __FUNCTION__, fn); + + if (fn) { + size_t bytecount = 0; + unsigned char *data = (unsigned char *) buf; + int cookie = desc->cookie; /* make a local copy */ + unsigned long ts; /* timestamp */ + + PRINTF ("%s: Function Table:\n" + "ptr:\t0x%p\n" + "struct: 0x%p\n" + "pgm:\t0x%p\n" + "init:\t0x%p\n" + "clk:\t0x%p\n" + "wr:\t0x%p\n" + "done:\t0x%p\n\n", + __FUNCTION__, &fn, fn, fn->pgm, fn->init, + fn->clk, fn->wr, fn->done); +#ifdef CFG_FPGA_PROG_FEEDBACK + printf ("Loading FPGA Device %d...\n", cookie); +#endif + + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) { + (*fn->pre) (cookie); + } + + /* Establish the initial state */ + (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ + + /* Wait for INIT state (init low) */ + ts = get_timer (0); /* get current time */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for INIT to start.\n"); + return FPGA_FAIL; + } + } while (!(*fn->init) (cookie)); + + /* Get ready for the burn */ + CONFIG_FPGA_DELAY (); + (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ + + ts = get_timer (0); /* get current time */ + /* Now wait for INIT to go high */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for INIT to clear.\n"); + return FPGA_FAIL; + } + } while ((*fn->init) (cookie)); + + /* Load the data */ + while (bytecount < bsize) { + + /* Xilinx detects an error if INIT goes low (active) + while DONE is low (inactive) */ + if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) { + puts ("** CRC error during FPGA load.\n"); + return (FPGA_FAIL); + } + val = data [bytecount ++]; + i = 8; + do { + /* Deassert the clock */ + (*fn->clk) (FALSE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + /* Write data */ + (*fn->wr) ((val < 0), TRUE, cookie); + CONFIG_FPGA_DELAY (); + /* Assert the clock */ + (*fn->clk) (TRUE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + val <<= 1; + i --; + } while (i > 0); + +#ifdef CFG_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + CONFIG_FPGA_DELAY (); + +#ifdef CFG_FPGA_PROG_FEEDBACK + putc ('\n'); /* terminate the dotted line */ +#endif + + /* now check for done signal */ + ts = get_timer (0); /* get current time */ + ret_val = FPGA_SUCCESS; + (*fn->wr) (TRUE, TRUE, cookie); + + while (! (*fn->done) (cookie)) { + /* XXX - we should have a check in here somewhere to + * make sure we aren't busy forever... */ + + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + putc ('*'); + + if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for DONE to clear.\n"); + ret_val = FPGA_FAIL; + break; + } + } + putc ('\n'); /* terminate the dotted line */ + +#ifdef CFG_FPGA_PROG_FEEDBACK + if (ret_val == FPGA_SUCCESS) { + puts ("Done.\n"); + } + else { + puts ("Fail.\n"); + } +#endif + + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + +static int Spartan3_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + /* Readback is only available through the Slave Parallel and */ + /* boundary-scan interfaces. */ + printf ("%s: Slave Serial Dumping is unavailable\n", + __FUNCTION__); + return FPGA_FAIL; +} + +static int Spartan3_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan3_Slave_Serial_fns *fn_r, *fn = + (Xilinx_Spartan3_Slave_Serial_fns *) (desc->iface_fns); + + if (fn) { + ulong addr; + + /* Get the relocated table address */ + addr = (ulong) fn + reloc_offset; + fn_r = (Xilinx_Spartan3_Slave_Serial_fns *) addr; + + if (!fn_r->relocated) { + + if (memcmp (fn_r, fn, + sizeof (Xilinx_Spartan3_Slave_Serial_fns)) + == 0) { + /* good copy of the table, fix the descriptor pointer */ + desc->iface_fns = fn_r; + } else { + PRINTF ("%s: Invalid function table at 0x%p\n", + __FUNCTION__, fn_r); + return FPGA_FAIL; + } + + PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, + desc); + + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + + addr = (ulong) (fn->pgm) + reloc_offset; + fn_r->pgm = (Xilinx_pgm_fn) addr; + + addr = (ulong) (fn->init) + reloc_offset; + fn_r->init = (Xilinx_init_fn) addr; + + addr = (ulong) (fn->done) + reloc_offset; + fn_r->done = (Xilinx_done_fn) addr; + + addr = (ulong) (fn->clk) + reloc_offset; + fn_r->clk = (Xilinx_clk_fn) addr; + + addr = (ulong) (fn->wr) + reloc_offset; + fn_r->wr = (Xilinx_wr_fn) addr; + + fn_r->relocated = TRUE; + + } else { + /* this table has already been moved */ + /* XXX - should check to see if the descriptor is correct */ + desc->iface_fns = fn_r; + } + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; + +} + +#endif diff --git a/common/usb_storage.c b/common/usb_storage.c index 69d195a..99e4ab0 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -490,7 +490,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us) */ int usb_stor_CB_comdat(ccb *srb, struct us_data *us) { - int result; + int result = 0; int dir_in,retry; unsigned int pipe; unsigned long status; @@ -528,7 +528,7 @@ int usb_stor_CB_comdat(ccb *srb, struct us_data *us) USB_STOR_PRINTF("CB_transport: control msg returned %d, direction is %s to go 0x%lx\n",result,dir_in ? "IN" : "OUT",srb->datalen); if (srb->datalen) { - result = us_one_transfer(us, pipe, srb->pdata,srb->datalen); + result = us_one_transfer(us, pipe, (char *)srb->pdata,srb->datalen); USB_STOR_PRINTF("CBI attempted to transfer data, result is %d status %lX, len %d\n", result,us->pusb_dev->status,us->pusb_dev->act_len); if(!(us->pusb_dev->status & USB_ST_NAK_REC)) break; @@ -847,7 +847,7 @@ static int usb_request_sense(ccb *srb,struct us_data *ss) { char *ptr; - ptr=srb->pdata; + ptr=(char *)srb->pdata; memset(&srb->cmd[0],0,12); srb->cmd[0]=SCSI_REQ_SENSE; srb->cmd[1]=srb->lun<<5; @@ -857,7 +857,7 @@ static int usb_request_sense(ccb *srb,struct us_data *ss) srb->cmdlen=12; ss->transport(srb,ss); USB_STOR_PRINTF("Request Sense returned %02X %02X %02X\n",srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]); - srb->pdata=ptr; + srb->pdata=(uchar *)ptr; return 0; } diff --git a/common/virtex2.c b/common/virtex2.c index bb44eaa..b5dc366 100644 --- a/common/virtex2.c +++ b/common/virtex2.c @@ -33,6 +33,10 @@ #if (CONFIG_FPGA & (CFG_XILINX | CFG_VIRTEX2)) +#if 0 +#define FPGA_DEBUG +#endif + #ifdef FPGA_DEBUG #define PRINTF(fmt,args...) printf (fmt ,##args) #else @@ -190,7 +194,7 @@ int Virtex2_reloc (Xilinx_desc * desc, ulong reloc_offset) * this process, a configuration error (most likely CRC failure) has * ocurred. At this point a status word may be read from the * SelectMap interface to determine the source of the problem (You - * could, for instance, put this in you 'abort' function handler). + * could, for instance, put this in your 'abort' function handler). * 4. After all data has been written, test the state of the FPGA * INIT_B and DONE lines. If both are high, configuration has * succeeded. Congratulations! @@ -251,7 +255,7 @@ static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) ts = get_timer (0); do { if (get_timer (ts) > CFG_FPGA_WAIT_INIT) { - printf ("%s:%d: ** Timeout after %d mS waiting for INIT" + printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" " to assert.\n", __FUNCTION__, __LINE__, CFG_FPGA_WAIT_INIT); (*fn->abort) (cookie); @@ -270,7 +274,7 @@ static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) do { CONFIG_FPGA_DELAY (); if (get_timer (ts) > CFG_FPGA_WAIT_INIT) { - printf ("%s:%d: ** Timeout after %d mS waiting for INIT" + printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" " to deassert.\n", __FUNCTION__, __LINE__, CFG_FPGA_WAIT_INIT); (*fn->abort) (cookie); @@ -293,14 +297,24 @@ static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) return FPGA_FAIL; } #endif + + if ((*fn->done) (cookie) == FPGA_SUCCESS) { + PRINTF ("%s:%d:done went active early, bytecount = %d\n", + __FUNCTION__, __LINE__, bytecount); + break; + } + #ifdef CFG_FPGA_CHECK_ERROR if ((*fn->init) (cookie)) { - printf ("%s:%d: ** Error: INIT asserted during" + printf ("\n%s:%d: ** Error: INIT asserted during" " configuration\n", __FUNCTION__, __LINE__); + printf ("%d = buffer offset, %d = buffer size\n", + bytecount, bsize); (*fn->abort) (cookie); return FPGA_FAIL; } #endif + (*fn->wdata) (data[bytecount++], TRUE, cookie); CONFIG_FPGA_DELAY (); @@ -315,7 +329,7 @@ static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) ts = get_timer (0); while ((*fn->busy) (cookie)) { if (get_timer (ts) > CFG_FPGA_WAIT_BUSY) { - printf ("%s:%d: ** Timeout after %d mS waiting for" + printf ("%s:%d: ** Timeout after %d ticks waiting for" " BUSY to deassert\n", __FUNCTION__, __LINE__, CFG_FPGA_WAIT_BUSY); (*fn->abort) (cookie); @@ -349,7 +363,7 @@ static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) ret_val = FPGA_SUCCESS; while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) { if (get_timer (ts) > CFG_FPGA_WAIT_CONFIG) { - printf ("%s:%d: ** Timeout after %d mS waiting for DONE to" + printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to" "assert and INIT to deassert\n", __FUNCTION__, __LINE__, CFG_FPGA_WAIT_CONFIG); (*fn->abort) (cookie); diff --git a/common/xilinx.c b/common/xilinx.c index b2e6169..e03e78c 100644 --- a/common/xilinx.c +++ b/common/xilinx.c @@ -30,6 +30,7 @@ #include <common.h> #include <virtex2.h> #include <spartan2.h> +#include <spartan3.h> #if (CONFIG_FPGA & CFG_FPGA_XILINX) @@ -53,7 +54,7 @@ int xilinx_load (Xilinx_desc * desc, void *buf, size_t bsize) { int ret_val = FPGA_FAIL; /* assume a failure */ - if (!xilinx_validate (desc, __FUNCTION__)) { + if (!xilinx_validate (desc, (char *)__FUNCTION__)) { printf ("%s: Invalid device descriptor\n", __FUNCTION__); } else switch (desc->family) { @@ -67,6 +68,16 @@ int xilinx_load (Xilinx_desc * desc, void *buf, size_t bsize) __FUNCTION__); #endif break; + case Xilinx_Spartan3: +#if (CONFIG_FPGA & CFG_SPARTAN3) + PRINTF ("%s: Launching the Spartan-III Loader...\n", + __FUNCTION__); + ret_val = Spartan3_load (desc, buf, bsize); +#else + printf ("%s: No support for Spartan-III devices.\n", + __FUNCTION__); +#endif + break; case Xilinx_Virtex2: #if (CONFIG_FPGA & CFG_VIRTEX2) PRINTF ("%s: Launching the Virtex-II Loader...\n", @@ -90,7 +101,7 @@ int xilinx_dump (Xilinx_desc * desc, void *buf, size_t bsize) { int ret_val = FPGA_FAIL; /* assume a failure */ - if (!xilinx_validate (desc, __FUNCTION__)) { + if (!xilinx_validate (desc, (char *)__FUNCTION__)) { printf ("%s: Invalid device descriptor\n", __FUNCTION__); } else switch (desc->family) { @@ -104,6 +115,16 @@ int xilinx_dump (Xilinx_desc * desc, void *buf, size_t bsize) __FUNCTION__); #endif break; + case Xilinx_Spartan3: +#if (CONFIG_FPGA & CFG_SPARTAN3) + PRINTF ("%s: Launching the Spartan-III Reader...\n", + __FUNCTION__); + ret_val = Spartan3_dump (desc, buf, bsize); +#else + printf ("%s: No support for Spartan-III devices.\n", + __FUNCTION__); +#endif + break; case Xilinx_Virtex2: #if (CONFIG_FPGA & CFG_VIRTEX2) PRINTF ("%s: Launching the Virtex-II Reader...\n", @@ -127,12 +148,15 @@ int xilinx_info (Xilinx_desc * desc) { int ret_val = FPGA_FAIL; - if (xilinx_validate (desc, __FUNCTION__)) { + if (xilinx_validate (desc, (char *)__FUNCTION__)) { printf ("Family: \t"); switch (desc->family) { case Xilinx_Spartan2: printf ("Spartan-II\n"); break; + case Xilinx_Spartan3: + printf ("Spartan-III\n"); + break; case Xilinx_Virtex2: printf ("Virtex-II\n"); break; @@ -182,6 +206,15 @@ int xilinx_info (Xilinx_desc * desc) __FUNCTION__); #endif break; + case Xilinx_Spartan3: +#if (CONFIG_FPGA & CFG_SPARTAN3) + Spartan3_info (desc); +#else + /* just in case */ + printf ("%s: No support for Spartan-III devices.\n", + __FUNCTION__); +#endif + break; case Xilinx_Virtex2: #if (CONFIG_FPGA & CFG_VIRTEX2) Virtex2_info (desc); @@ -211,7 +244,7 @@ int xilinx_reloc (Xilinx_desc * desc, ulong reloc_offset) { int ret_val = FPGA_FAIL; /* assume a failure */ - if (!xilinx_validate (desc, __FUNCTION__)) { + if (!xilinx_validate (desc, (char *)__FUNCTION__)) { printf ("%s: Invalid device descriptor\n", __FUNCTION__); } else switch (desc->family) { @@ -223,6 +256,14 @@ int xilinx_reloc (Xilinx_desc * desc, ulong reloc_offset) __FUNCTION__); #endif break; + case Xilinx_Spartan3: +#if (CONFIG_FPGA & CFG_SPARTAN3) + ret_val = Spartan3_reloc (desc, reloc_offset); +#else + printf ("%s: No support for Spartan-III devices.\n", + __FUNCTION__); +#endif + break; case Xilinx_Virtex2: #if (CONFIG_FPGA & CFG_VIRTEX2) ret_val = Virtex2_reloc (desc, reloc_offset); |