From e9b9c2c830f4f65a121876e00c61f3167501f5b7 Mon Sep 17 00:00:00 2001 From: Anthony Zhou Date: Wed, 4 Dec 2019 14:58:23 +0800 Subject: [PATCH] Tegra: sip: add VPR resize enabled check The Memory Controller provides a control register to check if the video memory can be resized. The previous bootloader might have locked this feature, which will be reflected by this register. This patch reads the control register before processing a video memory resize request. An error code, -ENOTSUP, is returned if the feature is locked. Change-Id: Ia1d67f7a94aa15c6b18ff5c9b9b952e179596ae3 Signed-off-by: Anthony Zhou --- plat/nvidia/tegra/common/tegra_sip_calls.c | 6 ++++++ plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c | 17 ++++++++++++++++- plat/nvidia/tegra/include/t132/tegra_def.h | 2 ++ plat/nvidia/tegra/include/t186/tegra_def.h | 2 ++ plat/nvidia/tegra/include/t194/tegra_def.h | 2 ++ plat/nvidia/tegra/include/t210/tegra_def.h | 2 ++ 6 files changed, 30 insertions(+), 1 deletion(-) diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c index 1d48cc01b..80a2c4d0c 100644 --- a/plat/nvidia/tegra/common/tegra_sip_calls.c +++ b/plat/nvidia/tegra/common/tegra_sip_calls.c @@ -52,6 +52,12 @@ uintptr_t tegra_sip_handler(uint32_t smc_fid, switch (smc_fid) { case TEGRA_SIP_NEW_VIDEOMEM_REGION: + /* Check whether Video memory resize is enabled */ + if (mmio_read_32(TEGRA_MC_BASE + MC_VIDEO_PROTECT_REG_CTRL) + != MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED) { + ERROR("Video Memory Resize isn't enabled! \n"); + SMC_RET1(handle, (uint64_t)-ENOTSUP); + } /* * Check if Video Memory overlaps TZDRAM (contains bl31/bl32) diff --git a/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c index 95bdada11..45c97fcc0 100644 --- a/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/drivers/memctrl/memctrl_v2.c @@ -127,9 +127,16 @@ void tegra_memctrl_restore_settings(void) if (video_mem_base != 0ULL) { tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)video_mem_base); + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_LO) + == (uint32_t)video_mem_base); tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(video_mem_base >> 32)); - tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb); + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_HI) + == (uint32_t)(video_mem_base >> 32)); + tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, + (uint32_t)video_mem_size_mb); + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_SIZE_MB) + == (uint32_t)video_mem_size_mb); /* * MCE propagates the VideoMem configuration values across the @@ -367,6 +374,14 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) (uint32_t)(phys_base >> 32)); tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20); + /* Redundancy check for Video Protect setting */ + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_LO) + == (uint32_t)phys_base); + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_BASE_HI) + == (uint32_t)(phys_base >> 32)); + assert(tegra_mc_read_32(MC_VIDEO_PROTECT_SIZE_MB) + == (size_in_bytes >> 20)); + /* * MCE propagates the VideoMem configuration values across the * CCPLEX. diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h index 8e6c1fd2b..afdcd3691 100644 --- a/plat/nvidia/tegra/include/t132/tegra_def.h +++ b/plat/nvidia/tegra/include/t132/tegra_def.h @@ -104,6 +104,8 @@ #define MC_VIDEO_PROTECT_BASE_HI U(0x978) #define MC_VIDEO_PROTECT_BASE_LO U(0x648) #define MC_VIDEO_PROTECT_SIZE_MB U(0x64c) +#define MC_VIDEO_PROTECT_REG_CTRL U(0x650) +#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3) /******************************************************************************* * Tegra TZRAM constants diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 1da9b4639..33b21021b 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -163,6 +163,8 @@ #define MC_VIDEO_PROTECT_BASE_HI U(0x978) #define MC_VIDEO_PROTECT_BASE_LO U(0x648) #define MC_VIDEO_PROTECT_SIZE_MB U(0x64C) +#define MC_VIDEO_PROTECT_REG_CTRL U(0x650) +#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3) /* * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index 6f44da619..2d8b88c93 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -105,6 +105,8 @@ #define MC_VIDEO_PROTECT_BASE_HI U(0x978) #define MC_VIDEO_PROTECT_BASE_LO U(0x648) #define MC_VIDEO_PROTECT_SIZE_MB U(0x64c) +#define MC_VIDEO_PROTECT_REG_CTRL U(0x650) +#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3) /* * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index f3013a8a5..32fcb4bd8 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -240,6 +240,8 @@ #define MC_VIDEO_PROTECT_BASE_HI U(0x978) #define MC_VIDEO_PROTECT_BASE_LO U(0x648) #define MC_VIDEO_PROTECT_SIZE_MB U(0x64c) +#define MC_VIDEO_PROTECT_REG_CTRL U(0x650) +#define MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED U(3) /* SMMU configuration registers*/ #define MC_SMMU_PPCS_ASID_0 0x270U