From 799cb2653fb1d2d1a89a10082f707b5ffac521af Mon Sep 17 00:00:00 2001 From: Greg Bellows Date: Wed, 22 Apr 2015 14:47:03 -0500 Subject: Add EL1 floating point tests Signed-off-by: Greg Bellows --- tztest/el1/nonsecure/tztest_el1_nsec.c | 1 + tztest/el1/secure/tztest_el1_sec.c | 3 +- tztest/el1/tztest_el1.c | 108 +++++++++++++++++++++++++++++++++ tztest/el1/tztest_el1.h | 1 + tztest/tztest.c | 4 ++ 5 files changed, 116 insertions(+), 1 deletion(-) 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 }; -- cgit v1.2.3