spl: Refactor spl_load_info->read to use units of bytes

Simplify things a bit for callers of spl_load_info->read by refactoring it
to use units of bytes instead of bl_len. This generally simplifies the
logic, as MMC is the only loader which actually works in sectors. It will
also allow further refactoring to remove the special-case handling of
filename.  spl_load_legacy_img already works in units of bytes (oops) so it
doesn't need to be changed.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c
index 93d48e5..d7f6cb4 100644
--- a/arch/arm/mach-imx/spl_imx_romapi.c
+++ b/arch/arm/mach-imx/spl_imx_romapi.c
@@ -53,16 +53,10 @@
 }
 
 static ulong spl_romapi_read_seekable(struct spl_load_info *load,
-				      ulong sector, ulong count,
+				      ulong offset, ulong byte,
 				      void *buf)
 {
-	u32 pagesize = *(u32 *)load->priv;
-	ulong byte = count * pagesize;
-	u32 offset;
-
-	offset = sector * pagesize;
-
-	return spl_romapi_raw_seekable_read(offset, byte, buf) / pagesize;
+	return spl_romapi_raw_seekable_read(offset, byte, buf);
 }
 
 static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
@@ -109,8 +103,7 @@
 		memset(&load, 0, sizeof(load));
 		load.bl_len = pagesize;
 		load.read = spl_romapi_read_seekable;
-		load.priv = &pagesize;
-		return spl_load_simple_fit(spl_image, &load, offset / pagesize, header);
+		return spl_load_simple_fit(spl_image, &load, offset, header);
 	} else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) &&
 		   valid_container_hdr((void *)header)) {
 		struct spl_load_info load;
@@ -118,9 +111,8 @@
 		memset(&load, 0, sizeof(load));
 		load.bl_len = pagesize;
 		load.read = spl_romapi_read_seekable;
-		load.priv = &pagesize;
 
-		ret = spl_load_imx_container(spl_image, &load, offset / pagesize);
+		ret = spl_load_imx_container(spl_image, &load, offset);
 	} else {
 		/* TODO */
 		puts("Can't support legacy image\n");
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 6084ead..ce7ef0e 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -180,7 +180,7 @@
 	if (info->filename)
 		return offset & ~(ARCH_DMA_MINALIGN - 1);
 
-	return offset / info->bl_len;
+	return ALIGN_DOWN(offset, info->bl_len);
 }
 
 static int get_aligned_image_overhead(struct spl_load_info *info, int offset)
@@ -205,7 +205,7 @@
 	if (info->filename)
 		return data_size;
 
-	return (data_size + info->bl_len - 1) / info->bl_len;
+	return ALIGN(data_size, info->bl_len);
 }
 
 /**
@@ -222,7 +222,7 @@
  *
  * Return:	0 on success or a negative error number.
  */
-static int load_simple_fit(struct spl_load_info *info, ulong sector,
+static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
 			   const struct spl_fit_info *ctx, int node,
 			   struct spl_image_info *image_info)
 {
@@ -234,7 +234,6 @@
 	void *load_ptr;
 	void *src;
 	ulong overhead;
-	int nr_sectors;
 	uint8_t image_comp = -1, type = -1;
 	const void *data;
 	const void *fit = ctx->fit;
@@ -291,11 +290,12 @@
 		length = len;
 
 		overhead = get_aligned_image_overhead(info, offset);
-		nr_sectors = get_aligned_image_size(info, length, offset);
+		size = get_aligned_image_size(info, length, offset);
 
 		if (info->read(info,
-			       sector + get_aligned_image_offset(info, offset),
-			       nr_sectors, src_ptr) != nr_sectors)
+			       fit_offset +
+			       get_aligned_image_offset(info, offset), size,
+			       src_ptr) != size)
 			return -EIO;
 
 		debug("External data: dst=%p, offset=%x, size=%lx\n",
@@ -380,7 +380,7 @@
 }
 
 static int spl_fit_append_fdt(struct spl_image_info *spl_image,
-			      struct spl_load_info *info, ulong sector,
+			      struct spl_load_info *info, ulong offset,
 			      const struct spl_fit_info *ctx)
 {
 	struct spl_image_info image_info;
@@ -414,7 +414,7 @@
 		spl_image->fdt_addr = map_sysmem(image_info.load_addr, size);
 		memcpy(spl_image->fdt_addr, gd->fdt_blob, size);
 	} else {
-		ret = load_simple_fit(info, sector, ctx, node, &image_info);
+		ret = load_simple_fit(info, offset, ctx, node, &image_info);
 		if (ret < 0)
 			return ret;
 
@@ -465,7 +465,7 @@
 					      __func__);
 			}
 			image_info.load_addr = (ulong)tmpbuffer;
-			ret = load_simple_fit(info, sector, ctx, node,
+			ret = load_simple_fit(info, offset, ctx, node,
 					      &image_info);
 			if (ret < 0)
 				break;
@@ -642,7 +642,7 @@
 }
 
 static int spl_fit_load_fpga(struct spl_fit_info *ctx,
-			     struct spl_load_info *info, ulong sector)
+			     struct spl_load_info *info, ulong offset)
 {
 	int node, ret;
 
@@ -657,7 +657,7 @@
 	warn_deprecated("'fpga' property in config node. Use 'loadables'");
 
 	/* Load the image and set up the fpga_image structure */
-	ret = load_simple_fit(info, sector, ctx, node, &fpga_image);
+	ret = load_simple_fit(info, offset, ctx, node, &fpga_image);
 	if (ret) {
 		printf("%s: Cannot load the FPGA: %i\n", __func__, ret);
 		return ret;
@@ -667,11 +667,10 @@
 }
 
 static int spl_simple_fit_read(struct spl_fit_info *ctx,
-			       struct spl_load_info *info, ulong sector,
+			       struct spl_load_info *info, ulong offset,
 			       const void *fit_header)
 {
 	unsigned long count, size;
-	int sectors;
 	void *buf;
 
 	/*
@@ -690,13 +689,13 @@
 	 * For FIT with data embedded, data is loaded as part of FIT image.
 	 * For FIT with external data, data is not loaded in this step.
 	 */
-	sectors = get_aligned_image_size(info, size, 0);
-	buf = board_spl_fit_buffer_addr(size, sectors, info->bl_len);
+	size = get_aligned_image_size(info, size, 0);
+	buf = board_spl_fit_buffer_addr(size, size, 1);
 
-	count = info->read(info, sector, sectors, buf);
+	count = info->read(info, offset, size, buf);
 	ctx->fit = buf;
-	debug("fit read sector %lx, sectors=%d, dst=%p, count=%lu, size=0x%lx\n",
-	      sector, sectors, buf, count, size);
+	debug("fit read offset %lx, size=%lu, dst=%p, count=%lu\n",
+	      offset, size, buf, count);
 
 	return (count == 0) ? -EIO : 0;
 }
@@ -728,7 +727,7 @@
 }
 
 int spl_load_simple_fit(struct spl_image_info *spl_image,
-			struct spl_load_info *info, ulong sector, void *fit)
+			struct spl_load_info *info, ulong offset, void *fit)
 {
 	struct spl_image_info image_info;
 	struct spl_fit_info ctx;
@@ -737,7 +736,7 @@
 	int index = 0;
 	int firmware_node;
 
-	ret = spl_simple_fit_read(&ctx, info, sector, fit);
+	ret = spl_simple_fit_read(&ctx, info, offset, fit);
 	if (ret < 0)
 		return ret;
 
@@ -752,7 +751,7 @@
 		return ret;
 
 	if (IS_ENABLED(CONFIG_SPL_FPGA))
-		spl_fit_load_fpga(&ctx, info, sector);
+		spl_fit_load_fpga(&ctx, info, offset);
 
 	/*
 	 * Find the U-Boot image using the following search order:
@@ -782,7 +781,7 @@
 	}
 
 	/* Load the image and set up the spl_image structure */
-	ret = load_simple_fit(info, sector, &ctx, node, spl_image);
+	ret = load_simple_fit(info, offset, &ctx, node, spl_image);
 	if (ret)
 		return ret;
 
@@ -800,7 +799,7 @@
 	 * We allow this to fail, as the U-Boot image might embed its FDT.
 	 */
 	if (os_takes_devicetree(spl_image->os)) {
-		ret = spl_fit_append_fdt(spl_image, info, sector, &ctx);
+		ret = spl_fit_append_fdt(spl_image, info, offset, &ctx);
 		if (ret < 0 && spl_image->os != IH_OS_U_BOOT)
 			return ret;
 	}
@@ -823,7 +822,7 @@
 			continue;
 
 		image_info.load_addr = 0;
-		ret = load_simple_fit(info, sector, &ctx, node, &image_info);
+		ret = load_simple_fit(info, offset, &ctx, node, &image_info);
 		if (ret < 0) {
 			printf("%s: can't load image loadables index %d (ret = %d)\n",
 			       __func__, index, ret);
@@ -837,7 +836,7 @@
 			debug("Loadable is %s\n", genimg_get_os_name(os_type));
 
 		if (os_takes_devicetree(os_type)) {
-			spl_fit_append_fdt(&image_info, info, sector, &ctx);
+			spl_fit_append_fdt(&image_info, info, offset, &ctx);
 			spl_image->fdt_addr = image_info.fdt_addr;
 		}
 
diff --git a/common/spl/spl_imx_container.c b/common/spl/spl_imx_container.c
index 1cc5178..ad89a99 100644
--- a/common/spl/spl_imx_container.c
+++ b/common/spl/spl_imx_container.c
@@ -19,11 +19,10 @@
 					  struct spl_load_info *info,
 					  struct container_hdr *container,
 					  int image_index,
-					  u32 container_sector)
+					  ulong container_offset)
 {
 	struct boot_img_t *images;
-	ulong sector;
-	u32 sectors;
+	ulong offset, overhead, size;
 
 	if (image_index > container->num_images) {
 		debug("Invalid image number\n");
@@ -39,16 +38,14 @@
 		return NULL;
 	}
 
-	sectors = ALIGN(images[image_index].size, info->bl_len) /
-		info->bl_len;
-	sector = images[image_index].offset / info->bl_len +
-		container_sector;
+	size = ALIGN(images[image_index].size, info->bl_len);
+	offset = images[image_index].offset + container_offset;
 
-	debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
-	      container, sector, sectors);
-	if (info->read(info, sector, sectors,
-		       map_sysmem(images[image_index].dst,
-				  images[image_index].size)) != sectors) {
+	debug("%s: container: %p offset: %lu size: %lu\n", __func__,
+	      container, offset, size);
+	if (info->read(info, offset, size,
+		       map_sysmem(images[image_index].dst - overhead,
+				  images[image_index].size)) != size) {
 		printf("%s wrong\n", __func__);
 		return NULL;
 	}
@@ -62,15 +59,13 @@
 }
 
 static int read_auth_container(struct spl_image_info *spl_image,
-			       struct spl_load_info *info, ulong sector)
+			       struct spl_load_info *info, ulong offset)
 {
 	struct container_hdr *container = NULL;
 	u16 length;
-	u32 sectors;
 	int i, size, ret = 0;
 
 	size = ALIGN(CONTAINER_HDR_ALIGNMENT, info->bl_len);
-	sectors = size / info->bl_len;
 
 	/*
 	 * It will not override the ATF code, so safe to use it here,
@@ -80,9 +75,9 @@
 	if (!container)
 		return -ENOMEM;
 
-	debug("%s: container: %p sector: %lu sectors: %u\n", __func__,
-	      container, sector, sectors);
-	if (info->read(info, sector, sectors, container) != sectors) {
+	debug("%s: container: %p offset: %lu size: %u\n", __func__,
+	      container, offset, size);
+	if (info->read(info, offset, size, container) != size) {
 		ret = -EIO;
 		goto end;
 	}
@@ -104,17 +99,15 @@
 
 	if (length > CONTAINER_HDR_ALIGNMENT) {
 		size = ALIGN(length, info->bl_len);
-		sectors = size / info->bl_len;
 
 		free(container);
 		container = malloc(size);
 		if (!container)
 			return -ENOMEM;
 
-		debug("%s: container: %p sector: %lu sectors: %u\n",
-		      __func__, container, sector, sectors);
-		if (info->read(info, sector, sectors, container) !=
-		    sectors) {
+		debug("%s: container: %p offset: %lu size: %u\n",
+		      __func__, container, offset, size);
+		if (info->read(info, offset, size, container) != size) {
 			ret = -EIO;
 			goto end;
 		}
@@ -129,7 +122,7 @@
 	for (i = 0; i < container->num_images; i++) {
 		struct boot_img_t *image = read_auth_image(spl_image, info,
 							   container, i,
-							   sector);
+							   offset);
 
 		if (!image) {
 			ret = -EINVAL;
@@ -154,7 +147,7 @@
 }
 
 int spl_load_imx_container(struct spl_image_info *spl_image,
-			   struct spl_load_info *info, ulong sector)
+			   struct spl_load_info *info, ulong offset)
 {
-	return read_auth_container(spl_image, info, sector);
+	return read_auth_container(spl_image, info, offset);
 }
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index 3d7551a..9f41ea6 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -62,12 +62,14 @@
 	return 0;
 }
 
-static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
-			     ulong count, void *buf)
+static ulong h_spl_load_read(struct spl_load_info *load, ulong off,
+			     ulong size, void *buf)
 {
-	struct mmc *mmc = load->priv;
+	struct blk_desc *bd = load->priv;
+	lbaint_t sector = off >> bd->log2blksz;
+	lbaint_t count = size >> bd->log2blksz;
 
-	return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
+	return blk_dread(bd, sector, count, buf) << bd->log2blksz;
 }
 
 static __maybe_unused unsigned long spl_mmc_raw_uboot_offset(int part)
@@ -105,21 +107,23 @@
 		struct spl_load_info load;
 
 		debug("Found FIT\n");
-		load.priv = mmc;
+		load.priv = bd;
 		load.filename = NULL;
-		load.bl_len = mmc->read_bl_len;
+		load.bl_len = bd->blksz;
 		load.read = h_spl_load_read;
-		ret = spl_load_simple_fit(spl_image, &load, sector, header);
+		ret = spl_load_simple_fit(spl_image, &load,
+					  sector << bd->log2blksz, header);
 	} else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) &&
 		   valid_container_hdr((void *)header)) {
 		struct spl_load_info load;
 
-		load.priv = mmc;
+		load.priv = bd;
 		load.filename = NULL;
-		load.bl_len = mmc->read_bl_len;
+		load.bl_len = bd->blksz;
 		load.read = h_spl_load_read;
 
-		ret = spl_load_imx_container(spl_image, &load, sector);
+		ret = spl_load_imx_container(spl_image, &load,
+					     sector << bd->log2blksz);
 	} else {
 		ret = mmc_load_legacy(spl_image, bootdev, mmc, sector, header);
 	}
diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c
index 9a5a5ff..1fcc89f 100644
--- a/common/spl/spl_nand.c
+++ b/common/spl/spl_nand.c
@@ -49,14 +49,12 @@
 	ulong sector;
 
 	sector = *(int *)load->priv;
-	offs *= load->bl_len;
-	size *= load->bl_len;
 	offs = sector + nand_spl_adjust_offset(sector, offs - sector);
 	err = nand_spl_load_image(offs, size, dst);
 	if (err)
 		return 0;
 
-	return size / load->bl_len;
+	return size;
 }
 
 static ulong spl_nand_legacy_read(struct spl_load_info *load, ulong offs,
@@ -95,7 +93,7 @@
 		load.filename = NULL;
 		load.bl_len = bl_len;
 		load.read = spl_nand_fit_read;
-		return spl_load_simple_fit(spl_image, &load, offset / bl_len, header);
+		return spl_load_simple_fit(spl_image, &load, offset, header);
 	} else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER) &&
 		   valid_container_hdr((void *)header)) {
 		struct spl_load_info load;
@@ -104,7 +102,7 @@
 		load.filename = NULL;
 		load.bl_len = bl_len;
 		load.read = spl_nand_fit_read;
-		return spl_load_imx_container(spl_image, &load, offset / bl_len);
+		return spl_load_imx_container(spl_image, &load, offset);
 	} else if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_FORMAT) &&
 		   image_get_magic(header) == IH_MAGIC) {
 		struct spl_load_info load;
diff --git a/include/spl.h b/include/spl.h
index 951e136..5a355e0 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -297,10 +297,12 @@
 	 * read() - Read from device
 	 *
 	 * @load: Information about the load state
-	 * @sector: Sector number to read from (each @load->bl_len bytes)
-	 * @count: Number of sectors to read
+	 * @offset: Offset to read from in bytes. This must be a multiple of
+	 *          @load->bl_len.
+	 * @count: Number of bytes to read. This must be a multiple of
+	 *         @load->bl_len.
 	 * @buf: Buffer to read into
-	 * @return number of sectors read, 0 on error
+	 * @return number of bytes read, 0 on error
 	 */
 	ulong (*read)(struct spl_load_info *load, ulong sector, ulong count,
 		      void *buf);
@@ -368,7 +370,8 @@
  * spl_load_simple_fit() - Loads a fit image from a device.
  * @spl_image:	Image description to set up
  * @info:	Structure containing the information required to load data.
- * @sector:	Sector number where FIT image is located in the device
+ * @offset:	Offset where FIT image is located in the device. Must be aligned
+ *              to the device's bl_len.
  * @fdt:	Pointer to the copied FIT header.
  *
  * Reads the FIT image @sector in the device. Loads u-boot image to
@@ -376,7 +379,7 @@
  * Returns 0 on success.
  */
 int spl_load_simple_fit(struct spl_image_info *spl_image,
-			struct spl_load_info *info, ulong sector, void *fdt);
+			struct spl_load_info *info, ulong offset, void *fdt);
 
 #define SPL_COPY_PAYLOAD_ONLY	1
 #define SPL_FIT_FOUND		2
@@ -402,13 +405,14 @@
  * spl_load_imx_container() - Loads a imx container image from a device.
  * @spl_image:	Image description to set up
  * @info:	Structure containing the information required to load data.
- * @sector:	Sector number where container image is located in the device
+ * @sector:	Offset where container image is located in the device. Must be
+ *              aligned to the device block size.
  *
  * Reads the container image @sector in the device. Loads u-boot image to
  * specified load address.
  */
 int spl_load_imx_container(struct spl_image_info *spl_image,
-			   struct spl_load_info *info, ulong sector);
+			   struct spl_load_info *info, ulong offset);
 
 /* SPL common functions */
 void preloader_console_init(void);
diff --git a/test/image/spl_load_os.c b/test/image/spl_load_os.c
index 49edf15..794cfad 100644
--- a/test/image/spl_load_os.c
+++ b/test/image/spl_load_os.c
@@ -16,14 +16,13 @@
 	int fd;
 };
 
-static ulong read_fit_image(struct spl_load_info *load, ulong sector,
-			    ulong count, void *buf)
+static ulong read_fit_image(struct spl_load_info *load, ulong offset,
+			    ulong size, void *buf)
 {
 	struct text_ctx *text_ctx = load->priv;
-	off_t offset, ret;
+	off_t ret;
 	ssize_t res;
 
-	offset = sector * load->bl_len;
 	ret = os_lseek(text_ctx->fd, offset, OS_SEEK_SET);
 	if (ret != offset) {
 		printf("Failed to seek to %zx, got %zx (errno=%d)\n", offset,
@@ -31,14 +30,14 @@
 		return 0;
 	}
 
-	res = os_read(text_ctx->fd, buf, count * load->bl_len);
+	res = os_read(text_ctx->fd, buf, size);
 	if (res == -1) {
 		printf("Failed to read %lx bytes, got %ld (errno=%d)\n",
-		       count * load->bl_len, res, errno);
+		       size, res, errno);
 		return 0;
 	}
 
-	return count;
+	return size;
 }
 
 static int spl_test_load(struct unit_test_state *uts)