Hi Bernd,

On 09/02/11 01:32, MKC GmbH - Bernd Büttner wrote:
As I understand the code, interrupts on all levels are blocked
on entry of the service routine and enabled with rte instruction.
Isn't it possible with seperate stacks to leave interrupts with
higher levels enabled?

No, I don't see how. We essentially only have 2 states. Interrupts
enabled or disabled, so there is never a notion of higher level
interrupts being enabled.

And besides all of this there has always been separate user and
supervisor stacks (this is not specific to m68k, it is fundamental
to how linux works and completely architecture independent). Each
process has its own kernel and user stacks used when running in
the appropriate mode.

This particular patch simply uses the hardware stack switching provided
on some ColdFire parts. Before this switching was done in the
interrupt entry and exit code. And this type of hardware switching
is completely the norm on any MMU equipped system.


At the moment any misbehaving interrupt can hold
the timer-tick and thus freeze the system.

I don't follow how that can happen, can you explain further?

Regards
Greg



Am 04.11.2010 05:50, schrieb Greg Ungerer:

Hi All,

This is a request for testing (and comment) on a patch that will
use the separate kernel/user stack pointer hardware that the more
modern ColdFire cores have. This has a performance benefit when
used, the exception entry and exit paths are quite a few instructions
shorter.

Currently the parts I know can use it are the 520[78], 523x, 527[12],
527[45], 523x (and 547x/548x).

The use of the separate stack pointer is based on a config option
(CONFIG_COLDFIRE_SW_A7) that is automatically selected based on
ColdFure CPU selection. This may well not be the best way to do this.
Maybe the selection should be based on the compiler define
__mcfisaaplus__. I didn't use this because only more modern toolchains
support it. My 4.2.4 based toolchain doesn't.

The older toolchain also required one more ugly hack. Pre 4.3 gcc
won't generate the "move usp" instructions required for this when
compiling for ColdFire. So I have had to hard code the opcode values
in place for these instructions for now.

Maybe we need to bite the bullet and just not support this using
older toolchains... Thoughts?

The patch below is against 2.6.36. If you prefer living on the edge,
you can pull this from from the for-linus branch of ther m68knommu
git tree (along with a bunch of other updates):

git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git
for-linus

Regards
Greg


---
[PATCH] m68knommu: use user stack pointer hardware on some ColdFire cores

The more modern ColdFire parts (even if based on older version cores)
have separate user and supervisor stack pointers (a7 register).
Modify the ColdFire CPU setup and exception code to enable and use
this on parts that have it.

Signed-off-by: Greg Ungerer<g...@uclinux.org>
---
m68k/include/asm/cacheflush_no.h | 4 +-
m68k/include/asm/entry_no.h | 59 ++++++++++++++++++++----------------
m68k/include/asm/mcfcache.h | 6 +--
m68k/include/asm/processor.h | 13 ++++---
m68knommu/Kconfig | 11 ++++++
m68knommu/platform/coldfire/entry.S | 56
++++++----------------------------
6 files changed, 68 insertions(+), 81 deletions(-)

diff -Naurp linux-2.6.36/arch/m68k/include/asm/cacheflush_no.h
linux-2.6.36.eusp/arch/m68k/include/asm/cacheflush_no.h
--- linux-2.6.36/arch/m68k/include/asm/cacheflush_no.h 2010-10-21
06:30:22.000000000 +1000
+++ linux-2.6.36.eusp/arch/m68k/include/asm/cacheflush_no.h 2010-11-04
14:32:46.491869598 +1000
@@ -54,7 +54,7 @@ static inline void __flush_cache_all(voi
#endif /* CONFIG_M5407 */
#if defined(CONFIG_M523x) || defined(CONFIG_M527x)
__asm__ __volatile__ (
- "movel #0x81400100, %%d0\n\t"
+ "movel #0x81400110, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
"nop\n\t"
: : : "d0" );
@@ -82,7 +82,7 @@ static inline void __flush_cache_all(voi
#endif /* CONFIG_M5249 */
#ifdef CONFIG_M532x
__asm__ __volatile__ (
- "movel #0x81000200, %%d0\n\t"
+ "movel #0x81000210, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
"nop\n\t"
: : : "d0" );
diff -Naurp linux-2.6.36/arch/m68k/include/asm/entry_no.h
linux-2.6.36.eusp/arch/m68k/include/asm/entry_no.h
--- linux-2.6.36/arch/m68k/include/asm/entry_no.h 2010-10-21
06:30:22.000000000 +1000
+++ linux-2.6.36.eusp/arch/m68k/include/asm/entry_no.h 2010-11-04
14:32:46.491869598 +1000
@@ -52,12 +52,16 @@ LENOSYS = 38
*/

#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_COLDFIRE_SW_A7
/*
- * This is made a little more tricky on the ColdFire. There is no
- * separate kernel and user stack pointers. Need to artificially
+ * This is made a little more tricky on older ColdFires. There is no
+ * separate supervisor and user stack pointers. Need to artificially
* construct a usp in software... When doing this we need to disable
- * interrupts, otherwise bad things could happen.
+ * interrupts, otherwise bad things will happen.
*/
+.globl sw_usp
+.globl sw_ksp
+
.macro SAVE_ALL
move #0x2700,%sr /* disable intrs */
btst #5,%sp@(2) /* from user? */
@@ -84,9 +88,7 @@ LENOSYS = 38
7:
.endm

-.macro RESTORE_ALL
- btst #5,%sp@(PT_SR) /* going user? */
- bnes 8f /* no, skip */
+.macro RESTORE_USER
move #0x2700,%sr /* disable intrs */
movel sw_usp,%a0 /* get usp */
movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */
@@ -101,19 +103,22 @@ LENOSYS = 38
subql #8,sw_usp /* set exception */
movel sw_usp,%sp /* restore usp */
rte
- 8:
- moveml %sp@,%d1-%d5/%a0-%a2
- lea %sp@(32),%sp /* space for 8 regs */
- movel %sp@+,%d0
- addql #4,%sp /* orig d0 */
- addl %sp@+,%sp /* stkadj */
- rte
.endm

+.macro RDUSP
+ movel sw_usp,%a2
+.endm
+
+.macro WRUSP
+ movel %a0,sw_usp
+.endm
+
+#else /* !CONFIG_COLDFIRE_SW_A7 */
/*
- * Quick exception save, use current stack only.
+ * Modern ColdFire parts have separate supervisor and user stack
+ * pointers. Simple load and restore macros for this case.
*/
-.macro SAVE_LOCAL
+.macro SAVE_ALL
move #0x2700,%sr /* disable intrs */
clrl %sp@- /* stkadj */
movel %d0,%sp@- /* orig d0 */
@@ -122,7 +127,7 @@ LENOSYS = 38
moveml %d1-%d5/%a0-%a2,%sp@
.endm

-.macro RESTORE_LOCAL
+.macro RESTORE_USER
moveml %sp@,%d1-%d5/%a0-%a2
lea %sp@(32),%sp /* space for 8 regs */
movel %sp@+,%d0
@@ -131,6 +136,18 @@ LENOSYS = 38
rte
.endm

+.macro RDUSP
+ /*move %usp,%a2*/
+ .word 0x4e6a
+.endm
+
+.macro WRUSP
+ /*move %a0,%usp*/
+ .word 0x4e60
+.endm
+
+#endif /* !CONFIG_COLDFIRE_SW_A7 */
+
.macro SAVE_SWITCH_STACK
lea %sp@(-24),%sp /* 6 regs */
moveml %a3-%a6/%d6-%d7,%sp@
@@ -141,14 +158,6 @@ LENOSYS = 38
lea %sp@(24),%sp /* 6 regs */
.endm

-/*
- * Software copy of the user and kernel stack pointers... Ugh...
- * Need these to get around ColdFire not having separate kernel
- * and user stack pointers.
- */
-.globl sw_usp
-.globl sw_ksp
-
#else /* !CONFIG_COLDFIRE */

/*
@@ -177,6 +186,6 @@ LENOSYS = 38
moveml %sp@+,%a3-%a6/%d6-%d7
.endm

-#endif /* !CONFIG_COLDFIRE */
+#endif /* !COLDFIRE_SW_A7 */
#endif /* __ASSEMBLY__ */
#endif /* __M68KNOMMU_ENTRY_H */
diff -Naurp linux-2.6.36/arch/m68k/include/asm/mcfcache.h
linux-2.6.36.eusp/arch/m68k/include/asm/mcfcache.h
--- linux-2.6.36/arch/m68k/include/asm/mcfcache.h 2010-10-21
06:30:22.000000000 +1000
+++ linux-2.6.36.eusp/arch/m68k/include/asm/mcfcache.h 2010-11-04
14:32:46.491869598 +1000
@@ -46,7 +46,7 @@
movec %d0,%ACR0
movel #0x00000000,%d0 /* no other regions cached */
movec %d0,%ACR1
- movel #0x80400100,%d0 /* configure cache */
+ movel #0x80400110,%d0 /* configure cache */
movec %d0,%CACR /* enable cache */
nop
.endm
@@ -101,7 +101,7 @@
movec %d0,%ACR0
movel #0x00000000,%d0 /* no other regions cached */
movec %d0,%ACR1
- movel #0x80000200,%d0 /* setup cache mask */
+ movel #0x80000210,%d0 /* setup cache mask */
movec %d0,%CACR /* enable cache */
nop
.endm
@@ -140,7 +140,7 @@
movec %d0,%ACR0
move.l #0x00000000,%d0 /* no other regions cached */
movec %d0,%ACR1
- move.l #0x80400000,%d0 /* enable 8K instruction cache */
+ move.l #0x80400010,%d0 /* enable 8K instruction cache */
movec %d0,%CACR
nop
.endm
diff -Naurp linux-2.6.36/arch/m68k/include/asm/processor.h
linux-2.6.36.eusp/arch/m68k/include/asm/processor.h
--- linux-2.6.36/arch/m68k/include/asm/processor.h 2010-10-21
06:30:22.000000000 +1000
+++ linux-2.6.36.eusp/arch/m68k/include/asm/processor.h 2010-11-04
14:32:46.491869598 +1000
@@ -20,23 +20,26 @@

static inline unsigned long rdusp(void)
{
-#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_COLDFIRE_SW_A7
extern unsigned int sw_usp;
return sw_usp;
#else
- unsigned long usp;
- __asm__ __volatile__("move %/usp,%0" : "=a" (usp));
+ register unsigned long usp __asm__("a0");
+ /* move %usp,%a0 */
+ __asm__ __volatile__(".word 0x4e68" : "=a" (usp));
return usp;
#endif
}

static inline void wrusp(unsigned long usp)
{
-#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_COLDFIRE_SW_A7
extern unsigned int sw_usp;
sw_usp = usp;
#else
- __asm__ __volatile__("move %0,%/usp" : : "a" (usp));
+ register unsigned long a0 __asm__("a0") = usp;
+ /* move %a0,%usp */
+ __asm__ __volatile__(".word 0x4e60" : : "a" (a0) );
#endif
}

diff -Naurp linux-2.6.36/arch/m68knommu/Kconfig
linux-2.6.36.eusp/arch/m68knommu/Kconfig
--- linux-2.6.36/arch/m68knommu/Kconfig 2010-10-21 06:30:22.000000000
+1000
+++ linux-2.6.36.eusp/arch/m68knommu/Kconfig 2010-11-04
14:32:46.491869598 +1000
@@ -78,6 +78,10 @@ config GENERIC_CLOCKEVENTS
config NO_IOPORT
def_bool y

+config COLDFIRE_SW_A7
+ bool
+ default n
+
source "init/Kconfig"

source "kernel/Kconfig.freezer"
@@ -110,11 +114,13 @@ config M68360

config M5206
bool "MCF5206"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5206 processor support.

config M5206e
bool "MCF5206e"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5206e processor support.

@@ -132,6 +138,7 @@ config M523x

config M5249
bool "MCF5249"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5249 processor support.

@@ -142,6 +149,7 @@ config M5271

config M5272
bool "MCF5272"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5272 processor support.

@@ -152,12 +160,14 @@ config M5275

config M528x
bool "MCF528x"
+ select COLDFIRE_SW_A7
select GENERIC_CLOCKEVENTS
help
Motorola ColdFire 5280/5282 processor support.

config M5307
bool "MCF5307"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5307 processor support.

@@ -168,6 +178,7 @@ config M532x

config M5407
bool "MCF5407"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5407 processor support.

diff -Naurp linux-2.6.36/arch/m68knommu/platform/coldfire/entry.S
linux-2.6.36.eusp/arch/m68knommu/platform/coldfire/entry.S
--- linux-2.6.36/arch/m68knommu/platform/coldfire/entry.S 2010-10-21
06:30:22.000000000 +1000
+++ linux-2.6.36.eusp/arch/m68knommu/platform/coldfire/entry.S
2010-11-04 14:36:40.132706032 +1000
@@ -36,13 +36,16 @@
#include<asm/asm-offsets.h>
#include<asm/entry.h>

+#ifdef CONFIG_COLDFIRE_SW_A7
+/*
+ * Define software copies of the supervisor and user stack pointers.
+ */
.bss
-
sw_ksp:
.long 0
-
sw_usp:
.long 0
+#endif /* CONFIG_COLDFIRE_SW_A7 */

.text

@@ -51,7 +54,6 @@ sw_usp:
.globl ret_from_exception
.globl ret_from_signal
.globl sys_call_table
-.globl ret_from_interrupt
.globl inthandler
.globl fasthandler

@@ -140,20 +142,7 @@ Luser_return:
jne Lwork_to_do /* still work to do */

Lreturn:
- move #0x2700,%sr /* disable intrs */
- movel sw_usp,%a0 /* get usp */
- movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */
- movel %sp@(PT_OFF_FORMATVEC),%a0@- /* copy exception
format/vector/sr */
- moveml %sp@,%d1-%d5/%a0-%a2
- lea %sp@(32),%sp /* space for 8 regs */
- movel %sp@+,%d0
- addql #4,%sp /* orig d0 */
- addl %sp@+,%sp /* stk adj */
- addql #8,%sp /* remove exception */
- movel %sp,sw_ksp /* save ksp */
- subql #8,sw_usp /* set exception */
- movel sw_usp,%sp /* restore usp */
- rte
+ RESTORE_USER

Lwork_to_do:
movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
@@ -192,31 +181,7 @@ ENTRY(inthandler)
jbsr do_IRQ /* call high level irq handler */
lea %sp@(8),%sp /* pop args off stack */

- bra ret_from_interrupt /* this was fallthrough */
-
-/*
- * This is the fast interrupt handler (for certain hardware interrupt
- * sources). Unlike the normal interrupt handler it just uses the
- * current stack (doesn't care if it is user or kernel). It also
- * doesn't bother doing the bottom half handlers.
- */
-ENTRY(fasthandler)
- SAVE_LOCAL
-
- movew %sp@(PT_OFF_FORMATVEC),%d0
- andl #0x03fc,%d0 /* mask out vector only */
-
- movel %sp,%sp@- /* push regs arg */
- lsrl #2,%d0 /* calculate real vector # */
- movel %d0,%sp@- /* push vector number */
- jbsr do_IRQ /* call high level irq handler */
- lea %sp@(8),%sp /* pop args off stack */
-
- RESTORE_LOCAL
-
-ENTRY(ret_from_interrupt)
- /* the fasthandler is confusing me, haven't seen any user */
- jmp ret_from_exception
+ bra ret_from_exception

/*
* Beware - when entering resume, prev (the current task) is
@@ -227,9 +192,8 @@ ENTRY(ret_from_interrupt)
*/
ENTRY(resume)
movel %a0, %d1 /* get prev thread in d1 */
-
- movel sw_usp,%d0 /* save usp */
- movel %d0,%a0@(TASK_THREAD+THREAD_USP)
+ RDUSP
+ movel %a2,%a0@(TASK_THREAD+THREAD_USP)

SAVE_SWITCH_STACK
movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */
@@ -237,5 +201,5 @@ ENTRY(resume)
RESTORE_SWITCH_STACK

movel %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore thread user stack */
- movel %a0, sw_usp
+ WRUSP
rts
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev


_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev



--
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     g...@snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close                             FAX:         +61 7 3217 5323
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev

Reply via email to