]>
Commit | Line | Data |
---|---|---|
1ba7fd25 MF |
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 | ||
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 | ||
19 | static 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 | ||
56 | struct ldr_flag { | |
57 | uint16_t flag; | |
58 | const char *desc; | |
59 | }; | |
60 | ||
61 | static 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 | ||
167 | static 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 | ||
188 | U_BOOT_CMD( | |
189 | ldrinfo, 2, 0, do_ldrinfo, | |
190 | "validate ldr image in memory", | |
191 | "[addr]\n" | |
192 | ); |