aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Bellows <greg.bellows@linaro.org>2015-04-14 10:37:42 -0500
committerGreg Bellows <greg.bellows@linaro.org>2015-04-14 10:37:42 -0500
commit7a32277fbcf32bf11c8f3a0319c9e468694ff9e3 (patch)
treee24801c366de384746d46b9712c594bc333c1d1b
parentd5b1df057fc63bc1c949f83d0536a164cb3f137c (diff)
Breakout EL0 tests
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
-rw-r--r--common/syscntl.h5
-rw-r--r--el0/el0_common.h1
-rw-r--r--el0/nonsecure/Makefile10
-rw-r--r--el0/nonsecure/el0_nsec.c34
-rw-r--r--el0/nonsecure/tztest_nsec.c79
-rw-r--r--el0/secure/Makefile10
-rw-r--r--el0/secure/el0_sec.c (renamed from el0/secure/tztest_sec.c)15
-rw-r--r--tztest/tztest.c332
-rw-r--r--tztest/tztest.h124
-rw-r--r--tztest/tztest_el0.c (renamed from el0/tztest.c)25
-rw-r--r--tztest/tztest_el0.h10
-rw-r--r--tztest/tztest_internal.h (renamed from el0/tztest.h)28
-rw-r--r--tztest/tztest_old.c307
-rw-r--r--tztest/tztest_old.h126
14 files changed, 559 insertions, 547 deletions
diff --git a/common/syscntl.h b/common/syscntl.h
index 75d2637..641fadd 100644
--- a/common/syscntl.h
+++ b/common/syscntl.h
@@ -1,6 +1,9 @@
#ifndef _SYSCNTL_H
#define _SYSCNTL_H
+#include <stdint.h>
+#include "libcflat.h"
+
typedef struct {
void *buf_pa;
void *buf_va;
@@ -34,4 +37,6 @@ typedef struct {
test_control_t *test_cntl;
} sys_control_t;
+extern sys_control_t *syscntl;
+
#endif
diff --git a/el0/el0_common.h b/el0/el0_common.h
index 8177038..5b91ddf 100644
--- a/el0/el0_common.h
+++ b/el0/el0_common.h
@@ -7,7 +7,6 @@
#include "arm_builtins.h"
#include "el0.h"
#include "debug.h"
-#include "tztest.h"
extern sys_control_t *syscntl;
diff --git a/el0/nonsecure/Makefile b/el0/nonsecure/Makefile
index d2b45d4..6686683 100644
--- a/el0/nonsecure/Makefile
+++ b/el0/nonsecure/Makefile
@@ -1,12 +1,13 @@
-VPATH = $(ARCH):../$(ARCH):../../common/$(ARCH):../
+VPATH = $(ARCH):../$(ARCH):../../common/$(ARCH):../:../../tztest
EL0_NS_ELF = el0_nsec.elf
EL0_NS_IMAGE = el0_nsec.bin
EL0_NS_LOAD = el0_nsec.lds
-EL0_NS_OBJS = tztest_nsec.o \
- tztest.o \
+EL0_NS_OBJS = el0_nsec.o \
el0.o \
- builtins.o
+ builtins.o \
+ tztest.o \
+ tztest_el0.o
libgcc := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
FLATLIBS = ../../libcflat/libcflat.a $(libgcc) ../../libcflat/$(ARCH)/libeabi.a
@@ -15,6 +16,7 @@ FLATLIBS = ../../libcflat/libcflat.a $(libgcc) ../../libcflat/$(ARCH)/libeabi.a
CFLAGS += -I$(ARCH) -I../$(ARCH) -I../ -I../$(ARCH)
CFLAGS += -I../../common/$(ARCH) -I../../common/
+CFLAGS += -I../../tztest
##################################################################
diff --git a/el0/nonsecure/el0_nsec.c b/el0/nonsecure/el0_nsec.c
new file mode 100644
index 0000000..b3676c4
--- /dev/null
+++ b/el0/nonsecure/el0_nsec.c
@@ -0,0 +1,34 @@
+#include "el0_common.h"
+#include "tztest.h"
+
+const char *sec_state_str = "non-secure";
+sys_control_t *syscntl = NULL;
+
+int main()
+{
+ svc_op_desc_t desc;
+
+ printf("EL0 (%s) started...\n", sec_state_str);
+
+ /* Fetch the system-wide control structure */
+ __svc(SVC_OP_GET_SYSCNTL, &desc);
+ syscntl = ((sys_control_t *)desc.get.data);
+
+ /* Allocate and globally map test control descriptor */
+ syscntl->test_cntl = (test_control_t*)alloc_mem(0, 0x1000);
+ map_va(syscntl->test_cntl, 0x1000, OP_MAP_ALL);
+
+ /* If we didn't get a valid control structure then something has already
+ * gone drastically wrong.
+ */
+ if (!syscntl) {
+ DEBUG_MSG("Failed to acquire system control structure\n");
+ __svc(SVC_OP_EXIT, &desc);
+ }
+
+ tztest_start();
+
+ __svc(SVC_OP_EXIT, NULL);
+
+ return 0;
+}
diff --git a/el0/nonsecure/tztest_nsec.c b/el0/nonsecure/tztest_nsec.c
deleted file mode 100644
index b1f3946..0000000
--- a/el0/nonsecure/tztest_nsec.c
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "el0_common.h"
-#include "tztest.h"
-
-tztest_t tztest[TZTEST_COUNT];
-const char *sec_state_str;
-
-void interop_test()
-{
- op_test_t test;
-
- test.orig = test.val = 1024;
- test.fail = test.count = 0;
- printf("\nValidating interop communication between ELs... ");
- __svc(SVC_OP_TEST, (svc_op_desc_t *)&test);
- TEST_CONDITION(!test.fail && test.val == (test.orig >> test.count));
-}
-
-void run_test(tztest_func_id_t fid, uint32_t el)
-{
- op_dispatch_t disp;
-
- tztest[fid](el);
-
- disp.func_id = fid;
- __svc(SVC_OP_DISPATCH, (svc_op_desc_t *)&disp);
-}
-
-int main()
-{
- svc_op_desc_t desc;
-
- /* ISSUE: For some reason, static initialization of the global security
- * state string fails. The pointer ends up being NULL in some cases, but
- * not in others. This likely has something to do with the position
- * independence of the EL0 code. The below workaround works fine.
- */
- const char *str = "non-secure";
- sec_state_str = str;
-
- printf("EL0 (%s) started...\n", sec_state_str);
-
- tztest_init();
-
- /* Fetch the system-wide control structure */
- __svc(SVC_OP_GET_SYSCNTL, &desc);
- syscntl = ((sys_control_t *)desc.get.data);
-
- /* Allocate and globally map test control descriptor */
- syscntl->test_cntl = (test_control_t*)alloc_mem(0, 0x1000);
- map_va(syscntl->test_cntl, 0x1000, OP_MAP_ALL);
-
- printf("Starting TZ test...\n");
-
- /* Test EL to EL communication */
- interop_test();
-
- /* If we didn't get a valid control structure then something has already
- * gone drastically wrong.
- */
- if (!syscntl) {
- DEBUG_MSG("Failed to acquire system control structure\n");
- __svc(SVC_OP_EXIT, &desc);
- }
-
- run_test(TZTEST_SMC, 0);
- run_test(TZTEST_REG_ACCESS, 0);
-#if AARCH64
- run_test(TZTEST_CPACR_TRAP, 0);
- run_test(TZTEST_WFX_TRAP, 0);
-#endif
-
- printf("\nValidation complete. Passed %d of %d tests.\n",
- syscntl->test_cntl->test_count - syscntl->test_cntl->fail_count,
- syscntl->test_cntl->test_count);
-
- __svc(SVC_OP_EXIT, NULL);
-
- return 0;
-}
diff --git a/el0/secure/Makefile b/el0/secure/Makefile
index d08f143..9917c5d 100644
--- a/el0/secure/Makefile
+++ b/el0/secure/Makefile
@@ -1,12 +1,13 @@
-VPATH = $(ARCH):../$(ARCH):../../common/$(ARCH):../
+VPATH = $(ARCH):../$(ARCH):../../common/$(ARCH):../:../../tztest
EL0_S_ELF = el0_sec.elf
EL0_S_IMAGE = el0_sec.bin
EL0_S_LOAD = el0_sec.lds
-EL0_S_OBJS = tztest_sec.o \
- tztest.o \
+EL0_S_OBJS = el0_sec.o \
el0.o \
- builtins.o
+ builtins.o \
+ tztest.o \
+ tztest_el0.o
libgcc := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
FLATLIBS = ../../libcflat/libcflat.a $(libgcc) ../../libcflat/$(ARCH)/libeabi.a
@@ -15,6 +16,7 @@ FLATLIBS = ../../libcflat/libcflat.a $(libgcc) ../../libcflat/$(ARCH)/libeabi.a
CFLAGS += -I$(ARCH) -I../$(ARCH) -I../ -I../$(ARCH)
CFLAGS += -I../../common/$(ARCH) -I../../common/
+CFLAGS += -I../../tztest
##################################################################
diff --git a/el0/secure/tztest_sec.c b/el0/secure/el0_sec.c
index 74e0518..43f9e2f 100644
--- a/el0/secure/tztest_sec.c
+++ b/el0/secure/el0_sec.c
@@ -1,7 +1,8 @@
#include "el0_common.h"
+#include "tztest.h"
-const char *sec_state_str;
-tztest_t tztest[TZTEST_COUNT];
+const char *sec_state_str = "secure";
+sys_control_t *syscntl = NULL;
void el0_sec_loop()
{
@@ -53,18 +54,8 @@ int main()
{
svc_op_desc_t desc;
- /* ISSUE: For some reason, static initialization of the global security
- * state string fails. The pointer ends up being NULL in some cases, but
- * not in others. This likely has something to do with the position
- * independence of the EL0 code. The below workaround works fine.
- */
- const char *str = "secure";
- sec_state_str = str;
-
printf("EL0 (%s) started...\n", sec_state_str);
- tztest_init();
-
/* Fetch the system-wide control structure */
__svc(SVC_OP_GET_SYSCNTL, &desc);
syscntl = (sys_control_t *)desc.get.data;
diff --git a/tztest/tztest.c b/tztest/tztest.c
index 1a3b79b..71591fc 100644
--- a/tztest/tztest.c
+++ b/tztest/tztest.c
@@ -1,307 +1,57 @@
-#include "tztest.h"
-#include "arch.h"
-
-extern void test_handshake();
-
-/* Make the below globals volatile as found that the compiler uses the
- * register value ratherh than the memory value making it look like the writes
- * actually happened.
- */
-volatile int *tztest_fail_count = &_tztest_fail_count;
-volatile int *tztest_test_count = &_tztest_test_count;
-
-/* Function for dispatching an empty SMC call. Inteded fo use from P0 or P1
- * mode.
- */
-static inline uint32_t smc_noop()
-{
- asm volatile(".arch_extension sec\n"
- "push {lr}\n"
- "mov r0, #0\n"
- "smc #0\n"
- "pop {lr}\n");
- return 0;
-}
-
-uint32_t P0_nonsecure_check_smc()
-{
- validate_state(CPSR_MODE_USR, TZTEST_STATE_NONSECURE);
- printf("\nValidating non-secure P0 smc behavior:\n");
- printf("\tUnprivileged P0 smc call ... ");
- TEST_EXCEPTION(smc_noop(), CPSR_MODE_UND);
-
- return 0;
-}
-
-uint32_t P0_check_register_access(int state)
-{
- char *state_str[2] = {"Secure", "Nonsecure"};
-
- /* Set things to non-secure P1 and attempt accesses */
- printf("\nValidating %s P0 restricted register access:\n",
- (state == TZTEST_STATE_NONSECURE) ? "nonsecure" : "secure");
-
- printf("\t%s P0 SCR read ... ", state_str[state]);
- TEST_EXCEPTION(_read_scr(), CPSR_MODE_UND);
-
- printf("\t%s P0 SCR write ... ", state_str[state]);
- TEST_EXCEPTION(_write_scr(0), CPSR_MODE_UND);
-
- printf("\t%s P0 SDER read ... ", state_str[state]);
- TEST_EXCEPTION(_read_sder(), CPSR_MODE_UND);
-
- printf("\t%s P0 SDER write ... ", state_str[state]);
- TEST_EXCEPTION(_write_sder(0), CPSR_MODE_UND);
-
- printf("\t%s P0 MVBAR read ... ", state_str[state]);
- TEST_EXCEPTION(_read_mvbar(), CPSR_MODE_UND);
-
- printf("\t%s P0 MVBAR write ... ", state_str[state]);
- TEST_EXCEPTION(_write_mvbar(0), CPSR_MODE_UND);
-
- printf("\t%s P0 NSACR write ... ", state_str[state]);
- TEST_EXCEPTION(_write_nsacr(0), CPSR_MODE_UND);
-
- return 0;
-}
-
-uint32_t P0_nonsecure_check_register_access()
-{
- validate_state(CPSR_MODE_USR, TZTEST_STATE_NONSECURE);
-
- P0_check_register_access(TZTEST_STATE_NONSECURE);
-
- return 0;
-}
-
-uint32_t P0_secure_check_register_access()
-{
- validate_state(CPSR_MODE_USR, TZTEST_STATE_SECURE);
-
- P0_check_register_access(TZTEST_STATE_SECURE);
-
- return 0;
-}
-SECURE_USR_FUNC(P0_secure_check_register_access);
-
-uint32_t P1_nonsecure_check_mask_bits()
-{
- uint32_t ret = 0;
-
- validate_state(CPSR_MODE_SVC, TZTEST_STATE_NONSECURE);
-
- uint32_t cpsr = _read_cpsr();
-
- /* Test: SCR.FW/AW protects access to CPSR.F/Aa when nonsecure
- * pg. B1-1151 table B1-2
- */
- printf("\nValidating nonsecure accessiblilty of CPSR:\n");
-
- /* It is safe to assume that we are in nonsecure state as we validated
- * this on entry. Set the SCR FW and AW bits and preserve the NS bit.
- * This SCR setting should allow the CPSR to be written from nonsecure
- * state.
- */
- DISPATCH_MONITOR(_write_scr, (SCR_AW | SCR_FW | SCR_NS), ret);
-
- printf("\tChecking CPSR.F with SCR.FW enabled... ");
- TEST_FUNCTION(_write_cpsr(cpsr | (1 << 6)),
- ((cpsr | (1 << 6)) == _read_cpsr()));
-
- /* Restore CPSR to its original value before next test. */
- _write_cpsr(cpsr);
-
- printf("\tChecking CPSR.A with SCR.AW enabled... ");
- TEST_FUNCTION(_write_cpsr(cpsr | (1 << 8)),
- (cpsr | (1 << 8)) == _read_cpsr());
-
- /* Restore CPSR to its original value before next test. */
- _write_cpsr(cpsr);
-
- /* Switch SCR back to what we likely started with and retry the CPSR
- * writes. At this point the setting of these bits should be blocked due
- * to the AW and FW bits being clear.
- */
- DISPATCH_MONITOR(_write_scr, SCR_NS, ret);
-
- printf("\tChecking CPSR.F with SCR.FW disabled... ");
- TEST_FUNCTION(_write_cpsr(cpsr | (1 << 6)),
- (cpsr == _read_cpsr()));
-
- /* Restore CPSR to its original value before next test. */
- _write_cpsr(cpsr);
-
- printf("\tChecking CPSR.A with SCR.AW disabled... ");
- TEST_FUNCTION(_write_cpsr(cpsr | (1 << 8)),
- (cpsr == _read_cpsr()));
-
- /* Restore CPSR to its original value */
- _write_cpsr(cpsr);
-
- return ret;
-}
-
-uint32_t MON_check_state()
-{
- printf("\nValidating monitor mode:\n");
-
- uint32_t cpsr = _read_cpsr();
-
- printf("\tChecking monitor mode... ");
- TEST_CONDITION(CPSR_MODE_MON == (cpsr & CPSR_MODE_MASK));
-
- // Test: Check that CPSR.A/I.F are set to 1 on exception to mon mode
- // pg. B1-1182
- printf("\tChecking monitor mode CPSR.F value... ");
- TEST_CONDITION(CPSR_F == (CPSR_F & cpsr));
-
- printf("\tChecking monitor mode CPSR.I value... ");
- TEST_CONDITION(CPSR_I == (CPSR_I & cpsr));
-
- printf("\tChecking monitor mode CPSR.A value... ");
- TEST_CONDITION(CPSR_A == (CPSR_A & cpsr));
-
- return 0;
-}
-
-uint32_t MON_check_exceptions()
-{
- printf("\nValidating monitor mode exception:\n");
-
- uint32_t scr = _read_scr();
-
- /* B1-1211: SMC exceptions from monitor mode cause transition to secure
- * state.
- * Test: Check that an exception from mon mode, NS cleared to 0
- * pg. B1-1170
- */
- /* Set our starting security state to secure */
- _write_scr(scr & ~SCR_NS);
- printf("\tChecking state after secure monitor... ");
- TEST_FUNCTION(smc_noop(), !SCR_NS == ((_read_scr() & SCR_NS)));
-
- /* Set our security state to nonsecure */
- _write_scr(scr | SCR_NS);
- printf("\tChecking state after nonsecure monitor... ");
- TEST_FUNCTION(smc_noop(), !SCR_NS == ((_read_scr() & SCR_NS)));
-
- /* Restore the original SCR */
- _write_scr(scr);
-
- return 0;
-}
+#include "syscntl.h"
+#include "interop.h"
+#include "svc.h"
+#include "libcflat.h"
+#include "tztest_internal.h"
+#include "tztest_el0.h"
+
+tztest_t tztest[TZTEST_COUNT] =
+{
+ [TZTEST_SMC] = el0_check_smc,
+ [TZTEST_REG_ACCESS] = el0_check_register_access,
+#ifdef AARCH64
+ [TZTEST_CPACR_TRAP] = el0_check_cpacr_trap,
+ [TZTEST_WFX_TRAP] = el0_check_wfx_trap
+#endif
+};
-uint32_t P1_nonsecure_novirt_behavior()
+void interop_test()
{
- int ret = 0;
+ op_test_t test;
- validate_state(CPSR_MODE_SVC, TZTEST_STATE_NONSECURE);
-
- printf("\nValidating non-virtualized behavior:\n");
-
- DISPATCH_MONITOR(_write_scr, (SCR_SCD | SCR_NS), ret);
-
- // Check that SCR.SIF/SCD are not restrictive when EL2 not present
- // pg. B1-1158
- printf("\tChecking SCR.SCD has no effect... ");
- TEST_EXCEPTION(smc_noop(), 0);
-
- /* Restore SCR to just the nonsecure state */
- DISPATCH_MONITOR(_write_scr, SCR_NS, ret);
-
- return ret;
+ test.orig = test.val = 1024;
+ test.fail = test.count = 0;
+ printf("\nValidating interop communication between ELs... ");
+ __svc(SVC_OP_TEST, (svc_op_desc_t *)&test);
+ TEST_CONDITION(!test.fail && test.val == (test.orig >> test.count));
}
-uint32_t MON_check_banked_regs()
+void run_test(tztest_func_id_t fid, uint32_t el)
{
- uint32_t scr = _read_scr();
- uint32_t val = 0;
-
- printf("\nValidating monitor banked register access:\n");
-
- VERIFY_REGISTER_CUSTOM(csselr, 0xF, TZTEST_SVAL, TZTEST_NSVAL);
- /* Modifying SCTLR is highly disruptive, so the test is heavily restricted
- * to avoid complications. We only flip the V-bit for comparison which is
- * safe unless we take an exception which should be low risk.
- */
- val = _read_sctlr();
- VERIFY_REGISTER_CUSTOM(sctlr, (1 << 13), val, (val | (1 << 13)));
-
- /* ACTLR is banked but not supported on Vexpress */
-
- /* For testing purposes we switch the secure world to the nonsecure page
- * table, so any translations can still be made. Since we are only working
- * out of the non-secure mappings we should be safe. This assumption could
- * be wrong.
- */
- VERIFY_REGISTER_CUSTOM(ttbr0, 0xFFF00000,
- (uint32_t)nsec_l1_page_table, TZTEST_NSVAL);
- VERIFY_REGISTER(ttbr1);
-
- /* Modifying TTBCR is highly disruptive, so the test is heavily restricted
- * to avoid complications. We only use the PD1-bit for comparison as we
- * are not using ttbr1 at this time.
- */
- val = _read_ttbcr();
-
- VERIFY_REGISTER_CUSTOM(ttbcr, (1 << 5), val, (val | (1 << 5)));
- /* Leave the bottom 4 bits alone as they will disrupt address translation
- * otherwise.
- */
- VERIFY_REGISTER_CUSTOM(dacr, 0xFFFFFFF0, 0x55555555, 0xAAAAAAA5);
+ op_dispatch_t disp;
- VERIFY_REGISTER(dfsr);
- VERIFY_REGISTER(ifsr);
- VERIFY_REGISTER(dfar);
- VERIFY_REGISTER(ifar);
- VERIFY_REGISTER_CUSTOM(par, 0xFFFFF000, TZTEST_SVAL, TZTEST_NSVAL);
- VERIFY_REGISTER(prrr);
- VERIFY_REGISTER(nmrr);
+ tztest[fid](el);
- /* The bottome 5 bits are SBZ */
- VERIFY_REGISTER_CUSTOM(vbar, 0xFFFFFFE0, TZTEST_SVAL, TZTEST_NSVAL);
-
- VERIFY_REGISTER(fcseidr);
- VERIFY_REGISTER(contextidr);
- VERIFY_REGISTER(tpidrurw);
- VERIFY_REGISTER(tpidruro);
- VERIFY_REGISTER(tpidrprw);
-
- /* Restore the SCR to it's original value */
- _write_scr(scr);
-
- return 0;
+ disp.func_id = fid;
+ __svc(SVC_OP_DISPATCH, (svc_op_desc_t *)&disp);
}
-uint32_t tztest_nonsecure_usr_main()
+void tztest_start()
{
- uint32_t ret = 0;
+ printf("Starting TZ test...\n");
- DEBUG_MSG("Entered\n");
- *tztest_test_count = 0;
- *tztest_fail_count = 0;
+ /* Test EL to EL communication */
+ interop_test();
- P0_nonsecure_check_smc();
- P0_nonsecure_check_register_access();
-
-#ifdef DEBUG
- test_handshake();
+ run_test(TZTEST_SMC, 0);
+ run_test(TZTEST_REG_ACCESS, 0);
+#if AARCH64
+ run_test(TZTEST_CPACR_TRAP, 0);
+ run_test(TZTEST_WFX_TRAP, 0);
#endif
- DISPATCH_SECURE_USR(P0_secure_check_register_access, 0, ret);
-
- DISPATCH_MONITOR(MON_check_state, 0, ret);
- DISPATCH_MONITOR(MON_check_exceptions, 0, ret);
- DISPATCH_MONITOR(MON_check_banked_regs, 0, ret);
-
- DISPATCH_NONSECURE_SVC(P1_nonsecure_check_mask_bits, 0, ret);
-
- DISPATCH_NONSECURE_SVC(P1_nonsecure_novirt_behavior, 0, ret);
-
- printf("\nValidation complete. Passed %d of %d tests\n",
- *tztest_test_count-*tztest_fail_count, *tztest_test_count);
-
- DEBUG_MSG("Exiting\n");
-
- return ret;
+ printf("\nValidation complete. Passed %d of %d tests.\n",
+ syscntl->test_cntl->test_count - syscntl->test_cntl->fail_count,
+ syscntl->test_cntl->test_count);
}
+
diff --git a/tztest/tztest.h b/tztest/tztest.h
index 34ced86..e56c911 100644
--- a/tztest/tztest.h
+++ b/tztest/tztest.h
@@ -1,126 +1,10 @@
#ifndef _TZTEST_H
#define _TZTEST_H
-#include "common_defs.h"
-#include "common_svc.h"
+#include <stdint.h>
-extern volatile int _tztest_fail_count;
-extern volatile int _tztest_test_count;
-
-#define CALL(_f) __svc(0, _f)
-#define RETURN(_r) __svc(0,(_r))
-
-#define DISPATCH(_op, _func, _arg, _ret) \
- do { \
- tztest_svc_desc_t _desc; \
- _desc.dispatch.func = (_func); \
- _desc.dispatch.arg = (_arg); \
- __svc((_op), &_desc); \
- (_ret) = _desc.dispatch.ret; \
- } while(0)
-
-#define SECURE_USR_FUNC(_func) \
- uint32_t _func##_wrapper(uint32_t arg) { RETURN(_func(arg)); return 0; }
-
-#define DISPATCH_SECURE_USR(_func, _arg, _ret) \
- DISPATCH(SVC_DISPATCH_SECURE_USR, (_func##_wrapper), (_arg), (_ret))
-#define DISPATCH_SECURE_SVC(_func, _arg, _ret) \
- DISPATCH(SVC_DISPATCH_SECURE_SVC, (_func), (_arg), (_ret))
-#define DISPATCH_MONITOR(_func, _arg, _ret) \
- DISPATCH(SVC_DISPATCH_MONITOR, (_func), (_arg), (_ret))
-#define DISPATCH_NONSECURE_SVC(_func, _arg, _ret) \
- DISPATCH(SVC_DISPATCH_NONSECURE_SVC, (_func), (_arg), (_ret))
-
-#define INC_TEST_COUNT() (*tztest_test_count += 1)
-#define INC_FAIL_COUNT() (*tztest_fail_count += 1)
-
-#define TEST_CONDITION(_cond) \
- do { \
- if (!(_cond)) { \
- printf("FAILED\n"); \
- INC_FAIL_COUNT(); \
- } else { \
- printf("PASSED\n"); \
- } \
- INC_TEST_COUNT(); \
- } while(0)
-
-#define TEST_FUNCTION(_fn, _cond) \
- do { \
- _fn; \
- TEST_CONDITION(_cond); \
- } while(0)
-
-#define TEST_EXCEPTION(_fn, _excp) \
- do { \
- TEST_FUNCTION(_fn, *tztest_exception == (_excp)); \
- *tztest_exception = 0; \
- } while (0)
-
-#define TZTEST_SVAL 0xaaaaaaaa
-#define TZTEST_NSVAL ~TZTEST_SVAL
-#define TZTEST_GET_REG_SECURE_BANK(_reg, _val) \
- do { \
- _write_scr(scr & ~SCR_NS); \
- (_val) = _read_##_reg(); \
- } while(0)
-
-#define TZTEST_GET_REG_NONSECURE_BANK(_reg, _val) \
- do { \
- _write_scr(scr | SCR_NS); \
- (_val) = _read_##_reg(); \
- } while(0)
-
-#define TZTEST_SET_REG_SECURE_BANK(_reg, _val) \
- do { \
- _write_scr(scr & ~SCR_NS); \
- _write_##_reg(_val); \
- } while(0)
-
-#define TZTEST_SET_REG_NONSECURE_BANK(_reg, _val) \
- do { \
- _write_scr(scr | SCR_NS); \
- _write_##_reg(_val); \
- } while(0)
-
-#define TZTEST_GET_REG_BANKS(_reg, _sval, _nsval) \
- do { \
- TZTEST_GET_REG_SECURE_BANK(_reg, _sval); \
- TZTEST_GET_REG_NONSECURE_BANK(_reg, _nsval);\
- } while(0)
-
-#define TZTEST_SET_REG_BANKS(_reg, _sval, _nsval) \
- do { \
- TZTEST_SET_REG_SECURE_BANK(_reg, _sval); \
- TZTEST_SET_REG_NONSECURE_BANK(_reg, _nsval);\
- } while(0)
-
-#define VERIFY_REGISTER_CUSTOM(_reg, _mask, _sval, _nsval) \
- do { \
- uint32_t sval = 0, nsval = 0; \
- uint32_t _reg[2] = {0,0}; \
- printf("\tChecking %s banks... ", #_reg); \
- TZTEST_GET_REG_BANKS(_reg, _reg[!SCR_NS], _reg[SCR_NS]); \
- TZTEST_SET_REG_BANKS(_reg, (_sval), (_nsval)); \
- TZTEST_GET_REG_SECURE_BANK(_reg, sval); \
- TZTEST_GET_REG_NONSECURE_BANK(_reg, nsval); \
- TEST_CONDITION(((sval & (_mask)) != (nsval & (_mask))) && \
- (((_sval) & (_mask)) == (sval & (_mask))) && \
- (((_nsval) & (_mask)) == (nsval & (_mask)))); \
- TZTEST_SET_REG_BANKS(_reg, _reg[!SCR_NS], _reg[SCR_NS]); \
- } while(0)
-
-#define VERIFY_REGISTER(_reg) \
- VERIFY_REGISTER_CUSTOM(_reg, 0xFFFFFFFF, TZTEST_SVAL, TZTEST_NSVAL)
-
-extern volatile int *tztest_exception;
-extern volatile int *tztest_exception_addr;
-extern volatile int *tztest_exception_status;
-extern volatile int *tztest_fail_count;
-extern volatile int *tztest_test_count;
-extern void validate_state(uint32_t, uint32_t);
-extern uint32_t _shared_memory_heap_base;
-extern uint32_t *nsec_l1_page_table;
-extern uint32_t *nsec_l2_page_table;
+typedef uint32_t (*tztest_t)(uint32_t);
+extern tztest_t tztest[];
+extern void tztest_start();
#endif
diff --git a/el0/tztest.c b/tztest/tztest_el0.c
index bd15505..ce0c60a 100644
--- a/el0/tztest.c
+++ b/tztest/tztest_el0.c
@@ -5,12 +5,10 @@
#include "exception.h"
#include "el0.h"
#include "debug.h"
-#include "el0_common.h"
-#include "tztest.h"
+#include "tztest_internal.h"
+#include "tztest_el0.h"
-sys_control_t *syscntl = NULL;
-
-uint32_t check_smc(uint32_t el)
+uint32_t el0_check_smc(uint32_t el)
{
TEST_HEAD("smc behavior");
@@ -20,7 +18,7 @@ uint32_t check_smc(uint32_t el)
return 0;
}
-uint32_t check_register_access(uint32_t el)
+uint32_t el0_check_register_access(uint32_t el)
{
/* Set things to non-secure P1 and attempt accesses */
TEST_HEAD("restricted register access");
@@ -60,7 +58,7 @@ uint32_t check_register_access(uint32_t el)
}
#ifdef AARCH64
-uint32_t check_cpacr_trap(uint32_t el)
+uint32_t el0_check_cpacr_trap(uint32_t el)
{
uint64_t cptr_el3, cpacr;
@@ -93,7 +91,7 @@ uint32_t check_cpacr_trap(uint32_t el)
return 0;
}
-uint32_t check_wfx_trap(uint32_t el)
+uint32_t el0_check_wfx_trap(uint32_t el)
{
uint64_t sctlr, scr;
@@ -160,14 +158,3 @@ uint32_t check_wfx_trap(uint32_t el)
return 0;
}
#endif
-
-void tztest_init()
-{
- tztest[TZTEST_SMC] = check_smc;
- tztest[TZTEST_REG_ACCESS] = check_register_access;
-#ifdef AARCH64
- tztest[TZTEST_CPACR_TRAP] = check_cpacr_trap;
- tztest[TZTEST_WFX_TRAP] = check_wfx_trap;
-#endif
-}
-
diff --git a/tztest/tztest_el0.h b/tztest/tztest_el0.h
new file mode 100644
index 0000000..1f85648
--- /dev/null
+++ b/tztest/tztest_el0.h
@@ -0,0 +1,10 @@
+#ifndef _TZTEST_EL0_H
+#define _TZTEST_EL0_H
+
+extern uint32_t el0_check_smc(uint32_t);
+extern uint32_t el0_check_register_access(uint32_t);
+extern uint32_t el0_check_cpacr_trap(uint32_t);
+extern uint32_t el0_check_wfx_trap(uint32_t);
+
+#endif
+
diff --git a/el0/tztest.h b/tztest/tztest_internal.h
index be31277..5be8c78 100644
--- a/el0/tztest.h
+++ b/tztest/tztest_internal.h
@@ -1,14 +1,15 @@
-#ifndef _TZTEST_H
-#define _TZTEST_H
+#ifndef _TZTEST_INTERNAL_H
+#define _TZTEST_INTERNAL_H
-typedef uint32_t (*tztest_t)(uint32_t el);
-extern tztest_t tztest[];
+#include "tztest.h"
-extern void tztest_init();
-extern uint32_t check_smc(uint32_t el);
-extern uint32_t check_register_access(uint32_t el);
-extern uint32_t check_cpacr_trap(uint32_t el);
-extern uint32_t check_wfx_trap(uint32_t el);
+typedef enum {
+ TZTEST_SMC = 0,
+ TZTEST_REG_ACCESS,
+ TZTEST_CPACR_TRAP,
+ TZTEST_WFX_TRAP,
+ TZTEST_COUNT
+} tztest_func_id_t;
#define TEST_HEAD(_str, ...) \
printf("\nValidating %s EL%d " _str ":\n", sec_state_str, el, ##__VA_ARGS__)
@@ -54,12 +55,5 @@ extern uint32_t check_wfx_trap(uint32_t el);
#define TEST_EL3_EXCEPTION(_fn, _excp) \
TEST_EXCEPTION(_fn, _excp, el3_excp)
-typedef enum {
- TZTEST_SMC = 0,
- TZTEST_REG_ACCESS,
- TZTEST_CPACR_TRAP,
- TZTEST_WFX_TRAP,
- TZTEST_COUNT
-} tztest_func_id_t;
-
#endif
+
diff --git a/tztest/tztest_old.c b/tztest/tztest_old.c
new file mode 100644
index 0000000..1a3b79b
--- /dev/null
+++ b/tztest/tztest_old.c
@@ -0,0 +1,307 @@
+#include "tztest.h"
+#include "arch.h"
+
+extern void test_handshake();
+
+/* Make the below globals volatile as found that the compiler uses the
+ * register value ratherh than the memory value making it look like the writes
+ * actually happened.
+ */
+volatile int *tztest_fail_count = &_tztest_fail_count;
+volatile int *tztest_test_count = &_tztest_test_count;
+
+/* Function for dispatching an empty SMC call. Inteded fo use from P0 or P1
+ * mode.
+ */
+static inline uint32_t smc_noop()
+{
+ asm volatile(".arch_extension sec\n"
+ "push {lr}\n"
+ "mov r0, #0\n"
+ "smc #0\n"
+ "pop {lr}\n");
+ return 0;
+}
+
+uint32_t P0_nonsecure_check_smc()
+{
+ validate_state(CPSR_MODE_USR, TZTEST_STATE_NONSECURE);
+ printf("\nValidating non-secure P0 smc behavior:\n");
+ printf("\tUnprivileged P0 smc call ... ");
+ TEST_EXCEPTION(smc_noop(), CPSR_MODE_UND);
+
+ return 0;
+}
+
+uint32_t P0_check_register_access(int state)
+{
+ char *state_str[2] = {"Secure", "Nonsecure"};
+
+ /* Set things to non-secure P1 and attempt accesses */
+ printf("\nValidating %s P0 restricted register access:\n",
+ (state == TZTEST_STATE_NONSECURE) ? "nonsecure" : "secure");
+
+ printf("\t%s P0 SCR read ... ", state_str[state]);
+ TEST_EXCEPTION(_read_scr(), CPSR_MODE_UND);
+
+ printf("\t%s P0 SCR write ... ", state_str[state]);
+ TEST_EXCEPTION(_write_scr(0), CPSR_MODE_UND);
+
+ printf("\t%s P0 SDER read ... ", state_str[state]);
+ TEST_EXCEPTION(_read_sder(), CPSR_MODE_UND);
+
+ printf("\t%s P0 SDER write ... ", state_str[state]);
+ TEST_EXCEPTION(_write_sder(0), CPSR_MODE_UND);
+
+ printf("\t%s P0 MVBAR read ... ", state_str[state]);
+ TEST_EXCEPTION(_read_mvbar(), CPSR_MODE_UND);
+
+ printf("\t%s P0 MVBAR write ... ", state_str[state]);
+ TEST_EXCEPTION(_write_mvbar(0), CPSR_MODE_UND);
+
+ printf("\t%s P0 NSACR write ... ", state_str[state]);
+ TEST_EXCEPTION(_write_nsacr(0), CPSR_MODE_UND);
+
+ return 0;
+}
+
+uint32_t P0_nonsecure_check_register_access()
+{
+ validate_state(CPSR_MODE_USR, TZTEST_STATE_NONSECURE);
+
+ P0_check_register_access(TZTEST_STATE_NONSECURE);
+
+ return 0;
+}
+
+uint32_t P0_secure_check_register_access()
+{
+ validate_state(CPSR_MODE_USR, TZTEST_STATE_SECURE);
+
+ P0_check_register_access(TZTEST_STATE_SECURE);
+
+ return 0;
+}
+SECURE_USR_FUNC(P0_secure_check_register_access);
+
+uint32_t P1_nonsecure_check_mask_bits()
+{
+ uint32_t ret = 0;
+
+ validate_state(CPSR_MODE_SVC, TZTEST_STATE_NONSECURE);
+
+ uint32_t cpsr = _read_cpsr();
+
+ /* Test: SCR.FW/AW protects access to CPSR.F/Aa when nonsecure
+ * pg. B1-1151 table B1-2
+ */
+ printf("\nValidating nonsecure accessiblilty of CPSR:\n");
+
+ /* It is safe to assume that we are in nonsecure state as we validated
+ * this on entry. Set the SCR FW and AW bits and preserve the NS bit.
+ * This SCR setting should allow the CPSR to be written from nonsecure
+ * state.
+ */
+ DISPATCH_MONITOR(_write_scr, (SCR_AW | SCR_FW | SCR_NS), ret);
+
+ printf("\tChecking CPSR.F with SCR.FW enabled... ");
+ TEST_FUNCTION(_write_cpsr(cpsr | (1 << 6)),
+ ((cpsr | (1 << 6)) == _read_cpsr()));
+
+ /* Restore CPSR to its original value before next test. */
+ _write_cpsr(cpsr);
+
+ printf("\tChecking CPSR.A with SCR.AW enabled... ");
+ TEST_FUNCTION(_write_cpsr(cpsr | (1 << 8)),
+ (cpsr | (1 << 8)) == _read_cpsr());
+
+ /* Restore CPSR to its original value before next test. */
+ _write_cpsr(cpsr);
+
+ /* Switch SCR back to what we likely started with and retry the CPSR
+ * writes. At this point the setting of these bits should be blocked due
+ * to the AW and FW bits being clear.
+ */
+ DISPATCH_MONITOR(_write_scr, SCR_NS, ret);
+
+ printf("\tChecking CPSR.F with SCR.FW disabled... ");
+ TEST_FUNCTION(_write_cpsr(cpsr | (1 << 6)),
+ (cpsr == _read_cpsr()));
+
+ /* Restore CPSR to its original value before next test. */
+ _write_cpsr(cpsr);
+
+ printf("\tChecking CPSR.A with SCR.AW disabled... ");
+ TEST_FUNCTION(_write_cpsr(cpsr | (1 << 8)),
+ (cpsr == _read_cpsr()));
+
+ /* Restore CPSR to its original value */
+ _write_cpsr(cpsr);
+
+ return ret;
+}
+
+uint32_t MON_check_state()
+{
+ printf("\nValidating monitor mode:\n");
+
+ uint32_t cpsr = _read_cpsr();
+
+ printf("\tChecking monitor mode... ");
+ TEST_CONDITION(CPSR_MODE_MON == (cpsr & CPSR_MODE_MASK));
+
+ // Test: Check that CPSR.A/I.F are set to 1 on exception to mon mode
+ // pg. B1-1182
+ printf("\tChecking monitor mode CPSR.F value... ");
+ TEST_CONDITION(CPSR_F == (CPSR_F & cpsr));
+
+ printf("\tChecking monitor mode CPSR.I value... ");
+ TEST_CONDITION(CPSR_I == (CPSR_I & cpsr));
+
+ printf("\tChecking monitor mode CPSR.A value... ");
+ TEST_CONDITION(CPSR_A == (CPSR_A & cpsr));
+
+ return 0;
+}
+
+uint32_t MON_check_exceptions()
+{
+ printf("\nValidating monitor mode exception:\n");
+
+ uint32_t scr = _read_scr();
+
+ /* B1-1211: SMC exceptions from monitor mode cause transition to secure
+ * state.
+ * Test: Check that an exception from mon mode, NS cleared to 0
+ * pg. B1-1170
+ */
+ /* Set our starting security state to secure */
+ _write_scr(scr & ~SCR_NS);
+ printf("\tChecking state after secure monitor... ");
+ TEST_FUNCTION(smc_noop(), !SCR_NS == ((_read_scr() & SCR_NS)));
+
+ /* Set our security state to nonsecure */
+ _write_scr(scr | SCR_NS);
+ printf("\tChecking state after nonsecure monitor... ");
+ TEST_FUNCTION(smc_noop(), !SCR_NS == ((_read_scr() & SCR_NS)));
+
+ /* Restore the original SCR */
+ _write_scr(scr);
+
+ return 0;
+}
+
+uint32_t P1_nonsecure_novirt_behavior()
+{
+ int ret = 0;
+
+ validate_state(CPSR_MODE_SVC, TZTEST_STATE_NONSECURE);
+
+ printf("\nValidating non-virtualized behavior:\n");
+
+ DISPATCH_MONITOR(_write_scr, (SCR_SCD | SCR_NS), ret);
+
+ // Check that SCR.SIF/SCD are not restrictive when EL2 not present
+ // pg. B1-1158
+ printf("\tChecking SCR.SCD has no effect... ");
+ TEST_EXCEPTION(smc_noop(), 0);
+
+ /* Restore SCR to just the nonsecure state */
+ DISPATCH_MONITOR(_write_scr, SCR_NS, ret);
+
+ return ret;
+}
+
+uint32_t MON_check_banked_regs()
+{
+ uint32_t scr = _read_scr();
+ uint32_t val = 0;
+
+ printf("\nValidating monitor banked register access:\n");
+
+ VERIFY_REGISTER_CUSTOM(csselr, 0xF, TZTEST_SVAL, TZTEST_NSVAL);
+ /* Modifying SCTLR is highly disruptive, so the test is heavily restricted
+ * to avoid complications. We only flip the V-bit for comparison which is
+ * safe unless we take an exception which should be low risk.
+ */
+ val = _read_sctlr();
+ VERIFY_REGISTER_CUSTOM(sctlr, (1 << 13), val, (val | (1 << 13)));
+
+ /* ACTLR is banked but not supported on Vexpress */
+
+ /* For testing purposes we switch the secure world to the nonsecure page
+ * table, so any translations can still be made. Since we are only working
+ * out of the non-secure mappings we should be safe. This assumption could
+ * be wrong.
+ */
+ VERIFY_REGISTER_CUSTOM(ttbr0, 0xFFF00000,
+ (uint32_t)nsec_l1_page_table, TZTEST_NSVAL);
+ VERIFY_REGISTER(ttbr1);
+
+ /* Modifying TTBCR is highly disruptive, so the test is heavily restricted
+ * to avoid complications. We only use the PD1-bit for comparison as we
+ * are not using ttbr1 at this time.
+ */
+ val = _read_ttbcr();
+
+ VERIFY_REGISTER_CUSTOM(ttbcr, (1 << 5), val, (val | (1 << 5)));
+ /* Leave the bottom 4 bits alone as they will disrupt address translation
+ * otherwise.
+ */
+ VERIFY_REGISTER_CUSTOM(dacr, 0xFFFFFFF0, 0x55555555, 0xAAAAAAA5);
+
+ VERIFY_REGISTER(dfsr);
+ VERIFY_REGISTER(ifsr);
+ VERIFY_REGISTER(dfar);
+ VERIFY_REGISTER(ifar);
+ VERIFY_REGISTER_CUSTOM(par, 0xFFFFF000, TZTEST_SVAL, TZTEST_NSVAL);
+ VERIFY_REGISTER(prrr);
+ VERIFY_REGISTER(nmrr);
+
+ /* The bottome 5 bits are SBZ */
+ VERIFY_REGISTER_CUSTOM(vbar, 0xFFFFFFE0, TZTEST_SVAL, TZTEST_NSVAL);
+
+ VERIFY_REGISTER(fcseidr);
+ VERIFY_REGISTER(contextidr);
+ VERIFY_REGISTER(tpidrurw);
+ VERIFY_REGISTER(tpidruro);
+ VERIFY_REGISTER(tpidrprw);
+
+ /* Restore the SCR to it's original value */
+ _write_scr(scr);
+
+ return 0;
+}
+
+uint32_t tztest_nonsecure_usr_main()
+{
+ uint32_t ret = 0;
+
+ DEBUG_MSG("Entered\n");
+ *tztest_test_count = 0;
+ *tztest_fail_count = 0;
+
+ P0_nonsecure_check_smc();
+ P0_nonsecure_check_register_access();
+
+#ifdef DEBUG
+ test_handshake();
+#endif
+
+ DISPATCH_SECURE_USR(P0_secure_check_register_access, 0, ret);
+
+ DISPATCH_MONITOR(MON_check_state, 0, ret);
+ DISPATCH_MONITOR(MON_check_exceptions, 0, ret);
+ DISPATCH_MONITOR(MON_check_banked_regs, 0, ret);
+
+ DISPATCH_NONSECURE_SVC(P1_nonsecure_check_mask_bits, 0, ret);
+
+ DISPATCH_NONSECURE_SVC(P1_nonsecure_novirt_behavior, 0, ret);
+
+ printf("\nValidation complete. Passed %d of %d tests\n",
+ *tztest_test_count-*tztest_fail_count, *tztest_test_count);
+
+ DEBUG_MSG("Exiting\n");
+
+ return ret;
+}
diff --git a/tztest/tztest_old.h b/tztest/tztest_old.h
new file mode 100644
index 0000000..34ced86
--- /dev/null
+++ b/tztest/tztest_old.h
@@ -0,0 +1,126 @@
+#ifndef _TZTEST_H
+#define _TZTEST_H
+
+#include "common_defs.h"
+#include "common_svc.h"
+
+extern volatile int _tztest_fail_count;
+extern volatile int _tztest_test_count;
+
+#define CALL(_f) __svc(0, _f)
+#define RETURN(_r) __svc(0,(_r))
+
+#define DISPATCH(_op, _func, _arg, _ret) \
+ do { \
+ tztest_svc_desc_t _desc; \
+ _desc.dispatch.func = (_func); \
+ _desc.dispatch.arg = (_arg); \
+ __svc((_op), &_desc); \
+ (_ret) = _desc.dispatch.ret; \
+ } while(0)
+
+#define SECURE_USR_FUNC(_func) \
+ uint32_t _func##_wrapper(uint32_t arg) { RETURN(_func(arg)); return 0; }
+
+#define DISPATCH_SECURE_USR(_func, _arg, _ret) \
+ DISPATCH(SVC_DISPATCH_SECURE_USR, (_func##_wrapper), (_arg), (_ret))
+#define DISPATCH_SECURE_SVC(_func, _arg, _ret) \
+ DISPATCH(SVC_DISPATCH_SECURE_SVC, (_func), (_arg), (_ret))
+#define DISPATCH_MONITOR(_func, _arg, _ret) \
+ DISPATCH(SVC_DISPATCH_MONITOR, (_func), (_arg), (_ret))
+#define DISPATCH_NONSECURE_SVC(_func, _arg, _ret) \
+ DISPATCH(SVC_DISPATCH_NONSECURE_SVC, (_func), (_arg), (_ret))
+
+#define INC_TEST_COUNT() (*tztest_test_count += 1)
+#define INC_FAIL_COUNT() (*tztest_fail_count += 1)
+
+#define TEST_CONDITION(_cond) \
+ do { \
+ if (!(_cond)) { \
+ printf("FAILED\n"); \
+ INC_FAIL_COUNT(); \
+ } else { \
+ printf("PASSED\n"); \
+ } \
+ INC_TEST_COUNT(); \
+ } while(0)
+
+#define TEST_FUNCTION(_fn, _cond) \
+ do { \
+ _fn; \
+ TEST_CONDITION(_cond); \
+ } while(0)
+
+#define TEST_EXCEPTION(_fn, _excp) \
+ do { \
+ TEST_FUNCTION(_fn, *tztest_exception == (_excp)); \
+ *tztest_exception = 0; \
+ } while (0)
+
+#define TZTEST_SVAL 0xaaaaaaaa
+#define TZTEST_NSVAL ~TZTEST_SVAL
+#define TZTEST_GET_REG_SECURE_BANK(_reg, _val) \
+ do { \
+ _write_scr(scr & ~SCR_NS); \
+ (_val) = _read_##_reg(); \
+ } while(0)
+
+#define TZTEST_GET_REG_NONSECURE_BANK(_reg, _val) \
+ do { \
+ _write_scr(scr | SCR_NS); \
+ (_val) = _read_##_reg(); \
+ } while(0)
+
+#define TZTEST_SET_REG_SECURE_BANK(_reg, _val) \
+ do { \
+ _write_scr(scr & ~SCR_NS); \
+ _write_##_reg(_val); \
+ } while(0)
+
+#define TZTEST_SET_REG_NONSECURE_BANK(_reg, _val) \
+ do { \
+ _write_scr(scr | SCR_NS); \
+ _write_##_reg(_val); \
+ } while(0)
+
+#define TZTEST_GET_REG_BANKS(_reg, _sval, _nsval) \
+ do { \
+ TZTEST_GET_REG_SECURE_BANK(_reg, _sval); \
+ TZTEST_GET_REG_NONSECURE_BANK(_reg, _nsval);\
+ } while(0)
+
+#define TZTEST_SET_REG_BANKS(_reg, _sval, _nsval) \
+ do { \
+ TZTEST_SET_REG_SECURE_BANK(_reg, _sval); \
+ TZTEST_SET_REG_NONSECURE_BANK(_reg, _nsval);\
+ } while(0)
+
+#define VERIFY_REGISTER_CUSTOM(_reg, _mask, _sval, _nsval) \
+ do { \
+ uint32_t sval = 0, nsval = 0; \
+ uint32_t _reg[2] = {0,0}; \
+ printf("\tChecking %s banks... ", #_reg); \
+ TZTEST_GET_REG_BANKS(_reg, _reg[!SCR_NS], _reg[SCR_NS]); \
+ TZTEST_SET_REG_BANKS(_reg, (_sval), (_nsval)); \
+ TZTEST_GET_REG_SECURE_BANK(_reg, sval); \
+ TZTEST_GET_REG_NONSECURE_BANK(_reg, nsval); \
+ TEST_CONDITION(((sval & (_mask)) != (nsval & (_mask))) && \
+ (((_sval) & (_mask)) == (sval & (_mask))) && \
+ (((_nsval) & (_mask)) == (nsval & (_mask)))); \
+ TZTEST_SET_REG_BANKS(_reg, _reg[!SCR_NS], _reg[SCR_NS]); \
+ } while(0)
+
+#define VERIFY_REGISTER(_reg) \
+ VERIFY_REGISTER_CUSTOM(_reg, 0xFFFFFFFF, TZTEST_SVAL, TZTEST_NSVAL)
+
+extern volatile int *tztest_exception;
+extern volatile int *tztest_exception_addr;
+extern volatile int *tztest_exception_status;
+extern volatile int *tztest_fail_count;
+extern volatile int *tztest_test_count;
+extern void validate_state(uint32_t, uint32_t);
+extern uint32_t _shared_memory_heap_base;
+extern uint32_t *nsec_l1_page_table;
+extern uint32_t *nsec_l2_page_table;
+
+#endif