Merge pull request #319 from vwadekar/tegra-video-mem-aperture-v3
Reserve a Video Memory aperture in DRAM memory
This commit is contained in:
commit
09aa0392b3
|
@ -28,11 +28,23 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <mmio.h>
|
||||
#include <memctrl.h>
|
||||
#include <string.h>
|
||||
#include <tegra_def.h>
|
||||
#include <xlat_tables.h>
|
||||
|
||||
extern void zeromem16(void *mem, unsigned int length);
|
||||
|
||||
#define TEGRA_GPU_RESET_REG_OFFSET 0x28c
|
||||
#define GPU_RESET_BIT (1 << 24)
|
||||
|
||||
/* Video Memory base and size (live values) */
|
||||
static uintptr_t video_mem_base;
|
||||
static uint64_t video_mem_size;
|
||||
|
||||
/*
|
||||
* Init SMMU.
|
||||
|
@ -71,6 +83,10 @@ void tegra_memctrl_setup(void)
|
|||
tegra_mc_write_32(MC_SMMU_CONFIG_0,
|
||||
MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE);
|
||||
(void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */
|
||||
|
||||
/* video memory carveout */
|
||||
tegra_mc_write_32(MC_VIDEO_PROTECT_BASE, video_mem_base);
|
||||
tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -90,3 +106,66 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
|
|||
tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base);
|
||||
tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
|
||||
}
|
||||
|
||||
/*
|
||||
* Program the Video Memory carveout region
|
||||
*
|
||||
* phys_base = physical base of aperture
|
||||
* size_in_bytes = size of aperture in bytes
|
||||
*/
|
||||
void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
|
||||
{
|
||||
uintptr_t vmem_end_old = video_mem_base + (video_mem_size << 20);
|
||||
uintptr_t vmem_end_new = phys_base + size_in_bytes;
|
||||
uint32_t regval;
|
||||
|
||||
/*
|
||||
* The GPU is the user of the Video Memory region. In order to
|
||||
* transition to the new memory region smoothly, we program the
|
||||
* new base/size ONLY if the GPU is in reset mode.
|
||||
*/
|
||||
regval = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET);
|
||||
if ((regval & GPU_RESET_BIT) == 0) {
|
||||
ERROR("GPU not in reset! Video Memory setup failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the Memory controller to restrict CPU accesses to the Video
|
||||
* Memory region
|
||||
*/
|
||||
INFO("Configuring Video Memory Carveout\n");
|
||||
|
||||
/*
|
||||
* Configure Memory Controller directly for the first time.
|
||||
*/
|
||||
if (video_mem_base == 0)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Clear the old regions now being exposed. The following cases
|
||||
* can occur -
|
||||
*
|
||||
* 1. clear whole old region (no overlap with new region)
|
||||
* 2. clear old sub-region below new base
|
||||
* 3. clear old sub-region above new end
|
||||
*/
|
||||
INFO("Cleaning previous Video Memory Carveout\n");
|
||||
|
||||
disable_mmu_el3();
|
||||
if (phys_base > vmem_end_old || video_mem_base > vmem_end_new)
|
||||
zeromem16((void *)video_mem_base, video_mem_size << 20);
|
||||
else if (video_mem_base < phys_base)
|
||||
zeromem16((void *)video_mem_base, phys_base - video_mem_base);
|
||||
else if (vmem_end_old > vmem_end_new)
|
||||
zeromem16((void *)vmem_end_new, vmem_end_old - vmem_end_new);
|
||||
enable_mmu_el3(0);
|
||||
|
||||
done:
|
||||
tegra_mc_write_32(MC_VIDEO_PROTECT_BASE, phys_base);
|
||||
tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20);
|
||||
|
||||
/* store new values */
|
||||
video_mem_base = phys_base;
|
||||
video_mem_size = size_in_bytes >> 20;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <cortex_a57.h>
|
||||
#include <cortex_a53.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <memctrl.h>
|
||||
#include <mmio.h>
|
||||
#include <platform.h>
|
||||
|
@ -230,3 +231,32 @@ void bl31_plat_arch_setup(void)
|
|||
/* enable the MMU */
|
||||
enable_mmu_el3(0);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Check if the given NS DRAM range is valid
|
||||
******************************************************************************/
|
||||
int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
|
||||
{
|
||||
uint64_t end = base + size_in_bytes - 1;
|
||||
|
||||
/*
|
||||
* Check if the NS DRAM address is valid
|
||||
*/
|
||||
if ((base < TEGRA_DRAM_BASE) || (end > TEGRA_DRAM_END) ||
|
||||
(base >= end)) {
|
||||
ERROR("NS address is out-of-bounds!\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/*
|
||||
* TZDRAM aperture contains the BL31 and BL32 images, so we need
|
||||
* to check if the NS DRAM range overlaps the TZDRAM aperture.
|
||||
*/
|
||||
if ((base < TZDRAM_END) && (end > tegra_bl31_phys_base)) {
|
||||
ERROR("NS address overlaps TZDRAM!\n");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* valid NS address */
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -59,4 +59,5 @@ BL31_SOURCES += drivers/arm/gic/arm_gic.c \
|
|||
${COMMON_DIR}/tegra_bl31_setup.c \
|
||||
${COMMON_DIR}/tegra_gic.c \
|
||||
${COMMON_DIR}/tegra_pm.c \
|
||||
${COMMON_DIR}/tegra_sip_calls.c \
|
||||
${COMMON_DIR}/tegra_topology.c
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <bl_common.h>
|
||||
#include <context_mgmt.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <memctrl.h>
|
||||
#include <runtime_svc.h>
|
||||
#include <tegra_private.h>
|
||||
|
||||
#define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003
|
||||
|
||||
/*******************************************************************************
|
||||
* This function is responsible for handling all SiP calls from the NS world
|
||||
******************************************************************************/
|
||||
uint64_t tegra_sip_handler(uint32_t smc_fid,
|
||||
uint64_t x1,
|
||||
uint64_t x2,
|
||||
uint64_t x3,
|
||||
uint64_t x4,
|
||||
void *cookie,
|
||||
void *handle,
|
||||
uint64_t flags)
|
||||
{
|
||||
uint32_t ns;
|
||||
int err;
|
||||
|
||||
/* Determine which security state this SMC originated from */
|
||||
ns = is_caller_non_secure(flags);
|
||||
if (!ns)
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
|
||||
switch (smc_fid) {
|
||||
|
||||
case TEGRA_SIP_NEW_VIDEOMEM_REGION:
|
||||
|
||||
/*
|
||||
* Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
|
||||
* or falls outside of the valid DRAM range
|
||||
*/
|
||||
err = bl31_check_ns_address(x1, x2);
|
||||
if (err)
|
||||
SMC_RET1(handle, err);
|
||||
|
||||
/*
|
||||
* Check if Video Memory is aligned to 1MB.
|
||||
*/
|
||||
if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) {
|
||||
ERROR("Unaligned Video Memory base address!\n");
|
||||
SMC_RET1(handle, -ENOTSUP);
|
||||
}
|
||||
|
||||
/* new video memory carveout settings */
|
||||
tegra_memctrl_videomem_setup(x1, x2);
|
||||
|
||||
SMC_RET1(handle, 0);
|
||||
|
||||
default:
|
||||
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
|
||||
break;
|
||||
}
|
||||
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
}
|
||||
|
||||
/* Define a runtime service descriptor for fast SMC calls */
|
||||
DECLARE_RT_SVC(
|
||||
tegra_sip_fast,
|
||||
|
||||
OEN_SIP_START,
|
||||
OEN_SIP_END,
|
||||
SMC_TYPE_FAST,
|
||||
NULL,
|
||||
tegra_sip_handler
|
||||
);
|
|
@ -64,6 +64,10 @@
|
|||
#define MC_SECURITY_CFG0_0 0x70
|
||||
#define MC_SECURITY_CFG1_0 0x74
|
||||
|
||||
/* Video Memory carveout configuration registers */
|
||||
#define MC_VIDEO_PROTECT_BASE 0x648
|
||||
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
|
||||
|
||||
static inline uint32_t tegra_mc_read_32(uint32_t off)
|
||||
{
|
||||
return mmio_read_32(TEGRA_MC_BASE + off);
|
||||
|
@ -76,5 +80,6 @@ static inline void tegra_mc_write_32(uint32_t off, uint32_t val)
|
|||
|
||||
void tegra_memctrl_setup(void);
|
||||
void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes);
|
||||
void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes);
|
||||
|
||||
#endif /* __MEMCTRL_H__ */
|
||||
|
|
|
@ -34,6 +34,12 @@
|
|||
#include <xlat_tables.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Tegra DRAM memory base address
|
||||
******************************************************************************/
|
||||
#define TEGRA_DRAM_BASE 0x80000000
|
||||
#define TEGRA_DRAM_END 0x27FFFFFFF
|
||||
|
||||
typedef struct plat_params_from_bl2 {
|
||||
uint64_t tzdram_size;
|
||||
uintptr_t bl32_params;
|
||||
|
@ -66,5 +72,6 @@ int tegra_prepare_cpu_on_finish(unsigned long mpidr);
|
|||
|
||||
/* Declarations for tegra_bl31_setup.c */
|
||||
plat_params_from_bl2_t *bl31_get_plat_params(void);
|
||||
int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes);
|
||||
|
||||
#endif /* __TEGRA_PRIVATE_H__ */
|
||||
|
|
Loading…
Reference in New Issue