From a2a3dfb8efc5d14cf39358ae0ec1da39667c2e6c Mon Sep 17 00:00:00 2001 From: john stultz Date: Tue, 25 Oct 2011 11:46:10 -0700 Subject: clocksource: m86k: Convert to clocksource_register_hz/khz Updated to merge the valid bits of the two m68k patches. This converts the m86k clocksources to use clocksource_register_hz/khz This is untested, so any assistance in testing would be appreciated! CC: Geert Uytterhoeven CC: Greg Ungerer Signed-off-by: John Stultz Signed-off-by: Greg Ungerer --- arch/m68k/platform/68328/timers.c | 4 +--- arch/m68k/platform/coldfire/dma_timer.c | 5 +---- arch/m68k/platform/coldfire/pit.c | 4 +--- arch/m68k/platform/coldfire/sltimers.c | 4 +--- arch/m68k/platform/coldfire/timers.c | 4 +--- 5 files changed, 5 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/m68k/platform/68328/timers.c b/arch/m68k/platform/68328/timers.c index 309f725995b..f2678866067 100644 --- a/arch/m68k/platform/68328/timers.c +++ b/arch/m68k/platform/68328/timers.c @@ -93,7 +93,6 @@ static struct clocksource m68328_clk = { .name = "timer", .rating = 250, .read = m68328_read_clk, - .shift = 20, .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -115,8 +114,7 @@ void hw_timer_init(void) /* Enable timer 1 */ TCTL |= TCTL_TEN; - m68328_clk.mult = clocksource_hz2mult(TICKS_PER_JIFFY*HZ, m68328_clk.shift); - clocksource_register(&m68328_clk); + clocksource_register_hz(&m68328_clk, TICKS_PER_JIFFY*HZ); } /***************************************************************************/ diff --git a/arch/m68k/platform/coldfire/dma_timer.c b/arch/m68k/platform/coldfire/dma_timer.c index a5f562823d7..235ad57c470 100644 --- a/arch/m68k/platform/coldfire/dma_timer.c +++ b/arch/m68k/platform/coldfire/dma_timer.c @@ -44,7 +44,6 @@ static struct clocksource clocksource_cf_dt = { .rating = 200, .read = cf_dt_get_cycles, .mask = CLOCKSOURCE_MASK(32), - .shift = 20, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -60,9 +59,7 @@ static int __init init_cf_dt_clocksource(void) __raw_writeb(0x00, DTER0); __raw_writel(0x00000000, DTRR0); __raw_writew(DMA_DTMR_CLK_DIV_16 | DMA_DTMR_ENABLE, DTMR0); - clocksource_cf_dt.mult = clocksource_hz2mult(DMA_FREQ, - clocksource_cf_dt.shift); - return clocksource_register(&clocksource_cf_dt); + return clocksource_register_hz(&clocksource_cf_dt, DMA_FREQ); } arch_initcall(init_cf_dt_clocksource); diff --git a/arch/m68k/platform/coldfire/pit.c b/arch/m68k/platform/coldfire/pit.c index c2b980926be..02663d25822 100644 --- a/arch/m68k/platform/coldfire/pit.c +++ b/arch/m68k/platform/coldfire/pit.c @@ -144,7 +144,6 @@ static struct clocksource pit_clk = { .name = "pit", .rating = 100, .read = pit_read_clk, - .shift = 20, .mask = CLOCKSOURCE_MASK(32), }; @@ -162,8 +161,7 @@ void hw_timer_init(void) setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &pit_irq); - pit_clk.mult = clocksource_hz2mult(FREQ, pit_clk.shift); - clocksource_register(&pit_clk); + clocksource_register_hz(&pit_clk, FREQ); } /***************************************************************************/ diff --git a/arch/m68k/platform/coldfire/sltimers.c b/arch/m68k/platform/coldfire/sltimers.c index 6a85daf9a7f..b7f822b552b 100644 --- a/arch/m68k/platform/coldfire/sltimers.c +++ b/arch/m68k/platform/coldfire/sltimers.c @@ -114,7 +114,6 @@ static struct clocksource mcfslt_clk = { .name = "slt", .rating = 250, .read = mcfslt_read_clk, - .shift = 20, .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -136,8 +135,7 @@ void hw_timer_init(void) setup_irq(MCF_IRQ_TIMER, &mcfslt_timer_irq); - mcfslt_clk.mult = clocksource_hz2mult(MCF_BUSCLK, mcfslt_clk.shift); - clocksource_register(&mcfslt_clk); + clocksource_register_hz(&mcfslt_clk, MCF_BUSCLK); #ifdef CONFIG_HIGHPROFILE mcfslt_profile_init(); diff --git a/arch/m68k/platform/coldfire/timers.c b/arch/m68k/platform/coldfire/timers.c index 60242f65fea..0d90da32fcd 100644 --- a/arch/m68k/platform/coldfire/timers.c +++ b/arch/m68k/platform/coldfire/timers.c @@ -88,7 +88,6 @@ static struct clocksource mcftmr_clk = { .name = "tmr", .rating = 250, .read = mcftmr_read_clk, - .shift = 20, .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -109,8 +108,7 @@ void hw_timer_init(void) __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); - mcftmr_clk.mult = clocksource_hz2mult(FREQ, mcftmr_clk.shift); - clocksource_register(&mcftmr_clk); + clocksource_register_hz(&mcftmr_clk, FREQ); setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq); -- cgit v1.2.3-18-g5258 From d85b40948654dee3be1d8e43b0fce511c1b42d78 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 26 Oct 2011 09:51:55 +0200 Subject: m68k: Fall back to __gpio_to_irq() for non-arch GPIOs gpiolib provides __gpio_to_irq() to map gpiolib gpios to interrupts - hook that up on m68k. Signed-off-by: Mark Brown Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/gpio.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h index b2046839f4b..00d0071de4c 100644 --- a/arch/m68k/include/asm/gpio.h +++ b/arch/m68k/include/asm/gpio.h @@ -225,7 +225,8 @@ static inline void gpio_set_value(unsigned gpio, int value) static inline int gpio_to_irq(unsigned gpio) { - return (gpio < MCFGPIO_IRQ_MAX) ? gpio + MCFGPIO_IRQ_VECBASE : -EINVAL; + return (gpio < MCFGPIO_IRQ_MAX) ? gpio + MCFGPIO_IRQ_VECBASE + : __gpio_to_irq(gpio); } static inline int irq_to_gpio(unsigned irq) -- cgit v1.2.3-18-g5258 From ed3da2c443e8d566a8eb0ab86069aefc7e928c74 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 30 Aug 2011 15:30:09 +1000 Subject: m68knommu: remove unused fasthandler declaration The fasthandler code was removed long ago. Remove the now unused declaration of it. Signed-off-by: Greg Ungerer --- arch/m68k/platform/coldfire/entry.S | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/platform/coldfire/entry.S b/arch/m68k/platform/coldfire/entry.S index 3157461a8d1..f567a163bc4 100644 --- a/arch/m68k/platform/coldfire/entry.S +++ b/arch/m68k/platform/coldfire/entry.S @@ -54,7 +54,6 @@ sw_usp: .globl ret_from_signal .globl sys_call_table .globl inthandler -.globl fasthandler enosys: mov.l #sys_ni_syscall,%d3 -- cgit v1.2.3-18-g5258 From 409ee2455c95495e182379883a568df1d40f5864 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 30 Aug 2011 16:11:05 +1000 Subject: m68k: merge the init_task code for mmu and non-mmu targets The init_task code can be the same for both mmu and non-mmu targets. None of the alignment carried out in the the current init_task code is necessary. The linker script takes care of aligning the init_thread structure to a THREAD SIZE boundary, and that is all we need. So use the init_task.c code for all target types, that makes m68k code consistent with what most other architectures do. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/Makefile | 7 ++----- arch/m68k/kernel/init_task.c | 3 +-- arch/m68k/kernel/process_mm.c | 16 ---------------- 3 files changed, 3 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index c5696193281..ea0a3967143 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile @@ -6,15 +6,12 @@ extra-$(CONFIG_MMU) := head.o extra-$(CONFIG_SUN3) := sun3-head.o extra-y += vmlinux.lds -obj-y := entry.o irq.o m68k_ksyms.o module.o process.o ptrace.o setup.o \ - signal.o sys_m68k.o syscalltable.o time.o traps.o +obj-y := entry.o init_task.o irq.o m68k_ksyms.o module.o process.o ptrace.o +obj-y += setup.o signal.o sys_m68k.o syscalltable.o time.o traps.o obj-$(CONFIG_MMU) += ints.o vectors.o ifndef CONFIG_MMU_SUN3 obj-y += dma.o endif -ifndef CONFIG_MMU -obj-y += init_task.o -endif diff --git a/arch/m68k/kernel/init_task.c b/arch/m68k/kernel/init_task.c index cbf9dc3cc51..c744cfc6bfa 100644 --- a/arch/m68k/kernel/init_task.c +++ b/arch/m68k/kernel/init_task.c @@ -19,7 +19,6 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); * * All other task structs will be allocated on slabs in fork.c */ -__asm__(".align 4"); struct task_struct init_task = INIT_TASK(init_task); EXPORT_SYMBOL(init_task); @@ -27,7 +26,7 @@ EXPORT_SYMBOL(init_task); /* * Initial thread structure. * - * We need to make sure that this is 8192-byte aligned due to the + * We need to make sure that this is THREAD size aligned due to the * way process stacks are handled. This is done by having a special * "init_task" linker map entry.. */ diff --git a/arch/m68k/kernel/process_mm.c b/arch/m68k/kernel/process_mm.c index 1bc223aa07e..58a3253f3eb 100644 --- a/arch/m68k/kernel/process_mm.c +++ b/arch/m68k/kernel/process_mm.c @@ -33,22 +33,6 @@ #include #include -/* - * Initial task/thread structure. Make this a per-architecture thing, - * because different architectures tend to have different - * alignment requirements and potentially different initial - * setup. - */ -static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); -union thread_union init_thread_union __init_task_data - __attribute__((aligned(THREAD_SIZE))) = - { INIT_THREAD_INFO(init_task) }; - -/* initial task structure */ -struct task_struct init_task = INIT_TASK(init_task); - -EXPORT_SYMBOL(init_task); asmlinkage void ret_from_fork(void); -- cgit v1.2.3-18-g5258 From 8d362b0dea1a35bea8d7d281317eb7ccb713edcb Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 2 Sep 2011 14:20:06 +1000 Subject: m68k: remove duplicate asm offset for task thread.info We have a duplicate name and definition for the offset of the thread.info struct within the task struct in our asm-offsets.c code. Remove one of them, and consolidate to use a single define, TASK_INFO. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/thread_info.h | 2 +- arch/m68k/kernel/asm-offsets.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h index 790988967ba..e4e2159ca6e 100644 --- a/arch/m68k/include/asm/thread_info.h +++ b/arch/m68k/include/asm/thread_info.h @@ -57,7 +57,7 @@ struct thread_info { #define task_thread_info(tsk) ((struct thread_info *) NULL) #else #include -#define task_thread_info(tsk) ((struct thread_info *)((char *)tsk+TASK_TINFO)) +#define task_thread_info(tsk) ((struct thread_info *)((char *)tsk+TASK_INFO)) #endif #define init_thread_info (init_task.thread.info) diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c index 983fed9d469..f6a54e203e8 100644 --- a/arch/m68k/kernel/asm-offsets.c +++ b/arch/m68k/kernel/asm-offsets.c @@ -25,7 +25,6 @@ int main(void) DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); DEFINE(TASK_MM, offsetof(struct task_struct, mm)); DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info)); - DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info)); /* offsets into the thread struct */ DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); -- cgit v1.2.3-18-g5258 From d25ba98afce7c87afa39f553a3ff8effed87db03 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 2 Sep 2011 14:29:34 +1000 Subject: m68k: remove thread_info struct from thread struct Currently on m68k we have a comeplete thread_info structure stored inside of the thread_struct, and we also have it in the initial part of the kernel stack. Mostly the code currently uses the one inside of the thread_struct, only using the "task" pointer from the stack based one. This is wasteful and confusing, we should only have the single instance of thread_info inside the stack page. And this is the norm for all other architectures. This change makes m68k handle thread_info consistently on both MMU enabled and non-MMU setups. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/processor.h | 2 -- arch/m68k/include/asm/thread_info.h | 30 ------------------------------ arch/m68k/kernel/asm-offsets.c | 2 +- arch/m68k/kernel/entry_mm.S | 31 +++++++++++++++++++++---------- 4 files changed, 22 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h index 568facf3027..7ec06096a6f 100644 --- a/arch/m68k/include/asm/processor.h +++ b/arch/m68k/include/asm/processor.h @@ -88,14 +88,12 @@ struct thread_struct { unsigned long fp[8*3]; unsigned long fpcntl[3]; /* fp control regs */ unsigned char fpstate[FPSTATESIZE]; /* floating point state */ - struct thread_info info; }; #define INIT_THREAD { \ .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ .sr = PS_S, \ .fs = __KERNEL_DS, \ - .info = INIT_THREAD_INFO(init_task), \ } #ifdef CONFIG_MMU diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h index e4e2159ca6e..01cef3ceff4 100644 --- a/arch/m68k/include/asm/thread_info.h +++ b/arch/m68k/include/asm/thread_info.h @@ -47,34 +47,6 @@ struct thread_info { #define init_stack (init_thread_union.stack) -#ifdef CONFIG_MMU - -#ifndef __ASSEMBLY__ -#include -#endif - -#ifdef ASM_OFFSETS_C -#define task_thread_info(tsk) ((struct thread_info *) NULL) -#else -#include -#define task_thread_info(tsk) ((struct thread_info *)((char *)tsk+TASK_INFO)) -#endif - -#define init_thread_info (init_task.thread.info) -#define task_stack_page(tsk) ((tsk)->stack) -#define current_thread_info() task_thread_info(current) - -#define __HAVE_THREAD_FUNCTIONS - -#define setup_thread_stack(p, org) ({ \ - *(struct task_struct **)(p)->stack = (p); \ - task_thread_info(p)->task = (p); \ -}) - -#define end_of_stack(p) ((unsigned long *)(p)->stack + 1) - -#else /* !CONFIG_MMU */ - #ifndef __ASSEMBLY__ /* how to get the thread information struct from C */ static inline struct thread_info *current_thread_info(void) @@ -92,8 +64,6 @@ static inline struct thread_info *current_thread_info(void) #define init_thread_info (init_thread_union.thread_info) -#endif /* CONFIG_MMU */ - /* entry.S relies on these definitions! * bits 0-7 are tested at every exception exit * bits 8-15 are also tested at syscall exit diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c index f6a54e203e8..a972b00cd77 100644 --- a/arch/m68k/kernel/asm-offsets.c +++ b/arch/m68k/kernel/asm-offsets.c @@ -24,7 +24,7 @@ int main(void) /* offsets into the task struct */ DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); DEFINE(TASK_MM, offsetof(struct task_struct, mm)); - DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info)); + DEFINE(TASK_STACK, offsetof(struct task_struct, stack)); /* offsets into the thread struct */ DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); diff --git a/arch/m68k/kernel/entry_mm.S b/arch/m68k/kernel/entry_mm.S index c713f514843..675a854966a 100644 --- a/arch/m68k/kernel/entry_mm.S +++ b/arch/m68k/kernel/entry_mm.S @@ -99,7 +99,8 @@ do_trace_exit: jra .Lret_from_exception ENTRY(ret_from_signal) - tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) + movel %curptr@(TASK_STACK),%a1 + tstb %a1@(TINFO_FLAGS+2) jge 1f jbsr syscall_trace 1: RESTORE_SWITCH_STACK @@ -120,11 +121,13 @@ ENTRY(system_call) SAVE_ALL_SYS GET_CURRENT(%d1) + movel %d1,%a1 + | save top of frame movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) | syscall trace? - tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) + tstb %a1@(TINFO_FLAGS+2) jmi do_trace_entry cmpl #NR_syscalls,%d0 jcc badsys @@ -133,7 +136,8 @@ syscall: movel %d0,%sp@(PT_OFF_D0) | save the return value ret_from_syscall: |oriw #0x0700,%sr - movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0 + movel %curptr@(TASK_STACK),%a1 + movew %a1@(TINFO_FLAGS+2),%d0 jne syscall_exit_work 1: RESTORE_ALL @@ -159,7 +163,8 @@ ENTRY(ret_from_exception) andw #ALLOWINT,%sr resume_userspace: - moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0 + movel %curptr@(TASK_STACK),%a1 + moveb %a1@(TINFO_FLAGS+3),%d0 jne exit_work 1: RESTORE_ALL @@ -199,7 +204,8 @@ do_delayed_trace: ENTRY(auto_inthandler) SAVE_ALL_INT GET_CURRENT(%d0) - addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) + movel %d0,%a1 + addqb #1,%a1@(TINFO_PREEMPT+1) | put exception # in d0 bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 subw #VEC_SPUR,%d0 @@ -211,7 +217,8 @@ auto_irqhandler_fixup = . + 2 addql #8,%sp | pop parameters off stack ret_from_interrupt: - subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) + movel %curptr@(TASK_STACK),%a1 + subqb #1,%a1@(TINFO_PREEMPT+1) jeq ret_from_last_interrupt 2: RESTORE_ALL @@ -232,7 +239,8 @@ ret_from_last_interrupt: ENTRY(user_inthandler) SAVE_ALL_INT GET_CURRENT(%d0) - addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) + movel %d0,%a1 + addqb #1,%a1@(TINFO_PREEMPT+1) | put exception # in d0 bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 user_irqvec_fixup = . + 2 @@ -243,7 +251,8 @@ user_irqvec_fixup = . + 2 jsr do_IRQ | process the IRQ addql #8,%sp | pop parameters off stack - subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) + movel %curptr@(TASK_STACK),%a1 + subqb #1,%a1@(TINFO_PREEMPT+1) jeq ret_from_last_interrupt RESTORE_ALL @@ -252,13 +261,15 @@ user_irqvec_fixup = . + 2 ENTRY(bad_inthandler) SAVE_ALL_INT GET_CURRENT(%d0) - addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) + movel %d0,%a1 + addqb #1,%a1@(TINFO_PREEMPT+1) movel %sp,%sp@- jsr handle_badint addql #4,%sp - subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) + movel %curptr@(TASK_STACK),%a1 + subqb #1,%a1@(TINFO_PREEMPT+1) jeq ret_from_last_interrupt RESTORE_ALL -- cgit v1.2.3-18-g5258 From 5717a02becd2f5dae8b11cb5808de4e5369d607c Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 19 Oct 2011 16:27:30 +1000 Subject: m68k: selection of GENERIC_ATOMIC64 is not MMU specific The selection of the CONFIG_GENERIC_ATOMIC64 option is not specific to the MMU being present and enabled. It is a property of certain CPU families. So select it based on those CPU types being selected. Signed-off-by: Greg Ungerer --- arch/m68k/Kconfig | 1 - arch/m68k/Kconfig.cpu | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 361d54019bb..2914b036d76 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -3,7 +3,6 @@ config M68K default y select HAVE_IDE select HAVE_AOUT if MMU - select GENERIC_ATOMIC64 if MMU select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index e632b2d1210..9af9e68c303 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -33,6 +33,7 @@ config COLDFIRE config M68020 bool "68020 support" depends on MMU + select GENERIC_ATOMIC64 help If you anticipate running this kernel on a computer with a MC68020 processor, say Y. Otherwise, say N. Note that the 68020 requires a @@ -42,6 +43,7 @@ config M68020 config M68030 bool "68030 support" depends on MMU && !MMU_SUN3 + select GENERIC_ATOMIC64 help If you anticipate running this kernel on a computer with a MC68030 processor, say Y. Otherwise, say N. Note that a MC68EC030 will not @@ -50,6 +52,7 @@ config M68030 config M68040 bool "68040 support" depends on MMU && !MMU_SUN3 + select GENERIC_ATOMIC64 help If you anticipate running this kernel on a computer with a MC68LC040 or MC68040 processor, say Y. Otherwise, say N. Note that an @@ -59,6 +62,7 @@ config M68040 config M68060 bool "68060 support" depends on MMU && !MMU_SUN3 + select GENERIC_ATOMIC64 help If you anticipate running this kernel on a computer with a MC68060 processor, say Y. Otherwise, say N. -- cgit v1.2.3-18-g5258 From 361a541dc2373e57cfa7a63e95fbe448ff5675d4 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 19 Oct 2011 21:37:08 +1000 Subject: m68knommu: move definition of mach_gettod to where it is used The mach_gettod function pointer is only called from the time_no.c code. So move its actual definition to there too. It is currently in setup_no.c for no particularly good reason. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/setup_no.c | 1 - arch/m68k/kernel/time_no.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c index 2ed8c0fb151..ca3df0dc7e8 100644 --- a/arch/m68k/kernel/setup_no.c +++ b/arch/m68k/kernel/setup_no.c @@ -47,7 +47,6 @@ EXPORT_SYMBOL(memory_end); char __initdata command_line[COMMAND_LINE_SIZE]; /* machine dependent timer functions */ -void (*mach_gettod)(int*, int*, int*, int*, int*, int*); int (*mach_set_clock_mmss)(unsigned long); /* machine dependent reboot functions */ diff --git a/arch/m68k/kernel/time_no.c b/arch/m68k/kernel/time_no.c index 6623909f70e..3ef0f7768dc 100644 --- a/arch/m68k/kernel/time_no.c +++ b/arch/m68k/kernel/time_no.c @@ -26,6 +26,9 @@ #define TICK_SIZE (tick_nsec / 1000) +/* machine dependent timer functions */ +void (*mach_gettod)(int*, int*, int*, int*, int*, int*); + static inline int set_rtc_mmss(unsigned long nowtime) { if (mach_set_clock_mmss) -- cgit v1.2.3-18-g5258 From e87c09a899d38d1b6858e010c22a1200fb77965d Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Thu, 13 Oct 2011 16:59:55 +1000 Subject: m68k: print memory layout info in boot log Output a table of the kernel memory regions at boot time. This is taken directly from the ARM architecture code that does this. The table looks like this: Virtual kernel memory layout: vector : 0x00000000 - 0x00000400 ( 0 KiB) kmap : 0xd0000000 - 0xe0000000 ( 256 MiB) vmalloc : 0xc0000000 - 0xcfffffff ( 255 MiB) lowmem : 0x00000000 - 0x02000000 ( 32 MiB) .init : 0x00128000 - 0x00134000 ( 48 KiB) .text : 0x00020000 - 0x00118d54 ( 996 KiB) .data : 0x00118d60 - 0x00126000 ( 53 KiB) .bss : 0x00134000 - 0x001413e0 ( 53 KiB) This has been very useful while debugging the ColdFire virtual memory support code. But in general I think it is nice to know extacly where the kernel has layed everything out on boot. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/traps.h | 1 + arch/m68k/kernel/vmlinux-std.lds | 2 ++ arch/m68k/kernel/vmlinux-sun3.lds | 2 ++ arch/m68k/mm/init_mm.c | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+) (limited to 'arch') diff --git a/arch/m68k/include/asm/traps.h b/arch/m68k/include/asm/traps.h index 151068f64f4..4aff3358fba 100644 --- a/arch/m68k/include/asm/traps.h +++ b/arch/m68k/include/asm/traps.h @@ -18,6 +18,7 @@ typedef void (*e_vector)(void); extern e_vector vectors[]; +extern e_vector *_ramvec; asmlinkage void auto_inthandler(void); asmlinkage void user_inthandler(void); diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds index d0993594f55..63407c83682 100644 --- a/arch/m68k/kernel/vmlinux-std.lds +++ b/arch/m68k/kernel/vmlinux-std.lds @@ -31,7 +31,9 @@ SECTIONS RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE) + _sbss = .; BSS_SECTION(0, 0, 0) + _ebss = .; _edata = .; /* End of data section */ diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds index 8080469ee6c..ad0f46d64c0 100644 --- a/arch/m68k/kernel/vmlinux-sun3.lds +++ b/arch/m68k/kernel/vmlinux-sun3.lds @@ -44,7 +44,9 @@ __init_begin = .; . = ALIGN(PAGE_SIZE); __init_end = .; + _sbss = .; BSS_SECTION(0, 0, 0) + _ebss = .; _end = . ; diff --git a/arch/m68k/mm/init_mm.c b/arch/m68k/mm/init_mm.c index bbe525434cc..85c5f0eee9f 100644 --- a/arch/m68k/mm/init_mm.c +++ b/arch/m68k/mm/init_mm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_ATARI @@ -75,6 +76,38 @@ extern void init_pointer_table(unsigned long ptable); extern pmd_t *zero_pgtable; +#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) +#define VECTORS &vectors[0] +#else +#define VECTORS _ramvec +#endif + +void __init print_memmap(void) +{ +#define UL(x) ((unsigned long) (x)) +#define MLK(b, t) UL(b), UL(t), (UL(t) - UL(b)) >> 10 +#define MLM(b, t) UL(b), UL(t), (UL(t) - UL(b)) >> 20 +#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), 1024) + + pr_notice("Virtual kernel memory layout:\n" + " vector : 0x%08lx - 0x%08lx (%4ld KiB)\n" + " kmap : 0x%08lx - 0x%08lx (%4ld MiB)\n" + " vmalloc : 0x%08lx - 0x%08lx (%4ld MiB)\n" + " lowmem : 0x%08lx - 0x%08lx (%4ld MiB)\n" + " .init : 0x%p" " - 0x%p" " (%4d KiB)\n" + " .text : 0x%p" " - 0x%p" " (%4d KiB)\n" + " .data : 0x%p" " - 0x%p" " (%4d KiB)\n" + " .bss : 0x%p" " - 0x%p" " (%4d KiB)\n", + MLK(VECTORS, VECTORS + 256), + MLM(KMAP_START, KMAP_END), + MLM(VMALLOC_START, VMALLOC_END), + MLM(PAGE_OFFSET, (unsigned long)high_memory), + MLK_ROUNDUP(__init_begin, __init_end), + MLK_ROUNDUP(_stext, _etext), + MLK_ROUNDUP(_sdata, _edata), + MLK_ROUNDUP(_sbss, _ebss)); +} + void __init mem_init(void) { pg_data_t *pgdat; @@ -125,6 +158,7 @@ void __init mem_init(void) codepages << (PAGE_SHIFT-10), datapages << (PAGE_SHIFT-10), initpages << (PAGE_SHIFT-10)); + print_memmap(); } #ifdef CONFIG_BLK_DEV_INITRD -- cgit v1.2.3-18-g5258 From d1db9120cd7df0872385fd29a25257f23cb70527 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 19 Oct 2011 11:46:03 +1000 Subject: m68k: support configure time command line for MMU m68k The non-MMU builds of m68k allow a fixed kernel boot command line to be configured at configure time. Allow this MMU builds as well. Signed-off-by: Greg Ungerer --- arch/m68k/Kconfig.debug | 16 ++++++++-------- arch/m68k/kernel/setup_mm.c | 4 ++++ 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/m68k/Kconfig.debug b/arch/m68k/Kconfig.debug index 2bdb1b01115..af4fd5f8f8d 100644 --- a/arch/m68k/Kconfig.debug +++ b/arch/m68k/Kconfig.debug @@ -2,6 +2,14 @@ menu "Kernel hacking" source "lib/Kconfig.debug" +config BOOTPARAM + bool 'Compiled-in Kernel Boot Parameter' + +config BOOTPARAM_STRING + string 'Kernel Boot Parameter' + default 'console=ttyS0,19200' + depends on BOOTPARAM + if !MMU config FULLDEBUG @@ -15,14 +23,6 @@ config HIGHPROFILE help Use a fast secondary clock to produce profiling information. -config BOOTPARAM - bool 'Compiled-in Kernel Boot Parameter' - -config BOOTPARAM_STRING - string 'Kernel Boot Parameter' - default 'console=ttyS0,19200' - depends on BOOTPARAM - config NO_KERNEL_MSG bool "Suppress Kernel BUG Messages" help diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c index c3b45061dd0..55f8f5049f6 100644 --- a/arch/m68k/kernel/setup_mm.c +++ b/arch/m68k/kernel/setup_mm.c @@ -258,6 +258,10 @@ void __init setup_arch(char **cmdline_p) init_mm.end_data = (unsigned long)_edata; init_mm.brk = (unsigned long)_end; +#if defined(CONFIG_BOOTPARAM) + strncpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE); + m68k_command_line[CL_SIZE - 1] = 0; +#endif /* CONFIG_BOOTPARAM */ *cmdline_p = m68k_command_line; memcpy(boot_command_line, *cmdline_p, CL_SIZE); -- cgit v1.2.3-18-g5258 From 46729d0eb301f689272c64a9417e7b40038f42a6 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 31 Oct 2011 14:26:52 +1000 Subject: m68knommu: no need to set register marker on traps Commit 61619b12078dc8b85a3d4cbfa16f650daa341bd1 ("m68k: merge mmu and non-mmu include/asm/entry.h files") made the trap entry code basically the same for mmu and non-mmu builds. This means we no longer need code to mark the stack frame as "system-call" type or other in the non-mmu trap handling entry points. This is done in the SAVE_ALL_INT macro now. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/entry_no.S | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/m68k/kernel/entry_no.S b/arch/m68k/kernel/entry_no.S index 1b4289061a6..ac86a9ffc1d 100644 --- a/arch/m68k/kernel/entry_no.S +++ b/arch/m68k/kernel/entry_no.S @@ -44,8 +44,6 @@ ENTRY(buserr) SAVE_ALL_INT - moveq #-1,%d0 - movel %d0,%sp@(PT_OFF_ORIG_D0) movel %sp,%sp@- /* stack frame pointer argument */ jsr buserr_c addql #4,%sp @@ -53,8 +51,6 @@ ENTRY(buserr) ENTRY(trap) SAVE_ALL_INT - moveq #-1,%d0 - movel %d0,%sp@(PT_OFF_ORIG_D0) movel %sp,%sp@- /* stack frame pointer argument */ jsr trap_c addql #4,%sp @@ -65,8 +61,6 @@ ENTRY(trap) .globl dbginterrupt ENTRY(dbginterrupt) SAVE_ALL_INT - moveq #-1,%d0 - movel %d0,%sp@(PT_OFF_ORIG_D0) movel %sp,%sp@- /* stack frame pointer argument */ jsr dbginterrupt_c addql #4,%sp -- cgit v1.2.3-18-g5258 From 479badc364b52774d77264aaf81f4d4b375a4a97 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 2 Nov 2011 15:44:42 +1000 Subject: m68k: make fp register stores consistent for m68k and ColdFire There is no reason we can't make the saved fp registers the same for all m68k types and ColdFire. There is a little wasted space, but the code consistency and cleanliness is a big win. sigcontext.h is an exported header, but currently there is no in-mainline users of the !__uClinux__ and __mcoldfire__ case that this change effects. Even better this change actually makes this structure consistent with the out-of-mainline ColdFire/MMU code. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/sigcontext.h | 4 ---- arch/m68k/include/asm/ucontext.h | 4 ---- 2 files changed, 8 deletions(-) (limited to 'arch') diff --git a/arch/m68k/include/asm/sigcontext.h b/arch/m68k/include/asm/sigcontext.h index a29dd74a17c..523db2a51cf 100644 --- a/arch/m68k/include/asm/sigcontext.h +++ b/arch/m68k/include/asm/sigcontext.h @@ -15,11 +15,7 @@ struct sigcontext { unsigned long sc_pc; unsigned short sc_formatvec; #ifndef __uClinux__ -# ifdef __mcoldfire__ - unsigned long sc_fpregs[2][2]; /* room for two fp registers */ -# else unsigned long sc_fpregs[2*3]; /* room for two fp registers */ -# endif unsigned long sc_fpcntl[3]; unsigned char sc_fpstate[216]; #endif diff --git a/arch/m68k/include/asm/ucontext.h b/arch/m68k/include/asm/ucontext.h index 00dcc5176c5..e4e22669edc 100644 --- a/arch/m68k/include/asm/ucontext.h +++ b/arch/m68k/include/asm/ucontext.h @@ -7,11 +7,7 @@ typedef greg_t gregset_t[NGREG]; typedef struct fpregset { int f_fpcntl[3]; -#ifdef __mcoldfire__ - int f_fpregs[8][2]; -#else int f_fpregs[8*3]; -#endif } fpregset_t; struct mcontext { -- cgit v1.2.3-18-g5258 From 7f73bafc4630a450ebe8b021efa14781ffd992b1 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 18 Oct 2011 15:49:19 +1000 Subject: m68k: simpler m68k and ColdFire CPU's can use generic csum code We have two implementations of the IP checksuming code for the m68k arch. One uses the more advanced instructions available in 68020 and above processors, the other uses the simpler instructions available on the original 68000 processors and the modern ColdFire processors. This simpler code is pretty much the same as the generic lib implementation of the IP csum functions. So lets just switch over to using that. That means we can completely remove the checksum_no.c file, and only have the local fast code used for the more complex 68k CPU family members. Signed-off-by: Greg Ungerer --- arch/m68k/Kconfig | 3 + arch/m68k/Kconfig.cpu | 2 + arch/m68k/include/asm/checksum.h | 31 +-- arch/m68k/lib/Makefile | 8 +- arch/m68k/lib/checksum.c | 425 +++++++++++++++++++++++++++++++++++++++ arch/m68k/lib/checksum_mm.c | 425 --------------------------------------- arch/m68k/lib/checksum_no.c | 156 -------------- 7 files changed, 441 insertions(+), 609 deletions(-) create mode 100644 arch/m68k/lib/checksum.c delete mode 100644 arch/m68k/lib/checksum_mm.c delete mode 100644 arch/m68k/lib/checksum_no.c (limited to 'arch') diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 2914b036d76..2fe2d633fe0 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -40,6 +40,9 @@ config GENERIC_CALIBRATE_DELAY config GENERIC_IOMAP def_bool MMU +config GENERIC_CSUM + bool + config TIME_LOW_RES bool default y diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index 9af9e68c303..17d37ed57f3 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -3,6 +3,7 @@ comment "Processor Type" config M68000 bool select CPU_HAS_NO_BITFIELDS + select GENERIC_CSUM help The Freescale (was Motorola) 68000 CPU is the first generation of the well known M68K family of processors. The CPU core as well as @@ -23,6 +24,7 @@ config COLDFIRE select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select CPU_HAS_NO_BITFIELDS + select GENERIC_CSUM help The Freescale ColdFire family of processors is a modern derivitive of the 68000 processor family. They are mainly targeted at embedded diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h index ec514485c8b..2f88d867c71 100644 --- a/arch/m68k/include/asm/checksum.h +++ b/arch/m68k/include/asm/checksum.h @@ -3,6 +3,10 @@ #include +#ifdef CONFIG_GENERIC_CSUM +#include +#else + /* * computes the checksum of a memory block at buff, length len, * and adds in "sum" (32-bit) @@ -34,30 +38,6 @@ extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum); - -#ifdef CONFIG_COLDFIRE - -/* - * The ColdFire cores don't support all the 68k instructions used - * in the optimized checksum code below. So it reverts back to using - * more standard C coded checksums. The fast checksum code is - * significantly larger than the optimized version, so it is not - * inlined here. - */ -__sum16 ip_fast_csum(const void *iph, unsigned int ihl); - -static inline __sum16 csum_fold(__wsum sum) -{ - unsigned int tmp = (__force u32)sum; - - tmp = (tmp & 0xffff) + (tmp >> 16); - tmp = (tmp & 0xffff) + (tmp >> 16); - - return (__force __sum16)~tmp; -} - -#else - /* * This is a version of ip_fast_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. @@ -97,8 +77,6 @@ static inline __sum16 csum_fold(__wsum sum) return (__force __sum16)~sum; } -#endif /* CONFIG_COLDFIRE */ - static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, __wsum sum) @@ -167,4 +145,5 @@ csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, return csum_fold(sum); } +#endif /* CONFIG_GENERIC_CSUM */ #endif /* _M68K_CHECKSUM_H */ diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index 1a1bd9067e9..b3b40e4ed33 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -7,8 +7,12 @@ lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ memcpy.o memset.o memmove.o ifdef CONFIG_MMU -lib-y += string.o uaccess.o checksum_mm.o +lib-y += string.o uaccess.o else -lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o checksum_no.o +lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o +endif + +ifndef CONFIG_GENERIC_CSUM +lib-y += checksum.o endif diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c new file mode 100644 index 00000000000..6216f12a756 --- /dev/null +++ b/arch/m68k/lib/checksum.c @@ -0,0 +1,425 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * IP/TCP/UDP checksumming routines + * + * Authors: Jorge Cwik, + * Arnt Gulbrandsen, + * Tom May, + * Andreas Schwab, + * Lots of code moved from tcp.c and ip.c; see those files + * for more names. + * + * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: + * Fixed some nasty bugs, causing some horrible crashes. + * A: At some points, the sum (%0) was used as + * length-counter instead of the length counter + * (%1). Thanks to Roman Hodek for pointing this out. + * B: GCC seems to mess up if one uses too many + * data-registers to hold input values and one tries to + * specify d0 and d1 as scratch registers. Letting gcc + * choose these registers itself solves the problem. + * + * This program 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 of the License, or (at your option) any later version. + * + * 1998/8/31 Andreas Schwab: + * Zero out rest of buffer on exception in + * csum_partial_copy_from_user. + */ + +#include +#include + +/* + * computes a partial checksum, e.g. for TCP/UDP fragments + */ + +__wsum csum_partial(const void *buff, int len, __wsum sum) +{ + unsigned long tmp1, tmp2; + /* + * Experiments with ethernet and slip connections show that buff + * is aligned on either a 2-byte or 4-byte boundary. + */ + __asm__("movel %2,%3\n\t" + "btst #1,%3\n\t" /* Check alignment */ + "jeq 2f\n\t" + "subql #2,%1\n\t" /* buff%4==2: treat first word */ + "jgt 1f\n\t" + "addql #2,%1\n\t" /* len was == 2, treat only rest */ + "jra 4f\n" + "1:\t" + "addw %2@+,%0\n\t" /* add first word to sum */ + "clrl %3\n\t" + "addxl %3,%0\n" /* add X bit */ + "2:\t" + /* unrolled loop for the main part: do 8 longs at once */ + "movel %1,%3\n\t" /* save len in tmp1 */ + "lsrl #5,%1\n\t" /* len/32 */ + "jeq 2f\n\t" /* not enough... */ + "subql #1,%1\n" + "1:\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "dbra %1,1b\n\t" + "clrl %4\n\t" + "addxl %4,%0\n\t" /* add X bit */ + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 1b\n" + "2:\t" + "movel %3,%1\n\t" /* restore len from tmp1 */ + "andw #0x1c,%3\n\t" /* number of rest longs */ + "jeq 4f\n\t" + "lsrw #2,%3\n\t" + "subqw #1,%3\n" + "3:\t" + /* loop for rest longs */ + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "dbra %3,3b\n\t" + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "4:\t" + /* now check for rest bytes that do not fit into longs */ + "andw #3,%1\n\t" + "jeq 7f\n\t" + "clrl %4\n\t" /* clear tmp2 for rest bytes */ + "subqw #2,%1\n\t" + "jlt 5f\n\t" + "movew %2@+,%4\n\t" /* have rest >= 2: get word */ + "swap %4\n\t" /* into bits 16..31 */ + "tstw %1\n\t" /* another byte? */ + "jeq 6f\n" + "5:\t" + "moveb %2@,%4\n\t" /* have odd rest: get byte */ + "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */ + "6:\t" + "addl %4,%0\n\t" /* now add rest long to sum */ + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "7:\t" + : "=d" (sum), "=d" (len), "=a" (buff), + "=&d" (tmp1), "=&d" (tmp2) + : "0" (sum), "1" (len), "2" (buff) + ); + return(sum); +} + +EXPORT_SYMBOL(csum_partial); + + +/* + * copy from user space while checksumming, with exception handling. + */ + +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *csum_err) +{ + /* + * GCC doesn't like more than 10 operands for the asm + * statements so we have to use tmp2 for the error + * code. + */ + unsigned long tmp1, tmp2; + + __asm__("movel %2,%4\n\t" + "btst #1,%4\n\t" /* Check alignment */ + "jeq 2f\n\t" + "subql #2,%1\n\t" /* buff%4==2: treat first word */ + "jgt 1f\n\t" + "addql #2,%1\n\t" /* len was == 2, treat only rest */ + "jra 4f\n" + "1:\n" + "10:\t" + "movesw %2@+,%4\n\t" /* add first word to sum */ + "addw %4,%0\n\t" + "movew %4,%3@+\n\t" + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "2:\t" + /* unrolled loop for the main part: do 8 longs at once */ + "movel %1,%4\n\t" /* save len in tmp1 */ + "lsrl #5,%1\n\t" /* len/32 */ + "jeq 2f\n\t" /* not enough... */ + "subql #1,%1\n" + "1:\n" + "11:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "12:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "13:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "14:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "15:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "16:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "17:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "18:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "dbra %1,1b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n\t" /* add X bit */ + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 1b\n" + "2:\t" + "movel %4,%1\n\t" /* restore len from tmp1 */ + "andw #0x1c,%4\n\t" /* number of rest longs */ + "jeq 4f\n\t" + "lsrw #2,%4\n\t" + "subqw #1,%4\n" + "3:\n" + /* loop for rest longs */ + "19:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "dbra %4,3b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n" /* add X bit */ + "4:\t" + /* now check for rest bytes that do not fit into longs */ + "andw #3,%1\n\t" + "jeq 7f\n\t" + "clrl %5\n\t" /* clear tmp2 for rest bytes */ + "subqw #2,%1\n\t" + "jlt 5f\n\t" + "20:\t" + "movesw %2@+,%5\n\t" /* have rest >= 2: get word */ + "movew %5,%3@+\n\t" + "swap %5\n\t" /* into bits 16..31 */ + "tstw %1\n\t" /* another byte? */ + "jeq 6f\n" + "5:\n" + "21:\t" + "movesb %2@,%5\n\t" /* have odd rest: get byte */ + "moveb %5,%3@+\n\t" + "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */ + "6:\t" + "addl %5,%0\n\t" /* now add rest long to sum */ + "clrl %5\n\t" + "addxl %5,%0\n\t" /* add X bit */ + "7:\t" + "clrl %5\n" /* no error - clear return value */ + "8:\n" + ".section .fixup,\"ax\"\n" + ".even\n" + /* If any exception occurs zero out the rest. + Similarities with the code above are intentional :-) */ + "90:\t" + "clrw %3@+\n\t" + "movel %1,%4\n\t" + "lsrl #5,%1\n\t" + "jeq 1f\n\t" + "subql #1,%1\n" + "91:\t" + "clrl %3@+\n" + "92:\t" + "clrl %3@+\n" + "93:\t" + "clrl %3@+\n" + "94:\t" + "clrl %3@+\n" + "95:\t" + "clrl %3@+\n" + "96:\t" + "clrl %3@+\n" + "97:\t" + "clrl %3@+\n" + "98:\t" + "clrl %3@+\n\t" + "dbra %1,91b\n\t" + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 91b\n" + "1:\t" + "movel %4,%1\n\t" + "andw #0x1c,%4\n\t" + "jeq 1f\n\t" + "lsrw #2,%4\n\t" + "subqw #1,%4\n" + "99:\t" + "clrl %3@+\n\t" + "dbra %4,99b\n\t" + "1:\t" + "andw #3,%1\n\t" + "jeq 9f\n" + "100:\t" + "clrw %3@+\n\t" + "tstw %1\n\t" + "jeq 9f\n" + "101:\t" + "clrb %3@+\n" + "9:\t" +#define STR(X) STR1(X) +#define STR1(X) #X + "moveq #-" STR(EFAULT) ",%5\n\t" + "jra 8b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + ".long 10b,90b\n" + ".long 11b,91b\n" + ".long 12b,92b\n" + ".long 13b,93b\n" + ".long 14b,94b\n" + ".long 15b,95b\n" + ".long 16b,96b\n" + ".long 17b,97b\n" + ".long 18b,98b\n" + ".long 19b,99b\n" + ".long 20b,100b\n" + ".long 21b,101b\n" + ".previous" + : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), + "=&d" (tmp1), "=d" (tmp2) + : "0" (sum), "1" (len), "2" (src), "3" (dst) + ); + + *csum_err = tmp2; + + return(sum); +} + +EXPORT_SYMBOL(csum_partial_copy_from_user); + + +/* + * copy from kernel space while checksumming, otherwise like csum_partial + */ + +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) +{ + unsigned long tmp1, tmp2; + __asm__("movel %2,%4\n\t" + "btst #1,%4\n\t" /* Check alignment */ + "jeq 2f\n\t" + "subql #2,%1\n\t" /* buff%4==2: treat first word */ + "jgt 1f\n\t" + "addql #2,%1\n\t" /* len was == 2, treat only rest */ + "jra 4f\n" + "1:\t" + "movew %2@+,%4\n\t" /* add first word to sum */ + "addw %4,%0\n\t" + "movew %4,%3@+\n\t" + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "2:\t" + /* unrolled loop for the main part: do 8 longs at once */ + "movel %1,%4\n\t" /* save len in tmp1 */ + "lsrl #5,%1\n\t" /* len/32 */ + "jeq 2f\n\t" /* not enough... */ + "subql #1,%1\n" + "1:\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "dbra %1,1b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n\t" /* add X bit */ + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 1b\n" + "2:\t" + "movel %4,%1\n\t" /* restore len from tmp1 */ + "andw #0x1c,%4\n\t" /* number of rest longs */ + "jeq 4f\n\t" + "lsrw #2,%4\n\t" + "subqw #1,%4\n" + "3:\t" + /* loop for rest longs */ + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "dbra %4,3b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n" /* add X bit */ + "4:\t" + /* now check for rest bytes that do not fit into longs */ + "andw #3,%1\n\t" + "jeq 7f\n\t" + "clrl %5\n\t" /* clear tmp2 for rest bytes */ + "subqw #2,%1\n\t" + "jlt 5f\n\t" + "movew %2@+,%5\n\t" /* have rest >= 2: get word */ + "movew %5,%3@+\n\t" + "swap %5\n\t" /* into bits 16..31 */ + "tstw %1\n\t" /* another byte? */ + "jeq 6f\n" + "5:\t" + "moveb %2@,%5\n\t" /* have odd rest: get byte */ + "moveb %5,%3@+\n\t" + "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */ + "6:\t" + "addl %5,%0\n\t" /* now add rest long to sum */ + "clrl %5\n\t" + "addxl %5,%0\n" /* add X bit */ + "7:\t" + : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), + "=&d" (tmp1), "=&d" (tmp2) + : "0" (sum), "1" (len), "2" (src), "3" (dst) + ); + return(sum); +} +EXPORT_SYMBOL(csum_partial_copy_nocheck); diff --git a/arch/m68k/lib/checksum_mm.c b/arch/m68k/lib/checksum_mm.c deleted file mode 100644 index 6216f12a756..00000000000 --- a/arch/m68k/lib/checksum_mm.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * IP/TCP/UDP checksumming routines - * - * Authors: Jorge Cwik, - * Arnt Gulbrandsen, - * Tom May, - * Andreas Schwab, - * Lots of code moved from tcp.c and ip.c; see those files - * for more names. - * - * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: - * Fixed some nasty bugs, causing some horrible crashes. - * A: At some points, the sum (%0) was used as - * length-counter instead of the length counter - * (%1). Thanks to Roman Hodek for pointing this out. - * B: GCC seems to mess up if one uses too many - * data-registers to hold input values and one tries to - * specify d0 and d1 as scratch registers. Letting gcc - * choose these registers itself solves the problem. - * - * This program 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 of the License, or (at your option) any later version. - * - * 1998/8/31 Andreas Schwab: - * Zero out rest of buffer on exception in - * csum_partial_copy_from_user. - */ - -#include -#include - -/* - * computes a partial checksum, e.g. for TCP/UDP fragments - */ - -__wsum csum_partial(const void *buff, int len, __wsum sum) -{ - unsigned long tmp1, tmp2; - /* - * Experiments with ethernet and slip connections show that buff - * is aligned on either a 2-byte or 4-byte boundary. - */ - __asm__("movel %2,%3\n\t" - "btst #1,%3\n\t" /* Check alignment */ - "jeq 2f\n\t" - "subql #2,%1\n\t" /* buff%4==2: treat first word */ - "jgt 1f\n\t" - "addql #2,%1\n\t" /* len was == 2, treat only rest */ - "jra 4f\n" - "1:\t" - "addw %2@+,%0\n\t" /* add first word to sum */ - "clrl %3\n\t" - "addxl %3,%0\n" /* add X bit */ - "2:\t" - /* unrolled loop for the main part: do 8 longs at once */ - "movel %1,%3\n\t" /* save len in tmp1 */ - "lsrl #5,%1\n\t" /* len/32 */ - "jeq 2f\n\t" /* not enough... */ - "subql #1,%1\n" - "1:\t" - "movel %2@+,%4\n\t" - "addxl %4,%0\n\t" - "movel %2@+,%4\n\t" - "addxl %4,%0\n\t" - "movel %2@+,%4\n\t" - "addxl %4,%0\n\t" - "movel %2@+,%4\n\t" - "addxl %4,%0\n\t" - "movel %2@+,%4\n\t" - "addxl %4,%0\n\t" - "movel %2@+,%4\n\t" - "addxl %4,%0\n\t" - "movel %2@+,%4\n\t" - "addxl %4,%0\n\t" - "movel %2@+,%4\n\t" - "addxl %4,%0\n\t" - "dbra %1,1b\n\t" - "clrl %4\n\t" - "addxl %4,%0\n\t" /* add X bit */ - "clrw %1\n\t" - "subql #1,%1\n\t" - "jcc 1b\n" - "2:\t" - "movel %3,%1\n\t" /* restore len from tmp1 */ - "andw #0x1c,%3\n\t" /* number of rest longs */ - "jeq 4f\n\t" - "lsrw #2,%3\n\t" - "subqw #1,%3\n" - "3:\t" - /* loop for rest longs */ - "movel %2@+,%4\n\t" - "addxl %4,%0\n\t" - "dbra %3,3b\n\t" - "clrl %4\n\t" - "addxl %4,%0\n" /* add X bit */ - "4:\t" - /* now check for rest bytes that do not fit into longs */ - "andw #3,%1\n\t" - "jeq 7f\n\t" - "clrl %4\n\t" /* clear tmp2 for rest bytes */ - "subqw #2,%1\n\t" - "jlt 5f\n\t" - "movew %2@+,%4\n\t" /* have rest >= 2: get word */ - "swap %4\n\t" /* into bits 16..31 */ - "tstw %1\n\t" /* another byte? */ - "jeq 6f\n" - "5:\t" - "moveb %2@,%4\n\t" /* have odd rest: get byte */ - "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */ - "6:\t" - "addl %4,%0\n\t" /* now add rest long to sum */ - "clrl %4\n\t" - "addxl %4,%0\n" /* add X bit */ - "7:\t" - : "=d" (sum), "=d" (len), "=a" (buff), - "=&d" (tmp1), "=&d" (tmp2) - : "0" (sum), "1" (len), "2" (buff) - ); - return(sum); -} - -EXPORT_SYMBOL(csum_partial); - - -/* - * copy from user space while checksumming, with exception handling. - */ - -__wsum -csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *csum_err) -{ - /* - * GCC doesn't like more than 10 operands for the asm - * statements so we have to use tmp2 for the error - * code. - */ - unsigned long tmp1, tmp2; - - __asm__("movel %2,%4\n\t" - "btst #1,%4\n\t" /* Check alignment */ - "jeq 2f\n\t" - "subql #2,%1\n\t" /* buff%4==2: treat first word */ - "jgt 1f\n\t" - "addql #2,%1\n\t" /* len was == 2, treat only rest */ - "jra 4f\n" - "1:\n" - "10:\t" - "movesw %2@+,%4\n\t" /* add first word to sum */ - "addw %4,%0\n\t" - "movew %4,%3@+\n\t" - "clrl %4\n\t" - "addxl %4,%0\n" /* add X bit */ - "2:\t" - /* unrolled loop for the main part: do 8 longs at once */ - "movel %1,%4\n\t" /* save len in tmp1 */ - "lsrl #5,%1\n\t" /* len/32 */ - "jeq 2f\n\t" /* not enough... */ - "subql #1,%1\n" - "1:\n" - "11:\t" - "movesl %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "12:\t" - "movesl %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "13:\t" - "movesl %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "14:\t" - "movesl %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "15:\t" - "movesl %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "16:\t" - "movesl %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "17:\t" - "movesl %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "18:\t" - "movesl %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "dbra %1,1b\n\t" - "clrl %5\n\t" - "addxl %5,%0\n\t" /* add X bit */ - "clrw %1\n\t" - "subql #1,%1\n\t" - "jcc 1b\n" - "2:\t" - "movel %4,%1\n\t" /* restore len from tmp1 */ - "andw #0x1c,%4\n\t" /* number of rest longs */ - "jeq 4f\n\t" - "lsrw #2,%4\n\t" - "subqw #1,%4\n" - "3:\n" - /* loop for rest longs */ - "19:\t" - "movesl %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "dbra %4,3b\n\t" - "clrl %5\n\t" - "addxl %5,%0\n" /* add X bit */ - "4:\t" - /* now check for rest bytes that do not fit into longs */ - "andw #3,%1\n\t" - "jeq 7f\n\t" - "clrl %5\n\t" /* clear tmp2 for rest bytes */ - "subqw #2,%1\n\t" - "jlt 5f\n\t" - "20:\t" - "movesw %2@+,%5\n\t" /* have rest >= 2: get word */ - "movew %5,%3@+\n\t" - "swap %5\n\t" /* into bits 16..31 */ - "tstw %1\n\t" /* another byte? */ - "jeq 6f\n" - "5:\n" - "21:\t" - "movesb %2@,%5\n\t" /* have odd rest: get byte */ - "moveb %5,%3@+\n\t" - "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */ - "6:\t" - "addl %5,%0\n\t" /* now add rest long to sum */ - "clrl %5\n\t" - "addxl %5,%0\n\t" /* add X bit */ - "7:\t" - "clrl %5\n" /* no error - clear return value */ - "8:\n" - ".section .fixup,\"ax\"\n" - ".even\n" - /* If any exception occurs zero out the rest. - Similarities with the code above are intentional :-) */ - "90:\t" - "clrw %3@+\n\t" - "movel %1,%4\n\t" - "lsrl #5,%1\n\t" - "jeq 1f\n\t" - "subql #1,%1\n" - "91:\t" - "clrl %3@+\n" - "92:\t" - "clrl %3@+\n" - "93:\t" - "clrl %3@+\n" - "94:\t" - "clrl %3@+\n" - "95:\t" - "clrl %3@+\n" - "96:\t" - "clrl %3@+\n" - "97:\t" - "clrl %3@+\n" - "98:\t" - "clrl %3@+\n\t" - "dbra %1,91b\n\t" - "clrw %1\n\t" - "subql #1,%1\n\t" - "jcc 91b\n" - "1:\t" - "movel %4,%1\n\t" - "andw #0x1c,%4\n\t" - "jeq 1f\n\t" - "lsrw #2,%4\n\t" - "subqw #1,%4\n" - "99:\t" - "clrl %3@+\n\t" - "dbra %4,99b\n\t" - "1:\t" - "andw #3,%1\n\t" - "jeq 9f\n" - "100:\t" - "clrw %3@+\n\t" - "tstw %1\n\t" - "jeq 9f\n" - "101:\t" - "clrb %3@+\n" - "9:\t" -#define STR(X) STR1(X) -#define STR1(X) #X - "moveq #-" STR(EFAULT) ",%5\n\t" - "jra 8b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - ".long 10b,90b\n" - ".long 11b,91b\n" - ".long 12b,92b\n" - ".long 13b,93b\n" - ".long 14b,94b\n" - ".long 15b,95b\n" - ".long 16b,96b\n" - ".long 17b,97b\n" - ".long 18b,98b\n" - ".long 19b,99b\n" - ".long 20b,100b\n" - ".long 21b,101b\n" - ".previous" - : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), - "=&d" (tmp1), "=d" (tmp2) - : "0" (sum), "1" (len), "2" (src), "3" (dst) - ); - - *csum_err = tmp2; - - return(sum); -} - -EXPORT_SYMBOL(csum_partial_copy_from_user); - - -/* - * copy from kernel space while checksumming, otherwise like csum_partial - */ - -__wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) -{ - unsigned long tmp1, tmp2; - __asm__("movel %2,%4\n\t" - "btst #1,%4\n\t" /* Check alignment */ - "jeq 2f\n\t" - "subql #2,%1\n\t" /* buff%4==2: treat first word */ - "jgt 1f\n\t" - "addql #2,%1\n\t" /* len was == 2, treat only rest */ - "jra 4f\n" - "1:\t" - "movew %2@+,%4\n\t" /* add first word to sum */ - "addw %4,%0\n\t" - "movew %4,%3@+\n\t" - "clrl %4\n\t" - "addxl %4,%0\n" /* add X bit */ - "2:\t" - /* unrolled loop for the main part: do 8 longs at once */ - "movel %1,%4\n\t" /* save len in tmp1 */ - "lsrl #5,%1\n\t" /* len/32 */ - "jeq 2f\n\t" /* not enough... */ - "subql #1,%1\n" - "1:\t" - "movel %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "movel %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "movel %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "movel %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "movel %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "movel %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "movel %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "movel %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "dbra %1,1b\n\t" - "clrl %5\n\t" - "addxl %5,%0\n\t" /* add X bit */ - "clrw %1\n\t" - "subql #1,%1\n\t" - "jcc 1b\n" - "2:\t" - "movel %4,%1\n\t" /* restore len from tmp1 */ - "andw #0x1c,%4\n\t" /* number of rest longs */ - "jeq 4f\n\t" - "lsrw #2,%4\n\t" - "subqw #1,%4\n" - "3:\t" - /* loop for rest longs */ - "movel %2@+,%5\n\t" - "addxl %5,%0\n\t" - "movel %5,%3@+\n\t" - "dbra %4,3b\n\t" - "clrl %5\n\t" - "addxl %5,%0\n" /* add X bit */ - "4:\t" - /* now check for rest bytes that do not fit into longs */ - "andw #3,%1\n\t" - "jeq 7f\n\t" - "clrl %5\n\t" /* clear tmp2 for rest bytes */ - "subqw #2,%1\n\t" - "jlt 5f\n\t" - "movew %2@+,%5\n\t" /* have rest >= 2: get word */ - "movew %5,%3@+\n\t" - "swap %5\n\t" /* into bits 16..31 */ - "tstw %1\n\t" /* another byte? */ - "jeq 6f\n" - "5:\t" - "moveb %2@,%5\n\t" /* have odd rest: get byte */ - "moveb %5,%3@+\n\t" - "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */ - "6:\t" - "addl %5,%0\n\t" /* now add rest long to sum */ - "clrl %5\n\t" - "addxl %5,%0\n" /* add X bit */ - "7:\t" - : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), - "=&d" (tmp1), "=&d" (tmp2) - : "0" (sum), "1" (len), "2" (src), "3" (dst) - ); - return(sum); -} -EXPORT_SYMBOL(csum_partial_copy_nocheck); diff --git a/arch/m68k/lib/checksum_no.c b/arch/m68k/lib/checksum_no.c deleted file mode 100644 index e4c6354da76..00000000000 --- a/arch/m68k/lib/checksum_no.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * IP/TCP/UDP checksumming routines - * - * Authors: Jorge Cwik, - * Arnt Gulbrandsen, - * Tom May, - * Andreas Schwab, - * Lots of code moved from tcp.c and ip.c; see those files - * for more names. - * - * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: - * Fixed some nasty bugs, causing some horrible crashes. - * A: At some points, the sum (%0) was used as - * length-counter instead of the length counter - * (%1). Thanks to Roman Hodek for pointing this out. - * B: GCC seems to mess up if one uses too many - * data-registers to hold input values and one tries to - * specify d0 and d1 as scratch registers. Letting gcc choose these - * registers itself solves the problem. - * - * This program 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 of the License, or (at your option) any later version. - */ - -/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most - of the assembly has to go. */ - -#include -#include - -static inline unsigned short from32to16(unsigned long x) -{ - /* add up 16-bit and 16-bit for 16+c bit */ - x = (x & 0xffff) + (x >> 16); - /* add up carry.. */ - x = (x & 0xffff) + (x >> 16); - return x; -} - -static unsigned long do_csum(const unsigned char * buff, int len) -{ - int odd, count; - unsigned long result = 0; - - if (len <= 0) - goto out; - odd = 1 & (unsigned long) buff; - if (odd) { - result = *buff; - len--; - buff++; - } - count = len >> 1; /* nr of 16-bit words.. */ - if (count) { - if (2 & (unsigned long) buff) { - result += *(unsigned short *) buff; - count--; - len -= 2; - buff += 2; - } - count >>= 1; /* nr of 32-bit words.. */ - if (count) { - unsigned long carry = 0; - do { - unsigned long w = *(unsigned long *) buff; - count--; - buff += 4; - result += carry; - result += w; - carry = (w > result); - } while (count); - result += carry; - result = (result & 0xffff) + (result >> 16); - } - if (len & 2) { - result += *(unsigned short *) buff; - buff += 2; - } - } - if (len & 1) - result += (*buff << 8); - result = from32to16(result); - if (odd) - result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); -out: - return result; -} - -#ifdef CONFIG_COLDFIRE -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - */ -__sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - return (__force __sum16)~do_csum(iph,ihl*4); -} -EXPORT_SYMBOL(ip_fast_csum); -#endif - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum) -{ - unsigned int result = do_csum(buff, len); - - /* add in old sum, and carry.. */ - result += (__force u32)sum; - if ((__force u32)sum > result) - result += 1; - return (__force __wsum)result; -} - -EXPORT_SYMBOL(csum_partial); - -/* - * copy from fs while checksumming, otherwise like csum_partial - */ - -__wsum -csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *csum_err) -{ - if (csum_err) *csum_err = 0; - memcpy(dst, (__force const void *)src, len); - return csum_partial(dst, len, sum); -} -EXPORT_SYMBOL(csum_partial_copy_from_user); - -/* - * copy from ds while checksumming, otherwise like csum_partial - */ - -__wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) -{ - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} -EXPORT_SYMBOL(csum_partial_copy_nocheck); -- cgit v1.2.3-18-g5258 From 84f3fb7a2aadeda3c0a34e61591a8eccf5e367b4 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 11 Nov 2011 15:13:08 +1000 Subject: m68k: handle presence of 64bit mul/div instructions cleanly The traditional 68000 processors and the newer reduced instruction set ColdFire processors do not support the 32*32->64 multiply or the 64/32->32 divide instructions. This is not a difference based on the presence of a hardware MMU or not. Create a new config symbol to mark that a CPU type doesn't support the longer multiply/divide instructions. Use this then as a basis for using the fast 64bit based divide (in div64.h) and for linking in the extra libgcc functions that may be required (mulsi3, divsi3, etc). Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/Kconfig | 3 +++ arch/m68k/Kconfig.cpu | 2 ++ arch/m68k/include/asm/div64.h | 8 ++++---- arch/m68k/kernel/m68k_ksyms.c | 2 +- arch/m68k/lib/Makefile | 8 +++----- 5 files changed, 13 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 2fe2d633fe0..32fd3642e71 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -63,6 +63,9 @@ config ZONE_DMA config CPU_HAS_NO_BITFIELDS bool +config CPU_HAS_NO_MULDIV64 + bool + config HZ int default 1000 if CLEOPATRA diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index 17d37ed57f3..017f4fc388d 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -3,6 +3,7 @@ comment "Processor Type" config M68000 bool select CPU_HAS_NO_BITFIELDS + selec