Skip site navigation (1)Skip section navigation (2)
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>