/* 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 "2sysincludes.h"
#include "2common.h"
#include "2misc.h"
#include "2nvstorage.h"

#include "sysincludes.h"
#include "ec_sync.h"
#include "gbb_header.h"
#include "vboot_api.h"
#include "vboot_common.h"
#include "vboot_kernel.h"

#define VB2_SD_FLAG_ECSYNC_RW					\
	(VB2_SD_FLAG_ECSYNC_EC_RW | VB2_SD_FLAG_ECSYNC_PD_RW)
#define VB2_SD_FLAG_ECSYNC_ANY					\
	(VB2_SD_FLAG_ECSYNC_EC_RO | VB2_SD_FLAG_ECSYNC_RW)
#define VB2_SD_FLAG_ECSYNC_IN_RW					\
	(VB2_SD_FLAG_ECSYNC_EC_IN_RW | VB2_SD_FLAG_ECSYNC_PD_IN_RW)

#define IN_RW(devidx)							\
	((devidx) ? VB2_SD_FLAG_ECSYNC_PD_IN_RW : VB2_SD_FLAG_ECSYNC_EC_IN_RW)

#define WHICH_EC(devidx, select) \
	((select) == VB_SELECT_FIRMWARE_READONLY ? VB2_SD_FLAG_ECSYNC_EC_RO : \
	 ((devidx) ? VB2_SD_FLAG_ECSYNC_PD_RW : VB2_SD_FLAG_ECSYNC_EC_RW))

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 VbExEcProtect() which sets recovery reason on error.
 */
static VbError_t protect_ec(struct vb2_context *ctx, int devidx,
			   enum VbSelectFirmware_t select)
{
	int rv = VbExEcProtect(devidx, select);

	if (rv == VBERROR_EC_REBOOT_TO_RO_REQUIRED) {
		VB2_DEBUG("VbExEcProtect() needs reboot\n");
	} else if (rv != VBERROR_SUCCESS) {
		VB2_DEBUG("VbExEcProtect() returned %d\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("%02x", hash[i]);
	VB2_DEBUG("\n");
}

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

	/* Get current EC hash. */
	const uint8_t *ec_hash = NULL;
	int ec_hash_size;
	int rv = VbExEcHashImage(devidx, select, &ec_hash, &ec_hash_size);
	if (rv) {
		VB2_DEBUG("%s: VbExEcHashImage() returned %d\n", __func__, rv);
		request_recovery(ctx, VB2_RECOVERY_EC_HASH_FAILED);
		return VB2_ERROR_EC_HASH_IMAGE;
	}
	print_hash(ec_hash, ec_hash_size,
		   select == VB_SELECT_FIRMWARE_READONLY ? "RO" : "RW");

	/* Get expected EC hash. */
	const uint8_t *hash = NULL;
	int hash_size;
	rv = VbExEcGetExpectedImageHash(devidx, select, &hash, &hash_size);
	if (rv) {
		VB2_DEBUG("%s: VbExEcGetExpectedImageHash() returned %d\n",
			  __func__, rv);
		request_recovery(ctx, VB2_RECOVERY_EC_EXPECTED_HASH);
		return VB2_ERROR_EC_HASH_EXPECTED;
	}
	if (ec_hash_size != hash_size) {
		VB2_DEBUG("%s: EC uses %d-byte hash, but AP-RW contains %d "
			  "bytes\n", __func__, 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 |= WHICH_EC(devidx, select);
	}

	return VB2_SUCCESS;
}

/**
 * Update the specified EC and verify the update succeeded
 *
 * @param ctx		Vboot2 context
 * @param devidx	Index of EC device to check
 * @param select	Which firmware image to check
 * @return VBERROR_SUCCESS, or non-zero error code.
 */
static VbError_t update_ec(struct vb2_context *ctx, int devidx,
			   enum VbSelectFirmware_t select)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);

	VB2_DEBUG("%s: updating %s...\n", __func__,
		  select == VB_SELECT_FIRMWARE_READONLY ? "RO" : "RW");

	/* Get expected EC image */
	const uint8_t *want = NULL;
	int want_size;
	int rv = VbExEcGetExpectedImage(devidx, select, &want, &want_size);
	if (rv) {
		VB2_DEBUG("%s: VbExEcGetExpectedImage() returned %d\n",
			  __func__, rv);
		request_recovery(ctx, VB2_RECOVERY_EC_EXPECTED_IMAGE);
		return rv;
	}
	VB2_DEBUG("%s: image len = %d\n", __func__, want_size);

	rv = VbExEcUpdateImage(devidx, select, want, want_size);
	if (rv != VBERROR_SUCCESS) {
		VB2_DEBUG("%s: VbExEcUpdateImage() returned %d\n",
			  __func__, 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 &= ~WHICH_EC(devidx, select);
	if (check_ec_hash(ctx, devidx, select) != VB2_SUCCESS)
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	if (sd->flags & WHICH_EC(devidx, select)) {
		VB2_DEBUG("%s: Failed to update\n", __func__);
		request_recovery(ctx, VB2_RECOVERY_EC_UPDATE);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	return VBERROR_SUCCESS;
}

/**
 * Check if the EC has the correct image active.
 *
 * @param ctx		Vboot2 context
 * @param devidx	Which device (EC=0, PD=1)
 * @return VBERROR_SUCCESS, or non-zero if error.
 */
static VbError_t check_ec_active(struct vb2_context *ctx, int devidx)
{
	struct vb2_shared_data *sd = vb2_get_sd(ctx);

	/* Determine whether the EC is in RO or RW */
	int in_rw = 0;
	int rv = VbExEcRunningRW(devidx, &in_rw);
	if (in_rw) {
		sd->flags |= IN_RW(devidx);
	}

	if (sd->recovery_reason) {
		/*
		 * Recovery mode; just verify the EC is in RO code.  Don't do
		 * software sync, since we don't have a RW image.
		 */
		if (rv == VBERROR_SUCCESS && in_rw == 1) {
			/*
			 * EC is definitely in RW firmware.  We want it in
			 * read-only code, so preserve the current recovery
			 * reason and reboot.
			 *
			 * We don't reboot on error or unknown EC code, because
			 * we could end up in an endless reboot loop.  If we
			 * had some way to track that we'd already rebooted for
			 * this reason, we could retry only once.
			 */
			VB2_DEBUG("%s: want recovery but got EC-RW\n",
				  __func__);
			request_recovery(ctx, sd->recovery_reason);
			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
		}

		VB2_DEBUG("%s: in recovery; EC-RO\n", __func__);
		return VBERROR_SUCCESS;
	}

	/*
	 * Not in recovery.  If we couldn't determine where the EC was,
	 * reboot to recovery.
	 */
	if (rv != VBERROR_SUCCESS) {
		VB2_DEBUG("%s: VbExEcRunningRW() returned %d\n", __func__, rv);
		request_recovery(ctx, VB2_RECOVERY_EC_UNKNOWN_IMAGE);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	return VBERROR_SUCCESS;
}

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

/**
 * Sync, jump, and protect one EC device
 *
 * @param ctx		Vboot2 context
 * @param devidx	Which device (EC=0, PD=1)
 * @return VBERROR_SUCCESS, or non-zero if error.
 */
static VbError_t sync_one_ec(struct vb2_context *ctx, int devidx,
			     VbCommonParams *cparams)
{
	VbSharedDataHeader *shared =
			(VbSharedDataHeader *)cparams->shared_data_blob;
	struct vb2_shared_data *sd = vb2_get_sd(ctx);
	const enum VbSelectFirmware_t select_rw =
		shared->firmware_index ? VB_SELECT_FIRMWARE_B :
		VB_SELECT_FIRMWARE_A;
	int rv;

	VB2_DEBUG("%s: devidx=%d\n", __func__, devidx);

	/* Update the RW Image */
	if (sd->flags & VB2_SD_FLAG_ECSYNC_RW) {
		if (VB2_SUCCESS != update_ec(ctx, devidx, select_rw))
			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	/* Tell EC to jump to its RW image */
	if (!(sd->flags & IN_RW(devidx))) {
		VB2_DEBUG("%s: jumping to EC-RW\n", __func__);
		rv = VbExEcJumpToRW(devidx);
		if (rv != VBERROR_SUCCESS) {
			VB2_DEBUG("%s: VbExEcJumpToRW() returned %x\n",
				  __func__, rv);

			/*
			 * If a previous AP boot has called VbExEcStayInRO(),
			 * 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 (but not PD-RO) */
	if (sd->flags & VB2_SD_FLAG_ECSYNC_EC_RO) {
		VB2_DEBUG("%s: RO Software Sync\n", __func__);

		/* 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, devidx, 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, devidx, VB_SELECT_FIRMWARE_READONLY);
	if (rv != VBERROR_SUCCESS)
		return rv;

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

	rv = VbExEcDisableJump(devidx);
	if (rv != VBERROR_SUCCESS) {
		VB2_DEBUG("%s: VbExEcDisableJump() returned %d\n",
			  __func__, rv);
		request_recovery(ctx, VB2_RECOVERY_EC_SOFTWARE_SYNC);
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	return rv;
}

VbError_t ec_sync_phase1(struct vb2_context *ctx, VbCommonParams *cparams)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	struct vb2_shared_data *sd = vb2_get_sd(ctx);

	/* Reasons not to do sync at all */
	if (!(shared->flags & VBSD_EC_SOFTWARE_SYNC))
		return VBERROR_SUCCESS;
	if (cparams->gbb->flags & GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC)
		return VBERROR_SUCCESS;

#ifdef PD_SYNC
	const int do_pd_sync = !(cparams->gbb->flags &
				 GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC);
#else
	const int do_pd_sync = 0;
#endif

	/* Make sure the EC is running the correct image */
	if (check_ec_active(ctx, 0))
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	if (do_pd_sync && check_ec_active(ctx, 1))
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;

	/*
	 * In recovery mode; just verify the EC is in RO code.  Don't do
	 * software sync, since we don't have a RW image.
	 */
	if (sd->recovery_reason)
		return VBERROR_SUCCESS;

	/* See if we need to update RW.  Failures trigger recovery mode. */
	const enum VbSelectFirmware_t select_rw =
			shared->firmware_index ? VB_SELECT_FIRMWARE_B :
			VB_SELECT_FIRMWARE_A;
	if (check_ec_hash(ctx, 0, select_rw))
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	if (do_pd_sync && check_ec_hash(ctx, 1, select_rw))
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	/*
	 * See if we need to update EC-RO (devidx=0).
	 *
	 * If we want to extend this in the future to update PD-RO, we'll use a
	 * different NV flag so we can track EC-RO and PD-RO updates
	 * separately.
	 */
	if (vb2_nv_get(ctx, VB2_NV_TRY_RO_SYNC) &&
	    !(shared->flags & VBSD_BOOT_FIRMWARE_WP_ENABLED) &&
	    check_ec_hash(ctx, 0, 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.
	 *
	 * TODO: Technically this isn't true for ECs which don't execute from
	 * flash.  For example, if the EC loads code from SPI into RAM before
	 * executing it.
	 */
	if ((sd->flags & VB2_SD_FLAG_ECSYNC_RW) &&
	    (sd->flags & VB2_SD_FLAG_ECSYNC_IN_RW)) {
		return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
	}

	return VBERROR_SUCCESS;
}

int ec_will_update_slowly(struct vb2_context *ctx, VbCommonParams *cparams)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	struct vb2_shared_data *sd = vb2_get_sd(ctx);

	return ((sd->flags & VB2_SD_FLAG_ECSYNC_ANY) &&
		(shared->flags & VBSD_EC_SLOW_UPDATE));
}

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

static int ec_sync_allowed(struct vb2_context *ctx, VbCommonParams *cparams)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;
	struct vb2_shared_data *sd = vb2_get_sd(ctx);

	/* Reasons not to do sync at all */
	if (!(shared->flags & VBSD_EC_SOFTWARE_SYNC))
		return 0;
	if (cparams->gbb->flags & GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC)
		return 0;
	if (sd->recovery_reason)
		return 0;
	return 1;
}

VbError_t ec_sync_check_aux_fw(struct vb2_context *ctx,
			       VbCommonParams *cparams,
			       VbAuxFwUpdateSeverity_t *severity)
{
	/* If we're not updating the EC, skip aux fw syncs as well */
	if (!ec_sync_allowed(ctx, cparams) ||
	    (cparams->gbb->flags & GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC)) {
		*severity = VB_AUX_FW_NO_UPDATE;
		return VBERROR_SUCCESS;
	}
	return VbExCheckAuxFw(severity);
}

VbError_t ec_sync_phase2(struct vb2_context *ctx, VbCommonParams *cparams)
{
	if (!ec_sync_allowed(ctx, cparams))
		return VBERROR_SUCCESS;

	/* Handle updates and jumps for EC */
	VbError_t retval = sync_one_ec(ctx, 0, cparams);
	if (retval != VBERROR_SUCCESS)
		return retval;

#ifdef PD_SYNC
	/* Handle updates and jumps for PD */
	if (!(cparams->gbb->flags & GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC)) {
		retval = sync_one_ec(ctx, 1, cparams);
		if (retval != VBERROR_SUCCESS)
			return retval;
	}
#endif

	return VBERROR_SUCCESS;
}

VbError_t ec_sync_phase3(struct vb2_context *ctx, VbCommonParams *cparams)
{
	VbSharedDataHeader *shared =
		(VbSharedDataHeader *)cparams->shared_data_blob;

	/* EC verification (and possibly updating / jumping) is done */
	VbError_t rv = VbExEcVbootDone(!!shared->recovery_reason);
	if (rv)
		return rv;

	/* Check if we need to cut-off battery. This must be done after EC
         * firmware updating and before kernel started. */
	if (vb2_nv_get(ctx, VB2_NV_BATTERY_CUTOFF_REQUEST)) {
		VB2_DEBUG("Request to cut-off battery\n");
		vb2_nv_set(ctx, VB2_NV_BATTERY_CUTOFF_REQUEST, 0);
		VbExEcBatteryCutOff();
		return VBERROR_SHUTDOWN_REQUESTED;
	}

	return VBERROR_SUCCESS;
}
