lsq_impl.hh revision 13688
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" 522292SN/A#include "cpu/o3/lsq.hh" 539444SAndreas.Sandberg@ARM.com#include "debug/Drain.hh" 548232Snate@binkert.org#include "debug/Fetch.hh" 558232Snate@binkert.org#include "debug/LSQ.hh" 568232Snate@binkert.org#include "debug/Writeback.hh" 576221Snate@binkert.org#include "params/DerivO3CPU.hh" 582292SN/A 596221Snate@binkert.orgusing namespace std; 605529Snate@binkert.org 612292SN/Atemplate <class Impl> 625529Snate@binkert.orgLSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) 638707Sandreas.hansson@arm.com : cpu(cpu_ptr), iewStage(iew_ptr), 6413590Srekai.gonzalezalberquilla@arm.com _cacheBlocked(false), 6513590Srekai.gonzalezalberquilla@arm.com cacheStorePorts(params->cacheStorePorts), usedStorePorts(0), 6613560Snikos.nikoleris@arm.com lsqPolicy(params->smtLSQPolicy), 674329Sktlim@umich.edu LQEntries(params->LQEntries), 684329Sktlim@umich.edu SQEntries(params->SQEntries), 6913472Srekai.gonzalezalberquilla@arm.com maxLQEntries(maxLSQAllocation(lsqPolicy, LQEntries, params->numThreads, 7013472Srekai.gonzalezalberquilla@arm.com params->smtLSQThreshold)), 7113472Srekai.gonzalezalberquilla@arm.com maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params->numThreads, 7213472Srekai.gonzalezalberquilla@arm.com params->smtLSQThreshold)), 7310333Smitch.hayenga@arm.com numThreads(params->numThreads) 742292SN/A{ 759868Sjthestness@gmail.com assert(numThreads > 0 && numThreads <= Impl::MaxThreads); 769868Sjthestness@gmail.com 772292SN/A //**********************************************/ 782292SN/A //************ Handle SMT Parameters ***********/ 792292SN/A //**********************************************/ 802292SN/A 8113590Srekai.gonzalezalberquilla@arm.com /* Run SMT olicy checks. */ 8213590Srekai.gonzalezalberquilla@arm.com if (lsqPolicy == SMTQueuePolicy::Dynamic) { 832292SN/A DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 8413560Snikos.nikoleris@arm.com } else if (lsqPolicy == SMTQueuePolicy::Partitioned) { 852292SN/A DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 868346Sksewell@umich.edu "%i entries per LQ | %i entries per SQ\n", 872292SN/A maxLQEntries,maxSQEntries); 8813560Snikos.nikoleris@arm.com } else if (lsqPolicy == SMTQueuePolicy::Threshold) { 892292SN/A 9013590Srekai.gonzalezalberquilla@arm.com assert(params->smtLSQThreshold > params->LQEntries); 9113590Srekai.gonzalezalberquilla@arm.com assert(params->smtLSQThreshold > params->SQEntries); 922292SN/A 932292SN/A DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 948346Sksewell@umich.edu "%i entries per LQ | %i entries per SQ\n", 952292SN/A maxLQEntries,maxSQEntries); 962292SN/A } else { 9713449Sgabeblack@google.com panic("Invalid LSQ sharing policy. Options are: Dynamic, " 9813449Sgabeblack@google.com "Partitioned, Threshold"); 992292SN/A } 1002292SN/A 10113472Srekai.gonzalezalberquilla@arm.com thread.reserve(numThreads); 1026221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 10313472Srekai.gonzalezalberquilla@arm.com thread.emplace_back(maxLQEntries, maxSQEntries); 10413472Srekai.gonzalezalberquilla@arm.com thread[tid].init(cpu, iew_ptr, params, this, tid); 1058850Sandreas.hansson@arm.com thread[tid].setDcachePort(&cpu_ptr->getDataPort()); 1062292SN/A } 1072292SN/A} 1082292SN/A 1092292SN/A 1102292SN/Atemplate<class Impl> 1112292SN/Astd::string 1122292SN/ALSQ<Impl>::name() const 1132292SN/A{ 1142292SN/A return iewStage->name() + ".lsq"; 1152292SN/A} 1162292SN/A 1172292SN/Atemplate<class Impl> 1182292SN/Avoid 1192727Sktlim@umich.eduLSQ<Impl>::regStats() 1202727Sktlim@umich.edu{ 1212727Sktlim@umich.edu //Initialize LSQs 1226221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1232727Sktlim@umich.edu thread[tid].regStats(); 1242727Sktlim@umich.edu } 1252727Sktlim@umich.edu} 1262727Sktlim@umich.edu 1272727Sktlim@umich.edutemplate<class Impl> 1282727Sktlim@umich.eduvoid 1296221Snate@binkert.orgLSQ<Impl>::setActiveThreads(list<ThreadID> *at_ptr) 1302292SN/A{ 1312292SN/A activeThreads = at_ptr; 1322292SN/A assert(activeThreads != 0); 1332292SN/A} 1342292SN/A 1352292SN/Atemplate <class Impl> 1362307SN/Avoid 1379444SAndreas.Sandberg@ARM.comLSQ<Impl>::drainSanityCheck() const 1382307SN/A{ 1399444SAndreas.Sandberg@ARM.com assert(isDrained()); 1409444SAndreas.Sandberg@ARM.com 1419444SAndreas.Sandberg@ARM.com for (ThreadID tid = 0; tid < numThreads; tid++) 1429444SAndreas.Sandberg@ARM.com thread[tid].drainSanityCheck(); 1439444SAndreas.Sandberg@ARM.com} 1449444SAndreas.Sandberg@ARM.com 1459444SAndreas.Sandberg@ARM.comtemplate <class Impl> 1469444SAndreas.Sandberg@ARM.combool 1479444SAndreas.Sandberg@ARM.comLSQ<Impl>::isDrained() const 1489444SAndreas.Sandberg@ARM.com{ 1499444SAndreas.Sandberg@ARM.com bool drained(true); 1509444SAndreas.Sandberg@ARM.com 1519444SAndreas.Sandberg@ARM.com if (!lqEmpty()) { 1529444SAndreas.Sandberg@ARM.com DPRINTF(Drain, "Not drained, LQ not empty.\n"); 1539444SAndreas.Sandberg@ARM.com drained = false; 1542307SN/A } 1559444SAndreas.Sandberg@ARM.com 1569444SAndreas.Sandberg@ARM.com if (!sqEmpty()) { 1579444SAndreas.Sandberg@ARM.com DPRINTF(Drain, "Not drained, SQ not empty.\n"); 1589444SAndreas.Sandberg@ARM.com drained = false; 1599444SAndreas.Sandberg@ARM.com } 1609444SAndreas.Sandberg@ARM.com 1619444SAndreas.Sandberg@ARM.com return drained; 1622307SN/A} 1632307SN/A 1642307SN/Atemplate <class Impl> 1652307SN/Avoid 1662307SN/ALSQ<Impl>::takeOverFrom() 1672307SN/A{ 16813590Srekai.gonzalezalberquilla@arm.com usedStorePorts = 0; 16913590Srekai.gonzalezalberquilla@arm.com _cacheBlocked = false; 17013590Srekai.gonzalezalberquilla@arm.com 1716221Snate@binkert.org for (ThreadID tid = 0; tid < numThreads; tid++) { 1722307SN/A thread[tid].takeOverFrom(); 1732307SN/A } 1742307SN/A} 1752307SN/A 17613590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 17713590Srekai.gonzalezalberquilla@arm.combool 17813590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::cacheBlocked() const 1792292SN/A{ 18013590Srekai.gonzalezalberquilla@arm.com return _cacheBlocked; 1812292SN/A} 1822292SN/A 1832292SN/Atemplate<class Impl> 1842292SN/Avoid 18513590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::cacheBlocked(bool v) 1862292SN/A{ 18713590Srekai.gonzalezalberquilla@arm.com _cacheBlocked = v; 18813590Srekai.gonzalezalberquilla@arm.com} 18913590Srekai.gonzalezalberquilla@arm.com 19013590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 19113590Srekai.gonzalezalberquilla@arm.combool 19213590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::storePortAvailable() const 19313590Srekai.gonzalezalberquilla@arm.com{ 19413590Srekai.gonzalezalberquilla@arm.com return usedStorePorts < cacheStorePorts; 1952292SN/A} 1962292SN/A 1972292SN/Atemplate<class Impl> 1982292SN/Avoid 19913590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::storePortBusy() 2002292SN/A{ 20113590Srekai.gonzalezalberquilla@arm.com usedStorePorts++; 20213590Srekai.gonzalezalberquilla@arm.com assert(usedStorePorts <= cacheStorePorts); 2032292SN/A} 2042292SN/A 2052292SN/Atemplate<class Impl> 2062292SN/Avoid 20713429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::insertLoad(const DynInstPtr &load_inst) 2082292SN/A{ 2096221Snate@binkert.org ThreadID tid = load_inst->threadNumber; 2102292SN/A 2112292SN/A thread[tid].insertLoad(load_inst); 2122292SN/A} 2132292SN/A 2142292SN/Atemplate<class Impl> 2152292SN/Avoid 21613429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::insertStore(const DynInstPtr &store_inst) 2172292SN/A{ 2186221Snate@binkert.org ThreadID tid = store_inst->threadNumber; 2192292SN/A 2202292SN/A thread[tid].insertStore(store_inst); 2212292SN/A} 2222292SN/A 2232292SN/Atemplate<class Impl> 2242292SN/AFault 22513429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::executeLoad(const DynInstPtr &inst) 2262292SN/A{ 2276221Snate@binkert.org ThreadID tid = inst->threadNumber; 2282292SN/A 2292292SN/A return thread[tid].executeLoad(inst); 2302292SN/A} 2312292SN/A 2322292SN/Atemplate<class Impl> 2332292SN/AFault 23413429Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::executeStore(const DynInstPtr &inst) 2352292SN/A{ 2366221Snate@binkert.org ThreadID tid = inst->threadNumber; 2372292SN/A 2382292SN/A return thread[tid].executeStore(inst); 2392292SN/A} 2402292SN/A 2412292SN/Atemplate<class Impl> 2422292SN/Avoid 2432292SN/ALSQ<Impl>::writebackStores() 2442292SN/A{ 2456221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 2466221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 2472292SN/A 2483867Sbinkertn@umich.edu while (threads != end) { 2496221Snate@binkert.org ThreadID tid = *threads++; 2502292SN/A 2512292SN/A if (numStoresToWB(tid) > 0) { 2522329SN/A DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores " 2532329SN/A "available for Writeback.\n", tid, numStoresToWB(tid)); 2542292SN/A } 2552292SN/A 2562292SN/A thread[tid].writebackStores(); 2572292SN/A } 2582292SN/A} 2592292SN/A 2602292SN/Atemplate<class Impl> 2612292SN/Abool 2622292SN/ALSQ<Impl>::violation() 2632292SN/A{ 2642292SN/A /* Answers: Does Anybody Have a Violation?*/ 2656221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 2666221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 2672292SN/A 2683867Sbinkertn@umich.edu while (threads != end) { 2696221Snate@binkert.org ThreadID tid = *threads++; 2703867Sbinkertn@umich.edu 2712292SN/A if (thread[tid].violation()) 2722292SN/A return true; 2732292SN/A } 2742292SN/A 2752292SN/A return false; 2762292SN/A} 2772292SN/A 2788707Sandreas.hansson@arm.comtemplate <class Impl> 2798707Sandreas.hansson@arm.comvoid 28010713Sandreas.hansson@arm.comLSQ<Impl>::recvReqRetry() 2818707Sandreas.hansson@arm.com{ 28210333Smitch.hayenga@arm.com iewStage->cacheUnblocked(); 28313590Srekai.gonzalezalberquilla@arm.com cacheBlocked(false); 28410333Smitch.hayenga@arm.com 28510333Smitch.hayenga@arm.com for (ThreadID tid : *activeThreads) { 28610333Smitch.hayenga@arm.com thread[tid].recvRetry(); 2878707Sandreas.hansson@arm.com } 2888707Sandreas.hansson@arm.com} 2898707Sandreas.hansson@arm.com 2908707Sandreas.hansson@arm.comtemplate <class Impl> 29113590Srekai.gonzalezalberquilla@arm.comvoid 29213590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::completeDataAccess(PacketPtr pkt) 29313590Srekai.gonzalezalberquilla@arm.com{ 29413590Srekai.gonzalezalberquilla@arm.com auto senderState = dynamic_cast<LSQSenderState*>(pkt->senderState); 29513590Srekai.gonzalezalberquilla@arm.com thread[cpu->contextToThread(senderState->contextId())] 29613590Srekai.gonzalezalberquilla@arm.com .completeDataAccess(pkt); 29713590Srekai.gonzalezalberquilla@arm.com} 29813590Srekai.gonzalezalberquilla@arm.com 29913590Srekai.gonzalezalberquilla@arm.comtemplate <class Impl> 3008707Sandreas.hansson@arm.combool 3018975Sandreas.hansson@arm.comLSQ<Impl>::recvTimingResp(PacketPtr pkt) 3028707Sandreas.hansson@arm.com{ 3038707Sandreas.hansson@arm.com if (pkt->isError()) 3048707Sandreas.hansson@arm.com DPRINTF(LSQ, "Got error packet back for address: %#X\n", 3058707Sandreas.hansson@arm.com pkt->getAddr()); 30610575SMarco.Elver@ARM.com 30713590Srekai.gonzalezalberquilla@arm.com auto senderState = dynamic_cast<LSQSenderState*>(pkt->senderState); 30813590Srekai.gonzalezalberquilla@arm.com panic_if(!senderState, "Got packet back with unknown sender state\n"); 30913590Srekai.gonzalezalberquilla@arm.com 31013590Srekai.gonzalezalberquilla@arm.com thread[cpu->contextToThread(senderState->contextId())].recvTimingResp(pkt); 31110575SMarco.Elver@ARM.com 31210575SMarco.Elver@ARM.com if (pkt->isInvalidate()) { 31310575SMarco.Elver@ARM.com // This response also contains an invalidate; e.g. this can be the case 31410575SMarco.Elver@ARM.com // if cmd is ReadRespWithInvalidate. 31510575SMarco.Elver@ARM.com // 31610575SMarco.Elver@ARM.com // The calling order between completeDataAccess and checkSnoop matters. 31710575SMarco.Elver@ARM.com // By calling checkSnoop after completeDataAccess, we ensure that the 31810575SMarco.Elver@ARM.com // fault set by checkSnoop is not lost. Calling writeback (more 31910575SMarco.Elver@ARM.com // specifically inst->completeAcc) in completeDataAccess overwrites 32010575SMarco.Elver@ARM.com // fault, and in case this instruction requires squashing (as 32110575SMarco.Elver@ARM.com // determined by checkSnoop), the ReExec fault set by checkSnoop would 32210575SMarco.Elver@ARM.com // be lost otherwise. 32310575SMarco.Elver@ARM.com 32410575SMarco.Elver@ARM.com DPRINTF(LSQ, "received invalidation with response for addr:%#x\n", 32510575SMarco.Elver@ARM.com pkt->getAddr()); 32610575SMarco.Elver@ARM.com 32710575SMarco.Elver@ARM.com for (ThreadID tid = 0; tid < numThreads; tid++) { 32810575SMarco.Elver@ARM.com thread[tid].checkSnoop(pkt); 32910575SMarco.Elver@ARM.com } 33010575SMarco.Elver@ARM.com } 33113590Srekai.gonzalezalberquilla@arm.com // Update the LSQRequest state (this may delete the request) 33213590Srekai.gonzalezalberquilla@arm.com senderState->request()->packetReplied(); 33310575SMarco.Elver@ARM.com 3348948Sandreas.hansson@arm.com return true; 3358948Sandreas.hansson@arm.com} 3368707Sandreas.hansson@arm.com 3378948Sandreas.hansson@arm.comtemplate <class Impl> 3388975Sandreas.hansson@arm.comvoid 3398975Sandreas.hansson@arm.comLSQ<Impl>::recvTimingSnoopReq(PacketPtr pkt) 3408948Sandreas.hansson@arm.com{ 3418948Sandreas.hansson@arm.com DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(), 3428948Sandreas.hansson@arm.com pkt->cmdString()); 3438948Sandreas.hansson@arm.com 3448948Sandreas.hansson@arm.com // must be a snoop 3458948Sandreas.hansson@arm.com if (pkt->isInvalidate()) { 3468948Sandreas.hansson@arm.com DPRINTF(LSQ, "received invalidation for addr:%#x\n", 3478948Sandreas.hansson@arm.com pkt->getAddr()); 3488948Sandreas.hansson@arm.com for (ThreadID tid = 0; tid < numThreads; tid++) { 3498948Sandreas.hansson@arm.com thread[tid].checkSnoop(pkt); 3508707Sandreas.hansson@arm.com } 3518707Sandreas.hansson@arm.com } 3528707Sandreas.hansson@arm.com} 3538707Sandreas.hansson@arm.com 3542292SN/Atemplate<class Impl> 3552292SN/Aint 3562292SN/ALSQ<Impl>::getCount() 3572292SN/A{ 3582292SN/A unsigned total = 0; 3592292SN/A 3606221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 3616221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 3622292SN/A 3633867Sbinkertn@umich.edu while (threads != end) { 3646221Snate@binkert.org ThreadID tid = *threads++; 3653867Sbinkertn@umich.edu 3662292SN/A total += getCount(tid); 3672292SN/A } 3682292SN/A 3692292SN/A return total; 3702292SN/A} 3712292SN/A 3722292SN/Atemplate<class Impl> 3732292SN/Aint 3742292SN/ALSQ<Impl>::numLoads() 3752292SN/A{ 3762292SN/A unsigned total = 0; 3772292SN/A 3786221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 3796221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 3802292SN/A 3813867Sbinkertn@umich.edu while (threads != end) { 3826221Snate@binkert.org ThreadID tid = *threads++; 3833867Sbinkertn@umich.edu 3842292SN/A total += numLoads(tid); 3852292SN/A } 3862292SN/A 3872292SN/A return total; 3882292SN/A} 3892292SN/A 3902292SN/Atemplate<class Impl> 3912292SN/Aint 3922292SN/ALSQ<Impl>::numStores() 3932292SN/A{ 3942292SN/A unsigned total = 0; 3952292SN/A 3966221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 3976221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 3982292SN/A 3993867Sbinkertn@umich.edu while (threads != end) { 4006221Snate@binkert.org ThreadID tid = *threads++; 4013867Sbinkertn@umich.edu 4022292SN/A total += thread[tid].numStores(); 4032292SN/A } 4042292SN/A 4052292SN/A return total; 4062292SN/A} 4072292SN/A 4082292SN/Atemplate<class Impl> 4092292SN/Aunsigned 41010239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeLoadEntries() 4112292SN/A{ 4122292SN/A unsigned total = 0; 4132292SN/A 4146221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 4156221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 4162292SN/A 4173867Sbinkertn@umich.edu while (threads != end) { 4186221Snate@binkert.org ThreadID tid = *threads++; 4193867Sbinkertn@umich.edu 42010239Sbinhpham@cs.rutgers.edu total += thread[tid].numFreeLoadEntries(); 4212292SN/A } 4222292SN/A 4232292SN/A return total; 4242292SN/A} 4252292SN/A 4262292SN/Atemplate<class Impl> 4272292SN/Aunsigned 42810239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeStoreEntries() 4292292SN/A{ 43010239Sbinhpham@cs.rutgers.edu unsigned total = 0; 43110239Sbinhpham@cs.rutgers.edu 43210239Sbinhpham@cs.rutgers.edu list<ThreadID>::iterator threads = activeThreads->begin(); 43310239Sbinhpham@cs.rutgers.edu list<ThreadID>::iterator end = activeThreads->end(); 43410239Sbinhpham@cs.rutgers.edu 43510239Sbinhpham@cs.rutgers.edu while (threads != end) { 43610239Sbinhpham@cs.rutgers.edu ThreadID tid = *threads++; 43710239Sbinhpham@cs.rutgers.edu 43810239Sbinhpham@cs.rutgers.edu total += thread[tid].numFreeStoreEntries(); 43910239Sbinhpham@cs.rutgers.edu } 44010239Sbinhpham@cs.rutgers.edu 44110239Sbinhpham@cs.rutgers.edu return total; 44210239Sbinhpham@cs.rutgers.edu} 44310239Sbinhpham@cs.rutgers.edu 44410239Sbinhpham@cs.rutgers.edutemplate<class Impl> 44510239Sbinhpham@cs.rutgers.eduunsigned 44610239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeLoadEntries(ThreadID tid) 44710239Sbinhpham@cs.rutgers.edu{ 44810239Sbinhpham@cs.rutgers.edu return thread[tid].numFreeLoadEntries(); 44910239Sbinhpham@cs.rutgers.edu} 45010239Sbinhpham@cs.rutgers.edu 45110239Sbinhpham@cs.rutgers.edutemplate<class Impl> 45210239Sbinhpham@cs.rutgers.eduunsigned 45310239Sbinhpham@cs.rutgers.eduLSQ<Impl>::numFreeStoreEntries(ThreadID tid) 45410239Sbinhpham@cs.rutgers.edu{ 45510239Sbinhpham@cs.rutgers.edu return thread[tid].numFreeStoreEntries(); 4562292SN/A} 4572292SN/A 4582292SN/Atemplate<class Impl> 4592292SN/Abool 4602292SN/ALSQ<Impl>::isFull() 4612292SN/A{ 4626221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 4636221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 4642292SN/A 4653867Sbinkertn@umich.edu while (threads != end) { 4666221Snate@binkert.org ThreadID tid = *threads++; 4673867Sbinkertn@umich.edu 4683867Sbinkertn@umich.edu if (!(thread[tid].lqFull() || thread[tid].sqFull())) 4692292SN/A return false; 4702292SN/A } 4712292SN/A 4722292SN/A return true; 4732292SN/A} 4742292SN/A 4752292SN/Atemplate<class Impl> 4762292SN/Abool 4776221Snate@binkert.orgLSQ<Impl>::isFull(ThreadID tid) 4782292SN/A{ 4792292SN/A //@todo: Change to Calculate All Entries for 4802292SN/A //Dynamic Policy 48113560Snikos.nikoleris@arm.com if (lsqPolicy == SMTQueuePolicy::Dynamic) 4822292SN/A return isFull(); 4832292SN/A else 4842292SN/A return thread[tid].lqFull() || thread[tid].sqFull(); 4852292SN/A} 4862292SN/A 4872292SN/Atemplate<class Impl> 4882292SN/Abool 4899444SAndreas.Sandberg@ARM.comLSQ<Impl>::isEmpty() const 4909444SAndreas.Sandberg@ARM.com{ 4919444SAndreas.Sandberg@ARM.com return lqEmpty() && sqEmpty(); 4929444SAndreas.Sandberg@ARM.com} 4939444SAndreas.Sandberg@ARM.com 4949444SAndreas.Sandberg@ARM.comtemplate<class Impl> 4959444SAndreas.Sandberg@ARM.combool 4969444SAndreas.Sandberg@ARM.comLSQ<Impl>::lqEmpty() const 4979444SAndreas.Sandberg@ARM.com{ 4989444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 4999444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 5009444SAndreas.Sandberg@ARM.com 5019444SAndreas.Sandberg@ARM.com while (threads != end) { 5029444SAndreas.Sandberg@ARM.com ThreadID tid = *threads++; 5039444SAndreas.Sandberg@ARM.com 5049444SAndreas.Sandberg@ARM.com if (!thread[tid].lqEmpty()) 5059444SAndreas.Sandberg@ARM.com return false; 5069444SAndreas.Sandberg@ARM.com } 5079444SAndreas.Sandberg@ARM.com 5089444SAndreas.Sandberg@ARM.com return true; 5099444SAndreas.Sandberg@ARM.com} 5109444SAndreas.Sandberg@ARM.com 5119444SAndreas.Sandberg@ARM.comtemplate<class Impl> 5129444SAndreas.Sandberg@ARM.combool 5139444SAndreas.Sandberg@ARM.comLSQ<Impl>::sqEmpty() const 5149444SAndreas.Sandberg@ARM.com{ 5159444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 5169444SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 5179444SAndreas.Sandberg@ARM.com 5189444SAndreas.Sandberg@ARM.com while (threads != end) { 5199444SAndreas.Sandberg@ARM.com ThreadID tid = *threads++; 5209444SAndreas.Sandberg@ARM.com 5219444SAndreas.Sandberg@ARM.com if (!thread[tid].sqEmpty()) 5229444SAndreas.Sandberg@ARM.com return false; 5239444SAndreas.Sandberg@ARM.com } 5249444SAndreas.Sandberg@ARM.com 5259444SAndreas.Sandberg@ARM.com return true; 5269444SAndreas.Sandberg@ARM.com} 5279444SAndreas.Sandberg@ARM.com 5289444SAndreas.Sandberg@ARM.comtemplate<class Impl> 5299444SAndreas.Sandberg@ARM.combool 5302292SN/ALSQ<Impl>::lqFull() 5312292SN/A{ 5326221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 5336221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 5342292SN/A 5353867Sbinkertn@umich.edu while (threads != end) { 5366221Snate@binkert.org ThreadID tid = *threads++; 5373867Sbinkertn@umich.edu 5382292SN/A if (!thread[tid].lqFull()) 5392292SN/A return false; 5402292SN/A } 5412292SN/A 5422292SN/A return true; 5432292SN/A} 5442292SN/A 5452292SN/Atemplate<class Impl> 5462292SN/Abool 5476221Snate@binkert.orgLSQ<Impl>::lqFull(ThreadID tid) 5482292SN/A{ 5492292SN/A //@todo: Change to Calculate All Entries for 5502292SN/A //Dynamic Policy 55113560Snikos.nikoleris@arm.com if (lsqPolicy == SMTQueuePolicy::Dynamic) 5522292SN/A return lqFull(); 5532292SN/A else 5542292SN/A return thread[tid].lqFull(); 5552292SN/A} 5562292SN/A 5572292SN/Atemplate<class Impl> 5582292SN/Abool 5592292SN/ALSQ<Impl>::sqFull() 5602292SN/A{ 5616221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 5626221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 5632292SN/A 5643867Sbinkertn@umich.edu while (threads != end) { 5656221Snate@binkert.org ThreadID tid = *threads++; 5663867Sbinkertn@umich.edu 5672292SN/A if (!sqFull(tid)) 5682292SN/A return false; 5692292SN/A } 5702292SN/A 5712292SN/A return true; 5722292SN/A} 5732292SN/A 5742292SN/Atemplate<class Impl> 5752292SN/Abool 5766221Snate@binkert.orgLSQ<Impl>::sqFull(ThreadID tid) 5772292SN/A{ 5782292SN/A //@todo: Change to Calculate All Entries for 5792292SN/A //Dynamic Policy 58013560Snikos.nikoleris@arm.com if (lsqPolicy == SMTQueuePolicy::Dynamic) 5812292SN/A return sqFull(); 5822292SN/A else 5832292SN/A return thread[tid].sqFull(); 5842292SN/A} 5852292SN/A 5862292SN/Atemplate<class Impl> 5872292SN/Abool 5882292SN/ALSQ<Impl>::isStalled() 5892292SN/A{ 5906221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 5916221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 5922292SN/A 5933867Sbinkertn@umich.edu while (threads != end) { 5946221Snate@binkert.org ThreadID tid = *threads++; 5953867Sbinkertn@umich.edu 5962292SN/A if (!thread[tid].isStalled()) 5972292SN/A return false; 5982292SN/A } 5992292SN/A 6002292SN/A return true; 6012292SN/A} 6022292SN/A 6032292SN/Atemplate<class Impl> 6042292SN/Abool 6056221Snate@binkert.orgLSQ<Impl>::isStalled(ThreadID tid) 6062292SN/A{ 60713560Snikos.nikoleris@arm.com if (lsqPolicy == SMTQueuePolicy::Dynamic) 6082292SN/A return isStalled(); 6092292SN/A else 6102292SN/A return thread[tid].isStalled(); 6112292SN/A} 6122292SN/A 6132292SN/Atemplate<class Impl> 6142292SN/Abool 6152292SN/ALSQ<Impl>::hasStoresToWB() 6162292SN/A{ 6176221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 6186221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 6192292SN/A 6203867Sbinkertn@umich.edu while (threads != end) { 6216221Snate@binkert.org ThreadID tid = *threads++; 6223867Sbinkertn@umich.edu 6235557Sktlim@umich.edu if (hasStoresToWB(tid)) 6245557Sktlim@umich.edu return true; 6252292SN/A } 6262292SN/A 6275557Sktlim@umich.edu return false; 6282292SN/A} 6292292SN/A 6302292SN/Atemplate<class Impl> 6312292SN/Abool 6322292SN/ALSQ<Impl>::willWB() 6332292SN/A{ 6346221Snate@binkert.org list<ThreadID>::iterator threads = activeThreads->begin(); 6356221Snate@binkert.org list<ThreadID>::iterator end = activeThreads->end(); 6362292SN/A 6373867Sbinkertn@umich.edu while (threads != end) { 6386221Snate@binkert.org ThreadID tid = *threads++; 6393867Sbinkertn@umich.edu 6405557Sktlim@umich.edu if (willWB(tid)) 6415557Sktlim@umich.edu return true; 6422292SN/A } 6432292SN/A 6445557Sktlim@umich.edu return false; 6452292SN/A} 6462292SN/A 6472292SN/Atemplate<class Impl> 6482292SN/Avoid 6499440SAndreas.Sandberg@ARM.comLSQ<Impl>::dumpInsts() const 6502292SN/A{ 6519440SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator threads = activeThreads->begin(); 6529440SAndreas.Sandberg@ARM.com list<ThreadID>::const_iterator end = activeThreads->end(); 6532292SN/A 6543867Sbinkertn@umich.edu while (threads != end) { 6556221Snate@binkert.org ThreadID tid = *threads++; 6563867Sbinkertn@umich.edu 6572292SN/A thread[tid].dumpInsts(); 6582292SN/A } 6592292SN/A} 6609944Smatt.horsnell@ARM.com 66113590Srekai.gonzalezalberquilla@arm.comstatic Addr 66213590Srekai.gonzalezalberquilla@arm.comaddrBlockOffset(Addr addr, unsigned int block_size) 66313590Srekai.gonzalezalberquilla@arm.com{ 66413590Srekai.gonzalezalberquilla@arm.com return addr & (block_size - 1); 66513590Srekai.gonzalezalberquilla@arm.com} 66613590Srekai.gonzalezalberquilla@arm.com 66713590Srekai.gonzalezalberquilla@arm.comstatic Addr 66813590Srekai.gonzalezalberquilla@arm.comaddrBlockAlign(Addr addr, uint64_t block_size) 66913590Srekai.gonzalezalberquilla@arm.com{ 67013590Srekai.gonzalezalberquilla@arm.com return addr & ~(block_size - 1); 67113590Srekai.gonzalezalberquilla@arm.com} 67213590Srekai.gonzalezalberquilla@arm.com 67313590Srekai.gonzalezalberquilla@arm.comstatic bool 67413590Srekai.gonzalezalberquilla@arm.comtransferNeedsBurst(Addr addr, uint64_t size, uint64_t block_size) 67513590Srekai.gonzalezalberquilla@arm.com{ 67613590Srekai.gonzalezalberquilla@arm.com return (addrBlockOffset(addr, block_size) + size) > block_size; 67713590Srekai.gonzalezalberquilla@arm.com} 67813590Srekai.gonzalezalberquilla@arm.com 67913590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 68013590Srekai.gonzalezalberquilla@arm.comFault 68113590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::pushRequest(const DynInstPtr& inst, bool isLoad, uint8_t *data, 68213590Srekai.gonzalezalberquilla@arm.com unsigned int size, Addr addr, Request::Flags flags, 68313652Sqtt2@cornell.edu uint64_t *res, AtomicOpFunctor *amo_op) 68413590Srekai.gonzalezalberquilla@arm.com{ 68513652Sqtt2@cornell.edu // This comming request can be either load, store or atomic. 68613652Sqtt2@cornell.edu // Atomic request has a corresponding pointer to its atomic memory 68713652Sqtt2@cornell.edu // operation 68813688Sgiacomo.travaglini@arm.com bool isAtomic M5_VAR_USED = !isLoad && amo_op; 68913652Sqtt2@cornell.edu 69013590Srekai.gonzalezalberquilla@arm.com ThreadID tid = cpu->contextToThread(inst->contextId()); 69113590Srekai.gonzalezalberquilla@arm.com auto cacheLineSize = cpu->cacheLineSize(); 69213590Srekai.gonzalezalberquilla@arm.com bool needs_burst = transferNeedsBurst(addr, size, cacheLineSize); 69313590Srekai.gonzalezalberquilla@arm.com LSQRequest* req = nullptr; 69413590Srekai.gonzalezalberquilla@arm.com 69513652Sqtt2@cornell.edu // Atomic requests that access data across cache line boundary are 69613652Sqtt2@cornell.edu // currently not allowed since the cache does not guarantee corresponding 69713652Sqtt2@cornell.edu // atomic memory operations to be executed atomically across a cache line. 69813652Sqtt2@cornell.edu // For ISAs such as x86 that supports cross-cache-line atomic instructions, 69913652Sqtt2@cornell.edu // the cache needs to be modified to perform atomic update to both cache 70013652Sqtt2@cornell.edu // lines. For now, such cross-line update is not supported. 70113652Sqtt2@cornell.edu assert(!isAtomic || (isAtomic && !needs_burst)); 70213652Sqtt2@cornell.edu 70313590Srekai.gonzalezalberquilla@arm.com if (inst->translationStarted()) { 70413590Srekai.gonzalezalberquilla@arm.com req = inst->savedReq; 70513590Srekai.gonzalezalberquilla@arm.com assert(req); 70613590Srekai.gonzalezalberquilla@arm.com } else { 70713590Srekai.gonzalezalberquilla@arm.com if (needs_burst) { 70813590Srekai.gonzalezalberquilla@arm.com req = new SplitDataRequest(&thread[tid], inst, isLoad, addr, 70913590Srekai.gonzalezalberquilla@arm.com size, flags, data, res); 71013590Srekai.gonzalezalberquilla@arm.com } else { 71113590Srekai.gonzalezalberquilla@arm.com req = new SingleDataRequest(&thread[tid], inst, isLoad, addr, 71213652Sqtt2@cornell.edu size, flags, data, res, amo_op); 71313590Srekai.gonzalezalberquilla@arm.com } 71413590Srekai.gonzalezalberquilla@arm.com assert(req); 71513590Srekai.gonzalezalberquilla@arm.com inst->setRequest(); 71613590Srekai.gonzalezalberquilla@arm.com req->taskId(cpu->taskId()); 71713590Srekai.gonzalezalberquilla@arm.com 71813590Srekai.gonzalezalberquilla@arm.com req->initiateTranslation(); 71913590Srekai.gonzalezalberquilla@arm.com } 72013590Srekai.gonzalezalberquilla@arm.com 72113590Srekai.gonzalezalberquilla@arm.com /* This is the place were instructions get the effAddr. */ 72213590Srekai.gonzalezalberquilla@arm.com if (req->isTranslationComplete()) { 72313590Srekai.gonzalezalberquilla@arm.com if (inst->getFault() == NoFault) { 72413590Srekai.gonzalezalberquilla@arm.com inst->effAddr = req->getVaddr(); 72513590Srekai.gonzalezalberquilla@arm.com inst->effSize = size; 72613590Srekai.gonzalezalberquilla@arm.com inst->effAddrValid(true); 72713590Srekai.gonzalezalberquilla@arm.com 72813590Srekai.gonzalezalberquilla@arm.com if (cpu->checker) { 72913590Srekai.gonzalezalberquilla@arm.com inst->reqToVerify = std::make_shared<Request>(*req->request()); 73013590Srekai.gonzalezalberquilla@arm.com } 73113590Srekai.gonzalezalberquilla@arm.com if (isLoad) 73213590Srekai.gonzalezalberquilla@arm.com inst->getFault() = cpu->read(req, inst->lqIdx); 73313590Srekai.gonzalezalberquilla@arm.com else 73413590Srekai.gonzalezalberquilla@arm.com inst->getFault() = cpu->write(req, data, inst->sqIdx); 73513590Srekai.gonzalezalberquilla@arm.com } else if (isLoad) { 73613590Srekai.gonzalezalberquilla@arm.com // Commit will have to clean up whatever happened. Set this 73713590Srekai.gonzalezalberquilla@arm.com // instruction as executed. 73813590Srekai.gonzalezalberquilla@arm.com inst->setExecuted(); 73913590Srekai.gonzalezalberquilla@arm.com } 74013590Srekai.gonzalezalberquilla@arm.com } 74113590Srekai.gonzalezalberquilla@arm.com 74213590Srekai.gonzalezalberquilla@arm.com if (inst->traceData) 74313590Srekai.gonzalezalberquilla@arm.com inst->traceData->setMem(addr, size, flags); 74413590Srekai.gonzalezalberquilla@arm.com 74513590Srekai.gonzalezalberquilla@arm.com return inst->getFault(); 74613590Srekai.gonzalezalberquilla@arm.com} 74713590Srekai.gonzalezalberquilla@arm.com 74813590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 74913590Srekai.gonzalezalberquilla@arm.comvoid 75013590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::finish(const Fault &fault, const RequestPtr &req, 75113590Srekai.gonzalezalberquilla@arm.com ThreadContext* tc, BaseTLB::Mode mode) 75213590Srekai.gonzalezalberquilla@arm.com{ 75313590Srekai.gonzalezalberquilla@arm.com _fault.push_back(fault); 75413590Srekai.gonzalezalberquilla@arm.com numInTranslationFragments = 0; 75513590Srekai.gonzalezalberquilla@arm.com numTranslatedFragments = 1; 75613590Srekai.gonzalezalberquilla@arm.com /* If the instruction has been squahsed, let the request know 75713590Srekai.gonzalezalberquilla@arm.com * as it may have to self-destruct. */ 75813590Srekai.gonzalezalberquilla@arm.com if (_inst->isSquashed()) { 75913590Srekai.gonzalezalberquilla@arm.com this->squashTranslation(); 76013590Srekai.gonzalezalberquilla@arm.com } else { 76113590Srekai.gonzalezalberquilla@arm.com _inst->strictlyOrdered(req->isStrictlyOrdered()); 76213590Srekai.gonzalezalberquilla@arm.com 76313590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::TranslationFinished); 76413590Srekai.gonzalezalberquilla@arm.com if (fault == NoFault) { 76513590Srekai.gonzalezalberquilla@arm.com _inst->physEffAddr = req->getPaddr(); 76613590Srekai.gonzalezalberquilla@arm.com _inst->memReqFlags = req->getFlags(); 76713590Srekai.gonzalezalberquilla@arm.com if (req->isCondSwap()) { 76813590Srekai.gonzalezalberquilla@arm.com assert(_res); 76913590Srekai.gonzalezalberquilla@arm.com req->setExtraData(*_res); 77013590Srekai.gonzalezalberquilla@arm.com } 77113590Srekai.gonzalezalberquilla@arm.com setState(State::Request); 77213590Srekai.gonzalezalberquilla@arm.com } else { 77313590Srekai.gonzalezalberquilla@arm.com setState(State::Fault); 77413590Srekai.gonzalezalberquilla@arm.com } 77513590Srekai.gonzalezalberquilla@arm.com 77613590Srekai.gonzalezalberquilla@arm.com LSQRequest::_inst->fault = fault; 77713590Srekai.gonzalezalberquilla@arm.com LSQRequest::_inst->translationCompleted(true); 77813590Srekai.gonzalezalberquilla@arm.com } 77913590Srekai.gonzalezalberquilla@arm.com} 78013590Srekai.gonzalezalberquilla@arm.com 78113590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 78213590Srekai.gonzalezalberquilla@arm.comvoid 78313590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::finish(const Fault &fault, const RequestPtr &req, 78413590Srekai.gonzalezalberquilla@arm.com ThreadContext* tc, BaseTLB::Mode mode) 78513590Srekai.gonzalezalberquilla@arm.com{ 78613590Srekai.gonzalezalberquilla@arm.com _fault.push_back(fault); 78713590Srekai.gonzalezalberquilla@arm.com assert(req == _requests[numTranslatedFragments] || this->isDelayed()); 78813590Srekai.gonzalezalberquilla@arm.com 78913590Srekai.gonzalezalberquilla@arm.com numInTranslationFragments--; 79013590Srekai.gonzalezalberquilla@arm.com numTranslatedFragments++; 79113590Srekai.gonzalezalberquilla@arm.com 79213590Srekai.gonzalezalberquilla@arm.com mainReq->setFlags(req->getFlags()); 79313590Srekai.gonzalezalberquilla@arm.com 79413590Srekai.gonzalezalberquilla@arm.com if (numTranslatedFragments == _requests.size()) { 79513590Srekai.gonzalezalberquilla@arm.com if (_inst->isSquashed()) { 79613590Srekai.gonzalezalberquilla@arm.com this->squashTranslation(); 79713590Srekai.gonzalezalberquilla@arm.com } else { 79813590Srekai.gonzalezalberquilla@arm.com _inst->strictlyOrdered(mainReq->isStrictlyOrdered()); 79913590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::TranslationFinished); 80013590Srekai.gonzalezalberquilla@arm.com auto fault_it = _fault.begin(); 80113590Srekai.gonzalezalberquilla@arm.com /* Ffwd to the first NoFault. */ 80213590Srekai.gonzalezalberquilla@arm.com while (fault_it != _fault.end() && *fault_it == NoFault) 80313590Srekai.gonzalezalberquilla@arm.com fault_it++; 80413590Srekai.gonzalezalberquilla@arm.com /* If none of the fragments faulted: */ 80513590Srekai.gonzalezalberquilla@arm.com if (fault_it == _fault.end()) { 80613590Srekai.gonzalezalberquilla@arm.com _inst->physEffAddr = request(0)->getPaddr(); 80713590Srekai.gonzalezalberquilla@arm.com 80813590Srekai.gonzalezalberquilla@arm.com _inst->memReqFlags = mainReq->getFlags(); 80913590Srekai.gonzalezalberquilla@arm.com if (mainReq->isCondSwap()) { 81013590Srekai.gonzalezalberquilla@arm.com assert(_res); 81113590Srekai.gonzalezalberquilla@arm.com mainReq->setExtraData(*_res); 81213590Srekai.gonzalezalberquilla@arm.com } 81313590Srekai.gonzalezalberquilla@arm.com setState(State::Request); 81413590Srekai.gonzalezalberquilla@arm.com _inst->fault = NoFault; 81513590Srekai.gonzalezalberquilla@arm.com } else { 81613590Srekai.gonzalezalberquilla@arm.com setState(State::Fault); 81713590Srekai.gonzalezalberquilla@arm.com _inst->fault = *fault_it; 81813590Srekai.gonzalezalberquilla@arm.com } 81913590Srekai.gonzalezalberquilla@arm.com _inst->translationCompleted(true); 82013590Srekai.gonzalezalberquilla@arm.com } 82113590Srekai.gonzalezalberquilla@arm.com } 82213590Srekai.gonzalezalberquilla@arm.com} 82313590Srekai.gonzalezalberquilla@arm.com 82413590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 82513590Srekai.gonzalezalberquilla@arm.comvoid 82613590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::initiateTranslation() 82713590Srekai.gonzalezalberquilla@arm.com{ 82813590Srekai.gonzalezalberquilla@arm.com _inst->translationStarted(true); 82913590Srekai.gonzalezalberquilla@arm.com setState(State::Translation); 83013590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::TranslationStarted); 83113590Srekai.gonzalezalberquilla@arm.com 83213590Srekai.gonzalezalberquilla@arm.com _inst->savedReq = this; 83313590Srekai.gonzalezalberquilla@arm.com sendFragmentToTranslation(0); 83413590Srekai.gonzalezalberquilla@arm.com 83513590Srekai.gonzalezalberquilla@arm.com if (isTranslationComplete()) { 83613590Srekai.gonzalezalberquilla@arm.com } 83713590Srekai.gonzalezalberquilla@arm.com} 83813590Srekai.gonzalezalberquilla@arm.com 83913590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 84013590Srekai.gonzalezalberquilla@arm.comPacketPtr 84113590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::mainPacket() 84213590Srekai.gonzalezalberquilla@arm.com{ 84313590Srekai.gonzalezalberquilla@arm.com return _mainPacket; 84413590Srekai.gonzalezalberquilla@arm.com} 84513590Srekai.gonzalezalberquilla@arm.com 84613590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 84713590Srekai.gonzalezalberquilla@arm.comRequestPtr 84813590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::mainRequest() 84913590Srekai.gonzalezalberquilla@arm.com{ 85013590Srekai.gonzalezalberquilla@arm.com return mainReq; 85113590Srekai.gonzalezalberquilla@arm.com} 85213590Srekai.gonzalezalberquilla@arm.com 85313590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 85413590Srekai.gonzalezalberquilla@arm.comvoid 85513590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::initiateTranslation() 85613590Srekai.gonzalezalberquilla@arm.com{ 85713590Srekai.gonzalezalberquilla@arm.com _inst->translationStarted(true); 85813590Srekai.gonzalezalberquilla@arm.com setState(State::Translation); 85913590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::TranslationStarted); 86013590Srekai.gonzalezalberquilla@arm.com 86113590Srekai.gonzalezalberquilla@arm.com unsigned int cacheLineSize = _port.cacheLineSize(); 86213590Srekai.gonzalezalberquilla@arm.com Addr base_addr = _addr; 86313590Srekai.gonzalezalberquilla@arm.com Addr next_addr = addrBlockAlign(_addr + cacheLineSize, cacheLineSize); 86413590Srekai.gonzalezalberquilla@arm.com Addr final_addr = addrBlockAlign(_addr + _size, cacheLineSize); 86513590Srekai.gonzalezalberquilla@arm.com uint32_t size_so_far = 0; 86613590Srekai.gonzalezalberquilla@arm.com 86713590Srekai.gonzalezalberquilla@arm.com mainReq = std::make_shared<Request>(_inst->getASID(), base_addr, 86813590Srekai.gonzalezalberquilla@arm.com _size, _flags, _inst->masterId(), 86913590Srekai.gonzalezalberquilla@arm.com _inst->instAddr(), _inst->contextId()); 87013590Srekai.gonzalezalberquilla@arm.com 87113590Srekai.gonzalezalberquilla@arm.com // Paddr is not used in mainReq. However, we will accumulate the flags 87213590Srekai.gonzalezalberquilla@arm.com // from the sub requests into mainReq by calling setFlags() in finish(). 87313590Srekai.gonzalezalberquilla@arm.com // setFlags() assumes that paddr is set so flip the paddr valid bit here to 87413590Srekai.gonzalezalberquilla@arm.com // avoid a potential assert in setFlags() when we call it from finish(). 87513590Srekai.gonzalezalberquilla@arm.com mainReq->setPaddr(0); 87613590Srekai.gonzalezalberquilla@arm.com 87713590Srekai.gonzalezalberquilla@arm.com /* Get the pre-fix, possibly unaligned. */ 87813590Srekai.gonzalezalberquilla@arm.com _requests.push_back(std::make_shared<Request>(_inst->getASID(), base_addr, 87913590Srekai.gonzalezalberquilla@arm.com next_addr - base_addr, _flags, _inst->masterId(), 88013590Srekai.gonzalezalberquilla@arm.com _inst->instAddr(), _inst->contextId())); 88113590Srekai.gonzalezalberquilla@arm.com size_so_far = next_addr - base_addr; 88213590Srekai.gonzalezalberquilla@arm.com 88313590Srekai.gonzalezalberquilla@arm.com /* We are block aligned now, reading whole blocks. */ 88413590Srekai.gonzalezalberquilla@arm.com base_addr = next_addr; 88513590Srekai.gonzalezalberquilla@arm.com while (base_addr != final_addr) { 88613590Srekai.gonzalezalberquilla@arm.com _requests.push_back(std::make_shared<Request>(_inst->getASID(), 88713590Srekai.gonzalezalberquilla@arm.com base_addr, cacheLineSize, _flags, _inst->masterId(), 88813590Srekai.gonzalezalberquilla@arm.com _inst->instAddr(), _inst->contextId())); 88913590Srekai.gonzalezalberquilla@arm.com size_so_far += cacheLineSize; 89013590Srekai.gonzalezalberquilla@arm.com base_addr += cacheLineSize; 89113590Srekai.gonzalezalberquilla@arm.com } 89213590Srekai.gonzalezalberquilla@arm.com 89313590Srekai.gonzalezalberquilla@arm.com /* Deal with the tail. */ 89413590Srekai.gonzalezalberquilla@arm.com if (size_so_far < _size) { 89513590Srekai.gonzalezalberquilla@arm.com _requests.push_back(std::make_shared<Request>(_inst->getASID(), 89613590Srekai.gonzalezalberquilla@arm.com base_addr, _size - size_so_far, _flags, _inst->masterId(), 89713590Srekai.gonzalezalberquilla@arm.com _inst->instAddr(), _inst->contextId())); 89813590Srekai.gonzalezalberquilla@arm.com } 89913590Srekai.gonzalezalberquilla@arm.com 90013590Srekai.gonzalezalberquilla@arm.com /* Setup the requests and send them to translation. */ 90113590Srekai.gonzalezalberquilla@arm.com for (auto& r: _requests) { 90213590Srekai.gonzalezalberquilla@arm.com r->setReqInstSeqNum(_inst->seqNum); 90313590Srekai.gonzalezalberquilla@arm.com r->taskId(_taskId); 90413590Srekai.gonzalezalberquilla@arm.com } 90513590Srekai.gonzalezalberquilla@arm.com this->_inst->savedReq = this; 90613590Srekai.gonzalezalberquilla@arm.com numInTranslationFragments = 0; 90713590Srekai.gonzalezalberquilla@arm.com numTranslatedFragments = 0; 90813590Srekai.gonzalezalberquilla@arm.com 90913590Srekai.gonzalezalberquilla@arm.com for (uint32_t i = 0; i < _requests.size(); i++) { 91013590Srekai.gonzalezalberquilla@arm.com sendFragmentToTranslation(i); 91113590Srekai.gonzalezalberquilla@arm.com } 91213590Srekai.gonzalezalberquilla@arm.com} 91313590Srekai.gonzalezalberquilla@arm.com 91413590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 91513590Srekai.gonzalezalberquilla@arm.comvoid 91613590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::LSQRequest::sendFragmentToTranslation(int i) 91713590Srekai.gonzalezalberquilla@arm.com{ 91813590Srekai.gonzalezalberquilla@arm.com numInTranslationFragments++; 91913590Srekai.gonzalezalberquilla@arm.com _port.dTLB()->translateTiming( 92013590Srekai.gonzalezalberquilla@arm.com this->request(i), 92113590Srekai.gonzalezalberquilla@arm.com this->_inst->thread->getTC(), this, 92213590Srekai.gonzalezalberquilla@arm.com this->isLoad() ? BaseTLB::Read : BaseTLB::Write); 92313590Srekai.gonzalezalberquilla@arm.com} 92413590Srekai.gonzalezalberquilla@arm.com 92513590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 92613590Srekai.gonzalezalberquilla@arm.combool 92713590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::recvTimingResp(PacketPtr pkt) 92813590Srekai.gonzalezalberquilla@arm.com{ 92913590Srekai.gonzalezalberquilla@arm.com assert(_numOutstandingPackets == 1); 93013590Srekai.gonzalezalberquilla@arm.com auto state = dynamic_cast<LSQSenderState*>(pkt->senderState); 93113590Srekai.gonzalezalberquilla@arm.com setState(State::Complete); 93213590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::Complete); 93313590Srekai.gonzalezalberquilla@arm.com state->outstanding--; 93413590Srekai.gonzalezalberquilla@arm.com assert(pkt == _packets.front()); 93513590Srekai.gonzalezalberquilla@arm.com _port.completeDataAccess(pkt); 93613590Srekai.gonzalezalberquilla@arm.com return true; 93713590Srekai.gonzalezalberquilla@arm.com} 93813590Srekai.gonzalezalberquilla@arm.com 93913590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 94013590Srekai.gonzalezalberquilla@arm.combool 94113590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::recvTimingResp(PacketPtr pkt) 94213590Srekai.gonzalezalberquilla@arm.com{ 94313590Srekai.gonzalezalberquilla@arm.com auto state = dynamic_cast<LSQSenderState*>(pkt->senderState); 94413590Srekai.gonzalezalberquilla@arm.com uint32_t pktIdx = 0; 94513590Srekai.gonzalezalberquilla@arm.com while (pktIdx < _packets.size() && pkt != _packets[pktIdx]) 94613590Srekai.gonzalezalberquilla@arm.com pktIdx++; 94713590Srekai.gonzalezalberquilla@arm.com assert(pktIdx < _packets.size()); 94813590Srekai.gonzalezalberquilla@arm.com assert(pkt->req == _requests[pktIdx]); 94913590Srekai.gonzalezalberquilla@arm.com assert(pkt == _packets[pktIdx]); 95013590Srekai.gonzalezalberquilla@arm.com numReceivedPackets++; 95113590Srekai.gonzalezalberquilla@arm.com state->outstanding--; 95213590Srekai.gonzalezalberquilla@arm.com if (numReceivedPackets == _packets.size()) { 95313590Srekai.gonzalezalberquilla@arm.com setState(State::Complete); 95413590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::Complete); 95513590Srekai.gonzalezalberquilla@arm.com /* Assemble packets. */ 95613590Srekai.gonzalezalberquilla@arm.com PacketPtr resp = isLoad() 95713590Srekai.gonzalezalberquilla@arm.com ? Packet::createRead(mainReq) 95813590Srekai.gonzalezalberquilla@arm.com : Packet::createWrite(mainReq); 95913590Srekai.gonzalezalberquilla@arm.com if (isLoad()) 96013590Srekai.gonzalezalberquilla@arm.com resp->dataStatic(_inst->memData); 96113590Srekai.gonzalezalberquilla@arm.com else 96213590Srekai.gonzalezalberquilla@arm.com resp->dataStatic(_data); 96313590Srekai.gonzalezalberquilla@arm.com resp->senderState = _senderState; 96413590Srekai.gonzalezalberquilla@arm.com _port.completeDataAccess(resp); 96513590Srekai.gonzalezalberquilla@arm.com delete resp; 96613590Srekai.gonzalezalberquilla@arm.com } 96713590Srekai.gonzalezalberquilla@arm.com return true; 96813590Srekai.gonzalezalberquilla@arm.com} 96913590Srekai.gonzalezalberquilla@arm.com 97013590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 97113590Srekai.gonzalezalberquilla@arm.comvoid 97213590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::buildPackets() 97313590Srekai.gonzalezalberquilla@arm.com{ 97413590Srekai.gonzalezalberquilla@arm.com assert(_senderState); 97513590Srekai.gonzalezalberquilla@arm.com /* Retries do not create new packets. */ 97613590Srekai.gonzalezalberquilla@arm.com if (_packets.size() == 0) { 97713590Srekai.gonzalezalberquilla@arm.com _packets.push_back( 97813590Srekai.gonzalezalberquilla@arm.com isLoad() 97913590Srekai.gonzalezalberquilla@arm.com ? Packet::createRead(request()) 98013590Srekai.gonzalezalberquilla@arm.com : Packet::createWrite(request())); 98113590Srekai.gonzalezalberquilla@arm.com _packets.back()->dataStatic(_inst->memData); 98213590Srekai.gonzalezalberquilla@arm.com _packets.back()->senderState = _senderState; 98313590Srekai.gonzalezalberquilla@arm.com } 98413590Srekai.gonzalezalberquilla@arm.com assert(_packets.size() == 1); 98513590Srekai.gonzalezalberquilla@arm.com} 98613590Srekai.gonzalezalberquilla@arm.com 98713590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 98813590Srekai.gonzalezalberquilla@arm.comvoid 98913590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::buildPackets() 99013590Srekai.gonzalezalberquilla@arm.com{ 99113590Srekai.gonzalezalberquilla@arm.com /* Extra data?? */ 99213590Srekai.gonzalezalberquilla@arm.com ptrdiff_t offset = 0; 99313590Srekai.gonzalezalberquilla@arm.com if (_packets.size() == 0) { 99413590Srekai.gonzalezalberquilla@arm.com /* New stuff */ 99513590Srekai.gonzalezalberquilla@arm.com if (isLoad()) { 99613590Srekai.gonzalezalberquilla@arm.com _mainPacket = Packet::createRead(mainReq); 99713590Srekai.gonzalezalberquilla@arm.com _mainPacket->dataStatic(_inst->memData); 99813590Srekai.gonzalezalberquilla@arm.com } 99913590Srekai.gonzalezalberquilla@arm.com for (auto& r: _requests) { 100013590Srekai.gonzalezalberquilla@arm.com PacketPtr pkt = isLoad() ? Packet::createRead(r) 100113590Srekai.gonzalezalberquilla@arm.com : Packet::createWrite(r); 100213590Srekai.gonzalezalberquilla@arm.com if (isLoad()) { 100313590Srekai.gonzalezalberquilla@arm.com pkt->dataStatic(_inst->memData + offset); 100413590Srekai.gonzalezalberquilla@arm.com } else { 100513590Srekai.gonzalezalberquilla@arm.com uint8_t* req_data = new uint8_t[r->getSize()]; 100613590Srekai.gonzalezalberquilla@arm.com std::memcpy(req_data, 100713590Srekai.gonzalezalberquilla@arm.com _inst->memData + offset, 100813590Srekai.gonzalezalberquilla@arm.com r->getSize()); 100913590Srekai.gonzalezalberquilla@arm.com pkt->dataDynamic(req_data); 101013590Srekai.gonzalezalberquilla@arm.com } 101113590Srekai.gonzalezalberquilla@arm.com offset += r->getSize(); 101213590Srekai.gonzalezalberquilla@arm.com pkt->senderState = _senderState; 101313590Srekai.gonzalezalberquilla@arm.com _packets.push_back(pkt); 101413590Srekai.gonzalezalberquilla@arm.com } 101513590Srekai.gonzalezalberquilla@arm.com } 101613590Srekai.gonzalezalberquilla@arm.com assert(_packets.size() == _requests.size()); 101713590Srekai.gonzalezalberquilla@arm.com} 101813590Srekai.gonzalezalberquilla@arm.com 101913590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 102013590Srekai.gonzalezalberquilla@arm.comvoid 102113590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::sendPacketToCache() 102213590Srekai.gonzalezalberquilla@arm.com{ 102313590Srekai.gonzalezalberquilla@arm.com assert(_numOutstandingPackets == 0); 102413590Srekai.gonzalezalberquilla@arm.com if (lsqUnit()->trySendPacket(isLoad(), _packets.at(0))) 102513590Srekai.gonzalezalberquilla@arm.com _numOutstandingPackets = 1; 102613590Srekai.gonzalezalberquilla@arm.com} 102713590Srekai.gonzalezalberquilla@arm.com 102813590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 102913590Srekai.gonzalezalberquilla@arm.comvoid 103013590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::sendPacketToCache() 103113590Srekai.gonzalezalberquilla@arm.com{ 103213590Srekai.gonzalezalberquilla@arm.com /* Try to send the packets. */ 103313590Srekai.gonzalezalberquilla@arm.com while (numReceivedPackets + _numOutstandingPackets < _packets.size() && 103413590Srekai.gonzalezalberquilla@arm.com lsqUnit()->trySendPacket(isLoad(), 103513590Srekai.gonzalezalberquilla@arm.com _packets.at(numReceivedPackets + _numOutstandingPackets))) { 103613590Srekai.gonzalezalberquilla@arm.com _numOutstandingPackets++; 103713590Srekai.gonzalezalberquilla@arm.com } 103813590Srekai.gonzalezalberquilla@arm.com} 103913590Srekai.gonzalezalberquilla@arm.com 104013590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 104113590Srekai.gonzalezalberquilla@arm.comvoid 104213590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::handleIprWrite(ThreadContext *thread, 104313590Srekai.gonzalezalberquilla@arm.com PacketPtr pkt) 104413590Srekai.gonzalezalberquilla@arm.com{ 104513590Srekai.gonzalezalberquilla@arm.com TheISA::handleIprWrite(thread, pkt); 104613590Srekai.gonzalezalberquilla@arm.com} 104713590Srekai.gonzalezalberquilla@arm.com 104813590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 104913590Srekai.gonzalezalberquilla@arm.comvoid 105013590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::handleIprWrite(ThreadContext *thread, 105113590Srekai.gonzalezalberquilla@arm.com PacketPtr mainPkt) 105213590Srekai.gonzalezalberquilla@arm.com{ 105313590Srekai.gonzalezalberquilla@arm.com unsigned offset = 0; 105413590Srekai.gonzalezalberquilla@arm.com for (auto r: _requests) { 105513590Srekai.gonzalezalberquilla@arm.com PacketPtr pkt = new Packet(r, MemCmd::WriteReq); 105613590Srekai.gonzalezalberquilla@arm.com pkt->dataStatic(mainPkt->getPtr<uint8_t>() + offset); 105713590Srekai.gonzalezalberquilla@arm.com TheISA::handleIprWrite(thread, pkt); 105813590Srekai.gonzalezalberquilla@arm.com offset += r->getSize(); 105913590Srekai.gonzalezalberquilla@arm.com delete pkt; 106013590Srekai.gonzalezalberquilla@arm.com } 106113590Srekai.gonzalezalberquilla@arm.com} 106213590Srekai.gonzalezalberquilla@arm.com 106313590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 106413590Srekai.gonzalezalberquilla@arm.comCycles 106513590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::handleIprRead(ThreadContext *thread, 106613590Srekai.gonzalezalberquilla@arm.com PacketPtr pkt) 106713590Srekai.gonzalezalberquilla@arm.com{ 106813590Srekai.gonzalezalberquilla@arm.com return TheISA::handleIprRead(thread, pkt); 106913590Srekai.gonzalezalberquilla@arm.com} 107013590Srekai.gonzalezalberquilla@arm.com 107113590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 107213590Srekai.gonzalezalberquilla@arm.comCycles 107313590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::handleIprRead(ThreadContext *thread, 107413590Srekai.gonzalezalberquilla@arm.com PacketPtr mainPkt) 107513590Srekai.gonzalezalberquilla@arm.com{ 107613590Srekai.gonzalezalberquilla@arm.com Cycles delay(0); 107713590Srekai.gonzalezalberquilla@arm.com unsigned offset = 0; 107813590Srekai.gonzalezalberquilla@arm.com 107913590Srekai.gonzalezalberquilla@arm.com for (auto r: _requests) { 108013590Srekai.gonzalezalberquilla@arm.com PacketPtr pkt = new Packet(r, MemCmd::ReadReq); 108113590Srekai.gonzalezalberquilla@arm.com pkt->dataStatic(mainPkt->getPtr<uint8_t>() + offset); 108213590Srekai.gonzalezalberquilla@arm.com Cycles d = TheISA::handleIprRead(thread, pkt); 108313590Srekai.gonzalezalberquilla@arm.com if (d > delay) 108413590Srekai.gonzalezalberquilla@arm.com delay = d; 108513590Srekai.gonzalezalberquilla@arm.com offset += r->getSize(); 108613590Srekai.gonzalezalberquilla@arm.com delete pkt; 108713590Srekai.gonzalezalberquilla@arm.com } 108813590Srekai.gonzalezalberquilla@arm.com return delay; 108913590Srekai.gonzalezalberquilla@arm.com} 109013590Srekai.gonzalezalberquilla@arm.com 109113590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 109213590Srekai.gonzalezalberquilla@arm.combool 109313590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SingleDataRequest::isCacheBlockHit(Addr blockAddr, Addr blockMask) 109413590Srekai.gonzalezalberquilla@arm.com{ 109513590Srekai.gonzalezalberquilla@arm.com return ( (LSQRequest::_requests[0]->getPaddr() & blockMask) == blockAddr); 109613590Srekai.gonzalezalberquilla@arm.com} 109713590Srekai.gonzalezalberquilla@arm.com 109813590Srekai.gonzalezalberquilla@arm.comtemplate<class Impl> 109913590Srekai.gonzalezalberquilla@arm.combool 110013590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::SplitDataRequest::isCacheBlockHit(Addr blockAddr, Addr blockMask) 110113590Srekai.gonzalezalberquilla@arm.com{ 110213590Srekai.gonzalezalberquilla@arm.com bool is_hit = false; 110313590Srekai.gonzalezalberquilla@arm.com for (auto &r: _requests) { 110413590Srekai.gonzalezalberquilla@arm.com if ((r->getPaddr() & blockMask) == blockAddr) { 110513590Srekai.gonzalezalberquilla@arm.com is_hit = true; 110613590Srekai.gonzalezalberquilla@arm.com break; 110713590Srekai.gonzalezalberquilla@arm.com } 110813590Srekai.gonzalezalberquilla@arm.com } 110913590Srekai.gonzalezalberquilla@arm.com return is_hit; 111013590Srekai.gonzalezalberquilla@arm.com} 111113590Srekai.gonzalezalberquilla@arm.com 11129944Smatt.horsnell@ARM.com#endif//__CPU_O3_LSQ_IMPL_HH__ 1113