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

#include <config.h>
#include <common.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>

#include <aboot.h>
#include <abr/abr.h>
#include <abr/ops.h>
#include <amlogic/storage_if.h>
#include <libavb/libavb.h>
#include <nand.h>
#include <partition_table.h>

#include <zircon/boot/image.h>
#include <zircon-estelle/partition.h>
#include <zircon-estelle/zircon.h>

#include "sysconfig-header.h"
#include "abr-wear-leveling.h"
#include "fvm_ftl_image.h"

/* most NANDs have ERASE GRP which does not exceed 256K */
#define ERASE_GRP_SIZE_MAX (256 * 1024)

#if defined(ZPARTITION_DEBUG)
#define debugP(fmt...)                                                         \
	printf("[Dbg zircon partition]%s:%d:", __func__, __LINE__), printf(fmt)
#else
#define debugP(fmt...)
#endif

extern struct mtd_partition *get_aml_mtd_partition(void);
extern int get_aml_partition_count(void);

enum {
	PART_BL2,
	PART_TPL,
	PART_FTS,
	PART_FACTORY,
	PART_ZIRCON_R,
	PART_ZIRCON_A,
	PART_ZIRCON_B,
	PART_FVM,
	PART_SYS_CONFIG,
	PART_MIGRATION,
	PART_COUNT,
};

static zbi_partition_map_t partition_map = {
	// .block_count filled in below
	// .block_size filled in below
	.guid = {},
	.partition_count = PART_COUNT,
	.partitions = {
		       {
			.type_guid = GUID_BL2_VALUE,
			.name = "bl2",
			},
		       {
			.type_guid = GUID_BOOTLOADER_VALUE,
			.name = "tpl",
			},
		       {
			.name = "fts",
			},
		       {
			.name = "factory",
			},
		       {
			.type_guid = GUID_ZIRCON_R_VALUE,
			.name = ZIRCON_PARTITION_PREFIX"r",
			},
		       {
			.type_guid = GUID_ZIRCON_A_VALUE,
			.name = ZIRCON_PARTITION_PREFIX"a",
			},
		       {
			.type_guid = GUID_ZIRCON_B_VALUE,
			.name = ZIRCON_PARTITION_PREFIX"b",
			},
		       {
			.type_guid = GUID_FVM_VALUE,
			.name = "fvm",
			},
		       {
			.type_guid = GUID_SYS_CONFIG_VALUE,
			.name = "sys-config",
			},
		       {
			.name = "migration",
			},
		       },
};

// This is the partition map passed to the ZBI.
// It is copied from partition_map below and modified to
// match the zircon partition naming scheme.
// The number of partitions must match PART_COUNT.
static zbi_partition_map_t zbi_partition_map = {
	.partitions = { {}, {}, {}, {}, {}, {}, {}, {}, {}, {} }
};

static nand_info_t *bl2_nand_info = &nand_info[0];
static nand_info_t *data_nand_info = &nand_info[1];

#define SYS_CFG_NUM_OF_COPIES 4

static void init_partition_map(void)
{
	struct mtd_partition *tpl_part = NULL;
	struct mtd_partition *fts_part = NULL;
	struct mtd_partition *factory_part = NULL;
	struct mtd_partition *recovery_part = NULL;
	struct mtd_partition *boot_part = NULL;
	struct mtd_partition *system_part = NULL;
	struct mtd_partition *sys_config_part = NULL;
	struct mtd_partition *migration_part = NULL;
	struct mtd_partition *partitions = get_aml_mtd_partition();
	int partition_count = get_aml_partition_count();
	int i;
	static int init_done = 0;

	if (init_done) {
		return;
	}

	for (i = 0; i < partition_count; i++) {
		struct mtd_partition *part = &partitions[i];
		if (!strcmp("tpl", part->name)) {
			tpl_part = part;
		} else if (!strcmp("fts", part->name)) {
			fts_part = part;
		} else if (!strcmp("factory", part->name)) {
			factory_part = part;
		} else if (!strcmp("recovery", part->name)) {
			recovery_part = part;
		} else if (!strcmp("boot", part->name)) {
			boot_part = part;
		} else if (!strcmp("system", part->name)) {
			system_part = part;
		} else if (!strcmp("sys-config", part->name)) {
			sys_config_part = part;
		} else if (!strcmp("migration", part->name)) {
			migration_part = part;
		}
	}

	if (!tpl_part) {
		printf("could not find tpl partition\n");
		return;
	}
	if (!fts_part) {
		printf("could not find fts partition\n");
		return;
	}
	if (!factory_part) {
		printf("could not find factory partition\n");
		return;
	}
	if (!recovery_part) {
		printf("could not find recovery partition\n");
		return;
	}
	if (!boot_part) {
		printf("could not find boot partition\n");
		return;
	}
	if (!system_part) {
		printf("could not find system partition\n");
		return;
	}
	if (!sys_config_part) {
		printf("could not find sys-config partition\n");
		return;
	}
	if (!migration_part) {
		printf("could not find migration partition\n");
		return;
	}

	uint32_t bl2_block_size = bl2_nand_info->writesize;
	uint64_t bl2_size = bl2_nand_info->size;

	partition_map.partitions[PART_BL2].first_block = 0;
	partition_map.partitions[PART_BL2].last_block =
		(bl2_size / bl2_block_size) - 1;

	uint32_t block_size = data_nand_info->writesize;
	uint64_t total_size = data_nand_info->size;

	partition_map.block_size = block_size;
	partition_map.block_count = total_size / block_size;

	/* map tpl partition to BOOTLOADER */
	partition_map.partitions[PART_TPL].first_block =
		tpl_part->offset / block_size;
	partition_map.partitions[PART_TPL].last_block =
		((tpl_part->offset + tpl_part->size) / block_size) - 1;
	/* map fts partition to "fts" */
	partition_map.partitions[PART_FTS].first_block =
		fts_part->offset / block_size;
	partition_map.partitions[PART_FTS].last_block =
		((fts_part->offset + fts_part->size) / block_size) - 1;
	/* map factory partition to "factory" */
	partition_map.partitions[PART_FACTORY].first_block =
		factory_part->offset / block_size;
	partition_map.partitions[PART_FACTORY].last_block =
		((factory_part->offset + factory_part->size) / block_size) - 1;
	/* map recovery partition to ZIRCON_R */
	partition_map.partitions[PART_ZIRCON_R].first_block =
		recovery_part->offset / block_size;
	partition_map.partitions[PART_ZIRCON_R].last_block =
		((recovery_part->offset + recovery_part->size) / block_size) -
		1;
	/* map boot partition to ZIRCON_A */
	partition_map.partitions[PART_ZIRCON_A].first_block =
		boot_part->offset / block_size;
	partition_map.partitions[PART_ZIRCON_A].last_block =
		((boot_part->offset + boot_part->size) / block_size) - 1;
	/* ZIRCON_B partition at start of system */
	partition_map.partitions[PART_ZIRCON_B].first_block =
		system_part->offset / block_size;
	partition_map.partitions[PART_ZIRCON_B].last_block =
		partition_map.partitions[PART_ZIRCON_B].first_block +
		(boot_part->size / block_size) - 1;
	/* FVM follows ZIRCON_B and extends to SYS_CONFIG */
	partition_map.partitions[PART_FVM].first_block =
		partition_map.partitions[PART_ZIRCON_B].last_block + 1;
	partition_map.partitions[PART_FVM].last_block =
		sys_config_part->offset / block_size - 1;
	/* map sys-config partition to SYS_CONFIG */
	partition_map.partitions[PART_SYS_CONFIG].first_block =
		sys_config_part->offset / block_size;
	partition_map.partitions[PART_SYS_CONFIG].last_block =
		((sys_config_part->offset + sys_config_part->size) /
		 block_size) -
		1;
	/* map migration partition to MIGRATION */
	partition_map.partitions[PART_MIGRATION].first_block =
		migration_part->offset / block_size;
	partition_map.partitions[PART_MIGRATION].last_block =
		((migration_part->offset + migration_part->size) / block_size) -
		1;

	assert(sys_config_part->size ==
	       SYS_CFG_NUM_OF_COPIES * data_nand_info->erasesize);

	assert(data_nand_info->erasesize <= ERASE_GRP_SIZE_MAX);

	uint64_t partition_map_size =
		sizeof(zbi_partition_map_t) +
		partition_map.partition_count * sizeof(zbi_partition_t);

	memcpy(&zbi_partition_map, &partition_map, partition_map_size);

	// Replace first underscore in each partition name with a dash.
	for (i = 0; i < zbi_partition_map.partition_count; i++) {
		char *underscore =
			strchr(zbi_partition_map.partitions[i].name, '_');
		if (underscore) {
			*underscore = '-';
		}
	}

	printf("Zircon partitions:\n");
	for (i = 0; i < PART_COUNT; i++) {
		printf("  0x%016llx - 0x%016llx : %s\n",
		       zbi_partition_map.partitions[i].first_block * block_size,
		       (zbi_partition_map.partitions[i].last_block + 1) *
			       block_size,
		       zbi_partition_map.partitions[i].name);
	}

	init_done = 1;
	return;
}

/**
 * Defines image types, which specify the expected contents of the partition.
 */
enum sys_config_img_type {
	IMG_TYPE_ANY, // Expected data is not erased (all 0xff)
	IMG_TYPE_VBMETA, // Expected data is a valid vbmeta image
	IMG_TYPE_ABR_META, // Expected data is valid ABR metadata
	IMG_TYPE_HEADER, // Expected data is syconfig header.
	IMG_TYPE_ABR_META_WEAR_LEVELING // Expected data is Abr metadata in wear-leveling.
};

const struct sysconfig_header *get_sysconfig_header(void);

/**
 * If a previous erase / write was interrupted by for ex. a power failure,
 * sys-config might be in an inconsistent state. For example, the first copy
 * could be erased, but with nothing written. This function provides a heuristic
 * to check if it is likely that the image is valid.
 *
 * For unknown image types, it checks if there is non-erased data in the region.
 * For VBMeta and A/B/R metadata, it verifies that the image is valid,
 * but not necessarily correct.
 */
static bool is_sys_config_img_likely_valid(const unsigned char *data,
					   size_t size,
					   enum sys_config_img_type img_type)
{
	switch (img_type) {
	case IMG_TYPE_ANY: {
		size_t i;
		for (i = 0; i < size; i++) {
			if (data[i] != 0xFF) {
				return true;
			}
		}
		return false;
	}

	case IMG_TYPE_VBMETA: {
		AvbVBMetaVerifyResult avb_res = avb_vbmeta_image_verify(
			data, size, /*out_public_key_data =*/NULL,
			/*out_public_key_length =*/NULL);
		return (avb_res == AVB_VBMETA_VERIFY_RESULT_OK);
	}

	case IMG_TYPE_ABR_META: {
		return AbrIsValidMetadata(data, size);
	}

	case IMG_TYPE_HEADER: {
		return sysconfig_header_valid(
			(const struct sysconfig_header *)data, PAGE_SIZE,
			ERASE_GRP_SIZE_MAX);
	}

	case IMG_TYPE_ABR_META_WEAR_LEVELING: {
		struct abr_metadata_ext latest;
		find_latest_abr_metadata_page(get_sysconfig_header(), data,
					      PAGE_SIZE, &latest);
		return AbrIsValidMetadata(latest.abr_data,
					  sizeof(latest.abr_data));
	}
	}
	return false;
}

static unsigned char sys_cfg_read_buf[ERASE_GRP_SIZE_MAX];
static unsigned char sys_cfg_write_buf[ERASE_GRP_SIZE_MAX];
static unsigned char sys_cfg_erase_buf[ERASE_GRP_SIZE_MAX];

#define NAND_READ_RETRIES 3
/**
 * The sys-config partition contains 4 replicated copies, each of which are the
 * size of an erase block. This tries to read each copy 3 times until a read
 * succeeds. This mitigates transient read failures.
 *
 * offset and size must be multiples of the NAND page size (normally 4096)
 */
static int read_from_sys_config(uint64_t offset, unsigned char *data,
				size_t size, enum sys_config_img_type img_type)
{
	init_partition_map();

	if (offset % data_nand_info->writesize ||
	    size % data_nand_info->writesize) {
		fprintf(stderr, "sys_config: ERROR: unaligned size / offset\n");
		return -1;
	}

	if ((offset + size) > data_nand_info->erasesize) {
		fprintf(stderr,
			"sys_config: ERROR: read overflows partition\n");
		return -1;
	}

	uint64_t sys_cfg_offset =
		partition_map.partitions[PART_SYS_CONFIG].first_block *
		partition_map.block_size;

	int ret = -1;

	int copy, retry;

	// at least one copy has to be read without error
	for (copy = 0; copy < SYS_CFG_NUM_OF_COPIES; copy++) {
		uint64_t copy_offset =
			sys_cfg_offset + (copy * data_nand_info->erasesize);
		uint64_t read_offset = copy_offset + offset;

		if (nand_block_isbad(data_nand_info, copy_offset)) {
			printf("sys_config: bad block @ 0x%llx, ignored for reading\n",
			       copy_offset);
			continue;
		}

		bool read_succeeded = false;

		for (retry = 0; retry < NAND_READ_RETRIES; retry++) {
			size_t len = size;

			if (!nand_read(data_nand_info, read_offset, &len,
				       sys_cfg_read_buf) &&
			    len == size) {
				read_succeeded = true;
				break;
			}

			fprintf(stderr,
				"sys_config: failed to read %zu bytes @ %llu (copy: %d, try: %d)\n",
				size, read_offset, copy, retry);
		} // Retry for loop

		if (!read_succeeded) {
			fprintf(stderr, "sys_config: failed to read copy %d\n",
				copy);
			continue;
		}

		// Return 0 if any read succeeds.
		ret = 0;
		memcpy(data, sys_cfg_read_buf, size);

		// Return if the contents look valid. If not, read the backup
		// copies. The copies should only differ in contents if a failure
		// occurs while writing.
		if (is_sys_config_img_likely_valid(data, size, img_type)) {
			return 0;
		}
		fprintf(stderr,
			"sys_config: Read copy %d, but contents look invalid (type: %d).\n",
			copy, img_type);

	} // Copies for loop

	if (ret) {
		fprintf(stderr, "sys_config: ERROR failed to read any copy!\n");
	}

	return ret;
}

typedef enum nand_block_write_result {
	NAND_BLOCK_WRITE_SUCCESS,
	NAND_BLOCK_WRITE_ERROR,
	NAND_BLOCK_WRITE_MARKBAD
} nand_block_write_result_t;

/**
 * The function support two modes for writing to sys-config.
 *
 * SYSCONFIG_READ_UPDATE_ERASE_WRITE:
 * Existing data is first read into a buffer. New data is updated in the
 * buffer. Last, the buffer is written to storage using normal erase-write
 * flow. This mode only changes |size| of data on storage from |offset|.
 * Otherdata remains the same.
 *
 * SYSCONFIG_ERASE_WRITE:
 * Erase sysconfig and write |size| of data from |offset|. Memory space
 * not in the specified range remains in an erased state.
 *
 * offset must be a multiple of writesize (normally 4096)
 *
 * size can be unaligned.
 */
typedef enum write_to_sys_config_mode {
	SYSCONFIG_READ_UPDATE_ERASE_WRITE,
	SYSCONFIG_ERASE_WRITE,
} write_to_sys_config_mode_t;

static nand_block_write_result_t sys_config_mark_copy_bad(uint64_t copy_offset)
{
	// Block will be marked bad.
	printf("sys_config: copy @ %llx will be marked bad.\n", copy_offset);
	if (mtd_block_markbad(data_nand_info, copy_offset)) {
		fprintf(stderr, "sys_config: Failed to mark copy bad");
		return NAND_BLOCK_WRITE_ERROR;
	}
	return NAND_BLOCK_WRITE_MARKBAD;
}

static nand_block_write_result_t
sys_config_write_copy(uint64_t sys_cfg_offset, int copy,
		      const unsigned char *data, size_t size,
		      uint64_t in_copy_offset)
{
	uint64_t copy_offset =
		sys_cfg_offset + (copy * data_nand_info->erasesize);
	if (nand_erase(data_nand_info, copy_offset,
		       data_nand_info->erasesize)) {
		printf("sys_config: Failed to erase copy @ 0x%llx\n",
		       copy_offset);
		return sys_config_mark_copy_bad(copy_offset);
	}
	printf("sys_config: Erased copy %d\n", copy);

	size_t written = size;
	if (nand_write(data_nand_info, copy_offset + in_copy_offset, &written,
		       (unsigned char *)data) ||
	    written != size) {
		printf("sys_config: Failed to write copy @ 0x%llx\n",
		       copy_offset);
		return sys_config_mark_copy_bad(copy_offset);
	}
	return NAND_BLOCK_WRITE_SUCCESS;
}

static int write_to_sys_config_mode_opt(uint64_t offset,
					const unsigned char *data, size_t size,
					write_to_sys_config_mode_t mode)
{
	int ret = -1;

	init_partition_map();

	if (offset % data_nand_info->writesize) {
		fprintf(stderr, "sys_config: ERROR: unaligned offset\n");
		return -1;
	}

	if (size == 0) {
		return 0;
	}

	if ((offset + size) > data_nand_info->erasesize) {
		fprintf(stderr,
			"sys_config: ERROR: write overflows partition\n");
		return -1;
	}

	uint64_t sys_cfg_offset =
		partition_map.partitions[PART_SYS_CONFIG].first_block *
		partition_map.block_size;

	// Skip reading existing data if overwriting the entire partition
	if (!(offset == 0 && size == data_nand_info->erasesize) &&
	    mode == SYSCONFIG_READ_UPDATE_ERASE_WRITE) {
		if (read_from_sys_config(0, sys_cfg_write_buf,
					 data_nand_info->erasesize,
					 IMG_TYPE_ANY)) {
			fprintf(stderr, "sys_config: read failed\n");
			return -1;
		}
	}

	// Update buffer with new data.
	memcpy(sys_cfg_write_buf + offset, data, size);

	uint64_t write_offset = 0;
	size_t write_len, expected_write_len;
	if (mode == SYSCONFIG_READ_UPDATE_ERASE_WRITE) {
		expected_write_len = data_nand_info->erasesize;
		write_offset = 0;
	} else if (mode == SYSCONFIG_ERASE_WRITE) {
		expected_write_len = size;
		write_offset = offset;
	} else {
		fprintf(stderr, "sys_config: Unknown mode: %d\n", (int)mode);
		return -1;
	}
	write_len = expected_write_len;

	int copy;
	for (copy = 0; copy < SYS_CFG_NUM_OF_COPIES; copy++) {
		uint64_t copy_offset =
			sys_cfg_offset + (copy * data_nand_info->erasesize);

		if (nand_block_isbad(data_nand_info, copy_offset)) {
			printf("sysconfig: Bad block @ %llx, skipping\n",
			       copy_offset);
			continue;
		}

		size_t read_len = data_nand_info->erasesize;

		// Read contents of this specific copy for the following optimizations.
		//  - Skip erase/write if the contents are the same.
		// If read fails, continue with erase/write.
		if (!nand_read(data_nand_info, copy_offset, &read_len,
			       sys_cfg_read_buf) &&
		    read_len == data_nand_info->erasesize) {
			if (!memcmp(sys_cfg_read_buf, sys_cfg_write_buf,
				    read_len)) {
				printf("sys_config: Skipping write to copy %d - same data as already exists\n",
				       copy);
				ret = 0;
				continue;
			}
		}

		if (sys_config_write_copy(
			    sys_cfg_offset, copy, sys_cfg_write_buf, write_len,
			    write_offset) == NAND_BLOCK_WRITE_SUCCESS) {
			ret = 0;
		}
	}

	if (ret) {
		fprintf(stderr,
			"sys_config: ERROR: Failed to write any copies!\n");
	}

	return ret;
}

static int write_to_sys_config(uint64_t offset, const unsigned char *data,
			       size_t size)
{
	return write_to_sys_config_mode_opt(offset, data, size,
					    SYSCONFIG_READ_UPDATE_ERASE_WRITE);
}

/**
 * erases subset of sys-config.
 *
 * offset and size must be multiples of writesize (normally 4096)
 */
static int erase_at_sys_config(uint64_t offset, size_t size)
{
	if ((offset + size) > data_nand_info->erasesize) {
		fprintf(stderr,
			"sys_config: ERROR: erase overflows partition\n");
		return -1;
	}

	if (offset % data_nand_info->writesize ||
	    size % data_nand_info->writesize) {
		fprintf(stderr, "sys_config: ERROR: unaligned offset\n");
		return -1;
	}

	// erase writes 0xff to the specified region.
	memset(sys_cfg_erase_buf, 0xff, size);

	return write_to_sys_config(offset, sys_cfg_erase_buf, size);
}

const zbi_partition_t *get_partition_by_name(const char *name)
{
	int i;
	if (name == NULL)
		return NULL;

	/* init partition layout in case it was not initialized already */
	init_partition_map();
	for (i = 0; i < PART_COUNT; i++) {
		if (!strncmp(partition_map.partitions[i].name, name,
			     ZBI_PARTITION_NAME_LEN)) {
			return &partition_map.partitions[i];
		}
	}

	return NULL;
}

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

const zbi_partition_map_t *zircon_get_partition_map(void)
{
	/* init partition layout in case it was not initialized already */
	init_partition_map();
	return &zbi_partition_map;
}

/*
 * ABR and AVBs metadatas are located on 'sys-config' partition.
 * 'sys-config' partition has following layout:
 * 00000 - 0EFFF  (60K) sys-config data
 * 0F000 - 0FFFF   (4K) A/B/R metadata
 * 10000 - 1FFFF  (64K) AVB -a metadata
 * 20000 - 2FFFF  (64K) AVB -b metadata
 * 30000 - 3FFFF  (64K) AVB -r metadata
 */
#define ABR_OFFSET 0x0F000
#define AVB_A_OFFSET 0x10000
#define AVB_B_OFFSET 0x20000
#define AVB_R_OFFSET 0x30000
#define SYSCONFIG_DATA_SIZE (60 * 1024)
#define ABR_SIZE (4 * 1024)
#define AVB_SIZE (64 * 1024)

static const struct sysconfig_header legacy_sysconfig_layout = {
	.magic = SYSCONFIG_HEADER_MAGIC_ARRAY,
	.sysconfig_data = { 0, SYSCONFIG_DATA_SIZE },
	.abr_metadata = { ABR_OFFSET, ABR_SIZE },
	.vb_metadata_a = { AVB_A_OFFSET, AVB_SIZE },
	.vb_metadata_b = { AVB_B_OFFSET, AVB_SIZE },
	.vb_metadata_r = { AVB_R_OFFSET, AVB_SIZE },
	.crc_value = 2716817057, // the value is precomputed
};

/*
 * Used for storing header loaded from storage.
 * It will only be loaded once, assuming that header from storage won't change.
 */
static struct sysconfig_header sysconfig_header_from_storage = {
	.magic = { 0 },
};

/*
 * A pointer for current header in use. If valid, it is returned by
 * get_sysconfig_header
 */
static const struct sysconfig_header *sysconfig_header_in_use = NULL;

const struct sysconfig_header *get_sysconfig_header(void)
{
	if (sysconfig_header_in_use) {
		return sysconfig_header_in_use;
	}

	uint8_t buf[PAGE_SIZE];
	int status;

	if ((status = read_from_sys_config(0, buf, PAGE_SIZE,
					   IMG_TYPE_HEADER))) {
		// When fail to read from storage, i.e. due to ecc error, default
		// to legacy header to try our best to boot into OS and also allow
		// partition writing to proceed for recovery.
		debugP("Failed to read sysconfig header from storage. "
		       "Default to legacy layout. %d\n",
		       status);
		return sysconfig_header_in_use = &legacy_sysconfig_layout;
	}

	struct sysconfig_header *header = (struct sysconfig_header *)buf;
	if (!sysconfig_header_valid(header, PAGE_SIZE, ERASE_GRP_SIZE_MAX)) {
		printf("Sysconfig does not contain a valid header. Default to legacy layout\n");
		return sysconfig_header_in_use = &legacy_sysconfig_layout;
	}

	sysconfig_header_from_storage = *header;
	return sysconfig_header_in_use = &sysconfig_header_from_storage;
}

uint32_t sysconfig_header_crc32(uint32_t crc, const uint8_t *buf, size_t len)
{
	return crc32(crc, buf, len);
}

static int abr_wear_leveling_read(uint64_t offset, unsigned char *data,
				  size_t size, int *page_index)
{
	int read_status;

	const struct sysconfig_header *header = get_sysconfig_header();
	offset += header->abr_metadata.offset;

	// If the layout have not been organized to support wear-leveling,
	// fall back to normal read.
	if (!layout_support_wear_leveling(header, PAGE_SIZE)) {
		if (page_index) {
			*page_index = -1;
		}
		return read_from_sys_config(offset, data, size,
					    IMG_TYPE_ABR_META);
	}

	// read entire abr sub-partition
	if ((read_status = read_from_sys_config(
		     offset, sys_cfg_read_buf, header->abr_metadata.size,
		     IMG_TYPE_ABR_META_WEAR_LEVELING))) {
		return read_status;
	}

	struct abr_metadata_ext latest;
	int idx = find_latest_abr_metadata_page(header, sys_cfg_read_buf,
						PAGE_SIZE, &latest);
	if (page_index) {
		*page_index = idx;
	}
	memcpy(data, &latest, min(size, sizeof(latest)));
	return 0;
}

/*
 * Writes new abr metadata while resetting the other pages in the sub-partition
 * to be empty. Specifically, it write the new data at the first page and reset
 * all other pages to empty. This is used when there are no empty page to write
 * or abr_wear_leveling_write_append fails.
 */
static int abr_wear_leveling_write_reset(uint64_t offset,
					 const uint8_t *new_abr_data,
					 size_t size,
					 const struct sysconfig_header *header,
					 uint8_t *data_on_storage);

/*
 * The function find a write new abr metadata to an empty page.
 */
static int abr_wear_leveling_write_append(uint64_t offset,
					  const uint8_t *new_abr_data,
					  size_t size,
					  const struct sysconfig_header *header,
					  const uint8_t *data_on_storage);

static int abr_wear_leveling_write(uint64_t offset, const unsigned char *data,
				   size_t size, bool force_reset)
{
	int read_status;

	const struct sysconfig_header *header = get_sysconfig_header();
	if (!layout_support_wear_leveling(header, PAGE_SIZE)) {
		return write_to_sys_config(offset + header->abr_metadata.offset,
					   data, size);
	}

	// Read current data from storage.
	if ((read_status =
		     read_from_sys_config(offset, sys_cfg_write_buf,
					  ERASE_GRP_SIZE_MAX, IMG_TYPE_ANY))) {
		return read_status;
	}

	// Always try append first. Unless |force_reset| is set.
	// But if any of the following happens:
	// 	1) no empty page is found
	// 	2) write append fails
	// fall back to normal write-flow (erase + write)
	if (force_reset ||
	    abr_wear_leveling_write_append(offset, data, size, header,
					   sys_cfg_write_buf)) {
		debugP("Abr metadata append fails. Fall back to erase + write flow\n");
		return abr_wear_leveling_write_reset(offset, data, size, header,
						     sys_cfg_write_buf);
	}
	return 0;
}

static int abr_wear_leveling_write_reset(uint64_t offset,
					 const uint8_t *new_abr_data,
					 size_t size,
					 const struct sysconfig_header *header,
					 uint8_t *data_on_storage)
{
	// 1. write the new abr data at the 1st page.
	// 2. set the rest of pages allocated to abr sub-partition as empty (0xff).
	int status = 0;
	size_t start_abr = header->abr_metadata.offset;
	// Put the new abr metadata at the first page.
	struct abr_metadata_ext copy;
	memcpy(&copy, new_abr_data, sizeof(copy));
	set_abr_metadata_ext_magic(&copy);
	// Copy the new data to the first page.
	memcpy(&data_on_storage[start_abr], &copy, sizeof(copy));

	size_t write_len =
		ERASE_GRP_SIZE_MAX - header->abr_metadata.size + PAGE_SIZE;
	// Use mode SYSCONFIG_ERASE_WRITE for two reason:
	// 1. Avoid writing trailing empty pages (even 0xff) so that they are
	// truly safe for write later.
	// 2. It's possible that this call is due to a fall back from
	// abr_wear_leveling_write_append, in which case the storage may have
	// already been compromised and unreadable. Thus, it is necessary to
	// directly go into erase + write and avoid any read.
	if ((status = write_to_sys_config_mode_opt(
		     0, data_on_storage, write_len, SYSCONFIG_ERASE_WRITE))) {
		debugP("Failed to write to sys-config partition. %d\n", status);
		return status;
	}
	return 0;
}

static int abr_wear_leveling_write_append(uint64_t offset,
					  const uint8_t *new_abr_data,
					  size_t size,
					  const struct sysconfig_header *header,
					  const uint8_t *data_on_storage)
{
	int ret = 0;
	int64_t candidate;
	// Find an empty page to write.
	if (!find_empty_page_for_wear_leveling(
		    header, &data_on_storage[header->abr_metadata.offset],
		    PAGE_SIZE, &candidate)) {
		debugP("Cannot find an empty page to write\n");
		return -1;
	}

	// Prepare the new abr metadata
	uint8_t write_buf[PAGE_SIZE] = { 0 };
	struct abr_metadata_ext copy;
	memcpy(&copy, new_abr_data, sizeof(copy));
	set_abr_metadata_ext_magic(&copy);
	memcpy(write_buf, &copy, sizeof(copy));

	nand_info_t *nand = &nand_info[nand_curr_device];
	assert(nand->erasesize <= ERASE_GRP_SIZE_MAX);
	assert((offset + size) <= nand->erasesize);

	// Write new abr metadata at <page_index> offset in abr for each copy.
	debugP("Attempt to append new abr metadata at page %lld\n", candidate);

	uint64_t start_abr = header->abr_metadata.offset;
	int i;
	for (i = 0; i < SYS_CFG_NUM_OF_COPIES; i++) {
		debugP("Append new abr metadata for copy %d\n", i);
		if (store_write_ops((unsigned char *)"sys-config", write_buf,
				    i * nand->erasesize + start_abr +
					    (uint64_t)candidate * PAGE_SIZE,
				    PAGE_SIZE)) {
			return __LINE__;
		}
	}

	// The following double-checks that the written data can be correctly read
	// back without failures. Returns error if not. It will lead the caller to
	// fall back to abr_wear_leveling_write_reset.
	uint8_t read_back_buffer[PAGE_SIZE];
	if ((ret = abr_wear_leveling_read(offset, read_back_buffer, PAGE_SIZE,
					  NULL))) {
		debugP("Failed while reading back for validation. %d\n", ret);
		return ret;
	}

	if (memcmp(&copy, read_back_buffer, sizeof(struct abr_metadata_ext))) {
		debugP("Validation failed. Read is different from write\n");
		return -1;
	}

	debugP("Successfully write abr metadata at page %zu without erase.\n",
	       candidate);
	return 0;
}

int abr_wear_leveling_reset_pages(void)
{
	uint8_t buffer[PAGE_SIZE];
	int page_idx;
	int status = abr_wear_leveling_read(0, buffer, PAGE_SIZE, &page_idx);
	if (status) {
		debugP("Failed to read from abr wear-leveling\n");
		return status;
	}

	if (page_idx == -1 || page_idx == 0) {
		return 0;
	}

	status = abr_wear_leveling_write(0, buffer, PAGE_SIZE, true);
	if (status) {
		debugP("Failed to write abr wear-leveling page\n");
		return status;
	}

	return 0;
}

#define OOB_SIZE 8
#define PAGE_PLUS_OOB_SIZE (PAGE_SIZE + OOB_SIZE)
#define BLOCK_WITH_OOB_SIZE                                                    \
	((ERASE_GRP_SIZE_MAX / PAGE_SIZE) * PAGE_PLUS_OOB_SIZE)

// Assume that the layout of data is:
// page->oob->page->oob->.....
static nand_block_write_result_t
raw_nand_write_block(size_t offset, const uint8_t *data, size_t size)
{
	if (size > BLOCK_WITH_OOB_SIZE) {
		printf("Cannot write more than one block of raw nand data\n");
		return -1;
	}

	// Allocate a dedicated buffer to make sure its DMA aligned.
	uint8_t *page_buffer = (uint8_t *)memalign(
		ARCH_DMA_MINALIGN, ROUNDUP(PAGE_SIZE, ARCH_DMA_MINALIGN));
	if (!page_buffer) {
		printf("Failed to allocate page buffer.\n");
		return -1;
	}

	const size_t pages = size / (PAGE_PLUS_OOB_SIZE);
	int ret = NAND_BLOCK_WRITE_SUCCESS;
	size_t i = 0;
	for (; i < pages; i++) {
		const uint8_t *page_data = data + i * PAGE_PLUS_OOB_SIZE;
		const uint8_t *oob = page_data + PAGE_SIZE;
		memcpy(page_buffer, page_data, PAGE_SIZE);
		size_t physical_offset = offset + i * PAGE_SIZE;
		struct mtd_oob_ops ops = {
			.mode = MTD_OPS_AUTO_OOB,
			.len = PAGE_SIZE,
			.ooblen = OOB_SIZE,
			.ooboffs = 0,
			.datbuf = page_buffer,
			.oobbuf = (uint8_t *)oob,
		};
		int result =
			mtd_write_oob(data_nand_info, physical_offset, &ops);
		if (result) {
			printf("Fail to write page @ %lx\n", physical_offset);
			ret = NAND_BLOCK_WRITE_ERROR;
			break;
		}

		if (ops.retlen != ops.len || ops.oobretlen != ops.ooblen) {
			printf("@ address %lx. Expect to write %zu of data, %zu of obb. "
			       "Actually write %zu of data, %zu of oob\n",
			       physical_offset, ops.len, ops.ooblen, ops.retlen,
			       ops.oobretlen);
			ret = NAND_BLOCK_WRITE_ERROR;
			break;
		}
	}

	free(page_buffer);
	return ret;
}

// Setting data = NULL equivalently performs an erase or mark bad operation.
static nand_block_write_result_t
raw_nand_write_block_or_mark_bad(size_t offset, const uint8_t *data,
				 size_t size, int retry)
{
	int attempt = 0;
	for (; attempt < retry; attempt++) {
		// We are not sure if previous attempt has written any data,
		// so erase the block first.
		int ret = nand_erase(data_nand_info, offset,
				     data_nand_info->erasesize);
		if (ret) {
			continue;
		}

		if (!data || raw_nand_write_block(offset, data, size) ==
				     NAND_BLOCK_WRITE_SUCCESS) {
			return NAND_BLOCK_WRITE_SUCCESS;
		}
	}

	// Mark the block bad
	printf("failed %d times erasing/writing @ %lx. block will be marked bad.\n",
	       attempt, offset);
	int ret = mtd_block_markbad(data_nand_info, offset);
	if (ret) {
		printf("failed to mark block @ %lx bad.\n", offset);
		return NAND_BLOCK_WRITE_ERROR;
	}
	return NAND_BLOCK_WRITE_MARKBAD;
}

#define RAW_NAND_RETRIES_BEFORE_MARKBAD 3

/**
 * Erase all blocks in memory space from |offset| to |offset + size|,
 * marking blocks as bad if necessary.
 */
static int raw_nand_erase_or_markbad(size_t offset, size_t size)
{
	size_t curr = offset, end = offset + size;
	for (; curr < end; curr += data_nand_info->erasesize) {
		if (nand_block_isbad(data_nand_info, curr)) {
			printf("skipping erasing bad block @ %lx\n", curr);
			continue;
		}

		nand_block_write_result_t ret =
			raw_nand_write_block_or_mark_bad(
				curr, NULL, 0, RAW_NAND_RETRIES_BEFORE_MARKBAD);
		if (ret == NAND_BLOCK_WRITE_ERROR) {
			return -1;
		}
	}
	return 0;
}

int write_fvm_ftl_raw_image(size_t ptn_offset, size_t ptn_size,
			    const uint8_t *data, size_t size)
{
	const uint8_t *block_start = data;
	const uint8_t *end = data + size;

	if (size % PAGE_PLUS_OOB_SIZE) {
		printf("Image size is not a multiple of page + oob size.\n");
		return -1;
	}

	size_t write_offset = ptn_offset;
	while (block_start < end) {
		size_t write_size = min((size_t)BLOCK_WITH_OOB_SIZE,
					(size_t)(end - block_start));

		if (write_offset + write_size > ptn_offset + ptn_size) {
			printf("FVM partition write overflow\n");
			return -1;
		}

		// Skip known bad blocks.
		if (nand_block_isbad(data_nand_info, write_offset)) {
			printf("skipping writing bad block @ %lx\n",
			       write_offset);
			write_offset += data_nand_info->erasesize;
			continue;
		}
		// Assume that block starts in an erased state.
		nand_block_write_result_t ret = raw_nand_write_block(
			write_offset, block_start, write_size);
		if (ret != NAND_BLOCK_WRITE_SUCCESS) {
			ret = raw_nand_write_block_or_mark_bad(
				write_offset, block_start, write_size,
				RAW_NAND_RETRIES_BEFORE_MARKBAD);
			if (ret == NAND_BLOCK_WRITE_ERROR) {
				return -1;
			}
		}
		// Succeed or markbad, |write_offset| needs to move to the next block.
		write_offset += data_nand_info->erasesize;
		if (ret == NAND_BLOCK_WRITE_SUCCESS) {
			block_start += write_size;
		}
	}
	return 0;
}

int validate_fvm_ftl_image_header(const struct RawNandImageHeader *header)
{
	if (header->magic != FVM_FTL_IMAGE_MAGIC) {
		printf("Incorrect magic for fvm ftl image\n");
		return -1;
	}

	if (header->version_major != FVM_FTL_IMAGE_MAJOR) {
		printf("Major version is not supported");
		return -1;
	}

	if (header->page_size != PAGE_SIZE) {
		printf("Image page size %d does not match device (%d)\n",
		       header->page_size, PAGE_SIZE);
		return -1;
	}

	if (header->oob_size != OOB_SIZE) {
		printf("Image oob size %d does not match device (%d)\n",
		       header->oob_size, OOB_SIZE);
		return -1;
	}

	return 0;
}

int write_fvm_ftl_image(const uint8_t *data, size_t size)
{
	const zbi_partition_t *ptn = get_partition_by_name("fvm");
	// Notes: the |block_size| here is not the erase block size, but
	// rather the minimum write size.
	uint32_t block_size = partition_map.block_size;
	if (!ptn) {
		return -1;
	}

	uint64_t ptn_offset = ptn->first_block * block_size;
	uint64_t ptn_size =
		(ptn->last_block - ptn->first_block + 1) * block_size;

	struct RawNandImageHeader header;
	memcpy(&header, data, sizeof(header));
	if (validate_fvm_ftl_image_header(&header)) {
		return -1;
	}

	if (raw_nand_erase_or_markbad(ptn_offset, ptn_size)) {
		printf("Failed to erase fvm partition\n");
		return -1;
	}

	data += sizeof(header);
	size -= sizeof(header);
	if (header.format == FVM_FTL_IMAGE_RAW) {
		return write_fvm_ftl_raw_image(ptn_offset, ptn_size, data,
					       size);
	} else {
		printf("Unsupported fvm ftl image format\n");
		return -1;
	}
}

int zircon_partition_write(const char *name, uint64_t offset,
			   const unsigned char *data, size_t size)
{
	size_t sub_off;
	/* size has to be multiple of page size. Otherwise low level API will crash */
	assert((size % PAGE_SIZE) == 0);

	/* TODO (dmitryya@) move partition boundary check for offset + size here. */
	if (!strcmp(name, "sys-config")) {
		return write_to_sys_config(offset, data, size);
	} else if (!strcmp(name, "sysconfig-data")) {
		sub_off = get_sysconfig_header()->sysconfig_data.offset;
		return write_to_sys_config(offset + sub_off, data, size);
	} else if (!strcmp(name, "misc")) {
		sub_off = get_sysconfig_header()->abr_metadata.offset;
		return write_to_sys_config(offset + sub_off, data, size);
	} else if (!strcmp(name, "abr-wear-leveling")) {
		return abr_wear_leveling_write(offset, data, size, false);
	} else if (!strcmp(name, "vbmeta_a")) {
		sub_off = get_sysconfig_header()->vb_metadata_a.offset;
		return write_to_sys_config(offset + sub_off, data, size);
	} else if (!strcmp(name, "vbmeta_b")) {
		sub_off = get_sysconfig_header()->vb_metadata_b.offset;
		return write_to_sys_config(offset + sub_off, data, size);
	} else if (!strcmp(name, "vbmeta_r")) {
		sub_off = get_sysconfig_header()->vb_metadata_r.offset;
		return write_to_sys_config(offset + sub_off, data, size);
	} else if (!strcmp(name, "fvm")) {
		return write_fvm_ftl_image(data, size);
	} else { /* access to general partition */
		/* erase whole partition if not in sys-config. */
		if (zircon_partition_erase(name)) {
			fprintf(stderr, "erase failed\n");
			return -1;
		}

		const zbi_partition_t *ptn = get_partition_by_name(name);
		uint32_t block_size = partition_map.block_size;

		if (ptn != NULL) {
			int flags = 0;
			size_t len = size;
			uint64_t ptn_size =
				(ptn->last_block - ptn->first_block + 1) *
				block_size;
			loff_t flash_offset =
				ptn->first_block * block_size + offset;

			if (flash_offset > ptn->last_block * block_size) {
				return -1;
			}

			return nand_write_skip_bad(data_nand_info, flash_offset,
						   &len, NULL,
						   ptn_size - offset,
						   (u_char *)data, flags);
		}
	}

	return -1;
}

int zircon_partition_read(const char *name, uint64_t offset,
			  unsigned char *data, size_t size)
{
	size_t sub_off;
	/* size has to be multiple of page size. Otherwise low level API will crash */
	assert((size % PAGE_SIZE) == 0);

	/* TODO (dmitryya@) move partition boundary check for offset + size here. */
	if (!strcmp(name, "sys-config")) {
		return read_from_sys_config(offset, data, size, IMG_TYPE_ANY);
	} else if (!strcmp(name, "sysconfig-data")) {
		sub_off = get_sysconfig_header()->sysconfig_data.offset;
		return read_from_sys_config(offset + sub_off, data, size,
					    IMG_TYPE_ANY);
	} else if (!strcmp(name, "misc")) {
		sub_off = get_sysconfig_header()->abr_metadata.offset;
		return read_from_sys_config(offset + sub_off, data, size,
					    IMG_TYPE_ABR_META);
	} else if (!strcmp(name, "abr-wear-leveling")) {
		return abr_wear_leveling_read(offset, data, size, NULL);
	} else if (!strcmp(name, "vbmeta_a")) {
		sub_off = get_sysconfig_header()->vb_metadata_a.offset;
		return read_from_sys_config(offset + sub_off, data, size,
					    IMG_TYPE_VBMETA);
	} else if (!strcmp(name, "vbmeta_b")) {
		sub_off = get_sysconfig_header()->vb_metadata_b.offset;
		return read_from_sys_config(offset + sub_off, data, size,
					    IMG_TYPE_VBMETA);
	} else if (!strcmp(name, "vbmeta_r")) {
		sub_off = get_sysconfig_header()->vb_metadata_r.offset;
		return read_from_sys_config(offset + sub_off, data, size,
					    IMG_TYPE_VBMETA);
	} else { /* access to general partition */
		const zbi_partition_t *ptn = get_partition_by_name(name);
		uint32_t block_size = partition_map.block_size;

		if (ptn != NULL) {
			size_t len = size;
			uint64_t ptn_size =
				(ptn->last_block - ptn->first_block + 1) *
				block_size;
			loff_t flash_offset =
				ptn->first_block * block_size + offset;

			if (flash_offset > ptn->last_block * block_size) {
				return -1;
			}

			return nand_read_skip_bad(data_nand_info, flash_offset,
						  &len, NULL, ptn_size - offset,
						  data);
		}
	}

	return -1;
}

// Reads a single page (data + OOB) starting at byte |address| into |buffer|.
// Retries a few times on failure; |buffer| does not need to be aligned.
// Returns 0 on success.
static int read_oob_page(nand_info_t *nand, uint64_t address, uint8_t *buffer)
{
	// Normal page data buffer needs to be DMA-aligned, OOB does not.
	static uint8_t aligned_buffer[PAGE_SIZE] __aligned(ARCH_DMA_MINALIGN);

	struct mtd_oob_ops ops = {
		.mode = MTD_OPS_AUTO_OOB,
		.len = PAGE_SIZE,
		.ooblen = OOB_SIZE,
		.ooboffs = 0,
		.datbuf = aligned_buffer,
		.oobbuf = &buffer[PAGE_SIZE],
	};

	for (int i = 0; i < NAND_READ_RETRIES; ++i) {
		if (mtd_read_oob(nand, address, &ops) == 0) {
			memcpy(buffer, aligned_buffer, PAGE_SIZE);
			return 0;
		}

		printf("Warning: read #%d failed at 0x%llX\n", i + 1, address);
	}

	return -1;
}

int zircon_partition_read_oob(const char *name, uint64_t offset,
			      uint8_t *buffer, size_t size,
			      uint64_t *offset_out, size_t *size_out)
{
	init_partition_map();
	const zbi_partition_t *part = get_partition_by_name(name);
	if (part == NULL) {
		printf("Error: failed to find partition '%s'\n", name);
		return -1;
	}

	nand_info_t *nand =
		(strcmp(name, "bl2") == 0) ? bl2_nand_info : data_nand_info;

	// Existing code uses PAGE_SIZE/OOB_SIZE constants pretty heavily, so
	// we'll do the same here for consistency. For our purposes the NAND
	// configuration will always be constant, just double-check here to be
	// sure.
	if (nand->writesize != PAGE_SIZE) {
		printf("Error: expected %u NAND write size, got %u\n",
		       PAGE_SIZE, nand->writesize);
		return -1;
	}
	if (nand->oobavail < OOB_SIZE) {
		printf("Error: expected %u NAND OOB bytes, got %u\n", OOB_SIZE,
		       nand->oobavail);
		return -1;
	}

	if (offset % PAGE_SIZE) {
		printf("Error: cannot read from non-page-aligned offset 0x%llX\n",
		       offset);
		return -1;
	}

	// Since we define partitions boundaries in terms of pages they will all
	// by definition be page-aligned.
	const uint64_t part_start = part->first_block * PAGE_SIZE;
	const uint64_t part_end = (part->last_block + 1) * PAGE_SIZE;

	uint64_t read_addr = part_start + offset;
	if (read_addr >= part_end || read_addr < part_start) {
		printf("Error: partition offset overflow\n");
		return -1;
	}

	// Make sure we can fit at least one page in the output buffer.
	if (size < PAGE_PLUS_OOB_SIZE) {
		printf("Error: buffer too small for a data+OOB page\n");
		return -1;
	}

	// Keep reading until we run out of partition or buffer.
	const uint8_t *buffer_start = buffer;
	while (size >= PAGE_PLUS_OOB_SIZE && read_addr < part_end) {
		const char *error_code = NULL;

		// We need to track every page, even if we couldn't read it, so
		// that the caller knows the exact NAND state. Read failures
		// are marked by an 8-char string followed by zeros.
		if (nand_block_isbad(nand, read_addr)) {
			error_code = READ_OOB_ERROR_CODE_BAD_BLOCK;
		} else if (read_oob_page(nand, read_addr, buffer)) {
			error_code = READ_OOB_ERROR_CODE_READ_FAILURE;
		}

		if (error_code) {
			printf("Warning: [%s] on page 0x%llX-0x%llX\n",
			       error_code, read_addr,
			       read_addr + PAGE_SIZE - 1);
			memset(buffer, 0, PAGE_PLUS_OOB_SIZE);
			memcpy(buffer, error_code, strlen(error_code));
		}

		size -= PAGE_PLUS_OOB_SIZE;
		buffer += PAGE_PLUS_OOB_SIZE;
		read_addr += PAGE_SIZE;
	}

	*offset_out = (read_addr < part_end) ? read_addr : 0;
	*size_out = buffer - buffer_start;
	return 0;
}

int zircon_get_partititon_size(const char *name, uint64_t *size)
{
	assert(size != NULL);

	/* virtual partitions */
	if (!strcmp(name, "sys-config")) {
		*size = data_nand_info->erasesize;
		return 0;
	} else if (!strcmp(name, "sysconfig-data")) {
		*size = get_sysconfig_header()->sysconfig_data.size;
		return 0;
	} else if (!strcmp(name, "misc")) {
		*size = get_sysconfig_header()->abr_metadata.size;
		return 0;
	} else if (!strcmp(name, "abr-wear-leveling")) {
		*size = PAGE_SIZE;
		return 0;
	} else if (!strcmp(name, "vbmeta_a")) {
		*size = get_sysconfig_header()->vb_metadata_a.size;
		return 0;
	} else if (!strcmp(name, "vbmeta_b")) {
		*size = get_sysconfig_header()->vb_metadata_b.size;
		return 0;
	} else if (!strcmp(name, "vbmeta_r")) {
		*size = get_sysconfig_header()->vb_metadata_r.size;
		return 0;
	} else {
		/* general partition */
		/* init partition layout in case it was not initialized already */
		init_partition_map();
		uint32_t block_size = partition_map.block_size;
		const zbi_partition_t *ptn = get_partition_by_name(name);
		if (ptn != NULL) {
			*size = (ptn->last_block - ptn->first_block + 1) *
				block_size;
			return 0;
		}
	}

	return -1;
}

int zircon_partition_erase(const char *name)
{
	struct sysconfig_subpartition subpart;
	if (!strcmp(name, "misc")) {
		subpart = get_sysconfig_header()->abr_metadata;
		return erase_at_sys_config(subpart.offset, subpart.size);
	} else if (!strcmp(name, "vbmeta_a")) {
		subpart = get_sysconfig_header()->vb_metadata_a;
		return erase_at_sys_config(subpart.offset, subpart.size);
	} else if (!strcmp(name, "vbmeta_b")) {
		subpart = get_sysconfig_header()->vb_metadata_b;
		return erase_at_sys_config(subpart.offset, subpart.size);
	} else if (!strcmp(name, "vbmeta_r")) {
		subpart = get_sysconfig_header()->vb_metadata_r;
		return erase_at_sys_config(subpart.offset, subpart.size);
	} else { /* access to general partition */
		/* general partition */
		uint32_t block_size;

		/* init partition layout in case it was not initialized already */
		init_partition_map();
		block_size = partition_map.block_size;
		const zbi_partition_t *ptn = get_partition_by_name(name);
		if (ptn != NULL) {
			nand_erase_options_t opts;
			int ret;

			memset(&opts, 0, sizeof(opts));
			opts.length = (ptn->last_block - ptn->first_block + 1) *
				      block_size;
			opts.offset = ptn->first_block * block_size;
			opts.quiet = 1;

			printf("Erasing blocks [0x%llx, 0x%llx)\n", opts.offset,
			       opts.offset + opts.length);

			ret = nand_erase_opts(data_nand_info, &opts);
			if (ret)
				return -1;

			printf("........ erased 0x%llx bytes from '%s'\n",
			       opts.length, name);

			return 0;
		}
	}

	return -1;
}
