Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
09aa0392
Commit
09aa0392
authored
Jun 18, 2015
by
danh-arm
Browse files
Merge pull request #319 from vwadekar/tegra-video-mem-aperture-v3
Reserve a Video Memory aperture in DRAM memory
parents
79b1ebda
9a964510
Changes
6
Hide whitespace changes
Inline
Side-by-side
plat/nvidia/tegra/common/drivers/memctrl/memctrl.c
View file @
09aa0392
...
...
@@ -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
;
}
plat/nvidia/tegra/common/tegra_bl31_setup.c
View file @
09aa0392
...
...
@@ -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
;
}
plat/nvidia/tegra/common/tegra_common.mk
View file @
09aa0392
...
...
@@ -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
plat/nvidia/tegra/common/tegra_sip_calls.c
0 → 100644
View file @
09aa0392
/*
* 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
);
plat/nvidia/tegra/include/drivers/memctrl.h
View file @
09aa0392
...
...
@@ -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__ */
plat/nvidia/tegra/include/tegra_private.h
View file @
09aa0392
...
...
@@ -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__ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment