summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas@sandberg.pp.se>2013-06-18 16:10:22 +0200
committerAndreas Sandberg <andreas@sandberg.pp.se>2013-06-18 16:10:22 +0200
commit6151c0f7f43f0e3b62a6a2887a4a80d1c2154a3b (patch)
tree552a910dbb81f8e2aab3af338e0bc85be8612c52
parent46a8cbbb7f55e92943cc26266edd98c774edadac (diff)
downloadgem5-6151c0f7f43f0e3b62a6a2887a4a80d1c2154a3b.tar.xz
kvm: Use the address finalization code in the TLB
Reuse the address finalization code in the TLB instead of replicating it when handling MMIO. This patch also adds support for injecting memory mapped IPR requests into the memory system.
-rw-r--r--src/cpu/kvm/base.cc23
-rw-r--r--src/mem/request.hh10
2 files changed, 27 insertions, 6 deletions
diff --git a/src/cpu/kvm/base.cc b/src/cpu/kvm/base.cc
index 4c176c18b..1631fb54c 100644
--- a/src/cpu/kvm/base.cc
+++ b/src/cpu/kvm/base.cc
@@ -46,6 +46,7 @@
#include <csignal>
#include <ostream>
+#include "arch/mmapped_ipr.hh"
#include "arch/utility.hh"
#include "cpu/kvm/base.hh"
#include "debug/Checkpoint.hh"
@@ -949,12 +950,32 @@ BaseKvmCPU::handleKvmExitFailEntry()
Tick
BaseKvmCPU::doMMIOAccess(Addr paddr, void *data, int size, bool write)
{
+ ThreadContext *tc(thread->getTC());
+ syncThreadContext();
+
mmio_req.setPhys(paddr, size, Request::UNCACHEABLE, dataMasterId());
+ // Some architectures do need to massage physical addresses a bit
+ // before they are inserted into the memory system. This enables
+ // APIC accesses on x86 and m5ops where supported through a MMIO
+ // interface.
+ BaseTLB::Mode tlb_mode(write ? BaseTLB::Write : BaseTLB::Read);
+ Fault fault(tc->getDTBPtr()->finalizePhysical(&mmio_req, tc, tlb_mode));
+ if (fault != NoFault)
+ warn("Finalization of MMIO address failed: %s\n", fault->name());
+
const MemCmd cmd(write ? MemCmd::WriteReq : MemCmd::ReadReq);
Packet pkt(&mmio_req, cmd);
pkt.dataStatic(data);
- return dataPort.sendAtomic(&pkt);
+
+ if (mmio_req.isMmappedIpr()) {
+ if (write)
+ return TheISA::handleIprWrite(tc, &pkt);
+ else
+ return TheISA::handleIprRead(tc, &pkt);
+ } else {
+ return dataPort.sendAtomic(&pkt);
+ }
}
void
diff --git a/src/mem/request.hh b/src/mem/request.hh
index 11f1c74b3..ac6e3550b 100644
--- a/src/mem/request.hh
+++ b/src/mem/request.hh
@@ -321,15 +321,15 @@ class Request
}
/**
- * Set just the physical address. This should only be used to
- * record the result of a translation, and thus the vaddr must be
- * valid before this method is called. Otherwise, use setPhys()
- * to guarantee that the size and flags are also set.
+ * Set just the physical address. This usually used to record the
+ * result of a translation. However, when using virtualized CPUs
+ * setPhys() is sometimes called to finalize a physical address
+ * without a virtual address, so we can't check if the virtual
+ * address is valid.
*/
void
setPaddr(Addr paddr)
{
- assert(privateFlags.isSet(VALID_VADDR));
_paddr = paddr;
privateFlags.set(VALID_PADDR);
}