SMPCache::Line *SMPCache::allocateLine(PAddr addr, MemRequest *mreq, CallbackBase *cb) { PAddr rpl_addr = 0; I(cache->findLine(addr)==0); //I(cache->findLineDebug(addr) == 0); if (cache->findLineDebug(addr)) printf("Error\n"); Line *l = cache->findLine2Replace(addr); if(!l) { // need to schedule allocate line for next cycle doAllocateLineCB::scheduleAbs(globalClock+1, this, addr, 0, mreq,cb); return 0; } rpl_addr = cache->calcAddr4Tag(l->getTag()); lineFill.inc(); nextSlot(); // have to do an access to check which line is free if(!l->isValid()) { cb->destroy(); l->setTag(cache->calcTag(addr)); return l; } if(isHighestLevel()) { if(l->isDirty()) { allocDirty.inc(); //This prevents further acces to this line //l->changeStateTo(SMP_TRANS_INV_D); doWriteBack(mreq); } cb->destroy(); l->invalidate(); l->setTag(cache->calcTag(addr)); return l; } I(pendInvTable.find(rpl_addr) == pendInvTable.end()); pendInvTable[rpl_addr].outsResps = getNumCachesInUpperLevels(); pendInvTable[rpl_addr].cb = doAllocateLineCB::create(this, addr, rpl_addr, mreq,cb); pendInvTable[rpl_addr].invalidate = false; protocol->preInvalidate(l); invUpperLevel(rpl_addr, cache->getLineSize(), this); return 0; }
void AddressPrefetcher::invalidate(PAddr addr,ushort size,MemObj *oc) { // Invalidate the local cache while (size) { cachePort->nextSlot(); Line *l = cache->readLine(addr); if(l) l->invalidate(); addr += cache->getLineSize(); size -= cache->getLineSize(); } invUpperLevel(addr,size,oc); }
void SMPCache::invalidate(PAddr addr, ushort size, MemObj *oc) { I(oc); I(pendInvTable.find(addr) == pendInvTable.end()); pendInvTable[addr].outsResps = getNumCachesInUpperLevels(); pendInvTable[addr].cb = doInvalidateCB::create(oc, addr, size); pendInvTable[addr].invalidate = true; if (!isHighestLevel()) { invUpperLevel(addr, size, this); return; } doInvalidate(addr, size); }
void SMPCache::invalidateLine(PAddr addr, CallbackBase *cb) { Line *l = cache->findLine(addr); I(l); I(pendInvTable.find(addr) == pendInvTable.end()); pendInvTable[addr].outsResps = getNumCachesInUpperLevels(); pendInvTable[addr].cb = cb; pendInvTable[addr].invalidate = true; protocol->preInvalidate(l); if(!isHighestLevel()) { invUpperLevel(addr, cache->getLineSize(), this); return; } doInvalidate(addr, cache->getLineSize()); }
void DummyMemObj::invalidate(PAddr addr, ushort size, MemObj *oc) { invUpperLevel(addr, size, oc); }
void MemCtrl::invalidate(PAddr addr,ushort size,MemObj *oc) { invUpperLevel(addr,size,oc); }
void PriorityBus::invalidate(PAddr addr,ushort size,MemObj *oc) { invUpperLevel(addr,size,oc); }
void SMPCache::doInvalidateLineTLS(MemRequest *mreq) { PAddr addr=mreq->getPAddr(); Line *l = cache->findLine(addr); ushort size =cache->getLineSize(); I(l); I(pendInvTable.find(addr) == pendInvTable.end()); pendInvTable[addr].outsResps = getNumCachesInUpperLevels(); pendInvTable[addr].cb = dummyCB::create(this,mreq);; pendInvTable[addr].invalidate = true; protocol->preInvalidate(l); if(!isHighestLevel()) { invUpperLevel(addr, cache->getLineSize(), this); return; } //doInvalidate(addr, cache->getLineSize()); ///Do invalidate I(pendInvTable.find(addr) != pendInvTable.end()); CallbackBase *cb = 0; bool invalidate = false; PendInvTable::iterator it = pendInvTable.find(addr); Entry *record = &(it->second); if(--(record->outsResps) <= 0) { cb = record->cb; invalidate = record->invalidate; pendInvTable.erase(addr); } if(cb) EventScheduler::schedule((TimeDelta_t) 2,cb); //if(invalidate) //realInvalidate(addr, size); if(invalidate) { while(size) { //Line *l = cache->findLine(addr); if (l) { nextSlot(); // counts for occupancy to invalidate line I(l->isValid()); if (l->isDirty()) { invalDirty.inc(); //This prevents further acces to this line //l->changeStateTo(SMP_TRANS_INV_D); doWriteBack(mreq); } l->invalidate(); } addr += cache->getLineSize(); size -= cache->getLineSize(); } } //mutExclBuffer->retire(addr); }
void SMPSystemBus::invalidate(PAddr addr, ushort size, MemObj *oc) { invUpperLevel(addr, size, oc); }