Merge pull request #853 from vwadekar/tegra-changes-from-downstream-v3

Tegra changes from downstream v3
This commit is contained in:
davidcunado-arm 2017-03-02 15:27:33 +00:00 committed by GitHub
commit bea7caff8d
15 changed files with 544 additions and 46 deletions

View File

@ -84,3 +84,10 @@ The PSCI implementation expects each platform to expose the 'power state'
parameter to be used during the 'SYSTEM SUSPEND' call. The state-id field
is implementation defined on Tegra SoCs and is preferably defined by
tegra_def.h.
Tegra configs
=============
* 'tegra_enable_l2_ecc_parity_prot': This flag enables the L2 ECC and Parity
Protection bit, for ARM Cortex-A57 CPUs, during CPU boot. This flag will
be enabled by Tegrs SoCs during 'Cluster power up' or 'System Suspend' exit.

View File

@ -87,6 +87,8 @@
#define L2_DATA_RAM_LATENCY_3_CYCLES 0x2
#define L2_TAG_RAM_LATENCY_3_CYCLES 0x2
#define L2_ECC_PARITY_PROTECTION_BIT (1 << 21)
/*******************************************************************************
* L2 Extended Control register specific definitions.
******************************************************************************/

View File

@ -52,6 +52,7 @@ __BEGIN_DECLS
void *memchr(const void *, int, size_t) __pure;
int memcmp(const void *, const void *, size_t) __pure;
void *memcpy(void * __restrict, const void * __restrict, size_t);
void *memcpy16(void * __restrict, const void * __restrict, size_t);
void *memmove(void *, const void *, size_t);
void *memset(void *, int, size_t);

View File

@ -59,7 +59,6 @@ func denver_enable_dco
mov x1, #1
lsl x1, x1, x0
msr s3_0_c15_c0_2, x1
isb
ret
endfunc denver_enable_dco

View File

@ -33,6 +33,7 @@
#include <cpu_macros.S>
#include <cortex_a57.h>
#include <cortex_a53.h>
#include <platform_def.h>
#include <tegra_def.h>
#define MIDR_PN_CORTEX_A57 0xD07
@ -67,6 +68,7 @@
.globl ns_image_entrypoint
.globl tegra_bl31_phys_base
.globl tegra_console_base
.globl tegra_enable_l2_ecc_parity_prot
/* ---------------------
* Common CPU init code
@ -75,8 +77,8 @@
.macro cpu_init_common
/* ------------------------------------------------
* We enable procesor retention and L2/CPUECTLR NS
* access for A57 CPUs only.
* We enable procesor retention, L2/CPUECTLR NS
* access and ECC/Parity protection for A57 CPUs
* ------------------------------------------------
*/
mrs x0, midr_el1
@ -89,7 +91,7 @@
/* ---------------------------
* Enable processor retention
* ---------------------------
*/
*/
mrs x0, L2ECTLR_EL1
mov x1, #RETENTION_ENTRY_TICKS_512 << L2ECTLR_RET_CTRL_SHIFT
bic x0, x0, #L2ECTLR_RET_CTRL_MASK
@ -107,12 +109,26 @@
/* -------------------------------------------------------
* Enable L2 and CPU ECTLR RW access from non-secure world
* -------------------------------------------------------
*/
*/
mov x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
msr actlr_el3, x0
msr actlr_el2, x0
isb
/* -------------------------------------------------------
* Enable L2 ECC and Parity Protection
* -------------------------------------------------------
*/
adr x0, tegra_enable_l2_ecc_parity_prot
ldr x0, [x0]
cbz x0, 1f
mrs x0, L2CTLR_EL1
and x1, x0, #L2_ECC_PARITY_PROTECTION_BIT
cbnz x1, 1f
orr x0, x0, #L2_ECC_PARITY_PROTECTION_BIT
msr L2CTLR_EL1, x0
isb
/* --------------------------------
* Enable the cycle count register
* --------------------------------
@ -254,6 +270,47 @@ endfunc plat_crash_console_putc
*/
func plat_reset_handler
/* ----------------------------------------------------
* Verify if we are running from BL31_BASE address
* ----------------------------------------------------
*/
adr x18, bl31_entrypoint
mov x17, #BL31_BASE
cmp x18, x17
b.eq 1f
/* ----------------------------------------------------
* Copy the entire BL31 code to BL31_BASE if we are not
* running from it already
* ----------------------------------------------------
*/
mov x0, x17
mov x1, x18
mov x2, #BL31_SIZE
_loop16:
cmp x2, #16
b.lt _loop1
ldp x3, x4, [x1], #16
stp x3, x4, [x0], #16
sub x2, x2, #16
b _loop16
/* copy byte per byte */
_loop1:
cbz x2, _end
ldrb w3, [x1], #1
strb w3, [x0], #1
subs x2, x2, #1
b.ne _loop1
/* ----------------------------------------------------
* Jump to BL31_BASE and start execution again
* ----------------------------------------------------
*/
_end: mov x0, x20
mov x1, x21
br x17
1:
/* -----------------------------------
* derive and save the phys_base addr
* -----------------------------------
@ -412,3 +469,10 @@ tegra_bl31_phys_base:
*/
tegra_console_base:
.quad 0
/* --------------------------------------------------
* Enable L2 ECC and Parity Protection
* --------------------------------------------------
*/
tegra_enable_l2_ecc_parity_prot:
.quad 0

View File

@ -44,9 +44,12 @@
#include <platform.h>
#include <platform_def.h>
#include <stddef.h>
#include <string.h>
#include <tegra_def.h>
#include <tegra_private.h>
extern void zeromem16(void *mem, unsigned int length);
/*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout
* of trusted SRAM
@ -79,6 +82,29 @@ static plat_params_from_bl2_t plat_bl31_params_from_bl2 = {
******************************************************************************/
extern uint64_t ns_image_entrypoint;
/*******************************************************************************
* The following platform setup functions are weakly defined. They
* provide typical implementations that will be overridden by a SoC.
******************************************************************************/
#pragma weak plat_early_platform_setup
#pragma weak plat_get_bl31_params
#pragma weak plat_get_bl31_plat_params
void plat_early_platform_setup(void)
{
; /* do nothing */
}
bl31_params_t *plat_get_bl31_params(void)
{
return NULL;
}
plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
{
return NULL;
}
/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for
* security state specified. BL33 corresponds to the non-secure image type
@ -89,7 +115,8 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
if (type == NON_SECURE)
return &bl33_image_ep_info;
if (type == SECURE)
/* return BL32 entry point info if it is valid */
if (type == SECURE && bl32_image_ep_info.pc)
return &bl32_image_ep_info;
return NULL;
@ -116,11 +143,25 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
#if DEBUG
int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
#endif
image_info_t bl32_img_info = { {0} };
uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
/*
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
* there's no argument to relay from a previous bootloader. Platforms
* might use custom ways to get arguments, so provide handlers which
* they can override.
*/
if (from_bl2 == NULL)
from_bl2 = plat_get_bl31_params();
if (plat_params == NULL)
plat_params = plat_get_bl31_plat_params();
/*
* Copy BL3-3, BL3-2 entry point information.
* They are stored in Secure RAM, in BL2's address space.
*/
assert(from_bl2);
assert(from_bl2->bl33_ep_info);
bl33_image_ep_info = *from_bl2->bl33_ep_info;
@ -135,6 +176,14 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
plat_bl31_params_from_bl2.tzdram_size = plat_params->tzdram_size;
plat_bl31_params_from_bl2.uart_id = plat_params->uart_id;
/*
* It is very important that we run either from TZDRAM or TZSRAM base.
* Add an explicit check here.
*/
if ((plat_bl31_params_from_bl2.tzdram_base != BL31_BASE) &&
(TEGRA_TZRAM_BASE != BL31_BASE))
panic();
/*
* Get the base address of the UART controller to be used for the
* console
@ -152,6 +201,51 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
/* Initialise crash console */
plat_crash_console_init();
/*
* Do initial security configuration to allow DRAM/device access.
*/
tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
plat_bl31_params_from_bl2.tzdram_size);
/*
* The previous bootloader might not have placed the BL32 image
* inside the TZDRAM. We check the BL32 image info to find out
* the base/PC values and relocate the image if necessary.
*/
if (from_bl2->bl32_image_info) {
bl32_img_info = *from_bl2->bl32_image_info;
/* Relocate BL32 if it resides outside of the TZDRAM */
tzdram_start = plat_bl31_params_from_bl2.tzdram_base;
tzdram_end = plat_bl31_params_from_bl2.tzdram_base +
plat_bl31_params_from_bl2.tzdram_size;
bl32_start = bl32_img_info.image_base;
bl32_end = bl32_img_info.image_base + bl32_img_info.image_size;
assert(tzdram_end > tzdram_start);
assert(bl32_end > bl32_start);
assert(bl32_image_ep_info.pc > tzdram_start);
assert(bl32_image_ep_info.pc < tzdram_end);
/* relocate BL32 */
if (bl32_start >= tzdram_end || bl32_end <= tzdram_start) {
INFO("Relocate BL32 to TZDRAM\n");
memcpy16((void *)(uintptr_t)bl32_image_ep_info.pc,
(void *)(uintptr_t)bl32_start,
bl32_img_info.image_size);
/* clean up non-secure intermediate buffer */
zeromem16((void *)(uintptr_t)bl32_start,
bl32_img_info.image_size);
}
}
/* Early platform setup for Tegra SoCs */
plat_early_platform_setup();
INFO("BL3-1: Boot CPU: %s Processor [%lx]\n", (impl == DENVER_IMPL) ?
"Denver" : "ARM", read_mpidr());
}
@ -163,6 +257,9 @@ void bl31_platform_setup(void)
{
uint32_t tmp_reg;
/* Initialize the gic cpu and distributor interfaces */
plat_gic_setup();
/*
* Initialize delay timer
*/
@ -178,12 +275,6 @@ void bl31_platform_setup(void)
*/
tegra_memctrl_setup();
/*
* Do initial security configuration to allow DRAM/device access.
*/
tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
plat_bl31_params_from_bl2.tzdram_size);
/*
* Set up the TZRAM memory aperture to allow only secure world
* access
@ -194,9 +285,6 @@ void bl31_platform_setup(void)
tmp_reg = SCR_RES1_BITS | SCR_RW_BIT;
write_scr(tmp_reg);
/* Initialize the gic cpu and distributor interfaces */
tegra_gic_setup();
INFO("BL3-1: Tegra platform setup complete\n");
}

View File

@ -47,16 +47,15 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
COMMON_DIR := plat/nvidia/tegra/common
BL31_SOURCES += drivers/arm/gic/gic_v2.c \
drivers/arm/gic/gic_v3.c \
drivers/console/aarch64/console.S \
drivers/delay_timer/delay_timer.c \
drivers/ti/uart/aarch64/16550_console.S \
plat/common/aarch64/platform_mp_stack.S \
plat/common/plat_psci_common.c \
${COMMON_DIR}/aarch64/tegra_helpers.S \
${COMMON_DIR}/drivers/pmc/pmc.c \
${COMMON_DIR}/tegra_bl31_setup.c \
${COMMON_DIR}/tegra_delay_timer.c \
${COMMON_DIR}/tegra_fiq_glue.c \
${COMMON_DIR}/tegra_gic.c \
${COMMON_DIR}/tegra_pm.c \
${COMMON_DIR}/tegra_sip_calls.c \

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2016, 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 <bakery_lock.h>
#include <bl_common.h>
#include <context.h>
#include <context_mgmt.h>
#include <debug.h>
#include <denver.h>
#include <gic_v2.h>
#include <interrupt_mgmt.h>
#include <platform.h>
#include <tegra_def.h>
#include <tegra_private.h>
DEFINE_BAKERY_LOCK(tegra_fiq_lock);
/*******************************************************************************
* Static variables
******************************************************************************/
static uint64_t ns_fiq_handler_addr;
static unsigned int fiq_handler_active;
static pcpu_fiq_state_t fiq_state[PLATFORM_CORE_COUNT];
/*******************************************************************************
* Handler for FIQ interrupts
******************************************************************************/
static uint64_t tegra_fiq_interrupt_handler(uint32_t id,
uint32_t flags,
void *handle,
void *cookie)
{
cpu_context_t *ctx = cm_get_context(NON_SECURE);
el3_state_t *el3state_ctx = get_el3state_ctx(ctx);
int cpu = plat_my_core_pos();
uint32_t irq;
bakery_lock_get(&tegra_fiq_lock);
/*
* The FIQ was generated when the execution was in the non-secure
* world. Save the context registers to start with.
*/
cm_el1_sysregs_context_save(NON_SECURE);
/*
* Save elr_el3 and spsr_el3 from the saved context, and overwrite
* the context with the NS fiq_handler_addr and SPSR value.
*/
fiq_state[cpu].elr_el3 = read_ctx_reg(el3state_ctx, CTX_ELR_EL3);
fiq_state[cpu].spsr_el3 = read_ctx_reg(el3state_ctx, CTX_SPSR_EL3);
/*
* Set the new ELR to continue execution in the NS world using the
* FIQ handler registered earlier.
*/
assert(ns_fiq_handler_addr);
write_ctx_reg(el3state_ctx, CTX_ELR_EL3, ns_fiq_handler_addr);
/*
* Mark this interrupt as complete to avoid a FIQ storm.
*/
irq = plat_ic_acknowledge_interrupt();
if (irq < 1022)
plat_ic_end_of_interrupt(irq);
bakery_lock_release(&tegra_fiq_lock);
return 0;
}
/*******************************************************************************
* Setup handler for FIQ interrupts
******************************************************************************/
void tegra_fiq_handler_setup(void)
{
uint64_t flags;
int rc;
/* return if already registered */
if (fiq_handler_active)
return;
/*
* Register an interrupt handler for FIQ interrupts generated for
* NS interrupt sources
*/
flags = 0;
set_interrupt_rm_flag(flags, NON_SECURE);
rc = register_interrupt_type_handler(INTR_TYPE_EL3,
tegra_fiq_interrupt_handler,
flags);
if (rc)
panic();
/* handler is now active */
fiq_handler_active = 1;
}
/*******************************************************************************
* Validate and store NS world's entrypoint for FIQ interrupts
******************************************************************************/
void tegra_fiq_set_ns_entrypoint(uint64_t entrypoint)
{
ns_fiq_handler_addr = entrypoint;
}
/*******************************************************************************
* Handler to return the NS EL1/EL0 CPU context
******************************************************************************/
int tegra_fiq_get_intr_context(void)
{
cpu_context_t *ctx = cm_get_context(NON_SECURE);
gp_regs_t *gpregs_ctx = get_gpregs_ctx(ctx);
el1_sys_regs_t *el1state_ctx = get_sysregs_ctx(ctx);
int cpu = plat_my_core_pos();
uint64_t val;
/*
* We store the ELR_EL3, SPSR_EL3, SP_EL0 and SP_EL1 registers so
* that el3_exit() sends these values back to the NS world.
*/
write_ctx_reg(gpregs_ctx, CTX_GPREG_X0, fiq_state[cpu].elr_el3);
write_ctx_reg(gpregs_ctx, CTX_GPREG_X1, fiq_state[cpu].spsr_el3);
val = read_ctx_reg(gpregs_ctx, CTX_GPREG_SP_EL0);
write_ctx_reg(gpregs_ctx, CTX_GPREG_X2, val);
val = read_ctx_reg(el1state_ctx, CTX_SP_EL1);
write_ctx_reg(gpregs_ctx, CTX_GPREG_X3, val);
return 0;
}

View File

@ -47,6 +47,9 @@
(GIC_HIGHEST_NS_PRIORITY << 16) | \
(GIC_HIGHEST_NS_PRIORITY << 24))
static const irq_sec_cfg_t *g_irq_sec_ptr;
static unsigned int g_num_irqs;
/*******************************************************************************
* Place the cpu interface in a state where it can never make a cpu exit wfi as
* as result of an asserted interrupt. This is critical for powering down a cpu
@ -110,7 +113,9 @@ static void tegra_gic_pcpu_distif_setup(unsigned int gicd_base)
******************************************************************************/
static void tegra_gic_distif_setup(unsigned int gicd_base)
{
unsigned int index, num_ints;
unsigned int index, num_ints, irq_num;
uint8_t target_cpus;
uint32_t val;
/*
* Mark out non-secure interrupts. Calculate number of
@ -128,6 +133,39 @@ static void tegra_gic_distif_setup(unsigned int gicd_base)
GICD_IPRIORITYR_DEF_VAL);
}
/* Configure SPI secure interrupts now */
if (g_irq_sec_ptr) {
for (index = 0; index < g_num_irqs; index++) {
irq_num = (g_irq_sec_ptr + index)->irq;
target_cpus = (g_irq_sec_ptr + index)->target_cpus;
if (irq_num >= MIN_SPI_ID) {
/* Configure as a secure interrupt */
gicd_clr_igroupr(gicd_base, irq_num);
/* Configure SPI priority */
mmio_write_8(gicd_base + GICD_IPRIORITYR +
irq_num,
GIC_HIGHEST_SEC_PRIORITY &
GIC_PRI_MASK);
/* Configure as level triggered */
val = gicd_read_icfgr(gicd_base, irq_num);
val |= (3 << ((irq_num & 0xF) << 1));
gicd_write_icfgr(gicd_base, irq_num, val);
/* Route SPI to the target CPUs */
gicd_set_itargetsr(gicd_base, irq_num,
target_cpus);
/* Enable this interrupt */
gicd_set_isenabler(gicd_base, irq_num);
}
}
}
/*
* Configure the SGI and PPI. This is done in a separated function
* because each CPU is responsible for initializing its own private
@ -139,8 +177,11 @@ static void tegra_gic_distif_setup(unsigned int gicd_base)
gicd_write_ctlr(gicd_base, ENABLE_GRP0 | ENABLE_GRP1);
}
void tegra_gic_setup(void)
void tegra_gic_setup(const irq_sec_cfg_t *irq_sec_ptr, unsigned int num_irqs)
{
g_irq_sec_ptr = irq_sec_ptr;
g_num_irqs = num_irqs;
tegra_gic_cpuif_setup(TEGRA_GICC_BASE);
tegra_gic_distif_setup(TEGRA_GICD_BASE);
}
@ -185,12 +226,17 @@ uint32_t tegra_gic_interrupt_type_to_line(uint32_t type,
uint32_t tegra_gic_get_pending_interrupt_type(void)
{
uint32_t id;
unsigned int index;
id = gicc_read_hppir(TEGRA_GICC_BASE) & INT_ID_MASK;
/* Assume that all secure interrupts are S-EL1 interrupts */
if (id < 1022)
return INTR_TYPE_S_EL1;
/* get the interrupt type */
if (id < 1022) {
for (index = 0; index < g_num_irqs; index++) {
if (id == (g_irq_sec_ptr + index)->irq)
return (g_irq_sec_ptr + index)->type;
}
}
if (id == GIC_SPURIOUS_INTERRUPT)
return INTR_TYPE_INVAL;
@ -248,14 +294,19 @@ void tegra_gic_end_of_interrupt(uint32_t id)
uint32_t tegra_gic_get_interrupt_type(uint32_t id)
{
uint32_t group;
unsigned int index;
group = gicd_get_igroupr(TEGRA_GICD_BASE, id);
/* Assume that all secure interrupts are S-EL1 interrupts */
if (group == GRP0)
return INTR_TYPE_S_EL1;
else
return INTR_TYPE_NS;
/* get the interrupt type */
if (group == GRP0) {
for (index = 0; index < g_num_irqs; index++) {
if (id == (g_irq_sec_ptr + index)->irq)
return (g_irq_sec_ptr + index)->type;
}
}
return INTR_TYPE_NS;
}
#else

View File

@ -57,6 +57,7 @@ extern uint64_t tegra_sec_entry_point;
#pragma weak tegra_soc_pwr_domain_power_down_wfi
#pragma weak tegra_soc_prepare_system_reset
#pragma weak tegra_soc_prepare_system_off
#pragma weak tegra_soc_get_target_pwr_state
int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
@ -94,6 +95,23 @@ __dead2 void tegra_soc_prepare_system_off(void)
panic();
}
plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
const plat_local_state_t *states,
unsigned int ncpu)
{
plat_local_state_t target = PLAT_MAX_RET_STATE, temp;
assert(ncpu);
do {
temp = *states++;
if ((temp > target) && (temp != PLAT_MAX_OFF_STATE))
target = temp;
} while (--ncpu);
return target;
}
/*******************************************************************************
* This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND`
* call to get the `power_state` parameter. This allows the platform to encode
@ -102,12 +120,9 @@ __dead2 void tegra_soc_prepare_system_off(void)
******************************************************************************/
void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
{
/* lower affinities use PLAT_MAX_OFF_STATE */
for (int i = MPIDR_AFFLVL0; i < PLAT_MAX_PWR_LVL; i++)
req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
/* max affinity uses system suspend state id */
req_state->pwr_domain_state[PLAT_MAX_PWR_LVL] = PSTATE_ID_SOC_POWERDN;
/* all affinities use system suspend state id */
for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
req_state->pwr_domain_state[i] = PSTATE_ID_SOC_POWERDN;
}
/*******************************************************************************
@ -183,7 +198,7 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
/*
* Initialize the GIC cpu and distributor interfaces
*/
tegra_gic_setup();
plat_gic_setup();
/*
* Check if we are exiting from deep sleep.
@ -203,6 +218,12 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
plat_params = bl31_get_plat_params();
tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
plat_params->tzdram_size);
/*
* Set up the TZRAM memory aperture to allow only secure world
* access
*/
tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
}
/*
@ -318,3 +339,14 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
return 0;
}
/*******************************************************************************
* Platform handler to calculate the proper target power level at the
* specified affinity level
******************************************************************************/
plat_local_state_t plat_get_target_pwr_state(unsigned int lvl,
const plat_local_state_t *states,
unsigned int ncpu)
{
return tegra_soc_get_target_pwr_state(lvl, states, ncpu);
}

View File

@ -42,6 +42,8 @@
* Common Tegra SiP SMCs
******************************************************************************/
#define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003
#define TEGRA_SIP_FIQ_NS_ENTRYPOINT 0x82000005
#define TEGRA_SIP_FIQ_NS_GET_CONTEXT 0x82000006
/*******************************************************************************
* SoC specific SiP handler
@ -60,7 +62,7 @@ int plat_sip_handler(uint32_t smc_fid,
}
/*******************************************************************************
* This function is responsible for handling all SiP calls from the NS world
* This function is responsible for handling all SiP calls
******************************************************************************/
uint64_t tegra_sip_handler(uint32_t smc_fid,
uint64_t x1,
@ -71,14 +73,8 @@ uint64_t tegra_sip_handler(uint32_t smc_fid,
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);
/* Check if this is a SoC specific SiP */
err = plat_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
if (err == 0)
@ -114,6 +110,41 @@ uint64_t tegra_sip_handler(uint32_t smc_fid,
SMC_RET1(handle, 0);
break;
/*
* The NS world registers the address of its handler to be
* used for processing the FIQ. This is normally used by the
* NS FIQ debugger driver to detect system hangs by programming
* a watchdog timer to fire a FIQ interrupt.
*/
case TEGRA_SIP_FIQ_NS_ENTRYPOINT:
if (!x1)
SMC_RET1(handle, SMC_UNK);
/*
* TODO: Check if x1 contains a valid DRAM address
*/
/* store the NS world's entrypoint */
tegra_fiq_set_ns_entrypoint(x1);
SMC_RET1(handle, 0);
break;
/*
* The NS world's FIQ handler issues this SMC to get the NS EL1/EL0
* CPU context when the FIQ interrupt was triggered. This allows the
* NS world to understand the CPU state when the watchdog interrupt
* triggered.
*/
case TEGRA_SIP_FIQ_NS_GET_CONTEXT:
/* retrieve context registers when FIQ triggered */
tegra_fiq_get_intr_context();
SMC_RET0(handle);
break;
default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
break;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2016, 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:
@ -42,6 +42,9 @@
#define TEGRA_DRAM_BASE 0x80000000
#define TEGRA_DRAM_END 0x27FFFFFFF
/*******************************************************************************
* Struct for parameters received from BL2
******************************************************************************/
typedef struct plat_params_from_bl2 {
/* TZ memory size */
uint64_t tzdram_size;
@ -51,6 +54,26 @@ typedef struct plat_params_from_bl2 {
int uart_id;
} plat_params_from_bl2_t;
/*******************************************************************************
* Per-CPU struct describing FIQ state to be stored
******************************************************************************/
typedef struct pcpu_fiq_state {
uint64_t elr_el3;
uint64_t spsr_el3;
} pcpu_fiq_state_t;
/*******************************************************************************
* Struct describing per-FIQ configuration settings
******************************************************************************/
typedef struct irq_sec_cfg {
/* IRQ number */
unsigned int irq;
/* Target CPUs servicing this interrupt */
unsigned int target_cpus;
/* type = INTR_TYPE_S_EL1 or INTR_TYPE_EL3 */
uint32_t type;
} irq_sec_cfg_t;
/* Declarations for plat_psci_handlers.c */
int32_t tegra_soc_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state);
@ -58,13 +81,21 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
/* Declarations for plat_setup.c */
const mmap_region_t *plat_get_mmio_map(void);
uint32_t plat_get_console_from_id(int id);
void plat_gic_setup(void);
bl31_params_t *plat_get_bl31_params(void);
plat_params_from_bl2_t *plat_get_bl31_plat_params(void);
/* Declarations for plat_secondary.c */
void plat_secondary_setup(void);
int plat_lock_cpu_vectors(void);
/* Declarations for tegra_fiq_glue.c */
void tegra_fiq_handler_setup(void);
int tegra_fiq_get_intr_context(void);
void tegra_fiq_set_ns_entrypoint(uint64_t entrypoint);
/* Declarations for tegra_gic.c */
void tegra_gic_setup(void);
void tegra_gic_setup(const irq_sec_cfg_t *irq_sec_ptr, unsigned int num_irqs);
void tegra_gic_cpuif_deactivate(void);
/* Declarations for tegra_security.c */
@ -83,6 +114,7 @@ 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);
void plat_early_platform_setup(void);
/* Declarations for tegra_delay_timer.c */
void tegra_delay_timer_init(void);

View File

@ -36,6 +36,14 @@ PSCI_EXTENDED_STATE_ID := 1
# Disable the PSCI platform compatibility layer
ENABLE_PLAT_COMPAT := 0
# Disable cache non-temporal hint for A57
A57_DISABLE_NON_TEMPORAL_HINT := 0
$(eval $(call add_define,A57_DISABLE_NON_TEMPORAL_HINT))
# Disable cache non-temporal hint for A53
A53_DISABLE_NON_TEMPORAL_HINT := 0
$(eval $(call add_define,A53_DISABLE_NON_TEMPORAL_HINT))
include plat/nvidia/tegra/common/tegra_common.mk
include ${SOC_DIR}/platform_${TARGET_SOC}.mk

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2016, 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:
@ -28,8 +28,11 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <xlat_tables.h>
#include <arch_helpers.h>
#include <bl_common.h>
#include <tegra_def.h>
#include <tegra_private.h>
#include <xlat_tables.h>
/*******************************************************************************
* The Tegra power domain tree has a single system level power domain i.e. a
@ -106,3 +109,11 @@ uint32_t plat_get_console_from_id(int id)
return tegra132_uart_addresses[id];
}
/*******************************************************************************
* Initialize the GIC and SGIs
******************************************************************************/
void plat_gic_setup(void)
{
tegra_gic_setup(NULL, 0);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2016, 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:
@ -28,8 +28,11 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <arch_helpers.h>
#include <bl_common.h>
#include <console.h>
#include <tegra_def.h>
#include <tegra_private.h>
#include <xlat_tables.h>
/*******************************************************************************
@ -112,3 +115,11 @@ uint32_t plat_get_console_from_id(int id)
return tegra210_uart_addresses[id];
}
/*******************************************************************************
* Initialize the GIC and SGIs
******************************************************************************/
void plat_gic_setup(void)
{
tegra_gic_setup(NULL, 0);
}