RubyPort.hh revision 11308:7d8836fd043d
111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2012-2013 ARM Limited
311308Santhony.gutierrez@amd.com * All rights reserved.
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * The license below extends only to copyright in the software and shall
611308Santhony.gutierrez@amd.com * not be construed as granting a license to any other intellectual
711308Santhony.gutierrez@amd.com * property including but not limited to intellectual property relating
811308Santhony.gutierrez@amd.com * to a hardware implementation of the functionality of the software
911308Santhony.gutierrez@amd.com * licensed hereunder.  You may use the software subject to the license
1011308Santhony.gutierrez@amd.com * terms below provided that you ensure that this notice is replicated
1111308Santhony.gutierrez@amd.com * unmodified and in its entirety in all distributions of the software,
1211308Santhony.gutierrez@amd.com * modified or unmodified, in source code or in binary form.
1311308Santhony.gutierrez@amd.com *
1411308Santhony.gutierrez@amd.com * Copyright (c) 2009-2013 Advanced Micro Devices, Inc.
1511308Santhony.gutierrez@amd.com * Copyright (c) 2011 Mark D. Hill and David A. Wood
1611308Santhony.gutierrez@amd.com * All rights reserved.
1711308Santhony.gutierrez@amd.com *
1811308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
1911308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are
2011308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright
2111308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer;
2211308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright
2311308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the
2411308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution;
2511308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its
2611308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from
2711308Santhony.gutierrez@amd.com * this software without specific prior written permission.
2811308Santhony.gutierrez@amd.com *
2911308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3011308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3111308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3211308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3311308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3411308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3511308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3611308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3711308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3811308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3911308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4011308Santhony.gutierrez@amd.com */
4111308Santhony.gutierrez@amd.com
4211308Santhony.gutierrez@amd.com#ifndef __MEM_RUBY_SYSTEM_RUBYPORT_HH__
4311308Santhony.gutierrez@amd.com#define __MEM_RUBY_SYSTEM_RUBYPORT_HH__
4411308Santhony.gutierrez@amd.com
4511308Santhony.gutierrez@amd.com#include <cassert>
4611308Santhony.gutierrez@amd.com#include <string>
4711308Santhony.gutierrez@amd.com
4811308Santhony.gutierrez@amd.com#include "mem/protocol/RequestStatus.hh"
4911308Santhony.gutierrez@amd.com#include "mem/ruby/network/MessageBuffer.hh"
5011308Santhony.gutierrez@amd.com#include "mem/ruby/system/RubySystem.hh"
5111308Santhony.gutierrez@amd.com#include "mem/mem_object.hh"
5211308Santhony.gutierrez@amd.com#include "mem/tport.hh"
5311308Santhony.gutierrez@amd.com#include "params/RubyPort.hh"
5411308Santhony.gutierrez@amd.com
5511639Salexandru.dutu@amd.comclass AbstractController;
5611308Santhony.gutierrez@amd.com
5711308Santhony.gutierrez@amd.comclass RubyPort : public MemObject
5811308Santhony.gutierrez@amd.com{
5911308Santhony.gutierrez@amd.com  public:
6011308Santhony.gutierrez@amd.com    class MemMasterPort : public QueuedMasterPort
6111639Salexandru.dutu@amd.com    {
6211639Salexandru.dutu@amd.com      private:
6311639Salexandru.dutu@amd.com        ReqPacketQueue reqQueue;
6411639Salexandru.dutu@amd.com        SnoopRespPacketQueue snoopRespQueue;
6511639Salexandru.dutu@amd.com
6611639Salexandru.dutu@amd.com      public:
6711639Salexandru.dutu@amd.com        MemMasterPort(const std::string &_name, RubyPort *_port);
6811639Salexandru.dutu@amd.com
6911639Salexandru.dutu@amd.com      protected:
7011639Salexandru.dutu@amd.com        bool recvTimingResp(PacketPtr pkt);
7111308Santhony.gutierrez@amd.com        void recvRangeChange() {}
7211639Salexandru.dutu@amd.com    };
7311639Salexandru.dutu@amd.com
7411308Santhony.gutierrez@amd.com    class MemSlavePort : public QueuedSlavePort
7511308Santhony.gutierrez@amd.com    {
7611639Salexandru.dutu@amd.com      private:
7711639Salexandru.dutu@amd.com        RespPacketQueue queue;
7811639Salexandru.dutu@amd.com        bool access_backing_store;
7911639Salexandru.dutu@amd.com        bool no_retry_on_stall;
8011308Santhony.gutierrez@amd.com
8111308Santhony.gutierrez@amd.com      public:
8211308Santhony.gutierrez@amd.com        MemSlavePort(const std::string &_name, RubyPort *_port,
8311308Santhony.gutierrez@amd.com                     bool _access_backing_store,
8411308Santhony.gutierrez@amd.com                     PortID id, bool _no_retry_on_stall);
8511308Santhony.gutierrez@amd.com        void hitCallback(PacketPtr pkt);
8611639Salexandru.dutu@amd.com        void evictionCallback(Addr address);
8711639Salexandru.dutu@amd.com
8811639Salexandru.dutu@amd.com      protected:
8911639Salexandru.dutu@amd.com        bool recvTimingReq(PacketPtr pkt);
9011534Sjohn.kalamatianos@amd.com
9111639Salexandru.dutu@amd.com        Tick recvAtomic(PacketPtr pkt)
9211534Sjohn.kalamatianos@amd.com        { panic("RubyPort::MemSlavePort::recvAtomic() not implemented!\n"); }
9311308Santhony.gutierrez@amd.com
9411308Santhony.gutierrez@amd.com        void recvFunctional(PacketPtr pkt);
9511308Santhony.gutierrez@amd.com
9611308Santhony.gutierrez@amd.com        AddrRangeList getAddrRanges() const
9711308Santhony.gutierrez@amd.com        { AddrRangeList ranges; return ranges; }
9811523Sdavid.guillen@arm.com
9911523Sdavid.guillen@arm.com        void addToRetryList();
10011308Santhony.gutierrez@amd.com
10111308Santhony.gutierrez@amd.com      private:
10211308Santhony.gutierrez@amd.com        bool isPhysMemAddress(Addr addr) const;
10311308Santhony.gutierrez@amd.com    };
10411308Santhony.gutierrez@amd.com
10511308Santhony.gutierrez@amd.com    class PioMasterPort : public QueuedMasterPort
10611308Santhony.gutierrez@amd.com    {
10711308Santhony.gutierrez@amd.com      private:
10811308Santhony.gutierrez@amd.com        ReqPacketQueue reqQueue;
10911308Santhony.gutierrez@amd.com        SnoopRespPacketQueue snoopRespQueue;
11011308Santhony.gutierrez@amd.com
11111308Santhony.gutierrez@amd.com      public:
11211308Santhony.gutierrez@amd.com        PioMasterPort(const std::string &_name, RubyPort *_port);
11311308Santhony.gutierrez@amd.com
11411308Santhony.gutierrez@amd.com      protected:
11511308Santhony.gutierrez@amd.com        bool recvTimingResp(PacketPtr pkt);
11611308Santhony.gutierrez@amd.com        void recvRangeChange();
11711308Santhony.gutierrez@amd.com    };
11811308Santhony.gutierrez@amd.com
11911308Santhony.gutierrez@amd.com    class PioSlavePort : public QueuedSlavePort
12011308Santhony.gutierrez@amd.com    {
12111308Santhony.gutierrez@amd.com      private:
12211308Santhony.gutierrez@amd.com        RespPacketQueue queue;
12311308Santhony.gutierrez@amd.com
12411308Santhony.gutierrez@amd.com      public:
12511308Santhony.gutierrez@amd.com        PioSlavePort(const std::string &_name, RubyPort *_port);
12611308Santhony.gutierrez@amd.com
12711308Santhony.gutierrez@amd.com      protected:
12811308Santhony.gutierrez@amd.com        bool recvTimingReq(PacketPtr pkt);
12911308Santhony.gutierrez@amd.com
13011308Santhony.gutierrez@amd.com        Tick recvAtomic(PacketPtr pkt)
13111308Santhony.gutierrez@amd.com        { panic("recvAtomic not supported with ruby!"); }
13211308Santhony.gutierrez@amd.com
13311308Santhony.gutierrez@amd.com        void recvFunctional(PacketPtr pkt)
13411308Santhony.gutierrez@amd.com        { panic("recvFunctional should never be called on pio slave port!"); }
13511308Santhony.gutierrez@amd.com
13611308Santhony.gutierrez@amd.com        AddrRangeList getAddrRanges() const;
13711308Santhony.gutierrez@amd.com    };
13811308Santhony.gutierrez@amd.com
13911308Santhony.gutierrez@amd.com    struct SenderState : public Packet::SenderState
14011308Santhony.gutierrez@amd.com    {
14111308Santhony.gutierrez@amd.com        MemSlavePort *port;
14211308Santhony.gutierrez@amd.com        SenderState(MemSlavePort * _port) : port(_port)
14311308Santhony.gutierrez@amd.com        {}
14411308Santhony.gutierrez@amd.com     };
14511308Santhony.gutierrez@amd.com
14611308Santhony.gutierrez@amd.com    typedef RubyPortParams Params;
14711308Santhony.gutierrez@amd.com    RubyPort(const Params *p);
14811308Santhony.gutierrez@amd.com    virtual ~RubyPort() {}
14911308Santhony.gutierrez@amd.com
15011308Santhony.gutierrez@amd.com    void init() override;
15111308Santhony.gutierrez@amd.com
15211308Santhony.gutierrez@amd.com    BaseMasterPort &getMasterPort(const std::string &if_name,
15311308Santhony.gutierrez@amd.com                                  PortID idx = InvalidPortID) override;
15411534Sjohn.kalamatianos@amd.com    BaseSlavePort &getSlavePort(const std::string &if_name,
15511308Santhony.gutierrez@amd.com                                PortID idx = InvalidPortID) override;
15611308Santhony.gutierrez@amd.com
15711308Santhony.gutierrez@amd.com    virtual RequestStatus makeRequest(PacketPtr pkt) = 0;
15811308Santhony.gutierrez@amd.com    virtual int outstandingCount() const = 0;
15911308Santhony.gutierrez@amd.com    virtual bool isDeadlockEventScheduled() const = 0;
16011308Santhony.gutierrez@amd.com    virtual void descheduleDeadlockEvent() = 0;
16111639Salexandru.dutu@amd.com
16211308Santhony.gutierrez@amd.com    //
16311308Santhony.gutierrez@amd.com    // Called by the controller to give the sequencer a pointer.
16411308Santhony.gutierrez@amd.com    // A pointer to the controller is needed for atomic support.
16511308Santhony.gutierrez@amd.com    //
16611308Santhony.gutierrez@amd.com    void setController(AbstractController* _cntrl) { m_controller = _cntrl; }
16711308Santhony.gutierrez@amd.com    uint32_t getId() { return m_version; }
16811308Santhony.gutierrez@amd.com    DrainState drain() override;
16911308Santhony.gutierrez@amd.com
17011308Santhony.gutierrez@amd.com    bool isCPUSequencer() { return m_isCPUSequencer; }
17111308Santhony.gutierrez@amd.com
17211308Santhony.gutierrez@amd.com  protected:
17311308Santhony.gutierrez@amd.com    void trySendRetries();
17411308Santhony.gutierrez@amd.com    void ruby_hit_callback(PacketPtr pkt);
17511308Santhony.gutierrez@amd.com    void testDrainComplete();
17611308Santhony.gutierrez@amd.com    void ruby_eviction_callback(Addr address);
17711308Santhony.gutierrez@amd.com
17811308Santhony.gutierrez@amd.com    /**
17911308Santhony.gutierrez@amd.com     * Called by the PIO port when receiving a timing response.
18011308Santhony.gutierrez@amd.com     *
18111308Santhony.gutierrez@amd.com     * @param pkt Response packet
18211308Santhony.gutierrez@amd.com     * @param master_port_id Port id of the PIO port
18311308Santhony.gutierrez@amd.com     *
18411308Santhony.gutierrez@amd.com     * @return Whether successfully sent
18511308Santhony.gutierrez@amd.com     */
18611308Santhony.gutierrez@amd.com    bool recvTimingResp(PacketPtr pkt, PortID master_port_id);
18711308Santhony.gutierrez@amd.com
18811308Santhony.gutierrez@amd.com    RubySystem *m_ruby_system;
18911308Santhony.gutierrez@amd.com    uint32_t m_version;
19011308Santhony.gutierrez@amd.com    AbstractController* m_controller;
19111308Santhony.gutierrez@amd.com    MessageBuffer* m_mandatory_q_ptr;
19211308Santhony.gutierrez@amd.com    bool m_usingRubyTester;
19311308Santhony.gutierrez@amd.com    System* system;
19411308Santhony.gutierrez@amd.com
19511308Santhony.gutierrez@amd.com  private:
19611308Santhony.gutierrez@amd.com    bool onRetryList(MemSlavePort * port)
19711308Santhony.gutierrez@amd.com    {
19811308Santhony.gutierrez@amd.com        return (std::find(retryList.begin(), retryList.end(), port) !=
19911308Santhony.gutierrez@amd.com                retryList.end());
20011308Santhony.gutierrez@amd.com    }
20111308Santhony.gutierrez@amd.com    void addToRetryList(MemSlavePort * port)
20211308Santhony.gutierrez@amd.com    {
20311308Santhony.gutierrez@amd.com        if (onRetryList(port)) return;
20411308Santhony.gutierrez@amd.com        retryList.push_back(port);
20511308Santhony.gutierrez@amd.com    }
20611308Santhony.gutierrez@amd.com
20711308Santhony.gutierrez@amd.com    PioMasterPort pioMasterPort;
20811308Santhony.gutierrez@amd.com    PioSlavePort pioSlavePort;
20911308Santhony.gutierrez@amd.com    MemMasterPort memMasterPort;
21011308Santhony.gutierrez@amd.com    MemSlavePort memSlavePort;
21111308Santhony.gutierrez@amd.com    unsigned int gotAddrRanges;
21211308Santhony.gutierrez@amd.com
21311308Santhony.gutierrez@amd.com    /** Vector of M5 Ports attached to this Ruby port. */
21411308Santhony.gutierrez@amd.com    typedef std::vector<MemSlavePort *>::iterator CpuPortIter;
21511308Santhony.gutierrez@amd.com    std::vector<MemSlavePort *> slave_ports;
21611308Santhony.gutierrez@amd.com    std::vector<PioMasterPort *> master_ports;
21711308Santhony.gutierrez@amd.com
21811308Santhony.gutierrez@amd.com    //
21911308Santhony.gutierrez@amd.com    // Based on similar code in the M5 bus.  Stores pointers to those ports
22011308Santhony.gutierrez@amd.com    // that should be called when the Sequencer becomes available after a stall.
22111308Santhony.gutierrez@amd.com    //
22211308Santhony.gutierrez@amd.com    std::vector<MemSlavePort *> retryList;
22311308Santhony.gutierrez@amd.com
22411308Santhony.gutierrez@amd.com    bool m_isCPUSequencer;
22511308Santhony.gutierrez@amd.com};
22611308Santhony.gutierrez@amd.com
22711308Santhony.gutierrez@amd.com#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__
22811308Santhony.gutierrez@amd.com