summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-02-27 09:23:17 -0800
committerGabe Black <gblack@eecs.umich.edu>2009-02-27 09:23:17 -0800
commite23d688d8f7e728e694f15752cd70df84bc4ae67 (patch)
tree36d6f7eb00444b18141c51bcf2b079de48ca9106
parent281ef8111a15e8501cee03fdf35e0c41437518e2 (diff)
downloadgem5-e23d688d8f7e728e694f15752cd70df84bc4ae67.tar.xz
X86: Set up a space for a GDT in SE so we can set up TLS or LDT segments.
-rw-r--r--src/arch/x86/process.cc18
-rw-r--r--src/arch/x86/process.hh9
2 files changed, 27 insertions, 0 deletions
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index 232f07934..22030cbfa 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -251,6 +251,20 @@ I386LiveProcess::startup()
argsInit(sizeof(uint32_t), VMPageSize);
+ /*
+ * Set up a GDT for this process. The whole GDT wouldn't really be for
+ * this process, but the only parts we care about are.
+ */
+ _gdtStart = stack_base;
+ _gdtSize = VMPageSize;
+ pTable->allocate(_gdtStart, _gdtSize);
+ uint64_t zero = 0;
+ assert(_gdtSize % sizeof(zero) == 0);
+ for (Addr gdtCurrent = _gdtStart;
+ gdtCurrent < _gdtStart + _gdtSize; gdtCurrent += sizeof(zero)) {
+ initVirtMem->write(gdtCurrent, zero);
+ }
+
for (int i = 0; i < contextIds.size(); i++) {
ThreadContext * tc = system->getThreadContext(contextIds[i]);
@@ -281,6 +295,10 @@ I386LiveProcess::startup()
tc->setMiscRegNoEffect(MISCREG_CS_ATTR, csAttr);
+ tc->setMiscRegNoEffect(MISCREG_TSG_BASE, _gdtStart);
+ tc->setMiscRegNoEffect(MISCREG_TSG_EFF_BASE, _gdtStart);
+ tc->setMiscRegNoEffect(MISCREG_TSG_LIMIT, _gdtStart + _gdtSize - 1);
+
//Set up the registers that describe the operating mode.
CR0 cr0 = 0;
cr0.pg = 1; // Turn on paging.
diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh
index e337e589e..2d72d3fd0 100644
--- a/src/arch/x86/process.hh
+++ b/src/arch/x86/process.hh
@@ -70,6 +70,9 @@ namespace X86ISA
class X86LiveProcess : public LiveProcess
{
protected:
+ Addr _gdtStart;
+ Addr _gdtSize;
+
SyscallDesc *syscallDescs;
const int numSyscallDescs;
@@ -80,6 +83,12 @@ namespace X86ISA
void argsInit(int pageSize);
public:
+ Addr gdtStart()
+ { return _gdtStart; }
+
+ Addr gdtSize()
+ { return _gdtSize; }
+
SyscallDesc* getDesc(int callnum);
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);