Loading arch/mips/kernel/asm-offsets.c +23 −3 Original line number Diff line number Diff line Loading @@ -241,6 +241,7 @@ void output_mm_defines(void) linefeed; } #ifdef CONFIG_32BIT void output_sc_defines(void) { text("/* Linux sigcontext offsets. */"); Loading @@ -252,10 +253,29 @@ void output_sc_defines(void) offset("#define SC_STATUS ", struct sigcontext, sc_status); offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); offset("#define SC_CAUSE ", struct sigcontext, sc_cause); offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr); offset("#define SC_HI1 ", struct sigcontext, sc_hi1); offset("#define SC_LO1 ", struct sigcontext, sc_lo1); offset("#define SC_HI2 ", struct sigcontext, sc_hi2); offset("#define SC_LO2 ", struct sigcontext, sc_lo2); offset("#define SC_HI3 ", struct sigcontext, sc_hi3); offset("#define SC_LO3 ", struct sigcontext, sc_lo3); linefeed; } #endif #ifdef CONFIG_64BIT void output_sc_defines(void) { text("/* Linux sigcontext offsets. */"); offset("#define SC_REGS ", struct sigcontext, sc_regs); offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs); offset("#define SC_MDHI ", struct sigcontext, sc_hi); offset("#define SC_MDLO ", struct sigcontext, sc_lo); offset("#define SC_PC ", struct sigcontext, sc_pc); offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); linefeed; } #endif #ifdef CONFIG_MIPS32_COMPAT void output_sc32_defines(void) Loading arch/mips/kernel/branch.c +18 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ */ int __compute_return_epc(struct pt_regs *regs) { unsigned int *addr, bit, fcr31; unsigned int *addr, bit, fcr31, dspcontrol; long epc; union mips_instruction insn; Loading Loading @@ -99,6 +99,18 @@ int __compute_return_epc(struct pt_regs *regs) epc += 8; regs->cp0_epc = epc; break; case bposge32_op: if (!cpu_has_dsp) goto sigill; dspcontrol = rddsp(0x01); if (dspcontrol >= 32) { epc = epc + 4 + (insn.i_format.simmediate << 2); } else epc += 8; regs->cp0_epc = epc; break; } break; Loading Loading @@ -200,4 +212,9 @@ int __compute_return_epc(struct pt_regs *regs) printk("%s: unaligned epc - sending SIGBUS.\n", current->comm); force_sig(SIGBUS, current); return -EFAULT; sigill: printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm); force_sig(SIGBUS, current); return -EFAULT; } arch/mips/kernel/cpu-probe.c +3 −0 Original line number Diff line number Diff line Loading @@ -482,6 +482,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) if (config3 & MIPS_CONF3_SM) c->ases |= MIPS_ASE_SMARTMIPS; if (config3 & MIPS_CONF3_DSP) c->ases |= MIPS_ASE_DSP; return config3 & MIPS_CONF_M; } Loading Loading @@ -529,6 +531,7 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c) c->cputype = CPU_20KC; break; case PRID_IMP_24K: case PRID_IMP_24KE: c->cputype = CPU_24K; break; case PRID_IMP_25KF: Loading arch/mips/kernel/genex.S +1 −0 Original line number Diff line number Diff line Loading @@ -291,6 +291,7 @@ NESTED(nmi_handler, PT_SIZE, sp) BUILD_HANDLER mdmx mdmx sti silent /* #22 */ BUILD_HANDLER watch watch sti verbose /* #23 */ BUILD_HANDLER mcheck mcheck cli verbose /* #24 */ BUILD_HANDLER dsp dsp sti silent /* #26 */ BUILD_HANDLER reserved reserved sti verbose /* others */ #ifdef CONFIG_64BIT Loading arch/mips/kernel/process.c +56 −2 Original line number Diff line number Diff line Loading @@ -25,8 +25,10 @@ #include <linux/init.h> #include <linux/completion.h> #include <asm/abi.h> #include <asm/bootinfo.h> #include <asm/cpu.h> #include <asm/dsp.h> #include <asm/fpu.h> #include <asm/pgtable.h> #include <asm/system.h> Loading Loading @@ -54,6 +56,54 @@ ATTRIB_NORET void cpu_idle(void) } } extern int do_signal(sigset_t *oldset, struct pt_regs *regs); extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); /* * Native o32 and N64 ABI without DSP ASE */ extern void setup_frame(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set); extern void setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info); struct mips_abi mips_abi = { .do_signal = do_signal, #ifdef CONFIG_TRAD_SIGNALS .setup_frame = setup_frame, #endif .setup_rt_frame = setup_rt_frame }; #ifdef CONFIG_MIPS32_O32 /* * o32 compatibility on 64-bit kernels, without DSP ASE */ extern void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set); extern void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info); struct mips_abi mips_abi_32 = { .do_signal = do_signal32, .setup_frame = setup_frame_32, .setup_rt_frame = setup_rt_frame_32 }; #endif /* CONFIG_MIPS32_O32 */ #ifdef CONFIG_MIPS32_N32 /* * N32 on 64-bit kernels, without DSP ASE */ extern void setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info); struct mips_abi mips_abi_n32 = { .do_signal = do_signal, .setup_rt_frame = setup_rt_frame_n32 }; #endif /* CONFIG_MIPS32_N32 */ asmlinkage void ret_from_fork(void); void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) Loading @@ -70,6 +120,8 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) regs->cp0_status = status; clear_used_math(); lose_fpu(); if (cpu_has_dsp) __init_dsp(); regs->cp0_epc = pc; regs->regs[29] = sp; current_thread_info()->addr_limit = USER_DS; Loading @@ -95,9 +147,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, preempt_disable(); if (is_fpu_owner()) { if (is_fpu_owner()) save_fp(p); } if (cpu_has_dsp) save_dsp(p); preempt_enable(); Loading Loading
arch/mips/kernel/asm-offsets.c +23 −3 Original line number Diff line number Diff line Loading @@ -241,6 +241,7 @@ void output_mm_defines(void) linefeed; } #ifdef CONFIG_32BIT void output_sc_defines(void) { text("/* Linux sigcontext offsets. */"); Loading @@ -252,10 +253,29 @@ void output_sc_defines(void) offset("#define SC_STATUS ", struct sigcontext, sc_status); offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); offset("#define SC_CAUSE ", struct sigcontext, sc_cause); offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr); offset("#define SC_HI1 ", struct sigcontext, sc_hi1); offset("#define SC_LO1 ", struct sigcontext, sc_lo1); offset("#define SC_HI2 ", struct sigcontext, sc_hi2); offset("#define SC_LO2 ", struct sigcontext, sc_lo2); offset("#define SC_HI3 ", struct sigcontext, sc_hi3); offset("#define SC_LO3 ", struct sigcontext, sc_lo3); linefeed; } #endif #ifdef CONFIG_64BIT void output_sc_defines(void) { text("/* Linux sigcontext offsets. */"); offset("#define SC_REGS ", struct sigcontext, sc_regs); offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs); offset("#define SC_MDHI ", struct sigcontext, sc_hi); offset("#define SC_MDLO ", struct sigcontext, sc_lo); offset("#define SC_PC ", struct sigcontext, sc_pc); offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); linefeed; } #endif #ifdef CONFIG_MIPS32_COMPAT void output_sc32_defines(void) Loading
arch/mips/kernel/branch.c +18 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ */ int __compute_return_epc(struct pt_regs *regs) { unsigned int *addr, bit, fcr31; unsigned int *addr, bit, fcr31, dspcontrol; long epc; union mips_instruction insn; Loading Loading @@ -99,6 +99,18 @@ int __compute_return_epc(struct pt_regs *regs) epc += 8; regs->cp0_epc = epc; break; case bposge32_op: if (!cpu_has_dsp) goto sigill; dspcontrol = rddsp(0x01); if (dspcontrol >= 32) { epc = epc + 4 + (insn.i_format.simmediate << 2); } else epc += 8; regs->cp0_epc = epc; break; } break; Loading Loading @@ -200,4 +212,9 @@ int __compute_return_epc(struct pt_regs *regs) printk("%s: unaligned epc - sending SIGBUS.\n", current->comm); force_sig(SIGBUS, current); return -EFAULT; sigill: printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm); force_sig(SIGBUS, current); return -EFAULT; }
arch/mips/kernel/cpu-probe.c +3 −0 Original line number Diff line number Diff line Loading @@ -482,6 +482,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) if (config3 & MIPS_CONF3_SM) c->ases |= MIPS_ASE_SMARTMIPS; if (config3 & MIPS_CONF3_DSP) c->ases |= MIPS_ASE_DSP; return config3 & MIPS_CONF_M; } Loading Loading @@ -529,6 +531,7 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c) c->cputype = CPU_20KC; break; case PRID_IMP_24K: case PRID_IMP_24KE: c->cputype = CPU_24K; break; case PRID_IMP_25KF: Loading
arch/mips/kernel/genex.S +1 −0 Original line number Diff line number Diff line Loading @@ -291,6 +291,7 @@ NESTED(nmi_handler, PT_SIZE, sp) BUILD_HANDLER mdmx mdmx sti silent /* #22 */ BUILD_HANDLER watch watch sti verbose /* #23 */ BUILD_HANDLER mcheck mcheck cli verbose /* #24 */ BUILD_HANDLER dsp dsp sti silent /* #26 */ BUILD_HANDLER reserved reserved sti verbose /* others */ #ifdef CONFIG_64BIT Loading
arch/mips/kernel/process.c +56 −2 Original line number Diff line number Diff line Loading @@ -25,8 +25,10 @@ #include <linux/init.h> #include <linux/completion.h> #include <asm/abi.h> #include <asm/bootinfo.h> #include <asm/cpu.h> #include <asm/dsp.h> #include <asm/fpu.h> #include <asm/pgtable.h> #include <asm/system.h> Loading Loading @@ -54,6 +56,54 @@ ATTRIB_NORET void cpu_idle(void) } } extern int do_signal(sigset_t *oldset, struct pt_regs *regs); extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); /* * Native o32 and N64 ABI without DSP ASE */ extern void setup_frame(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set); extern void setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info); struct mips_abi mips_abi = { .do_signal = do_signal, #ifdef CONFIG_TRAD_SIGNALS .setup_frame = setup_frame, #endif .setup_rt_frame = setup_rt_frame }; #ifdef CONFIG_MIPS32_O32 /* * o32 compatibility on 64-bit kernels, without DSP ASE */ extern void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set); extern void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info); struct mips_abi mips_abi_32 = { .do_signal = do_signal32, .setup_frame = setup_frame_32, .setup_rt_frame = setup_rt_frame_32 }; #endif /* CONFIG_MIPS32_O32 */ #ifdef CONFIG_MIPS32_N32 /* * N32 on 64-bit kernels, without DSP ASE */ extern void setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info); struct mips_abi mips_abi_n32 = { .do_signal = do_signal, .setup_rt_frame = setup_rt_frame_n32 }; #endif /* CONFIG_MIPS32_N32 */ asmlinkage void ret_from_fork(void); void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) Loading @@ -70,6 +120,8 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) regs->cp0_status = status; clear_used_math(); lose_fpu(); if (cpu_has_dsp) __init_dsp(); regs->cp0_epc = pc; regs->regs[29] = sp; current_thread_info()->addr_limit = USER_DS; Loading @@ -95,9 +147,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, preempt_disable(); if (is_fpu_owner()) { if (is_fpu_owner()) save_fp(p); } if (cpu_has_dsp) save_dsp(p); preempt_enable(); Loading