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