X86: Set up a space for a GDT in SE so we can set up TLS or LDT segments.
authorGabe Black <gblack@eecs.umich.edu>
Fri, 27 Feb 2009 17:23:17 +0000 (09:23 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Fri, 27 Feb 2009 17:23:17 +0000 (09:23 -0800)
src/arch/x86/process.cc
src/arch/x86/process.hh

index 232f07934040b71d6b8c5aced47ebb96ff7480f0..22030cbfa7aef95c6057c0e464f4bf278eafbcc4 100644 (file)
@@ -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.
index e337e589e7f5ce72edc540998ec6b3c7496ab53f..2d72d3fd0d109a1c29f31446a355135a6c31e882 100644 (file)
@@ -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);