Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Feb 2012 22:17:14 +0000 (UTC)
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r231312 - in head/sys/mips: include mips
Message-ID:  <201202092217.q19MHEuU039370@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gonzo
Date: Thu Feb  9 22:17:13 2012
New Revision: 231312
URL: http://svn.freebsd.org/changeset/base/231312

Log:
  - Emulate RDHWR instruction for TLS support
  
  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
  makes the following assumptions:
  - RDHWR is natively available or otherwise emulated by the kernel
  - Register $29 holds the TLS pointer
  
  Submitted by:	Robert Millan <rmh@debian.org>

Modified:
  head/sys/mips/include/mips_opcode.h
  head/sys/mips/mips/trap.c

Modified: head/sys/mips/include/mips_opcode.h
==============================================================================
--- head/sys/mips/include/mips_opcode.h	Thu Feb  9 22:13:20 2012	(r231311)
+++ head/sys/mips/include/mips_opcode.h	Thu Feb  9 22:17:13 2012	(r231312)
@@ -176,6 +176,11 @@ typedef union {
 #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 @@ typedef union {
 #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

Modified: head/sys/mips/mips/trap.c
==============================================================================
--- head/sys/mips/mips/trap.c	Thu Feb  9 22:13:20 2012	(r231311)
+++ head/sys/mips/mips/trap.c	Thu Feb  9 22:17:13 2012	(r231312)
@@ -414,6 +414,7 @@ trap(struct trapframe *trapframe)
 	intptr_t addr = 0;
 	register_t pc;
 	int cop;
+	register_t *frame_regs;
 
 	trapdebug_enter(trapframe, 0);
 	
@@ -762,9 +763,29 @@ dofault:
 		}
 
 	case T_RES_INST + T_USER:
-		log_illegal_instruction("RES_INST", trapframe);
-		i = SIGILL;
-		addr = trapframe->pc;
+		{
+			InstFmt inst;
+			inst = *(InstFmt *)trapframe->pc;
+			switch (inst.RType.op) {
+			case OP_SPECIAL3:
+				switch (inst.RType.func) {
+				case OP_RDHWR:
+					/* Register 29 used for TLS */
+					if (inst.RType.rd == 29) {
+						frame_regs = &(trapframe->zero);
+						frame_regs[inst.RType.rt] = (register_t)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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202092217.q19MHEuU039370>