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