summaryrefslogtreecommitdiffstats
path: root/bsps/shared/dev/irq
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/shared/dev/irq')
-rw-r--r--bsps/shared/dev/irq/arm-gicv2-get-attributes.c72
-rw-r--r--bsps/shared/dev/irq/arm-gicv2-zynqmp.c78
-rw-r--r--bsps/shared/dev/irq/arm-gicv2.c132
-rw-r--r--bsps/shared/dev/irq/arm-gicv3.c332
4 files changed, 281 insertions, 333 deletions
diff --git a/bsps/shared/dev/irq/arm-gicv2-get-attributes.c b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c
new file mode 100644
index 0000000000..613174bb3a
--- /dev/null
+++ b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup DevIRQGIC
+ *
+ * @brief This source file contains the implementation of
+ * bsp_interrupt_get_attributes() for the GICv2.
+ */
+
+/*
+ * Copyright (C) 2013, 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dev/irq/arm-gic.h>
+#include <bsp/irq-generic.h>
+
+rtems_status_code bsp_interrupt_get_attributes(
+ rtems_vector_number vector,
+ rtems_interrupt_attributes *attributes
+)
+{
+ attributes->is_maskable = true;
+ attributes->maybe_enable = true;
+ attributes->maybe_disable = true;
+ attributes->can_raise = true;
+
+ if ( vector <= ARM_GIC_IRQ_SGI_LAST ) {
+ /*
+ * It is implementation-defined whether implemented SGIs are permanently
+ * enabled, or can be enabled and disabled by writes to GICD_ISENABLER0 and
+ * GICD_ICENABLER0.
+ */
+ attributes->can_raise_on = true;
+ attributes->cleared_by_acknowledge = true;
+ attributes->trigger_signal = RTEMS_INTERRUPT_NO_SIGNAL;
+ } else {
+ attributes->can_disable = true;
+ attributes->can_clear = true;
+ attributes->trigger_signal = RTEMS_INTERRUPT_UNSPECIFIED_SIGNAL;
+
+ if ( vector > ARM_GIC_IRQ_PPI_LAST ) {
+ /* SPI */
+ attributes->can_get_affinity = true;
+ attributes->can_set_affinity = true;
+ }
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/shared/dev/irq/arm-gicv2-zynqmp.c b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c
new file mode 100644
index 0000000000..bb9bfafb48
--- /dev/null
+++ b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup DevIRQGIC
+ *
+ * @brief This source file contains the implementation of
+ * bsp_interrupt_get_attributes() for the GICv2 of Xilinx Zynq UltraScale+
+ * MPSoC and RFSoC devices.
+ */
+
+/*
+ * Copyright (C) 2021 On-Line Applications Research Corporation (OAR)
+ * Written by Kinsey Moore <kinsey.moore@oarcorp.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dev/irq/arm-gic.h>
+#include <bsp/irq-generic.h>
+
+rtems_status_code bsp_interrupt_get_attributes(
+ rtems_vector_number vector,
+ rtems_interrupt_attributes *attributes
+)
+{
+ attributes->is_maskable = true;
+ attributes->maybe_enable = true;
+ attributes->maybe_disable = true;
+ attributes->can_raise = true;
+
+ if ( vector <= ARM_GIC_IRQ_SGI_LAST ) {
+ /*
+ * It is implementation-defined whether implemented SGIs are permanently
+ * enabled, or can be enabled and disabled by writes to GICD_ISENABLER0 and
+ * GICD_ICENABLER0.
+ */
+ attributes->can_raise_on = true;
+ attributes->cleared_by_acknowledge = true;
+ attributes->trigger_signal = RTEMS_INTERRUPT_NO_SIGNAL;
+ } else {
+ attributes->can_disable = true;
+ attributes->can_clear = true;
+ attributes->trigger_signal = RTEMS_INTERRUPT_UNSPECIFIED_SIGNAL;
+
+ /*
+ * Interrupt 67 affinity value presents as unimplemented in the
+ * configuration of the GICv2 instance used in ZynqMP CPUs.
+ */
+ if ( vector > ARM_GIC_IRQ_PPI_LAST && vector != 67 ) {
+ /* SPI */
+ attributes->can_get_affinity = true;
+ attributes->can_set_affinity = true;
+ }
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/bsps/shared/dev/irq/arm-gicv2.c b/bsps/shared/dev/irq/arm-gicv2.c
index 9c47a4d47b..263278148b 100644
--- a/bsps/shared/dev/irq/arm-gicv2.c
+++ b/bsps/shared/dev/irq/arm-gicv2.c
@@ -1,23 +1,53 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup DevIRQGIC
+ *
+ * @brief This source file contains the implementation of the generic GICv2
+ * support.
+ */
+
/*
- * Copyright (c) 2013, 2021 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2013, 2021 embedded brains GmbH & Co. KG
*
- * embedded brains GmbH
- * Dornierstr. 4
- * 82178 Puchheim
- * Germany
- * <info@embedded-brains.de>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * 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.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
*/
#include <dev/irq/arm-gic.h>
#include <dev/irq/arm-gic-arch.h>
-#include <bsp/irq.h>
#include <bsp/irq-generic.h>
#include <bsp/start.h>
+#include <rtems/score/processormaskimpl.h>
+
+/*
+ * The GIC architecture reserves interrupt ID numbers 1020 to 1023 for special
+ * purposes.
+ */
+#if BSP_INTERRUPT_VECTOR_COUNT >= 1020
+#error "BSP_INTERRUPT_VECTOR_COUNT is too large"
+#endif
#define GIC_CPUIF ((volatile gic_cpuif *) BSP_ARM_GIC_CPUIF_BASE)
@@ -53,49 +83,22 @@
void bsp_interrupt_dispatch(void)
{
volatile gic_cpuif *cpuif = GIC_CPUIF;
- uint32_t icciar = cpuif->icciar;
- rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
- rtems_vector_number spurious = 1023;
- if (vector != spurious) {
- arm_interrupt_handler_dispatch(vector);
+ while (true) {
+ uint32_t icciar = cpuif->icciar;
+ rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
+ uint32_t status;
- cpuif->icceoir = icciar;
- }
-}
-
-rtems_status_code bsp_interrupt_get_attributes(
- rtems_vector_number vector,
- rtems_interrupt_attributes *attributes
-)
-{
- attributes->is_maskable = true;
- attributes->maybe_enable = true;
- attributes->maybe_disable = true;
- attributes->can_raise = true;
-
- if ( vector <= ARM_GIC_IRQ_SGI_LAST ) {
- /*
- * It is implementation-defined whether implemented SGIs are permanently
- * enabled, or can be enabled and disabled by writes to GICD_ISENABLER0 and
- * GICD_ICENABLER0.
- */
- attributes->can_raise_on = true;
- attributes->cleared_by_acknowledge = true;
- attributes->trigger_signal = RTEMS_INTERRUPT_NO_SIGNAL;
- } else {
- attributes->can_disable = true;
- attributes->can_clear = true;
- attributes->trigger_signal = RTEMS_INTERRUPT_UNSPECIFIED_SIGNAL;
-
- if ( vector > ARM_GIC_IRQ_PPI_LAST ) {
- /* SPI */
- attributes->can_get_affinity = true;
- attributes->can_set_affinity = true;
+ if (!bsp_interrupt_is_valid_vector(vector)) {
+ break;
}
- }
- return RTEMS_SUCCESSFUL;
+ status = arm_interrupt_enable_interrupts();
+ bsp_interrupt_handler_dispatch_unchecked(vector);
+ arm_interrupt_restore_interrupts(status);
+
+ cpuif->icceoir = icciar;
+ }
}
rtems_status_code bsp_interrupt_is_pending(
@@ -341,6 +344,7 @@ rtems_status_code arm_gic_irq_get_group(
return sc;
}
+#ifdef RTEMS_SMP
rtems_status_code bsp_interrupt_set_affinity(
rtems_vector_number vector,
const Processor_mask *affinity
@@ -348,11 +352,24 @@ rtems_status_code bsp_interrupt_set_affinity(
{
volatile gic_dist *dist = ARM_GIC_DIST;
uint8_t targets = (uint8_t) _Processor_mask_To_uint32_t(affinity, 0);
+ rtems_interrupt_attributes attr;
+ rtems_status_code sc;
+
+ memset( &attr, 0, sizeof( attr ) );
+ sc = bsp_interrupt_get_attributes( vector, &attr );
+
+ if ( sc ) {
+ return sc;
+ }
if ( vector <= ARM_GIC_IRQ_PPI_LAST ) {
return RTEMS_UNSATISFIED;
}
+ if ( attr.can_set_affinity == 0 ) {
+ return RTEMS_UNSATISFIED;
+ }
+
gic_id_set_targets(dist, vector, targets);
return RTEMS_SUCCESSFUL;
}
@@ -364,15 +381,30 @@ rtems_status_code bsp_interrupt_get_affinity(
{
volatile gic_dist *dist = ARM_GIC_DIST;
uint8_t targets;
+ rtems_interrupt_attributes attr;
+ rtems_status_code sc;
+
+ memset( &attr, 0, sizeof( attr ) );
+ sc = bsp_interrupt_get_attributes( vector, &attr );
+
+ if ( sc ) {
+ return sc;
+ }
if ( vector <= ARM_GIC_IRQ_PPI_LAST ) {
return RTEMS_UNSATISFIED;
}
targets = gic_id_get_targets(dist, vector);
+
+ if ( attr.can_get_affinity == 0 ) {
+ return RTEMS_UNSATISFIED;
+ }
+
_Processor_mask_From_uint32_t(affinity, targets, 0);
return RTEMS_SUCCESSFUL;
}
+#endif
void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets)
{
@@ -386,9 +418,11 @@ void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets)
| GIC_DIST_ICDSGIR_SGIINTID(vector);
}
+#ifdef RTEMS_SMP
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;
}
+#endif
diff --git a/bsps/shared/dev/irq/arm-gicv3.c b/bsps/shared/dev/irq/arm-gicv3.c
index ea123d325e..958b1061bd 100644
--- a/bsps/shared/dev/irq/arm-gicv3.c
+++ b/bsps/shared/dev/irq/arm-gicv3.c
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
*
+ * @ingroup DevIRQGIC
+ *
+ * @brief This source file contains the implementation of the generic GICv3
+ * support.
+ */
+
+/*
* Copyright (C) 2019 On-Line Applications Research Corporation (OAR)
*
* Redistribution and use in source and binary forms, with or without
@@ -25,140 +34,26 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <dev/irq/arm-gic.h>
-#include <dev/irq/arm-gic-arch.h>
+#include <dev/irq/arm-gicv3.h>
-#include <bsp/irq.h>
#include <bsp/irq-generic.h>
#include <bsp/start.h>
-
-#ifdef ARM_MULTILIB_ARCH_V4
-#include <rtems/score/armv4.h>
-#else
-#include <rtems/score/cpu_irq.h>
-#endif
-
-#define PRIORITY_DEFAULT 127
-
-#define MPIDR_AFFINITY2(val) BSP_FLD64(val, 16, 23)
-#define MPIDR_AFFINITY2_GET(reg) BSP_FLD64GET(reg, 16, 23)
-#define MPIDR_AFFINITY2_SET(reg, val) BSP_FLD64SET(reg, val, 16, 23)
-#define MPIDR_AFFINITY1(val) BSP_FLD64(val, 8, 15)
-#define MPIDR_AFFINITY1_GET(reg) BSP_FLD64GET(reg, 8, 15)
-#define MPIDR_AFFINITY1_SET(reg, val) BSP_FLD64SET(reg, val, 8, 15)
-#define MPIDR_AFFINITY0(val) BSP_FLD64(val, 0, 7)
-#define MPIDR_AFFINITY0_GET(reg) BSP_FLD64GET(reg, 0, 7)
-#define MPIDR_AFFINITY0_SET(reg, val) BSP_FLD64SET(reg, val, 0, 7)
-
-#define ICC_SGIR_AFFINITY3(val) BSP_FLD64(val, 48, 55)
-#define ICC_SGIR_AFFINITY3_GET(reg) BSP_FLD64GET(reg, 48, 55)
-#define ICC_SGIR_AFFINITY3_SET(reg, val) BSP_FLD64SET(reg, val, 48, 55)
-#define ICC_SGIR_IRM BSP_BIT32(40)
-#define ICC_SGIR_AFFINITY2(val) BSP_FLD64(val, 32, 39)
-#define ICC_SGIR_AFFINITY2_GET(reg) BSP_FLD64GET(reg, 32, 39)
-#define ICC_SGIR_AFFINITY2_SET(reg, val) BSP_FLD64SET(reg, val, 32, 39)
-#define ICC_SGIR_INTID(val) BSP_FLD64(val, 24, 27)
-#define ICC_SGIR_INTID_GET(reg) BSP_FLD64GET(reg, 24, 27)
-#define ICC_SGIR_INTID_SET(reg, val) BSP_FLD64SET(reg, val, 24, 27)
-#define ICC_SGIR_AFFINITY1(val) BSP_FLD64(val, 16, 23)
-#define ICC_SGIR_AFFINITY1_GET(reg) BSP_FLD64GET(reg, 16, 23)
-#define ICC_SGIR_AFFINITY1_SET(reg, val) BSP_FLD64SET(reg, val, 16, 23)
-#define ICC_SGIR_CPU_TARGET_LIST(val) BSP_FLD64(val, 0, 15)
-#define ICC_SGIR_CPU_TARGET_LIST_GET(reg) BSP_FLD64GET(reg, 0, 15)
-#define ICC_SGIR_CPU_TARGET_LIST_SET(reg, val) BSP_FLD64SET(reg, val, 0, 15)
-
-#ifdef ARM_MULTILIB_ARCH_V4
-/* cpuif->iccicr */
-#define ICC_CTLR "p15, 0, %0, c12, c12, 4"
-
-/* cpuif->iccpmr */
-#define ICC_PMR "p15, 0, %0, c4, c6, 0"
-
-/* cpuif->iccbpr */
-#define ICC_BPR0 "p15, 0, %0, c12, c8, 3"
-#define ICC_BPR1 "p15, 0, %0, c12, c12, 3"
-
-/* cpuif->icciar */
-#define ICC_IAR0 "p15, 0, %0, c12, c8, 0"
-#define ICC_IAR1 "p15, 0, %0, c12, c12, 0"
-
-/* cpuif->icceoir */
-#define ICC_EOIR0 "p15, 0, %0, c12, c8, 1"
-#define ICC_EOIR1 "p15, 0, %0, c12, c12, 1"
-
-#define ICC_SRE "p15, 0, %0, c12, c12, 5"
-
-#define ICC_IGRPEN0 "p15, 0, %0, c12, c12, 6"
-#define ICC_IGRPEN1 "p15, 0, %0, c12, c12, 7"
-
-#define MPIDR "p15, 0, %0, c0, c0, 5"
-
-#define READ_SR(SR_NAME) \
-({ \
- uint32_t value; \
- __asm__ volatile("mrc " SR_NAME : "=r" (value) ); \
- value; \
-})
-
-#define WRITE_SR(SR_NAME, VALUE) \
- __asm__ volatile("mcr " SR_NAME " \n" : : "r" (VALUE) );
-
-#define ICC_SGI1 "p15, 0, %Q0, %R0, c12"
-#define WRITE64_SR(SR_NAME, VALUE) \
- __asm__ volatile("mcrr " SR_NAME " \n" : : "r" (VALUE) );
-
-#else /* ARM_MULTILIB_ARCH_V4 */
-
-/* AArch64 GICv3 registers are not named in GCC */
-#define ICC_IGRPEN0 "S3_0_C12_C12_6, %0"
-#define ICC_IGRPEN1 "S3_0_C12_C12_7, %0"
-#define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7, %0"
-#define ICC_PMR "S3_0_C4_C6_0, %0"
-#define ICC_EOIR1 "S3_0_C12_C12_1, %0"
-#define ICC_SRE "S3_0_C12_C12_5, %0"
-#define ICC_BPR0 "S3_0_C12_C8_3, %0"
-#define ICC_CTLR "S3_0_C12_C12_4, %0"
-#define ICC_IAR1 "%0, S3_0_C12_C12_0"
-#define MPIDR "%0, mpidr_el1"
-#define MPIDR_AFFINITY3(val) BSP_FLD64(val, 32, 39)
-#define MPIDR_AFFINITY3_GET(reg) BSP_FLD64GET(reg, 32, 39)
-#define MPIDR_AFFINITY3_SET(reg, val) BSP_FLD64SET(reg, val, 32, 39)
-
-#define ICC_SGI1 "S3_0_C12_C11_5, %0"
-#define WRITE64_SR(SR_NAME, VALUE) \
- __asm__ volatile("msr " SR_NAME " \n" : : "r" (VALUE) );
-#define WRITE_SR(SR_NAME, VALUE) WRITE64_SR(SR_NAME, VALUE)
-
-#define READ_SR(SR_NAME) \
-({ \
- uint64_t value; \
- __asm__ volatile("mrs " SR_NAME : "=&r" (value) ); \
- value; \
-})
-
-
-#endif /* ARM_MULTILIB_ARCH_V4 */
-
-static volatile gic_redist *gicv3_get_redist(uint32_t cpu_index)
-{
- return (volatile gic_redist *)
- ((uintptr_t)BSP_ARM_GIC_REDIST_BASE + cpu_index * 0x20000);
-}
-
-static volatile gic_sgi_ppi *gicv3_get_sgi_ppi(uint32_t cpu_index)
-{
- return (volatile gic_sgi_ppi *)
- ((uintptr_t)BSP_ARM_GIC_REDIST_BASE + cpu_index * 0x20000 + 0x10000);
-}
+#include <rtems/score/processormaskimpl.h>
void bsp_interrupt_dispatch(void)
{
- uint32_t icciar = READ_SR(ICC_IAR1);
- rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
- rtems_vector_number spurious = 1023;
+ while (true) {
+ uint32_t icciar = READ_SR(ICC_IAR1);
+ rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
+ uint32_t status;
- if (vector != spurious) {
- arm_interrupt_handler_dispatch(vector);
+ if (!bsp_interrupt_is_valid_vector(vector)) {
+ break;
+ }
+
+ status = arm_interrupt_enable_interrupts();
+ bsp_interrupt_handler_dispatch_unchecked(vector);
+ arm_interrupt_restore_interrupts(status);
WRITE_SR(ICC_EOIR1, icciar);
}
@@ -169,32 +64,7 @@ rtems_status_code bsp_interrupt_get_attributes(
rtems_interrupt_attributes *attributes
)
{
- attributes->is_maskable = true;
- attributes->maybe_enable = true;
- attributes->maybe_disable = true;
- attributes->can_raise = true;
-
- if ( vector <= ARM_GIC_IRQ_SGI_LAST ) {
- /*
- * It is implementation-defined whether implemented SGIs are permanently
- * enabled, or can be enabled and disabled by writes to GICD_ISENABLER0 and
- * GICD_ICENABLER0.
- */
- attributes->can_raise_on = true;
- attributes->cleared_by_acknowledge = true;
- attributes->trigger_signal = RTEMS_INTERRUPT_NO_SIGNAL;
- } else {
- attributes->can_disable = true;
- attributes->can_clear = true;
- attributes->trigger_signal = RTEMS_INTERRUPT_UNSPECIFIED_SIGNAL;
-
- if ( vector > ARM_GIC_IRQ_PPI_LAST ) {
- /* SPI */
- attributes->can_get_affinity = true;
- attributes->can_set_affinity = true;
- }
- }
-
+ gicv3_get_attributes(vector, attributes);
return RTEMS_SUCCESSFUL;
}
@@ -207,10 +77,7 @@ rtems_status_code bsp_interrupt_is_pending(
bsp_interrupt_assert(pending != NULL);
if (vector <= ARM_GIC_IRQ_PPI_LAST) {
- volatile gic_sgi_ppi *sgi_ppi =
- gicv3_get_sgi_ppi(_SMP_Get_current_processor());
-
- *pending = (sgi_ppi->icspispendr[0] & (1U << vector)) != 0;
+ *pending = gicv3_sgi_ppi_is_pending(vector, _SMP_Get_current_processor());
} else {
volatile gic_dist *dist = ARM_GIC_DIST;
@@ -227,10 +94,7 @@ rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
if (vector <= ARM_GIC_IRQ_SGI_LAST) {
arm_gic_trigger_sgi(vector, 1U << _SMP_Get_current_processor());
} else if (vector <= ARM_GIC_IRQ_PPI_LAST) {
- volatile gic_sgi_ppi *sgi_ppi =
- gicv3_get_sgi_ppi(_SMP_Get_current_processor());
-
- sgi_ppi->icspispendr[0] = 1U << vector;
+ gicv3_ppi_set_pending(vector, _SMP_Get_current_processor());
} else {
volatile gic_dist *dist = ARM_GIC_DIST;
@@ -264,10 +128,7 @@ rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
}
if ( vector <= ARM_GIC_IRQ_PPI_LAST ) {
- volatile gic_sgi_ppi *sgi_ppi =
- gicv3_get_sgi_ppi(_SMP_Get_current_processor());
-
- sgi_ppi->icspicpendr[0] = 1U << vector;
+ gicv3_ppi_clear_pending(vector, _SMP_Get_current_processor());
} else {
volatile gic_dist *dist = ARM_GIC_DIST;
@@ -286,10 +147,7 @@ rtems_status_code bsp_interrupt_vector_is_enabled(
bsp_interrupt_assert(enabled != NULL);
if ( vector <= ARM_GIC_IRQ_PPI_LAST ) {
- volatile gic_sgi_ppi *sgi_ppi =
- gicv3_get_sgi_ppi(_SMP_Get_current_processor());
-
- *enabled = (sgi_ppi->icspiser[0] & (1U << vector)) != 0;
+ *enabled = gicv3_sgi_ppi_is_enabled(vector, _SMP_Get_current_processor());
} else {
volatile gic_dist *dist = ARM_GIC_DIST;
@@ -309,19 +167,7 @@ rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
gic_id_enable(dist, vector);
} else {
- volatile gic_sgi_ppi *sgi_ppi =
- gicv3_get_sgi_ppi(_SMP_Get_current_processor());
-
- /* Set interrupt group to 1 in the current security mode */
-#if defined(ARM_MULTILIB_ARCH_V4) || defined(AARCH64_IS_NONSECURE)
- sgi_ppi->icspigrpr[0] |= 1U << vector;
- sgi_ppi->icspigrpmodr[0] &= ~(1U << vector);
-#else
- sgi_ppi->icspigrpr[0] &= ~(1U << vector);
- sgi_ppi->icspigrpmodr[0] |= 1U << vector;
-#endif
- /* Set enable */
- sgi_ppi->icspiser[0] = 1U << vector;
+ gicv3_sgi_ppi_enable(vector, _SMP_Get_current_processor());
}
return RTEMS_SUCCESSFUL;
@@ -336,93 +182,17 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
gic_id_disable(dist, vector);
} else {
- volatile gic_sgi_ppi *sgi_ppi =
- gicv3_get_sgi_ppi(_SMP_Get_current_processor());
-
- sgi_ppi->icspicer[0] = 1U << vector;
+ gicv3_sgi_ppi_disable(vector, _SMP_Get_current_processor());
}
return RTEMS_SUCCESSFUL;
}
-static inline uint32_t get_id_count(volatile gic_dist *dist)
-{
- uint32_t id_count = GIC_DIST_ICDICTR_IT_LINES_NUMBER_GET(dist->icdictr);
-
- id_count = 32 * (id_count + 1);
- id_count = id_count <= 1020 ? id_count : 1020;
-
- return id_count;
-}
-
-static void gicv3_init_cpu_interface(void)
-{
- uint32_t cpu_index = _SMP_Get_current_processor();
- uint32_t sre_value = 0x7;
- WRITE_SR(ICC_SRE, sre_value);
- WRITE_SR(ICC_PMR, GIC_CPUIF_ICCPMR_PRIORITY(0xff));
- WRITE_SR(ICC_BPR0, GIC_CPUIF_ICCBPR_BINARY_POINT(0x0));
-
- volatile gic_redist *redist = gicv3_get_redist(cpu_index);
- uint32_t waker = redist->icrwaker;
- uint32_t waker_mask = GIC_REDIST_ICRWAKER_PROCESSOR_SLEEP;
- waker &= ~waker_mask;
- redist->icrwaker = waker;
-
- volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(cpu_index);
- /* Set interrupt group to 1 in the current security mode */
-#if defined(ARM_MULTILIB_ARCH_V4) || defined(AARCH64_IS_NONSECURE)
- sgi_ppi->icspigrpr[0] = 0xffffffff;
- sgi_ppi->icspigrpmodr[0] = 0;
-#else
- sgi_ppi->icspigrpr[0] = 0x0;
- sgi_ppi->icspigrpmodr[0] = 0xffffffff;
-#endif
- for (int id = 0; id < 32; id++) {
- sgi_ppi->icspiprior[id] = PRIORITY_DEFAULT;
- }
-
- /* Enable interrupt groups 0 and 1 */
- WRITE_SR(ICC_IGRPEN0, 0x1);
- WRITE_SR(ICC_IGRPEN1, 0x1);
- WRITE_SR(ICC_CTLR, 0x0);
-}
-
void bsp_interrupt_facility_initialize(void)
{
- volatile gic_dist *dist = ARM_GIC_DIST;
- uint32_t id_count = get_id_count(dist);
- uint32_t id;
-
arm_interrupt_facility_set_exception_handler();
-
- dist->icddcr = GIC_DIST_ICDDCR_ARE_NS | GIC_DIST_ICDDCR_ARE_S
- | GIC_DIST_ICDDCR_ENABLE_GRP1S | GIC_DIST_ICDDCR_ENABLE_GRP1NS
- | GIC_DIST_ICDDCR_ENABLE_GRP0;
-
- for (id = 0; id < id_count; id += 32) {
- /* Disable all interrupts */
- dist->icdicer[id / 32] = 0xffffffff;
-
- /* Set interrupt group to 1 in the current security mode */
-#if defined(ARM_MULTILIB_ARCH_V4) || defined(AARCH64_IS_NONSECURE)
- dist->icdigr[id / 32] = 0xffffffff;
- dist->icdigmr[id / 32] = 0;
-#else
- dist->icdigr[id / 32] = 0;
- dist->icdigmr[id / 32] = 0xffffffff;
-#endif
- }
-
- for (id = 0; id < id_count; ++id) {
- gic_id_set_priority(dist, id, PRIORITY_DEFAULT);
- }
-
- for (id = 32; id < id_count; ++id) {
- gic_id_set_targets(dist, id, 0x01);
- }
-
- gicv3_init_cpu_interface();
+ gicv3_init_dist(ARM_GIC_DIST);
+ gicv3_init_cpu_interface(_SMP_Get_current_processor());
}
#ifdef RTEMS_SMP
@@ -434,7 +204,7 @@ BSP_START_TEXT_SECTION void arm_gic_irq_initialize_secondary_cpu(void)
/* Wait */
}
- gicv3_init_cpu_interface();
+ gicv3_init_cpu_interface(_SMP_Get_current_processor());
}
#endif
@@ -450,9 +220,11 @@ rtems_status_code arm_gic_irq_set_priority(
volatile gic_dist *dist = ARM_GIC_DIST;
gic_id_set_priority(dist, vector, priority);
} else {
- volatile gic_sgi_ppi *sgi_ppi =
- gicv3_get_sgi_ppi(_SMP_Get_current_processor());
- sgi_ppi->icspiprior[vector] = priority;
+ gicv3_sgi_ppi_set_priority(
+ vector,
+ priority,
+ _SMP_Get_current_processor()
+ );
}
} else {
sc = RTEMS_INVALID_ID;
@@ -473,9 +245,10 @@ rtems_status_code arm_gic_irq_get_priority(
volatile gic_dist *dist = ARM_GIC_DIST;
*priority = gic_id_get_priority(dist, vector);
} else {
- volatile gic_sgi_ppi *sgi_ppi =
- gicv3_get_sgi_ppi(_SMP_Get_current_processor());
- *priority = sgi_ppi->icspiprior[vector];
+ *priority = gicv3_sgi_ppi_get_priority(
+ vector,
+ _SMP_Get_current_processor()
+ );
}
} else {
sc = RTEMS_INVALID_ID;
@@ -484,6 +257,7 @@ rtems_status_code arm_gic_irq_get_priority(
return sc;
}
+#ifdef RTEMS_SMP
rtems_status_code bsp_interrupt_set_affinity(
rtems_vector_number vector,
const Processor_mask *affinity
@@ -516,25 +290,14 @@ rtems_status_code bsp_interrupt_get_affinity(
_Processor_mask_From_uint32_t(affinity, targets, 0);
return RTEMS_SUCCESSFUL;
}
+#endif
void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets)
{
-#ifndef ARM_MULTILIB_ARCH_V4
- uint64_t mpidr;
-#else
- uint32_t mpidr;
-#endif
- mpidr = READ_SR(MPIDR);
- uint64_t value = ICC_SGIR_AFFINITY2(MPIDR_AFFINITY2_GET(mpidr))
- | ICC_SGIR_INTID(vector)
- | ICC_SGIR_AFFINITY1(MPIDR_AFFINITY1_GET(mpidr))
- | ICC_SGIR_CPU_TARGET_LIST(targets);
-#ifndef ARM_MULTILIB_ARCH_V4
- value |= ICC_SGIR_AFFINITY3(MPIDR_AFFINITY3_GET(mpidr));
-#endif
- WRITE64_SR(ICC_SGI1, value);
+ gicv3_trigger_sgi(vector, targets);
}
+#ifdef RTEMS_SMP
uint32_t arm_gic_irq_processor_count(void)
{
volatile gic_dist *dist = ARM_GIC_DIST;
@@ -561,3 +324,4 @@ uint32_t arm_gic_irq_processor_count(void)
return cpu_count;
}
+#endif