X86: Separate the effective seg base and the "hidden" seg base.
authorGabe Black <gblack@eecs.umich.edu>
Sun, 2 Dec 2007 07:00:15 +0000 (23:00 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Sun, 2 Dec 2007 07:00:15 +0000 (23:00 -0800)
--HG--
extra : convert_revision : 5fcb8d94dbab7a7d6fe797277a5856903c885ad4

src/arch/x86/isa/operands.isa
src/arch/x86/linux/syscalls.cc
src/arch/x86/miscregfile.cc
src/arch/x86/miscregs.hh
src/arch/x86/process.cc
src/arch/x86/utility.cc

index f50e71727b19a344f5aec010a5ae11fe9353b10c..7a2631a9c94379fd322fdb44f20026b15f9f3137 100644 (file)
@@ -121,11 +121,11 @@ def operands {{
         # The TOP register should needs to be more protected so that later
         # instructions don't map their indexes with an old value.
         'TOP':           ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 61),
-        'SegBase':       ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70),
+        'SegBase':       ('ControlReg', 'uqw', 'MISCREG_SEG_EFF_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70),
         'ControlDest':   ('ControlReg', 'uqw', 'MISCREG_CR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 71),
         'ControlSrc1':   ('ControlReg', 'uqw', 'MISCREG_CR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 72),
         'EferOp':        ('ControlReg', 'uqw', 'MISCREG_EFER', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 73),
         'CR4Op':         ('ControlReg', 'uqw', 'MISCREG_CR4', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 74),
-        'CSBase':        ('ControlReg', 'udw', 'MISCREG_CS_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 80),
+        'CSBase':        ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 80),
         'Mem':           ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
 }};
index c6b2fbb66955fd853519eceac86f73e78035f867..ae2ac243baaf70c2e737b4d8327bbb678b55923d 100644 (file)
@@ -103,6 +103,7 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
       //Each of these valid options should actually check addr.
       case SetFS:
         tc->setMiscRegNoEffect(MISCREG_FS_BASE, addr);
+        tc->setMiscRegNoEffect(MISCREG_FS_EFF_BASE, addr);
         return 0;
       case GetFS:
         fsBase = tc->readMiscRegNoEffect(MISCREG_FS_BASE);
@@ -110,6 +111,7 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
         return 0;
       case SetGS:
         tc->setMiscRegNoEffect(MISCREG_GS_BASE, addr);
+        tc->setMiscRegNoEffect(MISCREG_GS_EFF_BASE, addr);
         return 0;
       case GetGS:
         gsBase = tc->readMiscRegNoEffect(MISCREG_GS_BASE);
index 71908098e492a7c4924eeadc746df4381ac361ed..a019024783b09388849927b3fc70e759c631917c 100644 (file)
@@ -186,6 +186,25 @@ void MiscRegFile::setReg(int miscReg,
         break;
       case MISCREG_CR8:
         break;
+      case MISCREG_CS_ATTR:
+        {
+            SegAttr toggled = regVal[miscReg] ^ val;
+            SegAttr newCSAttr = val;
+            if (toggled.longMode) {
+                SegAttr newCSAttr = val;
+                if (newCSAttr.longMode) {
+                    regVal[MISCREG_ES_EFF_BASE] = 0;
+                    regVal[MISCREG_CS_EFF_BASE] = 0;
+                    regVal[MISCREG_SS_EFF_BASE] = 0;
+                    regVal[MISCREG_DS_EFF_BASE] = 0;
+                } else {
+                    regVal[MISCREG_ES_EFF_BASE] = regVal[MISCREG_ES_BASE];
+                    regVal[MISCREG_CS_EFF_BASE] = regVal[MISCREG_CS_BASE];
+                    regVal[MISCREG_SS_EFF_BASE] = regVal[MISCREG_SS_BASE];
+                    regVal[MISCREG_DS_EFF_BASE] = regVal[MISCREG_DS_BASE];
+                }
+            }
+        }
     }
     setRegNoEffect(miscReg, newVal);
 }
index 3a30b98002a8347f6483a5fcb5aafc5029eda3ef..d3960073a433e7ee8dd29a4b0106780aaf4b27ef 100644 (file)
@@ -270,8 +270,20 @@ namespace X86ISA
         MISCREG_GS_BASE,
         MISCREG_INT_BASE,
 
+        // The effective segment base, ie what is actually added to an
+        // address. In 64 bit mode this can be different from the above,
+        // namely 0.
+        MISCREG_SEG_EFF_BASE_BASE = MISCREG_SEG_BASE_BASE + NumSegments,
+        MISCREG_ES_EFF_BASE = MISCREG_SEG_EFF_BASE_BASE,
+        MISCREG_CS_EFF_BASE,
+        MISCREG_SS_EFF_BASE,
+        MISCREG_DS_EFF_BASE,
+        MISCREG_FS_EFF_BASE,
+        MISCREG_GS_EFF_BASE,
+        MISCREG_INT_EFF_BASE,
+
         // Hidden segment limit field
-        MISCREG_SEG_LIMIT_BASE = MISCREG_SEG_BASE_BASE + NumSegments,
+        MISCREG_SEG_LIMIT_BASE = MISCREG_SEG_EFF_BASE_BASE + NumSegments,
         MISCREG_ES_LIMIT = MISCREG_SEG_LIMIT_BASE,
         MISCREG_CS_LIMIT,
         MISCREG_SS_LIMIT,
@@ -406,6 +418,12 @@ namespace X86ISA
         return (MiscRegIndex)(MISCREG_SEG_BASE_BASE + index);
     }
 
+    static inline MiscRegIndex
+    MISCREG_SEG_EFF_BASE(int index)
+    {
+        return (MiscRegIndex)(MISCREG_SEG_EFF_BASE_BASE + index);
+    }
+
     static inline MiscRegIndex
     MISCREG_SEG_LIMIT(int index)
     {
index 633b2f13611a2f3ecd495dbffd86b5783d472cf7..76f0b5d04c14268a78be45ad455a25be6788e8c5 100644 (file)
@@ -160,6 +160,7 @@ X86LiveProcess::startup()
         //Initialize the segment registers.
         for(int seg = 0; seg < NUM_SEGMENTREGS; seg++) {
             tc->setMiscRegNoEffect(MISCREG_SEG_BASE(seg), 0);
+            tc->setMiscRegNoEffect(MISCREG_SEG_EFF_BASE(seg), 0);
             tc->setMiscRegNoEffect(MISCREG_SEG_ATTR(seg), dataAttr);
         }
 
index 0153f10e0b9061011bc63ea2a61cd6e99f272c3a..69179c1f4540c7f02c2cb3ae41be53d91ae3d298 100644 (file)
@@ -118,6 +118,7 @@ void initCPU(ThreadContext *tc, int cpuId)
     for (int seg = 0; seg != NUM_SEGMENTREGS; seg++) {
         tc->setMiscReg(MISCREG_SEG_SEL(seg), 0);
         tc->setMiscReg(MISCREG_SEG_BASE(seg), 0);
+        tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), 0);
         tc->setMiscReg(MISCREG_SEG_LIMIT(seg), 0xffff);
         tc->setMiscReg(MISCREG_SEG_ATTR(seg), dataAttr);
     }
@@ -130,7 +131,10 @@ void initCPU(ThreadContext *tc, int cpuId)
     codeAttr.defaultSize = 0;
 
     tc->setMiscReg(MISCREG_CS, 0xf000);
-    tc->setMiscReg(MISCREG_CS_BASE, 0x00000000ffff0000ULL);
+    tc->setMiscReg(MISCREG_CS_BASE,
+            0x00000000ffff0000ULL);
+    tc->setMiscReg(MISCREG_CS_EFF_BASE,
+            0x00000000ffff0000ULL);
     // This has the base value pre-added.
     tc->setMiscReg(MISCREG_CS_LIMIT, 0xffffffff);
     tc->setMiscReg(MISCREG_CS_ATTR, codeAttr);