mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
- 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>
This commit is contained in:
parent
0bdc3ecf11
commit
2675d18f77
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=231312
@ -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
|
||||
@ -388,6 +393,11 @@ typedef union {
|
||||
#define OP_R_BLTZALL OP_BLTZALL
|
||||
#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.
|
||||
*/
|
||||
|
@ -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 @@ trap(struct trapframe *trapframe)
|
||||
}
|
||||
|
||||
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:
|
||||
|
Loading…
Reference in New Issue
Block a user