summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2007-05-14 16:14:59 -0400
committerAli Saidi <saidi@eecs.umich.edu>2007-05-14 16:14:59 -0400
commitea4e6f2e3d4d0ce6473fd2be5d9307c1e6545f72 (patch)
tree918dc5c703c8f1446624b70e9b1faacb00f1936a
parentaf26532bbd1a97a1f423c2944361290f1b696193 (diff)
downloadgem5-ea4e6f2e3d4d0ce6473fd2be5d9307c1e6545f72.tar.xz
add uglyiness to fix dmas
src/dev/io_device.cc: extra printing and assertions src/mem/bridge.hh: deal with packets only satisfying part of a request by making many requests src/mem/cache/cache_impl.hh: make the cache try to satisfy a functional request from the cache above it before checking itself --HG-- extra : convert_revision : 1df52ab61d7967e14cc377c560495430a6af266a
-rw-r--r--src/dev/io_device.cc16
-rw-r--r--src/mem/bridge.hh20
-rw-r--r--src/mem/cache/cache_impl.hh6
3 files changed, 31 insertions, 11 deletions
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc
index d430ace72..6528bd81c 100644
--- a/src/dev/io_device.cc
+++ b/src/dev/io_device.cc
@@ -218,6 +218,9 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
DmaReqState *reqState = new DmaReqState(event, this, size);
+
+ DPRINTF(DMA, "Starting DMA for addr: %#x size: %d sched: %d\n", addr, size,
+ event->scheduled());
for (ChunkGenerator gen(addr, size, peerBlockSize());
!gen.done(); gen.next()) {
Request *req = new Request(gen.addr(), gen.size(), 0);
@@ -231,6 +234,8 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
assert(pendingCount >= 0);
pendingCount++;
+ DPRINTF(DMA, "--Queuing DMA for addr: %#x size: %d\n", gen.addr(),
+ gen.size());
queueDma(pkt);
}
@@ -281,19 +286,28 @@ DmaPort::sendDma()
if (transmitList.size() && backoffTime && !inRetry &&
!backoffEvent.scheduled()) {
+ DPRINTF(DMA, "-- Scheduling backoff timer for %d\n",
+ backoffTime+curTick);
backoffEvent.schedule(backoffTime+curTick);
}
} else if (state == System::Atomic) {
transmitList.pop_front();
Tick lat;
+ DPRINTF(DMA, "--Sending DMA for addr: %#x size: %d\n",
+ pkt->req->getPaddr(), pkt->req->getSize());
lat = sendAtomic(pkt);
assert(pkt->senderState);
DmaReqState *state = dynamic_cast<DmaReqState*>(pkt->senderState);
assert(state);
-
state->numBytes += pkt->req->getSize();
+
+ DPRINTF(DMA, "--Received response for DMA for addr: %#x size: %d nb: %d, tot: %d sched %d\n",
+ pkt->req->getPaddr(), pkt->req->getSize(), state->numBytes,
+ state->totBytes, state->completionEvent->scheduled());
+
if (state->totBytes == state->numBytes) {
+ assert(!state->completionEvent->scheduled());
state->completionEvent->schedule(curTick + lat);
delete state;
delete pkt->req;
diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh
index 7df3c767f..5951eeb98 100644
--- a/src/mem/bridge.hh
+++ b/src/mem/bridge.hh
@@ -108,18 +108,24 @@ class Bridge : public MemObject
assert(!partialWriteFixed);
assert(expectResponse);
- int pbs = port->peerBlockSize();
+ Addr pbs = port->peerBlockSize();
+ Addr blockAddr = pkt->getAddr() & ~(pbs-1);
partialWriteFixed = true;
PacketDataPtr data;
data = new uint8_t[pbs];
- PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq,
- Packet::Broadcast, pbs);
-
- funcPkt->dataStatic(data);
- port->sendFunctional(funcPkt);
- assert(funcPkt->result == Packet::Success);
+ RequestPtr funcReq = new Request(blockAddr, 4, 0);
+ PacketPtr funcPkt = new Packet(funcReq, MemCmd::ReadReq,
+ Packet::Broadcast);
+ for (int x = 0; x < pbs; x+=4) {
+ funcReq->setPhys(blockAddr + x, 4, 0);
+ funcPkt->reinitFromRequest();
+ funcPkt->dataStatic(data + x);
+ port->sendFunctional(funcPkt);
+ assert(funcPkt->result == Packet::Success);
+ }
delete funcPkt;
+ delete funcReq;
oldPkt = pkt;
memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(),
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index c70f10151..db488d33d 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -1290,9 +1290,9 @@ template<class TagStore, class Coherence>
void
Cache<TagStore,Coherence>::MemSidePort::recvFunctional(PacketPtr pkt)
{
- if (checkFunctional(pkt)) {
- myCache()->probe(pkt, false, cache->cpuSidePort);
- }
+ myCache()->probe(pkt, false, cache->cpuSidePort);
+ if (pkt->result != Packet::Success)
+ checkFunctional(pkt);
}