/* SPDX-License-Identifier: GPL-2.0-only */

#include <assert.h>
#include <cbfs.h>
#include <console/console.h>
#include <delay.h>
#include <ec/google/chromeec/ec.h>
#include <halt.h>
#include <security/vboot/misc.h>
#include <security/vboot/vbnv.h>
#include <security/vboot/vboot_common.h>
#include <timer.h>
#include <timestamp.h>
#include <vb2_api.h>

#define _EC_FILENAME(select, suffix) \
	(select == VB_SELECT_FIRMWARE_READONLY ? "ecro" suffix : "ecrw" suffix)
#define EC_IMAGE_FILENAME(select) _EC_FILENAME(select, "")
#define EC_HASH_FILENAME(select) _EC_FILENAME(select, ".hash")

/* Wait 10 ms between attempts to check if EC's hash is ready */
#define CROS_EC_HASH_CHECK_DELAY_MS 10
/* Give the EC 2 seconds to finish calculating its hash */
#define CROS_EC_HASH_TIMEOUT_MS 2000

/* Wait 3 seconds after software sync for EC to clear the limit power flag. */
#define LIMIT_POWER_WAIT_TIMEOUT_MS 3000
/* Check the limit power flag every 10 ms while waiting. */
#define LIMIT_POWER_POLL_SLEEP_MS 10

/* Wait 3 seconds for EC to sysjump to RW */
#define CROS_EC_SYSJUMP_TIMEOUT_MS 3000

/*
 * The external API for EC software sync.  This function calls into
 * vboot, which kicks off the process.  Vboot runs the verified boot
 * logic, and requires the client program to provide callbacks which
 * perform the work.
 */
void vboot_sync_ec(void)
{
	vb2_error_t retval = VB2_SUCCESS;
	struct vb2_context *ctx;

	timestamp_add_now(TS_START_EC_SYNC);

	ctx = vboot_get_context();
	ctx->flags |= VB2_CONTEXT_EC_SYNC_SUPPORTED;

	retval = vb2api_ec_sync(ctx);
	vboot_save_data(ctx);

	switch (retval) {
	case VB2_SUCCESS:
		break;

	case VB2_REQUEST_REBOOT_EC_TO_RO:
		printk(BIOS_INFO, "EC Reboot requested. Doing cold reboot\n");
		if (google_chromeec_reboot(0, EC_REBOOT_COLD, 0))
			printk(BIOS_EMERG, "Failed to get EC to cold reboot\n");

		halt();
		break;

	/* Only for EC-EFS */
	case VB2_REQUEST_REBOOT_EC_SWITCH_RW:
		printk(BIOS_INFO, "Switch EC slot requested. Doing cold reboot\n");
		if (google_chromeec_reboot(0, EC_REBOOT_COLD,
						EC_REBOOT_FLAG_SWITCH_RW_SLOT))
			printk(BIOS_EMERG, "Failed to get EC to cold reboot\n");

		halt();
		break;

	case VB2_REQUEST_REBOOT:
		printk(BIOS_INFO, "Reboot requested. Doing warm reboot\n");
		vboot_reboot();
		break;

	default:
		printk(BIOS_ERR, "EC software sync failed (%#x),"
			" rebooting\n", retval);
		vboot_reboot();
		break;
	}

	timestamp_add_now(TS_END_EC_SYNC);
}

/* Convert firmware image type into a flash offset */
static uint32_t get_vboot_hash_offset(enum vb2_firmware_selection select)
{
	switch (select) {
	case VB_SELECT_FIRMWARE_READONLY:
		return EC_VBOOT_HASH_OFFSET_RO;
	case VB_SELECT_FIRMWARE_EC_UPDATE:
		return EC_VBOOT_HASH_OFFSET_UPDATE;
	default:
		return EC_VBOOT_HASH_OFFSET_ACTIVE;
	}
}

/*
 * Asks the EC to calculate a hash of the specified firmware image, and
 * returns the information in **hash and *hash_size.
 */
static vb2_error_t ec_hash_image(enum vb2_firmware_selection select,
				 const uint8_t **hash, int *hash_size)
{
	static struct ec_response_vboot_hash resp;
	uint32_t hash_offset;
	int recalc_requested = 0;
	struct stopwatch sw;

	hash_offset = get_vboot_hash_offset(select);

	stopwatch_init_msecs_expire(&sw, CROS_EC_HASH_TIMEOUT_MS);
	do {
		if (google_chromeec_get_vboot_hash(hash_offset, &resp))
			return VB2_ERROR_UNKNOWN;

		switch (resp.status) {
		case EC_VBOOT_HASH_STATUS_NONE:
			/*
			 * There is no hash available right now.
			 * Request a recalc if it hasn't been done yet.
			 */
			if (recalc_requested)
				break;

			printk(BIOS_WARNING,
			       "%s: No valid hash (status=%d size=%d). "
			       "Computing...\n", __func__, resp.status,
			       resp.size);

			if (google_chromeec_start_vboot_hash(
				    EC_VBOOT_HASH_TYPE_SHA256, hash_offset, &resp))
				return VB2_ERROR_UNKNOWN;

			recalc_requested = 1;

			/*
			 * Expect status to be busy since we just sent
			 * a recalc request.
			 */
			resp.status = EC_VBOOT_HASH_STATUS_BUSY;

			/* Hash just started calculating, let it go for a bit */
			mdelay(CROS_EC_HASH_CHECK_DELAY_MS);
			break;

		case EC_VBOOT_HASH_STATUS_BUSY:
			/* Hash is still calculating. */
			mdelay(CROS_EC_HASH_CHECK_DELAY_MS);
			break;

		case EC_VBOOT_HASH_STATUS_DONE: /* intentional fallthrough */
		default:
			/* Hash is ready! */
			break;
		}
	} while (resp.status == EC_VBOOT_HASH_STATUS_BUSY &&
		 !stopwatch_expired(&sw));

	timestamp_add_now(TS_EC_HASH_READY);

	if (resp.status != EC_VBOOT_HASH_STATUS_DONE) {
		printk(BIOS_ERR, "%s: Hash status not done: %d\n", __func__,
		       resp.status);
		return VB2_ERROR_UNKNOWN;
	}
	if (resp.hash_type != EC_VBOOT_HASH_TYPE_SHA256) {
		printk(BIOS_ERR, "EC hash was the wrong type.\n");
		return VB2_ERROR_UNKNOWN;
	}

	printk(BIOS_INFO, "EC took %luus to calculate image hash\n",
		stopwatch_duration_usecs(&sw));

	*hash = resp.hash_digest;
	*hash_size = resp.digest_size;

	return VB2_SUCCESS;
}

/*
 * Asks the EC to protect or unprotect the specified flash region.
 */
static vb2_error_t ec_protect_flash(enum vb2_firmware_selection select, int enable)
{
	struct ec_response_flash_protect resp;
	uint32_t protected_region = EC_FLASH_PROTECT_ALL_NOW;
	const uint32_t mask = EC_FLASH_PROTECT_ALL_NOW | EC_FLASH_PROTECT_ALL_AT_BOOT;

	if (select == VB_SELECT_FIRMWARE_READONLY)
		protected_region = EC_FLASH_PROTECT_RO_NOW;

	if (google_chromeec_flash_protect(mask, enable ? mask : 0, &resp) != 0)
		return VB2_ERROR_UNKNOWN;

	if (!enable) {
		/* If protection is still enabled, need reboot */
		if (resp.flags & protected_region)
			return VB2_REQUEST_REBOOT_EC_TO_RO;

		return VB2_SUCCESS;
	}

	/*
	 * If write protect and ro-at-boot aren't both asserted, don't expect
	 * protection enabled.
	 */
	if ((~resp.flags) & (EC_FLASH_PROTECT_GPIO_ASSERTED |
			     EC_FLASH_PROTECT_RO_AT_BOOT))
		return VB2_SUCCESS;

	/* If flash is protected now, success */
	if (resp.flags & EC_FLASH_PROTECT_ALL_NOW)
		return VB2_SUCCESS;

	/* If RW will be protected at boot but not now, need a reboot */
	if (resp.flags & EC_FLASH_PROTECT_ALL_AT_BOOT)
		return VB2_REQUEST_REBOOT_EC_TO_RO;

	/* Otherwise, it's an error */
	return VB2_ERROR_UNKNOWN;
}

/* Convert a firmware image type to an EC flash region */
static enum ec_flash_region vboot_to_ec_region(enum vb2_firmware_selection select)
{
	switch (select) {
	case VB_SELECT_FIRMWARE_READONLY:
		return EC_FLASH_REGION_WP_RO;
	case VB_SELECT_FIRMWARE_EC_UPDATE:
		return EC_FLASH_REGION_UPDATE;
	default:
		return EC_FLASH_REGION_ACTIVE;
	}
}

/*
 * Read the EC's burst size bytes at a time from CBFS, and then send
 * the chunk to the EC for it to write into its flash.
 */
static vb2_error_t ec_flash_write(struct region_device *image_region,
				  uint32_t region_offset, int image_size)
{
	struct ec_response_get_protocol_info resp_proto;
	struct ec_response_flash_info resp_flash;
	ssize_t pdata_max_size;
	ssize_t burst;
	uint8_t *file_buf;
	struct ec_params_flash_write *params;
	uint32_t end, off;

	/*
	 * Get EC's protocol information, so that we can figure out how much
	 * data can be sent in one message.
	 */
	if (google_chromeec_get_protocol_info(&resp_proto)) {
		printk(BIOS_ERR, "Failed to get EC protocol information; "
		       "skipping flash write\n");
		return VB2_ERROR_UNKNOWN;
	}

	/*
	 * Determine burst size.  This must be a multiple of the write block
	 * size, and must also fit into the host parameter buffer.
	 */
	if (google_chromeec_flash_info(&resp_flash)) {
		printk(BIOS_ERR, "Failed to get EC flash information; "
		       "skipping flash write\n");
		return VB2_ERROR_UNKNOWN;
	}

	/* Limit the potential buffer stack allocation to 1K */
	pdata_max_size = MIN(1024, resp_proto.max_request_packet_size -
				   sizeof(struct ec_host_request));

	/* Round burst to a multiple of the flash write block size */
	burst = pdata_max_size - sizeof(*params);
	burst = (burst / resp_flash.write_block_size) *
		resp_flash.write_block_size;

	/* Buffer too small */
	if (burst <= 0) {
		printk(BIOS_ERR, "Flash write buffer too small!  skipping "
		       "flash write\n");
		return VB2_ERROR_UNKNOWN;
	}

	/* Allocate buffer on the stack */
	params = alloca(burst + sizeof(*params));

	/* Fill up the buffer */
	end = region_offset + image_size;
	for (off = region_offset; off < end; off += burst) {
		uint32_t todo = MIN(end - off, burst);
		uint32_t xfer_size = todo + sizeof(*params);

		/* Map 'todo' bytes into memory */
		file_buf = rdev_mmap(image_region, off - region_offset, todo);
		if (file_buf == NULL)
			return VB2_ERROR_UNKNOWN;

		params->offset = off;
		params->size = todo;

		/* Read todo bytes into the buffer */
		memcpy(params + 1, file_buf, todo);

		if (rdev_munmap(image_region, file_buf))
			return VB2_ERROR_UNKNOWN;

		/* Make sure to add back in the size of the parameters */
		if (google_chromeec_flash_write_block(
				(const uint8_t *)params, xfer_size)) {
			printk(BIOS_ERR, "EC failed flash write command, "
				"relative offset %u!\n", off - region_offset);
			return VB2_ERROR_UNKNOWN;
		}
	}

	return VB2_SUCCESS;
}

/*
 * The logic for updating an EC firmware image.
 */
static vb2_error_t ec_update_image(enum vb2_firmware_selection select)
{
	uint32_t region_offset, region_size;
	enum ec_flash_region region;
	vb2_error_t rv;
	size_t image_size;
	struct cbfsf fh;
	const char *filename;
	struct region_device image_region;

	/* Un-protect the flash region */
	rv = ec_protect_flash(select, 0);
	if (rv != VB2_SUCCESS)
		return rv;

	/* Convert vboot region into an EC region */
	region = vboot_to_ec_region(select);

	/* Get information about the flash region */
	if (google_chromeec_flash_region_info(region, &region_offset,
					      &region_size))
		return VB2_ERROR_UNKNOWN;

	/* Locate the CBFS file */
	filename = EC_IMAGE_FILENAME(select);
	if (cbfs_boot_locate(&fh, filename, NULL))
		return VB2_ERROR_UNKNOWN;

	/* Get the file size and the region struct */
	image_size = region_device_sz(&fh.data);
	cbfs_file_data(&image_region, &fh);

	/* Bail if the image is too large */
	if (image_size > region_size)
		return VB2_ERROR_INVALID_PARAMETER;

	/* Erase the region */
	if (google_chromeec_flash_erase(region_offset, region_size))
		return VB2_ERROR_UNKNOWN;

	/* Write the image into the region */
	if (ec_flash_write(&image_region, region_offset, image_size))
		return VB2_ERROR_UNKNOWN;

	/* Verify the image */
	if (google_chromeec_efs_verify(region))
		return VB2_ERROR_UNKNOWN;

	return VB2_SUCCESS;
}

static vb2_error_t ec_get_expected_hash(enum vb2_firmware_selection select,
					const uint8_t **hash,
					int *hash_size)
{
	size_t size;
	const char *filename = EC_HASH_FILENAME(select);

	/* vboot has no API to return this memory, so must permanently leak a mapping here. */
	const uint8_t *file = cbfs_map(filename, &size);

	if (file == NULL)
		return VB2_ERROR_UNKNOWN;

	*hash = file;
	*hash_size = (int)size;

	return VB2_SUCCESS;
}

/***********************************************************************
 * Vboot Callbacks
 ***********************************************************************/

/*
 * Write opaque data into NV storage region.
 */
vb2_error_t vb2ex_commit_data(struct vb2_context *ctx)
{
	save_vbnv(ctx->nvdata);
	return VB2_SUCCESS;
}

/*
 * Report whether the EC is in RW or not.
 */
vb2_error_t vb2ex_ec_running_rw(int *in_rw)
{
	*in_rw = !google_ec_running_ro();
	return VB2_SUCCESS;
}

/*
 * Callback for when Vboot is finished.
 */
vb2_error_t vb2ex_ec_vboot_done(struct vb2_context *ctx)
{
	int limit_power = 0;
	bool message_printed = false;
	struct stopwatch sw;
	int in_recovery = !!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE);

	/*
	 * Do not wait for the limit power flag to be cleared in
	 * recovery mode since we didn't just sysjump.
	 */
	if (in_recovery)
		return VB2_SUCCESS;

	timestamp_add_now(TS_EC_POWER_LIMIT_WAIT);

	stopwatch_init_msecs_expire(&sw, LIMIT_POWER_WAIT_TIMEOUT_MS);

	/* Ensure we have enough power to continue booting. */
	while (1) {
		if (google_chromeec_read_limit_power_request(&limit_power)) {
			printk(BIOS_ERR, "Failed to check EC limit power"
			       "flag.\n");
			return VB2_ERROR_UNKNOWN;
		}

		if (!limit_power || stopwatch_expired(&sw))
			break;

		if (!message_printed) {
			printk(BIOS_SPEW,
			       "Waiting for EC to clear limit power flag.\n");
			message_printed = true;
		}

		mdelay(LIMIT_POWER_POLL_SLEEP_MS);
	}

	if (limit_power) {
		printk(BIOS_INFO,
		       "EC requests limited power usage. Request shutdown.\n");
		return VB2_REQUEST_SHUTDOWN;
	} else {
		printk(BIOS_INFO, "Waited %luus to clear limit power flag.\n",
			stopwatch_duration_usecs(&sw));
	}

	return VB2_SUCCESS;
}

/*
 * Support battery cutoff if required.
 */
vb2_error_t vb2ex_ec_battery_cutoff(void)
{
	if (google_chromeec_battery_cutoff(EC_BATTERY_CUTOFF_FLAG_AT_SHUTDOWN))
		return VB2_ERROR_UNKNOWN;

	return VB2_SUCCESS;
}

/*
 * Vboot callback for calculating an EC image's hash.
 */
vb2_error_t vb2ex_ec_hash_image(enum vb2_firmware_selection select,
				const uint8_t **hash, int *hash_size)
{
	return ec_hash_image(select, hash, hash_size);
}

/*
 * Vboot callback for EC flash protection.
 */
vb2_error_t vb2ex_ec_protect(enum vb2_firmware_selection select)
{
	return ec_protect_flash(select, 1);
}

/*
 * Get hash for image.
 */
vb2_error_t vb2ex_ec_get_expected_image_hash(enum vb2_firmware_selection select,
					     const uint8_t **hash,
					     int *hash_size)
{
	return ec_get_expected_hash(select, hash, hash_size);
}

/*
 * Disable further sysjumps (i.e., stay in RW until next reboot)
 */
vb2_error_t vb2ex_ec_disable_jump(void)
{
	if (google_chromeec_reboot(0, EC_REBOOT_DISABLE_JUMP, 0))
		return VB2_ERROR_UNKNOWN;

	return VB2_SUCCESS;
}

/*
 * Update EC image.
 */
vb2_error_t vb2ex_ec_update_image(enum vb2_firmware_selection select)
{
	return ec_update_image(select);
}

/*
 * Vboot callback for commanding EC to sysjump to RW.
 */
vb2_error_t vb2ex_ec_jump_to_rw(void)
{
	struct stopwatch sw;

	if (google_chromeec_reboot(0, EC_REBOOT_JUMP_RW, 0))
		return VB2_ERROR_UNKNOWN;

	/* Give the EC 3 seconds to sysjump */
	stopwatch_init_msecs_expire(&sw, CROS_EC_SYSJUMP_TIMEOUT_MS);

	/* Default delay to wait after EC reboot */
	mdelay(50);
	while (google_chromeec_hello()) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "EC did not return from reboot after %luus\n",
			       stopwatch_duration_usecs(&sw));
			return VB2_ERROR_UNKNOWN;
		}

		mdelay(5);
	}

	printk(BIOS_INFO, "\nEC returned from reboot after %luus\n",
	       stopwatch_duration_usecs(&sw));

	return VB2_SUCCESS;
}
