aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2016-05-20 16:21:22 -0700
committerVarun Wadekar <vwadekar@nvidia.com>2017-02-28 08:50:01 -0800
commit45eab456e6da0e79c51ffced6c3a46053a1adc70 (patch)
treee203f54463080b2beac82ff7f2351c3aade2c903
parent78e2bd10aed75e2dd7d47abefd6270935fb889b7 (diff)
Tegra: GIC: differentiate between FIQs targeted towards EL3/S-EL1
This patch modifies the secure IRQ registration process to allow platforms to specify the target CPUs as well as the owner of the IRQ. IRQs "owned" by the EL3 would return INTR_TYPE_EL3 whereas those owned by the Trusted OS would return INTR_TYPE_S_EL1 as a result. Change-Id: I528f7c8220d0ae0c0f354e78d69e188abb666ef6 Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
-rw-r--r--plat/nvidia/tegra/common/tegra_fiq_glue.c2
-rw-r--r--plat/nvidia/tegra/common/tegra_gic.c36
-rw-r--r--plat/nvidia/tegra/include/t132/tegra_def.h5
-rw-r--r--plat/nvidia/tegra/include/t210/tegra_def.h5
-rw-r--r--plat/nvidia/tegra/include/tegra_private.h14
5 files changed, 36 insertions, 26 deletions
diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c
index 0c4d82c2..7fcc114c 100644
--- a/plat/nvidia/tegra/common/tegra_fiq_glue.c
+++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c
@@ -116,7 +116,7 @@ void tegra_fiq_handler_setup(void)
*/
flags = 0;
set_interrupt_rm_flag(flags, NON_SECURE);
- rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+ rc = register_interrupt_type_handler(INTR_TYPE_EL3,
tegra_fiq_interrupt_handler,
flags);
if (rc)
diff --git a/plat/nvidia/tegra/common/tegra_gic.c b/plat/nvidia/tegra/common/tegra_gic.c
index 786eefc1..6864f8bf 100644
--- a/plat/nvidia/tegra/common/tegra_gic.c
+++ b/plat/nvidia/tegra/common/tegra_gic.c
@@ -47,7 +47,7 @@
(GIC_HIGHEST_NS_PRIORITY << 16) | \
(GIC_HIGHEST_NS_PRIORITY << 24))
-static const unsigned int *g_irq_sec_ptr;
+static const irq_sec_cfg_t *g_irq_sec_ptr;
static unsigned int g_num_irqs;
/*******************************************************************************
@@ -136,11 +136,9 @@ static void tegra_gic_distif_setup(unsigned int gicd_base)
/* Configure SPI secure interrupts now */
if (g_irq_sec_ptr) {
- /* Read the target CPU mask */
- target_cpus = TEGRA_SEC_IRQ_TARGET_MASK & GIC_TARGET_CPU_MASK;
-
for (index = 0; index < g_num_irqs; index++) {
- irq_num = g_irq_sec_ptr[index];
+ irq_num = (g_irq_sec_ptr + index)->irq;
+ target_cpus = (g_irq_sec_ptr + index)->target_cpus;
if (irq_num >= MIN_SPI_ID) {
@@ -179,7 +177,7 @@ static void tegra_gic_distif_setup(unsigned int gicd_base)
gicd_write_ctlr(gicd_base, ENABLE_GRP0 | ENABLE_GRP1);
}
-void tegra_gic_setup(const unsigned int *irq_sec_ptr, unsigned int num_irqs)
+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;
@@ -228,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;
@@ -291,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
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
index 3bafb87d..318f4def 100644
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ b/plat/nvidia/tegra/include/t132/tegra_def.h
@@ -49,11 +49,6 @@
#define PLAT_MAX_OFF_STATE (PSTATE_ID_SOC_POWERDN + 1)
/*******************************************************************************
- * Secure IRQ definitions
- ******************************************************************************/
-#define TEGRA_SEC_IRQ_TARGET_MASK 0x3 /* 2 Denver's */
-
-/*******************************************************************************
* GIC memory map
******************************************************************************/
#define TEGRA_GICD_BASE 0x50041000
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index cc4c2d9f..ce85427e 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -57,11 +57,6 @@
#define PLAT_MAX_OFF_STATE (PSTATE_ID_SOC_POWERDN + 1)
/*******************************************************************************
- * Secure IRQ definitions
- ******************************************************************************/
-#define TEGRA_SEC_IRQ_TARGET_MASK 0xF /* 4 A57's or 4 A53's */
-
-/*******************************************************************************
* GIC memory map
******************************************************************************/
#define TEGRA_GICD_BASE 0x50041000
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index c65bacae..c09a153c 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -62,6 +62,18 @@ typedef struct pcpu_fiq_state {
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);
@@ -81,7 +93,7 @@ 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(const unsigned int *irq_sec_ptr, unsigned int num_irqs);
+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 */