From 1a27f7d9c27671e7ae3cd0a3ee316149fa0824dc Mon Sep 17 00:00:00 2001 From: Vitaly Kuzmichev Date: Tue, 15 Jun 2010 22:18:11 +0400 Subject: ARM: Align stack to 8 bytes The ARM ABI requires that the stack be aligned to 8 bytes as it is noted in Procedure Call Standard for the ARM Architecture: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/index.html Unaligned SP also causes the problem with variable-length arrays allocation when VLA address becomes less than stack pointer during aligning of this address, so the next 'push' in the stack overwrites first 4 bytes of VLA. Signed-off-by: Vitaly Kuzmichev --- arch/arm/cpu/arm1136/start.S | 1 + arch/arm/cpu/arm1176/start.S | 1 + arch/arm/cpu/arm720t/start.S | 1 + arch/arm/cpu/arm920t/start.S | 1 + arch/arm/cpu/arm925t/start.S | 1 + arch/arm/cpu/arm926ejs/start.S | 2 +- arch/arm/cpu/arm946es/start.S | 1 + arch/arm/cpu/arm_cortexa8/start.S | 2 +- arch/arm/cpu/arm_intcm/start.S | 1 + arch/arm/cpu/ixp/start.S | 1 + arch/arm/cpu/lh7a40x/start.S | 1 + arch/arm/cpu/pxa/start.S | 6 ++---- arch/arm/cpu/s3c44b0/start.S | 1 + arch/arm/cpu/sa1100/start.S | 1 + 14 files changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/arm/cpu/arm1136/start.S b/arch/arm/cpu/arm1136/start.S index 922d01c..41eb82d 100644 --- a/arch/arm/cpu/arm1136/start.S +++ b/arch/arm/cpu/arm1136/start.S @@ -185,6 +185,7 @@ stack_setup: #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ #endif /* CONFIG_PRELOADER */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ diff --git a/arch/arm/cpu/arm1176/start.S b/arch/arm/cpu/arm1176/start.S index a540edb..f98a7aa 100644 --- a/arch/arm/cpu/arm1176/start.S +++ b/arch/arm/cpu/arm1176/start.S @@ -276,6 +276,7 @@ stack_setup: sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ diff --git a/arch/arm/cpu/arm720t/start.S b/arch/arm/cpu/arm720t/start.S index 022b873..d6f2c16 100644 --- a/arch/arm/cpu/arm720t/start.S +++ b/arch/arm/cpu/arm720t/start.S @@ -172,6 +172,7 @@ stack_setup: sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ diff --git a/arch/arm/cpu/arm920t/start.S b/arch/arm/cpu/arm920t/start.S index 779f192..e532f55 100644 --- a/arch/arm/cpu/arm920t/start.S +++ b/arch/arm/cpu/arm920t/start.S @@ -204,6 +204,7 @@ stack_setup: sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ diff --git a/arch/arm/cpu/arm925t/start.S b/arch/arm/cpu/arm925t/start.S index 567e804..346615e 100644 --- a/arch/arm/cpu/arm925t/start.S +++ b/arch/arm/cpu/arm925t/start.S @@ -196,6 +196,7 @@ stack_setup: sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S index 3b81151..cf40ce1 100644 --- a/arch/arm/cpu/arm926ejs/start.S +++ b/arch/arm/cpu/arm926ejs/start.S @@ -196,7 +196,7 @@ stack_setup: #endif #endif /* CONFIG_PRELOADER */ sub sp, r0, #12 /* leave 3 words for abort-stack */ - bic sp, r0, #7 /* 8-byte align stack for ABI compliance */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ diff --git a/arch/arm/cpu/arm946es/start.S b/arch/arm/cpu/arm946es/start.S index 627e3cb..8844d44 100644 --- a/arch/arm/cpu/arm946es/start.S +++ b/arch/arm/cpu/arm946es/start.S @@ -163,6 +163,7 @@ stack_setup: sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ diff --git a/arch/arm/cpu/arm_cortexa8/start.S b/arch/arm/cpu/arm_cortexa8/start.S index 29dae2f..1e0a150 100644 --- a/arch/arm/cpu/arm_cortexa8/start.S +++ b/arch/arm/cpu/arm_cortexa8/start.S @@ -164,7 +164,7 @@ stack_setup: sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 @ leave 3 words for abort-stack - and sp, sp, #~7 @ 8 byte alinged for (ldr/str)d + bic sp, sp, #7 @ 8-byte alignment for ABI compliance /* Clear BSS (if any). Is below tx (watch load addr - need space) */ clear_bss: diff --git a/arch/arm/cpu/arm_intcm/start.S b/arch/arm/cpu/arm_intcm/start.S index bb1f003..328bae0 100644 --- a/arch/arm/cpu/arm_intcm/start.S +++ b/arch/arm/cpu/arm_intcm/start.S @@ -161,6 +161,7 @@ stack_setup: sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ diff --git a/arch/arm/cpu/ixp/start.S b/arch/arm/cpu/ixp/start.S index 5ebce53..6efe333 100644 --- a/arch/arm/cpu/ixp/start.S +++ b/arch/arm/cpu/ixp/start.S @@ -289,6 +289,7 @@ stack_setup: sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ diff --git a/arch/arm/cpu/lh7a40x/start.S b/arch/arm/cpu/lh7a40x/start.S index a1321b1..14a1fbe 100644 --- a/arch/arm/cpu/lh7a40x/start.S +++ b/arch/arm/cpu/lh7a40x/start.S @@ -178,6 +178,7 @@ stack_setup: sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ diff --git a/arch/arm/cpu/pxa/start.S b/arch/arm/cpu/pxa/start.S index 3989fa6..e07c8c2 100644 --- a/arch/arm/cpu/pxa/start.S +++ b/arch/arm/cpu/pxa/start.S @@ -140,10 +140,8 @@ stack_setup: #ifdef CONFIG_USE_IRQ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif /* CONFIG_USE_IRQ */ - sub r0, r0, #12 /* leave 3 words for abort-stack */ - bic sp, r0, #7 /* NOTE: stack MUST be aligned to */ - /* 8 bytes in case we want to use */ - /* 64bit datatypes (eg. VSPRINTF64) */ + sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ diff --git a/arch/arm/cpu/s3c44b0/start.S b/arch/arm/cpu/s3c44b0/start.S index f5a3d3a..0063063 100644 --- a/arch/arm/cpu/s3c44b0/start.S +++ b/arch/arm/cpu/s3c44b0/start.S @@ -163,6 +163,7 @@ stack_setup: sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ ldr pc, _start_armboot diff --git a/arch/arm/cpu/sa1100/start.S b/arch/arm/cpu/sa1100/start.S index 278c500..deb4745 100644 --- a/arch/arm/cpu/sa1100/start.S +++ b/arch/arm/cpu/sa1100/start.S @@ -153,6 +153,7 @@ stack_setup: sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ clear_bss: ldr r0, _bss_start /* find start of bss segment */ -- cgit v1.1 From 8d1f63554b0371d3b30e481ac0aafa8253b515df Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 16 Jun 2010 07:59:17 +0900 Subject: sh: Fix build on the target SH fails building on the target. This supports this. Signed-off-by: Nobuhiro Iwamatsu --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 87d5214..f46b123 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,8 @@ HOSTARCH := $(shell uname -m | \ -e s/sa110/arm/ \ -e s/ppc64/powerpc/ \ -e s/ppc/powerpc/ \ - -e s/macppc/powerpc/) + -e s/macppc/powerpc/\ + -e s/sh.*/sh/) HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ sed -e 's/\(cygwin\).*/cygwin/') -- cgit v1.1 From 61973afc5912c4c22d21f0412c824cbac1d3ee3f Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 16 Jun 2010 08:10:21 +0900 Subject: sh: Fix overflow problem in get_ticks Signed-off-by: Nobuhiro Iwamatsu --- arch/sh/lib/time.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/arch/sh/lib/time.c b/arch/sh/lib/time.c index 9a8f89a..bc1656f 100644 --- a/arch/sh/lib/time.c +++ b/arch/sh/lib/time.c @@ -2,7 +2,7 @@ * (C) Copyright 2009 * Jean-Christophe PLAGNIOL-VILLARD * - * (C) Copyright 2007-2008 + * (C) Copyright 2007-2010 * Nobobuhiro Iwamatsu * * (C) Copyright 2003 @@ -36,6 +36,8 @@ #define TMU_MAX_COUNTER (~0UL) static ulong timer_freq; +static unsigned long last_tcnt; +static unsigned long long overflow_ticks; static inline unsigned long long tick_to_time(unsigned long long tick) { @@ -97,12 +99,26 @@ int timer_init (void) tmu_timer_stop(0); tmu_timer_start(0); + last_tcnt = 0; + overflow_ticks = 0; + return 0; } unsigned long long get_ticks (void) { - return 0 - readl(TCNT0); + unsigned long tcnt = 0 - readl(TCNT0); + unsigned long ticks; + + if (last_tcnt > tcnt) { /* overflow */ + overflow_ticks++; + ticks = (0xffffffff - last_tcnt) + tcnt; + } else { + ticks = tcnt; + } + last_tcnt = tcnt; + + return (overflow_ticks << 32) | tcnt; } void __udelay (unsigned long usec) -- cgit v1.1 From 9a1e3e9fe3165130c228bc861bd96d49df708290 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 16 Jun 2010 16:53:45 +0900 Subject: sh: Fix path of irqflags.h This changes path of irqflags.h from linux/ to asm/. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Nobuhiro Iwamatsu --- arch/sh/include/asm/system.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index a62c422..90a53a0 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -8,7 +8,7 @@ * from linux kernel code. */ -#include +#include #include /* -- cgit v1.1 From 754613f740368f847a2261c5c41b034ff5c51b1c Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 16 Jun 2010 16:55:26 +0900 Subject: sh: Add trigger_address_error and support cpu reset This add support cpu reset by trigger_address_error function. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Nobuhiro Iwamatsu --- arch/sh/cpu/sh2/watchdog.c | 8 ++++++-- arch/sh/cpu/sh3/watchdog.c | 7 +++++++ arch/sh/cpu/sh4/watchdog.c | 4 ++++ arch/sh/include/asm/system.h | 10 ++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/arch/sh/cpu/sh2/watchdog.c b/arch/sh/cpu/sh2/watchdog.c index de0254b..0257d8d 100644 --- a/arch/sh/cpu/sh2/watchdog.c +++ b/arch/sh/cpu/sh2/watchdog.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2008 Nobuhiro Iwamatsu - * Copyright (C) 2008 Renesas Solutions Corp. + * Copyright (C) 2008,2010 Nobuhiro Iwamatsu + * Copyright (C) 2008,2010 Renesas Solutions Corp. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -20,6 +20,7 @@ #include #include +#include int watchdog_init(void) { @@ -28,6 +29,9 @@ int watchdog_init(void) void reset_cpu(unsigned long ignored) { + /* Address error with SR.BL=1 first. */ + trigger_address_error(); + while (1) ; } diff --git a/arch/sh/cpu/sh3/watchdog.c b/arch/sh/cpu/sh3/watchdog.c index 92bea74..90694f8 100644 --- a/arch/sh/cpu/sh3/watchdog.c +++ b/arch/sh/cpu/sh3/watchdog.c @@ -1,4 +1,7 @@ /* + * (C) Copyright 2010 + * Nobuhiro Iwamatsu + * * (C) Copyright 2007 * Yoshihiro Shimoda * @@ -20,6 +23,7 @@ #include #include +#include int watchdog_init(void) { @@ -28,6 +32,9 @@ int watchdog_init(void) void reset_cpu(unsigned long ignored) { + /* Address error with SR.BL=1 first. */ + trigger_address_error(); + while (1) ; } diff --git a/arch/sh/cpu/sh4/watchdog.c b/arch/sh/cpu/sh4/watchdog.c index f692429..d7e1703 100644 --- a/arch/sh/cpu/sh4/watchdog.c +++ b/arch/sh/cpu/sh4/watchdog.c @@ -17,6 +17,7 @@ #include #include +#include #include #define WDT_BASE WTCNT @@ -66,6 +67,9 @@ int watchdog_disable(void) void reset_cpu(unsigned long ignored) { + /* Address error with SR.BL=1 first. */ + trigger_address_error(); + while (1) ; } diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index 90a53a0..56fd77a 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -272,4 +272,14 @@ void enable_hlt(void); #define arch_align_stack(x) (x) +static inline void trigger_address_error(void) +{ + __asm__ __volatile__ ( + "ldc %0, sr\n\t" + "mov.l @%1, %0" + : + : "r" (0x10000000), "r" (0x80000001) + ); +} + #endif -- cgit v1.1