aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/process.c')
-rw-r--r--arch/mips/kernel/process.c58
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
59extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
60extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
61
62/*
63 * Native o32 and N64 ABI without DSP ASE
64 */
65extern void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
66 int signr, sigset_t *set);
67extern void setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
68 int signr, sigset_t *set, siginfo_t *info);
69
70struct 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 */
82extern void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
83 int signr, sigset_t *set);
84extern void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
85 int signr, sigset_t *set, siginfo_t *info);
86
87struct 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 */
98extern void setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs,
99 int signr, sigset_t *set, siginfo_t *info);
100
101struct 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
57asmlinkage void ret_from_fork(void); 107asmlinkage void ret_from_fork(void);
58 108
59void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) 109void 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