Commit 77fa164839048609e0379f4f2f276a5d6892a0eb
Exists in
v2017.01-smarct4x
and in
37 other branches
Merge branches 'topic/drivers/fpga-20141006', 'topic/drivers/mmc-20141006', 'top…
…ic/drivers/net-20141006', 'topic/tools/mkimage-20141006' and 'topic/arm/cache-20141006' into HEAD
Showing 14 changed files Side-by-side Diff
- arch/arm/include/asm/system.h
- arch/arm/lib/cache-cp15.c
- common/image.c
- drivers/mmc/dw_mmc.c
- drivers/net/designware.c
- drivers/net/phy/micrel.c
- include/configs/axs101.h
- include/configs/socfpga_cyclone5.h
- include/dwmmc.h
- include/image.h
- tools/Makefile
- tools/imagetool.c
- tools/imagetool.h
- tools/socfpgaimage.c
arch/arm/include/asm/system.h
arch/arm/lib/cache-cp15.c
... | ... | @@ -73,6 +73,8 @@ |
73 | 73 | i++) { |
74 | 74 | #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) |
75 | 75 | set_section_dcache(i, DCACHE_WRITETHROUGH); |
76 | +#elif defined(CONFIG_SYS_ARM_CACHE_WRITEALLOC) | |
77 | + set_section_dcache(i, DCACHE_WRITEALLOC); | |
76 | 78 | #else |
77 | 79 | set_section_dcache(i, DCACHE_WRITEBACK); |
78 | 80 | #endif |
common/image.c
... | ... | @@ -138,6 +138,7 @@ |
138 | 138 | { IH_TYPE_PBLIMAGE, "pblimage", "Freescale PBL Boot Image",}, |
139 | 139 | { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, |
140 | 140 | { IH_TYPE_SCRIPT, "script", "Script", }, |
141 | + { IH_TYPE_SOCFPGAIMAGE, "socfpgaimage", "Altera SOCFPGA preloader",}, | |
141 | 142 | { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, |
142 | 143 | { IH_TYPE_UBLIMAGE, "ublimage", "Davinci UBL image",}, |
143 | 144 | { IH_TYPE_MXSIMAGE, "mxsimage", "Freescale MXS Boot Image",}, |
drivers/mmc/dw_mmc.c
... | ... | @@ -119,7 +119,7 @@ |
119 | 119 | |
120 | 120 | while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) { |
121 | 121 | if (get_timer(start) > timeout) { |
122 | - printf("Timeout on data busy\n"); | |
122 | + printf("%s: Timeout on data busy\n", __func__); | |
123 | 123 | return TIMEOUT; |
124 | 124 | } |
125 | 125 | } |
126 | 126 | |
127 | 127 | |
128 | 128 | |
... | ... | @@ -177,14 +177,24 @@ |
177 | 177 | } |
178 | 178 | } |
179 | 179 | |
180 | - if (i == retry) | |
180 | + if (i == retry) { | |
181 | + printf("%s: Timeout.\n", __func__); | |
181 | 182 | return TIMEOUT; |
183 | + } | |
182 | 184 | |
183 | 185 | if (mask & DWMCI_INTMSK_RTO) { |
184 | - debug("Response Timeout..\n"); | |
186 | + /* | |
187 | + * Timeout here is not necessarily fatal. (e)MMC cards | |
188 | + * will splat here when they receive CMD55 as they do | |
189 | + * not support this command and that is exactly the way | |
190 | + * to tell them apart from SD cards. Thus, this output | |
191 | + * below shall be debug(). eMMC cards also do not favor | |
192 | + * CMD8, please keep that in mind. | |
193 | + */ | |
194 | + debug("%s: Response Timeout.\n", __func__); | |
185 | 195 | return TIMEOUT; |
186 | 196 | } else if (mask & DWMCI_INTMSK_RE) { |
187 | - debug("Response Error..\n"); | |
197 | + printf("%s: Response Error.\n", __func__); | |
188 | 198 | return -1; |
189 | 199 | } |
190 | 200 | |
... | ... | @@ -204,7 +214,7 @@ |
204 | 214 | do { |
205 | 215 | mask = dwmci_readl(host, DWMCI_RINTSTS); |
206 | 216 | if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) { |
207 | - debug("DATA ERROR!\n"); | |
217 | + printf("%s: DATA ERROR!\n", __func__); | |
208 | 218 | return -1; |
209 | 219 | } |
210 | 220 | } while (!(mask & DWMCI_INTMSK_DTO)); |
211 | 221 | |
212 | 222 | |
... | ... | @@ -232,16 +242,16 @@ |
232 | 242 | if ((freq == host->clock) || (freq == 0)) |
233 | 243 | return 0; |
234 | 244 | /* |
235 | - * If host->get_mmc_clk didn't define, | |
245 | + * If host->get_mmc_clk isn't defined, | |
236 | 246 | * then assume that host->bus_hz is source clock value. |
237 | - * host->bus_hz should be set from user. | |
247 | + * host->bus_hz should be set by user. | |
238 | 248 | */ |
239 | 249 | if (host->get_mmc_clk) |
240 | 250 | sclk = host->get_mmc_clk(host); |
241 | 251 | else if (host->bus_hz) |
242 | 252 | sclk = host->bus_hz; |
243 | 253 | else { |
244 | - printf("Didn't get source clock value..\n"); | |
254 | + printf("%s: Didn't get source clock value.\n", __func__); | |
245 | 255 | return -EINVAL; |
246 | 256 | } |
247 | 257 | |
... | ... | @@ -260,7 +270,7 @@ |
260 | 270 | do { |
261 | 271 | status = dwmci_readl(host, DWMCI_CMD); |
262 | 272 | if (timeout-- < 0) { |
263 | - printf("TIMEOUT error!!\n"); | |
273 | + printf("%s: Timeout!\n", __func__); | |
264 | 274 | return -ETIMEDOUT; |
265 | 275 | } |
266 | 276 | } while (status & DWMCI_CMD_START); |
... | ... | @@ -275,7 +285,7 @@ |
275 | 285 | do { |
276 | 286 | status = dwmci_readl(host, DWMCI_CMD); |
277 | 287 | if (timeout-- < 0) { |
278 | - printf("TIMEOUT error!!\n"); | |
288 | + printf("%s: Timeout!\n", __func__); | |
279 | 289 | return -ETIMEDOUT; |
280 | 290 | } |
281 | 291 | } while (status & DWMCI_CMD_START); |
... | ... | @@ -290,7 +300,7 @@ |
290 | 300 | struct dwmci_host *host = (struct dwmci_host *)mmc->priv; |
291 | 301 | u32 ctype, regs; |
292 | 302 | |
293 | - debug("Buswidth = %d, clock: %d\n",mmc->bus_width, mmc->clock); | |
303 | + debug("Buswidth = %d, clock: %d\n", mmc->bus_width, mmc->clock); | |
294 | 304 | |
295 | 305 | dwmci_setup_bus(host, mmc->clock); |
296 | 306 | switch (mmc->bus_width) { |
... | ... | @@ -329,7 +339,7 @@ |
329 | 339 | dwmci_writel(host, DWMCI_PWREN, 1); |
330 | 340 | |
331 | 341 | if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) { |
332 | - debug("%s[%d] Fail-reset!!\n",__func__,__LINE__); | |
342 | + printf("%s[%d] Fail-reset!!\n", __func__, __LINE__); | |
333 | 343 | return -1; |
334 | 344 | } |
335 | 345 |
drivers/net/designware.c
... | ... | @@ -279,19 +279,21 @@ |
279 | 279 | struct eth_dma_regs *dma_p = priv->dma_regs_p; |
280 | 280 | u32 desc_num = priv->tx_currdescnum; |
281 | 281 | struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num]; |
282 | - | |
282 | + uint32_t desc_start = (uint32_t)desc_p; | |
283 | + uint32_t desc_end = desc_start + | |
284 | + roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); | |
285 | + uint32_t data_start = (uint32_t)desc_p->dmamac_addr; | |
286 | + uint32_t data_end = data_start + | |
287 | + roundup(length, ARCH_DMA_MINALIGN); | |
283 | 288 | /* |
284 | 289 | * Strictly we only need to invalidate the "txrx_status" field |
285 | 290 | * for the following check, but on some platforms we cannot |
286 | - * invalidate only 4 bytes, so roundup to | |
287 | - * ARCH_DMA_MINALIGN. This is safe because the individual | |
288 | - * descriptors in the array are each aligned to | |
289 | - * ARCH_DMA_MINALIGN. | |
291 | + * invalidate only 4 bytes, so we flush the entire descriptor, | |
292 | + * which is 16 bytes in total. This is safe because the | |
293 | + * individual descriptors in the array are each aligned to | |
294 | + * ARCH_DMA_MINALIGN and padded appropriately. | |
290 | 295 | */ |
291 | - invalidate_dcache_range( | |
292 | - (unsigned long)desc_p, | |
293 | - (unsigned long)desc_p + | |
294 | - roundup(sizeof(desc_p->txrx_status), ARCH_DMA_MINALIGN)); | |
296 | + invalidate_dcache_range(desc_start, desc_end); | |
295 | 297 | |
296 | 298 | /* Check if the descriptor is owned by CPU */ |
297 | 299 | if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) { |
298 | 300 | |
... | ... | @@ -299,11 +301,10 @@ |
299 | 301 | return -1; |
300 | 302 | } |
301 | 303 | |
302 | - memcpy((void *)desc_p->dmamac_addr, packet, length); | |
304 | + memcpy(desc_p->dmamac_addr, packet, length); | |
303 | 305 | |
304 | 306 | /* Flush data to be sent */ |
305 | - flush_dcache_range((unsigned long)desc_p->dmamac_addr, | |
306 | - (unsigned long)desc_p->dmamac_addr + length); | |
307 | + flush_dcache_range(data_start, data_end); | |
307 | 308 | |
308 | 309 | #if defined(CONFIG_DW_ALTDESCRIPTOR) |
309 | 310 | desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; |
... | ... | @@ -321,8 +322,7 @@ |
321 | 322 | #endif |
322 | 323 | |
323 | 324 | /* Flush modified buffer descriptor */ |
324 | - flush_dcache_range((unsigned long)desc_p, | |
325 | - (unsigned long)desc_p + sizeof(struct dmamacdescr)); | |
325 | + flush_dcache_range(desc_start, desc_end); | |
326 | 326 | |
327 | 327 | /* Test the wrap-around condition. */ |
328 | 328 | if (++desc_num >= CONFIG_TX_DESCR_NUM) |
329 | 329 | |
... | ... | @@ -342,11 +342,14 @@ |
342 | 342 | u32 status, desc_num = priv->rx_currdescnum; |
343 | 343 | struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; |
344 | 344 | int length = 0; |
345 | + uint32_t desc_start = (uint32_t)desc_p; | |
346 | + uint32_t desc_end = desc_start + | |
347 | + roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); | |
348 | + uint32_t data_start = (uint32_t)desc_p->dmamac_addr; | |
349 | + uint32_t data_end; | |
345 | 350 | |
346 | 351 | /* Invalidate entire buffer descriptor */ |
347 | - invalidate_dcache_range((unsigned long)desc_p, | |
348 | - (unsigned long)desc_p + | |
349 | - sizeof(struct dmamacdescr)); | |
352 | + invalidate_dcache_range(desc_start, desc_end); | |
350 | 353 | |
351 | 354 | status = desc_p->txrx_status; |
352 | 355 | |
... | ... | @@ -357,9 +360,8 @@ |
357 | 360 | DESC_RXSTS_FRMLENSHFT; |
358 | 361 | |
359 | 362 | /* Invalidate received data */ |
360 | - invalidate_dcache_range((unsigned long)desc_p->dmamac_addr, | |
361 | - (unsigned long)desc_p->dmamac_addr + | |
362 | - roundup(length, ARCH_DMA_MINALIGN)); | |
363 | + data_end = data_start + roundup(length, ARCH_DMA_MINALIGN); | |
364 | + invalidate_dcache_range(data_start, data_end); | |
363 | 365 | |
364 | 366 | NetReceive(desc_p->dmamac_addr, length); |
365 | 367 | |
... | ... | @@ -370,9 +372,7 @@ |
370 | 372 | desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; |
371 | 373 | |
372 | 374 | /* Flush only status field - others weren't changed */ |
373 | - flush_dcache_range((unsigned long)&desc_p->txrx_status, | |
374 | - (unsigned long)&desc_p->txrx_status + | |
375 | - sizeof(desc_p->txrx_status)); | |
375 | + flush_dcache_range(desc_start, desc_end); | |
376 | 376 | |
377 | 377 | /* Test the wrap-around condition. */ |
378 | 378 | if (++desc_num >= CONFIG_RX_DESCR_NUM) |
drivers/net/phy/micrel.c
... | ... | @@ -25,8 +25,7 @@ |
25 | 25 | #ifndef CONFIG_PHY_MICREL_KSZ9021 |
26 | 26 | /* |
27 | 27 | * I can't believe Micrel used the exact same part number |
28 | - * for the KSZ9021 | |
29 | - * Shame Micrel, Shame!!!!! | |
28 | + * for the KSZ9021. Shame Micrel, Shame! | |
30 | 29 | */ |
31 | 30 | static struct phy_driver KS8721_driver = { |
32 | 31 | .name = "Micrel KS8721BL", |
... | ... | @@ -40,7 +39,7 @@ |
40 | 39 | #endif |
41 | 40 | |
42 | 41 | |
43 | -/** | |
42 | +/* | |
44 | 43 | * KSZ9021 - KSZ9031 common |
45 | 44 | */ |
46 | 45 | |
47 | 46 | |
... | ... | @@ -69,8 +68,8 @@ |
69 | 68 | phydev->speed = SPEED_10; |
70 | 69 | return 0; |
71 | 70 | } |
72 | -#ifdef CONFIG_PHY_MICREL_KSZ9021 | |
73 | 71 | |
72 | +#ifdef CONFIG_PHY_MICREL_KSZ9021 | |
74 | 73 | /* |
75 | 74 | * KSZ9021 |
76 | 75 | */ |
include/configs/axs101.h
include/configs/socfpga_cyclone5.h
include/dwmmc.h
include/image.h
... | ... | @@ -232,6 +232,7 @@ |
232 | 232 | #define IH_TYPE_MXSIMAGE 16 /* Freescale MXSBoot Image */ |
233 | 233 | #define IH_TYPE_GPIMAGE 17 /* TI Keystone GPHeader Image */ |
234 | 234 | #define IH_TYPE_ATMELIMAGE 18 /* ATMEL ROM bootable Image */ |
235 | +#define IH_TYPE_SOCFPGAIMAGE 19 /* Altera SOCFPGA Preloader */ | |
235 | 236 | |
236 | 237 | /* |
237 | 238 | * Compression Types |
tools/Makefile
tools/imagetool.c
tools/imagetool.h
... | ... | @@ -168,6 +168,7 @@ |
168 | 168 | void init_fit_image_type(void); |
169 | 169 | void init_ubl_image_type(void); |
170 | 170 | void init_omap_image_type(void); |
171 | +void init_socfpga_image_type(void); | |
171 | 172 | void init_gpimage_type(void); |
172 | 173 | |
173 | 174 | void pbl_load_uboot(int fd, struct image_tool_params *mparams); |
tools/socfpgaimage.c
1 | +/* | |
2 | + * Copyright (C) 2014 Charles Manning <cdhmanning@gmail.com> | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + * | |
6 | + * Reference doc http://www.altera.com.cn/literature/hb/cyclone-v/cv_5400A.pdf | |
7 | + * Note this doc is not entirely accurate. Of particular interest to us is the | |
8 | + * "header" length field being in U32s and not bytes. | |
9 | + * | |
10 | + * "Header" is a structure of the following format. | |
11 | + * this is positioned at 0x40. | |
12 | + * | |
13 | + * Endian is LSB. | |
14 | + * | |
15 | + * Offset Length Usage | |
16 | + * ----------------------- | |
17 | + * 0x40 4 Validation word 0x31305341 | |
18 | + * 0x44 1 Version (whatever, zero is fine) | |
19 | + * 0x45 1 Flags (unused, zero is fine) | |
20 | + * 0x46 2 Length (in units of u32, including the end checksum). | |
21 | + * 0x48 2 Zero | |
22 | + * 0x4A 2 Checksum over the header. NB Not CRC32 | |
23 | + * | |
24 | + * At the end of the code we have a 32-bit CRC checksum over whole binary | |
25 | + * excluding the CRC. | |
26 | + * | |
27 | + * Note that the CRC used here is **not** the zlib/Adler crc32. It is the | |
28 | + * CRC-32 used in bzip2, ethernet and elsewhere. | |
29 | + * | |
30 | + * The image is padded out to 64k, because that is what is | |
31 | + * typically used to write the image to the boot medium. | |
32 | + */ | |
33 | + | |
34 | +#include "pbl_crc32.h" | |
35 | +#include "imagetool.h" | |
36 | +#include <image.h> | |
37 | + | |
38 | +#define HEADER_OFFSET 0x40 | |
39 | +#define VALIDATION_WORD 0x31305341 | |
40 | +#define PADDED_SIZE 0x10000 | |
41 | + | |
42 | +/* To allow for adding CRC, the max input size is a bit smaller. */ | |
43 | +#define MAX_INPUT_SIZE (PADDED_SIZE - sizeof(uint32_t)) | |
44 | + | |
45 | +static uint8_t buffer[PADDED_SIZE]; | |
46 | + | |
47 | +static struct socfpga_header { | |
48 | + uint32_t validation; | |
49 | + uint8_t version; | |
50 | + uint8_t flags; | |
51 | + uint16_t length_u32; | |
52 | + uint16_t zero; | |
53 | + uint16_t checksum; | |
54 | +} header; | |
55 | + | |
56 | +/* | |
57 | + * The header checksum is just a very simple checksum over | |
58 | + * the header area. | |
59 | + * There is still a crc32 over the whole lot. | |
60 | + */ | |
61 | +static uint16_t hdr_checksum(struct socfpga_header *header) | |
62 | +{ | |
63 | + int len = sizeof(*header) - sizeof(header->checksum); | |
64 | + uint8_t *buf = (uint8_t *)header; | |
65 | + uint16_t ret = 0; | |
66 | + | |
67 | + while (--len) | |
68 | + ret += *buf++; | |
69 | + | |
70 | + return ret; | |
71 | +} | |
72 | + | |
73 | + | |
74 | +static void build_header(uint8_t *buf, uint8_t version, uint8_t flags, | |
75 | + uint16_t length_bytes) | |
76 | +{ | |
77 | + header.validation = htole32(VALIDATION_WORD); | |
78 | + header.version = version; | |
79 | + header.flags = flags; | |
80 | + header.length_u32 = htole16(length_bytes/4); | |
81 | + header.zero = 0; | |
82 | + header.checksum = htole16(hdr_checksum(&header)); | |
83 | + | |
84 | + memcpy(buf, &header, sizeof(header)); | |
85 | +} | |
86 | + | |
87 | +/* | |
88 | + * Perform a rudimentary verification of header and return | |
89 | + * size of image. | |
90 | + */ | |
91 | +static int verify_header(const uint8_t *buf) | |
92 | +{ | |
93 | + memcpy(&header, buf, sizeof(header)); | |
94 | + | |
95 | + if (le32toh(header.validation) != VALIDATION_WORD) | |
96 | + return -1; | |
97 | + if (le16toh(header.checksum) != hdr_checksum(&header)) | |
98 | + return -1; | |
99 | + | |
100 | + return le16toh(header.length_u32) * 4; | |
101 | +} | |
102 | + | |
103 | +/* Sign the buffer and return the signed buffer size */ | |
104 | +static int sign_buffer(uint8_t *buf, | |
105 | + uint8_t version, uint8_t flags, | |
106 | + int len, int pad_64k) | |
107 | +{ | |
108 | + uint32_t calc_crc; | |
109 | + | |
110 | + /* Align the length up */ | |
111 | + len = (len + 3) & (~3); | |
112 | + | |
113 | + /* Build header, adding 4 bytes to length to hold the CRC32. */ | |
114 | + build_header(buf + HEADER_OFFSET, version, flags, len + 4); | |
115 | + | |
116 | + /* Calculate and apply the CRC */ | |
117 | + calc_crc = ~pbl_crc32(0, (char *)buf, len); | |
118 | + | |
119 | + *((uint32_t *)(buf + len)) = htole32(calc_crc); | |
120 | + | |
121 | + if (!pad_64k) | |
122 | + return len + 4; | |
123 | + | |
124 | + return PADDED_SIZE; | |
125 | +} | |
126 | + | |
127 | +/* Verify that the buffer looks sane */ | |
128 | +static int verify_buffer(const uint8_t *buf) | |
129 | +{ | |
130 | + int len; /* Including 32bit CRC */ | |
131 | + uint32_t calc_crc; | |
132 | + uint32_t buf_crc; | |
133 | + | |
134 | + len = verify_header(buf + HEADER_OFFSET); | |
135 | + if (len < 0) { | |
136 | + fprintf(stderr, "Invalid header\n"); | |
137 | + return -1; | |
138 | + } | |
139 | + | |
140 | + if (len < HEADER_OFFSET || len > PADDED_SIZE) { | |
141 | + fprintf(stderr, "Invalid header length (%i)\n", len); | |
142 | + return -1; | |
143 | + } | |
144 | + | |
145 | + /* | |
146 | + * Adjust length to the base of the CRC. | |
147 | + * Check the CRC. | |
148 | + */ | |
149 | + len -= 4; | |
150 | + | |
151 | + calc_crc = ~pbl_crc32(0, (const char *)buf, len); | |
152 | + | |
153 | + buf_crc = le32toh(*((uint32_t *)(buf + len))); | |
154 | + | |
155 | + if (buf_crc != calc_crc) { | |
156 | + fprintf(stderr, "CRC32 does not match (%08x != %08x)\n", | |
157 | + buf_crc, calc_crc); | |
158 | + return -1; | |
159 | + } | |
160 | + | |
161 | + return 0; | |
162 | +} | |
163 | + | |
164 | +/* mkimage glue functions */ | |
165 | +static int socfpgaimage_verify_header(unsigned char *ptr, int image_size, | |
166 | + struct image_tool_params *params) | |
167 | +{ | |
168 | + if (image_size != PADDED_SIZE) | |
169 | + return -1; | |
170 | + | |
171 | + return verify_buffer(ptr); | |
172 | +} | |
173 | + | |
174 | +static void socfpgaimage_print_header(const void *ptr) | |
175 | +{ | |
176 | + if (verify_buffer(ptr) == 0) | |
177 | + printf("Looks like a sane SOCFPGA preloader\n"); | |
178 | + else | |
179 | + printf("Not a sane SOCFPGA preloader\n"); | |
180 | +} | |
181 | + | |
182 | +static int socfpgaimage_check_params(struct image_tool_params *params) | |
183 | +{ | |
184 | + /* Not sure if we should be accepting fflags */ | |
185 | + return (params->dflag && (params->fflag || params->lflag)) || | |
186 | + (params->fflag && (params->dflag || params->lflag)) || | |
187 | + (params->lflag && (params->dflag || params->fflag)); | |
188 | +} | |
189 | + | |
190 | +static int socfpgaimage_check_image_types(uint8_t type) | |
191 | +{ | |
192 | + if (type == IH_TYPE_SOCFPGAIMAGE) | |
193 | + return EXIT_SUCCESS; | |
194 | + return EXIT_FAILURE; | |
195 | +} | |
196 | + | |
197 | +/* | |
198 | + * To work in with the mkimage framework, we do some ugly stuff... | |
199 | + * | |
200 | + * First, socfpgaimage_vrec_header() is called. | |
201 | + * We prepend a fake header big enough to make the file PADDED_SIZE. | |
202 | + * This gives us enough space to do what we want later. | |
203 | + * | |
204 | + * Next, socfpgaimage_set_header() is called. | |
205 | + * We fix up the buffer by moving the image to the start of the buffer. | |
206 | + * We now have some room to do what we need (add CRC and padding). | |
207 | + */ | |
208 | + | |
209 | +static int data_size; | |
210 | +#define FAKE_HEADER_SIZE (PADDED_SIZE - data_size) | |
211 | + | |
212 | +static int socfpgaimage_vrec_header(struct image_tool_params *params, | |
213 | + struct image_type_params *tparams) | |
214 | +{ | |
215 | + struct stat sbuf; | |
216 | + | |
217 | + if (params->datafile && | |
218 | + stat(params->datafile, &sbuf) == 0 && | |
219 | + sbuf.st_size <= MAX_INPUT_SIZE) { | |
220 | + data_size = sbuf.st_size; | |
221 | + tparams->header_size = FAKE_HEADER_SIZE; | |
222 | + } | |
223 | + return 0; | |
224 | +} | |
225 | + | |
226 | +static void socfpgaimage_set_header(void *ptr, struct stat *sbuf, int ifd, | |
227 | + struct image_tool_params *params) | |
228 | +{ | |
229 | + uint8_t *buf = (uint8_t *)ptr; | |
230 | + | |
231 | + /* | |
232 | + * This function is called after vrec_header() has been called. | |
233 | + * At this stage we have the FAKE_HEADER_SIZE dummy bytes followed by | |
234 | + * data_size image bytes. Total = PADDED_SIZE. | |
235 | + * We need to fix the buffer by moving the image bytes back to | |
236 | + * the beginning of the buffer, then actually do the signing stuff... | |
237 | + */ | |
238 | + memmove(buf, buf + FAKE_HEADER_SIZE, data_size); | |
239 | + memset(buf + data_size, 0, FAKE_HEADER_SIZE); | |
240 | + | |
241 | + sign_buffer(buf, 0, 0, data_size, 0); | |
242 | +} | |
243 | + | |
244 | +static struct image_type_params socfpgaimage_params = { | |
245 | + .name = "Altera SOCFPGA preloader support", | |
246 | + .vrec_header = socfpgaimage_vrec_header, | |
247 | + .header_size = 0, /* This will be modified by vrec_header() */ | |
248 | + .hdr = (void *)buffer, | |
249 | + .check_image_type = socfpgaimage_check_image_types, | |
250 | + .verify_header = socfpgaimage_verify_header, | |
251 | + .print_header = socfpgaimage_print_header, | |
252 | + .set_header = socfpgaimage_set_header, | |
253 | + .check_params = socfpgaimage_check_params, | |
254 | +}; | |
255 | + | |
256 | +void init_socfpga_image_type(void) | |
257 | +{ | |
258 | + register_image_type(&socfpgaimage_params); | |
259 | +} |