lsq_impl.hh revision 10575
16019Shines@cs.fsu.edu/* 26019Shines@cs.fsu.edu * Copyright (c) 2011-2012, 2014 ARM Limited 37178Sgblack@eecs.umich.edu * Copyright (c) 2013 Advanced Micro Devices, Inc. 47178Sgblack@eecs.umich.edu * All rights reserved 57178Sgblack@eecs.umich.edu * 67178Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 77178Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 87178Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 97178Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 107178Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 117178Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 127178Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 137178Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 147178Sgblack@eecs.umich.edu * 156019Shines@cs.fsu.edu * Copyright (c) 2005-2006 The Regents of The University of Michigan 166019Shines@cs.fsu.edu * All rights reserved. 176019Shines@cs.fsu.edu * 186019Shines@cs.fsu.edu * Redistribution and use in source and binary forms, with or without 196019Shines@cs.fsu.edu * modification, are permitted provided that the following conditions are 206019Shines@cs.fsu.edu * met: redistributions of source code must retain the above copyright 216019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer; 226019Shines@cs.fsu.edu * redistributions in binary form must reproduce the above copyright 236019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer in the 246019Shines@cs.fsu.edu * documentation and/or other materials provided with the distribution; 256019Shines@cs.fsu.edu * neither the name of the copyright holders nor the names of its 266019Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from 276019Shines@cs.fsu.edu * this software without specific prior written permission. 286019Shines@cs.fsu.edu * 296019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 306019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 326019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 336019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 346019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 356019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 366019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 376019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 386019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 396019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 406019Shines@cs.fsu.edu * 416019Shines@cs.fsu.edu * Authors: Korey Sewell 426019Shines@cs.fsu.edu */ 436019Shines@cs.fsu.edu 446019Shines@cs.fsu.edu#ifndef __CPU_O3_LSQ_IMPL_HH__ 456019Shines@cs.fsu.edu#define __CPU_O3_LSQ_IMPL_HH__ 466019Shines@cs.fsu.edu 476019Shines@cs.fsu.edu#include <algorithm> 486019Shines@cs.fsu.edu#include <list> 496019Shines@cs.fsu.edu#include <string> 506019Shines@cs.fsu.edu 516019Shines@cs.fsu.edu#include "cpu/o3/lsq.hh" 526019Shines@cs.fsu.edu#include "debug/Drain.hh" 536019Shines@cs.fsu.edu#include "debug/Fetch.hh" 546019Shines@cs.fsu.edu#include "debug/LSQ.hh" 556019Shines@cs.fsu.edu#include "debug/Writeback.hh" 566019Shines@cs.fsu.edu#include "params/DerivO3CPU.hh" 576019Shines@cs.fsu.edu 586243Sgblack@eecs.umich.eduusing namespace std; 596243Sgblack@eecs.umich.edu 606243Sgblack@eecs.umich.edutemplate <class Impl> 616243Sgblack@eecs.umich.eduLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) 626243Sgblack@eecs.umich.edu : cpu(cpu_ptr), iewStage(iew_ptr), 636019Shines@cs.fsu.edu LQEntries(params->LQEntries), 646019Shines@cs.fsu.edu SQEntries(params->SQEntries), 656019Shines@cs.fsu.edu numThreads(params->numThreads) 666019Shines@cs.fsu.edu{ 676019Shines@cs.fsu.edu assert(numThreads > 0 && numThreads <= Impl::MaxThreads); 686019Shines@cs.fsu.edu 696019Shines@cs.fsu.edu //**********************************************/ 706019Shines@cs.fsu.edu //************ Handle SMT Parameters ***********/ 716019Shines@cs.fsu.edu //**********************************************/ 726019Shines@cs.fsu.edu std::string policy = params->smtLSQPolicy; 736019Shines@cs.fsu.edu 746019Shines@cs.fsu.edu //Convert string to lowercase 756019Shines@cs.fsu.edu std::transform(policy.begin(), policy.end(), policy.begin(), 766019Shines@cs.fsu.edu (int(*)(int)) tolower); 776019Shines@cs.fsu.edu 786019Shines@cs.fsu.edu //Figure out fetch policy 796019Shines@cs.fsu.edu if (policy == "dynamic") { 806019Shines@cs.fsu.edu lsqPolicy = Dynamic; 816019Shines@cs.fsu.edu 826019Shines@cs.fsu.edu maxLQEntries = LQEntries; 836019Shines@cs.fsu.edu maxSQEntries = SQEntries; 846019Shines@cs.fsu.edu 856019Shines@cs.fsu.edu DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 866019Shines@cs.fsu.edu } else if (policy == "partitioned") { 876019Shines@cs.fsu.edu lsqPolicy = Partitioned; 886019Shines@cs.fsu.edu 896019Shines@cs.fsu.edu //@todo:make work if part_amt doesnt divide evenly. 906019Shines@cs.fsu.edu maxLQEntries = LQEntries / numThreads; 916019Shines@cs.fsu.edu maxSQEntries = SQEntries / numThreads; 926019Shines@cs.fsu.edu 936019Shines@cs.fsu.edu DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 946252Sgblack@eecs.umich.edu "%i entries per LQ | %i entries per SQ\n", 956243Sgblack@eecs.umich.edu maxLQEntries,maxSQEntries); 966243Sgblack@eecs.umich.edu } else if (policy == "threshold") { 976243Sgblack@eecs.umich.edu lsqPolicy = Threshold; 986019Shines@cs.fsu.edu 996019Shines@cs.fsu.edu assert(params->smtLSQThreshold > LQEntries); 1006019Shines@cs.fsu.edu assert(params->smtLSQThreshold > SQEntries); 1016019Shines@cs.fsu.edu 1026019Shines@cs.fsu.edu //Divide up by threshold amount 1036252Sgblack@eecs.umich.edu //@todo: Should threads check the max and the total 1046243Sgblack@eecs.umich.edu //amount of the LSQ 1056243Sgblack@eecs.umich.edu maxLQEntries = params->smtLSQThreshold; 1066243Sgblack@eecs.umich.edu maxSQEntries = params->smtLSQThreshold; 1076019Shines@cs.fsu.edu 1086019Shines@cs.fsu.edu DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 1096019Shines@cs.fsu.edu "%i entries per LQ | %i entries per SQ\n", 1106019Shines@cs.fsu.edu maxLQEntries,maxSQEntries); 1116019Shines@cs.fsu.edu } else { 1126019Shines@cs.fsu.edu assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic," 1136019Shines@cs.fsu.edu "Partitioned, Threshold}"); 1146252Sgblack@eecs.umich.edu } 1156243Sgblack@eecs.umich.edu 1166243Sgblack@eecs.umich.edu //Initialize LSQs 1176243Sgblack@eecs.umich.edu thread = new LSQUnit[numThreads]; 1186019Shines@cs.fsu.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 1196019Shines@cs.fsu.edu thread[tid].init(cpu, iew_ptr, params, this, 1206019Shines@cs.fsu.edu maxLQEntries, maxSQEntries, tid); 1216019Shines@cs.fsu.edu thread[tid].setDcachePort(&cpu_ptr->getDataPort()); 1226019Shines@cs.fsu.edu } 1236019Shines@cs.fsu.edu} 1246019Shines@cs.fsu.edu 1256019Shines@cs.fsu.edu 1266019Shines@cs.fsu.edutemplate<class Impl> 1276019Shines@cs.fsu.edustd::string 1286019Shines@cs.fsu.eduLSQ<Impl>::name() const 1296019Shines@cs.fsu.edu{ 1306019Shines@cs.fsu.edu return iewStage->name() + ".lsq"; 1316019Shines@cs.fsu.edu} 1326019Shines@cs.fsu.edu 1336019Shines@cs.fsu.edutemplate<class Impl> 1346724Sgblack@eecs.umich.eduvoid 1356724Sgblack@eecs.umich.eduLSQ<Impl>::regStats() 1366019Shines@cs.fsu.edu{ 1376019Shines@cs.fsu.edu //Initialize LSQs 1386019Shines@cs.fsu.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 1396019Shines@cs.fsu.edu thread[tid].regStats(); 1406019Shines@cs.fsu.edu } 1416252Sgblack@eecs.umich.edu} 1426243Sgblack@eecs.umich.edu 1436243Sgblack@eecs.umich.edutemplate<class Impl> 1446243Sgblack@eecs.umich.eduvoid 1456019Shines@cs.fsu.eduLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 1466019Shines@cs.fsu.edu{ 1476019Shines@cs.fsu.edu activeThreads = at_ptr; 1486019Shines@cs.fsu.edu assert(activeThreads != 0); 1496019Shines@cs.fsu.edu} 1506019Shines@cs.fsu.edu 1517356Sgblack@eecs.umich.edutemplate <class Impl> 1527356Sgblack@eecs.umich.eduvoid 1537356Sgblack@eecs.umich.eduLSQ<Impl>::drainSanityCheck() const 1547356Sgblack@eecs.umich.edu{ 1557356Sgblack@eecs.umich.edu assert(isDrained()); 1567356Sgblack@eecs.umich.edu 1577356Sgblack@eecs.umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) 1587356Sgblack@eecs.umich.edu thread[tid].drainSanityCheck(); 1597178Sgblack@eecs.umich.edu} 1607178Sgblack@eecs.umich.edu 1617178Sgblack@eecs.umich.edutemplate <class Impl> 1627337Sgblack@eecs.umich.edubool 1637178Sgblack@eecs.umich.eduLSQ<Impl>::isDrained() const 1647178Sgblack@eecs.umich.edu{ 1657178Sgblack@eecs.umich.edu bool drained(true); 1667178Sgblack@eecs.umich.edu 1677178Sgblack@eecs.umich.edu if (!lqEmpty()) { 1687178Sgblack@eecs.umich.edu DPRINTF(Drain, "Not drained, LQ not empty.\n"); 1697178Sgblack@eecs.umich.edu drained = false; 1707178Sgblack@eecs.umich.edu } 1717178Sgblack@eecs.umich.edu 1727178Sgblack@eecs.umich.edu if (!sqEmpty()) { 1737178Sgblack@eecs.umich.edu DPRINTF(Drain, "Not drained, SQ not empty.\n"); 1747335Sgblack@eecs.umich.edu drained = false; 1757335Sgblack@eecs.umich.edu } 1767335Sgblack@eecs.umich.edu 1777335Sgblack@eecs.umich.edu return drained; 1787335Sgblack@eecs.umich.edu} 1797335Sgblack@eecs.umich.edu 1807335Sgblack@eecs.umich.edutemplate <class Impl> 1817335Sgblack@eecs.umich.eduvoid 1827335Sgblack@eecs.umich.eduLSQ<Impl>::takeOverFrom() 1837335Sgblack@eecs.umich.edu{ 1847335Sgblack@eecs.umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 1857335Sgblack@eecs.umich.edu thread[tid].takeOverFrom(); 1867337Sgblack@eecs.umich.edu } 1877335Sgblack@eecs.umich.edu} 1887335Sgblack@eecs.umich.edu 1897335Sgblack@eecs.umich.edutemplate <class Impl> 1907335Sgblack@eecs.umich.eduint 1917335Sgblack@eecs.umich.eduLSQ<Impl>::entryAmount(ThreadID num_threads) 1927335Sgblack@eecs.umich.edu{ 1937335Sgblack@eecs.umich.edu if (lsqPolicy == Partitioned) { 1947335Sgblack@eecs.umich.edu return LQEntries / num_threads; 1957335Sgblack@eecs.umich.edu } else { 1967335Sgblack@eecs.umich.edu return 0; 1977335Sgblack@eecs.umich.edu } 1987335Sgblack@eecs.umich.edu} 1997178Sgblack@eecs.umich.edu 2007178Sgblack@eecs.umich.edutemplate <class Impl> 2017178Sgblack@eecs.umich.eduvoid 2027178Sgblack@eecs.umich.eduLSQ<Impl>::resetEntries() 2037178Sgblack@eecs.umich.edu{ 2047178Sgblack@eecs.umich.edu if (lsqPolicy != Dynamic || numThreads > 1) { 2057178Sgblack@eecs.umich.edu int active_threads = activeThreads->size(); 2067178Sgblack@eecs.umich.edu 2077178Sgblack@eecs.umich.edu int maxEntries; 2087178Sgblack@eecs.umich.edu 2097178Sgblack@eecs.umich.edu if (lsqPolicy == Partitioned) { 2107178Sgblack@eecs.umich.edu maxEntries = LQEntries / active_threads; 2117178Sgblack@eecs.umich.edu } else if (lsqPolicy == Threshold && active_threads == 1) { 2127178Sgblack@eecs.umich.edu maxEntries = LQEntries; 2137178Sgblack@eecs.umich.edu } else { 2147178Sgblack@eecs.umich.edu maxEntries = LQEntries; 2157178Sgblack@eecs.umich.edu } 2167178Sgblack@eecs.umich.edu 2177178Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 2187178Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 2197178Sgblack@eecs.umich.edu 2207178Sgblack@eecs.umich.edu while (threads != end) { 2217178Sgblack@eecs.umich.edu ThreadID tid = *threads++; 2227178Sgblack@eecs.umich.edu 2237178Sgblack@eecs.umich.edu resizeEntries(maxEntries, tid); 2247178Sgblack@eecs.umich.edu } 2257178Sgblack@eecs.umich.edu } 2267178Sgblack@eecs.umich.edu} 2277178Sgblack@eecs.umich.edu 2287346Sgblack@eecs.umich.edutemplate<class Impl> 2297346Sgblack@eecs.umich.eduvoid 2307346Sgblack@eecs.umich.eduLSQ<Impl>::removeEntries(ThreadID tid) 2317346Sgblack@eecs.umich.edu{ 2327346Sgblack@eecs.umich.edu thread[tid].clearLQ(); 2337346Sgblack@eecs.umich.edu thread[tid].clearSQ(); 2347346Sgblack@eecs.umich.edu} 2357346Sgblack@eecs.umich.edu 2367346Sgblack@eecs.umich.edutemplate<class Impl> 2377346Sgblack@eecs.umich.eduvoid 2387178Sgblack@eecs.umich.eduLSQ<Impl>::resizeEntries(unsigned size, ThreadID tid) 2397346Sgblack@eecs.umich.edu{ 2407346Sgblack@eecs.umich.edu thread[tid].resizeLQ(size); 2417346Sgblack@eecs.umich.edu thread[tid].resizeSQ(size); 2427346Sgblack@eecs.umich.edu} 2437346Sgblack@eecs.umich.edu 2447346Sgblack@eecs.umich.edutemplate<class Impl> 2457346Sgblack@eecs.umich.eduvoid 2467346Sgblack@eecs.umich.eduLSQ<Impl>::tick() 2477346Sgblack@eecs.umich.edu{ 2487346Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 2497346Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 2507346Sgblack@eecs.umich.edu 2517346Sgblack@eecs.umich.edu while (threads != end) { 2527346Sgblack@eecs.umich.edu ThreadID tid = *threads++; 2537346Sgblack@eecs.umich.edu 2547178Sgblack@eecs.umich.edu thread[tid].tick(); 2557337Sgblack@eecs.umich.edu } 2567337Sgblack@eecs.umich.edu} 2577337Sgblack@eecs.umich.edu 2587337Sgblack@eecs.umich.edutemplate<class Impl> 2597337Sgblack@eecs.umich.eduvoid 2607337Sgblack@eecs.umich.eduLSQ<Impl>::insertLoad(DynInstPtr &load_inst) 2617337Sgblack@eecs.umich.edu{ 2627337Sgblack@eecs.umich.edu ThreadID tid = load_inst->threadNumber; 2637337Sgblack@eecs.umich.edu 2647337Sgblack@eecs.umich.edu thread[tid].insertLoad(load_inst); 2657337Sgblack@eecs.umich.edu} 2667337Sgblack@eecs.umich.edu 2677337Sgblack@eecs.umich.edutemplate<class Impl> 2687337Sgblack@eecs.umich.eduvoid 2697337Sgblack@eecs.umich.eduLSQ<Impl>::insertStore(DynInstPtr &store_inst) 2707178Sgblack@eecs.umich.edu{ 2717178Sgblack@eecs.umich.edu ThreadID tid = store_inst->threadNumber; 2727178Sgblack@eecs.umich.edu 2737178Sgblack@eecs.umich.edu thread[tid].insertStore(store_inst); 2747337Sgblack@eecs.umich.edu} 2757337Sgblack@eecs.umich.edu 2767337Sgblack@eecs.umich.edutemplate<class Impl> 2777337Sgblack@eecs.umich.eduFault 2787346Sgblack@eecs.umich.eduLSQ<Impl>::executeLoad(DynInstPtr &inst) 2797346Sgblack@eecs.umich.edu{ 2807346Sgblack@eecs.umich.edu ThreadID tid = inst->threadNumber; 2817346Sgblack@eecs.umich.edu 2827346Sgblack@eecs.umich.edu return thread[tid].executeLoad(inst); 2837337Sgblack@eecs.umich.edu} 2847178Sgblack@eecs.umich.edu 2857321Sgblack@eecs.umich.edutemplate<class Impl> 2867356Sgblack@eecs.umich.eduFault 2877321Sgblack@eecs.umich.eduLSQ<Impl>::executeStore(DynInstPtr &inst) 2887356Sgblack@eecs.umich.edu{ 2897356Sgblack@eecs.umich.edu ThreadID tid = inst->threadNumber; 2907356Sgblack@eecs.umich.edu 2917356Sgblack@eecs.umich.edu return thread[tid].executeStore(inst); 2927356Sgblack@eecs.umich.edu} 2937356Sgblack@eecs.umich.edu 2947356Sgblack@eecs.umich.edutemplate<class Impl> 2957356Sgblack@eecs.umich.eduvoid 2967356Sgblack@eecs.umich.eduLSQ<Impl>::writebackStores() 2977356Sgblack@eecs.umich.edu{ 2987356Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 2997356Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 3007321Sgblack@eecs.umich.edu 3017321Sgblack@eecs.umich.edu while (threads != end) { 3027321Sgblack@eecs.umich.edu ThreadID tid = *threads++; 3037321Sgblack@eecs.umich.edu 3047321Sgblack@eecs.umich.edu if (numStoresToWB(tid) > 0) { 3057321Sgblack@eecs.umich.edu DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores " 3067321Sgblack@eecs.umich.edu "available for Writeback.\n", tid, numStoresToWB(tid)); 3077321Sgblack@eecs.umich.edu } 3087321Sgblack@eecs.umich.edu 3097321Sgblack@eecs.umich.edu thread[tid].writebackStores(); 3107321Sgblack@eecs.umich.edu } 3117335Sgblack@eecs.umich.edu} 3127335Sgblack@eecs.umich.edu 3137335Sgblack@eecs.umich.edutemplate<class Impl> 3147335Sgblack@eecs.umich.edubool 3157335Sgblack@eecs.umich.eduLSQ<Impl>::violation() 3167335Sgblack@eecs.umich.edu{ 3177335Sgblack@eecs.umich.edu /* Answers: Does Anybody Have a Violation?*/ 3187335Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 3197335Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 3207321Sgblack@eecs.umich.edu 3217323Sgblack@eecs.umich.edu while (threads != end) { 3227323Sgblack@eecs.umich.edu ThreadID tid = *threads++; 3237323Sgblack@eecs.umich.edu 3247323Sgblack@eecs.umich.edu if (thread[tid].violation()) 3257323Sgblack@eecs.umich.edu return true; 3267323Sgblack@eecs.umich.edu } 3277323Sgblack@eecs.umich.edu 3287323Sgblack@eecs.umich.edu return false; 3297323Sgblack@eecs.umich.edu} 3307323Sgblack@eecs.umich.edu 3317323Sgblack@eecs.umich.edutemplate <class Impl> 3327323Sgblack@eecs.umich.eduvoid 3337323Sgblack@eecs.umich.eduLSQ<Impl>::recvRetry() 3347323Sgblack@eecs.umich.edu{ 3357323Sgblack@eecs.umich.edu iewStage->cacheUnblocked(); 3367323Sgblack@eecs.umich.edu 3377323Sgblack@eecs.umich.edu for (ThreadID tid : *activeThreads) { 3387321Sgblack@eecs.umich.edu thread[tid].recvRetry(); 3397321Sgblack@eecs.umich.edu } 3407321Sgblack@eecs.umich.edu} 3417335Sgblack@eecs.umich.edu 3427335Sgblack@eecs.umich.edutemplate <class Impl> 3437335Sgblack@eecs.umich.edubool 3447335Sgblack@eecs.umich.eduLSQ<Impl>::recvTimingResp(PacketPtr pkt) 3457335Sgblack@eecs.umich.edu{ 3467335Sgblack@eecs.umich.edu if (pkt->isError()) 3477335Sgblack@eecs.umich.edu DPRINTF(LSQ, "Got error packet back for address: %#X\n", 3487335Sgblack@eecs.umich.edu pkt->getAddr()); 3497335Sgblack@eecs.umich.edu 3507335Sgblack@eecs.umich.edu thread[pkt->req->threadId()].completeDataAccess(pkt); 3517335Sgblack@eecs.umich.edu 3527335Sgblack@eecs.umich.edu if (pkt->isInvalidate()) { 3537335Sgblack@eecs.umich.edu // This response also contains an invalidate; e.g. this can be the case 3547335Sgblack@eecs.umich.edu // if cmd is ReadRespWithInvalidate. 3557335Sgblack@eecs.umich.edu // 3567335Sgblack@eecs.umich.edu // The calling order between completeDataAccess and checkSnoop matters. 3577335Sgblack@eecs.umich.edu // By calling checkSnoop after completeDataAccess, we ensure that the 3587335Sgblack@eecs.umich.edu // fault set by checkSnoop is not lost. Calling writeback (more 3597335Sgblack@eecs.umich.edu // specifically inst->completeAcc) in completeDataAccess overwrites 3607335Sgblack@eecs.umich.edu // fault, and in case this instruction requires squashing (as 3617335Sgblack@eecs.umich.edu // determined by checkSnoop), the ReExec fault set by checkSnoop would 3627335Sgblack@eecs.umich.edu // be lost otherwise. 3637335Sgblack@eecs.umich.edu 3647335Sgblack@eecs.umich.edu DPRINTF(LSQ, "received invalidation with response for addr:%#x\n", 3657335Sgblack@eecs.umich.edu pkt->getAddr()); 3667335Sgblack@eecs.umich.edu 3677335Sgblack@eecs.umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 3687335Sgblack@eecs.umich.edu thread[tid].checkSnoop(pkt); 3697335Sgblack@eecs.umich.edu } 3707335Sgblack@eecs.umich.edu } 3717335Sgblack@eecs.umich.edu 3727335Sgblack@eecs.umich.edu delete pkt->req; 3737335Sgblack@eecs.umich.edu delete pkt; 3747321Sgblack@eecs.umich.edu return true; 3757321Sgblack@eecs.umich.edu} 3767321Sgblack@eecs.umich.edu 3777321Sgblack@eecs.umich.edutemplate <class Impl> 3787321Sgblack@eecs.umich.eduvoid 3797321Sgblack@eecs.umich.eduLSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt) 3807335Sgblack@eecs.umich.edu{ 3817335Sgblack@eecs.umich.edu DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(), 3827335Sgblack@eecs.umich.edu pkt->cmdString()); 3837335Sgblack@eecs.umich.edu 3847335Sgblack@eecs.umich.edu // must be a snoop 3857335Sgblack@eecs.umich.edu if (pkt->isInvalidate()) { 3867335Sgblack@eecs.umich.edu DPRINTF(LSQ, "received invalidation for addr:%#x\n", 3877335Sgblack@eecs.umich.edu pkt->getAddr()); 3887335Sgblack@eecs.umich.edu for (ThreadID tid = 0; tid < numThreads; tid++) { 3897321Sgblack@eecs.umich.edu thread[tid].checkSnoop(pkt); 3907326Sgblack@eecs.umich.edu } 3917326Sgblack@eecs.umich.edu } 3927326Sgblack@eecs.umich.edu} 3937326Sgblack@eecs.umich.edu 3947326Sgblack@eecs.umich.edutemplate<class Impl> 3957326Sgblack@eecs.umich.eduint 3967326Sgblack@eecs.umich.eduLSQ<Impl>::getCount() 3977326Sgblack@eecs.umich.edu{ 3987326Sgblack@eecs.umich.edu unsigned total = 0; 3997326Sgblack@eecs.umich.edu 4007326Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 4017326Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 4027326Sgblack@eecs.umich.edu 4037326Sgblack@eecs.umich.edu while (threads != end) { 4047326Sgblack@eecs.umich.edu ThreadID tid = *threads++; 4057326Sgblack@eecs.umich.edu 4067326Sgblack@eecs.umich.edu total += getCount(tid); 4077326Sgblack@eecs.umich.edu } 4087326Sgblack@eecs.umich.edu 4097326Sgblack@eecs.umich.edu return total; 4107326Sgblack@eecs.umich.edu} 4117326Sgblack@eecs.umich.edu 4127326Sgblack@eecs.umich.edutemplate<class Impl> 4137321Sgblack@eecs.umich.eduint 4147321Sgblack@eecs.umich.eduLSQ<Impl>::numLoads() 4157335Sgblack@eecs.umich.edu{ 4167335Sgblack@eecs.umich.edu unsigned total = 0; 4177335Sgblack@eecs.umich.edu 4187335Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 4197335Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 4207335Sgblack@eecs.umich.edu 4217335Sgblack@eecs.umich.edu while (threads != end) { 4227335Sgblack@eecs.umich.edu ThreadID tid = *threads++; 4237335Sgblack@eecs.umich.edu 4247335Sgblack@eecs.umich.edu total += numLoads(tid); 4257335Sgblack@eecs.umich.edu } 4267335Sgblack@eecs.umich.edu 4277335Sgblack@eecs.umich.edu return total; 4287335Sgblack@eecs.umich.edu} 4297335Sgblack@eecs.umich.edu 4307335Sgblack@eecs.umich.edutemplate<class Impl> 4317335Sgblack@eecs.umich.eduint 4327335Sgblack@eecs.umich.eduLSQ<Impl>::numStores() 4337335Sgblack@eecs.umich.edu{ 4347335Sgblack@eecs.umich.edu unsigned total = 0; 4357335Sgblack@eecs.umich.edu 4367335Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 4377335Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 4387335Sgblack@eecs.umich.edu 4397335Sgblack@eecs.umich.edu while (threads != end) { 4407335Sgblack@eecs.umich.edu ThreadID tid = *threads++; 4417335Sgblack@eecs.umich.edu 4427335Sgblack@eecs.umich.edu total += thread[tid].numStores(); 4437335Sgblack@eecs.umich.edu } 4447335Sgblack@eecs.umich.edu 4457335Sgblack@eecs.umich.edu return total; 4467335Sgblack@eecs.umich.edu} 4477335Sgblack@eecs.umich.edu 4487335Sgblack@eecs.umich.edutemplate<class Impl> 4497335Sgblack@eecs.umich.eduunsigned 4507335Sgblack@eecs.umich.eduLSQ<Impl>::numFreeLoadEntries() 4517335Sgblack@eecs.umich.edu{ 4527335Sgblack@eecs.umich.edu unsigned total = 0; 4537335Sgblack@eecs.umich.edu 4547335Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 4557335Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 4567335Sgblack@eecs.umich.edu 4577335Sgblack@eecs.umich.edu while (threads != end) { 4587335Sgblack@eecs.umich.edu ThreadID tid = *threads++; 4597321Sgblack@eecs.umich.edu 4607321Sgblack@eecs.umich.edu total += thread[tid].numFreeLoadEntries(); 4617321Sgblack@eecs.umich.edu } 4627321Sgblack@eecs.umich.edu 4637321Sgblack@eecs.umich.edu return total; 4647356Sgblack@eecs.umich.edu} 4657356Sgblack@eecs.umich.edu 4667356Sgblack@eecs.umich.edutemplate<class Impl> 4677356Sgblack@eecs.umich.eduunsigned 4687356Sgblack@eecs.umich.eduLSQ<Impl>::numFreeStoreEntries() 4697356Sgblack@eecs.umich.edu{ 4707363Sgblack@eecs.umich.edu unsigned total = 0; 4717363Sgblack@eecs.umich.edu 4727363Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 4737363Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 4747363Sgblack@eecs.umich.edu 4757363Sgblack@eecs.umich.edu while (threads != end) { 4767363Sgblack@eecs.umich.edu ThreadID tid = *threads++; 4777363Sgblack@eecs.umich.edu 4787363Sgblack@eecs.umich.edu total += thread[tid].numFreeStoreEntries(); 4797363Sgblack@eecs.umich.edu } 4807363Sgblack@eecs.umich.edu 4817363Sgblack@eecs.umich.edu return total; 4827363Sgblack@eecs.umich.edu} 4837363Sgblack@eecs.umich.edu 4847363Sgblack@eecs.umich.edutemplate<class Impl> 4857363Sgblack@eecs.umich.eduunsigned 4867363Sgblack@eecs.umich.eduLSQ<Impl>::numFreeLoadEntries(ThreadID tid) 4877363Sgblack@eecs.umich.edu{ 4887363Sgblack@eecs.umich.edu return thread[tid].numFreeLoadEntries(); 4897364Sgblack@eecs.umich.edu} 4907364Sgblack@eecs.umich.edu 4917364Sgblack@eecs.umich.edutemplate<class Impl> 4927364Sgblack@eecs.umich.eduunsigned 4937364Sgblack@eecs.umich.eduLSQ<Impl>::numFreeStoreEntries(ThreadID tid) 4947364Sgblack@eecs.umich.edu{ 4957364Sgblack@eecs.umich.edu return thread[tid].numFreeStoreEntries(); 4967364Sgblack@eecs.umich.edu} 4977364Sgblack@eecs.umich.edu 4987364Sgblack@eecs.umich.edutemplate<class Impl> 4997364Sgblack@eecs.umich.edubool 5007364Sgblack@eecs.umich.eduLSQ<Impl>::isFull() 5017364Sgblack@eecs.umich.edu{ 5027364Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 5037364Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 5047364Sgblack@eecs.umich.edu 5057364Sgblack@eecs.umich.edu while (threads != end) { 5067364Sgblack@eecs.umich.edu ThreadID tid = *threads++; 5077364Sgblack@eecs.umich.edu 5087363Sgblack@eecs.umich.edu if (!(thread[tid].lqFull() || thread[tid].sqFull())) 5097363Sgblack@eecs.umich.edu return false; 5107363Sgblack@eecs.umich.edu } 5117363Sgblack@eecs.umich.edu 5127363Sgblack@eecs.umich.edu return true; 5137367Sgblack@eecs.umich.edu} 5147367Sgblack@eecs.umich.edu 5157367Sgblack@eecs.umich.edutemplate<class Impl> 5167367Sgblack@eecs.umich.edubool 5177367Sgblack@eecs.umich.eduLSQ<Impl>::isFull(ThreadID tid) 5187367Sgblack@eecs.umich.edu{ 5197367Sgblack@eecs.umich.edu //@todo: Change to Calculate All Entries for 5207367Sgblack@eecs.umich.edu //Dynamic Policy 5217367Sgblack@eecs.umich.edu if (lsqPolicy == Dynamic) 5227367Sgblack@eecs.umich.edu return isFull(); 5237367Sgblack@eecs.umich.edu else 5247367Sgblack@eecs.umich.edu return thread[tid].lqFull() || thread[tid].sqFull(); 5257367Sgblack@eecs.umich.edu} 5267367Sgblack@eecs.umich.edu 5277367Sgblack@eecs.umich.edutemplate<class Impl> 5287367Sgblack@eecs.umich.edubool 5297367Sgblack@eecs.umich.eduLSQ<Impl>::isEmpty() const 5307367Sgblack@eecs.umich.edu{ 5317367Sgblack@eecs.umich.edu return lqEmpty() && sqEmpty(); 5327363Sgblack@eecs.umich.edu} 5337363Sgblack@eecs.umich.edu 5347363Sgblack@eecs.umich.edutemplate<class Impl> 5357363Sgblack@eecs.umich.edubool 5367363Sgblack@eecs.umich.eduLSQ<Impl>::lqEmpty() const 5377363Sgblack@eecs.umich.edu{ 5387363Sgblack@eecs.umich.edu list<ThreadID>::const_iterator threads = activeThreads->begin(); 5397363Sgblack@eecs.umich.edu list<ThreadID>::const_iterator end = activeThreads->end(); 5407363Sgblack@eecs.umich.edu 5417363Sgblack@eecs.umich.edu while (threads != end) { 5427363Sgblack@eecs.umich.edu ThreadID tid = *threads++; 5437363Sgblack@eecs.umich.edu 5447363Sgblack@eecs.umich.edu if (!thread[tid].lqEmpty()) 5457363Sgblack@eecs.umich.edu return false; 5467363Sgblack@eecs.umich.edu } 5477363Sgblack@eecs.umich.edu 5487363Sgblack@eecs.umich.edu return true; 5497363Sgblack@eecs.umich.edu} 5507363Sgblack@eecs.umich.edu 5517363Sgblack@eecs.umich.edutemplate<class Impl> 5527363Sgblack@eecs.umich.edubool 5537363Sgblack@eecs.umich.eduLSQ<Impl>::sqEmpty() const 5547363Sgblack@eecs.umich.edu{ 5557363Sgblack@eecs.umich.edu list<ThreadID>::const_iterator threads = activeThreads->begin(); 5567363Sgblack@eecs.umich.edu list<ThreadID>::const_iterator end = activeThreads->end(); 5577363Sgblack@eecs.umich.edu 5587363Sgblack@eecs.umich.edu while (threads != end) { 5597363Sgblack@eecs.umich.edu ThreadID tid = *threads++; 5607363Sgblack@eecs.umich.edu 5617363Sgblack@eecs.umich.edu if (!thread[tid].sqEmpty()) 5627363Sgblack@eecs.umich.edu return false; 5637363Sgblack@eecs.umich.edu } 5647363Sgblack@eecs.umich.edu 5657363Sgblack@eecs.umich.edu return true; 5667363Sgblack@eecs.umich.edu} 5677363Sgblack@eecs.umich.edu 5687363Sgblack@eecs.umich.edutemplate<class Impl> 5697363Sgblack@eecs.umich.edubool 5707363Sgblack@eecs.umich.eduLSQ<Impl>::lqFull() 5717363Sgblack@eecs.umich.edu{ 5727363Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 5737363Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 5747363Sgblack@eecs.umich.edu 5757366Sgblack@eecs.umich.edu while (threads != end) { 5767366Sgblack@eecs.umich.edu ThreadID tid = *threads++; 5777366Sgblack@eecs.umich.edu 5787366Sgblack@eecs.umich.edu if (!thread[tid].lqFull()) 5797366Sgblack@eecs.umich.edu return false; 5807366Sgblack@eecs.umich.edu } 5817366Sgblack@eecs.umich.edu 5827366Sgblack@eecs.umich.edu return true; 5837366Sgblack@eecs.umich.edu} 5847366Sgblack@eecs.umich.edu 5857366Sgblack@eecs.umich.edutemplate<class Impl> 5867366Sgblack@eecs.umich.edubool 5877366Sgblack@eecs.umich.eduLSQ<Impl>::lqFull(ThreadID tid) 5887366Sgblack@eecs.umich.edu{ 5897366Sgblack@eecs.umich.edu //@todo: Change to Calculate All Entries for 5907363Sgblack@eecs.umich.edu //Dynamic Policy 5917363Sgblack@eecs.umich.edu if (lsqPolicy == Dynamic) 5927363Sgblack@eecs.umich.edu return lqFull(); 5937365Sgblack@eecs.umich.edu else 5947365Sgblack@eecs.umich.edu return thread[tid].lqFull(); 5957365Sgblack@eecs.umich.edu} 5967365Sgblack@eecs.umich.edu 5977365Sgblack@eecs.umich.edutemplate<class Impl> 5987365Sgblack@eecs.umich.edubool 5997365Sgblack@eecs.umich.eduLSQ<Impl>::sqFull() 6007365Sgblack@eecs.umich.edu{ 6017365Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 6027365Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 6037365Sgblack@eecs.umich.edu 6047365Sgblack@eecs.umich.edu while (threads != end) { 6057365Sgblack@eecs.umich.edu ThreadID tid = *threads++; 6067365Sgblack@eecs.umich.edu 6077365Sgblack@eecs.umich.edu if (!sqFull(tid)) 6087363Sgblack@eecs.umich.edu return false; 6097363Sgblack@eecs.umich.edu } 6107363Sgblack@eecs.umich.edu 6117363Sgblack@eecs.umich.edu return true; 6127363Sgblack@eecs.umich.edu} 6137363Sgblack@eecs.umich.edu 6147363Sgblack@eecs.umich.edutemplate<class Impl> 6157363Sgblack@eecs.umich.edubool 6167363Sgblack@eecs.umich.eduLSQ<Impl>::sqFull(ThreadID tid) 6177363Sgblack@eecs.umich.edu{ 6187363Sgblack@eecs.umich.edu //@todo: Change to Calculate All Entries for 6197363Sgblack@eecs.umich.edu //Dynamic Policy 6207363Sgblack@eecs.umich.edu if (lsqPolicy == Dynamic) 6217363Sgblack@eecs.umich.edu return sqFull(); 6227363Sgblack@eecs.umich.edu else 6237363Sgblack@eecs.umich.edu return thread[tid].sqFull(); 6247363Sgblack@eecs.umich.edu} 6257363Sgblack@eecs.umich.edu 6267363Sgblack@eecs.umich.edutemplate<class Impl> 6277363Sgblack@eecs.umich.edubool 6287363Sgblack@eecs.umich.eduLSQ<Impl>::isStalled() 6297363Sgblack@eecs.umich.edu{ 6307363Sgblack@eecs.umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 6317363Sgblack@eecs.umich.edu list<ThreadID>::iterator end = activeThreads->end(); 6327363Sgblack@eecs.umich.edu 6337363Sgblack@eecs.umich.edu while (threads != end) { 6347363Sgblack@eecs.umich.edu ThreadID tid = *threads++; 6357363Sgblack@eecs.umich.edu 6367363Sgblack@eecs.umich.edu if (!thread[tid].isStalled()) 6377363Sgblack@eecs.umich.edu return false; 6387363Sgblack@eecs.umich.edu } 6397363Sgblack@eecs.umich.edu 6407363Sgblack@eecs.umich.edu return true; 6417363Sgblack@eecs.umich.edu} 6427363Sgblack@eecs.umich.edu 6437363Sgblack@eecs.umich.edutemplate<class Impl> 6447363Sgblack@eecs.umich.edubool 6457363Sgblack@eecs.umich.eduLSQ<Impl>::isStalled(ThreadID tid) 6467363Sgblack@eecs.umich.edu{ 6477363Sgblack@eecs.umich.edu if (lsqPolicy == Dynamic) 6487363Sgblack@eecs.umich.edu return isStalled(); 6497363Sgblack@eecs.umich.edu else 6507363Sgblack@eecs.umich.edu return thread[tid].isStalled(); 6517363Sgblack@eecs.umich.edu} 652 653template<class Impl> 654bool 655LSQ<Impl>::hasStoresToWB() 656{ 657 list<ThreadID>::iterator threads = activeThreads->begin(); 658 list<ThreadID>::iterator end = activeThreads->end(); 659 660 while (threads != end) { 661 ThreadID tid = *threads++; 662 663 if (hasStoresToWB(tid)) 664 return true; 665 } 666 667 return false; 668} 669 670template<class Impl> 671bool 672LSQ<Impl>::willWB() 673{ 674 list<ThreadID>::iterator threads = activeThreads->begin(); 675 list<ThreadID>::iterator end = activeThreads->end(); 676 677 while (threads != end) { 678 ThreadID tid = *threads++; 679 680 if (willWB(tid)) 681 return true; 682 } 683 684 return false; 685} 686 687template<class Impl> 688void 689LSQ<Impl>::dumpInsts() const 690{ 691 list<ThreadID>::const_iterator threads = activeThreads->begin(); 692 list<ThreadID>::const_iterator end = activeThreads->end(); 693 694 while (threads != end) { 695 ThreadID tid = *threads++; 696 697 thread[tid].dumpInsts(); 698 } 699} 700 701#endif//__CPU_O3_LSQ_IMPL_HH__ 702