aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Bellows <greg.bellows@linaro.org>2015-04-23 11:42:24 -0500
committerGreg Bellows <greg.bellows@linaro.org>2015-04-23 11:42:24 -0500
commit1aa3541986bee86f6059e96af16e25529b817054 (patch)
treecf513740d62f85dbf4686f4f92dc95097fec7a3c
parent6204523232f0ee90e413d8243ef670af76c3583d (diff)
Make secure state dynamic for EL3
Update the secure_state global so it can vary on EL3. This involved making it and the secure state message non-const. Updated messages to print the state dynamically. Fixed messages where needed. Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
-rw-r--r--common/debug.h3
-rw-r--r--common/state.h4
-rw-r--r--el0/nonsecure/el0_nsec.c6
-rw-r--r--el0/secure/el0_sec.c6
-rw-r--r--el1/nonsecure/el1_nsec.c4
-rw-r--r--el1/secure/el1_sec.c4
-rw-r--r--el3/el3.c38
-rw-r--r--tztest/el1/tztest_el1.c4
-rw-r--r--tztest/tztest_internal.h4
9 files changed, 41 insertions, 32 deletions
diff --git a/common/debug.h b/common/debug.h
index e391240..c9da3f1 100644
--- a/common/debug.h
+++ b/common/debug.h
@@ -5,7 +5,8 @@
#ifdef DEBUG
#define DEBUG_MSG(_str, ...) \
- printf("\n[DEBUG] %s (%s): " _str, __FUNCTION__, (sec_state_str)?sec_state_str:"MISSING", ##__VA_ARGS__)
+ printf("\n[DEBUG] %s (%s): "\
+ _str, __FUNCTION__, sec_state_str[secure_state], ##__VA_ARGS__)
#define DEBUG_ARG
#else
#define DEBUG_MSG(_str, ...)
diff --git a/common/state.h b/common/state.h
index 2c70471..0f24a4a 100644
--- a/common/state.h
+++ b/common/state.h
@@ -1,8 +1,8 @@
#ifndef _STATE_H
#define _STATE_H
-extern const char *sec_state_str;
-extern const uint32_t secure_state;
+extern char *sec_state_str[];
+extern uint32_t secure_state;
extern const uint32_t exception_level;
#define EL0 0
diff --git a/el0/nonsecure/el0_nsec.c b/el0/nonsecure/el0_nsec.c
index 3ef4c69..d766a2f 100644
--- a/el0/nonsecure/el0_nsec.c
+++ b/el0/nonsecure/el0_nsec.c
@@ -1,8 +1,8 @@
#include "el0_common.h"
#include "tztest.h"
-const char *sec_state_str = "non-secure";
-const uint32_t secure_state = NONSECURE;
+char *sec_state_str[] = {"secure", "nonsecure"};
+uint32_t secure_state = NONSECURE;
const uint32_t exception_level = EL0;
sys_control_t *syscntl = NULL;
@@ -10,7 +10,7 @@ int main()
{
svc_op_desc_t desc;
- printf("EL0 (%s) started...\n", sec_state_str);
+ printf("EL0 (%s) started...\n", sec_state_str[secure_state]);
/* Fetch the system-wide control structure */
__svc(SVC_OP_GET_SYSCNTL, &desc);
diff --git a/el0/secure/el0_sec.c b/el0/secure/el0_sec.c
index 3d0c78f..4b39a7f 100644
--- a/el0/secure/el0_sec.c
+++ b/el0/secure/el0_sec.c
@@ -1,8 +1,8 @@
#include "el0_common.h"
#include "tztest.h"
-const char *sec_state_str = "secure";
-const uint32_t secure_state = SECURE;
+char *sec_state_str[] = {"secure", "nonsecure"};
+uint32_t secure_state = SECURE;
const uint32_t exception_level = EL0;
sys_control_t *syscntl = NULL;
@@ -57,7 +57,7 @@ int main()
{
svc_op_desc_t desc;
- printf("EL0 (%s) started...\n", sec_state_str);
+ printf("EL0 (%s) started...\n", sec_state_str[secure_state]);
/* Fetch the system-wide control structure */
__svc(SVC_OP_GET_SYSCNTL, &desc);
diff --git a/el1/nonsecure/el1_nsec.c b/el1/nonsecure/el1_nsec.c
index 33d40bf..dbbe1f8 100644
--- a/el1/nonsecure/el1_nsec.c
+++ b/el1/nonsecure/el1_nsec.c
@@ -9,8 +9,8 @@ uintptr_t EL1_NS_DATA_BASE = (uintptr_t)&_EL1_NS_DATA_BASE;
uintptr_t EL1_NS_TEXT_SIZE = (uintptr_t)&_EL1_NS_TEXT_SIZE;
uintptr_t EL1_NS_DATA_SIZE = (uintptr_t)&_EL1_NS_DATA_SIZE;
-const char *sec_state_str = "non-secure";
-const uint32_t secure_state = NONSECURE;
+char *sec_state_str[] = {"secure", "nonsecure"};
+uint32_t secure_state = NONSECURE;
const uint32_t exception_level = EL1;
void el1_init_el0()
diff --git a/el1/secure/el1_sec.c b/el1/secure/el1_sec.c
index 7f11670..a2b7763 100644
--- a/el1/secure/el1_sec.c
+++ b/el1/secure/el1_sec.c
@@ -9,8 +9,8 @@ uintptr_t EL1_S_DATA_BASE = (uintptr_t)&_EL1_S_DATA_BASE;
uintptr_t EL1_S_TEXT_SIZE = (uintptr_t)&_EL1_S_TEXT_SIZE;
uintptr_t EL1_S_DATA_SIZE = (uintptr_t)&_EL1_S_DATA_SIZE;
-const char *sec_state_str = "secure";
-const uint32_t secure_state = SECURE;
+char *sec_state_str[] = {"secure", "nonsecure"};
+uint32_t secure_state = SECURE;
const uint32_t exception_level = EL1;
#if REMOVE_OR_INTEGRATE
diff --git a/el3/el3.c b/el3/el3.c
index 325c03c..78e69d1 100644
--- a/el3/el3.c
+++ b/el3/el3.c
@@ -31,9 +31,9 @@ const char *smc_op_name[] = {
};
#endif
-const char *sec_state_str = "EL3";
+char *sec_state_str[] = {"secure", "nonsecure"};
const uint32_t exception_level = EL3;
-const uint32_t secure_state = 0;
+uint32_t secure_state = SECURE;
uintptr_t EL3_TEXT_BASE = (uintptr_t)&_EL3_TEXT_BASE;
uintptr_t EL3_DATA_BASE = (uintptr_t)&_EL3_DATA_BASE;
@@ -86,14 +86,15 @@ int el3_handle_smc(uintptr_t op, smc_op_desc_t *desc,
uintptr_t __attribute((unused))far, uintptr_t elr)
{
op_test_t *test = (op_test_t*)desc;
+ uint32_t ret = 0;
DEBUG_MSG("Took an smc(%s) - desc = %p\n", smc_op_name[op], desc);
switch (op) {
case SMC_OP_YIELD:
- return SVC_OP_YIELD;
+ ret = SVC_OP_YIELD;
break;
case SMC_OP_MAP:
- return el3_map_mem((op_map_mem_t *)desc);
+ ret = el3_map_mem((op_map_mem_t *)desc);
break;
case SMC_OP_NOOP:
break;
@@ -106,7 +107,7 @@ int el3_handle_smc(uintptr_t op, smc_op_desc_t *desc,
run_test(desc->disp.fid, desc->disp.el,
desc->disp.state, desc->disp.arg);
} else {
- return SVC_OP_DISPATCH;
+ ret = SVC_OP_DISPATCH;
}
break;
case SMC_OP_TEST:
@@ -115,7 +116,7 @@ int el3_handle_smc(uintptr_t op, smc_op_desc_t *desc,
}
test->val >>= 1;
test->count++;
- return SVC_OP_TEST;
+ ret = SVC_OP_TEST;
case SMC_OP_GET_REG:
if (desc->get.el == 3) {
switch (desc->get.key) {
@@ -184,8 +185,14 @@ int el3_handle_smc(uintptr_t op, smc_op_desc_t *desc,
break;
}
+ /* EL3 can be secure or nonsecure. Change our global secure state
+ * indicator if we will be switching state.
+ */
+ if (ret) {
+ secure_state ^= 1;
+ }
__set_exception_return(elr);
- return 0;
+ return ret;
}
int el3_handle_exception(uintptr_t ec, uintptr_t iss, uintptr_t far,
@@ -203,23 +210,23 @@ int el3_handle_exception(uintptr_t ec, uintptr_t iss, uintptr_t far,
switch (ec) {
case EC_SMC64:
case EC_SMC32:
- printf("Took an SMC exception from EL3\n");
+ DEBUG_MSG("Took an SMC exception from EL3\n");
break;
case EC_IABORT_LOWER:
- printf("Instruction abort at lower level: far = %0lx\n", far);
+ DEBUG_MSG("Instruction abort at lower level: far = %0lx\n", far);
el3_shutdown();
break;
case EC_IABORT:
- printf("Instruction abort at EL3: far = %0lx\n", far);
+ DEBUG_MSG("Instruction abort at EL3: far = %0lx\n", far);
el3_shutdown();
break;
case EC_DABORT_LOWER:
- printf("Data abort at lower level: far = %0lx elr = %0lx\n",
- far, elr);
+ DEBUG_MSG("Data abort at lower level: far = %0lx elr = %0lx\n",
+ far, elr);
el3_shutdown();
break;
case EC_DABORT:
- printf("Data abort at EL3: far = %0lx elr = %0lx\n", far, elr);
+ DEBUG_MSG("Data abort at EL3: far = %0lx elr = %0lx\n", far, elr);
el3_shutdown();
break;
case EC_SYSINSN:
@@ -255,7 +262,8 @@ int el3_handle_exception(uintptr_t ec, uintptr_t iss, uintptr_t far,
}
break;
default:
- printf("Unhandled EL3 exception: EC = 0x%lx ISS = 0x%lx\n", ec, iss);
+ DEBUG_MSG("Unhandled EL3 exception: EC = 0x%lx ISS = 0x%lx\n",
+ ec, iss);
el3_shutdown();
break;
}
@@ -304,7 +312,7 @@ void el3_start(uintptr_t base, uintptr_t size)
uintptr_t addr = base;
size_t len;
- printf("EL3 started...\n");
+ printf("EL%d started...\n", exception_level);
/* Unmap the init segement so we don't accidentally use it */
for (len = 0; len < ((size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1));
diff --git a/tztest/el1/tztest_el1.c b/tztest/el1/tztest_el1.c
index 5309445..42e096a 100644
--- a/tztest/el1/tztest_el1.c
+++ b/tztest/el1/tztest_el1.c
@@ -95,7 +95,7 @@ uint32_t el1_check_wfx_trap(uint32_t __attribute__((unused))arg)
TEST_MSG("WFE (SCTLR.nTWE clear, SCR.WFE clear)");
TEST_NO_EXCEPTION(asm volatile("wfe\n"));
- /* Trap WFE instructions to EL3. This should work regardless od the
+ /* Trap WFE instructions to EL3. This should work regardless of the
* SCTLR.nTWE setting.
*/
SMC_SET_REG(SCR, 3, scr | SCR_TWE);
@@ -114,7 +114,7 @@ uint32_t el1_check_wfx_trap(uint32_t __attribute__((unused))arg)
* precedence.
*/
- /* Trap WFI instructions to EL3. This should work regardless od the
+ /* Trap WFI instructions to EL3. This should work regardless of the
* SCTLR.nTWE setting.
*/
SMC_SET_REG(SCR, 3, scr | SCR_TWI);
diff --git a/tztest/tztest_internal.h b/tztest/tztest_internal.h
index 0a309ec..d225249 100644
--- a/tztest/tztest_internal.h
+++ b/tztest/tztest_internal.h
@@ -16,11 +16,11 @@ typedef enum {
#define TEST_HEAD(_str, ...) \
printf("\nValidating %s EL%d " _str ":\n", \
- sec_state_str, exception_level, ##__VA_ARGS__)
+ sec_state_str[secure_state], exception_level, ##__VA_ARGS__)
#define TEST_MSG(_str, ...) \
printf("\tEL%d (%s): " _str "... ", \
- exception_level, sec_state_str, ##__VA_ARGS__)
+ exception_level, sec_state_str[secure_state], ##__VA_ARGS__)
#define TEST_MSG_SUCCESS() printf("PASSED\n")
#define TEST_MSG_FAILURE() printf("FAILED\n")