summaryrefslogtreecommitdiffstats
path: root/bsps/shared/dev/irq/arm-gicv3.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/shared/dev/irq/arm-gicv3.c')
-rw-r--r--bsps/shared/dev/irq/arm-gicv3.c299
1 files changed, 23 insertions, 276 deletions
diff --git a/bsps/shared/dev/irq/arm-gicv3.c b/bsps/shared/dev/irq/arm-gicv3.c
index ea123d325e..108d64348a 100644
--- a/bsps/shared/dev/irq/arm-gicv3.c
+++ b/bsps/shared/dev/irq/arm-gicv3.c
@@ -25,132 +25,12 @@
* 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);
-}
-
void bsp_interrupt_dispatch(void)
{
uint32_t icciar = READ_SR(ICC_IAR1);
@@ -169,32 +49,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 +62,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 +79,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 +113,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 +132,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 +152,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 +167,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 +189,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 +205,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 +230,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;
@@ -519,22 +277,10 @@ rtems_status_code bsp_interrupt_get_affinity(
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 +307,4 @@ uint32_t arm_gic_irq_processor_count(void)
return cpu_count;
}
+#endif