]> git.sur5r.net Git - u-boot/blob - common/fb_mmc.c
SPL: Add FIT data-position property support
[u-boot] / common / fb_mmc.c
1 /*
2  * Copyright 2014 Broadcom Corporation.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <config.h>
8 #include <common.h>
9 #include <blk.h>
10 #include <fastboot.h>
11 #include <fb_mmc.h>
12 #include <image-sparse.h>
13 #include <part.h>
14 #include <mmc.h>
15 #include <div64.h>
16 #include <linux/compat.h>
17 #include <android_image.h>
18
19 /*
20  * FIXME: Ensure we always set these names via Kconfig once xxx_PARTITION is
21  * migrated
22  */
23 #ifndef CONFIG_FASTBOOT_GPT_NAME
24 #define CONFIG_FASTBOOT_GPT_NAME "gpt"
25 #endif
26
27
28 #ifndef CONFIG_FASTBOOT_MBR_NAME
29 #define CONFIG_FASTBOOT_MBR_NAME "mbr"
30 #endif
31
32 #define BOOT_PARTITION_NAME "boot"
33
34 struct fb_mmc_sparse {
35         struct blk_desc *dev_desc;
36 };
37
38 static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc,
39                 const char *name, disk_partition_t *info)
40 {
41         int ret;
42
43         ret = part_get_info_by_name(dev_desc, name, info);
44         if (ret < 0) {
45                 /* strlen("fastboot_partition_alias_") + 32(part_name) + 1 */
46                 char env_alias_name[25 + 32 + 1];
47                 char *aliased_part_name;
48
49                 /* check for alias */
50                 strcpy(env_alias_name, "fastboot_partition_alias_");
51                 strncat(env_alias_name, name, 32);
52                 aliased_part_name = env_get(env_alias_name);
53                 if (aliased_part_name != NULL)
54                         ret = part_get_info_by_name(dev_desc,
55                                         aliased_part_name, info);
56         }
57         return ret;
58 }
59
60 static lbaint_t fb_mmc_sparse_write(struct sparse_storage *info,
61                 lbaint_t blk, lbaint_t blkcnt, const void *buffer)
62 {
63         struct fb_mmc_sparse *sparse = info->priv;
64         struct blk_desc *dev_desc = sparse->dev_desc;
65
66         return blk_dwrite(dev_desc, blk, blkcnt, buffer);
67 }
68
69 static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info,
70                 lbaint_t blk, lbaint_t blkcnt)
71 {
72         return blkcnt;
73 }
74
75 static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info,
76                 const char *part_name, void *buffer,
77                 unsigned int download_bytes)
78 {
79         lbaint_t blkcnt;
80         lbaint_t blks;
81
82         /* determine number of blocks to write */
83         blkcnt = ((download_bytes + (info->blksz - 1)) & ~(info->blksz - 1));
84         blkcnt = lldiv(blkcnt, info->blksz);
85
86         if (blkcnt > info->size) {
87                 pr_err("too large for partition: '%s'\n", part_name);
88                 fastboot_fail("too large for partition");
89                 return;
90         }
91
92         puts("Flashing Raw Image\n");
93
94         blks = blk_dwrite(dev_desc, info->start, blkcnt, buffer);
95         if (blks != blkcnt) {
96                 pr_err("failed writing to device %d\n", dev_desc->devnum);
97                 fastboot_fail("failed writing to device");
98                 return;
99         }
100
101         printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz,
102                part_name);
103         fastboot_okay("");
104 }
105
106 #ifdef CONFIG_ANDROID_BOOT_IMAGE
107 /**
108  * Read Android boot image header from boot partition.
109  *
110  * @param[in] dev_desc MMC device descriptor
111  * @param[in] info Boot partition info
112  * @param[out] hdr Where to store read boot image header
113  *
114  * @return Boot image header sectors count or 0 on error
115  */
116 static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
117                                        disk_partition_t *info,
118                                        struct andr_img_hdr *hdr)
119 {
120         ulong sector_size;              /* boot partition sector size */
121         lbaint_t hdr_sectors;           /* boot image header sectors count */
122         int res;
123
124         /* Calculate boot image sectors count */
125         sector_size = info->blksz;
126         hdr_sectors = DIV_ROUND_UP(sizeof(struct andr_img_hdr), sector_size);
127         if (hdr_sectors == 0) {
128                 pr_err("invalid number of boot sectors: 0");
129                 fastboot_fail("invalid number of boot sectors: 0");
130                 return 0;
131         }
132
133         /* Read the boot image header */
134         res = blk_dread(dev_desc, info->start, hdr_sectors, (void *)hdr);
135         if (res != hdr_sectors) {
136                 pr_err("cannot read header from boot partition");
137                 fastboot_fail("cannot read header from boot partition");
138                 return 0;
139         }
140
141         /* Check boot header magic string */
142         res = android_image_check_header(hdr);
143         if (res != 0) {
144                 pr_err("bad boot image magic");
145                 fastboot_fail("boot partition not initialized");
146                 return 0;
147         }
148
149         return hdr_sectors;
150 }
151
152 /**
153  * Write downloaded zImage to boot partition and repack it properly.
154  *
155  * @param dev_desc MMC device descriptor
156  * @param download_buffer Address to fastboot buffer with zImage in it
157  * @param download_bytes Size of fastboot buffer, in bytes
158  *
159  * @return 0 on success or -1 on error
160  */
161 static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
162                                 void *download_buffer,
163                                 unsigned int download_bytes)
164 {
165         uintptr_t hdr_addr;                     /* boot image header address */
166         struct andr_img_hdr *hdr;               /* boot image header */
167         lbaint_t hdr_sectors;                   /* boot image header sectors */
168         u8 *ramdisk_buffer;
169         u32 ramdisk_sector_start;
170         u32 ramdisk_sectors;
171         u32 kernel_sector_start;
172         u32 kernel_sectors;
173         u32 sectors_per_page;
174         disk_partition_t info;
175         int res;
176
177         puts("Flashing zImage\n");
178
179         /* Get boot partition info */
180         res = part_get_info_by_name(dev_desc, BOOT_PARTITION_NAME, &info);
181         if (res < 0) {
182                 pr_err("cannot find boot partition");
183                 fastboot_fail("cannot find boot partition");
184                 return -1;
185         }
186
187         /* Put boot image header in fastboot buffer after downloaded zImage */
188         hdr_addr = (uintptr_t)download_buffer + ALIGN(download_bytes, PAGE_SIZE);
189         hdr = (struct andr_img_hdr *)hdr_addr;
190
191         /* Read boot image header */
192         hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr);
193         if (hdr_sectors == 0) {
194                 pr_err("unable to read boot image header");
195                 fastboot_fail("unable to read boot image header");
196                 return -1;
197         }
198
199         /* Check if boot image has second stage in it (we don't support it) */
200         if (hdr->second_size > 0) {
201                 pr_err("moving second stage is not supported yet");
202                 fastboot_fail("moving second stage is not supported yet");
203                 return -1;
204         }
205
206         /* Extract ramdisk location */
207         sectors_per_page = hdr->page_size / info.blksz;
208         ramdisk_sector_start = info.start + sectors_per_page;
209         ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
210                                              sectors_per_page;
211         ramdisk_sectors = DIV_ROUND_UP(hdr->ramdisk_size, hdr->page_size) *
212                                        sectors_per_page;
213
214         /* Read ramdisk and put it in fastboot buffer after boot image header */
215         ramdisk_buffer = (u8 *)hdr + (hdr_sectors * info.blksz);
216         res = blk_dread(dev_desc, ramdisk_sector_start, ramdisk_sectors,
217                         ramdisk_buffer);
218         if (res != ramdisk_sectors) {
219                 pr_err("cannot read ramdisk from boot partition");
220                 fastboot_fail("cannot read ramdisk from boot partition");
221                 return -1;
222         }
223
224         /* Write new kernel size to boot image header */
225         hdr->kernel_size = download_bytes;
226         res = blk_dwrite(dev_desc, info.start, hdr_sectors, (void *)hdr);
227         if (res == 0) {
228                 pr_err("cannot writeback boot image header");
229                 fastboot_fail("cannot write back boot image header");
230                 return -1;
231         }
232
233         /* Write the new downloaded kernel */
234         kernel_sector_start = info.start + sectors_per_page;
235         kernel_sectors = DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
236                                       sectors_per_page;
237         res = blk_dwrite(dev_desc, kernel_sector_start, kernel_sectors,
238                          download_buffer);
239         if (res == 0) {
240                 pr_err("cannot write new kernel");
241                 fastboot_fail("cannot write new kernel");
242                 return -1;
243         }
244
245         /* Write the saved ramdisk back */
246         ramdisk_sector_start = info.start + sectors_per_page;
247         ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
248                                              sectors_per_page;
249         res = blk_dwrite(dev_desc, ramdisk_sector_start, ramdisk_sectors,
250                          ramdisk_buffer);
251         if (res == 0) {
252                 pr_err("cannot write back original ramdisk");
253                 fastboot_fail("cannot write back original ramdisk");
254                 return -1;
255         }
256
257         puts("........ zImage was updated in boot partition\n");
258         fastboot_okay("");
259         return 0;
260 }
261 #endif
262
263 void fb_mmc_flash_write(const char *cmd, void *download_buffer,
264                         unsigned int download_bytes)
265 {
266         struct blk_desc *dev_desc;
267         disk_partition_t info;
268
269         dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
270         if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
271                 pr_err("invalid mmc device\n");
272                 fastboot_fail("invalid mmc device");
273                 return;
274         }
275
276 #if CONFIG_IS_ENABLED(EFI_PARTITION)
277         if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
278                 printf("%s: updating MBR, Primary and Backup GPT(s)\n",
279                        __func__);
280                 if (is_valid_gpt_buf(dev_desc, download_buffer)) {
281                         printf("%s: invalid GPT - refusing to write to flash\n",
282                                __func__);
283                         fastboot_fail("invalid GPT partition");
284                         return;
285                 }
286                 if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
287                         printf("%s: writing GPT partitions failed\n", __func__);
288                         fastboot_fail("writing GPT partitions failed");
289                         return;
290                 }
291                 printf("........ success\n");
292                 fastboot_okay("");
293                 return;
294         }
295 #endif
296
297 #if CONFIG_IS_ENABLED(DOS_PARTITION)
298         if (strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME) == 0) {
299                 printf("%s: updating MBR\n", __func__);
300                 if (is_valid_dos_buf(download_buffer)) {
301                         printf("%s: invalid MBR - refusing to write to flash\n",
302                                __func__);
303                         fastboot_fail("invalid MBR partition");
304                         return;
305                 }
306                 if (write_mbr_partition(dev_desc, download_buffer)) {
307                         printf("%s: writing MBR partition failed\n", __func__);
308                         fastboot_fail("writing MBR partition failed");
309                         return;
310                 }
311                 printf("........ success\n");
312                 fastboot_okay("");
313                 return;
314         }
315 #endif
316
317 #ifdef CONFIG_ANDROID_BOOT_IMAGE
318         if (strncasecmp(cmd, "zimage", 6) == 0) {
319                 fb_mmc_update_zimage(dev_desc, download_buffer, download_bytes);
320                 return;
321         }
322 #endif
323
324         if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) {
325                 pr_err("cannot find partition: '%s'\n", cmd);
326                 fastboot_fail("cannot find partition");
327                 return;
328         }
329
330         if (is_sparse_image(download_buffer)) {
331                 struct fb_mmc_sparse sparse_priv;
332                 struct sparse_storage sparse;
333
334                 sparse_priv.dev_desc = dev_desc;
335
336                 sparse.blksz = info.blksz;
337                 sparse.start = info.start;
338                 sparse.size = info.size;
339                 sparse.write = fb_mmc_sparse_write;
340                 sparse.reserve = fb_mmc_sparse_reserve;
341
342                 printf("Flashing sparse image at offset " LBAFU "\n",
343                        sparse.start);
344
345                 sparse.priv = &sparse_priv;
346                 write_sparse_image(&sparse, cmd, download_buffer,
347                                    download_bytes);
348         } else {
349                 write_raw_image(dev_desc, &info, cmd, download_buffer,
350                                 download_bytes);
351         }
352 }
353
354 void fb_mmc_erase(const char *cmd)
355 {
356         int ret;
357         struct blk_desc *dev_desc;
358         disk_partition_t info;
359         lbaint_t blks, blks_start, blks_size, grp_size;
360         struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
361
362         if (mmc == NULL) {
363                 pr_err("invalid mmc device");
364                 fastboot_fail("invalid mmc device");
365                 return;
366         }
367
368         dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
369         if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
370                 pr_err("invalid mmc device");
371                 fastboot_fail("invalid mmc device");
372                 return;
373         }
374
375         ret = part_get_info_by_name_or_alias(dev_desc, cmd, &info);
376         if (ret < 0) {
377                 pr_err("cannot find partition: '%s'", cmd);
378                 fastboot_fail("cannot find partition");
379                 return;
380         }
381
382         /* Align blocks to erase group size to avoid erasing other partitions */
383         grp_size = mmc->erase_grp_size;
384         blks_start = (info.start + grp_size - 1) & ~(grp_size - 1);
385         if (info.size >= grp_size)
386                 blks_size = (info.size - (blks_start - info.start)) &
387                                 (~(grp_size - 1));
388         else
389                 blks_size = 0;
390
391         printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
392                blks_start, blks_start + blks_size);
393
394         blks = blk_derase(dev_desc, blks_start, blks_size);
395         if (blks != blks_size) {
396                 pr_err("failed erasing from device %d", dev_desc->devnum);
397                 fastboot_fail("failed erasing from device");
398                 return;
399         }
400
401         printf("........ erased " LBAFU " bytes from '%s'\n",
402                blks_size * info.blksz, cmd);
403         fastboot_okay("");
404 }