]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
39f520bb AA |
2 | /* |
3 | * Image manipulator for LPC32XX SoCs | |
4 | * | |
5 | * (C) Copyright 2015 DENX Software Engineering GmbH | |
6 | * Written-by: Albert ARIBAUD <[email protected]> | |
7 | * | |
8 | * Derived from omapimage.c: | |
9 | * | |
10 | * (C) Copyright 2010 | |
11 | * Linaro LTD, www.linaro.org | |
12 | * Author: John Rigby <[email protected]> | |
13 | * Based on TI's signGP.c | |
14 | * | |
15 | * (C) Copyright 2009 | |
16 | * Stefano Babic, DENX Software Engineering, [email protected]. | |
17 | * | |
18 | * (C) Copyright 2008 | |
19 | * Marvell Semiconductor <www.marvell.com> | |
20 | * Written-by: Prafulla Wadaskar <[email protected]> | |
39f520bb AA |
21 | */ |
22 | ||
23 | #include "imagetool.h" | |
24 | #include <compiler.h> | |
25 | #include <image.h> | |
26 | ||
27 | /* | |
28 | * NAND page 0 boot header | |
29 | */ | |
30 | ||
31 | struct nand_page_0_boot_header { | |
32 | uint32_t data[129]; | |
33 | uint32_t pad[383]; | |
34 | }; | |
35 | ||
36 | /* | |
37 | * Default ICC (interface configuration data [sic]) if none specified | |
38 | * in board config | |
39 | */ | |
40 | ||
41 | #ifndef LPC32XX_BOOT_ICR | |
42 | #define LPC32XX_BOOT_ICR 0x00000096 | |
43 | #endif | |
44 | ||
45 | /* | |
46 | * Default boot NAND page size if none specified in board config | |
47 | */ | |
48 | ||
49 | #ifndef LPC32XX_BOOT_NAND_PAGESIZE | |
50 | #define LPC32XX_BOOT_NAND_PAGESIZE 2048 | |
51 | #endif | |
52 | ||
53 | /* | |
54 | * Default boot NAND pages per sector if none specified in board config | |
55 | */ | |
56 | ||
57 | #ifndef LPC32XX_BOOT_NAND_PAGES_PER_SECTOR | |
58 | #define LPC32XX_BOOT_NAND_PAGES_PER_SECTOR 64 | |
59 | #endif | |
60 | ||
61 | /* | |
62 | * Maximum size for boot code is 56K unless defined in board config | |
63 | */ | |
64 | ||
65 | #ifndef LPC32XX_BOOT_CODESIZE | |
66 | #define LPC32XX_BOOT_CODESIZE (56*1024) | |
67 | #endif | |
68 | ||
69 | /* signature byte for a readable block */ | |
70 | ||
71 | #define LPC32XX_BOOT_BLOCK_OK 0xaa | |
72 | ||
73 | static struct nand_page_0_boot_header lpc32xximage_header; | |
74 | ||
75 | static int lpc32xximage_check_image_types(uint8_t type) | |
76 | { | |
77 | if (type == IH_TYPE_LPC32XXIMAGE) | |
78 | return EXIT_SUCCESS; | |
79 | return EXIT_FAILURE; | |
80 | } | |
81 | ||
82 | static int lpc32xximage_verify_header(unsigned char *ptr, int image_size, | |
83 | struct image_tool_params *params) | |
84 | { | |
85 | struct nand_page_0_boot_header *hdr = | |
86 | (struct nand_page_0_boot_header *)ptr; | |
87 | ||
88 | /* turn image size from bytes to NAND pages, page 0 included */ | |
89 | int image_size_in_pages = ((image_size - 1) | |
90 | / LPC32XX_BOOT_NAND_PAGESIZE); | |
91 | ||
92 | if (hdr->data[0] != (0xff & LPC32XX_BOOT_ICR)) | |
93 | return -1; | |
94 | if (hdr->data[1] != (0xff & ~LPC32XX_BOOT_ICR)) | |
95 | return -1; | |
96 | if (hdr->data[2] != (0xff & LPC32XX_BOOT_ICR)) | |
97 | return -1; | |
98 | if (hdr->data[3] != (0xff & ~LPC32XX_BOOT_ICR)) | |
99 | return -1; | |
100 | if (hdr->data[4] != (0xff & image_size_in_pages)) | |
101 | return -1; | |
102 | if (hdr->data[5] != (0xff & ~image_size_in_pages)) | |
103 | return -1; | |
104 | if (hdr->data[6] != (0xff & image_size_in_pages)) | |
105 | return -1; | |
106 | if (hdr->data[7] != (0xff & ~image_size_in_pages)) | |
107 | return -1; | |
108 | if (hdr->data[8] != (0xff & image_size_in_pages)) | |
109 | return -1; | |
110 | if (hdr->data[9] != (0xff & ~image_size_in_pages)) | |
111 | return -1; | |
112 | if (hdr->data[10] != (0xff & image_size_in_pages)) | |
113 | return -1; | |
114 | if (hdr->data[11] != (0xff & ~image_size_in_pages)) | |
115 | return -1; | |
116 | if (hdr->data[12] != LPC32XX_BOOT_BLOCK_OK) | |
117 | return -1; | |
118 | if (hdr->data[128] != LPC32XX_BOOT_BLOCK_OK) | |
119 | return -1; | |
120 | return 0; | |
121 | } | |
122 | ||
123 | static void print_hdr_byte(struct nand_page_0_boot_header *hdr, int ofs) | |
124 | { | |
125 | printf("header[%d] = %02x\n", ofs, hdr->data[ofs]); | |
126 | } | |
127 | ||
128 | static void lpc32xximage_print_header(const void *ptr) | |
129 | { | |
130 | struct nand_page_0_boot_header *hdr = | |
131 | (struct nand_page_0_boot_header *)ptr; | |
132 | int ofs; | |
133 | ||
134 | for (ofs = 0; ofs <= 12; ofs++) | |
135 | print_hdr_byte(hdr, ofs); | |
136 | print_hdr_byte(hdr, 128); | |
137 | } | |
138 | ||
139 | static void lpc32xximage_set_header(void *ptr, struct stat *sbuf, int ifd, | |
140 | struct image_tool_params *params) | |
141 | { | |
142 | struct nand_page_0_boot_header *hdr = | |
143 | (struct nand_page_0_boot_header *)ptr; | |
144 | ||
145 | /* turn image size from bytes to NAND pages, page 0 included */ | |
146 | int image_size_in_pages = ((sbuf->st_size | |
147 | + LPC32XX_BOOT_NAND_PAGESIZE - 1) | |
148 | / LPC32XX_BOOT_NAND_PAGESIZE); | |
149 | ||
150 | /* fill header -- default byte value is 0x00, not 0xFF */ | |
151 | memset((void *)hdr, 0, sizeof(*hdr)); | |
152 | hdr->data[0] = (hdr->data[2] = 0xff & LPC32XX_BOOT_ICR); | |
153 | hdr->data[1] = (hdr->data[3] = 0xff & ~LPC32XX_BOOT_ICR); | |
154 | hdr->data[4] = (hdr->data[6] = (hdr->data[8] | |
155 | = (hdr->data[10] = 0xff & image_size_in_pages))); | |
156 | hdr->data[5] = (hdr->data[7] = (hdr->data[9] | |
157 | = (hdr->data[11] = 0xff & ~image_size_in_pages))); | |
158 | hdr->data[12] = (hdr->data[128] = LPC32XX_BOOT_BLOCK_OK); | |
159 | } | |
160 | ||
161 | /* | |
162 | * lpc32xximage parameters | |
163 | */ | |
164 | U_BOOT_IMAGE_TYPE( | |
165 | lpc32xximage, | |
166 | "LPC32XX Boot Image", | |
167 | sizeof(lpc32xximage_header), | |
168 | (void *)&lpc32xximage_header, | |
169 | NULL, | |
170 | lpc32xximage_verify_header, | |
171 | lpc32xximage_print_header, | |
172 | lpc32xximage_set_header, | |
173 | NULL, | |
174 | lpc32xximage_check_image_types, | |
175 | NULL, | |
176 | NULL | |
177 | ); |