1/***************************************************************************** 2* Copyright 2003 - 20011 Broadcom Corporation. All rights reserved. 3* 4* Unless you and Broadcom execute a separate written software license 5* agreement governing use of this software, this software is licensed to you 6* under the terms of the GNU General Public License version 2, available at 7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). 8* 9* Notwithstanding the above, under no circumstances may you combine this 10* software in any way with any other Broadcom software provided under a 11* license other than the GPL, without Broadcom's express prior written 12* consent. 13*****************************************************************************/ 14 15#include <asm/hardware/gic.h> 16#include <plat/mpcore.h> 17#include <mach/io_map.h> 18 19 .macro disable_fiq 20 .endm 21 22 /* 23 * This is the interrupt handling part of the GIC code - 24 * the base_va exists in a variable, but here is defined 25 * at compile time for effeciency (?) 26 */ 27 28 .macro get_irqnr_preamble, base, tmp 29 ldr \base, =MPCORE_GIC_CPUIF_VA 30 .endm 31 32 /* 33 * Interrupts 0-15 are IPI 34 * 16-31 are local 35 * 32-1020 are global 36 * 1021-1022 are reserved 37 * 1023 is "spurious" (no interrupt) 38 * 39 * Spurious interrupt must be ignored in all events. 40 * When in SMP mode, then IPI interrupts must be ignored here, 41 * amd picked up later with the test_for_ipi macro. 42 * When in SMP mode and local timers are enabled, 43 * the private timer/watchdog interrupt must be ignored here 44 * so it can be handled later in test_for_ltirq routine. 45 * 46 * A simple read from the controller will tell us the number of the 47 * highest priority enabled interrupt. We then just need to check 48 * whether it is in the range that must be handled. 49 * 50 * Upon return, Z=1 tells to ignore this interrupt 51 */ 52 53 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp 54 55 /* bits 12-10 = src CPU, 9-0 = int # */ 56 ldr \irqstat, [\base, #GIC_CPU_INTACK] 57 bic \irqnr, \irqstat, #0x1c00 58 ldr \tmp, =0x3ff @ spurious irqnum 59 60 /* Ignore spurious interrupt */ 61 cmp \irqnr, \tmp 62 63#ifdef CONFIG_LOCAL_TIMERS 64 /* Leave private timer handling for later */ 65 cmpne \irqnr, #MPCORE_IRQ_LOCALTIMER 66 moveq \tmp, \irqnr 67#endif 68 69#ifdef CONFIG_SMP 70 /* Leave IPI (irq=0..15) handling for later */ 71 cmp \irqnr, #16 72 movcc \tmp, \irqnr 73 cmp \tmp, \irqnr 74#endif 75 .endm 76 77#ifdef CONFIG_SMP 78 /* We assume that irqstat (the raw value of the IRQ acknowledge 79 * register) is preserved from the macro above. 80 * If there is an IPI, we immediately signal end of interrupt on the 81 * controller, since this requires the original irqstat value which 82 * we won't easily be able to recreate later. 83 */ 84 .macro test_for_ipi, irqnr, irqstat, base, tmp 85 bic \irqnr, \irqstat, #0x1c00 86 cmp \irqnr, #16 87 strcc \irqstat, [\base, #GIC_CPU_EOI] 88 cmpcs \irqnr, \irqnr 89 .endm 90 91#ifdef CONFIG_LOCAL_TIMERS 92 .macro test_for_ltirq, irqnr, irqstat, base,tmp 93 bic \irqnr, \irqstat, #0x1c00 94 mov \tmp, #0 95 cmp \irqnr, #MPCORE_IRQ_LOCALTIMER 96 moveq \tmp, #1 97 streq \irqstat, [\base, #GIC_CPU_EOI] 98 cmp \tmp, #0 99 .endm 100#endif 101#endif /* SMP */ 102 103 .macro arch_ret_to_user, tmp1, tmp2 104 .endm 105