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;
+}
+