RubyPort.hh revision 10467:dcf27c8220ac
110259SAndrew.Bardsley@arm.com/*
210259SAndrew.Bardsley@arm.com * Copyright (c) 2012-2013 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 * Copyright (c) 2009 Advanced Micro Devices, Inc.
1510259SAndrew.Bardsley@arm.com * Copyright (c) 2011 Mark D. Hill and David A. Wood
1610259SAndrew.Bardsley@arm.com * All rights reserved.
1710259SAndrew.Bardsley@arm.com *
1810259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without
1910259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are
2010259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright
2110259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer;
2210259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright
2310259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the
2410259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution;
2510259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its
2610259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from
2710259SAndrew.Bardsley@arm.com * this software without specific prior written permission.
2810259SAndrew.Bardsley@arm.com *
2910259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3010259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3110259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3210259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3310259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3410259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3510259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3610259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3710259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3810259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3910259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4010259SAndrew.Bardsley@arm.com */
4110259SAndrew.Bardsley@arm.com
4210259SAndrew.Bardsley@arm.com#ifndef __MEM_RUBY_SYSTEM_RUBYPORT_HH__
4310259SAndrew.Bardsley@arm.com#define __MEM_RUBY_SYSTEM_RUBYPORT_HH__
4410259SAndrew.Bardsley@arm.com
4510259SAndrew.Bardsley@arm.com#include <cassert>
4610259SAndrew.Bardsley@arm.com#include <string>
4710259SAndrew.Bardsley@arm.com
4810259SAndrew.Bardsley@arm.com#include "mem/protocol/RequestStatus.hh"
4910259SAndrew.Bardsley@arm.com#include "mem/ruby/network/MessageBuffer.hh"
5010259SAndrew.Bardsley@arm.com#include "mem/ruby/system/System.hh"
5110259SAndrew.Bardsley@arm.com#include "mem/mem_object.hh"
5210259SAndrew.Bardsley@arm.com#include "mem/tport.hh"
5310259SAndrew.Bardsley@arm.com#include "params/RubyPort.hh"
5410259SAndrew.Bardsley@arm.com
5510259SAndrew.Bardsley@arm.comclass AbstractController;
5610259SAndrew.Bardsley@arm.com
5710259SAndrew.Bardsley@arm.comclass RubyPort : public MemObject
5810259SAndrew.Bardsley@arm.com{
5910259SAndrew.Bardsley@arm.com  public:
6010259SAndrew.Bardsley@arm.com    class MemMasterPort : public QueuedMasterPort
6110259SAndrew.Bardsley@arm.com    {
6210259SAndrew.Bardsley@arm.com      private:
6310259SAndrew.Bardsley@arm.com        MasterPacketQueue queue;
6410259SAndrew.Bardsley@arm.com
6510259SAndrew.Bardsley@arm.com      public:
6610259SAndrew.Bardsley@arm.com        MemMasterPort(const std::string &_name, RubyPort *_port);
6710259SAndrew.Bardsley@arm.com
6810259SAndrew.Bardsley@arm.com      protected:
6910259SAndrew.Bardsley@arm.com        bool recvTimingResp(PacketPtr pkt);
7010259SAndrew.Bardsley@arm.com        void recvRangeChange() {}
7110259SAndrew.Bardsley@arm.com    };
7210259SAndrew.Bardsley@arm.com
7310259SAndrew.Bardsley@arm.com    class MemSlavePort : public QueuedSlavePort
7410259SAndrew.Bardsley@arm.com    {
7510259SAndrew.Bardsley@arm.com      private:
7610259SAndrew.Bardsley@arm.com
7710259SAndrew.Bardsley@arm.com        SlavePacketQueue queue;
7810259SAndrew.Bardsley@arm.com        RubySystem* ruby_system;
7910259SAndrew.Bardsley@arm.com        bool access_phys_mem;
8010259SAndrew.Bardsley@arm.com
8110259SAndrew.Bardsley@arm.com      public:
8210259SAndrew.Bardsley@arm.com        MemSlavePort(const std::string &_name, RubyPort *_port,
8310259SAndrew.Bardsley@arm.com               RubySystem*_system, bool _access_phys_mem, PortID id);
8410259SAndrew.Bardsley@arm.com        void hitCallback(PacketPtr pkt);
8510259SAndrew.Bardsley@arm.com        void evictionCallback(const Address& address);
8610259SAndrew.Bardsley@arm.com
8710259SAndrew.Bardsley@arm.com      protected:
8810259SAndrew.Bardsley@arm.com        bool recvTimingReq(PacketPtr pkt);
8910259SAndrew.Bardsley@arm.com
9010259SAndrew.Bardsley@arm.com        Tick recvAtomic(PacketPtr pkt)
9110259SAndrew.Bardsley@arm.com        { panic("RubyPort::MemSlavePort::recvAtomic() not implemented!\n"); }
9210259SAndrew.Bardsley@arm.com
9310259SAndrew.Bardsley@arm.com        void recvFunctional(PacketPtr pkt);
9410259SAndrew.Bardsley@arm.com
9510259SAndrew.Bardsley@arm.com        AddrRangeList getAddrRanges() const
9610259SAndrew.Bardsley@arm.com        { AddrRangeList ranges; return ranges; }
9710259SAndrew.Bardsley@arm.com
9810259SAndrew.Bardsley@arm.com      private:
9910259SAndrew.Bardsley@arm.com        bool isPhysMemAddress(Addr addr) const;
10010259SAndrew.Bardsley@arm.com    };
10110259SAndrew.Bardsley@arm.com
10210259SAndrew.Bardsley@arm.com    class PioMasterPort : public QueuedMasterPort
10310259SAndrew.Bardsley@arm.com    {
10410259SAndrew.Bardsley@arm.com      private:
10510259SAndrew.Bardsley@arm.com        MasterPacketQueue queue;
10610259SAndrew.Bardsley@arm.com
10710259SAndrew.Bardsley@arm.com      public:
10810259SAndrew.Bardsley@arm.com        PioMasterPort(const std::string &_name, RubyPort *_port);
10910259SAndrew.Bardsley@arm.com
11010259SAndrew.Bardsley@arm.com      protected:
11110259SAndrew.Bardsley@arm.com        bool recvTimingResp(PacketPtr pkt);
11210259SAndrew.Bardsley@arm.com        void recvRangeChange();
11310259SAndrew.Bardsley@arm.com    };
11410259SAndrew.Bardsley@arm.com
11510259SAndrew.Bardsley@arm.com    class PioSlavePort : public QueuedSlavePort
11610259SAndrew.Bardsley@arm.com    {
11710259SAndrew.Bardsley@arm.com      private:
11810259SAndrew.Bardsley@arm.com        SlavePacketQueue queue;
11910259SAndrew.Bardsley@arm.com
12010259SAndrew.Bardsley@arm.com      public:
12110259SAndrew.Bardsley@arm.com        PioSlavePort(const std::string &_name, RubyPort *_port);
12210259SAndrew.Bardsley@arm.com
12310259SAndrew.Bardsley@arm.com      protected:
12410259SAndrew.Bardsley@arm.com        bool recvTimingReq(PacketPtr pkt);
12510259SAndrew.Bardsley@arm.com
12610259SAndrew.Bardsley@arm.com        Tick recvAtomic(PacketPtr pkt)
12710259SAndrew.Bardsley@arm.com        { panic("recvAtomic not supported with ruby!"); }
12810259SAndrew.Bardsley@arm.com
12910259SAndrew.Bardsley@arm.com        void recvFunctional(PacketPtr pkt)
13010259SAndrew.Bardsley@arm.com        { panic("recvFunctional should never be called on pio slave port!"); }
13110259SAndrew.Bardsley@arm.com
13210259SAndrew.Bardsley@arm.com        AddrRangeList getAddrRanges() const;
13310259SAndrew.Bardsley@arm.com    };
13410259SAndrew.Bardsley@arm.com
13510259SAndrew.Bardsley@arm.com    struct SenderState : public Packet::SenderState
13610259SAndrew.Bardsley@arm.com    {
13710259SAndrew.Bardsley@arm.com        MemSlavePort *port;
13810259SAndrew.Bardsley@arm.com        SenderState(MemSlavePort * _port) : port(_port)
13910259SAndrew.Bardsley@arm.com        {}
14010259SAndrew.Bardsley@arm.com     };
14110259SAndrew.Bardsley@arm.com
14210259SAndrew.Bardsley@arm.com    typedef RubyPortParams Params;
14310259SAndrew.Bardsley@arm.com    RubyPort(const Params *p);
14410259SAndrew.Bardsley@arm.com    virtual ~RubyPort() {}
14510259SAndrew.Bardsley@arm.com
14610259SAndrew.Bardsley@arm.com    void init();
14710259SAndrew.Bardsley@arm.com
14810259SAndrew.Bardsley@arm.com    BaseMasterPort &getMasterPort(const std::string &if_name,
14910259SAndrew.Bardsley@arm.com                                  PortID idx = InvalidPortID);
15010259SAndrew.Bardsley@arm.com    BaseSlavePort &getSlavePort(const std::string &if_name,
15110259SAndrew.Bardsley@arm.com                                PortID idx = InvalidPortID);
15210259SAndrew.Bardsley@arm.com
15310259SAndrew.Bardsley@arm.com    virtual RequestStatus makeRequest(PacketPtr pkt) = 0;
15410259SAndrew.Bardsley@arm.com    virtual int outstandingCount() const = 0;
15510259SAndrew.Bardsley@arm.com    virtual bool isDeadlockEventScheduled() const = 0;
15610259SAndrew.Bardsley@arm.com    virtual void descheduleDeadlockEvent() = 0;
15710259SAndrew.Bardsley@arm.com
15810259SAndrew.Bardsley@arm.com    //
15910259SAndrew.Bardsley@arm.com    // Called by the controller to give the sequencer a pointer.
16010259SAndrew.Bardsley@arm.com    // A pointer to the controller is needed for atomic support.
16110259SAndrew.Bardsley@arm.com    //
16210259SAndrew.Bardsley@arm.com    void setController(AbstractController* _cntrl) { m_controller = _cntrl; }
16310259SAndrew.Bardsley@arm.com    uint32_t getId() { return m_version; }
16410259SAndrew.Bardsley@arm.com    unsigned int drain(DrainManager *dm);
16510259SAndrew.Bardsley@arm.com
16610259SAndrew.Bardsley@arm.com  protected:
16710259SAndrew.Bardsley@arm.com    void ruby_hit_callback(PacketPtr pkt);
16810259SAndrew.Bardsley@arm.com    void testDrainComplete();
16910259SAndrew.Bardsley@arm.com    void ruby_eviction_callback(const Address& address);
17010259SAndrew.Bardsley@arm.com
17110259SAndrew.Bardsley@arm.com    /**
17210259SAndrew.Bardsley@arm.com     * Called by the PIO port when receiving a timing response.
17310259SAndrew.Bardsley@arm.com     *
17410259SAndrew.Bardsley@arm.com     * @param pkt Response packet
17510259SAndrew.Bardsley@arm.com     * @param master_port_id Port id of the PIO port
17610259SAndrew.Bardsley@arm.com     *
17710259SAndrew.Bardsley@arm.com     * @return Whether successfully sent
17810259SAndrew.Bardsley@arm.com     */
17910259SAndrew.Bardsley@arm.com    bool recvTimingResp(PacketPtr pkt, PortID master_port_id);
18010259SAndrew.Bardsley@arm.com
18110259SAndrew.Bardsley@arm.com    uint32_t m_version;
18210259SAndrew.Bardsley@arm.com    AbstractController* m_controller;
18310259SAndrew.Bardsley@arm.com    MessageBuffer* m_mandatory_q_ptr;
18410259SAndrew.Bardsley@arm.com    bool m_usingRubyTester;
18510259SAndrew.Bardsley@arm.com    System* system;
18610259SAndrew.Bardsley@arm.com
18710259SAndrew.Bardsley@arm.com  private:
18810259SAndrew.Bardsley@arm.com    void addToRetryList(MemSlavePort * port)
18910259SAndrew.Bardsley@arm.com    {
19010259SAndrew.Bardsley@arm.com        assert(std::find(retryList.begin(), retryList.end(), port) ==
19110259SAndrew.Bardsley@arm.com               retryList.end());
19210259SAndrew.Bardsley@arm.com        retryList.push_back(port);
19310259SAndrew.Bardsley@arm.com    }
19410259SAndrew.Bardsley@arm.com
19510259SAndrew.Bardsley@arm.com    unsigned int getChildDrainCount(DrainManager *dm);
19610259SAndrew.Bardsley@arm.com
19710259SAndrew.Bardsley@arm.com    PioMasterPort pioMasterPort;
19810259SAndrew.Bardsley@arm.com    PioSlavePort pioSlavePort;
19910259SAndrew.Bardsley@arm.com    MemMasterPort memMasterPort;
20010259SAndrew.Bardsley@arm.com    MemSlavePort memSlavePort;
20110259SAndrew.Bardsley@arm.com    unsigned int gotAddrRanges;
20210259SAndrew.Bardsley@arm.com
20310259SAndrew.Bardsley@arm.com    /** Vector of M5 Ports attached to this Ruby port. */
20410259SAndrew.Bardsley@arm.com    typedef std::vector<MemSlavePort *>::iterator CpuPortIter;
20510259SAndrew.Bardsley@arm.com    std::vector<MemSlavePort *> slave_ports;
20610259SAndrew.Bardsley@arm.com    std::vector<PioMasterPort *> master_ports;
20710259SAndrew.Bardsley@arm.com
20810259SAndrew.Bardsley@arm.com    DrainManager *drainManager;
20910259SAndrew.Bardsley@arm.com
21010259SAndrew.Bardsley@arm.com    //
21110259SAndrew.Bardsley@arm.com    // Based on similar code in the M5 bus.  Stores pointers to those ports
21210259SAndrew.Bardsley@arm.com    // that should be called when the Sequencer becomes available after a stall.
21310259SAndrew.Bardsley@arm.com    //
21410259SAndrew.Bardsley@arm.com    std::vector<MemSlavePort *> retryList;
21510259SAndrew.Bardsley@arm.com
21610259SAndrew.Bardsley@arm.com    bool access_phys_mem;
21710259SAndrew.Bardsley@arm.com};
21810259SAndrew.Bardsley@arm.com
21910259SAndrew.Bardsley@arm.com#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__
22010259SAndrew.Bardsley@arm.com