lsq.hh revision 11608
110259SAndrew.Bardsley@arm.com/* 210259SAndrew.Bardsley@arm.com * Copyright (c) 2013-2014 ARM Limited 310259SAndrew.Bardsley@arm.com * All rights reserved 410259SAndrew.Bardsley@arm.com * 510259SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall 610259SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual 710259SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating 810259SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software 910259SAndrew.Bardsley@arm.com * licensed hereunder. You may use the software subject to the license 1010259SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated 1110259SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software, 1210259SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form. 1310259SAndrew.Bardsley@arm.com * 1410259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without 1510259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are 1610259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright 1710259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer; 1810259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright 1910259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the 2010259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution; 2110259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its 2210259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from 2310259SAndrew.Bardsley@arm.com * this software without specific prior written permission. 2410259SAndrew.Bardsley@arm.com * 2510259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610259SAndrew.Bardsley@arm.com * 3710259SAndrew.Bardsley@arm.com * Authors: Andrew Bardsley 3810259SAndrew.Bardsley@arm.com */ 3910259SAndrew.Bardsley@arm.com 4010259SAndrew.Bardsley@arm.com/** 4110259SAndrew.Bardsley@arm.com * @file 4210259SAndrew.Bardsley@arm.com * 4310259SAndrew.Bardsley@arm.com * A load/store queue that allows outstanding reads and writes. 4410259SAndrew.Bardsley@arm.com * 4510259SAndrew.Bardsley@arm.com */ 4610259SAndrew.Bardsley@arm.com 4710259SAndrew.Bardsley@arm.com#ifndef __CPU_MINOR_NEW_LSQ_HH__ 4810259SAndrew.Bardsley@arm.com#define __CPU_MINOR_NEW_LSQ_HH__ 4910259SAndrew.Bardsley@arm.com 5010259SAndrew.Bardsley@arm.com#include "cpu/minor/buffers.hh" 5110259SAndrew.Bardsley@arm.com#include "cpu/minor/cpu.hh" 5210259SAndrew.Bardsley@arm.com#include "cpu/minor/pipe_data.hh" 5310259SAndrew.Bardsley@arm.com#include "cpu/minor/trace.hh" 5410259SAndrew.Bardsley@arm.com 5510259SAndrew.Bardsley@arm.comnamespace Minor 5610259SAndrew.Bardsley@arm.com{ 5710259SAndrew.Bardsley@arm.com 5810259SAndrew.Bardsley@arm.com/* Forward declaration */ 5910259SAndrew.Bardsley@arm.comclass Execute; 6010259SAndrew.Bardsley@arm.com 6110259SAndrew.Bardsley@arm.comclass LSQ : public Named 6210259SAndrew.Bardsley@arm.com{ 6310259SAndrew.Bardsley@arm.com protected: 6410259SAndrew.Bardsley@arm.com /** My owner(s) */ 6510259SAndrew.Bardsley@arm.com MinorCPU &cpu; 6610259SAndrew.Bardsley@arm.com Execute &execute; 6710259SAndrew.Bardsley@arm.com 6810259SAndrew.Bardsley@arm.com protected: 6910259SAndrew.Bardsley@arm.com /** State of memory access for head access. */ 7010259SAndrew.Bardsley@arm.com enum MemoryState 7110259SAndrew.Bardsley@arm.com { 7210259SAndrew.Bardsley@arm.com MemoryRunning, /* Default. Step dcache queues when possible. */ 7310259SAndrew.Bardsley@arm.com MemoryNeedsRetry /* Request rejected, will be asked to retry */ 7410259SAndrew.Bardsley@arm.com }; 7510259SAndrew.Bardsley@arm.com 7610259SAndrew.Bardsley@arm.com /** Print MemoryState values as shown in the enum definition */ 7710259SAndrew.Bardsley@arm.com friend std::ostream &operator <<(std::ostream &os, 7810259SAndrew.Bardsley@arm.com MemoryState state); 7910259SAndrew.Bardsley@arm.com 8010259SAndrew.Bardsley@arm.com /** Coverage of one address range with another */ 8110259SAndrew.Bardsley@arm.com enum AddrRangeCoverage 8210259SAndrew.Bardsley@arm.com { 8310259SAndrew.Bardsley@arm.com PartialAddrRangeCoverage, /* Two ranges partly overlap */ 8410259SAndrew.Bardsley@arm.com FullAddrRangeCoverage, /* One range fully covers another */ 8510259SAndrew.Bardsley@arm.com NoAddrRangeCoverage /* Two ranges are disjoint */ 8610259SAndrew.Bardsley@arm.com }; 8710259SAndrew.Bardsley@arm.com 8810259SAndrew.Bardsley@arm.com /** Exposable data port */ 8910259SAndrew.Bardsley@arm.com class DcachePort : public MinorCPU::MinorCPUPort 9010259SAndrew.Bardsley@arm.com { 9110259SAndrew.Bardsley@arm.com protected: 9210259SAndrew.Bardsley@arm.com /** My owner */ 9310259SAndrew.Bardsley@arm.com LSQ &lsq; 9410259SAndrew.Bardsley@arm.com 9510259SAndrew.Bardsley@arm.com public: 9610259SAndrew.Bardsley@arm.com DcachePort(std::string name, LSQ &lsq_, MinorCPU &cpu) : 9710259SAndrew.Bardsley@arm.com MinorCPU::MinorCPUPort(name, cpu), lsq(lsq_) 9810259SAndrew.Bardsley@arm.com { } 9910259SAndrew.Bardsley@arm.com 10010259SAndrew.Bardsley@arm.com protected: 10111341Sandreas.hansson@arm.com bool recvTimingResp(PacketPtr pkt) override 10210259SAndrew.Bardsley@arm.com { return lsq.recvTimingResp(pkt); } 10310259SAndrew.Bardsley@arm.com 10411341Sandreas.hansson@arm.com void recvReqRetry() override { lsq.recvReqRetry(); } 10510259SAndrew.Bardsley@arm.com 10611331Sandreas.hansson@arm.com bool isSnooping() const override { return true; } 10711331Sandreas.hansson@arm.com 10811341Sandreas.hansson@arm.com void recvTimingSnoopReq(PacketPtr pkt) override 10910259SAndrew.Bardsley@arm.com { return lsq.recvTimingSnoopReq(pkt); } 11011331Sandreas.hansson@arm.com 11111341Sandreas.hansson@arm.com void recvFunctionalSnoop(PacketPtr pkt) override { } 11210259SAndrew.Bardsley@arm.com }; 11310259SAndrew.Bardsley@arm.com 11410259SAndrew.Bardsley@arm.com DcachePort dcachePort; 11510259SAndrew.Bardsley@arm.com 11610259SAndrew.Bardsley@arm.com public: 11710259SAndrew.Bardsley@arm.com /** Derived SenderState to carry data access info. through address 11810259SAndrew.Bardsley@arm.com * translation, the queues in this port and back from the memory 11910259SAndrew.Bardsley@arm.com * system. */ 12010259SAndrew.Bardsley@arm.com class LSQRequest : 12110259SAndrew.Bardsley@arm.com public BaseTLB::Translation, /* For TLB lookups */ 12210259SAndrew.Bardsley@arm.com public Packet::SenderState /* For packing into a Packet */ 12310259SAndrew.Bardsley@arm.com { 12410259SAndrew.Bardsley@arm.com public: 12510259SAndrew.Bardsley@arm.com /** Owning port */ 12610259SAndrew.Bardsley@arm.com LSQ &port; 12710259SAndrew.Bardsley@arm.com 12810259SAndrew.Bardsley@arm.com /** Instruction which made this request */ 12910259SAndrew.Bardsley@arm.com MinorDynInstPtr inst; 13010259SAndrew.Bardsley@arm.com 13110259SAndrew.Bardsley@arm.com /** Load/store indication used for building packet. This isn't 13210259SAndrew.Bardsley@arm.com * carried by Request so we need to keep it here */ 13310259SAndrew.Bardsley@arm.com bool isLoad; 13410259SAndrew.Bardsley@arm.com 13510259SAndrew.Bardsley@arm.com /** Dynamically allocated and populated data carried for 13610259SAndrew.Bardsley@arm.com * building write packets */ 13710259SAndrew.Bardsley@arm.com PacketDataPtr data; 13810259SAndrew.Bardsley@arm.com 13910259SAndrew.Bardsley@arm.com /* Requests carry packets on their way to the memory system. 14010259SAndrew.Bardsley@arm.com * When a Packet returns from the memory system, its 14110259SAndrew.Bardsley@arm.com * request needs to have its packet updated as this 14210259SAndrew.Bardsley@arm.com * may have changed in flight */ 14310259SAndrew.Bardsley@arm.com PacketPtr packet; 14410259SAndrew.Bardsley@arm.com 14510259SAndrew.Bardsley@arm.com /** The underlying request of this LSQRequest */ 14610259SAndrew.Bardsley@arm.com Request request; 14710259SAndrew.Bardsley@arm.com 14810259SAndrew.Bardsley@arm.com /** Fault generated performing this request */ 14910259SAndrew.Bardsley@arm.com Fault fault; 15010259SAndrew.Bardsley@arm.com 15110259SAndrew.Bardsley@arm.com /** Res from pushRequest */ 15210259SAndrew.Bardsley@arm.com uint64_t *res; 15310259SAndrew.Bardsley@arm.com 15410259SAndrew.Bardsley@arm.com /** Was skipped. Set to indicate any reason (faulted, bad 15510259SAndrew.Bardsley@arm.com * stream sequence number, in a fault shadow) that this 15610259SAndrew.Bardsley@arm.com * request did not perform a memory transfer */ 15710259SAndrew.Bardsley@arm.com bool skipped; 15810259SAndrew.Bardsley@arm.com 15910259SAndrew.Bardsley@arm.com /** This in an access other than a normal cacheable load 16010259SAndrew.Bardsley@arm.com * that's visited the memory system */ 16110259SAndrew.Bardsley@arm.com bool issuedToMemory; 16210259SAndrew.Bardsley@arm.com 16310259SAndrew.Bardsley@arm.com enum LSQRequestState 16410259SAndrew.Bardsley@arm.com { 16510259SAndrew.Bardsley@arm.com NotIssued, /* Newly created */ 16610259SAndrew.Bardsley@arm.com InTranslation, /* TLB accessed, no reply yet */ 16710259SAndrew.Bardsley@arm.com Translated, /* Finished address translation */ 16810259SAndrew.Bardsley@arm.com Failed, /* The starting start of FailedDataRequests */ 16910259SAndrew.Bardsley@arm.com RequestIssuing, /* Load/store issued to memory in the requests 17010259SAndrew.Bardsley@arm.com queue */ 17110259SAndrew.Bardsley@arm.com StoreToStoreBuffer, /* Store in transfers on its way to the 17210259SAndrew.Bardsley@arm.com store buffer */ 17310259SAndrew.Bardsley@arm.com RequestNeedsRetry, /* Retry needed for load */ 17410259SAndrew.Bardsley@arm.com StoreInStoreBuffer, /* Store in the store buffer, before issuing 17510259SAndrew.Bardsley@arm.com a memory transfer */ 17610259SAndrew.Bardsley@arm.com StoreBufferIssuing, /* Store in store buffer and has been 17710259SAndrew.Bardsley@arm.com issued */ 17810259SAndrew.Bardsley@arm.com StoreBufferNeedsRetry, /* Retry needed for store */ 17910259SAndrew.Bardsley@arm.com /* All completed states. Includes 18010259SAndrew.Bardsley@arm.com completed loads, TLB faults and skipped requests whose 18110259SAndrew.Bardsley@arm.com seqNum's no longer match */ 18210259SAndrew.Bardsley@arm.com Complete 18310259SAndrew.Bardsley@arm.com }; 18410259SAndrew.Bardsley@arm.com 18510259SAndrew.Bardsley@arm.com LSQRequestState state; 18610259SAndrew.Bardsley@arm.com 18710259SAndrew.Bardsley@arm.com protected: 18810259SAndrew.Bardsley@arm.com /** BaseTLB::Translation interface */ 18910259SAndrew.Bardsley@arm.com void markDelayed() { } 19010259SAndrew.Bardsley@arm.com 19110259SAndrew.Bardsley@arm.com public: 19210259SAndrew.Bardsley@arm.com LSQRequest(LSQ &port_, MinorDynInstPtr inst_, bool isLoad_, 19310259SAndrew.Bardsley@arm.com PacketDataPtr data_ = NULL, uint64_t *res_ = NULL); 19410259SAndrew.Bardsley@arm.com 19510259SAndrew.Bardsley@arm.com virtual ~LSQRequest(); 19610259SAndrew.Bardsley@arm.com 19710259SAndrew.Bardsley@arm.com public: 19810259SAndrew.Bardsley@arm.com /** Make a packet to use with the memory transaction */ 19910259SAndrew.Bardsley@arm.com void makePacket(); 20010259SAndrew.Bardsley@arm.com 20110259SAndrew.Bardsley@arm.com /** Was no memory access attempted for this request? */ 20210259SAndrew.Bardsley@arm.com bool skippedMemAccess() { return skipped; } 20310259SAndrew.Bardsley@arm.com 20410259SAndrew.Bardsley@arm.com /** Set this request as having been skipped before a memory 20510259SAndrew.Bardsley@arm.com * transfer was attempt */ 20610259SAndrew.Bardsley@arm.com void setSkipped() { skipped = true; } 20710259SAndrew.Bardsley@arm.com 20810259SAndrew.Bardsley@arm.com /** Does address range req1 (req1_addr to req1_addr + req1_size - 1) 20910259SAndrew.Bardsley@arm.com * fully cover, partially cover or not cover at all the range req2 */ 21010259SAndrew.Bardsley@arm.com static AddrRangeCoverage containsAddrRangeOf( 21110259SAndrew.Bardsley@arm.com Addr req1_addr, unsigned int req1_size, 21210259SAndrew.Bardsley@arm.com Addr req2_addr, unsigned int req2_size); 21310259SAndrew.Bardsley@arm.com 21410259SAndrew.Bardsley@arm.com /** Does this request's address range fully cover the range 21510259SAndrew.Bardsley@arm.com * of other_request? */ 21610259SAndrew.Bardsley@arm.com AddrRangeCoverage containsAddrRangeOf(LSQRequest *other_request); 21710259SAndrew.Bardsley@arm.com 21810259SAndrew.Bardsley@arm.com /** Start the address translation process for this request. This 21910259SAndrew.Bardsley@arm.com * will issue a translation request to the TLB. */ 22010259SAndrew.Bardsley@arm.com virtual void startAddrTranslation() = 0; 22110259SAndrew.Bardsley@arm.com 22210259SAndrew.Bardsley@arm.com /** Get the next packet to issue for this request. For split 22310259SAndrew.Bardsley@arm.com * transfers, it will be necessary to step through the available 22410259SAndrew.Bardsley@arm.com * packets by calling do { getHeadPacket ; stepToNextPacket } while 22510259SAndrew.Bardsley@arm.com * (!sentAllPackets) and by retiring response using retireResponse */ 22610259SAndrew.Bardsley@arm.com virtual PacketPtr getHeadPacket() = 0; 22710259SAndrew.Bardsley@arm.com 22810259SAndrew.Bardsley@arm.com /** Step to the next packet for the next call to getHeadPacket */ 22910259SAndrew.Bardsley@arm.com virtual void stepToNextPacket() = 0; 23010259SAndrew.Bardsley@arm.com 23110259SAndrew.Bardsley@arm.com /** Have all packets been sent? */ 23210259SAndrew.Bardsley@arm.com virtual bool sentAllPackets() = 0; 23310259SAndrew.Bardsley@arm.com 23410259SAndrew.Bardsley@arm.com /** True if this request has any issued packets in the memory 23510259SAndrew.Bardsley@arm.com * system and so can't be interrupted until it gets responses */ 23610259SAndrew.Bardsley@arm.com virtual bool hasPacketsInMemSystem() = 0; 23710259SAndrew.Bardsley@arm.com 23810259SAndrew.Bardsley@arm.com /** Retire a response packet into the LSQRequest packet possibly 23910259SAndrew.Bardsley@arm.com * completing this transfer */ 24010259SAndrew.Bardsley@arm.com virtual void retireResponse(PacketPtr packet_) = 0; 24110259SAndrew.Bardsley@arm.com 24210259SAndrew.Bardsley@arm.com /** Is this a request a barrier? */ 24310259SAndrew.Bardsley@arm.com virtual bool isBarrier(); 24410259SAndrew.Bardsley@arm.com 24510259SAndrew.Bardsley@arm.com /** This request, once processed by the requests/transfers 24610259SAndrew.Bardsley@arm.com * queues, will need to go to the store buffer */ 24710259SAndrew.Bardsley@arm.com bool needsToBeSentToStoreBuffer(); 24810259SAndrew.Bardsley@arm.com 24910259SAndrew.Bardsley@arm.com /** Set state and output trace output */ 25010259SAndrew.Bardsley@arm.com void setState(LSQRequestState new_state); 25110259SAndrew.Bardsley@arm.com 25210259SAndrew.Bardsley@arm.com /** Has this request been completed. This includes *all* reasons 25310259SAndrew.Bardsley@arm.com * for completion: successful transfers, faults, skipped because 25410259SAndrew.Bardsley@arm.com * of preceding faults */ 25510259SAndrew.Bardsley@arm.com bool isComplete() const; 25610259SAndrew.Bardsley@arm.com 25710259SAndrew.Bardsley@arm.com /** MinorTrace report interface */ 25810259SAndrew.Bardsley@arm.com void reportData(std::ostream &os) const; 25910259SAndrew.Bardsley@arm.com }; 26010259SAndrew.Bardsley@arm.com 26110259SAndrew.Bardsley@arm.com typedef LSQRequest *LSQRequestPtr; 26210259SAndrew.Bardsley@arm.com 26310259SAndrew.Bardsley@arm.com friend std::ostream & operator <<(std::ostream &os, 26410259SAndrew.Bardsley@arm.com AddrRangeCoverage state); 26510259SAndrew.Bardsley@arm.com 26610259SAndrew.Bardsley@arm.com friend std::ostream & operator <<(std::ostream &os, 26710259SAndrew.Bardsley@arm.com LSQRequest::LSQRequestState state); 26810259SAndrew.Bardsley@arm.com 26910259SAndrew.Bardsley@arm.com protected: 27010259SAndrew.Bardsley@arm.com /** Special request types that don't actually issue memory requests */ 27110259SAndrew.Bardsley@arm.com class SpecialDataRequest : public LSQRequest 27210259SAndrew.Bardsley@arm.com { 27310259SAndrew.Bardsley@arm.com protected: 27410259SAndrew.Bardsley@arm.com /** TLB interace */ 27510379Sandreas.hansson@arm.com void finish(const Fault &fault_, RequestPtr request_, 27610379Sandreas.hansson@arm.com ThreadContext *tc, BaseTLB::Mode mode) 27710259SAndrew.Bardsley@arm.com { } 27810259SAndrew.Bardsley@arm.com 27910259SAndrew.Bardsley@arm.com public: 28010259SAndrew.Bardsley@arm.com /** Send single translation request */ 28110259SAndrew.Bardsley@arm.com void startAddrTranslation() { } 28210259SAndrew.Bardsley@arm.com 28310259SAndrew.Bardsley@arm.com /** Get the head packet as counted by numIssuedFragments */ 28410259SAndrew.Bardsley@arm.com PacketPtr getHeadPacket() 28510259SAndrew.Bardsley@arm.com { fatal("No packets in a SpecialDataRequest"); } 28610259SAndrew.Bardsley@arm.com 28710259SAndrew.Bardsley@arm.com /** Step on numIssuedFragments */ 28810259SAndrew.Bardsley@arm.com void stepToNextPacket() { } 28910259SAndrew.Bardsley@arm.com 29010259SAndrew.Bardsley@arm.com /** Has no packets to send */ 29110259SAndrew.Bardsley@arm.com bool sentAllPackets() { return true; } 29210259SAndrew.Bardsley@arm.com 29310259SAndrew.Bardsley@arm.com /** Never sends any requests */ 29410259SAndrew.Bardsley@arm.com bool hasPacketsInMemSystem() { return false; } 29510259SAndrew.Bardsley@arm.com 29610259SAndrew.Bardsley@arm.com /** Keep the given packet as the response packet 29710259SAndrew.Bardsley@arm.com * LSQRequest::packet */ 29810259SAndrew.Bardsley@arm.com void retireResponse(PacketPtr packet_) { } 29910259SAndrew.Bardsley@arm.com 30010259SAndrew.Bardsley@arm.com public: 30110259SAndrew.Bardsley@arm.com SpecialDataRequest(LSQ &port_, MinorDynInstPtr inst_) : 30210259SAndrew.Bardsley@arm.com /* Say this is a load, not actually relevant */ 30310259SAndrew.Bardsley@arm.com LSQRequest(port_, inst_, true, NULL, 0) 30410259SAndrew.Bardsley@arm.com { } 30510259SAndrew.Bardsley@arm.com }; 30610259SAndrew.Bardsley@arm.com 30710259SAndrew.Bardsley@arm.com /** FailedDataRequest represents requests from instructions that 30810259SAndrew.Bardsley@arm.com * failed their predicates but need to ride the requests/transfers 30910259SAndrew.Bardsley@arm.com * queues to maintain trace ordering */ 31010259SAndrew.Bardsley@arm.com class FailedDataRequest : public SpecialDataRequest 31110259SAndrew.Bardsley@arm.com { 31210259SAndrew.Bardsley@arm.com public: 31310259SAndrew.Bardsley@arm.com FailedDataRequest(LSQ &port_, MinorDynInstPtr inst_) : 31410259SAndrew.Bardsley@arm.com SpecialDataRequest(port_, inst_) 31510259SAndrew.Bardsley@arm.com { state = Failed; } 31610259SAndrew.Bardsley@arm.com }; 31710259SAndrew.Bardsley@arm.com 31810259SAndrew.Bardsley@arm.com /** Request for doing barrier accounting in the store buffer. Not 31910259SAndrew.Bardsley@arm.com * for use outside that unit */ 32010259SAndrew.Bardsley@arm.com class BarrierDataRequest : public SpecialDataRequest 32110259SAndrew.Bardsley@arm.com { 32210259SAndrew.Bardsley@arm.com public: 32310259SAndrew.Bardsley@arm.com bool isBarrier() { return true; } 32410259SAndrew.Bardsley@arm.com 32510259SAndrew.Bardsley@arm.com public: 32610259SAndrew.Bardsley@arm.com BarrierDataRequest(LSQ &port_, MinorDynInstPtr inst_) : 32710259SAndrew.Bardsley@arm.com SpecialDataRequest(port_, inst_) 32810259SAndrew.Bardsley@arm.com { state = Complete; } 32910259SAndrew.Bardsley@arm.com }; 33010259SAndrew.Bardsley@arm.com 33110259SAndrew.Bardsley@arm.com /** SingleDataRequest is used for requests that don't fragment */ 33210259SAndrew.Bardsley@arm.com class SingleDataRequest : public LSQRequest 33310259SAndrew.Bardsley@arm.com { 33410259SAndrew.Bardsley@arm.com protected: 33510259SAndrew.Bardsley@arm.com /** TLB interace */ 33610379Sandreas.hansson@arm.com void finish(const Fault &fault_, RequestPtr request_, 33710379Sandreas.hansson@arm.com ThreadContext *tc, BaseTLB::Mode mode); 33810259SAndrew.Bardsley@arm.com 33910259SAndrew.Bardsley@arm.com /** Has my only packet been sent to the memory system but has not 34010259SAndrew.Bardsley@arm.com * yet been responded to */ 34110259SAndrew.Bardsley@arm.com bool packetInFlight; 34210259SAndrew.Bardsley@arm.com 34310259SAndrew.Bardsley@arm.com /** Has the packet been at least sent to the memory system? */ 34410259SAndrew.Bardsley@arm.com bool packetSent; 34510259SAndrew.Bardsley@arm.com 34610259SAndrew.Bardsley@arm.com public: 34710259SAndrew.Bardsley@arm.com /** Send single translation request */ 34810259SAndrew.Bardsley@arm.com void startAddrTranslation(); 34910259SAndrew.Bardsley@arm.com 35010259SAndrew.Bardsley@arm.com /** Get the head packet as counted by numIssuedFragments */ 35110259SAndrew.Bardsley@arm.com PacketPtr getHeadPacket() { return packet; } 35210259SAndrew.Bardsley@arm.com 35310259SAndrew.Bardsley@arm.com /** Remember that the packet has been sent */ 35410259SAndrew.Bardsley@arm.com void stepToNextPacket() { packetInFlight = true; packetSent = true; } 35510259SAndrew.Bardsley@arm.com 35610259SAndrew.Bardsley@arm.com /** Has packet been sent */ 35710259SAndrew.Bardsley@arm.com bool hasPacketsInMemSystem() { return packetInFlight; } 35810259SAndrew.Bardsley@arm.com 35910259SAndrew.Bardsley@arm.com /** packetInFlight can become false again, so need to check 36010259SAndrew.Bardsley@arm.com * packetSent */ 36110259SAndrew.Bardsley@arm.com bool sentAllPackets() { return packetSent; } 36210259SAndrew.Bardsley@arm.com 36310259SAndrew.Bardsley@arm.com /** Keep the given packet as the response packet 36410259SAndrew.Bardsley@arm.com * LSQRequest::packet */ 36510259SAndrew.Bardsley@arm.com void retireResponse(PacketPtr packet_); 36610259SAndrew.Bardsley@arm.com 36710259SAndrew.Bardsley@arm.com public: 36810259SAndrew.Bardsley@arm.com SingleDataRequest(LSQ &port_, MinorDynInstPtr inst_, 36910259SAndrew.Bardsley@arm.com bool isLoad_, PacketDataPtr data_ = NULL, uint64_t *res_ = NULL) : 37010259SAndrew.Bardsley@arm.com LSQRequest(port_, inst_, isLoad_, data_, res_), 37110259SAndrew.Bardsley@arm.com packetInFlight(false), 37210259SAndrew.Bardsley@arm.com packetSent(false) 37310259SAndrew.Bardsley@arm.com { } 37410259SAndrew.Bardsley@arm.com }; 37510259SAndrew.Bardsley@arm.com 37610259SAndrew.Bardsley@arm.com class SplitDataRequest : public LSQRequest 37710259SAndrew.Bardsley@arm.com { 37810259SAndrew.Bardsley@arm.com protected: 37910259SAndrew.Bardsley@arm.com /** Event to step between translations */ 38010259SAndrew.Bardsley@arm.com class TranslationEvent : public Event 38110259SAndrew.Bardsley@arm.com { 38210259SAndrew.Bardsley@arm.com protected: 38310259SAndrew.Bardsley@arm.com SplitDataRequest &owner; 38410259SAndrew.Bardsley@arm.com 38510259SAndrew.Bardsley@arm.com public: 38610259SAndrew.Bardsley@arm.com TranslationEvent(SplitDataRequest &owner_) 38710259SAndrew.Bardsley@arm.com : owner(owner_) { } 38810259SAndrew.Bardsley@arm.com 38910259SAndrew.Bardsley@arm.com void process() 39010259SAndrew.Bardsley@arm.com { owner.sendNextFragmentToTranslation(); } 39110259SAndrew.Bardsley@arm.com }; 39210259SAndrew.Bardsley@arm.com 39310259SAndrew.Bardsley@arm.com TranslationEvent translationEvent; 39410259SAndrew.Bardsley@arm.com protected: 39510259SAndrew.Bardsley@arm.com /** Number of fragments this request is split into */ 39610259SAndrew.Bardsley@arm.com unsigned int numFragments; 39710259SAndrew.Bardsley@arm.com 39810259SAndrew.Bardsley@arm.com /** Number of fragments in the address translation mechanism */ 39910259SAndrew.Bardsley@arm.com unsigned int numInTranslationFragments; 40010259SAndrew.Bardsley@arm.com 40110259SAndrew.Bardsley@arm.com /** Number of fragments that have completed address translation, 40210259SAndrew.Bardsley@arm.com * (numTranslatedFragments + numInTranslationFragments) <= 40310259SAndrew.Bardsley@arm.com * numFragments. When numTranslatedFramgents == numFragments, 40410259SAndrew.Bardsley@arm.com * translation is complete */ 40510259SAndrew.Bardsley@arm.com unsigned int numTranslatedFragments; 40610259SAndrew.Bardsley@arm.com 40710259SAndrew.Bardsley@arm.com /** Number of fragments already issued (<= numFragments) */ 40810259SAndrew.Bardsley@arm.com unsigned int numIssuedFragments; 40910259SAndrew.Bardsley@arm.com 41010259SAndrew.Bardsley@arm.com /** Number of fragments retired back to this request */ 41110259SAndrew.Bardsley@arm.com unsigned int numRetiredFragments; 41210259SAndrew.Bardsley@arm.com 41310259SAndrew.Bardsley@arm.com /** Fragment Requests corresponding to the address ranges of 41410259SAndrew.Bardsley@arm.com * each fragment */ 41510259SAndrew.Bardsley@arm.com std::vector<Request *> fragmentRequests; 41610259SAndrew.Bardsley@arm.com 41710259SAndrew.Bardsley@arm.com /** Packets matching fragmentRequests to issue fragments to memory */ 41810259SAndrew.Bardsley@arm.com std::vector<Packet *> fragmentPackets; 41910259SAndrew.Bardsley@arm.com 42010259SAndrew.Bardsley@arm.com protected: 42110259SAndrew.Bardsley@arm.com /** TLB response interface */ 42210379Sandreas.hansson@arm.com void finish(const Fault &fault_, RequestPtr request_, 42310379Sandreas.hansson@arm.com ThreadContext *tc, BaseTLB::Mode mode); 42410259SAndrew.Bardsley@arm.com 42510259SAndrew.Bardsley@arm.com public: 42610259SAndrew.Bardsley@arm.com SplitDataRequest(LSQ &port_, MinorDynInstPtr inst_, 42710259SAndrew.Bardsley@arm.com bool isLoad_, PacketDataPtr data_ = NULL, 42810259SAndrew.Bardsley@arm.com uint64_t *res_ = NULL); 42910259SAndrew.Bardsley@arm.com 43010259SAndrew.Bardsley@arm.com ~SplitDataRequest(); 43110259SAndrew.Bardsley@arm.com 43210259SAndrew.Bardsley@arm.com public: 43310259SAndrew.Bardsley@arm.com /** Make all the Requests for this transfer's fragments so that those 43410259SAndrew.Bardsley@arm.com * requests can be sent for address translation */ 43510259SAndrew.Bardsley@arm.com void makeFragmentRequests(); 43610259SAndrew.Bardsley@arm.com 43710259SAndrew.Bardsley@arm.com /** Make the packets to go with the requests so they can be sent to 43810259SAndrew.Bardsley@arm.com * the memory system */ 43910259SAndrew.Bardsley@arm.com void makeFragmentPackets(); 44010259SAndrew.Bardsley@arm.com 44110259SAndrew.Bardsley@arm.com /** Start a loop of do { sendNextFragmentToTranslation ; 44210259SAndrew.Bardsley@arm.com * translateTiming ; finish } while (numTranslatedFragments != 44310259SAndrew.Bardsley@arm.com * numFragments) to complete all this requests' fragments' address 44410259SAndrew.Bardsley@arm.com * translations */ 44510259SAndrew.Bardsley@arm.com void startAddrTranslation(); 44610259SAndrew.Bardsley@arm.com 44710259SAndrew.Bardsley@arm.com /** Get the head packet as counted by numIssuedFragments */ 44810259SAndrew.Bardsley@arm.com PacketPtr getHeadPacket(); 44910259SAndrew.Bardsley@arm.com 45010259SAndrew.Bardsley@arm.com /** Step on numIssuedFragments */ 45110259SAndrew.Bardsley@arm.com void stepToNextPacket(); 45210259SAndrew.Bardsley@arm.com 45310259SAndrew.Bardsley@arm.com bool hasPacketsInMemSystem() 45410259SAndrew.Bardsley@arm.com { return numIssuedFragments != numRetiredFragments; } 45510259SAndrew.Bardsley@arm.com 45610259SAndrew.Bardsley@arm.com /** Have we stepped past the end of fragmentPackets? */ 45710259SAndrew.Bardsley@arm.com bool sentAllPackets() { return numIssuedFragments == numFragments; } 45810259SAndrew.Bardsley@arm.com 45910259SAndrew.Bardsley@arm.com /** For loads, paste the response data into the main 46010259SAndrew.Bardsley@arm.com * response packet */ 46110259SAndrew.Bardsley@arm.com void retireResponse(PacketPtr packet_); 46210259SAndrew.Bardsley@arm.com 46310259SAndrew.Bardsley@arm.com /** Part of the address translation loop, see startAddTranslation */ 46410259SAndrew.Bardsley@arm.com void sendNextFragmentToTranslation(); 46510259SAndrew.Bardsley@arm.com }; 46610259SAndrew.Bardsley@arm.com 46710259SAndrew.Bardsley@arm.com /** Store buffer. This contains stores which have been committed 46810259SAndrew.Bardsley@arm.com * but whose memory transfers have not yet been issued. Load data 46910259SAndrew.Bardsley@arm.com * can be forwarded out of the store buffer */ 47010259SAndrew.Bardsley@arm.com class StoreBuffer : public Named 47110259SAndrew.Bardsley@arm.com { 47210259SAndrew.Bardsley@arm.com public: 47310259SAndrew.Bardsley@arm.com /** My owner */ 47410259SAndrew.Bardsley@arm.com LSQ &lsq; 47510259SAndrew.Bardsley@arm.com 47610259SAndrew.Bardsley@arm.com /** Number of slots, this is a bound on the size of slots */ 47710259SAndrew.Bardsley@arm.com const unsigned int numSlots; 47810259SAndrew.Bardsley@arm.com 47910259SAndrew.Bardsley@arm.com /** Maximum number of stores that can be issued per cycle */ 48010259SAndrew.Bardsley@arm.com const unsigned int storeLimitPerCycle; 48110259SAndrew.Bardsley@arm.com 48210259SAndrew.Bardsley@arm.com public: 48310259SAndrew.Bardsley@arm.com /** Queue of store requests on their way to memory */ 48410259SAndrew.Bardsley@arm.com std::deque<LSQRequestPtr> slots; 48510259SAndrew.Bardsley@arm.com 48610259SAndrew.Bardsley@arm.com /** Number of occupied slots which have not yet issued a 48710259SAndrew.Bardsley@arm.com * memory access */ 48810259SAndrew.Bardsley@arm.com unsigned int numUnissuedAccesses; 48910259SAndrew.Bardsley@arm.com 49010259SAndrew.Bardsley@arm.com public: 49110259SAndrew.Bardsley@arm.com StoreBuffer(std::string name_, LSQ &lsq_, 49210259SAndrew.Bardsley@arm.com unsigned int store_buffer_size, 49310259SAndrew.Bardsley@arm.com unsigned int store_limit_per_cycle); 49410259SAndrew.Bardsley@arm.com 49510259SAndrew.Bardsley@arm.com public: 49610259SAndrew.Bardsley@arm.com /** Can a new request be inserted into the queue? */ 49710259SAndrew.Bardsley@arm.com bool canInsert() const; 49810259SAndrew.Bardsley@arm.com 49910259SAndrew.Bardsley@arm.com /** Delete the given request and free the slot it occupied */ 50010259SAndrew.Bardsley@arm.com void deleteRequest(LSQRequestPtr request); 50110259SAndrew.Bardsley@arm.com 50210259SAndrew.Bardsley@arm.com /** Insert a request at the back of the queue */ 50310259SAndrew.Bardsley@arm.com void insert(LSQRequestPtr request); 50410259SAndrew.Bardsley@arm.com 50510259SAndrew.Bardsley@arm.com /** Look for a store which satisfies the given load. Returns an 50610259SAndrew.Bardsley@arm.com * indication whether the forwarding request can be wholly, 50710259SAndrew.Bardsley@arm.com * partly or not all all satisfied. If the request can be 50810259SAndrew.Bardsley@arm.com * wholly satisfied, the store buffer slot number which can be used 50910259SAndrew.Bardsley@arm.com * is returned in found_slot */ 51010259SAndrew.Bardsley@arm.com AddrRangeCoverage canForwardDataToLoad(LSQRequestPtr request, 51110259SAndrew.Bardsley@arm.com unsigned int &found_slot); 51210259SAndrew.Bardsley@arm.com 51310259SAndrew.Bardsley@arm.com /** Fill the given packet with appropriate date from slot 51410259SAndrew.Bardsley@arm.com * slot_number */ 51510259SAndrew.Bardsley@arm.com void forwardStoreData(LSQRequestPtr load, unsigned int slot_number); 51610259SAndrew.Bardsley@arm.com 51710259SAndrew.Bardsley@arm.com /** Number of stores in the store buffer which have not been 51810259SAndrew.Bardsley@arm.com * completely issued to the memory system */ 51910259SAndrew.Bardsley@arm.com unsigned int numUnissuedStores() { return numUnissuedAccesses; } 52010259SAndrew.Bardsley@arm.com 52110581SAndrew.Bardsley@arm.com /** Count a store being issued to memory by decrementing 52210581SAndrew.Bardsley@arm.com * numUnissuedAccesses. Does not count barrier requests as they 52310581SAndrew.Bardsley@arm.com * will be handles as barriers are cleared from the buffer */ 52410581SAndrew.Bardsley@arm.com void countIssuedStore(LSQRequestPtr request); 52510581SAndrew.Bardsley@arm.com 52610259SAndrew.Bardsley@arm.com /** Drained if there is absolutely nothing left in the buffer */ 52710259SAndrew.Bardsley@arm.com bool isDrained() const { return slots.empty(); } 52810259SAndrew.Bardsley@arm.com 52910259SAndrew.Bardsley@arm.com /** Try to issue more stores to memory */ 53010259SAndrew.Bardsley@arm.com void step(); 53110259SAndrew.Bardsley@arm.com 53210259SAndrew.Bardsley@arm.com /** Report queue contents for MinorTrace */ 53310259SAndrew.Bardsley@arm.com void minorTrace() const; 53410259SAndrew.Bardsley@arm.com }; 53510259SAndrew.Bardsley@arm.com 53610259SAndrew.Bardsley@arm.com protected: 53710259SAndrew.Bardsley@arm.com /** Most recent execSeqNum of a memory barrier instruction or 53810259SAndrew.Bardsley@arm.com * 0 if there are no in-flight barriers. Useful as a 53910259SAndrew.Bardsley@arm.com * dependency for early-issued memory operations */ 54011567Smitch.hayenga@arm.com std::vector<InstSeqNum> lastMemBarrier; 54110259SAndrew.Bardsley@arm.com 54210259SAndrew.Bardsley@arm.com public: 54310259SAndrew.Bardsley@arm.com /** Retry state of last issued memory transfer */ 54410259SAndrew.Bardsley@arm.com MemoryState state; 54510259SAndrew.Bardsley@arm.com 54610259SAndrew.Bardsley@arm.com /** Maximum number of in-flight accesses issued to the memory system */ 54710259SAndrew.Bardsley@arm.com const unsigned int inMemorySystemLimit; 54810259SAndrew.Bardsley@arm.com 54910259SAndrew.Bardsley@arm.com /** Memory system access width (and snap) in bytes */ 55010259SAndrew.Bardsley@arm.com const unsigned int lineWidth; 55110259SAndrew.Bardsley@arm.com 55210259SAndrew.Bardsley@arm.com public: 55310259SAndrew.Bardsley@arm.com /** The LSQ consists of three queues: requests, transfers and the 55410259SAndrew.Bardsley@arm.com * store buffer storeBuffer. */ 55510259SAndrew.Bardsley@arm.com 55610259SAndrew.Bardsley@arm.com typedef Queue<LSQRequestPtr, 55710259SAndrew.Bardsley@arm.com ReportTraitsPtrAdaptor<LSQRequestPtr>, 55810259SAndrew.Bardsley@arm.com NoBubbleTraits<LSQRequestPtr> > 55910259SAndrew.Bardsley@arm.com LSQQueue; 56010259SAndrew.Bardsley@arm.com 56110259SAndrew.Bardsley@arm.com /** requests contains LSQRequests which have been issued to the TLB by 56210259SAndrew.Bardsley@arm.com * calling ExecContext::readMem/writeMem (which in turn calls 56310259SAndrew.Bardsley@arm.com * LSQ::pushRequest and LSQRequest::startAddrTranslation). Once they 56410259SAndrew.Bardsley@arm.com * have a physical address, requests at the head of requests can be 56510259SAndrew.Bardsley@arm.com * issued to the memory system. At this stage, it cannot be clear that 56610259SAndrew.Bardsley@arm.com * memory accesses *must* happen (that there are no preceding faults or 56710259SAndrew.Bardsley@arm.com * changes of flow of control) and so only cacheable reads are issued 56810259SAndrew.Bardsley@arm.com * to memory. 56910259SAndrew.Bardsley@arm.com * Cacheable stores are not issued at all (and just pass through 57010259SAndrew.Bardsley@arm.com * 'transfers' in order) and all other transfers are stalled in requests 57110259SAndrew.Bardsley@arm.com * until their corresponding instructions are at the head of the 57210259SAndrew.Bardsley@arm.com * inMemInsts instruction queue and have the right streamSeqNum. */ 57310259SAndrew.Bardsley@arm.com LSQQueue requests; 57410259SAndrew.Bardsley@arm.com 57510259SAndrew.Bardsley@arm.com /** Once issued to memory (or, for stores, just had their 57610259SAndrew.Bardsley@arm.com * state changed to StoreToStoreBuffer) LSQRequests pass through 57710259SAndrew.Bardsley@arm.com * transfers waiting for memory responses. At the head of transfers, 57810259SAndrew.Bardsley@arm.com * Execute::commitInst can pick up the memory response for a request 57910259SAndrew.Bardsley@arm.com * using LSQ::findResponse. Responses to be committed can then 58010259SAndrew.Bardsley@arm.com * have ExecContext::completeAcc on them. Stores can then be pushed 58110259SAndrew.Bardsley@arm.com * into the store buffer. All other transfers will then be complete. */ 58210259SAndrew.Bardsley@arm.com LSQQueue transfers; 58310259SAndrew.Bardsley@arm.com 58410259SAndrew.Bardsley@arm.com /* The store buffer contains committed cacheable stores on 58510259SAndrew.Bardsley@arm.com * their way to memory decoupled from subsequence instruction execution. 58610259SAndrew.Bardsley@arm.com * Before trying to issue a cacheable read from 'requests' to memory, 58710259SAndrew.Bardsley@arm.com * the store buffer is checked to see if a previous store contains the 58810259SAndrew.Bardsley@arm.com * needed data (StoreBuffer::canForwardDataToLoad) which can be 58910259SAndrew.Bardsley@arm.com * forwarded in lieu of a memory access. If there are outstanding 59010259SAndrew.Bardsley@arm.com * stores in the transfers queue, they must be promoted to the store 59110259SAndrew.Bardsley@arm.com * buffer (and so be commited) before they can be correctly checked 59210259SAndrew.Bardsley@arm.com * for forwarding. */ 59310259SAndrew.Bardsley@arm.com StoreBuffer storeBuffer; 59410259SAndrew.Bardsley@arm.com 59510259SAndrew.Bardsley@arm.com protected: 59610259SAndrew.Bardsley@arm.com /** Count of the number of mem. accesses which have left the 59710368SAndrew.Bardsley@arm.com * requests queue and are in the 'wild' in the memory system and who 59810368SAndrew.Bardsley@arm.com * *must not* be interrupted as they are not normal cacheable 59910368SAndrew.Bardsley@arm.com * accesses. This is a count of the number of in-flight requests 60010368SAndrew.Bardsley@arm.com * with issuedToMemory set who have visited tryToSendRequest at least 60110368SAndrew.Bardsley@arm.com * once */ 60210259SAndrew.Bardsley@arm.com unsigned int numAccessesInMemorySystem; 60310259SAndrew.Bardsley@arm.com 60410259SAndrew.Bardsley@arm.com /** Number of requests in the DTLB in the requests queue */ 60510259SAndrew.Bardsley@arm.com unsigned int numAccessesInDTLB; 60610259SAndrew.Bardsley@arm.com 60710259SAndrew.Bardsley@arm.com /** The number of stores in the transfers queue. Useful when 60810259SAndrew.Bardsley@arm.com * testing if the store buffer contains all the forwardable stores */ 60910259SAndrew.Bardsley@arm.com unsigned int numStoresInTransfers; 61010259SAndrew.Bardsley@arm.com 61110259SAndrew.Bardsley@arm.com /** The number of accesses which have been issued to the memory 61210259SAndrew.Bardsley@arm.com * system but have not been committed/discarded *excluding* 61310259SAndrew.Bardsley@arm.com * cacheable normal loads which don't need to be tracked */ 61410259SAndrew.Bardsley@arm.com unsigned int numAccessesIssuedToMemory; 61510259SAndrew.Bardsley@arm.com 61610259SAndrew.Bardsley@arm.com /** The request (from either requests or the store buffer) which is 61710259SAndrew.Bardsley@arm.com * currently waiting have its memory access retried */ 61810259SAndrew.Bardsley@arm.com LSQRequestPtr retryRequest; 61910259SAndrew.Bardsley@arm.com 62010259SAndrew.Bardsley@arm.com /** Address Mask for a cache block (e.g. ~(cache_block_size-1)) */ 62110259SAndrew.Bardsley@arm.com Addr cacheBlockMask; 62210259SAndrew.Bardsley@arm.com 62310259SAndrew.Bardsley@arm.com protected: 62410259SAndrew.Bardsley@arm.com /** Try and issue a memory access for a translated request at the 62510259SAndrew.Bardsley@arm.com * head of the requests queue. Also tries to move the request 62610259SAndrew.Bardsley@arm.com * between queues */ 62710259SAndrew.Bardsley@arm.com void tryToSendToTransfers(LSQRequestPtr request); 62810259SAndrew.Bardsley@arm.com 62910259SAndrew.Bardsley@arm.com /** Try to send (or resend) a memory request's next/only packet to 63010259SAndrew.Bardsley@arm.com * the memory system. Returns true if the request was successfully 63110259SAndrew.Bardsley@arm.com * sent to memory (and was also the last packet in a transfer) */ 63210259SAndrew.Bardsley@arm.com bool tryToSend(LSQRequestPtr request); 63310259SAndrew.Bardsley@arm.com 63410259SAndrew.Bardsley@arm.com /** Clear a barrier (if it's the last one marked up in lastMemBarrier) */ 63510259SAndrew.Bardsley@arm.com void clearMemBarrier(MinorDynInstPtr inst); 63610259SAndrew.Bardsley@arm.com 63710259SAndrew.Bardsley@arm.com /** Move a request between queues */ 63810259SAndrew.Bardsley@arm.com void moveFromRequestsToTransfers(LSQRequestPtr request); 63910259SAndrew.Bardsley@arm.com 64010259SAndrew.Bardsley@arm.com /** Can a request be sent to the memory system */ 64110259SAndrew.Bardsley@arm.com bool canSendToMemorySystem(); 64210259SAndrew.Bardsley@arm.com 64311567Smitch.hayenga@arm.com /** Snoop other threads monitors on memory system accesses */ 64411567Smitch.hayenga@arm.com void threadSnoop(LSQRequestPtr request); 64511567Smitch.hayenga@arm.com 64610259SAndrew.Bardsley@arm.com public: 64710259SAndrew.Bardsley@arm.com LSQ(std::string name_, std::string dcache_port_name_, 64810259SAndrew.Bardsley@arm.com MinorCPU &cpu_, Execute &execute_, 64910259SAndrew.Bardsley@arm.com unsigned int max_accesses_in_memory_system, unsigned int line_width, 65010259SAndrew.Bardsley@arm.com unsigned int requests_queue_size, unsigned int transfers_queue_size, 65110259SAndrew.Bardsley@arm.com unsigned int store_buffer_size, 65210259SAndrew.Bardsley@arm.com unsigned int store_buffer_cycle_store_limit); 65310259SAndrew.Bardsley@arm.com 65410259SAndrew.Bardsley@arm.com virtual ~LSQ(); 65510259SAndrew.Bardsley@arm.com 65610259SAndrew.Bardsley@arm.com public: 65710259SAndrew.Bardsley@arm.com /** Step checks the queues to see if their are issuable transfers 65810259SAndrew.Bardsley@arm.com * which were not otherwise picked up by tests at the end of other 65910259SAndrew.Bardsley@arm.com * events. 66010259SAndrew.Bardsley@arm.com * 66110259SAndrew.Bardsley@arm.com * Steppable actions include deferred actions which couldn't be 66210259SAndrew.Bardsley@arm.com * cascaded on the end of a memory response/TLB response event 66310259SAndrew.Bardsley@arm.com * because of resource congestion. */ 66410259SAndrew.Bardsley@arm.com void step(); 66510259SAndrew.Bardsley@arm.com 66610259SAndrew.Bardsley@arm.com /** Is their space in the request queue to be able to push a request by 66710259SAndrew.Bardsley@arm.com * issuing an isMemRef instruction */ 66810259SAndrew.Bardsley@arm.com bool canRequest() { return requests.unreservedRemainingSpace() != 0; } 66910259SAndrew.Bardsley@arm.com 67010259SAndrew.Bardsley@arm.com /** Returns a response if it's at the head of the transfers queue and 67110259SAndrew.Bardsley@arm.com * it's either complete or can be sent on to the store buffer. After 67210259SAndrew.Bardsley@arm.com * calling, the request still remains on the transfer queue until 67310259SAndrew.Bardsley@arm.com * popResponse is called */ 67410259SAndrew.Bardsley@arm.com LSQRequestPtr findResponse(MinorDynInstPtr inst); 67510259SAndrew.Bardsley@arm.com 67610259SAndrew.Bardsley@arm.com /** Sanity check and pop the head response */ 67710259SAndrew.Bardsley@arm.com void popResponse(LSQRequestPtr response); 67810259SAndrew.Bardsley@arm.com 67910259SAndrew.Bardsley@arm.com /** Must check this before trying to insert into the store buffer */ 68010259SAndrew.Bardsley@arm.com bool canPushIntoStoreBuffer() const { return storeBuffer.canInsert(); } 68110259SAndrew.Bardsley@arm.com 68210259SAndrew.Bardsley@arm.com /** A store has been committed, please move it to the store buffer */ 68310259SAndrew.Bardsley@arm.com void sendStoreToStoreBuffer(LSQRequestPtr request); 68410259SAndrew.Bardsley@arm.com 68510259SAndrew.Bardsley@arm.com /** Are there any accesses other than normal cached loads in the 68610259SAndrew.Bardsley@arm.com * memory system or having received responses which need to be 68710259SAndrew.Bardsley@arm.com * handled for their instruction's to be completed */ 68810259SAndrew.Bardsley@arm.com bool accessesInFlight() const 68910259SAndrew.Bardsley@arm.com { return numAccessesIssuedToMemory != 0; } 69010259SAndrew.Bardsley@arm.com 69110259SAndrew.Bardsley@arm.com /** A memory barrier instruction has been issued, remember its 69210259SAndrew.Bardsley@arm.com * execSeqNum that we can avoid issuing memory ops until it is 69310259SAndrew.Bardsley@arm.com * committed */ 69410259SAndrew.Bardsley@arm.com void issuedMemBarrierInst(MinorDynInstPtr inst); 69510259SAndrew.Bardsley@arm.com 69610259SAndrew.Bardsley@arm.com /** Get the execSeqNum of the last issued memory barrier */ 69711567Smitch.hayenga@arm.com InstSeqNum getLastMemBarrier(ThreadID thread_id) const 69811567Smitch.hayenga@arm.com { return lastMemBarrier[thread_id]; } 69910259SAndrew.Bardsley@arm.com 70010259SAndrew.Bardsley@arm.com /** Is there nothing left in the LSQ */ 70110259SAndrew.Bardsley@arm.com bool isDrained(); 70210259SAndrew.Bardsley@arm.com 70310259SAndrew.Bardsley@arm.com /** May need to be ticked next cycle as one of the queues contains 70410259SAndrew.Bardsley@arm.com * an actionable transfers or address translation */ 70510259SAndrew.Bardsley@arm.com bool needsToTick(); 70610259SAndrew.Bardsley@arm.com 70710259SAndrew.Bardsley@arm.com /** Complete a barrier instruction. Where committed, makes a 70810259SAndrew.Bardsley@arm.com * BarrierDataRequest and pushed it into the store buffer */ 70910259SAndrew.Bardsley@arm.com void completeMemBarrierInst(MinorDynInstPtr inst, 71010259SAndrew.Bardsley@arm.com bool committed); 71110259SAndrew.Bardsley@arm.com 71210259SAndrew.Bardsley@arm.com /** Single interface for readMem/writeMem to issue requests into 71310259SAndrew.Bardsley@arm.com * the LSQ */ 71410259SAndrew.Bardsley@arm.com void pushRequest(MinorDynInstPtr inst, bool isLoad, uint8_t *data, 71511608Snikos.nikoleris@arm.com unsigned int size, Addr addr, Request::Flags flags, 71611608Snikos.nikoleris@arm.com uint64_t *res); 71710259SAndrew.Bardsley@arm.com 71810259SAndrew.Bardsley@arm.com /** Push a predicate failed-representing request into the queues just 71910259SAndrew.Bardsley@arm.com * to maintain commit order */ 72010259SAndrew.Bardsley@arm.com void pushFailedRequest(MinorDynInstPtr inst); 72110259SAndrew.Bardsley@arm.com 72210259SAndrew.Bardsley@arm.com /** Memory interface */ 72310259SAndrew.Bardsley@arm.com bool recvTimingResp(PacketPtr pkt); 72410713Sandreas.hansson@arm.com void recvReqRetry(); 72510259SAndrew.Bardsley@arm.com void recvTimingSnoopReq(PacketPtr pkt); 72610259SAndrew.Bardsley@arm.com 72710259SAndrew.Bardsley@arm.com /** Return the raw-bindable port */ 72810259SAndrew.Bardsley@arm.com MinorCPU::MinorCPUPort &getDcachePort() { return dcachePort; } 72910259SAndrew.Bardsley@arm.com 73010259SAndrew.Bardsley@arm.com void minorTrace() const; 73110259SAndrew.Bardsley@arm.com}; 73210259SAndrew.Bardsley@arm.com 73310259SAndrew.Bardsley@arm.com/** Make a suitable packet for the given request. If the request is a store, 73410259SAndrew.Bardsley@arm.com * data will be the payload data. If sender_state is NULL, it won't be 73510259SAndrew.Bardsley@arm.com * pushed into the packet as senderState */ 73610259SAndrew.Bardsley@arm.comPacketPtr makePacketForRequest(Request &request, bool isLoad, 73710259SAndrew.Bardsley@arm.com Packet::SenderState *sender_state = NULL, PacketDataPtr data = NULL); 73810259SAndrew.Bardsley@arm.com} 73910259SAndrew.Bardsley@arm.com 74010259SAndrew.Bardsley@arm.com#endif /* __CPU_MINOR_NEW_LSQ_HH__ */ 741