diff options
author | nagendra modadugu <ngm@google.com> | 2015-10-30 18:49:00 -0700 |
---|---|---|
committer | Nagendra Modadugu <ngm@google.com> | 2015-11-03 18:50:48 +0000 |
commit | 058687e0ccb9e32bafdc97e1723ee717abb1b6b0 (patch) | |
tree | 3f2a1b0919d77dbcc0cec9995027ca4fc24e963c | |
parent | 792d00184ab5f50af52b64e9c60cd01bc1b01fc7 (diff) | |
download | chrome-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.c | 35 |
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); |