Date: Wed, 8 Dec 2010 17:34:00 +0100 From: Robert Millan <rmh@debian.org> To: freebsd-mips@freebsd.org Subject: [PATCH] Retrieval of TLS pointer via RDHWR Message-ID: <AANLkTimg3CUk0p8YPyepiumEHvKo2F6jdVA0=1CefYrQ@mail.gmail.com>
index | next in thread | raw e-mail
[-- Attachment #1 --]
This patch implements support for retrieving the TLS pointer via RDHWR
instruction.
It is implemented through emulation for platforms that don't provide
this instruction natively (such as gxemul/malta). Platforms that do
provide it would need a separate patch.
Reading register $29 with RDHWR is becoming the de-facto standard to
implement TLS. According to linux-mips wiki, MIPS Technologies has
reserved hardware register $29 for ABI use. Furthermore current GCC [1]
makes the following assumptions:
- RDHWR is natively available or otherwise emulated by the kernel
- Register $29 holds the TLS pointer
[1] gcc-4.4.4/gcc/config/mips/mips.md reads:
;; The TLS base pointer is accessed via "rdhwr $3, $29". No current
;; MIPS architecture defines this register, and no current
;; implementation provides it; instead, any OS which supports TLS is
;; expected to trap and emulate this instruction. rdhwr is part of the
;; MIPS 32r2 specification, but we use it on any architecture because
;; we expect it to be emulated.
--
Robert Millan
[-- Attachment #2 --]
Index: mips/include/mips_opcode.h
===================================================================
--- mips/include/mips_opcode.h (revision 216299)
+++ mips/include/mips_opcode.h (working copy)
@@ -176,6 +176,11 @@
#define OP_LDL 032
#define OP_LDR 033
+#define OP_SPECIAL2 034
+#define OP_JALX 035
+
+#define OP_SPECIAL3 037
+
#define OP_LB 040
#define OP_LH 041
#define OP_LWL 042
@@ -389,6 +394,11 @@
#define OP_R_BGEZALL OP_BGEZALL
/*
+ * Values for the 'func' field when 'op' == OP_SPECIAL3.
+ */
+#define OP_RDHWR 073
+
+/*
* Values for the 'rs' field when 'op' == OP_COPz.
*/
#define OP_MF 000
Index: mips/mips/trap.c
===================================================================
--- mips/mips/trap.c (revision 216299)
+++ mips/mips/trap.c (working copy)
@@ -824,9 +824,26 @@
}
case T_RES_INST + T_USER:
- log_illegal_instruction("RES_INST", trapframe);
- i = SIGILL;
- addr = trapframe->pc;
+ {
+ register_t inst = *((register_t *) trapframe->pc);
+ switch (MIPS_INST_OPCODE(inst)) {
+ case OP_SPECIAL3:
+ switch (MIPS_INST_FUNC(inst)) {
+ case OP_RDHWR:
+ /* Register 29 used for TLS */
+ if (MIPS_INST_RD(inst) == 29) {
+ ((register_t *) trapframe)[MIPS_INST_RT(inst)] = td->td_md.md_tls;
+ trapframe->pc += sizeof(int);
+ goto out;
+ }
+ break;
+ }
+ break;
+ }
+ log_illegal_instruction("RES_INST", trapframe);
+ i = SIGILL;
+ addr = trapframe->pc;
+ }
break;
case T_C2E:
case T_C2E + T_USER:
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTimg3CUk0p8YPyepiumEHvKo2F6jdVA0=1CefYrQ>
