Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: [MIPS] signal: do not inline handle_signal() [MIPS] signal: do not use save_static_function() anymore [MIPS] signal32: no need to save c0_status register in setup_sigcontext32() [MIPS] signal32: reduce {setup,restore}_sigcontext32 sizes [MIPS] signal: factorize debug code [MIPS] signal: test return value of install_sigtramp() [MIPS] signal32: remove duplicate code [MIPS] signal: clean up sigframe structure [MIPS] signal: do not inline functions in signal-common.h [MIPS] signals: reduce {setup,restore}_sigcontext sizes [MIPS] Fix warning in get_user when fetching pointer object from userspace. [MIPS] Fix eth2 platform device id for jaguar_atx and ocelot_3 platforms [MIPS] JMR3927 and RBTX49x7 support little endian [MIPS] RBTX49x7: declare prom_getcmdline() [MIPS] RTLX: Sprinkle device model code into code to make udev happier. [MIPS] VPE: Sprinkle device model code into code to make udev happier.
This commit is contained in:
commit
574009c1a8
15 changed files with 435 additions and 451 deletions
|
@ -757,6 +757,7 @@ config TOSHIBA_JMR3927
|
||||||
select SWAP_IO_SPACE
|
select SWAP_IO_SPACE
|
||||||
select SYS_HAS_CPU_TX39XX
|
select SYS_HAS_CPU_TX39XX
|
||||||
select SYS_SUPPORTS_32BIT_KERNEL
|
select SYS_SUPPORTS_32BIT_KERNEL
|
||||||
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
select SYS_SUPPORTS_BIG_ENDIAN
|
select SYS_SUPPORTS_BIG_ENDIAN
|
||||||
select TOSHIBA_BOARDS
|
select TOSHIBA_BOARDS
|
||||||
|
|
||||||
|
@ -771,6 +772,7 @@ config TOSHIBA_RBTX4927
|
||||||
select SYS_HAS_CPU_TX49XX
|
select SYS_HAS_CPU_TX49XX
|
||||||
select SYS_SUPPORTS_32BIT_KERNEL
|
select SYS_SUPPORTS_32BIT_KERNEL
|
||||||
select SYS_SUPPORTS_64BIT_KERNEL
|
select SYS_SUPPORTS_64BIT_KERNEL
|
||||||
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
select SYS_SUPPORTS_BIG_ENDIAN
|
select SYS_SUPPORTS_BIG_ENDIAN
|
||||||
select TOSHIBA_BOARDS
|
select TOSHIBA_BOARDS
|
||||||
select GENERIC_HARDIRQS_NO__DO_IRQ
|
select GENERIC_HARDIRQS_NO__DO_IRQ
|
||||||
|
|
|
@ -249,7 +249,6 @@ void output_sc_defines(void)
|
||||||
offset("#define SC_MDHI ", struct sigcontext, sc_mdhi);
|
offset("#define SC_MDHI ", struct sigcontext, sc_mdhi);
|
||||||
offset("#define SC_MDLO ", struct sigcontext, sc_mdlo);
|
offset("#define SC_MDLO ", struct sigcontext, sc_mdlo);
|
||||||
offset("#define SC_PC ", struct sigcontext, sc_pc);
|
offset("#define SC_PC ", struct sigcontext, sc_pc);
|
||||||
offset("#define SC_STATUS ", struct sigcontext, sc_status);
|
|
||||||
offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr);
|
offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr);
|
||||||
offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir);
|
offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir);
|
||||||
offset("#define SC_HI1 ", struct sigcontext, sc_hi1);
|
offset("#define SC_HI1 ", struct sigcontext, sc_hi1);
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
* Copyright (C) 2005 Mips Technologies, Inc
|
* Copyright (C) 2005 Mips Technologies, Inc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
|
#include <linux/module.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
|
|
||||||
|
@ -453,3 +455,20 @@ void mt_cflush_release(void)
|
||||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||||
/* FILL IN VSMP and AP/SP VERSIONS HERE */
|
/* FILL IN VSMP and AP/SP VERSIONS HERE */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct class *mt_class;
|
||||||
|
|
||||||
|
static int __init mt_init(void)
|
||||||
|
{
|
||||||
|
struct class *mtc;
|
||||||
|
|
||||||
|
mtc = class_create(THIS_MODULE, "mt");
|
||||||
|
if (IS_ERR(mtc))
|
||||||
|
return PTR_ERR(mtc);
|
||||||
|
|
||||||
|
mt_class = mtc;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
subsys_initcall(mt_init);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <asm/mipsmtregs.h>
|
#include <asm/mipsmtregs.h>
|
||||||
|
#include <asm/mips_mt.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/atomic.h>
|
#include <asm/atomic.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
|
@ -498,7 +500,8 @@ static char register_chrdev_failed[] __initdata =
|
||||||
|
|
||||||
static int rtlx_module_init(void)
|
static int rtlx_module_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
struct device *dev;
|
||||||
|
int i, err;
|
||||||
|
|
||||||
major = register_chrdev(0, module_name, &rtlx_fops);
|
major = register_chrdev(0, module_name, &rtlx_fops);
|
||||||
if (major < 0) {
|
if (major < 0) {
|
||||||
|
@ -511,6 +514,13 @@ static int rtlx_module_init(void)
|
||||||
init_waitqueue_head(&channel_wqs[i].rt_queue);
|
init_waitqueue_head(&channel_wqs[i].rt_queue);
|
||||||
init_waitqueue_head(&channel_wqs[i].lx_queue);
|
init_waitqueue_head(&channel_wqs[i].lx_queue);
|
||||||
channel_wqs[i].in_open = 0;
|
channel_wqs[i].in_open = 0;
|
||||||
|
|
||||||
|
dev = device_create(mt_class, NULL, MKDEV(major, i),
|
||||||
|
"%s%d", module_name, i);
|
||||||
|
if (IS_ERR(dev)) {
|
||||||
|
err = PTR_ERR(dev);
|
||||||
|
goto out_chrdev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set up notifiers */
|
/* set up notifiers */
|
||||||
|
@ -525,10 +535,21 @@ static int rtlx_module_init(void)
|
||||||
setup_irq(rtlx_irq_num, &rtlx_irq);
|
setup_irq(rtlx_irq_num, &rtlx_irq);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out_chrdev:
|
||||||
|
for (i = 0; i < RTLX_CHANNELS; i++)
|
||||||
|
device_destroy(mt_class, MKDEV(major, i));
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit rtlx_module_exit(void)
|
static void __exit rtlx_module_exit(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < RTLX_CHANNELS; i++)
|
||||||
|
device_destroy(mt_class, MKDEV(major, i));
|
||||||
|
|
||||||
unregister_chrdev(major, module_name);
|
unregister_chrdev(major, module_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,169 +8,57 @@
|
||||||
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __SIGNAL_COMMON_H
|
||||||
|
#define __SIGNAL_COMMON_H
|
||||||
|
|
||||||
static inline int
|
/* #define DEBUG_SIG */
|
||||||
setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
|
|
||||||
{
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
err |= __put_user(regs->cp0_epc, &sc->sc_pc);
|
#ifdef DEBUG_SIG
|
||||||
|
# define DEBUGP(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ##args)
|
||||||
|
#else
|
||||||
|
# define DEBUGP(fmt, args...)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define save_gp_reg(i) do { \
|
/*
|
||||||
err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \
|
* Horribly complicated - with the bloody RM9000 workarounds enabled
|
||||||
} while(0)
|
* the signal trampolines is moving to the end of the structure so we can
|
||||||
__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
|
* increase the alignment without breaking software compatibility.
|
||||||
save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
|
*/
|
||||||
save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
|
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
||||||
save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
|
|
||||||
save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
|
|
||||||
save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
|
|
||||||
save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
|
|
||||||
save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
|
|
||||||
save_gp_reg(31);
|
|
||||||
#undef save_gp_reg
|
|
||||||
|
|
||||||
err |= __put_user(regs->hi, &sc->sc_mdhi);
|
struct sigframe {
|
||||||
err |= __put_user(regs->lo, &sc->sc_mdlo);
|
u32 sf_ass[4]; /* argument save space for o32 */
|
||||||
if (cpu_has_dsp) {
|
u32 sf_code[2]; /* signal trampoline */
|
||||||
err |= __put_user(mfhi1(), &sc->sc_hi1);
|
struct sigcontext sf_sc;
|
||||||
err |= __put_user(mflo1(), &sc->sc_lo1);
|
sigset_t sf_mask;
|
||||||
err |= __put_user(mfhi2(), &sc->sc_hi2);
|
};
|
||||||
err |= __put_user(mflo2(), &sc->sc_lo2);
|
|
||||||
err |= __put_user(mfhi3(), &sc->sc_hi3);
|
|
||||||
err |= __put_user(mflo3(), &sc->sc_lo3);
|
|
||||||
err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
err |= __put_user(!!used_math(), &sc->sc_used_math);
|
#else /* ICACHE_REFILLS_WORKAROUND_WAR */
|
||||||
|
|
||||||
if (!used_math())
|
struct sigframe {
|
||||||
goto out;
|
u32 sf_ass[4]; /* argument save space for o32 */
|
||||||
|
u32 sf_pad[2];
|
||||||
|
struct sigcontext sf_sc; /* hw context */
|
||||||
|
sigset_t sf_mask;
|
||||||
|
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
|
||||||
* Save FPU state to signal context. Signal handler will "inherit"
|
|
||||||
* current FPU state.
|
|
||||||
*/
|
|
||||||
preempt_disable();
|
|
||||||
|
|
||||||
if (!is_fpu_owner()) {
|
/*
|
||||||
own_fpu();
|
* handle hardware context
|
||||||
restore_fp(current);
|
*/
|
||||||
}
|
extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
||||||
err |= save_fp_context(sc);
|
extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
||||||
|
|
||||||
preempt_enable();
|
|
||||||
|
|
||||||
out:
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
|
|
||||||
{
|
|
||||||
unsigned int used_math;
|
|
||||||
unsigned long treg;
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
|
||||||
|
|
||||||
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
|
|
||||||
err |= __get_user(regs->hi, &sc->sc_mdhi);
|
|
||||||
err |= __get_user(regs->lo, &sc->sc_mdlo);
|
|
||||||
if (cpu_has_dsp) {
|
|
||||||
err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define restore_gp_reg(i) do { \
|
|
||||||
err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
|
|
||||||
} while(0)
|
|
||||||
restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
|
|
||||||
restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
|
|
||||||
restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
|
|
||||||
restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
|
|
||||||
restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
|
|
||||||
restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
|
|
||||||
restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
|
|
||||||
restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
|
|
||||||
restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
|
|
||||||
restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
|
|
||||||
restore_gp_reg(31);
|
|
||||||
#undef restore_gp_reg
|
|
||||||
|
|
||||||
err |= __get_user(used_math, &sc->sc_used_math);
|
|
||||||
conditional_used_math(used_math);
|
|
||||||
|
|
||||||
preempt_disable();
|
|
||||||
|
|
||||||
if (used_math()) {
|
|
||||||
/* restore fpu context if we have used it before */
|
|
||||||
own_fpu();
|
|
||||||
err |= restore_fp_context(sc);
|
|
||||||
} else {
|
|
||||||
/* signal handler may have used FPU. Give it up. */
|
|
||||||
lose_fpu();
|
|
||||||
}
|
|
||||||
|
|
||||||
preempt_enable();
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine which stack to use..
|
* Determine which stack to use..
|
||||||
*/
|
*/
|
||||||
static inline void __user *
|
extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
|
||||||
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
|
size_t frame_size);
|
||||||
{
|
/*
|
||||||
unsigned long sp;
|
* install trampoline code to get back from the sig handler
|
||||||
|
*/
|
||||||
|
extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
|
||||||
|
|
||||||
/* Default to using normal stack */
|
#endif /* __SIGNAL_COMMON_H */
|
||||||
sp = regs->regs[29];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FPU emulator may have it's own trampoline active just
|
|
||||||
* above the user stack, 16-bytes before the next lowest
|
|
||||||
* 16 byte boundary. Try to avoid trashing it.
|
|
||||||
*/
|
|
||||||
sp -= 32;
|
|
||||||
|
|
||||||
/* This is the X/Open sanctioned signal stack switching. */
|
|
||||||
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
|
|
||||||
sp = current->sas_ss_sp + current->sas_ss_size;
|
|
||||||
|
|
||||||
return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int install_sigtramp(unsigned int __user *tramp,
|
|
||||||
unsigned int syscall)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up the return code ...
|
|
||||||
*
|
|
||||||
* li v0, __NR__foo_sigreturn
|
|
||||||
* syscall
|
|
||||||
*/
|
|
||||||
|
|
||||||
err = __put_user(0x24020000 + syscall, tramp + 0);
|
|
||||||
err |= __put_user(0x0000000c , tramp + 1);
|
|
||||||
if (ICACHE_REFILLS_WORKAROUND_WAR) {
|
|
||||||
err |= __put_user(0, tramp + 2);
|
|
||||||
err |= __put_user(0, tramp + 3);
|
|
||||||
err |= __put_user(0, tramp + 4);
|
|
||||||
err |= __put_user(0, tramp + 5);
|
|
||||||
err |= __put_user(0, tramp + 6);
|
|
||||||
err |= __put_user(0, tramp + 7);
|
|
||||||
}
|
|
||||||
flush_cache_sigtramp((unsigned long) tramp);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
|
@ -34,18 +34,174 @@
|
||||||
|
|
||||||
#include "signal-common.h"
|
#include "signal-common.h"
|
||||||
|
|
||||||
#define DEBUG_SIG 0
|
|
||||||
|
|
||||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||||
|
|
||||||
|
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
||||||
|
|
||||||
|
struct rt_sigframe {
|
||||||
|
u32 rs_ass[4]; /* argument save space for o32 */
|
||||||
|
u32 rs_code[2]; /* signal trampoline */
|
||||||
|
struct siginfo rs_info;
|
||||||
|
struct ucontext rs_uc;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct rt_sigframe {
|
||||||
|
u32 rs_ass[4]; /* argument save space for o32 */
|
||||||
|
u32 rs_pad[2];
|
||||||
|
struct siginfo rs_info;
|
||||||
|
struct ucontext rs_uc;
|
||||||
|
u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper routines
|
||||||
|
*/
|
||||||
|
int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
err |= __put_user(regs->cp0_epc, &sc->sc_pc);
|
||||||
|
|
||||||
|
err |= __put_user(0, &sc->sc_regs[0]);
|
||||||
|
for (i = 1; i < 32; i++)
|
||||||
|
err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
|
||||||
|
|
||||||
|
err |= __put_user(regs->hi, &sc->sc_mdhi);
|
||||||
|
err |= __put_user(regs->lo, &sc->sc_mdlo);
|
||||||
|
if (cpu_has_dsp) {
|
||||||
|
err |= __put_user(mfhi1(), &sc->sc_hi1);
|
||||||
|
err |= __put_user(mflo1(), &sc->sc_lo1);
|
||||||
|
err |= __put_user(mfhi2(), &sc->sc_hi2);
|
||||||
|
err |= __put_user(mflo2(), &sc->sc_lo2);
|
||||||
|
err |= __put_user(mfhi3(), &sc->sc_hi3);
|
||||||
|
err |= __put_user(mflo3(), &sc->sc_lo3);
|
||||||
|
err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
err |= __put_user(!!used_math(), &sc->sc_used_math);
|
||||||
|
|
||||||
|
if (used_math()) {
|
||||||
|
/*
|
||||||
|
* Save FPU state to signal context. Signal handler
|
||||||
|
* will "inherit" current FPU state.
|
||||||
|
*/
|
||||||
|
preempt_disable();
|
||||||
|
|
||||||
|
if (!is_fpu_owner()) {
|
||||||
|
own_fpu();
|
||||||
|
restore_fp(current);
|
||||||
|
}
|
||||||
|
err |= save_fp_context(sc);
|
||||||
|
|
||||||
|
preempt_enable();
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
|
||||||
|
{
|
||||||
|
unsigned int used_math;
|
||||||
|
unsigned long treg;
|
||||||
|
int err = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
|
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
|
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
|
||||||
|
err |= __get_user(regs->hi, &sc->sc_mdhi);
|
||||||
|
err |= __get_user(regs->lo, &sc->sc_mdlo);
|
||||||
|
if (cpu_has_dsp) {
|
||||||
|
err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < 32; i++)
|
||||||
|
err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
|
||||||
|
|
||||||
|
err |= __get_user(used_math, &sc->sc_used_math);
|
||||||
|
conditional_used_math(used_math);
|
||||||
|
|
||||||
|
preempt_disable();
|
||||||
|
|
||||||
|
if (used_math()) {
|
||||||
|
/* restore fpu context if we have used it before */
|
||||||
|
own_fpu();
|
||||||
|
err |= restore_fp_context(sc);
|
||||||
|
} else {
|
||||||
|
/* signal handler may have used FPU. Give it up. */
|
||||||
|
lose_fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
preempt_enable();
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
|
||||||
|
size_t frame_size)
|
||||||
|
{
|
||||||
|
unsigned long sp;
|
||||||
|
|
||||||
|
/* Default to using normal stack */
|
||||||
|
sp = regs->regs[29];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FPU emulator may have it's own trampoline active just
|
||||||
|
* above the user stack, 16-bytes before the next lowest
|
||||||
|
* 16 byte boundary. Try to avoid trashing it.
|
||||||
|
*/
|
||||||
|
sp -= 32;
|
||||||
|
|
||||||
|
/* This is the X/Open sanctioned signal stack switching. */
|
||||||
|
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
|
||||||
|
sp = current->sas_ss_sp + current->sas_ss_size;
|
||||||
|
|
||||||
|
return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
|
||||||
|
}
|
||||||
|
|
||||||
|
int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the return code ...
|
||||||
|
*
|
||||||
|
* li v0, __NR__foo_sigreturn
|
||||||
|
* syscall
|
||||||
|
*/
|
||||||
|
|
||||||
|
err = __put_user(0x24020000 + syscall, tramp + 0);
|
||||||
|
err |= __put_user(0x0000000c , tramp + 1);
|
||||||
|
if (ICACHE_REFILLS_WORKAROUND_WAR) {
|
||||||
|
err |= __put_user(0, tramp + 2);
|
||||||
|
err |= __put_user(0, tramp + 3);
|
||||||
|
err |= __put_user(0, tramp + 4);
|
||||||
|
err |= __put_user(0, tramp + 5);
|
||||||
|
err |= __put_user(0, tramp + 6);
|
||||||
|
err |= __put_user(0, tramp + 7);
|
||||||
|
}
|
||||||
|
flush_cache_sigtramp((unsigned long) tramp);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Atomically swap in the new signal mask, and wait for a signal.
|
* Atomically swap in the new signal mask, and wait for a signal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_TRAD_SIGNALS
|
#ifdef CONFIG_TRAD_SIGNALS
|
||||||
save_static_function(sys_sigsuspend);
|
asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||||
__attribute_used__ noinline static int
|
|
||||||
_sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
|
||||||
{
|
{
|
||||||
sigset_t newset;
|
sigset_t newset;
|
||||||
sigset_t __user *uset;
|
sigset_t __user *uset;
|
||||||
|
@ -68,9 +224,7 @@ _sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
save_static_function(sys_rt_sigsuspend);
|
asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||||
__attribute_used__ noinline static int
|
|
||||||
_sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
|
||||||
{
|
{
|
||||||
sigset_t newset;
|
sigset_t newset;
|
||||||
sigset_t __user *unewset;
|
sigset_t __user *unewset;
|
||||||
|
@ -148,45 +302,8 @@ asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
|
||||||
return do_sigaltstack(uss, uoss, usp);
|
return do_sigaltstack(uss, uoss, usp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Horribly complicated - with the bloody RM9000 workarounds enabled
|
|
||||||
* the signal trampolines is moving to the end of the structure so we can
|
|
||||||
* increase the alignment without breaking software compatibility.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_TRAD_SIGNALS
|
#ifdef CONFIG_TRAD_SIGNALS
|
||||||
struct sigframe {
|
asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||||
u32 sf_ass[4]; /* argument save space for o32 */
|
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR
|
|
||||||
u32 sf_pad[2];
|
|
||||||
#else
|
|
||||||
u32 sf_code[2]; /* signal trampoline */
|
|
||||||
#endif
|
|
||||||
struct sigcontext sf_sc;
|
|
||||||
sigset_t sf_mask;
|
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR
|
|
||||||
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct rt_sigframe {
|
|
||||||
u32 rs_ass[4]; /* argument save space for o32 */
|
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR
|
|
||||||
u32 rs_pad[2];
|
|
||||||
#else
|
|
||||||
u32 rs_code[2]; /* signal trampoline */
|
|
||||||
#endif
|
|
||||||
struct siginfo rs_info;
|
|
||||||
struct ucontext rs_uc;
|
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR
|
|
||||||
u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_TRAD_SIGNALS
|
|
||||||
save_static_function(sys_sigreturn);
|
|
||||||
__attribute_used__ noinline static void
|
|
||||||
_sys_sigreturn(nabi_no_regargs struct pt_regs regs)
|
|
||||||
{
|
{
|
||||||
struct sigframe __user *frame;
|
struct sigframe __user *frame;
|
||||||
sigset_t blocked;
|
sigset_t blocked;
|
||||||
|
@ -221,9 +338,7 @@ _sys_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_TRAD_SIGNALS */
|
#endif /* CONFIG_TRAD_SIGNALS */
|
||||||
|
|
||||||
save_static_function(sys_rt_sigreturn);
|
asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||||
__attribute_used__ noinline static void
|
|
||||||
_sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
|
|
||||||
{
|
{
|
||||||
struct rt_sigframe __user *frame;
|
struct rt_sigframe __user *frame;
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
|
@ -275,7 +390,7 @@ int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||||
goto give_sigsegv;
|
goto give_sigsegv;
|
||||||
|
|
||||||
install_sigtramp(frame->sf_code, __NR_sigreturn);
|
err |= install_sigtramp(frame->sf_code, __NR_sigreturn);
|
||||||
|
|
||||||
err |= setup_sigcontext(regs, &frame->sf_sc);
|
err |= setup_sigcontext(regs, &frame->sf_sc);
|
||||||
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
|
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
|
||||||
|
@ -299,11 +414,9 @@ int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
regs->regs[31] = (unsigned long) frame->sf_code;
|
regs->regs[31] = (unsigned long) frame->sf_code;
|
||||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||||
|
|
||||||
#if DEBUG_SIG
|
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||||
printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
|
|
||||||
current->comm, current->pid,
|
current->comm, current->pid,
|
||||||
frame, regs->cp0_epc, frame->regs[31]);
|
frame, regs->cp0_epc, regs->regs[31]);
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
give_sigsegv:
|
give_sigsegv:
|
||||||
|
@ -322,7 +435,7 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||||
goto give_sigsegv;
|
goto give_sigsegv;
|
||||||
|
|
||||||
install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
|
err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
|
||||||
|
|
||||||
/* Create siginfo. */
|
/* Create siginfo. */
|
||||||
err |= copy_siginfo_to_user(&frame->rs_info, info);
|
err |= copy_siginfo_to_user(&frame->rs_info, info);
|
||||||
|
@ -359,11 +472,10 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
regs->regs[31] = (unsigned long) frame->rs_code;
|
regs->regs[31] = (unsigned long) frame->rs_code;
|
||||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||||
|
|
||||||
#if DEBUG_SIG
|
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||||
printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
|
|
||||||
current->comm, current->pid,
|
current->comm, current->pid,
|
||||||
frame, regs->cp0_epc, regs->regs[31]);
|
frame, regs->cp0_epc, regs->regs[31]);
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
give_sigsegv:
|
give_sigsegv:
|
||||||
|
@ -371,7 +483,7 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int handle_signal(unsigned long sig, siginfo_t *info,
|
static int handle_signal(unsigned long sig, siginfo_t *info,
|
||||||
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
|
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include <asm/fpu.h>
|
#include <asm/fpu.h>
|
||||||
#include <asm/war.h>
|
#include <asm/war.h>
|
||||||
|
|
||||||
|
#include "signal-common.h"
|
||||||
|
|
||||||
#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
|
#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
|
||||||
|
|
||||||
typedef struct compat_siginfo {
|
typedef struct compat_siginfo {
|
||||||
|
@ -102,8 +104,6 @@ typedef struct compat_siginfo {
|
||||||
#define __NR_O32_rt_sigreturn 4193
|
#define __NR_O32_rt_sigreturn 4193
|
||||||
#define __NR_O32_restart_syscall 4253
|
#define __NR_O32_restart_syscall 4253
|
||||||
|
|
||||||
#define DEBUG_SIG 0
|
|
||||||
|
|
||||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||||
|
|
||||||
/* 32-bit compatibility types */
|
/* 32-bit compatibility types */
|
||||||
|
@ -139,6 +139,123 @@ struct ucontext32 {
|
||||||
sigset_t32 uc_sigmask; /* mask last for extensibility */
|
sigset_t32 uc_sigmask; /* mask last for extensibility */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
||||||
|
|
||||||
|
struct rt_sigframe32 {
|
||||||
|
u32 rs_ass[4]; /* argument save space for o32 */
|
||||||
|
u32 rs_code[2]; /* signal trampoline */
|
||||||
|
compat_siginfo_t rs_info;
|
||||||
|
struct ucontext32 rs_uc;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* ICACHE_REFILLS_WORKAROUND_WAR */
|
||||||
|
|
||||||
|
struct rt_sigframe32 {
|
||||||
|
u32 rs_ass[4]; /* argument save space for o32 */
|
||||||
|
u32 rs_pad[2];
|
||||||
|
compat_siginfo_t rs_info;
|
||||||
|
struct ucontext32 rs_uc;
|
||||||
|
u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigcontext handlers
|
||||||
|
*/
|
||||||
|
static int setup_sigcontext32(struct pt_regs *regs,
|
||||||
|
struct sigcontext32 __user *sc)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
err |= __put_user(regs->cp0_epc, &sc->sc_pc);
|
||||||
|
|
||||||
|
err |= __put_user(0, &sc->sc_regs[0]);
|
||||||
|
for (i = 1; i < 32; i++)
|
||||||
|
err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
|
||||||
|
|
||||||
|
err |= __put_user(regs->hi, &sc->sc_mdhi);
|
||||||
|
err |= __put_user(regs->lo, &sc->sc_mdlo);
|
||||||
|
if (cpu_has_dsp) {
|
||||||
|
err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
|
||||||
|
err |= __put_user(mfhi1(), &sc->sc_hi1);
|
||||||
|
err |= __put_user(mflo1(), &sc->sc_lo1);
|
||||||
|
err |= __put_user(mfhi2(), &sc->sc_hi2);
|
||||||
|
err |= __put_user(mflo2(), &sc->sc_lo2);
|
||||||
|
err |= __put_user(mfhi3(), &sc->sc_hi3);
|
||||||
|
err |= __put_user(mflo3(), &sc->sc_lo3);
|
||||||
|
}
|
||||||
|
|
||||||
|
err |= __put_user(!!used_math(), &sc->sc_used_math);
|
||||||
|
|
||||||
|
if (used_math()) {
|
||||||
|
/*
|
||||||
|
* Save FPU state to signal context. Signal handler
|
||||||
|
* will "inherit" current FPU state.
|
||||||
|
*/
|
||||||
|
preempt_disable();
|
||||||
|
|
||||||
|
if (!is_fpu_owner()) {
|
||||||
|
own_fpu();
|
||||||
|
restore_fp(current);
|
||||||
|
}
|
||||||
|
err |= save_fp_context32(sc);
|
||||||
|
|
||||||
|
preempt_enable();
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int restore_sigcontext32(struct pt_regs *regs,
|
||||||
|
struct sigcontext32 __user *sc)
|
||||||
|
{
|
||||||
|
u32 used_math;
|
||||||
|
int err = 0;
|
||||||
|
s32 treg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Always make any pending restarted system calls return -EINTR */
|
||||||
|
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
|
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
|
||||||
|
err |= __get_user(regs->hi, &sc->sc_mdhi);
|
||||||
|
err |= __get_user(regs->lo, &sc->sc_mdlo);
|
||||||
|
if (cpu_has_dsp) {
|
||||||
|
err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
|
||||||
|
err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < 32; i++)
|
||||||
|
err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
|
||||||
|
|
||||||
|
err |= __get_user(used_math, &sc->sc_used_math);
|
||||||
|
conditional_used_math(used_math);
|
||||||
|
|
||||||
|
preempt_disable();
|
||||||
|
|
||||||
|
if (used_math()) {
|
||||||
|
/* restore fpu context if we have used it before */
|
||||||
|
own_fpu();
|
||||||
|
err |= restore_fp_context32(sc);
|
||||||
|
} else {
|
||||||
|
/* signal handler may have used FPU. Give it up. */
|
||||||
|
lose_fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
preempt_enable();
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
extern void __put_sigset_unknown_nsig(void);
|
extern void __put_sigset_unknown_nsig(void);
|
||||||
extern void __get_sigset_unknown_nsig(void);
|
extern void __get_sigset_unknown_nsig(void);
|
||||||
|
|
||||||
|
@ -191,9 +308,7 @@ static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
|
||||||
* Atomically swap in the new signal mask, and wait for a signal.
|
* Atomically swap in the new signal mask, and wait for a signal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
save_static_function(sys32_sigsuspend);
|
asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||||
__attribute_used__ noinline static int
|
|
||||||
_sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
|
||||||
{
|
{
|
||||||
compat_sigset_t __user *uset;
|
compat_sigset_t __user *uset;
|
||||||
sigset_t newset;
|
sigset_t newset;
|
||||||
|
@ -215,9 +330,7 @@ _sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||||
return -ERESTARTNOHAND;
|
return -ERESTARTNOHAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
save_static_function(sys32_rt_sigsuspend);
|
asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||||
__attribute_used__ noinline static int
|
|
||||||
_sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
|
||||||
{
|
{
|
||||||
compat_sigset_t __user *uset;
|
compat_sigset_t __user *uset;
|
||||||
sigset_t newset;
|
sigset_t newset;
|
||||||
|
@ -326,91 +439,6 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 __user *sc)
|
|
||||||
{
|
|
||||||
u32 used_math;
|
|
||||||
int err = 0;
|
|
||||||
s32 treg;
|
|
||||||
|
|
||||||
/* Always make any pending restarted system calls return -EINTR */
|
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
|
||||||
|
|
||||||
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
|
|
||||||
err |= __get_user(regs->hi, &sc->sc_mdhi);
|
|
||||||
err |= __get_user(regs->lo, &sc->sc_mdlo);
|
|
||||||
if (cpu_has_dsp) {
|
|
||||||
err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
|
|
||||||
err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define restore_gp_reg(i) do { \
|
|
||||||
err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
|
|
||||||
} while(0)
|
|
||||||
restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
|
|
||||||
restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
|
|
||||||
restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
|
|
||||||
restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
|
|
||||||
restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
|
|
||||||
restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
|
|
||||||
restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
|
|
||||||
restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
|
|
||||||
restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
|
|
||||||
restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
|
|
||||||
restore_gp_reg(31);
|
|
||||||
#undef restore_gp_reg
|
|
||||||
|
|
||||||
err |= __get_user(used_math, &sc->sc_used_math);
|
|
||||||
conditional_used_math(used_math);
|
|
||||||
|
|
||||||
preempt_disable();
|
|
||||||
|
|
||||||
if (used_math()) {
|
|
||||||
/* restore fpu context if we have used it before */
|
|
||||||
own_fpu();
|
|
||||||
err |= restore_fp_context32(sc);
|
|
||||||
} else {
|
|
||||||
/* signal handler may have used FPU. Give it up. */
|
|
||||||
lose_fpu();
|
|
||||||
}
|
|
||||||
|
|
||||||
preempt_enable();
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sigframe {
|
|
||||||
u32 sf_ass[4]; /* argument save space for o32 */
|
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR
|
|
||||||
u32 sf_pad[2];
|
|
||||||
#else
|
|
||||||
u32 sf_code[2]; /* signal trampoline */
|
|
||||||
#endif
|
|
||||||
struct sigcontext32 sf_sc;
|
|
||||||
sigset_t sf_mask;
|
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR
|
|
||||||
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rt_sigframe32 {
|
|
||||||
u32 rs_ass[4]; /* argument save space for o32 */
|
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR
|
|
||||||
u32 rs_pad[2];
|
|
||||||
#else
|
|
||||||
u32 rs_code[2]; /* signal trampoline */
|
|
||||||
#endif
|
|
||||||
compat_siginfo_t rs_info;
|
|
||||||
struct ucontext32 rs_uc;
|
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR
|
|
||||||
u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
|
int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
@ -463,9 +491,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
save_static_function(sys32_sigreturn);
|
asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||||
__attribute_used__ noinline static void
|
|
||||||
_sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
|
|
||||||
{
|
{
|
||||||
struct sigframe __user *frame;
|
struct sigframe __user *frame;
|
||||||
sigset_t blocked;
|
sigset_t blocked;
|
||||||
|
@ -499,9 +525,7 @@ _sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||||
force_sig(SIGSEGV, current);
|
force_sig(SIGSEGV, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
save_static_function(sys32_rt_sigreturn);
|
asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||||
__attribute_used__ noinline static void
|
|
||||||
_sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
|
|
||||||
{
|
{
|
||||||
struct rt_sigframe32 __user *frame;
|
struct rt_sigframe32 __user *frame;
|
||||||
mm_segment_t old_fs;
|
mm_segment_t old_fs;
|
||||||
|
@ -554,89 +578,6 @@ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||||
force_sig(SIGSEGV, current);
|
force_sig(SIGSEGV, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int setup_sigcontext32(struct pt_regs *regs,
|
|
||||||
struct sigcontext32 __user *sc)
|
|
||||||
{
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
err |= __put_user(regs->cp0_epc, &sc->sc_pc);
|
|
||||||
err |= __put_user(regs->cp0_status, &sc->sc_status);
|
|
||||||
|
|
||||||
#define save_gp_reg(i) { \
|
|
||||||
err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \
|
|
||||||
} while(0)
|
|
||||||
__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
|
|
||||||
save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
|
|
||||||
save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
|
|
||||||
save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
|
|
||||||
save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
|
|
||||||
save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
|
|
||||||
save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
|
|
||||||
save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
|
|
||||||
save_gp_reg(31);
|
|
||||||
#undef save_gp_reg
|
|
||||||
|
|
||||||
err |= __put_user(regs->hi, &sc->sc_mdhi);
|
|
||||||
err |= __put_user(regs->lo, &sc->sc_mdlo);
|
|
||||||
if (cpu_has_dsp) {
|
|
||||||
err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
|
|
||||||
err |= __put_user(mfhi1(), &sc->sc_hi1);
|
|
||||||
err |= __put_user(mflo1(), &sc->sc_lo1);
|
|
||||||
err |= __put_user(mfhi2(), &sc->sc_hi2);
|
|
||||||
err |= __put_user(mflo2(), &sc->sc_lo2);
|
|
||||||
err |= __put_user(mfhi3(), &sc->sc_hi3);
|
|
||||||
err |= __put_user(mflo3(), &sc->sc_lo3);
|
|
||||||
}
|
|
||||||
|
|
||||||
err |= __put_user(!!used_math(), &sc->sc_used_math);
|
|
||||||
|
|
||||||
if (!used_math())
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Save FPU state to signal context. Signal handler will "inherit"
|
|
||||||
* current FPU state.
|
|
||||||
*/
|
|
||||||
preempt_disable();
|
|
||||||
|
|
||||||
if (!is_fpu_owner()) {
|
|
||||||
own_fpu();
|
|
||||||
restore_fp(current);
|
|
||||||
}
|
|
||||||
err |= save_fp_context32(sc);
|
|
||||||
|
|
||||||
preempt_enable();
|
|
||||||
|
|
||||||
out:
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine which stack to use..
|
|
||||||
*/
|
|
||||||
static inline void __user *get_sigframe(struct k_sigaction *ka,
|
|
||||||
struct pt_regs *regs,
|
|
||||||
size_t frame_size)
|
|
||||||
{
|
|
||||||
unsigned long sp;
|
|
||||||
|
|
||||||
/* Default to using normal stack */
|
|
||||||
sp = regs->regs[29];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FPU emulator may have it's own trampoline active just
|
|
||||||
* above the user stack, 16-bytes before the next lowest
|
|
||||||
* 16 byte boundary. Try to avoid trashing it.
|
|
||||||
*/
|
|
||||||
sp -= 32;
|
|
||||||
|
|
||||||
/* This is the X/Open sanctioned signal stack switching. */
|
|
||||||
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
|
|
||||||
sp = current->sas_ss_sp + current->sas_ss_size;
|
|
||||||
|
|
||||||
return (void __user *)((sp - frame_size) & ALMASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
int signr, sigset_t *set)
|
int signr, sigset_t *set)
|
||||||
{
|
{
|
||||||
|
@ -647,15 +588,7 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||||
goto give_sigsegv;
|
goto give_sigsegv;
|
||||||
|
|
||||||
/*
|
err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
|
||||||
* Set up the return code ...
|
|
||||||
*
|
|
||||||
* li v0, __NR_O32_sigreturn
|
|
||||||
* syscall
|
|
||||||
*/
|
|
||||||
err |= __put_user(0x24020000 + __NR_O32_sigreturn, frame->sf_code + 0);
|
|
||||||
err |= __put_user(0x0000000c , frame->sf_code + 1);
|
|
||||||
flush_cache_sigtramp((unsigned long) frame->sf_code);
|
|
||||||
|
|
||||||
err |= setup_sigcontext32(regs, &frame->sf_sc);
|
err |= setup_sigcontext32(regs, &frame->sf_sc);
|
||||||
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
|
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
|
||||||
|
@ -679,11 +612,10 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
regs->regs[31] = (unsigned long) frame->sf_code;
|
regs->regs[31] = (unsigned long) frame->sf_code;
|
||||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||||
|
|
||||||
#if DEBUG_SIG
|
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||||
printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
|
|
||||||
current->comm, current->pid,
|
current->comm, current->pid,
|
||||||
frame, regs->cp0_epc, frame->sf_code);
|
frame, regs->cp0_epc, regs->regs[31]);
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
give_sigsegv:
|
give_sigsegv:
|
||||||
|
@ -702,17 +634,7 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||||
goto give_sigsegv;
|
goto give_sigsegv;
|
||||||
|
|
||||||
/* Set up to return from userspace. If provided, use a stub already
|
err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
|
||||||
in userspace. */
|
|
||||||
/*
|
|
||||||
* Set up the return code ...
|
|
||||||
*
|
|
||||||
* li v0, __NR_O32_rt_sigreturn
|
|
||||||
* syscall
|
|
||||||
*/
|
|
||||||
err |= __put_user(0x24020000 + __NR_O32_rt_sigreturn, frame->rs_code + 0);
|
|
||||||
err |= __put_user(0x0000000c , frame->rs_code + 1);
|
|
||||||
flush_cache_sigtramp((unsigned long) frame->rs_code);
|
|
||||||
|
|
||||||
/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
|
/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
|
||||||
err |= copy_siginfo_to_user32(&frame->rs_info, info);
|
err |= copy_siginfo_to_user32(&frame->rs_info, info);
|
||||||
|
@ -750,11 +672,10 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
regs->regs[31] = (unsigned long) frame->rs_code;
|
regs->regs[31] = (unsigned long) frame->rs_code;
|
||||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||||
|
|
||||||
#if DEBUG_SIG
|
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||||
printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
|
|
||||||
current->comm, current->pid,
|
current->comm, current->pid,
|
||||||
frame, regs->cp0_epc, frame->rs_code);
|
frame, regs->cp0_epc, regs->regs[31]);
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
give_sigsegv:
|
give_sigsegv:
|
||||||
|
|
|
@ -47,8 +47,6 @@
|
||||||
#define __NR_N32_rt_sigreturn 6211
|
#define __NR_N32_rt_sigreturn 6211
|
||||||
#define __NR_N32_restart_syscall 6214
|
#define __NR_N32_restart_syscall 6214
|
||||||
|
|
||||||
#define DEBUG_SIG 0
|
|
||||||
|
|
||||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||||
|
|
||||||
/* IRIX compatible stack_t */
|
/* IRIX compatible stack_t */
|
||||||
|
@ -66,25 +64,30 @@ struct ucontextn32 {
|
||||||
sigset_t uc_sigmask; /* mask last for extensibility */
|
sigset_t uc_sigmask; /* mask last for extensibility */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
||||||
|
|
||||||
struct rt_sigframe_n32 {
|
struct rt_sigframe_n32 {
|
||||||
u32 rs_ass[4]; /* argument save space for o32 */
|
u32 rs_ass[4]; /* argument save space for o32 */
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR
|
|
||||||
u32 rs_pad[2];
|
|
||||||
#else
|
|
||||||
u32 rs_code[2]; /* signal trampoline */
|
u32 rs_code[2]; /* signal trampoline */
|
||||||
#endif
|
|
||||||
struct siginfo rs_info;
|
struct siginfo rs_info;
|
||||||
struct ucontextn32 rs_uc;
|
struct ucontextn32 rs_uc;
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR
|
|
||||||
u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#else /* ICACHE_REFILLS_WORKAROUND_WAR */
|
||||||
|
|
||||||
|
struct rt_sigframe_n32 {
|
||||||
|
u32 rs_ass[4]; /* argument save space for o32 */
|
||||||
|
u32 rs_pad[2];
|
||||||
|
struct siginfo rs_info;
|
||||||
|
struct ucontextn32 rs_uc;
|
||||||
|
u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
|
||||||
|
|
||||||
extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat);
|
extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat);
|
||||||
|
|
||||||
save_static_function(sysn32_rt_sigsuspend);
|
asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||||
__attribute_used__ noinline static int
|
|
||||||
_sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
|
||||||
{
|
{
|
||||||
compat_sigset_t __user *unewset;
|
compat_sigset_t __user *unewset;
|
||||||
compat_sigset_t uset;
|
compat_sigset_t uset;
|
||||||
|
@ -114,9 +117,7 @@ _sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||||
return -ERESTARTNOHAND;
|
return -ERESTARTNOHAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
save_static_function(sysn32_rt_sigreturn);
|
asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||||
__attribute_used__ noinline static void
|
|
||||||
_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
|
|
||||||
{
|
{
|
||||||
struct rt_sigframe_n32 __user *frame;
|
struct rt_sigframe_n32 __user *frame;
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
|
@ -214,11 +215,10 @@ int setup_rt_frame_n32(struct k_sigaction * ka,
|
||||||
regs->regs[31] = (unsigned long) frame->rs_code;
|
regs->regs[31] = (unsigned long) frame->rs_code;
|
||||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||||
|
|
||||||
#if DEBUG_SIG
|
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||||
printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
|
|
||||||
current->comm, current->pid,
|
current->comm, current->pid,
|
||||||
frame, regs->cp0_epc, regs->regs[31]);
|
frame, regs->cp0_epc, regs->regs[31]);
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
give_sigsegv:
|
give_sigsegv:
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/device.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
@ -48,6 +49,7 @@
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/atomic.h>
|
#include <asm/atomic.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
|
#include <asm/mips_mt.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/vpe.h>
|
#include <asm/vpe.h>
|
||||||
|
@ -64,6 +66,7 @@ typedef void *vpe_handle;
|
||||||
|
|
||||||
static char module_name[] = "vpe";
|
static char module_name[] = "vpe";
|
||||||
static int major;
|
static int major;
|
||||||
|
static const int minor = 1; /* fixed for now */
|
||||||
|
|
||||||
#ifdef CONFIG_MIPS_APSP_KSPD
|
#ifdef CONFIG_MIPS_APSP_KSPD
|
||||||
static struct kspd_notifications kspd_events;
|
static struct kspd_notifications kspd_events;
|
||||||
|
@ -1365,12 +1368,15 @@ static void kspd_sp_exit( int sp_id)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static struct device *vpe_dev;
|
||||||
|
|
||||||
static int __init vpe_module_init(void)
|
static int __init vpe_module_init(void)
|
||||||
{
|
{
|
||||||
struct vpe *v = NULL;
|
struct vpe *v = NULL;
|
||||||
|
struct device *dev;
|
||||||
struct tc *t;
|
struct tc *t;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
int i;
|
int i, err;
|
||||||
|
|
||||||
if (!cpu_has_mipsmt) {
|
if (!cpu_has_mipsmt) {
|
||||||
printk("VPE loader: not a MIPS MT capable processor\n");
|
printk("VPE loader: not a MIPS MT capable processor\n");
|
||||||
|
@ -1383,6 +1389,14 @@ static int __init vpe_module_init(void)
|
||||||
return major;
|
return major;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev = device_create(mt_class, NULL, MKDEV(major, minor),
|
||||||
|
"tc%d", minor);
|
||||||
|
if (IS_ERR(dev)) {
|
||||||
|
err = PTR_ERR(dev);
|
||||||
|
goto out_chrdev;
|
||||||
|
}
|
||||||
|
vpe_dev = dev;
|
||||||
|
|
||||||
dmt();
|
dmt();
|
||||||
dvpe();
|
dvpe();
|
||||||
|
|
||||||
|
@ -1478,6 +1492,11 @@ static int __init vpe_module_init(void)
|
||||||
kspd_events.kspd_sp_exit = kspd_sp_exit;
|
kspd_events.kspd_sp_exit = kspd_sp_exit;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out_chrdev:
|
||||||
|
unregister_chrdev(major, module_name);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit vpe_module_exit(void)
|
static void __exit vpe_module_exit(void)
|
||||||
|
@ -1490,6 +1509,7 @@ static void __exit vpe_module_exit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device_destroy(mt_class, MKDEV(major, minor));
|
||||||
unregister_chrdev(major, module_name);
|
unregister_chrdev(major, module_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ static struct mv643xx_eth_platform_data eth2_pd = {
|
||||||
|
|
||||||
static struct platform_device eth2_device = {
|
static struct platform_device eth2_device = {
|
||||||
.name = MV643XX_ETH_NAME,
|
.name = MV643XX_ETH_NAME,
|
||||||
.id = 1,
|
.id = 2,
|
||||||
.num_resources = ARRAY_SIZE(mv64x60_eth2_resources),
|
.num_resources = ARRAY_SIZE(mv64x60_eth2_resources),
|
||||||
.resource = mv64x60_eth2_resources,
|
.resource = mv64x60_eth2_resources,
|
||||||
.dev = {
|
.dev = {
|
||||||
|
|
|
@ -129,7 +129,7 @@ static struct mv643xx_eth_platform_data eth2_pd = {
|
||||||
|
|
||||||
static struct platform_device eth2_device = {
|
static struct platform_device eth2_device = {
|
||||||
.name = MV643XX_ETH_NAME,
|
.name = MV643XX_ETH_NAME,
|
||||||
.id = 1,
|
.id = 2,
|
||||||
.num_resources = ARRAY_SIZE(mv64x60_eth2_resources),
|
.num_resources = ARRAY_SIZE(mv64x60_eth2_resources),
|
||||||
.resource = mv64x60_eth2_resources,
|
.resource = mv64x60_eth2_resources,
|
||||||
.dev = {
|
.dev = {
|
||||||
|
|
|
@ -137,6 +137,8 @@ int tx4927_using_backplane = 0;
|
||||||
extern void gt64120_time_init(void);
|
extern void gt64120_time_init(void);
|
||||||
extern void toshiba_rbtx4927_irq_setup(void);
|
extern void toshiba_rbtx4927_irq_setup(void);
|
||||||
|
|
||||||
|
char *prom_getcmdline(void);
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
#ifdef CONFIG_PCI
|
||||||
#define CONFIG_TX4927BUG_WORKAROUND
|
#define CONFIG_TX4927BUG_WORKAROUND
|
||||||
#undef TX4927_SUPPORT_COMMAND_IO
|
#undef TX4927_SUPPORT_COMMAND_IO
|
||||||
|
|
|
@ -12,4 +12,7 @@ extern unsigned long mt_fpemul_threshold;
|
||||||
extern void mips_mt_regdump(unsigned long previous_mvpcontrol_value);
|
extern void mips_mt_regdump(unsigned long previous_mvpcontrol_value);
|
||||||
extern void mips_mt_set_cpuoptions(void);
|
extern void mips_mt_set_cpuoptions(void);
|
||||||
|
|
||||||
|
struct class;
|
||||||
|
extern struct class *mt_class;
|
||||||
|
|
||||||
#endif /* __ASM_MIPS_MT_H */
|
#endif /* __ASM_MIPS_MT_H */
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
*/
|
*/
|
||||||
struct sigcontext {
|
struct sigcontext {
|
||||||
unsigned int sc_regmask; /* Unused */
|
unsigned int sc_regmask; /* Unused */
|
||||||
unsigned int sc_status;
|
unsigned int sc_status; /* Unused */
|
||||||
unsigned long long sc_pc;
|
unsigned long long sc_pc;
|
||||||
unsigned long long sc_regs[32];
|
unsigned long long sc_regs[32];
|
||||||
unsigned long long sc_fpregs[32];
|
unsigned long long sc_fpregs[32];
|
||||||
|
@ -76,7 +76,7 @@ struct sigcontext {
|
||||||
|
|
||||||
struct sigcontext32 {
|
struct sigcontext32 {
|
||||||
__u32 sc_regmask; /* Unused */
|
__u32 sc_regmask; /* Unused */
|
||||||
__u32 sc_status;
|
__u32 sc_status; /* Unused */
|
||||||
__u64 sc_pc;
|
__u64 sc_pc;
|
||||||
__u64 sc_regs[32];
|
__u64 sc_regs[32];
|
||||||
__u64 sc_fpregs[32];
|
__u64 sc_fpregs[32];
|
||||||
|
|
|
@ -265,8 +265,6 @@ do { \
|
||||||
*/
|
*/
|
||||||
#define __get_user_asm_ll32(val, addr) \
|
#define __get_user_asm_ll32(val, addr) \
|
||||||
{ \
|
{ \
|
||||||
unsigned long long __gu_tmp; \
|
|
||||||
\
|
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"1: lw %1, (%3) \n" \
|
"1: lw %1, (%3) \n" \
|
||||||
"2: lw %D1, 4(%3) \n" \
|
"2: lw %D1, 4(%3) \n" \
|
||||||
|
@ -281,9 +279,8 @@ do { \
|
||||||
" " __UA_ADDR " 1b, 4b \n" \
|
" " __UA_ADDR " 1b, 4b \n" \
|
||||||
" " __UA_ADDR " 2b, 4b \n" \
|
" " __UA_ADDR " 2b, 4b \n" \
|
||||||
" .previous \n" \
|
" .previous \n" \
|
||||||
: "=r" (__gu_err), "=&r" (__gu_tmp) \
|
: "=r" (__gu_err), "=&r" (val) \
|
||||||
: "0" (0), "r" (addr), "i" (-EFAULT)); \
|
: "0" (0), "r" (addr), "i" (-EFAULT)); \
|
||||||
(val) = (__typeof__(*(addr))) __gu_tmp; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue