/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * EC software sync routines for vboot
 */

#include "2api.h"
#include "2common.h"
#include "2misc.h"
#include "2nvstorage.h"
#include "2sysincludes.h"
#include "vboot_api.h"
#include "vboot_display.h"
#include "vboot_kernel.h"

#define SYNC_FLAG(select)					\
	((select) == VB_SELECT_FIRMWARE_READONLY ?		\
	 VB2_SD_FLAG_ECSYNC_EC_RO : VB2_SD_FLAG_ECSYNC_EC_RW)

/**
 * Display the WAIT screen
 */
static void display_wait_screen(struct vb2_context *ctx)
{
	VB2_DEBUG("EC FW update is slow. Show WAIT screen.\n");
	VbDisplayScreen(ctx, VB_SCREEN_WAIT, 0, NULL);
}

/**
 * Set the RECOVERY_REQUEST flag in NV space
 */
static void request_recovery(struct vb2_context *ctx, uint32_t recovery_request)
{
	VB2_DEBUG("request_recovery(%u)\n", recovery_request);

	vb2_nv_set(ctx, VB2_NV_RECOVERY_REQUEST, recovery_request);
}

/**
 * Wrapper around vb2ex_ec_protect() which sets recovery reason on error.
 */
static vb2_error_t protect_ec(struct vb2_context *ctx,
			      enum vb2_firmware_selection select)
{
	vb2_error_t rv = vb2ex_ec_protect(select);

	if (rv == VBERROR_EC_REBOOT_TO_RO_REQUIRED) {
		VB2_DEBUG("vb2ex_ec_protect() needs reboot\n");
	} else if (rv != VB2_SUCCESS) {
		VB2_DEBUG("vb2ex_ec_protect() returned %#x\n", rv);
		request_recovery(ctx, VB2_RECOVERY_EC_PROTECT);
	}
	return rv;
}

/**
 * Print a hash to debug output
 *
 * @param hash		Pointer to the hash
 * @param hash_size	Size of the hash in bytes
 * @param desc		Description of what's being hashed
 */
static void print_hash(const uint8_t *hash, uint32_t hash_size,
		       const char *desc)
{
	int i;

	VB2_DEBUG("%s hash: ", desc);
	for (i = 0; i < hash_size; i++)
		VB2_DEBUG_RAW("%02x", hash[i]);
	VB2_DEBUG_RAW("\n");
}

static const char *image_name_to_string(enum vb2_firmware_selection select)
{
	switch (select) {
	case VB_SELECT_FIRMWARE_READONLY:
		return "RO";
	case VB_SELECT_FIRMWARE_EC_ACTIVE:
		return "RW(active)";
	case VB_SELECT_FIRMWARE_EC_UPDATE:
		return "RW(update)";
	default:
		return "UNKNOWN";
	}
}

/**
 * Check if the hash of the EC code matches the expected hash.
 *
 * @param ctx		Vboot2 context
 * @param select	Which firmware image to check
 * @return VB2_SUCCESS, or non-zero error code.
 */
static vb2_error_t check_ec_hash(struct vb2_context *ctx,
				 enum vb2_firmware_selection select)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);

	/* Get current EC hash. */
	const uint8_t *ec_hash = NULL;
	int ec_hash_size;
	vb2_error_t rv = vb2ex_ec_hash_image(select, &ec_hash, &ec_hash_size);
	if (rv) {
		VB2_DEBUG("vb2ex_ec_hash_image() returned %#x\n", rv);
		request_recovery(ctx, VB2_RECOVERY_EC_HASH_FAILED);
		return VB2_ERROR_EC_HASH_IMAGE;
	}
	print_hash(ec_hash, ec_hash_size, image_name_to_string(select));

	/* Get expected EC hash. */
	const uint8_t *hash = NULL;
	int hash_size;
	rv = vb2ex_ec_get_expected_image_hash(select, &hash, &hash_size);
	if (rv) {
		VB2_DEBUG("vb2ex_ec_get_expected_image_hash() returned %#x\n", rv);
		request_recovery(ctx, VB2_RECOVERY_EC_EXPECTED_HASH);
		return VB2_ERROR_EC_HASH_EXPECTED;
	}
	if (ec_hash_size != hash_size) {
		VB2_DEBUG("EC uses %d-byte hash, but AP-RW contains %d bytes\n",
			  ec_hash_size, hash_size);
		request_recovery(ctx, VB2_RECOVERY_EC_HASH_SIZE);
		return VB2_ERROR_EC_HASH_SIZE;
	}

	if (vb2_safe_memcmp(ec_hash, hash, hash_size)) {
		print_hash(hash, hash_size, "Expected");
		sd->flags |= SYNC_FLAG(select);
	}

	return VB2_SUCCESS;
}

/**
 * Update the specified EC and verify the update succeeded
 *
 * @param ctx		Vboot2 context
 * @param select	Which firmware image to check
 * @return VB2_SUCCESS, or non-zero error code.
 */
static vb2_error_t update_ec(struct vb2_context *ctx,
			     enum vb2_firmware_selection select)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	vb2_error_t rv;

	VB2_DEBUG("Updating %s...\n", image_name_to_string(select));

	rv = vb2ex_ec_update_image(select);
	if (rv != VB2_SUCCESS) {
		VB2_DEBUG("vb2ex_ec_update_image() returned %#x\n", rv);

		/*
		 * The EC may know it needs a reboot.  It may need to
		 * unprotect the region before updating, or may need to
		 * reboot after updating.  Either way, it's not an error
		 * requiring recovery mode.
		 *
		 * If we fail for any other reason, trigger recovery
		 * mode.
		 */
		if (rv != VBERROR_EC_REBOOT_TO_RO_REQUIRED)
			request_recovery(ctx, VB2_RECOVERY_EC_UPDATE);

		return rv;
	}

	/* Verify the EC was updated properly */
	sd->flags &= ~SYNC_FLAG(select);
	if (check_ec_hash(ctx, select) != VB2_SUCCESS)
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	if (sd->flags & SYNC_FLAG(select)) {
		VB2_DEBUG("Failed to update\n");
		request_recovery(ctx, VB2_RECOVERY_EC_UPDATE);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	return VB2_SUCCESS;
}

/**
 * Set VB2_SD_FLAG_ECSYNC_EC_IN_RW flag for the EC
 *
 * @param ctx		Vboot2 context
 * @return VB2_SUCCESS, or non-zero if error.
 */
static vb2_error_t check_ec_active(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	int in_rw = 0;
	/*
	 * We don't use vb2ex_ec_trusted, which checks EC_IN_RW. It is
	 * controlled by cr50 but on some platforms, cr50 can't know when a EC
	 * resets. So, we trust what EC-RW says. If it lies it's in RO, we'll
	 * flash RW while it's in RW.
	 */
	vb2_error_t rv = vb2ex_ec_running_rw(&in_rw);
	/* If we couldn't determine where the EC was, reboot to recovery. */
	if (rv != VB2_SUCCESS) {
		VB2_DEBUG("vb2ex_ec_running_rw() returned %#x\n", rv);
		request_recovery(ctx, VB2_RECOVERY_EC_UNKNOWN_IMAGE);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	if (in_rw)
		sd->flags |= VB2_SD_FLAG_ECSYNC_EC_IN_RW;

	return VB2_SUCCESS;
}

#define RO_RETRIES 2  /* Maximum times to retry flashing RO */

/**
 * Sync, jump, and protect EC device
 *
 * @param ctx		Vboot2 context
 * @return VB2_SUCCESS, or non-zero if error.
 */
static vb2_error_t sync_ec(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	vb2_error_t rv;

	const enum vb2_firmware_selection select_rw = EC_EFS ?
		VB_SELECT_FIRMWARE_EC_UPDATE :
		VB_SELECT_FIRMWARE_EC_ACTIVE;
	VB2_DEBUG("select_rw=%d\n", select_rw);

	/* Update the RW Image */
	if (sd->flags & SYNC_FLAG(select_rw)) {
		if (VB2_SUCCESS != update_ec(ctx, select_rw))
			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
		/* Updated successfully. Cold reboot to switch to the new RW.
		 * TODO: Switch slot and proceed if EC is still in RO. */
		if (EC_EFS) {
			VB2_DEBUG("Rebooting to jump to new EC-RW\n");
			return VBERROR_EC_REBOOT_TO_SWITCH_RW;
		}
	}

	/* Tell EC to jump to its RW image */
	if (!(sd->flags & VB2_SD_FLAG_ECSYNC_EC_IN_RW)) {
		VB2_DEBUG("jumping to EC-RW\n");
		rv = vb2ex_ec_jump_to_rw();
		if (rv != VB2_SUCCESS) {
			VB2_DEBUG("vb2ex_ec_jump_to_rw() returned %x\n", rv);

			/*
			 * If a previous AP boot has called
			 * vb2ex_ec_disable_jump(), we need to reboot the EC to
			 * unlock the ability to jump to the RW firmware.
			 *
			 * All other errors trigger recovery mode.
			 */
			if (rv != VBERROR_EC_REBOOT_TO_RO_REQUIRED)
				request_recovery(ctx, VB2_RECOVERY_EC_JUMP_RW);

			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
		}
	}

	/* Might need to update EC-RO */
	if (sd->flags & VB2_SD_FLAG_ECSYNC_EC_RO) {
		VB2_DEBUG("RO Software Sync\n");

		/* Reset RO Software Sync NV flag */
		vb2_nv_set(ctx, VB2_NV_TRY_RO_SYNC, 0);

		/*
		 * Get the current recovery request (if any).  This gets
		 * overwritten by a failed try.  If a later try succeeds, we'll
		 * need to restore this request (or the lack of a request), or
		 * else we'll end up in recovery mode even though RO software
		 * sync did eventually succeed.
		 */
		uint32_t recovery_request =
			vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST);

		/* Update the RO Image. */
		int num_tries;
		for (num_tries = 0; num_tries < RO_RETRIES; num_tries++) {
			if (VB2_SUCCESS ==
			    update_ec(ctx, VB_SELECT_FIRMWARE_READONLY))
				break;
		}
		if (num_tries == RO_RETRIES) {
			/* Ran out of tries */
			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
		} else if (num_tries) {
			/*
			 * Update succeeded after a failure, so we've polluted
			 * the recovery request.  Restore it.
			 */
			request_recovery(ctx, recovery_request);
		}
	}

	/* Protect RO flash */
	rv = protect_ec(ctx, VB_SELECT_FIRMWARE_READONLY);
	if (rv != VB2_SUCCESS)
		return rv;

	/* Protect RW flash */
	rv = protect_ec(ctx, select_rw);
	if (rv != VB2_SUCCESS)
		return rv;

	/* Disable further sysjumps */
	rv = vb2ex_ec_disable_jump();
	if (rv != VB2_SUCCESS) {
		VB2_DEBUG("vb2ex_ec_disable_jump() returned %#x\n", rv);
		request_recovery(ctx, VB2_RECOVERY_EC_SOFTWARE_SYNC);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	return rv;
}

/**
 * EC sync, phase 1
 *
 * This checks whether the EC is running the correct image to do EC sync, and
 * whether any updates are necessary.
 *
 * @param ctx		Vboot2 context
 * @return VB2_SUCCESS, VBERROR_EC_REBOOT_TO_RO_REQUIRED if the EC must
 * reboot back to its RO code to continue EC sync, or other non-zero error
 * code.
 */
static vb2_error_t ec_sync_phase1(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);

	/* Reasons not to do sync at all */
	if (!(ctx->flags & VB2_CONTEXT_EC_SYNC_SUPPORTED))
		return VB2_SUCCESS;
	if (gbb->flags & VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC)
		return VB2_SUCCESS;

	/* Set VB2_SD_FLAG_ECSYNC_EC_IN_RW flag */
	if (check_ec_active(ctx))
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;

	/* Check if we need to update RW.  Failures trigger recovery mode. */
	if (check_ec_hash(ctx, VB_SELECT_FIRMWARE_EC_ACTIVE))
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	/* See if we need to update EC-RO. */
	if (vb2_nv_get(ctx, VB2_NV_TRY_RO_SYNC) &&
	    check_ec_hash(ctx, VB_SELECT_FIRMWARE_READONLY)) {
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	/*
	 * If we're in RW, we need to reboot back to RO because RW can't be
	 * updated while we're running it.
	 *
	 * If EC supports RW-A/B slots, we can proceed but we need
	 * to jump to the new RW version later.
	 */
	if ((sd->flags & VB2_SD_FLAG_ECSYNC_EC_RW) &&
	    (sd->flags & VB2_SD_FLAG_ECSYNC_EC_IN_RW) && !EC_EFS) {
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	return VB2_SUCCESS;
}

/**
 * Returns non-zero if the EC will perform a slow update.
 *
 * This is only valid after calling ec_sync_phase1(), before calling
 * sync_ec().
 *
 * @param ctx		Vboot2 context
 * @return non-zero if a slow update will be done; zero if no update or a
 * fast update.
 */
static int ec_will_update_slowly(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);

	return (((sd->flags & VB2_SD_FLAG_ECSYNC_EC_RO) ||
		 (sd->flags & VB2_SD_FLAG_ECSYNC_EC_RW)) && EC_SLOW_UPDATE);
}

/**
 * determine if we can update the EC
 *
 * @param ctx		Vboot2 context
 * @return boolean (true iff we can update the EC)
 */

static int ec_sync_allowed(struct vb2_context *ctx)
{
	struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);

	/* Reasons not to do sync at all */
	if (!(ctx->flags & VB2_CONTEXT_EC_SYNC_SUPPORTED))
		return 0;
	if (gbb->flags & VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC)
		return 0;
	if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
		return 0;
	return 1;
}

/**
 * EC sync, phase 2
 *
 * This updates the EC if necessary, makes sure it has protected its image(s),
 * and makes sure it has jumped to the correct image.
 *
 * If ec_will_update_slowly(), it is suggested that the caller display a
 * warning screen before calling phase 2.
 *
 * @param ctx		Vboot2 context
 * @return VB2_SUCCESS, VBERROR_EC_REBOOT_TO_RO_REQUIRED if the EC must
 * reboot back to its RO code to continue EC sync, or other non-zero error
 * code.
 */
static vb2_error_t ec_sync_phase2(struct vb2_context *ctx)
{
	if (!ec_sync_allowed(ctx))
		return VB2_SUCCESS;

	/* Handle updates and jumps for EC */
	return sync_ec(ctx);
}

vb2_error_t vb2api_ec_sync(struct vb2_context *ctx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	vb2_error_t rv;

	/*
	 * If the flags indicate that the EC has already gone through
	 * software sync this boot, then don't do it again.
	 */
	if (sd->flags & VB2_SD_STATUS_EC_SYNC_COMPLETE) {
		VB2_DEBUG("EC software sync already performed this boot, skipping\n");
		return VB2_SUCCESS;
	}

	/*
	 * If the device is in recovery mode, then EC sync should
	 * not be performed.
	 */
	if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) {
		VB2_DEBUG("In recovery mode, skipping EC sync\n");
		return VB2_SUCCESS;
	}

	/* Phase 1; this determines if we need an update */
	vb2_error_t phase1_rv = ec_sync_phase1(ctx);
	int need_wait_screen = ec_will_update_slowly(ctx);

	if (need_wait_screen && vb2api_need_reboot_for_display(ctx))
		return VBERROR_REBOOT_REQUIRED;

	if (phase1_rv)
		return phase1_rv;

	if (need_wait_screen)
		display_wait_screen(ctx);

	/* Phase 2; Applies update and/or jumps to the correct EC image */
	rv = ec_sync_phase2(ctx);
	if (rv)
		return rv;

	/* Phase 3; Let the platform know that EC software sync is now done */
	rv = vb2ex_ec_vboot_done(ctx);
	if (rv)
		return rv;

	/* Establish that EC software sync is complete and successful */
	sd->flags |= VB2_SD_STATUS_EC_SYNC_COMPLETE;

	return VB2_SUCCESS;
}
