diff options
| author | Maxim Kuvyrkov <maxim@codesourcery.com> | 2009-09-22 17:22:43 -0400 |
|---|---|---|
| committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2010-02-27 12:44:10 -0500 |
| commit | 00ebfe58b002f0ff387f60c7cd23bc2b274fce1a (patch) | |
| tree | 2e88877140ddcb97cf2b5a01bbf0b3c443bf3ef9 | |
| parent | a58f75349063f60949614de39390df594ba1418d (diff) | |
m68k: Define sigcontext ABI of ColdFire
The following patch defines sigcontext ABI of ColdFire. Due to ISA
restrictions ColdFire needs different rt_sigreturn trampoline.
And due to ColdFire FP registers being 8-bytes instead of 12-bytes on
m68k, sigcontext and fpregset structures should be updated.
Regarding the sc_fpstate[16+6*8] field, it would've been enough 16
bytes to store ColdFire's FP state. To accomodate GLIBC's libSegFault
it would'be been enough 6*8 bytes (room for the 6 non-call-clobbered
FP registers). I set it to 16+6*8 to provide some extra space for any
future changes in the ColdFire FPU.
Signed-off-by: Maxim Kuvyrkov <maxim@codesourcery.com>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
| -rw-r--r-- | arch/m68k/include/asm/sigcontext.h | 6 | ||||
| -rw-r--r-- | arch/m68k/include/asm/ucontext.h | 4 | ||||
| -rw-r--r-- | arch/m68k/kernel/signal.c | 7 |
3 files changed, 17 insertions, 0 deletions
diff --git a/arch/m68k/include/asm/sigcontext.h b/arch/m68k/include/asm/sigcontext.h index 523db2a51cf3..1320eaa4cc2a 100644 --- a/arch/m68k/include/asm/sigcontext.h +++ b/arch/m68k/include/asm/sigcontext.h | |||
| @@ -15,9 +15,15 @@ struct sigcontext { | |||
| 15 | unsigned long sc_pc; | 15 | unsigned long sc_pc; |
| 16 | unsigned short sc_formatvec; | 16 | unsigned short sc_formatvec; |
| 17 | #ifndef __uClinux__ | 17 | #ifndef __uClinux__ |
| 18 | # ifdef __mcoldfire__ | ||
| 19 | unsigned long sc_fpregs[2][2]; /* room for two fp registers */ | ||
| 20 | unsigned long sc_fpcntl[3]; | ||
| 21 | unsigned char sc_fpstate[16+6*8]; | ||
| 22 | # else | ||
| 18 | unsigned long sc_fpregs[2*3]; /* room for two fp registers */ | 23 | unsigned long sc_fpregs[2*3]; /* room for two fp registers */ |
| 19 | unsigned long sc_fpcntl[3]; | 24 | unsigned long sc_fpcntl[3]; |
| 20 | unsigned char sc_fpstate[216]; | 25 | unsigned char sc_fpstate[216]; |
| 26 | # endif | ||
| 21 | #endif | 27 | #endif |
| 22 | }; | 28 | }; |
| 23 | 29 | ||
diff --git a/arch/m68k/include/asm/ucontext.h b/arch/m68k/include/asm/ucontext.h index e4e22669edc0..00dcc5176c57 100644 --- a/arch/m68k/include/asm/ucontext.h +++ b/arch/m68k/include/asm/ucontext.h | |||
| @@ -7,7 +7,11 @@ typedef greg_t gregset_t[NGREG]; | |||
| 7 | 7 | ||
| 8 | typedef struct fpregset { | 8 | typedef struct fpregset { |
| 9 | int f_fpcntl[3]; | 9 | int f_fpcntl[3]; |
| 10 | #ifdef __mcoldfire__ | ||
| 11 | int f_fpregs[8][2]; | ||
| 12 | #else | ||
| 10 | int f_fpregs[8*3]; | 13 | int f_fpregs[8*3]; |
| 14 | #endif | ||
| 11 | } fpregset_t; | 15 | } fpregset_t; |
| 12 | 16 | ||
| 13 | struct mcontext { | 17 | struct mcontext { |
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index de2d05ddd86d..4b387538706f 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c | |||
| @@ -897,10 +897,17 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 897 | 897 | ||
| 898 | /* Set up to return from userspace. */ | 898 | /* Set up to return from userspace. */ |
| 899 | err |= __put_user(frame->retcode, &frame->pretcode); | 899 | err |= __put_user(frame->retcode, &frame->pretcode); |
| 900 | #ifdef __mcoldfire__ | ||
| 901 | /* movel #__NR_rt_sigreturn,d0; trap #0 */ | ||
| 902 | err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0)); | ||
| 903 | err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16), | ||
| 904 | (long __user *)(frame->retcode + 4)); | ||
| 905 | #else | ||
| 900 | /* moveq #,d0; notb d0; trap #0 */ | 906 | /* moveq #,d0; notb d0; trap #0 */ |
| 901 | err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), | 907 | err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), |
| 902 | (long __user *)(frame->retcode + 0)); | 908 | (long __user *)(frame->retcode + 0)); |
| 903 | err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); | 909 | err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); |
| 910 | #endif | ||
| 904 | 911 | ||
| 905 | if (err) | 912 | if (err) |
| 906 | goto give_sigsegv; | 913 | goto give_sigsegv; |
