Home | History | Annotate | Line # | Download | only in iomd
iomd_irq.S revision 1.17
      1  1.17    skrll /*	$NetBSD: iomd_irq.S,v 1.17 2020/11/21 09:36:26 skrll Exp $	*/
      2   1.1  reinoud 
      3   1.1  reinoud /*
      4   1.1  reinoud  * Copyright (c) 1994-1998 Mark Brinicombe.
      5   1.1  reinoud  * Copyright (c) 1994 Brini.
      6   1.1  reinoud  * All rights reserved.
      7   1.1  reinoud  *
      8   1.1  reinoud  * This code is derived from software written for Brini by Mark Brinicombe
      9   1.1  reinoud  *
     10   1.1  reinoud  * Redistribution and use in source and binary forms, with or without
     11   1.1  reinoud  * modification, are permitted provided that the following conditions
     12   1.1  reinoud  * are met:
     13   1.1  reinoud  * 1. Redistributions of source code must retain the above copyright
     14   1.1  reinoud  *    notice, this list of conditions and the following disclaimer.
     15   1.1  reinoud  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1  reinoud  *    notice, this list of conditions and the following disclaimer in the
     17   1.1  reinoud  *    documentation and/or other materials provided with the distribution.
     18   1.1  reinoud  * 3. All advertising materials mentioning features or use of this software
     19   1.1  reinoud  *    must display the following acknowledgement:
     20   1.1  reinoud  *	This product includes software developed by Mark Brinicombe
     21   1.1  reinoud  *	for the NetBSD Project.
     22   1.1  reinoud  * 4. The name of the company nor the name of the author may be used to
     23   1.1  reinoud  *    endorse or promote products derived from this software without specific
     24   1.1  reinoud  *    prior written permission.
     25   1.1  reinoud  *
     26   1.1  reinoud  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     27   1.1  reinoud  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     28   1.1  reinoud  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     29   1.1  reinoud  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     30   1.1  reinoud  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     31   1.1  reinoud  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     32   1.1  reinoud  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     33   1.1  reinoud  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     34   1.1  reinoud  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     35   1.1  reinoud  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     36   1.1  reinoud  *
     37   1.1  reinoud  * Low level irq and fiq handlers
     38   1.1  reinoud  *
     39   1.1  reinoud  * Created      : 27/09/94
     40   1.1  reinoud  */
     41   1.1  reinoud 
     42   1.1  reinoud #include "opt_irqstats.h"
     43   1.1  reinoud 
     44   1.1  reinoud #include "assym.h"
     45  1.15     matt #include <arm/asm.h>
     46  1.15     matt #include <arm/locore.h>
     47   1.1  reinoud #include <arm/iomd/iomdreg.h>
     48   1.1  reinoud 
     49   1.1  reinoud 	.text
     50   1.1  reinoud 	.align	0
     51   1.1  reinoud /*
     52   1.1  reinoud  * ffs table used for servicing irq's quickly must be here otherwise adr can't
     53   1.1  reinoud  * reach it
     54   1.1  reinoud  * The algorithm for ffs was devised by D. Seal and posted to
     55   1.1  reinoud  * comp.sys.arm on 16 Feb 1994.
     56   1.1  reinoud  */
     57   1.1  reinoud .type Lirq_ffs_table, _ASM_TYPE_OBJECT;
     58   1.1  reinoud Lirq_ffs_table:
     59   1.1  reinoud /* same as ffs table but all nums are -1 from that */
     60   1.1  reinoud /*               0   1   2   3   4   5   6   7           */
     61   1.1  reinoud 	.byte	 0,  0,  1, 12,  2,  6,  0, 13  /*  0- 7 */
     62   1.1  reinoud 	.byte	 3,  0,  7,  0,  0,  0,  0, 14  /*  8-15 */
     63   1.1  reinoud 	.byte	10,  4,  0,  0,  8,  0,  0, 25  /* 16-23 */
     64   1.1  reinoud 	.byte	 0,  0,  0,  0,  0, 21, 27, 15  /* 24-31 */
     65   1.1  reinoud 	.byte	31, 11,  5,  0,  0,  0,  0,  0	/* 32-39 */
     66   1.1  reinoud 	.byte	 9,  0,  0, 24,  0,  0, 20, 26  /* 40-47 */
     67   1.1  reinoud 	.byte	30,  0,  0,  0,  0, 23,  0, 19  /* 48-55 */
     68   1.1  reinoud 	.byte   29,  0, 22, 18, 28, 17, 16,  0  /* 56-63 */
     69   1.1  reinoud 
     70   1.1  reinoud /*
     71   1.1  reinoud  *
     72   1.1  reinoud  * irq_entry
     73   1.1  reinoud  *
     74   1.1  reinoud  * Main entry point for the IRQ vector
     75   1.1  reinoud  *
     76   1.1  reinoud  * This function reads the irq request bits in the IOMD registers
     77   1.1  reinoud  * IRQRQA, IRQRQB and DMARQ
     78   1.1  reinoud  * It then calls an installed handler for each bit that is set.
     79   1.1  reinoud  * The function stray_irqhandler is called if a handler is not defined
     80   1.1  reinoud  * for a particular interrupt.
     81   1.1  reinoud  * If a interrupt handler is found then it is called with r0 containing
     82   1.1  reinoud  * the argument defined in the handler structure. If the field ih_arg
     83   1.1  reinoud  * is zero then a pointer to the IRQ frame on the stack is passed instead.
     84   1.1  reinoud  */
     85   1.1  reinoud 
     86  1.11     matt Lcurrent_spl_level:
     87  1.11     matt 	.word	_C_LABEL(cpu_info_store) + CI_CPL
     88  1.11     matt 
     89   1.1  reinoud Ldisabled_mask:
     90   1.1  reinoud 	.word	_C_LABEL(disabled_mask)
     91   1.1  reinoud 
     92   1.1  reinoud Lspl_masks:
     93   1.1  reinoud 	.word	_C_LABEL(spl_masks)
     94   1.1  reinoud 
     95   1.6  thorpej LOCK_CAS_CHECK_LOCALS
     96   1.6  thorpej 
     97   1.4      scw AST_ALIGNMENT_FAULT_LOCALS
     98   1.4      scw 
     99   1.1  reinoud /*
    100   1.1  reinoud  * Register usage
    101   1.1  reinoud  *
    102  1.11     matt  *  r4  - Address of cpu_info
    103   1.1  reinoud  *  r5  - Address of ffs table
    104   1.1  reinoud  *  r6  - Address of current handler
    105   1.1  reinoud  *  r7  - Pointer to handler pointer list
    106   1.1  reinoud  *  r8  - Current IRQ requests.
    107   1.1  reinoud  *  r10 - Base address of IOMD
    108   1.1  reinoud  *  r11 - IRQ requests still to service.
    109   1.1  reinoud  */
    110   1.1  reinoud 
    111   1.1  reinoud Liomd_base:
    112   1.1  reinoud 	.word	_C_LABEL(iomd_base)
    113   1.1  reinoud 
    114   1.1  reinoud Larm7500_ioc_found:
    115   1.1  reinoud 	.word	_C_LABEL(arm7500_ioc_found)
    116   1.1  reinoud 
    117   1.1  reinoud ASENTRY_NP(irq_entry)
    118   1.1  reinoud 	sub	lr, lr, #0x00000004	/* Adjust the lr */
    119   1.1  reinoud 
    120   1.1  reinoud 	PUSHFRAMEINSVC			/* Push an interrupt frame */
    121   1.4      scw 	ENABLE_ALIGNMENT_FAULTS
    122   1.1  reinoud 
    123  1.14     matt 	str	r7, [sp, #TF_FILL]	/* save r7 */
    124  1.14     matt 
    125   1.1  reinoud 	/* Load r8 with the IOMD interrupt requests */
    126   1.1  reinoud 
    127   1.1  reinoud 	ldr	r10, Liomd_base
    128   1.1  reinoud  	ldr	r10, [r10]			/* Point to the IOMD */
    129   1.1  reinoud 	ldrb	r8, [r10, #(IOMD_IRQRQA << 2)]	/* Get IRQ request A */
    130   1.1  reinoud 	ldrb	r9, [r10, #(IOMD_IRQRQB << 2)]	/* Get IRQ request B */
    131   1.1  reinoud 	orr	r8, r8, r9, lsl #8
    132   1.1  reinoud 
    133   1.1  reinoud 	ldr	r9, Larm7500_ioc_found
    134   1.1  reinoud 	ldr	r9, [r9]			/* get the flag      */
    135   1.1  reinoud 	cmp	r9, #0
    136   1.1  reinoud 	beq	skip_extended_IRQs_reading
    137   1.1  reinoud 
    138   1.1  reinoud 	/* ARM 7500 only */
    139   1.1  reinoud 	ldrb	r9, [r10, #(IOMD_IRQRQC << 2)]	/* Get IRQ request C */
    140   1.1  reinoud 	orr	r8, r8, r9, lsl #16
    141   1.1  reinoud 	ldrb	r9, [r10, #(IOMD_IRQRQD << 2)]	/* Get IRQ request D */
    142   1.1  reinoud 	orr	r8, r8, r9, lsl #24
    143   1.1  reinoud 	ldrb	r9, [r10, #(IOMD_DMARQ << 2)]	/* Get DMA Request */
    144   1.1  reinoud 	tst	r9, #0x10
    145   1.1  reinoud 	orrne	r8, r8, r9, lsl #27
    146   1.1  reinoud 	b	irq_entry_continue
    147   1.1  reinoud 
    148   1.1  reinoud skip_extended_IRQs_reading:
    149   1.1  reinoud 	/* non ARM7500 machines */
    150   1.1  reinoud 	ldrb	r9, [r10, #(IOMD_DMARQ << 2)]	/* Get DMA Request */
    151   1.1  reinoud 	orr	r8, r8, r9, lsl #16
    152   1.1  reinoud irq_entry_continue:
    153   1.1  reinoud 
    154   1.1  reinoud 	and	r0, r8, #0x7d		/* Clear IOMD IRQA bits */
    155   1.1  reinoud 	strb	r0, [r10, #(IOMD_IRQRQA << 2)]
    156   1.1  reinoud 
    157   1.1  reinoud 	/*
    158   1.1  reinoud 	 * Note that we have entered the IRQ handler.
    159   1.1  reinoud 	 * We are in SVC mode so we cannot use the processor mode
    160   1.1  reinoud 	 * to determine if we are in an IRQ. Instead we will count the
    161   1.1  reinoud 	 * each time the interrupt handler is nested.
    162   1.1  reinoud 	 */
    163   1.1  reinoud 
    164  1.11     matt 	ldr	r0, [r4, #CI_INTR_DEPTH]
    165  1.11     matt 	add	r0, r0, #1
    166  1.11     matt 	str	r0, [r4, #CI_INTR_DEPTH]
    167   1.1  reinoud 
    168   1.1  reinoud 	/* Block the current requested interrupts */
    169   1.1  reinoud 	ldr	r1, Ldisabled_mask
    170   1.1  reinoud 	ldr	r0, [r1]
    171   1.1  reinoud 	stmfd	sp!, {r0}
    172   1.1  reinoud 	orr	r0, r0, r8
    173   1.1  reinoud 
    174   1.1  reinoud 	/*
    175   1.1  reinoud  	 * Need to block all interrupts at the IPL or lower for
    176   1.1  reinoud 	 * all asserted interrupts.
    177   1.1  reinoud 	 * This basically emulates hardware interrupt priority levels.
    178   1.1  reinoud 	 * Means we need to go through the interrupt mask and for
    179   1.1  reinoud 	 * every asserted interrupt we need to mask out all other
    180   1.1  reinoud 	 * interrupts at the same or lower IPL.
    181   1.1  reinoud 	 * If only we could wait until the main loop but we need to sort
    182   1.1  reinoud 	 * this out first so interrupts can be re-enabled.
    183   1.1  reinoud 	 *
    184   1.1  reinoud 	 * This would benefit from a special ffs type routine
    185   1.1  reinoud 	 */
    186   1.1  reinoud 
    187  1.11     matt 	mov	r9, #(NIPL - 1)
    188   1.1  reinoud 	ldr	r7, Lspl_masks
    189   1.1  reinoud 
    190   1.1  reinoud Lfind_highest_ipl:
    191   1.1  reinoud 	ldr	r2, [r7, r9, lsl #2]
    192   1.1  reinoud 	tst	r8, r2
    193   1.1  reinoud 	subeq	r9, r9, #1
    194   1.1  reinoud 	beq	Lfind_highest_ipl
    195   1.1  reinoud 
    196   1.1  reinoud 	/* r9 = SPL level of highest priority interrupt */
    197   1.1  reinoud 	add	r9, r9, #1
    198   1.1  reinoud 	ldr	r2, [r7, r9, lsl #2]
    199   1.1  reinoud 	mvn	r2, r2
    200   1.1  reinoud 	orr	r0, r0, r2
    201   1.1  reinoud 
    202  1.17    skrll 	str	r0, [r1]
    203   1.1  reinoud 
    204  1.11     matt 	ldr	r0, [r4, #CI_CPL]
    205  1.11     matt 	str	r9, [r4, #CI_CPL]
    206  1.11     matt 	stmfd	sp!, {r0}
    207   1.1  reinoud 
    208   1.1  reinoud 	/* Update the IOMD irq masks */
    209   1.1  reinoud 	bl	_C_LABEL(irq_setmasks)
    210   1.1  reinoud 
    211  1.16    joerg         mrs     r0, cpsr		/* Enable IRQ's */
    212   1.1  reinoud 	bic	r0, r0, #I32_bit
    213   1.1  reinoud 	msr	cpsr_all, r0
    214   1.1  reinoud 
    215   1.3    bjh21 	ldr	r7, Lirqhandlers
    216   1.1  reinoud 
    217  1.17    skrll 	/*
    218   1.1  reinoud 	 * take a copy of the IRQ request so that we can strip bits out of it
    219   1.1  reinoud 	 * note that we only use 24 bits with iomd2 chips
    220   1.1  reinoud 	 */
    221  1.11     matt 	ldr	r5, Larm7500_ioc_found
    222  1.11     matt 	ldr	r5, [r5]			/* get the flag      */
    223  1.11     matt 	cmp	r5, #0
    224   1.1  reinoud 	movne	r11, r8				/* ARM7500  -> copy all bits   */
    225   1.1  reinoud 	biceq	r11, r8, #0xff000000		/* !ARM7500 -> only use 24 bit */
    226   1.1  reinoud 
    227   1.1  reinoud 	/* ffs routine to find first irq to service */
    228   1.1  reinoud 	/* standard trick to isolate bottom bit in a0 or 0 if a0 = 0 on entry */
    229  1.11     matt 	rsb	r5, r11, #0
    230  1.11     matt 	ands	r10, r11, r5
    231   1.1  reinoud 
    232  1.17    skrll 	/*
    233   1.1  reinoud 	 * now r10 has at most 1 set bit, call this X
    234   1.1  reinoud 	 * if X = 0, branch to exit code
    235   1.1  reinoud 	 */
    236   1.1  reinoud 	beq	exitirq
    237  1.12     matt irqloop:
    238   1.1  reinoud 	adr	r5, Lirq_ffs_table
    239   1.1  reinoud 	/*
    240   1.1  reinoud 	 * at this point:
    241   1.1  reinoud 	 *	r5 = address of ffs table
    242   1.1  reinoud 	 *	r7 = address of irq handlers table
    243   1.1  reinoud 	 *	r8 = irq request
    244   1.1  reinoud 	 *	r10 = bit of irq to be serviced
    245   1.1  reinoud 	 *	r11 = bitmask of IRQ's to service
    246   1.1  reinoud 	 */
    247   1.1  reinoud 
    248   1.1  reinoud 	/* find the set bit */
    249   1.1  reinoud 	orr	r9, r10, r10, lsl #4	/* X * 0x11 */
    250   1.1  reinoud 	orr	r9, r9, r9, lsl #6	/* X * 0x451 */
    251   1.1  reinoud 	rsb	r9, r9, r9, lsl #16	/* X * 0x0450fbaf */
    252   1.1  reinoud 	/* fetch the bit number */
    253   1.1  reinoud 	ldrb	r9, [r5, r9, lsr #26 ]
    254   1.1  reinoud 
    255  1.17    skrll 	/*
    256   1.1  reinoud 	 * r9 = irq to service
    257   1.1  reinoud 	 */
    258   1.1  reinoud 
    259   1.1  reinoud 	/* apologies for the dogs dinner of code here, but it's in an attempt
    260   1.1  reinoud 	 * to minimise stalling on SA's, hence lots of things happen here:
    261   1.1  reinoud 	 *	- getting address of handler, if it doesn't exist we call
    262   1.1  reinoud 	 *	  stray_irqhandler this is assumed to be rare so we don't
    263   1.1  reinoud 	 *	  care about performance for it
    264   1.1  reinoud 	 *	- statinfo is updated
    265   1.1  reinoud 	 *	- unsetting of the irq bit in r11
    266   1.1  reinoud 	 *	- irq stats (if enabled) also get put in the mix
    267   1.1  reinoud 	 */
    268   1.1  reinoud 	ldr	r6, [r7, r9, lsl #2]	/* Get address of first handler structure */
    269   1.1  reinoud 
    270   1.1  reinoud 	teq	r6, #0x00000000		/* Do we have a handler */
    271   1.1  reinoud 	moveq	r0, r8			/* IRQ requests as arg 0 */
    272   1.3    bjh21 	adreq	lr, nextirq		/* return Address */
    273   1.1  reinoud 	beq	_C_LABEL(stray_irqhandler) /* call special handler */
    274  1.17    skrll 
    275  1.13     matt 	/* stat info C */
    276  1.13     matt 	ldr	r1, [r4, #(CI_CC_NINTR)] /* Stat info B */
    277  1.13     matt 	ldr	r2, [r4, #(CI_CC_NINTR+4)]
    278  1.13     matt #ifdef _ARMEL
    279  1.13     matt 	adds	r1, r1, #0x00000001
    280  1.13     matt 	adc	r2, r2, #0x00000000
    281  1.13     matt #else
    282  1.13     matt 	adds	r2, r2, #0x00000001
    283  1.13     matt 	adc	r1, r1, #0x00000000
    284  1.13     matt #endif
    285  1.13     matt 	str	r1, [r4, #(CI_CC_NINTR)]
    286  1.13     matt 	str	r2, [r4, #(CI_CC_NINTR+4)]
    287  1.13     matt 
    288   1.1  reinoud #ifdef IRQSTATS
    289   1.1  reinoud 	ldr	r2, Lintrcnt
    290   1.1  reinoud 	ldr	r3, [r6, #(IH_NUM)]
    291   1.1  reinoud 	ldr	r3, [r2, r3, lsl #2]!
    292   1.1  reinoud #endif
    293   1.1  reinoud 	bic	r11, r11, r10		/* clear the IRQ bit */
    294   1.1  reinoud 
    295   1.1  reinoud #ifdef IRQSTATS
    296   1.1  reinoud 	add	r3, r3, #0x00000001
    297   1.1  reinoud 	str	r3, [r2]
    298   1.1  reinoud #endif	/* IRQSTATS */
    299   1.1  reinoud 
    300   1.1  reinoud irqchainloop:
    301   1.1  reinoud 	ldr	r0, [r6, #(IH_ARG)]	/* Get argument pointer */
    302   1.1  reinoud 	teq	r0, #0x00000000		/* If arg is zero pass stack frame */
    303   1.1  reinoud 	addeq	r0, sp, #8		/* ... stack frame [XXX needs care] */
    304   1.3    bjh21 	mov	lr, pc			/* return address */
    305   1.1  reinoud 	ldr	pc, [r6, #(IH_FUNC)]	/* Call handler */
    306   1.1  reinoud 
    307   1.1  reinoud 	ldr	r6, [r6, #(IH_NEXT)]	/* fetch next handler */
    308  1.17    skrll 
    309   1.1  reinoud 	teq	r0, #0x00000001		/* Was the irq serviced ? */
    310  1.17    skrll 
    311   1.1  reinoud 	/* if it was it'll just fall through this: */
    312   1.1  reinoud 	teqne	r6, #0x00000000
    313   1.1  reinoud 	bne	irqchainloop
    314   1.1  reinoud nextirq:
    315   1.1  reinoud 	/* Check for next irq */
    316  1.11     matt 	rsb	r5, r11, #0
    317  1.11     matt 	ands	r10, r11, r5
    318   1.1  reinoud 	/* check if there are anymore irq's to service */
    319   1.1  reinoud 	bne 	irqloop
    320   1.1  reinoud 
    321   1.1  reinoud exitirq:
    322   1.1  reinoud 	ldmfd	sp!, {r2, r3}
    323  1.11     matt 	ldr	r0, Ldisabled_mask
    324  1.11     matt 	str	r2, [r4, #CI_CPL]
    325  1.11     matt 	str	r3, [r0]
    326   1.1  reinoud 
    327   1.1  reinoud 	bl	_C_LABEL(irq_setmasks)
    328   1.1  reinoud 
    329  1.10     matt #if __HAVE_FAST_SOFTINTS
    330   1.1  reinoud 	bl	_C_LABEL(dosoftints)	/* Handle the soft interrupts */
    331  1.10     matt #endif
    332   1.1  reinoud 
    333   1.1  reinoud 	/* Kill IRQ's in preparation for exit */
    334  1.16    joerg         mrs     r0, cpsr
    335   1.1  reinoud         orr     r0, r0, #(I32_bit)
    336   1.1  reinoud         msr     cpsr_all, r0
    337   1.1  reinoud 
    338   1.1  reinoud 	/* Decrement the nest count */
    339  1.11     matt 	ldr	r0, [r4, #CI_INTR_DEPTH]
    340  1.11     matt 	sub	r0, r0, #1
    341  1.11     matt 	str	r0, [r4, #CI_INTR_DEPTH]
    342   1.1  reinoud 
    343  1.14     matt 	ldr	r7, [sp, #TF_FILL]		/* restore r7 */
    344   1.6  thorpej 	LOCK_CAS_CHECK
    345   1.6  thorpej 
    346   1.4      scw 	DO_AST_AND_RESTORE_ALIGNMENT_FAULTS
    347   1.1  reinoud 	PULLFRAMEFROMSVCANDEXIT
    348   1.1  reinoud 
    349   1.1  reinoud 	/* NOT REACHED */
    350   1.1  reinoud 	b	. - 8
    351   1.1  reinoud 
    352   1.1  reinoud Lcurrent_mask:
    353   1.1  reinoud 	.word	_C_LABEL(current_mask)	/* irq's that are usable */
    354   1.1  reinoud 
    355   1.1  reinoud ENTRY(irq_setmasks)
    356   1.1  reinoud 	/* Disable interrupts */
    357  1.16    joerg 	mrs	r3, cpsr
    358   1.1  reinoud 	orr	r1, r3,  #(I32_bit)
    359   1.1  reinoud 	msr	cpsr_all, r1
    360   1.1  reinoud 
    361   1.1  reinoud 	/* Calculate IOMD interrupt mask */
    362   1.1  reinoud 	ldr	r1, Lcurrent_mask	/* All the enabled interrupts */
    363   1.1  reinoud 	ldr	r1, [r1]
    364   1.7  tsutsui 	ldr	r0, Lspl_masks		/* Block due to current spl level */
    365   1.7  tsutsui 	ldr	r2, Lcurrent_spl_level
    366   1.1  reinoud 	ldr	r2, [r2]
    367   1.7  tsutsui 	ldr	r2, [r0, r2, lsl #2]
    368   1.1  reinoud 	and	r1, r1, r2
    369   1.1  reinoud 	ldr	r2, Ldisabled_mask	/* Block due to active interrupts */
    370   1.1  reinoud 	ldr	r2, [r2]
    371   1.1  reinoud 	bic	r1, r1, r2
    372   1.1  reinoud 
    373   1.1  reinoud 	ldr	r0, Liomd_base
    374   1.1  reinoud  	ldr	r0, [r0]			/* Point to the IOMD */
    375   1.1  reinoud 	strb	r1, [r0, #(IOMD_IRQMSKA << 2)]	/* Set IRQ mask A */
    376   1.1  reinoud 	mov	r1, r1, lsr #8
    377   1.1  reinoud 	strb	r1, [r0, #(IOMD_IRQMSKB << 2)]	/* Set IRQ mask B */
    378   1.1  reinoud 	mov	r1, r1, lsr #8
    379   1.1  reinoud 
    380   1.1  reinoud 	ldr	r2, Larm7500_ioc_found
    381   1.1  reinoud 	ldr	r2, [r2]
    382   1.1  reinoud 	cmp	r2, #0
    383   1.1  reinoud 	beq	skip_setting_extended_DMA_mask
    384   1.1  reinoud 
    385   1.1  reinoud 	/* only for ARM7500's */
    386   1.1  reinoud 	strb	r1, [r0, #(IOMD_IRQMSKC << 2)]
    387   1.1  reinoud 	mov	r1, r1, lsr #8
    388   1.1  reinoud 	and	r2, r1, #0xef
    389   1.1  reinoud 	strb	r2, [r0, #(IOMD_IRQMSKD << 2)]
    390   1.1  reinoud 	mov	r1, r1, lsr #3
    391   1.1  reinoud 	and	r2, r1, #0x10
    392   1.1  reinoud 	strb	r2, [r0, #(IOMD_DMAMSK << 2)]	/* Set DMA mask */
    393   1.1  reinoud 	b	continue_setting_masks
    394   1.1  reinoud 
    395   1.1  reinoud skip_setting_extended_DMA_mask:
    396   1.1  reinoud 	/* non ARM7500's */
    397   1.1  reinoud 	strb	r1, [r0, #(IOMD_DMAMSK << 2)]	/* Set DMA mask */
    398   1.1  reinoud 
    399   1.1  reinoud continue_setting_masks:
    400   1.1  reinoud 
    401   1.1  reinoud 	/* Restore old cpsr and exit */
    402   1.1  reinoud 	msr	cpsr_all, r3
    403   1.1  reinoud 	mov	pc, lr
    404   1.1  reinoud 
    405   1.1  reinoud Lintrcnt:
    406   1.1  reinoud 	.word	_C_LABEL(intrcnt)
    407   1.1  reinoud 
    408   1.1  reinoud 
    409   1.1  reinoud Lirqhandlers:
    410   1.1  reinoud 	.word	_C_LABEL(irqhandlers)	/* Pointer to array of irqhandlers */
    411   1.1  reinoud 
    412   1.1  reinoud #ifdef IRQSTATS
    413   1.1  reinoud /* These symbols are used by vmstat */
    414   1.1  reinoud 
    415  1.13     matt 	.section .rodata
    416  1.13     matt 
    417   1.1  reinoud 	.global	_C_LABEL(_intrnames)
    418   1.1  reinoud _C_LABEL(_intrnames):
    419   1.1  reinoud 	.word	_C_LABEL(intrnames)
    420   1.1  reinoud 
    421   1.1  reinoud         .globl  _C_LABEL(intrnames), _C_LABEL(eintrnames), _C_LABEL(intrcnt), _C_LABEL(sintrcnt), _C_LABEL(eintrcnt)
    422   1.1  reinoud _C_LABEL(intrnames):
    423   1.1  reinoud 	.asciz	"interrupt  0 "
    424   1.1  reinoud 	.asciz	"interrupt  1 "	/* reserved0 */
    425   1.1  reinoud 	.asciz	"interrupt  2 "
    426   1.1  reinoud 	.asciz	"interrupt  3 "
    427   1.1  reinoud 	.asciz	"interrupt  4 "
    428   1.1  reinoud 	.asciz	"interrupt  5 "
    429   1.1  reinoud 	.asciz	"interrupt  6 "
    430   1.1  reinoud 	.asciz	"interrupt  7 "	/* reserved1 */
    431   1.1  reinoud 	.asciz	"interrupt  8 " /* reserved2 */
    432   1.1  reinoud 	.asciz	"interrupt  9 "
    433   1.1  reinoud 	.asciz	"interrupt 10 "
    434   1.1  reinoud 	.asciz	"interrupt 11 "
    435   1.1  reinoud 	.asciz	"interrupt 12 "
    436   1.1  reinoud 	.asciz	"interrupt 13 "
    437   1.1  reinoud 	.asciz	"interrupt 14 "
    438   1.1  reinoud 	.asciz	"interrupt 15 "
    439   1.1  reinoud 	.asciz	"dma channel 0"
    440   1.1  reinoud 	.asciz	"dma channel 1"
    441   1.1  reinoud 	.asciz	"dma channel 2"
    442   1.1  reinoud 	.asciz	"dma channel 3"
    443   1.1  reinoud 	.asciz	"interrupt 20 "
    444   1.1  reinoud 	.asciz	"interrupt 21 "
    445   1.1  reinoud 	.asciz	"reserved 3   "
    446   1.1  reinoud 	.asciz	"reserved 4   "
    447   1.1  reinoud 	.asciz	"exp card 0   "
    448   1.1  reinoud 	.asciz	"exp card 1   "
    449   1.1  reinoud 	.asciz	"exp card 2   "
    450   1.1  reinoud 	.asciz	"exp card 3   "
    451   1.1  reinoud 	.asciz	"exp card 4   "
    452   1.1  reinoud 	.asciz	"exp card 5   "
    453   1.1  reinoud 	.asciz	"exp card 6   "
    454   1.1  reinoud 	.asciz	"exp card 7   "
    455   1.1  reinoud 
    456   1.1  reinoud _C_LABEL(sintrnames):
    457   1.1  reinoud 	.asciz	"softclock    "
    458   1.1  reinoud 	.asciz	"softnet      "
    459   1.1  reinoud 	.asciz	"softserial   "
    460   1.1  reinoud 	.asciz	"softintr  3  "
    461   1.1  reinoud 	.asciz	"softintr  4  "
    462   1.1  reinoud 	.asciz	"softintr  5  "
    463   1.1  reinoud 	.asciz	"softintr  6  "
    464   1.1  reinoud 	.asciz	"softintr  7   "
    465   1.1  reinoud 	.asciz	"softintr  8  "
    466   1.1  reinoud 	.asciz	"softintr  9  "
    467   1.1  reinoud 	.asciz	"softintr 10  "
    468   1.1  reinoud 	.asciz	"softintr 11  "
    469   1.1  reinoud 	.asciz	"softintr 12  "
    470   1.1  reinoud 	.asciz	"softintr 13  "
    471   1.1  reinoud 	.asciz	"softintr 14  "
    472   1.1  reinoud 	.asciz	"softintr 15  "
    473   1.1  reinoud 	.asciz	"softintr 16  "
    474   1.1  reinoud 	.asciz	"softintr 17  "
    475   1.1  reinoud 	.asciz	"softintr 18  "
    476   1.1  reinoud 	.asciz	"softintr 19  "
    477   1.1  reinoud 	.asciz	"softintr 20  "
    478   1.1  reinoud 	.asciz	"softintr 21  "
    479   1.1  reinoud 	.asciz	"softintr 22  "
    480   1.1  reinoud 	.asciz	"softintr 23  "
    481   1.1  reinoud 	.asciz	"softintr 24  "
    482   1.1  reinoud 	.asciz	"softintr 25  "
    483   1.1  reinoud 	.asciz	"softintr 26  "
    484   1.1  reinoud 	.asciz	"softintr 27  "
    485   1.1  reinoud 	.asciz	"softintr 28  "
    486   1.1  reinoud 	.asciz	"softintr 29  "
    487   1.1  reinoud 	.asciz	"softintr 30  "
    488   1.1  reinoud 	.asciz	"softintr 31  "
    489   1.1  reinoud _C_LABEL(eintrnames):
    490   1.1  reinoud 
    491   1.1  reinoud 	.bss
    492   1.1  reinoud 	.align	0
    493   1.1  reinoud _C_LABEL(intrcnt):
    494   1.1  reinoud 	.space	32*4	/* XXX Should be linked to number of interrupts */
    495   1.1  reinoud 
    496   1.1  reinoud _C_LABEL(sintrcnt):
    497   1.1  reinoud 	.space	32*4	/* XXX Should be linked to number of interrupts */
    498   1.1  reinoud _C_LABEL(eintrcnt):
    499   1.1  reinoud 
    500   1.1  reinoud #else	/* IRQSTATS */
    501   1.1  reinoud 	/* Dummy entries to keep vmstat happy */
    502   1.1  reinoud 
    503  1.13     matt 	.section .rodata
    504   1.1  reinoud         .globl  _C_LABEL(intrnames), _C_LABEL(eintrnames), _C_LABEL(intrcnt), _C_LABEL(eintrcnt)
    505   1.1  reinoud _C_LABEL(intrnames):
    506   1.1  reinoud 	.long	0
    507   1.1  reinoud _C_LABEL(eintrnames):
    508   1.1  reinoud 
    509   1.1  reinoud _C_LABEL(intrcnt):
    510   1.1  reinoud 	.long	0
    511   1.1  reinoud _C_LABEL(eintrcnt):
    512   1.1  reinoud #endif	/* IRQSTATS */
    513