From 76918e180a540c3705ab50300117345b024fdc0f Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 28 Feb 2019 10:40:10 +0100 Subject: bsps/arm: Add BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0 The following variants * GICv1 with Security Extensions, * GICv2 without Security Extensions, or * within Secure processor mode have the ability to assign group 0 or 1 to individual interrupts. Group 0 interrupts can be configured to raise an FIQ exception. This enables the use of NMIs with respect to RTEMS. BSPs can enable this feature with the BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0 define. Use arm_gic_irq_set_group() to change the group of an interrupt (default group is 1, if BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0 is defined). --- bsps/arm/include/bsp/arm-gic-irq.h | 3 +++ bsps/arm/shared/irq/irq-gic.c | 54 +++++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 3 deletions(-) (limited to 'bsps/arm') diff --git a/bsps/arm/include/bsp/arm-gic-irq.h b/bsps/arm/include/bsp/arm-gic-irq.h index fa0d63d063..b3e893de72 100644 --- a/bsps/arm/include/bsp/arm-gic-irq.h +++ b/bsps/arm/include/bsp/arm-gic-irq.h @@ -98,6 +98,9 @@ static inline rtems_status_code arm_gic_irq_generate_software_irq( dist->icdsgir = GIC_DIST_ICDSGIR_TARGET_LIST_FILTER(filter) | GIC_DIST_ICDSGIR_CPU_TARGET_LIST(targets) +#ifdef BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0 + | GIC_DIST_ICDSGIR_NSATT +#endif | GIC_DIST_ICDSGIR_SGIINTID(vector); } else { sc = RTEMS_INVALID_ID; diff --git a/bsps/arm/shared/irq/irq-gic.c b/bsps/arm/shared/irq/irq-gic.c index 6f525b753d..65a7e6f653 100644 --- a/bsps/arm/shared/irq/irq-gic.c +++ b/bsps/arm/shared/irq/irq-gic.c @@ -26,6 +26,33 @@ #define PRIORITY_DEFAULT 127 +/* + * The following variants + * + * - GICv1 with Security Extensions, + * - GICv2 without Security Extensions, or + * - within Secure processor mode + * + * have the ability to assign group 0 or 1 to individual interrupts. Group + * 0 interrupts can be configured to raise an FIQ exception. This enables + * the use of NMIs with respect to RTEMS. + * + * BSPs can enable this feature with the BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0 + * define. Use arm_gic_irq_set_group() to change the group of an + * interrupt (default group is 1, if BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0 is + * defined). + */ +#ifdef BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0 +#define DIST_ICDDCR (GIC_DIST_ICDDCR_ENABLE_GRP_1 | GIC_DIST_ICDDCR_ENABLE) +#define CPUIF_ICCICR \ + (GIC_CPUIF_ICCICR_CBPR | GIC_CPUIF_ICCICR_FIQ_EN \ + | GIC_CPUIF_ICCICR_ACK_CTL | GIC_CPUIF_ICCICR_ENABLE_GRP_1 \ + | GIC_CPUIF_ICCICR_ENABLE) +#else +#define DIST_ICDDCR GIC_DIST_ICDDCR_ENABLE +#define CPUIF_ICCICR GIC_CPUIF_ICCICR_ENABLE +#endif + void bsp_interrupt_dispatch(void) { volatile gic_cpuif *cpuif = GIC_CPUIF; @@ -72,6 +99,17 @@ static inline uint32_t get_id_count(volatile gic_dist *dist) return id_count; } +static void enable_fiq(void) +{ +#ifdef BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0 + rtems_interrupt_level level; + + rtems_interrupt_local_disable(level); + level &= ~ARM_PSR_F; + rtems_interrupt_local_enable(level); +#endif +} + rtems_status_code bsp_interrupt_facility_initialize(void) { volatile gic_cpuif *cpuif = GIC_CPUIF; @@ -85,6 +123,9 @@ rtems_status_code bsp_interrupt_facility_initialize(void) ); for (id = 0; id < id_count; id += 32) { +#ifdef BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0 + dist->icdigr[id / 32] = 0xffffffff; +#endif dist->icdicer[id / 32] = 0xffffffff; } @@ -98,10 +139,11 @@ rtems_status_code bsp_interrupt_facility_initialize(void) cpuif->iccpmr = GIC_CPUIF_ICCPMR_PRIORITY(0xff); cpuif->iccbpr = GIC_CPUIF_ICCBPR_BINARY_POINT(0x0); - cpuif->iccicr = GIC_CPUIF_ICCICR_ENABLE; + cpuif->iccicr = CPUIF_ICCICR; - dist->icddcr = GIC_DIST_ICDDCR_ENABLE; + dist->icddcr = GIC_DIST_ICDDCR_ENABLE_GRP_1 | GIC_DIST_ICDDCR_ENABLE; + enable_fiq(); return RTEMS_SUCCESSFUL; } @@ -115,9 +157,15 @@ BSP_START_TEXT_SECTION void arm_gic_irq_initialize_secondary_cpu(void) /* Wait */ } +#ifdef BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0 + dist->icdigr[0] = 0xffffffff; +#endif + cpuif->iccpmr = GIC_CPUIF_ICCPMR_PRIORITY(0xff); cpuif->iccbpr = GIC_CPUIF_ICCBPR_BINARY_POINT(0x0); - cpuif->iccicr = GIC_CPUIF_ICCICR_ENABLE; + cpuif->iccicr = CPUIF_ICCICR; + + enable_fiq(); } #endif -- cgit v1.2.3