diff --git a/sys/mips/include/proc.h b/sys/mips/include/proc.h index 6a0ce7dc0774..d09620a2d113 100644 --- a/sys/mips/include/proc.h +++ b/sys/mips/include/proc.h @@ -54,6 +54,7 @@ struct mdthread { int md_pc_count; /* performance counter */ int md_pc_spill; /* performance counter spill */ vm_offset_t md_realstack; + void *md_tls; }; /* md_flags */ diff --git a/sys/mips/include/sysarch.h b/sys/mips/include/sysarch.h index acb30713a469..350ad9583eec 100644 --- a/sys/mips/include/sysarch.h +++ b/sys/mips/include/sysarch.h @@ -35,16 +35,12 @@ #ifndef _MACHINE_SYSARCH_H_ #define _MACHINE_SYSARCH_H_ +#define MIPS_SET_TLS 1 +#define MIPS_GET_TLS 2 + #ifndef _KERNEL #include -#if 0 -/* Something useful for each MIPS platform. */ -#else -#define mips_tcb_set(tcb) do {} while (0) -#define mips_tcb_get() NULL -#endif /* _MIPS_ARCH_XLR */ - __BEGIN_DECLS int sysarch(int, void *); __END_DECLS diff --git a/sys/mips/include/ucontext.h b/sys/mips/include/ucontext.h index d9dfe4ea09f4..c28f08371c7a 100644 --- a/sys/mips/include/ucontext.h +++ b/sys/mips/include/ucontext.h @@ -53,6 +53,7 @@ typedef struct __mcontext { int mc_fpused; /* fp has been used */ f_register_t mc_fpregs[33]; /* fp regs 0 to 31 and csr */ register_t mc_fpc_eir; /* fp exception instruction reg */ + void *mc_tls; /* pointer to TLS area */ int __spare__[8]; /* XXX reserved */ } mcontext_t; #endif diff --git a/sys/mips/mips/genassym.c b/sys/mips/mips/genassym.c index 90974c7bcff5..2912ab10c626 100644 --- a/sys/mips/mips/genassym.c +++ b/sys/mips/mips/genassym.c @@ -69,6 +69,7 @@ ASSYM(TD_REALKSTACK, offsetof(struct thread, td_md.md_realstack)); ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); ASSYM(TD_LOCK, offsetof(struct thread, td_lock)); ASSYM(TD_FRAME, offsetof(struct thread, td_frame)); +ASSYM(TD_TLS, offsetof(struct thread, td_md.md_tls)); ASSYM(TF_REG_SR, offsetof(struct trapframe, sr)); diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 6bd518018e7c..7b2825714aa3 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -349,12 +349,6 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) pcpu->pc_asid_generation = 1; } -int -sysarch(struct thread *td, register struct sysarch_args *uap) -{ - return (ENOSYS); -} - int fill_dbregs(struct thread *td, struct dbreg *dbregs) { diff --git a/sys/mips/mips/pm_machdep.c b/sys/mips/mips/pm_machdep.c index 3c927521e0a5..097334756f4c 100644 --- a/sys/mips/mips/pm_machdep.c +++ b/sys/mips/mips/pm_machdep.c @@ -413,9 +413,16 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int flags) bcopy((void *)&td->td_frame->f0, (void *)&mcp->mc_fpregs, sizeof(mcp->mc_fpregs)); } + if (flags & GET_MC_CLEAR_RET) { + mcp->mc_regs[V0] = 0; + mcp->mc_regs[V1] = 0; + mcp->mc_regs[A3] = 0; + } + mcp->mc_pc = td->td_frame->pc; mcp->mullo = td->td_frame->mullo; mcp->mulhi = td->td_frame->mulhi; + mcp->mc_tls = td->td_md.md_tls; return (0); } @@ -436,6 +443,7 @@ set_mcontext(struct thread *td, const mcontext_t *mcp) td->td_frame->pc = mcp->mc_pc; td->td_frame->mullo = mcp->mullo; td->td_frame->mulhi = mcp->mulhi; + td->td_md.md_tls = mcp->mc_tls; /* Dont let user to set any bits in Status and casue registers */ return (0); diff --git a/sys/mips/mips/sys_machdep.c b/sys/mips/mips/sys_machdep.c new file mode 100644 index 000000000000..c316db33a722 --- /dev/null +++ b/sys/mips/mips/sys_machdep.c @@ -0,0 +1,77 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91 + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +#ifndef _SYS_SYSPROTO_H_ +struct sysarch_args { + int op; + char *parms; +}; +#endif + +int +sysarch(td, uap) + struct thread *td; + register struct sysarch_args *uap; +{ + int error; + void *tlsbase; + + switch (uap->op) { + case MIPS_SET_TLS : + td->td_md.md_tls = (void*)uap->parms; + error = 0; + break; + + case MIPS_GET_TLS : + tlsbase = td->td_md.md_tls; + error = copyout(&tlsbase, uap->parms, sizeof(tlsbase)); + break; + default: + error = EINVAL; + } + return (error); +} diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 08bb365d8766..9d39401119c3 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -156,6 +156,7 @@ cpu_fork(register struct thread *td1,register struct proc *p2, * that are needed. */ + td2->td_md.md_tls = td1->td_md.md_tls; td2->td_md.md_saved_intr = MIPS_SR_INT_IE; td2->td_md.md_spinlock_count = 1; #ifdef TARGET_OCTEON @@ -535,7 +536,7 @@ int cpu_set_user_tls(struct thread *td, void *tls_base) { - /* TBD */ + td->td_md.md_tls = tls_base; return (0); }