diff options
Diffstat (limited to 'arch/mips/kernel/process.c')
-rw-r--r-- | arch/mips/kernel/process.c | 58 |
1 files changed, 56 insertions, 2 deletions
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 368526af5f5e..98432097a86a 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -25,8 +25,10 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/completion.h> | 26 | #include <linux/completion.h> |
27 | 27 | ||
28 | #include <asm/abi.h> | ||
28 | #include <asm/bootinfo.h> | 29 | #include <asm/bootinfo.h> |
29 | #include <asm/cpu.h> | 30 | #include <asm/cpu.h> |
31 | #include <asm/dsp.h> | ||
30 | #include <asm/fpu.h> | 32 | #include <asm/fpu.h> |
31 | #include <asm/pgtable.h> | 33 | #include <asm/pgtable.h> |
32 | #include <asm/system.h> | 34 | #include <asm/system.h> |
@@ -54,6 +56,54 @@ ATTRIB_NORET void cpu_idle(void) | |||
54 | } | 56 | } |
55 | } | 57 | } |
56 | 58 | ||
59 | extern int do_signal(sigset_t *oldset, struct pt_regs *regs); | ||
60 | extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); | ||
61 | |||
62 | /* | ||
63 | * Native o32 and N64 ABI without DSP ASE | ||
64 | */ | ||
65 | extern void setup_frame(struct k_sigaction * ka, struct pt_regs *regs, | ||
66 | int signr, sigset_t *set); | ||
67 | extern void setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, | ||
68 | int signr, sigset_t *set, siginfo_t *info); | ||
69 | |||
70 | struct mips_abi mips_abi = { | ||
71 | .do_signal = do_signal, | ||
72 | #ifdef CONFIG_TRAD_SIGNALS | ||
73 | .setup_frame = setup_frame, | ||
74 | #endif | ||
75 | .setup_rt_frame = setup_rt_frame | ||
76 | }; | ||
77 | |||
78 | #ifdef CONFIG_MIPS32_O32 | ||
79 | /* | ||
80 | * o32 compatibility on 64-bit kernels, without DSP ASE | ||
81 | */ | ||
82 | extern void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | ||
83 | int signr, sigset_t *set); | ||
84 | extern void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | ||
85 | int signr, sigset_t *set, siginfo_t *info); | ||
86 | |||
87 | struct mips_abi mips_abi_32 = { | ||
88 | .do_signal = do_signal32, | ||
89 | .setup_frame = setup_frame_32, | ||
90 | .setup_rt_frame = setup_rt_frame_32 | ||
91 | }; | ||
92 | #endif /* CONFIG_MIPS32_O32 */ | ||
93 | |||
94 | #ifdef CONFIG_MIPS32_N32 | ||
95 | /* | ||
96 | * N32 on 64-bit kernels, without DSP ASE | ||
97 | */ | ||
98 | extern void setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs, | ||
99 | int signr, sigset_t *set, siginfo_t *info); | ||
100 | |||
101 | struct mips_abi mips_abi_n32 = { | ||
102 | .do_signal = do_signal, | ||
103 | .setup_rt_frame = setup_rt_frame_n32 | ||
104 | }; | ||
105 | #endif /* CONFIG_MIPS32_N32 */ | ||
106 | |||
57 | asmlinkage void ret_from_fork(void); | 107 | asmlinkage void ret_from_fork(void); |
58 | 108 | ||
59 | void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) | 109 | void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) |
@@ -70,6 +120,8 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) | |||
70 | regs->cp0_status = status; | 120 | regs->cp0_status = status; |
71 | clear_used_math(); | 121 | clear_used_math(); |
72 | lose_fpu(); | 122 | lose_fpu(); |
123 | if (cpu_has_dsp) | ||
124 | __init_dsp(); | ||
73 | regs->cp0_epc = pc; | 125 | regs->cp0_epc = pc; |
74 | regs->regs[29] = sp; | 126 | regs->regs[29] = sp; |
75 | current_thread_info()->addr_limit = USER_DS; | 127 | current_thread_info()->addr_limit = USER_DS; |
@@ -95,9 +147,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | |||
95 | 147 | ||
96 | preempt_disable(); | 148 | preempt_disable(); |
97 | 149 | ||
98 | if (is_fpu_owner()) { | 150 | if (is_fpu_owner()) |
99 | save_fp(p); | 151 | save_fp(p); |
100 | } | 152 | |
153 | if (cpu_has_dsp) | ||
154 | save_dsp(p); | ||
101 | 155 | ||
102 | preempt_enable(); | 156 | preempt_enable(); |
103 | 157 | ||