Date: Thu, 21 Jul 2016 08:46:34 -0700 From: Adrian Chadd <adrian@freebsd.org> To: "freebsd-mips@freebsd.org" <freebsd-mips@freebsd.org> Subject: Fwd: mips TLS! Message-ID: <CAJ-Vmo=EmjCeCqH2SiBkTwEwP5amUEJwmXp1Ve4S6-OXAS5E-Q@mail.gmail.com> In-Reply-To: <1289901750.3301205.1469111484769.JavaMail.yahoo@mail.yahoo.com> References: <CAJ-Vmokc2-7OekECAtbNKnpK25=cQ0=URuRrcwaR2VngfzTsxQ@mail.gmail.com> <D89FC2D9-37DB-4A91-BA4F-F44CCE7CD268@me.com> <CAJ-VmonHbK-Z1vGv-8XcWj4vb2R6OZPE5kGWFuPLc2eYE07iAQ@mail.gmail.com> <1166879717.1933909.1469073212661.JavaMail.yahoo@mail.yahoo.com> <CAJ-VmonFku%2BAect4fcq70e-A=rQKUjAa1J%2B7ubLA=dC7=-edzw@mail.gmail.com> <1289901750.3301205.1469111484769.JavaMail.yahoo@mail.yahoo.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
hi!
Stacey did up some TLS work for mips in 2014 but it never landed in
-HEAD. Dan updated it to compile/run for mips32, and the performance
improvements are great.
Does anyone have a mips64 system they can test this on? I'd like to
commit this soon. :)
Thanks!
-adrian
---------- Forwarded message ----------
From: Dan Nelson <dnelson_1901@yahoo.com>
Date: 21 July 2016 at 07:31
Subject: Re: mips TLS!
To: Adrian Chadd <adrian.chadd@gmail.com>
Cc: Stacey Son <sson@freebsd.org>, Robert Watson
<rwatson@freebsd.org>, Stacey Son <sson@me.com>
Oops - here they are. The benchmark numbers of course don't reflect
reflect the gains I saw in every program. I only picked ones that
were generating large amounts of syscalls. Some apps, like gcc,
managed to consume vast quantities of ram without needing TLS even
before patching.
________________________________
From: Adrian Chadd <adrian.chadd@gmail.com>
To: Dan Nelson <dnelson_1901@yahoo.com>
Cc: Stacey Son <sson@freebsd.org>; Robert Watson
<rwatson@freebsd.org>; Stacey Son <sson@me.com>
Sent: Thursday, July 21, 2016 12:10 AM
Subject: Re: mips TLS!
Woohoo!
Patches? :)
On Jul 20, 2016 8:54 PM, "Dan Nelson" <dnelson_1901@yahoo.com> wrote:
The TLS patches seem to be a success, after fixing a couple of
rejected patch blocks and fixing up some compile errors in the mips32
code. Tiny benchmark results:
>
>"sqlite3 /var/db/pkg/local.sqlite vacuum"
>total syscall count went from 570000 -> 117000
>20% reduction in user+sys cpu time (7.06 -> 5.66)
>
>"portupgrade -f doesntexist"
>total syscall count went from 3835000 -> 14000
>52% reduction in user+sys cpu time (25.3 -> 12.1)
>
>"du -s /usr/local"
>total syscall count went from 485000 -> 69400
>38% reduction in user+sys cpu time (5.08 -> 3.14)
>
>Raw numbers attached.
>
>
>
>________________________________
>From: Adrian Chadd <adrian.chadd@gmail.com>
>To: Stacey Son <sson@me.com>
>Cc: Stacey Son <sson@freebsd.org>; Robert Watson <rwatson@freebsd.org>; Dan Nelson <dnelson_1901@yahoo.com>
>Sent: Tuesday, July 19, 2016 8:00 PM
>Subject: Re: mips TLS!
>
>
>heh, dynamic patching always makes me itch. But, dtrace does it, right? :P
>
>Dan, let's give the TLS patches a go and see how well it works out. :)
>
>
>
>
>-a
[-- Attachment #2 --]
Index: sys/mips/include/cpufunc.h
===================================================================
--- sys/mips/include/cpufunc.h (revision 303126)
+++ sys/mips/include/cpufunc.h (working copy)
@@ -159,6 +159,7 @@ mips_wr_ ## n(uint64_t a0) \
MIPS_RW64_COP0(excpc, MIPS_COP_0_EXC_PC);
MIPS_RW64_COP0(entryhi, MIPS_COP_0_TLB_HI);
MIPS_RW64_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK);
+MIPS_RW64_COP0_SEL(userlocal, MIPS_COP_0_USERLOCAL, 2);
#ifdef CPU_CNMIPS
MIPS_RW64_COP0_SEL(cvmcount, MIPS_COP_0_COUNT, 6);
MIPS_RW64_COP0_SEL(cvmctl, MIPS_COP_0_COUNT, 7);
@@ -265,6 +266,7 @@ MIPS_RW32_COP0_SEL(cmgcrbase, 15, 3);
#if !defined(__mips_n64)
MIPS_RW32_COP0(entryhi, MIPS_COP_0_TLB_HI);
MIPS_RW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK);
+MIPS_RW32_COP0_SEL(userlocal, MIPS_COP_0_USERLOCAL, 2);
#endif
#ifdef CPU_NLM
MIPS_RW32_COP0_SEL(pagegrain, MIPS_COP_0_TLB_PG_MASK, 1);
@@ -289,6 +291,7 @@ MIPS_RW32_COP0_SEL(perfcnt0, MIPS_COP_0_PERFCNT, 0
MIPS_RW32_COP0_SEL(perfcnt1, MIPS_COP_0_PERFCNT, 1);
MIPS_RW32_COP0_SEL(perfcnt2, MIPS_COP_0_PERFCNT, 2);
MIPS_RW32_COP0_SEL(perfcnt3, MIPS_COP_0_PERFCNT, 3);
+MIPS_RW32_COP0(hwrena, MIPS_COP_0_HWRENA);
#undef MIPS_RW32_COP0
#undef MIPS_RW32_COP0_SEL
Index: sys/mips/include/cpuinfo.h
===================================================================
--- sys/mips/include/cpuinfo.h (revision 303126)
+++ sys/mips/include/cpuinfo.h (working copy)
@@ -58,6 +58,7 @@ struct mips_cpuinfo {
u_int16_t tlb_nentries;
u_int8_t icache_virtual;
boolean_t cache_coherent_dma;
+ boolean_t userlocal_reg;
struct {
u_int32_t ic_size;
u_int8_t ic_linesize;
Index: sys/mips/include/cpuregs.h
===================================================================
--- sys/mips/include/cpuregs.h (revision 303126)
+++ sys/mips/include/cpuregs.h (working copy)
@@ -454,9 +454,10 @@
* 2 MIPS_COP_0_TLB_LO0 .636 r4k TLB entry low.
* 3 MIPS_COP_0_TLB_LO1 .636 r4k TLB entry low, extended.
* 4 MIPS_COP_0_TLB_CONTEXT 3636 TLB Context.
+ * 4/2 MIPS_COP_0_USERLOCAL ..36 UserLocal.
* 5 MIPS_COP_0_TLB_PG_MASK .333 TLB Page Mask register.
* 6 MIPS_COP_0_TLB_WIRED .333 Wired TLB number.
- * 7 MIPS_COP_0_INFO ..33 Info registers
+ * 7 MIPS_COP_0_HWRENA ..33 rdHWR Enable.
* 8 MIPS_COP_0_BAD_VADDR 3636 Bad virtual address.
* 9 MIPS_COP_0_COUNT .333 Count register.
* 10 MIPS_COP_0_TLB_HI 3636 TLB entry high.
@@ -534,7 +535,8 @@
#define MIPS_COP_0_ERROR_PC _(30)
/* MIPS32/64 */
-#define MIPS_COP_0_INFO _(7)
+#define MIPS_COP_0_USERLOCAL _(4) /* sel 2 is userlevel register */
+#define MIPS_COP_0_HWRENA _(7)
#define MIPS_COP_0_DEBUG _(23)
#define MIPS_COP_0_DEPC _(24)
#define MIPS_COP_0_PERFCNT _(25)
@@ -548,11 +550,21 @@
#define MIPS_MMU_BAT 0x02 /* Standard BAT */
#define MIPS_MMU_FIXED 0x03 /* Standard fixed mapping */
-#define MIPS_CONFIG0_MT_MASK 0x00000380 /* bits 9..7 MMU Type */
-#define MIPS_CONFIG0_MT_SHIFT 7
-#define MIPS_CONFIG0_BE 0x00008000 /* data is big-endian */
-#define MIPS_CONFIG0_VI 0x00000008 /* instruction cache is virtual */
-
+/*
+ * Config Register Fields
+ * (See "MIPS Architecture for Programmers Volume III", MD00091, Table 9.39)
+ */
+#define MIPS_CONFIG0_M 0x80000000 /* Flag: Config1 is present. */
+#define MIPS_CONFIG0_MT_MASK 0x00000380 /* bits 9..7 MMU Type */
+#define MIPS_CONFIG0_MT_SHIFT 7
+#define MIPS_CONFIG0_BE 0x00008000 /* data is big-endian */
+#define MIPS_CONFIG0_VI 0x00000008 /* inst cache is virtual */
+
+/*
+ * Config1 Register Fields
+ * (See "MIPS Architecture for Programmers Volume III", MD00091, Table 9-1)
+ */
+#define MIPS_CONFIG1_M 0x80000000 /* Flag: Config2 is present. */
#define MIPS_CONFIG1_TLBSZ_MASK 0x7E000000 /* bits 30..25 # tlb entries minus one */
#define MIPS_CONFIG1_TLBSZ_SHIFT 25
@@ -586,6 +598,19 @@
#define MIPS_CONFIG3_CMGCR_MASK (1 << 29) /* Coherence manager present */
+/*
+ * Config2 Register Fields
+ * (See "MIPS Architecture for Programmers Volume III", MD00091, Table 9.40)
+ */
+#define MIPS_CONFIG2_M 0x80000000 /* Flag: Config3 is present. */
+
+/*
+ * Config3 Register Fields
+ * (See "MIPS Architecture for Programmers Volume III", MD00091, Table 9.41)
+ */
+#define MIPS_CONFIG3_M 0x80000000 /* Flag: Config4 is present */
+#define MIPS_CONFIG3_ULR 0x00002000 /* UserLocal reg implemented */
+
#define MIPS_CONFIG4_MMUSIZEEXT 0x000000FF /* bits 7.. 0 MMU Size Extension */
#define MIPS_CONFIG4_MMUEXTDEF 0x0000C000 /* bits 15.14 MMU Extension Definition */
#define MIPS_CONFIG4_MMUEXTDEF_MMUSIZEEXT 0x00004000 /* This values denotes CONFIG4 bits */
@@ -667,4 +692,15 @@
#define MIPS_CMGCRB_BASE 11
#define MIPS_CMGCRF_BASE (~((1 << MIPS_CMGCRB_BASE) - 1))
+/*
+ * Bits defined for for the HWREna (CP0 register 7, select 0).
+ */
+#define MIPS_HWRENA_CPUNUM (1<<0) /* CPU number program is running on */
+#define MIPS_HWRENA_SYNCI_STEP (1<<1) /* Address step sized used with SYNCI */
+#define MIPS_HWRENA_CC (1<<2) /* Hi Res cycle counter */
+#define MIPS_HWRENA_CCRES (1<<3) /* Cycle counter resolution */
+#define MIPS_HWRENA_UL (1<<29) /* UserLocal Register */
+#define MIPS_HWRENA_IMPL30 (1<<30) /* Implementation-dependent 30 */
+#define MIPS_HWRENA_IMPL31 (1<<31) /* Implementation-dependent 31 */
+
#endif /* _MIPS_CPUREGS_H_ */
Index: sys/mips/mips/cpu.c
===================================================================
--- sys/mips/mips/cpu.c (revision 303126)
+++ sys/mips/mips/cpu.c (working copy)
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/proc.h>
#include <sys/stdint.h>
#include <sys/bus.h>
@@ -49,6 +50,9 @@ __FBSDID("$FreeBSD$");
#include <machine/pte.h>
#include <machine/tlb.h>
#include <machine/hwfunc.h>
+#include <machine/mips_opcode.h>
+#include <machine/regnum.h>
+#include <machine/tls.h>
#if defined(CPU_CNMIPS)
#include <contrib/octeon-sdk/cvmx.h>
@@ -59,7 +63,64 @@ static void cpu_identify(void);
struct mips_cpuinfo cpuinfo;
+#define _ENCODE_INSN(a,b,c,d,e) \
+ ((uint32_t)(((a) << 26)|((b) << 21)|((c) << 16)|((d) << 11)|(e)))
+
+#if defined(__mips_n64)
+
+# define _LOAD_T0_MDTLS_A1 \
+ _ENCODE_INSN(OP_LD, A1, T0, 0, offsetof(struct thread, td_md.md_tls))
+
+# if defined(COMPAT_FREEBSD32)
+# define _ADDIU_V0_T0_TLS_OFFSET \
+ _ENCODE_INSN(OP_DADDIU, T0, V0, 0, (TLS_TP_OFFSET + TLS_TCB_SIZE32))
+# else
+# define _ADDIU_V0_T0_TLS_OFFSET \
+ _ENCODE_INSN(OP_DADDIU, T0, V0, 0, (TLS_TP_OFFSET + TLS_TCB_SIZE))
+# endif /* ! COMPAT_FREEBSD32 */
+
+# define _MTC0_V0_USERLOCAL \
+ _ENCODE_INSN(OP_COP0, OP_DMT, V0, 4, 2)
+
+#else /* mips 32 */
+
+# define _LOAD_T0_MDTLS_A1 \
+ _ENCODE_INSN(OP_LW, A1, T0, 0, offsetof(struct thread, td_md.md_tls))
+# define _ADDIU_V0_T0_TLS_OFFSET \
+ _ENCODE_INSN(OP_ADDIU, T0, V0, 0, (TLS_TP_OFFSET + TLS_TCB_SIZE))
+# define _MTC0_V0_USERLOCAL \
+ _ENCODE_INSN(OP_COP0, OP_MT, V0, 4, 2)
+
+#endif /* ! __mips_n64 */
+
+#define _JR_RA _ENCODE_INSN(OP_SPECIAL, RA, 0, 0, OP_JR)
+#define _NOP 0
+
/*
+ * Patch cpu_switch() by removing the UserLocal register code at the end.
+ * For MIPS hardware that don't support UserLocal Register Implementation
+ * we remove the instructions that update this register which may cause a
+ * reserved instruction exception in the kernel.
+ */
+static void
+remove_userlocal_code(uint32_t *cpu_switch_code)
+{
+ uint32_t *instructp;
+
+ for (instructp = cpu_switch_code;; instructp++) {
+ if (instructp[0] == _JR_RA)
+ panic("%s: Unable to patch cpu_switch().", __func__);
+ if (instructp[0] == _LOAD_T0_MDTLS_A1 &&
+ instructp[1] == _ADDIU_V0_T0_TLS_OFFSET &&
+ instructp[2] == _MTC0_V0_USERLOCAL) {
+ instructp[0] = _JR_RA;
+ instructp[1] = _NOP;
+ break;
+ }
+ }
+}
+
+/*
* Attempt to identify the MIPS CPU as much as possible.
*
* XXX: Assumes the CPU is MIPS{32,64}{,r2} compliant.
@@ -73,9 +134,8 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo)
u_int32_t prid;
u_int32_t cfg0;
u_int32_t cfg1;
-#ifndef CPU_CNMIPS
u_int32_t cfg2;
-#endif
+ u_int32_t cfg3;
#if defined(CPU_CNMIPS)
u_int32_t cfg4;
#endif
@@ -96,13 +156,36 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo)
((cfg0 & MIPS_CONFIG0_MT_MASK) >> MIPS_CONFIG0_MT_SHIFT);
cpuinfo->icache_virtual = cfg0 & MIPS_CONFIG0_VI;
- /* If config register selection 1 does not exist, exit. */
- if (!(cfg0 & MIPS_CONFIG_CM))
+ /* If config register selection 1 does not exist, return. */
+ if (!(cfg0 & MIPS_CONFIG0_M))
return;
/* Learn TLB size and L1 cache geometry. */
cfg1 = mips_rd_config1();
+ /* Get the Config2 and Config3 registers as well. */
+ if (cfg1 & MIPS_CONFIG1_M) {
+ cfg2 = mips_rd_config2();
+ if (cfg2 & MIPS_CONFIG2_M)
+ cfg3 = mips_rd_config3();
+ }
+
+ /* Check to see if UserLocal register is implemented. */
+ if (cfg3 & MIPS_CONFIG3_ULR) {
+ /* UserLocal register is implemented, enable it. */
+ cpuinfo->userlocal_reg = true;
+ tmp = mips_rd_hwrena();
+ mips_wr_hwrena(tmp | MIPS_HWRENA_UL);
+ } else {
+ /*
+ * UserLocal register is not implemented. Patch
+ * cpu_switch() and remove unsupported code.
+ */
+ cpuinfo->userlocal_reg = false;
+ remove_userlocal_code((uint32_t *)cpu_switch);
+ }
+
+
#if defined(CPU_NLM)
/* Account for Extended TLB entries in XLP */
tmp = mips_rd_config6();
@@ -387,7 +470,7 @@ cpu_identify(void)
/* Print Config3 if it contains any useful info */
if (cfg3 & ~(0x80000000))
- printf(" Config3=0x%b\n", cfg3, "\20\2SmartMIPS\1TraceLogic");
+ printf(" Config3=0x%b\n", cfg3, "\20\14ULRI\2SmartMIPS\1TraceLogic");
}
static struct rman cpu_hardirq_rman;
Index: sys/mips/mips/genassym.c
===================================================================
--- sys/mips/mips/genassym.c (revision 303126)
+++ sys/mips/mips/genassym.c (working copy)
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <machine/pcb.h>
#include <machine/sigframe.h>
#include <machine/proc.h>
+#include <machine/tls.h>
#ifdef CPU_CNMIPS
#include <machine/octeon_cop2.h>
@@ -72,7 +73,14 @@ ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack
ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
ASSYM(TD_MDFLAGS, offsetof(struct thread, td_md.md_flags));
+ASSYM(TD_MDTLS, offsetof(struct thread, td_md.md_tls));
+#if defined(__mips_n64) && defined(COMPAT_FREEBSD32)
+ASSYM(TLS_TCB_OFFSET, (TLS_TP_OFFSET + TLS_TCB_SIZE32));
+#else
+ASSYM(TLS_TCB_OFFSET, (TLS_TP_OFFSET + TLS_TCB_SIZE));
+#endif
+
ASSYM(U_PCB_REGS, offsetof(struct pcb, pcb_regs.zero));
ASSYM(U_PCB_CONTEXT, offsetof(struct pcb, pcb_context));
ASSYM(U_PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
Index: sys/mips/mips/swtch.S
===================================================================
--- sys/mips/mips/swtch.S (revision 303126)
+++ sys/mips/mips/swtch.S (working copy)
@@ -358,6 +358,7 @@ sw2:
* Restore registers and return.
*/
move a0, s0
+ move a1, s7
RESTORE_U_PCB_CONTEXT(gp, PCB_REG_GP, a0)
RESTORE_U_PCB_CONTEXT(v0, PCB_REG_SR, a0) # restore kernel context
RESTORE_U_PCB_CONTEXT(ra, PCB_REG_RA, a0)
@@ -377,6 +378,15 @@ sw2:
or v0, v0, t0
mtc0 v0, MIPS_COP_0_STATUS
ITLBNOPFIX
+/*
+ * Set the new thread's TLS pointer.
+ *
+ * Note that this code is removed if the CPU doesn't support ULRI by
+ * remove_userlocal_code() in cpu.c.
+ */
+ PTR_L t0, TD_MDTLS(a1) # Get TLS pointer
+ PTR_ADDIU v0, t0, TLS_TCB_OFFSET # Add TLS/TCB offset
+ MTC0 v0, MIPS_COP_0_USERLOCAL, 2 # write it to ULR for rdhwr
j ra
nop
Index: sys/mips/mips/sys_machdep.c
===================================================================
--- sys/mips/mips/sys_machdep.c (revision 303126)
+++ sys/mips/mips/sys_machdep.c (working copy)
@@ -39,7 +39,11 @@ __FBSDID("$FreeBSD$");
#include <sys/syscall.h>
#include <sys/sysent.h>
+#include <machine/cpufunc.h>
+#include <machine/cpuinfo.h>
#include <machine/sysarch.h>
+#include <machine/cpuregs.h>
+#include <machine/tls.h>
#ifndef _SYS_SYSPROTO_H_
struct sysarch_args {
@@ -57,6 +61,22 @@ sysarch(struct thread *td, struct sysarch_args *ua
switch (uap->op) {
case MIPS_SET_TLS:
td->td_md.md_tls = uap->parms;
+
+ /*
+ * If there is an user local register implementation (ULRI)
+ * update it as well. Add the TLS and TCB offsets so the
+ * value in this register is adjusted like in the case of the
+ * rdhwr trap() instruction handler.
+ */
+ if (cpuinfo.userlocal_reg == true) {
+#if defined(__mips_n64) && defined(COMPAT_FREEBSD32)
+ mips_wr_userlocal((unsigned long)(uap->parms +
+ TLS_TP_OFFSET + TLS_TCB_SIZE32));
+#else
+ mips_wr_userlocal((unsigned long)(uap->parms +
+ TLS_TP_OFFSET + TLS_TCB_SIZE));
+#endif
+ }
return (0);
case MIPS_GET_TLS:
tlsbase = td->td_md.md_tls;
Index: sys/mips/mips/vm_machdep.c
===================================================================
--- sys/mips/mips/vm_machdep.c (revision 303126)
+++ sys/mips/mips/vm_machdep.c (working copy)
@@ -60,8 +60,11 @@ __FBSDID("$FreeBSD$");
#include <machine/cache.h>
#include <machine/clock.h>
#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/cpuinfo.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
+#include <machine/tls.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -492,6 +495,15 @@ cpu_set_user_tls(struct thread *td, void *tls_base
{
td->td_md.md_tls = (char*)tls_base;
+ if (td == curthread && cpuinfo.userlocal_reg == true) {
+#if defined(__mips_n64) && defined(COMPAT_FREEBSD32)
+ mips_wr_userlocal((unsigned long)tls_base + TLS_TP_OFFSET +
+ TLS_TCB_SIZE32);
+#else
+ mips_wr_userlocal((unsigned long)tls_base + TLS_TP_OFFSET +
+ TLS_TCB_SIZE);
+#endif
+ }
return (0);
}
[-- Attachment #3 --]
Index: lib/libthr/arch/mips/include/pthread_md.h
===================================================================
--- lib/libthr/arch/mips/include/pthread_md.h (revision 303126)
+++ lib/libthr/arch/mips/include/pthread_md.h (working copy)
@@ -61,6 +61,7 @@ _tcb_set(struct tcb *tcb)
/*
* Get the current tcb.
*/
+#ifdef TLS_USE_SYSARCH
static __inline struct tcb *
_tcb_get(void)
{
@@ -70,6 +71,55 @@ _tcb_get(void)
return tcb;
}
+#else /* ! TLS_USE_SYSARCH */
+
+# if defined(__mips_n64)
+static __inline struct tcb *
+_tcb_get(void)
+{
+ uint64_t _rv;
+
+ __asm__ __volatile__ (
+ ".set\tpush\n\t"
+ ".set\tmips64r2\n\t"
+ "rdhwr\t%0, $29\n\t"
+ ".set\tpop"
+ : "=v" (_rv));
+
+ /*
+ * XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317'
+ *
+ * Remove the offset since this really a request to get the TLS
+ * pointer via sysarch() (in theory). Of course, this may go away
+ * once the TLS code is rewritten.
+ */
+ return (struct tcb *)(_rv - TLS_TP_OFFSET - TLS_TCB_SIZE);
+}
+# else /* mips 32 */
+static __inline struct tcb *
+_tcb_get(void)
+{
+ uint32_t _rv;
+
+ __asm__ __volatile__ (
+ ".set\tpush\n\t"
+ ".set\tmips32r2\n\t"
+ "rdhwr\t%0, $29\n\t"
+ ".set\tpop"
+ : "=v" (_rv));
+
+ /*
+ * XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317'
+ *
+ * Remove the offset since this really a request to get the TLS
+ * pointer via sysarch() (in theory). Of course, this may go away
+ * once the TLS code is rewritten.
+ */
+ return (struct tcb *)(_rv - TLS_TP_OFFSET - TLS_TCB_SIZE);
+}
+# endif /* ! __mips_n64 */
+#endif /* ! TLS_USE_SYSARCH */
+
extern struct pthread *_thr_initial;
static __inline struct pthread *
Index: libexec/rtld-elf/mips/reloc.c
===================================================================
--- libexec/rtld-elf/mips/reloc.c (revision 303126)
+++ libexec/rtld-elf/mips/reloc.c (working copy)
@@ -634,13 +634,67 @@ allocate_initial_tls(Obj_Entry *objs)
sysarch(MIPS_SET_TLS, tls);
}
+#ifdef __mips_n64
void *
+_mips_get_tls(void)
+{
+ uint64_t _rv;
+
+ __asm__ __volatile__ (
+ ".set\tpush\n\t"
+ ".set\tmips64r2\n\t"
+ "rdhwr\t%0, $29\n\t"
+ ".set\tpop"
+ : "=v" (_rv));
+ /*
+ * XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317'
+ *
+ * Remove the offset since this really a request to get the TLS
+ * pointer via sysarch() (in theory). Of course, this may go away
+ * once the TLS code is rewritten.
+ */
+ _rv = _rv - TLS_TP_OFFSET - TLS_TCB_SIZE;
+
+ return (void *)_rv;
+}
+
+#else /* mips 32 */
+
+void *
+_mips_get_tls(void)
+{
+ uint32_t _rv;
+
+ __asm__ __volatile__ (
+ ".set\tpush\n\t"
+ ".set\tmips32r2\n\t"
+ "rdhwr\t%0, $29\n\t"
+ ".set\tpop"
+ : "=v" (_rv));
+ /*
+ * XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317'
+ *
+ * Remove the offset since this really a request to get the TLS
+ * pointer via sysarch() (in theory). Of course, this may go away
+ * once the TLS code is rewritten.
+ */
+ _rv = _rv - TLS_TP_OFFSET - TLS_TCB_SIZE;
+
+ return (void *)_rv;
+}
+#endif /* ! __mips_n64 */
+
+void *
__tls_get_addr(tls_index* ti)
{
Elf_Addr** tls;
char *p;
+#ifdef TLS_USE_SYSARCH
sysarch(MIPS_GET_TLS, &tls);
+#else
+ tls = _mips_get_tls();
+#endif
p = tls_get_addr_common(tls, ti->ti_module, ti->ti_offset + TLS_DTP_OFFSET);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-Vmo=EmjCeCqH2SiBkTwEwP5amUEJwmXp1Ve4S6-OXAS5E-Q>
