summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}