svn commit: r231312 - in head/sys/mips: include mips
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Thu Feb 9 22:17:14 UTC 2012
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 at 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:
More information about the svn-src-head
mailing list