aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@uclinux.org>2011-10-18 23:58:55 -0400
committerGreg Ungerer <gerg@uclinux.org>2011-12-29 19:20:45 -0500
commite9fcffa49376b37518baf71a47adc15e74b2434c (patch)
tree8040672d03de61517a33e1936e1fba0188cccb1a /arch/m68k
parented865e31a8273be200db9ddcdb6b844e48777abd (diff)
m68k: adjustments to stack frame for ColdFire with MMU enabled
The exception return stack adjustment required by ColdFire when running with the MMU enabled is not completely identical to 680x0 processors. Specifically the format type 4 stack frame doesn't need any stack adjustment on exception return. And the ColdFire always must return with a frame type of 4, not 0. Signed-off-by: Greg Ungerer <gerg@uclinux.org> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> Acked-by: Matt Waddel <mwaddel@yahoo.com> Acked-by: Kurt Mahan <kmahan@xmission.com>
Diffstat (limited to 'arch/m68k')
-rw-r--r--arch/m68k/kernel/signal_mm.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/arch/m68k/kernel/signal_mm.c b/arch/m68k/kernel/signal_mm.c
index a0afc239304e..5f6b3d0fcd16 100644
--- a/arch/m68k/kernel/signal_mm.c
+++ b/arch/m68k/kernel/signal_mm.c
@@ -56,7 +56,11 @@ static const int frame_extra_sizes[16] = {
56 [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ 56 [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */
57 [2] = sizeof(((struct frame *)0)->un.fmt2), 57 [2] = sizeof(((struct frame *)0)->un.fmt2),
58 [3] = sizeof(((struct frame *)0)->un.fmt3), 58 [3] = sizeof(((struct frame *)0)->un.fmt3),
59#ifdef CONFIG_COLDFIRE
60 [4] = 0,
61#else
59 [4] = sizeof(((struct frame *)0)->un.fmt4), 62 [4] = sizeof(((struct frame *)0)->un.fmt4),
63#endif
60 [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */ 64 [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */
61 [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */ 65 [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */
62 [7] = sizeof(((struct frame *)0)->un.fmt7), 66 [7] = sizeof(((struct frame *)0)->un.fmt7),
@@ -84,7 +88,11 @@ int handle_kernel_fault(struct pt_regs *regs)
84 regs->stkadj = frame_extra_sizes[regs->format]; 88 regs->stkadj = frame_extra_sizes[regs->format];
85 tregs = (struct pt_regs *)((long)regs + regs->stkadj); 89 tregs = (struct pt_regs *)((long)regs + regs->stkadj);
86 tregs->vector = regs->vector; 90 tregs->vector = regs->vector;
91#ifdef CONFIG_COLDFIRE
92 tregs->format = 4;
93#else
87 tregs->format = 0; 94 tregs->format = 0;
95#endif
88 tregs->pc = fixup->fixup; 96 tregs->pc = fixup->fixup;
89 tregs->sr = regs->sr; 97 tregs->sr = regs->sr;
90 98
@@ -336,8 +344,12 @@ static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,
336 regs->format = formatvec >> 12; 344 regs->format = formatvec >> 12;
337 regs->vector = formatvec & 0xfff; 345 regs->vector = formatvec & 0xfff;
338#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) 346#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
339 __asm__ __volatile__ 347 __asm__ __volatile__ (
340 (" movel %0,%/a0\n\t" 348#ifdef CONFIG_COLDFIRE
349 " movel %0,%/sp\n\t"
350 " bra ret_from_signal\n"
351#else
352 " movel %0,%/a0\n\t"
341 " subl %1,%/a0\n\t" /* make room on stack */ 353 " subl %1,%/a0\n\t" /* make room on stack */
342 " movel %/a0,%/sp\n\t" /* set stack pointer */ 354 " movel %/a0,%/sp\n\t" /* set stack pointer */
343 /* move switch_stack and pt_regs */ 355 /* move switch_stack and pt_regs */
@@ -350,6 +362,7 @@ static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,
350 "2: movel %4@+,%/a0@+\n\t" 362 "2: movel %4@+,%/a0@+\n\t"
351 " dbra %1,2b\n\t" 363 " dbra %1,2b\n\t"
352 " bral ret_from_signal\n" 364 " bral ret_from_signal\n"
365#endif
353 : /* no outputs, it doesn't ever return */ 366 : /* no outputs, it doesn't ever return */
354 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), 367 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
355 "n" (frame_offset), "a" (buf + fsize/4) 368 "n" (frame_offset), "a" (buf + fsize/4)