Files
OpenCellular/chip/g/runlevel.c
Mary Ruthven f16d6e43d3 g: add permission level checks
The jittery clock and trng security features require high permissions to
be initialized. In the future these initializations and the permission
level drop may be moved to RO.

This change adds permission level checks before trying to access any
registers that require high permission, so when we update RO to change
the permission RW can still function fine.

BUG=chrome-os-partner:59107
BRANCH=none
TEST=Move the permission drop to the beginning of main and verify the
system still boots.

Change-Id: I5b7cb856decd0640288ad3476f875ec9edc42635
Signed-off-by: Mary Ruthven <mruthven@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/405840
2016-11-04 18:31:44 -07:00

50 lines
1.4 KiB
C

/* Copyright 2016 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "init_chip.h"
#include "registers.h"
/* Drop run level to at least medium. */
void init_runlevel(const enum permission_level desired_level)
{
volatile uint32_t *const reg_addrs[] = {
/* CPU's use of the system peripheral bus */
GREG32_ADDR(GLOBALSEC, CPU0_S_PERMISSION),
/* CPU's use of the system bus via the debug access port */
GREG32_ADDR(GLOBALSEC, CPU0_S_DAP_PERMISSION),
/* DMA's use of the system peripheral bus */
GREG32_ADDR(GLOBALSEC, DDMA0_PERMISSION),
/*
* Current software level affects which (if any) scratch
* registers can be used for a warm boot hardware-verified
* jump.
*/
GREG32_ADDR(GLOBALSEC, SOFTWARE_LVL),
};
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;
}
}
}
int runlevel_is_high(void)
{
return ((GREAD(GLOBALSEC, CPU0_S_PERMISSION) == PERMISSION_HIGH) ||
(GREAD(GLOBALSEC, CPU0_S_PERMISSION) == PERMISSION_HIGHEST));
}