From 06ef66081620e94fe35a518f98624b83a140096e Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:10:45 -0700 Subject: [IA64] __ia64_syscall() is no longer used anywhere in the kernel. Remove it. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 12 ------------ arch/ia64/kernel/ia64_ksyms.c | 3 --- 2 files changed, 15 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index bd86fea49a..5b469db232 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -470,18 +470,6 @@ ENTRY(load_switch_stack) br.cond.sptk.many b7 END(load_switch_stack) -GLOBAL_ENTRY(__ia64_syscall) - .regstk 6,0,0,0 - mov r15=in5 // put syscall number in place - break __BREAK_SYSCALL - movl r2=errno - cmp.eq p6,p7=-1,r10 - ;; -(p6) st4 [r2]=r8 -(p6) mov r8=-1 - br.ret.sptk.many rp -END(__ia64_syscall) - GLOBAL_ENTRY(execve) mov r15=__NR_execve // put syscall number in place break __BREAK_SYSCALL diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index 7bbf019c98..01572814ab 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -58,9 +58,6 @@ EXPORT_SYMBOL(__strlen_user); EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(__strnlen_user); -#include -EXPORT_SYMBOL(__ia64_syscall); - /* from arch/ia64/lib */ extern void __divsi3(void); extern void __udivsi3(void); -- cgit v1.2.2 From 9ec1a7ad434fa951ff845dbee3397cf6ad4f76df Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:13:33 -0700 Subject: [IA64] Use dynamic prediction for RSE-clearing branches. This by itself is good for a 1-2 cycle speed up. Effect is bigger when combined with the later patches. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 5b469db232..c0f28339d5 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1012,14 +1012,14 @@ rse_clear_invalid: mov loc5=0 mov loc6=0 mov loc7=0 -(pRecurse) br.call.sptk.few b0=rse_clear_invalid +(pRecurse) br.call.dptk.few b0=rse_clear_invalid ;; mov loc8=0 mov loc9=0 cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret mov loc10=0 mov loc11=0 -(pReturn) br.ret.sptk.many b0 +(pReturn) br.ret.dptk.many b0 #endif /* !CONFIG_ITANIUM */ # undef pRecurse # undef pReturn -- cgit v1.2.2 From 3c79c8b1d92a9ae3edf3cbcd2c43c553ee0f1d83 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:15:13 -0700 Subject: [IA64] Schedule fp-clearing insns at least 6 cycles after reading ar.bsp. Decreases syscall overhead by approximately 6 cycles. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index c0f28339d5..0c84bed1bd 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -705,15 +705,15 @@ ENTRY(ia64_leave_syscall) // start restoring the state saved on the kernel stack (struct pt_regs): ld8 r9=[r2],PT(CR_IPSR)-PT(R9) ld8 r11=[r3],PT(CR_IIP)-PT(R11) - mov f6=f0 // clear f6 + nop.i 0 ;; invala // M0|1 invalidate ALAT rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection - mov f9=f0 // clear f9 + nop.i 0 ld8 r29=[r2],16 // load cr.ipsr ld8 r28=[r3],16 // load cr.iip - mov f8=f0 // clear f8 + mov r22=r0 // clear r22 ;; ld8 r30=[r2],16 // M0|1 load cr.ifs ld8 r25=[r3],16 // M0|1 load ar.unat @@ -721,15 +721,15 @@ ENTRY(ia64_leave_syscall) ;; ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs (pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled - mov f10=f0 // clear f10 +(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 ;; ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc - mov f11=f0 // clear f11 + mov f6=f0 // clear f6 ;; ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage) ld8 r31=[r3],PT(R1)-PT(PR) // load predicates -(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 + mov f7=f0 // clear f7 ;; ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr ld8.fill r1=[r3],16 // load r1 @@ -737,24 +737,29 @@ ENTRY(ia64_leave_syscall) ;; srlz.d // M0 ensure interruption collection is off ld8.fill r13=[r3],16 - mov f7=f0 // clear f7 + mov f8=f0 // clear f8 ;; ld8.fill r12=[r2] // restore r12 (sp) mov.m ar.ssd=r0 // M2 clear ar.ssd - mov r22=r0 // clear r22 + mov b6=r18 // I0 restore b6 + nop.m 0 + mov f9=f0 // clear f9 + shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition + ;; ld8.fill r15=[r3] // restore r15 (pUStk) st1 [r14]=r17 addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0 ;; (pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8 mov.m ar.csd=r0 // M2 clear ar.csd - mov b6=r18 // I0 restore b6 + mov f10=f0 // clear f10 ;; mov r14=r0 // clear r14 - shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition + mov f11=f0 // clear f11 (pKStk) br.cond.dpnt.many skip_rbs_switch + mov.m ar.ccv=r0 // clear ar.ccv (pNonSys) br.cond.dpnt.many dont_preserve_current_frame br.cond.sptk.many rbs_switch -- cgit v1.2.2 From 96e017495e6833adcbad84783e3c5eb685836bbf Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:16:07 -0700 Subject: [IA64] On return from syscall, hint b7 with __kernel_syscall_via_epc(). Why is this a good idea? Clearing b7 to 0 is guaranteed to do us no good and writing it with __kernel_syscall_via_epc() yields a 6 cycle improvement _if_ the application performs another EPC-based system- call without overwriting b7, which is not all that uncommon. Well worth the minimal cost of 1 bundle of code. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 0c84bed1bd..6359d7ffbb 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -692,7 +692,7 @@ ENTRY(ia64_leave_syscall) ;; (p6) ld4 r31=[r18] // load current_thread_info()->flags ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" - mov b7=r0 // clear b7 + nop.i 0 ;; ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) ld8 r18=[r2],PT(R9)-PT(B6) // load b6 @@ -754,7 +754,14 @@ ENTRY(ia64_leave_syscall) (pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8 mov.m ar.csd=r0 // M2 clear ar.csd mov f10=f0 // clear f10 + + nop.m 0 + movl r14=__kernel_syscall_via_epc // X ;; + nop.m 0 + nop.m 0 + mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) + mov r14=r0 // clear r14 mov f11=f0 // clear f11 (pKStk) br.cond.dpnt.many skip_rbs_switch -- cgit v1.2.2 From 060561ff79b01eea58e6d72abfb8e7580ff21f2a Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:17:03 -0700 Subject: [IA64] In syscall-entry, use st8 instead of stf8 to clear pt_regs.r8 Using stf8 seemed like a clever idea at the time, but stf8 forces the cache-line to be invalidated in the L1D (if it happens to be there already). This patch eliminates a guaranteed L1D cache-miss and, by itself, is good for a 1-2 cycle improvement for heavy-weight syscalls. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/ivt.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index d9c05d5343..dc78c356dd 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -1,7 +1,7 @@ /* * arch/ia64/kernel/ivt.S * - * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co + * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co * Stephane Eranian * David Mosberger * Copyright (C) 2000, 2002-2003 Intel Co @@ -918,7 +918,7 @@ GLOBAL_ENTRY(ia64_syscall_setup) tnat.nz p14,p0=in6 cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8 ;; - stf8 [r16]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error) + mov r8=1 (p9) tnat.nz p10,p0=r15 adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch) @@ -929,9 +929,9 @@ GLOBAL_ENTRY(ia64_syscall_setup) mov r13=r2 // establish `current' movl r1=__gp // establish kernel global pointer ;; + st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error) (p14) mov in6=-1 (p8) mov in7=-1 - nop.i 0 cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 movl r17=FPSR_DEFAULT -- cgit v1.2.2 From 87e522a0f7f8a7a5a1a880517989835c4f09c63e Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:17:44 -0700 Subject: [IA64] Schedule ia64_leave_syscall() to read ar.bsp earlier Reschedule code to read ar.bsp as early as possible. To enable this, don't bother clearing some of the registers when we're returning to kernel stacks. Also, instead of trying to support the pNonSys case (which makes no sense), do a bugcheck instead (with break 0). Finally, remove a clear of r14 which is a left-over from the previous patch. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 6359d7ffbb..d97a07c77a 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -694,22 +694,22 @@ ENTRY(ia64_leave_syscall) ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" nop.i 0 ;; - ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) + mov r16=ar.bsp // M2 get existing backing store pointer ld8 r18=[r2],PT(R9)-PT(B6) // load b6 (p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? ;; - mov r16=ar.bsp // M2 get existing backing store pointer + ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) (p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending? (p6) br.cond.spnt .work_pending_syscall ;; // start restoring the state saved on the kernel stack (struct pt_regs): ld8 r9=[r2],PT(CR_IPSR)-PT(R9) ld8 r11=[r3],PT(CR_IIP)-PT(R11) - nop.i 0 +(pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE! ;; invala // M0|1 invalidate ALAT rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection - nop.i 0 + cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs ld8 r29=[r2],16 // load cr.ipsr ld8 r28=[r3],16 // load cr.iip @@ -717,11 +717,11 @@ ENTRY(ia64_leave_syscall) ;; ld8 r30=[r2],16 // M0|1 load cr.ifs ld8 r25=[r3],16 // M0|1 load ar.unat - cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs +(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 ;; ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs (pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled -(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 + nop 0 ;; ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc @@ -735,40 +735,35 @@ ENTRY(ia64_leave_syscall) ld8.fill r1=[r3],16 // load r1 (pUStk) mov r17=1 ;; - srlz.d // M0 ensure interruption collection is off +(pUStk) st1 [r14]=r17 ld8.fill r13=[r3],16 mov f8=f0 // clear f8 ;; ld8.fill r12=[r2] // restore r12 (sp) - mov.m ar.ssd=r0 // M2 clear ar.ssd + ld8.fill r15=[r3] // restore r15 mov b6=r18 // I0 restore b6 - nop.m 0 + addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 mov f9=f0 // clear f9 +(pKStk) br.cond.dpnt.many skip_rbs_switch + + srlz.d // M0 ensure interruption collection is off shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition + cover // B add current frame into dirty partition and set cr.ifs ;; - ld8.fill r15=[r3] // restore r15 -(pUStk) st1 [r14]=r17 - addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0 - ;; -(pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8 - mov.m ar.csd=r0 // M2 clear ar.csd +(pUStk) ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 + mov r19=ar.bsp // M2 get new backing store pointer mov f10=f0 // clear f10 nop.m 0 movl r14=__kernel_syscall_via_epc // X ;; - nop.m 0 - nop.m 0 + mov.m ar.csd=r0 // M2 clear ar.csd + mov.m ar.ccv=r0 // clear ar.ccv mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) - mov r14=r0 // clear r14 + mov.m ar.ssd=r0 // M2 clear ar.ssd mov f11=f0 // clear f11 -(pKStk) br.cond.dpnt.many skip_rbs_switch - - - mov.m ar.ccv=r0 // clear ar.ccv -(pNonSys) br.cond.dpnt.many dont_preserve_current_frame br.cond.sptk.many rbs_switch END(ia64_leave_syscall) @@ -946,10 +941,10 @@ GLOBAL_ENTRY(ia64_leave_kernel) */ (pNonSys) br.cond.dpnt dont_preserve_current_frame -rbs_switch: cover // add current frame into dirty partition and set cr.ifs ;; mov r19=ar.bsp // get new backing store pointer +rbs_switch: sub r16=r16,r18 // krbs = old bsp - size of dirty partition cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs ;; -- cgit v1.2.2 From c03f058fbf685f2ff630095d2c1e98d331b81e82 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:18:22 -0700 Subject: [IA64] In ia64_leave_syscall(), fix comments and whitespace only. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 79 ++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 40 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index d97a07c77a..a7542c3d3b 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -625,7 +625,7 @@ END(ia64_ret_from_syscall) * r8-r11: restored (syscall return value(s)) * r12: restored (user-level stack pointer) * r13: restored (user-level thread pointer) - * r14: cleared + * r14: set to __kernel_syscall_via_epc * r15: restored (syscall #) * r16-r17: cleared * r18: user-level b6 @@ -646,7 +646,7 @@ END(ia64_ret_from_syscall) * pr: restored (user-level pr) * b0: restored (user-level rp) * b6: restored - * b7: cleared + * b7: set to __kernel_syscall_via_epc * ar.unat: restored (user-level ar.unat) * ar.pfs: restored (user-level ar.pfs) * ar.rsc: restored (user-level ar.rsc) @@ -708,63 +708,63 @@ ENTRY(ia64_leave_syscall) (pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE! ;; invala // M0|1 invalidate ALAT - rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection - cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs + rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection + cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs - ld8 r29=[r2],16 // load cr.ipsr - ld8 r28=[r3],16 // load cr.iip - mov r22=r0 // clear r22 + ld8 r29=[r2],16 // M0|1 load cr.ipsr + ld8 r28=[r3],16 // M0|1 load cr.iip + mov r22=r0 // A clear r22 ;; ld8 r30=[r2],16 // M0|1 load cr.ifs ld8 r25=[r3],16 // M0|1 load ar.unat (pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 ;; ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs -(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled +(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled nop 0 ;; - ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 - ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc - mov f6=f0 // clear f6 + ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0 + ld8 r27=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc + mov f6=f0 // F clear f6 ;; - ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage) - ld8 r31=[r3],PT(R1)-PT(PR) // load predicates - mov f7=f0 // clear f7 + ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be garbage) + ld8 r31=[r3],PT(R1)-PT(PR) // M0|1 load predicates + mov f7=f0 // F clear f7 ;; - ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr - ld8.fill r1=[r3],16 // load r1 -(pUStk) mov r17=1 + ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr + ld8.fill r1=[r3],16 // M0|1 load r1 +(pUStk) mov r17=1 // A ;; -(pUStk) st1 [r14]=r17 - ld8.fill r13=[r3],16 - mov f8=f0 // clear f8 +(pUStk) st1 [r14]=r17 // M2|3 + ld8.fill r13=[r3],16 // M0|1 + mov f8=f0 // F clear f8 ;; - ld8.fill r12=[r2] // restore r12 (sp) - ld8.fill r15=[r3] // restore r15 - mov b6=r18 // I0 restore b6 + ld8.fill r12=[r2] // M0|1 restore r12 (sp) + ld8.fill r15=[r3] // M0|1 restore r15 + mov b6=r18 // I0 restore b6 - addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 - mov f9=f0 // clear f9 -(pKStk) br.cond.dpnt.many skip_rbs_switch + addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A + mov f9=f0 // F clear f9 +(pKStk) br.cond.dpnt.many skip_rbs_switch // B - srlz.d // M0 ensure interruption collection is off - shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition - cover // B add current frame into dirty partition and set cr.ifs + srlz.d // M0 ensure interruption collection is off (for cover) + shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition + cover // B add current frame into dirty partition & set cr.ifs ;; -(pUStk) ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 - mov r19=ar.bsp // M2 get new backing store pointer - mov f10=f0 // clear f10 +(pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8 + mov r19=ar.bsp // M2 get new backing store pointer + mov f10=f0 // F clear f10 nop.m 0 - movl r14=__kernel_syscall_via_epc // X + movl r14=__kernel_syscall_via_epc // X ;; - mov.m ar.csd=r0 // M2 clear ar.csd - mov.m ar.ccv=r0 // clear ar.ccv - mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) + mov.m ar.csd=r0 // M2 clear ar.csd + mov.m ar.ccv=r0 // M2 clear ar.ccv + mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) - mov.m ar.ssd=r0 // M2 clear ar.ssd - mov f11=f0 // clear f11 - br.cond.sptk.many rbs_switch + mov.m ar.ssd=r0 // M2 clear ar.ssd + mov f11=f0 // F clear f11 + br.cond.sptk.many rbs_switch // B END(ia64_leave_syscall) #ifdef CONFIG_IA32_SUPPORT @@ -940,7 +940,6 @@ GLOBAL_ENTRY(ia64_leave_kernel) * NOTE: alloc, loadrs, and cover can't be predicated. */ (pNonSys) br.cond.dpnt dont_preserve_current_frame - cover // add current frame into dirty partition and set cr.ifs ;; mov r19=ar.bsp // get new backing store pointer -- cgit v1.2.2 From f8fa5448fc9b4a7806b1297a0b57808f12fe4d43 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:19:04 -0700 Subject: [IA64] Reschedule break_fault() for better performance. This patch reorganizes break_fault() to optimistically assume that a system-call is being performed from user-space (which is almost always the case). If it turns out that (a) we're not being called due to a system call or (b) we're being called from within the kernel, we fixup the no-longer-valid assumptions in non_syscall() and .break_fixup(), respectively. With this approach, there are 3 major phases: - Phase 1: Read various control & application registers, in particular the current task pointer from AR.K6. - Phase 2: Do all memory loads (load system-call entry, load current_thread_info()->flags, prefetch kernel register-backing store) and switch to kernel register-stack. - Phase 3: Call ia64_syscall_setup() and invoke syscall-handler. Good for 26-30 cycles of improvement on break-based syscall-path. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/ivt.S | 173 ++++++++++++++++++++++++++++++------------------- 1 file changed, 106 insertions(+), 67 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index dc78c356dd..386087edab 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -687,82 +687,118 @@ ENTRY(break_fault) * to prevent leaking bits from kernel to user level. */ DBG_FAULT(11) - mov r16=IA64_KR(CURRENT) // r16 = current task; 12 cycle read lat. - mov r17=cr.iim - mov r18=__IA64_BREAK_SYSCALL - mov r21=ar.fpsr - mov r29=cr.ipsr - mov r19=b6 - mov r25=ar.unat - mov r27=ar.rsc - mov r26=ar.pfs - mov r28=cr.iip - mov r31=pr // prepare to save predicates - mov r20=r1 - ;; + mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc) + mov r29=cr.ipsr // M2 (12 cyc) + mov r31=pr // I0 (2 cyc) + + mov r17=cr.iim // M2 (2 cyc) + mov.m r27=ar.rsc // M2 (12 cyc) + mov r18=__IA64_BREAK_SYSCALL // A + + mov.m ar.rsc=0 // M2 + mov.m r21=ar.fpsr // M2 (12 cyc) + mov r19=b6 // I0 (2 cyc) + ;; + mov.m r23=ar.bspstore // M2 (12 cyc) + mov.m r24=ar.rnat // M2 (5 cyc) + mov.i r26=ar.pfs // I0 (2 cyc) + + invala // M0|1 + nop.m 0 // M + mov r20=r1 // A save r1 + + nop.m 0 + movl r30=sys_call_table // X + + mov r28=cr.iip // M2 (2 cyc) + cmp.eq p0,p7=r18,r17 // I0 is this a system call? +(p7) br.cond.spnt non_syscall // B no -> + // + // From this point on, we are definitely on the syscall-path + // and we can use (non-banked) scratch registers. + // +/////////////////////////////////////////////////////////////////////// + mov r1=r16 // A move task-pointer to "addl"-addressable reg + mov r2=r16 // A setup r2 for ia64_syscall_setup + add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = ¤t_thread_info()->flags + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 - cmp.eq p0,p7=r18,r17 // is this a system call? (p7 <- false, if so) -(p7) br.cond.spnt non_syscall + adds r15=-1024,r15 // A subtract 1024 from syscall number + mov r3=NR_syscalls - 1 ;; - ld1 r17=[r16] // load current->thread.on_ustack flag - st1 [r16]=r0 // clear current->thread.on_ustack flag - add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // set r1 for MINSTATE_START_SAVE_MIN_VIRT + ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag + ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags + extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr + + shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024) + addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS + cmp.leu p6,p7=r15,r3 // A syscall number in range? ;; - invala - /* adjust return address so we skip over the break instruction: */ + lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS +(p6) ld8 r30=[r30] // M0|1 load address of syscall entry point + tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT? - extr.u r8=r29,41,2 // extract ei field from cr.ipsr - ;; - cmp.eq p6,p7=2,r8 // isr.ei==2? - mov r2=r1 // setup r2 for ia64_syscall_setup - ;; -(p6) mov r8=0 // clear ei to 0 -(p6) adds r28=16,r28 // switch cr.iip to next bundle cr.ipsr.ei wrapped -(p7) adds r8=1,r8 // increment ei to next slot - ;; - cmp.eq pKStk,pUStk=r0,r17 // are we in kernel mode already? - dep r29=r8,r29,41,2 // insert new ei into cr.ipsr + mov.m ar.bspstore=r22 // M2 switch to kernel RBS + cmp.eq p8,p9=2,r8 // A isr.ei==2? ;; - // switch from user to kernel RBS: - MINSTATE_START_SAVE_MIN_VIRT - br.call.sptk.many b7=ia64_syscall_setup - ;; - MINSTATE_END_SAVE_MIN_VIRT // switch to bank 1 - ssm psr.ic | PSR_DEFAULT_BITS - ;; - srlz.i // guarantee that interruption collection is on - mov r3=NR_syscalls - 1 - ;; -(p15) ssm psr.i // restore psr.i - // p10==true means out registers are more than 8 or r15's Nat is true -(p10) br.cond.spnt.many ia64_ret_from_syscall - ;; - movl r16=sys_call_table +(p8) mov r8=0 // A clear ei to 0 +(p7) movl r30=sys_ni_syscall // X - adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024 - movl r2=ia64_ret_from_syscall - ;; - shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024) - cmp.leu p6,p7=r15,r3 // (syscall > 0 && syscall < 1024 + NR_syscalls) ? - mov rp=r2 // set the real return addr +(p8) adds r28=16,r28 // A switch cr.iip to next bundle +(p9) adds r8=1,r8 // A increment ei to next slot + nop.i 0 ;; -(p6) ld8 r20=[r20] // load address of syscall entry point -(p7) movl r20=sys_ni_syscall - add r2=TI_FLAGS+IA64_TASK_SIZE,r13 - ;; - ld4 r2=[r2] // r2 = current_thread_info()->flags - ;; - and r2=_TIF_SYSCALL_TRACEAUDIT,r2 // mask trace or audit + mov.m r25=ar.unat // M2 (5 cyc) + dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr + adds r15=1024,r15 // A restore original syscall number + // + // If any of the above loads miss in L1D, we'll stall here until + // the data arrives. + // +/////////////////////////////////////////////////////////////////////// + st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag + mov b6=r30 // I0 setup syscall handler branch reg early + cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already? + + and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit + mov r18=ar.bsp // M2 (12 cyc) +(pKStk) br.cond.spnt .break_fixup // B we're already in kernel-mode -- fix up RBS + ;; +.back_from_break_fixup: +(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack + cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? + br.call.sptk.many b7=ia64_syscall_setup // B +1: + mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 + nop 0 + bsw.1 // B (6 cyc) regs are saved, switch to bank 1 ;; - cmp.eq p8,p0=r2,r0 - mov b6=r20 + + ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection + movl r3=ia64_ret_from_syscall // X ;; -(p8) br.call.sptk.many b6=b6 // ignore this return addr - br.cond.sptk ia64_trace_syscall + + srlz.i // M0 ensure interruption collection is on + mov rp=r3 // I0 set the real return addr +(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT + +(p15) ssm psr.i // M2 restore psr.i +(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) + br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic // NOT REACHED +/////////////////////////////////////////////////////////////////////// + // On entry, we optimistically assumed that we're coming from user-space. + // For the rare cases where a system-call is done from within the kernel, + // we fix things up at this point: +.break_fixup: + add r1=-IA64_PT_REGS_SIZE,sp // A allocate space for pt_regs structure + mov ar.rnat=r24 // M2 restore kernel's AR.RNAT + ;; + mov ar.bspstore=r23 // M2 restore kernel's AR.BSPSTORE + br.cond.sptk .back_from_break_fixup END(break_fault) .org ia64_ivt+0x3000 @@ -837,8 +873,6 @@ END(interrupt) * - r31: saved pr * - b0: original contents (to be saved) * On exit: - * - executing on bank 1 registers - * - psr.ic enabled, interrupts restored * - p10: TRUE if syscall is invoked with more than 8 out * registers or r15's Nat is true * - r1: kernel's gp @@ -846,8 +880,11 @@ END(interrupt) * - r8: -EINVAL if p10 is true * - r12: points to kernel stack * - r13: points to current task + * - r14: preserved (same as on entry) + * - p13: preserved * - p15: TRUE if interrupts need to be re-enabled * - ar.fpsr: set to kernel settings + * - b6: preserved (same as on entry) */ GLOBAL_ENTRY(ia64_syscall_setup) #if PT(B6) != 0 @@ -915,7 +952,7 @@ GLOBAL_ENTRY(ia64_syscall_setup) (p13) mov in5=-1 ;; st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr - tnat.nz p14,p0=in6 + tnat.nz p13,p0=in6 cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8 ;; mov r8=1 @@ -930,7 +967,7 @@ GLOBAL_ENTRY(ia64_syscall_setup) movl r1=__gp // establish kernel global pointer ;; st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error) -(p14) mov in6=-1 +(p13) mov in6=-1 (p8) mov in7=-1 cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 @@ -1002,6 +1039,8 @@ END(dispatch_illegal_op_fault) FAULT(17) ENTRY(non_syscall) + mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER + ;; SAVE_MIN_WITH_COVER // There is no particular reason for this code to be here, other than that -- cgit v1.2.2 From 70929a57cfea8c18de13fcea9ae6771018a98949 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:19:37 -0700 Subject: [IA64] Reschedule __kernel_syscall_via_epc(). Avoid some stalls, which is good for about 2 cycles when invoking a light-weight handler. When invoking a heavy-weight handler, this helps by about 7 cycles, with most of the improvement coming from the improved branch-prediction achieved by splitting the BBB bundle into two MIB bundles. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/gate.S | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S index facf75acdc..3cd3f2e971 100644 --- a/arch/ia64/kernel/gate.S +++ b/arch/ia64/kernel/gate.S @@ -79,31 +79,34 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) ;; rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be" LOAD_FSYSCALL_TABLE(r14) - + ;; mov r16=IA64_KR(CURRENT) // 12 cycle read latency - tnat.nz p10,p9=r15 + shladd r18=r17,3,r14 mov r19=NR_syscalls-1 ;; - shladd r18=r17,3,r14 - - srlz.d - cmp.ne p8,p0=r0,r0 // p8 <- FALSE + lfetch [r18] // M0|1 + mov r29=psr // read psr (12 cyc load latency) /* Note: if r17 is a NaT, p6 will be set to zero. */ cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)? ;; -(p6) ld8 r18=[r18] mov r21=ar.fpsr - add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry + tnat.nz p10,p9=r15 + mov r26=ar.pfs ;; + srlz.d +(p6) ld8 r18=[r18] + nop.i 0 + ;; + nop.m 0 (p6) mov b7=r18 -(p6) tbit.z p8,p0=r18,0 +(p6) tbit.z.unc p8,p0=r18,0 + + nop.m 0 + nop.i 0 (p8) br.dptk.many b7 -(p6) rsm psr.i mov r27=ar.rsc - mov r26=ar.pfs - ;; - mov r29=psr // read psr (12 cyc load latency) +(p6) rsm psr.i /* * brl.cond doesn't work as intended because the linker would convert this branch * into a branch to a PLT. Perhaps there will be a way to avoid this with some @@ -111,6 +114,8 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) * instead. */ #ifdef CONFIG_ITANIUM + add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry + ;; (p6) ld8 r14=[r14] // r14 <- fsys_bubble_down ;; (p6) mov b7=r14 -- cgit v1.2.2 From 21bc4f9b34cc1eab3610955207f72c52495ae8ed Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:20:11 -0700 Subject: [IA64] Annotate __kernel_syscall_via_epc() with McKinley dispatch info. Two other very minor changes: use "mov.i" instead of "mov" for reading ar.pfs (for clarity; doesn't affect the code at all). Also, predicate the load of r14 for consistency. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/gate.S | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S index 3cd3f2e971..272e64c0e2 100644 --- a/arch/ia64/kernel/gate.S +++ b/arch/ia64/kernel/gate.S @@ -72,41 +72,41 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) * bundle get executed. The remaining code must be safe even if * they do not get executed. */ - adds r17=-1024,r15 - mov r10=0 // default to successful syscall execution - epc + adds r17=-1024,r15 // A + mov r10=0 // A default to successful syscall execution + epc // B causes split-issue } ;; - rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be" - LOAD_FSYSCALL_TABLE(r14) + rsm psr.be // M2 (5 cyc to srlz.d) + LOAD_FSYSCALL_TABLE(r14) // X ;; - mov r16=IA64_KR(CURRENT) // 12 cycle read latency - shladd r18=r17,3,r14 - mov r19=NR_syscalls-1 + mov r16=IA64_KR(CURRENT) // M2 (12 cyc) + shladd r18=r17,3,r14 // A + mov r19=NR_syscalls-1 // A ;; lfetch [r18] // M0|1 - mov r29=psr // read psr (12 cyc load latency) - /* Note: if r17 is a NaT, p6 will be set to zero. */ - cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)? + mov r29=psr // M2 (12 cyc) + // If r17 is a NaT, p6 will be zero + cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)? ;; - mov r21=ar.fpsr - tnat.nz p10,p9=r15 - mov r26=ar.pfs + mov r21=ar.fpsr // M2 (12 cyc) + tnat.nz p10,p9=r15 // I0 + mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...) ;; - srlz.d -(p6) ld8 r18=[r18] + srlz.d // M0 (forces split-issue) ensure PSR.BE==0 +(p6) ld8 r18=[r18] // M0|1 nop.i 0 ;; nop.m 0 -(p6) mov b7=r18 -(p6) tbit.z.unc p8,p0=r18,0 +(p6) mov b7=r18 // I0 +(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) nop.m 0 nop.i 0 -(p8) br.dptk.many b7 +(p8) br.dptk.many b7 // B - mov r27=ar.rsc -(p6) rsm psr.i + mov r27=ar.rsc // M2 (12 cyc) +(p6) rsm psr.i // M2 /* * brl.cond doesn't work as intended because the linker would convert this branch * into a branch to a PLT. Perhaps there will be a way to avoid this with some @@ -114,7 +114,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) * instead. */ #ifdef CONFIG_ITANIUM - add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry +(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry ;; (p6) ld8 r14=[r14] // r14 <- fsys_bubble_down ;; -- cgit v1.2.2 From 1ba7be7d691f6df2557d39c5b1a2e14c32e5dd20 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:20:51 -0700 Subject: [IA64] Reschedule fsys_bubble_down(). Improvements come from eliminating srlz.i, not scheduling AR/CR-reads too early (while there are others still pending), scheduling the backing-store switch as well as possible, splitting the BBB bundle into a MIB/MBB pair. Why is it safe to eliminate the srlz.i? Observe that we used to clear bits ~PSR_PRESERVED_BITS in PSR.L. Since PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}. However, PSR.BE : already is turned off in __kernel_syscall_via_epc() PSR.AC : don't care (kernel normally turns PSR.AC on) PSR.I : already turned off by the time fsys_bubble_down gets invoked PSR.DFL: always 0 (kernel never turns it on) PSR.DFH: don't care --- kernel never touches f32-f127 on its own initiative PSR.DI : always 0 (kernel never turns it on) PSR.SI : always 0 (kernel never turns it on) PSR.DB : don't care --- kernel never enables kernel-level breakpoints PSR.TB : must be 0 already; if it wasn't zero on entry to __kernel_syscall_via_epc, the branch to fsys_bubble_down will trigger a taken branch; the taken-trap-handler then converts the syscall into a break-based system-call. In other words: all the bits we're clearying are either 0 already or are don't cares! Thus, we don't have to write PSR.L at all and we don't have to do a srlz.i either. Good for another ~20 cycle improvement for EPC-based heavy-weight syscalls. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/fsys.S | 73 ++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 40 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 0d8650f7fc..57c6556b1e 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -549,9 +549,6 @@ GLOBAL_ENTRY(fsys_bubble_down) * - r27: ar.rsc * - r29: psr */ -# define PSR_PRESERVED_BITS (IA64_PSR_UP | IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_PK \ - | IA64_PSR_DT | IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_RT \ - | IA64_PSR_IC) /* * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. The rest we have * to synthesize. @@ -560,62 +557,58 @@ GLOBAL_ENTRY(fsys_bubble_down) | IA64_PSR_BN | IA64_PSR_I) invala - movl r8=PSR_ONE_BITS + movl r14=ia64_ret_from_syscall - mov r25=ar.unat // save ar.unat (5 cyc) - movl r9=PSR_PRESERVED_BITS - - mov ar.rsc=0 // set enforced lazy mode, pl 0, little-endian, loadrs=0 + nop.m 0 movl r28=__kernel_syscall_via_break ;; - mov r23=ar.bspstore // save ar.bspstore (12 cyc) - mov r31=pr // save pr (2 cyc) - mov r20=r1 // save caller's gp in r20 - ;; + mov r2=r16 // copy current task addr to addl-addressable register - and r9=r9,r29 - mov r19=b6 // save b6 (2 cyc) + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 + mov r31=pr // save pr (2 cyc) ;; - mov psr.l=r9 // slam the door (17 cyc to srlz.i) - or r29=r8,r29 // construct cr.ipsr value to save + st1 [r16]=r0 // clear current->thread.on_ustack flag addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS + add r3=TI_FLAGS+IA64_TASK_SIZE,r2 ;; - // GAS reports a spurious RAW hazard on the read of ar.rnat because it thinks - // we may be reading ar.itc after writing to psr.l. Avoid that message with - // this directive: - dv_serialize_data - mov.m r24=ar.rnat // read ar.rnat (5 cyc lat) + ld4 r3=[r3] // r2 = current_thread_info()->flags lfetch.fault.excl.nt1 [r22] - adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2 - - // ensure previous insn group is issued before we stall for srlz.i: + nop.i 0 ;; - srlz.i // ensure new psr.l has been established - ///////////////////////////////////////////////////////////////////////////// - ////////// from this point on, execution is not interruptible anymore - ///////////////////////////////////////////////////////////////////////////// - addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // compute base of memory stack - cmp.ne pKStk,pUStk=r0,r0 // set pKStk <- 0, pUStk <- 1 + mov ar.rsc=0 // set enforced lazy mode, pl 0, little-endian, loadrs=0 + nop.m 0 + nop.i 0 + ;; + mov r23=ar.bspstore // save ar.bspstore (12 cyc) + mov.m r24=ar.rnat // read ar.rnat (5 cyc lat) + nop.i 0 ;; - st1 [r16]=r0 // clear current->thread.on_ustack flag mov ar.bspstore=r22 // switch to kernel RBS - mov b6=r18 // copy syscall entry-point to b6 (7 cyc) - add r3=TI_FLAGS+IA64_TASK_SIZE,r2 + movl r8=PSR_ONE_BITS // X ;; - ld4 r3=[r3] // r2 = current_thread_info()->flags + mov r25=ar.unat // save ar.unat (5 cyc) + mov r19=b6 // save b6 (2 cyc) + mov r20=r1 // save caller's gp in r20 + ;; + or r29=r8,r29 // construct cr.ipsr value to save + mov b6=r18 // copy syscall entry-point to b6 (7 cyc) + addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // compute base of memory stack + mov r18=ar.bsp // save (kernel) ar.bsp (12 cyc) - mov ar.rsc=0x3 // set eager mode, pl 0, little-endian, loadrs=0 + cmp.ne pKStk,pUStk=r0,r0 // set pKStk <- 0, pUStk <- 1 br.call.sptk.many b7=ia64_syscall_setup ;; - ssm psr.i - movl r2=ia64_ret_from_syscall + mov ar.rsc=0x3 // set eager mode, pl 0, little-endian, loadrs=0 + mov rp=r14 // set the real return addr + nop.i 0 ;; - mov rp=r2 // set the real return addr + ssm psr.i tbit.z p8,p0=r3,TIF_SYSCALL_TRACE - ;; (p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8 + + nop.m 0 (p8) br.call.sptk.many b6=b6 // ignore this return addr - br.cond.sptk ia64_trace_syscall + br.cond.spnt ia64_trace_syscall END(fsys_bubble_down) .rodata -- cgit v1.2.2 From fbf7192ba06e4b55022231e5fdb9db8ce3ad6307 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:21:26 -0700 Subject: [IA64] Annotate fsys_bubble_down() with McKinley dispatch info. This patch changes comments & formatting only. There is no code change. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/fsys.S | 118 ++++++++++++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 57c6556b1e..d09a5b8a09 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -531,84 +531,114 @@ GLOBAL_ENTRY(fsys_bubble_down) .altrp b6 .body /* - * We get here for syscalls that don't have a lightweight handler. For those, we - * need to bubble down into the kernel and that requires setting up a minimal - * pt_regs structure, and initializing the CPU state more or less as if an - * interruption had occurred. To make syscall-restarts work, we setup pt_regs - * such that cr_iip points to the second instruction in syscall_via_break. - * Decrementing the IP hence will restart the syscall via break and not - * decrementing IP will return us to the caller, as usual. Note that we preserve - * the value of psr.pp rather than initializing it from dcr.pp. This makes it - * possible to distinguish fsyscall execution from other privileged execution. + * We get here for syscalls that don't have a lightweight + * handler. For those, we need to bubble down into the kernel + * and that requires setting up a minimal pt_regs structure, + * and initializing the CPU state more or less as if an + * interruption had occurred. To make syscall-restarts work, + * we setup pt_regs such that cr_iip points to the second + * instruction in syscall_via_break. Decrementing the IP + * hence will restart the syscall via break and not + * decrementing IP will return us to the caller, as usual. + * Note that we preserve the value of psr.pp rather than + * initializing it from dcr.pp. This makes it possible to + * distinguish fsyscall execution from other privileged + * execution. * * On entry: - * - normal fsyscall handler register usage, except that we also have: + * - normal fsyscall handler register usage, except + * that we also have: * - r18: address of syscall entry point * - r21: ar.fpsr * - r26: ar.pfs * - r27: ar.rsc * - r29: psr + * + * We used to clear some PSR bits here but that requires slow + * serialization. Fortuntely, that isn't really necessary. + * The rationale is as follows: we used to clear bits + * ~PSR_PRESERVED_BITS in PSR.L. Since + * PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we + * ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}. + * However, + * + * PSR.BE : already is turned off in __kernel_syscall_via_epc() + * PSR.AC : don't care (kernel normally turns PSR.AC on) + * PSR.I : already turned off by the time fsys_bubble_down gets + * invoked + * PSR.DFL: always 0 (kernel never turns it on) + * PSR.DFH: don't care --- kernel never touches f32-f127 on its own + * initiative + * PSR.DI : always 0 (kernel never turns it on) + * PSR.SI : always 0 (kernel never turns it on) + * PSR.DB : don't care --- kernel never enables kernel-level + * breakpoints + * PSR.TB : must be 0 already; if it wasn't zero on entry to + * __kernel_syscall_via_epc, the branch to fsys_bubble_down + * will trigger a taken branch; the taken-trap-handler then + * converts the syscall into a break-based system-call. */ /* - * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. The rest we have - * to synthesize. + * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. + * The rest we have to synthesize. */ -# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \ +# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) \ + | (0x1 << IA64_PSR_RI_BIT) \ | IA64_PSR_BN | IA64_PSR_I) - invala - movl r14=ia64_ret_from_syscall + invala // M0|1 + movl r14=ia64_ret_from_syscall // X nop.m 0 - movl r28=__kernel_syscall_via_break + movl r28=__kernel_syscall_via_break // X create cr.iip ;; - mov r2=r16 // copy current task addr to addl-addressable register - adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 - mov r31=pr // save pr (2 cyc) + mov r2=r16 // A get task addr to addl-addressable register + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // A + mov r31=pr // I0 save pr (2 cyc) ;; - st1 [r16]=r0 // clear current->thread.on_ustack flag - addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS - add r3=TI_FLAGS+IA64_TASK_SIZE,r2 + st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag + addl r22=IA64_RBS_OFFSET,r2 // A compute base of RBS + add r3=TI_FLAGS+IA64_TASK_SIZE,r2 // A ;; - ld4 r3=[r3] // r2 = current_thread_info()->flags - lfetch.fault.excl.nt1 [r22] + ld4 r3=[r3] // M0|1 r3 = current_thread_info()->flags + lfetch.fault.excl.nt1 [r22] // M0|1 prefetch register backing-store nop.i 0 ;; - mov ar.rsc=0 // set enforced lazy mode, pl 0, little-endian, loadrs=0 + mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0 nop.m 0 nop.i 0 ;; - mov r23=ar.bspstore // save ar.bspstore (12 cyc) - mov.m r24=ar.rnat // read ar.rnat (5 cyc lat) + mov r23=ar.bspstore // M2 (12 cyc) save ar.bspstore + mov.m r24=ar.rnat // M2 (5 cyc) read ar.rnat (dual-issues!) nop.i 0 ;; - mov ar.bspstore=r22 // switch to kernel RBS + mov ar.bspstore=r22 // M2 (6 cyc) switch to kernel RBS movl r8=PSR_ONE_BITS // X ;; - mov r25=ar.unat // save ar.unat (5 cyc) - mov r19=b6 // save b6 (2 cyc) - mov r20=r1 // save caller's gp in r20 + mov r25=ar.unat // M2 (5 cyc) save ar.unat + mov r19=b6 // I0 save b6 (2 cyc) + mov r20=r1 // A save caller's gp in r20 ;; - or r29=r8,r29 // construct cr.ipsr value to save - mov b6=r18 // copy syscall entry-point to b6 (7 cyc) - addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // compute base of memory stack + or r29=r8,r29 // A construct cr.ipsr value to save + mov b6=r18 // I0 copy syscall entry-point to b6 (7 cyc) + addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // A compute base of memory stack - mov r18=ar.bsp // save (kernel) ar.bsp (12 cyc) - cmp.ne pKStk,pUStk=r0,r0 // set pKStk <- 0, pUStk <- 1 - br.call.sptk.many b7=ia64_syscall_setup + mov r18=ar.bsp // M2 save (kernel) ar.bsp (12 cyc) + cmp.ne pKStk,pUStk=r0,r0 // A set pKStk <- 0, pUStk <- 1 + br.call.sptk.many b7=ia64_syscall_setup // B ;; - mov ar.rsc=0x3 // set eager mode, pl 0, little-endian, loadrs=0 - mov rp=r14 // set the real return addr + mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 + mov rp=r14 // I0 set the real return addr nop.i 0 ;; - ssm psr.i - tbit.z p8,p0=r3,TIF_SYSCALL_TRACE -(p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8 + ssm psr.i // M2 we're on kernel stacks now, reenable irqs + tbit.z p8,p0=r3,TIF_SYSCALL_TRACE // I0 +(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT nop.m 0 -(p8) br.call.sptk.many b6=b6 // ignore this return addr - br.cond.spnt ia64_trace_syscall +(p8) br.call.sptk.many b6=b6 // B (ignore return address) + br.cond.spnt ia64_trace_syscall // B END(fsys_bubble_down) .rodata -- cgit v1.2.2 From e7e965fa1961a8ce32cbbb1bd436c655ad03973e Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:22:08 -0700 Subject: [IA64] use srlz.d instead of srlz.i in ia64_leave_kernel() This patch switches the srlz.i in ia64_leave_kernel() to srlz.d. As per architecture manual, the former is needed only to ensure that the clearing of PSR.IC is seen by the VHPT for subsequent instruction fetches. However, since the remainder of the code (up to and including the RFI instruction) is mapped by a pinned TLB entry, there is no chance of an iTLB miss and we don't care whether or not the VHPT sees PSR.IC cleared. Since srlz.d is substantially cheaper than srlz.i, this should shave off a few cycles off the interrupt path (unverified though; I'm not setup to measure this at the moment). Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index a7542c3d3b..4517d4ab5e 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -880,7 +880,7 @@ GLOBAL_ENTRY(ia64_leave_kernel) ldf.fill f7=[r2],PT(F11)-PT(F7) ldf.fill f8=[r3],32 ;; - srlz.i // ensure interruption collection is off + srlz.d // ensure that inter. collection is off (VHPT is don't care, since text is pinned) mov ar.ccv=r15 ;; ldf.fill f11=[r2] -- cgit v1.2.2 From 8e3e50168c8537807b7a6f78588cd72e21363262 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:22:40 -0700 Subject: [IA64] need r29=psr *after* rsm psr.i Yanmin Zhang pointed out a sequence problem when saving the psr. David Mosberger provided this patch (which gave up a cycle). Signed-off-by: Tony Luck --- arch/ia64/kernel/gate.S | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S index 272e64c0e2..86948ce63e 100644 --- a/arch/ia64/kernel/gate.S +++ b/arch/ia64/kernel/gate.S @@ -77,7 +77,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) epc // B causes split-issue } ;; - rsm psr.be // M2 (5 cyc to srlz.d) + rsm psr.be | psr.i // M2 (5 cyc to srlz.d) LOAD_FSYSCALL_TABLE(r14) // X ;; mov r16=IA64_KR(CURRENT) // M2 (12 cyc) @@ -98,15 +98,14 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) nop.i 0 ;; nop.m 0 -(p6) mov b7=r18 // I0 (p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) - - nop.m 0 nop.i 0 + ;; +(p8) ssm psr.i +(p6) mov b7=r18 // I0 (p8) br.dptk.many b7 // B mov r27=ar.rsc // M2 (12 cyc) -(p6) rsm psr.i // M2 /* * brl.cond doesn't work as intended because the linker would convert this branch * into a branch to a PLT. Perhaps there will be a way to avoid this with some @@ -123,7 +122,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) #else BRL_COND_FSYS_BUBBLE_DOWN(p6) #endif - + ssm psr.i mov r10=-1 (p10) mov r8=EINVAL (p9) mov r8=ENOSYS -- cgit v1.2.2 From ebcc80c1b6629a445f7471cc1ddb48faf8a84e70 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Thu, 5 May 2005 06:40:00 -0700 Subject: [IA64] Merge audit fix for fsyscalls with syscall-optimizations Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/fsys.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index d09a5b8a09..f566ff43a3 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -630,10 +630,10 @@ GLOBAL_ENTRY(fsys_bubble_down) ;; mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 mov rp=r14 // I0 set the real return addr - nop.i 0 + and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A ;; ssm psr.i // M2 we're on kernel stacks now, reenable irqs - tbit.z p8,p0=r3,TIF_SYSCALL_TRACE // I0 + cmp.eq p8,p0=r3,r0 // A (p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT nop.m 0 -- cgit v1.2.2 From 7f9eaedf894dbaa08c157832e9a6c9c03ffed1ed Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Tue, 10 May 2005 12:49:00 -0700 Subject: [IA64] Fix convert_to_non_syscall() so gdb inferior calls work again Fix convert_to_non_syscall() so it arranges for the kernel to be left via ia64_leave_kernel() rather than ia64_leave_syscall(). The latter no longer tolerates being called with pSys=0 and pNonSys=1. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/ptrace.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index c253fd5914..9e730c7bf0 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -705,12 +705,32 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, break; } + /* + * Note: at the time of this call, the target task is blocked + * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL + * (aka, "pLvSys") we redirect execution from + * .work_pending_syscall_end to .work_processed_kernel. + */ unw_get_pr(&prev_info, &pr); - pr &= ~(1UL << PRED_SYSCALL); + pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL)); pr |= (1UL << PRED_NON_SYSCALL); unw_set_pr(&prev_info, pr); pt->cr_ifs = (1UL << 63) | cfm; + /* + * Clear the memory that is NOT written on syscall-entry to + * ensure we do not leak kernel-state to user when execution + * resumes. + */ + pt->r2 = 0; + pt->r3 = 0; + pt->r14 = 0; + memset(&pt->r16, 0, 16*8); /* clear r16-r31 */ + memset(&pt->f6, 0, 6*16); /* clear f6-f11 */ + pt->b7 = 0; + pt->ar_ccv = 0; + pt->ar_csd = 0; + pt->ar_ssd = 0; } static int -- cgit v1.2.2 From 09b8b5f843afc21daf710cc610e5ca890ee94696 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 26 Jun 2005 17:06:36 +0100 Subject: [PATCH] ARM: Add SA_TIMER flag to timer interrupts VST needs to know which timer handler is for the timer interrupt. Mark all timer interrupts with the SA_TIMER flag. Signed-off-by: Russell King --- arch/arm/mach-aaec2000/core.c | 4 ++-- arch/arm/mach-clps711x/time.c | 4 ++-- arch/arm/mach-clps7500/core.c | 4 ++-- arch/arm/mach-ebsa110/core.c | 4 ++-- arch/arm/mach-epxa10db/time.c | 4 ++-- arch/arm/mach-footbridge/dc21285-timer.c | 2 +- arch/arm/mach-footbridge/isa-timer.c | 2 +- arch/arm/mach-h720x/cpu-h7201.c | 4 ++-- arch/arm/mach-h720x/cpu-h7202.c | 4 ++-- arch/arm/mach-imx/time.c | 4 ++-- arch/arm/mach-integrator/core.c | 4 ++-- arch/arm/mach-iop3xx/iop321-time.c | 2 +- arch/arm/mach-iop3xx/iop331-time.c | 2 +- arch/arm/mach-ixp2000/core.c | 4 ++-- arch/arm/mach-ixp4xx/common.c | 4 ++-- arch/arm/mach-lh7a40x/time.c | 4 ++-- arch/arm/mach-omap/time.c | 10 +++++----- arch/arm/mach-pxa/time.c | 4 ++-- arch/arm/mach-s3c2410/time.c | 4 ++-- arch/arm/mach-sa1100/h3600.c | 2 +- arch/arm/mach-sa1100/time.c | 4 ++-- arch/arm/mach-shark/core.c | 4 ++-- arch/arm/mach-versatile/core.c | 4 ++-- 23 files changed, 44 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index fc145b3768..aece0cd4f0 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -128,8 +128,8 @@ aaec2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction aaec2000_timer_irq = { .name = "AAEC-2000 Timer Tick", - .flags = SA_INTERRUPT, - .handler = aaec2000_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = aaec2000_timer_interrupt, }; static void __init aaec2000_timer_init(void) diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c index 383d4e0c6e..1a23f0dcd4 100644 --- a/arch/arm/mach-clps711x/time.c +++ b/arch/arm/mach-clps711x/time.c @@ -57,8 +57,8 @@ p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction clps711x_timer_irq = { .name = "CLPS711x Timer Tick", - .flags = SA_INTERRUPT, - .handler = p720t_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = p720t_timer_interrupt, }; static void __init clps711x_timer_init(void) diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index 0bc7da4886..90e85f434f 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -298,8 +298,8 @@ clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction clps7500_timer_irq = { .name = "CLPS7500 Timer Tick", - .flags = SA_INTERRUPT, - .handler = clps7500_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = clps7500_timer_interrupt, }; /* diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index ef362d4494..86ffdbb562 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -173,8 +173,8 @@ ebsa110_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction ebsa110_timer_irq = { .name = "EBSA110 Timer Tick", - .flags = SA_INTERRUPT, - .handler = ebsa110_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = ebsa110_timer_interrupt, }; /* diff --git a/arch/arm/mach-epxa10db/time.c b/arch/arm/mach-epxa10db/time.c index 1b991f3cc3..4b1084dde8 100644 --- a/arch/arm/mach-epxa10db/time.c +++ b/arch/arm/mach-epxa10db/time.c @@ -56,8 +56,8 @@ epxa10db_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction epxa10db_timer_irq = { .name = "Excalibur Timer Tick", - .flags = SA_INTERRUPT, - .handler = epxa10db_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = epxa10db_timer_interrupt, }; /* diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index da5b9b7623..14a62d6008 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c @@ -43,7 +43,7 @@ timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction footbridge_timer_irq = { .name = "Timer1 timer tick", .handler = timer1_interrupt, - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_TIMER, }; /* diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c index a4fefa0bb5..c1d74f7ab6 100644 --- a/arch/arm/mach-footbridge/isa-timer.c +++ b/arch/arm/mach-footbridge/isa-timer.c @@ -72,7 +72,7 @@ isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction isa_timer_irq = { .name = "ISA timer tick", .handler = isa_timer_interrupt, - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_TIMER, }; static void __init isa_timer_init(void) diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c index 743656881e..af9e4a5d5e 100644 --- a/arch/arm/mach-h720x/cpu-h7201.c +++ b/arch/arm/mach-h720x/cpu-h7201.c @@ -41,8 +41,8 @@ h7201_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction h7201_timer_irq = { .name = "h7201 Timer Tick", - .flags = SA_INTERRUPT, - .handler = h7201_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = h7201_timer_interrupt, }; /* diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c index 21b8fb6122..593b6a2a30 100644 --- a/arch/arm/mach-h720x/cpu-h7202.c +++ b/arch/arm/mach-h720x/cpu-h7202.c @@ -171,8 +171,8 @@ static struct irqchip h7202_timerx_chip = { static struct irqaction h7202_timer_irq = { .name = "h7202 Timer Tick", - .flags = SA_INTERRUPT, - .handler = h7202_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = h7202_timer_interrupt, }; /* diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 11f1e56c36..ea805bfa5e 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -72,8 +72,8 @@ imx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction imx_timer_irq = { .name = "i.MX Timer Tick", - .flags = SA_INTERRUPT, - .handler = imx_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = imx_timer_interrupt, }; /* diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index bd1e5e3c9d..9222e57bd8 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -247,8 +247,8 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction integrator_timer_irq = { .name = "Integrator Timer Tick", - .flags = SA_INTERRUPT, - .handler = integrator_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = integrator_timer_interrupt, }; /* diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c index 9b7dd64d1b..d53af16695 100644 --- a/arch/arm/mach-iop3xx/iop321-time.c +++ b/arch/arm/mach-iop3xx/iop321-time.c @@ -86,7 +86,7 @@ iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction iop321_timer_irq = { .name = "IOP321 Timer Tick", .handler = iop321_timer_interrupt, - .flags = SA_INTERRUPT + .flags = SA_INTERRUPT | SA_TIMER, }; static void __init iop321_timer_init(void) diff --git a/arch/arm/mach-iop3xx/iop331-time.c b/arch/arm/mach-iop3xx/iop331-time.c index e016967692..1a6d9d661e 100644 --- a/arch/arm/mach-iop3xx/iop331-time.c +++ b/arch/arm/mach-iop3xx/iop331-time.c @@ -83,7 +83,7 @@ iop331_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction iop331_timer_irq = { .name = "IOP331 Timer Tick", .handler = iop331_timer_interrupt, - .flags = SA_INTERRUPT + .flags = SA_INTERRUPT | SA_TIMER, }; static void __init iop331_timer_init(void) diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index 0ee34acb8d..efd77eee06 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -194,8 +194,8 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction ixp2000_timer_irq = { .name = "IXP2000 Timer Tick", - .flags = SA_INTERRUPT, - .handler = ixp2000_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = ixp2000_timer_interrupt, }; void __init ixp2000_init_time(unsigned long tick_rate) diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index f39e840848..04490a9f8f 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -298,8 +298,8 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs static struct irqaction ixp4xx_timer_irq = { .name = "IXP4xx Timer Tick", - .flags = SA_INTERRUPT, - .handler = ixp4xx_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = ixp4xx_timer_interrupt, }; static void __init ixp4xx_timer_init(void) diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c index 51e1c814b4..be377e331f 100644 --- a/arch/arm/mach-lh7a40x/time.c +++ b/arch/arm/mach-lh7a40x/time.c @@ -53,8 +53,8 @@ lh7a40x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction lh7a40x_timer_irq = { .name = "LHA740x Timer Tick", - .flags = SA_INTERRUPT, - .handler = lh7a40x_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = lh7a40x_timer_interrupt, }; static void __init lh7a40x_timer_init(void) diff --git a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap/time.c index 4205fdcb63..589e8b2740 100644 --- a/arch/arm/mach-omap/time.c +++ b/arch/arm/mach-omap/time.c @@ -188,8 +188,8 @@ static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id, static struct irqaction omap_mpu_timer_irq = { .name = "mpu timer", - .flags = SA_INTERRUPT, - .handler = omap_mpu_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = omap_mpu_timer_interrupt, }; static unsigned long omap_mpu_timer1_overflows; @@ -203,7 +203,7 @@ static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id, static struct irqaction omap_mpu_timer1_irq = { .name = "mpu timer1 overflow", .flags = SA_INTERRUPT, - .handler = omap_mpu_timer1_interrupt + .handler = omap_mpu_timer1_interrupt, }; static __init void omap_init_mpu_timer(void) @@ -349,8 +349,8 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, static struct irqaction omap_32k_timer_irq = { .name = "32KHz timer", - .flags = SA_INTERRUPT, - .handler = omap_32k_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = omap_32k_timer_interrupt, }; static __init void omap_init_32k_timer(void) diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 473fb6173f..6e5202154f 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -105,8 +105,8 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction pxa_timer_irq = { .name = "PXA Timer Tick", - .flags = SA_INTERRUPT, - .handler = pxa_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = pxa_timer_interrupt, }; static void __init pxa_timer_init(void) diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c index 179f0e031a..765a3a9ae0 100644 --- a/arch/arm/mach-s3c2410/time.c +++ b/arch/arm/mach-s3c2410/time.c @@ -137,8 +137,8 @@ s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction s3c2410_timer_irq = { .name = "S3C2410 Timer Tick", - .flags = SA_INTERRUPT, - .handler = s3c2410_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = s3c2410_timer_interrupt, }; /* diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index 84c8654350..65dbe99142 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c @@ -727,7 +727,7 @@ static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc, struct pt_re static struct irqaction h3800_irq = { .name = "h3800_asic", .handler = h3800_IRQ_demux, - .flags = SA_INTERRUPT, + .flags = SA_INTERRUPT | SA_TIMER, }; u32 kpio_int_shadow = 0; diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index 19b0c0fd63..0eeb3616ff 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c @@ -99,8 +99,8 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction sa1100_timer_irq = { .name = "SA11xx Timer Tick", - .flags = SA_INTERRUPT, - .handler = sa1100_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = sa1100_timer_interrupt, }; static void __init sa1100_timer_init(void) diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index a9bc5d0dbd..aa0e2f6e02 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -84,8 +84,8 @@ shark_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static struct irqaction shark_timer_irq = { .name = "Shark Timer Tick", - .flags = SA_INTERRUPT, - .handler = shark_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = shark_timer_interrupt, }; /* diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 6a7cbea5e0..9d1f2253e9 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -875,8 +875,8 @@ static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_re static struct irqaction versatile_timer_irq = { .name = "Versatile Timer Tick", - .flags = SA_INTERRUPT, - .handler = versatile_timer_interrupt + .flags = SA_INTERRUPT | SA_TIMER, + .handler = versatile_timer_interrupt, }; /* -- cgit v1.2.2 From baaf7ed1797de1defce3e3a03f3c9c49cdf3b534 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sun, 26 Jun 2005 22:24:17 +0100 Subject: [PATCH] ARM: 2756/1: add ixp2000 msf mapping Patch from Lennert Buytenhek Add a mapping for the ixp2400 and ixp2800 msf unit. The msf is the ixp2000's 'media and switch fabric' unit, which handles the networking part of the chip. Signed-off-by: Lennert Buytenhek Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-ixp2000/core.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index efd77eee06..4b9d841e04 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -102,6 +102,11 @@ static struct map_desc ixp2000_io_desc[] __initdata = { .physical = IXP2000_PCI_CSR_PHYS_BASE, .length = IXP2000_PCI_CSR_SIZE, .type = MT_DEVICE + }, { + .virtual = IXP2000_MSF_VIRT_BASE, + .physical = IXP2000_MSF_PHYS_BASE, + .length = IXP2000_MSF_SIZE, + .type = MT_DEVICE }, { .virtual = IXP2000_PCI_IO_VIRT_BASE, .physical = IXP2000_PCI_IO_PHYS_BASE, -- cgit v1.2.2 From 26799e675e47c5aa3104628e2081a7299ea46557 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sun, 26 Jun 2005 22:24:19 +0100 Subject: [PATCH] ARM: 2757/1: remove ixdp2400_init_irq from ixdp2800 code Patch from Lennert Buytenhek Compiling one kernel that supports both ixdp2400 and ixdp2800 gives an error, as a copy of the ixdp2400 irq init routing accidentally ended up in ixdp2800.c somehow. Signed-off-by: Lennert Buytenhek Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-ixp2000/ixdp2800.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index aec13c7108..468a4bbfb7 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -42,12 +42,6 @@ #include #include - -void ixdp2400_init_irq(void) -{ - ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2400_NR_IRQS); -} - /************************************************************************* * IXDP2800 timer tick *************************************************************************/ -- cgit v1.2.2 From 99bcc0590806c4f7a4ecf1a11add335b56cde963 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 27 Jun 2005 13:59:43 +0100 Subject: [PATCH] ARM: Add missed AAEC2000 file My scripts missed committing this file. Signed-off-by: Russell King --- arch/arm/mach-aaec2000/Makefile.boot | 1 + 1 file changed, 1 insertion(+) create mode 100644 arch/arm/mach-aaec2000/Makefile.boot (limited to 'arch') diff --git a/arch/arm/mach-aaec2000/Makefile.boot b/arch/arm/mach-aaec2000/Makefile.boot new file mode 100644 index 0000000000..8f5a8b7c53 --- /dev/null +++ b/arch/arm/mach-aaec2000/Makefile.boot @@ -0,0 +1 @@ + zreladdr-y := 0xf0008000 -- cgit v1.2.2 From 2ea83398b75309d8fdc999c4bb252e72d7e4fd9d Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 27 Jun 2005 14:04:05 +0100 Subject: [PATCH] ARM: Add VST idle loop call This call allows the dynamic tick support to reprogram the timer immediately before the CPU idles. Signed-off-by: Russell King --- arch/arm/kernel/process.c | 5 ++++- arch/arm/kernel/time.c | 10 +++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 8f146a4b47..bbea636ff6 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -32,6 +32,7 @@ #include #include #include +#include extern const char *processor_modes[]; extern void setup_mm_for_reboot(char mode); @@ -85,8 +86,10 @@ EXPORT_SYMBOL(pm_power_off); void default_idle(void) { local_irq_disable(); - if (!need_resched() && !hlt_counter) + if (!need_resched() && !hlt_counter) { + timer_dyn_reprogram(); arch_idle(); + } local_irq_enable(); } diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 06054c9ba0..1b7fcd50c3 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -424,15 +424,19 @@ static int timer_dyn_tick_disable(void) return ret; } +/* + * Reprogram the system timer for at least the calculated time interval. + * This function should be called from the idle thread with IRQs disabled, + * immediately before sleeping. + */ void timer_dyn_reprogram(void) { struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; - unsigned long flags; - write_seqlock_irqsave(&xtime_lock, flags); + write_seqlock(&xtime_lock); if (dyn_tick->state & DYN_TICK_ENABLED) dyn_tick->reprogram(next_timer_interrupt() - jiffies); - write_sequnlock_irqrestore(&xtime_lock, flags); + write_sequnlock(&xtime_lock); } static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) -- cgit v1.2.2 From a343e6075a396e07eeff52c0da5629c8fd396be2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 27 Jun 2005 14:08:56 +0100 Subject: [PATCH] ARM: Move PGD kernel page table initialisation It doesn't make sense to have the PGD kernel pointers initialisation separate from the PGD user pointers, especially when we clean the data cache over the whole range. Signed-off-by: Russell King --- arch/arm/mm/mm-armv.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 2c2b93d77d..d79864a0df 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -169,7 +169,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm) memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); + /* + * Copy over the kernel and IO PGD entries + */ init_pgd = pgd_offset_k(0); + memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, + (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); + + clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); if (!vectors_high()) { /* @@ -198,14 +205,6 @@ pgd_t *get_pgd_slow(struct mm_struct *mm) spin_unlock(&mm->page_table_lock); } - /* - * Copy over the kernel and IO PGD entries - */ - memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, - (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); - - clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); - return new_pgd; no_pte: -- cgit v1.2.2 From a013053d4965d9a45300938e713a4b512e0257d8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 27 Jun 2005 14:16:47 +0100 Subject: [PATCH] ARM: Move memmap freeing into init.c It doesn't make sense for this to be in mm-armv.c now that 26-bit ARM support is no longer integrated into arch/arm. Signed-off-by: Russell King --- arch/arm/mm/init.c | 71 +++++++++++++++++++++++++++++++++++++++++++++----- arch/arm/mm/mm-armv.c | 72 --------------------------------------------------- 2 files changed, 65 insertions(+), 78 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index c08710b1ff..6dcb23d64b 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -522,6 +522,69 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s) printk(KERN_INFO "Freeing %s memory: %dK\n", s, size); } +static inline void +free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn) +{ + struct page *start_pg, *end_pg; + unsigned long pg, pgend; + + /* + * Convert start_pfn/end_pfn to a struct page pointer. + */ + start_pg = pfn_to_page(start_pfn); + end_pg = pfn_to_page(end_pfn); + + /* + * Convert to physical addresses, and + * round start upwards and end downwards. + */ + pg = PAGE_ALIGN(__pa(start_pg)); + pgend = __pa(end_pg) & PAGE_MASK; + + /* + * If there are free pages between these, + * free the section of the memmap array. + */ + if (pg < pgend) + free_bootmem_node(NODE_DATA(node), pg, pgend - pg); +} + +/* + * The mem_map array can get very big. Free the unused area of the memory map. + */ +static void __init free_unused_memmap_node(int node, struct meminfo *mi) +{ + unsigned long bank_start, prev_bank_end = 0; + unsigned int i; + + /* + * [FIXME] This relies on each bank being in address order. This + * may not be the case, especially if the user has provided the + * information on the command line. + */ + for (i = 0; i < mi->nr_banks; i++) { + if (mi->bank[i].size == 0 || mi->bank[i].node != node) + continue; + + bank_start = mi->bank[i].start >> PAGE_SHIFT; + if (bank_start < prev_bank_end) { + printk(KERN_ERR "MEM: unordered memory banks. " + "Not freeing memmap.\n"); + break; + } + + /* + * If we had a previous bank, and there is a space + * between the current bank and the previous, free it. + */ + if (prev_bank_end && prev_bank_end != bank_start) + free_memmap(node, prev_bank_end, bank_start); + + prev_bank_end = (mi->bank[i].start + + mi->bank[i].size) >> PAGE_SHIFT; + } +} + /* * mem_init() marks the free areas in the mem_map and tells us how much * memory is free. This is done after various parts of the system have @@ -540,16 +603,12 @@ void __init mem_init(void) max_mapnr = virt_to_page(high_memory) - mem_map; #endif - /* - * We may have non-contiguous memory. - */ - if (meminfo.nr_banks != 1) - create_memmap_holes(&meminfo); - /* this will put all unused low memory onto the freelists */ for_each_online_node(node) { pg_data_t *pgdat = NODE_DATA(node); + free_unused_memmap_node(node, &meminfo); + if (pgdat->node_spanned_pages != 0) totalram_pages += free_all_bootmem_node(pgdat); } diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index d79864a0df..052ab443ec 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -697,75 +697,3 @@ void __init iotable_init(struct map_desc *io_desc, int nr) for (i = 0; i < nr; i++) create_mapping(io_desc + i); } - -static inline void -free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn) -{ - struct page *start_pg, *end_pg; - unsigned long pg, pgend; - - /* - * Convert start_pfn/end_pfn to a struct page pointer. - */ - start_pg = pfn_to_page(start_pfn); - end_pg = pfn_to_page(end_pfn); - - /* - * Convert to physical addresses, and - * round start upwards and end downwards. - */ - pg = PAGE_ALIGN(__pa(start_pg)); - pgend = __pa(end_pg) & PAGE_MASK; - - /* - * If there are free pages between these, - * free the section of the memmap array. - */ - if (pg < pgend) - free_bootmem_node(NODE_DATA(node), pg, pgend - pg); -} - -static inline void free_unused_memmap_node(int node, struct meminfo *mi) -{ - unsigned long bank_start, prev_bank_end = 0; - unsigned int i; - - /* - * [FIXME] This relies on each bank being in address order. This - * may not be the case, especially if the user has provided the - * information on the command line. - */ - for (i = 0; i < mi->nr_banks; i++) { - if (mi->bank[i].size == 0 || mi->bank[i].node != node) - continue; - - bank_start = mi->bank[i].start >> PAGE_SHIFT; - if (bank_start < prev_bank_end) { - printk(KERN_ERR "MEM: unordered memory banks. " - "Not freeing memmap.\n"); - break; - } - - /* - * If we had a previous bank, and there is a space - * between the current bank and the previous, free it. - */ - if (prev_bank_end && prev_bank_end != bank_start) - free_memmap(node, prev_bank_end, bank_start); - - prev_bank_end = PAGE_ALIGN(mi->bank[i].start + - mi->bank[i].size) >> PAGE_SHIFT; - } -} - -/* - * The mem_map array can get very big. Free - * the unused area of the memory map. - */ -void __init create_memmap_holes(struct meminfo *mi) -{ - int node; - - for_each_online_node(node) - free_unused_memmap_node(node, mi); -} -- cgit v1.2.2 From f3bb742640338eca0d8c3fa8071df89168efbf0a Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 27 Jun 2005 14:49:10 +0100 Subject: [PATCH] ARM: Update mach-types Signed-off-by: Russell King --- arch/arm/tools/mach-types | 69 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 30c1dfbb05..6d3a79e5fe 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -6,7 +6,7 @@ # To add an entry into this database, please see Documentation/arm/README, # or contact rmk@arm.linux.org.uk # -# Last update: Thu Mar 24 14:34:50 2005 +# Last update: Thu Jun 23 20:19:33 2005 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -243,7 +243,7 @@ yoho ARCH_YOHO YOHO 231 jasper ARCH_JASPER JASPER 232 dsc25 ARCH_DSC25 DSC25 233 omap_innovator MACH_OMAP_INNOVATOR OMAP_INNOVATOR 234 -ramses ARCH_RAMSES RAMSES 235 +mnci ARCH_RAMSES RAMSES 235 s28x ARCH_S28X S28X 236 mport3 ARCH_MPORT3 MPORT3 237 pxa_eagle250 ARCH_PXA_EAGLE250 PXA_EAGLE250 238 @@ -323,7 +323,7 @@ nimbra29x ARCH_NIMBRA29X NIMBRA29X 311 nimbra210 ARCH_NIMBRA210 NIMBRA210 312 hhp_d95xx ARCH_HHP_D95XX HHP_D95XX 313 labarm ARCH_LABARM LABARM 314 -m825xx ARCH_M825XX M825XX 315 +comcerto ARCH_M825XX M825XX 315 m7100 SA1100_M7100 M7100 316 nipc2 ARCH_NIPC2 NIPC2 317 fu7202 ARCH_FU7202 FU7202 318 @@ -724,3 +724,66 @@ lpc22xx MACH_LPC22XX LPC22XX 715 omap_comet3 MACH_COMET3 COMET3 716 omap_comet4 MACH_COMET4 COMET4 717 csb625 MACH_CSB625 CSB625 718 +fortunet2 MACH_FORTUNET2 FORTUNET2 719 +s5h2200 MACH_S5H2200 S5H2200 720 +optorm920 MACH_OPTORM920 OPTORM920 721 +adsbitsyxb MACH_ADSBITSYXB ADSBITSYXB 722 +adssphere MACH_ADSSPHERE ADSSPHERE 723 +adsportal MACH_ADSPORTAL ADSPORTAL 724 +ln2410sbc MACH_LN2410SBC LN2410SBC 725 +cb3rufc MACH_CB3RUFC CB3RUFC 726 +mp2usb MACH_MP2USB MP2USB 727 +ntnp425c MACH_NTNP425C NTNP425C 728 +colibri MACH_COLIBRI COLIBRI 729 +pcm7220 MACH_PCM7220 PCM7220 730 +gateway7001 MACH_GATEWAY7001 GATEWAY7001 731 +pcm027 MACH_PCM027 PCM027 732 +cmpxa MACH_CMPXA CMPXA 733 +anubis MACH_ANUBIS ANUBIS 734 +ite8152 MACH_ITE8152 ITE8152 735 +lpc3xxx MACH_LPC3XXX LPC3XXX 736 +puppeteer MACH_PUPPETEER PUPPETEER 737 +vt001 MACH_MACH_VADATECH MACH_VADATECH 738 +e570 MACH_E570 E570 739 +x50 MACH_X50 X50 740 +recon MACH_RECON RECON 741 +xboardgp8 MACH_XBOARDGP8 XBOARDGP8 742 +fpic2 MACH_FPIC2 FPIC2 743 +akita MACH_AKITA AKITA 744 +a81 MACH_A81 A81 745 +svm_sc25x MACH_SVM_SC25X SVM_SC25X 746 +vt020 MACH_VADATECH020 VADATECH020 747 +tli MACH_TLI TLI 748 +edb9315lc MACH_EDB9315LC EDB9315LC 749 +passec MACH_PASSEC PASSEC 750 +ds_tiger MACH_DS_TIGER DS_TIGER 751 +e310 MACH_E310 E310 752 +e330 MACH_E330 E330 753 +rt3000 MACH_RT3000 RT3000 754 +nokia770 MACH_NOKIA770 NOKIA770 755 +pnx0106 MACH_PNX0106 PNX0106 756 +hx21xx MACH_HX21XX HX21XX 757 +faraday MACH_FARADAY FARADAY 758 +sbc9312 MACH_SBC9312 SBC9312 759 +batman MACH_BATMAN BATMAN 760 +jpd201 MACH_JPD201 JPD201 761 +mipsa MACH_MIPSA MIPSA 762 +kacom MACH_KACOM KACOM 763 +swarcocpu MACH_SWARCOCPU SWARCOCPU 764 +swarcodsl MACH_SWARCODSL SWARCODSL 765 +blueangel MACH_BLUEANGEL BLUEANGEL 766 +hairygrama MACH_HAIRYGRAMA HAIRYGRAMA 767 +banff MACH_BANFF BANFF 768 +carmeva MACH_CARMEVA CARMEVA 769 +sam255 MACH_SAM255 SAM255 770 +ppm10 MACH_PPM10 PPM10 771 +edb9315a MACH_EDB9315A EDB9315A 772 +sunset MACH_SUNSET SUNSET 773 +stargate2 MACH_STARGATE2 STARGATE2 774 +intelmote2 MACH_INTELMOTE2 INTELMOTE2 775 +trizeps4 MACH_TRIZEPS4 TRIZEPS4 776 +mainstone2 MACH_MAINSTONE2 MAINSTONE2 777 +ez_ixp42x MACH_EZ_IXP42X EZ_IXP42X 778 +tapwave_zodiac MACH_TAPWAVE_ZODIAC TAPWAVE_ZODIAC 779 +universalmeter MACH_UNIVERSALMETER UNIVERSALMETER 780 +hicoarm9 MACH_HICOARM9 HICOARM9 781 -- cgit v1.2.2 From 22e2c507c301c3dbbcf91b4948b88f78842ee6c9 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 27 Jun 2005 10:55:12 +0200 Subject: [PATCH] Update cfq io scheduler to time sliced design This updates the CFQ io scheduler to the new time sliced design (cfq v3). It provides full process fairness, while giving excellent aggregate system throughput even for many competing processes. It supports io priorities, either inherited from the cpu nice value or set directly with the ioprio_get/set syscalls. The latter closely mimic set/getpriority. This import is based on my latest from -mm. Signed-off-by: Jens Axboe Signed-off-by: Linus Torvalds --- arch/i386/kernel/syscall_table.S | 2 ++ arch/ia64/kernel/entry.S | 4 ++-- arch/ppc/kernel/misc.S | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index 442a6e937b..3db9a04aec 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S @@ -289,3 +289,5 @@ ENTRY(sys_call_table) .long sys_add_key .long sys_request_key .long sys_keyctl + .long sys_ioprio_set + .long sys_ioprio_get /* 290 */ diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index b1d5d3d527..785a51b0ad 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1577,8 +1577,8 @@ sys_call_table: data8 sys_add_key data8 sys_request_key data8 sys_keyctl - data8 sys_ni_syscall - data8 sys_ni_syscall // 1275 + data8 sys_ioprio_set + data8 sys_ioprio_get // 1275 data8 sys_set_zone_reclaim data8 sys_ni_syscall data8 sys_ni_syscall diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index b6a63a49a2..191a8def3b 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -1449,3 +1449,5 @@ _GLOBAL(sys_call_table) .long sys_request_key /* 270 */ .long sys_keyctl .long sys_waitid + .long sys_ioprio_set + .long sys_ioprio_get -- cgit v1.2.2 From 313980c92724cf42877a7bdafdef439ee9d68ccb Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 11 Apr 2005 15:38:25 -0700 Subject: [PATCH] USB: omap_udc updates (mostly cleanups) Various USB patches, mostly for portability: - Fifo mode 1 didn't work previously (oopsed), so now it's fixed and (why not) defines even more endpoints for composite devices. - OMAP 1710 doesn't have an internal transceiver. - Small PM update: if the USB link is suspended, don't disconnect on entry to deep sleep. - Be more correct about handling zero length control reads. OMAP seems to mis-handle that protocol peculiarity though; best avoided. - Platform device resources (for UDC and OTG controllers) now use physical addresses, so /proc/iomem is more consistent. - Minor cleanups, notably (by volume) for "sparse" NULL warnings. Signed-off-by: David Brownell --- arch/arm/mach-omap/usb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap/usb.c b/arch/arm/mach-omap/usb.c index 6e805d451d..7f37857b1a 100644 --- a/arch/arm/mach-omap/usb.c +++ b/arch/arm/mach-omap/usb.c @@ -288,8 +288,8 @@ static void usb_release(struct device *dev) static struct resource udc_resources[] = { /* order is significant! */ { /* registers */ - .start = IO_ADDRESS(UDC_BASE), - .end = IO_ADDRESS(UDC_BASE + 0xff), + .start = UDC_BASE, + .end = UDC_BASE + 0xff, .flags = IORESOURCE_MEM, }, { /* general IRQ */ .start = IH2_BASE + 20, @@ -355,8 +355,8 @@ static struct platform_device ohci_device = { static struct resource otg_resources[] = { /* order is significant! */ { - .start = IO_ADDRESS(OTG_BASE), - .end = IO_ADDRESS(OTG_BASE + 0xff), + .start = OTG_BASE, + .end = OTG_BASE + 0xff, .flags = IORESOURCE_MEM, }, { .start = IH2_BASE + 8, -- cgit v1.2.2 From 9c4142a133f7efee08238722b157656c3da7ca97 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 27 Jun 2005 14:36:16 -0700 Subject: [PATCH] ppc32: Fix compiling of sandpoint platform Lost a curly brace in translation. Everything is better now. Signed-off-by: Matt McClintock Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/platforms/sandpoint.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c index 70e58f43f2..8b149c2fc5 100644 --- a/arch/ppc/platforms/sandpoint.c +++ b/arch/ppc/platforms/sandpoint.c @@ -324,6 +324,7 @@ sandpoint_setup_arch(void) pdata[1].irq = 0; pdata[1].mapbase = 0; } + } printk(KERN_INFO "Motorola SPS Sandpoint Test Platform\n"); printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n"); -- cgit v1.2.2 From d4b3a80e399c989028acd5185c792fab82eda035 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Mon, 27 Jun 2005 14:36:30 -0700 Subject: [PATCH] mips: fixed try_to_freeze build error arch/mips/kernel/signal.c: In function 'do_signal': arch/mips/kernel/signal.c:460: error: too many arguments to function 'try_to_freeze' Signed-off-by: Yoichi Yuasa Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/signal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 508026ae58..65ee15396f 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -457,7 +457,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs) if (!user_mode(regs)) return 1; - if (try_to_freeze(0)) + if (try_to_freeze()) goto no_signal; if (!oldset) -- cgit v1.2.2 From bb1657468152c5e5232c7bf35cf0e9c41b5d9910 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Mon, 27 Jun 2005 13:09:00 -0300 Subject: [PATCH] 8xx: avoid "dcbst" misbehaviour with unpopulated TLB The proposed _tlbie call at update_mmu_cache() is safe because: Addresses for which update_mmu_cache() gets invocated are never inside the static kernel virtual mapping, meaning that there is no risk for the _tlbie() here to be thrashing the pinned entry, as Dan suspected. The intermediate TLB state in which this bug can be triggered is not visible by userspace or any other contexts, except the page fault handling path. So there is no need to worry about userspace dcbxxx users. The other solution to this is to avoid dcbst misbehaviour in the first place, which involves changing in-kernel "dcbst" callers to use 8xx specific SPR's. Summary: On 8xx, cache control instructions (particularly "dcbst" from flush_dcache_icache) fault as write operation if there is an unpopulated TLB entry for the address in question. To workaround that, we invalidate the TLB here, thus avoiding dcbst misbehaviour. Signed-off-by: Marcelo Tosatti Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/mm/init.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 334ef4150d..6164a2b347 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -606,9 +606,19 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, struct page *page = pfn_to_page(pfn); if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) { - if (vma->vm_mm == current->active_mm) + if (vma->vm_mm == current->active_mm) { +#ifdef CONFIG_8xx + /* On 8xx, cache control instructions (particularly + * "dcbst" from flush_dcache_icache) fault as write + * operation if there is an unpopulated TLB entry + * for the address in question. To workaround that, + * we invalidate the TLB here, thus avoiding dcbst + * misbehaviour. + */ + _tlbie(address); +#endif __flush_dcache_icache((void *) address); - else + } else flush_dcache_icache_page(page); set_bit(PG_arch_1, &page->flags); } -- cgit v1.2.2 From e4ee69c8c1e7ff9790fbce29c7be50db57323a6f Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 27 Jun 2005 14:36:32 -0700 Subject: [PATCH] ppc32: Bump PMU interrupt priority The Power Management Unit on PowerMacs is very sensitive to timeouts during async message exchanges. It uses rather crude protocol based on a shift register with an interrupt and is almost continuously exchanging messages with the host CPU on laptops. This patch adds a routine to the open_pic driver to be able to select a PMU driver so that it bumps it's interrupt priority to above the normal level. This will allow PMU interrupts to occur while another interrupt is pending, and thus reduce the risk of machine beeing abruptly shutdown by the PMU due to a timeout in PMU communication caused by excessive interrupt latency. The problem is very rare, and usually just doesn't happen, but it is still useful to make things even more robust. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/syslib/open_pic.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index b45d8268bf..ad39b86ca9 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c @@ -370,8 +370,9 @@ void __init openpic_init(int offset) /* Initialize IPI interrupts */ if ( ppc_md.progress ) ppc_md.progress("openpic: ipi",0x3bb); for (i = 0; i < OPENPIC_NUM_IPI; i++) { - /* Disabled, Priority 10..13 */ - openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+offset); + /* Disabled, increased priorities 10..13 */ + openpic_initipi(i, OPENPIC_PRIORITY_IPI_BASE+i, + OPENPIC_VEC_IPI+i+offset); /* IPIs are per-CPU */ irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU; irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi; @@ -399,8 +400,9 @@ void __init openpic_init(int offset) if (sense & IRQ_SENSE_MASK) irq_desc[i+offset].status = IRQ_LEVEL; - /* Enabled, Priority 8 */ - openpic_initirq(i, 8, i+offset, (sense & IRQ_POLARITY_MASK), + /* Enabled, Default priority */ + openpic_initirq(i, OPENPIC_PRIORITY_DEFAULT, i+offset, + (sense & IRQ_POLARITY_MASK), (sense & IRQ_SENSE_MASK)); /* Processor 0 */ openpic_mapirq(i, CPU_MASK_CPU0, CPU_MASK_NONE); @@ -655,6 +657,18 @@ static void __init openpic_maptimer(u_int timer, cpumask_t cpumask) cpus_addr(phys)[0]); } +/* + * Change the priority of an interrupt + */ +void __init +openpic_set_irq_priority(u_int irq, u_int pri) +{ + check_arg_irq(irq); + openpic_safe_writefield(&ISR[irq - open_pic_irq_offset]->Vector_Priority, + OPENPIC_PRIORITY_MASK, + pri << OPENPIC_PRIORITY_SHIFT); +} + /* * Initalize the interrupt source which will generate an NMI. * This raises the interrupt's priority from 8 to 9. @@ -665,9 +679,7 @@ void __init openpic_init_nmi_irq(u_int irq) { check_arg_irq(irq); - openpic_safe_writefield(&ISR[irq - open_pic_irq_offset]->Vector_Priority, - OPENPIC_PRIORITY_MASK, - 9 << OPENPIC_PRIORITY_SHIFT); + openpic_set_irq_priority(irq, OPENPIC_PRIORITY_NMI); } /* -- cgit v1.2.2 From 8c8709334cec803368a432a33e0f2e116d48fe07 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 27 Jun 2005 14:36:34 -0700 Subject: [PATCH] ppc32: Remove CONFIG_PMAC_PBOOK This patch removes CONFIG_PMAC_PBOOK (PowerBook support). This is now split into CONFIG_PMAC_MEDIABAY for the actual hotswap bay that some powerbooks have, CONFIG_PM for power management related code, and just left out of any CONFIG_* option for some generally useful stuff that can be used on non-laptops as well. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/platforms/pmac_sleep.S | 4 ++-- arch/ppc/platforms/pmac_time.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S index f459ade1bd..016a746491 100644 --- a/arch/ppc/platforms/pmac_sleep.S +++ b/arch/ppc/platforms/pmac_sleep.S @@ -46,7 +46,7 @@ .section .text .align 5 -#if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ_PMAC) +#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) /* This gets called by via-pmu.c late during the sleep process. * The PMU was already send the sleep command and will shut us down @@ -382,7 +382,7 @@ turn_on_mmu: isync rfi -#endif /* defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ) */ +#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */ .section .data .balign L1_CACHE_LINE_SIZE diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c index de60ccc7db..778ce4fec3 100644 --- a/arch/ppc/platforms/pmac_time.c +++ b/arch/ppc/platforms/pmac_time.c @@ -206,7 +206,7 @@ via_calibrate_decr(void) return 1; } -#ifdef CONFIG_PMAC_PBOOK +#ifdef CONFIG_PM /* * Reset the time after a sleep. */ @@ -238,7 +238,7 @@ time_sleep_notify(struct pmu_sleep_notifier *self, int when) static struct pmu_sleep_notifier time_sleep_notifier __pmacdata = { time_sleep_notify, SLEEP_LEVEL_MISC, }; -#endif /* CONFIG_PMAC_PBOOK */ +#endif /* CONFIG_PM */ /* * Query the OF and get the decr frequency. @@ -251,9 +251,9 @@ pmac_calibrate_decr(void) struct device_node *cpu; unsigned int freq, *fp; -#ifdef CONFIG_PMAC_PBOOK +#ifdef CONFIG_PM pmu_register_sleep_notifier(&time_sleep_notifier); -#endif /* CONFIG_PMAC_PBOOK */ +#endif /* CONFIG_PM */ /* We assume MacRISC2 machines have correct device-tree * calibration. That's better since the VIA itself seems -- cgit v1.2.2 From 6ae3db110e62b0846aae1b5c6e661484ee3a5ed1 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 27 Jun 2005 14:36:35 -0700 Subject: [PATCH] ppc64: Add missing exports This patch adds a couple of missing symbol exports. flush_dcache_page is used by the AGP driver and rtc_lock by the RTC driver. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/ppc_ksyms.c | 1 + arch/ppc64/kernel/time.c | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c index b230a63fe4..705742f4ee 100644 --- a/arch/ppc64/kernel/ppc_ksyms.c +++ b/arch/ppc64/kernel/ppc_ksyms.c @@ -75,6 +75,7 @@ EXPORT_SYMBOL(giveup_fpu); EXPORT_SYMBOL(giveup_altivec); #endif EXPORT_SYMBOL(__flush_icache_range); +EXPORT_SYMBOL(flush_dcache_range); #ifdef CONFIG_SMP #ifdef CONFIG_PPC_ISERIES diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 2348a75e05..2a532db913 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -91,6 +91,7 @@ unsigned long tb_to_xs; unsigned tb_to_us; unsigned long processor_freq; DEFINE_SPINLOCK(rtc_lock); +EXPORT_SYMBOL_GPL(rtc_lock); unsigned long tb_to_ns_scale; unsigned long tb_to_ns_shift; -- cgit v1.2.2 From ffaa8bd6c904d1ab79b677905067349a5ff51d84 Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Mon, 27 Jun 2005 14:36:36 -0700 Subject: [PATCH] seccomp: tsc disable I believe at least for seccomp it's worth to turn off the tsc, not just for HT but for the L2 cache too. So it's up to you, either you turn it off completely (which isn't very nice IMHO) or I recommend to apply this below patch. This has been tested successfully on x86-64 against current cogito repository (i686 compiles so I didn't bother testing ;). People selling the cpu through cpushare may appreciate this bit for a peace of mind. There's no way to get any timing info anymore with this applied (gettimeofday is forbidden of course). The seccomp environment is completely deterministic so it can't be allowed to get timing info, it has to be deterministic so in the future I can enable a computing mode that does a parallel computing for each task with server side transparent checkpointing and verification that the output is the same from all the 2/3 seller computers for each task, without the buyer even noticing (for now the verification is left to the buyer client side and there's no checkpointing, since that would require more kernel changes to track the dirty bits but it'll be easy to extend once the basic mode is finished). Eliminating a cold-cache read of the cr4 global variable will save one cacheline during the tlb flush while making the code per-cpu-safe at the same time. Thanks to Mikael Pettersson for noticing the tlb flush wasn't per-cpu-safe. The global tlb flush can run from irq (IPI calling do_flush_tlb_all) but it'll be transparent to the switch_to code since the IPI won't make any change to the cr4 contents from the point of view of the interrupted code and since it's now all per-cpu stuff, it will not race. So no need to disable irqs in switch_to slow path. Signed-off-by: Andrea Arcangeli Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/process.c | 29 +++++++++++++++++++++++++++++ arch/x86_64/kernel/process.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 5f8cfa6b79..ba243a4cc1 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -616,6 +616,33 @@ handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss) tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; } +/* + * This function selects if the context switch from prev to next + * has to tweak the TSC disable bit in the cr4. + */ +static inline void disable_tsc(struct task_struct *prev_p, + struct task_struct *next_p) +{ + struct thread_info *prev, *next; + + /* + * gcc should eliminate the ->thread_info dereference if + * has_secure_computing returns 0 at compile time (SECCOMP=n). + */ + prev = prev_p->thread_info; + next = next_p->thread_info; + + if (has_secure_computing(prev) || has_secure_computing(next)) { + /* slow path here */ + if (has_secure_computing(prev) && + !has_secure_computing(next)) { + write_cr4(read_cr4() & ~X86_CR4_TSD); + } else if (!has_secure_computing(prev) && + has_secure_computing(next)) + write_cr4(read_cr4() | X86_CR4_TSD); + } +} + /* * switch_to(x,yn) should switch tasks from x to y. * @@ -695,6 +722,8 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) handle_io_bitmap(next, tss); + disable_tsc(prev_p, next_p); + return prev_p; } diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 1d91271796..7577f9d7a7 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -481,6 +481,33 @@ out: return err; } +/* + * This function selects if the context switch from prev to next + * has to tweak the TSC disable bit in the cr4. + */ +static inline void disable_tsc(struct task_struct *prev_p, + struct task_struct *next_p) +{ + struct thread_info *prev, *next; + + /* + * gcc should eliminate the ->thread_info dereference if + * has_secure_computing returns 0 at compile time (SECCOMP=n). + */ + prev = prev_p->thread_info; + next = next_p->thread_info; + + if (has_secure_computing(prev) || has_secure_computing(next)) { + /* slow path here */ + if (has_secure_computing(prev) && + !has_secure_computing(next)) { + write_cr4(read_cr4() & ~X86_CR4_TSD); + } else if (!has_secure_computing(prev) && + has_secure_computing(next)) + write_cr4(read_cr4() | X86_CR4_TSD); + } +} + /* * This special macro can be used to load a debugging register */ @@ -599,6 +626,8 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct * } } + disable_tsc(prev_p, next_p); + return prev_p; } -- cgit v1.2.2 From 9ec4b1f356b3bad928ae8e2aa9caebfa737d52df Mon Sep 17 00:00:00 2001 From: Ananth N Mavinakayanahalli Date: Mon, 27 Jun 2005 15:17:01 -0700 Subject: [PATCH] kprobes: fix single-step out of line - take2 Now that PPC64 has no-execute support, here is a second try to fix the single step out of line during kprobe execution. Kprobes on x86_64 already solved this problem by allocating an executable page and using it as the scratch area for stepping out of line. Reuse that. Signed-off-by: Ananth N Mavinakayanahalli Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/kprobes.c | 26 ++++++++-- arch/x86_64/kernel/kprobes.c | 113 +------------------------------------------ 2 files changed, 23 insertions(+), 116 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 782ce3efa2..86cc5496db 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -36,6 +36,8 @@ #include #include +static DECLARE_MUTEX(kprobe_mutex); + static struct kprobe *current_kprobe; static unsigned long kprobe_status, kprobe_saved_msr; static struct kprobe *kprobe_prev; @@ -54,6 +56,15 @@ int arch_prepare_kprobe(struct kprobe *p) printk("Cannot register a kprobe on rfid or mtmsrd\n"); ret = -EINVAL; } + + /* insn must be on a special executable page on ppc64 */ + if (!ret) { + up(&kprobe_mutex); + p->ainsn.insn = get_insn_slot(); + down(&kprobe_mutex); + if (!p->ainsn.insn) + ret = -ENOMEM; + } return ret; } @@ -79,16 +90,22 @@ void arch_disarm_kprobe(struct kprobe *p) void arch_remove_kprobe(struct kprobe *p) { + up(&kprobe_mutex); + free_insn_slot(p->ainsn.insn); + down(&kprobe_mutex); } static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) { + kprobe_opcode_t insn = *p->ainsn.insn; + regs->msr |= MSR_SE; - /*single step inline if it a breakpoint instruction*/ - if (p->opcode == BREAKPOINT_INSTRUCTION) + + /* single step inline if it is a trap variant */ + if (IS_TW(insn) || IS_TD(insn) || IS_TWI(insn) || IS_TDI(insn)) regs->nip = (unsigned long)p->addr; else - regs->nip = (unsigned long)&p->ainsn.insn; + regs->nip = (unsigned long)p->ainsn.insn; } static inline void save_previous_kprobe(void) @@ -205,9 +222,10 @@ no_kprobe: static void resume_execution(struct kprobe *p, struct pt_regs *regs) { int ret; + unsigned int insn = *p->ainsn.insn; regs->nip = (unsigned long)p->addr; - ret = emulate_step(regs, p->ainsn.insn[0]); + ret = emulate_step(regs, insn); if (ret == 0) regs->nip = (unsigned long)p->addr + 4; } diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index 4e680f87a7..6a1c88376b 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c @@ -38,7 +38,7 @@ #include #include #include -#include + #include #include #include @@ -51,8 +51,6 @@ static struct kprobe *kprobe_prev; static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev; static struct pt_regs jprobe_saved_regs; static long *jprobe_saved_rsp; -static kprobe_opcode_t *get_insn_slot(void); -static void free_insn_slot(kprobe_opcode_t *slot); void jprobe_return_end(void); /* copy of the kernel stack at the probe fire time */ @@ -681,112 +679,3 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) } return 0; } - -/* - * kprobe->ainsn.insn points to the copy of the instruction to be single-stepped. - * By default on x86_64, pages we get from kmalloc or vmalloc are not - * executable. Single-stepping an instruction on such a page yields an - * oops. So instead of storing the instruction copies in their respective - * kprobe objects, we allocate a page, map it executable, and store all the - * instruction copies there. (We can allocate additional pages if somebody - * inserts a huge number of probes.) Each page can hold up to INSNS_PER_PAGE - * instruction slots, each of which is MAX_INSN_SIZE*sizeof(kprobe_opcode_t) - * bytes. - */ -#define INSNS_PER_PAGE (PAGE_SIZE/(MAX_INSN_SIZE*sizeof(kprobe_opcode_t))) -struct kprobe_insn_page { - struct hlist_node hlist; - kprobe_opcode_t *insns; /* page of instruction slots */ - char slot_used[INSNS_PER_PAGE]; - int nused; -}; - -static struct hlist_head kprobe_insn_pages; - -/** - * get_insn_slot() - Find a slot on an executable page for an instruction. - * We allocate an executable page if there's no room on existing ones. - */ -static kprobe_opcode_t *get_insn_slot(void) -{ - struct kprobe_insn_page *kip; - struct hlist_node *pos; - - hlist_for_each(pos, &kprobe_insn_pages) { - kip = hlist_entry(pos, struct kprobe_insn_page, hlist); - if (kip->nused < INSNS_PER_PAGE) { - int i; - for (i = 0; i < INSNS_PER_PAGE; i++) { - if (!kip->slot_used[i]) { - kip->slot_used[i] = 1; - kip->nused++; - return kip->insns + (i*MAX_INSN_SIZE); - } - } - /* Surprise! No unused slots. Fix kip->nused. */ - kip->nused = INSNS_PER_PAGE; - } - } - - /* All out of space. Need to allocate a new page. Use slot 0.*/ - kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_KERNEL); - if (!kip) { - return NULL; - } - - /* - * For the %rip-relative displacement fixups to be doable, we - * need our instruction copy to be within +/- 2GB of any data it - * might access via %rip. That is, within 2GB of where the - * kernel image and loaded module images reside. So we allocate - * a page in the module loading area. - */ - kip->insns = module_alloc(PAGE_SIZE); - if (!kip->insns) { - kfree(kip); - return NULL; - } - INIT_HLIST_NODE(&kip->hlist); - hlist_add_head(&kip->hlist, &kprobe_insn_pages); - memset(kip->slot_used, 0, INSNS_PER_PAGE); - kip->slot_used[0] = 1; - kip->nused = 1; - return kip->insns; -} - -/** - * free_insn_slot() - Free instruction slot obtained from get_insn_slot(). - */ -static void free_insn_slot(kprobe_opcode_t *slot) -{ - struct kprobe_insn_page *kip; - struct hlist_node *pos; - - hlist_for_each(pos, &kprobe_insn_pages) { - kip = hlist_entry(pos, struct kprobe_insn_page, hlist); - if (kip->insns <= slot - && slot < kip->insns+(INSNS_PER_PAGE*MAX_INSN_SIZE)) { - int i = (slot - kip->insns) / MAX_INSN_SIZE; - kip->slot_used[i] = 0; - kip->nused--; - if (kip->nused == 0) { - /* - * Page is no longer in use. Free it unless - * it's the last one. We keep the last one - * so as not to have to set it up again the - * next time somebody inserts a probe. - */ - hlist_del(&kip->hlist); - if (hlist_empty(&kprobe_insn_pages)) { - INIT_HLIST_NODE(&kip->hlist); - hlist_add_head(&kip->hlist, - &kprobe_insn_pages); - } else { - module_free(NULL, kip->insns); - kfree(kip); - } - } - return; - } - } -} -- cgit v1.2.2 From 4bdbd37f6d01abc4c002bb8de90ea2c3bc7abe7e Mon Sep 17 00:00:00 2001 From: Rusty Lynch Date: Mon, 27 Jun 2005 15:17:09 -0700 Subject: [PATCH] Return probe redesign: i386 specific changes The following patch contains the i386 specific changes for the new return probe design. Changes include: * Removing the architecture specific functions for querying a return probe instance off a stack address * Complete rework onf arch_prepare_kretprobe() and trampoline_probe_handler() * Removing trampoline_post_handler() * Adding arch_init() so that now we handle registering the return probe trampoline instead of kernel/kprobes.c doing it Signed-off-by: Rusty Lynch Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/kprobes.c | 133 ++++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 63 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 3762f6b35a..fc8b175217 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -127,48 +127,23 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) regs->eip = (unsigned long)&p->ainsn.insn; } -struct task_struct *arch_get_kprobe_task(void *ptr) -{ - return ((struct thread_info *) (((unsigned long) ptr) & - (~(THREAD_SIZE -1))))->task; -} - void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)®s->esp; - struct kretprobe_instance *ri; - static void *orig_ret_addr; + struct kretprobe_instance *ri; + + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *) *sara; - /* - * Save the return address when the return probe hits - * the first time, and use it to populate the (krprobe - * instance)->ret_addr for subsequent return probes at - * the same addrress since stack address would have - * the kretprobe_trampoline by then. - */ - if (((void*) *sara) != kretprobe_trampoline) - orig_ret_addr = (void*) *sara; - - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->stack_addr = sara; - ri->ret_addr = orig_ret_addr; - add_rp_inst(ri); /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; - } else { - rp->nmissed++; - } -} -void arch_kprobe_flush_task(struct task_struct *tk) -{ - struct kretprobe_instance *ri; - while ((ri = get_rp_inst_tsk(tk)) != NULL) { - *((unsigned long *)(ri->stack_addr)) = - (unsigned long) ri->ret_addr; - recycle_rp_inst(ri); - } + add_rp_inst(ri); + } else { + rp->nmissed++; + } } /* @@ -286,36 +261,59 @@ no_kprobe: */ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct task_struct *tsk; - struct kretprobe_instance *ri; - struct hlist_head *head; - struct hlist_node *node; - unsigned long *sara = ((unsigned long *) ®s->esp) - 1; - - tsk = arch_get_kprobe_task(sara); - head = kretprobe_inst_table_head(tsk); - - hlist_for_each_entry(ri, node, head, hlist) { - if (ri->stack_addr == sara && ri->rp) { - if (ri->rp->handler) - ri->rp->handler(ri, regs); - } - } - return 0; -} + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; + unsigned long orig_ret_address = 0; + unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; -void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs, - unsigned long flags) -{ - struct kretprobe_instance *ri; - /* RA already popped */ - unsigned long *sara = ((unsigned long *)®s->esp) - 1; + head = kretprobe_inst_table_head(current); - while ((ri = get_rp_inst(sara))) { - regs->eip = (unsigned long)ri->ret_addr; + /* + * It is possible to have multiple instances associated with a given + * task either because an multiple functions in the call path + * have a return probe installed on them, and/or more then one return + * return probe was registered for a target function. + * + * We can handle this because: + * - instances are always inserted at the head of the list + * - when multiple return probes are registered for the same + * function, the first instance's ret_addr will point to the + * real return address, and all the rest will point to + * kretprobe_trampoline + */ + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + if (ri->rp && ri->rp->handler) + ri->rp->handler(ri, regs); + + orig_ret_address = (unsigned long)ri->ret_addr; recycle_rp_inst(ri); + + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; } - regs->eflags &= ~TF_MASK; + + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); + regs->eip = orig_ret_address; + + unlock_kprobes(); + preempt_enable_no_resched(); + + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we have handled unlocking + * and re-enabling preemption. + */ + return 1; } /* @@ -403,8 +401,7 @@ static inline int post_kprobe_handler(struct pt_regs *regs) current_kprobe->post_handler(current_kprobe, regs, 0); } - if (current_kprobe->post_handler != trampoline_post_handler) - resume_execution(current_kprobe, regs); + resume_execution(current_kprobe, regs); regs->eflags |= kprobe_saved_eflags; /*Restore back the original saved kprobes variables and continue. */ @@ -534,3 +531,13 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) } return 0; } + +static struct kprobe trampoline_p = { + .addr = (kprobe_opcode_t *) &kretprobe_trampoline, + .pre_handler = trampoline_probe_handler +}; + +int __init arch_init(void) +{ + return register_kprobe(&trampoline_p); +} -- cgit v1.2.2 From ba8af12f432c4f00ddb0bc1068b57b20aac93ecf Mon Sep 17 00:00:00 2001 From: Rusty Lynch Date: Mon, 27 Jun 2005 15:17:10 -0700 Subject: [PATCH] Return probe redesign: x86_64 specific changes The following patch contains the x86_64 specific changes for the new return probe design. Changes include: * Removing the architecture specific functions for querying a return probe instance off a stack address * Complete rework onf arch_prepare_kretprobe() and trampoline_probe_handler() * Removing trampoline_post_handler() * Adding arch_init() so that now we handle registering the return probe trampoline instead of kernel/kprobes.c doing it NOTE: Note that with this new design, the dependency on calculating a pointer to the task off the stack pointer no longer exist (resolving the problem of interruption stacks as pointed out in the original feedback to this port.) Signed-off-by: Rusty Lynch Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/kprobes.c | 133 +++++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 63 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index 6a1c88376b..acd2a778eb 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c @@ -272,48 +272,23 @@ static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) regs->rip = (unsigned long)p->ainsn.insn; } -struct task_struct *arch_get_kprobe_task(void *ptr) -{ - return ((struct thread_info *) (((unsigned long) ptr) & - (~(THREAD_SIZE -1))))->task; -} - void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)regs->rsp; - struct kretprobe_instance *ri; - static void *orig_ret_addr; + struct kretprobe_instance *ri; + + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *) *sara; - /* - * Save the return address when the return probe hits - * the first time, and use it to populate the (krprobe - * instance)->ret_addr for subsequent return probes at - * the same addrress since stack address would have - * the kretprobe_trampoline by then. - */ - if (((void*) *sara) != kretprobe_trampoline) - orig_ret_addr = (void*) *sara; - - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->stack_addr = sara; - ri->ret_addr = orig_ret_addr; - add_rp_inst(ri); /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; - } else { - rp->nmissed++; - } -} -void arch_kprobe_flush_task(struct task_struct *tk) -{ - struct kretprobe_instance *ri; - while ((ri = get_rp_inst_tsk(tk)) != NULL) { - *((unsigned long *)(ri->stack_addr)) = - (unsigned long) ri->ret_addr; - recycle_rp_inst(ri); - } + add_rp_inst(ri); + } else { + rp->nmissed++; + } } /* @@ -426,36 +401,59 @@ no_kprobe: */ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct task_struct *tsk; - struct kretprobe_instance *ri; - struct hlist_head *head; - struct hlist_node *node; - unsigned long *sara = (unsigned long *)regs->rsp - 1; - - tsk = arch_get_kprobe_task(sara); - head = kretprobe_inst_table_head(tsk); - - hlist_for_each_entry(ri, node, head, hlist) { - if (ri->stack_addr == sara && ri->rp) { - if (ri->rp->handler) - ri->rp->handler(ri, regs); - } - } - return 0; -} + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; + unsigned long orig_ret_address = 0; + unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; -void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs, - unsigned long flags) -{ - struct kretprobe_instance *ri; - /* RA already popped */ - unsigned long *sara = ((unsigned long *)regs->rsp) - 1; + head = kretprobe_inst_table_head(current); - while ((ri = get_rp_inst(sara))) { - regs->rip = (unsigned long)ri->ret_addr; + /* + * It is possible to have multiple instances associated with a given + * task either because an multiple functions in the call path + * have a return probe installed on them, and/or more then one return + * return probe was registered for a target function. + * + * We can handle this because: + * - instances are always inserted at the head of the list + * - when multiple return probes are registered for the same + * function, the first instance's ret_addr will point to the + * real return address, and all the rest will point to + * kretprobe_trampoline + */ + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + if (ri->rp && ri->rp->handler) + ri->rp->handler(ri, regs); + + orig_ret_address = (unsigned long)ri->ret_addr; recycle_rp_inst(ri); + + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; } - regs->eflags &= ~TF_MASK; + + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); + regs->rip = orig_ret_address; + + unlock_kprobes(); + preempt_enable_no_resched(); + + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we have handled unlocking + * and re-enabling preemption. + */ + return 1; } /* @@ -548,8 +546,7 @@ int post_kprobe_handler(struct pt_regs *regs) current_kprobe->post_handler(current_kprobe, regs, 0); } - if (current_kprobe->post_handler != trampoline_post_handler) - resume_execution(current_kprobe, regs); + resume_execution(current_kprobe, regs); regs->eflags |= kprobe_saved_rflags; /* Restore the original saved kprobes variables and continue. */ @@ -679,3 +676,13 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) } return 0; } + +static struct kprobe trampoline_p = { + .addr = (kprobe_opcode_t *) &kretprobe_trampoline, + .pre_handler = trampoline_probe_handler +}; + +int __init arch_init(void) +{ + return register_kprobe(&trampoline_p); +} -- cgit v1.2.2 From 9508dbfe39112813612085c00d55bacd398eddc6 Mon Sep 17 00:00:00 2001 From: Rusty Lynch Date: Mon, 27 Jun 2005 15:17:12 -0700 Subject: [PATCH] Return probe redesign: ia64 specific implementation The following patch implements function return probes for ia64 using the revised design. With this new design we no longer need to do some of the odd hacks previous required on the last ia64 return probe port that I sent out for comments. Note that this new implementation still does not resolve the problem noted by Keith Owens where backtrace data is lost after a return probe is hit. Changes include: * Addition of kretprobe_trampoline to act as a dummy function for instrumented functions to return to, and for the return probe infrastructure to place a kprobe on on, gaining control so that the return probe handler can be called, and so that the instruction pointer can be moved back to the original return address. * Addition of arch_init(), allowing a kprobe to be registered on kretprobe_trampoline * Addition of trampoline_probe_handler() which is used as the pre_handler for the kprobe inserted on kretprobe_implementation. This is the function that handles the details for calling the return probe handler function and returning control back at the original return address * Addition of arch_prepare_kretprobe() which is setup as the pre_handler for a kprobe registered at the beginning of the target function by kernel/kprobes.c so that a return probe instance can be setup when a caller enters the target function. (A return probe instance contains all the needed information for trampoline_probe_handler to do it's job.) * Hooks added to the exit path of a task so that we can cleanup any left-over return probe instances (i.e. if a task dies while inside a targeted function then the return probe instance was reserved at the beginning of the function but the function never returns so we need to mark the instance as unused.) Signed-off-by: Rusty Lynch Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/kernel/kprobes.c | 103 ++++++++++++++++++++++++++++++++++++++++++++- arch/ia64/kernel/process.c | 16 +++++++ 2 files changed, 117 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 5978823d5c..c97e18e634 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -290,6 +290,94 @@ static inline void set_current_kprobe(struct kprobe *p) current_kprobe = p; } +static void kretprobe_trampoline(void) +{ +} + +/* + * At this point the target function has been tricked into + * returning into our trampoline. Lookup the associated instance + * and then: + * - call the handler function + * - cleanup by marking the instance as unused + * - long jump back to the original return address + */ +int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) +{ + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; + unsigned long orig_ret_address = 0; + unsigned long trampoline_address = + ((struct fnptr *)kretprobe_trampoline)->ip; + + head = kretprobe_inst_table_head(current); + + /* + * It is possible to have multiple instances associated with a given + * task either because an multiple functions in the call path + * have a return probe installed on them, and/or more then one return + * return probe was registered for a target function. + * + * We can handle this because: + * - instances are always inserted at the head of the list + * - when multiple return probes are registered for the same + * function, the first instance's ret_addr will point to the + * real return address, and all the rest will point to + * kretprobe_trampoline + */ + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + if (ri->rp && ri->rp->handler) + ri->rp->handler(ri, regs); + + orig_ret_address = (unsigned long)ri->ret_addr; + recycle_rp_inst(ri); + + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; + } + + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); + regs->cr_iip = orig_ret_address; + + unlock_kprobes(); + preempt_enable_no_resched(); + + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we have handled unlocking + * and re-enabling preemption. + */ + return 1; +} + +void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) +{ + struct kretprobe_instance *ri; + + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *)regs->b0; + + /* Replace the return addr with trampoline addr */ + regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip; + + add_rp_inst(ri); + } else { + rp->nmissed++; + } +} + int arch_prepare_kprobe(struct kprobe *p) { unsigned long addr = (unsigned long) p->addr; @@ -492,8 +580,8 @@ static int pre_kprobes_handler(struct die_args *args) if (p->pre_handler && p->pre_handler(p, regs)) /* * Our pre-handler is specifically requesting that we just - * do a return. This is handling the case where the - * pre-handler is really our special jprobe pre-handler. + * do a return. This is used for both the jprobe pre-handler + * and the kretprobe trampoline */ return 1; @@ -599,3 +687,14 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) *regs = jprobe_saved_regs; return 1; } + +static struct kprobe trampoline_p = { + .pre_handler = trampoline_probe_handler +}; + +int __init arch_init(void) +{ + trampoline_p.addr = + (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip; + return register_kprobe(&trampoline_p); +} diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index ebb71f3d6d..6e35bff05d 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -707,6 +708,13 @@ kernel_thread_helper (int (*fn)(void *), void *arg) void flush_thread (void) { + /* + * Remove function-return probe instances associated with this task + * and put them back on the free list. Do not insert an exit probe for + * this function, it will be disabled by kprobe_flush_task if you do. + */ + kprobe_flush_task(current); + /* drop floating-point and debug-register state if it exists: */ current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID); ia64_drop_fpu(current); @@ -721,6 +729,14 @@ flush_thread (void) void exit_thread (void) { + + /* + * Remove function-return probe instances associated with this task + * and put them back on the free list. Do not insert an exit probe for + * this function, it will be disabled by kprobe_flush_task if you do. + */ + kprobe_flush_task(current); + ia64_drop_fpu(current); #ifdef CONFIG_PERFMON /* if needed, stop monitoring and flush state to perfmon context */ -- cgit v1.2.2 From 97f7943d70ff0e1e92ea627c44cfacfdae65dbc4 Mon Sep 17 00:00:00 2001 From: Rusty Lynch Date: Mon, 27 Jun 2005 15:17:15 -0700 Subject: [PATCH] Return probe redesign: ppc64 specific implementation The following is a patch provided by Ananth Mavinakayanahalli that implements the new PPC64 specific parts of the new function return probe design. NOTE: Since getting Ananth's patch, I changed trampoline_probe_handler() to consume each of the outstanding return probem instances (feedback on my original RFC after Ananth cut a patch), and also added the arch_init() function (adding arch specific initialization.) I have cross compiled but have not testing this on a PPC64 machine. Changes include: * Addition of kretprobe_trampoline to act as a dummy function for instrumented functions to return to, and for the return probe infrastructure to place a kprobe on on, gaining control so that the return probe handler can be called, and so that the instruction pointer can be moved back to the original return address. * Addition of arch_init(), allowing a kprobe to be registered on kretprobe_trampoline * Addition of trampoline_probe_handler() which is used as the pre_handler for the kprobe inserted on kretprobe_implementation. This is the function that handles the details for calling the return probe handler function and returning control back at the original return address * Addition of arch_prepare_kretprobe() which is setup as the pre_handler for a kprobe registered at the beginning of the target function by kernel/kprobes.c so that a return probe instance can be setup when a caller enters the target function. (A return probe instance contains all the needed information for trampoline_probe_handler to do it's job.) * Hooks added to the exit path of a task so that we can cleanup any left-over return probe instances (i.e. if a task dies while inside a targeted function then the return probe instance was reserved at the beginning of the function but the function never returns so we need to mark the instance as unused.) Signed-off-by: Rusty Lynch Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/kprobes.c | 99 +++++++++++++++++++++++++++++++++++++++++++++ arch/ppc64/kernel/process.c | 4 ++ 2 files changed, 103 insertions(+) (limited to 'arch') diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 86cc5496db..1d2ff6d6b0 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -122,6 +122,23 @@ static inline void restore_previous_kprobe(void) kprobe_saved_msr = kprobe_saved_msr_prev; } +void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) +{ + struct kretprobe_instance *ri; + + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *)regs->link; + + /* Replace the return addr with trampoline addr */ + regs->link = (unsigned long)kretprobe_trampoline; + add_rp_inst(ri); + } else { + rp->nmissed++; + } +} + static inline int kprobe_handler(struct pt_regs *regs) { struct kprobe *p; @@ -211,6 +228,78 @@ no_kprobe: return ret; } +/* + * Function return probe trampoline: + * - init_kprobes() establishes a probepoint here + * - When the probed function returns, this probe + * causes the handlers to fire + */ +void kretprobe_trampoline_holder(void) +{ + asm volatile(".global kretprobe_trampoline\n" + "kretprobe_trampoline:\n" + "nop\n"); +} + +/* + * Called when the probe at kretprobe trampoline is hit + */ +int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) +{ + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; + unsigned long orig_ret_address = 0; + unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; + + head = kretprobe_inst_table_head(current); + + /* + * It is possible to have multiple instances associated with a given + * task either because an multiple functions in the call path + * have a return probe installed on them, and/or more then one return + * return probe was registered for a target function. + * + * We can handle this because: + * - instances are always inserted at the head of the list + * - when multiple return probes are registered for the same + * function, the first instance's ret_addr will point to the + * real return address, and all the rest will point to + * kretprobe_trampoline + */ + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + if (ri->rp && ri->rp->handler) + ri->rp->handler(ri, regs); + + orig_ret_address = (unsigned long)ri->ret_addr; + recycle_rp_inst(ri); + + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; + } + + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); + regs->nip = orig_ret_address; + + unlock_kprobes(); + + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we have handled unlocking + * and re-enabling preemption. + */ + return 1; +} + /* * Called after single-stepping. p->addr is the address of the * instruction whose first byte has been replaced by the "breakpoint" @@ -349,3 +438,13 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs)); return 1; } + +static struct kprobe trampoline_p = { + .addr = (kprobe_opcode_t *) &kretprobe_trampoline, + .pre_handler = trampoline_probe_handler +}; + +int __init arch_init(void) +{ + return register_kprobe(&trampoline_p); +} diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index aba89554d8..f7cae05e40 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -307,6 +308,8 @@ void show_regs(struct pt_regs * regs) void exit_thread(void) { + kprobe_flush_task(current); + #ifndef CONFIG_SMP if (last_task_used_math == current) last_task_used_math = NULL; @@ -321,6 +324,7 @@ void flush_thread(void) { struct thread_info *t = current_thread_info(); + kprobe_flush_task(current); if (t->flags & _TIF_ABI_PENDING) t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT); -- cgit v1.2.2 From a528e21c235862cc1ae50e7809eb9116dc40ea0c Mon Sep 17 00:00:00 2001 From: Rusty Lynch Date: Mon, 27 Jun 2005 15:17:15 -0700 Subject: [PATCH] kprobes/ia64: refuse inserting kprobe on slot 1 Without the ability to atomically write 16 bytes, we can not update the middle slot of a bundle, slot 1, unless we stop the machine first. This patch will ensure the ability to robustly insert and remove a kprobe by refusing to insert a kprobe on slot 1 until a mechanism is in place to safely handle this case. Signed-off-by: Rusty Lynch Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/kernel/kprobes.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index c97e18e634..ec2ceade12 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -270,6 +270,13 @@ static int valid_kprobe_addr(int template, int slot, unsigned long addr) addr); return -EINVAL; } + + if (slot == 1 && bundle_encoding[template][1] != L) { + printk(KERN_WARNING "Inserting kprobes on slot #1 " + "is not supported\n"); + return -EINVAL; + } + return 0; } -- cgit v1.2.2 From c7b645f934e52a54af58142d91fb51f881f8ce26 Mon Sep 17 00:00:00 2001 From: Keshavamurthy Anil S Date: Mon, 27 Jun 2005 15:17:16 -0700 Subject: [PATCH] kprobes/ia64: refuse kprobe on ivt code Not safe to insert kprobes on IVT code. This patch checks to see if the address on which Kprobes is being inserted is in ivt code and if it is in ivt code then refuse to register kprobe. Signed-off-by: Anil S Keshavamurthy Acked-by: David Mosberger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/kernel/kprobes.c | 18 ++++++++++++++++-- arch/ia64/kernel/vmlinux.lds.S | 7 ++++++- 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index ec2ceade12..3aa3167edb 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -34,6 +34,7 @@ #include #include +#include extern void jprobe_inst_return(void); @@ -263,14 +264,27 @@ static inline void get_kprobe_inst(bundle_t *bundle, uint slot, } } +/* Returns non-zero if the addr is in the Interrupt Vector Table */ +static inline int in_ivt_functions(unsigned long addr) +{ + return (addr >= (unsigned long)__start_ivt_text + && addr < (unsigned long)__end_ivt_text); +} + static int valid_kprobe_addr(int template, int slot, unsigned long addr) { if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) { - printk(KERN_WARNING "Attempting to insert unaligned kprobe at 0x%lx\n", - addr); + printk(KERN_WARNING "Attempting to insert unaligned kprobe " + "at 0x%lx\n", addr); return -EINVAL; } + if (in_ivt_functions(addr)) { + printk(KERN_WARNING "Kprobes can't be inserted inside " + "IVT functions at 0x%lx\n", addr); + return -EINVAL; + } + if (slot == 1 && bundle_encoding[template][1] != L) { printk(KERN_WARNING "Inserting kprobes on slot #1 " "is not supported\n"); diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index b9f0db4c1b..a676e79e06 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -8,6 +8,11 @@ #define LOAD_OFFSET (KERNEL_START - KERNEL_TR_PAGE_SIZE) #include +#define IVT_TEXT \ + VMLINUX_SYMBOL(__start_ivt_text) = .; \ + *(.text.ivt) \ + VMLINUX_SYMBOL(__end_ivt_text) = .; + OUTPUT_FORMAT("elf64-ia64-little") OUTPUT_ARCH(ia64) ENTRY(phys_start) @@ -39,7 +44,7 @@ SECTIONS .text : AT(ADDR(.text) - LOAD_OFFSET) { - *(.text.ivt) + IVT_TEXT *(.text) SCHED_TEXT LOCK_TEXT -- cgit v1.2.2 From b445e26cbf784cdba10f2b6c3e2cd3ee7bab360a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 27 Jun 2005 15:42:04 -0700 Subject: [SPARC64]: Avoid membar instructions in delay slots. In particular, avoid membar instructions in the delay slot of a jmpl instruction. UltraSPARC-I, II, IIi, and IIe have a bug, documented in the UltraSPARC-IIi User's Manual, Appendix K, Erratum 51 The long and short of it is that if the IMU unit misses on a branch or jmpl, and there is a store buffer synchronizing membar in the delay slot, the chip can stop fetching instructions. If interrupts are enabled or some other trap is enabled, the chip will unwedge itself, but performance will suffer. We already had a workaround for this bug in a few spots, but it's better to have the entire tree sanitized for this rule. Signed-off-by: David S. Miller --- arch/sparc64/kernel/entry.S | 6 ++- arch/sparc64/kernel/semaphore.c | 12 +++-- arch/sparc64/kernel/trampoline.S | 3 +- arch/sparc64/lib/U1memcpy.S | 103 ++++++++++++++++++++------------------- arch/sparc64/lib/VISsave.S | 15 +++++- arch/sparc64/lib/atomic.S | 42 ++++++++++------ arch/sparc64/lib/bitops.S | 31 +++++++----- arch/sparc64/lib/debuglocks.c | 6 ++- arch/sparc64/lib/dec_and_lock.S | 6 ++- arch/sparc64/lib/rwsem.S | 15 ++++-- arch/sparc64/mm/init.c | 6 ++- arch/sparc64/mm/ultra.S | 3 +- 12 files changed, 150 insertions(+), 98 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index a47f2d0b1a..ffe717ab7f 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -271,8 +271,9 @@ cplus_fptrap_insn_1: fmuld %f0, %f2, %f26 faddd %f0, %f2, %f28 fmuld %f0, %f2, %f30 + membar #Sync b,pt %xcc, fpdis_exit - membar #Sync + nop 2: andcc %g5, FPRS_DU, %g0 bne,pt %icc, 3f fzero %f32 @@ -301,8 +302,9 @@ cplus_fptrap_insn_2: fmuld %f32, %f34, %f58 faddd %f32, %f34, %f60 fmuld %f32, %f34, %f62 + membar #Sync ba,pt %xcc, fpdis_exit - membar #Sync + nop 3: mov SECONDARY_CONTEXT, %g3 add %g6, TI_FPREGS, %g1 ldxa [%g3] ASI_DMMU, %g5 diff --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c index 63496c43fe..a809e63f03 100644 --- a/arch/sparc64/kernel/semaphore.c +++ b/arch/sparc64/kernel/semaphore.c @@ -32,8 +32,9 @@ static __inline__ int __sem_update_count(struct semaphore *sem, int incr) " add %1, %4, %1\n" " cas [%3], %0, %1\n" " cmp %0, %1\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%icc, 1b\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) : "r" (&sem->count), "r" (incr), "m" (sem->count) : "cc"); @@ -71,8 +72,9 @@ void up(struct semaphore *sem) " cmp %%g1, %%g7\n" " bne,pn %%icc, 1b\n" " addcc %%g7, 1, %%g0\n" +" membar #StoreLoad | #StoreStore\n" " ble,pn %%icc, 3f\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" "2:\n" " .subsection 2\n" "3: mov %0, %%g1\n" @@ -128,8 +130,9 @@ void __sched down(struct semaphore *sem) " cmp %%g1, %%g7\n" " bne,pn %%icc, 1b\n" " cmp %%g7, 1\n" +" membar #StoreLoad | #StoreStore\n" " bl,pn %%icc, 3f\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" "2:\n" " .subsection 2\n" "3: mov %0, %%g1\n" @@ -233,8 +236,9 @@ int __sched down_interruptible(struct semaphore *sem) " cmp %%g1, %%g7\n" " bne,pn %%icc, 1b\n" " cmp %%g7, 1\n" +" membar #StoreLoad | #StoreStore\n" " bl,pn %%icc, 3f\n" -" membar #StoreLoad | #StoreStore\n" +" nop\n" "2:\n" " .subsection 2\n" "3: mov %2, %%g1\n" diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 2c8f9344b4..3a145fc39c 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S @@ -98,8 +98,9 @@ startup_continue: sethi %hi(prom_entry_lock), %g2 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1 + membar #StoreLoad | #StoreStore brnz,pn %g1, 1b - membar #StoreLoad | #StoreStore + nop sethi %hi(p1275buf), %g2 or %g2, %lo(p1275buf), %g2 diff --git a/arch/sparc64/lib/U1memcpy.S b/arch/sparc64/lib/U1memcpy.S index da9b520c71..bafd2fc07a 100644 --- a/arch/sparc64/lib/U1memcpy.S +++ b/arch/sparc64/lib/U1memcpy.S @@ -87,14 +87,17 @@ #define LOOP_CHUNK3(src, dest, len, branch_dest) \ MAIN_LOOP_CHUNK(src, dest, f32, f48, len, branch_dest) +#define DO_SYNC membar #Sync; #define STORE_SYNC(dest, fsrc) \ EX_ST(STORE_BLK(%fsrc, %dest)); \ - add %dest, 0x40, %dest; + add %dest, 0x40, %dest; \ + DO_SYNC #define STORE_JUMP(dest, fsrc, target) \ EX_ST(STORE_BLK(%fsrc, %dest)); \ add %dest, 0x40, %dest; \ - ba,pt %xcc, target; + ba,pt %xcc, target; \ + nop; #define FINISH_VISCHUNK(dest, f0, f1, left) \ subcc %left, 8, %left;\ @@ -239,17 +242,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f0, %f2, %f48 1: FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) - STORE_JUMP(o0, f48, 40f) membar #Sync + STORE_JUMP(o0, f48, 40f) 2: FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) - STORE_JUMP(o0, f48, 48f) membar #Sync + STORE_JUMP(o0, f48, 48f) 3: FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) - STORE_JUMP(o0, f48, 56f) membar #Sync + STORE_JUMP(o0, f48, 56f) 1: FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -260,17 +263,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f2, %f4, %f48 1: FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) - STORE_JUMP(o0, f48, 41f) membar #Sync + STORE_JUMP(o0, f48, 41f) 2: FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) - STORE_JUMP(o0, f48, 49f) membar #Sync + STORE_JUMP(o0, f48, 49f) 3: FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) - STORE_JUMP(o0, f48, 57f) membar #Sync + STORE_JUMP(o0, f48, 57f) 1: FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -281,17 +284,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f4, %f6, %f48 1: FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) - STORE_JUMP(o0, f48, 42f) membar #Sync + STORE_JUMP(o0, f48, 42f) 2: FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) - STORE_JUMP(o0, f48, 50f) membar #Sync + STORE_JUMP(o0, f48, 50f) 3: FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) - STORE_JUMP(o0, f48, 58f) membar #Sync + STORE_JUMP(o0, f48, 58f) 1: FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -302,17 +305,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f6, %f8, %f48 1: FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) - STORE_JUMP(o0, f48, 43f) membar #Sync + STORE_JUMP(o0, f48, 43f) 2: FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) - STORE_JUMP(o0, f48, 51f) membar #Sync + STORE_JUMP(o0, f48, 51f) 3: FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) - STORE_JUMP(o0, f48, 59f) membar #Sync + STORE_JUMP(o0, f48, 59f) 1: FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -323,17 +326,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f8, %f10, %f48 1: FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) - STORE_JUMP(o0, f48, 44f) membar #Sync + STORE_JUMP(o0, f48, 44f) 2: FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) - STORE_JUMP(o0, f48, 52f) membar #Sync + STORE_JUMP(o0, f48, 52f) 3: FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) - STORE_JUMP(o0, f48, 60f) membar #Sync + STORE_JUMP(o0, f48, 60f) 1: FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -344,17 +347,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f10, %f12, %f48 1: FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) - STORE_JUMP(o0, f48, 45f) membar #Sync + STORE_JUMP(o0, f48, 45f) 2: FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) - STORE_JUMP(o0, f48, 53f) membar #Sync + STORE_JUMP(o0, f48, 53f) 3: FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) - STORE_JUMP(o0, f48, 61f) membar #Sync + STORE_JUMP(o0, f48, 61f) 1: FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -365,17 +368,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f12, %f14, %f48 1: FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) - STORE_JUMP(o0, f48, 46f) membar #Sync + STORE_JUMP(o0, f48, 46f) 2: FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) - STORE_JUMP(o0, f48, 54f) membar #Sync + STORE_JUMP(o0, f48, 54f) 3: FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) - STORE_JUMP(o0, f48, 62f) membar #Sync + STORE_JUMP(o0, f48, 62f) 1: FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f) @@ -386,17 +389,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %xcc, 1b+4 faligndata %f14, %f16, %f48 1: FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) - STORE_JUMP(o0, f48, 47f) membar #Sync + STORE_JUMP(o0, f48, 47f) 2: FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) - STORE_JUMP(o0, f48, 55f) membar #Sync + STORE_JUMP(o0, f48, 55f) 3: FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) - STORE_SYNC(o0, f48) membar #Sync + STORE_SYNC(o0, f48) FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) - STORE_JUMP(o0, f48, 63f) membar #Sync + STORE_JUMP(o0, f48, 63f) 40: FINISH_VISCHUNK(o0, f0, f2, g3) 41: FINISH_VISCHUNK(o0, f2, f4, g3) diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S index 65e328d600..4e18989bd6 100644 --- a/arch/sparc64/lib/VISsave.S +++ b/arch/sparc64/lib/VISsave.S @@ -72,7 +72,11 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 stda %f48, [%g3 + %g1] ASI_BLK_P 5: membar #Sync - jmpl %g7 + %g0, %g0 + ba,pt %xcc, 80f + nop + + .align 32 +80: jmpl %g7 + %g0, %g0 nop 6: ldub [%g3 + TI_FPSAVED], %o5 @@ -87,8 +91,11 @@ vis1: ldub [%g6 + TI_FPSAVED], %g3 stda %f32, [%g2 + %g1] ASI_BLK_P stda %f48, [%g3 + %g1] ASI_BLK_P membar #Sync - jmpl %g7 + %g0, %g0 + ba,pt %xcc, 80f + nop + .align 32 +80: jmpl %g7 + %g0, %g0 nop .align 32 @@ -126,6 +133,10 @@ VISenterhalf: stda %f0, [%g2 + %g1] ASI_BLK_P stda %f16, [%g3 + %g1] ASI_BLK_P membar #Sync + ba,pt %xcc, 4f + nop + + .align 32 4: and %o5, FPRS_DU, %o5 jmpl %g7 + %g0, %g0 wr %o5, FPRS_FEF, %fprs diff --git a/arch/sparc64/lib/atomic.S b/arch/sparc64/lib/atomic.S index e528b8d1a3..faf87c3159 100644 --- a/arch/sparc64/lib/atomic.S +++ b/arch/sparc64/lib/atomic.S @@ -7,18 +7,6 @@ #include #include - /* On SMP we need to use memory barriers to ensure - * correct memory operation ordering, nop these out - * for uniprocessor. - */ -#ifdef CONFIG_SMP -#define ATOMIC_PRE_BARRIER membar #StoreLoad | #LoadLoad -#define ATOMIC_POST_BARRIER membar #StoreLoad | #StoreStore -#else -#define ATOMIC_PRE_BARRIER nop -#define ATOMIC_POST_BARRIER nop -#endif - .text /* Two versions of the atomic routines, one that @@ -52,6 +40,24 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ nop .size atomic_sub, .-atomic_sub + /* On SMP we need to use memory barriers to ensure + * correct memory operation ordering, nop these out + * for uniprocessor. + */ +#ifdef CONFIG_SMP + +#define ATOMIC_PRE_BARRIER membar #StoreLoad | #LoadLoad; +#define ATOMIC_POST_BARRIER \ + ba,pt %xcc, 80b; \ + membar #StoreLoad | #StoreStore + +80: retl + nop +#else +#define ATOMIC_PRE_BARRIER +#define ATOMIC_POST_BARRIER +#endif + .globl atomic_add_ret .type atomic_add_ret,#function atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ @@ -62,9 +68,10 @@ atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %icc, 1b add %g7, %o0, %g7 + sra %g7, 0, %o0 ATOMIC_POST_BARRIER retl - sra %g7, 0, %o0 + nop .size atomic_add_ret, .-atomic_add_ret .globl atomic_sub_ret @@ -77,9 +84,10 @@ atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %icc, 1b sub %g7, %o0, %g7 + sra %g7, 0, %o0 ATOMIC_POST_BARRIER retl - sra %g7, 0, %o0 + nop .size atomic_sub_ret, .-atomic_sub_ret .globl atomic64_add @@ -118,9 +126,10 @@ atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %xcc, 1b add %g7, %o0, %g7 + mov %g7, %o0 ATOMIC_POST_BARRIER retl - mov %g7, %o0 + nop .size atomic64_add_ret, .-atomic64_add_ret .globl atomic64_sub_ret @@ -133,7 +142,8 @@ atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ cmp %g1, %g7 bne,pn %xcc, 1b sub %g7, %o0, %g7 + mov %g7, %o0 ATOMIC_POST_BARRIER retl - mov %g7, %o0 + nop .size atomic64_sub_ret, .-atomic64_sub_ret diff --git a/arch/sparc64/lib/bitops.S b/arch/sparc64/lib/bitops.S index 886dcd2b37..31afbfe6c1 100644 --- a/arch/sparc64/lib/bitops.S +++ b/arch/sparc64/lib/bitops.S @@ -7,20 +7,26 @@ #include #include + .text + /* On SMP we need to use memory barriers to ensure * correct memory operation ordering, nop these out * for uniprocessor. */ + #ifdef CONFIG_SMP #define BITOP_PRE_BARRIER membar #StoreLoad | #LoadLoad -#define BITOP_POST_BARRIER membar #StoreLoad | #StoreStore +#define BITOP_POST_BARRIER \ + ba,pt %xcc, 80b; \ + membar #StoreLoad | #StoreStore + +80: retl + nop #else -#define BITOP_PRE_BARRIER nop -#define BITOP_POST_BARRIER nop +#define BITOP_PRE_BARRIER +#define BITOP_POST_BARRIER #endif - .text - .globl test_and_set_bit .type test_and_set_bit,#function test_and_set_bit: /* %o0=nr, %o1=addr */ @@ -37,10 +43,11 @@ test_and_set_bit: /* %o0=nr, %o1=addr */ cmp %g7, %g1 bne,pn %xcc, 1b and %g7, %o2, %g2 - BITOP_POST_BARRIER clr %o0 + movrne %g2, 1, %o0 + BITOP_POST_BARRIER retl - movrne %g2, 1, %o0 + nop .size test_and_set_bit, .-test_and_set_bit .globl test_and_clear_bit @@ -59,10 +66,11 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */ cmp %g7, %g1 bne,pn %xcc, 1b and %g7, %o2, %g2 - BITOP_POST_BARRIER clr %o0 + movrne %g2, 1, %o0 + BITOP_POST_BARRIER retl - movrne %g2, 1, %o0 + nop .size test_and_clear_bit, .-test_and_clear_bit .globl test_and_change_bit @@ -81,10 +89,11 @@ test_and_change_bit: /* %o0=nr, %o1=addr */ cmp %g7, %g1 bne,pn %xcc, 1b and %g7, %o2, %g2 - BITOP_POST_BARRIER clr %o0 + movrne %g2, 1, %o0 + BITOP_POST_BARRIER retl - movrne %g2, 1, %o0 + nop .size test_and_change_bit, .-test_and_change_bit .globl set_bit diff --git a/arch/sparc64/lib/debuglocks.c b/arch/sparc64/lib/debuglocks.c index c421e0c653..f03344cf78 100644 --- a/arch/sparc64/lib/debuglocks.c +++ b/arch/sparc64/lib/debuglocks.c @@ -252,8 +252,9 @@ wlock_again: " andn %%g1, %%g3, %%g7\n" " casx [%0], %%g1, %%g7\n" " cmp %%g1, %%g7\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%xcc, 1b\n" -" membar #StoreLoad | #StoreStore" +" nop" : /* no outputs */ : "r" (&(rw->lock)) : "g3", "g1", "g7", "cc", "memory"); @@ -351,8 +352,9 @@ int _do_write_trylock (rwlock_t *rw, char *str) " andn %%g1, %%g3, %%g7\n" " casx [%0], %%g1, %%g7\n" " cmp %%g1, %%g7\n" +" membar #StoreLoad | #StoreStore\n" " bne,pn %%xcc, 1b\n" -" membar #StoreLoad | #StoreStore" +" nop" : /* no outputs */ : "r" (&(rw->lock)) : "g3", "g1", "g7", "cc", "memory"); diff --git a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S index 7e6fdaebed..8ee288dd0a 100644 --- a/arch/sparc64/lib/dec_and_lock.S +++ b/arch/sparc64/lib/dec_and_lock.S @@ -48,8 +48,9 @@ start_to_zero: #endif to_zero: ldstub [%o1], %g3 + membar #StoreLoad | #StoreStore brnz,pn %g3, spin_on_lock - membar #StoreLoad | #StoreStore + nop loop2: cas [%o0], %g2, %g7 /* ASSERT(g7 == 0) */ cmp %g2, %g7 @@ -71,8 +72,9 @@ loop2: cas [%o0], %g2, %g7 /* ASSERT(g7 == 0) */ nop spin_on_lock: ldub [%o1], %g3 + membar #LoadLoad brnz,pt %g3, spin_on_lock - membar #LoadLoad + nop ba,pt %xcc, to_zero nop nop diff --git a/arch/sparc64/lib/rwsem.S b/arch/sparc64/lib/rwsem.S index 174ff7b916..75f0e6b951 100644 --- a/arch/sparc64/lib/rwsem.S +++ b/arch/sparc64/lib/rwsem.S @@ -17,8 +17,9 @@ __down_read: bne,pn %icc, 1b add %g7, 1, %g7 cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop @@ -57,8 +58,9 @@ __down_write: cmp %g3, %g7 bne,pn %icc, 1b cmp %g7, 0 + membar #StoreLoad | #StoreStore bne,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop 3: @@ -97,8 +99,9 @@ __up_read: cmp %g1, %g7 bne,pn %icc, 1b cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop 3: sethi %hi(RWSEM_ACTIVE_MASK), %g1 @@ -126,8 +129,9 @@ __up_write: bne,pn %icc, 1b sub %g7, %g1, %g7 cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop @@ -151,8 +155,9 @@ __downgrade_write: bne,pn %icc, 1b sub %g7, %g1, %g7 cmp %g7, 0 + membar #StoreLoad | #StoreStore bl,pn %icc, 3f - membar #StoreLoad | #StoreStore + nop 2: retl nop diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 9c5222075d..8fc413cb6a 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -136,8 +136,9 @@ static __inline__ void set_dcache_dirty(struct page *page, int this_cpu) "or %%g1, %0, %%g1\n\t" "casx [%2], %%g7, %%g1\n\t" "cmp %%g7, %%g1\n\t" + "membar #StoreLoad | #StoreStore\n\t" "bne,pn %%xcc, 1b\n\t" - " membar #StoreLoad | #StoreStore" + " nop" : /* no outputs */ : "r" (mask), "r" (non_cpu_bits), "r" (&page->flags) : "g1", "g7"); @@ -157,8 +158,9 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c " andn %%g7, %1, %%g1\n\t" "casx [%2], %%g7, %%g1\n\t" "cmp %%g7, %%g1\n\t" + "membar #StoreLoad | #StoreStore\n\t" "bne,pn %%xcc, 1b\n\t" - " membar #StoreLoad | #StoreStore\n" + " nop\n" "2:" : /* no outputs */ : "r" (cpu), "r" (mask), "r" (&page->flags), diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 7a09343210..7a2431d3ab 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -266,8 +266,9 @@ __cheetah_flush_tlb_pending: /* 22 insns */ andn %o3, 1, %o3 stxa %g0, [%o3] ASI_IMMU_DEMAP 2: stxa %g0, [%o3] ASI_DMMU_DEMAP + membar #Sync brnz,pt %o1, 1b - membar #Sync + nop stxa %g2, [%o4] ASI_DMMU flush %g6 wrpr %g0, 0, %tl -- cgit v1.2.2 From 63b614522cba5a015923c0e8f284be6e01c13f1a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 27 Jun 2005 17:04:45 -0700 Subject: [SPARC64]: Get rid of fast IRQ feature. The only real user was the assembler floppy interrupt handler, which does not need to be in assembly. This makes it so that there are less pieces of code which know about the internal layout of ivector_table[] and friends. Signed-off-by: David S. Miller --- arch/sparc64/kernel/auxio.c | 2 +- arch/sparc64/kernel/entry.S | 110 ----------------------- arch/sparc64/kernel/irq.c | 171 +++++++++++------------------------- arch/sparc64/kernel/sparc64_ksyms.c | 1 - 4 files changed, 51 insertions(+), 233 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c index a0716ccc2f..8852c20c8d 100644 --- a/arch/sparc64/kernel/auxio.c +++ b/arch/sparc64/kernel/auxio.c @@ -16,7 +16,7 @@ #include #include -/* This cannot be static, as it is referenced in entry.S */ +/* This cannot be static, as it is referenced in irq.c */ void __iomem *auxio_register = NULL; enum auxio_type { diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index ffe717ab7f..eee516a71c 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -701,116 +701,6 @@ utrap_ill: ba,pt %xcc, rtrap clr %l6 -#ifdef CONFIG_BLK_DEV_FD - .globl floppy_hardint -floppy_hardint: - wr %g0, (1 << 11), %clear_softint - sethi %hi(doing_pdma), %g1 - ld [%g1 + %lo(doing_pdma)], %g2 - brz,pn %g2, floppy_dosoftint - sethi %hi(fdc_status), %g3 - ldx [%g3 + %lo(fdc_status)], %g3 - sethi %hi(pdma_vaddr), %g5 - ldx [%g5 + %lo(pdma_vaddr)], %g4 - sethi %hi(pdma_size), %g5 - ldx [%g5 + %lo(pdma_size)], %g5 - -next_byte: - lduba [%g3] ASI_PHYS_BYPASS_EC_E, %g7 - andcc %g7, 0x80, %g0 - be,pn %icc, floppy_fifo_emptied - andcc %g7, 0x20, %g0 - be,pn %icc, floppy_overrun - andcc %g7, 0x40, %g0 - be,pn %icc, floppy_write - sub %g5, 1, %g5 - - inc %g3 - lduba [%g3] ASI_PHYS_BYPASS_EC_E, %g7 - dec %g3 - orcc %g0, %g5, %g0 - stb %g7, [%g4] - bne,pn %xcc, next_byte - add %g4, 1, %g4 - - b,pt %xcc, floppy_tdone - nop - -floppy_write: - ldub [%g4], %g7 - orcc %g0, %g5, %g0 - inc %g3 - stba %g7, [%g3] ASI_PHYS_BYPASS_EC_E - dec %g3 - bne,pn %xcc, next_byte - add %g4, 1, %g4 - -floppy_tdone: - sethi %hi(pdma_vaddr), %g1 - stx %g4, [%g1 + %lo(pdma_vaddr)] - sethi %hi(pdma_size), %g1 - stx %g5, [%g1 + %lo(pdma_size)] - sethi %hi(auxio_register), %g1 - ldx [%g1 + %lo(auxio_register)], %g7 - lduba [%g7] ASI_PHYS_BYPASS_EC_E, %g5 - or %g5, AUXIO_AUX1_FTCNT, %g5 -/* andn %g5, AUXIO_AUX1_MASK, %g5 */ - stba %g5, [%g7] ASI_PHYS_BYPASS_EC_E - andn %g5, AUXIO_AUX1_FTCNT, %g5 -/* andn %g5, AUXIO_AUX1_MASK, %g5 */ - - nop; nop; nop; nop; nop; nop; - nop; nop; nop; nop; nop; nop; - - stba %g5, [%g7] ASI_PHYS_BYPASS_EC_E - sethi %hi(doing_pdma), %g1 - b,pt %xcc, floppy_dosoftint - st %g0, [%g1 + %lo(doing_pdma)] - -floppy_fifo_emptied: - sethi %hi(pdma_vaddr), %g1 - stx %g4, [%g1 + %lo(pdma_vaddr)] - sethi %hi(pdma_size), %g1 - stx %g5, [%g1 + %lo(pdma_size)] - sethi %hi(irq_action), %g1 - or %g1, %lo(irq_action), %g1 - ldx [%g1 + (11 << 3)], %g3 ! irqaction[floppy_irq] - ldx [%g3 + 0x08], %g4 ! action->flags>>48==ino - sethi %hi(ivector_table), %g3 - srlx %g4, 48, %g4 - or %g3, %lo(ivector_table), %g3 - sllx %g4, 5, %g4 - ldx [%g3 + %g4], %g4 ! &ivector_table[ino] - ldx [%g4 + 0x10], %g4 ! bucket->iclr - stwa %g0, [%g4] ASI_PHYS_BYPASS_EC_E ! ICLR_IDLE - membar #Sync ! probably not needed... - retry - -floppy_overrun: - sethi %hi(pdma_vaddr), %g1 - stx %g4, [%g1 + %lo(pdma_vaddr)] - sethi %hi(pdma_size), %g1 - stx %g5, [%g1 + %lo(pdma_size)] - sethi %hi(doing_pdma), %g1 - st %g0, [%g1 + %lo(doing_pdma)] - -floppy_dosoftint: - rdpr %pil, %g2 - wrpr %g0, 15, %pil - sethi %hi(109f), %g7 - b,pt %xcc, etrap_irq -109: or %g7, %lo(109b), %g7 - - mov 11, %o0 - mov 0, %o1 - call sparc_floppy_irq - add %sp, PTREGS_OFF, %o2 - - b,pt %xcc, rtrap_irq - nop - -#endif /* CONFIG_BLK_DEV_FD */ - /* XXX Here is stuff we still need to write... -DaveM XXX */ .globl netbsd_syscall netbsd_syscall: diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 4dcb8af940..4247125773 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef CONFIG_SMP static void distribute_irqs(void); @@ -834,137 +835,65 @@ void handler_irq(int irq, struct pt_regs *regs) } #ifdef CONFIG_BLK_DEV_FD -extern void floppy_interrupt(int irq, void *dev_cookie, struct pt_regs *regs); +extern irqreturn_t floppy_interrupt(int, void *, struct pt_regs *);; -void sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs) -{ - struct irqaction *action = *(irq + irq_action); - struct ino_bucket *bucket; - int cpu = smp_processor_id(); - - irq_enter(); - kstat_this_cpu.irqs[irq]++; - - *(irq_work(cpu, irq)) = 0; - bucket = get_ino_in_irqaction(action) + ivector_table; - - bucket->flags |= IBF_INPROGRESS; - - floppy_interrupt(irq, dev_cookie, regs); - upa_writel(ICLR_IDLE, bucket->iclr); - - bucket->flags &= ~IBF_INPROGRESS; - - irq_exit(); -} -#endif - -/* The following assumes that the branch lies before the place we - * are branching to. This is the case for a trap vector... - * You have been warned. - */ -#define SPARC_BRANCH(dest_addr, inst_addr) \ - (0x10800000 | ((((dest_addr)-(inst_addr))>>2)&0x3fffff)) - -#define SPARC_NOP (0x01000000) +/* XXX No easy way to include asm/floppy.h XXX */ +extern unsigned char *pdma_vaddr; +extern unsigned long pdma_size; +extern volatile int doing_pdma; +extern unsigned long fdc_status; -static void install_fast_irq(unsigned int cpu_irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *)) +irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs) { - extern unsigned long sparc64_ttable_tl0; - unsigned long ttent = (unsigned long) &sparc64_ttable_tl0; - unsigned int *insns; - - ttent += 0x820; - ttent += (cpu_irq - 1) << 5; - insns = (unsigned int *) ttent; - insns[0] = SPARC_BRANCH(((unsigned long) handler), - ((unsigned long)&insns[0])); - insns[1] = SPARC_NOP; - __asm__ __volatile__("membar #StoreStore; flush %0" : : "r" (ttent)); -} - -int request_fast_irq(unsigned int irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, const char *name, void *dev_id) -{ - struct irqaction *action; - struct ino_bucket *bucket = __bucket(irq); - unsigned long flags; - - /* No pil0 dummy buckets allowed here. */ - if (bucket < &ivector_table[0] || - bucket >= &ivector_table[NUM_IVECS]) { - unsigned int *caller; - - __asm__ __volatile__("mov %%i7, %0" : "=r" (caller)); - printk(KERN_CRIT "request_fast_irq: Old style IRQ registry attempt " - "from %p, irq %08x.\n", caller, irq); - return -EINVAL; - } - - if (!handler) - return -EINVAL; + if (likely(doing_pdma)) { + void __iomem *stat = (void __iomem *) fdc_status; + unsigned char *vaddr = pdma_vaddr; + unsigned long size = pdma_size; + u8 val; + + while (size) { + val = readb(stat); + if (unlikely(!(val & 0x80))) { + pdma_vaddr = vaddr; + pdma_size = size; + return IRQ_HANDLED; + } + if (unlikely(!(val & 0x20))) { + pdma_vaddr = vaddr; + pdma_size = size; + doing_pdma = 0; + goto main_interrupt; + } + if (val & 0x40) { + /* read */ + *vaddr++ = readb(stat + 1); + } else { + unsigned char data = *vaddr++; - if ((bucket->pil == 0) || (bucket->pil == 14)) { - printk("request_fast_irq: Trying to register shared IRQ 0 or 14.\n"); - return -EBUSY; - } + /* write */ + writeb(data, stat + 1); + } + size--; + } - spin_lock_irqsave(&irq_action_lock, flags); + pdma_vaddr = vaddr; + pdma_size = size; - action = *(bucket->pil + irq_action); - if (action) { - if (action->flags & SA_SHIRQ) - panic("Trying to register fast irq when already shared.\n"); - if (irqflags & SA_SHIRQ) - panic("Trying to register fast irq as shared.\n"); - printk("request_fast_irq: Trying to register yet already owned.\n"); - spin_unlock_irqrestore(&irq_action_lock, flags); - return -EBUSY; - } + /* Send Terminal Count pulse to floppy controller. */ + val = readb(auxio_register); + val |= AUXIO_AUX1_FTCNT; + writeb(val, auxio_register); + val &= AUXIO_AUX1_FTCNT; + writeb(val, auxio_register); - /* - * We do not check for SA_SAMPLE_RANDOM in this path. Neither do we - * support smp intr affinity in this path. - */ - if (irqflags & SA_STATIC_ALLOC) { - if (static_irq_count < MAX_STATIC_ALLOC) - action = &static_irqaction[static_irq_count++]; - else - printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed " - "using kmalloc\n", bucket->pil, name); - } - if (action == NULL) - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), - GFP_ATOMIC); - if (!action) { - spin_unlock_irqrestore(&irq_action_lock, flags); - return -ENOMEM; + doing_pdma = 0; } - install_fast_irq(bucket->pil, handler); - bucket->irq_info = action; - bucket->flags |= IBF_ACTIVE; - - action->handler = handler; - action->flags = irqflags; - action->dev_id = NULL; - action->name = name; - action->next = NULL; - put_ino_in_irqaction(action, irq); - put_smpaff_in_irqaction(action, CPU_MASK_NONE); - - *(bucket->pil + irq_action) = action; - enable_irq(irq); - - spin_unlock_irqrestore(&irq_action_lock, flags); - -#ifdef CONFIG_SMP - distribute_irqs(); -#endif - return 0; +main_interrupt: + return floppy_interrupt(irq, dev_cookie, regs); } +EXPORT_SYMBOL(sparc_floppy_irq); +#endif /* We really don't need these at all on the Sparc. We only have * stubs here because they are exported to modules. diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index e78cc53594..56cd96f4a5 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -227,7 +227,6 @@ EXPORT_SYMBOL(__flush_dcache_range); EXPORT_SYMBOL(mostek_lock); EXPORT_SYMBOL(mstk48t02_regs); -EXPORT_SYMBOL(request_fast_irq); #ifdef CONFIG_SUN_AUXIO EXPORT_SYMBOL(auxio_set_led); EXPORT_SYMBOL(auxio_set_lte); -- cgit v1.2.2 From 120bb4246a99cc6e9cc976573fcbcd0ee9d544ef Mon Sep 17 00:00:00 2001 From: "jayalk@intworks.biz" Date: Mon, 21 Mar 2005 20:20:42 -0800 Subject: [PATCH] PCI Allow OutOfRange PIRQ table address I updated this to remove unnecessary variable initialization, make check_routing be inline only and not __init, switch to strtoul, and formatting fixes as per Randy Dunlap's recommendations. I updated this to change pirq_table_addr to a long, and to add a warning msg if the PIRQ table wasn't found at the specified address, as per thread with Matthew Wilcox. In our hardware situation, the BIOS is unable to store or generate it's PIRQ table in the F0000h-100000h standard range. This patch adds a pci kernel parameter, pirqaddr to allow the bootloader (or BIOS based loader) to inform the kernel where the PIRQ table got stored. A beneficial side-effect is that, if one's BIOS uses a static address each time for it's PIRQ table, then pirqaddr can be used to avoid the $pirq search through that address block each time at boot for normal PIRQ BIOSes. Signed-off-by: Jaya Kumar Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/common.c | 6 +++++- arch/i386/pci/irq.c | 51 ++++++++++++++++++++++++++++++++++++-------------- arch/i386/pci/pci.h | 1 + 3 files changed, 43 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 720975e1af..2a2e79fbfe 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | int pci_routeirq; int pcibios_last_bus = -1; -struct pci_bus *pci_root_bus = NULL; +unsigned long pirq_table_addr; +struct pci_bus *pci_root_bus; struct pci_raw_ops *raw_pci_ops; static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) @@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *str) } else if (!strcmp(str, "biosirq")) { pci_probe |= PCI_BIOS_IRQ_SCAN; return NULL; + } else if (!strncmp(str, "pirqaddr=", 9)) { + pirq_table_addr = simple_strtoul(str+9, NULL, 0); + return NULL; } #endif #ifdef CONFIG_PCI_DIRECT diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 83458f81e6..78ca1ecbb9 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -57,6 +57,35 @@ struct irq_router_handler { int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; +/* + * Check passed address for the PCI IRQ Routing Table signature + * and perform checksum verification. + */ + +static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr) +{ + struct irq_routing_table *rt; + int i; + u8 sum; + + rt = (struct irq_routing_table *) addr; + if (rt->signature != PIRQ_SIGNATURE || + rt->version != PIRQ_VERSION || + rt->size % 16 || + rt->size < sizeof(struct irq_routing_table)) + return NULL; + sum = 0; + for (i=0; i < rt->size; i++) + sum += addr[i]; + if (!sum) { + DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); + return rt; + } + return NULL; +} + + + /* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. */ @@ -65,23 +94,17 @@ static struct irq_routing_table * __init pirq_find_routing_table(void) { u8 *addr; struct irq_routing_table *rt; - int i; - u8 sum; + if (pirq_table_addr) { + rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr)); + if (rt) + return rt; + printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n"); + } for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { - rt = (struct irq_routing_table *) addr; - if (rt->signature != PIRQ_SIGNATURE || - rt->version != PIRQ_VERSION || - rt->size % 16 || - rt->size < sizeof(struct irq_routing_table)) - continue; - sum = 0; - for(i=0; isize; i++) - sum += addr[i]; - if (!sum) { - DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); + rt = pirq_check_routing_table(addr); + if (rt) return rt; - } } return NULL; } diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index a8fc80ca69..a80f0f55ff 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h @@ -27,6 +27,7 @@ #define PCI_ASSIGN_ALL_BUSSES 0x4000 extern unsigned int pci_probe; +extern unsigned long pirq_table_addr; /* pci-i386.c */ -- cgit v1.2.2 From c431ada45d65b305a6aab4557067e564b23ce5a5 Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:45 -0700 Subject: [PATCH] acpi bridge hotadd: ACPI based root bridge hot-add When you hot-plug a (root) bridge hierarchy, it may have p2p bridges and devices attached to it that have not been configured by firmware. In this case, we need to configure the devices before starting them. This patch separates device start from device scan so that we can introduce the configuration step in the middle. I kept the existing semantics for pci_scan_bus() since there are a huge number of callers to that function. Also, I have no way of testing the changes I made to the parisc files, so this needs review by those folks. Sorry for the massive cross-post, this touches files in many different places. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/common.c | 2 +- arch/i386/pci/legacy.c | 2 ++ arch/i386/pci/numa.c | 2 ++ arch/ia64/pci/pci.c | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 2a2e79fbfe..87325263cd 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -134,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); - return pci_scan_bus(busnum, &pci_root_ops, NULL); + return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL); } extern u8 pci_cache_line_size; diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c index 1492e37538..149a9588c2 100644 --- a/arch/i386/pci/legacy.c +++ b/arch/i386/pci/legacy.c @@ -45,6 +45,8 @@ static int __init pci_legacy_init(void) printk("PCI: Probing PCI hardware\n"); pci_root_bus = pcibios_scan_root(0); + if (pci_root_bus) + pci_bus_add_devices(pci_root_bus); pcibios_fixup_peer_bridges(); diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c index 9e36954618..adbe17a38f 100644 --- a/arch/i386/pci/numa.c +++ b/arch/i386/pci/numa.c @@ -115,6 +115,8 @@ static int __init pci_numa_init(void) return 0; pci_root_bus = pcibios_scan_root(0); + if (pci_root_bus) + pci_bus_add_devices(pci_root_bus); if (num_online_nodes() > 1) for_each_online_node(quad) { if (quad == 0) diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index e3fc4edea1..c0661d3382 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, &info); - pbus = pci_scan_bus(bus, &pci_root_ops, controller); + pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller); if (pbus) pcibios_setup_root_windows(pbus, controller); -- cgit v1.2.2 From fab3fb0ac8c83072465b28ca859c420da6c6511c Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:45 -0700 Subject: [PATCH] acpi bridge hotadd: Fix pci_enable_device() for p2p bridges When checking if a PCI to PCI bridge should be enabled to decode memory and/or IO resources, we need to look at all device resources not just the first 6. This is needed to allow PCI bridges to pass down memory and IO accesses to child devices even when the bridge itself does not consume resources in its PCI BARs. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/ia64/pci/pci.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index c0661d3382..2a14877584 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -418,18 +418,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) u16 cmd, old_cmd; int idx; struct resource *r; + unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; if (!dev) return -EINVAL; pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; - for (idx=0; idx<6; idx++) { + for (idx=0; idxresource[idx]; + if (!(r->flags & type_mask)) + continue; + if ((idx == PCI_ROM_RESOURCE) && + (!(r->flags & IORESOURCE_ROM_ENABLE))) + continue; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", @@ -441,8 +447,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) if (r->flags & IORESOURCE_MEM) cmd |= PCI_COMMAND_MEMORY; } - if (dev->resource[PCI_ROM_RESOURCE].start) - cmd |= PCI_COMMAND_MEMORY; if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); -- cgit v1.2.2 From 71c3511c22e8e0648094672abec898b3bf84c18b Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:46 -0700 Subject: [PATCH] acpi bridge hotadd: Make pcibios_fixup_bus() hot-plug safe PCI scan code calls the arch specific pcibios_fixup_bus() each time it scans a new bridge. For root bridge hot-plug, the bridge and it's attached devices may not have been configured properly yet, so it's not safe to claim those resources at this time. This code goes away when we clean up the way pci resources are claimed (in pci_enable_device()), so this is only a stopgap fix. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/ia64/pci/pci.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 2a14877584..d929858cfb 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev, res->end = region->end + offset; } +static int __devinit is_valid_resource(struct pci_dev *dev, int idx) +{ + unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; + struct resource *devr = &dev->resource[idx]; + + if (!dev->bus) + return 0; + for (i=0; ibus->resource[i]; + + if (!busr || ((busr->flags ^ devr->flags) & type_mask)) + continue; + if ((devr->start) && (devr->start >= busr->start) && + (devr->end <= busr->end)) + return 1; + } + return 0; +} + static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) { struct pci_bus_region region; @@ -386,7 +405,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) region.start = dev->resource[i].start; region.end = dev->resource[i].end; pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); - pci_claim_resource(dev, i); + if ((is_valid_resource(dev, i))) + pci_claim_resource(dev, i); } } -- cgit v1.2.2 From f7d473d919627262816459f8dba70d72812be074 Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:51 -0700 Subject: [PATCH] acpi bridge hotadd: Read bridge resources when fixing up the bus Read bridge io/mem/pfmem ranges when fixing up the bus so that bus resources are tracked. This is required to properly support pci end device and bridge hotplug. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/ia64/pci/pci.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index d929858cfb..720a861f88 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -418,6 +418,10 @@ pcibios_fixup_bus (struct pci_bus *b) { struct pci_dev *dev; + if (b->self) { + pci_read_bridge_bases(b); + pcibios_fixup_device_resources(b->self); + } list_for_each_entry(dev, &b->devices, bus_list) pcibios_fixup_device_resources(dev); -- cgit v1.2.2 From b1bb248a5d2230a3d8ef42199c742194a8580b15 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 28 Apr 2005 00:25:58 -0700 Subject: [PATCH] ACPI based I/O APIC hot-plug: add interfaces This patch adds the following new interfaces for I/O xAPIC hotplug. The implementation of these interfaces depends on each architecture. o int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base); This new interface is to add a new I/O xAPIC specified by phys_addr and gsi_base pair. phys_addr is the physical address to which the I/O xAPIC is mapped and gsi_base is global system interrupt base of the I/O xAPIC. acpi_register_ioapic returns 0 on success, or negative value on error. o int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); This new interface is to remove a I/O xAPIC specified by gsi_base. acpi_unregister_ioapic returns 0 on success, or negative value on error. Signed-off-by: Kenji Kaneshige Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/acpi/boot.c | 16 ++++++++++++++++ arch/ia64/kernel/acpi.c | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 9f63ae0f40..f5360d88bc 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -507,6 +507,22 @@ acpi_unmap_lsapic(int cpu) EXPORT_SYMBOL(acpi_unmap_lsapic); #endif /* CONFIG_ACPI_HOTPLUG_CPU */ +int +acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_register_ioapic); + +int +acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_unregister_ioapic); + static unsigned long __init acpi_scan_rsdp ( unsigned long start, diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 72dfd9e7de..ab798867ac 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -825,4 +825,21 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) return AE_OK; } #endif /* CONFIG_NUMA */ + +int +acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_register_ioapic); + +int +acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_unregister_ioapic); + #endif /* CONFIG_ACPI_BOOT */ -- cgit v1.2.2 From 0e888adc41ffc02b700ade715c182a17e766af84 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 28 Apr 2005 00:25:58 -0700 Subject: [PATCH] ACPI based I/O APIC hot-plug: ia64 support This is an ia64 implementation of acpi_register_ioapic() and acpi_unregister_ioapic() interfaces. Signed-off-by: Kenji Kaneshige Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/ia64/kernel/acpi.c | 21 ++++--- arch/ia64/kernel/iosapic.c | 134 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 126 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index ab798867ac..cda06f88c6 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -236,9 +236,7 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end) if (BAD_MADT_ENTRY(iosapic, end)) return -EINVAL; - iosapic_init(iosapic->address, iosapic->global_irq_base); - - return 0; + return iosapic_init(iosapic->address, iosapic->global_irq_base); } @@ -772,7 +770,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic); #ifdef CONFIG_ACPI_NUMA -acpi_status __init +acpi_status __devinit acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) { struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; @@ -829,16 +827,23 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) int acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base) { - /* TBD */ - return -EINVAL; + int err; + + if ((err = iosapic_init(phys_addr, gsi_base))) + return err; + +#if CONFIG_ACPI_NUMA + acpi_map_iosapic(handle, 0, NULL, NULL); +#endif /* CONFIG_ACPI_NUMA */ + + return 0; } EXPORT_SYMBOL(acpi_register_ioapic); int acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base) { - /* TBD */ - return -EINVAL; + return iosapic_remove(gsi_base); } EXPORT_SYMBOL(acpi_unregister_ioapic); diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 88b014381d..c170be095c 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -129,14 +129,13 @@ static struct iosapic { char __iomem *addr; /* base address of IOSAPIC */ unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ unsigned short num_rte; /* number of RTE in this IOSAPIC */ + int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ #ifdef CONFIG_NUMA unsigned short node; /* numa node association via pxm */ #endif } iosapic_lists[NR_IOSAPICS]; -static int num_iosapic; - -static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */ +static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */ static int iosapic_kmalloc_ok; static LIST_HEAD(free_rte_list); @@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi) { int i; - for (i = 0; i < num_iosapic; i++) { + for (i = 0; i < NR_IOSAPICS; i++) { if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) return i; } @@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, rte->refcnt++; list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); iosapic_intr_info[vector].count++; + iosapic_lists[index].rtes_inuse++; } else if (vector_is_shared(vector)) { struct iosapic_intr_info *info = &iosapic_intr_info[vector]; @@ -778,7 +778,7 @@ void iosapic_unregister_intr (unsigned int gsi) { unsigned long flags; - int irq, vector; + int irq, vector, index; irq_desc_t *idesc; u32 low32; unsigned long trigger, polarity; @@ -819,6 +819,9 @@ iosapic_unregister_intr (unsigned int gsi) list_del(&rte->rte_list); iosapic_intr_info[vector].count--; iosapic_free_rte(rte); + index = find_iosapic(gsi); + iosapic_lists[index].rtes_inuse--; + WARN_ON(iosapic_lists[index].rtes_inuse < 0); trigger = iosapic_intr_info[vector].trigger; polarity = iosapic_intr_info[vector].polarity; @@ -952,30 +955,86 @@ iosapic_system_init (int system_pcat_compat) } } -void __init +static inline int +iosapic_alloc (void) +{ + int index; + + for (index = 0; index < NR_IOSAPICS; index++) + if (!iosapic_lists[index].addr) + return index; + + printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__); + return -1; +} + +static inline void +iosapic_free (int index) +{ + memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0])); +} + +static inline int +iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) +{ + int index; + unsigned int gsi_end, base, end; + + /* check gsi range */ + gsi_end = gsi_base + ((ver >> 16) & 0xff); + for (index = 0; index < NR_IOSAPICS; index++) { + if (!iosapic_lists[index].addr) + continue; + + base = iosapic_lists[index].gsi_base; + end = base + iosapic_lists[index].num_rte - 1; + + if (gsi_base < base && gsi_end < base) + continue;/* OK */ + + if (gsi_base > end && gsi_end > end) + continue; /* OK */ + + return -EBUSY; + } + return 0; +} + +int __devinit iosapic_init (unsigned long phys_addr, unsigned int gsi_base) { - int num_rte; + int num_rte, err, index; unsigned int isa_irq, ver; char __iomem *addr; + unsigned long flags; + + spin_lock_irqsave(&iosapic_lock, flags); + { + addr = ioremap(phys_addr, 0); + ver = iosapic_version(addr); - addr = ioremap(phys_addr, 0); - ver = iosapic_version(addr); + if ((err = iosapic_check_gsi_range(gsi_base, ver))) { + iounmap(addr); + spin_unlock_irqrestore(&iosapic_lock, flags); + return err; + } - /* - * The MAX_REDIR register holds the highest input pin - * number (starting from 0). - * We add 1 so that we can use it for number of pins (= RTEs) - */ - num_rte = ((ver >> 16) & 0xff) + 1; + /* + * The MAX_REDIR register holds the highest input pin + * number (starting from 0). + * We add 1 so that we can use it for number of pins (= RTEs) + */ + num_rte = ((ver >> 16) & 0xff) + 1; - iosapic_lists[num_iosapic].addr = addr; - iosapic_lists[num_iosapic].gsi_base = gsi_base; - iosapic_lists[num_iosapic].num_rte = num_rte; + index = iosapic_alloc(); + iosapic_lists[index].addr = addr; + iosapic_lists[index].gsi_base = gsi_base; + iosapic_lists[index].num_rte = num_rte; #ifdef CONFIG_NUMA - iosapic_lists[num_iosapic].node = MAX_NUMNODES; + iosapic_lists[index].node = MAX_NUMNODES; #endif - num_iosapic++; + } + spin_unlock_irqrestore(&iosapic_lock, flags); if ((gsi_base == 0) && pcat_compat) { /* @@ -986,10 +1045,43 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base) for (isa_irq = 0; isa_irq < 16; ++isa_irq) iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); } + return 0; +} + +#ifdef CONFIG_HOTPLUG +int +iosapic_remove (unsigned int gsi_base) +{ + int index, err = 0; + unsigned long flags; + + spin_lock_irqsave(&iosapic_lock, flags); + { + index = find_iosapic(gsi_base); + if (index < 0) { + printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n", + __FUNCTION__, gsi_base); + goto out; + } + + if (iosapic_lists[index].rtes_inuse) { + err = -EBUSY; + printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", + __FUNCTION__, gsi_base); + goto out; + } + + iounmap(iosapic_lists[index].addr); + iosapic_free(index); + } + out: + spin_unlock_irqrestore(&iosapic_lock, flags); + return err; } +#endif /* CONFIG_HOTPLUG */ #ifdef CONFIG_NUMA -void __init +void __devinit map_iosapic_to_node(unsigned int gsi_base, int node) { int index; -- cgit v1.2.2 From 2311b1f2bbd36fa5f366a7448c718b2556e0f02c Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 13 May 2005 17:44:10 +1000 Subject: [PATCH] PCI: fix-pci-mmap-on-ppc-and-ppc64.patch This is an updated version of Ben's fix-pci-mmap-on-ppc-and-ppc64.patch which is in 2.6.12-rc4-mm1. It fixes the patch to work on PPC iSeries, removes some debug printks at Ben's request, and incorporates your fix-pci-mmap-on-ppc-and-ppc64-fix.patch also. Originally from Benjamin Herrenschmidt This patch was discussed at length on linux-pci and so far, the last iteration of it didn't raise any comment. It's effect is a nop on architecture that don't define the new pci_resource_to_user() callback anyway. It allows architecture like ppc who put weird things inside of PCI resource structures to convert to some different value for user visible ones. It also fixes mmap'ing of IO space on those archs. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Michael Ellerman Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/ppc/kernel/pci.c | 21 +++++++++++++++++++-- arch/ppc64/kernel/pci.c | 22 ++++++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 6d7b92d724..70cfb6ffd8 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -1495,7 +1495,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, *offset += hose->pci_mem_offset; res_bit = IORESOURCE_MEM; } else { - io_offset = (unsigned long)hose->io_base_virt; + io_offset = hose->io_base_virt - ___IO_BASE; *offset += io_offset; res_bit = IORESOURCE_IO; } @@ -1522,7 +1522,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* found it! construct the final physical address */ if (mmap_state == pci_mmap_io) - *offset += hose->io_base_phys - _IO_BASE; + *offset += hose->io_base_phys - io_offset; return rp; } @@ -1739,6 +1739,23 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) return result; } +void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end) +{ + struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); + unsigned long offset = 0; + + if (hose == NULL) + return; + + if (rsrc->flags & IORESOURCE_IO) + offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; + + *start = rsrc->start + offset; + *end = rsrc->end + offset; +} + void __init pci_init_resource(struct resource *res, unsigned long start, unsigned long end, int flags, char *name) diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index 580676f87d..ae6f579d3f 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c @@ -351,7 +351,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, *offset += hose->pci_mem_offset; res_bit = IORESOURCE_MEM; } else { - io_offset = (unsigned long)hose->io_base_virt; + io_offset = (unsigned long)hose->io_base_virt - pci_io_base; *offset += io_offset; res_bit = IORESOURCE_IO; } @@ -378,7 +378,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* found it! construct the final physical address */ if (mmap_state == pci_mmap_io) - *offset += hose->io_base_phys - io_offset; + *offset += hose->io_base_phys - io_offset; return rp; } @@ -944,4 +944,22 @@ int pci_read_irq_line(struct pci_dev *pci_dev) } EXPORT_SYMBOL(pci_read_irq_line); +void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + unsigned long offset = 0; + + if (hose == NULL) + return; + + if (rsrc->flags & IORESOURCE_IO) + offset = pci_io_base - (unsigned long)hose->io_base_virt + + hose->io_base_phys; + + *start = rsrc->start + offset; + *end = rsrc->end + offset; +} + #endif /* CONFIG_PPC_MULTIPLATFORM */ -- cgit v1.2.2 From 545493917dc90298e1c38f018ad893f5518928e7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Jun 2005 17:35:56 -0700 Subject: [PATCH] PCI: add proper MCFG table parsing to ACPI core. This patch is the first step in properly handling the MCFG PCI table. It defines the structures properly, and saves off the table so that the pci mmconfig code can access it. It moves the parsing of the table a little later in the boot process, but still before the information is needed. Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/acpi/boot.c | 41 +++++++++++++++++++++++++++++++++-------- arch/i386/pci/mmconfig.c | 12 +++++++----- arch/x86_64/pci/mmconfig.c | 16 +++++++++------- 3 files changed, 49 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index f5360d88bc..b7808a89d9 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) #endif #ifdef CONFIG_PCI_MMCONFIG -static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) +/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ +struct acpi_table_mcfg_config *pci_mmcfg_config; +int pci_mmcfg_config_num; + +int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) { struct acpi_table_mcfg *mcfg; + unsigned long i; + int config_size; if (!phys_addr || !size) return -EINVAL; @@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) return -ENODEV; } - if (mcfg->base_reserved) { - printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); + /* how many config structures do we have */ + pci_mmcfg_config_num = 0; + i = size - sizeof(struct acpi_table_mcfg); + while (i >= sizeof(struct acpi_table_mcfg_config)) { + ++pci_mmcfg_config_num; + i -= sizeof(struct acpi_table_mcfg_config); + }; + if (pci_mmcfg_config_num == 0) { + printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); return -ENODEV; } - pci_mmcfg_base_addr = mcfg->base_address; + config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); + pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); + if (!pci_mmcfg_config) { + printk(KERN_WARNING PREFIX + "No memory for MCFG config tables\n"); + return -ENOMEM; + } + + memcpy(pci_mmcfg_config, &mcfg->config, config_size); + for (i = 0; i < pci_mmcfg_config_num; ++i) { + if (mcfg->config[i].base_reserved) { + printk(KERN_ERR PREFIX + "MMCONFIG not in low 4GB of memory\n"); + return -ENODEV; + } + } return 0; } -#else -#define acpi_parse_mcfg NULL -#endif /* !CONFIG_PCI_MMCONFIG */ +#endif /* CONFIG_PCI_MMCONFIG */ #ifdef CONFIG_X86_LOCAL_APIC static int __init @@ -1139,7 +1165,6 @@ int __init acpi_boot_init(void) acpi_process_madt(); acpi_table_parse(ACPI_HPET, acpi_parse_hpet); - acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); return 0; } diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 021a50aa51..5fbaa91322 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -11,11 +11,9 @@ #include #include +#include #include "pci.h" -/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -u32 pci_mmcfg_base_addr; - #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) /* The base address of the last MMCONFIG device accessed */ @@ -27,7 +25,7 @@ static u32 mmcfg_last_accessed_device; static inline void pci_exp_set_dev_base(int bus, int devfn) { - u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); + u32 dev_base = pci_mmcfg_config[0].base_address | (bus << 20) | (devfn << 12); if (dev_base != mmcfg_last_accessed_device) { mmcfg_last_accessed_device = dev_base; set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); @@ -101,7 +99,11 @@ static int __init pci_mmcfg_init(void) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) goto out; - if (!pci_mmcfg_base_addr) + + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + if ((pci_mmcfg_config_num == 0) || + (pci_mmcfg_config == NULL) || + (pci_mmcfg_config[0].base_address == 0)) goto out; /* Kludge for now. Don't use mmconfig on AMD systems because diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index b693c232fd..09cfcc1234 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -7,15 +7,13 @@ #include #include +#include #include "pci.h" #define MMCONFIG_APER_SIZE (256*1024*1024) -/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -u32 pci_mmcfg_base_addr; - /* Static virtual mapping of the MMCONFIG aperture */ -char *pci_mmcfg_virt; +static char *pci_mmcfg_virt; static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) { @@ -77,7 +75,11 @@ static int __init pci_mmcfg_init(void) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) return 0; - if (!pci_mmcfg_base_addr) + + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + if ((pci_mmcfg_config_num == 0) || + (pci_mmcfg_config == NULL) || + (pci_mmcfg_config[0].base_address == 0)) return 0; /* Kludge for now. Don't use mmconfig on AMD systems because @@ -88,13 +90,13 @@ static int __init pci_mmcfg_init(void) return 0; /* RED-PEN i386 doesn't do _nocache right now */ - pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE); + pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_config[0].base_address, MMCONFIG_APER_SIZE); if (!pci_mmcfg_virt) { printk("PCI: Cannot map mmconfig aperture\n"); return 0; } - printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr); + printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[0].base_address); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; -- cgit v1.2.2 From d57e26ceb7dbf44cd08128cb6146116d4281b58b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Jun 2005 17:35:56 -0700 Subject: [PATCH] PCI: use the MCFG table to properly access pci devices (i386) Now that we have access to the whole MCFG table, let's properly use it for all pci device accesses (as that's what it is there for, some boxes don't put all the busses into one entry.) If, for some reason, the table is incorrect, we fallback to the "old style" of mmconfig accesses, namely, we just assume the first entry in the table is the one for us, and blindly use it. Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/mmconfig.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 5fbaa91322..60f0e7a116 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -22,10 +22,31 @@ static u32 mmcfg_last_accessed_device; /* * Functions for accessing PCI configuration space with MMCONFIG accesses */ +static u32 get_base_addr(unsigned int seg, int bus) +{ + int cfg_num = -1; + struct acpi_table_mcfg_config *cfg; + + while (1) { + ++cfg_num; + if (cfg_num >= pci_mmcfg_config_num) { + /* something bad is going on, no cfg table is found. */ + /* so we fall back to the old way we used to do this */ + /* and just rely on the first entry to be correct. */ + return pci_mmcfg_config[0].base_address; + } + cfg = &pci_mmcfg_config[cfg_num]; + if (cfg->pci_segment_group_number != seg) + continue; + if ((cfg->start_bus_number <= bus) && + (cfg->end_bus_number >= bus)) + return cfg->base_address; + } +} -static inline void pci_exp_set_dev_base(int bus, int devfn) +static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn) { - u32 dev_base = pci_mmcfg_config[0].base_address | (bus << 20) | (devfn << 12); + u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12); if (dev_base != mmcfg_last_accessed_device) { mmcfg_last_accessed_device = dev_base; set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); @@ -42,7 +63,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, spin_lock_irqsave(&pci_config_lock, flags); - pci_exp_set_dev_base(bus, devfn); + pci_exp_set_dev_base(seg, bus, devfn); switch (len) { case 1: @@ -71,7 +92,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, spin_lock_irqsave(&pci_config_lock, flags); - pci_exp_set_dev_base(bus, devfn); + pci_exp_set_dev_base(seg, bus, devfn); switch (len) { case 1: -- cgit v1.2.2 From 1cde8a16815bd85c8137d1ea556398983c597c11 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Jun 2005 17:35:56 -0700 Subject: [PATCH] PCI: use the MCFG table to properly access pci devices (x86-64) Now that we have access to the whole MCFG table, let's properly use it for all pci device accesses (as that's what it is there for, some boxes don't put all the busses into one entry.) If, for some reason, the table is incorrect, we fallback to the "old style" of mmconfig accesses, namely, we just assume the first entry in the table is the one for us, and blindly use it. Signed-off-by: Greg Kroah-Hartman --- arch/x86_64/pci/mmconfig.c | 58 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 09cfcc1234..657e88aa09 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -13,17 +13,44 @@ #define MMCONFIG_APER_SIZE (256*1024*1024) /* Static virtual mapping of the MMCONFIG aperture */ -static char *pci_mmcfg_virt; +struct mmcfg_virt { + struct acpi_table_mcfg_config *cfg; + char *virt; +}; +static struct mmcfg_virt *pci_mmcfg_virt; -static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) +static char *get_virt(unsigned int seg, int bus) { - return pci_mmcfg_virt + ((bus << 20) | (devfn << 12)); + int cfg_num = -1; + struct acpi_table_mcfg_config *cfg; + + while (1) { + ++cfg_num; + if (cfg_num >= pci_mmcfg_config_num) { + /* something bad is going on, no cfg table is found. */ + /* so we fall back to the old way we used to do this */ + /* and just rely on the first entry to be correct. */ + return pci_mmcfg_virt[0].virt; + } + cfg = pci_mmcfg_virt[cfg_num].cfg; + if (cfg->pci_segment_group_number != seg) + continue; + if ((cfg->start_bus_number <= bus) && + (cfg->end_bus_number >= bus)) + return pci_mmcfg_virt[cfg_num].virt; + } +} + +static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) +{ + + return get_virt(seg, bus) + ((bus << 20) | (devfn << 12)); } static int pci_mmcfg_read(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 *value) { - char *addr = pci_dev_base(bus, devfn); + char *addr = pci_dev_base(seg, bus, devfn); if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; @@ -46,7 +73,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, static int pci_mmcfg_write(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 value) { - char *addr = pci_dev_base(bus,devfn); + char *addr = pci_dev_base(seg, bus, devfn); if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; @@ -73,6 +100,8 @@ static struct pci_raw_ops pci_mmcfg = { static int __init pci_mmcfg_init(void) { + int i; + if ((pci_probe & PCI_PROBE_MMCONF) == 0) return 0; @@ -90,13 +119,22 @@ static int __init pci_mmcfg_init(void) return 0; /* RED-PEN i386 doesn't do _nocache right now */ - pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_config[0].base_address, MMCONFIG_APER_SIZE); - if (!pci_mmcfg_virt) { - printk("PCI: Cannot map mmconfig aperture\n"); + pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); + if (pci_mmcfg_virt == NULL) { + printk("PCI: Can not allocate memory for mmconfig structures\n"); return 0; - } + } + for (i = 0; i < pci_mmcfg_config_num; ++i) { + pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; + pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE); + if (!pci_mmcfg_virt[i].virt) { + printk("PCI: Cannot map mmconfig aperture for segment %d\n", + pci_mmcfg_config[i].pci_segment_group_number); + return 0; + } + printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address); + } - printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[0].base_address); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; -- cgit v1.2.2 From 564c90aa07cd43dc434d46cef8a15773a23d49a2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Jun 2005 13:46:09 +0100 Subject: [PATCH] ARM SMP: Use local_flush_tlb* where we really want to be local Signed-off-by: Russell King --- arch/arm/mm/init.c | 2 +- arch/arm/mm/mm-armv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 6dcb23d64b..edffa47a4b 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -437,7 +437,7 @@ void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) memtable_init(mi); if (mdesc->map_io) mdesc->map_io(); - flush_tlb_all(); + local_flush_tlb_all(); /* * initialise the zones within each node diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 052ab443ec..c3bd503b43 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -682,7 +682,7 @@ void __init memtable_init(struct meminfo *mi) } flush_cache_all(); - flush_tlb_all(); + local_flush_tlb_all(); top_pmd = pmd_off_k(0xffff0000); } -- cgit v1.2.2 From 4b0ef3b1127776d4a2787d7530ac0c4da82c2331 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Jun 2005 13:49:16 +0100 Subject: [PATCH] ARM SMP: Add IPI support code for SMP TLB flushing Signed-off-by: Russell King --- arch/arm/kernel/smp.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) (limited to 'arch') diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 34892758f0..a931409c8f 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -502,3 +502,126 @@ int __init setup_profiling_timer(unsigned int multiplier) { return -EINVAL; } + +static int +on_each_cpu_mask(void (*func)(void *), void *info, int retry, int wait, + cpumask_t mask) +{ + int ret = 0; + + preempt_disable(); + + ret = smp_call_function_on_cpu(func, info, retry, wait, mask); + if (cpu_isset(smp_processor_id(), mask)) + func(info); + + preempt_enable(); + + return ret; +} + +/**********************************************************************/ + +/* + * TLB operations + */ +struct tlb_args { + struct vm_area_struct *ta_vma; + unsigned long ta_start; + unsigned long ta_end; +}; + +static inline void ipi_flush_tlb_all(void *ignored) +{ + local_flush_tlb_all(); +} + +static inline void ipi_flush_tlb_mm(void *arg) +{ + struct mm_struct *mm = (struct mm_struct *)arg; + + local_flush_tlb_mm(mm); +} + +static inline void ipi_flush_tlb_page(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_page(ta->ta_vma, ta->ta_start); +} + +static inline void ipi_flush_tlb_kernel_page(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_kernel_page(ta->ta_start); +} + +static inline void ipi_flush_tlb_range(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end); +} + +static inline void ipi_flush_tlb_kernel_range(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end); +} + +void flush_tlb_all(void) +{ + on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1); +} + +void flush_tlb_mm(struct mm_struct *mm) +{ + cpumask_t mask = mm->cpu_vm_mask; + + on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, 1, mask); +} + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) +{ + cpumask_t mask = vma->vm_mm->cpu_vm_mask; + struct tlb_args ta; + + ta.ta_vma = vma; + ta.ta_start = uaddr; + + on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, 1, mask); +} + +void flush_tlb_kernel_page(unsigned long kaddr) +{ + struct tlb_args ta; + + ta.ta_start = kaddr; + + on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1, 1); +} + +void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + cpumask_t mask = vma->vm_mm->cpu_vm_mask; + struct tlb_args ta; + + ta.ta_vma = vma; + ta.ta_start = start; + ta.ta_end = end; + + on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, 1, mask); +} + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + struct tlb_args ta; + + ta.ta_start = start; + ta.ta_end = end; + + on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1, 1); +} -- cgit v1.2.2 From 66b7f8a30437b8639e798f7db8e9be1da5711efa Mon Sep 17 00:00:00 2001 From: Mark Maule Date: Mon, 25 Apr 2005 13:51:00 -0700 Subject: [IA64-SGI] pcdp: add PCDP pci interface support Resend 2 with changes per Bjorn Helgaas comments. Changes from original: + Change globals to vga_console_iobase/vga_console_membase and make them unconditional. + Address style-related comments. Patch to extend the PCDP vga setup code to support PCI io/mem translations for the legacy vga ioport and ram spaces on architectures (e.g. altix) which need them. Summary of the changes: drivers/firmware/pcdp.c drivers/firmware/pcdp.h ----------------------- + add declaration for the spec-defined PCI interface struct (pcdp_if_pci) as well as support macros. + extend setup_vga_console() to know about pcdp_if_pci and add a couple of globals to hold the io and mem translation offsets if present. arch/ia64/kernel/setup.c ------------------------ + tweek early_console_setup() to allow multiple early console setup routines to be called. include/asm-ia64/vga.h ---------------------- + make VGA_MAP_MEM vga_console_membase aware Signed-off-by: Mark Maule Signed-off-by: Tony Luck --- arch/ia64/kernel/setup.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index d14692e092..2693e1522d 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -72,6 +72,8 @@ DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); unsigned long ia64_cycles_per_usec; struct ia64_boot_param *ia64_boot_param; struct screen_info screen_info; +unsigned long vga_console_iobase; +unsigned long vga_console_membase; unsigned long ia64_max_cacheline_size; unsigned long ia64_iobase; /* virtual address for I/O accesses */ @@ -273,23 +275,25 @@ io_port_init (void) static inline int __init early_console_setup (char *cmdline) { + int earlycons = 0; + #ifdef CONFIG_SERIAL_SGI_L1_CONSOLE { extern int sn_serial_console_early_setup(void); if (!sn_serial_console_early_setup()) - return 0; + earlycons++; } #endif #ifdef CONFIG_EFI_PCDP if (!efi_setup_pcdp_console(cmdline)) - return 0; + earlycons++; #endif #ifdef CONFIG_SERIAL_8250_CONSOLE if (!early_serial_console_init(cmdline)) - return 0; + earlycons++; #endif - return -1; + return (earlycons) ? 0 : -1; } static inline void -- cgit v1.2.2 From a9f9de7378e3a81f7266f542f2290399a298ef52 Mon Sep 17 00:00:00 2001 From: Mark Maule Date: Tue, 26 Apr 2005 08:01:00 -0700 Subject: [IA64-SGI] altix: enable vgacon support Altix patch to enable use of vgacon driver on that platform. Depends on the PCDP generalization patch discussed at: http://marc.theaimsgroup.com/?l=linux-ia64&m=111446235101939&w=2 Signed-off-by: Mark Maule Signed-off-by: Tony Luck --- arch/ia64/configs/sn2_defconfig | 4 ++-- arch/ia64/sn/kernel/iomv.c | 6 ++++++ arch/ia64/sn/kernel/setup.c | 16 ++++++++++------ 3 files changed, 18 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index 487d2e36b0..c056139803 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig @@ -99,7 +99,7 @@ CONFIG_ACPI_DEALLOCATE_IRQ=y # Firmware Drivers # CONFIG_EFI_VARS=y -# CONFIG_EFI_PCDP is not set +CONFIG_EFI_PCDP=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set @@ -650,7 +650,7 @@ CONFIG_MMTIMER=y # # Console display driver support # -# CONFIG_VGA_CONSOLE is not set +CONFIG_VGA_CONSOLE=y CONFIG_DUMMY_CONSOLE=y # diff --git a/arch/ia64/sn/kernel/iomv.c b/arch/ia64/sn/kernel/iomv.c index fec6d8b823..7ce3cdad62 100644 --- a/arch/ia64/sn/kernel/iomv.c +++ b/arch/ia64/sn/kernel/iomv.c @@ -9,12 +9,16 @@ #include #include #include +#include #include #include #include #include #include +#define IS_LEGACY_VGA_IOPORT(p) \ + (((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df)) + /** * sn_io_addr - convert an in/out port to an i/o address * @port: port to convert @@ -26,6 +30,8 @@ void *sn_io_addr(unsigned long port) { if (!IS_RUNNING_ON_SIMULATOR()) { + if (IS_LEGACY_VGA_IOPORT(port)) + port += vga_console_iobase; /* On sn2, legacy I/O ports don't point at anything */ if (port < (64 * 1024)) return NULL; diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 44bfc7f318..3e5ba34ac2 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -273,14 +274,17 @@ void __init sn_setup(char **cmdline_p) ia64_sn_plat_set_error_handling_features(); +#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) /* - * If the generic code has enabled vga console support - lets - * get rid of it again. This is a kludge for the fact that ACPI - * currtently has no way of informing us if legacy VGA is available - * or not. + * If there was a primary vga adapter identified through the + * EFI PCDP table, make it the preferred console. Otherwise + * zero out conswitchp. */ -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) - if (conswitchp == &vga_con) { + + if (vga_console_membase) { + /* usable vga ... make tty0 the preferred default console */ + add_preferred_console("tty", 0, NULL); + } else { printk(KERN_DEBUG "SGI: Disabling VGA console\n"); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; -- cgit v1.2.2 From e15da40176f16050c8d92b36387a49370317e276 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 3 May 2005 12:07:00 -0700 Subject: [IA64] Recognize HP sx2000 chipset No functional change, just identify the device nicely: -IOC: Unknown (103c:12ec) 0.1 HPA 0xf8020002000 IOVA space 1024Mb at 0x40000000 +IOC: sx2000 0.1 HPA 0xf8020002000 IOVA space 1024Mb at 0x40000000 We used to create fake PCI devices for these chips, but we no longer do that. So I don't think there's any reason to touch pci_ids.h now. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/hp/common/sba_iommu.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index b8db6e3e5e..11957598a8 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -156,10 +156,13 @@ */ #define DELAYED_RESOURCE_CNT 64 +#define PCI_DEVICE_ID_HP_SX2000_IOC 0x12ec + #define ZX1_IOC_ID ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX2_IOC_ID ((PCI_DEVICE_ID_HP_ZX2_IOC << 16) | PCI_VENDOR_ID_HP) #define REO_IOC_ID ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP) #define SX1000_IOC_ID ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP) +#define SX2000_IOC_ID ((PCI_DEVICE_ID_HP_SX2000_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */ @@ -1726,6 +1729,7 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = { { ZX1_IOC_ID, "zx1", ioc_zx1_init }, { ZX2_IOC_ID, "zx2", NULL }, { SX1000_IOC_ID, "sx1000", NULL }, + { SX2000_IOC_ID, "sx2000", NULL }, }; static struct ioc * __init -- cgit v1.2.2 From 458f935527372499b714bf4f8e646a68bb0f52e3 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 4 May 2005 13:25:00 -0700 Subject: [IA64] Speed up lfetch.fault [NULL] This patch greatly speeds up the handling of lfetch.fault instructions which result in NaT consumption. Due to the NaT-page mapped at address 0, this is guaranteed to happen when lfetch.fault'ing a NULL pointer. With this patch in place, we can even define prefetch()/prefetchw() as lfetch.fault without significant performance degradation. More importantly, it allows compilers to be more aggressive with using lfetch.fault on pointers that might be NULL. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/ivt.S | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index b28d2212a7..3bb3a13c40 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -1243,6 +1243,25 @@ END(disabled_fp_reg) // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50) ENTRY(nat_consumption) DBG_FAULT(26) + + mov r16=cr.ipsr + mov r17=cr.isr + mov r31=pr // save PR + ;; + and r18=0xf,r17 // r18 = cr.ipsr.code{3:0} + tbit.z p6,p0=r17,IA64_ISR_NA_BIT + ;; + cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18 + dep r16=-1,r16,IA64_PSR_ED_BIT,1 +(p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH) + ;; + mov cr.ipsr=r16 // set cr.ipsr.na + mov pr=r31,-1 + ;; + rfi + +1: mov pr=r31,-1 + ;; FAULT(26) END(nat_consumption) -- cgit v1.2.2 From 8e4641b3ee8073a46995cf97e0875df25b88d776 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Mon, 9 May 2005 05:07:00 -0700 Subject: [IA64] sparse cleanup of shub_mmr.h This patch is a sparse compile cleanup of shub_mmr.h using both the defconfig and the sn2_defconfig config files. The issue with this file was the missing usage of __IA64_UL_CONST wrapper. This wrapper is defined in include/asm-ia64/types.h and wraps a long constant definition with UL or with nothing depending on its usage in the kernel. The missing wrapper caused many sparse compile errors like warning: constant 0x0x0000000010000380 so big it is long Signed-off-by: Prarit Bhargava Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/sn2/ptc_deadlock.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S index 7947312801..96cb71d156 100644 --- a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S +++ b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S @@ -6,6 +6,7 @@ * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved. */ +#include #include #define DEADLOCKBIT SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT -- cgit v1.2.2 From 71a5d027c90dd7e14ddaaf22358ff5138ba89ec9 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Tue, 10 May 2005 08:01:00 -0700 Subject: [IA64-SGI] - new macros for SGI SN simulator This patch changes some macros that are used when running kernel on the SGI simulator. Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/io_init.c | 2 +- arch/ia64/sn/kernel/setup.c | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 9e07f5463f..783eb43238 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -384,7 +384,7 @@ static int __init sn_pci_init(void) extern void register_sn_procfs(void); #endif - if (!ia64_platform_is("sn2") || IS_RUNNING_ON_SIMULATOR()) + if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; /* diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 3e5ba34ac2..22e10d282c 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -96,6 +96,7 @@ u8 sn_coherency_id; EXPORT_SYMBOL(sn_coherency_id); u8 sn_region_size; EXPORT_SYMBOL(sn_region_size); +int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */ short physical_node_map[MAX_PHYSNODE_ID]; @@ -354,7 +355,7 @@ void __init sn_setup(char **cmdline_p) ia64_mark_idle = &snidle; - /* + /* * For the bootcpu, we do this here. All other cpus will make the * call as part of cpu_init in slave cpu initialization. */ @@ -401,7 +402,7 @@ static void __init sn_init_pdas(char **cmdline_p) nodepdaindr[cnode] = alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t)); memset(nodepdaindr[cnode], 0, sizeof(nodepda_t)); - memset(nodepdaindr[cnode]->phys_cpuid, -1, + memset(nodepdaindr[cnode]->phys_cpuid, -1, sizeof(nodepdaindr[cnode]->phys_cpuid)); } @@ -431,7 +432,7 @@ static void __init sn_init_pdas(char **cmdline_p) } /* - * Initialize the per node hubdev. This includes IO Nodes and + * Initialize the per node hubdev. This includes IO Nodes and * headless/memless nodes. */ for (cnode = 0; cnode < numionodes; cnode++) { @@ -459,6 +460,14 @@ void __init sn_cpu_init(void) int i; static int wars_have_been_checked; + if (smp_processor_id() == 0 && IS_MEDUSA()) { + if (ia64_sn_is_fake_prom()) + sn_prom_type = 2; + else + sn_prom_type = 1; + printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake"); + } + memset(pda, 0, sizeof(pda)); if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift, &sn_system_size, &sn_sharing_domain_size, &sn_partition_id, @@ -524,7 +533,7 @@ void __init sn_cpu_init(void) */ { u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0}; - u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1, + u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3}; u64 *pio; pio = is_shub1() ? pio1 : pio2; @@ -556,6 +565,10 @@ static void __init scan_for_ionodes(void) int nasid = 0; lboard_t *brd; + /* fakeprom does not support klgraph */ + if (IS_RUNNING_ON_FAKE_PROM()) + return; + /* Setup ionodes with memory */ for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) { char *klgraph_header; @@ -567,8 +580,6 @@ static void __init scan_for_ionodes(void) cnodeid = -1; klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid)); if (!klgraph_header) { - if (IS_RUNNING_ON_SIMULATOR()) - continue; BUG(); /* All nodes must have klconfig tables! */ } cnodeid = nasid_to_cnodeid(nasid); @@ -634,8 +645,8 @@ int nasid_slice_to_cpuid(int nasid, int slice) { long cpu; - - for (cpu=0; cpu < NR_CPUS; cpu++) + + for (cpu=0; cpu < NR_CPUS; cpu++) if (cpuid_to_nasid(cpu) == nasid && cpuid_to_slice(cpu) == slice) return cpu; -- cgit v1.2.2 From 92a582ed2757456ca9599f8b4ea2064f2154eb02 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Tue, 10 May 2005 12:40:00 -0700 Subject: [IA64] sparse cleanup of TIOCA files This patch is a sparse compile cleanup of tioca_provider.c, sn_hwperf.h, and tioca_provider.h. Each of these files had sparse warnings when compiled. Signed-off-by: Prarit Bhargava Signed-off-by: Tony Luck --- arch/ia64/sn/pci/tioca_provider.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index 8dae9eb454..05aa8c2fe9 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -336,7 +336,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) if (!ct_addr) return 0; - bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffff); + bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL); node_upper = ct_addr >> 48; if (node_upper > 64) { @@ -464,7 +464,7 @@ map_return: * For mappings created using the direct modes (64 or 48) there are no * resources to release. */ -void +static void tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) { int i, entry; @@ -514,7 +514,7 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) * The mapping mode used is based on the devices dma_mask. As a last resort * use the GART mapped mode. */ -uint64_t +static uint64_t tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) { uint64_t mapaddr; @@ -580,7 +580,7 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt) * On successful setup, returns the kernel version of tioca_common back to * the caller. */ -void * +static void * tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft) { struct tioca_common *tioca_common; -- cgit v1.2.2 From c1ffb6a8aaed45ba2dc0a8f09241b0a96f9955ba Mon Sep 17 00:00:00 2001 From: Bruce Losure Date: Tue, 24 May 2005 08:30:00 -0700 Subject: [IA64-SGI] Altix patch to tiocx, add subsys_initcall This patch fixes an ordering issue between the init code for the tiocx bus driver and tiocx-related device drivers. Also adds a new brick to the list of known FPGA bricks. Signed-off-by: Bruce Losure Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/tiocx.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index a087b27484..8716f4d531 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -204,8 +204,8 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num, cx_dev->dev.parent = NULL; cx_dev->dev.bus = &tiocx_bus_type; cx_dev->dev.release = tiocx_bus_release; - snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d.0x%x", - cx_dev->cx_id.nasid, cx_dev->cx_id.part_num); + snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d", + cx_dev->cx_id.nasid); device_register(&cx_dev->dev); get_device(&cx_dev->dev); @@ -236,7 +236,6 @@ int cx_device_unregister(struct cx_dev *cx_dev) */ static int cx_device_reload(struct cx_dev *cx_dev) { - device_remove_file(&cx_dev->dev, &dev_attr_cxdev_control); cx_device_unregister(cx_dev); return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num, cx_dev->hubdev); @@ -383,6 +382,7 @@ static int is_fpga_brick(int nasid) switch (tiocx_btchar_get(nasid)) { case L1_BRICKTYPE_SA: case L1_BRICKTYPE_ATHENA: + case L1_BRICKTYPE_DAYTONA: return 1; } return 0; @@ -409,7 +409,7 @@ static int tiocx_reload(struct cx_dev *cx_dev) uint64_t cx_id; cx_id = - *(volatile int32_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) + + *(volatile uint64_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) + WIDGET_ID); part_num = XWIDGET_PART_NUM(cx_id); mfg_num = XWIDGET_MFG_NUM(cx_id); @@ -458,6 +458,10 @@ static ssize_t store_cxdev_control(struct device *dev, struct device_attribute * switch (n) { case 1: + tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET); + tiocx_reload(cx_dev); + break; + case 2: tiocx_reload(cx_dev); break; case 3: @@ -537,7 +541,7 @@ static void __exit tiocx_exit(void) bus_unregister(&tiocx_bus_type); } -module_init(tiocx_init); +subsys_initcall(tiocx_init); module_exit(tiocx_exit); /************************************************************************ -- cgit v1.2.2 From 819c67e69c4e0062787e27dd989f5f9d00d4834e Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Thu, 9 Jun 2005 22:40:00 -0700 Subject: [IA64] Replace stale KDB-code with useful MAGIC_SYSRQ code in simserial.c Patch makes it possible to use the "F4" function key to do magic sysrq in the HP Ski simulator. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/hp/sim/simserial.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 786e70718c..7a8ae0f4b3 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -149,12 +150,17 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs) seen_esc = 2; continue; } else if ( seen_esc == 2 ) { - if ( ch == 'P' ) show_state(); /* F1 key */ -#ifdef CONFIG_KDB - if ( ch == 'S' ) - kdb(KDB_REASON_KEYBOARD, 0, (kdb_eframe_t) regs); + if ( ch == 'P' ) /* F1 */ + show_state(); +#ifdef CONFIG_MAGIC_SYSRQ + if ( ch == 'S' ) { /* F4 */ + do + ch = ia64_ssc(0, 0, 0, 0, + SSC_GETCHAR); + while (!ch); + handle_sysrq(ch, regs, NULL); + } #endif - seen_esc = 0; continue; } -- cgit v1.2.2 From a68db763af9b676590c3fe9ec3f17bf18015eb2f Mon Sep 17 00:00:00 2001 From: Peter Chubb Date: Thu, 23 Jun 2005 21:14:00 -0700 Subject: [IA64] Fix another IA64 preemption problem There's another problem shown up by Ingo's recent patch to make smp_processor_id() complain if it's called with preemption enabled. local_finish_flush_tlb_mm() calls activate_context() in a situation where it could be rescheduled to another processor. This patch disables preemption around the call. Signed-off-by: Peter Chubb Signed-off-by: Tony Luck --- arch/ia64/kernel/smp.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index b49d4ddaab..0166a98470 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -231,13 +231,16 @@ smp_flush_tlb_all (void) void smp_flush_tlb_mm (struct mm_struct *mm) { + preempt_disable(); /* this happens for the common case of a single-threaded fork(): */ if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1)) { local_finish_flush_tlb_mm(mm); + preempt_enable(); return; } + preempt_enable(); /* * We could optimize this further by using mm->cpu_vm_mask to track which CPUs * have been running in the address space. It's not clear that this is worth the -- cgit v1.2.2 From fa0ebff62a8a25952a082641db0ed6b1cfc6c38c Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Tue, 28 Jun 2005 21:01:03 +0100 Subject: [PATCH] ARM: 2761/1: OProfile: Add call graphing support for arm Patch from Richard Purdie Add functions to generate backtraces of both kernel and user processes which allows oprofile's call graphing functionality to be used on arm. This requires unstripped binaries/libs which use a frame pointer. Signed-off-by: Richard Purdie Signed-off-by: Zwane Mwaikambo Signed-off-by: Russell King --- arch/arm/oprofile/Makefile | 2 +- arch/arm/oprofile/backtrace.c | 144 +++++++++++++++++++++++++++++++++++++++ arch/arm/oprofile/init.c | 2 + arch/arm/oprofile/op_arm_model.h | 2 + 4 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 arch/arm/oprofile/backtrace.c (limited to 'arch') diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile index ba1a6e9f2b..8ffb523e6c 100644 --- a/arch/arm/oprofile/Makefile +++ b/arch/arm/oprofile/Makefile @@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ oprofilefs.o oprofile_stats.o \ timer_int.o ) -oprofile-y := $(DRIVER_OBJS) init.o +oprofile-y := $(DRIVER_OBJS) init.o backtrace.o oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c new file mode 100644 index 0000000000..ec58d3e2eb --- /dev/null +++ b/arch/arm/oprofile/backtrace.c @@ -0,0 +1,144 @@ +/* + * Arm specific backtracing code for oprofile + * + * Copyright 2005 Openedhand Ltd. + * + * Author: Richard Purdie + * + * Based on i386 oprofile backtrace code by John Levon, David Smith + * + * 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. + * + */ + +#include +#include +#include +#include +#include + + +/* + * The registers we're interested in are at the end of the variable + * length saved register structure. The fp points at the end of this + * structure so the address of this struct is: + * (struct frame_tail *)(xxx->fp)-1 + */ +struct frame_tail { + struct frame_tail *fp; + unsigned long sp; + unsigned long lr; +} __attribute__((packed)); + + +#ifdef CONFIG_FRAME_POINTER +static struct frame_tail* kernel_backtrace(struct frame_tail *tail) +{ + oprofile_add_trace(tail->lr); + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (tail >= tail->fp) + return NULL; + + return tail->fp-1; +} +#endif + +static struct frame_tail* user_backtrace(struct frame_tail *tail) +{ + struct frame_tail buftail; + + /* hardware pte might not be valid due to dirty/accessed bit emulation + * so we use copy_from_user and benefit from exception fixups */ + if (copy_from_user(&buftail, tail, sizeof(struct frame_tail))) + return NULL; + + oprofile_add_trace(buftail.lr); + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (tail >= buftail.fp) + return NULL; + + return buftail.fp-1; +} + +/* Compare two addresses and see if they're on the same page */ +#define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \ + == ((((unsigned long) y) + offset) >> PAGE_SHIFT)) + +/* check that the page(s) containing the frame tail are present */ +static int pages_present(struct frame_tail *tail) +{ + struct mm_struct * mm = current->mm; + + if (!check_user_page_readable(mm, (unsigned long)tail)) + return 0; + + if (CMP_ADDR_EQUAL(tail, tail, 8)) + return 1; + + if (!check_user_page_readable(mm, ((unsigned long)tail) + 8)) + return 0; + + return 1; +} + +/* + * | | /\ Higher addresses + * | | + * --------------- stack base (address of current_thread_info) + * | thread info | + * . . + * | stack | + * --------------- saved regs->ARM_fp value if valid (frame_tail address) + * . . + * --------------- struct pt_regs stored on stack (struct pt_regs *) + * | | + * . . + * | | + * --------------- %esp + * | | + * | | \/ Lower addresses + * + * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values + */ +static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs) +{ + unsigned long tailaddr = (unsigned long)tail; + unsigned long stack = (unsigned long)regs; + unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE; + + return (tailaddr > stack) && (tailaddr < stack_base); +} + +void arm_backtrace(struct pt_regs const *regs, unsigned int depth) +{ + struct frame_tail *tail; + unsigned long last_address = 0; + + tail = ((struct frame_tail *) regs->ARM_fp) - 1; + + if (!user_mode(regs)) { + +#ifdef CONFIG_FRAME_POINTER + while (depth-- && tail && valid_kernel_stack(tail, regs)) { + tail = kernel_backtrace(tail); + } +#endif + return; + } + + while (depth-- && tail && !((unsigned long) tail & 3)) { + if ((!CMP_ADDR_EQUAL(last_address, tail, 0) + || !CMP_ADDR_EQUAL(last_address, tail, 8)) + && !pages_present(tail)) + return; + last_address = (unsigned long) tail; + tail = user_backtrace(tail); + } +} + diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c index cce3d3015e..d315a3a86c 100644 --- a/arch/arm/oprofile/init.c +++ b/arch/arm/oprofile/init.c @@ -20,6 +20,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ret = pmu_init(ops, &op_xscale_spec); #endif + ops->backtrace = arm_backtrace; + return ret; } diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h index 2d4caf4781..2148d07484 100644 --- a/arch/arm/oprofile/op_arm_model.h +++ b/arch/arm/oprofile/op_arm_model.h @@ -24,6 +24,8 @@ struct op_arm_model_spec { extern struct op_arm_model_spec op_xscale_spec; #endif +extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth); + extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); extern void pmu_exit(void); #endif /* OP_ARM_MODEL_H */ -- cgit v1.2.2 From f2be64b3b15f52ceb83ff26abc10705a31ae5352 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 28 Jun 2005 21:01:16 +0100 Subject: [PATCH] ARM: 2760/1: Add a warning on dynamic tick timekeeping on some platforms Patch from Tony Lindgren This patch was suggested by RMK, and adds a warning on the accuracy of timekeeping when using dynamic tick on some platforms. Depending on the timer implementation, dynamic tick may affect the accuracy of timekeeping. Currently at least OMAP is known to have accurate timekeeping with dynamic tick. Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c8d94dcd8e..620f2ca94e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -361,6 +361,11 @@ config NO_IDLE_HZ Alternatively, if you want dynamic tick automatically enabled during boot, pass "dyntick=enable" via the kernel command string. + Please note that dynamic tick may affect the accuracy of + timekeeping on some platforms depending on the implementation. + Currently at least OMAP platform is known to have accurate + timekeeping with dynamic tick. + config ARCH_DISCONTIGMEM_ENABLE bool default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) -- cgit v1.2.2 From 50273978975ee62938b7ca612e281927cd789c13 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 28 Jun 2005 22:42:06 +0100 Subject: [PATCH] ARM: 2763/1: S3C24XX - mark IRQ_LCD as valid Patch from Ben Dooks Fix the IRQ_LCD so that it is marked as valid since we no longer de-mux this in the main IRQ handler. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/irq.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index b668c48f43..cf9f46d880 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -40,8 +40,11 @@ * 04-Nov-2004 Ben Dooks * Fix standard IRQ wake for EINT0..4 and RTC * - * 22-Feb-2004 Ben Dooks + * 22-Feb-2005 Ben Dooks * Fixed edge-triggering on ADC IRQ + * + * 28-Jun-2005 Ben Dooks + * Mark IRQ_LCD valid */ #include @@ -366,7 +369,6 @@ static struct irqchip s3c_irq_eint0t4 = { #define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0)) #define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) -#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) static inline void s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, @@ -716,7 +718,6 @@ void __init s3c24xx_init_irq(void) case IRQ_UART0: case IRQ_UART1: case IRQ_UART2: - case IRQ_LCD: case IRQ_ADCPARENT: set_irq_chip(irqno, &s3c_irq_level_chip); set_irq_handler(irqno, do_level_IRQ); -- cgit v1.2.2 From a8f5034540195307362d071a8b387226b410469f Mon Sep 17 00:00:00 2001 From: "KAMBAROV, ZAUR" Date: Tue, 28 Jun 2005 20:45:06 -0700 Subject: [PATCH] coverity: i386: build.c: negative return to unsigned fix Variable "c" was declared as an unsigned int, but used in: 125 for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c ) 126 if (write(1, buf, c) != c) 127 die("Write call failed"); (akpm: read() can return -1. If it does, we fill the disk up with garbage). Signed-off-by: Zaur Kambarov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/boot/tools/build.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 4a17956512..6835f6d47c 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c @@ -70,7 +70,8 @@ void usage(void) int main(int argc, char ** argv) { - unsigned int i, c, sz, setup_sectors; + unsigned int i, sz, setup_sectors; + int c; u32 sys_size; byte major_root, minor_root; struct stat sb; -- cgit v1.2.2 From 200803dfe4ff772740d63db725ab2f1b185ccf92 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 28 Jun 2005 20:45:18 -0700 Subject: [PATCH] irqpoll Anyone reporting a stuck IRQ should try these options. Its effectiveness varies we've found in the Fedora case. Quite a few systems with misdescribed IRQ routing just work when you use irqpoll. It also fixes up the VIA systems although thats now fixed with the VIA quirk (which we could just make default as its what Redmond OS does but Linus didn't like it historically). A small number of systems have jammed IRQ sources or misdescribes that cause an IRQ that we have no handler registered anywhere for. In those cases it doesn't help. Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 3defc8c33a..ffe300611f 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -245,7 +245,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) spin_lock(&desc->lock); if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + note_interrupt(irq, desc, action_ret, regs); if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; -- cgit v1.2.2 From 2668fb91cbfbd5e6799017a3579f20309aac758b Mon Sep 17 00:00:00 2001 From: William Lee Irwin III Date: Tue, 28 Jun 2005 20:45:31 -0700 Subject: [PATCH] sparc32: Kconfig fixups Something reverted most of the arch/sparc/Kconfig changes, leaving arch/sparc/ unconfigurable. This patch re-removes the parts made redundant by drivers/Kconfig in addition to a mysterious, spurious second instance of source "mm/Kconfig". cvs strikes again? Signed-off-by: William Irwin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc/Kconfig | 56 ------------------------------------------------------ 1 file changed, 56 deletions(-) (limited to 'arch') diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 262e13d086..7a117ef473 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -270,66 +270,10 @@ endmenu source "drivers/Kconfig" -config PRINTER - tristate "Parallel printer support" - depends on PARPORT - ---help--- - If you intend to attach a printer to the parallel port of your Linux - box (as opposed to using a serial printer; if the connector at the - printer has 9 or 25 holes ["female"], then it's serial), say Y. - Also read the Printing-HOWTO, available from - . - - It is possible to share one parallel port among several devices - (e.g. printer and ZIP drive) and it is safe to compile the - corresponding drivers into the kernel. If you want to compile this - driver as a module however, choose M here and read - . The module will be called lp. - - If you have several parallel ports, you can specify which ports to - use with the "lp" kernel command line option. (Try "man bootparam" - or see the documentation of your boot loader (silo) about how to pass - options to the kernel at boot time.) The syntax of the "lp" command - line option can be found in . - - If you have more than 8 printers, you need to increase the LP_NO - macro in lp.c and the PARPORT_MAX macro in parport.h. - -source "mm/Kconfig" - -endmenu - -source "drivers/base/Kconfig" - -source "drivers/video/Kconfig" - -source "drivers/mtd/Kconfig" - -source "drivers/serial/Kconfig" - if !SUN4 source "drivers/sbus/char/Kconfig" endif -source "drivers/block/Kconfig" - -# Don't frighten a common SBus user -if PCI - -source "drivers/ide/Kconfig" - -endif - -source "drivers/isdn/Kconfig" - -source "drivers/scsi/Kconfig" - -source "drivers/fc4/Kconfig" - -source "drivers/md/Kconfig" - -source "net/Kconfig" - # This one must be before the filesystem configs. -DaveM menu "Unix98 PTY support" -- cgit v1.2.2 From f705b1aed7002495a504086705ff9725ed9412dc Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 29 Jun 2005 11:09:15 +0100 Subject: [PATCH] ARM: 2764/1: S3C24XX - Common PM functions for Simtec boards Patch from Ben Dooks All current S3C24XX implementations from Simtec share the same requirements for suspend/resume information. This patch moves the save code out of the mach-bast.c file, and into it's own so it can be shared by all the current Simtec S3C24XX implementations. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/Kconfig | 5 +++ arch/arm/mach-s3c2410/Makefile | 1 + arch/arm/mach-s3c2410/mach-bast.c | 39 +++-------------------- arch/arm/mach-s3c2410/pm-simtec.c | 65 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 35 deletions(-) create mode 100644 arch/arm/mach-s3c2410/pm-simtec.c (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 534df0c6c7..d4d03d0daa 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -154,6 +154,11 @@ config S3C2410_PM_CHECK_CHUNKSIZE the CRC data block will take more memory, but wil identify any faults with better precision. +config PM_SIMTEC + bool + depends on PM && (ARCH_BAST || MACH_VR1000) + default y + config S3C2410_LOWLEVEL_UART_PORT int "S3C2410 UART to use for low-level messages" default 0 diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 7c379aad5d..f99b689e43 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o # Power Management support obj-$(CONFIG_PM) += pm.o sleep.o +obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o # S3C2440 support diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index f3e970039b..549bcb1f32 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -27,6 +27,7 @@ * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA * 14-Mar-2006 BJD Updated for __iomem changes * 22-Jun-2006 BJD Added DM9000 platform information + * 28-Jun-2006 BJD Moved pm functionality out to common code */ #include @@ -67,7 +68,6 @@ #include "devs.h" #include "cpu.h" #include "usb-simtec.h" -#include "pm.h" #define COPYRIGHT ", (c) 2004-2005 Simtec Electronics" @@ -405,44 +405,13 @@ void __init bast_map_io(void) usb_simtec_init(); } -void __init bast_init_irq(void) -{ - s3c24xx_init_irq(); -} - -#ifdef CONFIG_PM - -/* bast_init_machine - * - * enable the power management functions for the EB2410ITX -*/ - -static __init void bast_init_machine(void) -{ - unsigned long gstatus4; - - printk(KERN_INFO "BAST Power Manangement" COPYRIGHT "\n"); - - gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30; - gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28; - gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK); - - __raw_writel(gstatus4, S3C2410_GSTATUS4); - - s3c2410_pm_init(); -} - -#else -#define bast_init_machine NULL -#endif - MACHINE_START(BAST, "Simtec-BAST") MAINTAINER("Ben Dooks ") BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(bast_map_io) - INITIRQ(bast_init_irq) - .init_machine = bast_init_machine, + + .map_io = bast_map_io, + .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c new file mode 100644 index 0000000000..2cb7988322 --- /dev/null +++ b/arch/arm/mach-s3c2410/pm-simtec.c @@ -0,0 +1,65 @@ +/* linux/arch/arm/mach-s3c2410/pm-simtec.c + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks + * + * http://armlinux.simtec.co.uk/ + * + * Power Management helpers for Simtec S3C24XX implementations + * + * 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. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include "pm.h" + +#define COPYRIGHT ", (c) 2005 Simtec Electronics" + +/* pm_simtec_init + * + * enable the power management functions +*/ + +static __init int pm_simtec_init(void) +{ + unsigned long gstatus4; + + /* check which machine we are running on */ + + if (!machine_is_bast() && !machine_is_vr1000()) + return 0; + + printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); + + gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30; + gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28; + gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK); + + __raw_writel(gstatus4, S3C2410_GSTATUS4); + + return s3c2410_pm_init(); +} + +arch_initcall(pm_simtec_init); -- cgit v1.2.2 From 6904b2465cf30265a67711025815784aa345bfad Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 29 Jun 2005 11:09:15 +0100 Subject: [PATCH] ARM: 2765/1: S3C24XX - small cleanups in arch/arm/mach-s3c2410 Patch from Ben Dooks Re-tab the devs.c file, and change the initialiser for the mach-vr1000.c to use `.xxx = yyy` form. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/devs.c | 4 ++-- arch/arm/mach-s3c2410/mach-vr1000.c | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c index 64792f6786..4664bd11ad 100644 --- a/arch/arm/mach-s3c2410/devs.c +++ b/arch/arm/mach-s3c2410/devs.c @@ -96,8 +96,8 @@ struct platform_device s3c_device_lcd = { .num_resources = ARRAY_SIZE(s3c_lcd_resource), .resource = s3c_lcd_resource, .dev = { - .dma_mask = &s3c_device_lcd_dmamask, - .coherent_dma_mask = 0xffffffffUL + .dma_mask = &s3c_device_lcd_dmamask, + .coherent_dma_mask = 0xffffffffUL } }; diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 76be074944..1db2855e3e 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -371,16 +371,12 @@ void __init vr1000_map_io(void) usb_simtec_init(); } -void __init vr1000_init_irq(void) -{ - s3c24xx_init_irq(); -} MACHINE_START(VR1000, "Thorcom-VR1000") MAINTAINER("Ben Dooks ") BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(vr1000_map_io) - INITIRQ(vr1000_init_irq) + .map_io = vr1000_map_io, + .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END -- cgit v1.2.2 From b720f73296916e87c744193c57bc8687d35888fe Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 15:15:54 +0100 Subject: [PATCH] ARM: Convert ARM timer implementations to use readl/writel Convert ARMs timer implementations to use readl/writel instead of accessing the registers via a struct. People have recently asked if accessing timers via a structure is the "right way" and its not the Linux way. So fix this code to conform to "The Linux Way"(tm). Signed-off-by: Russell King Acked-by: Catalin Marinas --- arch/arm/mach-integrator/core.c | 42 ++++++++++------------------ arch/arm/mach-versatile/core.c | 61 ++++++++++++++++------------------------- 2 files changed, 38 insertions(+), 65 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 9222e57bd8..797c7fddaa 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -156,16 +157,6 @@ EXPORT_SYMBOL(cm_control); #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) #endif -/* - * What does it look like? - */ -typedef struct TimerStruct { - unsigned long TimerLoad; - unsigned long TimerValue; - unsigned long TimerControl; - unsigned long TimerClear; -} TimerStruct_t; - static unsigned long timer_reload; /* @@ -174,7 +165,6 @@ static unsigned long timer_reload; */ unsigned long integrator_gettimeoffset(void) { - volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE; unsigned long ticks1, ticks2, status; /* @@ -183,11 +173,11 @@ unsigned long integrator_gettimeoffset(void) * an interrupt. We get around this by ensuring that the * counter has not reloaded between our two reads. */ - ticks2 = timer1->TimerValue & 0xffff; + ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; do { ticks1 = ticks2; status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); - ticks2 = timer1->TimerValue & 0xffff; + ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; } while (ticks2 > ticks1); /* @@ -213,20 +203,19 @@ unsigned long integrator_gettimeoffset(void) static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - write_seqlock(&xtime_lock); /* * clear the interrupt */ - timer1->TimerClear = 1; + writel(1, TIMER1_VA_BASE + TIMER_INTCLR); /* * the clock tick routines are only processed on the * primary CPU */ if (hard_smp_processor_id() == 0) { + nmi_tick(); timer_tick(regs); #ifdef CONFIG_SMP smp_send_timer(); @@ -256,32 +245,29 @@ static struct irqaction integrator_timer_irq = { */ void __init integrator_time_init(unsigned long reload, unsigned int ctrl) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; - unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */ + unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; timer_reload = reload; timer_ctrl |= ctrl; if (timer_reload > 0x100000) { timer_reload >>= 8; - timer_ctrl |= 0x08; /* /256 */ + timer_ctrl |= TIMER_CTRL_DIV256; } else if (timer_reload > 0x010000) { timer_reload >>= 4; - timer_ctrl |= 0x04; /* /16 */ + timer_ctrl |= TIMER_CTRL_DIV16; } /* * Initialise to a known state (all timers off) */ - timer0->TimerControl = 0; - timer1->TimerControl = 0; - timer2->TimerControl = 0; + writel(0, TIMER0_VA_BASE + TIMER_CTRL); + writel(0, TIMER1_VA_BASE + TIMER_CTRL); + writel(0, TIMER2_VA_BASE + TIMER_CTRL); - timer1->TimerLoad = timer_reload; - timer1->TimerValue = timer_reload; - timer1->TimerControl = timer_ctrl; + writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD); + writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE); + writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL); /* * Make irqs happen for the system timer diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 9d1f2253e9..f01c0f8a2b 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -788,38 +789,25 @@ void __init versatile_init(void) */ #define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) #if TIMER_INTERVAL >= 0x100000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */ -#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */ +#define TIMER_RELOAD (TIMER_INTERVAL >> 8) +#define TIMER_DIVISOR (TIMER_CTRL_DIV256) #define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) #elif TIMER_INTERVAL >= 0x10000 #define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ -#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */ +#define TIMER_DIVISOR (TIMER_CTRL_DIV16) #define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) #else #define TIMER_RELOAD (TIMER_INTERVAL) -#define TIMER_CTRL 0x80 /* Enable */ +#define TIMER_DIVISOR (TIMER_CTRL_DIV1) #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) #endif -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ - -/* - * What does it look like? - */ -typedef struct TimerStruct { - unsigned long TimerLoad; - unsigned long TimerValue; - unsigned long TimerControl; - unsigned long TimerClear; -} TimerStruct_t; - /* * Returns number of ms since last clock interrupt. Note that interrupts * will have been disabled by do_gettimeoffset() */ static unsigned long versatile_gettimeoffset(void) { - volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE; unsigned long ticks1, ticks2, status; /* @@ -828,11 +816,11 @@ static unsigned long versatile_gettimeoffset(void) * an interrupt. We get around this by ensuring that the * counter has not reloaded between our two reads. */ - ticks2 = timer0->TimerValue & 0xffff; + ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; do { ticks1 = ticks2; status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); - ticks2 = timer0->TimerValue & 0xffff; + ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; } while (ticks2 > ticks1); /* @@ -859,12 +847,10 @@ static unsigned long versatile_gettimeoffset(void) */ static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - write_seqlock(&xtime_lock); // ...clear the interrupt - timer0->TimerClear = 1; + writel(1, TIMER0_VA_BASE + TIMER_INTCLR); timer_tick(regs); @@ -884,31 +870,32 @@ static struct irqaction versatile_timer_irq = { */ static void __init versatile_timer_init(void) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; - volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE; + u32 val; /* * set clock frequency: * VERSATILE_REFCLK is 32KHz * VERSATILE_TIMCLK is 1MHz */ - *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= - ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | - (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel)); + val = readl(IO_ADDRESS(VERSATILE_SCTL_BASE)); + writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val, + IO_ADDRESS(VERSATILE_SCTL_BASE)); /* * Initialise to a known state (all timers off) */ - timer0->TimerControl = 0; - timer1->TimerControl = 0; - timer2->TimerControl = 0; - timer3->TimerControl = 0; - - timer0->TimerLoad = TIMER_RELOAD; - timer0->TimerValue = TIMER_RELOAD; - timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */ + writel(0, TIMER0_VA_BASE + TIMER_CTRL); + writel(0, TIMER1_VA_BASE + TIMER_CTRL); + writel(0, TIMER2_VA_BASE + TIMER_CTRL); + writel(0, TIMER3_VA_BASE + TIMER_CTRL); + + writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); + writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE); + writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC | + TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL); /* * Make irqs happen for the system timer -- cgit v1.2.2 From aaaa3f9e51245be3215ff67bb3c7aaf5abb82f00 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 29 Jun 2005 15:34:39 +0100 Subject: [PATCH] ARM: 2769/1: cpu_init() stack setup fix Patch from Catalin Marinas The compiler allocates r14 for the stk variable in the __asm__ directive. This is a shadowed register and gets changed when the mode is changed, causing random values in the SP register. The patch adds a clobber for the r14 register. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 8cf733daa8..35b7273cfd 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -359,7 +359,8 @@ void cpu_init(void) "I" (offsetof(struct stack, abt[0])), "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE), "I" (offsetof(struct stack, und[0])), - "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)); + "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE) + : "r14"); } static struct machine_desc * __init setup_machine(unsigned int nr) -- cgit v1.2.2 From c7e788766610bdc764d7150e69ace2e0c4196cf0 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 29 Jun 2005 18:10:54 +0100 Subject: [PATCH] ARM: 2723/2: remove __udivdi3 and __umoddi3 from the kernel Patch from Nicolas Pitre Those are big, slow and generally not recommended for kernel code. They are even not present on i386. So it should be concluded that one could as well get away with do_div() alone. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/armksyms.c | 6 -- arch/arm/lib/Makefile | 2 +- arch/arm/lib/longlong.h | 183 ------------------------------------- arch/arm/lib/udivdi3.c | 222 --------------------------------------------- 4 files changed, 1 insertion(+), 412 deletions(-) delete mode 100644 arch/arm/lib/longlong.h delete mode 100644 arch/arm/lib/udivdi3.c (limited to 'arch') diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 4c38bd8bc2..b713c44c6f 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -30,9 +30,6 @@ extern void __lshrdi3(void); extern void __modsi3(void); extern void __muldi3(void); extern void __ucmpdi2(void); -extern void __udivdi3(void); -extern void __umoddi3(void); -extern void __udivmoddi4(void); extern void __udivsi3(void); extern void __umodsi3(void); extern void __do_div64(void); @@ -134,9 +131,6 @@ EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__modsi3); EXPORT_SYMBOL(__muldi3); EXPORT_SYMBOL(__ucmpdi2); -EXPORT_SYMBOL(__udivdi3); -EXPORT_SYMBOL(__umoddi3); -EXPORT_SYMBOL(__udivmoddi4); EXPORT_SYMBOL(__udivsi3); EXPORT_SYMBOL(__umodsi3); EXPORT_SYMBOL(__do_div64); diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index c0e65833ff..8725d63e42 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -11,7 +11,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ strnlen_user.o strchr.o strrchr.o testchangebit.o \ testclearbit.o testsetbit.o uaccess.o getuser.o \ putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - ucmpdi2.o udivdi3.o lib1funcs.o div64.o \ + ucmpdi2.o lib1funcs.o div64.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o ifeq ($(CONFIG_CPU_32v3),y) diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h deleted file mode 100644 index 90ae647e4d..0000000000 --- a/arch/arm/lib/longlong.h +++ /dev/null @@ -1,183 +0,0 @@ -/* longlong.h -- based on code from gcc-2.95.3 - - definitions for mixed size 32/64 bit arithmetic. - Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. - - This definition file is free software; you can redistribute it - and/or modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2, or (at your option) any later version. - - This definition file is distributed in the hope that it will be - useful, but WITHOUT ANY WARRANTY; without even the implied - warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */ - -#ifndef SI_TYPE_SIZE -#define SI_TYPE_SIZE 32 -#endif - -#define __BITS4 (SI_TYPE_SIZE / 4) -#define __ll_B (1L << (SI_TYPE_SIZE / 2)) -#define __ll_lowpart(t) ((u32) (t) % __ll_B) -#define __ll_highpart(t) ((u32) (t) / __ll_B) - -/* Define auxiliary asm macros. - - 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) - multiplies two u32 integers MULTIPLER and MULTIPLICAND, - and generates a two-part u32 product in HIGH_PROD and - LOW_PROD. - - 2) __umulsidi3(a,b) multiplies two u32 integers A and B, - and returns a u64 product. This is just a variant of umul_ppmm. - - 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator) divides a two-word unsigned integer, composed by the - integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and - places the quotient in QUOTIENT and the remainder in REMAINDER. - HIGH_NUMERATOR must be less than DENOMINATOR for correct operation. - If, in addition, the most significant bit of DENOMINATOR must be 1, - then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1. - - 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator). Like udiv_qrnnd but the numbers are signed. The - quotient is rounded towards 0. - - 5) count_leading_zeros(count, x) counts the number of zero-bits from - the msb to the first non-zero bit. This is the number of steps X - needs to be shifted left to set the msb. Undefined for X == 0. - - 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, - high_addend_2, low_addend_2) adds two two-word unsigned integers, - composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and - LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and - LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is - lost. - - 7) sub_ddmmss(high_difference, low_difference, high_minuend, - low_minuend, high_subtrahend, low_subtrahend) subtracts two - two-word unsigned integers, composed by HIGH_MINUEND_1 and - LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2 - respectively. The result is placed in HIGH_DIFFERENCE and - LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, - and is lost. - - If any of these macros are left undefined for a particular CPU, - C macros are used. */ - -#if defined (__arm__) -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("adds %1, %4, %5 \n\ - adc %0, %2, %3" \ - : "=r" ((u32) (sh)), \ - "=&r" ((u32) (sl)) \ - : "%r" ((u32) (ah)), \ - "rI" ((u32) (bh)), \ - "%r" ((u32) (al)), \ - "rI" ((u32) (bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subs %1, %4, %5 \n\ - sbc %0, %2, %3" \ - : "=r" ((u32) (sh)), \ - "=&r" ((u32) (sl)) \ - : "r" ((u32) (ah)), \ - "rI" ((u32) (bh)), \ - "r" ((u32) (al)), \ - "rI" ((u32) (bl))) -#define umul_ppmm(xh, xl, a, b) \ -{register u32 __t0, __t1, __t2; \ - __asm__ ("%@ Inlined umul_ppmm \n\ - mov %2, %5, lsr #16 \n\ - mov %0, %6, lsr #16 \n\ - bic %3, %5, %2, lsl #16 \n\ - bic %4, %6, %0, lsl #16 \n\ - mul %1, %3, %4 \n\ - mul %4, %2, %4 \n\ - mul %3, %0, %3 \n\ - mul %0, %2, %0 \n\ - adds %3, %4, %3 \n\ - addcs %0, %0, #65536 \n\ - adds %1, %1, %3, lsl #16 \n\ - adc %0, %0, %3, lsr #16" \ - : "=&r" ((u32) (xh)), \ - "=r" ((u32) (xl)), \ - "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ - : "r" ((u32) (a)), \ - "r" ((u32) (b)));} -#define UMUL_TIME 20 -#define UDIV_TIME 100 -#endif /* __arm__ */ - -#define __umulsidi3(u, v) \ - ({DIunion __w; \ - umul_ppmm (__w.s.high, __w.s.low, u, v); \ - __w.ll; }) - -#define __udiv_qrnnd_c(q, r, n1, n0, d) \ - do { \ - u32 __d1, __d0, __q1, __q0; \ - u32 __r1, __r0, __m; \ - __d1 = __ll_highpart (d); \ - __d0 = __ll_lowpart (d); \ - \ - __r1 = (n1) % __d1; \ - __q1 = (n1) / __d1; \ - __m = (u32) __q1 * __d0; \ - __r1 = __r1 * __ll_B | __ll_highpart (n0); \ - if (__r1 < __m) \ - { \ - __q1--, __r1 += (d); \ - if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ - if (__r1 < __m) \ - __q1--, __r1 += (d); \ - } \ - __r1 -= __m; \ - \ - __r0 = __r1 % __d1; \ - __q0 = __r1 / __d1; \ - __m = (u32) __q0 * __d0; \ - __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ - if (__r0 < __m) \ - { \ - __q0--, __r0 += (d); \ - if (__r0 >= (d)) \ - if (__r0 < __m) \ - __q0--, __r0 += (d); \ - } \ - __r0 -= __m; \ - \ - (q) = (u32) __q1 * __ll_B | __q0; \ - (r) = __r0; \ - } while (0) - -#define UDIV_NEEDS_NORMALIZATION 1 -#define udiv_qrnnd __udiv_qrnnd_c - -#define count_leading_zeros(count, x) \ - do { \ - u32 __xr = (x); \ - u32 __a; \ - \ - if (SI_TYPE_SIZE <= 32) \ - { \ - __a = __xr < ((u32)1<<2*__BITS4) \ - ? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4) \ - : (__xr < ((u32)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ - } \ - else \ - { \ - for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \ - if (((__xr >> __a) & 0xff) != 0) \ - break; \ - } \ - \ - (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ - } while (0) diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c deleted file mode 100644 index e343be4c66..0000000000 --- a/arch/arm/lib/udivdi3.c +++ /dev/null @@ -1,222 +0,0 @@ -/* More subroutines needed by GCC output code on some machines. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. - */ -/* support functions required by the kernel. based on code from gcc-2.95.3 */ -/* I Molton 29/07/01 */ - -#include "gcclib.h" -#include "longlong.h" - -static const u8 __clz_tab[] = { - 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, -}; - -u64 __udivmoddi4(u64 n, u64 d, u64 * rp) -{ - DIunion ww; - DIunion nn, dd; - DIunion rr; - u32 d0, d1, n0, n1, n2; - u32 q0, q1; - u32 b, bm; - - nn.ll = n; - dd.ll = d; - - d0 = dd.s.low; - d1 = dd.s.high; - n0 = nn.s.low; - n1 = nn.s.high; - - if (d1 == 0) { - if (d0 > n1) { - /* 0q = nn / 0D */ - - count_leading_zeros(bm, d0); - - if (bm != 0) { - /* Normalize, i.e. make the most significant bit of the - denominator set. */ - - d0 = d0 << bm; - n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); - n0 = n0 << bm; - } - - udiv_qrnnd(q0, n0, n1, n0, d0); - q1 = 0; - - /* Remainder in n0 >> bm. */ - } else { - /* qq = NN / 0d */ - - if (d0 == 0) - d0 = 1 / d0; /* Divide intentionally by zero. */ - - count_leading_zeros(bm, d0); - - if (bm == 0) { - /* From (n1 >= d0) /\ (the most significant bit of d0 is set), - conclude (the most significant bit of n1 is set) /\ (the - leading quotient digit q1 = 1). - - This special case is necessary, not an optimization. - (Shifts counts of SI_TYPE_SIZE are undefined.) */ - - n1 -= d0; - q1 = 1; - } else { - /* Normalize. */ - - b = SI_TYPE_SIZE - bm; - - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; - - udiv_qrnnd(q1, n1, n2, n1, d0); - } - - /* n1 != d0... */ - - udiv_qrnnd(q0, n0, n1, n0, d0); - - /* Remainder in n0 >> bm. */ - } - - if (rp != 0) { - rr.s.low = n0 >> bm; - rr.s.high = 0; - *rp = rr.ll; - } - } else { - if (d1 > n1) { - /* 00 = nn / DD */ - - q0 = 0; - q1 = 0; - - /* Remainder in n1n0. */ - if (rp != 0) { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } else { - /* 0q = NN / dd */ - - count_leading_zeros(bm, d1); - if (bm == 0) { - /* From (n1 >= d1) /\ (the most significant bit of d1 is set), - conclude (the most significant bit of n1 is set) /\ (the - quotient digit q0 = 0 or 1). - - This special case is necessary, not an optimization. */ - - /* The condition on the next line takes advantage of that - n1 >= d1 (true due to program flow). */ - if (n1 > d1 || n0 >= d0) { - q0 = 1; - sub_ddmmss(n1, n0, n1, n0, d1, d0); - } else - q0 = 0; - - q1 = 0; - - if (rp != 0) { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } else { - u32 m1, m0; - /* Normalize. */ - - b = SI_TYPE_SIZE - bm; - - d1 = (d1 << bm) | (d0 >> b); - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; - - udiv_qrnnd(q0, n1, n2, n1, d1); - umul_ppmm(m1, m0, q0, d0); - - if (m1 > n1 || (m1 == n1 && m0 > n0)) { - q0--; - sub_ddmmss(m1, m0, m1, m0, d1, d0); - } - - q1 = 0; - - /* Remainder in (n1n0 - m1m0) >> bm. */ - if (rp != 0) { - sub_ddmmss(n1, n0, n1, n0, m1, m0); - rr.s.low = (n1 << b) | (n0 >> bm); - rr.s.high = n1 >> bm; - *rp = rr.ll; - } - } - } - } - - ww.s.low = q0; - ww.s.high = q1; - return ww.ll; -} - -u64 __udivdi3(u64 n, u64 d) -{ - return __udivmoddi4(n, d, (u64 *) 0); -} - -u64 __umoddi3(u64 u, u64 v) -{ - u64 w; - - (void)__udivmoddi4(u, v, &w); - - return w; -} -- cgit v1.2.2 From 20f720ccce8864583365d844d48d3fe8d0d171ad Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 18:26:19 +0100 Subject: [PATCH] ARM: Remove nmi_tick from integrator platforms The nmi watchdog code hasn't been merged for this platform yet. Signed-off-by: Russell King --- arch/arm/mach-integrator/core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 797c7fddaa..dacbf504da 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -215,7 +215,6 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * primary CPU */ if (hard_smp_processor_id() == 0) { - nmi_tick(); timer_tick(regs); #ifdef CONFIG_SMP smp_send_timer(); -- cgit v1.2.2 From 026d02a236f429eb61a1277166bd425f8514c431 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 18:45:19 +0100 Subject: [PATCH] Serial: Split 8250 port table (part 2) Remove legacy ISA serial ports for Accent, Boca, Fourport, Hub6 and MCA from the architecture specific serial.h include. The only ports which remain in asm-*/serial.h are the platform specific entries. These should really be converted by platform maintainers to use a platform device, such as can be found in arch/arm/mach-footbridge/isa.c Signed-off-by: Russell King --- arch/parisc/configs/712_defconfig | 2 +- arch/parisc/configs/a500_defconfig | 2 +- arch/parisc/configs/b180_defconfig | 2 +- arch/parisc/configs/c3000_defconfig | 2 +- arch/parisc/defconfig | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig index 872085dea8..6efaa9293e 100644 --- a/arch/parisc/configs/712_defconfig +++ b/arch/parisc/configs/712_defconfig @@ -506,7 +506,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_NR_UARTS=17 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig index d28ebfa107..30fc03ed0c 100644 --- a/arch/parisc/configs/a500_defconfig +++ b/arch/parisc/configs/a500_defconfig @@ -662,7 +662,7 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m -CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_NR_UARTS=17 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig index 1700d7aec6..46c9511f32 100644 --- a/arch/parisc/configs/b180_defconfig +++ b/arch/parisc/configs/b180_defconfig @@ -514,7 +514,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig index b27980161c..67aca6ccc9 100644 --- a/arch/parisc/configs/c3000_defconfig +++ b/arch/parisc/configs/c3000_defconfig @@ -661,7 +661,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig index ebd6301aa5..fdae21c503 100644 --- a/arch/parisc/defconfig +++ b/arch/parisc/defconfig @@ -517,7 +517,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y -- cgit v1.2.2 From b3402cf50efead37dd9553b90fbf1486e09fb78e Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 29 Jun 2005 19:59:48 +0100 Subject: [PATCH] ARM: 2771/1: Dynamic Tick support for OMAP, take 4 Patch from Tony Lindgren This patch adds support for Dynamic Tick Timer for OMAP. This patch is an updated version of ARM patch 2642/1 to make it work with the already integrated generic ARM dyntick support. Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/mach-omap/pm.c | 16 ++++++++++------ arch/arm/mach-omap/time.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap/pm.c b/arch/arm/mach-omap/pm.c index 00fac155df..6b03ccdc1e 100644 --- a/arch/arm/mach-omap/pm.c +++ b/arch/arm/mach-omap/pm.c @@ -41,7 +41,9 @@ #include #include +#include #include + #include #include #include @@ -80,13 +82,13 @@ void omap_pm_idle(void) return; } mask32 = omap_readl(ARM_SYSST); - local_fiq_enable(); - local_irq_enable(); -#if defined(CONFIG_OMAP_32K_TIMER) && defined(CONFIG_NO_IDLE_HZ) - /* Override timer to use VST for the next cycle */ - omap_32k_timer_next_vst_interrupt(); -#endif + /* + * Since an interrupt may set up a timer, we don't want to + * reprogram the hardware timer with interrupts enabled. + * Re-enable interrupts only after returning from idle. + */ + timer_dyn_reprogram(); if ((mask32 & DSP_IDLE) == 0) { __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); @@ -102,6 +104,8 @@ void omap_pm_idle(void) func_ptr(); } + local_fiq_enable(); + local_irq_enable(); } /* diff --git a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap/time.c index 589e8b2740..dd34e9f4c4 100644 --- a/arch/arm/mach-omap/time.c +++ b/arch/arm/mach-omap/time.c @@ -4,7 +4,7 @@ * OMAP Timers * * Copyright (C) 2004 Nokia Corporation - * Partial timer rewrite and additional VST timer support by + * Partial timer rewrite and additional dynamic tick timer support by * Tony Lindgen and * Tuukka Tikkanen * @@ -261,7 +261,6 @@ unsigned long long sched_clock(void) * so with HZ = 100, TVR = 327.68. */ #define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) -#define MAX_SKIP_JIFFIES 25 #define TIMER_32K_SYNCHRONIZED 0xfffbc410 #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ @@ -347,6 +346,42 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, return IRQ_HANDLED; } +#ifdef CONFIG_NO_IDLE_HZ +/* + * Programs the next timer interrupt needed. Called when dynamic tick is + * enabled, and to reprogram the ticks to skip from pm_idle. Note that + * we can keep the timer continuous, and don't need to set it to run in + * one-shot mode. This is because the timer will get reprogrammed again + * after next interrupt. + */ +void omap_32k_timer_reprogram(unsigned long next_tick) +{ + omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); +} + +static struct irqaction omap_32k_timer_irq; +extern struct timer_update_handler timer_update; + +static int omap_32k_timer_enable_dyn_tick(void) +{ + /* No need to reprogram timer, just use the next interrupt */ + return 0; +} + +static int omap_32k_timer_disable_dyn_tick(void) +{ + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); + return 0; +} + +static struct dyn_tick_timer omap_dyn_tick_timer = { + .enable = omap_32k_timer_enable_dyn_tick, + .disable = omap_32k_timer_disable_dyn_tick, + .reprogram = omap_32k_timer_reprogram, + .handler = omap_32k_timer_interrupt, +}; +#endif /* CONFIG_NO_IDLE_HZ */ + static struct irqaction omap_32k_timer_irq = { .name = "32KHz timer", .flags = SA_INTERRUPT | SA_TIMER, @@ -355,6 +390,11 @@ static struct irqaction omap_32k_timer_irq = { static __init void omap_init_32k_timer(void) { + +#ifdef CONFIG_NO_IDLE_HZ + omap_timer.dyn_tick = &omap_dyn_tick_timer; +#endif + setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); omap_timer.offset = omap_32k_timer_gettimeoffset; omap_32k_last_tick = omap_32k_sync_timer_read(); -- cgit v1.2.2 From 438a76167959061e371025f727fabec2ad9e70a7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 23:01:02 +0100 Subject: [PATCH] ARM: Fix VFP to use do_div() VFP used __divdi3 64-bit division needlessly. Convert it to use our 64-bit by 32-bit division instead. Signed-off-by: Russell King --- arch/arm/vfp/vfp.h | 15 +++++++++++++-- arch/arm/vfp/vfpdouble.c | 2 ++ arch/arm/vfp/vfpsingle.c | 14 ++++++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h index 55a02bc994..4b97950984 100644 --- a/arch/arm/vfp/vfp.h +++ b/arch/arm/vfp/vfp.h @@ -117,7 +117,13 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) if (nh >= m) return ~0ULL; mh = m >> 32; - z = (mh << 32 <= nh) ? 0xffffffff00000000ULL : (nh / mh) << 32; + if (mh << 32 <= nh) { + z = 0xffffffff00000000ULL; + } else { + z = nh; + do_div(z, mh); + z <<= 32; + } mul64to128(&termh, &terml, m, z); sub128(&remh, &reml, nh, nl, termh, terml); ml = m << 32; @@ -126,7 +132,12 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) add128(&remh, &reml, remh, reml, mh, ml); } remh = (remh << 32) | (reml >> 32); - z |= (mh << 32 <= remh) ? 0xffffffff : remh / mh; + if (mh << 32 <= remh) { + z |= 0xffffffff; + } else { + do_div(remh, mh); + z |= remh; + } return z; } diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index fa3053e84d..b801cd66b6 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -32,6 +32,8 @@ */ #include #include + +#include #include #include diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 6849fe35cb..14dd696dde 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -32,6 +32,8 @@ */ #include #include + +#include #include #include @@ -303,7 +305,11 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) if (z <= a) return (s32)a >> 1; } - return (u32)(((u64)a << 31) / z) + (z >> 1); + { + u64 v = (u64)a << 31; + do_div(v, z); + return v + (z >> 1); + } } static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr) @@ -1107,7 +1113,11 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) vsn.significand >>= 1; vsd.exponent++; } - vsd.significand = ((u64)vsn.significand << 32) / vsm.significand; + { + u64 significand = (u64)vsn.significand << 32; + do_div(significand, vsm.significand); + vsd.significand = significand; + } if ((vsd.significand & 0x3f) == 0) vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32); -- cgit v1.2.2 From da41119af78864d27ccbf505949df788d5e8aaf5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 23:02:02 +0100 Subject: [PATCH] ARM: Don't force SIGFPE We were forcing SIGFPE on to a user program for no good reason. Use send_sig_info() instead. Signed-off-by: Russell King --- arch/arm/vfp/vfpmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 3aeedd2afc..22f3da4e08 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -89,7 +89,7 @@ void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) current->thread.error_code = 0; current->thread.trap_no = 6; - force_sig_info(SIGFPE, &info, current); + send_sig_info(SIGFPE, &info, current); } static void vfp_panic(char *reason) -- cgit v1.2.2 From 06697eea4ce18870fbce82dffbb375e216145f47 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 29 Jun 2005 15:45:41 -0700 Subject: [IA64] Update tiger_defconfig Signed-off-by: Tony Luck --- arch/ia64/configs/tiger_defconfig | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index 47f45341ac..73454eee26 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-20050621 -# Tue Jun 21 14:03:24 2005 +# Linux kernel version: 2.6.13-rc1-20050629 +# Wed Jun 29 15:28:12 2005 # # @@ -80,18 +80,29 @@ CONFIG_MCKINLEY=y # CONFIG_IA64_PAGE_SIZE_8KB is not set CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 CONFIG_IA64_L1_CACHE_SHIFT=7 # CONFIG_NUMA is not set CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y CONFIG_IA64_CYCLONE=y CONFIG_IOSAPIC=y +# CONFIG_IA64_SGI_SN_XP is not set CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=4 CONFIG_HOTPLUG_CPU=y # CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y @@ -257,6 +268,7 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set @@ -395,6 +407,7 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -407,6 +420,8 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_TUNNEL is not set CONFIG_IP_TCPDIAG=y # CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -598,9 +613,7 @@ CONFIG_GAMEPORT=m # CONFIG_GAMEPORT_NS558 is not set # CONFIG_GAMEPORT_L4 is not set # CONFIG_GAMEPORT_EMU10K1 is not set -# CONFIG_GAMEPORT_VORTEX is not set # CONFIG_GAMEPORT_FM801 is not set -# CONFIG_GAMEPORT_CS461X is not set # # Character devices @@ -629,7 +642,6 @@ CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -743,6 +755,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=m # CONFIG_USB_OHCI_BIG_ENDIAN is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y @@ -779,9 +792,11 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -838,7 +853,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_TEST is not set # -# USB ATM/DSL drivers +# USB DSL modem support # # @@ -856,6 +871,10 @@ CONFIG_USB_HIDINPUT=y # # CONFIG_INFINIBAND is not set +# +# SN Devices +# + # # File systems # @@ -863,6 +882,7 @@ CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y @@ -922,7 +942,6 @@ CONFIG_NTFS_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_TMPFS_XATTR=y @@ -953,15 +972,18 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=m CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=m CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m @@ -1069,6 +1091,7 @@ CONFIG_LOG_BUF_SHIFT=20 # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set +# CONFIG_KPROBES is not set CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set # CONFIG_IA64_PRINT_HAZARDS is not set @@ -1090,7 +1113,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA1 is not set # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set -- cgit v1.2.2 From 0647d8cfd40f7974335884d73deef83feeffc2a0 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 29 Jun 2005 16:01:40 -0700 Subject: [IA64] Update zx1_defconfig Signed-off-by: Tony Luck --- arch/ia64/configs/zx1_defconfig | 166 +++++++++++++++++++++++++++++----------- 1 file changed, 122 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig index 21d6f9bab5..b7755e4436 100644 --- a/arch/ia64/configs/zx1_defconfig +++ b/arch/ia64/configs/zx1_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10 -# Wed Dec 29 09:05:48 2004 +# Linux kernel version: 2.6.13-rc1-20050629 +# Wed Jun 29 15:31:11 2005 # # @@ -12,6 +12,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -24,23 +25,26 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set +# CONFIG_CPUSETS is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -59,12 +63,15 @@ CONFIG_IA64=y CONFIG_64BIT=y CONFIG_MMU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_TIME_INTERPOLATION=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y # CONFIG_IA64_GENERIC is not set # CONFIG_IA64_DIG is not set CONFIG_IA64_HP_ZX1=y +# CONFIG_IA64_HP_ZX1_SWIOTLB is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_ITANIUM is not set @@ -73,22 +80,36 @@ CONFIG_MCKINLEY=y # CONFIG_IA64_PAGE_SIZE_8KB is not set CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 CONFIG_IA64_L1_CACHE_SHIFT=7 # CONFIG_NUMA is not set CONFIG_VIRTUAL_MEM_MAP=y +CONFIG_HOLES_IN_ZONE=y # CONFIG_IA64_CYCLONE is not set CONFIG_IOSAPIC=y +# CONFIG_IA64_SGI_SN_XP is not set CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=16 # CONFIG_HOTPLUG_CPU is not set +# CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y +CONFIG_ACPI_DEALLOCATE_IRQ=y # # Firmware Drivers @@ -120,6 +141,7 @@ CONFIG_ACPI_BUS=y CONFIG_ACPI_POWER=y CONFIG_ACPI_PCI=y CONFIG_ACPI_SYSTEM=y +# CONFIG_ACPI_CONTAINER is not set # # Bus options (PCI, PCMCIA) @@ -129,6 +151,7 @@ CONFIG_PCI_DOMAINS=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCI Hotplug Support @@ -138,7 +161,6 @@ CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_ACPI=y # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set # CONFIG_HOTPLUG_PCI_CPCI is not set -# CONFIG_HOTPLUG_PCI_PCIE is not set # CONFIG_HOTPLUG_PCI_SHPC is not set # @@ -146,10 +168,6 @@ CONFIG_HOTPLUG_PCI_ACPI=y # # CONFIG_PCCARD is not set -# -# PC-card bridges -# - # # Device Drivers # @@ -184,6 +202,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -203,6 +222,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set # # ATA/ATAPI/MFM/RLL support @@ -246,6 +266,7 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set @@ -275,6 +296,7 @@ CONFIG_CHR_DEV_OSST=y CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -288,6 +310,7 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set # # SCSI low-level drivers @@ -303,13 +326,10 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set @@ -319,8 +339,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y @@ -331,7 +349,7 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set @@ -344,9 +362,9 @@ CONFIG_SCSI_QLA2XXX=y # # Fusion MPT device support # -CONFIG_FUSION=y -CONFIG_FUSION_MAX_SGE=40 -# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set # # IEEE 1394 (FireWire) support @@ -368,12 +386,12 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -386,6 +404,8 @@ CONFIG_IP_MULTICAST=y # CONFIG_INET_TUNNEL is not set # CONFIG_IP_TCPDIAG is not set # CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y # # IP: Virtual Server Configuration @@ -405,8 +425,6 @@ CONFIG_NETFILTER=y CONFIG_IP_NF_ARPTABLES=y # CONFIG_IP_NF_ARPFILTER is not set # CONFIG_IP_NF_ARP_MANGLE is not set -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set # # SCTP Configuration (EXPERIMENTAL) @@ -483,7 +501,6 @@ CONFIG_NET_PCI=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y -# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -505,9 +522,11 @@ CONFIG_E1000=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) @@ -564,18 +583,6 @@ CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set - # # Input Device Drivers # @@ -585,6 +592,16 @@ CONFIG_SERIO=y # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + # # Character devices # @@ -603,7 +620,6 @@ CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -611,6 +627,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -644,6 +661,12 @@ CONFIG_DRM_RADEON=y # CONFIG_DRM_SIS is not set # CONFIG_RAW_DRIVER is not set # CONFIG_HPET is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -668,6 +691,7 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set @@ -691,10 +715,14 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set @@ -705,21 +733,29 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -746,6 +782,7 @@ CONFIG_VIDEO_DEV=y # # Video Adapters # +# CONFIG_TUNER_MULTI_I2C is not set # CONFIG_VIDEO_BT848 is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_SAA5246A is not set @@ -778,6 +815,11 @@ CONFIG_VIDEO_DEV=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_CIRRUS is not set @@ -785,6 +827,7 @@ CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set +# CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set # CONFIG_FB_RADEON_OLD is not set @@ -801,6 +844,7 @@ CONFIG_FB_RADEON_DEBUG=y # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_PM3 is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -820,6 +864,7 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -869,6 +914,8 @@ CONFIG_SND_AC97_CODEC=y # CONFIG_SND_CS46XX is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set # CONFIG_SND_KORG1212 is not set # CONFIG_SND_MIXART is not set # CONFIG_SND_NM256 is not set @@ -876,6 +923,7 @@ CONFIG_SND_AC97_CODEC=y # CONFIG_SND_RME96 is not set # CONFIG_SND_RME9652 is not set # CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set # CONFIG_SND_TRIDENT is not set # CONFIG_SND_YMFPCI is not set # CONFIG_SND_ALS4000 is not set @@ -893,13 +941,14 @@ CONFIG_SND_FM801_TEA575X=y # CONFIG_SND_INTEL8X0M is not set # CONFIG_SND_SONICVIBES is not set # CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set # CONFIG_SND_VX222 is not set +# CONFIG_SND_HDA_INTEL is not set # # USB devices # # CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_USX2Y is not set # # Open Sound System @@ -909,6 +958,8 @@ CONFIG_SND_FM801_TEA575X=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -920,8 +971,6 @@ CONFIG_USB_BANDWIDTH=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -929,7 +978,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set @@ -947,12 +999,11 @@ CONFIG_USB_UHCI_HCD=y # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_RW_DETECT is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set @@ -966,9 +1017,11 @@ CONFIG_USB_HIDINPUT=y CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -978,7 +1031,6 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set # # USB Multimedia devices @@ -992,6 +1044,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_SE401 is not set # CONFIG_USB_SN9C102 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_PWC is not set # # USB Network Adapters @@ -1001,6 +1054,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y # # USB port drivers @@ -1016,7 +1070,6 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_TIGL is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set @@ -1025,9 +1078,11 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set # -# USB ATM/DSL drivers +# USB DSL modem support # # @@ -1040,6 +1095,15 @@ CONFIG_USB_HIDDEV=y # # CONFIG_MMC is not set +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + # # File systems # @@ -1047,6 +1111,7 @@ CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y # CONFIG_EXT2_FS_POSIX_ACL is not set # CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set @@ -1056,6 +1121,10 @@ CONFIG_JBD=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1089,7 +1158,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_TMPFS_XATTR=y @@ -1120,15 +1188,18 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y @@ -1209,6 +1280,8 @@ CONFIG_NLS_UTF8=y # CONFIG_CRC_CCITT is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y # # Profiling support @@ -1218,14 +1291,18 @@ CONFIG_CRC32=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_KPROBES=y CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set CONFIG_IA64_PRINT_HAZARDS=y @@ -1252,6 +1329,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set -- cgit v1.2.2