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