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