plat/arm/board/arm_fpga: Initialize the Generic Interrupt Controller
This initializes the GIC using the Arm GIC drivers in TF-A.
The initial FPGA image uses a GIC600 implementation, and so that its
power controller is enabled, this platform port calls the corresponding
implementation-specific routines.
Signed-off-by: Oliver Swede <oli.swede@arm.com>
Change-Id: I88d5a073eead4b653b1ca73273182cd98a95e4c5
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
index 26228f6..d499379 100644
--- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c
+++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c
@@ -51,11 +51,12 @@
void bl31_platform_setup(void)
{
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ plat_fpga_gic_init();
+
/* Write frequency to CNTCRL and initialize timer */
generic_delay_timer_init();
mmio_write_32(FPGA_TIMER_BASE, ((1 << 8) | 1UL));
-
- /* TODO: initialize GIC using the specifications of the FPGA image */
}
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c
new file mode 100644
index 0000000..be1684e
--- /dev/null
+++ b/plat/arm/board/arm_fpga/fpga_gicv3.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/gicv3.h>
+#include <drivers/arm/gic_common.h>
+
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+static const interrupt_prop_t fpga_interrupt_props[] = {
+ PLATFORM_G1S_PROPS(INTR_GROUP1S),
+ PLATFORM_G0_PROPS(INTR_GROUP0)
+};
+
+static uintptr_t fpga_rdistif_base_addrs[PLATFORM_CORE_COUNT];
+
+static unsigned int fpga_mpidr_to_core_pos(unsigned long mpidr)
+{
+ return (unsigned int)plat_core_pos_by_mpidr(mpidr);
+}
+
+static const gicv3_driver_data_t fpga_gicv3_driver_data = {
+ .gicd_base = GICD_BASE,
+ .gicr_base = GICR_BASE,
+ .interrupt_props = fpga_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(fpga_interrupt_props),
+ .rdistif_num = PLATFORM_CORE_COUNT,
+ .rdistif_base_addrs = fpga_rdistif_base_addrs,
+ .mpidr_to_core_pos = fpga_mpidr_to_core_pos
+};
+
+void plat_fpga_gic_init(void)
+{
+ gicv3_driver_init(&fpga_gicv3_driver_data);
+ gicv3_distif_init();
+ gicv3_rdistif_init(plat_my_core_pos());
+ gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+void fpga_pwr_gic_on_finish(void)
+{
+ gicv3_rdistif_init(plat_my_core_pos());
+ gicv3_cpuif_enable(plat_my_core_pos());
+}
+
+void fpga_pwr_gic_off(void)
+{
+ gicv3_cpuif_disable(plat_my_core_pos());
+ gicv3_rdistif_off(plat_my_core_pos());
+}
diff --git a/plat/arm/board/arm_fpga/fpga_pm.c b/plat/arm/board/arm_fpga/fpga_pm.c
index a734e1d..4c37217 100644
--- a/plat/arm/board/arm_fpga/fpga_pm.c
+++ b/plat/arm/board/arm_fpga/fpga_pm.c
@@ -9,6 +9,8 @@
#include <lib/psci/psci.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
+
+#include "fpga_private.h"
#include <platform_def.h>
/*
@@ -52,8 +54,15 @@
return PSCI_E_SUCCESS;
}
+void fpga_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ fpga_pwr_gic_on_finish();
+}
+
static void fpga_pwr_domain_off(const psci_power_state_t *target_state)
{
+ fpga_pwr_gic_off();
+
while (1) {
wfi();
}
@@ -74,6 +83,7 @@
plat_psci_ops_t plat_fpga_psci_pm_ops = {
.pwr_domain_on = fpga_pwr_domain_on,
+ .pwr_domain_on_finish = fpga_pwr_domain_on_finish,
.pwr_domain_off = fpga_pwr_domain_off,
.cpu_standby = fpga_cpu_standby
};
diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h
index 28aaef2..7545bd1 100644
--- a/plat/arm/board/arm_fpga/fpga_private.h
+++ b/plat/arm/board/arm_fpga/fpga_private.h
@@ -11,4 +11,8 @@
void fpga_console_init(void);
+void plat_fpga_gic_init(void);
+void fpga_pwr_gic_on_finish(void);
+void fpga_pwr_gic_off(void);
+
#endif
diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h
index bf3245e..6e87a26 100644
--- a/plat/arm/board/arm_fpga/include/platform_def.h
+++ b/plat/arm/board/arm_fpga/include/platform_def.h
@@ -28,8 +28,51 @@
#define BL31_BASE UL(0x80000000)
#define BL31_LIMIT UL(0x80100000)
-#define PLAT_MAX_RET_STATE 1
-#define PLAT_MAX_OFF_STATE 2
+#define GICD_BASE 0x30000000
+#define GICR_BASE 0x30040000
+
+#define PLAT_SDEI_NORMAL_PRI 0x70
+
+#define ARM_IRQ_SEC_PHY_TIMER 29
+
+#define ARM_IRQ_SEC_SGI_0 8
+#define ARM_IRQ_SEC_SGI_1 9
+#define ARM_IRQ_SEC_SGI_2 10
+#define ARM_IRQ_SEC_SGI_3 11
+#define ARM_IRQ_SEC_SGI_4 12
+#define ARM_IRQ_SEC_SGI_5 13
+#define ARM_IRQ_SEC_SGI_6 14
+#define ARM_IRQ_SEC_SGI_7 15
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLATFORM_G1S_PROPS(grp) \
+ INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE)
+
+#define PLATFORM_G0_PROPS(grp) \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp), \
+ GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, (grp), \
+ GIC_INTR_CFG_EDGE)
+
+#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_OFF_STATE 2
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index 73e1870..8ce0ae0 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -37,9 +37,14 @@
FPGA_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S \
lib/cpus/aarch64/neoverse_zeus.S
-FPGA_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
- drivers/arm/gic/v3/gicv3_main.c \
- plat/common/plat_gicv3.c
+FPGA_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \
+ drivers/arm/gic/v3/gicdv3_helpers.c \
+ drivers/arm/gic/v3/gicrv3_helpers.c \
+ drivers/arm/gic/v3/gicv3_main.c \
+ drivers/arm/gic/v3/gic600.c \
+ drivers/arm/gic/common/gic_common.c \
+ plat/common/plat_gicv3.c \
+ plat/arm/board/arm_fpga/fpga_gicv3.c
PLAT_INCLUDES := -Iplat/arm/board/arm_fpga/include