MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / arch / arm / kernel / entry-armv.S
blobd8b0812dc4aa61fe6e6056ec4a03550ce24834d4
1 /*
2  *  linux/arch/arm/kernel/entry-armv.S
3  *
4  *  Copyright (C) 1996,1997,1998 Russell King.
5  *  ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk)
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  *  Low-level vector interface routines
12  *
13  *  Note:  there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes
14  *  it to save wrong values...  Be aware!
15  */
16 #include <linux/config.h>
17 #include <linux/init.h>
19 #include <asm/thread_info.h>
20 #include <asm/glue.h>
21 #include <asm/ptrace.h>
22 #include <asm/vfpmacros.h>
24 #include "entry-header.S"
26 #ifdef IOC_BASE
27 /* IOC / IOMD based hardware */
28 #include <asm/hardware/iomd.h>
30                 .equ    ioc_base_high, IOC_BASE & 0xff000000
31                 .equ    ioc_base_low, IOC_BASE & 0x00ff0000
32                 .macro  disable_fiq
33                 mov     r12, #ioc_base_high
34                 .if     ioc_base_low
35                 orr     r12, r12, #ioc_base_low
36                 .endif
37                 strb    r12, [r12, #0x38]       @ Disable FIQ register
38                 .endm
40                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
41                 mov     r4, #ioc_base_high              @ point at IOC
42                 .if     ioc_base_low
43                 orr     r4, r4, #ioc_base_low
44                 .endif
45                 ldrb    \irqstat, [r4, #IOMD_IRQREQB]   @ get high priority first
46                 ldr     \base, =irq_prio_h
47                 teq     \irqstat, #0
48 #ifdef IOMD_BASE
49                 ldreqb  \irqstat, [r4, #IOMD_DMAREQ]    @ get dma
50                 addeq   \base, \base, #256              @ irq_prio_h table size
51                 teqeq   \irqstat, #0
52                 bne     2406f
53 #endif
54                 ldreqb  \irqstat, [r4, #IOMD_IRQREQA]   @ get low priority
55                 addeq   \base, \base, #256              @ irq_prio_d table size
56                 teqeq   \irqstat, #0
57 #ifdef IOMD_IRQREQC
58                 ldreqb  \irqstat, [r4, #IOMD_IRQREQC]
59                 addeq   \base, \base, #256              @ irq_prio_l table size
60                 teqeq   \irqstat, #0
61 #endif
62 #ifdef IOMD_IRQREQD
63                 ldreqb  \irqstat, [r4, #IOMD_IRQREQD]
64                 addeq   \base, \base, #256              @ irq_prio_lc table size
65                 teqeq   \irqstat, #0
66 #endif
67 2406:           ldrneb  \irqnr, [\base, \irqstat]       @ get IRQ number
68                 .endm
71  * Interrupt table (incorporates priority).  Please note that we
72  * rely on the order of these tables (see above code).
73  */
74                 .macro  irq_prio_table
75 irq_prio_h:     .byte    0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
76                 .byte   12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
77                 .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
78                 .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
79                 .byte   14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
80                 .byte   14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
81                 .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
82                 .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
83                 .byte   15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
84                 .byte   15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
85                 .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
86                 .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
87                 .byte   15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
88                 .byte   15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
89                 .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
90                 .byte   13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
91 #ifdef IOMD_BASE
92 irq_prio_d:     .byte    0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
93                 .byte   20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
94                 .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
95                 .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
96                 .byte   22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
97                 .byte   22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
98                 .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
99                 .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
100                 .byte   23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
101                 .byte   23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
102                 .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
103                 .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
104                 .byte   22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
105                 .byte   22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
106                 .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
107                 .byte   21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
108 #endif
109 irq_prio_l:     .byte    0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
110                 .byte    4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
111                 .byte    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
112                 .byte    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
113                 .byte    6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
114                 .byte    6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
115                 .byte    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
116                 .byte    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
117                 .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
118                 .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
119                 .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
120                 .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
121                 .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
122                 .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
123                 .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
124                 .byte    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
125 #ifdef IOMD_IRQREQC
126 irq_prio_lc:    .byte   24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
127                 .byte   28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
128                 .byte   29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
129                 .byte   29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
130                 .byte   30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
131                 .byte   30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
132                 .byte   29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
133                 .byte   29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
134                 .byte   31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
135                 .byte   31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
136                 .byte   31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
137                 .byte   31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
138                 .byte   31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
139                 .byte   31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
140                 .byte   31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
141                 .byte   31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
142 #endif
143 #ifdef IOMD_IRQREQD
144 irq_prio_ld:    .byte   40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
145                 .byte   44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
146                 .byte   45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
147                 .byte   45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
148                 .byte   46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
149                 .byte   46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
150                 .byte   45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
151                 .byte   45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
152                 .byte   47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
153                 .byte   47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
154                 .byte   47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
155                 .byte   47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
156                 .byte   47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
157                 .byte   47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
158                 .byte   47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
159                 .byte   47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
160 #endif
161                 .endm
163 #elif defined(CONFIG_ARCH_EBSA110)
165 #define IRQ_STAT                0xff000000      /* read */
167                 .macro  disable_fiq
168                 .endm
170                 .macro  get_irqnr_and_base, irqnr, stat, base, tmp
171                 mov     \base, #IRQ_STAT
172                 ldrb    \stat, [\base]                  @ get interrupts
173                 mov     \irqnr, #0
174                 tst     \stat, #15
175                 addeq   \irqnr, \irqnr, #4
176                 moveq   \stat, \stat, lsr #4
177                 tst     \stat, #3
178                 addeq   \irqnr, \irqnr, #2
179                 moveq   \stat, \stat, lsr #2
180                 tst     \stat, #1
181                 addeq   \irqnr, \irqnr, #1
182                 moveq   \stat, \stat, lsr #1
183                 tst     \stat, #1                       @ bit 0 should be set
184                 .endm
186                 .macro  irq_prio_table
187                 .endm
189 #elif defined(CONFIG_ARCH_SHARK)
191                 .macro  disable_fiq
192                 .endm
194                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
195                 mov     r4, #0xe0000000
197                 mov     \irqstat, #0x0C
198                 strb    \irqstat, [r4, #0x20]           @outb(0x0C, 0x20) /* Poll command */
199                 ldrb    \irqnr, [r4, #0x20]             @irq = inb(0x20) & 7
200                 and     \irqstat, \irqnr, #0x80
201                 teq     \irqstat, #0
202                 beq     43f
203                 and     \irqnr, \irqnr, #7
204                 teq     \irqnr, #2
205                 bne     44f
206 43:             mov     \irqstat, #0x0C
207                 strb    \irqstat, [r4, #0xa0]           @outb(0x0C, 0xA0) /* Poll command */
208                 ldrb    \irqnr, [r4, #0xa0]             @irq = (inb(0xA0) & 7) + 8
209                 and     \irqstat, \irqnr, #0x80
210                 teq     \irqstat, #0
211                 beq     44f
212                 and     \irqnr, \irqnr, #7
213                 add     \irqnr, \irqnr, #8
214 44:             teq     \irqstat, #0
215                 .endm
217                 .macro  irq_prio_table
218                 .endm
220 #elif defined(CONFIG_FOOTBRIDGE)
221 #include <asm/hardware/dec21285.h>
223                 .macro  disable_fiq
224                 .endm
226                 .equ    dc21285_high, ARMCSR_BASE & 0xff000000
227                 .equ    dc21285_low, ARMCSR_BASE & 0x00ffffff
229                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
230                 mov     r4, #dc21285_high
231                 .if     dc21285_low
232                 orr     r4, r4, #dc21285_low
233                 .endif
234                 ldr     \irqstat, [r4, #0x180]          @ get interrupts
236                 mov     \irqnr, #IRQ_SDRAMPARITY
237                 tst     \irqstat, #IRQ_MASK_SDRAMPARITY
238                 bne     1001f
240                 tst     \irqstat, #IRQ_MASK_UART_RX
241                 movne   \irqnr, #IRQ_CONRX
242                 bne     1001f
244                 tst     \irqstat, #IRQ_MASK_DMA1
245                 movne   \irqnr, #IRQ_DMA1
246                 bne     1001f
248                 tst     \irqstat, #IRQ_MASK_DMA2
249                 movne   \irqnr, #IRQ_DMA2
250                 bne     1001f
252                 tst     \irqstat, #IRQ_MASK_IN0
253                 movne   \irqnr, #IRQ_IN0
254                 bne     1001f
256                 tst     \irqstat, #IRQ_MASK_IN1
257                 movne   \irqnr, #IRQ_IN1
258                 bne     1001f
260                 tst     \irqstat, #IRQ_MASK_IN2
261                 movne   \irqnr, #IRQ_IN2
262                 bne     1001f
264                 tst     \irqstat, #IRQ_MASK_IN3
265                 movne   \irqnr, #IRQ_IN3
266                 bne     1001f
268                 tst     \irqstat, #IRQ_MASK_PCI
269                 movne   \irqnr, #IRQ_PCI
270                 bne     1001f
272                 tst     \irqstat, #IRQ_MASK_DOORBELLHOST
273                 movne   \irqnr, #IRQ_DOORBELLHOST
274                 bne     1001f
275         
276                 tst     \irqstat, #IRQ_MASK_I2OINPOST
277                 movne   \irqnr, #IRQ_I2OINPOST
278                 bne     1001f
280                 tst     \irqstat, #IRQ_MASK_TIMER1
281                 movne   \irqnr, #IRQ_TIMER1
282                 bne     1001f
284                 tst     \irqstat, #IRQ_MASK_TIMER2
285                 movne   \irqnr, #IRQ_TIMER2
286                 bne     1001f
288                 tst     \irqstat, #IRQ_MASK_TIMER3
289                 movne   \irqnr, #IRQ_TIMER3
290                 bne     1001f
292                 tst     \irqstat, #IRQ_MASK_UART_TX
293                 movne   \irqnr, #IRQ_CONTX
294                 bne     1001f
296                 tst     \irqstat, #IRQ_MASK_PCI_ABORT
297                 movne   \irqnr, #IRQ_PCI_ABORT
298                 bne     1001f
300                 tst     \irqstat, #IRQ_MASK_PCI_SERR
301                 movne   \irqnr, #IRQ_PCI_SERR
302                 bne     1001f
304                 tst     \irqstat, #IRQ_MASK_DISCARD_TIMER
305                 movne   \irqnr, #IRQ_DISCARD_TIMER
306                 bne     1001f
308                 tst     \irqstat, #IRQ_MASK_PCI_DPERR
309                 movne   \irqnr, #IRQ_PCI_DPERR
310                 bne     1001f
312                 tst     \irqstat, #IRQ_MASK_PCI_PERR
313                 movne   \irqnr, #IRQ_PCI_PERR
314 1001:
315                 .endm
317                 .macro  irq_prio_table
318                 .endm
320 #elif defined(CONFIG_ARCH_NEXUSPCI)
322                 .macro  disable_fiq
323                 .endm
325                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
326                 ldr     \irqstat, =INTCONT_BASE
327                 ldr     \base, =soft_irq_mask
328                 ldr     \irqstat, [\irqstat]            @ get interrupts
329                 ldr     \base, [\base]
330                 mov     \irqnr, #0
331                 and     \irqstat, \irqstat, \base       @ mask out disabled ones
332 1001:           tst     \irqstat, #1
333                 addeq   \irqnr, \irqnr, #1
334                 moveq   \irqstat, \irqstat, lsr #1
335                 tsteq   \irqnr, #32
336                 beq     1001b
337                 teq     \irqnr, #32
338                 .endm
340                 .macro  irq_prio_table
341                 .ltorg
342                 .bss
343 ENTRY(soft_irq_mask)
344                 .word   0
345                 .text
346                 .endm
348 #elif defined(CONFIG_ARCH_TBOX)
350                 .macro  disable_fiq
351                 .endm
353                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
354                 ldr     \irqstat, =0xffff7000
355                 ldr     \irqstat, [\irqstat]            @ get interrupts
356                 ldr     \base, =soft_irq_mask
357                 ldr     \base, [\base]
358                 mov     \irqnr, #0
359                 and     \irqstat, \irqstat, \base       @ mask out disabled ones
360 1001:           tst     \irqstat, #1
361                 addeq   \irqnr, \irqnr, #1
362                 moveq   \irqstat, \irqstat, lsr #1
363                 tsteq   \irqnr, #32
364                 beq     1001b
365                 teq     \irqnr, #32
366                 .endm
368                 .macro  irq_prio_table
369                 .ltorg
370                 .bss
371 ENTRY(soft_irq_mask)
372                 .word   0
373                 .text
374                 .endm
376 #elif defined(CONFIG_ARCH_SA1100)
378                 .macro  disable_fiq
379                 .endm
381                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
382                 mov     r4, #0xfa000000                 @ ICIP = 0xfa050000
383                 add     r4, r4, #0x00050000
384                 ldr     \irqstat, [r4]                  @ get irqs
385                 ldr     \irqnr, [r4, #4]                @ ICMR = 0xfa050004
386                 ands    \irqstat, \irqstat, \irqnr
387                 mov     \irqnr, #0
388                 beq     1001f
389                 tst     \irqstat, #0xff
390                 moveq   \irqstat, \irqstat, lsr #8
391                 addeq   \irqnr, \irqnr, #8
392                 tsteq   \irqstat, #0xff
393                 moveq   \irqstat, \irqstat, lsr #8
394                 addeq   \irqnr, \irqnr, #8
395                 tsteq   \irqstat, #0xff
396                 moveq   \irqstat, \irqstat, lsr #8
397                 addeq   \irqnr, \irqnr, #8
398                 tst     \irqstat, #0x0f
399                 moveq   \irqstat, \irqstat, lsr #4
400                 addeq   \irqnr, \irqnr, #4
401                 tst     \irqstat, #0x03
402                 moveq   \irqstat, \irqstat, lsr #2
403                 addeq   \irqnr, \irqnr, #2
404                 tst     \irqstat, #0x01
405                 addeqs  \irqnr, \irqnr, #1
406 1001:
407                 .endm
409                 .macro  irq_prio_table
410                 .endm
412 #elif defined(CONFIG_ARCH_L7200)
413 #include <asm/hardware.h>
414         
415                 .equ    irq_base_addr,  IO_BASE_2
417                 .macro  disable_fiq
418                 .endm
420                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
421                 mov     \irqstat, #irq_base_addr                @ Virt addr IRQ regs
422                 add     \irqstat, \irqstat, #0x00001000         @ Status reg
423                 ldr     \irqstat, [\irqstat, #0]                @ get interrupts
424                 mov     \irqnr, #0
425 1001:           tst     \irqstat, #1
426                 addeq   \irqnr, \irqnr, #1
427                 moveq   \irqstat, \irqstat, lsr #1
428                 tsteq   \irqnr, #32
429                 beq     1001b
430                 teq     \irqnr, #32
431                 .endm
433                 .macro  irq_prio_table
434                 .endm
436 #elif defined(CONFIG_ARCH_INTEGRATOR)
438                 .macro  disable_fiq
439                 .endm
441                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
442 /* FIXME: should not be using soo many LDRs here */
443                 ldr     \base, =IO_ADDRESS(INTEGRATOR_IC_BASE)
444                 mov     \irqnr, #IRQ_PIC_START
445                 ldr     \irqstat, [\base, #IRQ_STATUS]          @ get masked status
446                 ldr     \base, =IO_ADDRESS(INTEGRATOR_HDR_BASE)
447                 teq     \irqstat, #0
448                 ldreq   \irqstat, [\base, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
449                 moveq   \irqnr, #IRQ_CIC_START
451 1001:           tst     \irqstat, #15
452                 bne     1002f
453                 add     \irqnr, \irqnr, #4
454                 movs    \irqstat, \irqstat, lsr #4
455                 bne     1001b
456 1002:           tst     \irqstat, #1
457                 bne     1003f
458                 add     \irqnr, \irqnr, #1
459                 movs    \irqstat, \irqstat, lsr #1
460                 bne     1002b
461 1003:           /* EQ will be set if no irqs pending */
462                 .endm
464                 .macro  irq_prio_table
465                 .endm
467 #elif defined(CONFIG_ARCH_VERSATILE_PB)
469                 .macro  disable_fiq
470                 .endm
472                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
473                 ldr     \base, =IO_ADDRESS(VERSATILE_VIC_BASE)
474                 ldr     \irqstat, [\base, #VIC_IRQ_STATUS]      @ get masked status
475                 mov     \irqnr, #0
476                 teq     \irqstat, #0
477                 beq     1003f
479 1001:           tst     \irqstat, #15
480                 bne     1002f
481                 add     \irqnr, \irqnr, #4
482                 movs    \irqstat, \irqstat, lsr #4
483                 bne     1001b
484 1002:           tst     \irqstat, #1
485                 bne     1003f
486                 add     \irqnr, \irqnr, #1
487                 movs    \irqstat, \irqstat, lsr #1
488                 bne     1002b
489 1003:           /* EQ will be set if no irqs pending */
491 @               clz     \irqnr, \irqstat
492 @1003:          /* EQ will be set if we reach MAXIRQNUM */
493                 .endm
495                 .macro  irq_prio_table
496                 .endm
498 #elif defined(CONFIG_ARCH_CLPS711X)
500 #include <asm/hardware/clps7111.h>
502                 .macro  disable_fiq
503                 .endm
505 #if (INTSR2 - INTSR1) != (INTMR2 - INTMR1)
506 #error INTSR stride != INTMR stride
507 #endif
509                 .macro  get_irqnr_and_base, irqnr, stat, base, mask
510                 mov     \base, #CLPS7111_BASE
511                 ldr     \stat, [\base, #INTSR1]
512                 ldr     \mask, [\base, #INTMR1]
513                 mov     \irqnr, #4
514                 mov     \mask, \mask, lsl #16
515                 and     \stat, \stat, \mask, lsr #16
516                 movs    \stat, \stat, lsr #4
517                 bne     1001f
519                 add     \base, \base, #INTSR2 - INTSR1
520                 ldr     \stat, [\base, #INTSR1]
521                 ldr     \mask, [\base, #INTMR1]
522                 mov     \irqnr, #16
523                 mov     \mask, \mask, lsl #16
524                 and     \stat, \stat, \mask, lsr #16
526 1001:           tst     \stat, #255
527                 addeq   \irqnr, \irqnr, #8
528                 moveq   \stat, \stat, lsr #8
529                 tst     \stat, #15
530                 addeq   \irqnr, \irqnr, #4
531                 moveq   \stat, \stat, lsr #4
532                 tst     \stat, #3
533                 addeq   \irqnr, \irqnr, #2
534                 moveq   \stat, \stat, lsr #2
535                 tst     \stat, #1
536                 addeq   \irqnr, \irqnr, #1
537                 moveq   \stat, \stat, lsr #1
538                 tst     \stat, #1                       @ bit 0 should be set
539                 .endm
541                 .macro  irq_prio_table
542                 .endm
543         
544 #elif defined (CONFIG_ARCH_CAMELOT)
545 #include <asm/arch/platform.h>
546 #undef IRQ_MODE /* same name defined in asm/proc/ptrace.h */
547 #include <asm/arch/int_ctrl00.h>
548         
549                 .macro  disable_fiq
550                 .endm
552                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
553         
554                 ldr     \irqstat, =INT_ID(IO_ADDRESS(EXC_INT_CTRL00_BASE))
555                 ldr     \irqnr,[\irqstat]               
556                 cmp     \irqnr,#0
557                 subne   \irqnr,\irqnr,#1
559         
560                 .endm
562                 .macro  irq_prio_table
563                 .endm
565 #elif defined(CONFIG_ARCH_IOP321)
566                 .macro  disable_fiq
567                 .endm
569                 /*
570                  * Note: only deal with normal interrupts, not FIQ
571                  */
572                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
573                 mov     \irqnr, #0
574                 mrc     p6, 0, \irqstat, c8, c0, 0      @ Read IINTSRC
575                 cmp     \irqstat, #0
576                 beq     1001f
577                 clz     \irqnr, \irqstat
578                 mov     \base, #31
579                 subs    \irqnr,\base,\irqnr
580                 add     \irqnr,\irqnr,#IRQ_IOP321_DMA0_EOT
581 1001:
582                 .endm
584                 .macro  irq_prio_table
585                 .endm
587 #elif defined(CONFIG_ARCH_IOP331)
588                 .macro  disable_fiq
589                 .endm
591                 /*
592                  * Note: only deal with normal interrupts, not FIQ
593                  */
594                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
595                 mov     \irqnr, #0
596                 mrc     p6, 0, \irqstat, c4, c0, 0      @ Read IINTSRC0
597                 cmp     \irqstat, #0
598                 bne     1002f
599                 mrc     p6, 0, \irqstat, c5, c0, 0      @ Read IINTSRC1
600                 cmp     \irqstat, #0
601                 beq     1001f
602                 clz     \irqnr, \irqstat
604  *              mov     \base, #31
605  *              subs    \irqnr,\base,\irqnr
606  */
607         rsbs    \irqnr,\irqnr,#31   @ recommend by RMK
608                 add     \irqnr,\irqnr,#IRQ_IOP331_XINT8
609                 b       1001f
610 1002:           clz     \irqnr, \irqstat
611                 mov     \base, #31
612                 subs    \irqnr,\base,\irqnr
613                 add     \irqnr,\irqnr,#IRQ_IOP331_DMA0_EOT
614 1001:
615                 .endm
617                 .macro  irq_prio_table
618                 .endm
620 #elif defined(CONFIG_ARCH_PXA)
622                 .macro  disable_fiq
623                 .endm
625                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
626 #ifdef CONFIG_PXA27x
627                 mrc     p6, 0, \irqstat, c0, c0, 0              @ ICIP
628                 mrc     p6, 0, \irqnr, c1, c0, 0                @ ICMR
629 #else
630                 mov     \base, #io_p2v(0x40000000)      @ IIR Ctl = 0x40d00000
631                 add     \base, \base, #0x00d00000
632                 ldr     \irqstat, [\base, #0]           @ ICIP
633                 ldr     \irqnr, [\base, #4]             @ ICMR
634 #endif
635                 ands    \irqnr, \irqstat, \irqnr
636                 beq     1001f
637                 rsb     \irqstat, \irqnr, #0
638                 and     \irqstat, \irqstat, \irqnr
639                 clz     \irqnr, \irqstat
640                 rsb     \irqnr, \irqnr, #(31 - PXA_IRQ_SKIP)
641 1001:
642                 .endm
644                 .macro  irq_prio_table
645                 .endm
647 #elif defined(CONFIG_ARCH_IXP2000)
649                 .macro  disable_fiq
650                 .endm
652                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
653                 
654                 mov     \irqnr, #0x0              @clear out irqnr as default
655                 mov     \base, #0xfe000000        
656                 orr     \base, \base, #0x00ff0000
657                 orr     \base, \base, #0x0000a000
658                 orr     \base, \base, #0x08
659                 ldr     \irqstat, [\base]         @ get interrupts 
660                 mov     \tmp, #IXP2000_VALID_IRQ_MASK & 0xff000000
661                 orr     \tmp, \tmp, #IXP2000_VALID_IRQ_MASK & 0x00ff0000
662                 orr     \tmp, \tmp, #IXP2000_VALID_IRQ_MASK & 0x0000ff00
663                 orr     \tmp, \tmp, #IXP2000_VALID_IRQ_MASK & 0x000000ff
664                 and     \irqstat, \irqstat, \tmp
666                 cmp     \irqstat, #0
667                 beq     1001f   
669                 clz     \irqnr, \irqstat
670                 mov     \base, #31
671                 subs    \irqnr, \base, \irqnr
672                 
673                 /*
674                  * We handle PCIA and PCIB here so we don't have an
675                  * extra layer of code just to check these two bits.
676                  */
677                 cmp     \irqnr, #IRQ_IXP2000_PCI
678                 bne     1001f
680                 mov     \base, #0xfe000000
681                 orr     \base, \base, #0x00fd0000
682                 orr     \base, \base, #0x0000e100
683                 orr     \base, \base, #0x00000058
684                 ldr     \irqstat, [\base]
686                 mov     \tmp, #(1<<26)
687                 tst     \irqstat, \tmp
688                 movne   \irqnr, #IRQ_IXP2000_PCIA
689                 bne     1001f
691                 mov     \tmp, #(1<<27)
692                 tst     \irqstat, \tmp
693                 movne   \irqnr, #IRQ_IXP2000_PCIB
695 1001:
696                 .endm 
697                 
698                 .macro  irq_prio_table
699                 .endm
701 #elif defined (CONFIG_ARCH_IXP4XX)
703                 .macro  disable_fiq
704                 .endm
705                 
706                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
707                 ldr     \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET)
708                 ldr     \irqstat, [\irqstat]            @ get interrupts
709                 cmp     \irqstat, #0
710                 beq     1002f
711                 clz     \irqnr, \irqstat
712                 mov     \base, #31
713                 subs    \irqnr, \base, \irqnr
714                 
716 1001:           tst     \irqstat, #1
717                 addeq   \irqnr, \irqnr, #1
718                 moveq   \irqstat, \irqstat, lsr #1
719                 tsteq   \irqnr, #32
720                 beq     1001b
721                 teq     \irqnr, #32
723 1002:
724                 .endm
726                 .macro  irq_prio_table
727                 .endm
729 #elif defined(CONFIG_ARCH_OMAP)
731                 .macro  disable_fiq
732                 .endm
734                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
735                 ldr     \base, =IO_ADDRESS(OMAP_IH1_BASE)
736                 ldr     \irqnr, [\base, #IRQ_ITR_REG_OFFSET]
737                 ldr     \tmp, [\base, #IRQ_MIR_REG_OFFSET]
738                 mov     \irqstat, #0xffffffff
739                 bic     \tmp, \irqstat, \tmp
740                 tst     \irqnr, \tmp
741                 beq     1510f
743                 ldr     \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
744                 cmp     \irqnr, #0
745                 ldreq   \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
746                 cmpeq   \irqnr, #INT_IH2_IRQ
747                 ldreq   \base, =IO_ADDRESS(OMAP_IH2_BASE)
748                 ldreq   \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
749                 addeqs  \irqnr, \irqnr, #32
750 1510:
751                 .endm
753                 .macro  irq_prio_table
754                 .endm
756 #elif defined(CONFIG_ARCH_S3C2410)
757                 /* S3C2410X IRQ Handler, <ben@simtec.co.uk> */
759                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
761 30000:
762                 mov     \tmp, #S3C2410_VA_IRQ
763                 ldr     \irqnr, [ \tmp, #0x14 ]         @ get irq no
764                 teq     \irqnr, #4
765                 teqne   \irqnr, #5
766                 beq     1002f                           @ external irq reg
767                 teq     \irqnr, #16
768                 beq     1003f                           @ lcd controller
770                 @ debug check to see if interrupt reported is the same
771                 @ as the offset....
773                 teq     \irqnr, #0
774                 beq     20002f
775                 ldr     \irqstat, [ \tmp, #0x10 ]       @ INTPND
776                 mov     \irqstat, \irqstat, lsr \irqnr
777                 tst     \irqstat, #1
778                 bne     20002f
780 #if 1
781                 stmfd   r13!, { r0 - r4 , r14 }
782                 ldr     r1,     [ \tmp, #0x14 ]         @ intoffset
783                 ldr     r2,     [ \tmp, #0x10 ]         @ INTPND
784                 ldr     r3,     [ \tmp, #0x00 ]         @ SRCPND
785                 adr     r0, 20003f
786                 bl      printk
787                 b       20004f
788 #endif
789 20003:
790                 .ascii  "<7>irq: err - bad offset %d, intpnd=%08x, srcpnd=%08x\n"
791                 .byte   0
792                 .align  4
793 20004:
794                 mov     r1, #1
795                 mov     \tmp, #S3C2410_VA_IRQ
796                 ldmfd   r13!, { r0 - r4 , r14 }
798                 @ try working out interript number for ourselves
799                 mov     \irqnr, #0
800                 ldr     \irqstat, [ \tmp, #0x10 ]       @ INTPND
801 10021:
802                 movs    \irqstat, \irqstat, lsr#1
803                 bcs     30000b          @ try and re-start the proccess
804                 add     \irqnr, \irqnr, #1
805                 cmp     \irqnr, #32
806                 ble     10021b
808                 @ found no interrupt, set Z flag and leave
809                 movs    \irqnr, #0
810                 b       1001f
812 20005:
813 20002:          @ exit
814                 @ we base the s3c2410x interrupts at 16 and above to allow
815                 @ isa peripherals to have their standard interrupts, also
816                 @ ensure that Z flag is un-set on exit
818                 @ note, we cannot be sure if we get IRQ_EINT0 (0) that
819                 @ there is simply no interrupt pending, so in all other
820                 @ cases we jump to say we have found something, otherwise
821                 @ we check to see if the interrupt really is assrted
822                 adds    \irqnr, \irqnr, #IRQ_EINT0
823                 teq     \irqnr, #IRQ_EINT0
824                 bne     1001f                           @ exit
825                 ldr     \irqstat, [ \tmp, #0x10 ]       @ INTPND
826                 teq     \irqstat, #0
827                 moveq   \irqnr, #0
828                 b       1001f
830                 @ we get here from no main or external interrupts pending
831 1002:
832                 add     \tmp, \tmp, #S3C2410_VA_GPIO - S3C2410_VA_IRQ
833                 ldr     \irqstat, [ \tmp, # 0xa8 ]      @ EXTINTPEND
834                 ldr     \irqnr, [ \tmp, # 0xa4 ]        @ EXTINTMASK
836                 bic     \irqstat, \irqstat, \irqnr      @ clear masked irqs
838                 mov     \irqnr, #IRQ_EINT4              @ start extint nos
839                 mov     \irqstat, \irqstat, lsr#4       @ ignore bottom 4 bits
840 10021:
841                 movs    \irqstat, \irqstat, lsr#1
842                 bcs     1004f
843                 add     \irqnr, \irqnr, #1
844                 cmp     \irqnr, #IRQ_EINT23
845                 ble     10021b
847                 @ found no interrupt, set Z flag and leave
848                 movs    \irqnr, #0
849                 b       1001f
851 1003:
852                 @ lcd interrupt has been asserted...
853                 add     \tmp, \tmp, #S3C2410_VA_LCD - S3C2410_VA_IRQ
854                 ldr     \irqstat, [ \tmp, # 0x54 ]      @ lcd int pending
856                 tst     \irqstat, #2
857                 movne   \irqnr, #IRQ_LCD_FRAME
858                 tst     \irqstat, #1
859                 movne   \irqnr, #IRQ_LCD_FIFO
861                 @ fall through to exit with flags updated
863 1004:           @ ensure Z flag clear in case our MOVS shifted out the last bit
864                 teq     \irqnr, #0
865 1001:
866                 @ exit irq routine
867                 .endm
870                 /* currently don't need an disable_fiq macro */
872                 .macro  disable_fiq
873                 .endm
875                 /* we don't have an irq priority table */
876                 .macro irq_prio_table
877                 .endm
879 #elif defined(CONFIG_ARCH_LH7A400)
881 # if defined (CONFIG_ARCH_LH7A404)
882 #  error "LH7A400 and LH7A404 are mutually exclusive"
883 # endif
884                 .macro  disable_fiq
885                 .endm
887                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
888                 mov     \irqnr, #0
889                 mov     \base, #io_p2v(0x80000000)      @ APB registers
890                 ldr     \irqstat, [\base, #0x500]       @ PIC INTSR
892 1001:           movs    \irqstat, \irqstat, lsr #1      @ Shift into carry
893                 bcs     1008f                           @ Bit set; irq found
894                 add     \irqnr, \irqnr, #1
895                 bne     1001b                           @ Until no bits
896                 b       1009f                           @ Nothing?  Hmm.
897 1008:           movs    \irqstat, #1                    @ Force !Z
898 1009:
899                .endm
901                .macro  irq_prio_table
902                .endm
904 #elif defined(CONFIG_ARCH_LH7A404)
906                 .macro  disable_fiq
907                 .endm
909                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
910                 mov     \irqnr, #0                      @ VIC1 irq base
911                 mov     \base, #io_p2v(0x80000000)      @ APB registers
912                 add     \base, \base, #0x8000
913                 ldr     \tmp, [\base, #0x0030]          @ VIC1_VECTADDR
914                 tst     \tmp, #VA_VECTORED              @ Direct vectored
915                 bne     1002f
916                 tst     \tmp, #VA_VIC1DEFAULT           @ Default vectored VIC1
917                 ldrne   \irqstat, [\base, #0]           @ VIC1_IRQSTATUS
918                 bne     1001f
919                 add     \base, \base, #(0xa000 - 0x8000)
920                 ldr     \tmp, [\base, #0x0030]          @ VIC2_VECTADDR
921                 tst     \tmp, #VA_VECTORED              @ Direct vectored
922                 bne     1002f
923                 ldr     \irqstat, [\base, #0]           @ VIC2_IRQSTATUS
924                 mov     \irqnr, #32                     @ VIC2 irq base
926 1001:           movs    \irqstat, \irqstat, lsr #1      @ Shift into carry
927                 bcs     1008f                           @ Bit set; irq found
928                 add     \irqnr, \irqnr, #1
929                 bne     1001b                           @ Until no bits
930                 b       1009f                           @ Nothing?  Hmm.
931 1002:           and     \irqnr, \tmp, #0x3f             @ Mask for valid bits
932 1008:           movs    \irqstat, #1                    @ Force !Z
933                 str     \tmp, [\base, #0x0030]          @ Clear vector
934 1009:
935                .endm
937                .macro  irq_prio_table
938                .endm
940 #elif defined(CONFIG_ARCH_IMX)
942                 .macro  disable_fiq
943                 .endm
944 #define AITC_NIVECSR   0x40
945                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
946                 ldr     \irqstat, =IO_ADDRESS(IMX_AITC_BASE)
947                 @ Load offset & priority of the highest priority
948                 @ interrupt pending.
949                 ldr     \irqnr, [\irqstat, #AITC_NIVECSR]
950                 @ Shift off the priority leaving the offset or
951                 @ "interrupt number"
952                 mov     \irqnr, \irqnr, lsr #16
953                 ldr     \irqstat, =1    @ dummy compare
954                 ldr     \base, =0xFFFF          // invalid interrupt
955                 cmp     \irqnr, \base
956                 bne     1001f
957                 ldr     \irqstat, =0
958 1001:
959                 tst     \irqstat, #1    @ to make the condition code = TRUE
960                 .endm
962                 .macro  irq_prio_table
963                 .endm
965 #elif defined(CONFIG_ARCH_H720X)
967                 .macro  disable_fiq
968                 .endm
970                 .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
971 #if defined (CONFIG_CPU_H7201) || defined (CONFIG_CPU_H7202)
972                 @ we could use the id register on H7202, but this is not
973                 @ properly updated when we come back from asm_do_irq
974                 @ without a previous return from interrupt
975                 @ (see loops below in irq_svc, irq_usr)
976                 @ We see unmasked pending ints only, as the masked pending ints
977                 @ are not visible here
979                 mov     \base, #0xf0000000             @ base register
980                 orr     \base, \base, #0x24000         @ irqbase
981                 ldr     \irqstat, [\base, #0x04]        @ get interrupt status
982 #if defined (CONFIG_CPU_H7201)
983                 ldr     \tmp, =0x001fffff
984 #else
985                 mvn     \tmp, #0xc0000000
986 #endif
987                 and     \irqstat, \irqstat, \tmp        @ mask out unused ints
988                 mov     \irqnr, #0
990                 mov     \tmp, #0xff00
991                 orr     \tmp, \tmp, #0xff
992                 tst     \irqstat, \tmp
993                 addeq   \irqnr, \irqnr, #16
994                 moveq   \irqstat, \irqstat, lsr #16
995                 tst     \irqstat, #255
996                 addeq   \irqnr, \irqnr, #8
997                 moveq   \irqstat, \irqstat, lsr #8
998                 tst     \irqstat, #15
999                 addeq   \irqnr, \irqnr, #4
1000                 moveq   \irqstat, \irqstat, lsr #4
1001                 tst     \irqstat, #3
1002                 addeq   \irqnr, \irqnr, #2
1003                 moveq   \irqstat, \irqstat, lsr #2
1004                 tst     \irqstat, #1
1005                 addeq   \irqnr, \irqnr, #1
1006                 moveq   \irqstat, \irqstat, lsr #1
1007                 tst     \irqstat, #1                   @ bit 0 should be set
1008                 .endm
1010                 .macro  irq_prio_table
1011                 .endm
1013 #else
1014 #error hynix processor selection missmatch
1015 #endif
1017 #elif defined(CONFIG_ARCH_MOXACPU)
1018                 .macro  disable_fiq
1019                 .endm
1021                 .macro get_fiqnr_and_base, irqnr, irqstat, base, tmp
1022                 ldr             \base, =(IO_ADDRESS(CPE_IC_BASE)+FIQ_STATUS_REG)
1023                 ldr             \irqstat, [\base]
1024                 mov             \irqnr, #32
1025 2001:
1026                 tst             \irqstat, #1
1027                 bne             2002f
1028                 add             \irqnr, \irqnr, #1
1029                 mov             \irqstat, \irqstat, lsr #1
1030                 cmp             \irqnr, #64
1031                 bcc             2001b
1032 2002:
1033                 .endm
1035                 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
1036                 ldr             \base, =(IO_ADDRESS(CPE_IC_BASE)+IRQ_STATUS_REG)
1037                 ldr             \irqstat, [\base]
1038                 mov             \irqnr, #0
1039 2003:
1040                 tst             \irqstat, #1
1041                 bne             2004f
1042                 add             \irqnr, \irqnr, #1
1043                 mov             \irqstat, \irqstat, lsr #1
1044                 cmp             \irqnr, #32
1045                 bcc             2003b
1046 2004:
1047                 .endm
1049                 .macro irq_prio_table
1050                 .endm
1052 #else
1053 #error Unknown architecture
1054 #endif
1057  * Invalid mode handlers
1058  */
1059 __pabt_invalid: sub     sp, sp, #S_FRAME_SIZE           @ Allocate frame size in one go
1060                 stmia   sp, {r0 - lr}                   @ Save XXX r0 - lr
1061                 ldr     r4, .LCabt
1062                 mov     r1, #BAD_PREFETCH
1063                 b       1f
1065 __dabt_invalid: sub     sp, sp, #S_FRAME_SIZE
1066                 stmia   sp, {r0 - lr}                   @ Save SVC r0 - lr [lr *should* be intact]
1067                 ldr     r4, .LCabt
1068                 mov     r1, #BAD_DATA
1069                 b       1f
1071 __irq_invalid:  sub     sp, sp, #S_FRAME_SIZE           @ Allocate space on stack for frame
1072                 stmfd   sp, {r0 - lr}                   @ Save r0 - lr
1073                 ldr     r4, .LCirq
1074                 mov     r1, #BAD_IRQ
1075                 b       1f
1077 __und_invalid:  sub     sp, sp, #S_FRAME_SIZE
1078                 stmia   sp, {r0 - lr}
1079                 ldr     r4, .LCund
1080                 mov     r1, #BAD_UNDEFINSTR             @ int reason
1082 1:              zero_fp
1083                 ldmia   r4, {r5 - r7}                   @ Get XXX pc, cpsr, old_r0
1084                 add     r4, sp, #S_PC
1085                 stmia   r4, {r5 - r7}                   @ Save XXX pc, cpsr, old_r0
1086                 mov     r0, sp
1087                 and     r2, r6, #31                     @ int mode
1088                 b       bad_mode
1091  * SVC mode handlers
1092  */
1093                 .align  5
1094 __dabt_svc:     sub     sp, sp, #S_FRAME_SIZE
1095                 stmia   sp, {r0 - r12}                  @ save r0 - r12
1096                 ldr     r2, .LCabt
1097                 add     r0, sp, #S_FRAME_SIZE
1098                 ldmia   r2, {r2 - r4}                   @ get pc, cpsr
1099                 add     r5, sp, #S_SP
1100                 mov     r1, lr
1101                 stmia   r5, {r0 - r4}                   @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
1102                 mrs     r9, cpsr                        @ Enable interrupts if they were
1103                 tst     r3, #PSR_I_BIT
1104                 biceq   r9, r9, #PSR_I_BIT              @ previously
1106  * This routine must not corrupt r9
1107  */
1108 #ifdef MULTI_ABORT
1109                 ldr     r4, .LCprocfns                  @ pass r2, r3 to
1110                 mov     lr, pc                          @ processor code
1111                 ldr     pc, [r4]                        @ call processor specific code
1112 #else
1113                 bl      CPU_ABORT_HANDLER
1114 #endif
1115                 msr     cpsr_c, r9
1116                 mov     r2, sp
1117                 bl      do_DataAbort
1118                 disable_irq r0
1119                 ldr     r0, [sp, #S_PSR]
1120                 msr     spsr_cxsf, r0
1121                 ldmia   sp, {r0 - pc}^                  @ load r0 - pc, cpsr
1123                 .align  5
1124 __irq_svc:      sub     sp, sp, #S_FRAME_SIZE
1125                 stmia   sp, {r0 - r12}                  @ save r0 - r12
1126                 ldr     r7, .LCirq
1127                 add     r5, sp, #S_FRAME_SIZE
1128                 ldmia   r7, {r7 - r9}
1129                 add     r4, sp, #S_SP
1130                 mov     r6, lr
1131                 stmia   r4, {r5, r6, r7, r8, r9}        @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
1132 #ifdef CONFIG_PREEMPT
1133                 get_thread_info r8
1134                 ldr     r9, [r8, #TI_PREEMPT]           @ get preempt count
1135                 add     r7, r9, #1                      @ increment it
1136                 str     r7, [r8, #TI_PREEMPT]
1137 #endif
1138 1:              get_irqnr_and_base r0, r6, r5, lr
1139                 movne   r1, sp
1140                 @
1141                 @ routine called with r0 = irq number, r1 = struct pt_regs *
1142                 @
1143                 adrsvc  ne, lr, 1b
1144                 bne     asm_do_IRQ
1145 #ifdef CONFIG_PREEMPT
1146                 ldr     r0, [r8, #TI_FLAGS]             @ get flags
1147                 tst     r0, #_TIF_NEED_RESCHED
1148                 blne    svc_preempt
1149 preempt_return:
1150                 ldr     r0, [r8, #TI_PREEMPT]           @ read preempt value
1151                 teq     r0, r7
1152                 str     r9, [r8, #TI_PREEMPT]           @ restore preempt count
1153                 strne   r0, [r0, -r0]                   @ bug()
1154 #endif
1155                 ldr     r0, [sp, #S_PSR]                @ irqs are already disabled
1156                 msr     spsr_cxsf, r0
1157                 ldmia   sp, {r0 - pc}^                  @ load r0 - pc, cpsr
1159                 .ltorg
1161 #ifdef CONFIG_PREEMPT
1162 svc_preempt:    teq     r9, #0                          @ was preempt count = 0
1163                 ldreq   r6, .LCirq_stat
1164                 movne   pc, lr                          @ no
1165                 ldr     r0, [r6, #4]                    @ local_irq_count
1166                 ldr     r1, [r6, #8]                    @ local_bh_count
1167                 adds    r0, r0, r1
1168                 movne   pc, lr
1169                 mov     r7, #PREEMPT_ACTIVE
1170                 str     r7, [r8, #TI_PREEMPT]           @ set PREEMPT_ACTIVE
1171 1:              enable_irq r2                           @ enable IRQs
1172                 bl      schedule
1173                 disable_irq r0                          @ disable IRQs
1174                 ldr     r0, [r8, #TI_FLAGS]             @ get new tasks TI_FLAGS
1175                 tst     r0, #_TIF_NEED_RESCHED
1176                 beq     preempt_return                  @ go again
1177                 b       1b
1178 #endif
1180                 .align  5
1181 __und_svc:      sub     sp, sp, #S_FRAME_SIZE
1182                 stmia   sp, {r0 - r12}                  @ save r0 - r12
1183                 ldr     r3, .LCund
1184                 mov     r4, lr
1185                 ldmia   r3, {r5 - r7}
1186                 add     r3, sp, #S_FRAME_SIZE
1187                 add     r2, sp, #S_SP
1188                 stmia   r2, {r3 - r7}                   @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
1190                 ldr     r0, [r5, #-4]                   @ r0 = instruction
1191                 adrsvc  al, r9, 1f                      @ r9 = normal FP return
1192                 bl      call_fpe                        @ lr = undefined instr return
1194                 mov     r0, sp                          @ struct pt_regs *regs
1195                 bl      do_undefinstr
1197 1:              disable_irq r0
1198                 ldr     lr, [sp, #S_PSR]                @ Get SVC cpsr
1199                 msr     spsr_cxsf, lr
1200                 ldmia   sp, {r0 - pc}^                  @ Restore SVC registers
1202                 .align  5
1203 __pabt_svc:     sub     sp, sp, #S_FRAME_SIZE
1204                 stmia   sp, {r0 - r12}                  @ save r0 - r12
1205                 ldr     r2, .LCabt
1206                 add     r0, sp, #S_FRAME_SIZE
1207                 ldmia   r2, {r2 - r4}                   @ get pc, cpsr
1208                 add     r5, sp, #S_SP
1209                 mov     r1, lr
1210                 stmia   r5, {r0 - r4}                   @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
1211                 mrs     r9, cpsr                        @ Enable interrupts if they were
1212                 tst     r3, #PSR_I_BIT
1213                 biceq   r9, r9, #PSR_I_BIT              @ previously
1214                 msr     cpsr_c, r9
1215                 mov     r0, r2                          @ address (pc)
1216                 mov     r1, sp                          @ regs
1217                 bl      do_PrefetchAbort                @ call abort handler
1218                 disable_irq r0
1219                 ldr     r0, [sp, #S_PSR]
1220                 msr     spsr_cxsf, r0
1221                 ldmia   sp, {r0 - pc}^                  @ load r0 - pc, cpsr
1223                 .align  5
1224 .LCirq:         .word   __temp_irq
1225 .LCund:         .word   __temp_und
1226 .LCabt:         .word   __temp_abt
1227 #ifdef MULTI_ABORT
1228 .LCprocfns:     .word   processor
1229 #endif
1230 .LCfp:          .word   fp_enter
1231 #ifdef CONFIG_PREEMPT
1232 .LCirq_stat:    .word   irq_stat
1233 #endif
1235                 irq_prio_table
1238  * User mode handlers
1239  */
1240                 .align  5
1241 __dabt_usr:     sub     sp, sp, #S_FRAME_SIZE           @ Allocate frame size in one go
1242                 stmia   sp, {r0 - r12}                  @ save r0 - r12
1243                 ldr     r7, .LCabt
1244                 add     r5, sp, #S_PC
1245                 ldmia   r7, {r2 - r4}                   @ Get USR pc, cpsr
1246                 stmia   r5, {r2 - r4}                   @ Save USR pc, cpsr, old_r0
1247                 stmdb   r5, {sp, lr}^
1248                 alignment_trap r7, r7, __temp_abt
1249                 zero_fp
1250 #ifdef MULTI_ABORT
1251                 ldr     r4, .LCprocfns                  @ pass r2, r3 to
1252                 mov     lr, pc                          @ processor code
1253                 ldr     pc, [r4]                        @ call processor specific code
1254 #else
1255                 bl      CPU_ABORT_HANDLER
1256 #endif
1257                 enable_irq r2                           @ Enable interrupts
1258                 mov     r2, sp
1259                 adrsvc  al, lr, ret_from_exception
1260                 b       do_DataAbort
1262                 .align  5
1263 __irq_usr:      sub     sp, sp, #S_FRAME_SIZE
1264                 stmia   sp, {r0 - r12}                  @ save r0 - r12
1265                 ldr     r4, .LCirq
1266                 add     r8, sp, #S_PC
1267                 ldmia   r4, {r5 - r7}                   @ get saved PC, SPSR
1268                 stmia   r8, {r5 - r7}                   @ save pc, psr, old_r0
1269                 stmdb   r8, {sp, lr}^
1270                 alignment_trap r4, r7, __temp_irq
1271                 zero_fp
1272 #ifdef CONFIG_PREEMPT
1273                 get_thread_info r8
1274                 ldr     r9, [r8, #TI_PREEMPT]           @ get preempt count
1275                 add     r7, r9, #1                      @ increment it
1276                 str     r7, [r8, #TI_PREEMPT]
1277 #endif
1278 1:              get_irqnr_and_base r0, r6, r5, lr
1279                 movne   r1, sp
1280                 adrsvc  ne, lr, 1b
1281                 @
1282                 @ routine called with r0 = irq number, r1 = struct pt_regs *
1283                 @
1284                 bne     asm_do_IRQ
1285 #ifdef CONFIG_PREEMPT
1286                 ldr     r0, [r8, #TI_PREEMPT]
1287                 teq     r0, r7
1288                 str     r9, [r8, #TI_PREEMPT]
1289                 strne   r0, [r0, -r0]
1290                 mov     tsk, r8
1291 #else
1292                 get_thread_info tsk
1293 #endif
1294                 mov     why, #0
1295                 b       ret_to_user
1297                 .ltorg
1299                 .align  5
1300 __und_usr:      sub     sp, sp, #S_FRAME_SIZE           @ Allocate frame size in one go
1301                 stmia   sp, {r0 - r12}                  @ Save r0 - r12
1302                 ldr     r4, .LCund
1303                 add     r8, sp, #S_PC
1304                 ldmia   r4, {r5 - r7}
1305                 stmia   r8, {r5 - r7}                   @ Save USR pc, cpsr, old_r0
1306                 stmdb   r8, {sp, lr}^                   @ Save user sp, lr
1307                 alignment_trap r4, r7, __temp_und
1308                 zero_fp
1309                 tst     r6, #PSR_T_BIT                  @ Thumb mode?
1310                 bne     fpundefinstr                    @ ignore FP
1311                 sub     r4, r5, #4
1312 1:              ldrt    r0, [r4]                        @ r0  = instruction
1313                 adrsvc  al, r9, ret_from_exception      @ r9  = normal FP return
1314                 adrsvc  al, lr, fpundefinstr            @ lr  = undefined instr return
1317  * The out of line fixup for the ldrt above.
1318  */
1319                 .section .fixup, "ax"
1320 2:              mov     pc, r9
1321                 .previous
1322                 .section __ex_table,"a"
1323                 .long   1b, 2b
1324                 .previous
1327  * r0 = instruction.
1329  * Check whether the instruction is a co-processor instruction.
1330  * If yes, we need to call the relevant co-processor handler.
1332  * Note that we don't do a full check here for the co-processor
1333  * instructions; all instructions with bit 27 set are well
1334  * defined.  The only instructions that should fault are the
1335  * co-processor instructions.  However, we have to watch out
1336  * for the ARM6/ARM7 SWI bug.
1338  * Emulators may wish to make use of the following registers:
1339  *  r0  - instruction opcode.
1340  *  r10 - this threads thread_info structure.
1341  */
1342 call_fpe:
1343                 tst     r0, #0x08000000                 @ only CDP/CPRT/LDC/STC have bit 27
1344 #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
1345                 and     r8, r0, #0x0f000000             @ mask out op-code bits
1346                 teqne   r8, #0x0f000000                 @ SWI (ARM6/7 bug)?
1347 #endif
1348                 moveq   pc, lr
1349                 get_thread_info r10                     @ get current thread
1350                 and     r8, r0, #0x00000f00             @ mask out CP number
1351                 mov     r7, #1
1352                 add     r6, r10, #TI_USED_CP
1353                 strb    r7, [r6, r8, lsr #8]            @ set appropriate used_cp[]
1354 #ifdef CONFIG_IWMMXT
1355                 @ Test if we need to give access to iWMMXt coprocessors
1356                 ldr     r5, [r10, #TI_FLAGS]
1357                 rsbs    r7, r8, #(1 << 8)               @ CP 0 or 1 only
1358                 movcss  r7, r5, lsr #(TIF_USING_IWMMXT + 1)
1359                 bcs     iwmmxt_task_enable
1360 #endif
1361                 enable_irq r7
1362                 add     pc, pc, r8, lsr #6
1363                 mov     r0, r0
1365                 mov     pc, lr                          @ CP#0
1366                 b       do_fpe                          @ CP#1 (FPE)
1367                 b       do_fpe                          @ CP#2 (FPE)
1368                 mov     pc, lr                          @ CP#3
1369                 mov     pc, lr                          @ CP#4
1370                 mov     pc, lr                          @ CP#5
1371                 mov     pc, lr                          @ CP#6
1372                 mov     pc, lr                          @ CP#7
1373                 mov     pc, lr                          @ CP#8
1374                 mov     pc, lr                          @ CP#9
1375 #ifdef CONFIG_VFP
1376                 b       do_vfp                          @ CP#10 (VFP)
1377                 b       do_vfp                          @ CP#11 (VFP)
1378 #else
1379                 mov     pc, lr                          @ CP#10 (VFP)
1380                 mov     pc, lr                          @ CP#11 (VFP)
1381 #endif
1382                 mov     pc, lr                          @ CP#12
1383                 mov     pc, lr                          @ CP#13
1384                 mov     pc, lr                          @ CP#14 (Debug)
1385                 mov     pc, lr                          @ CP#15 (Control)
1387 do_fpe:         ldr     r4, .LCfp
1388                 add     r10, r10, #TI_FPSTATE           @ r10 = workspace
1389                 ldr     pc, [r4]                        @ Call FP module USR entry point
1392  * The FP module is called with these registers set:
1393  *  r0  = instruction
1394  *  r5  = PC
1395  *  r9  = normal "successful" return address
1396  *  r10 = FP workspace
1397  *  lr  = unrecognised FP instruction return address
1398  */
1400                 .data
1401 ENTRY(fp_enter)
1402                 .word   fpundefinstr
1403                 .text
1405 fpundefinstr:   mov     r0, sp
1406                 adrsvc  al, lr, ret_from_exception
1407                 b       do_undefinstr
1409                 .align  5
1410 __pabt_usr:     sub     sp, sp, #S_FRAME_SIZE           @ Allocate frame size in one go
1411                 stmia   sp, {r0 - r12}                  @ Save r0 - r12
1412                 ldr     r4, .LCabt
1413                 add     r8, sp, #S_PC
1414                 ldmia   r4, {r5 - r7}                   @ Get USR pc, cpsr
1415                 stmia   r8, {r5 - r7}                   @ Save USR pc, cpsr, old_r0
1416                 stmdb   r8, {sp, lr}^                   @ Save sp_usr lr_usr
1417                 alignment_trap r4, r7, __temp_abt
1418                 zero_fp
1419                 enable_irq r0                           @ Enable interrupts
1420                 mov     r0, r5                          @ address (pc)
1421                 mov     r1, sp                          @ regs
1422                 bl      do_PrefetchAbort                @ call abort handler
1423                 /* fall through */
1425  * This is the return code to user mode for abort handlers
1426  */
1427 ENTRY(ret_from_exception)
1428                 get_thread_info tsk
1429                 mov     why, #0
1430                 b       ret_to_user
1433  * Register switch for ARMv3 and ARMv4 processors
1434  * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
1435  * previous and next are guaranteed not to be the same.
1436  */
1437 ENTRY(__switch_to)
1438                 add     ip, r1, #TI_CPU_SAVE
1439                 ldr     r3, [r2, #TI_CPU_DOMAIN]!
1440                 stmia   ip!, {r4 - sl, fp, sp, lr}      @ Store most regs on stack
1441 #if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
1442                 mra     r4, r5, acc0
1443                 stmia   ip, {r4, r5}
1444 #endif
1445                 mcr     p15, 0, r3, c3, c0, 0           @ Set domain register
1446 #ifdef CONFIG_VFP
1447                 @ Always disable VFP so we can lazily save/restore the old
1448                 @ state. This occurs in the context of the previous thread.
1449                 VFPFMRX r4, FPEXC
1450                 bic     r4, r4, #FPEXC_ENABLE
1451                 VFPFMXR FPEXC, r4
1452 #endif
1453 #if defined(CONFIG_IWMMXT)
1454                 bl      iwmmxt_task_switch
1455 #elif defined(CONFIG_CPU_XSCALE)
1456                 add     r4, r2, #40                     @ cpu_context_save->extra
1457                 ldmib   r4, {r4, r5}
1458                 mar     acc0, r4, r5
1459 #endif
1460                 ldmib   r2, {r4 - sl, fp, sp, pc}       @ Load all regs saved previously
1462                 __INIT
1464  * Vector stubs.  NOTE that we only align 'vector_IRQ' to a cache line boundary,
1465  * and we rely on each stub being exactly 48 (1.5 cache lines) in size.  This
1466  * means that we only ever load two cache lines for this code, or one if we're
1467  * lucky.  We also copy this code to 0x200 so that we can use branches in the
1468  * vectors, rather than ldr's.
1469  */
1470                 .align  5
1471 __stubs_start:
1473  * Interrupt dispatcher
1474  * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
1475  */
1476 vector_IRQ:     @
1477                 @ save mode specific registers
1478                 @
1479                 ldr     r13, .LCsirq
1480                 sub     lr, lr, #4
1481                 str     lr, [r13]                       @ save lr_IRQ
1482                 mrs     lr, spsr
1483                 str     lr, [r13, #4]                   @ save spsr_IRQ
1484 #if 1   /* add by Victor Yu. 06-09-2005 */
1485 #ifdef CONFIG_CPU_FA_IDLE
1486         nop
1487         nop
1488         and     lr, lr, #0x1f
1489         cmp     lr, #MODE_SVC
1490         bne     1000f
1491         ldr     r13, .LCsirq
1492         ldr     lr, [r13]
1493         ldr     r13, [lr]
1494         ldr     lr, .LCidle
1495         ldr     lr, [lr]
1496         cmp     r13, lr                         @ instruction is idle (mcr p15,0,r0,c7,c0,4)
1497         bne     1000f
1498 /* idle mode */
1499         ldr     r13, .LCsirq
1500         ldr     lr, [r13]
1501         add     lr, lr, #4                      @ next instruction
1502         str     lr, [r13]
1503 1000:
1504         nop
1505         nop
1506         mrs     lr, spsr
1507 #endif  /* CONFIG_CPU_FA_IDLE */
1508 #endif
1509                 @
1510                 @ now branch to the relevant MODE handling routine
1511                 @
1512                 mrs     r13, cpsr
1513                 bic     r13, r13, #MODE_MASK
1514                 orr     r13, r13, #MODE_SVC
1515                 msr     spsr_cxsf, r13                  @ switch to SVC_32 mode
1517                 and     lr, lr, #15
1518                 ldr     lr, [pc, lr, lsl #2]
1519                 movs    pc, lr                          @ Changes mode and branches
1521 .LCtab_irq:     .word   __irq_usr                       @  0  (USR_26 / USR_32)
1522                 .word   __irq_invalid                   @  1  (FIQ_26 / FIQ_32)
1523                 .word   __irq_invalid                   @  2  (IRQ_26 / IRQ_32)
1524                 .word   __irq_svc                       @  3  (SVC_26 / SVC_32)
1525                 .word   __irq_invalid                   @  4
1526                 .word   __irq_invalid                   @  5
1527                 .word   __irq_invalid                   @  6
1528                 .word   __irq_invalid                   @  7
1529                 .word   __irq_invalid                   @  8
1530                 .word   __irq_invalid                   @  9
1531                 .word   __irq_invalid                   @  a
1532                 .word   __irq_invalid                   @  b
1533                 .word   __irq_invalid                   @  c
1534                 .word   __irq_invalid                   @  d
1535                 .word   __irq_invalid                   @  e
1536                 .word   __irq_invalid                   @  f
1538                 .align  5
1541  * Data abort dispatcher - dispatches it to the correct handler for the processor mode
1542  * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
1543  */
1544 vector_data:    @
1545                 @ save mode specific registers
1546                 @
1547                 ldr     r13, .LCsabt
1548                 sub     lr, lr, #8
1549                 str     lr, [r13]
1550                 mrs     lr, spsr
1551                 str     lr, [r13, #4]
1552                 @
1553                 @ now branch to the relevant MODE handling routine
1554                 @
1555                 mrs     r13, cpsr
1556                 bic     r13, r13, #MODE_MASK
1557                 orr     r13, r13, #MODE_SVC
1558                 msr     spsr_cxsf, r13                  @ switch to SVC_32 mode
1560                 and     lr, lr, #15
1561                 ldr     lr, [pc, lr, lsl #2]
1562                 movs    pc, lr                          @ Changes mode and branches
1564 .LCtab_dabt:    .word   __dabt_usr                      @  0  (USR_26 / USR_32)
1565                 .word   __dabt_invalid                  @  1  (FIQ_26 / FIQ_32)
1566                 .word   __dabt_invalid                  @  2  (IRQ_26 / IRQ_32)
1567                 .word   __dabt_svc                      @  3  (SVC_26 / SVC_32)
1568                 .word   __dabt_invalid                  @  4
1569                 .word   __dabt_invalid                  @  5
1570                 .word   __dabt_invalid                  @  6
1571                 .word   __dabt_invalid                  @  7
1572                 .word   __dabt_invalid                  @  8
1573                 .word   __dabt_invalid                  @  9
1574                 .word   __dabt_invalid                  @  a
1575                 .word   __dabt_invalid                  @  b
1576                 .word   __dabt_invalid                  @  c
1577                 .word   __dabt_invalid                  @  d
1578                 .word   __dabt_invalid                  @  e
1579                 .word   __dabt_invalid                  @  f
1581                 .align  5
1584  * Prefetch abort dispatcher - dispatches it to the correct handler for the processor mode
1585  * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
1586  */
1587 vector_prefetch:
1588                 @
1589                 @ save mode specific registers
1590                 @
1591                 ldr     r13, .LCsabt
1592                 sub     lr, lr, #4
1593                 str     lr, [r13]                       @ save lr_ABT
1594                 mrs     lr, spsr
1595                 str     lr, [r13, #4]                   @ save spsr_ABT
1596                 @
1597                 @ now branch to the relevant MODE handling routine
1598                 @
1599                 mrs     r13, cpsr
1600                 bic     r13, r13, #MODE_MASK
1601                 orr     r13, r13, #MODE_SVC
1602                 msr     spsr_cxsf, r13                  @ switch to SVC_32 mode
1604                 ands    lr, lr, #15
1605                 ldr     lr, [pc, lr, lsl #2]
1606                 movs    pc, lr
1608 .LCtab_pabt:    .word   __pabt_usr                      @  0 (USR_26 / USR_32)
1609                 .word   __pabt_invalid                  @  1 (FIQ_26 / FIQ_32)
1610                 .word   __pabt_invalid                  @  2 (IRQ_26 / IRQ_32)
1611                 .word   __pabt_svc                      @  3 (SVC_26 / SVC_32)
1612                 .word   __pabt_invalid                  @  4
1613                 .word   __pabt_invalid                  @  5
1614                 .word   __pabt_invalid                  @  6
1615                 .word   __pabt_invalid                  @  7
1616                 .word   __pabt_invalid                  @  8
1617                 .word   __pabt_invalid                  @  9
1618                 .word   __pabt_invalid                  @  a
1619                 .word   __pabt_invalid                  @  b
1620                 .word   __pabt_invalid                  @  c
1621                 .word   __pabt_invalid                  @  d
1622                 .word   __pabt_invalid                  @  e
1623                 .word   __pabt_invalid                  @  f
1625                 .align  5
1628  * Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode
1629  * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
1630  */
1631 vector_undefinstr:
1632                 @
1633                 @ save mode specific registers
1634                 @
1635                 ldr     r13, .LCsund
1636                 str     lr, [r13]                       @ save lr_UND
1637                 mrs     lr, spsr
1638                 str     lr, [r13, #4]                   @ save spsr_UND
1639                 @
1640                 @ now branch to the relevant MODE handling routine
1641                 @
1642                 mrs     r13, cpsr
1643                 bic     r13, r13, #MODE_MASK
1644                 orr     r13, r13, #MODE_SVC
1645                 msr     spsr_cxsf, r13                  @ switch to SVC_32 mode
1647                 and     lr, lr, #15
1648                 ldr     lr, [pc, lr, lsl #2]
1649                 movs    pc, lr                          @ Changes mode and branches
1651 .LCtab_und:     .word   __und_usr                       @  0 (USR_26 / USR_32)
1652                 .word   __und_invalid                   @  1 (FIQ_26 / FIQ_32)
1653                 .word   __und_invalid                   @  2 (IRQ_26 / IRQ_32)
1654                 .word   __und_svc                       @  3 (SVC_26 / SVC_32)
1655                 .word   __und_invalid                   @  4
1656                 .word   __und_invalid                   @  5
1657                 .word   __und_invalid                   @  6
1658                 .word   __und_invalid                   @  7
1659                 .word   __und_invalid                   @  8
1660                 .word   __und_invalid                   @  9
1661                 .word   __und_invalid                   @  a
1662                 .word   __und_invalid                   @  b
1663                 .word   __und_invalid                   @  c
1664                 .word   __und_invalid                   @  d
1665                 .word   __und_invalid                   @  e
1666                 .word   __und_invalid                   @  f
1668                 .align  5
1670 /*=============================================================================
1671  * Undefined FIQs
1672  *-----------------------------------------------------------------------------
1673  * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
1674  * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg.
1675  * Basically to switch modes, we *HAVE* to clobber one register...  brain
1676  * damage alert!  I don't think that we can execute any code in here in any
1677  * other mode than FIQ...  Ok you can switch to another mode, but you can't
1678  * get out of that mode without clobbering one register.
1679  */
1680 vector_FIQ:     disable_fiq
1681                 subs    pc, lr, #4
1683 /*=============================================================================
1684  * Address exception handler
1685  *-----------------------------------------------------------------------------
1686  * These aren't too critical.
1687  * (they're not supposed to happen, and won't happen in 32-bit data mode).
1688  */
1690 vector_addrexcptn:
1691                 b       vector_addrexcptn
1694  * We group all the following data together to optimise
1695  * for CPUs with separate I & D caches.
1696  */
1697                 .align  5
1699 .LCvswi:        .word   vector_swi
1701 .LCsirq:        .word   __temp_irq
1702 .LCsund:        .word   __temp_und
1703 .LCsabt:        .word   __temp_abt
1704 #if 1   /* add by Victor Yu. 06-09-2005 */
1705 #ifdef CONFIG_CPU_FA_IDLE
1706 .LCidle:        .word   __idle_inst
1707 #endif  /* CONFIG_CPU_FA_IDLE */
1708 #endif
1710 __stubs_end:
1712                 .equ    __real_stubs_start, .LCvectors + 0x200
1714 .LCvectors:     swi     SYS_ERROR0
1715                 b       __real_stubs_start + (vector_undefinstr - __stubs_start)
1716                 ldr     pc, __real_stubs_start + (.LCvswi - __stubs_start)
1717                 b       __real_stubs_start + (vector_prefetch - __stubs_start)
1718                 b       __real_stubs_start + (vector_data - __stubs_start)
1719                 b       __real_stubs_start + (vector_addrexcptn - __stubs_start)
1720                 b       __real_stubs_start + (vector_IRQ - __stubs_start)
1721                 b       __real_stubs_start + (vector_FIQ - __stubs_start)
1723 ENTRY(__trap_init)
1724                 stmfd   sp!, {r4 - r6, lr}
1726                 adr     r1, .LCvectors                  @ set up the vectors
1727                 ldmia   r1, {r1, r2, r3, r4, r5, r6, ip, lr}
1728                 stmia   r0, {r1, r2, r3, r4, r5, r6, ip, lr}
1730                 add     r2, r0, #0x200
1731                 adr     r0, __stubs_start               @ copy stubs to 0x200
1732                 adr     r1, __stubs_end
1733 1:              ldr     r3, [r0], #4
1734                 str     r3, [r2], #4
1735                 cmp     r0, r1
1736                 blt     1b
1737 #ifdef CONFIG_BDI2000_XSCALE
1738                 bkpt    1
1739 #endif
1740                 LOADREGS(fd, sp!, {r4 - r6, pc})
1742                 .data
1745  * Do not reorder these, and do not insert extra data between...
1746  */
1748 __temp_irq:     .word   0                               @ saved lr_irq
1749                 .word   0                               @ saved spsr_irq
1750                 .word   -1                              @ old_r0
1751 __temp_und:     .word   0                               @ Saved lr_und
1752                 .word   0                               @ Saved spsr_und
1753                 .word   -1                              @ old_r0
1754 __temp_abt:     .word   0                               @ Saved lr_abt
1755                 .word   0                               @ Saved spsr_abt
1756                 .word   -1                              @ old_r0
1757 #if 1   /* add by Victor Yu. 06-09-2005 */
1758 #ifdef CONFIG_CPU_FA_IDLE
1759 __idle_inst:
1760         .word   0xee070f90                      @ machine code of (mcr p15,0,r0,c7,c0,4)
1761 #endif  /* CONFIG_CPU_FA_IDLE */
1762 #endif
1764                 .globl  cr_alignment
1765                 .globl  cr_no_alignment
1766 cr_alignment:
1767                 .space  4
1768 cr_no_alignment:
1769                 .space  4