X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fkernel%2Ffiq.c;h=a45c7874a467f7e01b7822b1672a1db0d5e18f36;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=6f7938162e46cc635cda8049a1a0717e45dbaa0a;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index 6f7938162..a45c7874a 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -46,32 +46,22 @@ #include #include -#define FIQ_VECTOR (vectors_base() + 0x1c) +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#warning This file requires GCC 3.3.x or older to build. Alternatively, +#warning please talk to GCC people to resolve the issues with the +#warning assembly clobber list. +#endif static unsigned long no_fiq_insn; -static inline void unprotect_page_0(void) -{ - modify_domain(DOMAIN_USER, DOMAIN_MANAGER); -} - -static inline void protect_page_0(void) -{ - modify_domain(DOMAIN_USER, DOMAIN_CLIENT); -} - /* Default reacquire function * - we always relinquish FIQ control * - we always reacquire FIQ control */ static int fiq_def_op(void *ref, int relinquish) { - if (!relinquish) { - unprotect_page_0(); - *(unsigned long *)FIQ_VECTOR = no_fiq_insn; - protect_page_0(); - flush_icache_range(FIQ_VECTOR, FIQ_VECTOR + 4); - } + if (!relinquish) + set_fiq_handler(&no_fiq_insn, sizeof(no_fiq_insn)); return 0; } @@ -93,12 +83,10 @@ int show_fiq_list(struct seq_file *p, void *v) void set_fiq_handler(void *start, unsigned int length) { - unprotect_page_0(); - - memcpy((void *)FIQ_VECTOR, start, length); - - protect_page_0(); - flush_icache_range(FIQ_VECTOR, FIQ_VECTOR + length); + memcpy((void *)0xffff001c, start, length); + flush_icache_range(0xffff001c, 0xffff001c + length); + if (!vectors_high()) + flush_icache_range(0x1c, 0x1c + length); } /* @@ -107,16 +95,15 @@ void set_fiq_handler(void *start, unsigned int length) */ void set_fiq_regs(struct pt_regs *regs) { - register unsigned long tmp, tmp2; + register unsigned long tmp; __asm__ volatile ( "mrs %0, cpsr\n\ - mov %1, %3\n\ - msr cpsr_c, %1 @ select FIQ mode\n\ + msr cpsr_c, %2 @ select FIQ mode\n\ mov r0, r0\n\ - ldmia %2, {r8 - r14}\n\ + ldmia %1, {r8 - r14}\n\ msr cpsr_c, %0 @ return to SVC mode\n\ mov r0, r0" - : "=&r" (tmp), "=&r" (tmp2) + : "=&r" (tmp) : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE) /* These registers aren't modified by the above code in a way visible to the compiler, but we mark them as clobbers anyway @@ -127,16 +114,15 @@ void set_fiq_regs(struct pt_regs *regs) void get_fiq_regs(struct pt_regs *regs) { - register unsigned long tmp, tmp2; + register unsigned long tmp; __asm__ volatile ( "mrs %0, cpsr\n\ - mov %1, %3\n\ - msr cpsr_c, %1 @ select FIQ mode\n\ + msr cpsr_c, %2 @ select FIQ mode\n\ mov r0, r0\n\ - stmia %2, {r8 - r14}\n\ + stmia %1, {r8 - r14}\n\ msr cpsr_c, %0 @ return to SVC mode\n\ mov r0, r0" - : "=&r" (tmp), "=&r" (tmp2) + : "=&r" (tmp) : "r" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE) /* These registers aren't modified by the above code in a way visible to the compiler, but we mark them as clobbers anyway @@ -198,6 +184,5 @@ EXPORT_SYMBOL(disable_fiq); void __init init_FIQ(void) { - no_fiq_insn = *(unsigned long *)FIQ_VECTOR; - set_fs(get_fs()); + no_fiq_insn = *(unsigned long *)0xffff001c; }