12292SN/A/* 213590Srekai.gonzalezalberquilla@arm.com * Copyright (c) 2011-2012, 2014, 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 * 152329SN/A * Copyright (c) 2004-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 442292SN/A#ifndef __CPU_O3_LSQ_HH__ 452292SN/A#define __CPU_O3_LSQ_HH__ 462292SN/A 472292SN/A#include <map> 482292SN/A#include <queue> 492292SN/A 5013590Srekai.gonzalezalberquilla@arm.com#include "arch/generic/tlb.hh" 5113590Srekai.gonzalezalberquilla@arm.com#include "cpu/inst_seq.hh" 528229Snate@binkert.org#include "cpu/o3/lsq_unit.hh" 5313954Sgiacomo.gabrielli@arm.com#include "cpu/utils.hh" 5413560Snikos.nikoleris@arm.com#include "enums/SMTQueuePolicy.hh" 552669Sktlim@umich.edu#include "mem/port.hh" 562292SN/A#include "sim/sim_object.hh" 572292SN/A 588737Skoansin.tan@gmail.comstruct DerivO3CPUParams; 595529Snate@binkert.org 602292SN/Atemplate <class Impl> 6114194Sgabeblack@google.comclass FullO3CPU; 6214194Sgabeblack@google.com 6314194Sgabeblack@google.comtemplate <class Impl> 6413590Srekai.gonzalezalberquilla@arm.comclass LSQ 6513590Srekai.gonzalezalberquilla@arm.com 6613590Srekai.gonzalezalberquilla@arm.com{ 672292SN/A public: 682733Sktlim@umich.edu typedef typename Impl::O3CPU O3CPU; 692292SN/A typedef typename Impl::DynInstPtr DynInstPtr; 702292SN/A typedef typename Impl::CPUPol::IEW IEW; 712292SN/A typedef typename Impl::CPUPol::LSQUnit LSQUnit; 722292SN/A 7313590Srekai.gonzalezalberquilla@arm.com class LSQRequest; 7413590Srekai.gonzalezalberquilla@arm.com /** Derived class to hold any sender state the LSQ needs. */ 7513590Srekai.gonzalezalberquilla@arm.com class LSQSenderState : public Packet::SenderState 7613590Srekai.gonzalezalberquilla@arm.com { 7713590Srekai.gonzalezalberquilla@arm.com protected: 7813590Srekai.gonzalezalberquilla@arm.com /** The senderState needs to know the LSQRequest who owns it. */ 7913590Srekai.gonzalezalberquilla@arm.com LSQRequest* _request; 8013590Srekai.gonzalezalberquilla@arm.com 8113590Srekai.gonzalezalberquilla@arm.com /** Default constructor. */ 8213590Srekai.gonzalezalberquilla@arm.com LSQSenderState(LSQRequest* request, bool isLoad_) 8313590Srekai.gonzalezalberquilla@arm.com : _request(request), mainPkt(nullptr), pendingPacket(nullptr), 8413590Srekai.gonzalezalberquilla@arm.com outstanding(0), isLoad(isLoad_), needWB(isLoad_), isSplit(false), 8513590Srekai.gonzalezalberquilla@arm.com pktToSend(false), deleted(false) 8613590Srekai.gonzalezalberquilla@arm.com { } 8713590Srekai.gonzalezalberquilla@arm.com public: 8813590Srekai.gonzalezalberquilla@arm.com 8913590Srekai.gonzalezalberquilla@arm.com /** Instruction which initiated the access to memory. */ 9013590Srekai.gonzalezalberquilla@arm.com DynInstPtr inst; 9113590Srekai.gonzalezalberquilla@arm.com /** The main packet from a split load, used during writeback. */ 9213590Srekai.gonzalezalberquilla@arm.com PacketPtr mainPkt; 9313590Srekai.gonzalezalberquilla@arm.com /** A second packet from a split store that needs sending. */ 9413590Srekai.gonzalezalberquilla@arm.com PacketPtr pendingPacket; 9513590Srekai.gonzalezalberquilla@arm.com /** Number of outstanding packets to complete. */ 9613590Srekai.gonzalezalberquilla@arm.com uint8_t outstanding; 9713590Srekai.gonzalezalberquilla@arm.com /** Whether or not it is a load. */ 9813590Srekai.gonzalezalberquilla@arm.com bool isLoad; 9913590Srekai.gonzalezalberquilla@arm.com /** Whether or not the instruction will need to writeback. */ 10013590Srekai.gonzalezalberquilla@arm.com bool needWB; 10113590Srekai.gonzalezalberquilla@arm.com /** Whether or not this access is split in two. */ 10213590Srekai.gonzalezalberquilla@arm.com bool isSplit; 10313590Srekai.gonzalezalberquilla@arm.com /** Whether or not there is a packet that needs sending. */ 10413590Srekai.gonzalezalberquilla@arm.com bool pktToSend; 10513590Srekai.gonzalezalberquilla@arm.com /** Has the request been deleted? 10613590Srekai.gonzalezalberquilla@arm.com * LSQ entries can be squashed before the response comes back. in that 10713590Srekai.gonzalezalberquilla@arm.com * case the SenderState knows. 10813590Srekai.gonzalezalberquilla@arm.com */ 10913590Srekai.gonzalezalberquilla@arm.com bool deleted; 11013590Srekai.gonzalezalberquilla@arm.com ContextID contextId() { return inst->contextId(); } 11113590Srekai.gonzalezalberquilla@arm.com 11213590Srekai.gonzalezalberquilla@arm.com /** Completes a packet and returns whether the access is finished. */ 11313590Srekai.gonzalezalberquilla@arm.com inline bool isComplete() { return outstanding == 0; } 11413590Srekai.gonzalezalberquilla@arm.com inline void deleteRequest() { deleted = true; } 11513590Srekai.gonzalezalberquilla@arm.com inline bool alive() { return !deleted; } 11613590Srekai.gonzalezalberquilla@arm.com LSQRequest* request() { return _request; } 11713590Srekai.gonzalezalberquilla@arm.com virtual void complete() = 0; 11813590Srekai.gonzalezalberquilla@arm.com void writebackDone() { _request->writebackDone(); } 11913590Srekai.gonzalezalberquilla@arm.com }; 12013590Srekai.gonzalezalberquilla@arm.com 12114194Sgabeblack@google.com /** 12214194Sgabeblack@google.com * DcachePort class for the load/store queue. 12314194Sgabeblack@google.com */ 12414194Sgabeblack@google.com class DcachePort : public MasterPort 12514194Sgabeblack@google.com { 12614194Sgabeblack@google.com protected: 12714194Sgabeblack@google.com 12814194Sgabeblack@google.com /** Pointer to LSQ. */ 12914194Sgabeblack@google.com LSQ<Impl> *lsq; 13014194Sgabeblack@google.com FullO3CPU<Impl> *cpu; 13114194Sgabeblack@google.com 13214194Sgabeblack@google.com public: 13314194Sgabeblack@google.com /** Default constructor. */ 13414194Sgabeblack@google.com DcachePort(LSQ<Impl> *_lsq, FullO3CPU<Impl>* _cpu) 13514194Sgabeblack@google.com : MasterPort(_cpu->name() + ".dcache_port", _cpu), lsq(_lsq), 13614194Sgabeblack@google.com cpu(_cpu) 13714194Sgabeblack@google.com { } 13814194Sgabeblack@google.com 13914194Sgabeblack@google.com protected: 14014194Sgabeblack@google.com 14114194Sgabeblack@google.com /** Timing version of receive. Handles writing back and 14214194Sgabeblack@google.com * completing the load or store that has returned from 14314194Sgabeblack@google.com * memory. */ 14414194Sgabeblack@google.com virtual bool recvTimingResp(PacketPtr pkt); 14514194Sgabeblack@google.com virtual void recvTimingSnoopReq(PacketPtr pkt); 14614194Sgabeblack@google.com 14714194Sgabeblack@google.com virtual void recvFunctionalSnoop(PacketPtr pkt) 14814194Sgabeblack@google.com { 14914194Sgabeblack@google.com // @todo: Is there a need for potential invalidation here? 15014194Sgabeblack@google.com } 15114194Sgabeblack@google.com 15214194Sgabeblack@google.com /** Handles doing a retry of the previous send. */ 15314194Sgabeblack@google.com virtual void recvReqRetry(); 15414194Sgabeblack@google.com 15514194Sgabeblack@google.com /** 15614194Sgabeblack@google.com * As this CPU requires snooping to maintain the load store queue 15714194Sgabeblack@google.com * change the behaviour from the base CPU port. 15814194Sgabeblack@google.com * 15914194Sgabeblack@google.com * @return true since we have to snoop 16014194Sgabeblack@google.com */ 16114194Sgabeblack@google.com virtual bool isSnooping() const { return true; } 16214194Sgabeblack@google.com }; 16314194Sgabeblack@google.com 16413590Srekai.gonzalezalberquilla@arm.com /** Memory operation metadata. 16513590Srekai.gonzalezalberquilla@arm.com * This class holds the information about a memory operation. It lives 16613590Srekai.gonzalezalberquilla@arm.com * from initiateAcc to resource deallocation at commit or squash. 16713590Srekai.gonzalezalberquilla@arm.com * LSQRequest objects are owned by the LQ/SQ Entry in the LSQUnit that 16813590Srekai.gonzalezalberquilla@arm.com * holds the operation. It is also used by the LSQSenderState. In addition, 16913590Srekai.gonzalezalberquilla@arm.com * the LSQRequest is a TranslationState, therefore, upon squash, there must 17013590Srekai.gonzalezalberquilla@arm.com * be a defined ownership transferal in case the LSQ resources are 17113590Srekai.gonzalezalberquilla@arm.com * deallocated before the TLB is done using the TranslationState. If that 17213590Srekai.gonzalezalberquilla@arm.com * happens, the LSQRequest will be self-owned, and responsible to detect 17313590Srekai.gonzalezalberquilla@arm.com * that its services are no longer required and self-destruct. 17413590Srekai.gonzalezalberquilla@arm.com * 17513590Srekai.gonzalezalberquilla@arm.com * Lifetime of a LSQRequest: 17613590Srekai.gonzalezalberquilla@arm.com * +--------------------+ 17713590Srekai.gonzalezalberquilla@arm.com * |LSQ creates and owns| 17813590Srekai.gonzalezalberquilla@arm.com * +--------------------+ 17913590Srekai.gonzalezalberquilla@arm.com * | 18013590Srekai.gonzalezalberquilla@arm.com * +--------------------+ 18113590Srekai.gonzalezalberquilla@arm.com * | Initate translation| 18213590Srekai.gonzalezalberquilla@arm.com * +--------------------+ 18313590Srekai.gonzalezalberquilla@arm.com * | 18413590Srekai.gonzalezalberquilla@arm.com * ___^___ 18513590Srekai.gonzalezalberquilla@arm.com * ___/ \___ 18613590Srekai.gonzalezalberquilla@arm.com * ______/ Squashed? \ 18713590Srekai.gonzalezalberquilla@arm.com * | \___ ___/ 18813590Srekai.gonzalezalberquilla@arm.com * | \___ ___/ 18913590Srekai.gonzalezalberquilla@arm.com * | v 19013590Srekai.gonzalezalberquilla@arm.com * | | 19113590Srekai.gonzalezalberquilla@arm.com * | +--------------------+ 19213590Srekai.gonzalezalberquilla@arm.com * | | Translation done | 19313590Srekai.gonzalezalberquilla@arm.com * | +--------------------+ 19413590Srekai.gonzalezalberquilla@arm.com * | | 19513590Srekai.gonzalezalberquilla@arm.com * | +--------------------+ 19613590Srekai.gonzalezalberquilla@arm.com * | | Send packet |<------+ 19713590Srekai.gonzalezalberquilla@arm.com * | +--------------------+ | 19813590Srekai.gonzalezalberquilla@arm.com * | | | 19913590Srekai.gonzalezalberquilla@arm.com * | ___^___ | 20013590Srekai.gonzalezalberquilla@arm.com * | ___/ \___ | 20113590Srekai.gonzalezalberquilla@arm.com * | ____/ Squashed? \ | 20213590Srekai.gonzalezalberquilla@arm.com * | | \___ ___/ | 20313590Srekai.gonzalezalberquilla@arm.com * | | \___ ___/ | 20413590Srekai.gonzalezalberquilla@arm.com * | | v | 20513590Srekai.gonzalezalberquilla@arm.com * | | | | 20613590Srekai.gonzalezalberquilla@arm.com * | | ___^___ | 20713590Srekai.gonzalezalberquilla@arm.com * | | ___/ \___ | 20813590Srekai.gonzalezalberquilla@arm.com * | | / Done? \__________| 20913590Srekai.gonzalezalberquilla@arm.com * | | \___ ___/ 21013590Srekai.gonzalezalberquilla@arm.com * | | \___ ___/ 21113590Srekai.gonzalezalberquilla@arm.com * | | v 21213590Srekai.gonzalezalberquilla@arm.com * | | | 21313590Srekai.gonzalezalberquilla@arm.com * | | +--------------------+ 21413590Srekai.gonzalezalberquilla@arm.com * | | | Manage stuff | 21513590Srekai.gonzalezalberquilla@arm.com * | | | Free resources | 21613590Srekai.gonzalezalberquilla@arm.com * | | +--------------------+ 21713590Srekai.gonzalezalberquilla@arm.com * | | 21813590Srekai.gonzalezalberquilla@arm.com * | | +--------------------+ 21913590Srekai.gonzalezalberquilla@arm.com * | | | senderState owns | 22013590Srekai.gonzalezalberquilla@arm.com * | +->| onRecvTimingResp | 22113590Srekai.gonzalezalberquilla@arm.com * | | free resources | 22213590Srekai.gonzalezalberquilla@arm.com * | +--------------------+ 22313590Srekai.gonzalezalberquilla@arm.com * | 22413590Srekai.gonzalezalberquilla@arm.com * | +----------------------+ 22513590Srekai.gonzalezalberquilla@arm.com * | | self owned (Trans) | 22613590Srekai.gonzalezalberquilla@arm.com * +-->| on TranslationFinish | 22713590Srekai.gonzalezalberquilla@arm.com * | free resources | 22813590Srekai.gonzalezalberquilla@arm.com * +----------------------+ 22913590Srekai.gonzalezalberquilla@arm.com * 23013590Srekai.gonzalezalberquilla@arm.com * 23113590Srekai.gonzalezalberquilla@arm.com */ 23213590Srekai.gonzalezalberquilla@arm.com class LSQRequest : public BaseTLB::Translation 23313590Srekai.gonzalezalberquilla@arm.com { 23413590Srekai.gonzalezalberquilla@arm.com protected: 23513590Srekai.gonzalezalberquilla@arm.com typedef uint32_t FlagsStorage; 23613590Srekai.gonzalezalberquilla@arm.com typedef ::Flags<FlagsStorage> FlagsType; 23713590Srekai.gonzalezalberquilla@arm.com 23813590Srekai.gonzalezalberquilla@arm.com enum Flag : FlagsStorage 23913590Srekai.gonzalezalberquilla@arm.com { 24013590Srekai.gonzalezalberquilla@arm.com IsLoad = 0x00000001, 24113652Sqtt2@cornell.edu /** True if this is a store/atomic that writes registers (SC). */ 24213590Srekai.gonzalezalberquilla@arm.com WbStore = 0x00000002, 24313590Srekai.gonzalezalberquilla@arm.com Delayed = 0x00000004, 24413590Srekai.gonzalezalberquilla@arm.com IsSplit = 0x00000008, 24513590Srekai.gonzalezalberquilla@arm.com /** True if any translation has been sent to TLB. */ 24613590Srekai.gonzalezalberquilla@arm.com TranslationStarted = 0x00000010, 24713590Srekai.gonzalezalberquilla@arm.com /** True if there are un-replied outbound translations.. */ 24813590Srekai.gonzalezalberquilla@arm.com TranslationFinished = 0x00000020, 24913590Srekai.gonzalezalberquilla@arm.com Sent = 0x00000040, 25013590Srekai.gonzalezalberquilla@arm.com Retry = 0x00000080, 25113590Srekai.gonzalezalberquilla@arm.com Complete = 0x00000100, 25213590Srekai.gonzalezalberquilla@arm.com /** Ownership tracking flags. */ 25313590Srekai.gonzalezalberquilla@arm.com /** Translation squashed. */ 25413590Srekai.gonzalezalberquilla@arm.com TranslationSquashed = 0x00000200, 25513590Srekai.gonzalezalberquilla@arm.com /** Request discarded */ 25613590Srekai.gonzalezalberquilla@arm.com Discarded = 0x00000400, 25713590Srekai.gonzalezalberquilla@arm.com /** LSQ resources freed. */ 25813590Srekai.gonzalezalberquilla@arm.com LSQEntryFreed = 0x00000800, 25913590Srekai.gonzalezalberquilla@arm.com /** Store written back. */ 26013590Srekai.gonzalezalberquilla@arm.com WritebackScheduled = 0x00001000, 26113652Sqtt2@cornell.edu WritebackDone = 0x00002000, 26213652Sqtt2@cornell.edu /** True if this is an atomic request */ 26313652Sqtt2@cornell.edu IsAtomic = 0x00004000 26413590Srekai.gonzalezalberquilla@arm.com }; 26513590Srekai.gonzalezalberquilla@arm.com FlagsType flags; 26613590Srekai.gonzalezalberquilla@arm.com 26713590Srekai.gonzalezalberquilla@arm.com enum class State 26813590Srekai.gonzalezalberquilla@arm.com { 26913590Srekai.gonzalezalberquilla@arm.com NotIssued, 27013590Srekai.gonzalezalberquilla@arm.com Translation, 27113590Srekai.gonzalezalberquilla@arm.com Request, 27213590Srekai.gonzalezalberquilla@arm.com Fault, 27314105Sgabor.dozsa@arm.com PartialFault, 27413590Srekai.gonzalezalberquilla@arm.com }; 27513590Srekai.gonzalezalberquilla@arm.com State _state; 27613590Srekai.gonzalezalberquilla@arm.com LSQSenderState* _senderState; 27713590Srekai.gonzalezalberquilla@arm.com void setState(const State& newState) { _state = newState; } 27813590Srekai.gonzalezalberquilla@arm.com 27913590Srekai.gonzalezalberquilla@arm.com uint32_t numTranslatedFragments; 28013590Srekai.gonzalezalberquilla@arm.com uint32_t numInTranslationFragments; 28113590Srekai.gonzalezalberquilla@arm.com 28213590Srekai.gonzalezalberquilla@arm.com /** LQ/SQ entry idx. */ 28313590Srekai.gonzalezalberquilla@arm.com uint32_t _entryIdx; 28413590Srekai.gonzalezalberquilla@arm.com 28513628SAndrea.Mondelli@ucf.edu void markDelayed() override { flags.set(Flag::Delayed); } 28613590Srekai.gonzalezalberquilla@arm.com bool isDelayed() { return flags.isSet(Flag::Delayed); } 28713590Srekai.gonzalezalberquilla@arm.com 28813590Srekai.gonzalezalberquilla@arm.com public: 28913590Srekai.gonzalezalberquilla@arm.com LSQUnit& _port; 29013590Srekai.gonzalezalberquilla@arm.com const DynInstPtr _inst; 29113590Srekai.gonzalezalberquilla@arm.com uint32_t _taskId; 29213590Srekai.gonzalezalberquilla@arm.com PacketDataPtr _data; 29313590Srekai.gonzalezalberquilla@arm.com std::vector<PacketPtr> _packets; 29413590Srekai.gonzalezalberquilla@arm.com std::vector<RequestPtr> _requests; 29513590Srekai.gonzalezalberquilla@arm.com std::vector<Fault> _fault; 29613590Srekai.gonzalezalberquilla@arm.com uint64_t* _res; 29713590Srekai.gonzalezalberquilla@arm.com const Addr _addr; 29813590Srekai.gonzalezalberquilla@arm.com const uint32_t _size; 29913590Srekai.gonzalezalberquilla@arm.com const Request::Flags _flags; 30013954Sgiacomo.gabrielli@arm.com std::vector<bool> _byteEnable; 30113590Srekai.gonzalezalberquilla@arm.com uint32_t _numOutstandingPackets; 30214297Sjordi.vaquero@metempsy.com AtomicOpFunctorPtr _amo_op; 30313590Srekai.gonzalezalberquilla@arm.com protected: 30413590Srekai.gonzalezalberquilla@arm.com LSQUnit* lsqUnit() { return &_port; } 30513590Srekai.gonzalezalberquilla@arm.com LSQRequest(LSQUnit* port, const DynInstPtr& inst, bool isLoad) : 30613590Srekai.gonzalezalberquilla@arm.com _state(State::NotIssued), _senderState(nullptr), 30713590Srekai.gonzalezalberquilla@arm.com _port(*port), _inst(inst), _data(nullptr), 30813590Srekai.gonzalezalberquilla@arm.com _res(nullptr), _addr(0), _size(0), _flags(0), 30913652Sqtt2@cornell.edu _numOutstandingPackets(0), _amo_op(nullptr) 31013590Srekai.gonzalezalberquilla@arm.com { 31113590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::IsLoad, isLoad); 31213652Sqtt2@cornell.edu flags.set(Flag::WbStore, 31313652Sqtt2@cornell.edu _inst->isStoreConditional() || _inst->isAtomic()); 31413652Sqtt2@cornell.edu flags.set(Flag::IsAtomic, _inst->isAtomic()); 31513590Srekai.gonzalezalberquilla@arm.com install(); 31613590Srekai.gonzalezalberquilla@arm.com } 31713590Srekai.gonzalezalberquilla@arm.com LSQRequest(LSQUnit* port, const DynInstPtr& inst, bool isLoad, 31813590Srekai.gonzalezalberquilla@arm.com const Addr& addr, const uint32_t& size, 31913590Srekai.gonzalezalberquilla@arm.com const Request::Flags& flags_, 32013652Sqtt2@cornell.edu PacketDataPtr data = nullptr, uint64_t* res = nullptr, 32114297Sjordi.vaquero@metempsy.com AtomicOpFunctorPtr amo_op = nullptr) 32213590Srekai.gonzalezalberquilla@arm.com : _state(State::NotIssued), _senderState(nullptr), 32313590Srekai.gonzalezalberquilla@arm.com numTranslatedFragments(0), 32413590Srekai.gonzalezalberquilla@arm.com numInTranslationFragments(0), 32513590Srekai.gonzalezalberquilla@arm.com _port(*port), _inst(inst), _data(data), 32613590Srekai.gonzalezalberquilla@arm.com _res(res), _addr(addr), _size(size), 32713590Srekai.gonzalezalberquilla@arm.com _flags(flags_), 32813652Sqtt2@cornell.edu _numOutstandingPackets(0), 32914297Sjordi.vaquero@metempsy.com _amo_op(std::move(amo_op)) 33013590Srekai.gonzalezalberquilla@arm.com { 33113590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::IsLoad, isLoad); 33213652Sqtt2@cornell.edu flags.set(Flag::WbStore, 33313652Sqtt2@cornell.edu _inst->isStoreConditional() || _inst->isAtomic()); 33413652Sqtt2@cornell.edu flags.set(Flag::IsAtomic, _inst->isAtomic()); 33513590Srekai.gonzalezalberquilla@arm.com install(); 33613590Srekai.gonzalezalberquilla@arm.com } 33713590Srekai.gonzalezalberquilla@arm.com 33813590Srekai.gonzalezalberquilla@arm.com bool 33913590Srekai.gonzalezalberquilla@arm.com isLoad() const 34013590Srekai.gonzalezalberquilla@arm.com { 34113590Srekai.gonzalezalberquilla@arm.com return flags.isSet(Flag::IsLoad); 34213590Srekai.gonzalezalberquilla@arm.com } 34313590Srekai.gonzalezalberquilla@arm.com 34413652Sqtt2@cornell.edu bool 34513652Sqtt2@cornell.edu isAtomic() const 34613652Sqtt2@cornell.edu { 34713652Sqtt2@cornell.edu return flags.isSet(Flag::IsAtomic); 34813652Sqtt2@cornell.edu } 34913652Sqtt2@cornell.edu 35013590Srekai.gonzalezalberquilla@arm.com /** Install the request in the LQ/SQ. */ 35113590Srekai.gonzalezalberquilla@arm.com void install() 35213590Srekai.gonzalezalberquilla@arm.com { 35313590Srekai.gonzalezalberquilla@arm.com if (isLoad()) { 35413590Srekai.gonzalezalberquilla@arm.com _port.loadQueue[_inst->lqIdx].setRequest(this); 35513590Srekai.gonzalezalberquilla@arm.com } else { 35613652Sqtt2@cornell.edu // Store, StoreConditional, and Atomic requests are pushed 35713652Sqtt2@cornell.edu // to this storeQueue 35813590Srekai.gonzalezalberquilla@arm.com _port.storeQueue[_inst->sqIdx].setRequest(this); 35913590Srekai.gonzalezalberquilla@arm.com } 36013590Srekai.gonzalezalberquilla@arm.com } 36113590Srekai.gonzalezalberquilla@arm.com virtual bool 36213590Srekai.gonzalezalberquilla@arm.com squashed() const override 36313590Srekai.gonzalezalberquilla@arm.com { 36413590Srekai.gonzalezalberquilla@arm.com return _inst->isSquashed(); 36513590Srekai.gonzalezalberquilla@arm.com } 36613590Srekai.gonzalezalberquilla@arm.com 36713590Srekai.gonzalezalberquilla@arm.com /** 36813590Srekai.gonzalezalberquilla@arm.com * Test if the LSQRequest has been released, i.e. self-owned. 36913590Srekai.gonzalezalberquilla@arm.com * An LSQRequest manages itself when the resources on the LSQ are freed 37013590Srekai.gonzalezalberquilla@arm.com * but the translation is still going on and the LSQEntry was freed. 37113590Srekai.gonzalezalberquilla@arm.com */ 37213590Srekai.gonzalezalberquilla@arm.com bool 37313590Srekai.gonzalezalberquilla@arm.com isReleased() 37413590Srekai.gonzalezalberquilla@arm.com { 37513590Srekai.gonzalezalberquilla@arm.com return flags.isSet(Flag::LSQEntryFreed) || 37613590Srekai.gonzalezalberquilla@arm.com flags.isSet(Flag::Discarded); 37713590Srekai.gonzalezalberquilla@arm.com } 37813590Srekai.gonzalezalberquilla@arm.com 37913590Srekai.gonzalezalberquilla@arm.com /** Release the LSQRequest. 38013590Srekai.gonzalezalberquilla@arm.com * Notify the sender state that the request it points to is not valid 38113590Srekai.gonzalezalberquilla@arm.com * anymore. Understand if the request is orphan (self-managed) and if 38213590Srekai.gonzalezalberquilla@arm.com * so, mark it as freed, else destroy it, as this means 38313590Srekai.gonzalezalberquilla@arm.com * the end of its life cycle. 38413590Srekai.gonzalezalberquilla@arm.com * An LSQRequest is orphan when its resources are released 38513590Srekai.gonzalezalberquilla@arm.com * but there is any in-flight translation request to the TLB or access 38613590Srekai.gonzalezalberquilla@arm.com * request to the memory. 38713590Srekai.gonzalezalberquilla@arm.com */ 38813590Srekai.gonzalezalberquilla@arm.com void release(Flag reason) 38913590Srekai.gonzalezalberquilla@arm.com { 39013590Srekai.gonzalezalberquilla@arm.com assert(reason == Flag::LSQEntryFreed || reason == Flag::Discarded); 39113590Srekai.gonzalezalberquilla@arm.com if (!isAnyOutstandingRequest()) { 39213590Srekai.gonzalezalberquilla@arm.com delete this; 39313590Srekai.gonzalezalberquilla@arm.com } else { 39413590Srekai.gonzalezalberquilla@arm.com if (_senderState) { 39513590Srekai.gonzalezalberquilla@arm.com _senderState->deleteRequest(); 39613590Srekai.gonzalezalberquilla@arm.com } 39713590Srekai.gonzalezalberquilla@arm.com flags.set(reason); 39813590Srekai.gonzalezalberquilla@arm.com } 39913590Srekai.gonzalezalberquilla@arm.com } 40013590Srekai.gonzalezalberquilla@arm.com 40113954Sgiacomo.gabrielli@arm.com /** Helper function used to add a (sub)request, given its address 40213954Sgiacomo.gabrielli@arm.com * `addr`, size `size` and byte-enable mask `byteEnable`. 40313954Sgiacomo.gabrielli@arm.com * 40413954Sgiacomo.gabrielli@arm.com * The request is only added if the mask is empty or if there is at 40513954Sgiacomo.gabrielli@arm.com * least an active element in it. 40613954Sgiacomo.gabrielli@arm.com */ 40713954Sgiacomo.gabrielli@arm.com void 40813954Sgiacomo.gabrielli@arm.com addRequest(Addr addr, unsigned size, 40913954Sgiacomo.gabrielli@arm.com const std::vector<bool>& byteEnable) 41013954Sgiacomo.gabrielli@arm.com { 41113954Sgiacomo.gabrielli@arm.com if (byteEnable.empty() || 41213954Sgiacomo.gabrielli@arm.com isAnyActiveElement(byteEnable.begin(), byteEnable.end())) { 41313954Sgiacomo.gabrielli@arm.com auto request = std::make_shared<Request>(_inst->getASID(), 41413954Sgiacomo.gabrielli@arm.com addr, size, _flags, _inst->masterId(), 41514297Sjordi.vaquero@metempsy.com _inst->instAddr(), _inst->contextId(), 41614297Sjordi.vaquero@metempsy.com std::move(_amo_op)); 41713954Sgiacomo.gabrielli@arm.com if (!byteEnable.empty()) { 41813954Sgiacomo.gabrielli@arm.com request->setByteEnable(byteEnable); 41913954Sgiacomo.gabrielli@arm.com } 42013954Sgiacomo.gabrielli@arm.com _requests.push_back(request); 42113954Sgiacomo.gabrielli@arm.com } 42213954Sgiacomo.gabrielli@arm.com } 42313954Sgiacomo.gabrielli@arm.com 42413590Srekai.gonzalezalberquilla@arm.com /** Destructor. 42513590Srekai.gonzalezalberquilla@arm.com * The LSQRequest owns the request. If the packet has already been 42613590Srekai.gonzalezalberquilla@arm.com * sent, the sender state will be deleted upon receiving the reply. 42713590Srekai.gonzalezalberquilla@arm.com */ 42813590Srekai.gonzalezalberquilla@arm.com virtual ~LSQRequest() 42913590Srekai.gonzalezalberquilla@arm.com { 43013590Srekai.gonzalezalberquilla@arm.com assert(!isAnyOutstandingRequest()); 43113590Srekai.gonzalezalberquilla@arm.com _inst->savedReq = nullptr; 43213590Srekai.gonzalezalberquilla@arm.com if (_senderState) 43313590Srekai.gonzalezalberquilla@arm.com delete _senderState; 43413590Srekai.gonzalezalberquilla@arm.com 43513590Srekai.gonzalezalberquilla@arm.com for (auto r: _packets) 43613590Srekai.gonzalezalberquilla@arm.com delete r; 43713590Srekai.gonzalezalberquilla@arm.com }; 43813590Srekai.gonzalezalberquilla@arm.com 43913590Srekai.gonzalezalberquilla@arm.com 44013590Srekai.gonzalezalberquilla@arm.com public: 44113590Srekai.gonzalezalberquilla@arm.com /** Convenience getters/setters. */ 44213590Srekai.gonzalezalberquilla@arm.com /** @{ */ 44313590Srekai.gonzalezalberquilla@arm.com /** Set up Context numbers. */ 44413590Srekai.gonzalezalberquilla@arm.com void 44513590Srekai.gonzalezalberquilla@arm.com setContext(const ContextID& context_id) 44613590Srekai.gonzalezalberquilla@arm.com { 44713590Srekai.gonzalezalberquilla@arm.com request()->setContext(context_id); 44813590Srekai.gonzalezalberquilla@arm.com } 44913590Srekai.gonzalezalberquilla@arm.com 45013590Srekai.gonzalezalberquilla@arm.com const DynInstPtr& 45113590Srekai.gonzalezalberquilla@arm.com instruction() 45213590Srekai.gonzalezalberquilla@arm.com { 45313590Srekai.gonzalezalberquilla@arm.com return _inst; 45413590Srekai.gonzalezalberquilla@arm.com } 45513590Srekai.gonzalezalberquilla@arm.com 45613590Srekai.gonzalezalberquilla@arm.com /** Set up virtual request. 45713590Srekai.gonzalezalberquilla@arm.com * For a previously allocated Request objects. 45813590Srekai.gonzalezalberquilla@arm.com */ 45913590Srekai.gonzalezalberquilla@arm.com void 46013590Srekai.gonzalezalberquilla@arm.com setVirt(int asid, Addr vaddr, unsigned size, Request::Flags flags_, 46113590Srekai.gonzalezalberquilla@arm.com MasterID mid, Addr pc) 46213590Srekai.gonzalezalberquilla@arm.com { 46313590Srekai.gonzalezalberquilla@arm.com request()->setVirt(asid, vaddr, size, flags_, mid, pc); 46413590Srekai.gonzalezalberquilla@arm.com } 46513590Srekai.gonzalezalberquilla@arm.com 46613590Srekai.gonzalezalberquilla@arm.com void 46713590Srekai.gonzalezalberquilla@arm.com taskId(const uint32_t& v) 46813590Srekai.gonzalezalberquilla@arm.com { 46913590Srekai.gonzalezalberquilla@arm.com _taskId = v; 47013590Srekai.gonzalezalberquilla@arm.com for (auto& r: _requests) 47113590Srekai.gonzalezalberquilla@arm.com r->taskId(v); 47213590Srekai.gonzalezalberquilla@arm.com } 47313590Srekai.gonzalezalberquilla@arm.com 47413590Srekai.gonzalezalberquilla@arm.com uint32_t taskId() const { return _taskId; } 47513590Srekai.gonzalezalberquilla@arm.com RequestPtr request(int idx = 0) { return _requests.at(idx); } 47613590Srekai.gonzalezalberquilla@arm.com 47713590Srekai.gonzalezalberquilla@arm.com const RequestPtr 47813590Srekai.gonzalezalberquilla@arm.com request(int idx = 0) const 47913590Srekai.gonzalezalberquilla@arm.com { 48013590Srekai.gonzalezalberquilla@arm.com return _requests.at(idx); 48113590Srekai.gonzalezalberquilla@arm.com } 48213590Srekai.gonzalezalberquilla@arm.com 48313590Srekai.gonzalezalberquilla@arm.com Addr getVaddr(int idx = 0) const { return request(idx)->getVaddr(); } 48413590Srekai.gonzalezalberquilla@arm.com virtual void initiateTranslation() = 0; 48513590Srekai.gonzalezalberquilla@arm.com 48613590Srekai.gonzalezalberquilla@arm.com PacketPtr packet(int idx = 0) { return _packets.at(idx); } 48713590Srekai.gonzalezalberquilla@arm.com 48813590Srekai.gonzalezalberquilla@arm.com virtual PacketPtr 48913590Srekai.gonzalezalberquilla@arm.com mainPacket() 49013590Srekai.gonzalezalberquilla@arm.com { 49113590Srekai.gonzalezalberquilla@arm.com assert (_packets.size() == 1); 49213590Srekai.gonzalezalberquilla@arm.com return packet(); 49313590Srekai.gonzalezalberquilla@arm.com } 49413590Srekai.gonzalezalberquilla@arm.com 49513590Srekai.gonzalezalberquilla@arm.com virtual RequestPtr 49613590Srekai.gonzalezalberquilla@arm.com mainRequest() 49713590Srekai.gonzalezalberquilla@arm.com { 49813590Srekai.gonzalezalberquilla@arm.com assert (_requests.size() == 1); 49913590Srekai.gonzalezalberquilla@arm.com return request(); 50013590Srekai.gonzalezalberquilla@arm.com } 50113590Srekai.gonzalezalberquilla@arm.com 50213590Srekai.gonzalezalberquilla@arm.com void 50313590Srekai.gonzalezalberquilla@arm.com senderState(LSQSenderState* st) 50413590Srekai.gonzalezalberquilla@arm.com { 50513590Srekai.gonzalezalberquilla@arm.com _senderState = st; 50613590Srekai.gonzalezalberquilla@arm.com for (auto& pkt: _packets) { 50713590Srekai.gonzalezalberquilla@arm.com if (pkt) 50813590Srekai.gonzalezalberquilla@arm.com pkt->senderState = st; 50913590Srekai.gonzalezalberquilla@arm.com } 51013590Srekai.gonzalezalberquilla@arm.com } 51113590Srekai.gonzalezalberquilla@arm.com 51213590Srekai.gonzalezalberquilla@arm.com const LSQSenderState* 51313590Srekai.gonzalezalberquilla@arm.com senderState() const 51413590Srekai.gonzalezalberquilla@arm.com { 51513590Srekai.gonzalezalberquilla@arm.com return _senderState; 51613590Srekai.gonzalezalberquilla@arm.com } 51713590Srekai.gonzalezalberquilla@arm.com 51813590Srekai.gonzalezalberquilla@arm.com /** 51913590Srekai.gonzalezalberquilla@arm.com * Mark senderState as discarded. This will cause to discard response 52013590Srekai.gonzalezalberquilla@arm.com * packets from the cache. 52113590Srekai.gonzalezalberquilla@arm.com */ 52213590Srekai.gonzalezalberquilla@arm.com void 52313590Srekai.gonzalezalberquilla@arm.com discardSenderState() 52413590Srekai.gonzalezalberquilla@arm.com { 52513590Srekai.gonzalezalberquilla@arm.com assert(_senderState); 52613590Srekai.gonzalezalberquilla@arm.com _senderState->deleteRequest(); 52713590Srekai.gonzalezalberquilla@arm.com } 52813590Srekai.gonzalezalberquilla@arm.com 52913590Srekai.gonzalezalberquilla@arm.com /** 53013590Srekai.gonzalezalberquilla@arm.com * Test if there is any in-flight translation or mem access request 53113590Srekai.gonzalezalberquilla@arm.com */ 53213590Srekai.gonzalezalberquilla@arm.com bool 53313590Srekai.gonzalezalberquilla@arm.com isAnyOutstandingRequest() 53413590Srekai.gonzalezalberquilla@arm.com { 53513590Srekai.gonzalezalberquilla@arm.com return numInTranslationFragments > 0 || 53613590Srekai.gonzalezalberquilla@arm.com _numOutstandingPackets > 0 || 53713590Srekai.gonzalezalberquilla@arm.com (flags.isSet(Flag::WritebackScheduled) && 53813590Srekai.gonzalezalberquilla@arm.com !flags.isSet(Flag::WritebackDone)); 53913590Srekai.gonzalezalberquilla@arm.com } 54013590Srekai.gonzalezalberquilla@arm.com 54113590Srekai.gonzalezalberquilla@arm.com bool 54213590Srekai.gonzalezalberquilla@arm.com isSplit() const 54313590Srekai.gonzalezalberquilla@arm.com { 54413590Srekai.gonzalezalberquilla@arm.com return flags.isSet(Flag::IsSplit); 54513590Srekai.gonzalezalberquilla@arm.com } 54613590Srekai.gonzalezalberquilla@arm.com /** @} */ 54713590Srekai.gonzalezalberquilla@arm.com virtual bool recvTimingResp(PacketPtr pkt) = 0; 54813590Srekai.gonzalezalberquilla@arm.com virtual void sendPacketToCache() = 0; 54913590Srekai.gonzalezalberquilla@arm.com virtual void buildPackets() = 0; 55013590Srekai.gonzalezalberquilla@arm.com 55113590Srekai.gonzalezalberquilla@arm.com /** 55213590Srekai.gonzalezalberquilla@arm.com * Memory mapped IPR accesses 55313590Srekai.gonzalezalberquilla@arm.com */ 55413590Srekai.gonzalezalberquilla@arm.com virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt) = 0; 55513590Srekai.gonzalezalberquilla@arm.com virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt) = 0; 55613590Srekai.gonzalezalberquilla@arm.com 55713590Srekai.gonzalezalberquilla@arm.com /** 55813590Srekai.gonzalezalberquilla@arm.com * Test if the request accesses a particular cache line. 55913590Srekai.gonzalezalberquilla@arm.com */ 56013590Srekai.gonzalezalberquilla@arm.com virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask) = 0; 56113590Srekai.gonzalezalberquilla@arm.com 56213590Srekai.gonzalezalberquilla@arm.com /** Update the status to reflect that a packet was sent. */ 56313590Srekai.gonzalezalberquilla@arm.com void 56413590Srekai.gonzalezalberquilla@arm.com packetSent() 56513590Srekai.gonzalezalberquilla@arm.com { 56613590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::Sent); 56713590Srekai.gonzalezalberquilla@arm.com } 56813590Srekai.gonzalezalberquilla@arm.com /** Update the status to reflect that a packet was not sent. 56913590Srekai.gonzalezalberquilla@arm.com * When a packet fails to be sent, we mark the request as needing a 57013590Srekai.gonzalezalberquilla@arm.com * retry. Note that Retry flag is sticky. 57113590Srekai.gonzalezalberquilla@arm.com */ 57213590Srekai.gonzalezalberquilla@arm.com void 57313590Srekai.gonzalezalberquilla@arm.com packetNotSent() 57413590Srekai.gonzalezalberquilla@arm.com { 57513590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::Retry); 57613590Srekai.gonzalezalberquilla@arm.com flags.clear(Flag::Sent); 57713590Srekai.gonzalezalberquilla@arm.com } 57813590Srekai.gonzalezalberquilla@arm.com 57913590Srekai.gonzalezalberquilla@arm.com void sendFragmentToTranslation(int i); 58013590Srekai.gonzalezalberquilla@arm.com bool 58113590Srekai.gonzalezalberquilla@arm.com isComplete() 58213590Srekai.gonzalezalberquilla@arm.com { 58313590Srekai.gonzalezalberquilla@arm.com return flags.isSet(Flag::Complete); 58413590Srekai.gonzalezalberquilla@arm.com } 58513590Srekai.gonzalezalberquilla@arm.com 58613590Srekai.gonzalezalberquilla@arm.com bool 58713590Srekai.gonzalezalberquilla@arm.com isInTranslation() 58813590Srekai.gonzalezalberquilla@arm.com { 58913590Srekai.gonzalezalberquilla@arm.com return _state == State::Translation; 59013590Srekai.gonzalezalberquilla@arm.com } 59113590Srekai.gonzalezalberquilla@arm.com 59213590Srekai.gonzalezalberquilla@arm.com bool 59313590Srekai.gonzalezalberquilla@arm.com isTranslationComplete() 59413590Srekai.gonzalezalberquilla@arm.com { 59513590Srekai.gonzalezalberquilla@arm.com return flags.isSet(Flag::TranslationStarted) && 59613590Srekai.gonzalezalberquilla@arm.com !isInTranslation(); 59713590Srekai.gonzalezalberquilla@arm.com } 59813590Srekai.gonzalezalberquilla@arm.com 59913590Srekai.gonzalezalberquilla@arm.com bool 60013590Srekai.gonzalezalberquilla@arm.com isTranslationBlocked() 60113590Srekai.gonzalezalberquilla@arm.com { 60213590Srekai.gonzalezalberquilla@arm.com return _state == State::Translation && 60313590Srekai.gonzalezalberquilla@arm.com flags.isSet(Flag::TranslationStarted) && 60413590Srekai.gonzalezalberquilla@arm.com !flags.isSet(Flag::TranslationFinished); 60513590Srekai.gonzalezalberquilla@arm.com } 60613590Srekai.gonzalezalberquilla@arm.com 60713590Srekai.gonzalezalberquilla@arm.com bool 60813590Srekai.gonzalezalberquilla@arm.com isSent() 60913590Srekai.gonzalezalberquilla@arm.com { 61013590Srekai.gonzalezalberquilla@arm.com return flags.isSet(Flag::Sent); 61113590Srekai.gonzalezalberquilla@arm.com } 61213590Srekai.gonzalezalberquilla@arm.com 61314105Sgabor.dozsa@arm.com bool 61414105Sgabor.dozsa@arm.com isPartialFault() 61514105Sgabor.dozsa@arm.com { 61614105Sgabor.dozsa@arm.com return _state == State::PartialFault; 61714105Sgabor.dozsa@arm.com } 61814105Sgabor.dozsa@arm.com 61914105Sgabor.dozsa@arm.com bool 62014105Sgabor.dozsa@arm.com isMemAccessRequired() 62114105Sgabor.dozsa@arm.com { 62214105Sgabor.dozsa@arm.com return (_state == State::Request || 62314105Sgabor.dozsa@arm.com (isPartialFault() && isLoad())); 62414105Sgabor.dozsa@arm.com } 62514105Sgabor.dozsa@arm.com 62613590Srekai.gonzalezalberquilla@arm.com /** 62713590Srekai.gonzalezalberquilla@arm.com * The LSQ entry is cleared 62813590Srekai.gonzalezalberquilla@arm.com */ 62913590Srekai.gonzalezalberquilla@arm.com void 63013590Srekai.gonzalezalberquilla@arm.com freeLSQEntry() 63113590Srekai.gonzalezalberquilla@arm.com { 63213590Srekai.gonzalezalberquilla@arm.com release(Flag::LSQEntryFreed); 63313590Srekai.gonzalezalberquilla@arm.com } 63413590Srekai.gonzalezalberquilla@arm.com 63513590Srekai.gonzalezalberquilla@arm.com /** 63613590Srekai.gonzalezalberquilla@arm.com * The request is discarded (e.g. partial store-load forwarding) 63713590Srekai.gonzalezalberquilla@arm.com */ 63813590Srekai.gonzalezalberquilla@arm.com void 63913590Srekai.gonzalezalberquilla@arm.com discard() 64013590Srekai.gonzalezalberquilla@arm.com { 64113590Srekai.gonzalezalberquilla@arm.com release(Flag::Discarded); 64213590Srekai.gonzalezalberquilla@arm.com } 64313590Srekai.gonzalezalberquilla@arm.com 64413590Srekai.gonzalezalberquilla@arm.com void 64513590Srekai.gonzalezalberquilla@arm.com packetReplied() 64613590Srekai.gonzalezalberquilla@arm.com { 64713590Srekai.gonzalezalberquilla@arm.com assert(_numOutstandingPackets > 0); 64813590Srekai.gonzalezalberquilla@arm.com _numOutstandingPackets--; 64913590Srekai.gonzalezalberquilla@arm.com if (_numOutstandingPackets == 0 && isReleased()) 65013590Srekai.gonzalezalberquilla@arm.com delete this; 65113590Srekai.gonzalezalberquilla@arm.com } 65213590Srekai.gonzalezalberquilla@arm.com 65313590Srekai.gonzalezalberquilla@arm.com void 65413590Srekai.gonzalezalberquilla@arm.com writebackScheduled() 65513590Srekai.gonzalezalberquilla@arm.com { 65613590Srekai.gonzalezalberquilla@arm.com assert(!flags.isSet(Flag::WritebackScheduled)); 65713590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::WritebackScheduled); 65813590Srekai.gonzalezalberquilla@arm.com } 65913590Srekai.gonzalezalberquilla@arm.com 66013590Srekai.gonzalezalberquilla@arm.com void 66113590Srekai.gonzalezalberquilla@arm.com writebackDone() 66213590Srekai.gonzalezalberquilla@arm.com { 66313590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::WritebackDone); 66413590Srekai.gonzalezalberquilla@arm.com /* If the lsq resources are already free */ 66513590Srekai.gonzalezalberquilla@arm.com if (isReleased()) { 66613590Srekai.gonzalezalberquilla@arm.com delete this; 66713590Srekai.gonzalezalberquilla@arm.com } 66813590Srekai.gonzalezalberquilla@arm.com } 66913590Srekai.gonzalezalberquilla@arm.com 67013590Srekai.gonzalezalberquilla@arm.com void 67113590Srekai.gonzalezalberquilla@arm.com squashTranslation() 67213590Srekai.gonzalezalberquilla@arm.com { 67313590Srekai.gonzalezalberquilla@arm.com assert(numInTranslationFragments == 0); 67413590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::TranslationSquashed); 67513590Srekai.gonzalezalberquilla@arm.com /* If we are on our own, self-destruct. */ 67613590Srekai.gonzalezalberquilla@arm.com if (isReleased()) { 67713590Srekai.gonzalezalberquilla@arm.com delete this; 67813590Srekai.gonzalezalberquilla@arm.com } 67913590Srekai.gonzalezalberquilla@arm.com } 68013590Srekai.gonzalezalberquilla@arm.com 68113590Srekai.gonzalezalberquilla@arm.com void 68213590Srekai.gonzalezalberquilla@arm.com complete() 68313590Srekai.gonzalezalberquilla@arm.com { 68413590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::Complete); 68513590Srekai.gonzalezalberquilla@arm.com } 68613590Srekai.gonzalezalberquilla@arm.com }; 68713590Srekai.gonzalezalberquilla@arm.com 68813590Srekai.gonzalezalberquilla@arm.com class SingleDataRequest : public LSQRequest 68913590Srekai.gonzalezalberquilla@arm.com { 69013590Srekai.gonzalezalberquilla@arm.com protected: 69113590Srekai.gonzalezalberquilla@arm.com /* Given that we are inside templates, children need explicit 69213590Srekai.gonzalezalberquilla@arm.com * declaration of the names in the parent class. */ 69313590Srekai.gonzalezalberquilla@arm.com using Flag = typename LSQRequest::Flag; 69413590Srekai.gonzalezalberquilla@arm.com using State = typename LSQRequest::State; 69513954Sgiacomo.gabrielli@arm.com using LSQRequest::_addr; 69613590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_fault; 69713954Sgiacomo.gabrielli@arm.com using LSQRequest::_flags; 69813954Sgiacomo.gabrielli@arm.com using LSQRequest::_size; 69913954Sgiacomo.gabrielli@arm.com using LSQRequest::_byteEnable; 70013954Sgiacomo.gabrielli@arm.com using LSQRequest::_requests; 70113590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_inst; 70213590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_packets; 70313590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_port; 70413590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_res; 70513954Sgiacomo.gabrielli@arm.com using LSQRequest::_taskId; 70613590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_senderState; 70713590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_state; 70813590Srekai.gonzalezalberquilla@arm.com using LSQRequest::flags; 70913590Srekai.gonzalezalberquilla@arm.com using LSQRequest::isLoad; 71013590Srekai.gonzalezalberquilla@arm.com using LSQRequest::isTranslationComplete; 71113590Srekai.gonzalezalberquilla@arm.com using LSQRequest::lsqUnit; 71213590Srekai.gonzalezalberquilla@arm.com using LSQRequest::request; 71313590Srekai.gonzalezalberquilla@arm.com using LSQRequest::sendFragmentToTranslation; 71413590Srekai.gonzalezalberquilla@arm.com using LSQRequest::setState; 71513590Srekai.gonzalezalberquilla@arm.com using LSQRequest::numInTranslationFragments; 71613590Srekai.gonzalezalberquilla@arm.com using LSQRequest::numTranslatedFragments; 71713590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_numOutstandingPackets; 71813652Sqtt2@cornell.edu using LSQRequest::_amo_op; 71913590Srekai.gonzalezalberquilla@arm.com public: 72013590Srekai.gonzalezalberquilla@arm.com SingleDataRequest(LSQUnit* port, const DynInstPtr& inst, bool isLoad, 72113590Srekai.gonzalezalberquilla@arm.com const Addr& addr, const uint32_t& size, 72213590Srekai.gonzalezalberquilla@arm.com const Request::Flags& flags_, 72313590Srekai.gonzalezalberquilla@arm.com PacketDataPtr data = nullptr, 72413652Sqtt2@cornell.edu uint64_t* res = nullptr, 72514297Sjordi.vaquero@metempsy.com AtomicOpFunctorPtr amo_op = nullptr) : 72613652Sqtt2@cornell.edu LSQRequest(port, inst, isLoad, addr, size, flags_, data, res, 72714297Sjordi.vaquero@metempsy.com std::move(amo_op)) {} 72813954Sgiacomo.gabrielli@arm.com 72913590Srekai.gonzalezalberquilla@arm.com inline virtual ~SingleDataRequest() {} 73013590Srekai.gonzalezalberquilla@arm.com virtual void initiateTranslation(); 73113590Srekai.gonzalezalberquilla@arm.com virtual void finish(const Fault &fault, const RequestPtr &req, 73213590Srekai.gonzalezalberquilla@arm.com ThreadContext* tc, BaseTLB::Mode mode); 73313590Srekai.gonzalezalberquilla@arm.com virtual bool recvTimingResp(PacketPtr pkt); 73413590Srekai.gonzalezalberquilla@arm.com virtual void sendPacketToCache(); 73513590Srekai.gonzalezalberquilla@arm.com virtual void buildPackets(); 73613590Srekai.gonzalezalberquilla@arm.com virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt); 73713590Srekai.gonzalezalberquilla@arm.com virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt); 73813590Srekai.gonzalezalberquilla@arm.com virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask); 73913590Srekai.gonzalezalberquilla@arm.com }; 74013590Srekai.gonzalezalberquilla@arm.com 74113590Srekai.gonzalezalberquilla@arm.com class SplitDataRequest : public LSQRequest 74213590Srekai.gonzalezalberquilla@arm.com { 74313590Srekai.gonzalezalberquilla@arm.com protected: 74413590Srekai.gonzalezalberquilla@arm.com /* Given that we are inside templates, children need explicit 74513590Srekai.gonzalezalberquilla@arm.com * declaration of the names in the parent class. */ 74613590Srekai.gonzalezalberquilla@arm.com using Flag = typename LSQRequest::Flag; 74713590Srekai.gonzalezalberquilla@arm.com using State = typename LSQRequest::State; 74813590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_addr; 74913590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_data; 75013590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_fault; 75113590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_flags; 75213590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_inst; 75313590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_packets; 75413590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_port; 75513590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_requests; 75613590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_res; 75713954Sgiacomo.gabrielli@arm.com using LSQRequest::_byteEnable; 75813590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_senderState; 75913590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_size; 76013590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_state; 76113590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_taskId; 76213590Srekai.gonzalezalberquilla@arm.com using LSQRequest::flags; 76313590Srekai.gonzalezalberquilla@arm.com using LSQRequest::isLoad; 76413590Srekai.gonzalezalberquilla@arm.com using LSQRequest::isTranslationComplete; 76513590Srekai.gonzalezalberquilla@arm.com using LSQRequest::lsqUnit; 76613590Srekai.gonzalezalberquilla@arm.com using LSQRequest::numInTranslationFragments; 76713590Srekai.gonzalezalberquilla@arm.com using LSQRequest::numTranslatedFragments; 76813590Srekai.gonzalezalberquilla@arm.com using LSQRequest::request; 76913590Srekai.gonzalezalberquilla@arm.com using LSQRequest::sendFragmentToTranslation; 77013590Srekai.gonzalezalberquilla@arm.com using LSQRequest::setState; 77113590Srekai.gonzalezalberquilla@arm.com using LSQRequest::_numOutstandingPackets; 77213590Srekai.gonzalezalberquilla@arm.com 77313590Srekai.gonzalezalberquilla@arm.com uint32_t numFragments; 77413590Srekai.gonzalezalberquilla@arm.com uint32_t numReceivedPackets; 77513590Srekai.gonzalezalberquilla@arm.com RequestPtr mainReq; 77613590Srekai.gonzalezalberquilla@arm.com PacketPtr _mainPacket; 77713590Srekai.gonzalezalberquilla@arm.com 77813590Srekai.gonzalezalberquilla@arm.com public: 77913590Srekai.gonzalezalberquilla@arm.com SplitDataRequest(LSQUnit* port, const DynInstPtr& inst, bool isLoad, 78013590Srekai.gonzalezalberquilla@arm.com const Addr& addr, const uint32_t& size, 78113590Srekai.gonzalezalberquilla@arm.com const Request::Flags & flags_, 78213590Srekai.gonzalezalberquilla@arm.com PacketDataPtr data = nullptr, 78313590Srekai.gonzalezalberquilla@arm.com uint64_t* res = nullptr) : 78413954Sgiacomo.gabrielli@arm.com LSQRequest(port, inst, isLoad, addr, size, flags_, data, res, 78513954Sgiacomo.gabrielli@arm.com nullptr), 78613590Srekai.gonzalezalberquilla@arm.com numFragments(0), 78713590Srekai.gonzalezalberquilla@arm.com numReceivedPackets(0), 78813590Srekai.gonzalezalberquilla@arm.com mainReq(nullptr), 78913590Srekai.gonzalezalberquilla@arm.com _mainPacket(nullptr) 79013590Srekai.gonzalezalberquilla@arm.com { 79113590Srekai.gonzalezalberquilla@arm.com flags.set(Flag::IsSplit); 79213590Srekai.gonzalezalberquilla@arm.com } 79313590Srekai.gonzalezalberquilla@arm.com virtual ~SplitDataRequest() 79413590Srekai.gonzalezalberquilla@arm.com { 79513590Srekai.gonzalezalberquilla@arm.com if (mainReq) { 79613590Srekai.gonzalezalberquilla@arm.com mainReq = nullptr; 79713590Srekai.gonzalezalberquilla@arm.com } 79813590Srekai.gonzalezalberquilla@arm.com if (_mainPacket) { 79913590Srekai.gonzalezalberquilla@arm.com delete _mainPacket; 80013590Srekai.gonzalezalberquilla@arm.com _mainPacket = nullptr; 80113590Srekai.gonzalezalberquilla@arm.com } 80213590Srekai.gonzalezalberquilla@arm.com } 80313590Srekai.gonzalezalberquilla@arm.com virtual void finish(const Fault &fault, const RequestPtr &req, 80413590Srekai.gonzalezalberquilla@arm.com ThreadContext* tc, BaseTLB::Mode mode); 80513590Srekai.gonzalezalberquilla@arm.com virtual bool recvTimingResp(PacketPtr pkt); 80613590Srekai.gonzalezalberquilla@arm.com virtual void initiateTranslation(); 80713590Srekai.gonzalezalberquilla@arm.com virtual void sendPacketToCache(); 80813590Srekai.gonzalezalberquilla@arm.com virtual void buildPackets(); 80913590Srekai.gonzalezalberquilla@arm.com 81013590Srekai.gonzalezalberquilla@arm.com virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt); 81113590Srekai.gonzalezalberquilla@arm.com virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt); 81213590Srekai.gonzalezalberquilla@arm.com virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask); 81313590Srekai.gonzalezalberquilla@arm.com 81413590Srekai.gonzalezalberquilla@arm.com virtual RequestPtr mainRequest(); 81513590Srekai.gonzalezalberquilla@arm.com virtual PacketPtr mainPacket(); 81613590Srekai.gonzalezalberquilla@arm.com }; 81713590Srekai.gonzalezalberquilla@arm.com 8182292SN/A /** Constructs an LSQ with the given parameters. */ 8195529Snate@binkert.org LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params); 82013472Srekai.gonzalezalberquilla@arm.com ~LSQ() { } 8212292SN/A 8222292SN/A /** Returns the name of the LSQ. */ 8232292SN/A std::string name() const; 8242292SN/A 8252727Sktlim@umich.edu /** Registers statistics of each LSQ unit. */ 8262727Sktlim@umich.edu void regStats(); 8272727Sktlim@umich.edu 8282292SN/A /** Sets the pointer to the list of active threads. */ 8296221Snate@binkert.org void setActiveThreads(std::list<ThreadID> *at_ptr); 8309444SAndreas.Sandberg@ARM.com 8319444SAndreas.Sandberg@ARM.com /** Perform sanity checks after a drain. */ 8329444SAndreas.Sandberg@ARM.com void drainSanityCheck() const; 8339444SAndreas.Sandberg@ARM.com /** Has the LSQ drained? */ 8349444SAndreas.Sandberg@ARM.com bool isDrained() const; 8352348SN/A /** Takes over execution from another CPU's thread. */ 8362307SN/A void takeOverFrom(); 8372307SN/A 8382292SN/A /** Number of entries needed for the given amount of threads.*/ 8396221Snate@binkert.org int entryAmount(ThreadID num_threads); 8402292SN/A 8412292SN/A /** Ticks the LSQ. */ 84213710Sgabor.dozsa@arm.com void tick(); 8432292SN/A 8442292SN/A /** Inserts a load into the LSQ. */ 84513429Srekai.gonzalezalberquilla@arm.com void insertLoad(const DynInstPtr &load_inst); 8462292SN/A /** Inserts a store into the LSQ. */ 84713429Srekai.gonzalezalberquilla@arm.com void insertStore(const DynInstPtr &store_inst); 8482292SN/A 8492292SN/A /** Executes a load. */ 85013429Srekai.gonzalezalberquilla@arm.com Fault executeLoad(const DynInstPtr &inst); 8512292SN/A 8522292SN/A /** Executes a store. */ 85313429Srekai.gonzalezalberquilla@arm.com Fault executeStore(const DynInstPtr &inst); 8542292SN/A 8552292SN/A /** 8562292SN/A * Commits loads up until the given sequence number for a specific thread. 8572292SN/A */ 8586221Snate@binkert.org void commitLoads(InstSeqNum &youngest_inst, ThreadID tid) 85913590Srekai.gonzalezalberquilla@arm.com { thread.at(tid).commitLoads(youngest_inst); } 8602329SN/A 8612292SN/A /** 8622292SN/A * Commits stores up until the given sequence number for a specific thread. 8632292SN/A */ 8646221Snate@binkert.org void commitStores(InstSeqNum &youngest_inst, ThreadID tid) 86513590Srekai.gonzalezalberquilla@arm.com { thread.at(tid).commitStores(youngest_inst); } 8662292SN/A 8672292SN/A /** 8682292SN/A * Attempts to write back stores until all cache ports are used or the 8692292SN/A * interface becomes blocked. 8702292SN/A */ 8712292SN/A void writebackStores(); 8722292SN/A /** Same as above, but only for one thread. */ 8736221Snate@binkert.org void writebackStores(ThreadID tid); 8742292SN/A 8752292SN/A /** 8762292SN/A * Squash instructions from a thread until the specified sequence number. 8772292SN/A */ 87813590Srekai.gonzalezalberquilla@arm.com void 87913590Srekai.gonzalezalberquilla@arm.com squash(const InstSeqNum &squashed_num, ThreadID tid) 88013590Srekai.gonzalezalberquilla@arm.com { 88113590Srekai.gonzalezalberquilla@arm.com thread.at(tid).squash(squashed_num); 88213590Srekai.gonzalezalberquilla@arm.com } 8832292SN/A 8842292SN/A /** Returns whether or not there was a memory ordering violation. */ 8852292SN/A bool violation(); 8862292SN/A /** 8872292SN/A * Returns whether or not there was a memory ordering violation for a 8882292SN/A * specific thread. 8892292SN/A */ 89013590Srekai.gonzalezalberquilla@arm.com bool violation(ThreadID tid) { return thread.at(tid).violation(); } 8912292SN/A 8922292SN/A /** Gets the instruction that caused the memory ordering violation. */ 89313590Srekai.gonzalezalberquilla@arm.com DynInstPtr 89413590Srekai.gonzalezalberquilla@arm.com getMemDepViolator(ThreadID tid) 89513590Srekai.gonzalezalberquilla@arm.com { 89613590Srekai.gonzalezalberquilla@arm.com return thread.at(tid).getMemDepViolator(); 89713590Srekai.gonzalezalberquilla@arm.com } 8982292SN/A 8992292SN/A /** Returns the head index of the load queue for a specific thread. */ 90013590Srekai.gonzalezalberquilla@arm.com int getLoadHead(ThreadID tid) { return thread.at(tid).getLoadHead(); } 9012329SN/A 9022292SN/A /** Returns the sequence number of the head of the load queue. */ 90313590Srekai.gonzalezalberquilla@arm.com InstSeqNum 90413590Srekai.gonzalezalberquilla@arm.com getLoadHeadSeqNum(ThreadID tid) 9052292SN/A { 90613590Srekai.gonzalezalberquilla@arm.com return thread.at(tid).getLoadHeadSeqNum(); 9072292SN/A } 9082292SN/A 9092292SN/A /** Returns the head index of the store queue. */ 91013590Srekai.gonzalezalberquilla@arm.com int getStoreHead(ThreadID tid) { return thread.at(tid).getStoreHead(); } 9112329SN/A 9122292SN/A /** Returns the sequence number of the head of the store queue. */ 91313590Srekai.gonzalezalberquilla@arm.com InstSeqNum 91413590Srekai.gonzalezalberquilla@arm.com getStoreHeadSeqNum(ThreadID tid) 9152292SN/A { 91613590Srekai.gonzalezalberquilla@arm.com return thread.at(tid).getStoreHeadSeqNum(); 9172292SN/A } 9182292SN/A 9192292SN/A /** Returns the number of instructions in all of the queues. */ 9202292SN/A int getCount(); 9212292SN/A /** Returns the number of instructions in the queues of one thread. */ 92213590Srekai.gonzalezalberquilla@arm.com int getCount(ThreadID tid) { return thread.at(tid).getCount(); } 9232292SN/A 9242292SN/A /** Returns the total number of loads in the load queue. */ 9252292SN/A int numLoads(); 9262292SN/A /** Returns the total number of loads for a single thread. */ 92713590Srekai.gonzalezalberquilla@arm.com int numLoads(ThreadID tid) { return thread.at(tid).numLoads(); } 9282292SN/A 9292292SN/A /** Returns the total number of stores in the store queue. */ 9302292SN/A int numStores(); 9312292SN/A /** Returns the total number of stores for a single thread. */ 93213590Srekai.gonzalezalberquilla@arm.com int numStores(ThreadID tid) { return thread.at(tid).numStores(); } 9332292SN/A 93410239Sbinhpham@cs.rutgers.edu /** Returns the number of free load entries. */ 93510239Sbinhpham@cs.rutgers.edu unsigned numFreeLoadEntries(); 93610239Sbinhpham@cs.rutgers.edu 93710239Sbinhpham@cs.rutgers.edu /** Returns the number of free store entries. */ 93810239Sbinhpham@cs.rutgers.edu unsigned numFreeStoreEntries(); 93910239Sbinhpham@cs.rutgers.edu 9402292SN/A /** Returns the number of free entries for a specific thread. */ 9416221Snate@binkert.org unsigned numFreeEntries(ThreadID tid); 9422292SN/A 94310239Sbinhpham@cs.rutgers.edu /** Returns the number of free entries in the LQ for a specific thread. */ 94410239Sbinhpham@cs.rutgers.edu unsigned numFreeLoadEntries(ThreadID tid); 94510239Sbinhpham@cs.rutgers.edu 94610239Sbinhpham@cs.rutgers.edu /** Returns the number of free entries in the SQ for a specific thread. */ 94710239Sbinhpham@cs.rutgers.edu unsigned numFreeStoreEntries(ThreadID tid); 94810239Sbinhpham@cs.rutgers.edu 9492292SN/A /** Returns if the LSQ is full (either LQ or SQ is full). */ 9502292SN/A bool isFull(); 9512292SN/A /** 9522292SN/A * Returns if the LSQ is full for a specific thread (either LQ or SQ is 9532292SN/A * full). 9542292SN/A */ 9556221Snate@binkert.org bool isFull(ThreadID tid); 9562292SN/A 9579444SAndreas.Sandberg@ARM.com /** Returns if the LSQ is empty (both LQ and SQ are empty). */ 9589444SAndreas.Sandberg@ARM.com bool isEmpty() const; 9599444SAndreas.Sandberg@ARM.com /** Returns if all of the LQs are empty. */ 9609444SAndreas.Sandberg@ARM.com bool lqEmpty() const; 9619444SAndreas.Sandberg@ARM.com /** Returns if all of the SQs are empty. */ 9629444SAndreas.Sandberg@ARM.com bool sqEmpty() const; 9639444SAndreas.Sandberg@ARM.com 9642292SN/A /** Returns if any of the LQs are full. */ 9652292SN/A bool lqFull(); 9662292SN/A /** Returns if the LQ of a given thread is full. */ 9676221Snate@binkert.org bool lqFull(ThreadID tid); 9682292SN/A 9692292SN/A /** Returns if any of the SQs are full. */ 9702292SN/A bool sqFull(); 9712292SN/A /** Returns if the SQ of a given thread is full. */ 9726221Snate@binkert.org bool sqFull(ThreadID tid); 9732292SN/A 9742292SN/A /** 9752292SN/A * Returns if the LSQ is stalled due to a memory operation that must be 9762292SN/A * replayed. 9772292SN/A */ 9782292SN/A bool isStalled(); 9792292SN/A /** 9802292SN/A * Returns if the LSQ of a specific thread is stalled due to a memory 9812292SN/A * operation that must be replayed. 9822292SN/A */ 9836221Snate@binkert.org bool isStalled(ThreadID tid); 9842292SN/A 9852292SN/A /** Returns whether or not there are any stores to write back to memory. */ 9862292SN/A bool hasStoresToWB(); 9872329SN/A 9882292SN/A /** Returns whether or not a specific thread has any stores to write back 9892292SN/A * to memory. 9902292SN/A */ 99113590Srekai.gonzalezalberquilla@arm.com bool hasStoresToWB(ThreadID tid) { return thread.at(tid).hasStoresToWB(); } 9922329SN/A 9932292SN/A /** Returns the number of stores a specific thread has to write back. */ 99413590Srekai.gonzalezalberquilla@arm.com int numStoresToWB(ThreadID tid) { return thread.at(tid).numStoresToWB(); } 9952292SN/A 9962292SN/A /** Returns if the LSQ will write back to memory this cycle. */ 9972292SN/A bool willWB(); 9982292SN/A /** Returns if the LSQ of a specific thread will write back to memory this 9992292SN/A * cycle. 10002292SN/A */ 100113590Srekai.gonzalezalberquilla@arm.com bool willWB(ThreadID tid) { return thread.at(tid).willWB(); } 10022292SN/A 10032292SN/A /** Debugging function to print out all instructions. */ 10049440SAndreas.Sandberg@ARM.com void dumpInsts() const; 10052292SN/A /** Debugging function to print out instructions from a specific thread. */ 100613590Srekai.gonzalezalberquilla@arm.com void dumpInsts(ThreadID tid) const { thread.at(tid).dumpInsts(); } 10072292SN/A 10086974Stjones1@inf.ed.ac.uk /** Executes a read operation, using the load specified at the load 10096974Stjones1@inf.ed.ac.uk * index. 10106974Stjones1@inf.ed.ac.uk */ 101113590Srekai.gonzalezalberquilla@arm.com Fault read(LSQRequest* req, int load_idx); 10122292SN/A 10132292SN/A /** Executes a store operation, using the store specified at the store 10146974Stjones1@inf.ed.ac.uk * index. 10152292SN/A */ 101613590Srekai.gonzalezalberquilla@arm.com Fault write(LSQRequest* req, uint8_t *data, int store_idx); 10172292SN/A 10188707Sandreas.hansson@arm.com /** 10198707Sandreas.hansson@arm.com * Retry the previous send that failed. 10208707Sandreas.hansson@arm.com */ 102110713Sandreas.hansson@arm.com void recvReqRetry(); 10228707Sandreas.hansson@arm.com 102313590Srekai.gonzalezalberquilla@arm.com void completeDataAccess(PacketPtr pkt); 10248707Sandreas.hansson@arm.com /** 10258707Sandreas.hansson@arm.com * Handles writing back and completing the load or store that has 10268707Sandreas.hansson@arm.com * returned from memory. 10278707Sandreas.hansson@arm.com * 10288707Sandreas.hansson@arm.com * @param pkt Response packet from the memory sub-system 10298707Sandreas.hansson@arm.com */ 10308975Sandreas.hansson@arm.com bool recvTimingResp(PacketPtr pkt); 10318707Sandreas.hansson@arm.com 10328975Sandreas.hansson@arm.com void recvTimingSnoopReq(PacketPtr pkt); 10338948Sandreas.hansson@arm.com 103413590Srekai.gonzalezalberquilla@arm.com Fault pushRequest(const DynInstPtr& inst, bool isLoad, uint8_t *data, 103513590Srekai.gonzalezalberquilla@arm.com unsigned int size, Addr addr, Request::Flags flags, 103614297Sjordi.vaquero@metempsy.com uint64_t *res, AtomicOpFunctorPtr amo_op, 103713954Sgiacomo.gabrielli@arm.com const std::vector<bool>& byteEnable); 103813590Srekai.gonzalezalberquilla@arm.com 10394329Sktlim@umich.edu /** The CPU pointer. */ 10404329Sktlim@umich.edu O3CPU *cpu; 10414329Sktlim@umich.edu 10424329Sktlim@umich.edu /** The IEW stage pointer. */ 10434329Sktlim@umich.edu IEW *iewStage; 10444329Sktlim@umich.edu 104513590Srekai.gonzalezalberquilla@arm.com /** Is D-cache blocked? */ 104613590Srekai.gonzalezalberquilla@arm.com bool cacheBlocked() const; 104713590Srekai.gonzalezalberquilla@arm.com /** Set D-cache blocked status */ 104813590Srekai.gonzalezalberquilla@arm.com void cacheBlocked(bool v); 104913590Srekai.gonzalezalberquilla@arm.com /** Is any store port available to use? */ 105013710Sgabor.dozsa@arm.com bool cachePortAvailable(bool is_load) const; 105113590Srekai.gonzalezalberquilla@arm.com /** Another store port is in use */ 105213710Sgabor.dozsa@arm.com void cachePortBusy(bool is_load); 105313590Srekai.gonzalezalberquilla@arm.com 105414194Sgabeblack@google.com MasterPort &getDataPort() { return dcachePort; } 105514194Sgabeblack@google.com 10562907Sktlim@umich.edu protected: 105713590Srekai.gonzalezalberquilla@arm.com /** D-cache is blocked */ 105813590Srekai.gonzalezalberquilla@arm.com bool _cacheBlocked; 105913590Srekai.gonzalezalberquilla@arm.com /** The number of cache ports available each cycle (stores only). */ 106013590Srekai.gonzalezalberquilla@arm.com int cacheStorePorts; 106113590Srekai.gonzalezalberquilla@arm.com /** The number of used cache ports in this cycle by stores. */ 106213590Srekai.gonzalezalberquilla@arm.com int usedStorePorts; 106313710Sgabor.dozsa@arm.com /** The number of cache ports available each cycle (loads only). */ 106413710Sgabor.dozsa@arm.com int cacheLoadPorts; 106513710Sgabor.dozsa@arm.com /** The number of used cache ports in this cycle by loads. */ 106613710Sgabor.dozsa@arm.com int usedLoadPorts; 106713590Srekai.gonzalezalberquilla@arm.com 106813590Srekai.gonzalezalberquilla@arm.com 10692292SN/A /** The LSQ policy for SMT mode. */ 107013560Snikos.nikoleris@arm.com SMTQueuePolicy lsqPolicy; 107113472Srekai.gonzalezalberquilla@arm.com 107213472Srekai.gonzalezalberquilla@arm.com /** Auxiliary function to calculate per-thread max LSQ allocation limit. 107313472Srekai.gonzalezalberquilla@arm.com * Depending on a policy, number of entries and possibly number of threads 107413472Srekai.gonzalezalberquilla@arm.com * and threshold, this function calculates how many resources each thread 107513472Srekai.gonzalezalberquilla@arm.com * can occupy at most. 107613472Srekai.gonzalezalberquilla@arm.com */ 107713590Srekai.gonzalezalberquilla@arm.com static uint32_t 107813590Srekai.gonzalezalberquilla@arm.com maxLSQAllocation(SMTQueuePolicy pol, uint32_t entries, 107913590Srekai.gonzalezalberquilla@arm.com uint32_t numThreads, uint32_t SMTThreshold) 108013590Srekai.gonzalezalberquilla@arm.com { 108113560Snikos.nikoleris@arm.com if (pol == SMTQueuePolicy::Dynamic) { 108213472Srekai.gonzalezalberquilla@arm.com return entries; 108313560Snikos.nikoleris@arm.com } else if (pol == SMTQueuePolicy::Partitioned) { 108413472Srekai.gonzalezalberquilla@arm.com //@todo:make work if part_amt doesnt divide evenly. 108513472Srekai.gonzalezalberquilla@arm.com return entries / numThreads; 108613560Snikos.nikoleris@arm.com } else if (pol == SMTQueuePolicy::Threshold) { 108713472Srekai.gonzalezalberquilla@arm.com //Divide up by threshold amount 108813472Srekai.gonzalezalberquilla@arm.com //@todo: Should threads check the max and the total 108913472Srekai.gonzalezalberquilla@arm.com //amount of the LSQ 109013472Srekai.gonzalezalberquilla@arm.com return SMTThreshold; 109113472Srekai.gonzalezalberquilla@arm.com } 109213472Srekai.gonzalezalberquilla@arm.com return 0; 109313472Srekai.gonzalezalberquilla@arm.com } 10942292SN/A 10952292SN/A /** List of Active Threads in System. */ 10966221Snate@binkert.org std::list<ThreadID> *activeThreads; 10972292SN/A 10982292SN/A /** Total Size of LQ Entries. */ 10992292SN/A unsigned LQEntries; 11002292SN/A /** Total Size of SQ Entries. */ 11012292SN/A unsigned SQEntries; 11022292SN/A 11032292SN/A /** Max LQ Size - Used to Enforce Sharing Policies. */ 11042292SN/A unsigned maxLQEntries; 11052292SN/A 11062292SN/A /** Max SQ Size - Used to Enforce Sharing Policies. */ 11072292SN/A unsigned maxSQEntries; 11082292SN/A 110914194Sgabeblack@google.com /** Data port. */ 111014194Sgabeblack@google.com DcachePort dcachePort; 111114194Sgabeblack@google.com 111213472Srekai.gonzalezalberquilla@arm.com /** The LSQ units for individual threads. */ 111313472Srekai.gonzalezalberquilla@arm.com std::vector<LSQUnit> thread; 111413472Srekai.gonzalezalberquilla@arm.com 11152292SN/A /** Number of Threads. */ 11166221Snate@binkert.org ThreadID numThreads; 11172292SN/A}; 11182292SN/A 11192292SN/Atemplate <class Impl> 11202292SN/AFault 112113590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::read(LSQRequest* req, int load_idx) 11222292SN/A{ 112313590Srekai.gonzalezalberquilla@arm.com ThreadID tid = cpu->contextToThread(req->request()->contextId()); 11242292SN/A 112513590Srekai.gonzalezalberquilla@arm.com return thread.at(tid).read(req, load_idx); 11262292SN/A} 11272292SN/A 11282292SN/Atemplate <class Impl> 11292292SN/AFault 113013590Srekai.gonzalezalberquilla@arm.comLSQ<Impl>::write(LSQRequest* req, uint8_t *data, int store_idx) 11312292SN/A{ 113213590Srekai.gonzalezalberquilla@arm.com ThreadID tid = cpu->contextToThread(req->request()->contextId()); 11332292SN/A 113413590Srekai.gonzalezalberquilla@arm.com return thread.at(tid).write(req, data, store_idx); 11352292SN/A} 11362292SN/A 11372292SN/A#endif // __CPU_O3_LSQ_HH__ 1138