12292SN/A/*
213590Srekai.gonzalezalberquilla@arm.com * Copyright (c) 2011-2012, 2014, 2017-2018 ARM Limited
310239Sbinhpham@cs.rutgers.edu * Copyright (c) 2013 Advanced Micro Devices, Inc.
48707Sandreas.hansson@arm.com * All rights reserved
58707Sandreas.hansson@arm.com *
68707Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
78707Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
88707Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
98707Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
108707Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
118707Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
128707Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
138707Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
148707Sandreas.hansson@arm.com *
152727Sktlim@umich.edu * Copyright (c) 2005-2006 The Regents of The University of Michigan
162292SN/A * All rights reserved.
172292SN/A *
182292SN/A * Redistribution and use in source and binary forms, with or without
192292SN/A * modification, are permitted provided that the following conditions are
202292SN/A * met: redistributions of source code must retain the above copyright
212292SN/A * notice, this list of conditions and the following disclaimer;
222292SN/A * redistributions in binary form must reproduce the above copyright
232292SN/A * notice, this list of conditions and the following disclaimer in the
242292SN/A * documentation and/or other materials provided with the distribution;
252292SN/A * neither the name of the copyright holders nor the names of its
262292SN/A * contributors may be used to endorse or promote products derived from
272292SN/A * this software without specific prior written permission.
282292SN/A *
292292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402689Sktlim@umich.edu *
412689Sktlim@umich.edu * Authors: Korey Sewell
422292SN/A */
432292SN/A
449944Smatt.horsnell@ARM.com#ifndef __CPU_O3_LSQ_IMPL_HH__
459944Smatt.horsnell@ARM.com#define __CPU_O3_LSQ_IMPL_HH__
469944Smatt.horsnell@ARM.com
472329SN/A#include <algorithm>
482980Sgblack@eecs.umich.edu#include <list>
492329SN/A#include <string>
502329SN/A
5113449Sgabeblack@google.com#include "base/logging.hh"
5214194Sgabeblack@google.com#include "cpu/o3/cpu.hh"
532292SN/A#include "cpu/o3/lsq.hh"
549444SAndreas.Sandberg@ARM.com#include "debug/Drain.hh"
558232Snate@binkert.org#include "debug/Fetch.hh"
568232Snate@binkert.org#include "debug/LSQ.hh"
578232Snate@binkert.org#include "debug/Writeback.hh"
586221Snate@binkert.org#include "params/DerivO3CPU.hh"
592292SN/A
606221Snate@binkert.orgusing namespace std;
615529Snate@binkert.org
622292SN/Atemplate <class Impl>
635529Snate@binkert.orgLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
648707Sandreas.hansson@arm.com    : cpu(cpu_ptr), iewStage(iew_ptr),
6513590Srekai.gonzalezalberquilla@arm.com      _cacheBlocked(false),
6613590Srekai.gonzalezalberquilla@arm.com      cacheStorePorts(params->cacheStorePorts), usedStorePorts(0),
6713710Sgabor.dozsa@arm.com      cacheLoadPorts(params->cacheLoadPorts), usedLoadPorts(0),
6813560Snikos.nikoleris@arm.com      lsqPolicy(params->smtLSQPolicy),
694329Sktlim@umich.edu      LQEntries(params->LQEntries),
704329Sktlim@umich.edu      SQEntries(params->SQEntries),
7113472Srekai.gonzalezalberquilla@arm.com      maxLQEntries(maxLSQAllocation(lsqPolicy, LQEntries, params->numThreads,
7213472Srekai.gonzalezalberquilla@arm.com                  params->smtLSQThreshold)),
7313472Srekai.gonzalezalberquilla@arm.com      maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params->numThreads,
7413472Srekai.gonzalezalberquilla@arm.com                  params->smtLSQThreshold)),
7514194Sgabeblack@google.com      dcachePort(this, cpu_ptr),
7610333Smitch.hayenga@arm.com      numThreads(params->numThreads)
772292SN/A{
789868Sjthestness@gmail.com    assert(numThreads > 0 && numThreads <= Impl::MaxThreads);
799868Sjthestness@gmail.com
802292SN/A    //**********************************************/
812292SN/A    //************ Handle SMT Parameters ***********/
822292SN/A    //**********************************************/
832292SN/A
8413590Srekai.gonzalezalberquilla@arm.com    /* Run SMT olicy checks. */
8513590Srekai.gonzalezalberquilla@arm.com        if (lsqPolicy == SMTQueuePolicy::Dynamic) {
862292SN/A        DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
8713560Snikos.nikoleris@arm.com    } else if (lsqPolicy == SMTQueuePolicy::Partitioned) {
882292SN/A        DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
898346Sksewell@umich.edu                "%i entries per LQ | %i entries per SQ\n",
902292SN/A                maxLQEntries,maxSQEntries);
9113560Snikos.nikoleris@arm.com    } else if (lsqPolicy == SMTQueuePolicy::Threshold) {
922292SN/A
9313590Srekai.gonzalezalberquilla@arm.com        assert(params->smtLSQThreshold > params->LQEntries);
9413590Srekai.gonzalezalberquilla@arm.com        assert(params->smtLSQThreshold > params->SQEntries);
952292SN/A
962292SN/A        DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
978346Sksewell@umich.edu                "%i entries per LQ | %i entries per SQ\n",
982292SN/A                maxLQEntries,maxSQEntries);
992292SN/A    } else {
10013449Sgabeblack@google.com        panic("Invalid LSQ sharing policy. Options are: Dynamic, "
10113449Sgabeblack@google.com                    "Partitioned, Threshold");
1022292SN/A    }
1032292SN/A
10413472Srekai.gonzalezalberquilla@arm.com    thread.reserve(numThreads);
1056221Snate@binkert.org    for (ThreadID tid = 0; tid < numThreads; tid++) {
10613472Srekai.gonzalezalberquilla@arm.com        thread.emplace_back(maxLQEntries, maxSQEntries);
10713472Srekai.gonzalezalberquilla@arm.com        thread[tid].init(cpu, iew_ptr, params, this, tid);
10814194Sgabeblack@google.com        thread[tid].setDcachePort(&dcachePort);
1092292SN/A    }
1102292SN/A}
1112292SN/A
1122292SN/A
1132292SN/Atemplate<class Impl>
1142292SN/Astd::string
1152292SN/ALSQ<Impl>::name() const
1162292SN/A{
1172292SN/A    return iewStage->name() + ".lsq";
1182292SN/A}
1192292SN/A
1202292SN/Atemplate<class Impl>
1212292SN/Avoid
1222727Sktlim@umich.eduLSQ<Impl>::regStats()
1232727Sktlim@umich.edu{
1242727Sktlim@umich.edu    //Initialize LSQs
1256221Snate@binkert.org    for (ThreadID tid = 0; tid < numThreads; tid++) {
1262727Sktlim@umich.edu        thread[tid].regStats();
1272727Sktlim@umich.edu    }
1282727Sktlim@umich.edu}
1292727Sktlim@umich.edu
1302727Sktlim@umich.edutemplate<class Impl>
1312727Sktlim@umich.eduvoid
1326221Snate@binkert.orgLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
1332292SN/A{
1342292SN/A    activeThreads = at_ptr;
1352292SN/A    assert(activeThreads != 0);
1362292SN/A}
1372292SN/A
1382292SN/Atemplate <class Impl>
1392307SN/Avoid
1409444SAndreas.Sandberg@ARM.comLSQ<Impl>::drainSanityCheck() const
1412307SN/A{
1429444SAndreas.Sandberg@ARM.com    assert(isDrained());
1439444SAndreas.Sandberg@ARM.com
1449444SAndreas.Sandberg@ARM.com    for (ThreadID tid = 0; tid < numThreads; tid++)
1459444SAndreas.Sandberg@ARM.com        thread[tid].drainSanityCheck();
1469444SAndreas.Sandberg@ARM.com}
1479444SAndreas.Sandberg@ARM.com
1489444SAndreas.Sandberg@ARM.comtemplate <class Impl>
1499444SAndreas.Sandberg@ARM.combool
1509444SAndreas.Sandberg@ARM.comLSQ<Impl>::isDrained() const
1519444SAndreas.Sandberg@ARM.com{
1529444SAndreas.Sandberg@ARM.com    bool drained(true);
1539444SAndreas.Sandberg@ARM.com
1549444SAndreas.Sandberg@ARM.com    if (!lqEmpty()) {
1559444SAndreas.Sandberg@ARM.com        DPRINTF(Drain, "Not drained, LQ not empty.\n");
1569444SAndreas.Sandberg@ARM.com        drained = false;
1572307SN/A    }
1589444SAndreas.Sandberg@ARM.com
1599444SAndreas.Sandberg@ARM.com    if (!sqEmpty()) {
1609444SAndreas.Sandberg@ARM.com        DPRINTF(Drain, "Not drained, SQ not empty.\n");
1619444SAndreas.Sandberg@ARM.com        drained = false;
1629444SAndreas.Sandberg@ARM.com    }
1639444SAndreas.Sandberg@ARM.com
1649444SAndreas.Sandberg@ARM.com    return drained;
1652307SN/A}
1662307SN/A
1672307SN/Atemplate <class Impl>
1682307SN/Avoid
1692307SN/ALSQ<Impl>::takeOverFrom()
1702307SN/A{
17113590Srekai.gonzalezalberquilla@arm.com    usedStorePorts = 0;
17213590Srekai.gonzalezalberquilla@arm.com    _cacheBlocked = false;
17313590Srekai.gonzalezalberquilla@arm.com
1746221Snate@binkert.org    for (ThreadID tid = 0; tid < numThreads; tid++) {
1752307SN/A        thread[tid].takeOverFrom();
1762307SN/A    }
1772307SN/A}
1782307SN/A
17913710Sgabor.dozsa@arm.comtemplate <class Impl>
18013710Sgabor.dozsa@arm.comvoid
18113710Sgabor.dozsa@arm.comLSQ<Impl>::tick()
18213710Sgabor.dozsa@arm.com{
18313710Sgabor.dozsa@arm.com    // Re-issue loads which got blocked on the per-cycle load ports limit.
18413710Sgabor.dozsa@arm.com    if (usedLoadPorts == cacheLoadPorts && !_cacheBlocked)
18513710Sgabor.dozsa@arm.com        iewStage->cacheUnblocked();
18613710Sgabor.dozsa@arm.com
18713710Sgabor.dozsa@arm.com    usedLoadPorts = 0;
18813710Sgabor.dozsa@arm.com    usedStorePorts = 0;
18913710Sgabor.dozsa@arm.com}
19013710Sgabor.dozsa@arm.com
19113590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
19213590Srekai.gonzalezalberquilla@arm.combool
19313590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::cacheBlocked() const
1942292SN/A{
19513590Srekai.gonzalezalberquilla@arm.com    return _cacheBlocked;
1962292SN/A}
1972292SN/A
1982292SN/Atemplate<class Impl>
1992292SN/Avoid
20013590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::cacheBlocked(bool v)
2012292SN/A{
20213590Srekai.gonzalezalberquilla@arm.com    _cacheBlocked = v;
20313590Srekai.gonzalezalberquilla@arm.com}
20413590Srekai.gonzalezalberquilla@arm.com
20513590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
20613590Srekai.gonzalezalberquilla@arm.combool
20713710Sgabor.dozsa@arm.comLSQ<Impl>::cachePortAvailable(bool is_load) const
20813590Srekai.gonzalezalberquilla@arm.com{
20913710Sgabor.dozsa@arm.com    bool ret;
21013710Sgabor.dozsa@arm.com    if (is_load) {
21113710Sgabor.dozsa@arm.com        ret  = usedLoadPorts < cacheLoadPorts;
21213710Sgabor.dozsa@arm.com    } else {
21313710Sgabor.dozsa@arm.com        ret  = usedStorePorts < cacheStorePorts;
21413710Sgabor.dozsa@arm.com    }
21513710Sgabor.dozsa@arm.com    return ret;
2162292SN/A}
2172292SN/A
2182292SN/Atemplate<class Impl>
2192292SN/Avoid
22013710Sgabor.dozsa@arm.comLSQ<Impl>::cachePortBusy(bool is_load)
2212292SN/A{
22213710Sgabor.dozsa@arm.com    assert(cachePortAvailable(is_load));
22313710Sgabor.dozsa@arm.com    if (is_load) {
22413710Sgabor.dozsa@arm.com        usedLoadPorts++;
22513710Sgabor.dozsa@arm.com    } else {
22613710Sgabor.dozsa@arm.com        usedStorePorts++;
22713710Sgabor.dozsa@arm.com    }
2282292SN/A}
2292292SN/A
2302292SN/Atemplate<class Impl>
2312292SN/Avoid
23213429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::insertLoad(const DynInstPtr &load_inst)
2332292SN/A{
2346221Snate@binkert.org    ThreadID tid = load_inst->threadNumber;
2352292SN/A
2362292SN/A    thread[tid].insertLoad(load_inst);
2372292SN/A}
2382292SN/A
2392292SN/Atemplate<class Impl>
2402292SN/Avoid
24113429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::insertStore(const DynInstPtr &store_inst)
2422292SN/A{
2436221Snate@binkert.org    ThreadID tid = store_inst->threadNumber;
2442292SN/A
2452292SN/A    thread[tid].insertStore(store_inst);
2462292SN/A}
2472292SN/A
2482292SN/Atemplate<class Impl>
2492292SN/AFault
25013429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::executeLoad(const DynInstPtr &inst)
2512292SN/A{
2526221Snate@binkert.org    ThreadID tid = inst->threadNumber;
2532292SN/A
2542292SN/A    return thread[tid].executeLoad(inst);
2552292SN/A}
2562292SN/A
2572292SN/Atemplate<class Impl>
2582292SN/AFault
25913429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::executeStore(const DynInstPtr &inst)
2602292SN/A{
2616221Snate@binkert.org    ThreadID tid = inst->threadNumber;
2622292SN/A
2632292SN/A    return thread[tid].executeStore(inst);
2642292SN/A}
2652292SN/A
2662292SN/Atemplate<class Impl>
2672292SN/Avoid
2682292SN/ALSQ<Impl>::writebackStores()
2692292SN/A{
2706221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
2716221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
2722292SN/A
2733867Sbinkertn@umich.edu    while (threads != end) {
2746221Snate@binkert.org        ThreadID tid = *threads++;
2752292SN/A
2762292SN/A        if (numStoresToWB(tid) > 0) {
2772329SN/A            DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
2782329SN/A                "available for Writeback.\n", tid, numStoresToWB(tid));
2792292SN/A        }
2802292SN/A
2812292SN/A        thread[tid].writebackStores();
2822292SN/A    }
2832292SN/A}
2842292SN/A
2852292SN/Atemplate<class Impl>
2862292SN/Abool
2872292SN/ALSQ<Impl>::violation()
2882292SN/A{
2892292SN/A    /* Answers: Does Anybody Have a Violation?*/
2906221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
2916221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
2922292SN/A
2933867Sbinkertn@umich.edu    while (threads != end) {
2946221Snate@binkert.org        ThreadID tid = *threads++;
2953867Sbinkertn@umich.edu
2962292SN/A        if (thread[tid].violation())
2972292SN/A            return true;
2982292SN/A    }
2992292SN/A
3002292SN/A    return false;
3012292SN/A}
3022292SN/A
3038707Sandreas.hansson@arm.comtemplate <class Impl>
3048707Sandreas.hansson@arm.comvoid
30510713Sandreas.hansson@arm.comLSQ<Impl>::recvReqRetry()
3068707Sandreas.hansson@arm.com{
30710333Smitch.hayenga@arm.com    iewStage->cacheUnblocked();
30813590Srekai.gonzalezalberquilla@arm.com    cacheBlocked(false);
30910333Smitch.hayenga@arm.com
31010333Smitch.hayenga@arm.com    for (ThreadID tid : *activeThreads) {
31110333Smitch.hayenga@arm.com        thread[tid].recvRetry();
3128707Sandreas.hansson@arm.com    }
3138707Sandreas.hansson@arm.com}
3148707Sandreas.hansson@arm.com
3158707Sandreas.hansson@arm.comtemplate <class Impl>
31613590Srekai.gonzalezalberquilla@arm.comvoid
31713590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::completeDataAccess(PacketPtr pkt)
31813590Srekai.gonzalezalberquilla@arm.com{
31913590Srekai.gonzalezalberquilla@arm.com    auto senderState = dynamic_cast<LSQSenderState*>(pkt->senderState);
32013590Srekai.gonzalezalberquilla@arm.com    thread[cpu->contextToThread(senderState->contextId())]
32113590Srekai.gonzalezalberquilla@arm.com        .completeDataAccess(pkt);
32213590Srekai.gonzalezalberquilla@arm.com}
32313590Srekai.gonzalezalberquilla@arm.com
32413590Srekai.gonzalezalberquilla@arm.comtemplate <class Impl>
3258707Sandreas.hansson@arm.combool
3268975Sandreas.hansson@arm.comLSQ<Impl>::recvTimingResp(PacketPtr pkt)
3278707Sandreas.hansson@arm.com{
3288707Sandreas.hansson@arm.com    if (pkt->isError())
3298707Sandreas.hansson@arm.com        DPRINTF(LSQ, "Got error packet back for address: %#X\n",
3308707Sandreas.hansson@arm.com                pkt->getAddr());
33110575SMarco.Elver@ARM.com
33213590Srekai.gonzalezalberquilla@arm.com    auto senderState = dynamic_cast<LSQSenderState*>(pkt->senderState);
33313590Srekai.gonzalezalberquilla@arm.com    panic_if(!senderState, "Got packet back with unknown sender state\n");
33413590Srekai.gonzalezalberquilla@arm.com
33513590Srekai.gonzalezalberquilla@arm.com    thread[cpu->contextToThread(senderState->contextId())].recvTimingResp(pkt);
33610575SMarco.Elver@ARM.com
33710575SMarco.Elver@ARM.com    if (pkt->isInvalidate()) {
33810575SMarco.Elver@ARM.com        // This response also contains an invalidate; e.g. this can be the case
33910575SMarco.Elver@ARM.com        // if cmd is ReadRespWithInvalidate.
34010575SMarco.Elver@ARM.com        //
34110575SMarco.Elver@ARM.com        // The calling order between completeDataAccess and checkSnoop matters.
34210575SMarco.Elver@ARM.com        // By calling checkSnoop after completeDataAccess, we ensure that the
34310575SMarco.Elver@ARM.com        // fault set by checkSnoop is not lost. Calling writeback (more
34410575SMarco.Elver@ARM.com        // specifically inst->completeAcc) in completeDataAccess overwrites
34510575SMarco.Elver@ARM.com        // fault, and in case this instruction requires squashing (as
34610575SMarco.Elver@ARM.com        // determined by checkSnoop), the ReExec fault set by checkSnoop would
34710575SMarco.Elver@ARM.com        // be lost otherwise.
34810575SMarco.Elver@ARM.com
34910575SMarco.Elver@ARM.com        DPRINTF(LSQ, "received invalidation with response for addr:%#x\n",
35010575SMarco.Elver@ARM.com                pkt->getAddr());
35110575SMarco.Elver@ARM.com
35210575SMarco.Elver@ARM.com        for (ThreadID tid = 0; tid < numThreads; tid++) {
35310575SMarco.Elver@ARM.com            thread[tid].checkSnoop(pkt);
35410575SMarco.Elver@ARM.com        }
35510575SMarco.Elver@ARM.com    }
35613590Srekai.gonzalezalberquilla@arm.com    // Update the LSQRequest state (this may delete the request)
35713590Srekai.gonzalezalberquilla@arm.com    senderState->request()->packetReplied();
35810575SMarco.Elver@ARM.com
3598948Sandreas.hansson@arm.com    return true;
3608948Sandreas.hansson@arm.com}
3618707Sandreas.hansson@arm.com
3628948Sandreas.hansson@arm.comtemplate <class Impl>
3638975Sandreas.hansson@arm.comvoid
3648975Sandreas.hansson@arm.comLSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt)
3658948Sandreas.hansson@arm.com{
3668948Sandreas.hansson@arm.com    DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(),
3678948Sandreas.hansson@arm.com            pkt->cmdString());
3688948Sandreas.hansson@arm.com
3698948Sandreas.hansson@arm.com    // must be a snoop
3708948Sandreas.hansson@arm.com    if (pkt->isInvalidate()) {
3718948Sandreas.hansson@arm.com        DPRINTF(LSQ, "received invalidation for addr:%#x\n",
3728948Sandreas.hansson@arm.com                pkt->getAddr());
3738948Sandreas.hansson@arm.com        for (ThreadID tid = 0; tid < numThreads; tid++) {
3748948Sandreas.hansson@arm.com            thread[tid].checkSnoop(pkt);
3758707Sandreas.hansson@arm.com        }
3768707Sandreas.hansson@arm.com    }
3778707Sandreas.hansson@arm.com}
3788707Sandreas.hansson@arm.com
3792292SN/Atemplate<class Impl>
3802292SN/Aint
3812292SN/ALSQ<Impl>::getCount()
3822292SN/A{
3832292SN/A    unsigned total = 0;
3842292SN/A
3856221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
3866221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
3872292SN/A
3883867Sbinkertn@umich.edu    while (threads != end) {
3896221Snate@binkert.org        ThreadID tid = *threads++;
3903867Sbinkertn@umich.edu
3912292SN/A        total += getCount(tid);
3922292SN/A    }
3932292SN/A
3942292SN/A    return total;
3952292SN/A}
3962292SN/A
3972292SN/Atemplate<class Impl>
3982292SN/Aint
3992292SN/ALSQ<Impl>::numLoads()
4002292SN/A{
4012292SN/A    unsigned total = 0;
4022292SN/A
4036221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
4046221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
4052292SN/A
4063867Sbinkertn@umich.edu    while (threads != end) {
4076221Snate@binkert.org        ThreadID tid = *threads++;
4083867Sbinkertn@umich.edu
4092292SN/A        total += numLoads(tid);
4102292SN/A    }
4112292SN/A
4122292SN/A    return total;
4132292SN/A}
4142292SN/A
4152292SN/Atemplate<class Impl>
4162292SN/Aint
4172292SN/ALSQ<Impl>::numStores()
4182292SN/A{
4192292SN/A    unsigned total = 0;
4202292SN/A
4216221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
4226221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
4232292SN/A
4243867Sbinkertn@umich.edu    while (threads != end) {
4256221Snate@binkert.org        ThreadID tid = *threads++;
4263867Sbinkertn@umich.edu
4272292SN/A        total += thread[tid].numStores();
4282292SN/A    }
4292292SN/A
4302292SN/A    return total;
4312292SN/A}
4322292SN/A
4332292SN/Atemplate<class Impl>
4342292SN/Aunsigned
43510239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeLoadEntries()
4362292SN/A{
4372292SN/A    unsigned total = 0;
4382292SN/A
4396221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
4406221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
4412292SN/A
4423867Sbinkertn@umich.edu    while (threads != end) {
4436221Snate@binkert.org        ThreadID tid = *threads++;
4443867Sbinkertn@umich.edu
44510239Sbinhpham@cs.rutgers.edu        total += thread[tid].numFreeLoadEntries();
4462292SN/A    }
4472292SN/A
4482292SN/A    return total;
4492292SN/A}
4502292SN/A
4512292SN/Atemplate<class Impl>
4522292SN/Aunsigned
45310239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeStoreEntries()
4542292SN/A{
45510239Sbinhpham@cs.rutgers.edu    unsigned total = 0;
45610239Sbinhpham@cs.rutgers.edu
45710239Sbinhpham@cs.rutgers.edu    list<ThreadID>::iterator threads = activeThreads->begin();
45810239Sbinhpham@cs.rutgers.edu    list<ThreadID>::iterator end = activeThreads->end();
45910239Sbinhpham@cs.rutgers.edu
46010239Sbinhpham@cs.rutgers.edu    while (threads != end) {
46110239Sbinhpham@cs.rutgers.edu        ThreadID tid = *threads++;
46210239Sbinhpham@cs.rutgers.edu
46310239Sbinhpham@cs.rutgers.edu        total += thread[tid].numFreeStoreEntries();
46410239Sbinhpham@cs.rutgers.edu    }
46510239Sbinhpham@cs.rutgers.edu
46610239Sbinhpham@cs.rutgers.edu    return total;
46710239Sbinhpham@cs.rutgers.edu}
46810239Sbinhpham@cs.rutgers.edu
46910239Sbinhpham@cs.rutgers.edutemplate<class Impl>
47010239Sbinhpham@cs.rutgers.eduunsigned
47110239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeLoadEntries(ThreadID tid)
47210239Sbinhpham@cs.rutgers.edu{
47310239Sbinhpham@cs.rutgers.edu        return thread[tid].numFreeLoadEntries();
47410239Sbinhpham@cs.rutgers.edu}
47510239Sbinhpham@cs.rutgers.edu
47610239Sbinhpham@cs.rutgers.edutemplate<class Impl>
47710239Sbinhpham@cs.rutgers.eduunsigned
47810239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeStoreEntries(ThreadID tid)
47910239Sbinhpham@cs.rutgers.edu{
48010239Sbinhpham@cs.rutgers.edu        return thread[tid].numFreeStoreEntries();
4812292SN/A}
4822292SN/A
4832292SN/Atemplate<class Impl>
4842292SN/Abool
4852292SN/ALSQ<Impl>::isFull()
4862292SN/A{
4876221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
4886221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
4892292SN/A
4903867Sbinkertn@umich.edu    while (threads != end) {
4916221Snate@binkert.org        ThreadID tid = *threads++;
4923867Sbinkertn@umich.edu
4933867Sbinkertn@umich.edu        if (!(thread[tid].lqFull() || thread[tid].sqFull()))
4942292SN/A            return false;
4952292SN/A    }
4962292SN/A
4972292SN/A    return true;
4982292SN/A}
4992292SN/A
5002292SN/Atemplate<class Impl>
5012292SN/Abool
5026221Snate@binkert.orgLSQ<Impl>::isFull(ThreadID tid)
5032292SN/A{
5042292SN/A    //@todo: Change to Calculate All Entries for
5052292SN/A    //Dynamic Policy
50613560Snikos.nikoleris@arm.com    if (lsqPolicy == SMTQueuePolicy::Dynamic)
5072292SN/A        return isFull();
5082292SN/A    else
5092292SN/A        return thread[tid].lqFull() || thread[tid].sqFull();
5102292SN/A}
5112292SN/A
5122292SN/Atemplate<class Impl>
5132292SN/Abool
5149444SAndreas.Sandberg@ARM.comLSQ<Impl>::isEmpty() const
5159444SAndreas.Sandberg@ARM.com{
5169444SAndreas.Sandberg@ARM.com    return lqEmpty() && sqEmpty();
5179444SAndreas.Sandberg@ARM.com}
5189444SAndreas.Sandberg@ARM.com
5199444SAndreas.Sandberg@ARM.comtemplate<class Impl>
5209444SAndreas.Sandberg@ARM.combool
5219444SAndreas.Sandberg@ARM.comLSQ<Impl>::lqEmpty() const
5229444SAndreas.Sandberg@ARM.com{
5239444SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator threads = activeThreads->begin();
5249444SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator end = activeThreads->end();
5259444SAndreas.Sandberg@ARM.com
5269444SAndreas.Sandberg@ARM.com    while (threads != end) {
5279444SAndreas.Sandberg@ARM.com        ThreadID tid = *threads++;
5289444SAndreas.Sandberg@ARM.com
5299444SAndreas.Sandberg@ARM.com        if (!thread[tid].lqEmpty())
5309444SAndreas.Sandberg@ARM.com            return false;
5319444SAndreas.Sandberg@ARM.com    }
5329444SAndreas.Sandberg@ARM.com
5339444SAndreas.Sandberg@ARM.com    return true;
5349444SAndreas.Sandberg@ARM.com}
5359444SAndreas.Sandberg@ARM.com
5369444SAndreas.Sandberg@ARM.comtemplate<class Impl>
5379444SAndreas.Sandberg@ARM.combool
5389444SAndreas.Sandberg@ARM.comLSQ<Impl>::sqEmpty() const
5399444SAndreas.Sandberg@ARM.com{
5409444SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator threads = activeThreads->begin();
5419444SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator end = activeThreads->end();
5429444SAndreas.Sandberg@ARM.com
5439444SAndreas.Sandberg@ARM.com    while (threads != end) {
5449444SAndreas.Sandberg@ARM.com        ThreadID tid = *threads++;
5459444SAndreas.Sandberg@ARM.com
5469444SAndreas.Sandberg@ARM.com        if (!thread[tid].sqEmpty())
5479444SAndreas.Sandberg@ARM.com            return false;
5489444SAndreas.Sandberg@ARM.com    }
5499444SAndreas.Sandberg@ARM.com
5509444SAndreas.Sandberg@ARM.com    return true;
5519444SAndreas.Sandberg@ARM.com}
5529444SAndreas.Sandberg@ARM.com
5539444SAndreas.Sandberg@ARM.comtemplate<class Impl>
5549444SAndreas.Sandberg@ARM.combool
5552292SN/ALSQ<Impl>::lqFull()
5562292SN/A{
5576221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
5586221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
5592292SN/A
5603867Sbinkertn@umich.edu    while (threads != end) {
5616221Snate@binkert.org        ThreadID tid = *threads++;
5623867Sbinkertn@umich.edu
5632292SN/A        if (!thread[tid].lqFull())
5642292SN/A            return false;
5652292SN/A    }
5662292SN/A
5672292SN/A    return true;
5682292SN/A}
5692292SN/A
5702292SN/Atemplate<class Impl>
5712292SN/Abool
5726221Snate@binkert.orgLSQ<Impl>::lqFull(ThreadID tid)
5732292SN/A{
5742292SN/A    //@todo: Change to Calculate All Entries for
5752292SN/A    //Dynamic Policy
57613560Snikos.nikoleris@arm.com    if (lsqPolicy == SMTQueuePolicy::Dynamic)
5772292SN/A        return lqFull();
5782292SN/A    else
5792292SN/A        return thread[tid].lqFull();
5802292SN/A}
5812292SN/A
5822292SN/Atemplate<class Impl>
5832292SN/Abool
5842292SN/ALSQ<Impl>::sqFull()
5852292SN/A{
5866221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
5876221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
5882292SN/A
5893867Sbinkertn@umich.edu    while (threads != end) {
5906221Snate@binkert.org        ThreadID tid = *threads++;
5913867Sbinkertn@umich.edu
5922292SN/A        if (!sqFull(tid))
5932292SN/A            return false;
5942292SN/A    }
5952292SN/A
5962292SN/A    return true;
5972292SN/A}
5982292SN/A
5992292SN/Atemplate<class Impl>
6002292SN/Abool
6016221Snate@binkert.orgLSQ<Impl>::sqFull(ThreadID tid)
6022292SN/A{
6032292SN/A     //@todo: Change to Calculate All Entries for
6042292SN/A    //Dynamic Policy
60513560Snikos.nikoleris@arm.com    if (lsqPolicy == SMTQueuePolicy::Dynamic)
6062292SN/A        return sqFull();
6072292SN/A    else
6082292SN/A        return thread[tid].sqFull();
6092292SN/A}
6102292SN/A
6112292SN/Atemplate<class Impl>
6122292SN/Abool
6132292SN/ALSQ<Impl>::isStalled()
6142292SN/A{
6156221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
6166221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
6172292SN/A
6183867Sbinkertn@umich.edu    while (threads != end) {
6196221Snate@binkert.org        ThreadID tid = *threads++;
6203867Sbinkertn@umich.edu
6212292SN/A        if (!thread[tid].isStalled())
6222292SN/A            return false;
6232292SN/A    }
6242292SN/A
6252292SN/A    return true;
6262292SN/A}
6272292SN/A
6282292SN/Atemplate<class Impl>
6292292SN/Abool
6306221Snate@binkert.orgLSQ<Impl>::isStalled(ThreadID tid)
6312292SN/A{
63213560Snikos.nikoleris@arm.com    if (lsqPolicy == SMTQueuePolicy::Dynamic)
6332292SN/A        return isStalled();
6342292SN/A    else
6352292SN/A        return thread[tid].isStalled();
6362292SN/A}
6372292SN/A
6382292SN/Atemplate<class Impl>
6392292SN/Abool
6402292SN/ALSQ<Impl>::hasStoresToWB()
6412292SN/A{
6426221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
6436221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
6442292SN/A
6453867Sbinkertn@umich.edu    while (threads != end) {
6466221Snate@binkert.org        ThreadID tid = *threads++;
6473867Sbinkertn@umich.edu
6485557Sktlim@umich.edu        if (hasStoresToWB(tid))
6495557Sktlim@umich.edu            return true;
6502292SN/A    }
6512292SN/A
6525557Sktlim@umich.edu    return false;
6532292SN/A}
6542292SN/A
6552292SN/Atemplate<class Impl>
6562292SN/Abool
6572292SN/ALSQ<Impl>::willWB()
6582292SN/A{
6596221Snate@binkert.org    list<ThreadID>::iterator threads = activeThreads->begin();
6606221Snate@binkert.org    list<ThreadID>::iterator end = activeThreads->end();
6612292SN/A
6623867Sbinkertn@umich.edu    while (threads != end) {
6636221Snate@binkert.org        ThreadID tid = *threads++;
6643867Sbinkertn@umich.edu
6655557Sktlim@umich.edu        if (willWB(tid))
6665557Sktlim@umich.edu            return true;
6672292SN/A    }
6682292SN/A
6695557Sktlim@umich.edu    return false;
6702292SN/A}
6712292SN/A
6722292SN/Atemplate<class Impl>
6732292SN/Avoid
6749440SAndreas.Sandberg@ARM.comLSQ<Impl>::dumpInsts() const
6752292SN/A{
6769440SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator threads = activeThreads->begin();
6779440SAndreas.Sandberg@ARM.com    list<ThreadID>::const_iterator end = activeThreads->end();
6782292SN/A
6793867Sbinkertn@umich.edu    while (threads != end) {
6806221Snate@binkert.org        ThreadID tid = *threads++;
6813867Sbinkertn@umich.edu
6822292SN/A        thread[tid].dumpInsts();
6832292SN/A    }
6842292SN/A}
6859944Smatt.horsnell@ARM.com
68613590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
68713590Srekai.gonzalezalberquilla@arm.comFault
68813590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::pushRequest(const DynInstPtr& inst, bool isLoad, uint8_t *data,
68913590Srekai.gonzalezalberquilla@arm.com                       unsigned int size, Addr addr, Request::Flags flags,
69014297Sjordi.vaquero@metempsy.com                       uint64_t *res, AtomicOpFunctorPtr amo_op,
69113954Sgiacomo.gabrielli@arm.com                       const std::vector<bool>& byteEnable)
69213590Srekai.gonzalezalberquilla@arm.com{
69313652Sqtt2@cornell.edu    // This comming request can be either load, store or atomic.
69413652Sqtt2@cornell.edu    // Atomic request has a corresponding pointer to its atomic memory
69513652Sqtt2@cornell.edu    // operation
69613688Sgiacomo.travaglini@arm.com    bool isAtomic M5_VAR_USED = !isLoad && amo_op;
69713652Sqtt2@cornell.edu
69813590Srekai.gonzalezalberquilla@arm.com    ThreadID tid = cpu->contextToThread(inst->contextId());
69913590Srekai.gonzalezalberquilla@arm.com    auto cacheLineSize = cpu->cacheLineSize();
70013590Srekai.gonzalezalberquilla@arm.com    bool needs_burst = transferNeedsBurst(addr, size, cacheLineSize);
70113590Srekai.gonzalezalberquilla@arm.com    LSQRequest* req = nullptr;
70213590Srekai.gonzalezalberquilla@arm.com
70313652Sqtt2@cornell.edu    // Atomic requests that access data across cache line boundary are
70413652Sqtt2@cornell.edu    // currently not allowed since the cache does not guarantee corresponding
70513652Sqtt2@cornell.edu    // atomic memory operations to be executed atomically across a cache line.
70613652Sqtt2@cornell.edu    // For ISAs such as x86 that supports cross-cache-line atomic instructions,
70713652Sqtt2@cornell.edu    // the cache needs to be modified to perform atomic update to both cache
70813652Sqtt2@cornell.edu    // lines. For now, such cross-line update is not supported.
70913652Sqtt2@cornell.edu    assert(!isAtomic || (isAtomic && !needs_burst));
71013652Sqtt2@cornell.edu
71113590Srekai.gonzalezalberquilla@arm.com    if (inst->translationStarted()) {
71213590Srekai.gonzalezalberquilla@arm.com        req = inst->savedReq;
71313590Srekai.gonzalezalberquilla@arm.com        assert(req);
71413590Srekai.gonzalezalberquilla@arm.com    } else {
71513590Srekai.gonzalezalberquilla@arm.com        if (needs_burst) {
71613590Srekai.gonzalezalberquilla@arm.com            req = new SplitDataRequest(&thread[tid], inst, isLoad, addr,
71713590Srekai.gonzalezalberquilla@arm.com                    size, flags, data, res);
71813590Srekai.gonzalezalberquilla@arm.com        } else {
71913590Srekai.gonzalezalberquilla@arm.com            req = new SingleDataRequest(&thread[tid], inst, isLoad, addr,
72014297Sjordi.vaquero@metempsy.com                    size, flags, data, res, std::move(amo_op));
72113590Srekai.gonzalezalberquilla@arm.com        }
72213590Srekai.gonzalezalberquilla@arm.com        assert(req);
72313954Sgiacomo.gabrielli@arm.com        if (!byteEnable.empty()) {
72413954Sgiacomo.gabrielli@arm.com            req->_byteEnable = byteEnable;
72513954Sgiacomo.gabrielli@arm.com        }
72613590Srekai.gonzalezalberquilla@arm.com        inst->setRequest();
72713590Srekai.gonzalezalberquilla@arm.com        req->taskId(cpu->taskId());
72813590Srekai.gonzalezalberquilla@arm.com
72914080Sgabor.dozsa@arm.com        // There might be fault from a previous execution attempt if this is
73014080Sgabor.dozsa@arm.com        // a strictly ordered load
73114080Sgabor.dozsa@arm.com        inst->getFault() = NoFault;
73214080Sgabor.dozsa@arm.com
73313590Srekai.gonzalezalberquilla@arm.com        req->initiateTranslation();
73413590Srekai.gonzalezalberquilla@arm.com    }
73513590Srekai.gonzalezalberquilla@arm.com
73613590Srekai.gonzalezalberquilla@arm.com    /* This is the place were instructions get the effAddr. */
73713590Srekai.gonzalezalberquilla@arm.com    if (req->isTranslationComplete()) {
73814105Sgabor.dozsa@arm.com        if (req->isMemAccessRequired()) {
73913590Srekai.gonzalezalberquilla@arm.com            inst->effAddr = req->getVaddr();
74013590Srekai.gonzalezalberquilla@arm.com            inst->effSize = size;
74113590Srekai.gonzalezalberquilla@arm.com            inst->effAddrValid(true);
74213590Srekai.gonzalezalberquilla@arm.com
74313590Srekai.gonzalezalberquilla@arm.com            if (cpu->checker) {
74413590Srekai.gonzalezalberquilla@arm.com                inst->reqToVerify = std::make_shared<Request>(*req->request());
74513590Srekai.gonzalezalberquilla@arm.com            }
74614105Sgabor.dozsa@arm.com            Fault fault;
74713590Srekai.gonzalezalberquilla@arm.com            if (isLoad)
74814105Sgabor.dozsa@arm.com                fault = cpu->read(req, inst->lqIdx);
74913590Srekai.gonzalezalberquilla@arm.com            else
75014105Sgabor.dozsa@arm.com                fault = cpu->write(req, data, inst->sqIdx);
75114105Sgabor.dozsa@arm.com            // inst->getFault() may have the first-fault of a
75214105Sgabor.dozsa@arm.com            // multi-access split request at this point.
75314105Sgabor.dozsa@arm.com            // Overwrite that only if we got another type of fault
75414105Sgabor.dozsa@arm.com            // (e.g. re-exec).
75514105Sgabor.dozsa@arm.com            if (fault != NoFault)
75614105Sgabor.dozsa@arm.com                inst->getFault() = fault;
75713590Srekai.gonzalezalberquilla@arm.com        } else if (isLoad) {
75813954Sgiacomo.gabrielli@arm.com            inst->setMemAccPredicate(false);
75913590Srekai.gonzalezalberquilla@arm.com            // Commit will have to clean up whatever happened.  Set this
76013590Srekai.gonzalezalberquilla@arm.com            // instruction as executed.
76113590Srekai.gonzalezalberquilla@arm.com            inst->setExecuted();
76213590Srekai.gonzalezalberquilla@arm.com        }
76313590Srekai.gonzalezalberquilla@arm.com    }
76413590Srekai.gonzalezalberquilla@arm.com
76513590Srekai.gonzalezalberquilla@arm.com    if (inst->traceData)
76613590Srekai.gonzalezalberquilla@arm.com        inst->traceData->setMem(addr, size, flags);
76713590Srekai.gonzalezalberquilla@arm.com
76813590Srekai.gonzalezalberquilla@arm.com    return inst->getFault();
76913590Srekai.gonzalezalberquilla@arm.com}
77013590Srekai.gonzalezalberquilla@arm.com
77113590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
77213590Srekai.gonzalezalberquilla@arm.comvoid
77313590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::finish(const Fault &fault, const RequestPtr &req,
77413590Srekai.gonzalezalberquilla@arm.com        ThreadContext* tc, BaseTLB::Mode mode)
77513590Srekai.gonzalezalberquilla@arm.com{
77613590Srekai.gonzalezalberquilla@arm.com    _fault.push_back(fault);
77713590Srekai.gonzalezalberquilla@arm.com    numInTranslationFragments = 0;
77813590Srekai.gonzalezalberquilla@arm.com    numTranslatedFragments = 1;
77913590Srekai.gonzalezalberquilla@arm.com    /* If the instruction has been squahsed, let the request know
78013590Srekai.gonzalezalberquilla@arm.com     * as it may have to self-destruct. */
78113590Srekai.gonzalezalberquilla@arm.com    if (_inst->isSquashed()) {
78213590Srekai.gonzalezalberquilla@arm.com        this->squashTranslation();
78313590Srekai.gonzalezalberquilla@arm.com    } else {
78413590Srekai.gonzalezalberquilla@arm.com        _inst->strictlyOrdered(req->isStrictlyOrdered());
78513590Srekai.gonzalezalberquilla@arm.com
78613590Srekai.gonzalezalberquilla@arm.com        flags.set(Flag::TranslationFinished);
78713590Srekai.gonzalezalberquilla@arm.com        if (fault == NoFault) {
78813590Srekai.gonzalezalberquilla@arm.com            _inst->physEffAddr = req->getPaddr();
78913590Srekai.gonzalezalberquilla@arm.com            _inst->memReqFlags = req->getFlags();
79013590Srekai.gonzalezalberquilla@arm.com            if (req->isCondSwap()) {
79113590Srekai.gonzalezalberquilla@arm.com                assert(_res);
79213590Srekai.gonzalezalberquilla@arm.com                req->setExtraData(*_res);
79313590Srekai.gonzalezalberquilla@arm.com            }
79413590Srekai.gonzalezalberquilla@arm.com            setState(State::Request);
79513590Srekai.gonzalezalberquilla@arm.com        } else {
79613590Srekai.gonzalezalberquilla@arm.com            setState(State::Fault);
79713590Srekai.gonzalezalberquilla@arm.com        }
79813590Srekai.gonzalezalberquilla@arm.com
79913590Srekai.gonzalezalberquilla@arm.com        LSQRequest::_inst->fault = fault;
80013590Srekai.gonzalezalberquilla@arm.com        LSQRequest::_inst->translationCompleted(true);
80113590Srekai.gonzalezalberquilla@arm.com    }
80213590Srekai.gonzalezalberquilla@arm.com}
80313590Srekai.gonzalezalberquilla@arm.com
80413590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
80513590Srekai.gonzalezalberquilla@arm.comvoid
80613590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::finish(const Fault &fault, const RequestPtr &req,
80713590Srekai.gonzalezalberquilla@arm.com        ThreadContext* tc, BaseTLB::Mode mode)
80813590Srekai.gonzalezalberquilla@arm.com{
80914105Sgabor.dozsa@arm.com    int i;
81014105Sgabor.dozsa@arm.com    for (i = 0; i < _requests.size() && _requests[i] != req; i++);
81114105Sgabor.dozsa@arm.com    assert(i < _requests.size());
81214105Sgabor.dozsa@arm.com    _fault[i] = fault;
81313590Srekai.gonzalezalberquilla@arm.com
81413590Srekai.gonzalezalberquilla@arm.com    numInTranslationFragments--;
81513590Srekai.gonzalezalberquilla@arm.com    numTranslatedFragments++;
81613590Srekai.gonzalezalberquilla@arm.com
81714105Sgabor.dozsa@arm.com    if (fault == NoFault)
81814105Sgabor.dozsa@arm.com        mainReq->setFlags(req->getFlags());
81913590Srekai.gonzalezalberquilla@arm.com
82013590Srekai.gonzalezalberquilla@arm.com    if (numTranslatedFragments == _requests.size()) {
82113590Srekai.gonzalezalberquilla@arm.com        if (_inst->isSquashed()) {
82213590Srekai.gonzalezalberquilla@arm.com            this->squashTranslation();
82313590Srekai.gonzalezalberquilla@arm.com        } else {
82413590Srekai.gonzalezalberquilla@arm.com            _inst->strictlyOrdered(mainReq->isStrictlyOrdered());
82513590Srekai.gonzalezalberquilla@arm.com            flags.set(Flag::TranslationFinished);
82614105Sgabor.dozsa@arm.com            _inst->translationCompleted(true);
82714105Sgabor.dozsa@arm.com
82814105Sgabor.dozsa@arm.com            for (i = 0; i < _fault.size() && _fault[i] == NoFault; i++);
82914105Sgabor.dozsa@arm.com            if (i > 0) {
83013590Srekai.gonzalezalberquilla@arm.com                _inst->physEffAddr = request(0)->getPaddr();
83113590Srekai.gonzalezalberquilla@arm.com                _inst->memReqFlags = mainReq->getFlags();
83213590Srekai.gonzalezalberquilla@arm.com                if (mainReq->isCondSwap()) {
83314105Sgabor.dozsa@arm.com                    assert (i == _fault.size());
83413590Srekai.gonzalezalberquilla@arm.com                    assert(_res);
83513590Srekai.gonzalezalberquilla@arm.com                    mainReq->setExtraData(*_res);
83613590Srekai.gonzalezalberquilla@arm.com                }
83714105Sgabor.dozsa@arm.com                if (i == _fault.size()) {
83814105Sgabor.dozsa@arm.com                    _inst->fault = NoFault;
83914105Sgabor.dozsa@arm.com                    setState(State::Request);
84014105Sgabor.dozsa@arm.com                } else {
84114105Sgabor.dozsa@arm.com                  _inst->fault = _fault[i];
84214105Sgabor.dozsa@arm.com                  setState(State::PartialFault);
84314105Sgabor.dozsa@arm.com                }
84413590Srekai.gonzalezalberquilla@arm.com            } else {
84514105Sgabor.dozsa@arm.com                _inst->fault = _fault[0];
84613590Srekai.gonzalezalberquilla@arm.com                setState(State::Fault);
84713590Srekai.gonzalezalberquilla@arm.com            }
84813590Srekai.gonzalezalberquilla@arm.com        }
84914105Sgabor.dozsa@arm.com
85013590Srekai.gonzalezalberquilla@arm.com    }
85113590Srekai.gonzalezalberquilla@arm.com}
85213590Srekai.gonzalezalberquilla@arm.com
85313590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
85413590Srekai.gonzalezalberquilla@arm.comvoid
85513590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::initiateTranslation()
85613590Srekai.gonzalezalberquilla@arm.com{
85713954Sgiacomo.gabrielli@arm.com    assert(_requests.size() == 0);
85813590Srekai.gonzalezalberquilla@arm.com
85913954Sgiacomo.gabrielli@arm.com    this->addRequest(_addr, _size, _byteEnable);
86013590Srekai.gonzalezalberquilla@arm.com
86113954Sgiacomo.gabrielli@arm.com    if (_requests.size() > 0) {
86213954Sgiacomo.gabrielli@arm.com        _requests.back()->setReqInstSeqNum(_inst->seqNum);
86313954Sgiacomo.gabrielli@arm.com        _requests.back()->taskId(_taskId);
86413954Sgiacomo.gabrielli@arm.com        _inst->translationStarted(true);
86513954Sgiacomo.gabrielli@arm.com        setState(State::Translation);
86613954Sgiacomo.gabrielli@arm.com        flags.set(Flag::TranslationStarted);
86713954Sgiacomo.gabrielli@arm.com
86813954Sgiacomo.gabrielli@arm.com        _inst->savedReq = this;
86913954Sgiacomo.gabrielli@arm.com        sendFragmentToTranslation(0);
87013954Sgiacomo.gabrielli@arm.com    } else {
87113954Sgiacomo.gabrielli@arm.com        _inst->setMemAccPredicate(false);
87213590Srekai.gonzalezalberquilla@arm.com    }
87313590Srekai.gonzalezalberquilla@arm.com}
87413590Srekai.gonzalezalberquilla@arm.com
87513590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
87613590Srekai.gonzalezalberquilla@arm.comPacketPtr
87713590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::mainPacket()
87813590Srekai.gonzalezalberquilla@arm.com{
87913590Srekai.gonzalezalberquilla@arm.com    return _mainPacket;
88013590Srekai.gonzalezalberquilla@arm.com}
88113590Srekai.gonzalezalberquilla@arm.com
88213590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
88313590Srekai.gonzalezalberquilla@arm.comRequestPtr
88413590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::mainRequest()
88513590Srekai.gonzalezalberquilla@arm.com{
88613590Srekai.gonzalezalberquilla@arm.com    return mainReq;
88713590Srekai.gonzalezalberquilla@arm.com}
88813590Srekai.gonzalezalberquilla@arm.com
88913590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
89013590Srekai.gonzalezalberquilla@arm.comvoid
89113590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::initiateTranslation()
89213590Srekai.gonzalezalberquilla@arm.com{
89313954Sgiacomo.gabrielli@arm.com    auto cacheLineSize = _port.cacheLineSize();
89413590Srekai.gonzalezalberquilla@arm.com    Addr base_addr = _addr;
89513590Srekai.gonzalezalberquilla@arm.com    Addr next_addr = addrBlockAlign(_addr + cacheLineSize, cacheLineSize);
89613590Srekai.gonzalezalberquilla@arm.com    Addr final_addr = addrBlockAlign(_addr + _size, cacheLineSize);
89713590Srekai.gonzalezalberquilla@arm.com    uint32_t size_so_far = 0;
89813590Srekai.gonzalezalberquilla@arm.com
89913590Srekai.gonzalezalberquilla@arm.com    mainReq = std::make_shared<Request>(_inst->getASID(), base_addr,
90013590Srekai.gonzalezalberquilla@arm.com                _size, _flags, _inst->masterId(),
90113590Srekai.gonzalezalberquilla@arm.com                _inst->instAddr(), _inst->contextId());
90213954Sgiacomo.gabrielli@arm.com    if (!_byteEnable.empty()) {
90313954Sgiacomo.gabrielli@arm.com        mainReq->setByteEnable(_byteEnable);
90413954Sgiacomo.gabrielli@arm.com    }
90513590Srekai.gonzalezalberquilla@arm.com
90613590Srekai.gonzalezalberquilla@arm.com    // Paddr is not used in mainReq. However, we will accumulate the flags
90713590Srekai.gonzalezalberquilla@arm.com    // from the sub requests into mainReq by calling setFlags() in finish().
90813590Srekai.gonzalezalberquilla@arm.com    // setFlags() assumes that paddr is set so flip the paddr valid bit here to
90913590Srekai.gonzalezalberquilla@arm.com    // avoid a potential assert in setFlags() when we call it from  finish().
91013590Srekai.gonzalezalberquilla@arm.com    mainReq->setPaddr(0);
91113590Srekai.gonzalezalberquilla@arm.com
91213590Srekai.gonzalezalberquilla@arm.com    /* Get the pre-fix, possibly unaligned. */
91313954Sgiacomo.gabrielli@arm.com    if (_byteEnable.empty()) {
91413954Sgiacomo.gabrielli@arm.com        this->addRequest(base_addr, next_addr - base_addr, _byteEnable);
91513954Sgiacomo.gabrielli@arm.com    } else {
91613954Sgiacomo.gabrielli@arm.com        auto it_start = _byteEnable.begin();
91713954Sgiacomo.gabrielli@arm.com        auto it_end = _byteEnable.begin() + (next_addr - base_addr);
91813954Sgiacomo.gabrielli@arm.com        this->addRequest(base_addr, next_addr - base_addr,
91913954Sgiacomo.gabrielli@arm.com                         std::vector<bool>(it_start, it_end));
92013954Sgiacomo.gabrielli@arm.com    }
92113590Srekai.gonzalezalberquilla@arm.com    size_so_far = next_addr - base_addr;
92213590Srekai.gonzalezalberquilla@arm.com
92313590Srekai.gonzalezalberquilla@arm.com    /* We are block aligned now, reading whole blocks. */
92413590Srekai.gonzalezalberquilla@arm.com    base_addr = next_addr;
92513590Srekai.gonzalezalberquilla@arm.com    while (base_addr != final_addr) {
92613954Sgiacomo.gabrielli@arm.com        if (_byteEnable.empty()) {
92713954Sgiacomo.gabrielli@arm.com            this->addRequest(base_addr, cacheLineSize, _byteEnable);
92813954Sgiacomo.gabrielli@arm.com        } else {
92913954Sgiacomo.gabrielli@arm.com            auto it_start = _byteEnable.begin() + size_so_far;
93013954Sgiacomo.gabrielli@arm.com            auto it_end = _byteEnable.begin() + size_so_far + cacheLineSize;
93113954Sgiacomo.gabrielli@arm.com            this->addRequest(base_addr, cacheLineSize,
93213954Sgiacomo.gabrielli@arm.com                             std::vector<bool>(it_start, it_end));
93313954Sgiacomo.gabrielli@arm.com        }
93413590Srekai.gonzalezalberquilla@arm.com        size_so_far += cacheLineSize;
93513590Srekai.gonzalezalberquilla@arm.com        base_addr += cacheLineSize;
93613590Srekai.gonzalezalberquilla@arm.com    }
93713590Srekai.gonzalezalberquilla@arm.com
93813590Srekai.gonzalezalberquilla@arm.com    /* Deal with the tail. */
93913590Srekai.gonzalezalberquilla@arm.com    if (size_so_far < _size) {
94013954Sgiacomo.gabrielli@arm.com        if (_byteEnable.empty()) {
94113954Sgiacomo.gabrielli@arm.com            this->addRequest(base_addr, _size - size_so_far, _byteEnable);
94213954Sgiacomo.gabrielli@arm.com        } else {
94313954Sgiacomo.gabrielli@arm.com            auto it_start = _byteEnable.begin() + size_so_far;
94413954Sgiacomo.gabrielli@arm.com            auto it_end = _byteEnable.end();
94513954Sgiacomo.gabrielli@arm.com            this->addRequest(base_addr, _size - size_so_far,
94613954Sgiacomo.gabrielli@arm.com                             std::vector<bool>(it_start, it_end));
94713954Sgiacomo.gabrielli@arm.com        }
94813590Srekai.gonzalezalberquilla@arm.com    }
94913590Srekai.gonzalezalberquilla@arm.com
95013954Sgiacomo.gabrielli@arm.com    if (_requests.size() > 0) {
95113954Sgiacomo.gabrielli@arm.com        /* Setup the requests and send them to translation. */
95213954Sgiacomo.gabrielli@arm.com        for (auto& r: _requests) {
95313954Sgiacomo.gabrielli@arm.com            r->setReqInstSeqNum(_inst->seqNum);
95413954Sgiacomo.gabrielli@arm.com            r->taskId(_taskId);
95513954Sgiacomo.gabrielli@arm.com        }
95613590Srekai.gonzalezalberquilla@arm.com
95713954Sgiacomo.gabrielli@arm.com        _inst->translationStarted(true);
95813954Sgiacomo.gabrielli@arm.com        setState(State::Translation);
95913954Sgiacomo.gabrielli@arm.com        flags.set(Flag::TranslationStarted);
96013954Sgiacomo.gabrielli@arm.com        this->_inst->savedReq = this;
96113954Sgiacomo.gabrielli@arm.com        numInTranslationFragments = 0;
96213954Sgiacomo.gabrielli@arm.com        numTranslatedFragments = 0;
96313954Sgiacomo.gabrielli@arm.com        _fault.resize(_requests.size());
96413954Sgiacomo.gabrielli@arm.com
96513954Sgiacomo.gabrielli@arm.com        for (uint32_t i = 0; i < _requests.size(); i++) {
96613954Sgiacomo.gabrielli@arm.com            sendFragmentToTranslation(i);
96713954Sgiacomo.gabrielli@arm.com        }
96813954Sgiacomo.gabrielli@arm.com    } else {
96913954Sgiacomo.gabrielli@arm.com        _inst->setMemAccPredicate(false);
97013590Srekai.gonzalezalberquilla@arm.com    }
97113590Srekai.gonzalezalberquilla@arm.com}
97213590Srekai.gonzalezalberquilla@arm.com
97313590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
97413590Srekai.gonzalezalberquilla@arm.comvoid
97513590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::LSQRequest::sendFragmentToTranslation(int i)
97613590Srekai.gonzalezalberquilla@arm.com{
97713590Srekai.gonzalezalberquilla@arm.com    numInTranslationFragments++;
97813590Srekai.gonzalezalberquilla@arm.com    _port.dTLB()->translateTiming(
97913590Srekai.gonzalezalberquilla@arm.com            this->request(i),
98013590Srekai.gonzalezalberquilla@arm.com            this->_inst->thread->getTC(), this,
98113590Srekai.gonzalezalberquilla@arm.com            this->isLoad() ? BaseTLB::Read : BaseTLB::Write);
98213590Srekai.gonzalezalberquilla@arm.com}
98313590Srekai.gonzalezalberquilla@arm.com
98413590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
98513590Srekai.gonzalezalberquilla@arm.combool
98613590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::recvTimingResp(PacketPtr pkt)
98713590Srekai.gonzalezalberquilla@arm.com{
98813590Srekai.gonzalezalberquilla@arm.com    assert(_numOutstandingPackets == 1);
98913590Srekai.gonzalezalberquilla@arm.com    auto state = dynamic_cast<LSQSenderState*>(pkt->senderState);
99013590Srekai.gonzalezalberquilla@arm.com    flags.set(Flag::Complete);
99113590Srekai.gonzalezalberquilla@arm.com    state->outstanding--;
99213590Srekai.gonzalezalberquilla@arm.com    assert(pkt == _packets.front());
99313590Srekai.gonzalezalberquilla@arm.com    _port.completeDataAccess(pkt);
99413590Srekai.gonzalezalberquilla@arm.com    return true;
99513590Srekai.gonzalezalberquilla@arm.com}
99613590Srekai.gonzalezalberquilla@arm.com
99713590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
99813590Srekai.gonzalezalberquilla@arm.combool
99913590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::recvTimingResp(PacketPtr pkt)
100013590Srekai.gonzalezalberquilla@arm.com{
100113590Srekai.gonzalezalberquilla@arm.com    auto state = dynamic_cast<LSQSenderState*>(pkt->senderState);
100213590Srekai.gonzalezalberquilla@arm.com    uint32_t pktIdx = 0;
100313590Srekai.gonzalezalberquilla@arm.com    while (pktIdx < _packets.size() && pkt != _packets[pktIdx])
100413590Srekai.gonzalezalberquilla@arm.com        pktIdx++;
100513590Srekai.gonzalezalberquilla@arm.com    assert(pktIdx < _packets.size());
100613590Srekai.gonzalezalberquilla@arm.com    numReceivedPackets++;
100713590Srekai.gonzalezalberquilla@arm.com    state->outstanding--;
100813590Srekai.gonzalezalberquilla@arm.com    if (numReceivedPackets == _packets.size()) {
100913590Srekai.gonzalezalberquilla@arm.com        flags.set(Flag::Complete);
101013590Srekai.gonzalezalberquilla@arm.com        /* Assemble packets. */
101113590Srekai.gonzalezalberquilla@arm.com        PacketPtr resp = isLoad()
101213590Srekai.gonzalezalberquilla@arm.com            ? Packet::createRead(mainReq)
101313590Srekai.gonzalezalberquilla@arm.com            : Packet::createWrite(mainReq);
101413590Srekai.gonzalezalberquilla@arm.com        if (isLoad())
101513590Srekai.gonzalezalberquilla@arm.com            resp->dataStatic(_inst->memData);
101613590Srekai.gonzalezalberquilla@arm.com        else
101713590Srekai.gonzalezalberquilla@arm.com            resp->dataStatic(_data);
101813590Srekai.gonzalezalberquilla@arm.com        resp->senderState = _senderState;
101913590Srekai.gonzalezalberquilla@arm.com        _port.completeDataAccess(resp);
102013590Srekai.gonzalezalberquilla@arm.com        delete resp;
102113590Srekai.gonzalezalberquilla@arm.com    }
102213590Srekai.gonzalezalberquilla@arm.com    return true;
102313590Srekai.gonzalezalberquilla@arm.com}
102413590Srekai.gonzalezalberquilla@arm.com
102513590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
102613590Srekai.gonzalezalberquilla@arm.comvoid
102713590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::buildPackets()
102813590Srekai.gonzalezalberquilla@arm.com{
102913590Srekai.gonzalezalberquilla@arm.com    assert(_senderState);
103013590Srekai.gonzalezalberquilla@arm.com    /* Retries do not create new packets. */
103113590Srekai.gonzalezalberquilla@arm.com    if (_packets.size() == 0) {
103213590Srekai.gonzalezalberquilla@arm.com        _packets.push_back(
103313590Srekai.gonzalezalberquilla@arm.com                isLoad()
103413590Srekai.gonzalezalberquilla@arm.com                    ?  Packet::createRead(request())
103513590Srekai.gonzalezalberquilla@arm.com                    :  Packet::createWrite(request()));
103613590Srekai.gonzalezalberquilla@arm.com        _packets.back()->dataStatic(_inst->memData);
103713590Srekai.gonzalezalberquilla@arm.com        _packets.back()->senderState = _senderState;
103813590Srekai.gonzalezalberquilla@arm.com    }
103913590Srekai.gonzalezalberquilla@arm.com    assert(_packets.size() == 1);
104013590Srekai.gonzalezalberquilla@arm.com}
104113590Srekai.gonzalezalberquilla@arm.com
104213590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
104313590Srekai.gonzalezalberquilla@arm.comvoid
104413590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::buildPackets()
104513590Srekai.gonzalezalberquilla@arm.com{
104613590Srekai.gonzalezalberquilla@arm.com    /* Extra data?? */
104713954Sgiacomo.gabrielli@arm.com    Addr base_address = _addr;
104813954Sgiacomo.gabrielli@arm.com
104913590Srekai.gonzalezalberquilla@arm.com    if (_packets.size() == 0) {
105013590Srekai.gonzalezalberquilla@arm.com        /* New stuff */
105113590Srekai.gonzalezalberquilla@arm.com        if (isLoad()) {
105213590Srekai.gonzalezalberquilla@arm.com            _mainPacket = Packet::createRead(mainReq);
105313590Srekai.gonzalezalberquilla@arm.com            _mainPacket->dataStatic(_inst->memData);
105413590Srekai.gonzalezalberquilla@arm.com        }
105513954Sgiacomo.gabrielli@arm.com        for (int i = 0; i < _requests.size() && _fault[i] == NoFault; i++) {
105613954Sgiacomo.gabrielli@arm.com            RequestPtr r = _requests[i];
105713590Srekai.gonzalezalberquilla@arm.com            PacketPtr pkt = isLoad() ? Packet::createRead(r)
105813954Sgiacomo.gabrielli@arm.com                                     : Packet::createWrite(r);
105913954Sgiacomo.gabrielli@arm.com            ptrdiff_t offset = r->getVaddr() - base_address;
106013590Srekai.gonzalezalberquilla@arm.com            if (isLoad()) {
106113590Srekai.gonzalezalberquilla@arm.com                pkt->dataStatic(_inst->memData + offset);
106213590Srekai.gonzalezalberquilla@arm.com            } else {
106313590Srekai.gonzalezalberquilla@arm.com                uint8_t* req_data = new uint8_t[r->getSize()];
106413590Srekai.gonzalezalberquilla@arm.com                std::memcpy(req_data,
106513590Srekai.gonzalezalberquilla@arm.com                        _inst->memData + offset,
106613590Srekai.gonzalezalberquilla@arm.com                        r->getSize());
106713590Srekai.gonzalezalberquilla@arm.com                pkt->dataDynamic(req_data);
106813590Srekai.gonzalezalberquilla@arm.com            }
106913590Srekai.gonzalezalberquilla@arm.com            pkt->senderState = _senderState;
107013590Srekai.gonzalezalberquilla@arm.com            _packets.push_back(pkt);
107113590Srekai.gonzalezalberquilla@arm.com        }
107213590Srekai.gonzalezalberquilla@arm.com    }
107313954Sgiacomo.gabrielli@arm.com    assert(_packets.size() > 0);
107413590Srekai.gonzalezalberquilla@arm.com}
107513590Srekai.gonzalezalberquilla@arm.com
107613590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
107713590Srekai.gonzalezalberquilla@arm.comvoid
107813590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::sendPacketToCache()
107913590Srekai.gonzalezalberquilla@arm.com{
108013590Srekai.gonzalezalberquilla@arm.com    assert(_numOutstandingPackets == 0);
108113590Srekai.gonzalezalberquilla@arm.com    if (lsqUnit()->trySendPacket(isLoad(), _packets.at(0)))
108213590Srekai.gonzalezalberquilla@arm.com        _numOutstandingPackets = 1;
108313590Srekai.gonzalezalberquilla@arm.com}
108413590Srekai.gonzalezalberquilla@arm.com
108513590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
108613590Srekai.gonzalezalberquilla@arm.comvoid
108713590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::sendPacketToCache()
108813590Srekai.gonzalezalberquilla@arm.com{
108913590Srekai.gonzalezalberquilla@arm.com    /* Try to send the packets. */
109013590Srekai.gonzalezalberquilla@arm.com    while (numReceivedPackets + _numOutstandingPackets < _packets.size() &&
109113590Srekai.gonzalezalberquilla@arm.com            lsqUnit()->trySendPacket(isLoad(),
109213590Srekai.gonzalezalberquilla@arm.com                _packets.at(numReceivedPackets + _numOutstandingPackets))) {
109313590Srekai.gonzalezalberquilla@arm.com        _numOutstandingPackets++;
109413590Srekai.gonzalezalberquilla@arm.com    }
109513590Srekai.gonzalezalberquilla@arm.com}
109613590Srekai.gonzalezalberquilla@arm.com
109713590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
109813590Srekai.gonzalezalberquilla@arm.comvoid
109913590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::handleIprWrite(ThreadContext *thread,
110013590Srekai.gonzalezalberquilla@arm.com                                             PacketPtr pkt)
110113590Srekai.gonzalezalberquilla@arm.com{
110213590Srekai.gonzalezalberquilla@arm.com    TheISA::handleIprWrite(thread, pkt);
110313590Srekai.gonzalezalberquilla@arm.com}
110413590Srekai.gonzalezalberquilla@arm.com
110513590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
110613590Srekai.gonzalezalberquilla@arm.comvoid
110713590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::handleIprWrite(ThreadContext *thread,
110813590Srekai.gonzalezalberquilla@arm.com                                            PacketPtr mainPkt)
110913590Srekai.gonzalezalberquilla@arm.com{
111013590Srekai.gonzalezalberquilla@arm.com    unsigned offset = 0;
111113590Srekai.gonzalezalberquilla@arm.com    for (auto r: _requests) {
111213590Srekai.gonzalezalberquilla@arm.com        PacketPtr pkt = new Packet(r, MemCmd::WriteReq);
111313590Srekai.gonzalezalberquilla@arm.com        pkt->dataStatic(mainPkt->getPtr<uint8_t>() + offset);
111413590Srekai.gonzalezalberquilla@arm.com        TheISA::handleIprWrite(thread, pkt);
111513590Srekai.gonzalezalberquilla@arm.com        offset += r->getSize();
111613590Srekai.gonzalezalberquilla@arm.com        delete pkt;
111713590Srekai.gonzalezalberquilla@arm.com    }
111813590Srekai.gonzalezalberquilla@arm.com}
111913590Srekai.gonzalezalberquilla@arm.com
112013590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
112113590Srekai.gonzalezalberquilla@arm.comCycles
112213590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::handleIprRead(ThreadContext *thread,
112313590Srekai.gonzalezalberquilla@arm.com                                            PacketPtr pkt)
112413590Srekai.gonzalezalberquilla@arm.com{
112513590Srekai.gonzalezalberquilla@arm.com    return TheISA::handleIprRead(thread, pkt);
112613590Srekai.gonzalezalberquilla@arm.com}
112713590Srekai.gonzalezalberquilla@arm.com
112813590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
112913590Srekai.gonzalezalberquilla@arm.comCycles
113013590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::handleIprRead(ThreadContext *thread,
113113590Srekai.gonzalezalberquilla@arm.com                                           PacketPtr mainPkt)
113213590Srekai.gonzalezalberquilla@arm.com{
113313590Srekai.gonzalezalberquilla@arm.com    Cycles delay(0);
113413590Srekai.gonzalezalberquilla@arm.com    unsigned offset = 0;
113513590Srekai.gonzalezalberquilla@arm.com
113613590Srekai.gonzalezalberquilla@arm.com    for (auto r: _requests) {
113713590Srekai.gonzalezalberquilla@arm.com        PacketPtr pkt = new Packet(r, MemCmd::ReadReq);
113813590Srekai.gonzalezalberquilla@arm.com        pkt->dataStatic(mainPkt->getPtr<uint8_t>() + offset);
113913590Srekai.gonzalezalberquilla@arm.com        Cycles d = TheISA::handleIprRead(thread, pkt);
114013590Srekai.gonzalezalberquilla@arm.com        if (d > delay)
114113590Srekai.gonzalezalberquilla@arm.com            delay = d;
114213590Srekai.gonzalezalberquilla@arm.com        offset += r->getSize();
114313590Srekai.gonzalezalberquilla@arm.com        delete pkt;
114413590Srekai.gonzalezalberquilla@arm.com    }
114513590Srekai.gonzalezalberquilla@arm.com    return delay;
114613590Srekai.gonzalezalberquilla@arm.com}
114713590Srekai.gonzalezalberquilla@arm.com
114813590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
114913590Srekai.gonzalezalberquilla@arm.combool
115013590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::isCacheBlockHit(Addr blockAddr, Addr blockMask)
115113590Srekai.gonzalezalberquilla@arm.com{
115213590Srekai.gonzalezalberquilla@arm.com    return ( (LSQRequest::_requests[0]->getPaddr() & blockMask) == blockAddr);
115313590Srekai.gonzalezalberquilla@arm.com}
115413590Srekai.gonzalezalberquilla@arm.com
115513590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl>
115613590Srekai.gonzalezalberquilla@arm.combool
115713590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::isCacheBlockHit(Addr blockAddr, Addr blockMask)
115813590Srekai.gonzalezalberquilla@arm.com{
115913590Srekai.gonzalezalberquilla@arm.com    bool is_hit = false;
116013590Srekai.gonzalezalberquilla@arm.com    for (auto &r: _requests) {
116113590Srekai.gonzalezalberquilla@arm.com        if ((r->getPaddr() & blockMask) == blockAddr) {
116213590Srekai.gonzalezalberquilla@arm.com            is_hit = true;
116313590Srekai.gonzalezalberquilla@arm.com            break;
116413590Srekai.gonzalezalberquilla@arm.com        }
116513590Srekai.gonzalezalberquilla@arm.com    }
116613590Srekai.gonzalezalberquilla@arm.com    return is_hit;
116713590Srekai.gonzalezalberquilla@arm.com}
116813590Srekai.gonzalezalberquilla@arm.com
116914194Sgabeblack@google.comtemplate <class Impl>
117014194Sgabeblack@google.combool
117114194Sgabeblack@google.comLSQ<Impl>::DcachePort::recvTimingResp(PacketPtr pkt)
117214194Sgabeblack@google.com{
117314194Sgabeblack@google.com    return lsq->recvTimingResp(pkt);
117414194Sgabeblack@google.com}
117514194Sgabeblack@google.com
117614194Sgabeblack@google.comtemplate <class Impl>
117714194Sgabeblack@google.comvoid
117814194Sgabeblack@google.comLSQ<Impl>::DcachePort::recvTimingSnoopReq(PacketPtr pkt)
117914194Sgabeblack@google.com{
118014194Sgabeblack@google.com    for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
118114194Sgabeblack@google.com        if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
118214194Sgabeblack@google.com            cpu->wakeup(tid);
118314194Sgabeblack@google.com        }
118414194Sgabeblack@google.com    }
118514194Sgabeblack@google.com    lsq->recvTimingSnoopReq(pkt);
118614194Sgabeblack@google.com}
118714194Sgabeblack@google.com
118814194Sgabeblack@google.comtemplate <class Impl>
118914194Sgabeblack@google.comvoid
119014194Sgabeblack@google.comLSQ<Impl>::DcachePort::recvReqRetry()
119114194Sgabeblack@google.com{
119214194Sgabeblack@google.com    lsq->recvReqRetry();
119314194Sgabeblack@google.com}
119414194Sgabeblack@google.com
11959944Smatt.horsnell@ARM.com#endif//__CPU_O3_LSQ_IMPL_HH__
1196