diff options
Diffstat (limited to 'arch/sh/kernel/cpu/sh5')
| -rw-r--r-- | arch/sh/kernel/cpu/sh5/clock-sh5.c | 12 | ||||
| -rw-r--r-- | arch/sh/kernel/cpu/sh5/entry.S | 125 | ||||
| -rw-r--r-- | arch/sh/kernel/cpu/sh5/fpu.c | 3 | ||||
| -rw-r--r-- | arch/sh/kernel/cpu/sh5/probe.c | 2 | ||||
| -rw-r--r-- | arch/sh/kernel/cpu/sh5/setup-sh5.c | 91 | ||||
| -rw-r--r-- | arch/sh/kernel/cpu/sh5/unwind.c | 63 | 
6 files changed, 94 insertions, 202 deletions
diff --git a/arch/sh/kernel/cpu/sh5/clock-sh5.c b/arch/sh/kernel/cpu/sh5/clock-sh5.c index 9cfc19b8dbe..c48b93d4c08 100644 --- a/arch/sh/kernel/cpu/sh5/clock-sh5.c +++ b/arch/sh/kernel/cpu/sh5/clock-sh5.c @@ -28,7 +28,7 @@ static void master_clk_init(struct clk *clk)  	clk->rate *= ifc_table[idx];  } -static struct clk_ops sh5_master_clk_ops = { +static struct sh_clk_ops sh5_master_clk_ops = {  	.init		= master_clk_init,  }; @@ -38,7 +38,7 @@ static unsigned long module_clk_recalc(struct clk *clk)  	return clk->parent->rate / ifc_table[idx];  } -static struct clk_ops sh5_module_clk_ops = { +static struct sh_clk_ops sh5_module_clk_ops = {  	.recalc		= module_clk_recalc,  }; @@ -48,7 +48,7 @@ static unsigned long bus_clk_recalc(struct clk *clk)  	return clk->parent->rate / ifc_table[idx];  } -static struct clk_ops sh5_bus_clk_ops = { +static struct sh_clk_ops sh5_bus_clk_ops = {  	.recalc		= bus_clk_recalc,  }; @@ -58,18 +58,18 @@ static unsigned long cpu_clk_recalc(struct clk *clk)  	return clk->parent->rate / ifc_table[idx];  } -static struct clk_ops sh5_cpu_clk_ops = { +static struct sh_clk_ops sh5_cpu_clk_ops = {  	.recalc		= cpu_clk_recalc,  }; -static struct clk_ops *sh5_clk_ops[] = { +static struct sh_clk_ops *sh5_clk_ops[] = {  	&sh5_master_clk_ops,  	&sh5_module_clk_ops,  	&sh5_bus_clk_ops,  	&sh5_cpu_clk_ops,  }; -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)  {  	cprc_base = (unsigned long)ioremap_nocache(CPRC_BASE, 1024);  	BUG_ON(!cprc_base); diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S index 6b80295dd7a..0c8d0377d40 100644 --- a/arch/sh/kernel/cpu/sh5/entry.S +++ b/arch/sh/kernel/cpu/sh5/entry.S @@ -335,7 +335,7 @@ tlb_miss:  	/* If the fast path handler fixed the fault, just drop through quickly  	   to the restore code right away to return to the excepting context.  	   */ -	beqi/u	r2, 0, tr1 +	bnei/u	r2, 0, tr1  fast_tlb_miss_restore:  	ld.q	SP, SAVED_TR0, r2 @@ -933,7 +933,7 @@ ret_with_reschedule:  	pta	restore_all, tr1 -	movi	_TIF_SIGPENDING, r8 +	movi	(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), r8  	and	r8, r7, r8  	pta	work_notifysig, tr0  	bne	r8, ZERO, tr0 @@ -1079,9 +1079,8 @@ restore_all:   *   * Kernel TLB fault handlers will get a slightly different interface.   * (r2)   struct pt_regs *, original register's frame pointer - * (r3)   writeaccess, whether it's a store fault as opposed to load fault - * (r4)   execaccess, whether it's a ITLB fault as opposed to DTLB fault - * (r5)   Effective Address of fault + * (r3)   page fault error code (see asm/thread_info.h) + * (r4)   Effective Address of fault   * (LINK) return address   * (SP)   = r2   * @@ -1092,26 +1091,25 @@ restore_all:  tlb_miss_load:  	or	SP, ZERO, r2  	or	ZERO, ZERO, r3		/* Read */ -	or	ZERO, ZERO, r4		/* Data */ -	getcon	TEA, r5 +	getcon	TEA, r4  	pta	call_do_page_fault, tr0  	beq	ZERO, ZERO, tr0  tlb_miss_store:  	or	SP, ZERO, r2 -	movi	1, r3			/* Write */ -	or	ZERO, ZERO, r4		/* Data */ -	getcon	TEA, r5 +	movi	FAULT_CODE_WRITE, r3		/* Write */ +	getcon	TEA, r4  	pta	call_do_page_fault, tr0  	beq	ZERO, ZERO, tr0  itlb_miss_or_IRQ:  	pta	its_IRQ, tr0  	beqi/u	r4, EVENT_INTERRUPT, tr0 + +	/* ITLB miss */  	or	SP, ZERO, r2 -	or	ZERO, ZERO, r3		/* Read */ -	movi	1, r4			/* Text */ -	getcon	TEA, r5 +	movi	FAULT_CODE_ITLB, r3 +	getcon	TEA, r4  	/* Fall through */  call_do_page_fault: @@ -1230,6 +1228,25 @@ ret_from_fork:  	pta	ret_from_syscall, tr0  	blink	tr0, ZERO +.global	ret_from_kernel_thread +ret_from_kernel_thread: + +	movi	schedule_tail,r5 +	ori	r5, 1, r5 +	ptabs	r5, tr0 +	blink	tr0, LINK + +	ld.q	SP, FRAME_R(2), r2 +	ld.q	SP, FRAME_R(3), r3 +	ptabs	r3, tr0 +	blink	tr0, LINK + +	ld.q	SP, FRAME_S(FSPC), r2 +	addi	r2, 4, r2		/* Move PC, being pre-execution event */ +	st.q	SP, FRAME_S(FSPC), r2 +	pta	ret_from_syscall, tr0 +	blink	tr0, ZERO +  syscall_allowed:  	/* Use LINK to deflect the exit point, default is syscall_ret */  	pta	syscall_ret, tr0 @@ -1571,86 +1588,6 @@ ___clear_user_exit:  #endif /* CONFIG_MMU */  /* - * int __strncpy_from_user(unsigned long __dest, unsigned long __src, - *			   int __count) - * - * Inputs: - * (r2)  target address - * (r3)  source address - * (r4)  maximum size in bytes - * - * Ouputs: - * (*r2) copied data - * (r2)  -EFAULT (in case of faulting) - *       copied data (otherwise) - */ -	.global	__strncpy_from_user -__strncpy_from_user: -	pta	___strncpy_from_user1, tr0 -	pta	___strncpy_from_user_done, tr1 -	or	r4, ZERO, r5		/* r5 = original count */ -	beq/u	r4, r63, tr1		/* early exit if r4==0 */ -	movi	-(EFAULT), r6		/* r6 = reply, no real fixup */ -	or	ZERO, ZERO, r7		/* r7 = data, clear top byte of data */ - -___strncpy_from_user1: -	ld.b	r3, 0, r7		/* Fault address: only in reading */ -	st.b	r2, 0, r7 -	addi	r2, 1, r2 -	addi	r3, 1, r3 -	beq/u	ZERO, r7, tr1 -	addi	r4, -1, r4		/* return real number of copied bytes */ -	bne/l	ZERO, r4, tr0 - -___strncpy_from_user_done: -	sub	r5, r4, r6		/* If done, return copied */ - -___strncpy_from_user_exit: -	or	r6, ZERO, r2 -	ptabs	LINK, tr0 -	blink	tr0, ZERO - -/* - * extern long __strnlen_user(const char *__s, long __n) - * - * Inputs: - * (r2)  source address - * (r3)  source size in bytes - * - * Ouputs: - * (r2)  -EFAULT (in case of faulting) - *       string length (otherwise) - */ -	.global	__strnlen_user -__strnlen_user: -	pta	___strnlen_user_set_reply, tr0 -	pta	___strnlen_user1, tr1 -	or	ZERO, ZERO, r5		/* r5 = counter */ -	movi	-(EFAULT), r6		/* r6 = reply, no real fixup */ -	or	ZERO, ZERO, r7		/* r7 = data, clear top byte of data */ -	beq	r3, ZERO, tr0 - -___strnlen_user1: -	ldx.b	r2, r5, r7		/* Fault address: only in reading */ -	addi	r3, -1, r3		/* No real fixup */ -	addi	r5, 1, r5 -	beq	r3, ZERO, tr0 -	bne	r7, ZERO, tr1 -! The line below used to be active.  This meant led to a junk byte lying between each pair -! of entries in the argv & envp structures in memory.  Whilst the program saw the right data -! via the argv and envp arguments to main, it meant the 'flat' representation visible through -! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example. -!	addi	r5, 1, r5		/* Include '\0' */ - -___strnlen_user_set_reply: -	or	r5, ZERO, r6		/* If done, return counter */ - -___strnlen_user_exit: -	or	r6, ZERO, r2 -	ptabs	LINK, tr0 -	blink	tr0, ZERO - -/*   * extern long __get_user_asm_?(void *val, long addr)   *   * Inputs: @@ -1984,8 +1921,6 @@ asm_uaccess_start:  	.long	___copy_user2, ___copy_user_exit  	.long	___clear_user1, ___clear_user_exit  #endif -	.long	___strncpy_from_user1, ___strncpy_from_user_exit -	.long	___strnlen_user1, ___strnlen_user_exit  	.long	___get_user_asm_b1, ___get_user_asm_b_exit  	.long	___get_user_asm_w1, ___get_user_asm_w_exit  	.long	___get_user_asm_l1, ___get_user_asm_l_exit diff --git a/arch/sh/kernel/cpu/sh5/fpu.c b/arch/sh/kernel/cpu/sh5/fpu.c index 4b3bb35e99f..9f8713aa718 100644 --- a/arch/sh/kernel/cpu/sh5/fpu.c +++ b/arch/sh/kernel/cpu/sh5/fpu.c @@ -107,8 +107,5 @@ asmlinkage void do_fpu_error(unsigned long ex, struct pt_regs *regs)  	regs->pc += 4; -	tsk->thread.trap_no = 11; -	tsk->thread.error_code = 0; -  	force_sig(SIGFPE, tsk);  } diff --git a/arch/sh/kernel/cpu/sh5/probe.c b/arch/sh/kernel/cpu/sh5/probe.c index 9e882409e4e..eca427c2f2f 100644 --- a/arch/sh/kernel/cpu/sh5/probe.c +++ b/arch/sh/kernel/cpu/sh5/probe.c @@ -17,7 +17,7 @@  #include <asm/cache.h>  #include <asm/tlb.h> -void __cpuinit cpu_probe(void) +void cpu_probe(void)  {  	unsigned long long cir; diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index d910666142b..1bf0b2cf665 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -17,15 +17,23 @@  #include <asm/addrspace.h>  static struct plat_sci_port scif0_platform_data = { -	.mapbase	= PHYS_PERIPHERAL_BLOCK + 0x01030000,  	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP, +	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_REIE,  	.type		= PORT_SCIF, -	.irqs		= { 39, 40, 42, 0 }, +}; + +static struct resource scif0_resources[] = { +	DEFINE_RES_MEM(PHYS_PERIPHERAL_BLOCK + 0x01030000, 0x100), +	DEFINE_RES_IRQ(39), +	DEFINE_RES_IRQ(40), +	DEFINE_RES_IRQ(42),  };  static struct platform_device scif0_device = {  	.name		= "sh-sci",  	.id		= 0, +	.resource	= scif0_resources, +	.num_resources	= ARRAY_SIZE(scif0_resources),  	.dev		= {  		.platform_data	= &scif0_platform_data,  	}, @@ -63,30 +71,20 @@ static struct platform_device rtc_device = {  #define	TMU_BLOCK_OFF	0x01020000  #define TMU_BASE	PHYS_PERIPHERAL_BLOCK + TMU_BLOCK_OFF -#define TMU0_BASE	(TMU_BASE + 0x8 + (0xc * 0x0)) -#define TMU1_BASE	(TMU_BASE + 0x8 + (0xc * 0x1)) -#define TMU2_BASE	(TMU_BASE + 0x8 + (0xc * 0x2))  static struct sh_timer_config tmu0_platform_data = { -	.channel_offset = 0x04, -	.timer_bit = 0, -	.clockevent_rating = 200, +	.channels_mask = 7,  };  static struct resource tmu0_resources[] = { -	[0] = { -		.start	= TMU0_BASE, -		.end	= TMU0_BASE + 0xc - 1, -		.flags	= IORESOURCE_MEM, -	}, -	[1] = { -		.start	= IRQ_TUNI0, -		.flags	= IORESOURCE_IRQ, -	}, +	DEFINE_RES_MEM(TMU_BASE, 0x30), +	DEFINE_RES_IRQ(IRQ_TUNI0), +	DEFINE_RES_IRQ(IRQ_TUNI1), +	DEFINE_RES_IRQ(IRQ_TUNI2),  };  static struct platform_device tmu0_device = { -	.name		= "sh_tmu", +	.name		= "sh-tmu",  	.id		= 0,  	.dev = {  		.platform_data	= &tmu0_platform_data, @@ -95,66 +93,9 @@ static struct platform_device tmu0_device = {  	.num_resources	= ARRAY_SIZE(tmu0_resources),  }; -static struct sh_timer_config tmu1_platform_data = { -	.channel_offset = 0x10, -	.timer_bit = 1, -	.clocksource_rating = 200, -}; - -static struct resource tmu1_resources[] = { -	[0] = { -		.start	= TMU1_BASE, -		.end	= TMU1_BASE + 0xc - 1, -		.flags	= IORESOURCE_MEM, -	}, -	[1] = { -		.start	= IRQ_TUNI1, -		.flags	= IORESOURCE_IRQ, -	}, -}; - -static struct platform_device tmu1_device = { -	.name		= "sh_tmu", -	.id		= 1, -	.dev = { -		.platform_data	= &tmu1_platform_data, -	}, -	.resource	= tmu1_resources, -	.num_resources	= ARRAY_SIZE(tmu1_resources), -}; - -static struct sh_timer_config tmu2_platform_data = { -	.channel_offset = 0x1c, -	.timer_bit = 2, -}; - -static struct resource tmu2_resources[] = { -	[0] = { -		.start	= TMU2_BASE, -		.end	= TMU2_BASE + 0xc - 1, -		.flags	= IORESOURCE_MEM, -	}, -	[1] = { -		.start	= IRQ_TUNI2, -		.flags	= IORESOURCE_IRQ, -	}, -}; - -static struct platform_device tmu2_device = { -	.name		= "sh_tmu", -	.id		= 2, -	.dev = { -		.platform_data	= &tmu2_platform_data, -	}, -	.resource	= tmu2_resources, -	.num_resources	= ARRAY_SIZE(tmu2_resources), -}; -  static struct platform_device *sh5_early_devices[] __initdata = {  	&scif0_device,  	&tmu0_device, -	&tmu1_device, -	&tmu2_device,  };  static struct platform_device *sh5_devices[] __initdata = { diff --git a/arch/sh/kernel/cpu/sh5/unwind.c b/arch/sh/kernel/cpu/sh5/unwind.c index b205b25eaf4..10aed41757f 100644 --- a/arch/sh/kernel/cpu/sh5/unwind.c +++ b/arch/sh/kernel/cpu/sh5/unwind.c @@ -16,6 +16,8 @@  #include <asm/ptrace.h>  #include <asm/processor.h>  #include <asm/io.h> +#include <asm/unwinder.h> +#include <asm/stacktrace.h>  static u8 regcache[63]; @@ -199,8 +201,11 @@ static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc,  	return 0;  } -/* Don't put this on the stack since we'll want to call sh64_unwind - * when we're close to underflowing the stack anyway. */ +/* + * Don't put this on the stack since we'll want to call in to + * sh64_unwinder_dump() when we're close to underflowing the stack + * anyway. + */  static struct pt_regs here_regs;  extern const char syscall_ret; @@ -208,17 +213,19 @@ extern const char ret_from_syscall;  extern const char ret_from_exception;  extern const char ret_from_irq; -static void sh64_unwind_inner(struct pt_regs *regs); +static void sh64_unwind_inner(const struct stacktrace_ops *ops, +			      void *data, struct pt_regs *regs); -static void unwind_nested (unsigned long pc, unsigned long fp) +static inline void unwind_nested(const struct stacktrace_ops *ops, void *data, +				 unsigned long pc, unsigned long fp)  {  	if ((fp >= __MEMORY_START) && -	    ((fp & 7) == 0)) { -		sh64_unwind_inner((struct pt_regs *) fp); -	} +	    ((fp & 7) == 0)) +		sh64_unwind_inner(ops, data, (struct pt_regs *)fp);  } -static void sh64_unwind_inner(struct pt_regs *regs) +static void sh64_unwind_inner(const struct stacktrace_ops *ops, +			      void *data, struct pt_regs *regs)  {  	unsigned long pc, fp;  	int ofs = 0; @@ -232,29 +239,29 @@ static void sh64_unwind_inner(struct pt_regs *regs)  		int cond;  		unsigned long next_fp, next_pc; -		if (pc == ((unsigned long) &syscall_ret & ~1)) { +		if (pc == ((unsigned long)&syscall_ret & ~1)) {  			printk("SYSCALL\n"); -			unwind_nested(pc,fp); +			unwind_nested(ops, data, pc, fp);  			return;  		} -		if (pc == ((unsigned long) &ret_from_syscall & ~1)) { +		if (pc == ((unsigned long)&ret_from_syscall & ~1)) {  			printk("SYSCALL (PREEMPTED)\n"); -			unwind_nested(pc,fp); +			unwind_nested(ops, data, pc, fp);  			return;  		}  		/* In this case, the PC is discovered by lookup_prev_stack_frame but  		   it has 4 taken off it to look like the 'caller' */ -		if (pc == ((unsigned long) &ret_from_exception & ~1)) { +		if (pc == ((unsigned long)&ret_from_exception & ~1)) {  			printk("EXCEPTION\n"); -			unwind_nested(pc,fp); +			unwind_nested(ops, data, pc, fp);  			return;  		} -		if (pc == ((unsigned long) &ret_from_irq & ~1)) { +		if (pc == ((unsigned long)&ret_from_irq & ~1)) {  			printk("IRQ\n"); -			unwind_nested(pc,fp); +			unwind_nested(ops, data, pc, fp);  			return;  		} @@ -263,8 +270,7 @@ static void sh64_unwind_inner(struct pt_regs *regs)  		pc -= ofs; -		printk("[<%08lx>] ", pc); -		print_symbol("%s\n", pc); +		ops->address(data, pc, 1);  		if (first_pass) {  			/* If the innermost frame is a leaf function, it's @@ -287,10 +293,13 @@ static void sh64_unwind_inner(struct pt_regs *regs)  	}  	printk("\n"); -  } -void sh64_unwind(struct pt_regs *regs) +static void sh64_unwinder_dump(struct task_struct *task, +			       struct pt_regs *regs, +			       unsigned long *sp, +			       const struct stacktrace_ops *ops, +			       void *data)  {  	if (!regs) {  		/* @@ -320,7 +329,17 @@ void sh64_unwind(struct pt_regs *regs)  		);  	} -	printk("\nCall Trace:\n"); -	sh64_unwind_inner(regs); +	sh64_unwind_inner(ops, data, regs);  } +static struct unwinder sh64_unwinder = { +	.name	= "sh64-unwinder", +	.dump	= sh64_unwinder_dump, +	.rating	= 150, +}; + +static int __init sh64_unwinder_init(void) +{ +	return unwinder_register(&sh64_unwinder); +} +early_initcall(sh64_unwinder_init);  | 
