summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-12-31 15:30:50 -0500
committerGabe Black <gblack@eecs.umich.edu>2009-12-31 15:30:50 -0500
commitd3ed32b989b9be65805290c931739096786b39ce (patch)
treea1d7ea44f4bdf1ad712c6e3b21a0d38756ebfd9c
parentcc07dcf02654267227d9de6ae0898d39d5ea5438 (diff)
downloadgem5-d3ed32b989b9be65805290c931739096786b39ce.tar.xz
MIPS: Create an artificial control register to hold the thread pointer.
In Linux, the set_thread_area system call stores the address of the thread local storage area into a field of the current thread_info structure. Later, to access that value, the program uses the rdhwr instruction to read a "hardware register" with index 29. The 64 bit MIPS manual, volume II, says that index 29 is reserved for a future ABI extension and should cause a "Reserved Instruction Exception". In Linux (and potentially other ISAs) that exception is trapped and emulated to return the value stored by set_thread_area as if that were actually stored by a physical register. The tp_value address (as named in the Linux kernel) is ironically stored as a control register so that it goes with a particular ThreadContext. Syscall emulation will use that to emulate storing to the OS's thread info structure, and rdhwr will emulate faulting and returning that value from software by returning the value itself, as if it was in hardware. In other words, we fake faking the register in SE mode. In an FS mode implementation it should work as specified in the manual.
-rw-r--r--src/arch/mips/isa/operands.isa5
-rw-r--r--src/arch/mips/registers.hh1
2 files changed, 5 insertions, 1 deletions
diff --git a/src/arch/mips/isa/operands.isa b/src/arch/mips/isa/operands.isa
index 50726cd30..27cb4357a 100644
--- a/src/arch/mips/isa/operands.isa
+++ b/src/arch/mips/isa/operands.isa
@@ -109,8 +109,11 @@ def operands {{
#LL Flag
'LLFlag': ('ControlReg', 'uw', 'MISCREG_LLFLAG', None, 1),
+ #Thread pointer value for SE mode
+ 'TpValue': ('ControlReg', 'ud', 'MISCREG_TP_VALUE', None, 1),
+
# Index Register
- 'Index':('ControlReg','uw','MISCREG_INDEX',None,1),
+ 'Index': ('ControlReg','uw','MISCREG_INDEX',None,1),
'CP0_RD_SEL': ('ControlReg', 'uw', '(RD << 3 | SEL)', None, 1),
diff --git a/src/arch/mips/registers.hh b/src/arch/mips/registers.hh
index fdb04b131..5cf76634d 100644
--- a/src/arch/mips/registers.hh
+++ b/src/arch/mips/registers.hh
@@ -275,6 +275,7 @@ enum MiscRegIndex{
MISCREG_DESAVE = 248, //Bank 31: 248-256
MISCREG_LLFLAG = 257,
+ MISCREG_TP_VALUE,
MISCREG_NUMREGS
};