cache.cc (11081:4d8b7783a692) | cache.cc (11127:f39c2cc0d44e) |
---|---|
1/* 2 * Copyright (c) 2010-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 --- 1716 unchanged lines hidden (view full) --- 1725 // Here we reset the timing of the packet. 1726 pkt->headerDelay = pkt->payloadDelay = 0; 1727 DPRINTF(Cache, "%s created response: %s addr %#llx size %d tick: %lu\n", 1728 __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize(), 1729 forward_time); 1730 memSidePort->schedTimingSnoopResp(pkt, forward_time, true); 1731} 1732 | 1/* 2 * Copyright (c) 2010-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 --- 1716 unchanged lines hidden (view full) --- 1725 // Here we reset the timing of the packet. 1726 pkt->headerDelay = pkt->payloadDelay = 0; 1727 DPRINTF(Cache, "%s created response: %s addr %#llx size %d tick: %lu\n", 1728 __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize(), 1729 forward_time); 1730 memSidePort->schedTimingSnoopResp(pkt, forward_time, true); 1731} 1732 |
1733void | 1733uint32_t |
1734Cache::handleSnoop(PacketPtr pkt, CacheBlk *blk, bool is_timing, 1735 bool is_deferred, bool pending_inval) 1736{ 1737 DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__, 1738 pkt->cmdString(), pkt->getAddr(), pkt->getSize()); 1739 // deferred snoops can only happen in timing mode 1740 assert(!(is_deferred && !is_timing)); 1741 // pending_inval only makes sense on deferred snoops 1742 assert(!(pending_inval && !is_deferred)); 1743 assert(pkt->isRequest()); 1744 1745 // the packet may get modified if we or a forwarded snooper 1746 // responds in atomic mode, so remember a few things about the 1747 // original packet up front 1748 bool invalidate = pkt->isInvalidate(); 1749 bool M5_VAR_USED needs_exclusive = pkt->needsExclusive(); 1750 | 1734Cache::handleSnoop(PacketPtr pkt, CacheBlk *blk, bool is_timing, 1735 bool is_deferred, bool pending_inval) 1736{ 1737 DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__, 1738 pkt->cmdString(), pkt->getAddr(), pkt->getSize()); 1739 // deferred snoops can only happen in timing mode 1740 assert(!(is_deferred && !is_timing)); 1741 // pending_inval only makes sense on deferred snoops 1742 assert(!(pending_inval && !is_deferred)); 1743 assert(pkt->isRequest()); 1744 1745 // the packet may get modified if we or a forwarded snooper 1746 // responds in atomic mode, so remember a few things about the 1747 // original packet up front 1748 bool invalidate = pkt->isInvalidate(); 1749 bool M5_VAR_USED needs_exclusive = pkt->needsExclusive(); 1750 |
1751 uint32_t snoop_delay = 0; 1752 |
|
1751 if (forwardSnoops) { 1752 // first propagate snoop upward to see if anyone above us wants to 1753 // handle it. save & restore packet src since it will get 1754 // rewritten to be relative to cpu-side bus (if any) 1755 bool alreadyResponded = pkt->memInhibitAsserted(); 1756 if (is_timing) { 1757 // copy the packet so that we can clear any flags before 1758 // forwarding it upwards, we also allocate data (passing 1759 // the pointer along in case of static data), in case 1760 // there is a snoop hit in upper levels 1761 Packet snoopPkt(pkt, true, true); 1762 snoopPkt.setExpressSnoop(); 1763 snoopPkt.pushSenderState(new ForwardResponseRecord()); 1764 // the snoop packet does not need to wait any additional 1765 // time 1766 snoopPkt.headerDelay = snoopPkt.payloadDelay = 0; 1767 cpuSidePort->sendTimingSnoopReq(&snoopPkt); | 1753 if (forwardSnoops) { 1754 // first propagate snoop upward to see if anyone above us wants to 1755 // handle it. save & restore packet src since it will get 1756 // rewritten to be relative to cpu-side bus (if any) 1757 bool alreadyResponded = pkt->memInhibitAsserted(); 1758 if (is_timing) { 1759 // copy the packet so that we can clear any flags before 1760 // forwarding it upwards, we also allocate data (passing 1761 // the pointer along in case of static data), in case 1762 // there is a snoop hit in upper levels 1763 Packet snoopPkt(pkt, true, true); 1764 snoopPkt.setExpressSnoop(); 1765 snoopPkt.pushSenderState(new ForwardResponseRecord()); 1766 // the snoop packet does not need to wait any additional 1767 // time 1768 snoopPkt.headerDelay = snoopPkt.payloadDelay = 0; 1769 cpuSidePort->sendTimingSnoopReq(&snoopPkt); |
1770 1771 // add the header delay (including crossbar and snoop 1772 // delays) of the upward snoop to the snoop delay for this 1773 // cache 1774 snoop_delay += snoopPkt.headerDelay; 1775 |
|
1768 if (snoopPkt.memInhibitAsserted()) { 1769 // cache-to-cache response from some upper cache 1770 assert(!alreadyResponded); 1771 pkt->assertMemInhibit(); 1772 } else { 1773 // no cache (or anyone else for that matter) will 1774 // respond, so delete the ForwardResponseRecord here 1775 delete snoopPkt.popSenderState(); --- 15 unchanged lines hidden (view full) --- 1791 assert(pkt->isResponse()); 1792 } 1793 } 1794 } 1795 1796 if (!blk || !blk->isValid()) { 1797 DPRINTF(Cache, "%s snoop miss for %s addr %#llx size %d\n", 1798 __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize()); | 1776 if (snoopPkt.memInhibitAsserted()) { 1777 // cache-to-cache response from some upper cache 1778 assert(!alreadyResponded); 1779 pkt->assertMemInhibit(); 1780 } else { 1781 // no cache (or anyone else for that matter) will 1782 // respond, so delete the ForwardResponseRecord here 1783 delete snoopPkt.popSenderState(); --- 15 unchanged lines hidden (view full) --- 1799 assert(pkt->isResponse()); 1800 } 1801 } 1802 } 1803 1804 if (!blk || !blk->isValid()) { 1805 DPRINTF(Cache, "%s snoop miss for %s addr %#llx size %d\n", 1806 __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize()); |
1799 return; | 1807 return snoop_delay; |
1800 } else { 1801 DPRINTF(Cache, "%s snoop hit for %s for addr %#llx size %d, " 1802 "old state is %s\n", __func__, pkt->cmdString(), 1803 pkt->getAddr(), pkt->getSize(), blk->print()); 1804 } 1805 1806 chatty_assert(!(isReadOnly && blk->isDirty()), 1807 "Should never have a dirty block in a read-only cache %s\n", --- 11 unchanged lines hidden (view full) --- 1819 // Invalidate any prefetch's from below that would strip write permissions 1820 // MemCmd::HardPFReq is only observed by upstream caches. After missing 1821 // above and in it's own cache, a new MemCmd::ReadReq is created that 1822 // downstream caches observe. 1823 if (pkt->mustCheckAbove()) { 1824 DPRINTF(Cache, "Found addr %#llx in upper level cache for snoop %s from" 1825 " lower cache\n", pkt->getAddr(), pkt->cmdString()); 1826 pkt->setBlockCached(); | 1808 } else { 1809 DPRINTF(Cache, "%s snoop hit for %s for addr %#llx size %d, " 1810 "old state is %s\n", __func__, pkt->cmdString(), 1811 pkt->getAddr(), pkt->getSize(), blk->print()); 1812 } 1813 1814 chatty_assert(!(isReadOnly && blk->isDirty()), 1815 "Should never have a dirty block in a read-only cache %s\n", --- 11 unchanged lines hidden (view full) --- 1827 // Invalidate any prefetch's from below that would strip write permissions 1828 // MemCmd::HardPFReq is only observed by upstream caches. After missing 1829 // above and in it's own cache, a new MemCmd::ReadReq is created that 1830 // downstream caches observe. 1831 if (pkt->mustCheckAbove()) { 1832 DPRINTF(Cache, "Found addr %#llx in upper level cache for snoop %s from" 1833 " lower cache\n", pkt->getAddr(), pkt->cmdString()); 1834 pkt->setBlockCached(); |
1827 return; | 1835 return snoop_delay; |
1828 } 1829 1830 if (!pkt->req->isUncacheable() && pkt->isRead() && !invalidate) { 1831 // reading non-exclusive shared data, note that we retain 1832 // the block in owned state if it is dirty, with the response 1833 // taken care of below, and otherwhise simply downgrade to 1834 // shared 1835 assert(!needs_exclusive); --- 43 unchanged lines hidden (view full) --- 1879 // like that 1880 if (invalidate) { 1881 if (blk != tempBlock) 1882 tags->invalidate(blk); 1883 blk->invalidate(); 1884 } 1885 1886 DPRINTF(Cache, "new state is %s\n", blk->print()); | 1836 } 1837 1838 if (!pkt->req->isUncacheable() && pkt->isRead() && !invalidate) { 1839 // reading non-exclusive shared data, note that we retain 1840 // the block in owned state if it is dirty, with the response 1841 // taken care of below, and otherwhise simply downgrade to 1842 // shared 1843 assert(!needs_exclusive); --- 43 unchanged lines hidden (view full) --- 1887 // like that 1888 if (invalidate) { 1889 if (blk != tempBlock) 1890 tags->invalidate(blk); 1891 blk->invalidate(); 1892 } 1893 1894 DPRINTF(Cache, "new state is %s\n", blk->print()); |
1895 1896 return snoop_delay; |
|
1887} 1888 1889 1890void 1891Cache::recvTimingSnoopReq(PacketPtr pkt) 1892{ 1893 DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__, 1894 pkt->cmdString(), pkt->getAddr(), pkt->getSize()); --- 7 unchanged lines hidden (view full) --- 1902 } 1903 1904 bool is_secure = pkt->isSecure(); 1905 CacheBlk *blk = tags->findBlock(pkt->getAddr(), is_secure); 1906 1907 Addr blk_addr = blockAlign(pkt->getAddr()); 1908 MSHR *mshr = mshrQueue.findMatch(blk_addr, is_secure); 1909 | 1897} 1898 1899 1900void 1901Cache::recvTimingSnoopReq(PacketPtr pkt) 1902{ 1903 DPRINTF(Cache, "%s for %s addr %#llx size %d\n", __func__, 1904 pkt->cmdString(), pkt->getAddr(), pkt->getSize()); --- 7 unchanged lines hidden (view full) --- 1912 } 1913 1914 bool is_secure = pkt->isSecure(); 1915 CacheBlk *blk = tags->findBlock(pkt->getAddr(), is_secure); 1916 1917 Addr blk_addr = blockAlign(pkt->getAddr()); 1918 MSHR *mshr = mshrQueue.findMatch(blk_addr, is_secure); 1919 |
1920 // Update the latency cost of the snoop so that the crossbar can 1921 // account for it. Do not overwrite what other neighbouring caches 1922 // have already done, rather take the maximum. The update is 1923 // tentative, for cases where we return before an upward snoop 1924 // happens below. 1925 pkt->snoopDelay = std::max<uint32_t>(pkt->snoopDelay, 1926 lookupLatency * clockPeriod()); 1927 |
|
1910 // Inform request(Prefetch, CleanEvict or Writeback) from below of 1911 // MSHR hit, set setBlockCached. 1912 if (mshr && pkt->mustCheckAbove()) { 1913 DPRINTF(Cache, "Setting block cached for %s from" 1914 "lower cache on mshr hit %#x\n", 1915 pkt->cmdString(), pkt->getAddr()); 1916 pkt->setBlockCached(); 1917 return; --- 81 unchanged lines hidden (view full) --- 1999 } 2000 } 2001 2002 // If this was a shared writeback, there may still be 2003 // other shared copies above that require invalidation. 2004 // We could be more selective and return here if the 2005 // request is non-exclusive or if the writeback is 2006 // exclusive. | 1928 // Inform request(Prefetch, CleanEvict or Writeback) from below of 1929 // MSHR hit, set setBlockCached. 1930 if (mshr && pkt->mustCheckAbove()) { 1931 DPRINTF(Cache, "Setting block cached for %s from" 1932 "lower cache on mshr hit %#x\n", 1933 pkt->cmdString(), pkt->getAddr()); 1934 pkt->setBlockCached(); 1935 return; --- 81 unchanged lines hidden (view full) --- 2017 } 2018 } 2019 2020 // If this was a shared writeback, there may still be 2021 // other shared copies above that require invalidation. 2022 // We could be more selective and return here if the 2023 // request is non-exclusive or if the writeback is 2024 // exclusive. |
2007 handleSnoop(pkt, blk, true, false, false); | 2025 uint32_t snoop_delay = handleSnoop(pkt, blk, true, false, false); 2026 2027 // Override what we did when we first saw the snoop, as we now 2028 // also have the cost of the upwards snoops to account for 2029 pkt->snoopDelay = std::max<uint32_t>(pkt->snoopDelay, snoop_delay + 2030 lookupLatency * clockPeriod()); |
2008} 2009 2010bool 2011Cache::CpuSidePort::recvTimingSnoopResp(PacketPtr pkt) 2012{ 2013 // Express snoop responses from master to slave, e.g., from L1 to L2 2014 cache->recvTimingSnoopResp(pkt); 2015 return true; --- 9 unchanged lines hidden (view full) --- 2025 // atomic we have no Writebacks/CleanEvicts queued and no prefetches, 2026 // hence there is no need to snoop upwards and determine if they are 2027 // present above. 2028 if (pkt->evictingBlock() || !inRange(pkt->getAddr())) { 2029 return 0; 2030 } 2031 2032 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure()); | 2031} 2032 2033bool 2034Cache::CpuSidePort::recvTimingSnoopResp(PacketPtr pkt) 2035{ 2036 // Express snoop responses from master to slave, e.g., from L1 to L2 2037 cache->recvTimingSnoopResp(pkt); 2038 return true; --- 9 unchanged lines hidden (view full) --- 2048 // atomic we have no Writebacks/CleanEvicts queued and no prefetches, 2049 // hence there is no need to snoop upwards and determine if they are 2050 // present above. 2051 if (pkt->evictingBlock() || !inRange(pkt->getAddr())) { 2052 return 0; 2053 } 2054 2055 CacheBlk *blk = tags->findBlock(pkt->getAddr(), pkt->isSecure()); |
2033 handleSnoop(pkt, blk, false, false, false); 2034 // We consider forwardLatency here because a snoop occurs in atomic mode 2035 return forwardLatency * clockPeriod(); | 2056 uint32_t snoop_delay = handleSnoop(pkt, blk, false, false, false); 2057 return snoop_delay + lookupLatency * clockPeriod(); |
2036} 2037 2038 2039MSHR * 2040Cache::getNextMSHR() 2041{ 2042 // Check both MSHR queue and write buffer for potential requests, 2043 // note that null does not mean there is no request, it could --- 446 unchanged lines hidden --- | 2058} 2059 2060 2061MSHR * 2062Cache::getNextMSHR() 2063{ 2064 // Check both MSHR queue and write buffer for potential requests, 2065 // note that null does not mean there is no request, it could --- 446 unchanged lines hidden --- |