blob: 94fab4e5e0e89d5ee61c9c6e66153cb3434b1401 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Steve Raec0aebb32014-08-26 11:47:27 -07002/*
3 * Copyright 2014 Broadcom Corporation.
Steve Raec0aebb32014-08-26 11:47:27 -07004 */
5
Steve Rae0ff7e582014-12-12 15:51:54 -08006#include <config.h>
Steve Raec0aebb32014-08-26 11:47:27 -07007#include <common.h>
Simon Glass2a981dc2016-02-29 15:25:52 -07008#include <blk.h>
Simon Glass7b51b572019-08-01 09:46:52 -06009#include <env.h>
Maxime Ripard3c8f98f2015-10-15 14:34:13 +020010#include <fastboot.h>
Alex Kiernanf73a7df2018-05-29 15:30:53 +000011#include <fastboot-internal.h>
Steve Raec0aebb32014-08-26 11:47:27 -070012#include <fb_mmc.h>
Simon Glassb79fdc72020-05-10 11:39:54 -060013#include <flash.h>
Maxime Ripard3d4ef382015-10-15 14:34:19 +020014#include <image-sparse.h>
Simon Glass4d72caa2020-05-10 11:40:01 -060015#include <image.h>
Steve Raec0aebb32014-08-26 11:47:27 -070016#include <part.h>
Dileep Katta89792382015-02-17 18:48:23 +053017#include <mmc.h>
Siarhei Siamashka5e0efc12015-10-28 06:24:16 +020018#include <div64.h>
Sam Protsenkoefeccfe2017-05-18 15:04:59 +030019#include <linux/compat.h>
20#include <android_image.h>
Steve Raec0aebb32014-08-26 11:47:27 -070021
Alex Kiernanf73a7df2018-05-29 15:30:53 +000022#define FASTBOOT_MAX_BLK_WRITE 16384
23
Sam Protsenkoefeccfe2017-05-18 15:04:59 +030024#define BOOT_PARTITION_NAME "boot"
25
Maxime Riparda5d1e042015-10-15 14:34:14 +020026struct fb_mmc_sparse {
Simon Glass4101f682016-02-29 15:25:34 -070027 struct blk_desc *dev_desc;
Maxime Riparda5d1e042015-10-15 14:34:14 +020028};
29
Petr Kulhavyb6dd69a2016-09-09 10:27:16 +020030static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc,
Simon Glass05289792020-05-10 11:39:57 -060031 const char *name, struct disk_partition *info)
Michael Scott8a418022015-03-11 10:02:31 -070032{
33 int ret;
34
Petr Kulhavy87b85302016-09-09 10:27:15 +020035 ret = part_get_info_by_name(dev_desc, name, info);
Alex Deymo88b63292017-04-02 01:49:50 -070036 if (ret < 0) {
Alex Kiernanb762aa12019-04-09 05:30:05 +000037 /* strlen("fastboot_partition_alias_") + PART_NAME_LEN + 1 */
38 char env_alias_name[25 + PART_NAME_LEN + 1];
Michael Scott8a418022015-03-11 10:02:31 -070039 char *aliased_part_name;
40
41 /* check for alias */
42 strcpy(env_alias_name, "fastboot_partition_alias_");
Alex Kiernanb762aa12019-04-09 05:30:05 +000043 strncat(env_alias_name, name, PART_NAME_LEN);
Simon Glass00caae62017-08-03 12:22:12 -060044 aliased_part_name = env_get(env_alias_name);
Michael Scott8a418022015-03-11 10:02:31 -070045 if (aliased_part_name != NULL)
Petr Kulhavy87b85302016-09-09 10:27:15 +020046 ret = part_get_info_by_name(dev_desc,
Michael Scott8a418022015-03-11 10:02:31 -070047 aliased_part_name, info);
48 }
49 return ret;
50}
51
Alex Kiernanf73a7df2018-05-29 15:30:53 +000052/**
53 * fb_mmc_blk_write() - Write/erase MMC in chunks of FASTBOOT_MAX_BLK_WRITE
54 *
55 * @block_dev: Pointer to block device
56 * @start: First block to write/erase
57 * @blkcnt: Count of blocks
58 * @buffer: Pointer to data buffer for write or NULL for erase
59 */
60static lbaint_t fb_mmc_blk_write(struct blk_desc *block_dev, lbaint_t start,
61 lbaint_t blkcnt, const void *buffer)
62{
63 lbaint_t blk = start;
64 lbaint_t blks_written;
65 lbaint_t cur_blkcnt;
66 lbaint_t blks = 0;
67 int i;
68
69 for (i = 0; i < blkcnt; i += FASTBOOT_MAX_BLK_WRITE) {
70 cur_blkcnt = min((int)blkcnt - i, FASTBOOT_MAX_BLK_WRITE);
71 if (buffer) {
72 if (fastboot_progress_callback)
73 fastboot_progress_callback("writing");
74 blks_written = blk_dwrite(block_dev, blk, cur_blkcnt,
75 buffer + (i * block_dev->blksz));
76 } else {
77 if (fastboot_progress_callback)
78 fastboot_progress_callback("erasing");
79 blks_written = blk_derase(block_dev, blk, cur_blkcnt);
80 }
81 blk += blks_written;
82 blks += blks_written;
83 }
84 return blks;
85}
86
Steve Raecc0f08cd2016-06-07 11:19:36 -070087static lbaint_t fb_mmc_sparse_write(struct sparse_storage *info,
88 lbaint_t blk, lbaint_t blkcnt, const void *buffer)
Maxime Riparda5d1e042015-10-15 14:34:14 +020089{
Steve Raecc0f08cd2016-06-07 11:19:36 -070090 struct fb_mmc_sparse *sparse = info->priv;
Simon Glass4101f682016-02-29 15:25:34 -070091 struct blk_desc *dev_desc = sparse->dev_desc;
Maxime Riparda5d1e042015-10-15 14:34:14 +020092
Alex Kiernanf73a7df2018-05-29 15:30:53 +000093 return fb_mmc_blk_write(dev_desc, blk, blkcnt, buffer);
Maxime Riparda5d1e042015-10-15 14:34:14 +020094}
95
Steve Rae2c724042016-06-07 11:19:38 -070096static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info,
97 lbaint_t blk, lbaint_t blkcnt)
98{
99 return blkcnt;
100}
101
Simon Glass05289792020-05-10 11:39:57 -0600102static void write_raw_image(struct blk_desc *dev_desc,
103 struct disk_partition *info, const char *part_name,
104 void *buffer, u32 download_bytes, char *response)
Steve Raec0aebb32014-08-26 11:47:27 -0700105{
106 lbaint_t blkcnt;
107 lbaint_t blks;
108
109 /* determine number of blocks to write */
110 blkcnt = ((download_bytes + (info->blksz - 1)) & ~(info->blksz - 1));
Siarhei Siamashka5e0efc12015-10-28 06:24:16 +0200111 blkcnt = lldiv(blkcnt, info->blksz);
Steve Raec0aebb32014-08-26 11:47:27 -0700112
113 if (blkcnt > info->size) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900114 pr_err("too large for partition: '%s'\n", part_name);
Alex Kiernanc4ded032018-05-29 15:30:40 +0000115 fastboot_fail("too large for partition", response);
Steve Raec0aebb32014-08-26 11:47:27 -0700116 return;
117 }
118
119 puts("Flashing Raw Image\n");
120
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000121 blks = fb_mmc_blk_write(dev_desc, info->start, blkcnt, buffer);
122
Steve Raec0aebb32014-08-26 11:47:27 -0700123 if (blks != blkcnt) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900124 pr_err("failed writing to device %d\n", dev_desc->devnum);
Alex Kiernanc4ded032018-05-29 15:30:40 +0000125 fastboot_fail("failed writing to device", response);
Steve Raec0aebb32014-08-26 11:47:27 -0700126 return;
127 }
128
129 printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz,
130 part_name);
Alex Kiernanc4ded032018-05-29 15:30:40 +0000131 fastboot_okay(NULL, response);
Steve Raec0aebb32014-08-26 11:47:27 -0700132}
133
mingming lee1fdbad02020-01-16 16:11:42 +0800134#ifdef CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT
135static int fb_mmc_erase_mmc_hwpart(struct blk_desc *dev_desc)
136{
137 lbaint_t blks;
138
139 debug("Start Erasing mmc hwpart[%u]...\n", dev_desc->hwpart);
140
141 blks = fb_mmc_blk_write(dev_desc, 0, dev_desc->lba, NULL);
142
143 if (blks != dev_desc->lba) {
144 pr_err("Failed to erase mmc hwpart[%u]\n", dev_desc->hwpart);
145 return 1;
146 }
147
148 printf("........ erased %lu bytes from mmc hwpart[%u]\n",
149 dev_desc->lba * dev_desc->blksz, dev_desc->hwpart);
150
151 return 0;
152}
153
154static void fb_mmc_boot1_ops(struct blk_desc *dev_desc, void *buffer,
155 u32 buff_sz, char *response)
156{
157 lbaint_t blkcnt;
158 lbaint_t blks;
159 unsigned long blksz;
160
161 // To operate on EMMC_BOOT1 (mmc0boot0), we first change the hwpart
162 if (blk_dselect_hwpart(dev_desc, 1)) {
163 pr_err("Failed to select hwpart\n");
164 fastboot_fail("Failed to select hwpart", response);
165 return;
166 }
167
168 if (buffer) { /* flash */
169
170 /* determine number of blocks to write */
171 blksz = dev_desc->blksz;
172 blkcnt = ((buff_sz + (blksz - 1)) & ~(blksz - 1));
173 blkcnt = lldiv(blkcnt, blksz);
174
175 if (blkcnt > dev_desc->lba) {
176 pr_err("Image size too large\n");
177 fastboot_fail("Image size too large", response);
178 return;
179 }
180
181 debug("Start Flashing Image to EMMC_BOOT1...\n");
182
183 blks = fb_mmc_blk_write(dev_desc, 0, blkcnt, buffer);
184
185 if (blks != blkcnt) {
186 pr_err("Failed to write EMMC_BOOT1\n");
187 fastboot_fail("Failed to write EMMC_BOOT1", response);
188 return;
189 }
190
191 printf("........ wrote %lu bytes to EMMC_BOOT1\n",
192 blkcnt * blksz);
193 } else { /* erase */
194 if (fb_mmc_erase_mmc_hwpart(dev_desc)) {
195 fastboot_fail("Failed to erase EMMC_BOOT1", response);
196 return;
197 }
198 }
199
200 fastboot_okay(NULL, response);
201}
202#endif
203
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300204#ifdef CONFIG_ANDROID_BOOT_IMAGE
205/**
206 * Read Android boot image header from boot partition.
207 *
208 * @param[in] dev_desc MMC device descriptor
209 * @param[in] info Boot partition info
210 * @param[out] hdr Where to store read boot image header
211 *
212 * @return Boot image header sectors count or 0 on error
213 */
214static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
Simon Glass05289792020-05-10 11:39:57 -0600215 struct disk_partition *info,
Alex Kiernanc4ded032018-05-29 15:30:40 +0000216 struct andr_img_hdr *hdr,
217 char *response)
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300218{
219 ulong sector_size; /* boot partition sector size */
220 lbaint_t hdr_sectors; /* boot image header sectors count */
221 int res;
222
223 /* Calculate boot image sectors count */
224 sector_size = info->blksz;
225 hdr_sectors = DIV_ROUND_UP(sizeof(struct andr_img_hdr), sector_size);
226 if (hdr_sectors == 0) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000227 pr_err("invalid number of boot sectors: 0\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000228 fastboot_fail("invalid number of boot sectors: 0", response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300229 return 0;
230 }
231
232 /* Read the boot image header */
233 res = blk_dread(dev_desc, info->start, hdr_sectors, (void *)hdr);
Tom Rini6bafa5a2017-08-14 21:00:44 -0400234 if (res != hdr_sectors) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000235 pr_err("cannot read header from boot partition\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000236 fastboot_fail("cannot read header from boot partition",
237 response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300238 return 0;
239 }
240
241 /* Check boot header magic string */
242 res = android_image_check_header(hdr);
243 if (res != 0) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000244 pr_err("bad boot image magic\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000245 fastboot_fail("boot partition not initialized", response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300246 return 0;
247 }
248
249 return hdr_sectors;
250}
251
252/**
253 * Write downloaded zImage to boot partition and repack it properly.
254 *
255 * @param dev_desc MMC device descriptor
256 * @param download_buffer Address to fastboot buffer with zImage in it
257 * @param download_bytes Size of fastboot buffer, in bytes
258 *
259 * @return 0 on success or -1 on error
260 */
261static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
262 void *download_buffer,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000263 u32 download_bytes,
Alex Kiernanc4ded032018-05-29 15:30:40 +0000264 char *response)
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300265{
Tom Rini2341c802017-06-10 09:15:37 -0400266 uintptr_t hdr_addr; /* boot image header address */
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300267 struct andr_img_hdr *hdr; /* boot image header */
268 lbaint_t hdr_sectors; /* boot image header sectors */
269 u8 *ramdisk_buffer;
270 u32 ramdisk_sector_start;
271 u32 ramdisk_sectors;
272 u32 kernel_sector_start;
273 u32 kernel_sectors;
274 u32 sectors_per_page;
Simon Glass05289792020-05-10 11:39:57 -0600275 struct disk_partition info;
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300276 int res;
277
278 puts("Flashing zImage\n");
279
280 /* Get boot partition info */
281 res = part_get_info_by_name(dev_desc, BOOT_PARTITION_NAME, &info);
282 if (res < 0) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000283 pr_err("cannot find boot partition\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000284 fastboot_fail("cannot find boot partition", response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300285 return -1;
286 }
287
288 /* Put boot image header in fastboot buffer after downloaded zImage */
Tom Rini2341c802017-06-10 09:15:37 -0400289 hdr_addr = (uintptr_t)download_buffer + ALIGN(download_bytes, PAGE_SIZE);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300290 hdr = (struct andr_img_hdr *)hdr_addr;
291
292 /* Read boot image header */
Alex Kiernanc4ded032018-05-29 15:30:40 +0000293 hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr, response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300294 if (hdr_sectors == 0) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000295 pr_err("unable to read boot image header\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000296 fastboot_fail("unable to read boot image header", response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300297 return -1;
298 }
299
300 /* Check if boot image has second stage in it (we don't support it) */
301 if (hdr->second_size > 0) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000302 pr_err("moving second stage is not supported yet\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000303 fastboot_fail("moving second stage is not supported yet",
304 response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300305 return -1;
306 }
307
308 /* Extract ramdisk location */
309 sectors_per_page = hdr->page_size / info.blksz;
310 ramdisk_sector_start = info.start + sectors_per_page;
311 ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
312 sectors_per_page;
313 ramdisk_sectors = DIV_ROUND_UP(hdr->ramdisk_size, hdr->page_size) *
314 sectors_per_page;
315
316 /* Read ramdisk and put it in fastboot buffer after boot image header */
317 ramdisk_buffer = (u8 *)hdr + (hdr_sectors * info.blksz);
318 res = blk_dread(dev_desc, ramdisk_sector_start, ramdisk_sectors,
319 ramdisk_buffer);
Tom Rini6bafa5a2017-08-14 21:00:44 -0400320 if (res != ramdisk_sectors) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000321 pr_err("cannot read ramdisk from boot partition\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000322 fastboot_fail("cannot read ramdisk from boot partition",
323 response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300324 return -1;
325 }
326
327 /* Write new kernel size to boot image header */
328 hdr->kernel_size = download_bytes;
329 res = blk_dwrite(dev_desc, info.start, hdr_sectors, (void *)hdr);
330 if (res == 0) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000331 pr_err("cannot writeback boot image header\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000332 fastboot_fail("cannot write back boot image header", response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300333 return -1;
334 }
335
336 /* Write the new downloaded kernel */
337 kernel_sector_start = info.start + sectors_per_page;
338 kernel_sectors = DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
339 sectors_per_page;
340 res = blk_dwrite(dev_desc, kernel_sector_start, kernel_sectors,
341 download_buffer);
342 if (res == 0) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000343 pr_err("cannot write new kernel\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000344 fastboot_fail("cannot write new kernel", response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300345 return -1;
346 }
347
348 /* Write the saved ramdisk back */
349 ramdisk_sector_start = info.start + sectors_per_page;
350 ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
351 sectors_per_page;
352 res = blk_dwrite(dev_desc, ramdisk_sector_start, ramdisk_sectors,
353 ramdisk_buffer);
354 if (res == 0) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000355 pr_err("cannot write back original ramdisk\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000356 fastboot_fail("cannot write back original ramdisk", response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300357 return -1;
358 }
359
360 puts("........ zImage was updated in boot partition\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000361 fastboot_okay(NULL, response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300362 return 0;
363}
364#endif
365
Alex Kiernand1a119d2018-05-29 15:30:48 +0000366/**
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000367 * fastboot_mmc_get_part_info() - Lookup eMMC partion by name
368 *
369 * @part_name: Named partition to lookup
370 * @dev_desc: Pointer to returned blk_desc pointer
Simon Glass05289792020-05-10 11:39:57 -0600371 * @part_info: Pointer to returned struct disk_partition
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000372 * @response: Pointer to fastboot response buffer
373 */
Sam Protsenkocacb03e2019-06-13 21:11:07 +0300374int fastboot_mmc_get_part_info(const char *part_name,
375 struct blk_desc **dev_desc,
Simon Glass05289792020-05-10 11:39:57 -0600376 struct disk_partition *part_info, char *response)
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000377{
378 int r;
379
380 *dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
381 if (!*dev_desc) {
382 fastboot_fail("block device not found", response);
383 return -ENOENT;
384 }
Eugeniu Roscaa40297d2019-03-28 14:31:33 +0100385 if (!part_name || !strcmp(part_name, "")) {
386 fastboot_fail("partition not given", response);
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000387 return -ENOENT;
388 }
389
390 r = part_get_info_by_name_or_alias(*dev_desc, part_name, part_info);
391 if (r < 0) {
392 fastboot_fail("partition not found", response);
393 return r;
394 }
395
396 return r;
397}
398
399/**
Alex Kiernand1a119d2018-05-29 15:30:48 +0000400 * fastboot_mmc_flash_write() - Write image to eMMC for fastboot
401 *
402 * @cmd: Named partition to write image to
403 * @download_buffer: Pointer to image data
404 * @download_bytes: Size of image data
405 * @response: Pointer to fastboot response buffer
406 */
407void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000408 u32 download_bytes, char *response)
Steve Raec0aebb32014-08-26 11:47:27 -0700409{
Simon Glass4101f682016-02-29 15:25:34 -0700410 struct blk_desc *dev_desc;
Simon Glass05289792020-05-10 11:39:57 -0600411 struct disk_partition info;
Steve Raec0aebb32014-08-26 11:47:27 -0700412
Simon Glassdb1d9e72016-02-29 15:25:42 -0700413 dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
Steve Raec0aebb32014-08-26 11:47:27 -0700414 if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900415 pr_err("invalid mmc device\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000416 fastboot_fail("invalid mmc device", response);
Steve Raec0aebb32014-08-26 11:47:27 -0700417 return;
418 }
419
mingming lee1fdbad02020-01-16 16:11:42 +0800420#ifdef CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT
421 if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) {
422 fb_mmc_boot1_ops(dev_desc, download_buffer,
423 download_bytes, response);
424 return;
425 }
426#endif
427
Patrick Delaunaybd42a942017-01-27 11:00:41 +0100428#if CONFIG_IS_ENABLED(EFI_PARTITION)
mingming lee1fdbad02020-01-16 16:11:42 +0800429#ifndef CONFIG_FASTBOOT_MMC_USER_NAME
Steve Rae0ff7e582014-12-12 15:51:54 -0800430 if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
mingming lee1fdbad02020-01-16 16:11:42 +0800431#else
432 if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0 ||
433 strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) {
434#endif
Steve Rae0ff7e582014-12-12 15:51:54 -0800435 printf("%s: updating MBR, Primary and Backup GPT(s)\n",
436 __func__);
437 if (is_valid_gpt_buf(dev_desc, download_buffer)) {
438 printf("%s: invalid GPT - refusing to write to flash\n",
439 __func__);
Alex Kiernanc4ded032018-05-29 15:30:40 +0000440 fastboot_fail("invalid GPT partition", response);
Steve Rae0ff7e582014-12-12 15:51:54 -0800441 return;
442 }
443 if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
444 printf("%s: writing GPT partitions failed\n", __func__);
Alex Kiernanc4ded032018-05-29 15:30:40 +0000445 fastboot_fail("writing GPT partitions failed",
446 response);
Steve Rae0ff7e582014-12-12 15:51:54 -0800447 return;
448 }
449 printf("........ success\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000450 fastboot_okay(NULL, response);
Steve Rae0ff7e582014-12-12 15:51:54 -0800451 return;
Petr Kulhavyb6dd69a2016-09-09 10:27:16 +0200452 }
453#endif
454
Patrick Delaunayb0cf7332017-01-27 11:00:37 +0100455#if CONFIG_IS_ENABLED(DOS_PARTITION)
Petr Kulhavyb6dd69a2016-09-09 10:27:16 +0200456 if (strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME) == 0) {
457 printf("%s: updating MBR\n", __func__);
458 if (is_valid_dos_buf(download_buffer)) {
459 printf("%s: invalid MBR - refusing to write to flash\n",
460 __func__);
Alex Kiernanc4ded032018-05-29 15:30:40 +0000461 fastboot_fail("invalid MBR partition", response);
Petr Kulhavyb6dd69a2016-09-09 10:27:16 +0200462 return;
463 }
464 if (write_mbr_partition(dev_desc, download_buffer)) {
465 printf("%s: writing MBR partition failed\n", __func__);
Alex Kiernanc4ded032018-05-29 15:30:40 +0000466 fastboot_fail("writing MBR partition failed",
467 response);
Petr Kulhavyb6dd69a2016-09-09 10:27:16 +0200468 return;
469 }
470 printf("........ success\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000471 fastboot_okay(NULL, response);
Petr Kulhavyb6dd69a2016-09-09 10:27:16 +0200472 return;
473 }
474#endif
475
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300476#ifdef CONFIG_ANDROID_BOOT_IMAGE
477 if (strncasecmp(cmd, "zimage", 6) == 0) {
Alex Kiernanc4ded032018-05-29 15:30:40 +0000478 fb_mmc_update_zimage(dev_desc, download_buffer,
479 download_bytes, response);
Sam Protsenkoefeccfe2017-05-18 15:04:59 +0300480 return;
481 }
482#endif
483
Alex Deymo88b63292017-04-02 01:49:50 -0700484 if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900485 pr_err("cannot find partition: '%s'\n", cmd);
Alex Kiernanc4ded032018-05-29 15:30:40 +0000486 fastboot_fail("cannot find partition", response);
Steve Raec0aebb32014-08-26 11:47:27 -0700487 return;
488 }
489
Maxime Riparda5d1e042015-10-15 14:34:14 +0200490 if (is_sparse_image(download_buffer)) {
491 struct fb_mmc_sparse sparse_priv;
Steve Raecc0f08cd2016-06-07 11:19:36 -0700492 struct sparse_storage sparse;
Jassi Brar2f83f212018-04-06 12:05:09 +0530493 int err;
Maxime Riparda5d1e042015-10-15 14:34:14 +0200494
495 sparse_priv.dev_desc = dev_desc;
496
Steve Raecc0f08cd2016-06-07 11:19:36 -0700497 sparse.blksz = info.blksz;
Maxime Riparda5d1e042015-10-15 14:34:14 +0200498 sparse.start = info.start;
499 sparse.size = info.size;
Maxime Riparda5d1e042015-10-15 14:34:14 +0200500 sparse.write = fb_mmc_sparse_write;
Steve Rae2c724042016-06-07 11:19:38 -0700501 sparse.reserve = fb_mmc_sparse_reserve;
Jassi Brar2f83f212018-04-06 12:05:09 +0530502 sparse.mssg = fastboot_fail;
Maxime Riparda5d1e042015-10-15 14:34:14 +0200503
504 printf("Flashing sparse image at offset " LBAFU "\n",
Steve Raecc0f08cd2016-06-07 11:19:36 -0700505 sparse.start);
Maxime Riparda5d1e042015-10-15 14:34:14 +0200506
Steve Raecc0f08cd2016-06-07 11:19:36 -0700507 sparse.priv = &sparse_priv;
Alex Kiernanc4ded032018-05-29 15:30:40 +0000508 err = write_sparse_image(&sparse, cmd, download_buffer,
509 response);
Jassi Brar2f83f212018-04-06 12:05:09 +0530510 if (!err)
Alex Kiernanc4ded032018-05-29 15:30:40 +0000511 fastboot_okay(NULL, response);
Maxime Riparda5d1e042015-10-15 14:34:14 +0200512 } else {
Steve Raee5bf9872014-08-26 11:47:30 -0700513 write_raw_image(dev_desc, &info, cmd, download_buffer,
Alex Kiernanc4ded032018-05-29 15:30:40 +0000514 download_bytes, response);
Maxime Riparda5d1e042015-10-15 14:34:14 +0200515 }
Steve Raec0aebb32014-08-26 11:47:27 -0700516}
Dileep Katta89792382015-02-17 18:48:23 +0530517
Alex Kiernand1a119d2018-05-29 15:30:48 +0000518/**
519 * fastboot_mmc_flash_erase() - Erase eMMC for fastboot
520 *
521 * @cmd: Named partition to erase
522 * @response: Pointer to fastboot response buffer
523 */
524void fastboot_mmc_erase(const char *cmd, char *response)
Dileep Katta89792382015-02-17 18:48:23 +0530525{
526 int ret;
Simon Glass4101f682016-02-29 15:25:34 -0700527 struct blk_desc *dev_desc;
Simon Glass05289792020-05-10 11:39:57 -0600528 struct disk_partition info;
Dileep Katta89792382015-02-17 18:48:23 +0530529 lbaint_t blks, blks_start, blks_size, grp_size;
530 struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
531
532 if (mmc == NULL) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000533 pr_err("invalid mmc device\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000534 fastboot_fail("invalid mmc device", response);
Dileep Katta89792382015-02-17 18:48:23 +0530535 return;
536 }
537
Simon Glassdb1d9e72016-02-29 15:25:42 -0700538 dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
Dileep Katta89792382015-02-17 18:48:23 +0530539 if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000540 pr_err("invalid mmc device\n");
Alex Kiernanc4ded032018-05-29 15:30:40 +0000541 fastboot_fail("invalid mmc device", response);
Dileep Katta89792382015-02-17 18:48:23 +0530542 return;
543 }
544
mingming lee1fdbad02020-01-16 16:11:42 +0800545#ifdef CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT
546 if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) {
547 /* erase EMMC boot1 */
548 fb_mmc_boot1_ops(dev_desc, NULL, 0, response);
549 return;
550 }
551#endif
552
553#ifdef CONFIG_FASTBOOT_MMC_USER_NAME
554 if (strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) {
555 /* erase EMMC userdata */
556 if (fb_mmc_erase_mmc_hwpart(dev_desc))
557 fastboot_fail("Failed to erase EMMC_USER", response);
558 else
559 fastboot_okay(NULL, response);
560 return;
561 }
562#endif
563
Petr Kulhavyb6dd69a2016-09-09 10:27:16 +0200564 ret = part_get_info_by_name_or_alias(dev_desc, cmd, &info);
Alex Deymo88b63292017-04-02 01:49:50 -0700565 if (ret < 0) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000566 pr_err("cannot find partition: '%s'\n", cmd);
Alex Kiernanc4ded032018-05-29 15:30:40 +0000567 fastboot_fail("cannot find partition", response);
Dileep Katta89792382015-02-17 18:48:23 +0530568 return;
569 }
570
571 /* Align blocks to erase group size to avoid erasing other partitions */
572 grp_size = mmc->erase_grp_size;
573 blks_start = (info.start + grp_size - 1) & ~(grp_size - 1);
574 if (info.size >= grp_size)
575 blks_size = (info.size - (blks_start - info.start)) &
576 (~(grp_size - 1));
577 else
578 blks_size = 0;
579
580 printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
581 blks_start, blks_start + blks_size);
582
Alex Kiernanf73a7df2018-05-29 15:30:53 +0000583 blks = fb_mmc_blk_write(dev_desc, blks_start, blks_size, NULL);
584
Dileep Katta89792382015-02-17 18:48:23 +0530585 if (blks != blks_size) {
Alex Kiernan1ad5fac2018-05-29 15:30:43 +0000586 pr_err("failed erasing from device %d\n", dev_desc->devnum);
Alex Kiernanc4ded032018-05-29 15:30:40 +0000587 fastboot_fail("failed erasing from device", response);
Dileep Katta89792382015-02-17 18:48:23 +0530588 return;
589 }
590
591 printf("........ erased " LBAFU " bytes from '%s'\n",
592 blks_size * info.blksz, cmd);
Alex Kiernanc4ded032018-05-29 15:30:40 +0000593 fastboot_okay(NULL, response);
Dileep Katta89792382015-02-17 18:48:23 +0530594}