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