X86: Fix address size handling so real mode works properly.
authorGabe Black <gblack@eecs.umich.edu>
Sat, 31 Mar 2012 19:27:33 +0000 (12:27 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Sat, 31 Mar 2012 19:27:33 +0000 (12:27 -0700)
Virtual (pre-segmentation) addresses are truncated based on address size, and
any non-64 bit linear address is truncated to 32 bits. This means that real
mode addresses aren't truncated down to 16 bits after their segment bases are
added in.

src/arch/x86/isa/microops/ldstop.isa
src/arch/x86/tlb.cc

index 8bcf55c995958e75d5fe5d5ac2e15a495bb5f283..75519f417c5b185659e31927cdd0b9e63e9688a5 100644 (file)
@@ -361,7 +361,7 @@ let {{
     exec_output = ""
 
     calculateEA = '''
-    EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0);
+    EA = SegBase + bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
     '''
 
     def defineMicroLoadOp(mnemonic, code, bigCode='',
index 89561f8515c46955093207be81e2546df4a8515c..100f8cf0f76ff85c833d8c72bd8be1116edf1276 100644 (file)
@@ -281,6 +281,9 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
                     return new GeneralProtection(0);
             }
         }
+        if (m5Reg.mode != LongMode ||
+                (flags & (AddrSizeFlagBit << FlagShift)))
+            vaddr &= mask(32);
         // If paging is enabled, do the translation.
         if (m5Reg.paging) {
             DPRINTF(TLB, "Paging enabled.\n");