aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Bellows <greg.bellows@linaro.org>2015-04-22 14:47:03 -0500
committerGreg Bellows <greg.bellows@linaro.org>2015-04-22 14:47:03 -0500
commit799cb2653fb1d2d1a89a10082f707b5ffac521af (patch)
treecb3cb054ee4c25ae17d595b473d3e74a1a8cac57
parentf93a8c7aca28050ed19f4ed7bcd6ce4d3696a777 (diff)
Add EL1 floating point tests
Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
-rw-r--r--tztest/el1/nonsecure/tztest_el1_nsec.c1
-rw-r--r--tztest/el1/secure/tztest_el1_sec.c3
-rw-r--r--tztest/el1/tztest_el1.c108
-rw-r--r--tztest/el1/tztest_el1.h1
-rw-r--r--tztest/tztest.c4
5 files changed, 116 insertions, 1 deletions
diff --git a/tztest/el1/nonsecure/tztest_el1_nsec.c b/tztest/el1/nonsecure/tztest_el1_nsec.c
index d8cc1cd..a6188e8 100644
--- a/tztest/el1/nonsecure/tztest_el1_nsec.c
+++ b/tztest/el1/nonsecure/tztest_el1_nsec.c
@@ -127,6 +127,7 @@ tztest_t test_func[] = {
#ifdef AARCH64
[TZTEST_CPACR_TRAP] = el1_check_cpacr_trap,
[TZTEST_WFX_TRAP] = el1_check_wfx_trap,
+ [TZTEST_FP_TRAP] = el1_check_fp_trap,
#endif
#ifdef AARCH32
[TZTEST_MASK_BITS] = check_mask_bits,
diff --git a/tztest/el1/secure/tztest_el1_sec.c b/tztest/el1/secure/tztest_el1_sec.c
index 2923b1a..47fa525 100644
--- a/tztest/el1/secure/tztest_el1_sec.c
+++ b/tztest/el1/secure/tztest_el1_sec.c
@@ -74,7 +74,8 @@ tztest_t test_func[] = {
[TZTEST_REG_ACCESS] = el1_check_register_access,
#ifdef AARCH64
[TZTEST_CPACR_TRAP] = el1_check_cpacr_trap,
- [TZTEST_WFX_TRAP] = el1_check_wfx_trap
+ [TZTEST_WFX_TRAP] = el1_check_wfx_trap,
+ [TZTEST_FP_TRAP] = el1_check_fp_trap,
#endif
};
diff --git a/tztest/el1/tztest_el1.c b/tztest/el1/tztest_el1.c
index 58e1228..0a9ee49 100644
--- a/tztest/el1/tztest_el1.c
+++ b/tztest/el1/tztest_el1.c
@@ -134,5 +134,113 @@ uint32_t el1_check_wfx_trap(uint32_t __attribute__((unused))arg)
return 0;
}
+
+uint32_t el1_check_fp_trap(uint32_t __attribute__((unused))arg)
+{
+#ifdef DEBUG
+ /* This test cannot be run easily when debug is enabled as messing with the
+ * floating-point enable disables printing. It is easier to disable
+ * debugging than change the debugging to support floating-point enable, so
+ * the test is disabled.
+ */
+ TEST_HEAD("FP trapping test disabled during debug");
+#else
+
+ /* Disabling floating-point also disables printing and causes hangs if you
+ * try to print. For this reason not all standard test macros can be used
+ * so instead checking and printing status is pulled out so printing can be
+ * reenabled ahead of time.
+ */
+ uint64_t cptr_el3, cpacr;
+
+ TEST_HEAD("FP trapping");
+
+ /* Get the current CPTR so we can restore it later */
+ SMC_GET_REG(CPTR_EL3, 3, cptr_el3);
+ cpacr = READ_CPACR();
+
+ /* First check that enabled FP does not give us an exception */
+ TEST_MSG("FP enabled (CPACR.FPEN = 3, CPTR_EL3 = 0)");
+ WRITE_CPACR(cpacr | CPACR_FPEN(3));
+ SMC_SET_REG(CPTR_EL3, 3, cptr_el3 & ~CPTR_TFP);
+ TEST_NO_EXCEPTION(asm volatile("fcmp s0, #0.0\n"));
+
+ /* Disable CPACR FP access */
+ TEST_MSG("FP disabled (CPACR.FPEN = 0, CPTR_EL3 = 0)");
+ WRITE_CPACR(cpacr & ~(CPACR_FPEN(3)));
+ TEST_ENABLE_EXCP_LOG();
+ asm volatile("fcmp s0, #0.0\n");
+ WRITE_CPACR(cpacr); /* Reenable printing */
+ if (syscntl->excp.taken && syscntl->excp.el == 1 &&
+ syscntl->excp.ec == EC_SIMD) {
+ TEST_MSG_SUCCESS();
+ } else {
+ TEST_MSG_FAILURE();
+ INC_FAIL_COUNT();
+ }
+ INC_TEST_COUNT();
+ TEST_EXCP_RESET();
+
+ TEST_MSG("FP disabled (CPACR.FPEN = 1, CPTR_EL3 = 0)");
+ WRITE_CPACR(cpacr & ~(CPACR_FPEN(2)));
+ /* No exception in EL1 if FPEN = 1 */
+ TEST_NO_EXCEPTION(asm volatile("fcmp s0, #0.0\n"));
+
+ TEST_MSG("FP disabled (CPACR.FPEN = 2, CPTR_EL3 = 0)");
+ WRITE_CPACR(cpacr & ~(CPACR_FPEN(1)));
+ TEST_ENABLE_EXCP_LOG();
+ asm volatile("fcmp s0, #0.0\n");
+ WRITE_CPACR(cpacr); /* Reenable printing */
+ if (syscntl->excp.taken && syscntl->excp.el == 1 &&
+ syscntl->excp.ec == EC_SIMD) {
+ TEST_MSG_SUCCESS();
+ } else {
+ TEST_MSG_FAILURE();
+ INC_FAIL_COUNT();
+ }
+ INC_TEST_COUNT();
+ TEST_EXCP_RESET();
+
+ TEST_MSG("FP disabled (CPACR.FPEN = 0, CPTR_EL3 = 1)");
+ WRITE_CPACR(cpacr & ~(CPACR_FPEN(3)));
+ SMC_SET_REG(CPTR_EL3, 3, cptr_el3 | CPTR_TFP);
+ TEST_ENABLE_EXCP_LOG();
+ asm volatile("fcmp s0, #0.0\n");
+ WRITE_CPACR(cpacr); /* Reenable printing */
+ SMC_SET_REG(CPTR_EL3, 3, cptr_el3); /* Reenable printing */
+ if (syscntl->excp.taken && syscntl->excp.el == 1 &&
+ syscntl->excp.ec == EC_SIMD) {
+ TEST_MSG_SUCCESS();
+ } else {
+ TEST_MSG_FAILURE();
+ INC_FAIL_COUNT();
+ }
+ INC_TEST_COUNT();
+ TEST_EXCP_RESET();
+
+ TEST_MSG("FP disabled (CPACR.FPEN = 3, CPTR_EL3 = 1)");
+ SMC_SET_REG(CPTR_EL3, 3, cptr_el3 | CPTR_TFP);
+ TEST_ENABLE_EXCP_LOG();
+ asm volatile("fcmp s0, #0.0\n");
+ SMC_SET_REG(CPTR_EL3, 3, cptr_el3); /* Reenable printing */
+ if (syscntl->excp.taken && syscntl->excp.el == 3 &&
+ syscntl->excp.ec == EC_SIMD) {
+ TEST_MSG_SUCCESS();
+ } else {
+ TEST_MSG_FAILURE();
+ INC_FAIL_COUNT();
+ }
+ INC_TEST_COUNT();
+ TEST_EXCP_RESET();
+
+ /* Restore the original CPACR*/
+ WRITE_CPACR(cpacr);
+
+ /* Restore the original CPTR */
+ SMC_SET_REG(CPTR_EL3, 3, cptr_el3);
+#endif
+
+ return 0;
+}
#endif
diff --git a/tztest/el1/tztest_el1.h b/tztest/el1/tztest_el1.h
index 429588d..09d2a35 100644
--- a/tztest/el1/tztest_el1.h
+++ b/tztest/el1/tztest_el1.h
@@ -4,6 +4,7 @@
uint32_t el1_check_smc(uint32_t);
uint32_t el1_check_cpacr_trap(uint32_t);
uint32_t el1_check_wfx_trap(uint32_t);
+uint32_t el1_check_fp_trap(uint32_t);
uint32_t el1_check_register_access(uint32_t);
#endif
diff --git a/tztest/tztest.c b/tztest/tztest.c
index b807763..405837c 100644
--- a/tztest/tztest.c
+++ b/tztest/tztest.c
@@ -25,10 +25,12 @@ tztest_case_t tztest[] = {
TEST(TZTEST_FP_TRAP, EL0, NONSECURE, 0),
TEST(TZTEST_FP_TRAP, EL0, SECURE, 0),
#endif
+
TEST(TZTEST_SMC, EL1, NONSECURE, 0),
TEST(TZTEST_SMC, EL1, SECURE, 0),
TEST(TZTEST_REG_ACCESS, EL1, NONSECURE, 0),
TEST(TZTEST_REG_ACCESS, EL1, SECURE, 0),
+
#ifdef AARCH32
TEST(TZTEST_MASK_BITS, EL1, NONSECURE, 0),
TEST(TZTEST_SMC, EL3, SECURE, 0),
@@ -38,6 +40,8 @@ tztest_case_t tztest[] = {
TEST(TZTEST_CPACR_TRAP, EL1, SECURE, 0),
TEST(TZTEST_WFX_TRAP, EL1, NONSECURE, 0),
TEST(TZTEST_WFX_TRAP, EL1, SECURE, 0),
+ TEST(TZTEST_FP_TRAP, EL1, NONSECURE, 0),
+ TEST(TZTEST_FP_TRAP, EL1, SECURE, 0),
#endif
TEST_END
};