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 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated --- 38 unchanged lines hidden (view full) --- 49#include "sim/system.hh" 50 51std::pair<SnoopFilter::SnoopList, Cycles> 52SnoopFilter::lookupRequest(const Packet* cpkt, const SlavePort& slave_port) 53{ 54 DPRINTF(SnoopFilter, "%s: packet src %s addr 0x%x cmd %s\n", 55 __func__, slave_port.name(), cpkt->getAddr(), cpkt->cmdString()); 56 |
57 // Ultimately we should check if the packet came from an 58 // allocating source, not just if the port is snooping 59 bool allocate = !cpkt->req->isUncacheable() && slave_port.isSnooping(); 60 Addr line_addr = cpkt->getBlockAddr(linesize); |
61 SnoopMask req_port = portToMask(slave_port); 62 auto sf_it = cachedLocations.find(line_addr); 63 bool is_hit = (sf_it != cachedLocations.end()); |
64 65 // If the snoop filter has no entry, and we should not allocate, 66 // do not create a new snoop filter entry, simply return a NULL 67 // portlist. 68 if (!is_hit && !allocate) 69 return snoopDown(lookupLatency); 70 |
71 // Create a new element through operator[] and modify in-place 72 SnoopItem& sf_item = is_hit ? sf_it->second : cachedLocations[line_addr]; 73 SnoopMask interested = sf_item.holder | sf_item.requested; 74 75 totRequests++; 76 if (is_hit) { 77 // Single bit set -> value is a power of two 78 if (isPow2(interested)) 79 hitSingleRequests++; 80 else 81 hitMultiRequests++; 82 } 83 84 DPRINTF(SnoopFilter, "%s: SF value %x.%x\n", 85 __func__, sf_item.requested, sf_item.holder); 86 |
87 if (allocate && cpkt->needsResponse()) { |
88 if (!cpkt->memInhibitAsserted()) { 89 // Max one request per address per port 90 panic_if(sf_item.requested & req_port, "double request :( "\ 91 "SF value %x.%x\n", sf_item.requested, sf_item.holder); 92 93 // Mark in-flight requests to distinguish later on 94 sf_item.requested |= req_port; 95 } else { --- 13 unchanged lines hidden (view full) --- 109 110void 111SnoopFilter::updateRequest(const Packet* cpkt, const SlavePort& slave_port, 112 bool will_retry) 113{ 114 DPRINTF(SnoopFilter, "%s: packet src %s addr 0x%x cmd %s\n", 115 __func__, slave_port.name(), cpkt->getAddr(), cpkt->cmdString()); 116 |
117 // Ultimately we should check if the packet came from an 118 // allocating source, not just if the port is snooping 119 bool allocate = !cpkt->req->isUncacheable() && slave_port.isSnooping(); 120 if (!allocate) |
121 return; 122 |
123 Addr line_addr = cpkt->getBlockAddr(linesize); |
124 SnoopMask req_port = portToMask(slave_port); 125 SnoopItem& sf_item = cachedLocations[line_addr]; 126 127 DPRINTF(SnoopFilter, "%s: old SF value %x.%x retry: %i\n", 128 __func__, sf_item.requested, sf_item.holder, will_retry); 129 130 if (will_retry) { 131 // Unmark a request that will come again. --- 32 unchanged lines hidden (view full) --- 164 assert(cpkt->isRequest()); 165 166 // Broadcast / filter upward snoops 167 const bool filter_upward = true; // @todo: Make configurable 168 169 if (!filter_upward) 170 return snoopAll(lookupLatency); 171 |
172 Addr line_addr = cpkt->getBlockAddr(linesize); |
173 auto sf_it = cachedLocations.find(line_addr); 174 bool is_hit = (sf_it != cachedLocations.end()); 175 // Create a new element through operator[] and modify in-place 176 SnoopItem& sf_item = is_hit ? sf_it->second : cachedLocations[line_addr]; 177 178 DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 179 __func__, sf_item.requested, sf_item.holder); 180 --- 34 unchanged lines hidden (view full) --- 215{ 216 DPRINTF(SnoopFilter, "%s: packet rsp %s req %s addr 0x%x cmd %s\n", 217 __func__, rsp_port.name(), req_port.name(), cpkt->getAddr(), 218 cpkt->cmdString()); 219 220 assert(cpkt->isResponse()); 221 assert(cpkt->memInhibitAsserted()); 222 |
223 // Ultimately we should check if the packet came from an 224 // allocating source, not just if the port is snooping 225 bool allocate = !cpkt->req->isUncacheable() && req_port.isSnooping(); 226 if (!allocate) |
227 return; 228 |
229 Addr line_addr = cpkt->getBlockAddr(linesize); |
230 SnoopMask rsp_mask = portToMask(rsp_port); 231 SnoopMask req_mask = portToMask(req_port); 232 SnoopItem& sf_item = cachedLocations[line_addr]; 233 234 DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 235 __func__, sf_item.requested, sf_item.holder); 236 237 // The source should have the line --- 27 unchanged lines hidden (view full) --- 265void 266SnoopFilter::updateSnoopForward(const Packet* cpkt, 267 const SlavePort& rsp_port, const MasterPort& req_port) 268{ 269 DPRINTF(SnoopFilter, "%s: packet rsp %s req %s addr 0x%x cmd %s\n", 270 __func__, rsp_port.name(), req_port.name(), cpkt->getAddr(), 271 cpkt->cmdString()); 272 |
273 Addr line_addr = cpkt->getBlockAddr(linesize); |
274 SnoopItem& sf_item = cachedLocations[line_addr]; 275 SnoopMask rsp_mask M5_VAR_USED = portToMask(rsp_port); 276 277 assert(cpkt->isResponse()); 278 assert(cpkt->memInhibitAsserted()); 279 280 DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 281 __func__, sf_item.requested, sf_item.holder); --- 13 unchanged lines hidden (view full) --- 295void 296SnoopFilter::updateResponse(const Packet* cpkt, const SlavePort& slave_port) 297{ 298 DPRINTF(SnoopFilter, "%s: packet src %s addr 0x%x cmd %s\n", 299 __func__, slave_port.name(), cpkt->getAddr(), cpkt->cmdString()); 300 301 assert(cpkt->isResponse()); 302 |
303 // Ultimately we should check if the packet came from an 304 // allocating source, not just if the port is snooping 305 bool allocate = !cpkt->req->isUncacheable() && slave_port.isSnooping(); 306 if (!allocate) |
307 return; 308 |
309 Addr line_addr = cpkt->getBlockAddr(linesize); |
310 SnoopMask slave_mask = portToMask(slave_port); 311 SnoopItem& sf_item = cachedLocations[line_addr]; 312 313 DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 314 __func__, sf_item.requested, sf_item.holder); 315 316 // Make sure we have seen the actual request, too 317 panic_if(!(sf_item.requested & slave_mask), "SF value %x.%x missing "\ --- 48 unchanged lines hidden --- |