summaryrefslogtreecommitdiffstats
path: root/bsps/include
diff options
context:
space:
mode:
authorKinsey Moore <kinsey.moore@oarcorp.com>2020-08-27 22:13:47 -0500
committerJoel Sherrill <joel@rtems.org>2020-10-05 16:11:39 -0500
commitf8ad5bb2a442b73536cc3cecfb65a2fc796bec70 (patch)
tree9f45b2a0b6d254772c94caa75854296d2501a770 /bsps/include
parentbsps: Break out AArch32 portions of GPT driver (diff)
downloadrtems-f8ad5bb2a442b73536cc3cecfb65a2fc796bec70.tar.bz2
bsps: Break out AArch32 GICv3 support
This breaks out AArch32-specific code so that the shared GICv3 code can be reused by other architectures.
Diffstat (limited to 'bsps/include')
-rw-r--r--bsps/include/dev/irq/arm-gic-irq.h143
-rw-r--r--bsps/include/dev/irq/arm-gic-regs.h217
-rw-r--r--bsps/include/dev/irq/arm-gic-tm27.h103
-rw-r--r--bsps/include/dev/irq/arm-gic.h242
4 files changed, 705 insertions, 0 deletions
diff --git a/bsps/include/dev/irq/arm-gic-irq.h b/bsps/include/dev/irq/arm-gic-irq.h
new file mode 100644
index 0000000000..a97191faca
--- /dev/null
+++ b/bsps/include/dev/irq/arm-gic-irq.h
@@ -0,0 +1,143 @@
+/**
+ * @file
+ *
+ * @ingroup arm_gic
+ *
+ * @brief ARM GIC IRQ
+ */
+
+/*
+ * Copyright (c) 2013, 2019 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef LIBBSP_ARM_SHARED_ARM_GIC_IRQ_H
+#define LIBBSP_ARM_SHARED_ARM_GIC_IRQ_H
+
+#include <bsp.h>
+#include <dev/irq/arm-gic.h>
+#include <rtems/score/processormask.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define ARM_GIC_IRQ_SGI_0 0
+#define ARM_GIC_IRQ_SGI_1 1
+#define ARM_GIC_IRQ_SGI_2 2
+#define ARM_GIC_IRQ_SGI_3 3
+#define ARM_GIC_IRQ_SGI_5 5
+#define ARM_GIC_IRQ_SGI_6 6
+#define ARM_GIC_IRQ_SGI_7 7
+#define ARM_GIC_IRQ_SGI_8 8
+#define ARM_GIC_IRQ_SGI_9 9
+#define ARM_GIC_IRQ_SGI_10 10
+#define ARM_GIC_IRQ_SGI_11 11
+#define ARM_GIC_IRQ_SGI_12 12
+#define ARM_GIC_IRQ_SGI_13 13
+#define ARM_GIC_IRQ_SGI_14 14
+#define ARM_GIC_IRQ_SGI_15 15
+
+#define ARM_GIC_DIST ((volatile gic_dist *) BSP_ARM_GIC_DIST_BASE)
+
+rtems_status_code arm_gic_irq_set_priority(
+ rtems_vector_number vector,
+ uint8_t priority
+);
+
+rtems_status_code arm_gic_irq_get_priority(
+ rtems_vector_number vector,
+ uint8_t *priority
+);
+
+rtems_status_code arm_gic_irq_set_group(
+ rtems_vector_number vector,
+ gic_group group
+);
+
+rtems_status_code arm_gic_irq_get_group(
+ rtems_vector_number vector,
+ gic_group *group
+);
+
+void bsp_interrupt_set_affinity(
+ rtems_vector_number vector,
+ const Processor_mask *affinity
+);
+
+void bsp_interrupt_get_affinity(
+ rtems_vector_number vector,
+ Processor_mask *affinity
+);
+
+typedef enum {
+ ARM_GIC_IRQ_SOFTWARE_IRQ_TO_ALL_IN_LIST,
+ ARM_GIC_IRQ_SOFTWARE_IRQ_TO_ALL_EXCEPT_SELF,
+ ARM_GIC_IRQ_SOFTWARE_IRQ_TO_SELF
+} arm_gic_irq_software_irq_target_filter;
+
+void arm_gic_trigger_sgi(
+ rtems_vector_number vector,
+ arm_gic_irq_software_irq_target_filter filter,
+ uint8_t targets
+);
+
+static inline rtems_status_code arm_gic_irq_generate_software_irq(
+ rtems_vector_number vector,
+ arm_gic_irq_software_irq_target_filter filter,
+ uint8_t targets
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+ if (vector <= ARM_GIC_IRQ_SGI_15) {
+ arm_gic_trigger_sgi(vector, filter, targets);
+ } else {
+ sc = RTEMS_INVALID_ID;
+ }
+
+ return sc;
+}
+
+/**
+ * This architecture-specific function sets the exception vector for handling
+ * IRQs.
+ */
+void arm_interrupt_facility_set_exception_handler(void);
+
+/**
+ * This architecture-specific function dispatches a triggered IRQ.
+ *
+ * @param[in] vector The vector on which the IRQ occurred.
+ */
+void arm_interrupt_handler_dispatch(rtems_vector_number vector);
+
+/**
+ * This is the GICv3 interrupt dispatcher that is to be called from the
+ * architecture-specific implementation of the IRQ handler.
+ */
+void gicv3_interrupt_dispatch(void);
+
+static inline uint32_t arm_gic_irq_processor_count(void)
+{
+ volatile gic_dist *dist = ARM_GIC_DIST;
+
+ return GIC_DIST_ICDICTR_CPU_NUMBER_GET(dist->icdictr) + 1;
+}
+
+void arm_gic_irq_initialize_secondary_cpu(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIBBSP_ARM_SHARED_ARM_GIC_IRQ_H */
diff --git a/bsps/include/dev/irq/arm-gic-regs.h b/bsps/include/dev/irq/arm-gic-regs.h
new file mode 100644
index 0000000000..8a65294b6f
--- /dev/null
+++ b/bsps/include/dev/irq/arm-gic-regs.h
@@ -0,0 +1,217 @@
+/**
+ * @file
+ *
+ * @ingroup arm_gic
+ *
+ * @brief ARM GIC Register definitions
+ */
+
+/*
+ * Copyright (c) 2013, 2019 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef LIBBSP_ARM_SHARED_ARM_GIC_REGS_H
+#define LIBBSP_ARM_SHARED_ARM_GIC_REGS_H
+
+#include <bsp/utility.h>
+
+typedef struct {
+ uint32_t iccicr;
+#define GIC_CPUIF_ICCICR_CBPR BSP_BIT32(4)
+#define GIC_CPUIF_ICCICR_FIQ_EN BSP_BIT32(3)
+#define GIC_CPUIF_ICCICR_ACK_CTL BSP_BIT32(2)
+#define GIC_CPUIF_ICCICR_ENABLE_GRP_1 BSP_BIT32(1)
+#define GIC_CPUIF_ICCICR_ENABLE BSP_BIT32(0)
+ uint32_t iccpmr;
+#define GIC_CPUIF_ICCPMR_PRIORITY(val) BSP_FLD32(val, 0, 7)
+#define GIC_CPUIF_ICCPMR_PRIORITY_GET(reg) BSP_FLD32GET(reg, 0, 7)
+#define GIC_CPUIF_ICCPMR_PRIORITY_SET(reg, val) BSP_FLD32SET(reg, val, 0, 7)
+ uint32_t iccbpr;
+#define GIC_CPUIF_ICCBPR_BINARY_POINT(val) BSP_FLD32(val, 0, 2)
+#define GIC_CPUIF_ICCBPR_BINARY_POINT_GET(reg) BSP_FLD32GET(reg, 0, 2)
+#define GIC_CPUIF_ICCBPR_BINARY_POINT_SET(reg, val) BSP_FLD32SET(reg, val, 0, 2)
+ uint32_t icciar;
+#define GIC_CPUIF_ICCIAR_CPUID(val) BSP_FLD32(val, 10, 12)
+#define GIC_CPUIF_ICCIAR_CPUID_GET(reg) BSP_FLD32GET(reg, 10, 12)
+#define GIC_CPUIF_ICCIAR_CPUID_SET(reg, val) BSP_FLD32SET(reg, val, 10, 12)
+#define GIC_CPUIF_ICCIAR_ACKINTID(val) BSP_FLD32(val, 0, 9)
+#define GIC_CPUIF_ICCIAR_ACKINTID_GET(reg) BSP_FLD32GET(reg, 0, 9)
+#define GIC_CPUIF_ICCIAR_ACKINTID_SET(reg, val) BSP_FLD32SET(reg, val, 0, 9)
+ uint32_t icceoir;
+#define GIC_CPUIF_ICCEOIR_CPUID(val) BSP_FLD32(val, 10, 12)
+#define GIC_CPUIF_ICCEOIR_CPUID_GET(reg) BSP_FLD32GET(reg, 10, 12)
+#define GIC_CPUIF_ICCEOIR_CPUID_SET(reg, val) BSP_FLD32SET(reg, val, 10, 12)
+#define GIC_CPUIF_ICCEOIR_EOIINTID(val) BSP_FLD32(val, 0, 9)
+#define GIC_CPUIF_ICCEOIR_EOIINTID_GET(reg) BSP_FLD32GET(reg, 0, 9)
+#define GIC_CPUIF_ICCEOIR_EOIINTID_SET(reg, val) BSP_FLD32SET(reg, val, 0, 9)
+ uint32_t iccrpr;
+#define GIC_CPUIF_ICCRPR_PRIORITY(val) BSP_FLD32(val, 0, 7)
+#define GIC_CPUIF_ICCRPR_PRIORITY_GET(reg) BSP_FLD32GET(reg, 0, 7)
+#define GIC_CPUIF_ICCRPR_PRIORITY_SET(reg, val) BSP_FLD32SET(reg, val, 0, 7)
+ uint32_t icchpir;
+#define GIC_CPUIF_ICCHPIR_CPUID(val) BSP_FLD32(val, 10, 12)
+#define GIC_CPUIF_ICCHPIR_CPUID_GET(reg) BSP_FLD32GET(reg, 10, 12)
+#define GIC_CPUIF_ICCHPIR_CPUID_SET(reg, val) BSP_FLD32SET(reg, val, 10, 12)
+#define GIC_CPUIF_ICCHPIR_PENDINTID(val) BSP_FLD32(val, 0, 9)
+#define GIC_CPUIF_ICCHPIR_PENDINTID_GET(reg) BSP_FLD32GET(reg, 0, 9)
+#define GIC_CPUIF_ICCHPIR_PENDINTID_SET(reg, val) BSP_FLD32SET(reg, val, 0, 9)
+ uint32_t iccabpr;
+#define GIC_CPUIF_ICCABPR_BINARY_POINT(val) BSP_FLD32(val, 0, 2)
+#define GIC_CPUIF_ICCABPR_BINARY_POINT_GET(reg) BSP_FLD32GET(reg, 0, 2)
+#define GIC_CPUIF_ICCABPR_BINARY_POINT_SET(reg, val) BSP_FLD32SET(reg, val, 0, 2)
+ uint32_t reserved_20[55];
+ uint32_t icciidr;
+#define GIC_CPUIF_ICCIIDR_PRODUCT_ID(val) BSP_FLD32(val, 24, 31)
+#define GIC_CPUIF_ICCIIDR_PRODUCT_ID_GET(reg) BSP_FLD32GET(reg, 24, 31)
+#define GIC_CPUIF_ICCIIDR_PRODUCT_ID_SET(reg, val) BSP_FLD32SET(reg, val, 24, 31)
+#define GIC_CPUIF_ICCIIDR_ARCH_VERSION(val) BSP_FLD32(val, 16, 19)
+#define GIC_CPUIF_ICCIIDR_ARCH_VERSION_GET(reg) BSP_FLD32GET(reg, 16, 19)
+#define GIC_CPUIF_ICCIIDR_ARCH_VERSION_SET(reg, val) BSP_FLD32SET(reg, val, 16, 19)
+#define GIC_CPUIF_ICCIIDR_REVISION(val) BSP_FLD32(val, 12, 15)
+#define GIC_CPUIF_ICCIIDR_REVISION_GET(reg) BSP_FLD32GET(reg, 12, 15)
+#define GIC_CPUIF_ICCIIDR_REVISION_SET(reg, val) BSP_FLD32SET(reg, val, 12, 15)
+#define GIC_CPUIF_ICCIIDR_IMPLEMENTER(val) BSP_FLD32(val, 0, 11)
+#define GIC_CPUIF_ICCIIDR_IMPLEMENTER_GET(reg) BSP_FLD32GET(reg, 0, 11)
+#define GIC_CPUIF_ICCIIDR_IMPLEMENTER_SET(reg, val) BSP_FLD32SET(reg, val, 0, 11)
+} gic_cpuif;
+
+typedef struct {
+ /* GICD_CTLR */
+ uint32_t icddcr;
+/* GICv3 only */
+#define GIC_DIST_ICDDCR_RWP BSP_BIT32(31)
+#define GIC_DIST_ICDDCR_E1NWF BSP_BIT32(7)
+#define GIC_DIST_ICDDCR_DS BSP_BIT32(6)
+#define GIC_DIST_ICDDCR_ARE_NS BSP_BIT32(5)
+#define GIC_DIST_ICDDCR_ARE_S BSP_BIT32(4)
+#define GIC_DIST_ICDDCR_ENABLE_GRP1S BSP_BIT32(2)
+#define GIC_DIST_ICDDCR_ENABLE_GRP1NS BSP_BIT32(1)
+#define GIC_DIST_ICDDCR_ENABLE_GRP0 BSP_BIT32(0)
+/* GICv1/GICv2 */
+#define GIC_DIST_ICDDCR_ENABLE_GRP_1 BSP_BIT32(1)
+#define GIC_DIST_ICDDCR_ENABLE BSP_BIT32(0)
+ uint32_t icdictr;
+#define GIC_DIST_ICDICTR_LSPI(val) BSP_FLD32(val, 11, 15)
+#define GIC_DIST_ICDICTR_LSPI_GET(reg) BSP_FLD32GET(reg, 11, 15)
+#define GIC_DIST_ICDICTR_LSPI_SET(reg, val) BSP_FLD32SET(reg, val, 11, 15)
+#define GIC_DIST_ICDICTR_SECURITY_EXTN BSP_BIT32(10)
+#define GIC_DIST_ICDICTR_CPU_NUMBER(val) BSP_FLD32(val, 5, 7)
+#define GIC_DIST_ICDICTR_CPU_NUMBER_GET(reg) BSP_FLD32GET(reg, 5, 7)
+#define GIC_DIST_ICDICTR_CPU_NUMBER_SET(reg, val) BSP_FLD32SET(reg, val, 5, 7)
+#define GIC_DIST_ICDICTR_IT_LINES_NUMBER(val) BSP_FLD32(val, 0, 4)
+#define GIC_DIST_ICDICTR_IT_LINES_NUMBER_GET(reg) BSP_FLD32GET(reg, 0, 4)
+#define GIC_DIST_ICDICTR_IT_LINES_NUMBER_SET(reg, val) BSP_FLD32SET(reg, val, 0, 4)
+ uint32_t icdiidr;
+#define GIC_DIST_ICDIIDR_PRODUCT_ID(val) BSP_FLD32(val, 24, 31)
+#define GIC_DIST_ICDIIDR_PRODUCT_ID_GET(reg) BSP_FLD32GET(reg, 24, 31)
+#define GIC_DIST_ICDIIDR_PRODUCT_ID_SET(reg, val) BSP_FLD32SET(reg, val, 24, 31)
+#define GIC_DIST_ICDIIDR_VARIANT(val) BSP_FLD32(val, 16, 19)
+#define GIC_DIST_ICDIIDR_VARIANT_GET(reg) BSP_FLD32GET(reg, 16, 19)
+#define GIC_DIST_ICDIIDR_VARIANT_SET(reg, val) BSP_FLD32SET(reg, val, 16, 19)
+#define GIC_DIST_ICDIIDR_REVISION(val) BSP_FLD32(val, 12, 15)
+#define GIC_DIST_ICDIIDR_REVISION_GET(reg) BSP_FLD32GET(reg, 12, 15)
+#define GIC_DIST_ICDIIDR_REVISION_SET(reg, val) BSP_FLD32SET(reg, val, 12, 15)
+#define GIC_DIST_ICDIIDR_IMPLEMENTER(val) BSP_FLD32(val, 0, 11)
+#define GIC_DIST_ICDIIDR_IMPLEMENTER_GET(reg) BSP_FLD32GET(reg, 0, 11)
+#define GIC_DIST_ICDIIDR_IMPLEMENTER_SET(reg, val) BSP_FLD32SET(reg, val, 0, 11)
+ uint32_t reserved_0c[29];
+ uint32_t icdigr[32];
+ uint32_t icdiser[32];
+ uint32_t icdicer[32];
+ uint32_t icdispr[32];
+ uint32_t icdicpr[32];
+ uint32_t icdabr[32];
+ uint32_t reserved_380[32];
+ uint8_t icdipr[256];
+ uint32_t reserved_500[192];
+ uint8_t icdiptr[256];
+ uint32_t reserved_900[192];
+ uint32_t icdicfr[64];
+ /* GICD_IGRPMODR GICv3 only, reserved in GICv1/GICv2 */
+ uint32_t icdigmr[32];
+ uint32_t reserved_d80[96];
+ uint32_t icdsgir;
+#define GIC_DIST_ICDSGIR_TARGET_LIST_FILTER(val) BSP_FLD32(val, 24, 25)
+#define GIC_DIST_ICDSGIR_TARGET_LIST_FILTER_GET(reg) BSP_FLD32GET(reg, 24, 25)
+#define GIC_DIST_ICDSGIR_TARGET_LIST_FILTER_SET(reg, val) BSP_FLD32SET(reg, val, 24, 25)
+#define GIC_DIST_ICDSGIR_CPU_TARGET_LIST(val) BSP_FLD32(val, 16, 23)
+#define GIC_DIST_ICDSGIR_CPU_TARGET_LIST_GET(reg) BSP_FLD32GET(reg, 16, 23)
+#define GIC_DIST_ICDSGIR_CPU_TARGET_LIST_SET(reg, val) BSP_FLD32SET(reg, val, 16, 23)
+#define GIC_DIST_ICDSGIR_NSATT BSP_BIT32(15)
+#define GIC_DIST_ICDSGIR_SGIINTID(val) BSP_FLD32(val, 0, 3)
+#define GIC_DIST_ICDSGIR_SGIINTID_GET(reg) BSP_FLD32GET(reg, 0, 3)
+#define GIC_DIST_ICDSGIR_SGIINTID_SET(reg, val) BSP_FLD32SET(reg, val, 0, 3)
+} gic_dist;
+
+/* GICv3 only */
+typedef struct {
+ /* GICR_CTLR */
+ uint32_t icrrcr;
+#define GIC_REDIST_ICRRCR_UWP BSP_BIT32(31)
+#define GIC_REDIST_ICRRCR_DPG1S BSP_BIT32(26)
+#define GIC_REDIST_ICRRCR_DPG1NS BSP_BIT32(25)
+#define GIC_REDIST_ICRRCR_DPG0 BSP_BIT32(24)
+#define GIC_REDIST_ICRRCR_RWP BSP_BIT32(4)
+#define GIC_REDIST_ICRRCR_ENABLE_LPI BSP_BIT32(0)
+ uint32_t icriidr;
+ uint64_t icrtyper;
+#define GIC_REDIST_ICRTYPER_AFFINITY_VALUE(val) BSP_FLD64(val, 32, 63)
+#define GIC_REDIST_ICRTYPER_AFFINITY_VALUE_GET(reg) BSP_FLD64GET(reg, 32, 63)
+#define GIC_REDIST_ICRTYPER_AFFINITY_VALUE_SET(reg, val) BSP_FLD64SET(reg, val, 32, 63)
+#define GIC_REDIST_ICRTYPER_COMMON_LPI_AFFINITY(val) BSP_FLD64(val, 24, 25)
+#define GIC_REDIST_ICRTYPER_COMMON_LPI_AFFINITY_GET(reg) BSP_FLD64GET(reg, 24, 25)
+#define GIC_REDIST_ICRTYPER_COMMON_LPI_AFFINITY_SET(reg, val) BSP_FLD64SET(reg, val, 24, 25)
+#define GIC_REDIST_ICRTYPER_CPU_NUMBER(val) BSP_FLD64(val, 8, 23)
+#define GIC_REDIST_ICRTYPER_CPU_NUMBER_GET(reg) BSP_FLD64GET(reg, 8, 23)
+#define GIC_REDIST_ICRTYPER_CPU_NUMBER_SET(reg, val) BSP_FLD64SET(reg, val, 8, 23)
+#define GIC_REDIST_ICRTYPER_DPGS BSP_BIT64(5)
+#define GIC_REDIST_ICRTYPER_LAST BSP_BIT64(4)
+#define GIC_REDIST_ICRTYPER_DIRECT_LPI BSP_BIT64(3)
+#define GIC_REDIST_ICRTYPER_VLPIS BSP_BIT64(1)
+#define GIC_REDIST_ICRTYPER_PLPIS BSP_BIT64(0)
+ uint32_t unused_10;
+ uint32_t icrwaker;
+#define GIC_REDIST_ICRWAKER_CHILDREN_ASLEEP BSP_BIT32(2)
+#define GIC_REDIST_ICRWAKER_PROCESSOR_SLEEP BSP_BIT32(1)
+} gic_redist;
+
+/* GICv3 only */
+typedef struct {
+ uint32_t reserved_0_80[32];
+ /* GICR_IGROUPR0 */
+ uint32_t icspigrpr[32];
+ /* GICR_ISENABLER0 */
+ uint32_t icspiser[32];
+ /* GICR_ICENABLER0 */
+ uint32_t icspicer[32];
+ /* GICR_ISPENDR0 */
+ uint32_t icspispendr[32];
+ /* GICR_ICPENDR0 */
+ uint32_t icspicpendr[32];
+ /* GICR_ISACTIVER0 */
+ uint32_t icspisar[32];
+ /* GICR_ICACTIVER0 */
+ uint32_t icspicar[32];
+ /* GICR_IPRIORITYR */
+ uint8_t icspiprior[32];
+ uint32_t reserved_420_bfc[504];
+ /* GICR_ICFGR0 */
+ uint32_t icspicfgr0;
+ /* GICR_ICFGR1 */
+ uint32_t icspicfgr1;
+ uint32_t reserved_c08_cfc[62];
+ /* GICR_IGRPMODR0 */
+ uint32_t icspigrpmodr[64];
+} gic_sgi_ppi;
+
+#endif /* LIBBSP_ARM_SHARED_ARM_GIC_REGS_H */
diff --git a/bsps/include/dev/irq/arm-gic-tm27.h b/bsps/include/dev/irq/arm-gic-tm27.h
new file mode 100644
index 0000000000..95f3077716
--- /dev/null
+++ b/bsps/include/dev/irq/arm-gic-tm27.h
@@ -0,0 +1,103 @@
+/**
+ * @file
+ *
+ * @ingroup arm_gic
+ *
+ * @brief ARM GIC TM27 Support
+ */
+
+/*
+ * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_TMTEST27
+#error "This is an RTEMS internal file you must not include directly."
+#endif
+
+#ifndef LIBBSP_ARM_SHARED_ARM_GIC_TM27_H
+#define LIBBSP_ARM_SHARED_ARM_GIC_TM27_H
+
+#include <assert.h>
+
+#include <bsp.h>
+#include <bsp/irq.h>
+
+#define MUST_WAIT_FOR_INTERRUPT 1
+
+#define ARM_GIC_TM27_IRQ_LOW ARM_GIC_IRQ_SGI_12
+
+#define ARM_GIC_TM27_IRQ_HIGH ARM_GIC_IRQ_SGI_13
+
+#define ARM_GIC_TM27_PRIO_LOW 0x80
+
+#define ARM_GIC_TM27_PRIO_HIGH 0x00
+
+static inline void Install_tm27_vector(void (*handler)(rtems_vector_number))
+{
+ rtems_status_code sc = rtems_interrupt_handler_install(
+ ARM_GIC_TM27_IRQ_LOW,
+ "tm27 low",
+ RTEMS_INTERRUPT_UNIQUE,
+ (rtems_interrupt_handler) handler,
+ NULL
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = arm_gic_irq_set_priority(
+ ARM_GIC_TM27_IRQ_LOW,
+ ARM_GIC_TM27_PRIO_LOW
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_interrupt_handler_install(
+ ARM_GIC_TM27_IRQ_HIGH,
+ "tm27 high",
+ RTEMS_INTERRUPT_UNIQUE,
+ (rtems_interrupt_handler) handler,
+ NULL
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = arm_gic_irq_set_priority(
+ ARM_GIC_TM27_IRQ_HIGH,
+ ARM_GIC_TM27_PRIO_HIGH
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static inline void Cause_tm27_intr(void)
+{
+ rtems_status_code sc = arm_gic_irq_generate_software_irq(
+ ARM_GIC_TM27_IRQ_LOW,
+ ARM_GIC_IRQ_SOFTWARE_IRQ_TO_SELF,
+ 0
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static inline void Clear_tm27_intr(void)
+{
+ /* Nothing to do */
+}
+
+static inline void Lower_tm27_intr(void)
+{
+ rtems_status_code sc = arm_gic_irq_generate_software_irq(
+ ARM_GIC_TM27_IRQ_HIGH,
+ ARM_GIC_IRQ_SOFTWARE_IRQ_TO_SELF,
+ 0
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+}
+
+#endif /* LIBBSP_ARM_SHARED_ARM_GIC_TM27_H */
diff --git a/bsps/include/dev/irq/arm-gic.h b/bsps/include/dev/irq/arm-gic.h
new file mode 100644
index 0000000000..23c70e7b0e
--- /dev/null
+++ b/bsps/include/dev/irq/arm-gic.h
@@ -0,0 +1,242 @@
+/**
+ * @file
+ *
+ * @ingroup arm_gic
+ *
+ * @brief ARM GIC Support
+ */
+
+/*
+ * Copyright (c) 2013, 2019 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <info@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef LIBBSP_ARM_SHARED_ARM_GIC_H
+#define LIBBSP_ARM_SHARED_ARM_GIC_H
+
+#include <dev/irq/arm-gic-regs.h>
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup arm_gic ARM GIC
+ *
+ * @ingroup RTEMSBSPsARMShared
+ *
+ * @brief ARM_GIC Support Package
+ */
+
+#define GIC_ID_TO_ONE_BIT_REG_INDEX(id) ((id) >> 5)
+#define GIC_ID_TO_ONE_BIT_REG_BIT(id) (1U << ((id) & 0x1fU))
+
+#define GIC_ID_TO_TWO_BITS_REG_INDEX(id) ((id) >> 4)
+#define GIC_ID_TO_TWO_BITS_REG_OFFSET(id) (((id) & 0xfU) << 1)
+
+static inline bool gic_id_is_enabled(volatile gic_dist *dist, uint32_t id)
+{
+ uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
+ uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
+
+ return (dist->icdiser[i] & bit) != 0;
+}
+
+static inline void gic_id_enable(volatile gic_dist *dist, uint32_t id)
+{
+ uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
+ uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
+
+ dist->icdiser[i] = bit;
+}
+
+static inline void gic_id_disable(volatile gic_dist *dist, uint32_t id)
+{
+ uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
+ uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
+
+ dist->icdicer[i] = bit;
+}
+
+static inline bool gic_id_is_pending(volatile gic_dist *dist, uint32_t id)
+{
+ uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
+ uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
+
+ return (dist->icdispr[i] & bit) != 0;
+}
+
+static inline void gic_id_set_pending(volatile gic_dist *dist, uint32_t id)
+{
+ uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
+ uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
+
+ dist->icdispr[i] = bit;
+}
+
+static inline void gic_id_clear_pending(volatile gic_dist *dist, uint32_t id)
+{
+ uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
+ uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
+
+ dist->icdicpr[i] = bit;
+}
+
+static inline bool gic_id_is_active(volatile gic_dist *dist, uint32_t id)
+{
+ uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
+ uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
+
+ return (dist->icdabr[i] & bit) != 0;
+}
+
+typedef enum {
+ GIC_GROUP_0,
+ GIC_GROUP_1
+} gic_group;
+
+static inline gic_group gic_id_get_group(
+ volatile gic_dist *dist,
+ uint32_t id
+)
+{
+ uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
+ uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
+
+ return (dist->icdigr[i] & bit) != 0 ? GIC_GROUP_1 : GIC_GROUP_0;
+}
+
+static inline void gic_id_set_group(
+ volatile gic_dist *dist,
+ uint32_t id,
+ gic_group group
+)
+{
+ uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
+ uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
+ uint32_t icdigr = dist->icdigr[i];
+
+ icdigr &= ~bit;
+
+ if (group == GIC_GROUP_1) {
+ icdigr |= bit;
+ }
+
+ dist->icdigr[i] = icdigr;
+}
+
+static inline void gic_id_set_priority(
+ volatile gic_dist *dist,
+ uint32_t id,
+ uint8_t priority
+)
+{
+ dist->icdipr[id] = priority;
+}
+
+static inline uint8_t gic_id_get_priority(volatile gic_dist *dist, uint32_t id)
+{
+ return dist->icdipr[id];
+}
+
+static inline void gic_id_set_targets(
+ volatile gic_dist *dist,
+ uint32_t id,
+ uint8_t targets
+)
+{
+ dist->icdiptr[id] = targets;
+}
+
+static inline uint8_t gic_id_get_targets(volatile gic_dist *dist, uint32_t id)
+{
+ return dist->icdiptr[id];
+}
+
+typedef enum {
+ GIC_LEVEL_SENSITIVE,
+ GIC_EDGE_TRIGGERED
+} gic_trigger_mode;
+
+static inline gic_trigger_mode gic_id_get_trigger_mode(
+ volatile gic_dist *dist,
+ uint32_t id
+)
+{
+ uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
+ uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id) + 1;
+ uint32_t bit = 1U << o;
+
+ return (dist->icdicfr[i] & bit) != 0 ?
+ GIC_EDGE_TRIGGERED : GIC_LEVEL_SENSITIVE;
+}
+
+static inline void gic_id_set_trigger_mode(
+ volatile gic_dist *dist,
+ uint32_t id,
+ gic_trigger_mode mode
+)
+{
+ uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
+ uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id) + 1;
+ uint32_t bit = mode << o;
+ uint32_t mask = 1U << o;
+ uint32_t icdicfr = dist->icdicfr[i];
+
+ icdicfr &= ~mask;
+ icdicfr |= bit;
+
+ dist->icdicfr[i] = icdicfr;
+}
+
+typedef enum {
+ GIC_N_TO_N,
+ GIC_1_TO_N
+} gic_handling_model;
+
+static inline gic_handling_model gic_id_get_handling_model(
+ volatile gic_dist *dist,
+ uint32_t id
+)
+{
+ uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
+ uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id);
+ uint32_t bit = 1U << o;
+
+ return (dist->icdicfr[i] & bit) != 0 ? GIC_1_TO_N : GIC_N_TO_N;
+}
+
+static inline void gic_id_set_handling_model(
+ volatile gic_dist *dist,
+ uint32_t id,
+ gic_handling_model model
+)
+{
+ uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
+ uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id);
+ uint32_t bit = model << o;
+ uint32_t mask = 1U << o;
+ uint32_t icdicfr = dist->icdicfr[i];
+
+ icdicfr &= ~mask;
+ icdicfr |= bit;
+
+ dist->icdicfr[i] = icdicfr;
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIBBSP_ARM_SHARED_ARM_GIC_H */