Merge zizzer:/bk/newmem
into zeep.pool:/z/saidi/work/m5.newmem --HG-- extra : convert_revision : e445097240af7b4e73efaca855cd1f217cf00313
This commit is contained in:
commit
fcf85725b5
7 changed files with 115 additions and 28 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>(),
|
||||||
|
|
6
src/mem/cache/cache_impl.hh
vendored
6
src/mem/cache/cache_impl.hh
vendored
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue