lsq_impl.hh revision 9444
19665Sandreas.hansson@arm.com/* 29665Sandreas.hansson@arm.com * Copyright (c) 2011-2012 ARM Limited 39665Sandreas.hansson@arm.com * All rights reserved 49665Sandreas.hansson@arm.com * 59665Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 69665Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 79665Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 89665Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 99665Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 109665Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 119665Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 129665Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 135353Svilas.sridharan@gmail.com * 143395Shsul@eecs.umich.edu * Copyright (c) 2005-2006 The Regents of The University of Michigan 153395Shsul@eecs.umich.edu * All rights reserved. 163395Shsul@eecs.umich.edu * 173395Shsul@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 183395Shsul@eecs.umich.edu * modification, are permitted provided that the following conditions are 193395Shsul@eecs.umich.edu * met: redistributions of source code must retain the above copyright 203395Shsul@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 213395Shsul@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 223395Shsul@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 233395Shsul@eecs.umich.edu * documentation and/or other materials provided with the distribution; 243395Shsul@eecs.umich.edu * neither the name of the copyright holders nor the names of its 253395Shsul@eecs.umich.edu * contributors may be used to endorse or promote products derived from 263395Shsul@eecs.umich.edu * this software without specific prior written permission. 273395Shsul@eecs.umich.edu * 283395Shsul@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 293395Shsul@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 303395Shsul@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 313395Shsul@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 323395Shsul@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 333395Shsul@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 343395Shsul@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 353395Shsul@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 363395Shsul@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 373395Shsul@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 383395Shsul@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 393395Shsul@eecs.umich.edu * 403395Shsul@eecs.umich.edu * Authors: Korey Sewell 4113774Sandreas.sandberg@arm.com */ 4213774Sandreas.sandberg@arm.com 4313774Sandreas.sandberg@arm.com#include <algorithm> 448920Snilay@cs.wisc.edu#include <list> 458920Snilay@cs.wisc.edu#include <string> 468920Snilay@cs.wisc.edu 477025SBrad.Beckmann@amd.com#include "cpu/o3/lsq.hh" 4813774Sandreas.sandberg@arm.com#include "debug/Drain.hh" 4913774Sandreas.sandberg@arm.com#include "debug/Fetch.hh" 5013774Sandreas.sandberg@arm.com#include "debug/LSQ.hh" 5113876Sjavier.bueno@metempsy.com#include "debug/Writeback.hh" 5213774Sandreas.sandberg@arm.com#include "params/DerivO3CPU.hh" 5313774Sandreas.sandberg@arm.com 5410747SChris.Emmons@arm.comusing namespace std; 559520SAndreas.Sandberg@ARM.com 569520SAndreas.Sandberg@ARM.comtemplate <class Impl> 579520SAndreas.Sandberg@ARM.comLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) 589520SAndreas.Sandberg@ARM.com : cpu(cpu_ptr), iewStage(iew_ptr), 5913432Spau.cabre@metempsy.com LQEntries(params->LQEntries), 6013432Spau.cabre@metempsy.com SQEntries(params->SQEntries), 6113432Spau.cabre@metempsy.com numThreads(params->numThreads), 6213432Spau.cabre@metempsy.com retryTid(-1) 6313876Sjavier.bueno@metempsy.com{ 6413876Sjavier.bueno@metempsy.com //**********************************************/ 6513876Sjavier.bueno@metempsy.com //************ Handle SMT Parameters ***********/ 6613876Sjavier.bueno@metempsy.com //**********************************************/ 6713958Sjairo.balart@metempsy.com std::string policy = params->smtLSQPolicy; 6813958Sjairo.balart@metempsy.com 6913958Sjairo.balart@metempsy.com //Convert string to lowercase 7013958Sjairo.balart@metempsy.com std::transform(policy.begin(), policy.end(), policy.begin(), 719665Sandreas.hansson@arm.com (int(*)(int)) tolower); 729665Sandreas.hansson@arm.com 739665Sandreas.hansson@arm.com //Figure out fetch policy 749665Sandreas.hansson@arm.com if (policy == "dynamic") { 7511238Sandreas.sandberg@arm.com lsqPolicy = Dynamic; 7611238Sandreas.sandberg@arm.com 7711238Sandreas.sandberg@arm.com maxLQEntries = LQEntries; 7811238Sandreas.sandberg@arm.com maxSQEntries = SQEntries; 7911688Sandreas.hansson@arm.com 8011688Sandreas.hansson@arm.com DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 8111688Sandreas.hansson@arm.com } else if (policy == "partitioned") { 8211688Sandreas.hansson@arm.com lsqPolicy = Partitioned; 838920Snilay@cs.wisc.edu 849827Sakash.bagdia@arm.com //@todo:make work if part_amt doesnt divide evenly. 859827Sakash.bagdia@arm.com maxLQEntries = LQEntries / numThreads; 869827Sakash.bagdia@arm.com maxSQEntries = SQEntries / numThreads; 879827Sakash.bagdia@arm.com 889790Sakash.bagdia@arm.com DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 899790Sakash.bagdia@arm.com "%i entries per LQ | %i entries per SQ\n", 909790Sakash.bagdia@arm.com maxLQEntries,maxSQEntries); 919790Sakash.bagdia@arm.com } else if (policy == "threshold") { 9211688Sandreas.hansson@arm.com lsqPolicy = Threshold; 9311688Sandreas.hansson@arm.com 9411688Sandreas.hansson@arm.com assert(params->smtLSQThreshold > LQEntries); 9511688Sandreas.hansson@arm.com assert(params->smtLSQThreshold > SQEntries); 9611688Sandreas.hansson@arm.com 9711837Swendy.elsasser@arm.com //Divide up by threshold amount 9811688Sandreas.hansson@arm.com //@todo: Should threads check the max and the total 9911688Sandreas.hansson@arm.com //amount of the LSQ 10011688Sandreas.hansson@arm.com maxLQEntries = params->smtLSQThreshold; 10111688Sandreas.hansson@arm.com maxSQEntries = params->smtLSQThreshold; 10211688Sandreas.hansson@arm.com 10311688Sandreas.hansson@arm.com DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 10411688Sandreas.hansson@arm.com "%i entries per LQ | %i entries per SQ\n", 10511688Sandreas.hansson@arm.com maxLQEntries,maxSQEntries); 10611688Sandreas.hansson@arm.com } else { 10714038Smatthew.poremba@amd.com assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic," 10814038Smatthew.poremba@amd.com "Partitioned, Threshold}"); 10911688Sandreas.hansson@arm.com } 11011688Sandreas.hansson@arm.com 11111688Sandreas.hansson@arm.com //Initialize LSQs 11211688Sandreas.hansson@arm.com for (ThreadID tid = 0; tid < numThreads; tid++) { 11311688Sandreas.hansson@arm.com thread[tid].init(cpu, iew_ptr, params, this, 11411688Sandreas.hansson@arm.com maxLQEntries, maxSQEntries, tid); 11511688Sandreas.hansson@arm.com thread[tid].setDcachePort(&cpu_ptr->getDataPort()); 11611688Sandreas.hansson@arm.com } 11711688Sandreas.hansson@arm.com} 11811688Sandreas.hansson@arm.com 11911688Sandreas.hansson@arm.com 12011688Sandreas.hansson@arm.comtemplate<class Impl> 12111688Sandreas.hansson@arm.comstd::string 12211688Sandreas.hansson@arm.comLSQ<Impl>::name() const 12311688Sandreas.hansson@arm.com{ 12411688Sandreas.hansson@arm.com return iewStage->name() + ".lsq"; 12511688Sandreas.hansson@arm.com} 12611688Sandreas.hansson@arm.com 12711688Sandreas.hansson@arm.comtemplate<class Impl> 12811688Sandreas.hansson@arm.comvoid 12911688Sandreas.hansson@arm.comLSQ<Impl>::regStats() 13011688Sandreas.hansson@arm.com{ 13111688Sandreas.hansson@arm.com //Initialize LSQs 13211688Sandreas.hansson@arm.com for (ThreadID tid = 0; tid < numThreads; tid++) { 13311688Sandreas.hansson@arm.com thread[tid].regStats(); 13411688Sandreas.hansson@arm.com } 13511688Sandreas.hansson@arm.com} 13611688Sandreas.hansson@arm.com 13711688Sandreas.hansson@arm.comtemplate<class Impl> 13811688Sandreas.hansson@arm.comvoid 13911688Sandreas.hansson@arm.comLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 14011688Sandreas.hansson@arm.com{ 14111688Sandreas.hansson@arm.com activeThreads = at_ptr; 14211688Sandreas.hansson@arm.com assert(activeThreads != 0); 14311688Sandreas.hansson@arm.com} 14411688Sandreas.hansson@arm.com 14511688Sandreas.hansson@arm.comtemplate <class Impl> 14611688Sandreas.hansson@arm.comvoid 14713357Sciro.santilli@arm.comLSQ<Impl>::drainSanityCheck() const 14813357Sciro.santilli@arm.com{ 14913357Sciro.santilli@arm.com assert(isDrained()); 15013357Sciro.santilli@arm.com 15113357Sciro.santilli@arm.com for (ThreadID tid = 0; tid < numThreads; tid++) 15213357Sciro.santilli@arm.com thread[tid].drainSanityCheck(); 15313357Sciro.santilli@arm.com} 15413357Sciro.santilli@arm.com 15511688Sandreas.hansson@arm.comtemplate <class Impl> 15611688Sandreas.hansson@arm.combool 15711688Sandreas.hansson@arm.comLSQ<Impl>::isDrained() const 15811688Sandreas.hansson@arm.com{ 15911688Sandreas.hansson@arm.com bool drained(true); 16011688Sandreas.hansson@arm.com 16111688Sandreas.hansson@arm.com if (!lqEmpty()) { 16211688Sandreas.hansson@arm.com DPRINTF(Drain, "Not drained, LQ not empty.\n"); 16311688Sandreas.hansson@arm.com drained = false; 16411688Sandreas.hansson@arm.com } 16511995Sgabeblack@google.com 16611688Sandreas.hansson@arm.com if (!sqEmpty()) { 16711688Sandreas.hansson@arm.com DPRINTF(Drain, "Not drained, SQ not empty.\n"); 16813432Spau.cabre@metempsy.com drained = false; 16913432Spau.cabre@metempsy.com } 17013432Spau.cabre@metempsy.com 17113958Sjairo.balart@metempsy.com if (retryTid != InvalidThreadID) { 17213958Sjairo.balart@metempsy.com DPRINTF(Drain, "Not drained, the LSQ has blocked the caches.\n"); 17313958Sjairo.balart@metempsy.com drained = false; 17413432Spau.cabre@metempsy.com } 17513432Spau.cabre@metempsy.com 17613432Spau.cabre@metempsy.com return drained; 17713432Spau.cabre@metempsy.com} 17813432Spau.cabre@metempsy.com 17913432Spau.cabre@metempsy.comtemplate <class Impl> 18013958Sjairo.balart@metempsy.comvoid 18113958Sjairo.balart@metempsy.comLSQ<Impl>::takeOverFrom() 18213958Sjairo.balart@metempsy.com{ 18313958Sjairo.balart@metempsy.com for (ThreadID tid = 0; tid < numThreads; tid++) { 18413876Sjavier.bueno@metempsy.com thread[tid].takeOverFrom(); 18513876Sjavier.bueno@metempsy.com } 18613876Sjavier.bueno@metempsy.com} 18713876Sjavier.bueno@metempsy.com 18813876Sjavier.bueno@metempsy.comtemplate <class Impl> 18913876Sjavier.bueno@metempsy.comint 19013876Sjavier.bueno@metempsy.comLSQ<Impl>::entryAmount(ThreadID num_threads) 19113876Sjavier.bueno@metempsy.com{ 19213876Sjavier.bueno@metempsy.com if (lsqPolicy == Partitioned) { 19313876Sjavier.bueno@metempsy.com return LQEntries / num_threads; 19413876Sjavier.bueno@metempsy.com } else { 19513876Sjavier.bueno@metempsy.com return 0; 19613876Sjavier.bueno@metempsy.com } 19713876Sjavier.bueno@metempsy.com} 19813876Sjavier.bueno@metempsy.com 19913876Sjavier.bueno@metempsy.comtemplate <class Impl> 20013876Sjavier.bueno@metempsy.comvoid 20113876Sjavier.bueno@metempsy.comLSQ<Impl>::resetEntries() 20213876Sjavier.bueno@metempsy.com{ 20313876Sjavier.bueno@metempsy.com if (lsqPolicy != Dynamic || numThreads > 1) { 20413876Sjavier.bueno@metempsy.com int active_threads = activeThreads->size(); 20513876Sjavier.bueno@metempsy.com 20613876Sjavier.bueno@metempsy.com int maxEntries; 20711688Sandreas.hansson@arm.com 2089789Sakash.bagdia@arm.com if (lsqPolicy == Partitioned) { 2099789Sakash.bagdia@arm.com maxEntries = LQEntries / active_threads; 2109789Sakash.bagdia@arm.com } else if (lsqPolicy == Threshold && active_threads == 1) { 2119800Snilay@cs.wisc.edu maxEntries = LQEntries; 2129800Snilay@cs.wisc.edu } else { 2139800Snilay@cs.wisc.edu maxEntries = LQEntries; 2149800Snilay@cs.wisc.edu } 2159800Snilay@cs.wisc.edu 21611251Sradhika.jagtap@ARM.com list<ThreadID>::iterator threads = activeThreads->begin(); 21711251Sradhika.jagtap@ARM.com list<ThreadID>::iterator end = activeThreads->end(); 21811251Sradhika.jagtap@ARM.com 21911251Sradhika.jagtap@ARM.com while (threads != end) { 22011251Sradhika.jagtap@ARM.com ThreadID tid = *threads++; 22111251Sradhika.jagtap@ARM.com 22211251Sradhika.jagtap@ARM.com resizeEntries(maxEntries, tid); 22311251Sradhika.jagtap@ARM.com } 22411251Sradhika.jagtap@ARM.com } 22511251Sradhika.jagtap@ARM.com} 22611251Sradhika.jagtap@ARM.com 22711251Sradhika.jagtap@ARM.comtemplate<class Impl> 22811251Sradhika.jagtap@ARM.comvoid 2299800Snilay@cs.wisc.eduLSQ<Impl>::removeEntries(ThreadID tid) 23010037SARM gem5 Developers{ 23110037SARM gem5 Developers thread[tid].clearLQ(); 23210037SARM gem5 Developers thread[tid].clearSQ(); 23311626Smichael.lebeane@amd.com} 23411626Smichael.lebeane@amd.com 23511626Smichael.lebeane@amd.comtemplate<class Impl> 23611703Smichael.lebeane@amd.comvoid 23711703Smichael.lebeane@amd.comLSQ<Impl>::resizeEntries(unsigned size, ThreadID tid) 23811626Smichael.lebeane@amd.com{ 23911626Smichael.lebeane@amd.com thread[tid].resizeLQ(size); 24011626Smichael.lebeane@amd.com thread[tid].resizeSQ(size); 24111626Smichael.lebeane@amd.com} 24211626Smichael.lebeane@amd.com 24311626Smichael.lebeane@amd.comtemplate<class Impl> 24411626Smichael.lebeane@amd.comvoid 24511626Smichael.lebeane@amd.comLSQ<Impl>::tick() 24611626Smichael.lebeane@amd.com{ 24711626Smichael.lebeane@amd.com list<ThreadID>::iterator threads = activeThreads->begin(); 24811626Smichael.lebeane@amd.com list<ThreadID>::iterator end = activeThreads->end(); 24911626Smichael.lebeane@amd.com 25011626Smichael.lebeane@amd.com while (threads != end) { 25111626Smichael.lebeane@amd.com ThreadID tid = *threads++; 25211626Smichael.lebeane@amd.com 25311626Smichael.lebeane@amd.com thread[tid].tick(); 25411626Smichael.lebeane@amd.com } 25511626Smichael.lebeane@amd.com} 25611626Smichael.lebeane@amd.com 25711626Smichael.lebeane@amd.comtemplate<class Impl> 25811626Smichael.lebeane@amd.comvoid 25911626Smichael.lebeane@amd.comLSQ<Impl>::insertLoad(DynInstPtr &load_inst) 26011626Smichael.lebeane@amd.com{ 26111626Smichael.lebeane@amd.com ThreadID tid = load_inst->threadNumber; 26211626Smichael.lebeane@amd.com 26311626Smichael.lebeane@amd.com thread[tid].insertLoad(load_inst); 26411626Smichael.lebeane@amd.com} 26511626Smichael.lebeane@amd.com 26611626Smichael.lebeane@amd.comtemplate<class Impl> 26711626Smichael.lebeane@amd.comvoid 2688920Snilay@cs.wisc.eduLSQ<Impl>::insertStore(DynInstPtr &store_inst) 2698920Snilay@cs.wisc.edu{ 2708920Snilay@cs.wisc.edu ThreadID tid = store_inst->threadNumber; 2718920Snilay@cs.wisc.edu 2728920Snilay@cs.wisc.edu thread[tid].insertStore(store_inst); 2738920Snilay@cs.wisc.edu} 27410159Sgedare@rtems.org 27510159Sgedare@rtems.orgtemplate<class Impl> 2768920Snilay@cs.wisc.eduFault 2778920Snilay@cs.wisc.eduLSQ<Impl>::executeLoad(DynInstPtr &inst) 2788920Snilay@cs.wisc.edu{ 2798920Snilay@cs.wisc.edu ThreadID tid = inst->threadNumber; 2808920Snilay@cs.wisc.edu 2818920Snilay@cs.wisc.edu return thread[tid].executeLoad(inst); 2828920Snilay@cs.wisc.edu} 2838920Snilay@cs.wisc.edu 2848920Snilay@cs.wisc.edutemplate<class Impl> 28510757SCurtis.Dunham@arm.comFault 28610757SCurtis.Dunham@arm.comLSQ<Impl>::executeStore(DynInstPtr &inst) 28710757SCurtis.Dunham@arm.com{ 2886776SBrad.Beckmann@amd.com ThreadID tid = inst->threadNumber; 2899800Snilay@cs.wisc.edu 2909800Snilay@cs.wisc.edu return thread[tid].executeStore(inst); 2919800Snilay@cs.wisc.edu} 2929800Snilay@cs.wisc.edu 2939800Snilay@cs.wisc.edutemplate<class Impl> 29410608Sdam.sunwoo@arm.comvoid 29510608Sdam.sunwoo@arm.comLSQ<Impl>::writebackStores() 29610608Sdam.sunwoo@arm.com{ 29710608Sdam.sunwoo@arm.com list<ThreadID>::iterator threads = activeThreads->begin(); 29810608Sdam.sunwoo@arm.com list<ThreadID>::iterator end = activeThreads->end(); 2999800Snilay@cs.wisc.edu 3008920Snilay@cs.wisc.edu while (threads != end) { 3018920Snilay@cs.wisc.edu ThreadID tid = *threads++; 3028920Snilay@cs.wisc.edu 3038920Snilay@cs.wisc.edu if (numStoresToWB(tid) > 0) { 3049357Sandreas.hansson@arm.com DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores " 3058920Snilay@cs.wisc.edu "available for Writeback.\n", tid, numStoresToWB(tid)); 3068920Snilay@cs.wisc.edu } 3078920Snilay@cs.wisc.edu 3088920Snilay@cs.wisc.edu thread[tid].writebackStores(); 3098920Snilay@cs.wisc.edu } 3108920Snilay@cs.wisc.edu} 3118920Snilay@cs.wisc.edu 3128920Snilay@cs.wisc.edutemplate<class Impl> 3138920Snilay@cs.wisc.edubool 3148920Snilay@cs.wisc.eduLSQ<Impl>::violation() 3158920Snilay@cs.wisc.edu{ 3168920Snilay@cs.wisc.edu /* Answers: Does Anybody Have a Violation?*/ 3178920Snilay@cs.wisc.edu list<ThreadID>::iterator threads = activeThreads->begin(); 3188920Snilay@cs.wisc.edu list<ThreadID>::iterator end = activeThreads->end(); 3198920Snilay@cs.wisc.edu 32011995Sgabeblack@google.com while (threads != end) { 3218920Snilay@cs.wisc.edu ThreadID tid = *threads++; 3223395Shsul@eecs.umich.edu 3235361Srstrong@cs.ucsd.edu if (thread[tid].violation()) 3248920Snilay@cs.wisc.edu return true; 3258920Snilay@cs.wisc.edu } 3268920Snilay@cs.wisc.edu 3279151Satgutier@umich.edu return false; 3289151Satgutier@umich.edu} 3299151Satgutier@umich.edu 3309151Satgutier@umich.edutemplate <class Impl> 3319151Satgutier@umich.eduvoid 3329151Satgutier@umich.eduLSQ<Impl>::recvRetry() 3339562Ssaidi@eecs.umich.edu{ 3348920Snilay@cs.wisc.edu if (retryTid == InvalidThreadID) 3358920Snilay@cs.wisc.edu { 3368920Snilay@cs.wisc.edu //Squashed, so drop it 3378920Snilay@cs.wisc.edu return; 3388920Snilay@cs.wisc.edu } 3398920Snilay@cs.wisc.edu int curr_retry_tid = retryTid; 3408920Snilay@cs.wisc.edu // Speculatively clear the retry Tid. This will get set again if 3418920Snilay@cs.wisc.edu // the LSQUnit was unable to complete its access. 3428920Snilay@cs.wisc.edu retryTid = -1; 3438920Snilay@cs.wisc.edu thread[curr_retry_tid].recvRetry(); 3448920Snilay@cs.wisc.edu} 3458920Snilay@cs.wisc.edu 3468920Snilay@cs.wisc.edutemplate <class Impl> 3478920Snilay@cs.wisc.edubool 3488920Snilay@cs.wisc.eduLSQ<Impl>::recvTimingResp(PacketPtr pkt) 3498920Snilay@cs.wisc.edu{ 3508920Snilay@cs.wisc.edu if (pkt->isError()) 35110037SARM gem5 Developers DPRINTF(LSQ, "Got error packet back for address: %#X\n", 35210037SARM gem5 Developers pkt->getAddr()); 35310037SARM gem5 Developers thread[pkt->req->threadId()].completeDataAccess(pkt); 35410037SARM gem5 Developers return true; 35510037SARM gem5 Developers} 35610037SARM gem5 Developers 35710037SARM gem5 Developerstemplate <class Impl> 35810037SARM gem5 Developersvoid 3598920Snilay@cs.wisc.eduLSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt) 3608920Snilay@cs.wisc.edu{ 3618920Snilay@cs.wisc.edu DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(), 3628920Snilay@cs.wisc.edu pkt->cmdString()); 3638920Snilay@cs.wisc.edu 3648920Snilay@cs.wisc.edu // must be a snoop 3658920Snilay@cs.wisc.edu if (pkt->isInvalidate()) { 3668920Snilay@cs.wisc.edu DPRINTF(LSQ, "received invalidation for addr:%#x\n", 36710803Sbrandon.potter@amd.com pkt->getAddr()); 36810803Sbrandon.potter@amd.com for (ThreadID tid = 0; tid < numThreads; tid++) { 3698920Snilay@cs.wisc.edu thread[tid].checkSnoop(pkt); 3708920Snilay@cs.wisc.edu } 3718920Snilay@cs.wisc.edu } 3728920Snilay@cs.wisc.edu} 3738920Snilay@cs.wisc.edu 3748920Snilay@cs.wisc.edutemplate<class Impl> 37513883Sdavid.hashe@amd.comint 37613883Sdavid.hashe@amd.comLSQ<Impl>::getCount() 37713883Sdavid.hashe@amd.com{ 37813883Sdavid.hashe@amd.com unsigned total = 0; 37913883Sdavid.hashe@amd.com 38013883Sdavid.hashe@amd.com list<ThreadID>::iterator threads = activeThreads->begin(); 38113883Sdavid.hashe@amd.com list<ThreadID>::iterator end = activeThreads->end(); 38213883Sdavid.hashe@amd.com 38313883Sdavid.hashe@amd.com while (threads != end) { 38413883Sdavid.hashe@amd.com ThreadID tid = *threads++; 38513883Sdavid.hashe@amd.com 38613883Sdavid.hashe@amd.com total += getCount(tid); 38713883Sdavid.hashe@amd.com } 3888920Snilay@cs.wisc.edu 3898920Snilay@cs.wisc.edu return total; 39013774Sandreas.sandberg@arm.com} 39111688Sandreas.hansson@arm.com 3928920Snilay@cs.wisc.edutemplate<class Impl> 3938920Snilay@cs.wisc.eduint 3948920Snilay@cs.wisc.eduLSQ<Impl>::numLoads() 3958920Snilay@cs.wisc.edu{ 3968920Snilay@cs.wisc.edu unsigned total = 0; 3978920Snilay@cs.wisc.edu 39810747SChris.Emmons@arm.com list<ThreadID>::iterator threads = activeThreads->begin(); 39913731Sandreas.sandberg@arm.com list<ThreadID>::iterator end = activeThreads->end(); 40013731Sandreas.sandberg@arm.com 40113731Sandreas.sandberg@arm.com while (threads != end) { 4028920Snilay@cs.wisc.edu ThreadID tid = *threads++; 4038920Snilay@cs.wisc.edu 4048920Snilay@cs.wisc.edu total += numLoads(tid); 4058920Snilay@cs.wisc.edu } 4068920Snilay@cs.wisc.edu 4078920Snilay@cs.wisc.edu return total; 4088920Snilay@cs.wisc.edu} 4098920Snilay@cs.wisc.edu 41011238Sandreas.sandberg@arm.comtemplate<class Impl> 41111238Sandreas.sandberg@arm.comint 41211238Sandreas.sandberg@arm.comLSQ<Impl>::numStores() 4138920Snilay@cs.wisc.edu{ 41411238Sandreas.sandberg@arm.com unsigned total = 0; 41511238Sandreas.sandberg@arm.com 4169539Satgutier@umich.edu list<ThreadID>::iterator threads = activeThreads->begin(); 4179539Satgutier@umich.edu list<ThreadID>::iterator end = activeThreads->end(); 4189539Satgutier@umich.edu 41912079Sgedare@rtems.org while (threads != end) { 42012079Sgedare@rtems.org ThreadID tid = *threads++; 4219935Sdam.sunwoo@arm.com 4229935Sdam.sunwoo@arm.com total += thread[tid].numStores(); 4239935Sdam.sunwoo@arm.com } 4249935Sdam.sunwoo@arm.com 4258920Snilay@cs.wisc.edu return total; 4268920Snilay@cs.wisc.edu} 4278920Snilay@cs.wisc.edu 4288920Snilay@cs.wisc.edutemplate<class Impl> 4298920Snilay@cs.wisc.eduunsigned 4308920Snilay@cs.wisc.eduLSQ<Impl>::numFreeEntries() 4318920Snilay@cs.wisc.edu{ 4328920Snilay@cs.wisc.edu unsigned total = 0; 4338920Snilay@cs.wisc.edu 4348920Snilay@cs.wisc.edu list<ThreadID>::iterator threads = activeThreads->begin(); 4358920Snilay@cs.wisc.edu list<ThreadID>::iterator end = activeThreads->end(); 4368920Snilay@cs.wisc.edu 4378956Sjayneel@cs.wisc.edu while (threads != end) { 4388956Sjayneel@cs.wisc.edu ThreadID tid = *threads++; 4398956Sjayneel@cs.wisc.edu 4408956Sjayneel@cs.wisc.edu total += thread[tid].numFreeEntries(); 44110697SCurtis.Dunham@arm.com } 44210697SCurtis.Dunham@arm.com 44310594Sgabeblack@google.com return total; 44410594Sgabeblack@google.com} 44510594Sgabeblack@google.com 44610594Sgabeblack@google.comtemplate<class Impl> 44710594Sgabeblack@google.comunsigned 44810594Sgabeblack@google.comLSQ<Impl>::numFreeEntries(ThreadID tid) 44910594Sgabeblack@google.com{ 45010594Sgabeblack@google.com //if (lsqPolicy == Dynamic) 451 //return numFreeEntries(); 452 //else 453 return thread[tid].numFreeEntries(); 454} 455 456template<class Impl> 457bool 458LSQ<Impl>::isFull() 459{ 460 list<ThreadID>::iterator threads = activeThreads->begin(); 461 list<ThreadID>::iterator end = activeThreads->end(); 462 463 while (threads != end) { 464 ThreadID tid = *threads++; 465 466 if (!(thread[tid].lqFull() || thread[tid].sqFull())) 467 return false; 468 } 469 470 return true; 471} 472 473template<class Impl> 474bool 475LSQ<Impl>::isFull(ThreadID tid) 476{ 477 //@todo: Change to Calculate All Entries for 478 //Dynamic Policy 479 if (lsqPolicy == Dynamic) 480 return isFull(); 481 else 482 return thread[tid].lqFull() || thread[tid].sqFull(); 483} 484 485template<class Impl> 486bool 487LSQ<Impl>::isEmpty() const 488{ 489 return lqEmpty() && sqEmpty(); 490} 491 492template<class Impl> 493bool 494LSQ<Impl>::lqEmpty() const 495{ 496 list<ThreadID>::const_iterator threads = activeThreads->begin(); 497 list<ThreadID>::const_iterator end = activeThreads->end(); 498 499 while (threads != end) { 500 ThreadID tid = *threads++; 501 502 if (!thread[tid].lqEmpty()) 503 return false; 504 } 505 506 return true; 507} 508 509template<class Impl> 510bool 511LSQ<Impl>::sqEmpty() const 512{ 513 list<ThreadID>::const_iterator threads = activeThreads->begin(); 514 list<ThreadID>::const_iterator end = activeThreads->end(); 515 516 while (threads != end) { 517 ThreadID tid = *threads++; 518 519 if (!thread[tid].sqEmpty()) 520 return false; 521 } 522 523 return true; 524} 525 526template<class Impl> 527bool 528LSQ<Impl>::lqFull() 529{ 530 list<ThreadID>::iterator threads = activeThreads->begin(); 531 list<ThreadID>::iterator end = activeThreads->end(); 532 533 while (threads != end) { 534 ThreadID tid = *threads++; 535 536 if (!thread[tid].lqFull()) 537 return false; 538 } 539 540 return true; 541} 542 543template<class Impl> 544bool 545LSQ<Impl>::lqFull(ThreadID tid) 546{ 547 //@todo: Change to Calculate All Entries for 548 //Dynamic Policy 549 if (lsqPolicy == Dynamic) 550 return lqFull(); 551 else 552 return thread[tid].lqFull(); 553} 554 555template<class Impl> 556bool 557LSQ<Impl>::sqFull() 558{ 559 list<ThreadID>::iterator threads = activeThreads->begin(); 560 list<ThreadID>::iterator end = activeThreads->end(); 561 562 while (threads != end) { 563 ThreadID tid = *threads++; 564 565 if (!sqFull(tid)) 566 return false; 567 } 568 569 return true; 570} 571 572template<class Impl> 573bool 574LSQ<Impl>::sqFull(ThreadID tid) 575{ 576 //@todo: Change to Calculate All Entries for 577 //Dynamic Policy 578 if (lsqPolicy == Dynamic) 579 return sqFull(); 580 else 581 return thread[tid].sqFull(); 582} 583 584template<class Impl> 585bool 586LSQ<Impl>::isStalled() 587{ 588 list<ThreadID>::iterator threads = activeThreads->begin(); 589 list<ThreadID>::iterator end = activeThreads->end(); 590 591 while (threads != end) { 592 ThreadID tid = *threads++; 593 594 if (!thread[tid].isStalled()) 595 return false; 596 } 597 598 return true; 599} 600 601template<class Impl> 602bool 603LSQ<Impl>::isStalled(ThreadID tid) 604{ 605 if (lsqPolicy == Dynamic) 606 return isStalled(); 607 else 608 return thread[tid].isStalled(); 609} 610 611template<class Impl> 612bool 613LSQ<Impl>::hasStoresToWB() 614{ 615 list<ThreadID>::iterator threads = activeThreads->begin(); 616 list<ThreadID>::iterator end = activeThreads->end(); 617 618 while (threads != end) { 619 ThreadID tid = *threads++; 620 621 if (hasStoresToWB(tid)) 622 return true; 623 } 624 625 return false; 626} 627 628template<class Impl> 629bool 630LSQ<Impl>::willWB() 631{ 632 list<ThreadID>::iterator threads = activeThreads->begin(); 633 list<ThreadID>::iterator end = activeThreads->end(); 634 635 while (threads != end) { 636 ThreadID tid = *threads++; 637 638 if (willWB(tid)) 639 return true; 640 } 641 642 return false; 643} 644 645template<class Impl> 646void 647LSQ<Impl>::dumpInsts() const 648{ 649 list<ThreadID>::const_iterator threads = activeThreads->begin(); 650 list<ThreadID>::const_iterator end = activeThreads->end(); 651 652 while (threads != end) { 653 ThreadID tid = *threads++; 654 655 thread[tid].dumpInsts(); 656 } 657} 658