diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile | 1 | ||||
-rw-r--r-- | common/cmd_bootldr.c | 21 | ||||
-rw-r--r-- | common/cmd_ldrinfo.c | 192 |
3 files changed, 201 insertions, 13 deletions
diff --git a/common/Makefile b/common/Makefile index 048df0c..4555716 100644 --- a/common/Makefile +++ b/common/Makefile @@ -105,6 +105,7 @@ COBJS-$(CONFIG_CMD_IRQ) += cmd_irq.o COBJS-$(CONFIG_CMD_ITEST) += cmd_itest.o COBJS-$(CONFIG_CMD_JFFS2) += cmd_jffs2.o COBJS-$(CONFIG_CMD_CRAMFS) += cmd_cramfs.o +COBJS-$(CONFIG_CMD_LDRINFO) += cmd_ldrinfo.o COBJS-$(CONFIG_CMD_LICENSE) += cmd_license.o COBJS-y += cmd_load.o COBJS-$(CONFIG_LOGBUFFER) += cmd_log.o diff --git a/common/cmd_bootldr.c b/common/cmd_bootldr.c index 535b931..bc5c1f9 100644 --- a/common/cmd_bootldr.c +++ b/common/cmd_bootldr.c @@ -24,7 +24,7 @@ static bool ldr_valid_signature(uint8_t *data) #if defined(__ADSPBF561__) /* BF56x has a 4 byte global header */ - if (data[3] == 0xA0) + if (data[3] == (GFLAG_56X_SIGN_MAGIC << (GFLAG_56X_SIGN_SHIFT - 24))) return true; #elif defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \ @@ -53,11 +53,6 @@ static bool ldr_valid_signature(uint8_t *data) * LDRs from random memory addresses. So whenever possible, use that. In * the older cases (BF53x/BF561), parse the LDR format ourselves. */ -#define ZEROFILL 0x0001 -#define RESVECT 0x0002 -#define INIT 0x0008 -#define IGNORE 0x0010 -#define FINAL 0x8000 static void ldr_load(uint8_t *base_addr) { #if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \ @@ -76,7 +71,7 @@ static void ldr_load(uint8_t *base_addr) # endif memmove(&flags, base_addr + 8, sizeof(flags)); - bfin_write_EVT1(flags & RESVECT ? 0xFFA00000 : 0xFFA08000); + bfin_write_EVT1(flags & BFLAG_53X_RESVECT ? 0xFFA00000 : 0xFFA08000); do { /* block header may not be aligned */ @@ -85,24 +80,24 @@ static void ldr_load(uint8_t *base_addr) memmove(&flags, base_addr+8, sizeof(flags)); base_addr += sizeof(addr) + sizeof(count) + sizeof(flags); - printf("loading to 0x%08x (0x%x bytes) flags: 0x%04x\n", + printf("loading to 0x%08x (%#x bytes) flags: 0x%04x\n", addr, count, flags); - if (!(flags & IGNORE)) { - if (flags & ZEROFILL) + if (!(flags & BFLAG_53X_IGNORE)) { + if (flags & BFLAG_53X_ZEROFILL) memset((void *)addr, 0x00, count); else memcpy((void *)addr, base_addr, count); - if (flags & INIT) { + if (flags & BFLAG_53X_INIT) { void (*init)(void) = (void *)addr; init(); } } - if (!(flags & ZEROFILL)) + if (!(flags & BFLAG_53X_ZEROFILL)) base_addr += count; - } while (!(flags & FINAL)); + } while (!(flags & BFLAG_53X_FINAL)); #endif } diff --git a/common/cmd_ldrinfo.c b/common/cmd_ldrinfo.c new file mode 100644 index 0000000..2aa56bd --- /dev/null +++ b/common/cmd_ldrinfo.c @@ -0,0 +1,192 @@ +/* + * U-boot - ldrinfo + * + * Copyright (c) 2010 Analog Devices Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * Licensed under the GPL-2 or later. + */ + +#include <config.h> +#include <common.h> +#include <command.h> + +#include <asm/blackfin.h> +#include <asm/mach-common/bits/bootrom.h> + +static uint32_t ldrinfo_header(const void *addr) +{ + uint32_t skip = 0; + +#if defined(__ADSPBF561__) + /* BF56x has a 4 byte global header */ + uint32_t header, sign; + static const char * const spi_speed[] = { + "500K", "1M", "2M", "??", + }; + + memcpy(&header, addr, sizeof(header)); + + sign = (header & GFLAG_56X_SIGN_MASK) >> GFLAG_56X_SIGN_SHIFT; + printf("Header: %08X ( %s-bit-flash wait:%i hold:%i spi:%s %s)\n", + header, + (header & GFLAG_56X_16BIT_FLASH) ? "16" : "8", + (header & GFLAG_56X_WAIT_MASK) >> GFLAG_56X_WAIT_SHIFT, + (header & GFLAG_56X_HOLD_MASK) >> GFLAG_56X_HOLD_SHIFT, + spi_speed[(header & GFLAG_56X_SPI_MASK) >> GFLAG_56X_SPI_SHIFT], + sign == GFLAG_56X_SIGN_MAGIC ? "" : "!!hdrsign!! "); + + skip = 4; +#endif + + /* |Block @ 12345678: 12345678 12345678 12345678 12345678 | */ +#if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \ + defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) || \ + defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__) + printf(" Address Count Flags\n"); +#else + printf(" BCode Address Count Argument\n"); +#endif + + return skip; +} + +struct ldr_flag { + uint16_t flag; + const char *desc; +}; + +static uint32_t ldrinfo_block(const void *base_addr) +{ + uint32_t count; + + printf("Block @ %08X: ", (uint32_t)base_addr); + +#if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \ + defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) || \ + defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__) + + uint32_t addr, pval; + uint16_t flags; + int i; + static const struct ldr_flag ldr_flags[] = { + { BFLAG_53X_ZEROFILL, "zerofill" }, + { BFLAG_53X_RESVECT, "resvect" }, + { BFLAG_53X_INIT, "init" }, + { BFLAG_53X_IGNORE, "ignore" }, + { BFLAG_53X_COMPRESSED, "compressed"}, + { BFLAG_53X_FINAL, "final" }, + }; + + memcpy(&addr, base_addr, sizeof(addr)); + memcpy(&count, base_addr+4, sizeof(count)); + memcpy(&flags, base_addr+8, sizeof(flags)); + + printf("%08X %08X %04X ( ", addr, count, flags); + + for (i = 0; i < ARRAY_SIZE(ldr_flags); ++i) + if (flags & ldr_flags[i].flag) + printf("%s ", ldr_flags[i].desc); + + pval = (flags & BFLAG_53X_PFLAG_MASK) >> BFLAG_53X_PFLAG_SHIFT; + if (pval) + printf("gpio%i ", pval); + pval = (flags & BFLAG_53X_PPORT_MASK) >> BFLAG_53X_PPORT_SHIFT; + if (pval) + printf("port%c ", 'e' + pval); + + if (flags & BFLAG_53X_ZEROFILL) + count = 0; + if (flags & BFLAG_53X_FINAL) + count = 0; + else + count += sizeof(addr) + sizeof(count) + sizeof(flags); + +#else + + const uint8_t *raw8 = base_addr; + uint32_t bcode, addr, arg, sign, chk; + int i; + static const struct ldr_flag ldr_flags[] = { + { BFLAG_SAFE, "safe" }, + { BFLAG_AUX, "aux" }, + { BFLAG_FILL, "fill" }, + { BFLAG_QUICKBOOT, "quickboot" }, + { BFLAG_CALLBACK, "callback" }, + { BFLAG_INIT, "init" }, + { BFLAG_IGNORE, "ignore" }, + { BFLAG_INDIRECT, "indirect" }, + { BFLAG_FIRST, "first" }, + { BFLAG_FINAL, "final" }, + }; + + memcpy(&bcode, base_addr, sizeof(bcode)); + memcpy(&addr, base_addr+4, sizeof(addr)); + memcpy(&count, base_addr+8, sizeof(count)); + memcpy(&arg, base_addr+12, sizeof(arg)); + + printf("%08X %08X %08X %08X ( ", bcode, addr, count, arg); + + if (addr % 4) + printf("!!addralgn!! "); + if (count % 4) + printf("!!cntalgn!! "); + + sign = (bcode & BFLAG_HDRSIGN_MASK) >> BFLAG_HDRSIGN_SHIFT; + if (sign != BFLAG_HDRSIGN_MAGIC) + printf("!!hdrsign!! "); + + chk = 0; + for (i = 0; i < 16; ++i) + chk ^= raw8[i]; + if (chk) + printf("!!hdrchk!! "); + + printf("dma:%i ", bcode & BFLAG_DMACODE_MASK); + + for (i = 0; i < ARRAY_SIZE(ldr_flags); ++i) + if (bcode & ldr_flags[i].flag) + printf("%s ", ldr_flags[i].desc); + + if (bcode & BFLAG_FILL) + count = 0; + if (bcode & BFLAG_FINAL) + count = 0; + else + count += sizeof(bcode) + sizeof(addr) + sizeof(count) + sizeof(arg); + +#endif + + printf(")\n"); + + return count; +} + +static int do_ldrinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const void *addr; + uint32_t skip; + + /* Get the address */ + if (argc < 2) + addr = (void *)load_addr; + else + addr = (void *)simple_strtoul(argv[1], NULL, 16); + + /* Walk the LDR */ + addr += ldrinfo_header(addr); + do { + skip = ldrinfo_block(addr); + addr += skip; + } while (skip); + + return 0; +} + +U_BOOT_CMD( + ldrinfo, 2, 0, do_ldrinfo, + "validate ldr image in memory", + "[addr]\n" +); |