diff options
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/dma-isa.c | 2 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 42 | ||||
-rw-r--r-- | arch/arm/kernel/entry-common.S | 2 | ||||
-rw-r--r-- | arch/arm/kernel/time.c | 2 |
4 files changed, 44 insertions, 4 deletions
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c index 0a3e9ad297d8..2f080a35a2d9 100644 --- a/arch/arm/kernel/dma-isa.c +++ b/arch/arm/kernel/dma-isa.c @@ -216,7 +216,7 @@ void __init isa_init_dma(dma_t *dma) request_dma(DMA_ISA_CASCADE, "cascade"); - for (i = 0; i < sizeof(dma_resources) / sizeof(dma_resources[0]); i++) + for (i = 0; i < ARRAY_SIZE(dma_resources); i++) request_resource(&ioport_resource, dma_resources + i); } } diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 3727537f5825..a46d5b456765 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -11,8 +11,8 @@ * * 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! + * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction + * that causes it to save wrong values... Be aware! */ #include <asm/memory.h> @@ -493,6 +493,13 @@ __und_usr: * co-processor instructions. However, we have to watch out * for the ARM6/ARM7 SWI bug. * + * NEON is a special case that has to be handled here. Not all + * NEON instructions are co-processor instructions, so we have + * to make a special case of checking for them. Plus, there's + * five groups of them, so we have a table of mask/opcode pairs + * to check against, and if any match then we branch off into the + * NEON handler code. + * * Emulators may wish to make use of the following registers: * r0 = instruction opcode. * r2 = PC+4 @@ -501,6 +508,23 @@ __und_usr: * lr = unrecognised instruction return address */ call_fpe: +#ifdef CONFIG_NEON + adr r6, .LCneon_opcodes +2: + ldr r7, [r6], #4 @ mask value + cmp r7, #0 @ end mask? + beq 1f + and r8, r0, r7 + ldr r7, [r6], #4 @ opcode bits matching in mask + cmp r8, r7 @ NEON instruction? + bne 2b + get_thread_info r10 + mov r7, #1 + strb r7, [r10, #TI_USED_CP + 10] @ mark CP#10 as used + strb r7, [r10, #TI_USED_CP + 11] @ mark CP#11 as used + b do_vfp @ let VFP handler handle this +1: +#endif tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) and r8, r0, #0x0f000000 @ mask out op-code bits @@ -550,6 +574,20 @@ call_fpe: mov pc, lr @ CP#14 (Debug) mov pc, lr @ CP#15 (Control) +#ifdef CONFIG_NEON + .align 6 + +.LCneon_opcodes: + .word 0xfe000000 @ mask + .word 0xf2000000 @ opcode + + .word 0xff100000 @ mask + .word 0xf4000000 @ opcode + + .word 0x00000000 @ mask + .word 0x00000000 @ opcode +#endif + do_fpe: enable_irq ldr r4, .LCfp diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 33e6cc2ffd3b..6c90c50a9ee3 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -72,7 +72,7 @@ no_work_pending: ldr r1, [sp, #S_PSR] @ get calling cpsr ldr lr, [sp, #S_PC]! @ get pc msr spsr_cxsf, r1 @ save in spsr_svc - ldmdb sp, {r0 - lr}^ @ get calling r1 - lr + ldmdb sp, {r0 - lr}^ @ get calling r0 - lr mov r0, r0 add sp, sp, #S_FRAME_SIZE - S_PC movs pc, lr @ return & move spsr_svc into cpsr diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index e59b5b84168d..b5867eca1d0b 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -325,7 +325,9 @@ void timer_tick(void) profile_tick(CPU_PROFILING); do_leds(); do_set_rtc(); + write_seqlock(&xtime_lock); do_timer(1); + write_sequnlock(&xtime_lock); #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); #endif |