From f55ef85ebfd61d708f6c77465edf3f8d059ca93d Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 11 Oct 2019 23:26:39 +0200 Subject: [PATCH] rockchip: px30: cleanup securing of ddr regions So far the px30-related ddr security was loading data for regions to secure from a pre-specified memory location and also setting region0 to secure the first megabyte of memory in hard-coded setting (top=0, end=0, meaning 1MB). To make things more explicit and easier to read add a function doing the settings for specified memory areas, like other socs have and also add an assert to make sure any descriptor read from memory does not overlap the TZRAM security in region0 and TEE security in region1. Signed-off-by: Heiko Stuebner Change-Id: I78441875112bf66a62fde5f1789f4e52a78ef95f --- plat/rockchip/px30/drivers/secure/secure.c | 63 ++++++++++++++++------ plat/rockchip/px30/px30_def.h | 1 + 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/plat/rockchip/px30/drivers/secure/secure.c b/plat/rockchip/px30/drivers/secure/secure.c index 94a6d4295..bb2b02ab7 100644 --- a/plat/rockchip/px30/drivers/secure/secure.c +++ b/plat/rockchip/px30/drivers/secure/secure.c @@ -4,10 +4,49 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include +#include #include #include +/** + * There are 8 regions for DDR security control + * @rgn - the DDR regions 0 ~ 7 which are can be configured. + * @st - start address to set as secure + * @sz - length of area to set as secure + * The internal unit is megabytes, so memory areas need to be aligned + * to megabyte borders. + */ +static void secure_ddr_region(uint32_t rgn, + uintptr_t st, size_t sz) +{ + uintptr_t ed = st + sz; + uintptr_t st_mb, ed_mb; + uint32_t val; + + assert(rgn <= 7); + assert(st < ed); + + /* check aligned 1MB */ + assert(st % SIZE_M(1) == 0); + assert(ed % SIZE_M(1) == 0); + + st_mb = st / SIZE_M(1); + ed_mb = ed / SIZE_M(1); + + /* map top and base */ + mmio_write_32(FIREWALL_DDR_BASE + + FIREWALL_DDR_FW_DDR_RGN(rgn), + RG_MAP_SECURE(ed_mb, st_mb)); + + /* enable secure */ + val = mmio_read_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_CON_REG); + val |= BIT(rgn); + mmio_write_32(FIREWALL_DDR_BASE + + FIREWALL_DDR_FW_DDR_CON_REG, val); +} + void secure_timer_init(void) { mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG, @@ -23,27 +62,21 @@ void secure_timer_init(void) void sgrf_init(void) { - uint32_t i, val; + uint32_t i; struct param_ddr_usage usg; /* general secure regions */ usg = ddr_region_usage_parse(DDR_PARAM_BASE, PLAT_MAX_DDR_CAPACITY_MB); - for (i = 0; i < usg.s_nr; i++) { - /* enable secure */ - val = mmio_read_32(FIREWALL_DDR_BASE + - FIREWALL_DDR_FW_DDR_CON_REG); - val |= BIT(7 - i); - mmio_write_32(FIREWALL_DDR_BASE + - FIREWALL_DDR_FW_DDR_CON_REG, val); - /* map top and base */ - mmio_write_32(FIREWALL_DDR_BASE + - FIREWALL_DDR_FW_DDR_RGN(7 - i), - RG_MAP_SECURE(usg.s_top[i], usg.s_base[i])); - } - /* set ddr rgn0_top and rga0_top as 0 */ - mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_RGN(0), 0x0); + /* region-0 for TF-A, region-1 for optional OP-TEE */ + assert(usg.s_nr < 7); + + for (i = 0; i < usg.s_nr; i++) + secure_ddr_region(7 - i, usg.s_top[i], usg.s_base[i]); + + /* secure the trustzone ram */ + secure_ddr_region(0, TZRAM_BASE, TZRAM_SIZE); /* set all slave ip into no-secure, except stimer */ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(4), SGRF_SLV_S_ALL_NS); diff --git a/plat/rockchip/px30/px30_def.h b/plat/rockchip/px30/px30_def.h index 283b60641..efe789e1e 100644 --- a/plat/rockchip/px30/px30_def.h +++ b/plat/rockchip/px30/px30_def.h @@ -11,6 +11,7 @@ #define MINOR_VERSION (0) #define SIZE_K(n) ((n) * 1024) +#define SIZE_M(n) ((n) * 1024 * 1024) #define WITH_16BITS_WMSK(bits) (0xffff0000 | (bits))