summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2012-03-31 12:27:33 -0700
committerGabe Black <gblack@eecs.umich.edu>2012-03-31 12:27:33 -0700
commita7859f7e4541f2750df52ec725563d378ab7ddbb (patch)
tree3ae67d8844327f87e14b839ea24fdf4db9137159 /src/arch
parent74043c4f5c6f4b4d43c518f47da4cd1bd68b9e08 (diff)
downloadgem5-a7859f7e4541f2750df52ec725563d378ab7ddbb.tar.xz
X86: Fix address size handling so real mode works properly.
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.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/isa/microops/ldstop.isa2
-rw-r--r--src/arch/x86/tlb.cc3
2 files changed, 4 insertions, 1 deletions
diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa
index 8bcf55c99..75519f417 100644
--- a/src/arch/x86/isa/microops/ldstop.isa
+++ b/src/arch/x86/isa/microops/ldstop.isa
@@ -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='',
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index 89561f851..100f8cf0f 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -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");