/* Copyright 2019 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.
 *
 * Tests for auxfw synchronization.
 */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include "2common.h"
#include "2misc.h"
#include "2nvstorage.h"
#include "2sysincludes.h"
#include "host_common.h"
#include "load_kernel_fw.h"
#include "test_common.h"
#include "vboot_audio.h"
#include "vboot_kernel.h"
#include "vboot_struct.h"
#include "vboot_ui_legacy.h"

/* Mock data */
static struct vb2_context *ctx;
static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
	__attribute__((aligned(VB2_WORKBUF_ALIGN)));
static struct vb2_shared_data *sd;
static struct vb2_gbb_header gbb;

static vb2_error_t auxfw_retval;
static int auxfw_update_req;
static enum vb2_auxfw_update_severity auxfw_mock_severity;
static enum vb2_auxfw_update_severity auxfw_update_severity;
static int auxfw_mock_display_available;
static int auxfw_protected;
static vb2_error_t auxfw_done_retval;

/* Reset mock data (for use before each test) */
static void ResetMocks(void)
{
	TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx),
		  "vb2api_init failed");

	ctx->flags = VB2_CONTEXT_EC_SYNC_SUPPORTED;
	vb2_nv_init(ctx);

	sd = vb2_get_sd(ctx);

	memset(&gbb, 0, sizeof(gbb));

	auxfw_retval = VB2_SUCCESS;
	auxfw_mock_severity = VB2_AUXFW_NO_UPDATE;
	auxfw_update_severity = VB2_AUXFW_NO_UPDATE;
	auxfw_mock_display_available = 1;
	auxfw_update_req = 0;
	auxfw_protected = 0;
	auxfw_done_retval = VB2_SUCCESS;
}

/* Mock functions */
struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
{
	return &gbb;
}

vb2_error_t vb2ex_auxfw_check(enum vb2_auxfw_update_severity *severity)
{
	*severity = auxfw_mock_severity;
	auxfw_update_severity = auxfw_mock_severity;
	if (*severity == VB2_AUXFW_SLOW_UPDATE)
		if (!auxfw_mock_display_available)
			return VB2_REQUEST_REBOOT;
	return VB2_SUCCESS;
}

vb2_error_t vb2ex_auxfw_update(void)
{
	if (auxfw_update_severity != VB2_AUXFW_NO_DEVICE &&
	    auxfw_update_severity != VB2_AUXFW_NO_UPDATE)
		auxfw_update_req = 1;
	return auxfw_retval;
}

vb2_error_t vb2ex_auxfw_finalize(struct vb2_context *c)
{
	auxfw_protected = auxfw_update_severity != VB2_AUXFW_NO_DEVICE;
	return auxfw_done_retval;
}

static void test_auxsync(vb2_error_t retval, int recovery_reason,
			 const char *desc)
{
	TEST_EQ(vb2api_auxfw_sync(ctx), retval, desc);
	TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
		recovery_reason, "  recovery reason");
}

/* Tests */

static void VbSoftwareSyncTest(void)
{
	ResetMocks();
	gbb.flags |= VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC;
	auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE;
	test_auxsync(VB2_REQUEST_REBOOT_EC_TO_RO, 0,
		     "VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC"
		     " does not disable auxfw update request");
	TEST_EQ(auxfw_update_req, 1, "  auxfw update requested");
	TEST_EQ(auxfw_protected, 0, "  auxfw protected");

	ResetMocks();
	gbb.flags |= VB2_GBB_FLAG_DISABLE_AUXFW_SOFTWARE_SYNC;
	auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE;
	test_auxsync(VB2_SUCCESS, 0,
		     "VB2_GBB_FLAG_DISABLE_AUXFW_SOFTWARE_SYNC"
		     " disables auxfw update request");
	TEST_EQ(auxfw_update_req, 0, "  auxfw update disabled");
	TEST_EQ(auxfw_protected, 1, "  auxfw protected");

	ResetMocks();
	auxfw_mock_severity = VB2_AUXFW_NO_DEVICE;
	test_auxsync(VB2_SUCCESS, 0,
		     "No auxfw update needed");
	TEST_EQ(auxfw_update_req, 0, "  no auxfw update requested");
	TEST_EQ(auxfw_protected, 0, "  no auxfw protected");

	ResetMocks();
	auxfw_mock_severity = VB2_AUXFW_NO_UPDATE;
	test_auxsync(VB2_SUCCESS, 0,
		"No auxfw update needed");
	TEST_EQ(auxfw_update_req, 0, "  no auxfw update requested");
	TEST_EQ(auxfw_protected, 1, "  auxfw protected");

	ResetMocks();
	auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE;
	test_auxsync(VB2_REQUEST_REBOOT_EC_TO_RO, 0,
		     "Fast auxfw update needed");
	TEST_EQ(auxfw_update_req, 1, "  auxfw update requested");
	TEST_EQ(auxfw_protected, 0, "  auxfw protected");

	ResetMocks();
	auxfw_mock_severity = VB2_AUXFW_SLOW_UPDATE;
	auxfw_mock_display_available = 0;
	test_auxsync(VB2_REQUEST_REBOOT, 0,
		     "Slow auxfw update needed - reboot for display");

	ResetMocks();
	auxfw_mock_severity = VB2_AUXFW_SLOW_UPDATE;
	test_auxsync(VB2_REQUEST_REBOOT_EC_TO_RO, 0,
		     "Slow auxfw update needed");
	TEST_EQ(auxfw_update_req, 1, "  auxfw update requested");
	TEST_EQ(auxfw_protected, 0, "  auxfw protected");

	ResetMocks();
	auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE;
	auxfw_retval = VB2_ERROR_UNKNOWN;
	test_auxsync(VB2_ERROR_UNKNOWN, VB2_RECOVERY_AUXFW_UPDATE,
		     "Error updating auxfw");
}

int main(void)
{
	VbSoftwareSyncTest();

	return gTestSuccess ? 0 : 255;
}
