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 ---