xref: /netbsd/sys/arch/arm/iomd/iomd_irq.S (revision d878f7e0)
1*d878f7e0Sskrll/*	$NetBSD: iomd_irq.S,v 1.18 2020/11/21 19:52:56 skrll Exp $	*/
27d4a1addSreinoud
37d4a1addSreinoud/*
47d4a1addSreinoud * Copyright (c) 1994-1998 Mark Brinicombe.
57d4a1addSreinoud * Copyright (c) 1994 Brini.
67d4a1addSreinoud * All rights reserved.
77d4a1addSreinoud *
87d4a1addSreinoud * This code is derived from software written for Brini by Mark Brinicombe
97d4a1addSreinoud *
107d4a1addSreinoud * Redistribution and use in source and binary forms, with or without
117d4a1addSreinoud * modification, are permitted provided that the following conditions
127d4a1addSreinoud * are met:
137d4a1addSreinoud * 1. Redistributions of source code must retain the above copyright
147d4a1addSreinoud *    notice, this list of conditions and the following disclaimer.
157d4a1addSreinoud * 2. Redistributions in binary form must reproduce the above copyright
167d4a1addSreinoud *    notice, this list of conditions and the following disclaimer in the
177d4a1addSreinoud *    documentation and/or other materials provided with the distribution.
187d4a1addSreinoud * 3. All advertising materials mentioning features or use of this software
197d4a1addSreinoud *    must display the following acknowledgement:
207d4a1addSreinoud *	This product includes software developed by Mark Brinicombe
217d4a1addSreinoud *	for the NetBSD Project.
227d4a1addSreinoud * 4. The name of the company nor the name of the author may be used to
237d4a1addSreinoud *    endorse or promote products derived from this software without specific
247d4a1addSreinoud *    prior written permission.
257d4a1addSreinoud *
267d4a1addSreinoud * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
277d4a1addSreinoud * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
287d4a1addSreinoud * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
297d4a1addSreinoud * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
307d4a1addSreinoud * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
317d4a1addSreinoud * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
327d4a1addSreinoud * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
337d4a1addSreinoud * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
347d4a1addSreinoud * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
357d4a1addSreinoud * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
367d4a1addSreinoud *
377d4a1addSreinoud * Low level irq and fiq handlers
387d4a1addSreinoud *
397d4a1addSreinoud * Created      : 27/09/94
407d4a1addSreinoud */
417d4a1addSreinoud
427d4a1addSreinoud#include "opt_irqstats.h"
437d4a1addSreinoud
447d4a1addSreinoud#include "assym.h"
457de0cf26Smatt#include <arm/asm.h>
467de0cf26Smatt#include <arm/locore.h>
477d4a1addSreinoud#include <arm/iomd/iomdreg.h>
487d4a1addSreinoud
497d4a1addSreinoud	.text
507d4a1addSreinoud	.align	0
517d4a1addSreinoud/*
527d4a1addSreinoud * ffs table used for servicing irq's quickly must be here otherwise adr can't
537d4a1addSreinoud * reach it
547d4a1addSreinoud * The algorithm for ffs was devised by D. Seal and posted to
557d4a1addSreinoud * comp.sys.arm on 16 Feb 1994.
567d4a1addSreinoud */
577d4a1addSreinoud.type Lirq_ffs_table, _ASM_TYPE_OBJECT;
587d4a1addSreinoudLirq_ffs_table:
597d4a1addSreinoud/* same as ffs table but all nums are -1 from that */
607d4a1addSreinoud/*               0   1   2   3   4   5   6   7           */
617d4a1addSreinoud	.byte	 0,  0,  1, 12,  2,  6,  0, 13  /*  0- 7 */
627d4a1addSreinoud	.byte	 3,  0,  7,  0,  0,  0,  0, 14  /*  8-15 */
637d4a1addSreinoud	.byte	10,  4,  0,  0,  8,  0,  0, 25  /* 16-23 */
647d4a1addSreinoud	.byte	 0,  0,  0,  0,  0, 21, 27, 15  /* 24-31 */
657d4a1addSreinoud	.byte	31, 11,  5,  0,  0,  0,  0,  0	/* 32-39 */
667d4a1addSreinoud	.byte	 9,  0,  0, 24,  0,  0, 20, 26  /* 40-47 */
677d4a1addSreinoud	.byte	30,  0,  0,  0,  0, 23,  0, 19  /* 48-55 */
687d4a1addSreinoud	.byte   29,  0, 22, 18, 28, 17, 16,  0  /* 56-63 */
697d4a1addSreinoud
707d4a1addSreinoud/*
717d4a1addSreinoud *
727d4a1addSreinoud * irq_entry
737d4a1addSreinoud *
747d4a1addSreinoud * Main entry point for the IRQ vector
757d4a1addSreinoud *
767d4a1addSreinoud * This function reads the irq request bits in the IOMD registers
777d4a1addSreinoud * IRQRQA, IRQRQB and DMARQ
787d4a1addSreinoud * It then calls an installed handler for each bit that is set.
797d4a1addSreinoud * The function stray_irqhandler is called if a handler is not defined
807d4a1addSreinoud * for a particular interrupt.
817d4a1addSreinoud * If a interrupt handler is found then it is called with r0 containing
827d4a1addSreinoud * the argument defined in the handler structure. If the field ih_arg
837d4a1addSreinoud * is zero then a pointer to the IRQ frame on the stack is passed instead.
847d4a1addSreinoud */
857d4a1addSreinoud
86825088edSmattLcurrent_spl_level:
87825088edSmatt	.word	_C_LABEL(cpu_info_store) + CI_CPL
88825088edSmatt
897d4a1addSreinoudLdisabled_mask:
907d4a1addSreinoud	.word	_C_LABEL(disabled_mask)
917d4a1addSreinoud
927d4a1addSreinoudLspl_masks:
937d4a1addSreinoud	.word	_C_LABEL(spl_masks)
947d4a1addSreinoud
95165d4e6dSthorpejLOCK_CAS_CHECK_LOCALS
96165d4e6dSthorpej
97f77bf2bbSscwAST_ALIGNMENT_FAULT_LOCALS
98f77bf2bbSscw
997d4a1addSreinoud/*
1007d4a1addSreinoud * Register usage
1017d4a1addSreinoud *
102825088edSmatt *  r4  - Address of cpu_info
103*d878f7e0Sskrll *  r5  - Address of curlwp
1047d4a1addSreinoud *  r6  - Address of current handler
1057d4a1addSreinoud *  r7  - Pointer to handler pointer list
1067d4a1addSreinoud *  r8  - Current IRQ requests.
107*d878f7e0Sskrll *  r9  - scratch
1087d4a1addSreinoud *  r10 - Base address of IOMD
1097d4a1addSreinoud *  r11 - IRQ requests still to service.
1107d4a1addSreinoud */
1117d4a1addSreinoud
1127d4a1addSreinoudLiomd_base:
1137d4a1addSreinoud	.word	_C_LABEL(iomd_base)
1147d4a1addSreinoud
1157d4a1addSreinoudLarm7500_ioc_found:
1167d4a1addSreinoud	.word	_C_LABEL(arm7500_ioc_found)
1177d4a1addSreinoud
1187d4a1addSreinoudASENTRY_NP(irq_entry)
1197d4a1addSreinoud	sub	lr, lr, #0x00000004	/* Adjust the lr */
1207d4a1addSreinoud
1217d4a1addSreinoud	PUSHFRAMEINSVC			/* Push an interrupt frame */
122*d878f7e0Sskrll	ENABLE_ALIGNMENT_FAULTS		/* puts cur{cpu,lwp} in r4/r5 */
1237d4a1addSreinoud
1243c89ebf5Smatt	str	r7, [sp, #TF_FILL]	/* save r7 */
1253c89ebf5Smatt
1267d4a1addSreinoud	/* Load r8 with the IOMD interrupt requests */
1277d4a1addSreinoud
1287d4a1addSreinoud	ldr	r10, Liomd_base
1297d4a1addSreinoud 	ldr	r10, [r10]			/* Point to the IOMD */
1307d4a1addSreinoud	ldrb	r8, [r10, #(IOMD_IRQRQA << 2)]	/* Get IRQ request A */
1317d4a1addSreinoud	ldrb	r9, [r10, #(IOMD_IRQRQB << 2)]	/* Get IRQ request B */
1327d4a1addSreinoud	orr	r8, r8, r9, lsl #8
1337d4a1addSreinoud
1347d4a1addSreinoud	ldr	r9, Larm7500_ioc_found
1357d4a1addSreinoud	ldr	r9, [r9]			/* get the flag      */
1367d4a1addSreinoud	cmp	r9, #0
1377d4a1addSreinoud	beq	skip_extended_IRQs_reading
1387d4a1addSreinoud
1397d4a1addSreinoud	/* ARM 7500 only */
1407d4a1addSreinoud	ldrb	r9, [r10, #(IOMD_IRQRQC << 2)]	/* Get IRQ request C */
1417d4a1addSreinoud	orr	r8, r8, r9, lsl #16
1427d4a1addSreinoud	ldrb	r9, [r10, #(IOMD_IRQRQD << 2)]	/* Get IRQ request D */
1437d4a1addSreinoud	orr	r8, r8, r9, lsl #24
1447d4a1addSreinoud	ldrb	r9, [r10, #(IOMD_DMARQ << 2)]	/* Get DMA Request */
1457d4a1addSreinoud	tst	r9, #0x10
1467d4a1addSreinoud	orrne	r8, r8, r9, lsl #27
1477d4a1addSreinoud	b	irq_entry_continue
1487d4a1addSreinoud
1497d4a1addSreinoudskip_extended_IRQs_reading:
1507d4a1addSreinoud	/* non ARM7500 machines */
1517d4a1addSreinoud	ldrb	r9, [r10, #(IOMD_DMARQ << 2)]	/* Get DMA Request */
1527d4a1addSreinoud	orr	r8, r8, r9, lsl #16
1537d4a1addSreinoudirq_entry_continue:
1547d4a1addSreinoud
1557d4a1addSreinoud	and	r0, r8, #0x7d		/* Clear IOMD IRQA bits */
1567d4a1addSreinoud	strb	r0, [r10, #(IOMD_IRQRQA << 2)]
1577d4a1addSreinoud
1587d4a1addSreinoud	/*
1597d4a1addSreinoud	 * Note that we have entered the IRQ handler.
1607d4a1addSreinoud	 * We are in SVC mode so we cannot use the processor mode
1617d4a1addSreinoud	 * to determine if we are in an IRQ. Instead we will count the
1627d4a1addSreinoud	 * each time the interrupt handler is nested.
1637d4a1addSreinoud	 */
1647d4a1addSreinoud
165825088edSmatt	ldr	r0, [r4, #CI_INTR_DEPTH]
166825088edSmatt	add	r0, r0, #1
167825088edSmatt	str	r0, [r4, #CI_INTR_DEPTH]
1687d4a1addSreinoud
1697d4a1addSreinoud	/* Block the current requested interrupts */
1707d4a1addSreinoud	ldr	r1, Ldisabled_mask
1717d4a1addSreinoud	ldr	r0, [r1]
1727d4a1addSreinoud	stmfd	sp!, {r0}
1737d4a1addSreinoud	orr	r0, r0, r8
1747d4a1addSreinoud
1757d4a1addSreinoud	/*
1767d4a1addSreinoud 	 * Need to block all interrupts at the IPL or lower for
1777d4a1addSreinoud	 * all asserted interrupts.
1787d4a1addSreinoud	 * This basically emulates hardware interrupt priority levels.
1797d4a1addSreinoud	 * Means we need to go through the interrupt mask and for
1807d4a1addSreinoud	 * every asserted interrupt we need to mask out all other
1817d4a1addSreinoud	 * interrupts at the same or lower IPL.
1827d4a1addSreinoud	 * If only we could wait until the main loop but we need to sort
1837d4a1addSreinoud	 * this out first so interrupts can be re-enabled.
1847d4a1addSreinoud	 *
1857d4a1addSreinoud	 * This would benefit from a special ffs type routine
1867d4a1addSreinoud	 */
1877d4a1addSreinoud
188825088edSmatt	mov	r9, #(NIPL - 1)
1897d4a1addSreinoud	ldr	r7, Lspl_masks
1907d4a1addSreinoud
1917d4a1addSreinoudLfind_highest_ipl:
1927d4a1addSreinoud	ldr	r2, [r7, r9, lsl #2]
1937d4a1addSreinoud	tst	r8, r2
1947d4a1addSreinoud	subeq	r9, r9, #1
1957d4a1addSreinoud	beq	Lfind_highest_ipl
1967d4a1addSreinoud
1977d4a1addSreinoud	/* r9 = SPL level of highest priority interrupt */
1987d4a1addSreinoud	add	r9, r9, #1
1997d4a1addSreinoud	ldr	r2, [r7, r9, lsl #2]
2007d4a1addSreinoud	mvn	r2, r2
2017d4a1addSreinoud	orr	r0, r0, r2
2027d4a1addSreinoud
2037d4a1addSreinoud	str	r0, [r1]
2047d4a1addSreinoud
205825088edSmatt	ldr	r0, [r4, #CI_CPL]
206825088edSmatt	str	r9, [r4, #CI_CPL]
207825088edSmatt	stmfd	sp!, {r0}
2087d4a1addSreinoud
2097d4a1addSreinoud	/* Update the IOMD irq masks */
2107d4a1addSreinoud	bl	_C_LABEL(irq_setmasks)
2117d4a1addSreinoud
2122078c1f5Sjoerg        mrs     r0, cpsr		/* Enable IRQ's */
2137d4a1addSreinoud	bic	r0, r0, #I32_bit
2147d4a1addSreinoud	msr	cpsr_all, r0
2157d4a1addSreinoud
2167d4a1addSreinoud	/*
2177d4a1addSreinoud	 * take a copy of the IRQ request so that we can strip bits out of it
2187d4a1addSreinoud	 * note that we only use 24 bits with iomd2 chips
2197d4a1addSreinoud	 */
220*d878f7e0Sskrll	ldr	r7, Larm7500_ioc_found
221*d878f7e0Sskrll	ldr	r7, [r7]			/* get the flag      */
222*d878f7e0Sskrll	cmp	r7, #0
2237d4a1addSreinoud	movne	r11, r8				/* ARM7500  -> copy all bits   */
2247d4a1addSreinoud	biceq	r11, r8, #0xff000000		/* !ARM7500 -> only use 24 bit */
2257d4a1addSreinoud
2267d4a1addSreinoud	/* ffs routine to find first irq to service */
2277d4a1addSreinoud	/* standard trick to isolate bottom bit in a0 or 0 if a0 = 0 on entry */
228*d878f7e0Sskrll	rsb	r7, r11, #0
229*d878f7e0Sskrll	ands	r10, r11, r7
2307d4a1addSreinoud
2317d4a1addSreinoud	/*
2327d4a1addSreinoud	 * now r10 has at most 1 set bit, call this X
2337d4a1addSreinoud	 * if X = 0, branch to exit code
2347d4a1addSreinoud	 */
2357d4a1addSreinoud	beq	exitirq
2367d4a1addSreinoudirqloop:
237*d878f7e0Sskrll	ldr	r6, Lirqhandlers
238*d878f7e0Sskrll	adr	r7, Lirq_ffs_table
2397d4a1addSreinoud	/*
2407d4a1addSreinoud	 * at this point:
241*d878f7e0Sskrll	 * 	r6 = address of irq handlers table
242*d878f7e0Sskrll	 *	r7 = address of ffs table
2437d4a1addSreinoud	 *	r8 = irq request
2447d4a1addSreinoud	 *	r10 = bit of irq to be serviced
2457d4a1addSreinoud	 *	r11 = bitmask of IRQ's to service
2467d4a1addSreinoud	 */
2477d4a1addSreinoud	/* find the set bit */
2487d4a1addSreinoud	orr	r9, r10, r10, lsl #4	/* X * 0x11 */
2497d4a1addSreinoud	orr	r9, r9, r9, lsl #6	/* X * 0x451 */
2507d4a1addSreinoud	rsb	r9, r9, r9, lsl #16	/* X * 0x0450fbaf */
2517d4a1addSreinoud	/* fetch the bit number */
252*d878f7e0Sskrll	ldrb	r9, [r7, r9, lsr #26 ]
2537d4a1addSreinoud
2547d4a1addSreinoud	/*
2557d4a1addSreinoud	 * r9 = irq to service
2567d4a1addSreinoud	 */
2577d4a1addSreinoud
2587d4a1addSreinoud	/* apologies for the dogs dinner of code here, but it's in an attempt
2597d4a1addSreinoud	 * to minimise stalling on SA's, hence lots of things happen here:
2607d4a1addSreinoud	 *	- getting address of handler, if it doesn't exist we call
2617d4a1addSreinoud	 *	  stray_irqhandler this is assumed to be rare so we don't
2627d4a1addSreinoud	 *	  care about performance for it
2637d4a1addSreinoud	 *	- statinfo is updated
2647d4a1addSreinoud	 *	- unsetting of the irq bit in r11
2657d4a1addSreinoud	 *	- irq stats (if enabled) also get put in the mix
2667d4a1addSreinoud	 */
267*d878f7e0Sskrll	ldr	r6, [r6, r9, lsl #2]	/* Get address of first handler structure */
2687d4a1addSreinoud
2697d4a1addSreinoud	teq	r6, #0x00000000		/* Do we have a handler */
2707d4a1addSreinoud	moveq	r0, r8			/* IRQ requests as arg 0 */
271d599df95Sbjh21	adreq	lr, nextirq		/* return Address */
2727d4a1addSreinoud	beq	_C_LABEL(stray_irqhandler) /* call special handler */
2737d4a1addSreinoud
274ccde4787Smatt	/* stat info C */
275ccde4787Smatt	ldr	r1, [r4, #(CI_CC_NINTR)] /* Stat info B */
276ccde4787Smatt	ldr	r2, [r4, #(CI_CC_NINTR+4)]
277ccde4787Smatt#ifdef _ARMEL
278ccde4787Smatt	adds	r1, r1, #0x00000001
279ccde4787Smatt	adc	r2, r2, #0x00000000
280ccde4787Smatt#else
281ccde4787Smatt	adds	r2, r2, #0x00000001
282ccde4787Smatt	adc	r1, r1, #0x00000000
283ccde4787Smatt#endif
284ccde4787Smatt	str	r1, [r4, #(CI_CC_NINTR)]
285ccde4787Smatt	str	r2, [r4, #(CI_CC_NINTR+4)]
286ccde4787Smatt
2877d4a1addSreinoud#ifdef IRQSTATS
2887d4a1addSreinoud	ldr	r2, Lintrcnt
2897d4a1addSreinoud	ldr	r3, [r6, #(IH_NUM)]
2907d4a1addSreinoud	ldr	r3, [r2, r3, lsl #2]!
2917d4a1addSreinoud#endif
2927d4a1addSreinoud	bic	r11, r11, r10		/* clear the IRQ bit */
2937d4a1addSreinoud
2947d4a1addSreinoud#ifdef IRQSTATS
2957d4a1addSreinoud	add	r3, r3, #0x00000001
2967d4a1addSreinoud	str	r3, [r2]
2977d4a1addSreinoud#endif	/* IRQSTATS */
2987d4a1addSreinoud
2997d4a1addSreinoudirqchainloop:
3007d4a1addSreinoud	ldr	r0, [r6, #(IH_ARG)]	/* Get argument pointer */
3017d4a1addSreinoud	teq	r0, #0x00000000		/* If arg is zero pass stack frame */
3027d4a1addSreinoud	addeq	r0, sp, #8		/* ... stack frame [XXX needs care] */
303*d878f7e0Sskrll
304d599df95Sbjh21	mov	lr, pc			/* return address */
3057d4a1addSreinoud	ldr	pc, [r6, #(IH_FUNC)]	/* Call handler */
3067d4a1addSreinoud
3077d4a1addSreinoud	ldr	r6, [r6, #(IH_NEXT)]	/* fetch next handler */
3087d4a1addSreinoud
3097d4a1addSreinoud	teq	r0, #0x00000001		/* Was the irq serviced ? */
3107d4a1addSreinoud
3117d4a1addSreinoud	/* if it was it'll just fall through this: */
3127d4a1addSreinoud	teqne	r6, #0x00000000
3137d4a1addSreinoud	bne	irqchainloop
3147d4a1addSreinoudnextirq:
3157d4a1addSreinoud	/* Check for next irq */
316*d878f7e0Sskrll	rsb	r7, r11, #0
317*d878f7e0Sskrll	ands	r10, r11, r7
3187d4a1addSreinoud	/* check if there are anymore irq's to service */
3197d4a1addSreinoud	bne 	irqloop
3207d4a1addSreinoud
3217d4a1addSreinoudexitirq:
3227d4a1addSreinoud	ldmfd	sp!, {r2, r3}
323825088edSmatt	ldr	r0, Ldisabled_mask
324825088edSmatt	str	r2, [r4, #CI_CPL]
325825088edSmatt	str	r3, [r0]
3267d4a1addSreinoud
3277d4a1addSreinoud	bl	_C_LABEL(irq_setmasks)
3287d4a1addSreinoud
3297d4a1addSreinoud	/* Kill IRQ's in preparation for exit */
3302078c1f5Sjoerg        mrs     r0, cpsr
3317d4a1addSreinoud        orr     r0, r0, #(I32_bit)
3327d4a1addSreinoud        msr     cpsr_all, r0
3337d4a1addSreinoud
3347d4a1addSreinoud	/* Decrement the nest count */
335825088edSmatt	ldr	r0, [r4, #CI_INTR_DEPTH]
336825088edSmatt	sub	r0, r0, #1
337825088edSmatt	str	r0, [r4, #CI_INTR_DEPTH]
3387d4a1addSreinoud
3393c89ebf5Smatt	ldr	r7, [sp, #TF_FILL]		/* restore r7 */
340165d4e6dSthorpej	LOCK_CAS_CHECK
341165d4e6dSthorpej
342f77bf2bbSscw	DO_AST_AND_RESTORE_ALIGNMENT_FAULTS
3437d4a1addSreinoud	PULLFRAMEFROMSVCANDEXIT
3447d4a1addSreinoud
3457d4a1addSreinoud	/* NOT REACHED */
3467d4a1addSreinoud	b	. - 8
3477d4a1addSreinoud
3487d4a1addSreinoudLcurrent_mask:
3497d4a1addSreinoud	.word	_C_LABEL(current_mask)	/* irq's that are usable */
3507d4a1addSreinoud
3517d4a1addSreinoudENTRY(irq_setmasks)
3527d4a1addSreinoud	/* Disable interrupts */
3532078c1f5Sjoerg	mrs	r3, cpsr
3547d4a1addSreinoud	orr	r1, r3,  #(I32_bit)
3557d4a1addSreinoud	msr	cpsr_all, r1
3567d4a1addSreinoud
3577d4a1addSreinoud	/* Calculate IOMD interrupt mask */
3587d4a1addSreinoud	ldr	r1, Lcurrent_mask	/* All the enabled interrupts */
3597d4a1addSreinoud	ldr	r1, [r1]
360908dae93Stsutsui	ldr	r0, Lspl_masks		/* Block due to current spl level */
361908dae93Stsutsui	ldr	r2, Lcurrent_spl_level
3627d4a1addSreinoud	ldr	r2, [r2]
363908dae93Stsutsui	ldr	r2, [r0, r2, lsl #2]
3647d4a1addSreinoud	and	r1, r1, r2
3657d4a1addSreinoud	ldr	r2, Ldisabled_mask	/* Block due to active interrupts */
3667d4a1addSreinoud	ldr	r2, [r2]
3677d4a1addSreinoud	bic	r1, r1, r2
3687d4a1addSreinoud
3697d4a1addSreinoud	ldr	r0, Liomd_base
3707d4a1addSreinoud 	ldr	r0, [r0]			/* Point to the IOMD */
3717d4a1addSreinoud	strb	r1, [r0, #(IOMD_IRQMSKA << 2)]	/* Set IRQ mask A */
3727d4a1addSreinoud	mov	r1, r1, lsr #8
3737d4a1addSreinoud	strb	r1, [r0, #(IOMD_IRQMSKB << 2)]	/* Set IRQ mask B */
3747d4a1addSreinoud	mov	r1, r1, lsr #8
3757d4a1addSreinoud
3767d4a1addSreinoud	ldr	r2, Larm7500_ioc_found
3777d4a1addSreinoud	ldr	r2, [r2]
3787d4a1addSreinoud	cmp	r2, #0
3797d4a1addSreinoud	beq	skip_setting_extended_DMA_mask
3807d4a1addSreinoud
3817d4a1addSreinoud	/* only for ARM7500's */
3827d4a1addSreinoud	strb	r1, [r0, #(IOMD_IRQMSKC << 2)]
3837d4a1addSreinoud	mov	r1, r1, lsr #8
3847d4a1addSreinoud	and	r2, r1, #0xef
3857d4a1addSreinoud	strb	r2, [r0, #(IOMD_IRQMSKD << 2)]
3867d4a1addSreinoud	mov	r1, r1, lsr #3
3877d4a1addSreinoud	and	r2, r1, #0x10
3887d4a1addSreinoud	strb	r2, [r0, #(IOMD_DMAMSK << 2)]	/* Set DMA mask */
3897d4a1addSreinoud	b	continue_setting_masks
3907d4a1addSreinoud
3917d4a1addSreinoudskip_setting_extended_DMA_mask:
3927d4a1addSreinoud	/* non ARM7500's */
3937d4a1addSreinoud	strb	r1, [r0, #(IOMD_DMAMSK << 2)]	/* Set DMA mask */
3947d4a1addSreinoud
3957d4a1addSreinoudcontinue_setting_masks:
3967d4a1addSreinoud
3977d4a1addSreinoud	/* Restore old cpsr and exit */
3987d4a1addSreinoud	msr	cpsr_all, r3
3997d4a1addSreinoud	mov	pc, lr
4007d4a1addSreinoud
4017d4a1addSreinoudLintrcnt:
4027d4a1addSreinoud	.word	_C_LABEL(intrcnt)
4037d4a1addSreinoud
4047d4a1addSreinoud
4057d4a1addSreinoudLirqhandlers:
4067d4a1addSreinoud	.word	_C_LABEL(irqhandlers)	/* Pointer to array of irqhandlers */
4077d4a1addSreinoud
4087d4a1addSreinoud#ifdef IRQSTATS
4097d4a1addSreinoud/* These symbols are used by vmstat */
4107d4a1addSreinoud
411ccde4787Smatt	.section .rodata
412ccde4787Smatt
4137d4a1addSreinoud	.global	_C_LABEL(_intrnames)
4147d4a1addSreinoud_C_LABEL(_intrnames):
4157d4a1addSreinoud	.word	_C_LABEL(intrnames)
4167d4a1addSreinoud
4177d4a1addSreinoud        .globl  _C_LABEL(intrnames), _C_LABEL(eintrnames), _C_LABEL(intrcnt), _C_LABEL(sintrcnt), _C_LABEL(eintrcnt)
4187d4a1addSreinoud_C_LABEL(intrnames):
4197d4a1addSreinoud	.asciz	"interrupt  0 "
4207d4a1addSreinoud	.asciz	"interrupt  1 "	/* reserved0 */
4217d4a1addSreinoud	.asciz	"interrupt  2 "
4227d4a1addSreinoud	.asciz	"interrupt  3 "
4237d4a1addSreinoud	.asciz	"interrupt  4 "
4247d4a1addSreinoud	.asciz	"interrupt  5 "
4257d4a1addSreinoud	.asciz	"interrupt  6 "
4267d4a1addSreinoud	.asciz	"interrupt  7 "	/* reserved1 */
4277d4a1addSreinoud	.asciz	"interrupt  8 " /* reserved2 */
4287d4a1addSreinoud	.asciz	"interrupt  9 "
4297d4a1addSreinoud	.asciz	"interrupt 10 "
4307d4a1addSreinoud	.asciz	"interrupt 11 "
4317d4a1addSreinoud	.asciz	"interrupt 12 "
4327d4a1addSreinoud	.asciz	"interrupt 13 "
4337d4a1addSreinoud	.asciz	"interrupt 14 "
4347d4a1addSreinoud	.asciz	"interrupt 15 "
4357d4a1addSreinoud	.asciz	"dma channel 0"
4367d4a1addSreinoud	.asciz	"dma channel 1"
4377d4a1addSreinoud	.asciz	"dma channel 2"
4387d4a1addSreinoud	.asciz	"dma channel 3"
4397d4a1addSreinoud	.asciz	"interrupt 20 "
4407d4a1addSreinoud	.asciz	"interrupt 21 "
4417d4a1addSreinoud	.asciz	"reserved 3   "
4427d4a1addSreinoud	.asciz	"reserved 4   "
4437d4a1addSreinoud	.asciz	"exp card 0   "
4447d4a1addSreinoud	.asciz	"exp card 1   "
4457d4a1addSreinoud	.asciz	"exp card 2   "
4467d4a1addSreinoud	.asciz	"exp card 3   "
4477d4a1addSreinoud	.asciz	"exp card 4   "
4487d4a1addSreinoud	.asciz	"exp card 5   "
4497d4a1addSreinoud	.asciz	"exp card 6   "
4507d4a1addSreinoud	.asciz	"exp card 7   "
4517d4a1addSreinoud
4527d4a1addSreinoud_C_LABEL(sintrnames):
4537d4a1addSreinoud	.asciz	"softclock    "
4547d4a1addSreinoud	.asciz	"softnet      "
4557d4a1addSreinoud	.asciz	"softserial   "
4567d4a1addSreinoud	.asciz	"softintr  3  "
4577d4a1addSreinoud	.asciz	"softintr  4  "
4587d4a1addSreinoud	.asciz	"softintr  5  "
4597d4a1addSreinoud	.asciz	"softintr  6  "
4607d4a1addSreinoud	.asciz	"softintr  7   "
4617d4a1addSreinoud	.asciz	"softintr  8  "
4627d4a1addSreinoud	.asciz	"softintr  9  "
4637d4a1addSreinoud	.asciz	"softintr 10  "
4647d4a1addSreinoud	.asciz	"softintr 11  "
4657d4a1addSreinoud	.asciz	"softintr 12  "
4667d4a1addSreinoud	.asciz	"softintr 13  "
4677d4a1addSreinoud	.asciz	"softintr 14  "
4687d4a1addSreinoud	.asciz	"softintr 15  "
4697d4a1addSreinoud	.asciz	"softintr 16  "
4707d4a1addSreinoud	.asciz	"softintr 17  "
4717d4a1addSreinoud	.asciz	"softintr 18  "
4727d4a1addSreinoud	.asciz	"softintr 19  "
4737d4a1addSreinoud	.asciz	"softintr 20  "
4747d4a1addSreinoud	.asciz	"softintr 21  "
4757d4a1addSreinoud	.asciz	"softintr 22  "
4767d4a1addSreinoud	.asciz	"softintr 23  "
4777d4a1addSreinoud	.asciz	"softintr 24  "
4787d4a1addSreinoud	.asciz	"softintr 25  "
4797d4a1addSreinoud	.asciz	"softintr 26  "
4807d4a1addSreinoud	.asciz	"softintr 27  "
4817d4a1addSreinoud	.asciz	"softintr 28  "
4827d4a1addSreinoud	.asciz	"softintr 29  "
4837d4a1addSreinoud	.asciz	"softintr 30  "
4847d4a1addSreinoud	.asciz	"softintr 31  "
4857d4a1addSreinoud_C_LABEL(eintrnames):
4867d4a1addSreinoud
4877d4a1addSreinoud	.bss
4887d4a1addSreinoud	.align	0
4897d4a1addSreinoud_C_LABEL(intrcnt):
4907d4a1addSreinoud	.space	32*4	/* XXX Should be linked to number of interrupts */
4917d4a1addSreinoud
4927d4a1addSreinoud_C_LABEL(sintrcnt):
4937d4a1addSreinoud	.space	32*4	/* XXX Should be linked to number of interrupts */
4947d4a1addSreinoud_C_LABEL(eintrcnt):
4957d4a1addSreinoud
4967d4a1addSreinoud#else	/* IRQSTATS */
4977d4a1addSreinoud	/* Dummy entries to keep vmstat happy */
4987d4a1addSreinoud
499ccde4787Smatt	.section .rodata
5007d4a1addSreinoud        .globl  _C_LABEL(intrnames), _C_LABEL(eintrnames), _C_LABEL(intrcnt), _C_LABEL(eintrcnt)
5017d4a1addSreinoud_C_LABEL(intrnames):
5027d4a1addSreinoud	.long	0
5037d4a1addSreinoud_C_LABEL(eintrnames):
5047d4a1addSreinoud
5057d4a1addSreinoud_C_LABEL(intrcnt):
5067d4a1addSreinoud	.long	0
5077d4a1addSreinoud_C_LABEL(eintrcnt):
5087d4a1addSreinoud#endif	/* IRQSTATS */
509