void SMPCache::returnAccess(MemRequest *mreq) { SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq); MemOperation memOp = sreq->getMemOperation(); if(sreq->getRequestor() == this) { // request from this cache (response is ready) if(memOp == MemRead) { protocol->readMissAckHandler(sreq); } else if(memOp == MemReadW) { if(sreq->needsData()) { protocol->writeMissAckHandler(sreq); } else { protocol->invalidateAckHandler(sreq); } } else if(memOp == MemWrite) { I(!sreq->needsData()); I(sreq->needsSnoop()); protocol->invalidateAckHandler(sreq); } else if(memOp == MemPush) { protocol->writeBackAckHandler(sreq); } } else { receiveFromBelow(sreq); } }
void SMPSystemBus::doWrite(MemRequest *mreq) { SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq); // no need to snoop, go straight to memory if(!sreq->needsSnoop()) { goToMem(mreq); return; } if(pendReqsTable.find(mreq) == pendReqsTable.end()) { unsigned numSnoops = getNumSnoopCaches(sreq); // operation is starting now, add it to the pending requests buffer pendReqsTable[mreq] = getNumSnoopCaches(sreq); if(!numSnoops) { // nothing to snoop on this chip finalizeWrite(mreq); return; // TODO: even if there is only one processor on each chip, // request is doing two rounds: snoop and memory } //VERSION COMBINING REGISTER ALLOCATED HERE #ifdef TLS if (mreq->isDataReq()&& sreq->needsData())VCRCount++; #endif // distribute requests to other caches, wait for responses for(uint i = 0; i < upperLevel.size(); i++) { if(upperLevel[i] != static_cast<SMPMemRequest *>(mreq)->getRequestor()) { upperLevel[i]->returnAccess(mreq); } } } else { // operation has already been sent to other caches, receive responses I(pendReqsTable[mreq] > 0); I(pendReqsTable[mreq] <= (int) upperLevel.size()); pendReqsTable[mreq]--; if(pendReqsTable[mreq] != 0) { // this is an intermediate response, request is not serviced yet return; } // this is the final response, request can go up now finalizeWrite(mreq); } }
void SMPSystemBus::doPush(MemRequest *mreq) { #ifdef TLS SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq); TimeDelta_t VCRDelay; PAddr addr= mreq->getPAddr(); // no need to snoop, go straight to memory if(!sreq->needsSnoop()) { goToMem(mreq); return; } if(pendReqsTable.find(mreq) == pendReqsTable.end()) { unsigned numSnoops = getNumSnoopCaches(sreq); // operation is starting now, add it to the pending requests buffer pendReqsTable[mreq] = getNumSnoopCaches(sreq); VCRCount++; // distribute requests to other caches, wait for responses for(uint i = 0; i < upperLevel.size(); i++) { if(upperLevel[i] != static_cast<SMPMemRequest *>(mreq)->getRequestor()) { upperLevel[i]->returnAccess(mreq); } } return; } else { // operation has already been sent to other caches, receive responses I(pendReqsTable[mreq] > 0); I(pendReqsTable[mreq] <= (int) upperLevel.size()); pendReqsTable[mreq]--; if(pendReqsTable[mreq] != 0) { // this is an intermediate response, request is not serviced yet return; } // this is the final response, Request will now be sent down VCRDelay=finalizePush(mreq); mreq->goDown(VCRDelay+delay, lowerLevel[0]); } #else mreq->goDown(delay, lowerLevel[0]); #endif }