1/* 2 * Copyright (c) 2013-2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 160 unchanged lines hidden (view full) --- 169std::pair<SnoopFilter::SnoopList, Cycles> 170SnoopFilter::lookupSnoop(const Packet* cpkt) 171{ 172 DPRINTF(SnoopFilter, "%s: packet addr 0x%x cmd %s\n", 173 __func__, cpkt->getAddr(), cpkt->cmdString()); 174 175 assert(cpkt->isRequest()); 176 |
177 Addr line_addr = cpkt->getBlockAddr(linesize); 178 auto sf_it = cachedLocations.find(line_addr); 179 bool is_hit = (sf_it != cachedLocations.end()); 180 181 panic_if(!is_hit && (cachedLocations.size() >= maxEntryCount), 182 "snoop filter exceeded capacity of %d cache blocks\n", 183 maxEntryCount); 184 |
185 // If the snoop filter has no entry, simply return a NULL 186 // portlist, there is no point creating an entry only to remove it 187 // later 188 if (!is_hit) |
189 return snoopDown(lookupLatency); 190 |
191 SnoopItem& sf_item = sf_it->second; 192 193 DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 194 __func__, sf_item.requested, sf_item.holder); 195 196 SnoopMask interested = (sf_item.holder | sf_item.requested); 197 198 totSnoops++; |
199 // Single bit set -> value is a power of two 200 if (isPow2(interested)) 201 hitSingleSnoops++; 202 else 203 hitMultiSnoops++; 204 |
205 // ReadEx and Writes require both invalidation and exlusivity, while reads 206 // require neither. Writebacks on the other hand require exclusivity but 207 // not the invalidation. Previously Writebacks did not generate upward 208 // snoops so this was never an aissue. Now that Writebacks generate snoops 209 // we need to special case for Writebacks. 210 assert(cpkt->cmd == MemCmd::Writeback || cpkt->req->isUncacheable() || 211 (cpkt->isInvalidate() == cpkt->needsExclusive())); 212 if (cpkt->isInvalidate() && !sf_item.requested) { --- 68 unchanged lines hidden (view full) --- 281void 282SnoopFilter::updateSnoopForward(const Packet* cpkt, 283 const SlavePort& rsp_port, const MasterPort& req_port) 284{ 285 DPRINTF(SnoopFilter, "%s: packet rsp %s req %s addr 0x%x cmd %s\n", 286 __func__, rsp_port.name(), req_port.name(), cpkt->getAddr(), 287 cpkt->cmdString()); 288 |
289 assert(cpkt->isResponse()); 290 assert(cpkt->memInhibitAsserted()); 291 |
292 Addr line_addr = cpkt->getBlockAddr(linesize); 293 auto sf_it = cachedLocations.find(line_addr); |
294 bool is_hit = sf_it != cachedLocations.end(); |
295 |
296 // Nothing to do if it is not a hit 297 if (!is_hit) 298 return; |
299 |
300 SnoopItem& sf_item = sf_it->second; 301 |
302 DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 303 __func__, sf_item.requested, sf_item.holder); 304 |
305 // Remote (to this snoop filter) snoops update the filter 306 // already when they arrive from below, because we may not see 307 // any response. |
308 if (cpkt->needsExclusive()) { |
309 // If the request to this snoop response hit an in-flight 310 // transaction, |
311 // the holder was not reset -> no assertion & do that here, now! 312 //assert(sf_item.holder == 0); 313 sf_item.holder = 0; 314 } 315 DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 316 __func__, sf_item.requested, sf_item.holder); 317 eraseIfNullEntry(sf_it); |
318 |
319} 320 321void 322SnoopFilter::updateResponse(const Packet* cpkt, const SlavePort& slave_port) 323{ 324 DPRINTF(SnoopFilter, "%s: packet src %s addr 0x%x cmd %s\n", 325 __func__, slave_port.name(), cpkt->getAddr(), cpkt->cmdString()); 326 --- 67 unchanged lines hidden --- |