Merge zizzer:/bk/newmem

into  zeep.pool:/z/saidi/work/m5.newmem

--HG--
extra : convert_revision : e445097240af7b4e73efaca855cd1f217cf00313
This commit is contained in:
Ali Saidi 2007-05-14 16:37:22 -04:00
commit fcf85725b5
7 changed files with 115 additions and 28 deletions

View file

@ -1,7 +1,4 @@
echo "switching cpus" insmod /modules/devtime.ko dataAddr=0x9000008 count=100
m5 switchcpu
echo "done"
insmod /modules/devtime.ko dataAddr=0x9000004 count=100
rmmod devtime rmmod devtime
insmod /modules/devtime.ko dataAddr=0x1a0000300 count=100 insmod /modules/devtime.ko dataAddr=0x1a0000300 count=100
rmmod devtime rmmod devtime

View file

@ -656,7 +656,7 @@ IGbE::RxDescCache::writePacket(EthPacketPtr packet)
return false; return false;
pktPtr = packet; pktPtr = packet;
pktDone = false;
igbe->dmaWrite(igbe->platform->pciToDma(unusedCache.front()->buf), igbe->dmaWrite(igbe->platform->pciToDma(unusedCache.front()->buf),
packet->length, &pktEvent, packet->data); packet->length, &pktEvent, packet->data);
return true; return true;
@ -683,8 +683,12 @@ IGbE::RxDescCache::pktComplete()
uint8_t status = RXDS_DD | RXDS_EOP; uint8_t status = RXDS_DD | RXDS_EOP;
uint8_t err = 0; uint8_t err = 0;
IpPtr ip(pktPtr); IpPtr ip(pktPtr);
if (ip) { if (ip) {
DPRINTF(EthernetDesc, "Proccesing Ip packet with Id=%d\n", ip->id());
if (igbe->regs.rxcsum.ipofld()) { if (igbe->regs.rxcsum.ipofld()) {
DPRINTF(EthernetDesc, "Checking IP checksum\n"); DPRINTF(EthernetDesc, "Checking IP checksum\n");
status |= RXDS_IPCS; status |= RXDS_IPCS;
@ -715,7 +719,10 @@ IGbE::RxDescCache::pktComplete()
err |= RXDE_TCPE; err |= RXDE_TCPE;
} }
} }
} // if ip } else { // if ip
DPRINTF(EthernetSM, "Proccesing Non-Ip packet\n");
}
desc->status = htole(status); desc->status = htole(status);
desc->errors = htole(err); desc->errors = htole(err);
@ -912,10 +919,20 @@ IGbE::TxDescCache::pktComplete()
DPRINTF(EthernetDesc, "TxDescriptor data d1: %#llx d2: %#llx\n", desc->d1, desc->d2); DPRINTF(EthernetDesc, "TxDescriptor data d1: %#llx d2: %#llx\n", desc->d1, desc->d2);
if (DTRACE(EthernetDesc)) {
IpPtr ip(pktPtr);
if (ip)
DPRINTF(EthernetDesc, "Proccesing Ip packet with Id=%d\n",
ip->id());
else
DPRINTF(EthernetSM, "Proccesing Non-Ip packet\n");
}
// Checksums are only ofloaded for new descriptor types // Checksums are only ofloaded for new descriptor types
if (TxdOp::isData(desc) && ( TxdOp::ixsm(desc) || TxdOp::txsm(desc)) ) { if (TxdOp::isData(desc) && ( TxdOp::ixsm(desc) || TxdOp::txsm(desc)) ) {
DPRINTF(EthernetDesc, "Calculating checksums for packet\n"); DPRINTF(EthernetDesc, "Calculating checksums for packet\n");
IpPtr ip(pktPtr); IpPtr ip(pktPtr);
if (TxdOp::ixsm(desc)) { if (TxdOp::ixsm(desc)) {
ip->sum(0); ip->sum(0);
ip->sum(cksum(ip)); ip->sum(cksum(ip));
@ -1192,6 +1209,7 @@ IGbE::rxStateMachine()
// If the packet is done check for interrupts/descriptors/etc // If the packet is done check for interrupts/descriptors/etc
if (rxDescCache.packetDone()) { if (rxDescCache.packetDone()) {
rxDmaPacket = false;
DPRINTF(EthernetSM, "RXS: Packet completed DMA to memory\n"); DPRINTF(EthernetSM, "RXS: Packet completed DMA to memory\n");
int descLeft = rxDescCache.descLeft(); int descLeft = rxDescCache.descLeft();
switch (regs.rctl.rdmts()) { switch (regs.rctl.rdmts()) {
@ -1236,6 +1254,12 @@ IGbE::rxStateMachine()
return; return;
} }
if (rxDmaPacket) {
DPRINTF(EthernetSM, "RXS: stopping ticking until packet DMA completes\n");
rxTick = false;
return;
}
if (!rxDescCache.descUnused()) { if (!rxDescCache.descUnused()) {
DPRINTF(EthernetSM, "RXS: No descriptors available in cache, stopping ticking\n"); DPRINTF(EthernetSM, "RXS: No descriptors available in cache, stopping ticking\n");
rxTick = false; rxTick = false;
@ -1262,6 +1286,7 @@ IGbE::rxStateMachine()
rxFifo.pop(); rxFifo.pop();
DPRINTF(EthernetSM, "RXS: stopping ticking until packet DMA completes\n"); DPRINTF(EthernetSM, "RXS: stopping ticking until packet DMA completes\n");
rxTick = false; rxTick = false;
rxDmaPacket = true;
} }
void void

View file

@ -80,6 +80,8 @@ class IGbE : public PciDev
bool txTick; bool txTick;
bool txFifoTick; bool txFifoTick;
bool rxDmaPacket;
// Event and function to deal with RDTR timer expiring // Event and function to deal with RDTR timer expiring
void rdtrProcess() { void rdtrProcess() {
rxDescCache.writeback(0); rxDescCache.writeback(0);

View file

@ -218,6 +218,9 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
DmaReqState *reqState = new DmaReqState(event, this, size); 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()); for (ChunkGenerator gen(addr, size, peerBlockSize());
!gen.done(); gen.next()) { !gen.done(); gen.next()) {
Request *req = new Request(gen.addr(), gen.size(), 0); 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); assert(pendingCount >= 0);
pendingCount++; pendingCount++;
DPRINTF(DMA, "--Queuing DMA for addr: %#x size: %d\n", gen.addr(),
gen.size());
queueDma(pkt); queueDma(pkt);
} }
@ -281,19 +286,28 @@ DmaPort::sendDma()
if (transmitList.size() && backoffTime && !inRetry && if (transmitList.size() && backoffTime && !inRetry &&
!backoffEvent.scheduled()) { !backoffEvent.scheduled()) {
DPRINTF(DMA, "-- Scheduling backoff timer for %d\n",
backoffTime+curTick);
backoffEvent.schedule(backoffTime+curTick); backoffEvent.schedule(backoffTime+curTick);
} }
} else if (state == System::Atomic) { } else if (state == System::Atomic) {
transmitList.pop_front(); transmitList.pop_front();
Tick lat; Tick lat;
DPRINTF(DMA, "--Sending DMA for addr: %#x size: %d\n",
pkt->req->getPaddr(), pkt->req->getSize());
lat = sendAtomic(pkt); lat = sendAtomic(pkt);
assert(pkt->senderState); assert(pkt->senderState);
DmaReqState *state = dynamic_cast<DmaReqState*>(pkt->senderState); DmaReqState *state = dynamic_cast<DmaReqState*>(pkt->senderState);
assert(state); assert(state);
state->numBytes += pkt->req->getSize(); 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) { if (state->totBytes == state->numBytes) {
assert(!state->completionEvent->scheduled());
state->completionEvent->schedule(curTick + lat); state->completionEvent->schedule(curTick + lat);
delete state; delete state;
delete pkt->req; delete pkt->req;

View file

@ -119,7 +119,14 @@ Bridge::BridgePort::recvTiming(PacketPtr pkt)
DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n", DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n",
pkt->getSrc(), pkt->getDest(), pkt->getAddr()); pkt->getSrc(), pkt->getDest(), pkt->getAddr());
if (pkt->isRequest() && otherPort->reqQueueFull()) { DPRINTF(BusBridge, "Local queue size: %d outreq: %d outresp: %d\n",
sendQueue.size(), queuedRequests, outstandingResponses);
DPRINTF(BusBridge, "Remove queue size: %d outreq: %d outresp: %d\n",
otherPort->sendQueue.size(), otherPort->queuedRequests,
otherPort->outstandingResponses);
if (pkt->isRequest() && otherPort->reqQueueFull() && pkt->result !=
Packet::Nacked) {
DPRINTF(BusBridge, "Remote queue full, nacking\n"); DPRINTF(BusBridge, "Remote queue full, nacking\n");
nackRequest(pkt); nackRequest(pkt);
return true; return true;
@ -191,7 +198,7 @@ Bridge::BridgePort::nackRequest(PacketPtr pkt)
void void
Bridge::BridgePort::queueForSendTiming(PacketPtr pkt) Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
{ {
if (pkt->isResponse() || pkt->result == Packet::Nacked) { if (pkt->isResponse() || pkt->result == Packet::Nacked) {
// This is a response for a request we forwarded earlier. The // This is a response for a request we forwarded earlier. The
// corresponding PacketBuffer should be stored in the packet's // corresponding PacketBuffer should be stored in the packet's
// senderState field. // senderState field.
@ -201,9 +208,9 @@ Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
// from original request // from original request
buf->fixResponse(pkt); buf->fixResponse(pkt);
// Check if this packet was expecting a response (this is either it or // Check if this packet was expecting a response and it's a nacked
// its a nacked packet and we won't be seeing that response) // packet, in which case we will never being seeing it
if (buf->expectResponse) if (buf->expectResponse && pkt->result == Packet::Nacked)
--outstandingResponses; --outstandingResponses;
@ -213,6 +220,13 @@ Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
delete buf; delete buf;
} }
if (pkt->isRequest() && pkt->result != Packet::Nacked) {
++queuedRequests;
}
Tick readyTime = curTick + delay; Tick readyTime = curTick + delay;
PacketBuffer *buf = new PacketBuffer(pkt, readyTime); PacketBuffer *buf = new PacketBuffer(pkt, readyTime);
DPRINTF(BusBridge, "old sender state: %#X, new sender state: %#X\n", DPRINTF(BusBridge, "old sender state: %#X, new sender state: %#X\n",
@ -225,7 +239,6 @@ Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
if (sendQueue.empty()) { if (sendQueue.empty()) {
sendEvent.schedule(readyTime); sendEvent.schedule(readyTime);
} }
++queuedRequests;
sendQueue.push_back(buf); sendQueue.push_back(buf);
} }
@ -254,6 +267,8 @@ Bridge::BridgePort::trySend()
DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n", DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
buf->origSrc, pkt->getDest(), pkt->getAddr()); buf->origSrc, pkt->getDest(), pkt->getAddr());
bool wasReq = pkt->isRequest();
bool wasNacked = pkt->result == Packet::Nacked;
if (sendTiming(pkt)) { if (sendTiming(pkt)) {
// send successful // send successful
@ -270,8 +285,12 @@ Bridge::BridgePort::trySend()
delete buf; delete buf;
} }
if (!buf->nacked) if (!wasNacked) {
if (wasReq)
--queuedRequests; --queuedRequests;
else
--outstandingResponses;
}
// If there are more packets to send, schedule event to try again. // If there are more packets to send, schedule event to try again.
if (!sendQueue.empty()) { if (!sendQueue.empty()) {
@ -305,7 +324,32 @@ Bridge::BridgePort::recvRetry()
Tick Tick
Bridge::BridgePort::recvAtomic(PacketPtr pkt) Bridge::BridgePort::recvAtomic(PacketPtr pkt)
{ {
return otherPort->sendAtomic(pkt) + delay; int pbs = otherPort->peerBlockSize();
Tick atomic_delay;
// fix partial atomic writes... similar to the timing code that does the
// same
if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite &&
pkt->getOffset(pbs) && pkt->getSize() != pbs) {
PacketDataPtr data;
data = new uint8_t[pbs];
PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq,
Packet::Broadcast, pbs);
funcPkt->dataStatic(data);
otherPort->sendFunctional(funcPkt);
assert(funcPkt->result == Packet::Success);
delete funcPkt;
memcpy(data + pkt->getOffset(pbs), pkt->getPtr<uint8_t>(),
pkt->getSize());
PacketPtr newPkt = new Packet(pkt->req, MemCmd::WriteInvalidateReq,
Packet::Broadcast, pbs);
pkt->dataDynamicArray(data);
atomic_delay = otherPort->sendAtomic(newPkt);
delete newPkt;
} else {
atomic_delay = otherPort->sendAtomic(pkt);
}
return atomic_delay + delay;
} }
/** Function called by the port when the bus is receiving a Functional /** Function called by the port when the bus is receiving a Functional

View file

@ -82,16 +82,15 @@ class Bridge : public MemObject
bool partialWriteFixed; bool partialWriteFixed;
PacketPtr oldPkt; PacketPtr oldPkt;
bool nacked;
PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false) PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
: ready(t), pkt(_pkt), : ready(t), pkt(_pkt),
origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()), origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
expectResponse(_pkt->needsResponse() && !nack), expectResponse(_pkt->needsResponse() && !nack),
partialWriteFixed(false), nacked(nack) partialWriteFixed(false)
{ {
if (!pkt->isResponse() && !nack) if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked)
pkt->senderState = this; pkt->senderState = this;
} }
@ -109,18 +108,24 @@ class Bridge : public MemObject
assert(!partialWriteFixed); assert(!partialWriteFixed);
assert(expectResponse); assert(expectResponse);
int pbs = port->peerBlockSize(); Addr pbs = port->peerBlockSize();
Addr blockAddr = pkt->getAddr() & ~(pbs-1);
partialWriteFixed = true; partialWriteFixed = true;
PacketDataPtr data; PacketDataPtr data;
data = new uint8_t[pbs]; data = new uint8_t[pbs];
PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq, RequestPtr funcReq = new Request(blockAddr, 4, 0);
Packet::Broadcast, pbs); PacketPtr funcPkt = new Packet(funcReq, MemCmd::ReadReq,
Packet::Broadcast);
funcPkt->dataStatic(data); for (int x = 0; x < pbs; x+=4) {
port->sendFunctional(funcPkt); funcReq->setPhys(blockAddr + x, 4, 0);
assert(funcPkt->result == Packet::Success); funcPkt->reinitFromRequest();
funcPkt->dataStatic(data + x);
port->sendFunctional(funcPkt);
assert(funcPkt->result == Packet::Success);
}
delete funcPkt; delete funcPkt;
delete funcReq;
oldPkt = pkt; oldPkt = pkt;
memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(), memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(),

View file

@ -1290,9 +1290,9 @@ template<class TagStore, class Coherence>
void void
Cache<TagStore,Coherence>::MemSidePort::recvFunctional(PacketPtr pkt) 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);
} }