coherent_xbar.cc (12346:9b1144d046ca) | coherent_xbar.cc (12351:17eaa27bef22) |
---|---|
1/* 2 * Copyright (c) 2011-2017 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 --- 26 unchanged lines hidden (view full) --- 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Ali Saidi 41 * Andreas Hansson 42 * William Wang | 1/* 2 * Copyright (c) 2011-2017 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 --- 26 unchanged lines hidden (view full) --- 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Ali Saidi 41 * Andreas Hansson 42 * William Wang |
43 * Nikos Nikoleris |
|
43 */ 44 45/** 46 * @file 47 * Definition of a crossbar object. 48 */ 49 50#include "mem/coherent_xbar.hh" --- 138 unchanged lines hidden (view full) --- 189 // the request 190 const bool is_destination = isDestination(pkt); 191 192 const bool snoop_caches = !system->bypassCaches() && 193 pkt->cmd != MemCmd::WriteClean; 194 if (snoop_caches) { 195 assert(pkt->snoopDelay == 0); 196 | 44 */ 45 46/** 47 * @file 48 * Definition of a crossbar object. 49 */ 50 51#include "mem/coherent_xbar.hh" --- 138 unchanged lines hidden (view full) --- 190 // the request 191 const bool is_destination = isDestination(pkt); 192 193 const bool snoop_caches = !system->bypassCaches() && 194 pkt->cmd != MemCmd::WriteClean; 195 if (snoop_caches) { 196 assert(pkt->snoopDelay == 0); 197 |
198 if (pkt->isClean() && !is_destination) { 199 // before snooping we need to make sure that the memory 200 // below is not busy and the cache clean request can be 201 // forwarded to it 202 if (!masterPorts[master_port_id]->tryTiming(pkt)) { 203 DPRINTF(CoherentXBar, "%s: src %s packet %s RETRY\n", __func__, 204 src_port->name(), pkt->print()); 205 206 // update the layer state and schedule an idle event 207 reqLayers[master_port_id]->failedTiming(src_port, 208 clockEdge(Cycles(1))); 209 return false; 210 } 211 } 212 213 |
|
197 // the packet is a memory-mapped request and should be 198 // broadcasted to our snoopers but the source 199 if (snoopFilter) { 200 // check with the snoop filter where to forward this packet 201 auto sf_res = snoopFilter->lookupRequest(pkt, *src_port); 202 // the time required by a packet to be delivered through 203 // the xbar has to be charged also with to lookup latency 204 // of the snoop filter --- 132 unchanged lines hidden (view full) --- 337 snoopTraffic += pkt_size; 338 } 339 } 340 341 if (sink_packet) 342 // queue the packet for deletion 343 pendingDelete.reset(pkt); 344 | 214 // the packet is a memory-mapped request and should be 215 // broadcasted to our snoopers but the source 216 if (snoopFilter) { 217 // check with the snoop filter where to forward this packet 218 auto sf_res = snoopFilter->lookupRequest(pkt, *src_port); 219 // the time required by a packet to be delivered through 220 // the xbar has to be charged also with to lookup latency 221 // of the snoop filter --- 132 unchanged lines hidden (view full) --- 354 snoopTraffic += pkt_size; 355 } 356 } 357 358 if (sink_packet) 359 // queue the packet for deletion 360 pendingDelete.reset(pkt); 361 |
362 // normally we respond to the packet we just received if we need to 363 PacketPtr rsp_pkt = pkt; 364 PortID rsp_port_id = slave_port_id; 365 366 // If this is the destination of the cache clean operation the 367 // crossbar is responsible for responding. This crossbar will 368 // respond when the cache clean is complete. A cache clean 369 // is complete either: 370 // * direcly, if no cache above had a dirty copy of the block 371 // as indicated by the satisfied flag of the packet, or 372 // * when the crossbar has seen both the cache clean request 373 // (CleanSharedReq, CleanInvalidReq) and the corresponding 374 // write (WriteClean) which updates the block in the memory 375 // below. 376 if (success && 377 ((pkt->isClean() && pkt->satisfied()) || 378 pkt->cmd == MemCmd::WriteClean) && 379 is_destination) { 380 PacketPtr deferred_rsp = pkt->isWrite() ? nullptr : pkt; 381 auto cmo_lookup = outstandingCMO.find(pkt->id); 382 if (cmo_lookup != outstandingCMO.end()) { 383 // the cache clean request has already reached this xbar 384 respond_directly = true; 385 if (pkt->isWrite()) { 386 rsp_pkt = cmo_lookup->second; 387 assert(rsp_pkt); 388 389 // determine the destination 390 const auto route_lookup = routeTo.find(rsp_pkt->req); 391 assert(route_lookup != routeTo.end()); 392 rsp_port_id = route_lookup->second; 393 assert(rsp_port_id != InvalidPortID); 394 assert(rsp_port_id < respLayers.size()); 395 // remove the request from the routing table 396 routeTo.erase(route_lookup); 397 } 398 outstandingCMO.erase(cmo_lookup); 399 } else { 400 respond_directly = false; 401 outstandingCMO.emplace(pkt->id, deferred_rsp); 402 if (!pkt->isWrite()) { 403 assert(routeTo.find(pkt->req) == routeTo.end()); 404 routeTo[pkt->req] = slave_port_id; 405 406 panic_if(routeTo.size() > 512, 407 "Routing table exceeds 512 packets\n"); 408 } 409 } 410 } 411 412 |
|
345 if (respond_directly) { | 413 if (respond_directly) { |
346 assert(pkt->needsResponse()); | 414 assert(rsp_pkt->needsResponse()); |
347 assert(success); 348 | 415 assert(success); 416 |
349 pkt->makeResponse(); | 417 rsp_pkt->makeResponse(); |
350 351 if (snoopFilter && !system->bypassCaches()) { 352 // let the snoop filter inspect the response and update its state | 418 419 if (snoopFilter && !system->bypassCaches()) { 420 // let the snoop filter inspect the response and update its state |
353 snoopFilter->updateResponse(pkt, *slavePorts[slave_port_id]); | 421 snoopFilter->updateResponse(rsp_pkt, *slavePorts[rsp_port_id]); |
354 } 355 | 422 } 423 |
424 // we send the response after the current packet, even if the 425 // response is not for this packet (e.g. cache clean operation 426 // where both the request and the write packet have to cross 427 // the destination xbar before the response is sent.) |
|
356 Tick response_time = clockEdge() + pkt->headerDelay; | 428 Tick response_time = clockEdge() + pkt->headerDelay; |
357 pkt->headerDelay = 0; | 429 rsp_pkt->headerDelay = 0; |
358 | 430 |
359 slavePorts[slave_port_id]->schedTimingResp(pkt, response_time); | 431 slavePorts[rsp_port_id]->schedTimingResp(rsp_pkt, response_time); |
360 } 361 362 return success; 363} 364 365bool 366CoherentXBar::recvTimingResp(PacketPtr pkt, PortID master_port_id) 367{ --- 381 unchanged lines hidden (view full) --- 749 // if we got a response from a snooper, restore it here 750 if (snoop_response_cmd != MemCmd::InvalidCmd) { 751 // no one else should have responded 752 assert(!pkt->isResponse()); 753 pkt->cmd = snoop_response_cmd; 754 response_latency = snoop_response_latency; 755 } 756 | 432 } 433 434 return success; 435} 436 437bool 438CoherentXBar::recvTimingResp(PacketPtr pkt, PortID master_port_id) 439{ --- 381 unchanged lines hidden (view full) --- 821 // if we got a response from a snooper, restore it here 822 if (snoop_response_cmd != MemCmd::InvalidCmd) { 823 // no one else should have responded 824 assert(!pkt->isResponse()); 825 pkt->cmd = snoop_response_cmd; 826 response_latency = snoop_response_latency; 827 } 828 |
829 // If this is the destination of the cache clean operation the 830 // crossbar is responsible for responding. This crossbar will 831 // respond when the cache clean is complete. An atomic cache clean 832 // is complete when the crossbars receives the cache clean 833 // request (CleanSharedReq, CleanInvalidReq), as either: 834 // * no cache above had a dirty copy of the block as indicated by 835 // the satisfied flag of the packet, or 836 // * the crossbar has already seen the corresponding write 837 // (WriteClean) which updates the block in the memory below. 838 if (pkt->isClean() && isDestination(pkt) && pkt->satisfied()) { 839 auto it = outstandingCMO.find(pkt->id); 840 assert(it != outstandingCMO.end()); 841 // we are responding right away 842 outstandingCMO.erase(it); 843 } else if (pkt->cmd == MemCmd::WriteClean && isDestination(pkt)) { 844 // if this is the destination of the operation, the xbar 845 // sends the responce to the cache clean operation only 846 // after having encountered the cache clean request 847 auto M5_VAR_USED ret = outstandingCMO.emplace(pkt->id, nullptr); 848 // in atomic mode we know that the WriteClean packet should 849 // precede the clean request 850 assert(ret.second); 851 } 852 |
|
757 // add the response data 758 if (pkt->isResponse()) { 759 pkt_size = pkt->hasData() ? pkt->getSize() : 0; 760 pkt_cmd = pkt->cmdToIndex(); 761 762 // stats updates 763 pktCount[slave_port_id][master_port_id]++; 764 pktSize[slave_port_id][master_port_id] += pkt_size; --- 218 unchanged lines hidden (view full) --- 983 (pkt->cacheResponding() && 984 (!pkt->needsWritable() || pkt->responderHadWritable())); 985} 986 987bool 988CoherentXBar::forwardPacket(const PacketPtr pkt) 989{ 990 // we are forwarding the packet if: | 853 // add the response data 854 if (pkt->isResponse()) { 855 pkt_size = pkt->hasData() ? pkt->getSize() : 0; 856 pkt_cmd = pkt->cmdToIndex(); 857 858 // stats updates 859 pktCount[slave_port_id][master_port_id]++; 860 pktSize[slave_port_id][master_port_id] += pkt_size; --- 218 unchanged lines hidden (view full) --- 1079 (pkt->cacheResponding() && 1080 (!pkt->needsWritable() || pkt->responderHadWritable())); 1081} 1082 1083bool 1084CoherentXBar::forwardPacket(const PacketPtr pkt) 1085{ 1086 // we are forwarding the packet if: |
991 // 1) this is a read or a write 992 // 2) this crossbar is above the point of coherency | 1087 // 1) this is a cache clean request to the PoU/PoC and this 1088 // crossbar is above the PoU/PoC 1089 // 2) this is a read or a write 1090 // 3) this crossbar is above the point of coherency 1091 if (pkt->isClean()) { 1092 return !isDestination(pkt); 1093 } |
993 return pkt->isRead() || pkt->isWrite() || !pointOfCoherency; 994} 995 996 997void 998CoherentXBar::regStats() 999{ 1000 // register the stats of the base class and our layers --- 30 unchanged lines hidden --- | 1094 return pkt->isRead() || pkt->isWrite() || !pointOfCoherency; 1095} 1096 1097 1098void 1099CoherentXBar::regStats() 1100{ 1101 // register the stats of the base class and our layers --- 30 unchanged lines hidden --- |