diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index 6f28721..bec0bcb 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -77,6 +77,13 @@ Flag defining the LLC (L3) cache state. The cache is enabled by default (``LLC_ENABLE=1``). +- LLC_SRAM + + Flag defining the LLC (L3) cache SRAM support. The feature is + disabled by default (``LLC_ENABLE=0``). + When LLC SRAM is enabled, the secure payload (BL32) is loaded into this + SRAM area instead of the DRAM. + - MARVELL_SECURE_BOOT Build trusted(=1)/non trusted(=0) image, default is non trusted. diff --git a/drivers/marvell/cache_llc.c b/drivers/marvell/cache_llc.c index 9b614c4..836aae7 100644 --- a/drivers/marvell/cache_llc.c +++ b/drivers/marvell/cache_llc.c @@ -109,3 +109,41 @@ reg |= (0x1 << CCU_SET_POC_OFFSET); mmio_write_32(CCU_HTC_CR(ap_index), reg); } + +#if LLC_SRAM +void llc_sram_enable(int ap_index) +{ + uint32_t tc, way; + uint32_t way_addr; + + /* Lockdown all available ways for all traffic classes */ + for (tc = 0; tc < LLC_TC_NUM; tc++) + mmio_write_32(LLC_TCN_LOCK(ap_index, tc), LLC_WAY_MASK); + + /* Clear the high bits of SRAM address */ + mmio_write_32(LLC_BANKED_MNT_AHR(ap_index), 0); + + way_addr = PLAT_MARVELL_TRUSTED_RAM_BASE; + for (way = 0; way < LLC_WAYS; way++) { + /* Trigger allocation block command */ + mmio_write_32(LLC_BLK_ALOC(ap_index), + LLC_BLK_ALOC_BASE_ADDR(way_addr) | + LLC_BLK_ALOC_WAY_DATA_CLR | + LLC_BLK_ALOC_WAY_ID(way)); + way_addr += LLC_WAY_SIZE; + } + llc_enable(ap_index, 1); +} + +void llc_sram_disable(int ap_index) +{ + uint32_t tc; + + /* Disable the line lockings */ + for (tc = 0; tc < LLC_TC_NUM; tc++) + mmio_write_32(LLC_TCN_LOCK(ap_index, tc), 0); + + /* Invalidate all ways */ + llc_inv_all(ap_index); +} +#endif /* LLC_SRAM */ diff --git a/include/drivers/marvell/cache_llc.h b/include/drivers/marvell/cache_llc.h index d8eca9f..b326474 100644 --- a/include/drivers/marvell/cache_llc.h +++ b/include/drivers/marvell/cache_llc.h @@ -13,17 +13,18 @@ #define CACHE_LLC_H #define LLC_CTRL(ap) (MVEBU_LLC_BASE(ap) + 0x100) +#define LLC_SECURE_CTRL(ap) (MVEBU_LLC_BASE(ap) + 0x10C) #define LLC_SYNC(ap) (MVEBU_LLC_BASE(ap) + 0x700) #define LLC_BANKED_MNT_AHR(ap) (MVEBU_LLC_BASE(ap) + 0x724) #define LLC_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x77C) #define LLC_BLK_ALOC(ap) (MVEBU_LLC_BASE(ap) + 0x78c) #define LLC_CLEAN_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7BC) #define LLC_CLEAN_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7FC) -#define LLC_TC0_LOCK(ap) (MVEBU_LLC_BASE(ap) + 0x920) +#define LLC_TCN_LOCK(ap, tc) (MVEBU_LLC_BASE(ap) + 0x920 + 4 * (tc)) #define MASTER_LLC_CTRL LLC_CTRL(MVEBU_AP0) #define MASTER_LLC_INV_WAY LLC_INV_WAY(MVEBU_AP0) -#define MASTER_LLC_TC0_LOCK LLC_TC0_LOCK(MVEBU_AP0) +#define MASTER_LLC_TC0_LOCK LLC_TCN_LOCK(MVEBU_AP0, 0) #define LLC_CTRL_EN 1 #define LLC_EXCLUSIVE_EN 0x100 @@ -34,7 +35,13 @@ #define LLC_WAY_MASK ((1 << LLC_WAYS) - 1) #define LLC_SIZE (1024 * 1024) #define LLC_WAY_SIZE (LLC_SIZE / LLC_WAYS) +#define LLC_TC_NUM 15 +#define LLC_BLK_ALOC_WAY_ID(way) ((way) & 0x1f) +#define LLC_BLK_ALOC_WAY_DATA_DSBL (0x0 << 6) +#define LLC_BLK_ALOC_WAY_DATA_CLR (0x1 << 6) +#define LLC_BLK_ALOC_WAY_DATA_SET (0x3 << 6) +#define LLC_BLK_ALOC_BASE_ADDR(addr) ((addr) & (LLC_WAY_SIZE - 1)) #ifndef __ASSEMBLER__ void llc_cache_sync(int ap_index); @@ -45,6 +52,10 @@ void llc_enable(int ap_index, int excl_mode); int llc_is_exclusive(int ap_index); void llc_runtime_enable(int ap_index); -#endif +#if LLC_SRAM +void llc_sram_enable(int ap_index); +void llc_sram_disable(int ap_index); +#endif /* LLC_SRAM */ +#endif /* __ASSEMBLY__ */ #endif /* CACHE_LLC_H */ diff --git a/plat/marvell/armada/common/marvell_common.mk b/plat/marvell/armada/common/marvell_common.mk index f5f0c41..fcc97ac 100644 --- a/plat/marvell/armada/common/marvell_common.mk +++ b/plat/marvell/armada/common/marvell_common.mk @@ -16,8 +16,21 @@ # flag to switch from PLL to ARO ARO_ENABLE := 0 $(eval $(call add_define,ARO_ENABLE)) + +# Convert LLC to secure SRAM +LLC_SRAM := 0 +$(eval $(call add_define,LLC_SRAM)) + # Enable/Disable LLC +ifeq (${LLC_SRAM}, 0) LLC_ENABLE := 1 +else +# When LLC_SRAM=1, the entire LLC converted to SRAM and enabled at BL1. +# All existing cases activating LLC at BL31 stage should be disabled. +# The below assignment does not allow changing the LLC_ENABLE +# value in the command line. +LLC_ENABLE = 0 +endif $(eval $(call add_define,LLC_ENABLE)) include lib/xlat_tables_v2/xlat_tables.mk