summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagendra modadugu <ngm@google.com>2015-10-30 18:49:00 -0700
committerNagendra Modadugu <ngm@google.com>2015-11-03 18:50:48 +0000
commit058687e0ccb9e32bafdc97e1723ee717abb1b6b0 (patch)
tree3f2a1b0919d77dbcc0cec9995027ca4fc24e963c
parent792d00184ab5f50af52b64e9c60cd01bc1b01fc7 (diff)
downloadchrome-ec-058687e0ccb9e32bafdc97e1723ee717abb1b6b0.tar.gz
Drop permissions to MEDIUM (APP level).
Drop permissions as soon as initialization is complete. APP code is expected to run at MEDIUM permission level. BRANCH=none BUG=chrome-os-partner:43025 TEST=serial shell starts up Change-Id: I181d55ca96eb5998ad49856af9f82afb67b03024 Signed-off-by: nagendra modadugu <ngm@google.com> Reviewed-on: https://chromium-review.googlesource.com/309919 Reviewed-by: Vadim Bendebury <vbendeb@google.com> Reviewed-by: Bill Richardson <wfrichar@chromium.org> Tested-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--board/cr50/board.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 8dee558cca..fa03e429ba 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -77,11 +77,46 @@ static void init_interrutps(void)
gpio_enable_interrupt(gpio_signals[i]);
}
+enum permission_level {
+ PERMISSION_LOW = 0x00,
+ PERMISSION_MEDIUM = 0x33, /* APPS run at medium */
+ PERMISSION_HIGH = 0x3C,
+ PERMISSION_HIGHEST = 0x55
+};
+
+/* Drop run level to at least medium. */
+static void init_runlevel(const enum permission_level desired_level)
+{
+ volatile uint32_t *const reg_addrs[] = {
+ GREG32_ADDR(GLOBALSEC, CPU0_S_PERMISSION),
+ GREG32_ADDR(GLOBALSEC, CPU0_S_DAP_PERMISSION),
+ GREG32_ADDR(GLOBALSEC, DDMA0_PERMISSION),
+ };
+ int i;
+
+ /* Permission registers drop by 1 level (e.g. HIGHEST -> HIGH)
+ * each time a write is encountered (the value written does
+ * not matter). So we repeat writes and reads, until the
+ * desired level is reached.
+ */
+ for (i = 0; i < ARRAY_SIZE(reg_addrs); i++) {
+ uint32_t current_level;
+
+ while (1) {
+ current_level = *reg_addrs[i];
+ if (current_level <= desired_level)
+ break;
+ *reg_addrs[i] = desired_level;
+ }
+ }
+}
+
/* Initialize board. */
static void board_init(void)
{
init_interrutps();
init_trng();
+ init_runlevel(PERMISSION_MEDIUM);
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);