/*
 * Copyright (c) 2019 The Fuchsia Authors
 *
 * SPDX-License-Identifier:	BSD-3-Clause
 */

#include <common.h>
#include <amlogic/aml_mtd.h>
#include <amlogic/storage.h>
#include <blk.h>
#include <emmc_partitions.h>
#include <mmc.h>
#include <part_efi.h>
#include <zircon_uboot/partition.h>
#include <zircon_uboot/partition_internal.h>
#include <zircon_uboot/vboot.h>

#define ERASE_GROUP_SIZE (512 * 1024)

/* Temporary buffer when we need to cache data locally. Only valid for use
   within a single call, do not expect the contents to be consistent across
   multiple calls since other functions may have modified it. */
static uint8_t temp_buffer[ERASE_GROUP_SIZE] __aligned(ARCH_DMA_MINALIGN);

static int store_call_setup(const zircon_partition *part, uint64_t offset,
			    size_t length)
{
	if (offset + length > part->size) {
		fprintf(stderr,
			"Error: operation cannot exceed partition boundary\n");
		return -1;
	}

	if (store_set_device(BOOT_EMMC)) {
		fprintf(stderr, "Error: Unable to set storage device\n");
		return -1;
	}

	return 0;
}

static int gpt_part_read(const zircon_partition *part, uint64_t offset,
			 void *buffer, size_t length)
{
	if (store_call_setup(part, offset, length)) {
		return -1;
	}

	// store_read() offset must be at a block boundary. If our |offset| is
	// not, read the first partial block manually.
	uint64_t first_block_offset = offset % part->data->mmc->read_bl_len;
	size_t first_block_bytes_used = 0;
	if (first_block_offset) {
		// Read from the beginning of the block to at most the end of the block.
		size_t first_block_length =
			min(length + first_block_offset,
			    (uint64_t)part->data->mmc->read_bl_len);

		int ret = store_read(part->data->gpt_name,
				     part->data->gpt_offset + offset -
					     first_block_offset,
				     first_block_length, temp_buffer);
		if (ret) {
			fprintf(stderr, "Error: partial page read failure\n");
			return ret;
		}

		// Track the bytes we just read, but leave them in the temp
		// buffer for now (see note below about alignment).
		first_block_bytes_used =
			first_block_length - first_block_offset;
		offset += first_block_bytes_used;
		length -= first_block_bytes_used;

		// If that was the entire requested amount, we're done.
		if (length == 0) {
			memcpy(buffer, temp_buffer + first_block_offset,
			       first_block_bytes_used);
			return 0;
		}
	}

	// store_read() also requires that the destination buffer has
	// certain alignment (DMA alignment I think?), so we have to read this
	// next chunk directly into |buffer| without any offset.
	int ret = store_read(part->data->gpt_name,
			     part->data->gpt_offset + offset, length, buffer);
	if (ret != 0) {
		return ret;
	}

	// Finally, if we did a first page partial read, move the main read
	// back and copy the first partial read into the correct place.
	if (first_block_bytes_used) {
		memmove(buffer + first_block_bytes_used, buffer, length);
		memcpy(buffer, temp_buffer + first_block_offset,
		       first_block_bytes_used);
	}

	return 0;
}

static int gpt_part_write(const zircon_partition *part, uint64_t offset,
			  const void *buffer, size_t length)
{
	if (store_call_setup(part, offset, length)) {
		return -1;
	}

	// store_write() offset must be at a block boundary. If our |offset| is
	// not, read the first partial block, modify and write back manually.
	// Compute the unaligned write offset within the first block.
	size_t first_block_write_offset =
		offset % part->data->mmc->write_bl_len;
	if (first_block_write_offset) {
		static uint8_t scratch_buffer[512] __aligned(ARCH_DMA_MINALIGN);
		assert(sizeof(scratch_buffer) == part->data->mmc->write_bl_len);
		// The aligned offset of the first block.
		size_t first_block_offset = offset - first_block_write_offset;

		// Read the block
		int res = gpt_part_read(part, first_block_offset,
					scratch_buffer, sizeof(scratch_buffer));
		if (res) {
			return res;
		}

		// The amount of data to write for the first block. It's the smaller
		// of the total length and the remaining part in the block.
		size_t first_block_write_length =
			min(length,
			    sizeof(scratch_buffer) - first_block_write_offset);

		// Modify
		memcpy(scratch_buffer + first_block_write_offset, buffer,
		       first_block_write_length);

		// Write back the modified data.
		res = gpt_part_write(part, first_block_offset, scratch_buffer,
				     sizeof(scratch_buffer));
		if (res) {
			return res;
		}

		offset += first_block_write_length;
		length -= first_block_write_length;
		buffer = (const uint8_t *)(buffer) + first_block_write_length;
		if (length == 0) {
			return 0;
		}
	}

	return store_write(part->data->gpt_name,
			   part->data->gpt_offset + offset, length, buffer);
}

static int gpt_part_erase(const zircon_partition *part)
{
	if (store_call_setup(part, 0, 0)) {
		return -1;
	}

	// store_erase can only erase erase-block aligned partitions.
	// For unaligned partitions, this uses store_write to write 0x00 to the unaligned sections.

	size_t min_erase_size =
		part->data->mmc->erase_grp_size * part->data->mmc->write_bl_len;

	if (part->data->abs_offset % min_erase_size == 0 &&
	    part->size % min_erase_size == 0) {
		return store_erase(part->data->gpt_name, part->data->gpt_offset,
				   part->size, 0);
	}

	if (sizeof(temp_buffer) < min_erase_size) {
		fprintf(stderr, "Error: erase buffer too small\n");
		return -1;
	}

	if (part->size <= sizeof(temp_buffer)) {
		memset(temp_buffer, 0x00, part->size);
		return store_write(part->data->gpt_name, part->data->gpt_offset,
				   part->size, temp_buffer);
	}

	uint64_t erase_start = roundup(part->data->abs_offset, min_erase_size);

	// 'write' to erase beginning of partition if unaligned
	if (part->data->abs_offset < erase_start) {
		uint64_t write_len = erase_start - part->data->abs_offset;

		memset(temp_buffer, 0x00, write_len);
		if (store_write(part->data->gpt_name, part->data->gpt_offset,
				write_len, temp_buffer)) {
			return -1;
		};
	}

	uint64_t part_end = part->data->abs_offset + part->size;

	uint64_t erase_end = rounddown(part_end, min_erase_size);

	// 'write' to erase end of partition if unaligned.
	if (part_end > erase_end) {
		uint64_t write_len = part_end - erase_end;

		uint64_t part_offset = erase_end - part->data->abs_offset;

		memset(temp_buffer, 0x00, write_len);
		if (store_write(part->data->gpt_name,
				part->data->gpt_offset + part_offset, write_len,
				temp_buffer)) {
			return -1;
		};
	}

	// If there are any full erase blocks within the partition, erase them.
	if (erase_start < erase_end) {
		uint64_t erase_off_lba =
			erase_start / part->data->blk_desc->blksz;
		uint64_t erase_len_lba =
			(erase_end - erase_start) / part->data->blk_desc->blksz;

		return blk_derase(part->data->blk_desc, erase_off_lba,
				  erase_len_lba);
	}

	return 0;
}

static int bootloader_write(const zircon_partition *part, uint64_t offset,
			    const void *buffer, size_t length)
{
	if (store_call_setup(part, offset, length)) {
		return -1;
	}

	if (offset != 0) {
		fprintf(stderr,
			"Error: Unable to write bootloader at offset\n");
		return -1;
	}

	return store_boot_write(BOOT_LOADER, BOOT_OPS_ALL, length, buffer);
}

static int bootloader_erase(const zircon_partition *part)
{
	if (store_call_setup(part, 0, 0)) {
		return -1;
	}

	return store_boot_erase(BOOT_LOADER, BOOT_OPS_ALL);
}

static int reset_hwpart(struct blk_desc *blk_desc)
{
	if (blk_dselect_hwpart(blk_desc, MMC_PART_USER)) {
		fprintf(stderr, "Error: switch hwpart failed\n");
		return -1;
	}
	return 0;
}

static int set_hwpart(struct blk_desc *blk_desc, int hw_part)
{
	if (blk_dselect_hwpart(blk_desc, hw_part)) {
		fprintf(stderr, "Error: switch hwpart failed\n");
		reset_hwpart(blk_desc);
		return -1;
	}
	return 0;
}

enum raw_emmc_op_type {
	RAW_EMMC_OP_READ,
	RAW_EMMC_OP_WRITE,
	RAW_EMMC_OP_ERASE,
};

static int raw_emmc_erase_unaligned(struct blk_desc *blk_desc, lbaint_t offset,
				    lbaint_t size, lbaint_t erase_grp_size)
{
	lbaint_t end = size + offset;
	lbaint_t left = roundup(offset, erase_grp_size);
	lbaint_t right = rounddown(end, erase_grp_size);
	if (right > left) {
		if (blk_derase(blk_desc, left, right - left)) {
			fprintf(stderr, "Error: failed to erase blocks\n");
			return -1;
		}
	}

	lbaint_t segs[][2] = {
		{ offset, min(left, end) },
		{ max(offset, right), end },
	};
	assert(sizeof(temp_buffer) == erase_grp_size * blk_desc->blksz);
	memset(temp_buffer, 0x00,
	       max(segs[0][1] - segs[0][0], segs[1][1] - segs[1][0]));

	for (uint32_t i = 0; i < (offset >= right ? 1 : 2); i++) {
		lbaint_t to_write = segs[i][1] - segs[i][0];
		uint64_t n =
			blk_dwrite(blk_desc, segs[i][0], to_write, temp_buffer);
		if (n != to_write) {
			fprintf(stderr,
				"Error: attempted to write " LBAFU " blocks, "
				"wrote %llu blocks\n",
				to_write, n);
			return -1;
		}
	}
	return 0;
}

static int raw_emmc_op(enum raw_emmc_op_type op, const zircon_partition *part,
		       uint64_t offset, size_t length, void *read_buf,
		       const void *write_buf)
{
	struct blk_desc *blk_desc = part->data->blk_desc;

	lbaint_t lba_offset = part->data->lba_offset;
	lbaint_t lba_size = part->data->lba_size;

	if (op == RAW_EMMC_OP_READ || op == RAW_EMMC_OP_WRITE) {
		if (offset + length > part->size) {
			fprintf(stderr,
				"Error: operation cannot exceed partition boundary\n");
			return -1;
		}

		if (offset % blk_desc->blksz || length % blk_desc->blksz) {
			fprintf(stderr,
				"Error: length/offset must be multiples of block size\n");
			return -1;
		}

		lba_offset += offset / blk_desc->blksz;
		lba_size = length / blk_desc->blksz;
	}

	if (set_hwpart(blk_desc, part->data->hw_part)) {
		return -1;
	}

	int ret = 0;
	uint64_t n;

	switch (op) {
	case RAW_EMMC_OP_READ:
		n = blk_dread(blk_desc, lba_offset, lba_size, read_buf);
		if (n != lba_size) {
			fprintf(stderr,
				"Error: attempted to read " LBAFU
				" blocks, actually read %llu blocks\n",
				lba_size, n);
			ret = -1;
		}
		break;

	case RAW_EMMC_OP_WRITE:
		n = blk_dwrite(blk_desc, lba_offset, lba_size, write_buf);
		if (n != lba_size) {
			fprintf(stderr,
				"Error: attempted to write " LBAFU
				" blocks, wrote %llu blocks\n",
				lba_size, n);
			ret = -1;
		}
		break;

	case RAW_EMMC_OP_ERASE:
		// blk_derase silently erases the surrounding erase block,
		// so write 0x00 instead if unaligned.
		if (!(lba_offset % part->data->mmc->erase_grp_size ||
		      lba_size % part->data->mmc->erase_grp_size)) {
			if (blk_derase(blk_desc, lba_offset, lba_size)) {
				fprintf(stderr,
					"Error: erase of " LBAFU
					" blocks failed\n",
					lba_size);
				ret = -1;
			}
			break;
		}

		ret = raw_emmc_erase_unaligned(blk_desc, lba_offset, lba_size,
					       part->data->mmc->erase_grp_size);
		break;
	}

	if (reset_hwpart(blk_desc)) {
		return -1;
	}

	return ret;
}

static int raw_emmc_read(const zircon_partition *part, uint64_t offset,
			 void *buffer, size_t length)
{
	return raw_emmc_op(RAW_EMMC_OP_READ, part, offset, length, buffer,
			   NULL);
}

static int raw_emmc_write(const zircon_partition *part, uint64_t offset,
			  const void *buffer, size_t length)
{
	return raw_emmc_op(RAW_EMMC_OP_WRITE, part, offset, length, NULL,
			   buffer);
}

static int raw_emmc_erase(const zircon_partition *part)
{
	return raw_emmc_op(RAW_EMMC_OP_ERASE, part, 0, 0, NULL, NULL);
}

static int gpt_write(const zircon_partition *part, uint64_t offset,
		     const void *buffer, size_t length)
{
	if (offset != 0) {
		fprintf(stderr, "Error: Unable to write GPT at offset\n");
		return -1;
	}

	if (length > part->size) {
		fprintf(stderr, "Error: write larger than partition size\n");
		return -1;
	}

	/* write_mbr_and_gpt_partitions() does a fair bit of modification to the GPT
	   buffer, both for validation checks and for conversion to a backup header.

	   While we could probably get away with modifying the data at the moment,
	   it breaks the write() API contract and may cause unexpected problems in
	   the future. Instead, we just copy the GPT to the temporary buffer and do
	   the operation there. */
	if (length > sizeof(temp_buffer)) {
		fprintf(stderr, "Error: GPT larger than temp buffer\n");
		return -1;
	}
	memcpy(temp_buffer, buffer, length);

	if (write_mbr_and_gpt_partitions(part->data->blk_desc, temp_buffer)) {
		fprintf(stderr, "Error: GPT write failed\n");
		return -1;
	}

	// reinitialize mmc to update the cached partition table.
	mmc_device_init(part->data->mmc);

	return 0;
}

static int gpt_erase(const zircon_partition *part)
{
	if (raw_emmc_erase(part)) {
		return -1;
	}

	zircon_partition *gpt_backup = zircon_get_partition("gpt_backup");
	if (!gpt_backup) {
		fprintf(stderr, "Error: Unable to find gpt_backup\n");
		return -1;
	}

	if (raw_emmc_erase(gpt_backup)) {
		zircon_free_partition(gpt_backup);
		return -1;
	}

	zircon_free_partition(gpt_backup);
	return 0;
}

static int composite_get_part_and_op_size(const subpart_t *sub, size_t img_len,
					  zircon_partition **out_part,
					  uint32_t *op_size)
{
	*out_part = zircon_get_partition(sub->name);
	if (!(*out_part)) {
		fprintf(stderr, "Failed to get sub partition %s\n", sub->name);
		return -1;
	}
	// Set to 0 value if |*op_size| doesn't matter. (i.e. erase)
	if (!img_len)
		return 0;

	if (sub->image_offset > img_len) {
		fprintf(stderr,
			"image offset %u for sub partition %s "
			"exceeds image size %zu\n",
			sub->image_offset, sub->name, img_len);
		return -1;
	}

	uint32_t available_img_size = (img_len - sub->image_offset);

	// |sub->image_size|=0 specifies that we read/write upto the
	// partition size at most.
	uint32_t allowed_size =
		sub->image_size == 0 ? (*out_part)->size : sub->image_size;

	// Further take into consideration available image size.
	*op_size = min(allowed_size, available_img_size);

	return 0;
}

static int composite_part_write(const zircon_partition *part, uint64_t offset,
				const void *buffer, size_t length)
{
	if (offset) {
		fprintf(stderr,
			"composite partition does not support offset.\n");
		return -1;
	}

	for (uint32_t i = 0; i < part->data->sub_parts_count; i++) {
		const subpart_t *sub = &part->data->sub_parts[i];
		zircon_partition *sub_part = NULL;
		uint32_t image_size;

		if (composite_get_part_and_op_size(sub, length, &sub_part,
						   &image_size)) {
			zircon_free_partition(sub_part);
			return -1;
		}

		int ret = sub_part->write(
			sub_part, 0,
			&((const uint8_t *)buffer)[sub->image_offset],
			image_size);
		if (ret) {
			zircon_free_partition(sub_part);
			return ret;
		}

		zircon_free_partition(sub_part);
	}

	return 0;
}

static bool composite_part_is_read_redundant(const subpart_t *parts,
					     uint32_t curr_idx)
{
	const subpart_t *curr = &parts[curr_idx];
	for (uint32_t i = 0; i < curr_idx; i++) {
		const subpart_t *prev = &parts[i];
		if (curr->image_offset == prev->image_offset &&
		    prev->last_read_size == curr->last_read_size)
			return true;
	}

	return false;
}

static int composite_part_read(const zircon_partition *part, uint64_t offset,
			       void *buffer, size_t length)
{
	if (offset) {
		fprintf(stderr,
			"composite partition does not support offset.\n");
		return -1;
	}

	for (uint32_t i = 0; i < part->data->sub_parts_count; i++) {
		const subpart_t *sub = &part->data->sub_parts[i];
		zircon_partition *sub_part = NULL;

		/* Have to cast away the const on |last_read_size| so we can update it
		   here. This is OK since it's just internal bookkeeping, and no callers
		   should be relying on it. */
		if (composite_get_part_and_op_size(
			    sub, length, &sub_part,
			    (uint32_t *)&sub->last_read_size)) {
			zircon_free_partition(sub_part);
			return -1;
		}

		if (composite_part_is_read_redundant(part->data->sub_parts,
						     i)) {
			printf("skip reading %s\n", sub->name);
			zircon_free_partition(sub_part);
			continue;
		}

		int ret =
			sub_part->read(sub_part, 0,
				       &((uint8_t *)buffer)[sub->image_offset],
				       sub->last_read_size);
		if (ret) {
			zircon_free_partition(sub_part);
			return ret;
		}

		zircon_free_partition(sub_part);
	}

	return 0;
}

static int composite_part_erase(const zircon_partition *part)
{
	for (uint32_t i = 0; i < part->data->sub_parts_count; i++) {
		const subpart_t *sub = &part->data->sub_parts[i];
		zircon_partition *sub_part = NULL;
		uint32_t image_size;

		if (composite_get_part_and_op_size(sub, 0, &sub_part,
						   &image_size)) {
			zircon_free_partition(sub_part);
			return -1;
		}

		int ret = sub_part->erase(sub_part);
		if (ret) {
			zircon_free_partition(sub_part);
			return ret;
		}

		zircon_free_partition(sub_part);
	}

	return 0;
}

static bool is_partition_composite(const char *name)
{
	for (int i = 0; i < zircon_partition_map_count; i++) {
		if (strcmp(name, zircon_partition_map[i].name)) {
			continue;
		}
		return zircon_partition_map[i].type ==
		       ZIRCON_PART_TYPE_COMPOSITE;
	}
	return false;
}

static int find_zircon_partition(const char *name,
				 zircon_partition_data_t *out_zircon_part);

static int determine_composite_partition_size(zircon_partition_data_t *part)
{
	// Determine a safe size for reading
	part->size = 0;
	bool image_offset_start_from_0 = false;
	for (uint32_t i = 0; i < part->sub_parts_count; i++) {
		const subpart_t *sub = &part->sub_parts[i];
		if (is_partition_composite(sub->name)) {
			fprintf(stderr,
				"Error: Nested composite partition is not allowed: "
				"%s contains %s\n",
				part->name, sub->name);
			return -1;
		}
		size_t sub_part_size = sub->image_size;
		if (sub_part_size == 0) {
			zircon_partition_data_t sub_part;
			if (find_zircon_partition(sub->name, &sub_part)) {
				fprintf(stderr,
					"Error: Failed to find sub-partition %s\n",
					sub->name);
			}
			sub_part_size = sub_part.size;
		}
		part->size = max((size_t)part->size,
				 sub->image_offset + sub_part_size);
		image_offset_start_from_0 =
			image_offset_start_from_0 || (!sub->image_offset);
	}
	if (!image_offset_start_from_0) {
		fprintf(stderr, "There must be a sub-partition with 0 "
				"image_offset\n");
		return -1;
	}
	return 0;
}

/**
 * find_zircon_partition() - Finds zircon partition.
 *
 * @name:		Zircon partition name
 * @out_zircon_part:	Outputs zircon partition
 *
 * If the partition name exists in the GPT and there does not exist an entry in
 * the hardcoded partition map with `prioritize_over_gpt` enabled, the GPT
 * partition is used.
 *
 * Otherwise, a `zircon_partition_data_t` is created from the hardcoded translation
 * layer.
 *
 * Return:	0 if OK, non-zero value on error.
 */
static int find_zircon_partition(const char *name,
				 zircon_partition_data_t *out_zircon_part)
{
	const zircon_partition_data_t *zircon_part = NULL;

	// The partition name must be able to fit in PART_NAME_LEN, including the
	// null terminator.
	if (strlen(name) + 1 > PART_NAME_LEN) {
		fprintf(stderr, "Error: partition name '%s' is too long\n",
			name);
		return -1;
	}

	for (int i = 0; i < zircon_partition_map_count; i++) {
		if (strcmp(name, zircon_partition_map[i].name)) {
			continue;
		}
		zircon_part = &zircon_partition_map[i];
	}

	struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
	if (!mmc) {
		fprintf(stderr, "Error: No MMC device found\n");
		return -1;
	}

	struct blk_desc *blk_desc = mmc_get_blk_desc(mmc);
	if (!blk_desc) {
		fprintf(stderr, "Error: mmc_get_blk_desc failed\n");
		return -1;
	}

	if (store_set_device(BOOT_EMMC)) {
		fprintf(stderr, "Error: Unable to set storage device\n");
		return -1;
	}

	struct partitions *part_info = find_mmc_partition_by_name(name);

	// If `name` is in `zircon_partition_map` and the GPT, check if it is
	// prioritized over the GPT partition.
	if (part_info && (!zircon_part ||
			  (zircon_part && !zircon_part->prioritize_over_gpt))) {
		strncpy(out_zircon_part->name, name, PART_NAME_LEN);
		out_zircon_part->type = ZIRCON_PART_TYPE_GPT_EMMC_USER;
		out_zircon_part->fastboot_locked_access =
			(zircon_part ? zircon_part->fastboot_locked_access : 0);
		strncpy(out_zircon_part->gpt_name, name, PART_NAME_LEN);
		out_zircon_part->gpt_offset = 0;
		out_zircon_part->abs_offset = part_info->offset;
		out_zircon_part->size = part_info->size;
		out_zircon_part->mmc = mmc;
		out_zircon_part->blk_desc = blk_desc;

		return 0;
	}

	if (!zircon_part) {
		return -1;
	}

	memcpy(out_zircon_part, zircon_part, sizeof(zircon_partition_data_t));

	out_zircon_part->mmc = mmc;
	out_zircon_part->blk_desc = blk_desc;

	switch (zircon_part->type) {
	case ZIRCON_PART_TYPE_GPT_EMMC_USER: {
		part_info = find_mmc_partition_by_name(zircon_part->gpt_name);

		if (!part_info) {
			fprintf(stderr,
				"Error: unable to find mapped gpt partition: %s, zircon partition: %s\n",
				zircon_part->gpt_name, zircon_part->name);
			return -1;
		}

		if (zircon_part->gpt_offset + zircon_part->size >
		    part_info->size) {
			fprintf(stderr,
				"Error: zircon partition, %s, exceeds its parent gpt partition, %s",
				zircon_part->name, zircon_part->gpt_name);
			return -1;
		}

		if (out_zircon_part->size == 0) {
			out_zircon_part->size =
				part_info->size - out_zircon_part->gpt_offset;
		}
		out_zircon_part->abs_offset =
			part_info->offset + zircon_part->gpt_offset;

		return 0;
	}
	case ZIRCON_PART_TYPE_GPT:
	case ZIRCON_PART_TYPE_BOOTLOADER:
	case ZIRCON_PART_TYPE_RAW_EMMC: {
		if (set_hwpart(blk_desc, zircon_part->hw_part)) {
			return -1;
		}

		if (zircon_part->lba_offset < 0) {
			out_zircon_part->lba_offset += blk_desc->lba;
		}

		if (out_zircon_part->lba_offset < 0 ||
		    out_zircon_part->lba_offset > blk_desc->lba) {
			fprintf(stderr, "Error: invalid block offset\n");
			reset_hwpart(blk_desc);
			return -1;
		}

		if (!zircon_part->lba_size) {
			out_zircon_part->lba_size =
				blk_desc->lba - out_zircon_part->lba_offset;
		}

		if (out_zircon_part->lba_size >
		    blk_desc->lba - out_zircon_part->lba_offset) {
			fprintf(stderr, "Error: lba size too large\n");
			reset_hwpart(blk_desc);
			return -1;
		}

		out_zircon_part->abs_offset =
			out_zircon_part->lba_offset * blk_desc->blksz;
		out_zircon_part->size =
			out_zircon_part->lba_size * blk_desc->blksz;

		return reset_hwpart(blk_desc);
	}
	case ZIRCON_PART_TYPE_COMPOSITE:
		return determine_composite_partition_size(out_zircon_part);
	}

	return -1;
}

/* === public API === */

zircon_partition *zircon_get_partition(const char *name)
{
	zircon_partition *part = calloc(1, sizeof(zircon_partition));
	zircon_partition_data_t *data =
		calloc(1, sizeof(zircon_partition_data_t));

	if (!part || !data) {
		fprintf(stderr, "calloc failed\n");
		return NULL;
	}

	part->data = data;

	if (find_zircon_partition(name, data)) {
		fprintf(stderr, "Error: Unable to find partition: %s\n", name);
		zircon_free_partition(part);
		return NULL;
	}

	part->size = data->size;

	switch (data->type) {
	case ZIRCON_PART_TYPE_GPT_EMMC_USER:
		part->read = gpt_part_read;
		part->write = gpt_part_write;
		part->erase = gpt_part_erase;
		break;

	case ZIRCON_PART_TYPE_RAW_EMMC:
		part->read = raw_emmc_read;
		part->write = raw_emmc_write;
		part->erase = raw_emmc_erase;
		break;

	case ZIRCON_PART_TYPE_BOOTLOADER:
		part->read = raw_emmc_read;
		part->write = bootloader_write;
		part->erase = bootloader_erase;
		break;

	case ZIRCON_PART_TYPE_GPT:
		part->read = raw_emmc_read;
		part->write = gpt_write;
		part->erase = gpt_erase;
		break;

	case ZIRCON_PART_TYPE_COMPOSITE:
		part->read = composite_part_read;
		part->write = composite_part_write;
		part->erase = composite_part_erase;
		break;
	}

	return part;
}

zircon_partition *zircon_get_fastboot_partition(const char *name)
{
	bool unlocked;
	if (zircon_vboot_is_unlocked(&unlocked)) {
		fprintf(stderr, "Failed to get current lock/unlock state\n");
		return NULL;
	}

	zircon_partition *part = zircon_get_partition(name);
	if (!part) {
		return NULL;
	}

	// If we are not in dev build, check if access is dev only.
#if !defined(DEV_BUILD_CONFIG)
	if (part->data->fastboot_locked_access &
	    ZIRCON_PARTITION_ACCESS_DEV_ONLY) {
		part->write = NULL;
		part->erase = NULL;
		return part;
	}
#endif

	if (unlocked) {
		return part;
	}

	if (part->data->fastboot_locked_access &
	    ZIRCON_PARTITION_ACCESS_FLAG_WRITE) {
		return part;
	}
	part->write = NULL;

	if (part->data->fastboot_locked_access &
	    ZIRCON_PARTITION_ACCESS_FLAG_ERASE) {
		return part;
	}
	part->erase = NULL;

	return part;
}

void zircon_free_partition(zircon_partition *part)
{
	if (part) {
		free(part->data);
		free(part);
	}
}
