lsq.hh revision 10581
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: 10110259SAndrew.Bardsley@arm.com bool recvTimingResp(PacketPtr pkt) 10210259SAndrew.Bardsley@arm.com { return lsq.recvTimingResp(pkt); } 10310259SAndrew.Bardsley@arm.com 10410259SAndrew.Bardsley@arm.com void recvRetry() { lsq.recvRetry(); } 10510259SAndrew.Bardsley@arm.com 10610259SAndrew.Bardsley@arm.com void recvTimingSnoopReq(PacketPtr pkt) 10710259SAndrew.Bardsley@arm.com { return lsq.recvTimingSnoopReq(pkt); } 10810259SAndrew.Bardsley@arm.com }; 10910259SAndrew.Bardsley@arm.com 11010259SAndrew.Bardsley@arm.com DcachePort dcachePort; 11110259SAndrew.Bardsley@arm.com 11210259SAndrew.Bardsley@arm.com public: 11310259SAndrew.Bardsley@arm.com /** Derived SenderState to carry data access info. through address 11410259SAndrew.Bardsley@arm.com * translation, the queues in this port and back from the memory 11510259SAndrew.Bardsley@arm.com * system. */ 11610259SAndrew.Bardsley@arm.com class LSQRequest : 11710259SAndrew.Bardsley@arm.com public BaseTLB::Translation, /* For TLB lookups */ 11810259SAndrew.Bardsley@arm.com public Packet::SenderState /* For packing into a Packet */ 11910259SAndrew.Bardsley@arm.com { 12010259SAndrew.Bardsley@arm.com public: 12110259SAndrew.Bardsley@arm.com /** Owning port */ 12210259SAndrew.Bardsley@arm.com LSQ &port; 12310259SAndrew.Bardsley@arm.com 12410259SAndrew.Bardsley@arm.com /** Instruction which made this request */ 12510259SAndrew.Bardsley@arm.com MinorDynInstPtr inst; 12610259SAndrew.Bardsley@arm.com 12710259SAndrew.Bardsley@arm.com /** Load/store indication used for building packet. This isn't 12810259SAndrew.Bardsley@arm.com * carried by Request so we need to keep it here */ 12910259SAndrew.Bardsley@arm.com bool isLoad; 13010259SAndrew.Bardsley@arm.com 13110259SAndrew.Bardsley@arm.com /** Dynamically allocated and populated data carried for 13210259SAndrew.Bardsley@arm.com * building write packets */ 13310259SAndrew.Bardsley@arm.com PacketDataPtr data; 13410259SAndrew.Bardsley@arm.com 13510259SAndrew.Bardsley@arm.com /* Requests carry packets on their way to the memory system. 13610259SAndrew.Bardsley@arm.com * When a Packet returns from the memory system, its 13710259SAndrew.Bardsley@arm.com * request needs to have its packet updated as this 13810259SAndrew.Bardsley@arm.com * may have changed in flight */ 13910259SAndrew.Bardsley@arm.com PacketPtr packet; 14010259SAndrew.Bardsley@arm.com 14110259SAndrew.Bardsley@arm.com /** The underlying request of this LSQRequest */ 14210259SAndrew.Bardsley@arm.com Request request; 14310259SAndrew.Bardsley@arm.com 14410259SAndrew.Bardsley@arm.com /** Fault generated performing this request */ 14510259SAndrew.Bardsley@arm.com Fault fault; 14610259SAndrew.Bardsley@arm.com 14710259SAndrew.Bardsley@arm.com /** Res from pushRequest */ 14810259SAndrew.Bardsley@arm.com uint64_t *res; 14910259SAndrew.Bardsley@arm.com 15010259SAndrew.Bardsley@arm.com /** Was skipped. Set to indicate any reason (faulted, bad 15110259SAndrew.Bardsley@arm.com * stream sequence number, in a fault shadow) that this 15210259SAndrew.Bardsley@arm.com * request did not perform a memory transfer */ 15310259SAndrew.Bardsley@arm.com bool skipped; 15410259SAndrew.Bardsley@arm.com 15510259SAndrew.Bardsley@arm.com /** This in an access other than a normal cacheable load 15610259SAndrew.Bardsley@arm.com * that's visited the memory system */ 15710259SAndrew.Bardsley@arm.com bool issuedToMemory; 15810259SAndrew.Bardsley@arm.com 15910259SAndrew.Bardsley@arm.com enum LSQRequestState 16010259SAndrew.Bardsley@arm.com { 16110259SAndrew.Bardsley@arm.com NotIssued, /* Newly created */ 16210259SAndrew.Bardsley@arm.com InTranslation, /* TLB accessed, no reply yet */ 16310259SAndrew.Bardsley@arm.com Translated, /* Finished address translation */ 16410259SAndrew.Bardsley@arm.com Failed, /* The starting start of FailedDataRequests */ 16510259SAndrew.Bardsley@arm.com RequestIssuing, /* Load/store issued to memory in the requests 16610259SAndrew.Bardsley@arm.com queue */ 16710259SAndrew.Bardsley@arm.com StoreToStoreBuffer, /* Store in transfers on its way to the 16810259SAndrew.Bardsley@arm.com store buffer */ 16910259SAndrew.Bardsley@arm.com RequestNeedsRetry, /* Retry needed for load */ 17010259SAndrew.Bardsley@arm.com StoreInStoreBuffer, /* Store in the store buffer, before issuing 17110259SAndrew.Bardsley@arm.com a memory transfer */ 17210259SAndrew.Bardsley@arm.com StoreBufferIssuing, /* Store in store buffer and has been 17310259SAndrew.Bardsley@arm.com issued */ 17410259SAndrew.Bardsley@arm.com StoreBufferNeedsRetry, /* Retry needed for store */ 17510259SAndrew.Bardsley@arm.com /* All completed states. Includes 17610259SAndrew.Bardsley@arm.com completed loads, TLB faults and skipped requests whose 17710259SAndrew.Bardsley@arm.com seqNum's no longer match */ 17810259SAndrew.Bardsley@arm.com Complete 17910259SAndrew.Bardsley@arm.com }; 18010259SAndrew.Bardsley@arm.com 18110259SAndrew.Bardsley@arm.com LSQRequestState state; 18210259SAndrew.Bardsley@arm.com 18310259SAndrew.Bardsley@arm.com protected: 18410259SAndrew.Bardsley@arm.com /** BaseTLB::Translation interface */ 18510259SAndrew.Bardsley@arm.com void markDelayed() { } 18610259SAndrew.Bardsley@arm.com 18710259SAndrew.Bardsley@arm.com public: 18810259SAndrew.Bardsley@arm.com LSQRequest(LSQ &port_, MinorDynInstPtr inst_, bool isLoad_, 18910259SAndrew.Bardsley@arm.com PacketDataPtr data_ = NULL, uint64_t *res_ = NULL); 19010259SAndrew.Bardsley@arm.com 19110259SAndrew.Bardsley@arm.com virtual ~LSQRequest(); 19210259SAndrew.Bardsley@arm.com 19310259SAndrew.Bardsley@arm.com public: 19410259SAndrew.Bardsley@arm.com /** Make a packet to use with the memory transaction */ 19510259SAndrew.Bardsley@arm.com void makePacket(); 19610259SAndrew.Bardsley@arm.com 19710259SAndrew.Bardsley@arm.com /** Was no memory access attempted for this request? */ 19810259SAndrew.Bardsley@arm.com bool skippedMemAccess() { return skipped; } 19910259SAndrew.Bardsley@arm.com 20010259SAndrew.Bardsley@arm.com /** Set this request as having been skipped before a memory 20110259SAndrew.Bardsley@arm.com * transfer was attempt */ 20210259SAndrew.Bardsley@arm.com void setSkipped() { skipped = true; } 20310259SAndrew.Bardsley@arm.com 20410259SAndrew.Bardsley@arm.com /** Does address range req1 (req1_addr to req1_addr + req1_size - 1) 20510259SAndrew.Bardsley@arm.com * fully cover, partially cover or not cover at all the range req2 */ 20610259SAndrew.Bardsley@arm.com static AddrRangeCoverage containsAddrRangeOf( 20710259SAndrew.Bardsley@arm.com Addr req1_addr, unsigned int req1_size, 20810259SAndrew.Bardsley@arm.com Addr req2_addr, unsigned int req2_size); 20910259SAndrew.Bardsley@arm.com 21010259SAndrew.Bardsley@arm.com /** Does this request's address range fully cover the range 21110259SAndrew.Bardsley@arm.com * of other_request? */ 21210259SAndrew.Bardsley@arm.com AddrRangeCoverage containsAddrRangeOf(LSQRequest *other_request); 21310259SAndrew.Bardsley@arm.com 21410259SAndrew.Bardsley@arm.com /** Start the address translation process for this request. This 21510259SAndrew.Bardsley@arm.com * will issue a translation request to the TLB. */ 21610259SAndrew.Bardsley@arm.com virtual void startAddrTranslation() = 0; 21710259SAndrew.Bardsley@arm.com 21810259SAndrew.Bardsley@arm.com /** Get the next packet to issue for this request. For split 21910259SAndrew.Bardsley@arm.com * transfers, it will be necessary to step through the available 22010259SAndrew.Bardsley@arm.com * packets by calling do { getHeadPacket ; stepToNextPacket } while 22110259SAndrew.Bardsley@arm.com * (!sentAllPackets) and by retiring response using retireResponse */ 22210259SAndrew.Bardsley@arm.com virtual PacketPtr getHeadPacket() = 0; 22310259SAndrew.Bardsley@arm.com 22410259SAndrew.Bardsley@arm.com /** Step to the next packet for the next call to getHeadPacket */ 22510259SAndrew.Bardsley@arm.com virtual void stepToNextPacket() = 0; 22610259SAndrew.Bardsley@arm.com 22710259SAndrew.Bardsley@arm.com /** Have all packets been sent? */ 22810259SAndrew.Bardsley@arm.com virtual bool sentAllPackets() = 0; 22910259SAndrew.Bardsley@arm.com 23010259SAndrew.Bardsley@arm.com /** True if this request has any issued packets in the memory 23110259SAndrew.Bardsley@arm.com * system and so can't be interrupted until it gets responses */ 23210259SAndrew.Bardsley@arm.com virtual bool hasPacketsInMemSystem() = 0; 23310259SAndrew.Bardsley@arm.com 23410259SAndrew.Bardsley@arm.com /** Retire a response packet into the LSQRequest packet possibly 23510259SAndrew.Bardsley@arm.com * completing this transfer */ 23610259SAndrew.Bardsley@arm.com virtual void retireResponse(PacketPtr packet_) = 0; 23710259SAndrew.Bardsley@arm.com 23810259SAndrew.Bardsley@arm.com /** Is this a request a barrier? */ 23910259SAndrew.Bardsley@arm.com virtual bool isBarrier(); 24010259SAndrew.Bardsley@arm.com 24110259SAndrew.Bardsley@arm.com /** This request, once processed by the requests/transfers 24210259SAndrew.Bardsley@arm.com * queues, will need to go to the store buffer */ 24310259SAndrew.Bardsley@arm.com bool needsToBeSentToStoreBuffer(); 24410259SAndrew.Bardsley@arm.com 24510259SAndrew.Bardsley@arm.com /** Set state and output trace output */ 24610259SAndrew.Bardsley@arm.com void setState(LSQRequestState new_state); 24710259SAndrew.Bardsley@arm.com 24810259SAndrew.Bardsley@arm.com /** Has this request been completed. This includes *all* reasons 24910259SAndrew.Bardsley@arm.com * for completion: successful transfers, faults, skipped because 25010259SAndrew.Bardsley@arm.com * of preceding faults */ 25110259SAndrew.Bardsley@arm.com bool isComplete() const; 25210259SAndrew.Bardsley@arm.com 25310259SAndrew.Bardsley@arm.com /** MinorTrace report interface */ 25410259SAndrew.Bardsley@arm.com void reportData(std::ostream &os) const; 25510259SAndrew.Bardsley@arm.com }; 25610259SAndrew.Bardsley@arm.com 25710259SAndrew.Bardsley@arm.com typedef LSQRequest *LSQRequestPtr; 25810259SAndrew.Bardsley@arm.com 25910259SAndrew.Bardsley@arm.com friend std::ostream & operator <<(std::ostream &os, 26010259SAndrew.Bardsley@arm.com AddrRangeCoverage state); 26110259SAndrew.Bardsley@arm.com 26210259SAndrew.Bardsley@arm.com friend std::ostream & operator <<(std::ostream &os, 26310259SAndrew.Bardsley@arm.com LSQRequest::LSQRequestState state); 26410259SAndrew.Bardsley@arm.com 26510259SAndrew.Bardsley@arm.com protected: 26610259SAndrew.Bardsley@arm.com /** Special request types that don't actually issue memory requests */ 26710259SAndrew.Bardsley@arm.com class SpecialDataRequest : public LSQRequest 26810259SAndrew.Bardsley@arm.com { 26910259SAndrew.Bardsley@arm.com protected: 27010259SAndrew.Bardsley@arm.com /** TLB interace */ 27110379Sandreas.hansson@arm.com void finish(const Fault &fault_, RequestPtr request_, 27210379Sandreas.hansson@arm.com ThreadContext *tc, BaseTLB::Mode mode) 27310259SAndrew.Bardsley@arm.com { } 27410259SAndrew.Bardsley@arm.com 27510259SAndrew.Bardsley@arm.com public: 27610259SAndrew.Bardsley@arm.com /** Send single translation request */ 27710259SAndrew.Bardsley@arm.com void startAddrTranslation() { } 27810259SAndrew.Bardsley@arm.com 27910259SAndrew.Bardsley@arm.com /** Get the head packet as counted by numIssuedFragments */ 28010259SAndrew.Bardsley@arm.com PacketPtr getHeadPacket() 28110259SAndrew.Bardsley@arm.com { fatal("No packets in a SpecialDataRequest"); } 28210259SAndrew.Bardsley@arm.com 28310259SAndrew.Bardsley@arm.com /** Step on numIssuedFragments */ 28410259SAndrew.Bardsley@arm.com void stepToNextPacket() { } 28510259SAndrew.Bardsley@arm.com 28610259SAndrew.Bardsley@arm.com /** Has no packets to send */ 28710259SAndrew.Bardsley@arm.com bool sentAllPackets() { return true; } 28810259SAndrew.Bardsley@arm.com 28910259SAndrew.Bardsley@arm.com /** Never sends any requests */ 29010259SAndrew.Bardsley@arm.com bool hasPacketsInMemSystem() { return false; } 29110259SAndrew.Bardsley@arm.com 29210259SAndrew.Bardsley@arm.com /** Keep the given packet as the response packet 29310259SAndrew.Bardsley@arm.com * LSQRequest::packet */ 29410259SAndrew.Bardsley@arm.com void retireResponse(PacketPtr packet_) { } 29510259SAndrew.Bardsley@arm.com 29610259SAndrew.Bardsley@arm.com public: 29710259SAndrew.Bardsley@arm.com SpecialDataRequest(LSQ &port_, MinorDynInstPtr inst_) : 29810259SAndrew.Bardsley@arm.com /* Say this is a load, not actually relevant */ 29910259SAndrew.Bardsley@arm.com LSQRequest(port_, inst_, true, NULL, 0) 30010259SAndrew.Bardsley@arm.com { } 30110259SAndrew.Bardsley@arm.com }; 30210259SAndrew.Bardsley@arm.com 30310259SAndrew.Bardsley@arm.com /** FailedDataRequest represents requests from instructions that 30410259SAndrew.Bardsley@arm.com * failed their predicates but need to ride the requests/transfers 30510259SAndrew.Bardsley@arm.com * queues to maintain trace ordering */ 30610259SAndrew.Bardsley@arm.com class FailedDataRequest : public SpecialDataRequest 30710259SAndrew.Bardsley@arm.com { 30810259SAndrew.Bardsley@arm.com public: 30910259SAndrew.Bardsley@arm.com FailedDataRequest(LSQ &port_, MinorDynInstPtr inst_) : 31010259SAndrew.Bardsley@arm.com SpecialDataRequest(port_, inst_) 31110259SAndrew.Bardsley@arm.com { state = Failed; } 31210259SAndrew.Bardsley@arm.com }; 31310259SAndrew.Bardsley@arm.com 31410259SAndrew.Bardsley@arm.com /** Request for doing barrier accounting in the store buffer. Not 31510259SAndrew.Bardsley@arm.com * for use outside that unit */ 31610259SAndrew.Bardsley@arm.com class BarrierDataRequest : public SpecialDataRequest 31710259SAndrew.Bardsley@arm.com { 31810259SAndrew.Bardsley@arm.com public: 31910259SAndrew.Bardsley@arm.com bool isBarrier() { return true; } 32010259SAndrew.Bardsley@arm.com 32110259SAndrew.Bardsley@arm.com public: 32210259SAndrew.Bardsley@arm.com BarrierDataRequest(LSQ &port_, MinorDynInstPtr inst_) : 32310259SAndrew.Bardsley@arm.com SpecialDataRequest(port_, inst_) 32410259SAndrew.Bardsley@arm.com { state = Complete; } 32510259SAndrew.Bardsley@arm.com }; 32610259SAndrew.Bardsley@arm.com 32710259SAndrew.Bardsley@arm.com /** SingleDataRequest is used for requests that don't fragment */ 32810259SAndrew.Bardsley@arm.com class SingleDataRequest : public LSQRequest 32910259SAndrew.Bardsley@arm.com { 33010259SAndrew.Bardsley@arm.com protected: 33110259SAndrew.Bardsley@arm.com /** TLB interace */ 33210379Sandreas.hansson@arm.com void finish(const Fault &fault_, RequestPtr request_, 33310379Sandreas.hansson@arm.com ThreadContext *tc, BaseTLB::Mode mode); 33410259SAndrew.Bardsley@arm.com 33510259SAndrew.Bardsley@arm.com /** Has my only packet been sent to the memory system but has not 33610259SAndrew.Bardsley@arm.com * yet been responded to */ 33710259SAndrew.Bardsley@arm.com bool packetInFlight; 33810259SAndrew.Bardsley@arm.com 33910259SAndrew.Bardsley@arm.com /** Has the packet been at least sent to the memory system? */ 34010259SAndrew.Bardsley@arm.com bool packetSent; 34110259SAndrew.Bardsley@arm.com 34210259SAndrew.Bardsley@arm.com public: 34310259SAndrew.Bardsley@arm.com /** Send single translation request */ 34410259SAndrew.Bardsley@arm.com void startAddrTranslation(); 34510259SAndrew.Bardsley@arm.com 34610259SAndrew.Bardsley@arm.com /** Get the head packet as counted by numIssuedFragments */ 34710259SAndrew.Bardsley@arm.com PacketPtr getHeadPacket() { return packet; } 34810259SAndrew.Bardsley@arm.com 34910259SAndrew.Bardsley@arm.com /** Remember that the packet has been sent */ 35010259SAndrew.Bardsley@arm.com void stepToNextPacket() { packetInFlight = true; packetSent = true; } 35110259SAndrew.Bardsley@arm.com 35210259SAndrew.Bardsley@arm.com /** Has packet been sent */ 35310259SAndrew.Bardsley@arm.com bool hasPacketsInMemSystem() { return packetInFlight; } 35410259SAndrew.Bardsley@arm.com 35510259SAndrew.Bardsley@arm.com /** packetInFlight can become false again, so need to check 35610259SAndrew.Bardsley@arm.com * packetSent */ 35710259SAndrew.Bardsley@arm.com bool sentAllPackets() { return packetSent; } 35810259SAndrew.Bardsley@arm.com 35910259SAndrew.Bardsley@arm.com /** Keep the given packet as the response packet 36010259SAndrew.Bardsley@arm.com * LSQRequest::packet */ 36110259SAndrew.Bardsley@arm.com void retireResponse(PacketPtr packet_); 36210259SAndrew.Bardsley@arm.com 36310259SAndrew.Bardsley@arm.com public: 36410259SAndrew.Bardsley@arm.com SingleDataRequest(LSQ &port_, MinorDynInstPtr inst_, 36510259SAndrew.Bardsley@arm.com bool isLoad_, PacketDataPtr data_ = NULL, uint64_t *res_ = NULL) : 36610259SAndrew.Bardsley@arm.com LSQRequest(port_, inst_, isLoad_, data_, res_), 36710259SAndrew.Bardsley@arm.com packetInFlight(false), 36810259SAndrew.Bardsley@arm.com packetSent(false) 36910259SAndrew.Bardsley@arm.com { } 37010259SAndrew.Bardsley@arm.com }; 37110259SAndrew.Bardsley@arm.com 37210259SAndrew.Bardsley@arm.com class SplitDataRequest : public LSQRequest 37310259SAndrew.Bardsley@arm.com { 37410259SAndrew.Bardsley@arm.com protected: 37510259SAndrew.Bardsley@arm.com /** Event to step between translations */ 37610259SAndrew.Bardsley@arm.com class TranslationEvent : public Event 37710259SAndrew.Bardsley@arm.com { 37810259SAndrew.Bardsley@arm.com protected: 37910259SAndrew.Bardsley@arm.com SplitDataRequest &owner; 38010259SAndrew.Bardsley@arm.com 38110259SAndrew.Bardsley@arm.com public: 38210259SAndrew.Bardsley@arm.com TranslationEvent(SplitDataRequest &owner_) 38310259SAndrew.Bardsley@arm.com : owner(owner_) { } 38410259SAndrew.Bardsley@arm.com 38510259SAndrew.Bardsley@arm.com void process() 38610259SAndrew.Bardsley@arm.com { owner.sendNextFragmentToTranslation(); } 38710259SAndrew.Bardsley@arm.com }; 38810259SAndrew.Bardsley@arm.com 38910259SAndrew.Bardsley@arm.com TranslationEvent translationEvent; 39010259SAndrew.Bardsley@arm.com protected: 39110259SAndrew.Bardsley@arm.com /** Number of fragments this request is split into */ 39210259SAndrew.Bardsley@arm.com unsigned int numFragments; 39310259SAndrew.Bardsley@arm.com 39410259SAndrew.Bardsley@arm.com /** Number of fragments in the address translation mechanism */ 39510259SAndrew.Bardsley@arm.com unsigned int numInTranslationFragments; 39610259SAndrew.Bardsley@arm.com 39710259SAndrew.Bardsley@arm.com /** Number of fragments that have completed address translation, 39810259SAndrew.Bardsley@arm.com * (numTranslatedFragments + numInTranslationFragments) <= 39910259SAndrew.Bardsley@arm.com * numFragments. When numTranslatedFramgents == numFragments, 40010259SAndrew.Bardsley@arm.com * translation is complete */ 40110259SAndrew.Bardsley@arm.com unsigned int numTranslatedFragments; 40210259SAndrew.Bardsley@arm.com 40310259SAndrew.Bardsley@arm.com /** Number of fragments already issued (<= numFragments) */ 40410259SAndrew.Bardsley@arm.com unsigned int numIssuedFragments; 40510259SAndrew.Bardsley@arm.com 40610259SAndrew.Bardsley@arm.com /** Number of fragments retired back to this request */ 40710259SAndrew.Bardsley@arm.com unsigned int numRetiredFragments; 40810259SAndrew.Bardsley@arm.com 40910259SAndrew.Bardsley@arm.com /** Fragment Requests corresponding to the address ranges of 41010259SAndrew.Bardsley@arm.com * each fragment */ 41110259SAndrew.Bardsley@arm.com std::vector<Request *> fragmentRequests; 41210259SAndrew.Bardsley@arm.com 41310259SAndrew.Bardsley@arm.com /** Packets matching fragmentRequests to issue fragments to memory */ 41410259SAndrew.Bardsley@arm.com std::vector<Packet *> fragmentPackets; 41510259SAndrew.Bardsley@arm.com 41610259SAndrew.Bardsley@arm.com protected: 41710259SAndrew.Bardsley@arm.com /** TLB response interface */ 41810379Sandreas.hansson@arm.com void finish(const Fault &fault_, RequestPtr request_, 41910379Sandreas.hansson@arm.com ThreadContext *tc, BaseTLB::Mode mode); 42010259SAndrew.Bardsley@arm.com 42110259SAndrew.Bardsley@arm.com public: 42210259SAndrew.Bardsley@arm.com SplitDataRequest(LSQ &port_, MinorDynInstPtr inst_, 42310259SAndrew.Bardsley@arm.com bool isLoad_, PacketDataPtr data_ = NULL, 42410259SAndrew.Bardsley@arm.com uint64_t *res_ = NULL); 42510259SAndrew.Bardsley@arm.com 42610259SAndrew.Bardsley@arm.com ~SplitDataRequest(); 42710259SAndrew.Bardsley@arm.com 42810259SAndrew.Bardsley@arm.com public: 42910259SAndrew.Bardsley@arm.com /** Make all the Requests for this transfer's fragments so that those 43010259SAndrew.Bardsley@arm.com * requests can be sent for address translation */ 43110259SAndrew.Bardsley@arm.com void makeFragmentRequests(); 43210259SAndrew.Bardsley@arm.com 43310259SAndrew.Bardsley@arm.com /** Make the packets to go with the requests so they can be sent to 43410259SAndrew.Bardsley@arm.com * the memory system */ 43510259SAndrew.Bardsley@arm.com void makeFragmentPackets(); 43610259SAndrew.Bardsley@arm.com 43710259SAndrew.Bardsley@arm.com /** Start a loop of do { sendNextFragmentToTranslation ; 43810259SAndrew.Bardsley@arm.com * translateTiming ; finish } while (numTranslatedFragments != 43910259SAndrew.Bardsley@arm.com * numFragments) to complete all this requests' fragments' address 44010259SAndrew.Bardsley@arm.com * translations */ 44110259SAndrew.Bardsley@arm.com void startAddrTranslation(); 44210259SAndrew.Bardsley@arm.com 44310259SAndrew.Bardsley@arm.com /** Get the head packet as counted by numIssuedFragments */ 44410259SAndrew.Bardsley@arm.com PacketPtr getHeadPacket(); 44510259SAndrew.Bardsley@arm.com 44610259SAndrew.Bardsley@arm.com /** Step on numIssuedFragments */ 44710259SAndrew.Bardsley@arm.com void stepToNextPacket(); 44810259SAndrew.Bardsley@arm.com 44910259SAndrew.Bardsley@arm.com bool hasPacketsInMemSystem() 45010259SAndrew.Bardsley@arm.com { return numIssuedFragments != numRetiredFragments; } 45110259SAndrew.Bardsley@arm.com 45210259SAndrew.Bardsley@arm.com /** Have we stepped past the end of fragmentPackets? */ 45310259SAndrew.Bardsley@arm.com bool sentAllPackets() { return numIssuedFragments == numFragments; } 45410259SAndrew.Bardsley@arm.com 45510259SAndrew.Bardsley@arm.com /** For loads, paste the response data into the main 45610259SAndrew.Bardsley@arm.com * response packet */ 45710259SAndrew.Bardsley@arm.com void retireResponse(PacketPtr packet_); 45810259SAndrew.Bardsley@arm.com 45910259SAndrew.Bardsley@arm.com /** Part of the address translation loop, see startAddTranslation */ 46010259SAndrew.Bardsley@arm.com void sendNextFragmentToTranslation(); 46110259SAndrew.Bardsley@arm.com }; 46210259SAndrew.Bardsley@arm.com 46310259SAndrew.Bardsley@arm.com /** Store buffer. This contains stores which have been committed 46410259SAndrew.Bardsley@arm.com * but whose memory transfers have not yet been issued. Load data 46510259SAndrew.Bardsley@arm.com * can be forwarded out of the store buffer */ 46610259SAndrew.Bardsley@arm.com class StoreBuffer : public Named 46710259SAndrew.Bardsley@arm.com { 46810259SAndrew.Bardsley@arm.com public: 46910259SAndrew.Bardsley@arm.com /** My owner */ 47010259SAndrew.Bardsley@arm.com LSQ &lsq; 47110259SAndrew.Bardsley@arm.com 47210259SAndrew.Bardsley@arm.com /** Number of slots, this is a bound on the size of slots */ 47310259SAndrew.Bardsley@arm.com const unsigned int numSlots; 47410259SAndrew.Bardsley@arm.com 47510259SAndrew.Bardsley@arm.com /** Maximum number of stores that can be issued per cycle */ 47610259SAndrew.Bardsley@arm.com const unsigned int storeLimitPerCycle; 47710259SAndrew.Bardsley@arm.com 47810259SAndrew.Bardsley@arm.com public: 47910259SAndrew.Bardsley@arm.com /** Queue of store requests on their way to memory */ 48010259SAndrew.Bardsley@arm.com std::deque<LSQRequestPtr> slots; 48110259SAndrew.Bardsley@arm.com 48210259SAndrew.Bardsley@arm.com /** Number of occupied slots which have not yet issued a 48310259SAndrew.Bardsley@arm.com * memory access */ 48410259SAndrew.Bardsley@arm.com unsigned int numUnissuedAccesses; 48510259SAndrew.Bardsley@arm.com 48610259SAndrew.Bardsley@arm.com public: 48710259SAndrew.Bardsley@arm.com StoreBuffer(std::string name_, LSQ &lsq_, 48810259SAndrew.Bardsley@arm.com unsigned int store_buffer_size, 48910259SAndrew.Bardsley@arm.com unsigned int store_limit_per_cycle); 49010259SAndrew.Bardsley@arm.com 49110259SAndrew.Bardsley@arm.com public: 49210259SAndrew.Bardsley@arm.com /** Can a new request be inserted into the queue? */ 49310259SAndrew.Bardsley@arm.com bool canInsert() const; 49410259SAndrew.Bardsley@arm.com 49510259SAndrew.Bardsley@arm.com /** Delete the given request and free the slot it occupied */ 49610259SAndrew.Bardsley@arm.com void deleteRequest(LSQRequestPtr request); 49710259SAndrew.Bardsley@arm.com 49810259SAndrew.Bardsley@arm.com /** Insert a request at the back of the queue */ 49910259SAndrew.Bardsley@arm.com void insert(LSQRequestPtr request); 50010259SAndrew.Bardsley@arm.com 50110259SAndrew.Bardsley@arm.com /** Look for a store which satisfies the given load. Returns an 50210259SAndrew.Bardsley@arm.com * indication whether the forwarding request can be wholly, 50310259SAndrew.Bardsley@arm.com * partly or not all all satisfied. If the request can be 50410259SAndrew.Bardsley@arm.com * wholly satisfied, the store buffer slot number which can be used 50510259SAndrew.Bardsley@arm.com * is returned in found_slot */ 50610259SAndrew.Bardsley@arm.com AddrRangeCoverage canForwardDataToLoad(LSQRequestPtr request, 50710259SAndrew.Bardsley@arm.com unsigned int &found_slot); 50810259SAndrew.Bardsley@arm.com 50910259SAndrew.Bardsley@arm.com /** Fill the given packet with appropriate date from slot 51010259SAndrew.Bardsley@arm.com * slot_number */ 51110259SAndrew.Bardsley@arm.com void forwardStoreData(LSQRequestPtr load, unsigned int slot_number); 51210259SAndrew.Bardsley@arm.com 51310259SAndrew.Bardsley@arm.com /** Number of stores in the store buffer which have not been 51410259SAndrew.Bardsley@arm.com * completely issued to the memory system */ 51510259SAndrew.Bardsley@arm.com unsigned int numUnissuedStores() { return numUnissuedAccesses; } 51610259SAndrew.Bardsley@arm.com 51710581SAndrew.Bardsley@arm.com /** Count a store being issued to memory by decrementing 51810581SAndrew.Bardsley@arm.com * numUnissuedAccesses. Does not count barrier requests as they 51910581SAndrew.Bardsley@arm.com * will be handles as barriers are cleared from the buffer */ 52010581SAndrew.Bardsley@arm.com void countIssuedStore(LSQRequestPtr request); 52110581SAndrew.Bardsley@arm.com 52210259SAndrew.Bardsley@arm.com /** Drained if there is absolutely nothing left in the buffer */ 52310259SAndrew.Bardsley@arm.com bool isDrained() const { return slots.empty(); } 52410259SAndrew.Bardsley@arm.com 52510259SAndrew.Bardsley@arm.com /** Try to issue more stores to memory */ 52610259SAndrew.Bardsley@arm.com void step(); 52710259SAndrew.Bardsley@arm.com 52810259SAndrew.Bardsley@arm.com /** Report queue contents for MinorTrace */ 52910259SAndrew.Bardsley@arm.com void minorTrace() const; 53010259SAndrew.Bardsley@arm.com }; 53110259SAndrew.Bardsley@arm.com 53210259SAndrew.Bardsley@arm.com protected: 53310259SAndrew.Bardsley@arm.com /** Most recent execSeqNum of a memory barrier instruction or 53410259SAndrew.Bardsley@arm.com * 0 if there are no in-flight barriers. Useful as a 53510259SAndrew.Bardsley@arm.com * dependency for early-issued memory operations */ 53610259SAndrew.Bardsley@arm.com InstSeqNum lastMemBarrier; 53710259SAndrew.Bardsley@arm.com 53810259SAndrew.Bardsley@arm.com public: 53910259SAndrew.Bardsley@arm.com /** Retry state of last issued memory transfer */ 54010259SAndrew.Bardsley@arm.com MemoryState state; 54110259SAndrew.Bardsley@arm.com 54210259SAndrew.Bardsley@arm.com /** Maximum number of in-flight accesses issued to the memory system */ 54310259SAndrew.Bardsley@arm.com const unsigned int inMemorySystemLimit; 54410259SAndrew.Bardsley@arm.com 54510259SAndrew.Bardsley@arm.com /** Memory system access width (and snap) in bytes */ 54610259SAndrew.Bardsley@arm.com const unsigned int lineWidth; 54710259SAndrew.Bardsley@arm.com 54810259SAndrew.Bardsley@arm.com public: 54910259SAndrew.Bardsley@arm.com /** The LSQ consists of three queues: requests, transfers and the 55010259SAndrew.Bardsley@arm.com * store buffer storeBuffer. */ 55110259SAndrew.Bardsley@arm.com 55210259SAndrew.Bardsley@arm.com typedef Queue<LSQRequestPtr, 55310259SAndrew.Bardsley@arm.com ReportTraitsPtrAdaptor<LSQRequestPtr>, 55410259SAndrew.Bardsley@arm.com NoBubbleTraits<LSQRequestPtr> > 55510259SAndrew.Bardsley@arm.com LSQQueue; 55610259SAndrew.Bardsley@arm.com 55710259SAndrew.Bardsley@arm.com /** requests contains LSQRequests which have been issued to the TLB by 55810259SAndrew.Bardsley@arm.com * calling ExecContext::readMem/writeMem (which in turn calls 55910259SAndrew.Bardsley@arm.com * LSQ::pushRequest and LSQRequest::startAddrTranslation). Once they 56010259SAndrew.Bardsley@arm.com * have a physical address, requests at the head of requests can be 56110259SAndrew.Bardsley@arm.com * issued to the memory system. At this stage, it cannot be clear that 56210259SAndrew.Bardsley@arm.com * memory accesses *must* happen (that there are no preceding faults or 56310259SAndrew.Bardsley@arm.com * changes of flow of control) and so only cacheable reads are issued 56410259SAndrew.Bardsley@arm.com * to memory. 56510259SAndrew.Bardsley@arm.com * Cacheable stores are not issued at all (and just pass through 56610259SAndrew.Bardsley@arm.com * 'transfers' in order) and all other transfers are stalled in requests 56710259SAndrew.Bardsley@arm.com * until their corresponding instructions are at the head of the 56810259SAndrew.Bardsley@arm.com * inMemInsts instruction queue and have the right streamSeqNum. */ 56910259SAndrew.Bardsley@arm.com LSQQueue requests; 57010259SAndrew.Bardsley@arm.com 57110259SAndrew.Bardsley@arm.com /** Once issued to memory (or, for stores, just had their 57210259SAndrew.Bardsley@arm.com * state changed to StoreToStoreBuffer) LSQRequests pass through 57310259SAndrew.Bardsley@arm.com * transfers waiting for memory responses. At the head of transfers, 57410259SAndrew.Bardsley@arm.com * Execute::commitInst can pick up the memory response for a request 57510259SAndrew.Bardsley@arm.com * using LSQ::findResponse. Responses to be committed can then 57610259SAndrew.Bardsley@arm.com * have ExecContext::completeAcc on them. Stores can then be pushed 57710259SAndrew.Bardsley@arm.com * into the store buffer. All other transfers will then be complete. */ 57810259SAndrew.Bardsley@arm.com LSQQueue transfers; 57910259SAndrew.Bardsley@arm.com 58010259SAndrew.Bardsley@arm.com /* The store buffer contains committed cacheable stores on 58110259SAndrew.Bardsley@arm.com * their way to memory decoupled from subsequence instruction execution. 58210259SAndrew.Bardsley@arm.com * Before trying to issue a cacheable read from 'requests' to memory, 58310259SAndrew.Bardsley@arm.com * the store buffer is checked to see if a previous store contains the 58410259SAndrew.Bardsley@arm.com * needed data (StoreBuffer::canForwardDataToLoad) which can be 58510259SAndrew.Bardsley@arm.com * forwarded in lieu of a memory access. If there are outstanding 58610259SAndrew.Bardsley@arm.com * stores in the transfers queue, they must be promoted to the store 58710259SAndrew.Bardsley@arm.com * buffer (and so be commited) before they can be correctly checked 58810259SAndrew.Bardsley@arm.com * for forwarding. */ 58910259SAndrew.Bardsley@arm.com StoreBuffer storeBuffer; 59010259SAndrew.Bardsley@arm.com 59110259SAndrew.Bardsley@arm.com protected: 59210259SAndrew.Bardsley@arm.com /** Count of the number of mem. accesses which have left the 59310368SAndrew.Bardsley@arm.com * requests queue and are in the 'wild' in the memory system and who 59410368SAndrew.Bardsley@arm.com * *must not* be interrupted as they are not normal cacheable 59510368SAndrew.Bardsley@arm.com * accesses. This is a count of the number of in-flight requests 59610368SAndrew.Bardsley@arm.com * with issuedToMemory set who have visited tryToSendRequest at least 59710368SAndrew.Bardsley@arm.com * once */ 59810259SAndrew.Bardsley@arm.com unsigned int numAccessesInMemorySystem; 59910259SAndrew.Bardsley@arm.com 60010259SAndrew.Bardsley@arm.com /** Number of requests in the DTLB in the requests queue */ 60110259SAndrew.Bardsley@arm.com unsigned int numAccessesInDTLB; 60210259SAndrew.Bardsley@arm.com 60310259SAndrew.Bardsley@arm.com /** The number of stores in the transfers queue. Useful when 60410259SAndrew.Bardsley@arm.com * testing if the store buffer contains all the forwardable stores */ 60510259SAndrew.Bardsley@arm.com unsigned int numStoresInTransfers; 60610259SAndrew.Bardsley@arm.com 60710259SAndrew.Bardsley@arm.com /** The number of accesses which have been issued to the memory 60810259SAndrew.Bardsley@arm.com * system but have not been committed/discarded *excluding* 60910259SAndrew.Bardsley@arm.com * cacheable normal loads which don't need to be tracked */ 61010259SAndrew.Bardsley@arm.com unsigned int numAccessesIssuedToMemory; 61110259SAndrew.Bardsley@arm.com 61210259SAndrew.Bardsley@arm.com /** The request (from either requests or the store buffer) which is 61310259SAndrew.Bardsley@arm.com * currently waiting have its memory access retried */ 61410259SAndrew.Bardsley@arm.com LSQRequestPtr retryRequest; 61510259SAndrew.Bardsley@arm.com 61610259SAndrew.Bardsley@arm.com /** Address Mask for a cache block (e.g. ~(cache_block_size-1)) */ 61710259SAndrew.Bardsley@arm.com Addr cacheBlockMask; 61810259SAndrew.Bardsley@arm.com 61910259SAndrew.Bardsley@arm.com protected: 62010259SAndrew.Bardsley@arm.com /** Try and issue a memory access for a translated request at the 62110259SAndrew.Bardsley@arm.com * head of the requests queue. Also tries to move the request 62210259SAndrew.Bardsley@arm.com * between queues */ 62310259SAndrew.Bardsley@arm.com void tryToSendToTransfers(LSQRequestPtr request); 62410259SAndrew.Bardsley@arm.com 62510259SAndrew.Bardsley@arm.com /** Try to send (or resend) a memory request's next/only packet to 62610259SAndrew.Bardsley@arm.com * the memory system. Returns true if the request was successfully 62710259SAndrew.Bardsley@arm.com * sent to memory (and was also the last packet in a transfer) */ 62810259SAndrew.Bardsley@arm.com bool tryToSend(LSQRequestPtr request); 62910259SAndrew.Bardsley@arm.com 63010259SAndrew.Bardsley@arm.com /** Clear a barrier (if it's the last one marked up in lastMemBarrier) */ 63110259SAndrew.Bardsley@arm.com void clearMemBarrier(MinorDynInstPtr inst); 63210259SAndrew.Bardsley@arm.com 63310259SAndrew.Bardsley@arm.com /** Move a request between queues */ 63410259SAndrew.Bardsley@arm.com void moveFromRequestsToTransfers(LSQRequestPtr request); 63510259SAndrew.Bardsley@arm.com 63610259SAndrew.Bardsley@arm.com /** Can a request be sent to the memory system */ 63710259SAndrew.Bardsley@arm.com bool canSendToMemorySystem(); 63810259SAndrew.Bardsley@arm.com 63910259SAndrew.Bardsley@arm.com public: 64010259SAndrew.Bardsley@arm.com LSQ(std::string name_, std::string dcache_port_name_, 64110259SAndrew.Bardsley@arm.com MinorCPU &cpu_, Execute &execute_, 64210259SAndrew.Bardsley@arm.com unsigned int max_accesses_in_memory_system, unsigned int line_width, 64310259SAndrew.Bardsley@arm.com unsigned int requests_queue_size, unsigned int transfers_queue_size, 64410259SAndrew.Bardsley@arm.com unsigned int store_buffer_size, 64510259SAndrew.Bardsley@arm.com unsigned int store_buffer_cycle_store_limit); 64610259SAndrew.Bardsley@arm.com 64710259SAndrew.Bardsley@arm.com virtual ~LSQ(); 64810259SAndrew.Bardsley@arm.com 64910259SAndrew.Bardsley@arm.com public: 65010259SAndrew.Bardsley@arm.com /** Step checks the queues to see if their are issuable transfers 65110259SAndrew.Bardsley@arm.com * which were not otherwise picked up by tests at the end of other 65210259SAndrew.Bardsley@arm.com * events. 65310259SAndrew.Bardsley@arm.com * 65410259SAndrew.Bardsley@arm.com * Steppable actions include deferred actions which couldn't be 65510259SAndrew.Bardsley@arm.com * cascaded on the end of a memory response/TLB response event 65610259SAndrew.Bardsley@arm.com * because of resource congestion. */ 65710259SAndrew.Bardsley@arm.com void step(); 65810259SAndrew.Bardsley@arm.com 65910259SAndrew.Bardsley@arm.com /** Is their space in the request queue to be able to push a request by 66010259SAndrew.Bardsley@arm.com * issuing an isMemRef instruction */ 66110259SAndrew.Bardsley@arm.com bool canRequest() { return requests.unreservedRemainingSpace() != 0; } 66210259SAndrew.Bardsley@arm.com 66310259SAndrew.Bardsley@arm.com /** Returns a response if it's at the head of the transfers queue and 66410259SAndrew.Bardsley@arm.com * it's either complete or can be sent on to the store buffer. After 66510259SAndrew.Bardsley@arm.com * calling, the request still remains on the transfer queue until 66610259SAndrew.Bardsley@arm.com * popResponse is called */ 66710259SAndrew.Bardsley@arm.com LSQRequestPtr findResponse(MinorDynInstPtr inst); 66810259SAndrew.Bardsley@arm.com 66910259SAndrew.Bardsley@arm.com /** Sanity check and pop the head response */ 67010259SAndrew.Bardsley@arm.com void popResponse(LSQRequestPtr response); 67110259SAndrew.Bardsley@arm.com 67210259SAndrew.Bardsley@arm.com /** Must check this before trying to insert into the store buffer */ 67310259SAndrew.Bardsley@arm.com bool canPushIntoStoreBuffer() const { return storeBuffer.canInsert(); } 67410259SAndrew.Bardsley@arm.com 67510259SAndrew.Bardsley@arm.com /** A store has been committed, please move it to the store buffer */ 67610259SAndrew.Bardsley@arm.com void sendStoreToStoreBuffer(LSQRequestPtr request); 67710259SAndrew.Bardsley@arm.com 67810259SAndrew.Bardsley@arm.com /** Are there any accesses other than normal cached loads in the 67910259SAndrew.Bardsley@arm.com * memory system or having received responses which need to be 68010259SAndrew.Bardsley@arm.com * handled for their instruction's to be completed */ 68110259SAndrew.Bardsley@arm.com bool accessesInFlight() const 68210259SAndrew.Bardsley@arm.com { return numAccessesIssuedToMemory != 0; } 68310259SAndrew.Bardsley@arm.com 68410259SAndrew.Bardsley@arm.com /** A memory barrier instruction has been issued, remember its 68510259SAndrew.Bardsley@arm.com * execSeqNum that we can avoid issuing memory ops until it is 68610259SAndrew.Bardsley@arm.com * committed */ 68710259SAndrew.Bardsley@arm.com void issuedMemBarrierInst(MinorDynInstPtr inst); 68810259SAndrew.Bardsley@arm.com 68910259SAndrew.Bardsley@arm.com /** Get the execSeqNum of the last issued memory barrier */ 69010259SAndrew.Bardsley@arm.com InstSeqNum getLastMemBarrier() const { return lastMemBarrier; } 69110259SAndrew.Bardsley@arm.com 69210259SAndrew.Bardsley@arm.com /** Is there nothing left in the LSQ */ 69310259SAndrew.Bardsley@arm.com bool isDrained(); 69410259SAndrew.Bardsley@arm.com 69510259SAndrew.Bardsley@arm.com /** May need to be ticked next cycle as one of the queues contains 69610259SAndrew.Bardsley@arm.com * an actionable transfers or address translation */ 69710259SAndrew.Bardsley@arm.com bool needsToTick(); 69810259SAndrew.Bardsley@arm.com 69910259SAndrew.Bardsley@arm.com /** Complete a barrier instruction. Where committed, makes a 70010259SAndrew.Bardsley@arm.com * BarrierDataRequest and pushed it into the store buffer */ 70110259SAndrew.Bardsley@arm.com void completeMemBarrierInst(MinorDynInstPtr inst, 70210259SAndrew.Bardsley@arm.com bool committed); 70310259SAndrew.Bardsley@arm.com 70410259SAndrew.Bardsley@arm.com /** Single interface for readMem/writeMem to issue requests into 70510259SAndrew.Bardsley@arm.com * the LSQ */ 70610259SAndrew.Bardsley@arm.com void pushRequest(MinorDynInstPtr inst, bool isLoad, uint8_t *data, 70710259SAndrew.Bardsley@arm.com unsigned int size, Addr addr, unsigned int flags, uint64_t *res); 70810259SAndrew.Bardsley@arm.com 70910259SAndrew.Bardsley@arm.com /** Push a predicate failed-representing request into the queues just 71010259SAndrew.Bardsley@arm.com * to maintain commit order */ 71110259SAndrew.Bardsley@arm.com void pushFailedRequest(MinorDynInstPtr inst); 71210259SAndrew.Bardsley@arm.com 71310259SAndrew.Bardsley@arm.com /** Memory interface */ 71410259SAndrew.Bardsley@arm.com bool recvTimingResp(PacketPtr pkt); 71510259SAndrew.Bardsley@arm.com void recvRetry(); 71610259SAndrew.Bardsley@arm.com void recvTimingSnoopReq(PacketPtr pkt); 71710259SAndrew.Bardsley@arm.com 71810259SAndrew.Bardsley@arm.com /** Return the raw-bindable port */ 71910259SAndrew.Bardsley@arm.com MinorCPU::MinorCPUPort &getDcachePort() { return dcachePort; } 72010259SAndrew.Bardsley@arm.com 72110259SAndrew.Bardsley@arm.com void minorTrace() const; 72210259SAndrew.Bardsley@arm.com}; 72310259SAndrew.Bardsley@arm.com 72410259SAndrew.Bardsley@arm.com/** Make a suitable packet for the given request. If the request is a store, 72510259SAndrew.Bardsley@arm.com * data will be the payload data. If sender_state is NULL, it won't be 72610259SAndrew.Bardsley@arm.com * pushed into the packet as senderState */ 72710259SAndrew.Bardsley@arm.comPacketPtr makePacketForRequest(Request &request, bool isLoad, 72810259SAndrew.Bardsley@arm.com Packet::SenderState *sender_state = NULL, PacketDataPtr data = NULL); 72910259SAndrew.Bardsley@arm.com} 73010259SAndrew.Bardsley@arm.com 73110259SAndrew.Bardsley@arm.com#endif /* __CPU_MINOR_NEW_LSQ_HH__ */ 732