/*
 * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>

#include <common/debug.h>
#include <common/tf_crc32.h>
#include <drivers/io/io_storage.h>
#include <drivers/partition/efi.h>
#include <drivers/partition/partition.h>
#include <drivers/partition/gpt.h>
#include <drivers/partition/mbr.h>
#include <plat/common/platform.h>

static uint8_t mbr_sector[PLAT_PARTITION_BLOCK_SIZE];
static partition_entry_list_t list;

#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
static void dump_entries(int num)
{
	char name[EFI_NAMELEN];
	int i, j, len;

	VERBOSE("Partition table with %d entries:\n", num);
	for (i = 0; i < num; i++) {
		len = snprintf(name, EFI_NAMELEN, "%s", list.list[i].name);
		for (j = 0; j < EFI_NAMELEN - len - 1; j++) {
			name[len + j] = ' ';
		}
		name[EFI_NAMELEN - 1] = '\0';
		VERBOSE("%d: %s %" PRIx64 "-%" PRIx64 "\n", i + 1, name, list.list[i].start,
			list.list[i].start + list.list[i].length - 4);
	}
}
#else
#define dump_entries(num)	((void)num)
#endif

/*
 * Load the first sector that carries MBR header.
 * The MBR boot signature should be always valid whether it's MBR or GPT.
 */
static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry)
{
	size_t bytes_read;
	int result;
	mbr_entry_t *tmp;

	assert(mbr_entry != NULL);
	/* MBR partition table is in LBA0. */
	result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET);
	if (result != 0) {
		VERBOSE("Failed to seek (%i)\n", result);
		return result;
	}
	result = io_read(image_handle, (uintptr_t)&mbr_sector,
			 PLAT_PARTITION_BLOCK_SIZE, &bytes_read);
	if ((result != 0) || (bytes_read != PLAT_PARTITION_BLOCK_SIZE)) {
		VERBOSE("Failed to read data (%i)\n", result);
		return result;
	}

	/* Check MBR boot signature. */
	if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) ||
	    (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) {
		VERBOSE("MBR boot signature failure\n");
		return -ENOENT;
	}

	tmp = (mbr_entry_t *)(&mbr_sector[MBR_PRIMARY_ENTRY_OFFSET]);

	if (tmp->first_lba != 1) {
		VERBOSE("MBR header may have an invalid first LBA\n");
		return -EINVAL;
	}

	if ((tmp->sector_nums == 0) || (tmp->sector_nums == UINT32_MAX)) {
		VERBOSE("MBR header entry has an invalid number of sectors\n");
		return -EINVAL;
	}

	memcpy(mbr_entry, tmp, sizeof(mbr_entry_t));
	return 0;
}

/*
 * Load GPT header and check the GPT signature and header CRC.
 * If partition numbers could be found, check & update it.
 */
static int load_gpt_header(uintptr_t image_handle, size_t header_offset,
			   gpt_header_t *header)
{
	size_t bytes_read;
	int result;
	uint32_t header_crc, calc_crc;

	result = io_seek(image_handle, IO_SEEK_SET, header_offset);
	if (result != 0) {
		VERBOSE("Failed to seek into the GPT image at offset (%zu)\n",
			header_offset);
		return result;
	}
	result = io_read(image_handle, (uintptr_t)header,
			 sizeof(gpt_header_t), &bytes_read);
	if ((result != 0) || (sizeof(gpt_header_t) != bytes_read)) {
		VERBOSE("GPT header read error(%i) or read mismatch occurred,"
			"expected(%zu) and actual(%zu)\n", result,
			sizeof(gpt_header_t), bytes_read);
		return result;
	}
	if (memcmp(header->signature, GPT_SIGNATURE,
			   sizeof(header->signature)) != 0) {
		VERBOSE("GPT header signature failure\n");
		return -EINVAL;
	}

	/*
	 * UEFI Spec 2.8 March 2019 Page 119: HeaderCRC32 value is
	 * computed by setting this field to 0, and computing the
	 * 32-bit CRC for HeaderSize bytes.
	 */
	header_crc = header->header_crc;
	header->header_crc = 0U;

	calc_crc = tf_crc32(0U, (uint8_t *)header, sizeof(gpt_header_t));
	if (header_crc != calc_crc) {
		ERROR("Invalid GPT Header CRC: Expected 0x%x but got 0x%x.\n",
		      header_crc, calc_crc);
		return -EINVAL;
	}

	header->header_crc = header_crc;

	/* partition numbers can't exceed PLAT_PARTITION_MAX_ENTRIES */
	list.entry_count = header->list_num;
	if (list.entry_count > PLAT_PARTITION_MAX_ENTRIES) {
		list.entry_count = PLAT_PARTITION_MAX_ENTRIES;
	}

	return 0;
}

/*
 * Load a single MBR entry based on details from MBR header.
 */
static int load_mbr_entry(uintptr_t image_handle, mbr_entry_t *mbr_entry,
			  int part_number)
{
	size_t bytes_read;
	uintptr_t offset;
	int result;

	assert(mbr_entry != NULL);
	/* MBR partition table is in LBA0. */
	result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET);
	if (result != 0) {
		VERBOSE("Failed to seek (%i)\n", result);
		return result;
	}
	result = io_read(image_handle, (uintptr_t)&mbr_sector,
			 PLAT_PARTITION_BLOCK_SIZE, &bytes_read);
	if (result != 0) {
		VERBOSE("Failed to read data (%i)\n", result);
		return result;
	}

	/* Check MBR boot signature. */
	if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) ||
	    (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) {
		VERBOSE("MBR Entry boot signature failure\n");
		return -ENOENT;
	}
	offset = (uintptr_t)&mbr_sector +
		MBR_PRIMARY_ENTRY_OFFSET +
		MBR_PRIMARY_ENTRY_SIZE * part_number;
	memcpy(mbr_entry, (void *)offset, sizeof(mbr_entry_t));

	return 0;
}

/*
 * Load MBR entries based on max number of partition entries.
 */
static int load_mbr_entries(uintptr_t image_handle)
{
	mbr_entry_t mbr_entry;
	unsigned int i;

	list.entry_count = MBR_PRIMARY_ENTRY_NUMBER;

	for (i = 0U; i < list.entry_count; i++) {
		load_mbr_entry(image_handle, &mbr_entry, i);
		list.list[i].start = mbr_entry.first_lba * 512;
		list.list[i].length = mbr_entry.sector_nums * 512;
		list.list[i].name[0] = mbr_entry.type;
	}

	return 0;
}

/*
 * Try to read and load a single GPT entry.
 */
static int load_gpt_entry(uintptr_t image_handle, gpt_entry_t *entry)
{
	size_t bytes_read = 0U;
	int result;

	assert(entry != NULL);
	result = io_read(image_handle, (uintptr_t)entry, sizeof(gpt_entry_t),
			&bytes_read);
	if ((result != 0) || (sizeof(gpt_entry_t) != bytes_read)) {
		VERBOSE("GPT Entry read error(%i) or read mismatch occurred,"
			"expected(%zu) and actual(%zu)\n", result,
			sizeof(gpt_entry_t), bytes_read);
		return -EINVAL;
	}

	return result;
}

/*
 * Retrieve each entry in the partition table, parse the data from each
 * entry and store them in the list of partition table entries.
 */
static int load_partition_gpt(uintptr_t image_handle, gpt_header_t header)
{
	const signed long long gpt_entry_offset = LBA(header.part_lba);
	gpt_entry_t entry;
	int result;
	unsigned int i;
	uint32_t calc_crc = 0U;

	result = io_seek(image_handle, IO_SEEK_SET, gpt_entry_offset);
	if (result != 0) {
		VERBOSE("Failed to seek (%i), Failed loading GPT partition"
			"table entries\n", result);
		return result;
	}

	for (i = 0U; i < list.entry_count; i++) {
		result = load_gpt_entry(image_handle, &entry);
		if (result != 0) {
			VERBOSE("Failed to load gpt entry data(%u) error is (%i)\n",
				i, result);
			return result;
		}

		result = parse_gpt_entry(&entry, &list.list[i]);
		if (result != 0) {
			result = io_seek(image_handle, IO_SEEK_SET,
					(gpt_entry_offset + (i * sizeof(gpt_entry_t))));
			if (result != 0) {
				VERBOSE("Failed to seek (%i)\n", result);
				return result;
			}
			break;
		}

		/*
		 * Calculate CRC of Partition entry array to compare with CRC
		 * value in header
		 */
		calc_crc = tf_crc32(calc_crc, (uint8_t *)&entry, sizeof(gpt_entry_t));
	}
	if (i == 0) {
		VERBOSE("No Valid GPT Entries found\n");
		return -EINVAL;
	}

	/*
	 * Only records the valid partition number that is loaded from
	 * partition table.
	 */
	list.entry_count = i;
	dump_entries(list.entry_count);

	/*
	 * If there are less valid entries than the possible number of entries
	 * from the header, continue to load the partition entry table to
	 * calculate the full CRC in order to check against the partition CRC
	 * from the header for validation.
	 */
	for (; i < header.list_num; i++) {
		result = load_gpt_entry(image_handle, &entry);
		if (result != 0) {
			VERBOSE("Failed to load gpt entry data(%u) error is (%i)\n",
				i, result);
			return result;
		}

		calc_crc = tf_crc32(calc_crc, (uint8_t *)&entry, sizeof(gpt_entry_t));
	}

	if (header.part_crc != calc_crc) {
		ERROR("Invalid GPT Partition Array Entry CRC: Expected 0x%x"
				" but got 0x%x.\n", header.part_crc, calc_crc);
		return -EINVAL;
	}

	return 0;
}

/*
 * Try retrieving and parsing the backup-GPT header and backup GPT entries.
 * Last 33 blocks contains the backup-GPT entries and header.
 */
static int load_backup_gpt(unsigned int image_id, unsigned int sector_nums)
{
	int result;
	gpt_header_t header;
	size_t gpt_header_offset;
	uintptr_t dev_handle, image_spec, image_handle;
	io_block_spec_t *block_spec;
	int part_num_entries;

	result = plat_get_image_source(image_id, &dev_handle, &image_spec);
	if (result != 0) {
		VERBOSE("Failed to obtain reference to image id=%u (%i)\n",
			image_id, result);
		return result;
	}

	block_spec = (io_block_spec_t *)image_spec;
	/*
	 * We need to read 32 blocks of GPT entries and one block of GPT header
	 * try mapping only last 33 last blocks from the image to read the
	 * Backup-GPT header and its entries.
	 */
	part_num_entries = (PLAT_PARTITION_MAX_ENTRIES / 4);
	/* Move the offset base to LBA-33 */
	block_spec->offset += LBA(sector_nums - part_num_entries);
	/*
	 * Set length as LBA-33, 32 blocks of backup-GPT entries and one
	 * block of backup-GPT header.
	 */
	block_spec->length = LBA(part_num_entries + 1);

	result = io_open(dev_handle, image_spec, &image_handle);
	if (result != 0) {
		VERBOSE("Failed to access image id (%i)\n", result);
		return result;
	}

	INFO("Trying to retrieve back-up GPT header\n");
	/* Last block is backup-GPT header, after the end of GPT entries */
	gpt_header_offset = LBA(part_num_entries);
	result = load_gpt_header(image_handle, gpt_header_offset, &header);
	if ((result != 0) || (header.part_lba == 0)) {
		ERROR("Failed to retrieve Backup GPT header,"
		      "Partition maybe corrupted\n");
		goto out;
	}

	/*
	 * Note we mapped last 33 blocks(LBA-33), first block here starts with
	 * entries while last block was header.
	 */
	header.part_lba = 0;
	result = load_partition_gpt(image_handle, header);

out:
	io_close(image_handle);
	return result;
}

/*
 * Load a GPT partition, Try retrieving and parsing the primary GPT header,
 * if its corrupted try loading backup GPT header and then retrieve list
 * of partition table entries found from the GPT.
 */
static int load_primary_gpt(uintptr_t image_handle, unsigned int first_lba)
{
	int result;
	size_t gpt_header_offset;
	gpt_header_t header;

	/* Try to load Primary GPT header from LBA1 */
	gpt_header_offset = LBA(first_lba);
	result = load_gpt_header(image_handle, gpt_header_offset, &header);
	if ((result != 0) || (header.part_lba == 0)) {
		VERBOSE("Failed to retrieve Primary GPT header,"
			"trying to retrieve back-up GPT header\n");
		return result;
	}

	return load_partition_gpt(image_handle, header);
}

/*
 * Load the partition table info based on the image id provided.
 */
int load_partition_table(unsigned int image_id)
{
	uintptr_t dev_handle, image_handle, image_spec = 0;
	mbr_entry_t mbr_entry;
	int result;

	result = plat_get_image_source(image_id, &dev_handle, &image_spec);
	if (result != 0) {
		VERBOSE("Failed to obtain reference to image id=%u (%i)\n",
			image_id, result);
		return result;
	}

	result = io_open(dev_handle, image_spec, &image_handle);
	if (result != 0) {
		VERBOSE("Failed to access image id=%u (%i)\n", image_id, result);
		return result;
	}

	result = load_mbr_header(image_handle, &mbr_entry);
	if (result != 0) {
		VERBOSE("Failed to access image id=%u (%i)\n", image_id, result);
		goto out;
	}
	if (mbr_entry.type == PARTITION_TYPE_GPT) {
		result = load_primary_gpt(image_handle, mbr_entry.first_lba);
		if (result != 0) {
			io_close(image_handle);
			return load_backup_gpt(BKUP_GPT_IMAGE_ID,
					       mbr_entry.sector_nums);
		}
	} else {
		result = load_mbr_entries(image_handle);
	}

out:
	io_close(image_handle);
	return result;
}

/*
 * Try retrieving a partition table entry based on the name of the partition.
 */
const partition_entry_t *get_partition_entry(const char *name)
{
	unsigned int i;

	for (i = 0U; i < list.entry_count; i++) {
		if (strcmp(name, list.list[i].name) == 0) {
			return &list.list[i];
		}
	}
	return NULL;
}

/*
 * Try retrieving a partition table entry based on the partition type GUID.
 */
const partition_entry_t *get_partition_entry_by_type(
	const struct efi_guid *type_guid)
{
	unsigned int i;

	for (i = 0U; i < list.entry_count; i++) {
		if (guidcmp(type_guid, &list.list[i].type_guid) == 0) {
			return &list.list[i];
		}
	}

	return NULL;
}

/*
 * Try retrieving a partition table entry based on the unique partition GUID.
 */
const partition_entry_t *get_partition_entry_by_guid(
	const struct efi_guid *part_guid)
{
	unsigned int i;

	for (i = 0U; i < list.entry_count; i++) {
		if (guidcmp(part_guid, &list.list[i].part_guid) == 0) {
			return &list.list[i];
		}
	}

	return NULL;
}

/*
 * Return entry to the list of partition table entries.
 */
const partition_entry_list_t *get_partition_entry_list(void)
{
	return &list;
}

/*
 * Try loading partition table info for the given image ID.
 */
void partition_init(unsigned int image_id)
{
	int ret;

	ret = load_partition_table(image_id);
	if (ret != 0) {
		ERROR("Failed to parse partition with image id = %u\n",
		      image_id);
	}
}

/*
 * Load a GPT based image.
 */
int gpt_partition_init(void)
{
	return load_partition_table(GPT_IMAGE_ID);
}
