/* 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_RAW("%02x", hash[i]);
	VB2_DEBUG_RAW("\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("VbExEcHashImage() returned %d\n", 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("VbExEcGetExpectedImageHash() returned %d\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 |= 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("updating %s...\n",
		  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("VbExEcGetExpectedImage() returned %d\n", rv);
		request_recovery(ctx, VB2_RECOVERY_EC_EXPECTED_IMAGE);
		return rv;
	}
	VB2_DEBUG("image len = %d\n", want_size);

	rv = VbExEcUpdateImage(devidx, select, want, want_size);
	if (rv != VBERROR_SUCCESS) {
		VB2_DEBUG("VbExEcUpdateImage() returned %d\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 &= ~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("Failed to update\n");
		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("want recovery but got EC-RW\n");
			request_recovery(ctx, sd->recovery_reason);
			return VBERROR_EC_REBOOT_TO_RO_REQUIRED;
		}

		VB2_DEBUG("in recovery; EC-RO\n");
		return VBERROR_SUCCESS;
	}

	/*
	 * Not in recovery.  If we couldn't determine where the EC was,
	 * reboot to recovery.
	 */
	if (rv != VBERROR_SUCCESS) {
		VB2_DEBUG("VbExEcRunningRW() returned %d\n", 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("devidx=%d\n", 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("jumping to EC-RW\n");
		rv = VbExEcJumpToRW(devidx);
		if (rv != VBERROR_SUCCESS) {
			VB2_DEBUG("VbExEcJumpToRW() returned %x\n", 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("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, 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("VbExEcDisableJump() returned %d\n", 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_update_aux_fw(struct vb2_context *ctx)
{
	VbError_t rv = VbExUpdateAuxFw();
	if (rv) {
		if (rv == VBERROR_EC_REBOOT_TO_RO_REQUIRED) {
			VB2_DEBUG("AUX firmware update requires RO reboot.\n");
		} else {
			VB2_DEBUG("AUX firmware update/protect failed.\n");
			request_recovery(ctx, VB2_RECOVERY_AUX_FW_UPDATE);
		}
	}
	return rv;
}

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);
		/* May lose power immediately, so commit our update now. */
		vb2_nv_commit(ctx);
		VbExEcBatteryCutOff();
		return VBERROR_SHUTDOWN_REQUESTED;
	}

	return VBERROR_SUCCESS;
}
