Trusted Firmware-A Tests, version 2.0

This is the first public version of the tests for the Trusted
Firmware-A project. Please see the documentation provided in the
source tree for more details.

Change-Id: I6f3452046a1351ac94a71b3525c30a4ca8db7867
Signed-off-by: Sandrine Bailleux <sandrine.bailleux@arm.com>
Co-authored-by: amobal01 <amol.balasokamble@arm.com>
Co-authored-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Co-authored-by: Asha R <asha.r@arm.com>
Co-authored-by: Chandni Cherukuri <chandni.cherukuri@arm.com>
Co-authored-by: David Cunado <david.cunado@arm.com>
Co-authored-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
Co-authored-by: Douglas Raillard <douglas.raillard@arm.com>
Co-authored-by: dp-arm <dimitris.papastamos@arm.com>
Co-authored-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Co-authored-by: Jonathan Wright <jonathan.wright@arm.com>
Co-authored-by: Kévin Petit <kevin.petit@arm.com>
Co-authored-by: Roberto Vargas <roberto.vargas@arm.com>
Co-authored-by: Sathees Balya <sathees.balya@arm.com>
Co-authored-by: Shawon Roy <Shawon.Roy@arm.com>
Co-authored-by: Soby Mathew <soby.mathew@arm.com>
Co-authored-by: Thomas Abraham <thomas.abraham@arm.com>
Co-authored-by: Vikram Kanigiri <vikram.kanigiri@arm.com>
Co-authored-by: Yatharth Kochar <yatharth.kochar@arm.com>
diff --git a/plat/common/fwu_nvm_accessors.c b/plat/common/fwu_nvm_accessors.c
new file mode 100644
index 0000000..5b32151
--- /dev/null
+++ b/plat/common/fwu_nvm_accessors.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <firmware_image_package.h>
+#include <fwu_nvm.h>
+#include <io_fip.h>
+#include <io_storage.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <status.h>
+#include <string.h>
+#include <uuid_utils.h>
+
+
+STATUS fwu_nvm_write(unsigned long long offset, const void *buffer, size_t size)
+{
+	uintptr_t nvm_handle;
+	int ret;
+	size_t length_write;
+
+	if (offset + size > FLASH_SIZE)
+		return STATUS_OUT_OF_RESOURCES;
+
+	/* Obtain a handle to the NVM by querying the platfom layer */
+	plat_get_nvm_handle(&nvm_handle);
+
+	/* Seek to the given offset. */
+	ret = io_seek(nvm_handle, IO_SEEK_SET, offset);
+	if (ret != IO_SUCCESS)
+		return STATUS_FAIL;
+
+	/* Write to the given offset. */
+	ret = io_write(nvm_handle, (const uintptr_t)buffer,
+		size, &length_write);
+	if ((ret != IO_SUCCESS) || (size != length_write))
+		return STATUS_FAIL;
+
+	return STATUS_SUCCESS;
+}
+
+STATUS fwu_nvm_read(unsigned long long offset, void *buffer, size_t size)
+{
+	uintptr_t nvm_handle;
+	int ret;
+	size_t length_read;
+
+	if (offset + size > FLASH_SIZE)
+		return STATUS_OUT_OF_RESOURCES;
+
+	/* Obtain a handle to the NVM by querying the platform layer */
+	plat_get_nvm_handle(&nvm_handle);
+
+	/* Seek to the given offset. */
+	ret = io_seek(nvm_handle, IO_SEEK_SET, offset);
+	if (ret != IO_SUCCESS)
+		return STATUS_FAIL;
+
+	/* Read from the given offset. */
+	ret = io_read(nvm_handle, (const uintptr_t)buffer,
+		size, &length_read);
+	if ((ret != IO_SUCCESS) || (size != length_read))
+		return STATUS_FAIL;
+
+	return STATUS_SUCCESS;
+}
+
+
+STATUS fwu_update_fip(unsigned long fip_addr)
+{
+	uintptr_t nvm_handle;
+	int ret;
+	size_t bytes;
+	int fip_size;
+	unsigned int fip_read;
+	fip_toc_header_t *toc_header;
+	fip_toc_entry_t *toc_entry;
+
+	/* Obtain a handle to the NVM by querying the platform layer */
+	plat_get_nvm_handle(&nvm_handle);
+
+#if FWU_BL_TEST
+	/* Read the address of backup fip.bin for Firmware Update. */
+	ret = io_seek(nvm_handle, IO_SEEK_SET,
+			FWU_TFTF_TESTCASE_BUFFER_OFFSET);
+	if (ret != IO_SUCCESS)
+		return STATUS_FAIL;
+
+	ret = io_read(nvm_handle, (const uintptr_t)&fip_addr,
+			sizeof(bytes), &bytes);
+	if (ret != IO_SUCCESS)
+		return STATUS_FAIL;
+#endif /* FWU_BL_TEST */
+
+	/* If the new FIP address is 0 it means no update. */
+	if (fip_addr == 0)
+		return STATUS_SUCCESS;
+
+	/* Set the ToC Header at the base of the buffer */
+	toc_header = (fip_toc_header_t *)fip_addr;
+
+	/* Check if this FIP is Valid */
+	if ((toc_header->name != TOC_HEADER_NAME) ||
+		(toc_header->serial_number == 0))
+		return STATUS_LOAD_ERROR;
+
+	/* Get to the last NULL TOC entry */
+	toc_entry = (fip_toc_entry_t *)(toc_header + 1);
+	while (!is_uuid_null(&toc_entry->uuid))
+		toc_entry++;
+
+	/* get the total size of this FIP */
+	fip_size = (int)toc_entry->offset_address;
+
+	/* Copy the new FIP in DDR. */
+	memcpy((void *)FIP_IMAGE_TMP_DDR_ADDRESS, (void *)fip_addr, fip_size);
+
+	/* Update the FIP */
+	ret = io_seek(nvm_handle, IO_SEEK_SET, 0);
+	if (ret != IO_SUCCESS)
+		return STATUS_FAIL;
+
+	ret = io_write(nvm_handle, (const uintptr_t)FIP_IMAGE_TMP_DDR_ADDRESS,
+			fip_size, &bytes);
+	if ((ret != IO_SUCCESS) || fip_size != bytes)
+		return STATUS_LOAD_ERROR;
+
+	/* Read the TOC header after update. */
+	ret = io_seek(nvm_handle, IO_SEEK_SET, 0);
+	if (ret != IO_SUCCESS)
+		return STATUS_LOAD_ERROR;
+
+	ret = io_read(nvm_handle, (const uintptr_t)&fip_read,
+		sizeof(bytes), &bytes);
+	if (ret != IO_SUCCESS)
+		return STATUS_FAIL;
+
+	/* Check if this FIP is Valid */
+	if (fip_read != TOC_HEADER_NAME)
+		return STATUS_LOAD_ERROR;
+
+#if FWU_BL_TEST
+	unsigned int done_flag = FIP_IMAGE_UPDATE_DONE_FLAG;
+	/* Update the TFTF test case buffer with DONE flag */
+	ret = io_seek(nvm_handle, IO_SEEK_SET,
+			FWU_TFTF_TESTCASE_BUFFER_OFFSET);
+	if (ret != IO_SUCCESS)
+		return STATUS_FAIL;
+
+	ret = io_write(nvm_handle, (const uintptr_t)&done_flag,
+			4, &bytes);
+	if (ret != IO_SUCCESS)
+		return STATUS_FAIL;
+#endif /* FWU_BL_TEST */
+
+	INFO("FWU Image update success\n");
+
+	return STATUS_SUCCESS;
+}
+