dev, kvm: Add a fast KVM-aware mode in DmaReadFifo
Use a fast, functional, read operations keep the DMA FIFO full when running in KVM mode. Change-Id: I5b378c2fb6a1d3e687cef15e807e63a0a53a60e2 Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/2226 Reviewed-by: Rahul Thakur <rjthakur@google.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
parent
746e2f3c27
commit
82a8230aa7
2 changed files with 44 additions and 10 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2015 ARM Limited
|
* Copyright (c) 2012, 2015, 2017 ARM Limited
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* The license below extends only to copyright in the software and shall
|
* The license below extends only to copyright in the software and shall
|
||||||
|
@ -50,6 +50,7 @@
|
||||||
#include "base/chunk_generator.hh"
|
#include "base/chunk_generator.hh"
|
||||||
#include "debug/DMA.hh"
|
#include "debug/DMA.hh"
|
||||||
#include "debug/Drain.hh"
|
#include "debug/Drain.hh"
|
||||||
|
#include "mem/port_proxy.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
DmaPort::DmaPort(MemObject *dev, System *s)
|
DmaPort::DmaPort(MemObject *dev, System *s)
|
||||||
|
@ -371,6 +372,40 @@ DmaReadFifo::resumeFill()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const bool old_eob(atEndOfBlock());
|
const bool old_eob(atEndOfBlock());
|
||||||
|
|
||||||
|
if (port.sys->bypassCaches())
|
||||||
|
resumeFillFunctional();
|
||||||
|
else
|
||||||
|
resumeFillTiming();
|
||||||
|
|
||||||
|
if (!old_eob && atEndOfBlock())
|
||||||
|
onEndOfBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DmaReadFifo::resumeFillFunctional()
|
||||||
|
{
|
||||||
|
const size_t fifo_space = buffer.capacity() - buffer.size();
|
||||||
|
const size_t kvm_watermark = port.sys->cacheLineSize();
|
||||||
|
if (fifo_space >= kvm_watermark || buffer.capacity() < kvm_watermark) {
|
||||||
|
const size_t block_remaining = endAddr - nextAddr;
|
||||||
|
const size_t xfer_size = std::min(fifo_space, block_remaining);
|
||||||
|
std::vector<uint8_t> tmp_buffer(xfer_size);
|
||||||
|
|
||||||
|
assert(pendingRequests.empty());
|
||||||
|
DPRINTF(DMA, "KVM Bypassing startAddr=%#x xfer_size=%#x " \
|
||||||
|
"fifo_space=%#x block_remaining=%#x\n",
|
||||||
|
nextAddr, xfer_size, fifo_space, block_remaining);
|
||||||
|
|
||||||
|
port.sys->physProxy.readBlob(nextAddr, tmp_buffer.data(), xfer_size);
|
||||||
|
buffer.write(tmp_buffer.begin(), xfer_size);
|
||||||
|
nextAddr += xfer_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DmaReadFifo::resumeFillTiming()
|
||||||
|
{
|
||||||
size_t size_pending(0);
|
size_t size_pending(0);
|
||||||
for (auto &e : pendingRequests)
|
for (auto &e : pendingRequests)
|
||||||
size_pending += e->requestSize();
|
size_pending += e->requestSize();
|
||||||
|
@ -392,11 +427,6 @@ DmaReadFifo::resumeFill()
|
||||||
|
|
||||||
pendingRequests.emplace_back(std::move(event));
|
pendingRequests.emplace_back(std::move(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOB can be set before a call to dmaDone() if in-flight accesses
|
|
||||||
// have been canceled.
|
|
||||||
if (!old_eob && atEndOfBlock())
|
|
||||||
onEndOfBlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -430,8 +460,6 @@ DmaReadFifo::handlePending()
|
||||||
signalDrainDone();
|
signalDrainDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DrainState
|
DrainState
|
||||||
DmaReadFifo::drain()
|
DmaReadFifo::drain()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012-2013, 2015 ARM Limited
|
* Copyright (c) 2012-2013, 2015, 2017 ARM Limited
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* The license below extends only to copyright in the software and shall
|
* The license below extends only to copyright in the software and shall
|
||||||
|
@ -494,9 +494,15 @@ class DmaReadFifo : public Drainable, public Serializable
|
||||||
/** Handle pending requests that have been flagged as done. */
|
/** Handle pending requests that have been flagged as done. */
|
||||||
void handlePending();
|
void handlePending();
|
||||||
|
|
||||||
/** Try to issue new DMA requests */
|
/** Try to issue new DMA requests or bypass DMA requests*/
|
||||||
void resumeFill();
|
void resumeFill();
|
||||||
|
|
||||||
|
/** Try to issue new DMA requests during normal execution*/
|
||||||
|
void resumeFillTiming();
|
||||||
|
|
||||||
|
/** Try to bypass DMA requests in KVM execution mode */
|
||||||
|
void resumeFillFunctional();
|
||||||
|
|
||||||
private: // Internal state
|
private: // Internal state
|
||||||
Fifo<uint8_t> buffer;
|
Fifo<uint8_t> buffer;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue