diff options
author | Daniel Hellstrom <daniel@gaisler.com> | 2014-05-29 21:39:18 +0200 |
---|---|---|
committer | Daniel Hellstrom <daniel@gaisler.com> | 2014-10-09 13:18:01 +0200 |
commit | fad33860ae86b78e8fedd2f8832f379e80909c83 (patch) | |
tree | aebd4b0a47047e407256100557f38d4a0fee5702 | |
parent | SPARC BSPs: added CPU aware interrupt ctrl operations (diff) | |
download | rtems-fad33860ae86b78e8fedd2f8832f379e80909c83.tar.bz2 |
LEON3 SMP: support static interrupt affinity
Changed LEON3_irq-mp to const also.
-rw-r--r-- | c/src/lib/libbsp/sparc/leon3/include/bsp.h | 13 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/irq/irq-shared.c | 39 |
3 files changed, 46 insertions, 8 deletions
diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp.h b/c/src/lib/libbsp/sparc/leon3/include/bsp.h index a4a4a6f788..5cc6e026a6 100644 --- a/c/src/lib/libbsp/sparc/leon3/include/bsp.h +++ b/c/src/lib/libbsp/sparc/leon3/include/bsp.h @@ -220,7 +220,18 @@ extern void BSP_shared_interrupt_mask(int irq); * to override the BSP default. * See startup/bspsmp.c for the default value. */ -extern unsigned char LEON3_mp_irq; +extern const unsigned char LEON3_mp_irq; + +#ifdef RTEMS_SMP +/* Weak table used to implement static interrupt CPU affinity in a SMP + * configuration. The array index is the interrupt to be looked up, and + * the array[INTERRUPT] content is the CPU number relative to boot CPU + * index that will be servicing the interrupts from the IRQ source. The + * default is to let the first CPU (the boot cpu) to handle all + * interrupts (all zeros). + */ +extern const unsigned char LEON3_irq_to_cpu[32]; +#endif #ifdef __cplusplus } diff --git a/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c b/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c index 567c971d2e..45ac92be0b 100644 --- a/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c +++ b/c/src/lib/libbsp/sparc/leon3/startup/bspsmp.c @@ -24,7 +24,7 @@ /* Irq used by shared memory driver and for inter-processor interrupts. * Can be overridden by being defined in the application. */ -unsigned char LEON3_mp_irq __attribute__((weak)) = 14; +const unsigned char LEON3_mp_irq __attribute__((weak)) = 14; #if !defined(__leon__) || defined(RTEMS_PARAVIRT) uint32_t _CPU_SMP_Get_current_processor( void ) diff --git a/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c b/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c index b49621f956..46c8307668 100644 --- a/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c +++ b/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c @@ -2,6 +2,31 @@ #include <bsp.h> #include <bsp/irq-generic.h> +#if defined(RTEMS_SMP) && defined(LEON3) +/* Interrupt to CPU map. Default to CPU0 since in BSS. */ +const unsigned char LEON3_irq_to_cpu[32] __attribute__((weak)); + +/* On SMP use map table above relative to SMP Boot CPU (normally CPU0) */ +static inline int bsp_irq_cpu(int irq) +{ + /* protect from bad user configuration, default to boot cpu */ + if (rtems_configuration_get_maximum_processors() <= LEON3_irq_to_cpu[irq]) + return LEON3_Cpu_Index; + else + return LEON3_Cpu_Index + LEON3_irq_to_cpu[irq]; +} +#else +/* when not SMP the local CPU is returned */ +static inline int bsp_irq_cpu(int irq) +{ +#ifdef LEON3 + return _LEON3_Get_current_processor(); +#else + return 0; +#endif +} +#endif + static inline void bsp_dispatch_irq(int irq) { bsp_interrupt_handler_entry *e = @@ -54,26 +79,28 @@ rtems_status_code bsp_interrupt_facility_initialize(void) rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector) { - BSP_Unmask_interrupt((int)vector); + int irq = (int)vector; + BSP_Cpu_Unmask_interrupt(irq, bsp_irq_cpu(irq)); - return RTEMS_SUCCESSFUL; + return RTEMS_SUCCESSFUL; } rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) { - BSP_Mask_interrupt((int)vector); + int irq = (int)vector; + BSP_Cpu_Mask_interrupt(irq, bsp_irq_cpu(irq)); - return RTEMS_SUCCESSFUL; + return RTEMS_SUCCESSFUL; } void BSP_shared_interrupt_mask(int irq) { - BSP_Mask_interrupt(irq); + BSP_Cpu_Mask_interrupt(irq, bsp_irq_cpu(irq)); } void BSP_shared_interrupt_unmask(int irq) { - BSP_Unmask_interrupt(irq); + BSP_Cpu_Unmask_interrupt(irq, bsp_irq_cpu(irq)); } void BSP_shared_interrupt_clear(int irq) |