diff options
Diffstat (limited to 'bsps/shared/dev/irq/arm-gicv3.c')
-rw-r--r-- | bsps/shared/dev/irq/arm-gicv3.c | 299 |
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 |