summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAchin Gupta <achin.gupta@arm.com>2015-09-07 10:09:07 +0100
committerAchin Gupta <achin.gupta@arm.com>2015-09-22 18:36:58 +0100
commit7edb86dabef415b0aae99478a186ef5299d8ee28 (patch)
tree726b4be8fdf9764ccefe9cfe52b2758b699b9726
parent9dae88c9232135b3ba425f11f90df1b7ec58c639 (diff)
downloadarm-trusted-firmware-7edb86dabef415b0aae99478a186ef5299d8ee28.tar.gz
fvp: Demonstrate use of GICv3 driver
This patch makes temporary changes to the FVP port to use the GICv3 driver. The major changes are as follows: 1. The driver expects a separate list of interrupts IDs corresponding to Group0 and Group1 Secure interrupts. SGI0 and SGI6 are marked as Group0 interrupts as an example. 2. The hash function used to convert an MPIDR into a linear index by plat_get_core_pos_by_mpidr() and plat_get_my_core_pos() APIs is passed to the driver to enable conversion of GIC affinity values from GICR_TYPER to processor numbers. 3. The common driver for handling interrupts in plat/common/plat_gic.c has been changed to assume the presence of only a GICv3 driver. Change-Id: I7fc27d61fc6c2a60cea2436b676c5737d0257df6
-rw-r--r--plat/arm/board/fvp/aarch64/fvp_common.c34
-rw-r--r--plat/arm/board/fvp/fvp_pm.c85
-rw-r--r--plat/arm/common/arm_bl31_setup.c6
-rw-r--r--plat/arm/common/arm_common.mk6
-rw-r--r--plat/arm/common/tsp/arm_tsp.mk5
-rw-r--r--plat/common/plat_gic.c15
6 files changed, 88 insertions, 63 deletions
diff --git a/plat/arm/board/fvp/aarch64/fvp_common.c b/plat/arm/board/fvp/aarch64/fvp_common.c
index 58b646a45..ed4d3cd50 100644
--- a/plat/arm/board/fvp/aarch64/fvp_common.c
+++ b/plat/arm/board/fvp/aarch64/fvp_common.c
@@ -30,7 +30,7 @@
#include <arm_config.h>
#include <arm_def.h>
-#include <arm_gic.h>
+#include <arm_gicv3.h>
#include <cci.h>
#include <debug.h>
#include <mmio.h>
@@ -111,28 +111,42 @@ ARM_CASSERT_MMAP
#if IMAGE_BL31 || IMAGE_BL32
-/* Array of secure interrupts to be configured by the gic driver */
-const unsigned int irq_sec_array[] = {
+/* Array of Group1 secure interrupts to be configured by the gic driver */
+const unsigned int g1s_interrupt_array[] = {
ARM_IRQ_SEC_PHY_TIMER,
- ARM_IRQ_SEC_SGI_0,
ARM_IRQ_SEC_SGI_1,
ARM_IRQ_SEC_SGI_2,
ARM_IRQ_SEC_SGI_3,
ARM_IRQ_SEC_SGI_4,
ARM_IRQ_SEC_SGI_5,
- ARM_IRQ_SEC_SGI_6,
ARM_IRQ_SEC_SGI_7,
FVP_IRQ_TZ_WDOG,
FVP_IRQ_SEC_SYS_TIMER
};
+/* Array of Group0 interrupts to be configured by the gic driver */
+const unsigned int g0_interrupt_array[] = {
+ ARM_IRQ_SEC_SGI_0,
+ ARM_IRQ_SEC_SGI_6
+};
+
+uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+arm_gicv3_driver_data_t plat_gic_data = {
+ .gicr_base = BASE_GICR_BASE,
+ .g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array),
+ .g1s_interrupt_num = ARRAY_SIZE(g1s_interrupt_array),
+ .g0_interrupt_array = g0_interrupt_array,
+ .g1s_interrupt_array = g1s_interrupt_array,
+ .rdistif_num = PLATFORM_CORE_COUNT,
+ .rdistif_base_addrs = rdistif_base_addrs,
+ .mpidr_to_core_pos = plat_arm_calc_core_pos
+};
+
void plat_arm_gic_init(void)
{
- arm_gic_init(arm_config.gicc_base,
- arm_config.gicd_base,
- BASE_GICR_BASE,
- irq_sec_array,
- ARRAY_SIZE(irq_sec_array));
+ plat_gic_data.gicd_base = arm_config.gicd_base;
+ arm_gicv3_driver_init(&plat_gic_data);
}
#endif
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 9d6ab9ce6..123ef247e 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -30,7 +30,7 @@
#include <arch_helpers.h>
#include <arm_config.h>
-#include <arm_gic.h>
+#include <arm_gicv3.h>
#include <assert.h>
#include <debug.h>
#include <errno.h>
@@ -83,7 +83,7 @@ static void fvp_program_mailbox(uintptr_t address)
static void fvp_cpu_pwrdwn_common(void)
{
/* Prevent interrupts from spuriously waking up this cpu */
- arm_gic_cpuif_deactivate();
+ arm_gicv3_cpuif_deinit(plat_my_core_pos());
/* Program the power controller to power off this cpu. */
fvp_pwrc_write_ppoffr(read_mpidr_el1());
@@ -104,6 +104,42 @@ static void fvp_cluster_pwrdwn_common(void)
fvp_pwrc_write_pcoffr(mpidr);
}
+static void fvp_power_domain_on_finish_common(const psci_power_state_t *target_state)
+{
+ unsigned long mpidr;
+
+ assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
+ ARM_LOCAL_STATE_OFF);
+
+ /* Get the mpidr for this cpu */
+ mpidr = read_mpidr_el1();
+
+ /* Perform the common cluster specific operations */
+ if (target_state->pwr_domain_state[ARM_PWR_LVL1] ==
+ ARM_LOCAL_STATE_OFF) {
+ /*
+ * This CPU might have woken up whilst the cluster was
+ * attempting to power down. In this case the FVP power
+ * controller will have a pending cluster power off request
+ * which needs to be cleared by writing to the PPONR register.
+ * This prevents the power controller from interpreting a
+ * subsequent entry of this cpu into a simple wfi as a power
+ * down request.
+ */
+ fvp_pwrc_write_pponr(mpidr);
+
+ /* Enable coherency if this cluster was off */
+ fvp_cci_enable();
+ }
+
+ /*
+ * Clear PWKUPR.WEN bit to ensure interrupts do not interfere
+ * with a cpu power down unless the bit is set again
+ */
+ fvp_pwrc_clr_wen(mpidr);
+}
+
+
/*******************************************************************************
* FVP handler called when a CPU is about to enter standby.
******************************************************************************/
@@ -207,43 +243,11 @@ void fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
******************************************************************************/
void fvp_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
- unsigned long mpidr;
-
- assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
- ARM_LOCAL_STATE_OFF);
-
- /* Get the mpidr for this cpu */
- mpidr = read_mpidr_el1();
-
- /* Perform the common cluster specific operations */
- if (target_state->pwr_domain_state[ARM_PWR_LVL1] ==
- ARM_LOCAL_STATE_OFF) {
- /*
- * This CPU might have woken up whilst the cluster was
- * attempting to power down. In this case the FVP power
- * controller will have a pending cluster power off request
- * which needs to be cleared by writing to the PPONR register.
- * This prevents the power controller from interpreting a
- * subsequent entry of this cpu into a simple wfi as a power
- * down request.
- */
- fvp_pwrc_write_pponr(mpidr);
-
- /* Enable coherency if this cluster was off */
- fvp_cci_enable();
- }
+ fvp_power_domain_on_finish_common(target_state);
- /*
- * Clear PWKUPR.WEN bit to ensure interrupts do not interfere
- * with a cpu power down unless the bit is set again
- */
- fvp_pwrc_clr_wen(mpidr);
-
- /* Enable the gic cpu interface */
- arm_gic_cpuif_setup();
-
- /* TODO: This setup is needed only after a cold boot */
- arm_gic_pcpu_distif_setup();
+ /* Enable the gic cpu and re-distributor interfaces */
+ arm_gicv3_rdistif_init(plat_my_core_pos());
+ arm_gicv3_cpuif_init(plat_my_core_pos());
}
/*******************************************************************************
@@ -262,7 +266,10 @@ void fvp_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
ARM_LOCAL_STATE_RET)
return;
- fvp_pwr_domain_on_finish(target_state);
+ fvp_power_domain_on_finish_common(target_state);
+
+ /* Enable the gic cpu interfaces */
+ arm_gicv3_cpuif_init(plat_my_core_pos());
}
/*******************************************************************************
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 899463ee9..054a70247 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -31,7 +31,7 @@
#include <arch.h>
#include <arch_helpers.h>
#include <arm_def.h>
-#include <arm_gic.h>
+#include <arm_gicv3.h>
#include <assert.h>
#include <bl_common.h>
#include <cci.h>
@@ -201,7 +201,9 @@ void arm_bl31_platform_setup(void)
/* Initialize the gic cpu and distributor interfaces */
plat_arm_gic_init();
- arm_gic_setup();
+ arm_gicv3_distif_init();
+ arm_gicv3_rdistif_init(plat_my_core_pos());
+ arm_gicv3_cpuif_init(plat_my_core_pos());
#if RESET_TO_BL31
/*
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 12346194d..7672ea579 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -91,9 +91,9 @@ BL2_SOURCES += drivers/arm/tzc400/tzc400.c \
plat/common/aarch64/platform_up_stack.S
BL31_SOURCES += drivers/arm/cci/cci.c \
- drivers/arm/gic/arm_gic.c \
- drivers/arm/gic/gic_v2.c \
- drivers/arm/gic/gic_v3.c \
+ drivers/arm/gic/common/arm_gic_common.c \
+ drivers/arm/gic/v3/arm_gicv3_main.c \
+ drivers/arm/gic/v3/arm_gicv3_helpers.c \
drivers/arm/tzc400/tzc400.c \
plat/arm/common/arm_bl31_setup.c \
plat/arm/common/arm_pm.c \
diff --git a/plat/arm/common/tsp/arm_tsp.mk b/plat/arm/common/tsp/arm_tsp.mk
index f285f5857..a3862a876 100644
--- a/plat/arm/common/tsp/arm_tsp.mk
+++ b/plat/arm/common/tsp/arm_tsp.mk
@@ -29,8 +29,9 @@
#
# TSP source files common to ARM standard platforms
-BL32_SOURCES += drivers/arm/gic/arm_gic.c \
- drivers/arm/gic/gic_v2.c \
+BL32_SOURCES += drivers/arm/gic/common/arm_gic_common.c \
+ drivers/arm/gic/v3/arm_gicv3_main.c \
+ drivers/arm/gic/v3/arm_gicv3_helpers.c \
plat/arm/common/arm_topology.c \
plat/arm/common/tsp/arm_tsp_setup.c \
plat/common/aarch64/platform_mp_stack.S \
diff --git a/plat/common/plat_gic.c b/plat/common/plat_gic.c
index f736e55a8..bfe3e96cf 100644
--- a/plat/common/plat_gic.c
+++ b/plat/common/plat_gic.c
@@ -27,7 +27,8 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <arm_gic.h>
+#include <arm_gicv3.h>
+#include <platform.h>
/*
* The following platform GIC functions are weakly defined. They
@@ -43,31 +44,31 @@
uint32_t plat_ic_get_pending_interrupt_id(void)
{
- return arm_gic_get_pending_interrupt_id();
+ return arm_gicv3_get_pending_interrupt_id();
}
uint32_t plat_ic_get_pending_interrupt_type(void)
{
- return arm_gic_get_pending_interrupt_type();
+ return arm_gicv3_get_pending_interrupt_type();
}
uint32_t plat_ic_acknowledge_interrupt(void)
{
- return arm_gic_acknowledge_interrupt();
+ return arm_gicv3_acknowledge_interrupt();
}
uint32_t plat_ic_get_interrupt_type(uint32_t id)
{
- return arm_gic_get_interrupt_type(id);
+ return arm_gicv3_get_interrupt_type(id, plat_my_core_pos());
}
void plat_ic_end_of_interrupt(uint32_t id)
{
- arm_gic_end_of_interrupt(id);
+ arm_gicv3_end_of_interrupt(id);
}
uint32_t plat_interrupt_type_to_line(uint32_t type,
uint32_t security_state)
{
- return arm_gic_interrupt_type_to_line(type, security_state);
+ return arm_gicv3_interrupt_type_to_line(type, security_state);
}