ldrinfo.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * U-Boot - ldrinfo
  3. *
  4. * Copyright (c) 2010 Analog Devices Inc.
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * project.
  8. *
  9. * Licensed under the GPL-2 or later.
  10. */
  11. #include <config.h>
  12. #include <common.h>
  13. #include <command.h>
  14. #include <asm/blackfin.h>
  15. #include <asm/mach-common/bits/bootrom.h>
  16. static uint32_t ldrinfo_header(const void *addr)
  17. {
  18. uint32_t skip = 0;
  19. #if defined(__ADSPBF561__)
  20. /* BF56x has a 4 byte global header */
  21. uint32_t header, sign;
  22. static const char * const spi_speed[] = {
  23. "500K", "1M", "2M", "??",
  24. };
  25. memcpy(&header, addr, sizeof(header));
  26. sign = (header & GFLAG_56X_SIGN_MASK) >> GFLAG_56X_SIGN_SHIFT;
  27. printf("Header: %08X ( %s-bit-flash wait:%i hold:%i spi:%s %s)\n",
  28. header,
  29. (header & GFLAG_56X_16BIT_FLASH) ? "16" : "8",
  30. (header & GFLAG_56X_WAIT_MASK) >> GFLAG_56X_WAIT_SHIFT,
  31. (header & GFLAG_56X_HOLD_MASK) >> GFLAG_56X_HOLD_SHIFT,
  32. spi_speed[(header & GFLAG_56X_SPI_MASK) >> GFLAG_56X_SPI_SHIFT],
  33. sign == GFLAG_56X_SIGN_MAGIC ? "" : "!!hdrsign!! ");
  34. skip = 4;
  35. #endif
  36. /* |Block @ 12345678: 12345678 12345678 12345678 12345678 | */
  37. #if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
  38. defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) || \
  39. defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
  40. printf(" Address Count Flags\n");
  41. #else
  42. printf(" BCode Address Count Argument\n");
  43. #endif
  44. return skip;
  45. }
  46. struct ldr_flag {
  47. uint16_t flag;
  48. const char *desc;
  49. };
  50. static uint32_t ldrinfo_block(const void *base_addr)
  51. {
  52. uint32_t count;
  53. printf("Block @ %08X: ", (uint32_t)base_addr);
  54. #if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
  55. defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) || \
  56. defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
  57. uint32_t addr, pval;
  58. uint16_t flags;
  59. int i;
  60. static const struct ldr_flag ldr_flags[] = {
  61. { BFLAG_53X_ZEROFILL, "zerofill" },
  62. { BFLAG_53X_RESVECT, "resvect" },
  63. { BFLAG_53X_INIT, "init" },
  64. { BFLAG_53X_IGNORE, "ignore" },
  65. { BFLAG_53X_COMPRESSED, "compressed"},
  66. { BFLAG_53X_FINAL, "final" },
  67. };
  68. memcpy(&addr, base_addr, sizeof(addr));
  69. memcpy(&count, base_addr+4, sizeof(count));
  70. memcpy(&flags, base_addr+8, sizeof(flags));
  71. printf("%08X %08X %04X ( ", addr, count, flags);
  72. for (i = 0; i < ARRAY_SIZE(ldr_flags); ++i)
  73. if (flags & ldr_flags[i].flag)
  74. printf("%s ", ldr_flags[i].desc);
  75. pval = (flags & BFLAG_53X_PFLAG_MASK) >> BFLAG_53X_PFLAG_SHIFT;
  76. if (pval)
  77. printf("gpio%i ", pval);
  78. pval = (flags & BFLAG_53X_PPORT_MASK) >> BFLAG_53X_PPORT_SHIFT;
  79. if (pval)
  80. printf("port%c ", 'e' + pval);
  81. if (flags & BFLAG_53X_ZEROFILL)
  82. count = 0;
  83. if (flags & BFLAG_53X_FINAL)
  84. count = 0;
  85. else
  86. count += sizeof(addr) + sizeof(count) + sizeof(flags);
  87. #else
  88. const uint8_t *raw8 = base_addr;
  89. uint32_t bcode, addr, arg, sign, chk;
  90. int i;
  91. static const struct ldr_flag ldr_flags[] = {
  92. { BFLAG_SAFE, "safe" },
  93. { BFLAG_AUX, "aux" },
  94. { BFLAG_FILL, "fill" },
  95. { BFLAG_QUICKBOOT, "quickboot" },
  96. { BFLAG_CALLBACK, "callback" },
  97. { BFLAG_INIT, "init" },
  98. { BFLAG_IGNORE, "ignore" },
  99. { BFLAG_INDIRECT, "indirect" },
  100. { BFLAG_FIRST, "first" },
  101. { BFLAG_FINAL, "final" },
  102. };
  103. memcpy(&bcode, base_addr, sizeof(bcode));
  104. memcpy(&addr, base_addr+4, sizeof(addr));
  105. memcpy(&count, base_addr+8, sizeof(count));
  106. memcpy(&arg, base_addr+12, sizeof(arg));
  107. printf("%08X %08X %08X %08X ( ", bcode, addr, count, arg);
  108. if (addr % 4)
  109. printf("!!addralgn!! ");
  110. if (count % 4)
  111. printf("!!cntalgn!! ");
  112. sign = (bcode & BFLAG_HDRSIGN_MASK) >> BFLAG_HDRSIGN_SHIFT;
  113. if (sign != BFLAG_HDRSIGN_MAGIC)
  114. printf("!!hdrsign!! ");
  115. chk = 0;
  116. for (i = 0; i < 16; ++i)
  117. chk ^= raw8[i];
  118. if (chk)
  119. printf("!!hdrchk!! ");
  120. printf("dma:%i ", bcode & BFLAG_DMACODE_MASK);
  121. for (i = 0; i < ARRAY_SIZE(ldr_flags); ++i)
  122. if (bcode & ldr_flags[i].flag)
  123. printf("%s ", ldr_flags[i].desc);
  124. if (bcode & BFLAG_FILL)
  125. count = 0;
  126. if (bcode & BFLAG_FINAL)
  127. count = 0;
  128. else
  129. count += sizeof(bcode) + sizeof(addr) + sizeof(count) + sizeof(arg);
  130. #endif
  131. printf(")\n");
  132. return count;
  133. }
  134. static int do_ldrinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  135. {
  136. const void *addr;
  137. uint32_t skip;
  138. /* Get the address */
  139. if (argc < 2)
  140. addr = (void *)load_addr;
  141. else
  142. addr = (void *)simple_strtoul(argv[1], NULL, 16);
  143. /* Walk the LDR */
  144. addr += ldrinfo_header(addr);
  145. do {
  146. skip = ldrinfo_block(addr);
  147. addr += skip;
  148. } while (skip);
  149. return 0;
  150. }
  151. U_BOOT_CMD(
  152. ldrinfo, 2, 0, do_ldrinfo,
  153. "validate ldr image in memory",
  154. "[addr]\n"
  155. );