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>
This commit is contained in:
Greg Ungerer 2011-10-19 13:58:55 +10:00
parent ed865e31a8
commit e9fcffa493

View File

@ -56,7 +56,11 @@ static const int frame_extra_sizes[16] = {
[1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */
[2] = sizeof(((struct frame *)0)->un.fmt2), [2] = sizeof(((struct frame *)0)->un.fmt2),
[3] = sizeof(((struct frame *)0)->un.fmt3), [3] = sizeof(((struct frame *)0)->un.fmt3),
#ifdef CONFIG_COLDFIRE
[4] = 0,
#else
[4] = sizeof(((struct frame *)0)->un.fmt4), [4] = sizeof(((struct frame *)0)->un.fmt4),
#endif
[5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */ [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */
[6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */ [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */
[7] = sizeof(((struct frame *)0)->un.fmt7), [7] = sizeof(((struct frame *)0)->un.fmt7),
@ -84,7 +88,11 @@ int handle_kernel_fault(struct pt_regs *regs)
regs->stkadj = frame_extra_sizes[regs->format]; regs->stkadj = frame_extra_sizes[regs->format];
tregs = (struct pt_regs *)((long)regs + regs->stkadj); tregs = (struct pt_regs *)((long)regs + regs->stkadj);
tregs->vector = regs->vector; tregs->vector = regs->vector;
#ifdef CONFIG_COLDFIRE
tregs->format = 4;
#else
tregs->format = 0; tregs->format = 0;
#endif
tregs->pc = fixup->fixup; tregs->pc = fixup->fixup;
tregs->sr = regs->sr; tregs->sr = regs->sr;
@ -336,8 +344,12 @@ static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,
regs->format = formatvec >> 12; regs->format = formatvec >> 12;
regs->vector = formatvec & 0xfff; regs->vector = formatvec & 0xfff;
#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
__asm__ __volatile__ __asm__ __volatile__ (
(" movel %0,%/a0\n\t" #ifdef CONFIG_COLDFIRE
" movel %0,%/sp\n\t"
" bra ret_from_signal\n"
#else
" movel %0,%/a0\n\t"
" subl %1,%/a0\n\t" /* make room on stack */ " subl %1,%/a0\n\t" /* make room on stack */
" movel %/a0,%/sp\n\t" /* set stack pointer */ " movel %/a0,%/sp\n\t" /* set stack pointer */
/* move switch_stack and pt_regs */ /* move switch_stack and pt_regs */
@ -350,6 +362,7 @@ static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,
"2: movel %4@+,%/a0@+\n\t" "2: movel %4@+,%/a0@+\n\t"
" dbra %1,2b\n\t" " dbra %1,2b\n\t"
" bral ret_from_signal\n" " bral ret_from_signal\n"
#endif
: /* no outputs, it doesn't ever return */ : /* no outputs, it doesn't ever return */
: "a" (sw), "d" (fsize), "d" (frame_offset/4-1), : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
"n" (frame_offset), "a" (buf + fsize/4) "n" (frame_offset), "a" (buf + fsize/4)