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/include/common/aarch32/asm_macros.S b/include/common/aarch32/asm_macros.S
new file mode 100644
index 0000000..2edf5b9
--- /dev/null
+++ b/include/common/aarch32/asm_macros.S
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __ASM_MACROS_S__
+#define __ASM_MACROS_S__
+
+#include <arch.h>
+#include <asm_macros_common.S>
+
+#define TLB_INVALIDATE(_reg, _coproc) \
+ stcopr _reg, _coproc
+
+ /*
+ * Co processor register accessors
+ */
+ .macro ldcopr reg, coproc, opc1, CRn, CRm, opc2
+ mrc \coproc, \opc1, \reg, \CRn, \CRm, \opc2
+ .endm
+
+ .macro ldcopr16 reg1, reg2, coproc, opc1, CRm
+ mrrc \coproc, \opc1, \reg1, \reg2, \CRm
+ .endm
+
+ .macro stcopr reg, coproc, opc1, CRn, CRm, opc2
+ mcr \coproc, \opc1, \reg, \CRn, \CRm, \opc2
+ .endm
+
+ .macro stcopr16 reg1, reg2, coproc, opc1, CRm
+ mcrr \coproc, \opc1, \reg1, \reg2, \CRm
+ .endm
+
+ /* Cache line size helpers */
+ .macro dcache_line_size reg, tmp
+ ldcopr \tmp, CTR
+ ubfx \tmp, \tmp, #16, #4
+ mov \reg, #4
+ lsl \reg, \reg, \tmp
+ .endm
+
+ .macro icache_line_size reg, tmp
+ ldcopr \tmp, CTR
+ and \tmp, \tmp, #0xf
+ mov \reg, #4
+ lsl \reg, \reg, \tmp
+ .endm
+
+ /*
+ * Declare the exception vector table, enforcing it is aligned on a
+ * 32 byte boundary.
+ */
+ .macro vector_base label
+ .section .vectors, "ax"
+ .align 5
+ \label:
+ .endm
+
+ /*
+ * This macro calculates the base address of an MP stack using the
+ * platform_get_core_pos() index, the name of the stack storage and
+ * the size of each stack
+ * Out: r0 = physical address of stack base
+ * Clobber: r14, r1, r2
+ */
+ .macro get_mp_stack _name, _size
+ bl platform_get_core_pos
+ ldr r2, =(\_name + \_size)
+ mov r1, #\_size
+ mla r0, r0, r1, r2
+ .endm
+
+ /*
+ * This macro calculates the base address of a uniprocessor(UP) stack
+ * using the name of the stack storage and the size of the stack
+ * Out: r0 = physical address of stack base
+ */
+ .macro get_up_stack _name, _size
+ ldr r0, =(\_name + \_size)
+ .endm
+
+#endif /* __ASM_MACROS_S__ */
+
diff --git a/include/common/aarch32/assert_macros.S b/include/common/aarch32/assert_macros.S
new file mode 100644
index 0000000..5dc9e64
--- /dev/null
+++ b/include/common/aarch32/assert_macros.S
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __ASSERT_MACROS_S__
+#define __ASSERT_MACROS_S__
+
+ /*
+ * Assembler macro to enable asm_assert. We assume that the stack is
+ * initialized prior to invoking this macro. Please note that the
+ * macro makes use of label '300' to provide the logic and the
+ * caller should make sure that this label is not used to branch
+ * prior to calling this macro.
+ */
+#define ASM_ASSERT(_cc) \
+.ifndef .L_assert_filename ;\
+ .pushsection .rodata.str1.1, "aS" ;\
+ .L_assert_filename: ;\
+ .string __FILE__ ;\
+ .popsection ;\
+.endif ;\
+ b##_cc 300f ;\
+ ldr r0, =.L_assert_filename ;\
+ mov r1, #__LINE__ ;\
+ b asm_assert ;\
+300:
+
+#endif /* __ASSERT_MACROS_S__ */
diff --git a/include/common/aarch64/asm_macros.S b/include/common/aarch64/asm_macros.S
new file mode 100644
index 0000000..ad47290
--- /dev/null
+++ b/include/common/aarch64/asm_macros.S
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __ASM_MACROS_S__
+#define __ASM_MACROS_S__
+
+#include <arch.h>
+#include <asm_macros_common.S>
+
+#define TLB_INVALIDATE(_type) \
+ tlbi _type
+
+ .macro func_prologue
+ stp x29, x30, [sp, #-0x10]!
+ mov x29,sp
+ .endm
+
+ .macro func_epilogue
+ ldp x29, x30, [sp], #0x10
+ .endm
+
+
+ .macro dcache_line_size reg, tmp
+ mrs \tmp, ctr_el0
+ ubfx \tmp, \tmp, #16, #4
+ mov \reg, #4
+ lsl \reg, \reg, \tmp
+ .endm
+
+
+ .macro icache_line_size reg, tmp
+ mrs \tmp, ctr_el0
+ and \tmp, \tmp, #0xf
+ mov \reg, #4
+ lsl \reg, \reg, \tmp
+ .endm
+
+ /*
+ * Declare the exception vector table, enforcing it is aligned on a
+ * 2KB boundary, as required by the ARMv8 architecture.
+ * Use zero bytes as the fill value to be stored in the padding bytes
+ * so that it inserts illegal AArch64 instructions. This increases
+ * security, robustness and potentially facilitates debugging.
+ */
+ .macro vector_base label
+ .section .vectors, "ax"
+ .align 11, 0
+ \label:
+ .endm
+
+ /*
+ * Create an entry in the exception vector table, enforcing it is
+ * aligned on a 128-byte boundary, as required by the ARMv8
+ * architecture. Use zero bytes as the fill value to be stored in the
+ * padding bytes so that it inserts illegal AArch64 instructions.
+ * This increases security, robustness and potentially facilitates
+ * debugging.
+ */
+ .macro vector_entry label
+ .section .vectors, "ax"
+ .align 7, 0
+ \label:
+ .endm
+
+ /*
+ * This macro verifies that the a given vector doesn't exceed the
+ * architectural limit of 32 instructions. This is meant to be placed
+ * immedately after the last instruction in the vector. It takes the
+ * vector entry as the parameter
+ */
+ .macro check_vector_size since
+ .if (. - \since) > (32 * 4)
+ .error "Vector exceeds 32 instructions"
+ .endif
+ .endm
+
+ /*
+ * This macro calculates the base address of an MP stack using the
+ * platform_get_core_pos() index, the name of the stack storage and
+ * the size of each stack
+ * Out: X0 = physical address of stack base
+ * Clobber: X30, X1, X2
+ */
+ .macro get_mp_stack _name, _size
+ bl platform_get_core_pos
+ ldr x2, =(\_name + \_size)
+ mov x1, #\_size
+ madd x0, x0, x1, x2
+ .endm
+
+ /*
+ * This macro calculates the base address of a UP stack using the
+ * name of the stack storage and the size of the stack
+ * Out: X0 = physical address of stack base
+ */
+ .macro get_up_stack _name, _size
+ ldr x0, =(\_name + \_size)
+ .endm
+
+ /*
+ * Helper macro to generate the best mov/movk combinations according
+ * the value to be moved. The 16 bits from '_shift' are tested and
+ * if not zero, they are moved into '_reg' without affecting
+ * other bits.
+ */
+ .macro _mov_imm16 _reg, _val, _shift
+ .if (\_val >> \_shift) & 0xffff
+ .if (\_val & (1 << \_shift - 1))
+ movk \_reg, (\_val >> \_shift) & 0xffff, LSL \_shift
+ .else
+ mov \_reg, \_val & (0xffff << \_shift)
+ .endif
+ .endif
+ .endm
+
+ /*
+ * Helper macro to load arbitrary values into 32 or 64-bit registers
+ * which generates the best mov/movk combinations. Many base addresses
+ * are 64KB aligned the macro will eliminate updating bits 15:0 in
+ * that case
+ */
+ .macro mov_imm _reg, _val
+ .if (\_val) == 0
+ mov \_reg, #0
+ .else
+ _mov_imm16 \_reg, (\_val), 0
+ _mov_imm16 \_reg, (\_val), 16
+ _mov_imm16 \_reg, (\_val), 32
+ _mov_imm16 \_reg, (\_val), 48
+ .endif
+ .endm
+
+ .macro asm_read_sysreg_el1_or_el2 sysreg
+ mrs x0, CurrentEL
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq 1f
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq 2f
+ b dead
+1:
+ mrs x0, \sysreg\()_el1
+ b 3f
+2:
+ mrs x0, \sysreg\()_el2
+3:
+ .endm
+
+ .macro asm_write_sysreg_el1_or_el2 sysreg scratch_reg
+ mrs \scratch_reg, CurrentEL
+ cmp \scratch_reg, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq 1f
+ cmp \scratch_reg, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq 2f
+ b dead
+1:
+ msr \sysreg\()_el1, x0
+ b 3f
+2:
+ msr \sysreg\()_el2, x0
+3:
+ .endm
+
+ .macro asm_read_sctlr_el1_or_el2
+ asm_read_sysreg_el1_or_el2 sctlr
+ .endm
+
+ .macro asm_write_sctlr_el1_or_el2 scratch_reg
+ asm_write_sysreg_el1_or_el2 sctlr \scratch_reg
+ .endm
+
+ .macro asm_write_vbar_el1_or_el2 scratch_reg
+ asm_write_sysreg_el1_or_el2 vbar \scratch_reg
+ .endm
+
+/*
+ * Depending on the current exception level, jump to 'label_el1' or 'label_el2'.
+ * If the current exception level is neither EL1 nor EL2, jump to 'label_error'
+ * instead.
+ * The caller needs to provide the macro with a scratch 64-bit register to use.
+ * Its contents prior to calling this function will be lost.
+ */
+ .macro JUMP_EL1_OR_EL2 scratch_reg, label_el1, label_el2, label_error
+ mrs \scratch_reg, CurrentEL
+ cmp \scratch_reg, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq \label_el1
+ cmp \scratch_reg, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq \label_el2
+ b \label_error
+ .endm
+
+#endif /* __ASM_MACROS_S__ */
diff --git a/include/common/aarch64/assert_macros.S b/include/common/aarch64/assert_macros.S
new file mode 100644
index 0000000..b916331
--- /dev/null
+++ b/include/common/aarch64/assert_macros.S
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __ASSERT_MACROS_S__
+#define __ASSERT_MACROS_S__
+
+ /*
+ * Assembler macro to enable asm_assert. Use this macro wherever
+ * assert is required in assembly. Please note that the macro makes
+ * use of label '300' to provide the logic and the caller
+ * should make sure that this label is not used to branch prior
+ * to calling this macro.
+ */
+#define ASM_ASSERT(_cc) \
+.ifndef .L_assert_filename ;\
+ .pushsection .rodata.str1.1, "aS" ;\
+ .L_assert_filename: ;\
+ .string __FILE__ ;\
+ .popsection ;\
+.endif ;\
+ b._cc 300f ;\
+ adr x0, .L_assert_filename ;\
+ mov x1, __LINE__ ;\
+ b asm_assert ;\
+300:
+
+#endif /* __ASSERT_MACROS_S__ */
diff --git a/include/common/asm_macros_common.S b/include/common/asm_macros_common.S
new file mode 100644
index 0000000..d38dcce
--- /dev/null
+++ b/include/common/asm_macros_common.S
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __ASM_MACROS_COMMON_S__
+#define __ASM_MACROS_COMMON_S__
+
+ /*
+ * This macro is used to create a function label and place the
+ * code into a separate text section based on the function name
+ * to enable elimination of unused code during linking. It also adds
+ * basic debug information to enable call stack printing most of the
+ * time.
+ */
+ .macro func _name
+ /*
+ * Add Call Frame Information entry in the .debug_frame section for
+ * debugger consumption. This enables callstack printing in debuggers.
+ * This does not use any space in the final loaded binary, only in the
+ * ELF file.
+ * Note that a function manipulating the CFA pointer location (i.e. the
+ * x29 frame pointer on AArch64) should declare it using the
+ * appropriate .cfi* directives, or be prepared to have a degraded
+ * debugging experience.
+ */
+ .cfi_sections .debug_frame
+ .section .text.\_name, "ax"
+ .type \_name, %function
+ .func \_name
+ /*
+ * .cfi_startproc and .cfi_endproc are needed to output entries in
+ * .debug_frame
+ */
+ .cfi_startproc
+ \_name:
+ .endm
+
+ /*
+ * This macro is used to mark the end of a function.
+ */
+ .macro endfunc _name
+ .endfunc
+ .cfi_endproc
+ .size \_name, . - \_name
+ .endm
+
+ /*
+ * This macro declares an array of 1 or more stacks, properly
+ * aligned and in the requested section
+ */
+#define STACK_ALIGN 6
+
+ .macro declare_stack _name, _section, _size, _count
+ .if ((\_size & ((1 << STACK_ALIGN) - 1)) <> 0)
+ .error "Stack size not correctly aligned"
+ .endif
+ .section \_section, "aw", %nobits
+ .align STACK_ALIGN
+ \_name:
+ .space ((\_count) * (\_size)), 0
+ .endm
+
+#endif /* __ASM_MACROS_COMMON_S__ */
+
diff --git a/include/common/debug.h b/include/common/debug.h
new file mode 100644
index 0000000..c5b0f8e
--- /dev/null
+++ b/include/common/debug.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014-2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+#include <stdio.h>
+
+/* TODO: Deal with per-image printf functions in a cleaner way. */
+
+#ifdef IMAGE_CACTUS
+/*
+ * The register MPIDR_EL1 can't be read from EL0, which means that mp_printf()
+ * can't be used.
+ */
+#define mp_printf printf
+#else
+/*
+ * Print a formatted string on the UART.
+ *
+ * Does the same thing as the standard libc's printf() function but in a MP-safe
+ * manner, i.e. it can be called from several CPUs simultaneously without
+ * getting interleaved messages.
+ *
+ * The messages printed using mp_printf() won't be saved in the test results
+ * (use tftf_testcase_output() instead for that). mp_printf() is meant to be
+ * used for debug traces only. Unlike messages stored in the tests output which
+ * appear only at the end of the test session in the test report, messages
+ * printed using mp_printf() will be displayed straight away.
+ *
+ * Messaged will be prefixed by the CPU MPID issuing the call, like that:
+ * [cpu 0x0002] Sending SGI #1 to cpu 0
+ */
+__attribute__((format(printf, 1, 2)))
+void mp_printf(const char *fmt, ...);
+#endif
+
+/*
+ * The log output macros print output to the console. These macros produce
+ * compiled log output only if the LOG_LEVEL defined in the makefile (or the
+ * make command line) is greater or equal than the level required for that
+ * type of log output.
+ * The format expected is similar to printf(). For example:
+ * INFO("Info %s.\n", "message") -> [cpu 0xxx] INFO: Info message.
+ * WARN("Warning %s.\n", "message") -> [cpu 0xxx] WARNING: Warning message.
+ */
+#define LOG_LEVEL_NONE 0
+#define LOG_LEVEL_ERROR 10
+#define LOG_LEVEL_NOTICE 20
+#define LOG_LEVEL_WARNING 30
+#define LOG_LEVEL_INFO 40
+#define LOG_LEVEL_VERBOSE 50
+
+#if LOG_LEVEL >= LOG_LEVEL_NOTICE
+# define NOTICE(...) mp_printf("NOTICE: " __VA_ARGS__)
+#else
+# define NOTICE(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_ERROR
+# define ERROR(...) mp_printf("ERROR: " __VA_ARGS__)
+#else
+# define ERROR(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_WARNING
+# define WARN(...) mp_printf("WARNING: " __VA_ARGS__)
+#else
+# define WARN(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+# define INFO(...) mp_printf("INFO: " __VA_ARGS__)
+#else
+# define INFO(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+# define VERBOSE(...) mp_printf("VERBOSE: " __VA_ARGS__)
+#else
+# define VERBOSE(...)
+#endif
+
+/*
+ * For the moment this Panic function is very basic, Report an error and
+ * spin. This can be expanded in the future to provide more information.
+ */
+#if DEBUG
+void __attribute__((__noreturn__)) do_panic(const char *file, int line);
+#define panic() do_panic(__FILE__, __LINE__)
+
+void __attribute__((__noreturn__)) do_bug_unreachable(const char *file, int line);
+#define bug_unreachable() do_bug_unreachable(__FILE__, __LINE__)
+
+#else
+void __attribute__((__noreturn__)) do_panic(void);
+#define panic() do_panic()
+
+void __attribute__((__noreturn__)) do_bug_unreachable(void);
+#define bug_unreachable() do_bug_unreachable()
+
+#endif
+
+#endif /* __DEBUG_H__ */
diff --git a/include/common/firmware_image_package.h b/include/common/firmware_image_package.h
new file mode 100644
index 0000000..f168f23
--- /dev/null
+++ b/include/common/firmware_image_package.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __FIRMWARE_IMAGE_PACKAGE_H__
+#define __FIRMWARE_IMAGE_PACKAGE_H__
+
+#include <stdint.h>
+#include <uuid.h>
+
+/* This is used as a signature to validate the blob header */
+#define TOC_HEADER_NAME 0xAA640001
+
+/* ToC Entry UUIDs */
+#define UUID_FIRMWARE_UPDATE_SCP_BL2U \
+ {0x03279265, 0x742f, 0x44e6, 0x8d, 0xff, {0x57, 0x9a, 0xc1, 0xff, 0x06, 0x10} }
+#define UUID_FIRMWARE_UPDATE_BL2U \
+ {0x37ebb360, 0xe5c1, 0x41ea, 0x9d, 0xf3, {0x19, 0xed, 0xa1, 0x1f, 0x68, 0x01} }
+#define UUID_FIRMWARE_UPDATE_NS_BL2U \
+ {0x111d514f, 0xe52b, 0x494e, 0xb4, 0xc5, {0x83, 0xc2, 0xf7, 0x15, 0x84, 0x0a} }
+#define UUID_FIRMWARE_UPDATE_FWU_CERT \
+ {0xb28a4071, 0xd618, 0x4c87, 0x8b, 0x2e, {0xc6, 0xdc, 0xcd, 0x50, 0xf0, 0x96} }
+
+typedef struct fip_toc_header {
+ uint32_t name;
+ uint32_t serial_number;
+ uint64_t flags;
+} fip_toc_header_t;
+
+typedef struct fip_toc_entry {
+ uuid_t uuid;
+ uint64_t offset_address;
+ uint64_t size;
+ uint64_t flags;
+} fip_toc_entry_t;
+
+#endif /* __FIRMWARE_IMAGE_PACKAGE_H__ */
diff --git a/include/common/fwu_nvm.h b/include/common/fwu_nvm.h
new file mode 100644
index 0000000..923a596
--- /dev/null
+++ b/include/common/fwu_nvm.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __FWU_NVM_H__
+#define __FWU_NVM_H__
+
+#include <nvm.h>
+#include <platform_def.h>
+
+#define FIP_IMAGE_UPDATE_DONE_FLAG (0xDEADBEEF)
+/*
+ * This is the temporary ddr address for loading backup fip.bin
+ * image from NVM which is used for replacing original fip.bin
+ * This address is chosen such that the NS_BL2U can be expanded
+ * in future and also considering the large size of fip.bin.
+ */
+#define FIP_IMAGE_TMP_DDR_ADDRESS (DRAM_BASE + 0x100000)
+#define FWU_TFTF_TESTCASE_BUFFER_OFFSET \
+ (TFTF_NVM_OFFSET + TFTF_STATE_OFFSET(testcase_buffer))
+
+/*
+ * This offset is used to corrupt data in fip.bin
+ * The offset is from the base where fip.bin is
+ * located in NVM. This particular value is chosen
+ * to make sure the corruption is done beyond fip header.
+ */
+#define FIP_CORRUPT_OFFSET (0x300)
+
+/*
+ * This is the base address for backup fip.bin image in NVM
+ * which is used for replacing original fip.bin
+ * This address is chosen such that it can stay with all
+ * the other images in the NVM.
+ */
+#define FIP_BKP_ADDRESS (FLASH_BASE + 0x1000000)
+
+/* Writes the buffer to the flash at offset with length equal to
+ * size
+ * Returns: STATUS_FAIL, STATUS_SUCCESS, STATUS_OUT_OF_RESOURCES
+ */
+STATUS fwu_nvm_write(unsigned long long offset, const void *buffer, size_t size);
+
+/* Reads the flash into buffer at offset with length equal to
+ * size
+ * Returns: STATUS_FAIL, STATUS_SUCCESS, STATUS_OUT_OF_RESOURCES
+ */
+STATUS fwu_nvm_read(unsigned long long offset, void *buffer, size_t size);
+
+/*
+ * This function is used to replace the original fip.bin
+ * by the backup fip.bin passed through fip_addr argument.
+ */
+STATUS fwu_update_fip(unsigned long fip_addr);
+
+#endif /* __FWU_NVM_H__ */
diff --git a/include/common/image_loader.h b/include/common/image_loader.h
new file mode 100644
index 0000000..032c00e
--- /dev/null
+++ b/include/common/image_loader.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __IMAGE_LOADER_H__
+#define __IMAGE_LOADER_H__
+
+#include <firmware_image_package.h>
+#include <stddef.h>
+#include <stdint.h>
+
+/* Generic function to get flash offset of an image */
+unsigned long get_image_offset(unsigned int image_id);
+
+/* Generic function to return the size of an image */
+unsigned long get_image_size(unsigned int image_id);
+
+/*
+ * Generic function to load an image at a specific address given an image id
+ * Returns 0 on success, a negative error code otherwise.
+ */
+int load_image(unsigned int image_id,
+ uintptr_t image_base);
+
+/*
+ * Generic function to load partial image at a specific address given
+ * an image id. The flag argument is used to indicate last block to be
+ * loaded in the partial loading scenario. If is_last_block == 0 then
+ * devices are closed else they are kept open for partial image loading.
+ * Returns 0 on success, a negative error code otherwise.
+ */
+int load_partial_image(unsigned int image_id,
+ uintptr_t image_base,
+ size_t image_size,
+ unsigned int is_last_block);
+
+/* This is to keep track of file related data. */
+typedef struct {
+ unsigned int file_pos;
+ fip_toc_entry_t entry;
+} fip_file_state_t;
+
+#endif /* __IMAGE_LOADER_H__ */
diff --git a/include/common/param_header.h b/include/common/param_header.h
new file mode 100644
index 0000000..32763dd
--- /dev/null
+++ b/include/common/param_header.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PARAM_HEADER_H__
+#define __PARAM_HEADER_H__
+
+/* Param header types */
+#define PARAM_EP 0x01
+#define PARAM_IMAGE_BINARY 0x02
+#define PARAM_BL31 0x03
+#define PARAM_BL_LOAD_INFO 0x04
+#define PARAM_BL_PARAMS 0x05
+#define PARAM_PSCI_LIB_ARGS 0x06
+#define PARAM_SP_IMAGE_BOOT_INFO 0x07
+
+/* Param header version */
+#define VERSION_1 0x01
+#define VERSION_2 0x02
+
+#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \
+ (_p)->h.type = (uint8_t)(_type); \
+ (_p)->h.version = (uint8_t)(_ver); \
+ (_p)->h.size = (uint16_t)sizeof(*_p); \
+ (_p)->h.attr = (uint32_t)(_attr) ; \
+ } while (0)
+
+/* Following is used for populating structure members statically. */
+#define SET_STATIC_PARAM_HEAD(_p, _type, _ver, _p_type, _attr) \
+ ._p.h.type = (uint8_t)(_type), \
+ ._p.h.version = (uint8_t)(_ver), \
+ ._p.h.size = (uint16_t)sizeof(_p_type), \
+ ._p.h.attr = (uint32_t)(_attr)
+
+#ifndef __ASSEMBLY__
+
+#include <types.h>
+
+/***************************************************************************
+ * This structure provides version information and the size of the
+ * structure, attributes for the structure it represents
+ ***************************************************************************/
+typedef struct param_header {
+ uint8_t type; /* type of the structure */
+ uint8_t version; /* version of this structure */
+ uint16_t size; /* size of this structure in bytes */
+ uint32_t attr; /* attributes: unused bits SBZ */
+} param_header_t;
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* __PARAM_HEADER_H__ */
+
diff --git a/include/common/test_helpers.h b/include/common/test_helpers.h
new file mode 100644
index 0000000..942e9f8
--- /dev/null
+++ b/include/common/test_helpers.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __TEST_HELPERS_H__
+#define __TEST_HELPERS_H__
+
+#include <plat_topology.h>
+#include <psci.h>
+#include <tftf_lib.h>
+#include <trusted_os.h>
+#include <tsp.h>
+#include <uuid.h>
+#include <uuid_utils.h>
+
+typedef struct {
+ uintptr_t addr;
+ size_t size;
+ unsigned int attr;
+ void *arg;
+} map_args_unmap_t;
+
+typedef test_result_t (*test_function_arg_t)(void *arg);
+
+#define SKIP_TEST_IF_LESS_THAN_N_CLUSTERS(n) \
+ do { \
+ unsigned int clusters_cnt; \
+ clusters_cnt = tftf_get_total_clusters_count(); \
+ if (clusters_cnt < (n)) { \
+ tftf_testcase_printf( \
+ "Need at least %u clusters, only found %u\n", \
+ (n), clusters_cnt); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ } while (0)
+
+#define SKIP_TEST_IF_LESS_THAN_N_CPUS(n) \
+ do { \
+ unsigned int cpus_cnt; \
+ cpus_cnt = tftf_get_total_cpus_count(); \
+ if (cpus_cnt < (n)) { \
+ tftf_testcase_printf( \
+ "Need at least %u CPUs, only found %u\n", \
+ (n), cpus_cnt); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ } while (0)
+
+#define SKIP_TEST_IF_TRUSTED_OS_NOT_PRESENT() \
+ do { \
+ uuid_t tos_uuid; \
+ \
+ if (!is_trusted_os_present(&tos_uuid)) { \
+ tftf_testcase_printf("No Trusted OS detected\n"); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ } while (0)
+
+#define SKIP_TEST_IF_TSP_NOT_PRESENT() \
+ do { \
+ uuid_t tos_uuid; \
+ char tos_uuid_str[UUID_STR_SIZE]; \
+ \
+ if (!is_trusted_os_present(&tos_uuid)) { \
+ tftf_testcase_printf("No Trusted OS detected\n"); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ \
+ if (!uuid_equal(&tos_uuid, &tsp_uuid)) { \
+ tftf_testcase_printf( \
+ "Trusted OS is not the TSP, its UUID is: %s\n", \
+ uuid_to_str(&tos_uuid, tos_uuid_str)); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ } while (0)
+
+#define SKIP_TEST_IF_MM_NOT_PRESENT() \
+ do { \
+ smc_args version_smc = { MM_VERSION_AARCH32 }; \
+ smc_ret_values smc_ret = tftf_smc(&version_smc); \
+ uint32_t version = smc_ret.ret0; \
+ \
+ if (version == (uint32_t) SMC_UNKNOWN) { \
+ tftf_testcase_printf("SPM not detected.\n"); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ } while (0)
+
+#define SKIP_TEST_IF_MM_VERSION_LESS_THAN(major, minor) \
+ do { \
+ smc_args version_smc = { MM_VERSION_AARCH32 }; \
+ smc_ret_values smc_ret = tftf_smc(&version_smc); \
+ uint32_t version = smc_ret.ret0; \
+ \
+ if (version == (uint32_t) SMC_UNKNOWN) { \
+ tftf_testcase_printf("SPM not detected.\n"); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ \
+ if (version < MM_VERSION_FORM(major, minor)) { \
+ tftf_testcase_printf("MM_VERSION returned %d.%d\n" \
+ "The required version is %d.%d\n", \
+ version >> MM_VERSION_MAJOR_SHIFT, \
+ version & MM_VERSION_MINOR_MASK, \
+ major, minor); \
+ return TEST_RESULT_SKIPPED; \
+ } \
+ \
+ VERBOSE("MM_VERSION returned %d.%d\n", \
+ version >> MM_VERSION_MAJOR_SHIFT, \
+ version & MM_VERSION_MINOR_MASK); \
+ } while (0)
+
+/* Helper macro to verify if system suspend API is supported */
+#define is_psci_sys_susp_supported() \
+ (tftf_get_psci_feature_info(SMC_PSCI_SYSTEM_SUSPEND) \
+ == PSCI_E_SUCCESS)
+
+/* Helper macro to verify if PSCI_STAT_COUNT API is supported */
+#define is_psci_stat_count_supported() \
+ (tftf_get_psci_feature_info(SMC_PSCI_STAT_COUNT) \
+ == PSCI_E_SUCCESS)
+
+/*
+ * Helper function to verify the system state is ready for system
+ * suspend. i.e., a single CPU is running and all other CPUs are powered off.
+ * Returns 1 if the system is ready to suspend, 0 otherwise.
+ */
+int is_sys_suspend_state_ready(void);
+
+/*
+ * Helper function to reset the system. This function shouldn't return.
+ * It is not marked with __dead to help the test to catch some error in
+ * TF
+ */
+void psci_system_reset(void);
+
+/*
+ * Helper function that enables/disables the mem_protect mechanism
+ */
+int psci_mem_protect(int val);
+
+
+/*
+ * Helper function to call PSCI MEM_PROTECT_CHECK
+ */
+int psci_mem_protect_check(uintptr_t addr, size_t size);
+
+
+/*
+ * Helper function to get a sentinel address that can be used to test mem_protect
+ */
+unsigned char *psci_mem_prot_get_sentinel(void);
+
+/*
+ * Helper function to memory map and unmap a region needed by a test.
+ *
+ * Return TEST_RESULT_FAIL if the memory could not be successfully mapped or
+ * unmapped. Otherwise, return the test functions's result.
+ */
+test_result_t map_test_unmap(const map_args_unmap_t *args,
+ test_function_arg_t test);
+
+#endif /* __TEST_HELPERS_H__ */