diff options
author | Cedric Neveux <cedric.neveux@nxp.com> | 2017-11-14 09:05:09 +0000 |
---|---|---|
committer | Silvano di Ninno <silvano.dininno@nxp.com> | 2018-08-02 15:37:23 +0200 |
commit | ffd5df34288a32e3c2fd6a39ee3fab691820d8cc (patch) | |
tree | 9a58a2355a2fd17eeea37e6117ddee47045db5ce /core | |
parent | b091867c9b658943e6ef74dd481706c9616987e7 (diff) |
TEE-243-4 Add OCRAM as service init
- Add a OCRAM initialization as a service init
- Function is called automatically at boot and no need
to call it at suspend time
Signed-off-by: Cedric Neveux <cedric.neveux@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Diffstat (limited to 'core')
-rw-r--r-- | core/arch/arm/plat-imx/conf.mk | 1 | ||||
-rw-r--r-- | core/arch/arm/plat-imx/imx_ocram.c | 132 | ||||
-rw-r--r-- | core/arch/arm/plat-imx/imx_pm.h | 5 | ||||
-rw-r--r-- | core/arch/arm/plat-imx/pm/pm-imx7.c | 56 | ||||
-rw-r--r-- | core/arch/arm/plat-imx/sub.mk | 1 |
5 files changed, 139 insertions, 56 deletions
diff --git a/core/arch/arm/plat-imx/conf.mk b/core/arch/arm/plat-imx/conf.mk index 65820cd0..47361320 100644 --- a/core/arch/arm/plat-imx/conf.mk +++ b/core/arch/arm/plat-imx/conf.mk @@ -361,5 +361,6 @@ endif ifeq ($(filter y, $(CFG_PSCI_ARM32)), y) CFG_HWSUPP_MEM_PERM_WXN = n CFG_IMX_WDOG ?= y +$(call force,CFG_IMX_OCRAM,y) endif diff --git a/core/arch/arm/plat-imx/imx_ocram.c b/core/arch/arm/plat-imx/imx_ocram.c new file mode 100644 index 00000000..1c07bae6 --- /dev/null +++ b/core/arch/arm/plat-imx/imx_ocram.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Copyright 2017 NXP + * + */ + +#include <kernel/panic.h> +#include <initcall.h> +#include <trace.h> +#include <mm/core_memprot.h> +#include <string.h> +#include <io.h> + +#include <imx.h> +#include <imx_pm.h> + +paddr_t iram_tlb_phys_addr = -1UL; + +#ifdef CFG_MX7 +static const paddr_t phys_addr_imx7[] = { + AIPS1_BASE, AIPS2_BASE, AIPS3_BASE, 0 +}; +#endif + +#if defined(CFG_MX7) +static void init_tz_ocram(void) +{ + /* Configure the Secure OCRAM granularity */ + vaddr_t iomux_base; + uint32_t val; + uint32_t lock; + + iomux_base = (vaddr_t)phys_to_virt(IOMUXC_GPR_BASE, MEM_AREA_IO_SEC); + + val = read32(iomux_base + IOMUX_GPRx_OFFSET(IOMUX_GPR_OCRAM_ID)); + + /* Configure the OCRAM Retention to start at offset 0 */ + val &= ~BM_IOMUX_GPR_OCRAM_S_TZ_ADDR; + val |= IOMUX_GPR_OCRAM_S_TZ_ENABLE; + + lock = BM_IOMUX_GPR_OCRAM_S_TZ_ADDR | IOMUX_GPR_OCRAM_S_TZ_ENABLE; + + write32(val, (iomux_base + IOMUX_GPRx_OFFSET(IOMUX_GPR_OCRAM_ID))); + + /* Then lock configuration */ + write32(IOMUX_GPR_OCRAM_LOCK(lock) | val, + (iomux_base + IOMUX_GPRx_OFFSET(IOMUX_GPR_OCRAM_ID))); +} + +static TEE_Result init_ocram(void) +{ + struct tee_mmap_region map; + const paddr_t *phys_addr; + size_t size_area; + void *iram_tlb_vaddr; + + DMSG("IRAM TLB phys addr = 0x%X", (uint32_t)iram_tlb_phys_addr); + + /* iram tlb already initialized */ + if (iram_tlb_phys_addr != (-1UL)) { + return TEE_SUCCESS; + } + + /* Initialize the Secure OCRAM */ + init_tz_ocram(); + +#ifdef CFG_MX7 + iram_tlb_phys_addr = TRUSTZONE_OCRAM_START + IRAM_TBL_OFFSET; + phys_addr = phys_addr_imx7; + size_area = AIPS1_SIZE; /* 4M for AIPS1/2/3 */ +#endif + + iram_tlb_vaddr = phys_to_virt(iram_tlb_phys_addr, + MEM_AREA_TEE_COHERENT); + + /* 16KB */ + DMSG("%x %x\n", (uint32_t)iram_tlb_phys_addr, + (uint32_t)iram_tlb_vaddr); + memset(iram_tlb_vaddr, 0, 16 * 1024); + + do { + map.pa = *phys_addr; + map.va = (vaddr_t)phys_to_virt(map.pa, MEM_AREA_IO_SEC); + map.region_size = CORE_MMU_DEVICE_SIZE; + map.size = size_area; + map.type = MEM_AREA_IO_SEC; + map.attr = TEE_MATTR_VALID_BLOCK | TEE_MATTR_PRW | + TEE_MATTR_GLOBAL | TEE_MATTR_SECURE | + (TEE_MATTR_CACHE_NONCACHE << + TEE_MATTR_CACHE_SHIFT); + map_memarea_sections(&map, (uint32_t *)iram_tlb_vaddr); + } while (*(++phys_addr)); + +#ifdef CFG_MX7 + /* Note IRAM_S_BASE is not 1M aligned, so take care */ + map.pa = ROUNDDOWN(IRAM_S_BASE, CORE_MMU_DEVICE_SIZE); + map.va = (vaddr_t)phys_to_virt(map.pa, MEM_AREA_TEE_COHERENT); + map.region_size = CORE_MMU_DEVICE_SIZE; + map.size = CORE_MMU_DEVICE_SIZE; + map.type = MEM_AREA_TEE_COHERENT; + map.attr = TEE_MATTR_VALID_BLOCK | TEE_MATTR_PRW | TEE_MATTR_GLOBAL | + TEE_MATTR_SECURE | TEE_MATTR_PX; + map_memarea_sections(&map, (uint32_t *)iram_tlb_vaddr); + + map.pa = GIC_BASE; + map.va = (vaddr_t)phys_to_virt((paddr_t)GIC_BASE, MEM_AREA_IO_SEC); + map.region_size = CORE_MMU_DEVICE_SIZE; + map.size = CORE_MMU_DEVICE_SIZE; + map.type = MEM_AREA_TEE_COHERENT; + map.attr = TEE_MATTR_VALID_BLOCK | TEE_MATTR_PRW | TEE_MATTR_GLOBAL | + TEE_MATTR_SECURE | TEE_MATTR_PX; + map_memarea_sections(&map, (uint32_t *)iram_tlb_vaddr); + + + /* + * Note: DRAM space is not mapped, DRAM is in auto-selfrefresh, + * If map DRAM in to MMU, mmu will access DRAM which + * hang system. + */ +#endif + + return TEE_SUCCESS; +} +#else +static TEE_Result init_ocram(void) +{ + + return TEE_SUCCESS; +} +#endif + +service_init(init_ocram); diff --git a/core/arch/arm/plat-imx/imx_pm.h b/core/arch/arm/plat-imx/imx_pm.h index 2cdd260f..7e922510 100644 --- a/core/arch/arm/plat-imx/imx_pm.h +++ b/core/arch/arm/plat-imx/imx_pm.h @@ -17,6 +17,11 @@ #define SUSPEND_OCRAM_OFFSET 0x0 #define LOWPOWER_IDLE_OCRAM_OFFSET 0x1000 +/* + * Except i.MX6SX only 16KB ocram_s available, others use 16KB offset. + */ +#define IRAM_TBL_OFFSET 0x4000 + #ifndef ASM #include <sm/sm.h> diff --git a/core/arch/arm/plat-imx/pm/pm-imx7.c b/core/arch/arm/plat-imx/pm/pm-imx7.c index 3a96cd89..858551d9 100644 --- a/core/arch/arm/plat-imx/pm/pm-imx7.c +++ b/core/arch/arm/plat-imx/pm/pm-imx7.c @@ -14,9 +14,6 @@ #include <mmdc.h> #include <string.h> -paddr_t iram_tlb_phys_addr = -1UL; -void *iram_tlb_virt_addr; - #define READ_DATA_FROM_HARDWARE 0 static uint32_t imx7d_ddrc_lpddr3_setting[][2] = { @@ -143,58 +140,6 @@ static struct imx7_pm_data imx7d_pm_data_ddr3 = { .ddrc_phy_offset = imx7d_ddrc_phy_ddr3_setting, }; -paddr_t phys_addr[] = { - AIPS1_BASE, AIPS2_BASE, AIPS3_BASE -}; - -static int pm_imx7_iram_tlb_init(void) -{ - uint32_t i; - struct tee_mmap_region map; - - /* iram mmu translation table already initialized */ - if (iram_tlb_phys_addr != (-1UL)) - return 0; - - iram_tlb_phys_addr = TRUSTZONE_OCRAM_START + 16 * 1024; - iram_tlb_virt_addr = phys_to_virt(iram_tlb_phys_addr, - MEM_AREA_TEE_COHERENT); - - /* 16KB */ - memset(iram_tlb_virt_addr, 0, 16 * 1024); - - for (i = 0; i < ARRAY_SIZE(phys_addr); i++) { - map.pa = phys_addr[i]; - map.va = (vaddr_t)phys_to_virt(phys_addr[i], MEM_AREA_IO_SEC); - map.region_size = CORE_MMU_PGDIR_SIZE; - map.size = AIPS1_SIZE; /* 4M for AIPS1/2/3 */ - map.type = MEM_AREA_IO_SEC; - map.attr = TEE_MATTR_VALID_BLOCK | TEE_MATTR_PRW | - TEE_MATTR_SECURE | - (TEE_MATTR_CACHE_NONCACHE << TEE_MATTR_CACHE_SHIFT); - map_memarea_sections(&map, (uint32_t *)iram_tlb_virt_addr); - } - - /* Note IRAM_S_BASE is not 1M aligned, so take care */ - map.pa = ROUNDDOWN(IRAM_S_BASE, CORE_MMU_PGDIR_SIZE); - map.va = (vaddr_t)phys_to_virt(map.pa, MEM_AREA_TEE_COHERENT); - map.region_size = CORE_MMU_PGDIR_SIZE; - map.size = CORE_MMU_DEVICE_SIZE; - map.type = MEM_AREA_TEE_COHERENT; - map.attr = TEE_MATTR_VALID_BLOCK | TEE_MATTR_PRWX | TEE_MATTR_SECURE; - map_memarea_sections(&map, (uint32_t *)iram_tlb_virt_addr); - - map.pa = GIC_BASE; - map.va = (vaddr_t)phys_to_virt((paddr_t)GIC_BASE, MEM_AREA_IO_SEC); - map.region_size = CORE_MMU_PGDIR_SIZE; - map.size = CORE_MMU_DEVICE_SIZE; - map.type = MEM_AREA_TEE_COHERENT; - map.attr = TEE_MATTR_VALID_BLOCK | TEE_MATTR_PRW | TEE_MATTR_SECURE; - map_memarea_sections(&map, (uint32_t *)iram_tlb_virt_addr); - - return 0; -} - struct imx7_pm_info *pm_info; int imx7_suspend_init(void) @@ -208,7 +153,6 @@ int imx7_suspend_init(void) struct imx7_pm_info *p = (struct imx7_pm_info *)suspend_ocram_base; struct imx7_pm_data *pm_data; - pm_imx7_iram_tlb_init(); pm_info = p; dcache_op_level1(DCACHE_OP_CLEAN_INV); diff --git a/core/arch/arm/plat-imx/sub.mk b/core/arch/arm/plat-imx/sub.mk index edacb297..1be0685b 100644 --- a/core/arch/arm/plat-imx/sub.mk +++ b/core/arch/arm/plat-imx/sub.mk @@ -25,3 +25,4 @@ subdirs-$(CFG_PSCI_ARM32) += pm srcs-$(CFG_TZC380) += tzasc.c srcs-$(CFG_CSU) += imx_csu.c srcs-$(CFG_SCU) += imx_scu.c +srcs-$(CFG_IMX_OCRAM) += imx_ocram.c
\ No newline at end of file |