/* * linux/arch/armnommu/kernel/entry-armv.S [Kernel 2.4.x] * * Copyright (C) 1996,1997,1998 Russell King. * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Low-level vector interface routines * * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes * it to save wrong values... Be aware! * * added some NET+ARM code by Joe deBlaquiere --rp * added S3C4510 code by Mac Wang * added S3C4530 code by Arcturus Networks Inc. * */ #include #include "entry-header.S" #ifdef IOC_BASE /* IOC / IOMD based hardware */ #include .equ ioc_base_high, IOC_BASE & 0xff000000 .equ ioc_base_low, IOC_BASE & 0x00ff0000 .macro disable_fiq mov r12, #ioc_base_high .if ioc_base_low orr r12, r12, #ioc_base_low .endif strb r12, [r12, #0x38] @ Disable FIQ register .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov r4, #ioc_base_high @ point at IOC .if ioc_base_low orr r4, r4, #ioc_base_low .endif ldrb \irqstat, [r4, #IOMD_IRQREQB] @ get high priority first ldr \base, =irq_prio_h teq \irqstat, #0 #ifdef IOMD_BASE ldreqb \irqstat, [r4, #IOMD_DMAREQ] @ get dma addeq \base, \base, #256 @ irq_prio_h table size teqeq \irqstat, #0 bne 2406f #endif ldreqb \irqstat, [r4, #IOMD_IRQREQA] @ get low priority addeq \base, \base, #256 @ irq_prio_d table size teqeq \irqstat, #0 #ifdef IOMD_IRQREQC ldreqb \irqstat, [r4, #IOMD_IRQREQC] addeq \base, \base, #256 @ irq_prio_l table size teqeq \irqstat, #0 #endif #ifdef IOMD_IRQREQD ldreqb \irqstat, [r4, #IOMD_IRQREQD] addeq \base, \base, #256 @ irq_prio_lc table size teqeq \irqstat, #0 #endif 2406: ldrneb \irqnr, [\base, \irqstat] @ get IRQ number .endm /* * Interrupt table (incorporates priority). Please note that we * rely on the order of these tables (see above code). */ .macro irq_prio_table irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10 .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10 .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 #ifdef IOMD_BASE irq_prio_d: .byte 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 #endif irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3 .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 #ifdef IOMD_IRQREQC irq_prio_lc: .byte 24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27 .byte 28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27 .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27 .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27 .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 #endif #ifdef IOMD_IRQREQD irq_prio_ld: .byte 40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43 .byte 44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43 .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43 .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43 .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 #endif .endm #elif defined(CONFIG_ARCH_EBSA110) #define IRQ_STAT 0xff000000 /* read */ .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, stat, base, tmp mov \base, #IRQ_STAT ldrb \stat, [\base] @ get interrupts mov \irqnr, #0 tst \stat, #15 addeq \irqnr, \irqnr, #4 moveq \stat, \stat, lsr #4 tst \stat, #3 addeq \irqnr, \irqnr, #2 moveq \stat, \stat, lsr #2 tst \stat, #1 addeq \irqnr, \irqnr, #1 moveq \stat, \stat, lsr #1 tst \stat, #1 @ bit 0 should be set .endm .macro irq_prio_table .endm #elif defined(CONFIG_ARCH_SHARK) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov r4, #0xe0000000 orr r4, r4, #0x20 mov \irqstat, #0x0C strb \irqstat, [r4] @outb(0x0C, 0x20) /* Poll command */ ldrb \irqnr, [r4] @irq = inb(0x20) & 7 and \irqstat, \irqnr, #0x80 teq \irqstat, #0 beq 43f and \irqnr, \irqnr, #7 teq \irqnr, #2 bne 44f 43: mov \irqstat, #0x0C strb \irqstat, [r4, #0x80] @outb(0x0C, 0xA0) /* Poll command */ ldrb \irqnr, [r4, #0x80] @irq = (inb(0xA0) & 7) + 8 and \irqstat, \irqnr, #0x80 teq \irqstat, #0 beq 44f and \irqnr, \irqnr, #7 add \irqnr, \irqnr, #8 44: teq \irqstat, #0 .endm .macro irq_prio_table .endm #elif defined(CONFIG_FOOTBRIDGE) #include .macro disable_fiq .endm .equ dc21285_high, ARMCSR_BASE & 0xff000000 .equ dc21285_low, ARMCSR_BASE & 0x00ffffff .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov r4, #dc21285_high .if dc21285_low orr r4, r4, #dc21285_low .endif ldr \irqstat, [r4, #0x180] @ get interrupts mov \irqnr, #IRQ_SDRAMPARITY tst \irqstat, #IRQ_MASK_SDRAMPARITY bne 1001f tst \irqstat, #IRQ_MASK_UART_RX movne \irqnr, #IRQ_CONRX bne 1001f tst \irqstat, #IRQ_MASK_DMA1 movne \irqnr, #IRQ_DMA1 bne 1001f tst \irqstat, #IRQ_MASK_DMA2 movne \irqnr, #IRQ_DMA2 bne 1001f tst \irqstat, #IRQ_MASK_IN0 movne \irqnr, #IRQ_IN0 bne 1001f tst \irqstat, #IRQ_MASK_IN1 movne \irqnr, #IRQ_IN1 bne 1001f tst \irqstat, #IRQ_MASK_IN2 movne \irqnr, #IRQ_IN2 bne 1001f tst \irqstat, #IRQ_MASK_IN3 movne \irqnr, #IRQ_IN3 bne 1001f tst \irqstat, #IRQ_MASK_PCI movne \irqnr, #IRQ_PCI bne 1001f tst \irqstat, #IRQ_MASK_DOORBELLHOST movne \irqnr, #IRQ_DOORBELLHOST bne 1001f tst \irqstat, #IRQ_MASK_I2OINPOST movne \irqnr, #IRQ_I2OINPOST bne 1001f tst \irqstat, #IRQ_MASK_TIMER1 movne \irqnr, #IRQ_TIMER1 bne 1001f tst \irqstat, #IRQ_MASK_TIMER2 movne \irqnr, #IRQ_TIMER2 bne 1001f tst \irqstat, #IRQ_MASK_TIMER3 movne \irqnr, #IRQ_TIMER3 bne 1001f tst \irqstat, #IRQ_MASK_UART_TX movne \irqnr, #IRQ_CONTX bne 1001f tst \irqstat, #IRQ_MASK_PCI_ABORT movne \irqnr, #IRQ_PCI_ABORT bne 1001f tst \irqstat, #IRQ_MASK_PCI_SERR movne \irqnr, #IRQ_PCI_SERR bne 1001f tst \irqstat, #IRQ_MASK_DISCARD_TIMER movne \irqnr, #IRQ_DISCARD_TIMER bne 1001f tst \irqstat, #IRQ_MASK_PCI_DPERR movne \irqnr, #IRQ_PCI_DPERR bne 1001f tst \irqstat, #IRQ_MASK_PCI_PERR movne \irqnr, #IRQ_PCI_PERR 1001: .endm .macro irq_prio_table .endm #elif defined(CONFIG_ARCH_NEXUSPCI) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, =INTCONT_BASE ldr \base, =soft_irq_mask ldr \irqstat, [\irqstat] @ get interrupts ldr \base, [\base] mov \irqnr, #0 and \irqstat, \irqstat, \base @ mask out disabled ones 1001: tst \irqstat, #1 addeq \irqnr, \irqnr, #1 moveq \irqstat, \irqstat, lsr #1 tsteq \irqnr, #32 beq 1001b teq \irqnr, #32 .endm .macro irq_prio_table .ltorg .bss ENTRY(soft_irq_mask) .word 0 .text .endm #elif defined(CONFIG_ARCH_TBOX) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, =0xffff7000 ldr \irqstat, [\irqstat] @ get interrupts ldr \base, =soft_irq_mask ldr \base, [\base] mov \irqnr, #0 and \irqstat, \irqstat, \base @ mask out disabled ones 1001: tst \irqstat, #1 addeq \irqnr, \irqnr, #1 moveq \irqstat, \irqstat, lsr #1 tsteq \irqnr, #32 beq 1001b teq \irqnr, #32 .endm .macro irq_prio_table .ltorg .bss ENTRY(soft_irq_mask) .word 0 .text .endm #elif defined(CONFIG_ARCH_SA1100) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov r4, #0xfa000000 @ ICIP = 0xfa050000 add r4, r4, #0x00050000 ldr \irqstat, [r4] @ get irqs ldr \irqnr, [r4, #4] @ ICMR = 0xfa050004 ands \irqstat, \irqstat, \irqnr mov \irqnr, #0 beq 1001f tst \irqstat, #0xff moveq \irqstat, \irqstat, lsr #8 addeq \irqnr, \irqnr, #8 tsteq \irqstat, #0xff moveq \irqstat, \irqstat, lsr #8 addeq \irqnr, \irqnr, #8 tsteq \irqstat, #0xff moveq \irqstat, \irqstat, lsr #8 addeq \irqnr, \irqnr, #8 tst \irqstat, #0x0f moveq \irqstat, \irqstat, lsr #4 addeq \irqnr, \irqnr, #4 tst \irqstat, #0x03 moveq \irqstat, \irqstat, lsr #2 addeq \irqnr, \irqnr, #2 tst \irqstat, #0x01 addeqs \irqnr, \irqnr, #1 1001: .endm .macro irq_prio_table .endm #elif defined(CONFIG_ARCH_L7200) .equ irq_base_addr, IO_BASE_2 .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \irqstat, #irq_base_addr @ Virt addr IRQ regs add \irqstat, \irqstat, #0x00001000 @ Status reg ldr \irqstat, [\irqstat, #0] @ get interrupts mov \irqnr, #0 1001: tst \irqstat, #1 addeq \irqnr, \irqnr, #1 moveq \irqstat, \irqstat, lsr #1 tsteq \irqnr, #32 beq 1001b teq \irqnr, #32 .endm .macro irq_prio_table .endm #elif defined(CONFIG_ARCH_INTEGRATOR) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp /* FIXME: should not be using soo many LDRs here */ ldr \irqnr, =IO_ADDRESS(INTEGRATOR_IC_BASE) ldr \irqstat, [\irqnr, #IRQ_STATUS] @ get masked status ldr \irqnr, =IO_ADDRESS(INTEGRATOR_HDR_BASE) ldr \irqnr, [\irqnr, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)] orr \irqstat, \irqstat, \irqnr, lsl #INTEGRATOR_CM_INT0 mov \irqnr, #0 1001: tst \irqstat, #1 bne 1002f add \irqnr, \irqnr, #1 mov \irqstat, \irqstat, lsr #1 cmp \irqnr, #22 bcc 1001b 1002: /* EQ will be set if we reach 22 */ .endm .macro irq_prio_table .endm #elif defined(CONFIG_ARCH_CLPS711X) #include .macro disable_fiq .endm #if (INTSR2 - INTSR1) != (INTMR2 - INTMR1) #error INTSR stride != INTMR stride #endif .macro get_irqnr_and_base, irqnr, stat, base, mask mov \base, #CLPS7111_BASE ldr \stat, [\base, #INTSR1] ldr \mask, [\base, #INTMR1] mov \irqnr, #4 mov \mask, \mask, lsl #16 and \stat, \stat, \mask, lsr #16 movs \stat, \stat, lsr #4 bne 1001f add \base, \base, #INTSR2 - INTSR1 ldr \stat, [\base, #INTSR1] ldr \mask, [\base, #INTMR1] mov \irqnr, #16 mov \mask, \mask, lsl #16 and \stat, \stat, \mask, lsr #16 1001: tst \stat, #255 addeq \irqnr, \irqnr, #8 moveq \stat, \stat, lsr #8 tst \stat, #15 addeq \irqnr, \irqnr, #4 moveq \stat, \stat, lsr #4 tst \stat, #3 addeq \irqnr, \irqnr, #2 moveq \stat, \stat, lsr #2 tst \stat, #1 addeq \irqnr, \irqnr, #1 moveq \stat, \stat, lsr #1 tst \stat, #1 @ bit 0 should be set .endm .macro irq_prio_table .endm #elif defined(CONFIG_ARCH_ANAKIN) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \base, #IO_BASE mov \irqstat, #INTERRUPT_CONTROLLER ldr \tmp, =anakin_irq_mask ldr \irqstat, [\base, \irqstat] ldr \tmp, [\tmp] ands \irqstat, \irqstat, \tmp ldrne \tmp, =anakin_active_irqs strne \irqstat, [\tmp] movne \irqnr, #IRQ_ANAKIN .endm .macro irq_prio_table .ltorg .bss ENTRY(anakin_irq_mask) .word 0 ENTRY(anakin_active_irqs) .space 4 .text .endm #elif defined(CONFIG_ARCH_CNXT) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp #ifdef CONFIG_ARCH_P52 ldr r4, =P52INT_STATUS_M ldr \irqstat, [r4] tst \irqstat, #P52INT_MASK_TIMER_1 movne \irqnr, #P52INT_LVL_TIMER_1 bne 1001f tst \irqstat, #P52INT_MASK_TIMER_2 movne \irqnr, #P52INT_LVL_TIMER_2 bne 1001f tst \irqstat, #P52INT_MASK_TIMER_3 movne \irqnr, #P52INT_LVL_TIMER_3 bne 1001f tst \irqstat, #P52INT_MASK_TIMER_4 movne \irqnr, #P52INT_LVL_TIMER_4 bne 1001f tst \irqstat, #P52INT_MASK_USB movne \irqnr, #P52INT_LVL_USB bne 1001f tst \irqstat, #P52INT_MASK_HOST movne \irqnr, #P52INT_LVL_HOST bne 1001f tst \irqstat, #P52INT_MASK_HOST_ERR movne \irqnr, #P52INT_LVL_HOST_ERR bne 1001f tst \irqstat, #P52INT_MASK_DMA8 movne \irqnr, #P52INT_LVL_DMA8 bne 1001f tst \irqstat, #P52INT_MASK_DMA6 movne \irqnr, #P52INT_LVL_DMA6 bne 1001f tst \irqstat, #P52INT_MASK_DMA5 movne \irqnr, #P52INT_LVL_DMA5 bne 1001f tst \irqstat, #P52INT_MASK_DMA4 movne \irqnr, #P52INT_LVL_DMA4 bne 1001f tst \irqstat, #P52INT_MASK_DMA3 movne \irqnr, #P52INT_LVL_DMA3 bne 1001f tst \irqstat, #P52INT_MASK_DMA2 movne \irqnr, #P52INT_LVL_DMA2 bne 1001f tst \irqstat, #P52INT_MASK_DMA1 movne \irqnr, #P52INT_LVL_DMA1 bne 1001f tst \irqstat, #P52INT_MASK_DMA_ERR movne \irqnr, #P52INT_LVL_DMA_ERR bne 1001f tst \irqstat, #P52INT_MASK_E2_ERR movne \irqnr, #P52INT_LVL_E2_ERR bne 1001f tst \irqstat, #P52INT_MASK_E1_ERR movne \irqnr, #P52INT_LVL_E1_ERR bne 1001f tst \irqstat, #P52INT_MASK_DSL movne \irqnr, #P52INT_LVL_DSL bne 1001f tst \irqstat, #P52INT_MASK_GPIO movne \irqnr, #P52INT_LVL_GPIO bne 1001f tst \irqstat, #P52INT_MASK_COMMTX movne \irqnr, #P52INT_LVL_COMMTX bne 1001f tst \irqstat, #P52INT_MASK_COMMRX movne \irqnr, #P52INT_LVL_COMMRX bne 1001f tst \irqstat, #P52INT_MASK_SW1 movne \irqnr, #P52INT_LVL_SW1 bne 1001f tst \irqstat, #P52INT_MASK_SW2 movne \irqnr, #P52INT_LVL_SW2 bne 1001f tst \irqstat, #P52INT_MASK_SW3 movne \irqnr, #P52INT_LVL_SW3 bne 1001f tst \irqstat, #P52INT_MASK_SW4 movne \irqnr, #P52INT_LVL_SW4 1001: #endif #ifdef CONFIG_ARCH_SPIPE @ @ not been tested @ ldr r4, =0x350044 ldr \irqnr, [r4] mov r5,#0 icloopusr: cmp r5,#31 ble icshftusr b icendusr icshftusr: mov r4,r6,lsr r5 @ shift untill we get one and r0,r4,#1 @ int priority is in the status cmp r0,#0 beq incicusr b icendusr incicusr: add r5,r5,#1 b icloopusr icendusr: mov r0, r5 #endif .endm .macro irq_prio_table .endm #elif defined(CONFIG_ARCH_ATMEL) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr r4, =AIC_IVR ldr \irqnr, [r4] @ignore value ldr r4, =AIC_ISR @read interrupt nr. ldr \irqnr, [r4] teq \irqnr, #0 ldreq r4, =AIC_EOICR @ EOI streq r4, [r4] @ value=dont care .endm .macro irq_prio_table .endm #elif defined(CONFIG_ARCH_TA7S) #include .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, stat, base, temp ldr \irqnr, =INT_IRQ_STATUS_REG ldr \stat, =INT_IRQ_STATUS_REG ldr \base, [\irqnr, #0] @ stash ISTATUS mov \irqnr, #0 1001: cmp \base, #0 @ no flags set? beq 1002f @ keep "eq" status when finishing! tst \base, #1 @ lsb set? addeq \irqnr, \irqnr, #1 @ if not, incr IRQ# moveq \base, \base, LSR #1 @ r = r >> 1 beq 1001b 1002: adr \base, irq_prio_ta7 .endm .macro irq_prio_table irq_prio_ta7: .byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 .byte 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 .endm #elif defined(CONFIG_ARCH_NETARM) #include .macro disable_fiq mrs r13, spsr orr r13, r13, #F_BIT msr spsr_c, r13 .endm .macro get_irqnr_and_base, irqnr, stat, base, temp ldr \irqnr, =(NETARM_GEN_MODULE_BASE+NETARM_GEN_INTR_STATUS_EN) ldr \base, [\irqnr, #0] @ stash ISTATUS mov \irqnr, #0 1001: cmp \base, #0 @ no flags set? beq 1002f @ keep "eq" status when finishing! tst \base, #1 @ lsb set? addeq \irqnr, \irqnr, #1 @ if not, incr IRQ# moveq \base, \base, LSR #1 @ r = r >> 1 beq 1001b cmp \irqnr, #32 @ IRQ# too big? blge _netarm_led_FAIL2 1002: adr \base, irq_prio_netarm .endm .macro irq_prio_table irq_prio_netarm: .byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 .byte 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 .endm #elif defined(CONFIG_CPU_S3C4510) || defined(CONFIG_CPU_S3C4530) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \base, =INTOSET_IRQ ldr \irqnr, [\base] mov \irqnr, \irqnr, lsr #2 teq \irqnr, #NR_IRQS .endm .macro irq_prio_table .endm #elif defined(CONFIG_CPU_W90N745) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \base, =AIC_IPER ldr \irqnr, [\base] @mov \irqnr, \irqnr, lsr #2 teq \irqnr, #0x0 .endm .macro irq_prio_table .endm #elif defined(CONFIG_CPU_S3C3410) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, =.LCintpnd @ load address of interrupt pending ldr \irqstat, [\irqstat] @ register INTPND ldr \irqnr, [\irqstat] @ \irqnr = INTPND add \irqstat, \irqstat, #(S3C3410X_INTMSK-S3C3410X_INTPND) ldr \irqstat, [\irqstat] @ \irqstat = INTMSK and \irqstat, \irqnr, \irqstat @ \irqstat = (INTPND & INTMSK) mov \irqnr, #0 1001: tst \irqstat, #1 bne 1002f add \irqnr, \irqnr, #1 mov \irqstat, \irqstat, lsr #1 cmp \irqnr, #32 bcc 1001b 1002: /* EQ will be set if we reach 32 */ .endm .macro irq_prio_table .endm #elif defined(CONFIG_ARCH_SWARM) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, =SWARM_INT_IRQ_STATUS ldr \irqstat, [\irqstat] @ get interrupts mov \irqnr, #0 1001: tst \irqstat, #1 bne 1002f add \irqnr, \irqnr, #1 mov \irqstat, \irqstat, lsr #1 cmp \irqnr, #32 bcc 1001b 1002: /* EQ will be set if we reach 32 */ .endm .macro irq_prio_table irq_prio_swarm: .byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 .endm #else #error Unknown architecture #endif /* * Invalid mode handlers */ __pabt_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - lr} @ Save XXX r0 - lr ldr r4, .LCabt mov r1, #BAD_PREFETCH b 1f __dabt_invalid: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - lr} @ Save SVC r0 - lr [lr *should* be intact] ldr r4, .LCabt mov r1, #BAD_DATA b 1f __irq_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate space on stack for frame stmfd sp, {r0 - lr} @ Save r0 - lr ldr r4, .LCirq mov r1, #BAD_IRQ b 1f __und_invalid: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - lr} ldr r4, .LCund mov r1, #BAD_UNDEFINSTR @ int reason 1: zero_fp ldmia r4, {r5 - r7} @ Get XXX pc, cpsr, old_r0 add r4, sp, #S_PC stmia r4, {r5 - r7} @ Save XXX pc, cpsr, old_r0 mov r0, sp and r2, r6, #31 @ int mode b SYMBOL_NAME(bad_mode) #if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE /* The FPE is always present */ .equ fpe_not_present, 0 #else wfs_mask_data: .word 0x0e200110 @ WFS/RFS .word 0x0fef0fff .word 0x0d000100 @ LDF [sp]/STF [sp] .word 0x0d000100 @ LDF [fp]/STF [fp] .word 0x0f000f00 /* We get here if an undefined instruction happens and the floating * point emulator is not present. If the offending instruction was * a WFS, we just perform a normal return as if we had emulated the * operation. This is a hack to allow some basic userland binaries * to run so that the emulator module proper can be loaded. --philb */ fpe_not_present: adr r10, wfs_mask_data ldmia r10, {r4, r5, r6, r7, r8} ldr r10, [sp, #S_PC] @ Load PC sub r10, r10, #4 mask_pc r10, r10 ldrt r10, [r10] @ get instruction and r5, r10, r5 teq r5, r4 @ Is it WFS? moveq pc, r9 and r5, r10, r8 teq r5, r6 @ Is it LDF/STF on sp or fp? teqne r5, r7 movne pc, lr tst r10, #0x00200000 @ Does it have WB moveq pc, r9 and r4, r10, #255 @ get offset and r6, r10, #0x000f0000 tst r10, #0x00800000 @ +/- ldr r5, [sp, r6, lsr #14] @ Load reg rsbeq r4, r4, #0 add r5, r5, r4, lsl #2 str r5, [sp, r6, lsr #14] @ Save reg mov pc, r9 #endif /* * SVC mode handlers */ .align 5 __dabt_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 ldr r2, .LCabt add r0, sp, #S_FRAME_SIZE ldmia r2, {r2 - r4} @ get pc, cpsr add r5, sp, #S_SP mov r1, lr stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro mrs r9, cpsr @ Enable interrupts if they were tst r3, #I_BIT biceq r9, r9, #I_BIT @ previously mov r0, r2 /* * This routine must not corrupt r9 */ #ifdef MULTI_CPU ldr r2, .LCprocfns mov lr, pc ldr pc, [r2] @ call processor specific code #else bl cpu_data_abort #endif msr cpsr_c, r9 mov r2, sp bl SYMBOL_NAME(do_DataAbort) mrs r0, cpsr bic r0, r0, #MODE_MASK orr r0, r0, #I_BIT | MODE_SVC @ preserve FIQ bit msr cpsr_c, r0 ldr r0, [sp, #S_PSR] msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr .align 5 __irq_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r1 ldr r7, .LCirq add r5, sp, #S_FRAME_SIZE ldmia r7, {r7 - r9} add r4, sp, #S_SP mov r6, lr stmia r4, {r5, r6, r7, r8, r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro 1: get_irqnr_and_base r0, r6, r5, lr movne r1, sp @ @ routine called with r0 = irq number, r1 = struct pt_regs * @ adrsvc ne, lr, 1b bne do_IRQ ldr r0, [sp, #S_PSR] @ irqs are already disabled msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr .align 5 __und_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 ldr r7, .LCund mov r6, lr ldmia r7, {r7 - r9} add r5, sp, #S_FRAME_SIZE add r4, sp, #S_SP stmia r4, {r5 - r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro adrsvc al, r9, 1f @ r9 = normal FP return bl call_fpe @ lr = undefined instr return mov r0, r5 @ unsigned long pc mov r1, sp @ struct pt_regs *regs bl SYMBOL_NAME(do_undefinstr) 1: mrs r0, cpsr bic r0, r0, #MODE_MASK @ preserve F-bit orr r0, r0, #I_BIT | MODE_SVC msr cpsr_c, r0 ldr lr, [sp, #S_PSR] @ Get SVC cpsr msr spsr, lr ldmia sp, {r0 - pc}^ @ Restore SVC registers .align 5 __pabt_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 ldr r2, .LCabt add r0, sp, #S_FRAME_SIZE ldmia r2, {r2 - r4} @ get pc, cpsr add r5, sp, #S_SP mov r1, lr stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro mrs r9, cpsr @ Enable interrupts if they were tst r3, #I_BIT biceq r9, r9, #I_BIT @ previously msr cpsr_c, r9 mov r0, r2 @ address (pc) mov r1, sp @ regs bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler mrs r0, cpsr bic r0, r0, #MODE_MASK @ preserve F-bit orr r0, r0, #I_BIT | MODE_SVC msr cpsr_c, r0 ldr r0, [sp, #S_PSR] msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr .align 5 .LCirq: .word __temp_irq .LCund: .word __temp_und .LCabt: .word __temp_abt #ifdef MULTI_CPU .LCprocfns: .word SYMBOL_NAME(processor) #endif .LCfp: .word SYMBOL_NAME(fp_enter) #ifdef CONFIG_CPU_S3C3410 .LCintpnd: .word S3C3410X_INTPND #endif irq_prio_table /* * User mode handlers */ .align 5 __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - r12} @ save r0 - r12 ldr r4, .LCabt add r3, sp, #S_PC ldmia r4, {r0 - r2} @ Get USR pc, cpsr stmia r3, {r0 - r2} @ Save USR pc, cpsr, old_r0 stmdb r3, {sp, lr}^ alignment_trap r4, r7, __temp_abt zero_fp #ifdef MULTI_CPU ldr r2, .LCprocfns mov lr, pc ldr pc, [r2] @ call processor specific code #else bl cpu_data_abort #endif mrs r2, cpsr bic r2, r2, #I_BIT | MODE_MASK @ preserve F-bit orr r2, r2, #MODE_SVC msr cpsr_c, r2 @ Enable interrupts mov r2, sp adrsvc al, lr, ret_from_exception b SYMBOL_NAME(do_DataAbort) .align 5 __irq_usr: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 ldr r4, .LCirq add r8, sp, #S_PC ldmia r4, {r5 - r7} @ get saved PC, SPSR stmia r8, {r5 - r7} @ save pc, psr, old_r0 stmdb r8, {sp, lr}^ alignment_trap r4, r7, __temp_irq zero_fp 1: get_irqnr_and_base r0, r6, r5, lr movne r1, sp adrsvc ne, lr, 1b @ @ routine called with r0 = irq number, r1 = struct pt_regs * @ bne do_IRQ mov why, #0 get_current_task tsk b ret_to_user .align 5 __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - r12} @ Save r0 - r12 ldr r4, .LCund add r8, sp, #S_PC ldmia r4, {r5 - r7} stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0 stmdb r8, {sp, lr}^ @ Save user sp, lr alignment_trap r4, r7, __temp_und zero_fp adrsvc al, r9, ret_from_exception @ r9 = normal FP return adrsvc al, lr, fpundefinstr @ lr = undefined instr return call_fpe: get_current_task r10 mov r8, #1 strb r8, [r10, #TSK_USED_MATH] @ set current->used_math ldr r4, .LCfp add r10, r10, #TSS_FPESAVE @ r10 = workspace ldr pc, [r4] @ Call FP module USR entry point fpundefinstr: mrs r0, cpsr bic r0, r0, #MODE_MASK | I_BIT @ preserve F-bit orr r0, r0, #MODE_SVC msr cpsr_c, r0 @ Enable interrupts mov r0, lr mov r1, sp adrsvc al, lr, ret_from_exception b SYMBOL_NAME(do_undefinstr) .align 5 __pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - r12} @ Save r0 - r12 ldr r4, .LCabt add r8, sp, #S_PC ldmia r4, {r5 - r7} @ Get USR pc, cpsr stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0 stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr alignment_trap r4, r7, __temp_abt zero_fp mrs r0, cpsr bic r0, r0, #MODE_MASK | I_BIT @ preserve F-bit orr r0, r0, #MODE_SVC msr cpsr_c, r0 @ Enable interrupts mov r0, r5 @ address (pc) mov r1, sp @ regs bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler /* fall through */ /* * This is the return code to user mode for abort handlers */ ENTRY(ret_from_exception) get_current_task tsk mov why, #0 b ret_to_user .data ENTRY(fp_enter) .word fpe_not_present .text /* * Register switch for ARMv3 and ARMv4 processors * r0 = previous, r1 = next, return previous. * previous and next are guaranteed not to be the same. */ ENTRY(__switch_to) stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on stack mrs ip, cpsr str ip, [sp, #-4]! @ Save cpsr_SVC str sp, [r0, #TSS_SAVE] @ Save sp_SVC ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC #ifndef CONFIG_UCLINUX ldr r2, [r1, #TSS_DOMAIN] mcr p15, 0, r2, c3, c0 @ Set domain register #endif ldr ip, [sp], #4 msr spsr, ip @ Save tasks CPSR into SPSR for this return ldmfd sp!, {r4 - sl, fp, pc}^ @ Load all regs saved previously .section ".text.init",#alloc,#execinstr /* * Vector stubs. NOTE that we only align 'vector_IRQ' to a cache line boundary, * and we rely on each stub being exactly 48 (1.5 cache lines) in size. This * means that we only ever load two cache lines for this code, or one if we're * lucky. We also copy this code to 0x200 so that we can use branches in the * vectors, rather than ldr's. */ .align 5 __stubs_start: /* * Interrupt dispatcher * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC */ vector_IRQ: @ @ save mode specific registers @ ldr r13, .LCsirq sub lr, lr, #4 str lr, [r13] @ save lr_IRQ mrs lr, spsr str lr, [r13, #4] @ save spsr_IRQ @ @ now branch to the relevent MODE handling routine @ mrs r13, spsr @ switch to SVC_32 mode bic r13, r13, #MODE_MASK @ preserve F and T bits orr r13, r13, #MODE_SVC|I_BIT msr spsr_c, r13 @ switch to SVC_32 mode and lr, lr, #15 ldr lr, [pc, lr, lsl #2] movs pc, lr @ Changes mode and branches .LCtab_irq: .word __irq_usr @ 0 (USR_26 / USR_32) .word __irq_invalid @ 1 (FIQ_26 / FIQ_32) .word __irq_invalid @ 2 (IRQ_26 / IRQ_32) .word __irq_svc @ 3 (SVC_26 / SVC_32) .word __irq_invalid @ 4 .word __irq_invalid @ 5 .word __irq_invalid @ 6 .word __irq_invalid @ 7 .word __irq_invalid @ 8 .word __irq_invalid @ 9 .word __irq_invalid @ a .word __irq_invalid @ b .word __irq_invalid @ c .word __irq_invalid @ d .word __irq_invalid @ e .word __irq_invalid @ f .align 5 /* * Data abort dispatcher - dispatches it to the correct handler for the processor mode * Enter in ABT mode, spsr = USR CPSR, lr = USR PC */ vector_data: @ @ save mode specific registers @ ldr r13, .LCsabt sub lr, lr, #8 str lr, [r13] mrs lr, spsr str lr, [r13, #4] @ @ now branch to the relevent MODE handling routine @ mrs r13, spsr bic r13, r13, #MODE_MASK @ preserve F and T bits orr r13, r13, #I_BIT | MODE_SVC msr spsr_c, r13 @ switch to SVC_32 mode and lr, lr, #15 ldr lr, [pc, lr, lsl #2] movs pc, lr @ Changes mode and branches .LCtab_dabt: .word __dabt_usr @ 0 (USR_26 / USR_32) .word __dabt_invalid @ 1 (FIQ_26 / FIQ_32) .word __dabt_invalid @ 2 (IRQ_26 / IRQ_32) .word __dabt_svc @ 3 (SVC_26 / SVC_32) .word __dabt_invalid @ 4 .word __dabt_invalid @ 5 .word __dabt_invalid @ 6 .word __dabt_invalid @ 7 .word __dabt_invalid @ 8 .word __dabt_invalid @ 9 .word __dabt_invalid @ a .word __dabt_invalid @ b .word __dabt_invalid @ c .word __dabt_invalid @ d .word __dabt_invalid @ e .word __dabt_invalid @ f .align 5 /* * Prefetch abort dispatcher - dispatches it to the correct handler for the processor mode * Enter in ABT mode, spsr = USR CPSR, lr = USR PC */ vector_prefetch: @ @ save mode specific registers @ ldr r13, .LCsabt sub lr, lr, #4 str lr, [r13] @ save lr_ABT mrs lr, spsr str lr, [r13, #4] @ save spsr_ABT @ @ now branch to the relevent MODE handling routine @ mrs r13, spsr bic r13, r13, #MODE_MASK @ preserve F and T bits orr r13, r13, #I_BIT | MODE_SVC msr spsr_c, r13 @ switch to SVC_32 mode ands lr, lr, #15 ldr lr, [pc, lr, lsl #2] movs pc, lr .LCtab_pabt: .word __pabt_usr @ 0 (USR_26 / USR_32) .word __pabt_invalid @ 1 (FIQ_26 / FIQ_32) .word __pabt_invalid @ 2 (IRQ_26 / IRQ_32) .word __pabt_svc @ 3 (SVC_26 / SVC_32) .word __pabt_invalid @ 4 .word __pabt_invalid @ 5 .word __pabt_invalid @ 6 .word __pabt_invalid @ 7 .word __pabt_invalid @ 8 .word __pabt_invalid @ 9 .word __pabt_invalid @ a .word __pabt_invalid @ b .word __pabt_invalid @ c .word __pabt_invalid @ d .word __pabt_invalid @ e .word __pabt_invalid @ f .align 5 /* * Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC */ vector_undefinstr: @ @ save mode specific registers @ ldr r13, .LCsund str lr, [r13] @ save lr_UND mrs lr, spsr str lr, [r13, #4] @ save spsr_UND @ @ now branch to the relevent MODE handling routine @ mrs r13, spsr bic r13, r13, #MODE_MASK @ preserve F and T bits orr r13, r13, #I_BIT | MODE_SVC msr spsr_c, r13 @ switch to SVC_32 mode and lr, lr, #15 ldr lr, [pc, lr, lsl #2] movs pc, lr @ Changes mode and branches .LCtab_und: .word __und_usr @ 0 (USR_26 / USR_32) .word __und_invalid @ 1 (FIQ_26 / FIQ_32) .word __und_invalid @ 2 (IRQ_26 / IRQ_32) .word __und_svc @ 3 (SVC_26 / SVC_32) .word __und_invalid @ 4 .word __und_invalid @ 5 .word __und_invalid @ 6 .word __und_invalid @ 7 .word __und_invalid @ 8 .word __und_invalid @ 9 .word __und_invalid @ a .word __und_invalid @ b .word __und_invalid @ c .word __und_invalid @ d .word __und_invalid @ e .word __und_invalid @ f .align 5 /*============================================================================= * Undefined FIQs *----------------------------------------------------------------------------- * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg. * Basically to switch modes, we *HAVE* to clobber one register... brain * damage alert! I don't think that we can execute any code in here in any * other mode than FIQ... Ok you can switch to another mode, but you can't * get out of that mode without clobbering one register. */ vector_FIQ: disable_fiq subs pc, lr, #4 /*============================================================================= * Address exception handler *----------------------------------------------------------------------------- * These aren't too critical. * (they're not supposed to happen, and won't happen in 32-bit data mode). */ vector_addrexcptn: b vector_addrexcptn /* * We group all the following data together to optimise * for CPUs with separate I & D caches. */ .align 5 .LCvswi: .word vector_swi .LCsirq: .word __temp_irq .LCsund: .word __temp_und .LCsabt: .word __temp_abt #if defined(CONFIG_CPU_S3C3410) || defined(CONFIG_CPU_S3C3410) .INTPRIO0: .word S3C3410X_INTPRI0 #endif __stubs_end: .equ __real_stubs_start, .LCvectors + 0x200 .LCvectors: swi SYS_ERROR0 b __real_stubs_start + (vector_undefinstr - __stubs_start) ldr pc, __real_stubs_start + (.LCvswi - __stubs_start) b __real_stubs_start + (vector_prefetch - __stubs_start) b __real_stubs_start + (vector_data - __stubs_start) b __real_stubs_start + (vector_addrexcptn - __stubs_start) b __real_stubs_start + (vector_IRQ - __stubs_start) b __real_stubs_start + (vector_FIQ - __stubs_start) #ifdef CONFIG_CPU_S3C3410 /* 32 interrupt vectors @ 0x0000.0080 */ /* preset to the global default handler vector_IRQ */ b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 b __real_stubs_start + (vector_IRQ - __stubs_start) - 0x60 #endif ENTRY(__trap_init) stmfd sp!, {r4 - r9, lr} mrs r1, cpsr @ code from 2.0.38 bic r1, r1, #MODE_MASK @ clear mode bits orr r1, r1, #I_BIT|F_BIT|MODE_SVC @ set SVC mode, disable IRQ,FIQ msr cpsr, r1 #ifdef CONFIG_CPU_S3C3410 /* * make sure that interrupt priority is not used. Otherwise * the IRQ and FIQ vector addresses are not writeable */ adr r1, .INTPRIO0 ldr r1, [r1] ldr r2, [r1] and r2, r2, #0x1FFFFFFF str r2, [r1] #endif /* CONFIG_CPU_S3C3410 */ adr r1, .LCvectors @ set up the vectors ldmia r1, {r2, r3, r4, r5, r6, r7, r8, r9} stmia r0, {r2, r3, r4, r5, r6, r7, r8, r9} #ifdef CONFIG_CPU_S3C3410 /* * Enable the vector table based interrupt mode */ adr r4, .INTPRIO0 ldr r4, [r4] ldr r3, [r4] orr r3, r3, #0xE0000000 @ bit 31...29 must be set for this str r3, [r4] mov r4, r0 mov r0, #(0x0080) @ R0 = 0x0080 (RAM) add r1, r1, #(8*4) @ R1 = start of vectors (ROM) add r2, r1, #(32*4) @ R2 = end of vectors (ROM) 2: ldr r3, [r1], #4 str r3, [r0], #4 cmp r1, r2 blt 2b mov r0, r4 #endif /* CONFIG_CPU_S3C3410 */ add r2, r0, #0x200 adr r0, __stubs_start @ copy stubs to 0x200 adr r1, __stubs_end 1: ldr r3, [r0], #4 str r3, [r2], #4 cmp r0, r1 blt 1b LOADREGS(fd, sp!, {r4 - r9, pc}) .data /* * Do not reorder these, and do not insert extra data between... */ __temp_irq: .word 0 @ saved lr_irq .word 0 @ saved spsr_irq .word -1 @ old_r0 __temp_und: .word 0 @ Saved lr_und .word 0 @ Saved spsr_und .word -1 @ old_r0 __temp_abt: .word 0 @ Saved lr_abt .word 0 @ Saved spsr_abt .word -1 @ old_r0 .globl SYMBOL_NAME(cr_alignment) .globl SYMBOL_NAME(cr_no_alignment) SYMBOL_NAME(cr_alignment): .space 4 SYMBOL_NAME(cr_no_alignment): .space 4