From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Campbell Subject: [PATCH 3/9] arm: gic: implement IPIs using SGI mechanism Date: Wed, 6 Mar 2013 08:54:30 +0000 Message-ID: <1362560076-25897-3-git-send-email-ijc@hellion.org.uk> References: <1362559920.8941.98.camel@hastur.hellion.org.uk> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1362559920.8941.98.camel@hastur.hellion.org.uk> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: stefano.stabellini@citrix.com, tim@xen.org, Ian Campbell List-Id: xen-devel@lists.xenproject.org From: Ian Campbell Signed-off-by: Ian Campbell --- xen/arch/arm/arm32/mode_switch.S | 2 +- xen/arch/arm/gic.c | 88 +++++++++++++++++++++++++++++++++++--- xen/arch/arm/smp.c | 14 +++--- xen/include/asm-arm/gic.h | 22 +++++++++- 4 files changed, 108 insertions(+), 18 deletions(-) diff --git a/xen/arch/arm/arm32/mode_switch.S b/xen/arch/arm/arm32/mode_switch.S index bc2be74..d6741d0 100644 --- a/xen/arch/arm/arm32/mode_switch.S +++ b/xen/arch/arm/arm32/mode_switch.S @@ -43,7 +43,7 @@ kick_cpus: mov r2, #0x1 str r2, [r0, #(GICD_CTLR * 4)] /* enable distributor */ mov r2, #0xfe0000 - str r2, [r0, #(GICD_SGIR * 4)] /* send IPI to everybody */ + str r2, [r0, #(GICD_SGIR * 4)] /* send IPI to everybody, SGI0 = Event check */ dsb str r2, [r0, #(GICD_CTLR * 4)] /* disable distributor */ mov pc, lr diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index bbb8e04..6592562 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -354,10 +354,55 @@ void __init gic_init(void) spin_unlock(&gic.lock); } +void send_SGI_mask(const cpumask_t *cpumask, enum gic_sgi sgi) +{ + unsigned long mask = cpumask_bits(cpumask)[0]; + + ASSERT(sgi < 16); /* There are only 16 SGIs */ + + mask &= cpumask_bits(&cpu_online_map)[0]; + + ASSERT(mask < 0x100); /* The target bitmap only supports 8 CPUs */ + + dsb(); + + GICD[GICD_SGIR] = GICD_SGI_TARGET_LIST + | (mask<= 16 && irq < 1021) ) + { + local_irq_enable(); do_IRQ(regs, irq, is_fiq); + local_irq_disable(); + } + else if (unlikely(irq < 16)) + { + unsigned int cpu = (intack & GICC_IA_CPU_MASK) >> GICC_IA_CPU_SHIFT; + do_sgi(regs, cpu, irq); + } else + { + local_irq_disable(); break; - - local_irq_disable(); + } } while (1); } diff --git a/xen/arch/arm/smp.c b/xen/arch/arm/smp.c index 12260f4..a902d84 100644 --- a/xen/arch/arm/smp.c +++ b/xen/arch/arm/smp.c @@ -3,10 +3,11 @@ #include #include #include +#include void flush_tlb_mask(const cpumask_t *mask) { - /* XXX IPI other processors */ + /* No need to IPI other processors on ARM, the processor takes care of it. */ flush_xen_data_tlb(); } @@ -15,17 +16,12 @@ void smp_call_function( void *info, int wait) { - /* TODO: No SMP just now, does not include self so nothing to do. - cpumask_t allbutself = cpu_online_map; - cpu_clear(smp_processor_id(), allbutself); - on_selected_cpus(&allbutself, func, info, wait); - */ + panic("%s not implmented\n", __func__); } + void smp_send_event_check_mask(const cpumask_t *mask) { - /* TODO: No SMP just now, does not include self so nothing to do. - send_IPI_mask(mask, EVENT_CHECK_VECTOR); - */ + send_SGI_mask(mask, GIC_SGI_EVENT_CHECK); } /* diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 6bf50bb..24c0d5c 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -51,6 +51,13 @@ #define GICD_SPENDSGIRN (0xF2C/4) #define GICD_ICPIDR2 (0xFE8/4) +#define GICD_SGI_TARGET_LIST (0UL<<24) +#define GICD_SGI_TARGET_OTHERS (1UL<<24) +#define GICD_SGI_TARGET_SELF (2UL<<24) +#define GICD_SGI_TARGET_SHIFT (16) +#define GICD_SGI_TARGET_MASK (0xFFUL<