snoop_filter.cc (11132:fbd597034299) | snoop_filter.cc (11134:dfa51840de1f) |
---|---|
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 | 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 // Broadcast / filter upward snoops 178 const bool filter_upward = true; // @todo: Make configurable 179 180 if (!filter_upward) 181 return snoopAll(lookupLatency); 182 | |
183 Addr line_addr = cpkt->getBlockAddr(linesize); 184 auto sf_it = cachedLocations.find(line_addr); 185 bool is_hit = (sf_it != cachedLocations.end()); 186 187 panic_if(!is_hit && (cachedLocations.size() >= maxEntryCount), 188 "snoop filter exceeded capacity of %d cache blocks\n", 189 maxEntryCount); 190 | 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 |
191 // If the snoop filter has no entry and its an uncacheable 192 // request, do not create a new snoop filter entry, simply return 193 // a NULL portlist. 194 if (!is_hit && cpkt->req->isUncacheable()) | 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) |
195 return snoopDown(lookupLatency); 196 | 189 return snoopDown(lookupLatency); 190 |
197 // If no hit in snoop filter create a new element and update iterator 198 if (!is_hit) 199 sf_it = cachedLocations.emplace(line_addr, SnoopItem()).first; | |
200 SnoopItem& sf_item = sf_it->second; 201 202 DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 203 __func__, sf_item.requested, sf_item.holder); 204 205 SnoopMask interested = (sf_item.holder | sf_item.requested); 206 207 totSnoops++; | 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++; |
208 if (is_hit) { 209 // Single bit set -> value is a power of two 210 if (isPow2(interested)) 211 hitSingleSnoops++; 212 else 213 hitMultiSnoops++; 214 } | 199 // Single bit set -> value is a power of two 200 if (isPow2(interested)) 201 hitSingleSnoops++; 202 else 203 hitMultiSnoops++; 204 |
215 // ReadEx and Writes require both invalidation and exlusivity, while reads 216 // require neither. Writebacks on the other hand require exclusivity but 217 // not the invalidation. Previously Writebacks did not generate upward 218 // snoops so this was never an aissue. Now that Writebacks generate snoops 219 // we need to special case for Writebacks. 220 assert(cpkt->cmd == MemCmd::Writeback || cpkt->req->isUncacheable() || 221 (cpkt->isInvalidate() == cpkt->needsExclusive())); 222 if (cpkt->isInvalidate() && !sf_item.requested) { --- 68 unchanged lines hidden (view full) --- 291void 292SnoopFilter::updateSnoopForward(const Packet* cpkt, 293 const SlavePort& rsp_port, const MasterPort& req_port) 294{ 295 DPRINTF(SnoopFilter, "%s: packet rsp %s req %s addr 0x%x cmd %s\n", 296 __func__, rsp_port.name(), req_port.name(), cpkt->getAddr(), 297 cpkt->cmdString()); 298 | 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 |
|
299 Addr line_addr = cpkt->getBlockAddr(linesize); 300 auto sf_it = cachedLocations.find(line_addr); | 292 Addr line_addr = cpkt->getBlockAddr(linesize); 293 auto sf_it = cachedLocations.find(line_addr); |
301 if (sf_it == cachedLocations.end()) 302 sf_it = cachedLocations.emplace(line_addr, SnoopItem()).first; 303 SnoopItem& sf_item = sf_it->second; 304 SnoopMask rsp_mask M5_VAR_USED = portToMask(rsp_port); | 294 bool is_hit = sf_it != cachedLocations.end(); |
305 | 295 |
306 assert(cpkt->isResponse()); 307 assert(cpkt->memInhibitAsserted()); | 296 // Nothing to do if it is not a hit 297 if (!is_hit) 298 return; |
308 | 299 |
300 SnoopItem& sf_item = sf_it->second; 301 |
|
309 DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 310 __func__, sf_item.requested, sf_item.holder); 311 | 302 DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 303 __func__, sf_item.requested, sf_item.holder); 304 |
312 // Remote (to this snoop filter) snoops update the filter already when they 313 // arrive from below, because we may not see any response. | 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. |
314 if (cpkt->needsExclusive()) { | 308 if (cpkt->needsExclusive()) { |
315 // If the request to this snoop response hit an in-flight transaction, | 309 // If the request to this snoop response hit an in-flight 310 // transaction, |
316 // the holder was not reset -> no assertion & do that here, now! 317 //assert(sf_item.holder == 0); 318 sf_item.holder = 0; 319 } 320 DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 321 __func__, sf_item.requested, sf_item.holder); 322 eraseIfNullEntry(sf_it); | 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 |
|
323} 324 325void 326SnoopFilter::updateResponse(const Packet* cpkt, const SlavePort& slave_port) 327{ 328 DPRINTF(SnoopFilter, "%s: packet src %s addr 0x%x cmd %s\n", 329 __func__, slave_port.name(), cpkt->getAddr(), cpkt->cmdString()); 330 --- 67 unchanged lines hidden --- | 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 --- |