lsq_impl.hh revision 14297
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