aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--defaults.mk3
-rw-r--r--docs/user-guide.rst5
-rw-r--r--drivers/io/vexpress_nor/io_vexpress_nor_hw.c3
-rw-r--r--fwu/ns_bl1u/ns_bl1u.mk1
-rw-r--r--fwu/ns_bl2u/ns_bl2u.mk1
-rw-r--r--fwu/ns_bl2u/ns_bl2u_main.c2
-rw-r--r--include/common/debug.h23
-rw-r--r--include/lib/aarch32/arch_helpers.h12
-rw-r--r--include/lib/aarch64/arch_helpers.h12
-rw-r--r--include/lib/stdlib/stdio.h2
-rw-r--r--include/lib/tftf_lib.h4
-rw-r--r--lib/delay/delay.c16
-rw-r--r--lib/power_management/suspend/tftf_suspend.c4
-rw-r--r--lib/sdei/sdei.c32
-rw-r--r--lib/smc/aarch64/asm_smc.S2
-rw-r--r--lib/smc/aarch64/smc.c4
-rw-r--r--lib/stdlib/printf.c30
-rw-r--r--lib/utils/mp_printf.c58
-rw-r--r--spm/cactus/cactus.mk2
-rw-r--r--spm/common/sp_helpers.h4
-rw-r--r--spm/ivy/ivy.mk2
-rw-r--r--tftf/framework/include/tftf.h5
-rw-r--r--tftf/framework/main.c25
-rw-r--r--tftf/framework/report.c113
-rw-r--r--tftf/framework/timer/timer_framework.c10
-rw-r--r--tftf/tests/performance_tests/smc_latencies.c6
-rw-r--r--tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_1.c6
-rw-r--r--tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_2.c6
-rw-r--r--tftf/tests/runtime_services/generic/generic_smc.c227
-rw-r--r--tftf/tests/runtime_services/sip_service/test_exec_state_switch.c8
-rw-r--r--tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c2
-rw-r--r--tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c4
-rw-r--r--tftf/tests/runtime_services/standard_service/query_std_svc.c6
-rw-r--r--tftf/tests/runtime_services/standard_service/unknown_smc.c2
-rw-r--r--tftf/tests/runtime_services/trusted_os/tsp/test_irq_preempted_std_smc.c18
-rw-r--r--tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c4
-rw-r--r--tftf/tests/runtime_services/trusted_os/tsp/test_normal_int_switch.c38
-rw-r--r--tftf/tests/runtime_services/trusted_os/tsp/test_smc_tsp_std_fn_call.c4
-rw-r--r--tftf/tests/tests-smc.mk7
-rw-r--r--tftf/tests/tests-smc.xml19
-rw-r--r--tftf/tests/tests-standard.mk1
-rw-r--r--tftf/tests/tests-standard.xml2
43 files changed, 483 insertions, 254 deletions
diff --git a/Makefile b/Makefile
index 9c4ae7eb7..745685827 100644
--- a/Makefile
+++ b/Makefile
@@ -133,7 +133,6 @@ $(eval $(call assert_boolean,ENABLE_ASSERTIONS))
$(eval $(call assert_boolean,FIRMWARE_UPDATE))
$(eval $(call assert_boolean,FWU_BL_TEST))
$(eval $(call assert_boolean,NEW_TEST_SESSION))
-$(eval $(call assert_boolean,SHELL_COLOR))
$(eval $(call assert_boolean,USE_NVM))
################################################################################
@@ -148,7 +147,6 @@ $(eval $(call add_define,TFTF_DEFINES,ENABLE_ASSERTIONS))
$(eval $(call add_define,TFTF_DEFINES,LOG_LEVEL))
$(eval $(call add_define,TFTF_DEFINES,NEW_TEST_SESSION))
$(eval $(call add_define,TFTF_DEFINES,PLAT_${PLAT}))
-$(eval $(call add_define,TFTF_DEFINES,SHELL_COLOR))
$(eval $(call add_define,TFTF_DEFINES,USE_NVM))
ifeq (${ARCH},aarch32)
diff --git a/defaults.mk b/defaults.mk
index 63c1b2e1c..0f7465268 100644
--- a/defaults.mk
+++ b/defaults.mk
@@ -37,9 +37,6 @@ FWU_BL_TEST := 1
# framework should try to resume a previous one if it was interrupted
NEW_TEST_SESSION := 1
-# Use of shell colors
-SHELL_COLOR := 0
-
# Use non volatile memory for storing results
USE_NVM := 0
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 397b4c2c9..e11a6bfa0 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -367,11 +367,6 @@ TFTF build options
session was interrupted and resume it. It can take either 1 (always
start new session) or 0 (resume session as appropriate). 1 is the default.
-- ``SHELL_COLOR``: Choose whether text messages should use shell's color escape
- sequences to ease identifying which CPU displays it. If enabled, this makes
- each CPU write part of the message in a different color. It can take either
- 0 (disabled) or 1 (enabled) as values. 0 is the default.
-
- ``TESTS``: Set of tests to run. Use the following command to list all
possible sets of tests:
diff --git a/drivers/io/vexpress_nor/io_vexpress_nor_hw.c b/drivers/io/vexpress_nor/io_vexpress_nor_hw.c
index de7b4ceff..6e563c9f0 100644
--- a/drivers/io/vexpress_nor/io_vexpress_nor_hw.c
+++ b/drivers/io/vexpress_nor/io_vexpress_nor_hw.c
@@ -159,7 +159,6 @@ static int flash_erase_block(const io_nor_flash_spec_t *device,
int err = IO_SUCCESS;
uint32_t status_register;
- VERBOSE("%s : 0x%x\n", __func__, block_offset);
/* Request a block erase and then confirm it */
nor_send_cmd(block_offset, NOR_CMD_BLOCK_ERASE);
nor_send_cmd(block_offset, NOR_CMD_BLOCK_ERASE_ACK);
@@ -359,7 +358,6 @@ int flash_block_write(file_state_t *fp, uint32_t offset,
/* address passed should be block aligned */
assert(!(offset % fp->block_spec->block_size));
- VERBOSE("%s : 0x%x\n", __func__, flash_pos);
/* Unlock block */
flash_unlock_block_if_necessary(fp->block_spec, block_offset);
@@ -398,7 +396,6 @@ int flash_block_write(file_state_t *fp, uint32_t offset,
*written = fp->block_spec->block_size;
lock_block:
- VERBOSE("%s : 0x%x\n", __func__, block_offset);
/* Lock the block once done */
flash_perform_lock_operation(fp->block_spec,
block_offset,
diff --git a/fwu/ns_bl1u/ns_bl1u.mk b/fwu/ns_bl1u/ns_bl1u.mk
index 0d7efcce0..d5c78069e 100644
--- a/fwu/ns_bl1u/ns_bl1u.mk
+++ b/fwu/ns_bl1u/ns_bl1u.mk
@@ -28,7 +28,6 @@ NS_BL1U_INCLUDES := \
NS_BL1U_SOURCES := $(addprefix tftf/framework/, \
${ARCH}/arch.c \
${ARCH}/asm_debug.S \
- ${ARCH}/exceptions.S \
debug.c \
)
diff --git a/fwu/ns_bl2u/ns_bl2u.mk b/fwu/ns_bl2u/ns_bl2u.mk
index 0605c3c2d..abd5ac555 100644
--- a/fwu/ns_bl2u/ns_bl2u.mk
+++ b/fwu/ns_bl2u/ns_bl2u.mk
@@ -28,7 +28,6 @@ NS_BL2U_INCLUDES := \
NS_BL2U_SOURCES := $(addprefix tftf/framework/, \
${ARCH}/arch.c \
${ARCH}/asm_debug.S \
- ${ARCH}/exceptions.S \
debug.c \
)
diff --git a/fwu/ns_bl2u/ns_bl2u_main.c b/fwu/ns_bl2u/ns_bl2u_main.c
index babcf93e0..5b1373f64 100644
--- a/fwu/ns_bl2u/ns_bl2u_main.c
+++ b/fwu/ns_bl2u/ns_bl2u_main.c
@@ -52,7 +52,7 @@ void ns_bl2u_main(void)
/* Call FWU_SMC_UPDATE_DONE to indicate image update done. */
INFO("NS_BL2U: Calling FWU_SMC_UPDATE_DONE\n");
- fwu_params.arg0 = FWU_SMC_UPDATE_DONE;
+ fwu_params.fid = FWU_SMC_UPDATE_DONE;
fwu_result = tftf_smc(&fwu_params);
ERROR("NS_BL2U: Unexpected return from FWU process (%d)\n",
(int)fwu_result.ret0);
diff --git a/include/common/debug.h b/include/common/debug.h
index bfbff093d..216c53d9b 100644
--- a/include/common/debug.h
+++ b/include/common/debug.h
@@ -9,34 +9,15 @@
#include <stdio.h>
-/* TODO: Deal with per-image printf functions in a cleaner way. */
-
-#if defined(IMAGE_CACTUS) || defined(IMAGE_IVY)
-/*
- * 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
@@ -44,8 +25,8 @@ void mp_printf(const char *fmt, ...);
* 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.
+ * INFO("Info %s.\n", "message") -> INFO: Info message.
+ * WARN("Warning %s.\n", "message") -> WARNING: Warning message.
*/
#define LOG_LEVEL_NONE 0
#define LOG_LEVEL_ERROR 10
diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h
index ee7ed3145..3e6e6f9cc 100644
--- a/include/lib/aarch32/arch_helpers.h
+++ b/include/lib/aarch32/arch_helpers.h
@@ -442,4 +442,16 @@ static inline void disable_fiq(void)
void disable_mmu_icache(void);
+/* Read the count value of the system counter. */
+static inline uint64_t syscounter_read(void)
+{
+ /*
+ * The instruction barrier is needed to guarantee that we read an
+ * accurate value. Otherwise, the CPU might speculatively read it and
+ * return a stale value.
+ */
+ isb();
+ return read64_cntpct();
+}
+
#endif /* ARCH_HELPERS_H */
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 1d9202d04..053f8ba67 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -468,4 +468,16 @@ static inline uint64_t el_implemented(unsigned int el)
}
}
+/* Read the count value of the system counter. */
+static inline uint64_t syscounter_read(void)
+{
+ /*
+ * The instruction barrier is needed to guarantee that we read an
+ * accurate value. Otherwise, the CPU might speculatively read it and
+ * return a stale value.
+ */
+ isb();
+ return read_cntpct_el0();
+}
+
#endif /* ARCH_HELPERS_H */
diff --git a/include/lib/stdlib/stdio.h b/include/lib/stdlib/stdio.h
index 80110a8b4..55d8fe2c1 100644
--- a/include/lib/stdlib/stdio.h
+++ b/include/lib/stdlib/stdio.h
@@ -59,6 +59,8 @@ typedef __ssize_t ssize_t;
#define EOF (-1)
int printf(const char * __restrict, ...) __printflike(1, 2);
+int vprintf(const char * __restrict, __va_list);
+
int putchar(int);
int puts(const char *);
int sprintf(char * __restrict, const char * __restrict, ...)
diff --git a/include/lib/tftf_lib.h b/include/lib/tftf_lib.h
index 97b6f411d..58112b4b6 100644
--- a/include/lib/tftf_lib.h
+++ b/include/lib/tftf_lib.h
@@ -36,8 +36,6 @@ typedef enum {
TEST_RESULT_MAX
} test_result_t;
-const char *test_result_to_string(test_result_t result);
-
#define TEST_RESULT_IS_VALID(result) \
((result >= TEST_RESULT_MIN) && (result < TEST_RESULT_MAX))
@@ -133,7 +131,7 @@ void waitus(uint64_t us);
*/
typedef struct {
/* Function identifier. Identifies which function is being invoked. */
- uint32_t arg0;
+ uint32_t fid;
u_register_t arg1;
u_register_t arg2;
diff --git a/lib/delay/delay.c b/lib/delay/delay.c
index d88e500c6..f6b29d1e8 100644
--- a/lib/delay/delay.c
+++ b/lib/delay/delay.c
@@ -5,22 +5,14 @@
*/
#include <arch_helpers.h>
-#include <tftf.h>
void waitus(uint64_t us)
{
- uint64_t cntp_ct_val_base;
- uint32_t cnt_frq;
- uint64_t wait_cycles;
+ uint64_t start_count_val = syscounter_read();
+ uint64_t wait_cycles = (us * read_cntfrq_el0()) / 1000000;
- cnt_frq = read_cntfrq_el0();
- cntp_ct_val_base = read_cntpct_el0();
-
- /* Waitms in terms of counter freq */
- wait_cycles = (us * cnt_frq) / 1000000;
-
- while (read_cntpct_el0() - cntp_ct_val_base < wait_cycles)
- ;
+ while ((syscounter_read() - start_count_val) < wait_cycles)
+ /* Busy wait... */;
}
void waitms(uint64_t ms)
diff --git a/lib/power_management/suspend/tftf_suspend.c b/lib/power_management/suspend/tftf_suspend.c
index 75c2ade06..d6c989afe 100644
--- a/lib/power_management/suspend/tftf_suspend.c
+++ b/lib/power_management/suspend/tftf_suspend.c
@@ -6,6 +6,7 @@
#include <arch_helpers.h>
#include <arm_gic.h>
+#include <console.h>
#include <debug.h>
#include <platform.h>
#include <power_management.h>
@@ -51,6 +52,9 @@ int32_t tftf_enter_suspend(const suspend_info_t *info,
*/
flush_dcache_range((u_register_t)ctx, sizeof(*ctx));
+ /* Make sure any outstanding message is printed. */
+ console_flush();
+
if (info->psci_api == SMC_PSCI_CPU_SUSPEND)
rc = tftf_smc(&cpu_suspend_args);
else
diff --git a/lib/sdei/sdei.c b/lib/sdei/sdei.c
index 846b96eb4..264da28ae 100644
--- a/lib/sdei/sdei.c
+++ b/lib/sdei/sdei.c
@@ -32,7 +32,7 @@ int64_t sdei_interrupt_bind(int intr, struct sdei_intr_ctx *intr_ctx)
intr_ctx->enabled = arm_gic_intr_enabled(intr);
arm_gic_intr_disable(intr);
- args.arg0 = SDEI_INTERRUPT_BIND;
+ args.fid = SDEI_INTERRUPT_BIND;
args.arg1 = intr;
ret = tftf_smc(&args);
if (ret.ret0 < 0) {
@@ -51,7 +51,7 @@ int64_t sdei_interrupt_release(int ev, const struct sdei_intr_ctx *intr_ctx)
assert(intr_ctx);
- args.arg0 = SDEI_INTERRUPT_RELEASE;
+ args.fid = SDEI_INTERRUPT_RELEASE;
args.arg1 = ev;
ret = tftf_smc(&args);
if (ret.ret0 == 0) {
@@ -69,7 +69,7 @@ int64_t sdei_event_register(int ev, sdei_handler_t *ep,
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_EVENT_REGISTER;
+ args.fid = SDEI_EVENT_REGISTER;
args.arg1 = ev;
args.arg2 = (u_register_t)ep;
args.arg3 = ep_arg;
@@ -84,7 +84,7 @@ int64_t sdei_event_unregister(int ev)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_EVENT_UNREGISTER;
+ args.fid = SDEI_EVENT_UNREGISTER;
args.arg1 = ev;
ret = tftf_smc(&args);
return ret.ret0;
@@ -95,7 +95,7 @@ int64_t sdei_event_enable(int ev)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_EVENT_ENABLE;
+ args.fid = SDEI_EVENT_ENABLE;
args.arg1 = ev;
ret = tftf_smc(&args);
return ret.ret0;
@@ -106,7 +106,7 @@ int64_t sdei_event_disable(int ev)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_EVENT_DISABLE;
+ args.fid = SDEI_EVENT_DISABLE;
args.arg1 = ev;
ret = tftf_smc(&args);
return ret.ret0;
@@ -117,7 +117,7 @@ int64_t sdei_pe_mask(void)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_PE_MASK;
+ args.fid = SDEI_PE_MASK;
ret = tftf_smc(&args);
return ret.ret0;
}
@@ -127,7 +127,7 @@ int64_t sdei_pe_unmask(void)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_PE_UNMASK;
+ args.fid = SDEI_PE_UNMASK;
ret = tftf_smc(&args);
return ret.ret0;
}
@@ -137,7 +137,7 @@ int64_t sdei_private_reset(void)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_PRIVATE_RESET;
+ args.fid = SDEI_PRIVATE_RESET;
ret = tftf_smc(&args);
return ret.ret0;
}
@@ -147,7 +147,7 @@ int64_t sdei_shared_reset(void)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_SHARED_RESET;
+ args.fid = SDEI_SHARED_RESET;
ret = tftf_smc(&args);
return ret.ret0;
}
@@ -157,7 +157,7 @@ int64_t sdei_event_signal(uint64_t mpidr)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_EVENT_SIGNAL;
+ args.fid = SDEI_EVENT_SIGNAL;
args.arg1 = 0; /* must be event 0 */
args.arg2 = mpidr;
ret = tftf_smc(&args);
@@ -169,7 +169,7 @@ int64_t sdei_event_status(int32_t ev)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_EVENT_STATUS;
+ args.fid = SDEI_EVENT_STATUS;
args.arg1 = ev;
ret = tftf_smc(&args);
return ret.ret0;
@@ -180,7 +180,7 @@ int64_t sdei_event_routing_set(int32_t ev, uint64_t flags)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_EVENT_ROUTING_SET;
+ args.fid = SDEI_EVENT_ROUTING_SET;
args.arg1 = ev;
args.arg2 = flags;
ret = tftf_smc(&args);
@@ -192,7 +192,7 @@ int64_t sdei_event_context(uint32_t param)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_EVENT_CONTEXT;
+ args.fid = SDEI_EVENT_CONTEXT;
args.arg1 = param;
ret = tftf_smc(&args);
return ret.ret0;
@@ -203,7 +203,7 @@ int64_t sdei_event_complete(uint32_t flags)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_EVENT_COMPLETE;
+ args.fid = SDEI_EVENT_COMPLETE;
args.arg1 = flags;
ret = tftf_smc(&args);
return ret.ret0;
@@ -214,7 +214,7 @@ int64_t sdei_event_complete_and_resume(uint64_t addr)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = SDEI_EVENT_COMPLETE_AND_RESUME;
+ args.fid = SDEI_EVENT_COMPLETE_AND_RESUME;
args.arg1 = addr;
ret = tftf_smc(&args);
return ret.ret0;
diff --git a/lib/smc/aarch64/asm_smc.S b/lib/smc/aarch64/asm_smc.S
index 48a80a3f7..1180f518e 100644
--- a/lib/smc/aarch64/asm_smc.S
+++ b/lib/smc/aarch64/asm_smc.S
@@ -12,7 +12,7 @@
/* ---------------------------------------------------------------------------
- * smc_ret_values asm_tftf_smc64(uint32_t arg0,
+ * smc_ret_values asm_tftf_smc64(uint32_t fid,
* u_register_t arg1,
* u_register_t arg2,
* u_register_t arg3,
diff --git a/lib/smc/aarch64/smc.c b/lib/smc/aarch64/smc.c
index cbe4bb9fd..6667ee7be 100644
--- a/lib/smc/aarch64/smc.c
+++ b/lib/smc/aarch64/smc.c
@@ -7,7 +7,7 @@
#include <stdint.h>
#include <tftf.h>
-smc_ret_values asm_tftf_smc64(uint32_t arg0,
+smc_ret_values asm_tftf_smc64(uint32_t fid,
u_register_t arg1,
u_register_t arg2,
u_register_t arg3,
@@ -18,7 +18,7 @@ smc_ret_values asm_tftf_smc64(uint32_t arg0,
smc_ret_values tftf_smc(const smc_args *args)
{
- return asm_tftf_smc64(args->arg0,
+ return asm_tftf_smc64(args->fid,
args->arg1,
args->arg2,
args->arg3,
diff --git a/lib/stdlib/printf.c b/lib/stdlib/printf.c
index 6329157d0..8ae7c2635 100644
--- a/lib/stdlib/printf.c
+++ b/lib/stdlib/printf.c
@@ -9,28 +9,34 @@
/* Choose max of 512 chars for now. */
#define PRINT_BUFFER_SIZE 512
-int printf(const char *fmt, ...)
+
+int vprintf(const char *fmt, va_list args)
{
- va_list args;
char buf[PRINT_BUFFER_SIZE];
int count;
- va_start(args, fmt);
vsnprintf(buf, sizeof(buf) - 1, fmt, args);
- va_end(args);
+ buf[PRINT_BUFFER_SIZE - 1] = '\0';
/* Use putchar directly as 'puts()' adds a newline. */
- buf[PRINT_BUFFER_SIZE - 1] = '\0';
count = 0;
- while (buf[count])
- {
- if (putchar(buf[count]) != EOF) {
- count++;
- } else {
- count = EOF;
- break;
+ while (buf[count] != 0) {
+ if (putchar(buf[count]) == EOF) {
+ return EOF;
}
+ count++;
}
return count;
}
+
+int printf(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ int count = vprintf(fmt, args);
+ va_end(args);
+
+ return count;
+}
diff --git a/lib/utils/mp_printf.c b/lib/utils/mp_printf.c
index d1eb780ea..777c736ad 100644
--- a/lib/utils/mp_printf.c
+++ b/lib/utils/mp_printf.c
@@ -4,8 +4,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <arch_helpers.h>
-#include <platform.h>
#include <spinlock.h>
#include <stdarg.h>
#include <stdio.h>
@@ -13,60 +11,14 @@
/* Lock to avoid concurrent accesses to the serial console */
static spinlock_t printf_lock;
-/*
- * Print the MPID header, e.g.: [cpu 0x0100]
- *
- * If SHELL_COLOR == 1, this also prints shell's color escape sequences to ease
- * identifying which CPU displays the message. There are 8 standard colors so
- * if the platform has more than 8 CPUs, some colors will be reused.
- */
-#if SHELL_COLOR
-#define PRINT_MPID_HDR(_mpid) \
- do { \
- unsigned int linear_id = platform_get_core_pos(_mpid); \
- printf("\033[1;%u;40m", 30 + (linear_id & 0x7)); \
- printf("[cpu 0x%.4x] ", _mpid); \
- printf("\033[0m"); \
- } while (0)
-#else
-#define PRINT_MPID_HDR(_mpid) \
- printf("[cpu 0x%.4x] ", _mpid)
-#endif /* SHELL_COLOR */
-
void mp_printf(const char *fmt, ...)
{
- va_list ap;
- char str[256];
- /*
- * As part of testing Firmware Update feature on Cortex-A57 CPU, an
- * issue was discovered while printing in NS_BL1U stage. The issue
- * appears when the second call to `NOTICE()` is made in the
- * `ns_bl1u_main()`. As a result of this issue the CPU hangs and the
- * debugger is also not able to connect anymore.
- *
- * After further debugging and experiments it was found that if
- * `read_mpidr_el1()` is avoided or volatile qualifier is used for
- * reading the mpidr, this issue gets resolved.
- *
- * NOTE: The actual/real reason why this happens is still not known.
- * Moreover this problem is not encountered on Cortex-A53 CPU.
- */
- volatile unsigned int mpid = read_mpidr_el1() & 0xFFFF;
-
- /*
- * TODO: It would be simpler to use vprintf() instead of
- * vsnprintf() + printf(), we wouldn't need to declare a static buffer
- * for storing the product of vsnprintf(). Unfortunately our C library
- * doesn't provide vprintf() at the moment.
- * Import vprintf() code from FreeBSD C library to our local C library.
- */
- va_start(ap, fmt);
- vsnprintf(str, sizeof(str), fmt, ap);
- str[sizeof(str) - 1] = 0;
- va_end(ap);
+ va_list args;
+ va_start(args, fmt);
spin_lock(&printf_lock);
- PRINT_MPID_HDR(mpid);
- printf("%s", str);
+ vprintf(fmt, args);
spin_unlock(&printf_lock);
+
+ va_end(args);
}
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index 1ebc6927b..03d809d10 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -58,6 +58,8 @@ CACTUS_SOURCES += \
CACTUS_SOURCES += drivers/arm/pl011/${ARCH}/pl011_console.S \
lib/${ARCH}/cache_helpers.S \
lib/${ARCH}/misc_helpers.S \
+ lib/locks/${ARCH}/spinlock.S \
+ lib/utils/mp_printf.c \
${STDLIB_SOURCES} \
${SPRT_LIB_SOURCES}
diff --git a/spm/common/sp_helpers.h b/spm/common/sp_helpers.h
index fb2d8ac94..1bd4425ff 100644
--- a/spm/common/sp_helpers.h
+++ b/spm/common/sp_helpers.h
@@ -11,7 +11,7 @@
#include <sys/types.h>
typedef struct {
- u_register_t arg0;
+ u_register_t fid;
u_register_t arg1;
u_register_t arg2;
u_register_t arg3;
@@ -28,7 +28,7 @@ typedef struct {
* structure. The return values of the SVC call will be stored in the same
* structure (overriding the input arguments).
*
- * Return the first return value. It is equivalent to args.arg0 but is also
+ * Return the first return value. It is equivalent to args.fid but is also
* provided as the return value for convenience.
*/
u_register_t sp_svc(svc_args *args);
diff --git a/spm/ivy/ivy.mk b/spm/ivy/ivy.mk
index 89fd92d47..c7726f4fd 100644
--- a/spm/ivy/ivy.mk
+++ b/spm/ivy/ivy.mk
@@ -55,6 +55,8 @@ IVY_SOURCES += \
IVY_SOURCES += drivers/arm/pl011/${ARCH}/pl011_console.S \
lib/${ARCH}/cache_helpers.S \
lib/${ARCH}/misc_helpers.S \
+ lib/locks/${ARCH}/spinlock.S \
+ lib/utils/mp_printf.c \
${STDLIB_SOURCES} \
${SPRT_LIB_SOURCES}
diff --git a/tftf/framework/include/tftf.h b/tftf/framework/include/tftf.h
index 8231e284a..43f1e7ea5 100644
--- a/tftf/framework/include/tftf.h
+++ b/tftf/framework/include/tftf.h
@@ -130,7 +130,10 @@ STATUS tftf_testcase_set_result(const test_case_t *testcase,
*/
STATUS tftf_testcase_get_result(const test_case_t *testcase, TESTCASE_RESULT *result, char *test_output);
-void tftf_report_generate(void);
+void print_testsuite_start(const test_suite_t *testsuite);
+void print_test_start(const test_case_t *test);
+void print_test_end(const test_case_t *test);
+void print_tests_summary(void);
/*
* Exit the TFTF.
diff --git a/tftf/framework/main.c b/tftf/framework/main.c
index 3f94dc94a..02b54386e 100644
--- a/tftf/framework/main.c
+++ b/tftf/framework/main.c
@@ -148,8 +148,14 @@ static void prepare_next_test(void)
for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; ++i)
test_results[i] = TEST_RESULT_NA;
- NOTICE("Starting unittest '%s - %s'\n",
- current_testsuite()->name, current_testcase()->name);
+ /* If we're starting a new testsuite, announce it. */
+ test_ref_t test_to_run;
+ tftf_get_test_to_run(&test_to_run);
+ if (test_to_run.testcase_idx == 0) {
+ print_testsuite_start(current_testsuite());
+ }
+
+ print_test_start(current_testcase());
/* Program the watchdog */
tftf_platform_watchdog_set();
@@ -176,7 +182,6 @@ static test_result_t get_overall_test_result(void)
switch (test_results[core_pos]) {
case TEST_RESULT_NA:
- VERBOSE("CPU%u not involved in the test\n", core_pos);
/* Ignoring */
break;
@@ -185,7 +190,6 @@ static test_result_t get_overall_test_result(void)
* If at least one CPU skipped the test, consider the
* whole test as skipped as well.
*/
- NOTICE("CPU%u skipped the test\n", core_pos);
return TEST_RESULT_SKIPPED;
case TEST_RESULT_SUCCESS:
@@ -193,7 +197,6 @@ static test_result_t get_overall_test_result(void)
break;
case TEST_RESULT_FAIL:
- ERROR("CPU%u failed the test\n", core_pos);
return TEST_RESULT_FAIL;
case TEST_RESULT_CRASHED:
@@ -205,7 +208,6 @@ static test_result_t get_overall_test_result(void)
* If at least one CPU crashed, consider the whole test
* as crashed as well.
*/
- ERROR("CPU%u never returned from the test!\n", core_pos);
return TEST_RESULT_CRASHED;
default:
@@ -263,21 +265,18 @@ static unsigned int close_test(void)
assert(tftf_get_ref_cnt() == 0);
/* Save test result in NVM */
- test_result_t overall_test_result = get_overall_test_result();
tftf_testcase_set_result(current_testcase(),
- overall_test_result,
+ get_overall_test_result(),
0);
- NOTICE("Unittest '%s - %s' complete. Result: %s\n",
- current_testsuite()->name, current_testcase()->name,
- test_result_to_string(overall_test_result));
+ print_test_end(current_testcase());
/* The test is finished, let's move to the next one (if any) */
next_test = advance_to_next_test();
/* If this was the last test then report all results */
if (!next_test) {
- tftf_report_generate();
+ print_tests_summary();
tftf_clean_nvm();
return 1;
} else {
@@ -551,7 +550,7 @@ void __dead2 tftf_cold_boot_main(void)
NOTICE("Resuming interrupted test session\n");
rc = resume_test_session();
if (rc < 0) {
- tftf_report_generate();
+ print_tests_summary();
tftf_clean_nvm();
tftf_exit();
}
diff --git a/tftf/framework/report.c b/tftf/framework/report.c
index faae34b87..663caf365 100644
--- a/tftf/framework/report.c
+++ b/tftf/framework/report.c
@@ -6,70 +6,97 @@
#include <assert.h>
#include <debug.h>
-#include <platform_def.h> /* For TESTCASE_OUTPUT_MAX_SIZE */
#include <stdio.h>
-#include <string.h>
+#include <stdbool.h>
#include <tftf.h>
-static unsigned int total_tests;
-static unsigned int tests_stats[TEST_RESULT_MAX];
-
-static void tftf_update_tests_statistics(test_result_t result)
-{
- assert(TEST_RESULT_IS_VALID(result));
- total_tests++;
- tests_stats[result]++;
-}
-
static const char *test_result_strings[TEST_RESULT_MAX] = {
"Skipped", "Passed", "Failed", "Crashed",
};
-const char *test_result_to_string(test_result_t result)
+static const char *test_result_to_string(test_result_t result)
{
assert(TEST_RESULT_IS_VALID(result));
return test_result_strings[result];
}
-void tftf_report_generate(void)
+void print_testsuite_start(const test_suite_t *testsuite)
{
- unsigned i, j;
- const test_case_t *testcases;
- TESTCASE_RESULT testcase_result;
- char test_output[TESTCASE_OUTPUT_MAX_SIZE];
- STATUS status;
-
- /* Extract the result of all the testcases */
- printf("========== TEST REPORT ==========\n");
- for (i = 0; testsuites[i].name != NULL; i++) {
- printf("# Test suite '%s':\n", testsuites[i].name);
- testcases = testsuites[i].testcases;
-
- for (j = 0; testcases[j].name != NULL; j++) {
- status = tftf_testcase_get_result(&testcases[j], &testcase_result, test_output);
- if (status != STATUS_SUCCESS) {
- printf("Failed to get test result.\n");
+ mp_printf("--\n");
+ mp_printf("Running test suite '%s'\n", testsuite->name);
+ mp_printf("Description: %s\n", testsuite->description);
+ mp_printf("\n");
+}
+
+void print_test_start(const test_case_t *test)
+{
+ mp_printf("> Executing '%s'\n", test->name);
+}
+
+void print_test_end(const test_case_t *test)
+{
+ TESTCASE_RESULT result;
+ char output[TESTCASE_OUTPUT_MAX_SIZE];
+
+ tftf_testcase_get_result(test, &result, output);
+
+ mp_printf(" TEST COMPLETE %54s\n",
+ test_result_to_string(result.result));
+ if (strlen(output) != 0) {
+ mp_printf("%s", output);
+ }
+ mp_printf("\n");
+}
+
+void print_tests_summary(void)
+{
+ int total_tests = 0;
+ int tests_stats[TEST_RESULT_MAX] = { 0 };
+
+ mp_printf("******************************* Summary *******************************\n");
+
+ /* Go through the list of test suites. */
+ for (int i = 0; testsuites[i].name != NULL; i++) {
+ bool passed = true;
+
+ mp_printf("> Test suite '%s'\n", testsuites[i].name);
+
+ const test_case_t *testcases = testsuites[i].testcases;
+
+ /* Go through the list of tests inside this test suite. */
+ for (int j = 0; testcases[j].name != NULL; j++) {
+ TESTCASE_RESULT result;
+ char output[TESTCASE_OUTPUT_MAX_SIZE];
+
+ if (tftf_testcase_get_result(&testcases[j], &result,
+ output) != STATUS_SUCCESS) {
+ mp_printf("Failed to get test result.\n");
continue;
}
- tftf_update_tests_statistics(testcase_result.result);
- /* TODO: print test duration */
- printf("\t - %s: %s\n", testcases[j].name,
- test_result_to_string(testcase_result.result));
+ assert(TEST_RESULT_IS_VALID(result.result));
- if (strlen(test_output) != 0) {
- printf("--- output ---\n");
- printf("%s", test_output);
- printf("--------------\n");
+ /*
+ * Consider that a test suite passed if all of its
+ * tests passed or were skipped.
+ */
+ if ((result.result != TEST_RESULT_SUCCESS) &&
+ (result.result != TEST_RESULT_SKIPPED)) {
+ passed = false;
}
+
+ total_tests++;
+ tests_stats[result.result]++;
}
+ mp_printf("%70s\n", passed ? "Passed" : "Failed");
}
- printf("=================================\n");
- for (i = TEST_RESULT_MIN; i < TEST_RESULT_MAX; i++) {
- printf("Tests %-8s: %d\n",
+ mp_printf("=================================\n");
+
+ for (int i = TEST_RESULT_MIN; i < TEST_RESULT_MAX; i++) {
+ mp_printf("Tests %-8s: %d\n",
test_result_to_string(i), tests_stats[i]);
}
- printf("%-14s: %d\n", "Total tests", total_tests);
- printf("=================================\n");
+ mp_printf("%-14s: %d\n", "Total tests", total_tests);
+ mp_printf("=================================\n");
}
diff --git a/tftf/framework/timer/timer_framework.c b/tftf/framework/timer/timer_framework.c
index e5e9a0f86..0b0a7a53a 100644
--- a/tftf/framework/timer/timer_framework.c
+++ b/tftf/framework/timer/timer_framework.c
@@ -71,15 +71,11 @@ static inline unsigned long long get_current_prog_time(void)
int tftf_initialise_timer(void)
{
- int rc;
- unsigned int i;
-
/*
* Get platform specific timer information
*/
- rc = plat_initialise_timer_ops(&plat_timer_info);
- if (rc) {
- ERROR("%s %d: No timer data found\n", __func__, __LINE__);
+ int rc = plat_initialise_timer_ops(&plat_timer_info);
+ if (rc != 0) {
return rc;
}
@@ -87,7 +83,7 @@ int tftf_initialise_timer(void)
assert(TIMER_STEP_VALUE);
/* Initialise the array to max possible time */
- for (i = 0; i < PLATFORM_CORE_COUNT; i++)
+ for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; i++)
interrupt_req_time[i] = INVALID_TIME;
tftf_irq_register_handler(TIMER_IRQ, tftf_timer_framework_handler);
diff --git a/tftf/tests/performance_tests/smc_latencies.c b/tftf/tests/performance_tests/smc_latencies.c
index fe226790e..49733cfb6 100644
--- a/tftf/tests/performance_tests/smc_latencies.c
+++ b/tftf/tests/performance_tests/smc_latencies.c
@@ -143,7 +143,7 @@ test_result_t smc_arch_workaround_1(void)
/* Check if SMCCC version is at least v1.1 */
expected_ver = MAKE_SMCCC_VERSION(1, 1);
memset(&args, 0, sizeof(args));
- args.arg0 = SMCCC_VERSION;
+ args.fid = SMCCC_VERSION;
ret = tftf_smc(&args);
if ((int32_t)ret.ret0 < expected_ver) {
printf("Unexpected SMCCC version: 0x%x\n",
@@ -153,7 +153,7 @@ test_result_t smc_arch_workaround_1(void)
/* Check if SMCCC_ARCH_WORKAROUND_1 is implemented */
memset(&args, 0, sizeof(args));
- args.arg0 = SMCCC_ARCH_FEATURES;
+ args.fid = SMCCC_ARCH_FEATURES;
args.arg1 = SMCCC_ARCH_WORKAROUND_1;
ret = tftf_smc(&args);
if ((int)ret.ret0 == -1) {
@@ -162,7 +162,7 @@ test_result_t smc_arch_workaround_1(void)
}
memset(&args, 0, sizeof(args));
- args.arg0 = SMCCC_ARCH_WORKAROUND_1;
+ args.fid = SMCCC_ARCH_WORKAROUND_1;
test_measure_smc_latency(&args, &latency);
tftf_testcase_printf(
diff --git a/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_1.c b/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_1.c
index 4a45ad4d8..90a43f33b 100644
--- a/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_1.c
+++ b/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_1.c
@@ -60,7 +60,7 @@ static test_result_t test_smccc_entrypoint(void)
/* Check if SMCCC version is at least v1.1 */
expected_ver = MAKE_SMCCC_VERSION(1, 1);
memset(&args, 0, sizeof(args));
- args.arg0 = SMCCC_VERSION;
+ args.fid = SMCCC_VERSION;
ret = tftf_smc(&args);
if ((int32_t)ret.ret0 < expected_ver) {
tftf_testcase_printf("Unexpected SMCCC version: 0x%x\n",
@@ -70,7 +70,7 @@ static test_result_t test_smccc_entrypoint(void)
/* Check if SMCCC_ARCH_WORKAROUND_1 is required or not */
memset(&args, 0, sizeof(args));
- args.arg0 = SMCCC_ARCH_FEATURES;
+ args.fid = SMCCC_ARCH_FEATURES;
args.arg1 = SMCCC_ARCH_WORKAROUND_1;
ret = tftf_smc(&args);
if ((int)ret.ret0 == -1) {
@@ -104,7 +104,7 @@ static test_result_t test_smccc_entrypoint(void)
/* Invoke the workaround to make sure nothing nasty happens */
memset(&args, 0, sizeof(args));
- args.arg0 = SMCCC_ARCH_WORKAROUND_1;
+ args.fid = SMCCC_ARCH_WORKAROUND_1;
tftf_smc(&args);
return TEST_RESULT_SUCCESS;
}
diff --git a/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_2.c b/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_2.c
index dd0542ca3..a09087411 100644
--- a/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_2.c
+++ b/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_2.c
@@ -43,7 +43,7 @@ static test_result_t test_smccc_entrypoint(void)
/* Check if SMCCC version is at least v1.1 */
expected_ver = MAKE_SMCCC_VERSION(1, 1);
memset(&args, 0, sizeof(args));
- args.arg0 = SMCCC_VERSION;
+ args.fid = SMCCC_VERSION;
ret = tftf_smc(&args);
if ((int32_t)ret.ret0 < expected_ver) {
tftf_testcase_printf("Unexpected SMCCC version: 0x%x\n",
@@ -53,7 +53,7 @@ static test_result_t test_smccc_entrypoint(void)
/* Check if SMCCC_ARCH_WORKAROUND_2 is required or not */
memset(&args, 0, sizeof(args));
- args.arg0 = SMCCC_ARCH_FEATURES;
+ args.fid = SMCCC_ARCH_FEATURES;
args.arg1 = SMCCC_ARCH_WORKAROUND_2;
ret = tftf_smc(&args);
if ((int)ret.ret0 == -1) {
@@ -87,7 +87,7 @@ static test_result_t test_smccc_entrypoint(void)
/* Invoke the workaround to make sure nothing nasty happens */
memset(&args, 0, sizeof(args));
- args.arg0 = SMCCC_ARCH_WORKAROUND_2;
+ args.fid = SMCCC_ARCH_WORKAROUND_2;
tftf_smc(&args);
return TEST_RESULT_SUCCESS;
}
diff --git a/tftf/tests/runtime_services/generic/generic_smc.c b/tftf/tests/runtime_services/generic/generic_smc.c
new file mode 100644
index 000000000..901b44812
--- /dev/null
+++ b/tftf/tests/runtime_services/generic/generic_smc.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psci.h>
+#include <smccc.h>
+#include <std_svc.h>
+#include <string.h>
+#include <tftf_lib.h>
+#include <tsp.h>
+#include <utils_def.h>
+
+/* An invalid SMC function number. */
+#define INVALID_FN 0x666
+
+/* PSCI version returned by TF-A. */
+static const uint32_t psci_version = PSCI_VERSION(PSCI_MAJOR_VER,
+ PSCI_MINOR_VER);
+
+/* UUID of the standard service in TF-A. */
+static const smc_ret_values std_svc_uuid = {
+ 0x108d905b, 0x47e8f863, 0xfbc02dae, 0xe2f64156
+};
+
+/*
+ * Build an SMC function ID given its type (fast/yielding), calling convention,
+ * owning entity number and function number.
+ */
+static inline uint32_t make_smc_fid(unsigned int type, unsigned int cc,
+ unsigned int oen, unsigned int func_num)
+{
+ return (type << FUNCID_TYPE_SHIFT) | (cc << FUNCID_CC_SHIFT)
+ | (oen << FUNCID_OEN_SHIFT) | (func_num << FUNCID_NUM_SHIFT);
+}
+
+/* Exit the test if the specified condition holds true. */
+#define FAIL_IF(_cond) \
+ do { \
+ if ((_cond)) { \
+ return TEST_RESULT_FAIL; \
+ } \
+ } while (0)
+
+/*
+ * Send an SMC with the specified arguments.
+ * Check that the values it returns match the expected ones. If not, write an
+ * error message in the test report.
+ */
+static bool smc_check_eq(const smc_args *args, const smc_ret_values *expect)
+{
+ smc_ret_values ret = tftf_smc(args);
+
+ if (memcmp(&ret, expect, sizeof(smc_ret_values)) == 0) {
+ return true;
+ } else {
+ tftf_testcase_printf(
+ "Got {0x%lx,0x%lx,0x%lx,0x%lx}, expected {0x%lx,0x%lx,0x%lx,0x%lx}.\n",
+ ret.ret0, ret.ret1, ret.ret2, ret.ret3,
+ expect->ret0, expect->ret1, expect->ret2, expect->ret3);
+ return false;
+ }
+}
+
+/* Exercise SMC32 calling convention with fast SMC calls. */
+test_result_t smc32_fast(void)
+{
+ /* Valid Fast SMC32 using all 4 return values. */
+ const smc_args args1 = { .fid = SMC_STD_SVC_UID };
+ FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+
+ /* Invalid Fast SMC32. */
+ const smc_args args2 = {
+ make_smc_fid(SMC_TYPE_FAST, SMC_32, OEN_ARM_START, INVALID_FN),
+ 0x11111111, 0x22222222, 0x33333333 };
+ const smc_ret_values ret2
+ = { SMC_UNKNOWN, 0x11111111, 0x22222222, 0x33333333 };
+ FAIL_IF(!smc_check_eq(&args2, &ret2));
+
+ /* Valid Fast SMC32 using 1 return value. */
+ const smc_args args3
+ = { SMC_PSCI_VERSION, 0x44444444, 0x55555555, 0x66666666 };
+ const smc_ret_values ret3
+ = { psci_version, 0x44444444, 0x55555555, 0x66666666 };
+ FAIL_IF(!smc_check_eq(&args3, &ret3));
+
+ return TEST_RESULT_SUCCESS;
+}
+
+/* Exercise SMC64 calling convention with yielding SMC calls. */
+test_result_t smc64_yielding(void)
+{
+ /* Valid Fast SMC32 using all 4 return values. */
+ const smc_args args1 = { .fid = SMC_STD_SVC_UID };
+ FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+
+ /* Invalid function number, SMC64 Yielding. */
+ const smc_args args2 = {
+ make_smc_fid(SMC_TYPE_STD, SMC_64, OEN_ARM_START, INVALID_FN),
+ 0x11111111, 0x22222222, 0x33333333 };
+ const smc_ret_values ret2
+ = { SMC_UNKNOWN, 0x11111111, 0x22222222, 0x33333333 };
+ FAIL_IF(!smc_check_eq(&args2, &ret2));
+
+ /*
+ * Valid[1] yielding SMC64 using 1 return value.
+ *
+ * [1] Valid from the point of view of the generic SMC handler if the
+ * TSPd is present. In this case, the SMC request gets passed to the
+ * TSPd handler code. The fact that it then gets rejected by the TSPd is
+ * irrelevant here, as we are not trying to test the TSPd nor the TSP.
+ *
+ * In other cases (i.e. AArch64 BL31 with no TSPd support or AArch32
+ * SP_MIN) this test should still fail in the same way, although it
+ * doesn't exercise the same code path in TF-A.
+ */
+ const smc_args args3 = {
+ make_smc_fid(SMC_TYPE_STD, SMC_64, OEN_TOS_START, INVALID_FN),
+ 0x44444444, 0x55555555, 0x66666666 };
+ const smc_ret_values ret3
+ = { SMC_UNKNOWN, 0x44444444, 0x55555555, 0x66666666 };
+ FAIL_IF(!smc_check_eq(&args3, &ret3));
+
+ return TEST_RESULT_SUCCESS;
+}
+
+#ifdef AARCH32
+static test_result_t smc64_fast_caller32(void)
+{
+ /* Valid Fast SMC32 using all 4 return values. */
+ smc_args args1 = { .fid = SMC_STD_SVC_UID };
+ FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+
+ /* Invalid SMC function number, Fast SMC64. */
+ const smc_args args2 = {
+ make_smc_fid(SMC_TYPE_FAST, SMC_64, OEN_ARM_START, INVALID_FN),
+ 0x11111111, 0x22222222, 0x33333333 };
+ const smc_ret_values ret2
+ = { SMC_UNKNOWN, 0x11111111, 0x22222222, 0x33333333 };
+ FAIL_IF(!smc_check_eq(&args2, &ret2));
+
+ /*
+ * Valid SMC function number, Fast SMC64. However, 32-bit callers are
+ * forbidden to use the SMC64 calling convention.
+ */
+ const smc_args args3 = { SMC_PSCI_AFFINITY_INFO_AARCH64,
+ 0x44444444, 0x55555555, 0x66666666 };
+ const smc_ret_values ret3
+ = { SMC_UNKNOWN, 0x44444444, 0x55555555, 0x66666666 };
+ FAIL_IF(!smc_check_eq(&args3, &ret3));
+
+ return TEST_RESULT_SUCCESS;
+}
+#else
+static test_result_t smc64_fast_caller64(void)
+{
+ /* Valid Fast SMC32 using all 4 return values. */
+ smc_args args1 = { .fid = SMC_STD_SVC_UID };
+ FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+
+ /* Invalid function number, Fast SMC64. */
+ const smc_args args2 = {
+ make_smc_fid(SMC_TYPE_FAST, SMC_64, OEN_ARM_START, INVALID_FN),
+ 0x11111111, 0x22222222, 0x33333333 };
+ const smc_ret_values ret2
+ = { SMC_UNKNOWN, 0x11111111, 0x22222222, 0x33333333 };
+ FAIL_IF(!smc_check_eq(&args2, &ret2));
+
+ /* Valid Fast SMC64 using 1 return value. */
+ const smc_args args3 = { SMC_PSCI_AFFINITY_INFO_AARCH64,
+ 0x44444444, 0x55555555, 0x66666666 };
+ const smc_ret_values ret3
+ = { PSCI_E_INVALID_PARAMS, 0x44444444, 0x55555555, 0x66666666 };
+ FAIL_IF(!smc_check_eq(&args3, &ret3));
+
+ return TEST_RESULT_SUCCESS;
+}
+#endif /* AARCH32 */
+
+/* Exercise SMC64 calling convention with fast SMC calls. */
+test_result_t smc64_fast(void)
+{
+#ifdef AARCH32
+ return smc64_fast_caller32();
+#else
+ return smc64_fast_caller64();
+#endif
+}
+
+/* Exercise SMC32 calling convention with yielding SMC calls. */
+test_result_t smc32_yielding(void)
+{
+ /* Valid Fast SMC32 using all 4 return values. */
+ const smc_args args1 = { .fid = SMC_STD_SVC_UID };
+ FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+
+ /* Invalid function number, SMC32 Yielding. */
+ const smc_args args2 = {
+ make_smc_fid(SMC_TYPE_STD, SMC_32, OEN_ARM_START, INVALID_FN),
+ 0x11111111, 0x22222222, 0x33333333 };
+ const smc_ret_values ret2
+ = { SMC_UNKNOWN, 0x11111111, 0x22222222, 0x33333333 };
+ FAIL_IF(!smc_check_eq(&args2, &ret2));
+
+ /*
+ * Valid[1] yielding SMC32 using 1 return value.
+ *
+ * [1] Valid from the point of view of the generic SMC handler if a
+ * secure payload dispatcher handling this SMC range is present. In this
+ * case, the SMC request gets passed to the dispatcher handler code. The
+ * fact that it then gets rejected by the dispatcher is irrelevant here,
+ * as we are not trying to test the dispatcher nor the secure payload.
+ *
+ * In BL31 has no SPD support, this test should still fail in the same
+ * way, although it doesn't exercise the same code path in TF-A.
+ */
+ const smc_args args3 = {
+ make_smc_fid(SMC_TYPE_STD, SMC_32, OEN_TOS_START, INVALID_FN),
+ 0x44444444, 0x55555555, 0x66666666 };
+ const smc_ret_values ret3
+ = { SMC_UNKNOWN, 0x44444444, 0x55555555, 0x66666666 };
+ FAIL_IF(!smc_check_eq(&args3, &ret3));
+
+ return TEST_RESULT_SUCCESS;
+}
+
diff --git a/tftf/tests/runtime_services/sip_service/test_exec_state_switch.c b/tftf/tests/runtime_services/sip_service/test_exec_state_switch.c
index 120a99ee0..713c8196e 100644
--- a/tftf/tests/runtime_services/sip_service/test_exec_state_switch.c
+++ b/tftf/tests/runtime_services/sip_service/test_exec_state_switch.c
@@ -130,7 +130,7 @@ test_result_t test_exec_state_switch_invalid_pc(void)
int ret;
smc_args args = {
- .arg0 = ARM_SIP_SVC_EXE_STATE_SWITCH,
+ .fid = ARM_SIP_SVC_EXE_STATE_SWITCH,
.arg1 = (u_register_t) -1,
.arg2 = LO32(&state_switch_a32_entry),
.arg3 = HI32(&state_switch_cookie),
@@ -163,7 +163,7 @@ test_result_t test_exec_state_switch_invalid_ctx(void)
int ret;
smc_args args = {
- .arg0 = ARM_SIP_SVC_EXE_STATE_SWITCH,
+ .fid = ARM_SIP_SVC_EXE_STATE_SWITCH,
.arg1 = HI32(&state_switch_a32_entry),
.arg2 = LO32(&state_switch_a32_entry),
.arg3 = -1,
@@ -195,7 +195,7 @@ test_result_t test_exec_state_switch_valid(void)
int ret;
smc_args args = {
- .arg0 = ARM_SIP_SVC_EXE_STATE_SWITCH,
+ .fid = ARM_SIP_SVC_EXE_STATE_SWITCH,
.arg1 = HI32(&state_switch_a32_entry),
.arg2 = LO32(&state_switch_a32_entry),
.arg3 = HI32(&state_switch_cookie),
@@ -259,7 +259,7 @@ test_result_t test_exec_state_switch_after_cpu_on(void)
int ret;
smc_args args = {
- .arg0 = ARM_SIP_SVC_EXE_STATE_SWITCH,
+ .fid = ARM_SIP_SVC_EXE_STATE_SWITCH,
.arg1 = HI32(&state_switch_a32_entry),
.arg2 = LO32(&state_switch_a32_entry),
.arg3 = HI32(&state_switch_cookie),
diff --git a/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c b/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
index ac811e209..3a3701e92 100644
--- a/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
+++ b/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
@@ -55,7 +55,7 @@ static u_register_t pmf_get_ts(u_register_t tid, u_register_t *v)
smc_args args = { 0 };
smc_ret_values ret;
- args.arg0 = PMF_SMC_GET_TIMESTAMP;
+ args.fid = PMF_SMC_GET_TIMESTAMP;
args.arg1 = tid;
args.arg2 = read_mpidr_el1();
ret = tftf_smc(&args);
diff --git a/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c b/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c
index 73a10489f..50462d7fd 100644
--- a/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c
+++ b/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c
@@ -43,7 +43,7 @@ test_result_t test_migrate_info_type(void)
int32_t migrate_ret;
/* Identify the level of multicore support present in the Trusted OS */
- args.arg0 = SMC_PSCI_MIG_INFO_TYPE;
+ args.fid = SMC_PSCI_MIG_INFO_TYPE;
ret = tftf_smc(&args);
mp_support = (int32_t) ret.ret0;
@@ -84,7 +84,7 @@ test_result_t test_migrate_info_type(void)
* Either there is no Trusted OS or the Trusted OS is the TSP.
* In both cases, the MIGRATE call should not be supported.
*/
- args.arg0 = SMC_PSCI_MIG;
+ args.fid = SMC_PSCI_MIG;
/*
* Pass a valid MPID so that the MIGRATE call doesn't fail because of
* invalid parameters
diff --git a/tftf/tests/runtime_services/standard_service/query_std_svc.c b/tftf/tests/runtime_services/standard_service/query_std_svc.c
index e96d4ae13..34141d2b8 100644
--- a/tftf/tests/runtime_services/standard_service/query_std_svc.c
+++ b/tftf/tests/runtime_services/standard_service/query_std_svc.c
@@ -41,7 +41,7 @@ test_result_t test_query_std_svc(void)
test_result_t test_result = TEST_RESULT_SUCCESS;
/* Standard Service Call UID */
- std_svc_args.arg0 = SMC_STD_SVC_UID;
+ std_svc_args.fid = SMC_STD_SVC_UID;
ret = tftf_smc(&std_svc_args);
make_uuid_from_4words(&std_svc_uuid,
@@ -55,7 +55,7 @@ test_result_t test_query_std_svc(void)
}
/* Standard Service Call Count */
- std_svc_args.arg0 = SMC_STD_SVC_CALL_COUNT;
+ std_svc_args.fid = SMC_STD_SVC_CALL_COUNT;
ret = tftf_smc(&std_svc_args);
if (ret.ret0 == SMC_UNKNOWN) {
@@ -68,7 +68,7 @@ test_result_t test_query_std_svc(void)
}
/* Standard Service Call Revision details */
- std_svc_args.arg0 = SMC_STD_SVC_REVISION;
+ std_svc_args.fid = SMC_STD_SVC_REVISION;
ret = tftf_smc(&std_svc_args);
if ((ret.ret0 != STD_SVC_REVISION_MAJOR) ||
diff --git a/tftf/tests/runtime_services/standard_service/unknown_smc.c b/tftf/tests/runtime_services/standard_service/unknown_smc.c
index 70175e3d1..d2a81ca62 100644
--- a/tftf/tests/runtime_services/standard_service/unknown_smc.c
+++ b/tftf/tests/runtime_services/standard_service/unknown_smc.c
@@ -20,7 +20,7 @@ test_result_t test_unknown_smc(void)
smc_args unk_smc;
smc_ret_values ret;
- unk_smc.arg0 = INVALID_FID;
+ unk_smc.fid = INVALID_FID;
ret = tftf_smc(&unk_smc);
if (ret.ret0 != SMC_UNKNOWN) {
diff --git a/tftf/tests/runtime_services/trusted_os/tsp/test_irq_preempted_std_smc.c b/tftf/tests/runtime_services/trusted_os/tsp/test_irq_preempted_std_smc.c
index 22e35dbc1..b8bfcfe5e 100644
--- a/tftf/tests/runtime_services/trusted_os/tsp/test_irq_preempted_std_smc.c
+++ b/tftf/tests/runtime_services/trusted_os/tsp/test_irq_preempted_std_smc.c
@@ -125,7 +125,7 @@ static int preempt_std_smc_on_this_cpu(void)
* Invoke an STD SMC. Should be pre-empted because of the SGI
* that is waiting.
*/
- std_smc_args.arg0 = TSP_STD_FID(TSP_ADD);
+ std_smc_args.fid = TSP_STD_FID(TSP_ADD);
std_smc_args.arg1 = TEST_VALUE_1;
std_smc_args.arg2 = TEST_VALUE_2;
smc_ret = tftf_smc(&std_smc_args);
@@ -163,7 +163,7 @@ static int resume_std_smc_on_this_cpu(void)
unsigned int core_pos = platform_get_core_pos(core_mpid);
/* Resume the STD SMC. Verify result. */
- std_smc_args.arg0 = TSP_FID_RESUME;
+ std_smc_args.fid = TSP_FID_RESUME;
smc_ret = tftf_smc(&std_smc_args);
if ((smc_ret.ret0 != 0) || (smc_ret.ret1 != TEST_VALUE_1 * 2)
|| (smc_ret.ret2 != TEST_VALUE_2 * 2)) {
@@ -191,7 +191,7 @@ static int resume_fail_std_smc_on_this_cpu(void)
unsigned int core_pos = platform_get_core_pos(core_mpid);
/* Resume the STD SMC. Verify result. */
- std_smc_args.arg0 = TSP_FID_RESUME;
+ std_smc_args.fid = TSP_FID_RESUME;
smc_ret = tftf_smc(&std_smc_args);
if (smc_ret.ret0 != SMC_UNKNOWN) {
tftf_testcase_printf(
@@ -304,7 +304,7 @@ static test_result_t test_resume_preempted_std_smc_other_cpus_non_lead_fn(void)
*/
smc_args std_smc_args;
- std_smc_args.arg0 = TSP_FID_RESUME;
+ std_smc_args.fid = TSP_FID_RESUME;
smc_ret_values smc_ret = tftf_smc(&std_smc_args);
if (smc_ret.ret0 != SMC_UNKNOWN) {
tftf_testcase_printf(
@@ -427,7 +427,7 @@ static test_result_t test_resume_different_cpu_preempted_std_smc_non_lead_fn(voi
* waiting. It has to be different than the one invoked from the lead
* CPU.
*/
- std_smc_args.arg0 = TSP_STD_FID(TSP_MUL);
+ std_smc_args.fid = TSP_STD_FID(TSP_MUL);
std_smc_args.arg1 = TEST_VALUE_1;
std_smc_args.arg2 = TEST_VALUE_2;
smc_ret = tftf_smc(&std_smc_args);
@@ -458,7 +458,7 @@ static test_result_t test_resume_different_cpu_preempted_std_smc_non_lead_fn(voi
}
/* Resume the STD SMC. Verify result. */
- std_smc_args.arg0 = TSP_FID_RESUME;
+ std_smc_args.fid = TSP_FID_RESUME;
smc_ret = tftf_smc(&std_smc_args);
if ((smc_ret.ret0 != 0) || (smc_ret.ret1 != TEST_VALUE_1*TEST_VALUE_1)
|| (smc_ret.ret2 != TEST_VALUE_2*TEST_VALUE_2)) {
@@ -474,7 +474,7 @@ static test_result_t test_resume_different_cpu_preempted_std_smc_non_lead_fn(voi
}
/* Try to resume the lead CPU STD SMC. Verify result. */
- std_smc_args.arg0 = TSP_FID_RESUME;
+ std_smc_args.fid = TSP_FID_RESUME;
smc_ret = tftf_smc(&std_smc_args);
if (smc_ret.ret0 != SMC_UNKNOWN) {
tftf_testcase_printf(
@@ -536,7 +536,7 @@ test_result_t test_resume_different_cpu_preempted_std_smc(void)
* Invoke an STD SMC. Should be pre-empted because of the SGI that is
* waiting.
*/
- std_smc_args.arg0 = TSP_STD_FID(TSP_ADD);
+ std_smc_args.fid = TSP_STD_FID(TSP_ADD);
std_smc_args.arg1 = TEST_VALUE_1;
std_smc_args.arg2 = TEST_VALUE_2;
smc_ret = tftf_smc(&std_smc_args);
@@ -589,7 +589,7 @@ test_result_t test_resume_different_cpu_preempted_std_smc(void)
* Try to resume the STD SMC from the lead CPU. It should be able resume
* the one it generated before and to return the correct result.
*/
- std_smc_args.arg0 = TSP_FID_RESUME;
+ std_smc_args.fid = TSP_FID_RESUME;
smc_ret = tftf_smc(&std_smc_args);
if ((smc_ret.ret0 != 0) || (smc_ret.ret1 != TEST_VALUE_1 * 2) ||
(smc_ret.ret2 != TEST_VALUE_2 * 2)) {
diff --git a/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c b/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c
index 767484014..6eaf0465a 100644
--- a/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c
+++ b/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c
@@ -70,7 +70,7 @@ static test_result_t test_multicore_spurious_interrupt_non_lead_fn(void)
smc_ret_values smc_ret;
/* Invoke an STD SMC. */
- std_smc_args.arg0 = TSP_STD_FID(TSP_ADD);
+ std_smc_args.fid = TSP_STD_FID(TSP_ADD);
std_smc_args.arg1 = TEST_VALUE_1;
std_smc_args.arg2 = TEST_VALUE_2;
smc_ret = tftf_smc(&std_smc_args);
@@ -93,7 +93,7 @@ static test_result_t test_multicore_spurious_interrupt_non_lead_fn(void)
}
} else if (smc_ret.ret0 == TSP_SMC_PREEMPTED) {
/* Resume the STD SMC. */
- std_smc_args.arg0 = TSP_FID_RESUME;
+ std_smc_args.fid = TSP_FID_RESUME;
smc_ret = tftf_smc(&std_smc_args);
preempted_count[core_pos]++;
} else {
diff --git a/tftf/tests/runtime_services/trusted_os/tsp/test_normal_int_switch.c b/tftf/tests/runtime_services/trusted_os/tsp/test_normal_int_switch.c
index c2223894c..0128ffae8 100644
--- a/tftf/tests/runtime_services/trusted_os/tsp/test_normal_int_switch.c
+++ b/tftf/tests/runtime_services/trusted_os/tsp/test_normal_int_switch.c
@@ -129,7 +129,7 @@ test_result_t tsp_int_and_resume(void)
SKIP_TEST_IF_TSP_NOT_PRESENT();
/* Standard SMC */
- tsp_svc_params.arg0 = TSP_STD_FID(TSP_ADD);
+ tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
tsp_svc_params.arg1 = 4;
tsp_svc_params.arg2 = 6;
res = preempt_tsp_via_SGI(&tsp_svc_params, 0);
@@ -137,7 +137,7 @@ test_result_t tsp_int_and_resume(void)
return res;
/* Now that we have ensured preemption, issue RESUME */
- tsp_svc_params.arg0 = TSP_FID_RESUME;
+ tsp_svc_params.fid = TSP_FID_RESUME;
tsp_result = tftf_smc(&tsp_svc_params);
/* Check the result of the addition */
@@ -153,7 +153,7 @@ test_result_t tsp_int_and_resume(void)
}
/* Standard SMC */
- tsp_svc_params.arg0 = TSP_STD_FID(TSP_SUB);
+ tsp_svc_params.fid = TSP_STD_FID(TSP_SUB);
tsp_svc_params.arg1 = 4;
tsp_svc_params.arg2 = 6;
res = preempt_tsp_via_SGI(&tsp_svc_params, 0);
@@ -161,7 +161,7 @@ test_result_t tsp_int_and_resume(void)
return res;
/* Now that we have ensured preemption, issue RESUME */
- tsp_svc_params.arg0 = TSP_FID_RESUME;
+ tsp_svc_params.fid = TSP_FID_RESUME;
tsp_result = tftf_smc(&tsp_svc_params);
/* Check the result of the substraction */
@@ -176,7 +176,7 @@ test_result_t tsp_int_and_resume(void)
}
/* Standard SMC */
- tsp_svc_params.arg0 = TSP_STD_FID(TSP_MUL);
+ tsp_svc_params.fid = TSP_STD_FID(TSP_MUL);
tsp_svc_params.arg1 = 4;
tsp_svc_params.arg2 = 6;
res = preempt_tsp_via_SGI(&tsp_svc_params, 0);
@@ -184,7 +184,7 @@ test_result_t tsp_int_and_resume(void)
return res;
/* Now that we have ensured preemption, issue RESUME */
- tsp_svc_params.arg0 = TSP_FID_RESUME;
+ tsp_svc_params.fid = TSP_FID_RESUME;
tsp_result = tftf_smc(&tsp_svc_params);
/* Check the result of the multiplication */
@@ -199,7 +199,7 @@ test_result_t tsp_int_and_resume(void)
}
/* Standard SMC */
- tsp_svc_params.arg0 = TSP_STD_FID(TSP_DIV);
+ tsp_svc_params.fid = TSP_STD_FID(TSP_DIV);
tsp_svc_params.arg1 = 4;
tsp_svc_params.arg2 = 6;
res = preempt_tsp_via_SGI(&tsp_svc_params, 0);
@@ -207,7 +207,7 @@ test_result_t tsp_int_and_resume(void)
return res;
/* Now that we have ensured preemption, issue RESUME */
- tsp_svc_params.arg0 = TSP_FID_RESUME;
+ tsp_svc_params.fid = TSP_FID_RESUME;
tsp_result = tftf_smc(&tsp_svc_params);
/* Check the result of the division */
@@ -241,7 +241,7 @@ test_result_t test_fast_smc_when_tsp_preempted(void)
SKIP_TEST_IF_TSP_NOT_PRESENT();
/* Standard SMC */
- tsp_svc_params.arg0 = TSP_STD_FID(TSP_ADD);
+ tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
tsp_svc_params.arg1 = 4;
tsp_svc_params.arg2 = 6;
res = preempt_tsp_via_SGI(&tsp_svc_params, 0);
@@ -249,7 +249,7 @@ test_result_t test_fast_smc_when_tsp_preempted(void)
return res;
/* Now that we have ensured preemption, issue Fast SMC */
- tsp_svc_params.arg0 = TSP_FAST_FID(TSP_ADD);
+ tsp_svc_params.fid = TSP_FAST_FID(TSP_ADD);
tsp_svc_params.arg1 = 4;
tsp_svc_params.arg2 = 6;
@@ -262,7 +262,7 @@ test_result_t test_fast_smc_when_tsp_preempted(void)
}
/* Issue RESUME */
- tsp_svc_params.arg0 = TSP_FID_RESUME;
+ tsp_svc_params.fid = TSP_FID_RESUME;
tsp_result = tftf_smc(&tsp_svc_params);
/* Check the result of the addition */
@@ -302,7 +302,7 @@ static test_result_t test_std_smc_when_tsp_preempted(int abort_smc)
SKIP_TEST_IF_TSP_NOT_PRESENT();
/* Standard SMC */
- tsp_svc_params.arg0 = TSP_STD_FID(TSP_ADD);
+ tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
tsp_svc_params.arg1 = 4;
tsp_svc_params.arg2 = 6;
res = preempt_tsp_via_SGI(&tsp_svc_params, 0);
@@ -310,7 +310,7 @@ static test_result_t test_std_smc_when_tsp_preempted(int abort_smc)
return res;
/* Now that we have ensured preemption, issue Standard SMC */
- tsp_svc_params.arg0 = TSP_STD_FID(TSP_ADD);
+ tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
tsp_svc_params.arg1 = 4;
tsp_svc_params.arg2 = 6;
@@ -322,7 +322,7 @@ static test_result_t test_std_smc_when_tsp_preempted(int abort_smc)
}
/* Issue ABORT or RESUME */
- tsp_svc_params.arg0 = abort_smc ? TSP_FID_ABORT : TSP_FID_RESUME;
+ tsp_svc_params.fid = abort_smc ? TSP_FID_ABORT : TSP_FID_RESUME;
tsp_result = tftf_smc(&tsp_svc_params);
/*
@@ -370,7 +370,7 @@ test_result_t test_resume_smc_without_preemption(void)
SKIP_TEST_IF_TSP_NOT_PRESENT();
/* Issue RESUME */
- tsp_svc_params.arg0 = TSP_FID_RESUME;
+ tsp_svc_params.fid = TSP_FID_RESUME;
tsp_result = tftf_smc(&tsp_svc_params);
if (tsp_result.ret0 != SMC_UNKNOWN) {
@@ -403,7 +403,7 @@ test_result_t tsp_int_and_resume_stress(void)
while ((count < STRESS_COUNT) &&
(res == TEST_RESULT_SUCCESS)) {
/* Standard SMC */
- tsp_svc_params.arg0 = TSP_STD_FID(TSP_ADD);
+ tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
tsp_svc_params.arg1 = 4;
tsp_svc_params.arg2 = 6;
/* Try to preempt TSP via IRQ */
@@ -412,7 +412,7 @@ test_result_t tsp_int_and_resume_stress(void)
return res;
/* Issue RESUME */
- tsp_svc_params.arg0 = TSP_FID_RESUME;
+ tsp_svc_params.fid = TSP_FID_RESUME;
tsp_result = tftf_smc(&tsp_svc_params);
/* Check the result of the addition */
@@ -454,7 +454,7 @@ test_result_t tsp_fiq_while_int(void)
SKIP_TEST_IF_TSP_NOT_PRESENT();
/* Standard SMC */
- tsp_svc_params.arg0 = TSP_STD_FID(TSP_ADD);
+ tsp_svc_params.fid = TSP_STD_FID(TSP_ADD);
tsp_svc_params.arg1 = 4;
tsp_svc_params.arg2 = 6;
res = preempt_tsp_via_SGI(&tsp_svc_params, 1);
@@ -462,7 +462,7 @@ test_result_t tsp_fiq_while_int(void)
return res;
/* Now that we have ensured preemption, issue RESUME */
- tsp_svc_params.arg0 = TSP_FID_RESUME;
+ tsp_svc_params.fid = TSP_FID_RESUME;
tsp_result = tftf_smc(&tsp_svc_params);
/* Check the result of the addition */
diff --git a/tftf/tests/runtime_services/trusted_os/tsp/test_smc_tsp_std_fn_call.c b/tftf/tests/runtime_services/trusted_os/tsp/test_smc_tsp_std_fn_call.c
index 836367667..6e99309bd 100644
--- a/tftf/tests/runtime_services/trusted_os/tsp/test_smc_tsp_std_fn_call.c
+++ b/tftf/tests/runtime_services/trusted_os/tsp/test_smc_tsp_std_fn_call.c
@@ -29,7 +29,7 @@ test_result_t test_smc_tsp_std_fns_call(void)
SKIP_TEST_IF_TSP_NOT_PRESENT();
/* TrustedOS Service Call Count */
- std_svc_args.arg0 = SMC_TOS_CALL_COUNT;
+ std_svc_args.fid = SMC_TOS_CALL_COUNT;
ret = tftf_smc(&std_svc_args);
if (ret.ret0 != TSP_NUM_FID) {
tftf_testcase_printf("Wrong Call Count: expected %u,\n"
@@ -39,7 +39,7 @@ test_result_t test_smc_tsp_std_fns_call(void)
}
/* TrustedOS Service Call Revision details */
- std_svc_args.arg0 = SMC_TOS_REVISION;
+ std_svc_args.fid = SMC_TOS_REVISION;
ret = tftf_smc(&std_svc_args);
if ((ret.ret0 != TSP_REVISION_MAJOR) ||
ret.ret1 != TSP_REVISION_MINOR) {
diff --git a/tftf/tests/tests-smc.mk b/tftf/tests/tests-smc.mk
new file mode 100644
index 000000000..8496cd1de
--- /dev/null
+++ b/tftf/tests/tests-smc.mk
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TESTS_SOURCES += tftf/tests/runtime_services/generic/generic_smc.c
diff --git a/tftf/tests/tests-smc.xml b/tftf/tests/tests-smc.xml
new file mode 100644
index 000000000..56f987dd9
--- /dev/null
+++ b/tftf/tests/tests-smc.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (c) 2018, Arm Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+-->
+
+<testsuites>
+
+ <testsuite name="SMC calling convention"
+ description="Test different flavours of the SMC calling convention">
+ <testcase name="Fast SMC32" function="smc32_fast" />
+ <testcase name="Fast SMC64" function="smc64_fast" />
+ <testcase name="Yielding SMC32" function="smc32_yielding" />
+ <testcase name="Yielding SMC64" function="smc64_yielding" />
+ </testsuite>
+
+</testsuites>
diff --git a/tftf/tests/tests-standard.mk b/tftf/tests/tests-standard.mk
index c4d35c609..72c2ec0d0 100644
--- a/tftf/tests/tests-standard.mk
+++ b/tftf/tests/tests-standard.mk
@@ -16,6 +16,7 @@ TESTS_MAKEFILE := $(addprefix tftf/tests/, \
tests-runtime-instrumentation.mk \
tests-sdei.mk \
tests-single-fault.mk \
+ tests-smc.mk \
tests-spm.mk \
tests-template.mk \
tests-tftf-validation.mk \
diff --git a/tftf/tests/tests-standard.xml b/tftf/tests/tests-standard.xml
index e2a1a2bd8..a1323d555 100644
--- a/tftf/tests/tests-standard.xml
+++ b/tftf/tests/tests-standard.xml
@@ -19,6 +19,7 @@
<!ENTITY tests-state-switch SYSTEM "tests-arm-state-switch.xml">
<!ENTITY tests-cpu-extensions SYSTEM "tests-cpu-extensions.xml">
<!ENTITY tests-performance SYSTEM "tests-performance.xml">
+ <!ENTITY tests-smc SYSTEM "tests-smc.xml">
]>
<testsuites>
@@ -33,5 +34,6 @@
&tests-state-switch;
&tests-cpu-extensions;
&tests-performance;
+ &tests-smc;
</testsuites>