summaryrefslogtreecommitdiff
path: root/src/arch/x86/tlb.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2008-06-12 00:46:22 -0400
committerGabe Black <gblack@eecs.umich.edu>2008-06-12 00:46:22 -0400
commitb3e55339f90dbf7f719e8f8348356e1ad03d74bb (patch)
tree2d9876ba1f707b5e64805602f89e9e0db2a27516 /src/arch/x86/tlb.cc
parent561a541797d71f1eff4290a769cac2920b8e4cb8 (diff)
downloadgem5-b3e55339f90dbf7f719e8f8348356e1ad03d74bb.tar.xz
X86: Remove enforcement of APIC register access alignment. Panic if more than one register is accessed at a time.
Diffstat (limited to 'src/arch/x86/tlb.cc')
-rw-r--r--src/arch/x86/tlb.cc15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index 3e720c9ae..cbd59c19e 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * Copyright (c) 2007-2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
@@ -598,13 +598,24 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
Addr paddr = req->getPaddr();
if (baseAddr <= paddr && baseAddr + (1 << 12) > paddr) {
req->setMmapedIpr(true);
+ // The Intel developer's manuals say the below restrictions apply,
+ // but the linux kernel, because of a compiler optimization, breaks
+ // them.
+ /*
// Check alignment
if (paddr & ((32/8) - 1))
return new GeneralProtection(0);
// Check access size
if (req->getSize() != (32/8))
return new GeneralProtection(0);
+ */
+
+ //Make sure we're at least only accessing one register.
+ if ((paddr & ~mask(3)) != ((paddr + req->getSize()) & ~mask(3)))
+ panic("Accessed more than one register at a time in the APIC!\n");
MiscReg regNum;
+ Addr offset = paddr & mask(3);
+ paddr &= ~mask(3);
switch (paddr - baseAddr)
{
case 0x20:
@@ -732,7 +743,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
return new GeneralProtection(0);
break;
}
- req->setPaddr(regNum * sizeof(MiscReg));
+ req->setPaddr(regNum * sizeof(MiscReg) + offset);
}
#endif
return NoFault;