RubyPort.hh revision 10089:bc3126a05a7f
110859Sandreas.sandberg@arm.com/*
211840SCurtis.Dunham@arm.com * Copyright (c) 2012-2013 ARM Limited
310859Sandreas.sandberg@arm.com * All rights reserved.
410859Sandreas.sandberg@arm.com *
510859Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
610859Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
710859Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
810859Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
910859Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1010859Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1110859Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1210859Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1310859Sandreas.sandberg@arm.com *
1410859Sandreas.sandberg@arm.com * Copyright (c) 2009 Advanced Micro Devices, Inc.
1510859Sandreas.sandberg@arm.com * Copyright (c) 2011 Mark D. Hill and David A. Wood
1610859Sandreas.sandberg@arm.com * All rights reserved.
1710859Sandreas.sandberg@arm.com *
1810859Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1910859Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
2010859Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
2110859Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
2210859Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
2310859Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2410859Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2510859Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2610859Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2710859Sandreas.sandberg@arm.com * this software without specific prior written permission.
2810859Sandreas.sandberg@arm.com *
2910859Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3010859Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3110859Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3210859Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3310859Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3410859Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3510859Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3610859Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3710859Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3811840SCurtis.Dunham@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3910859Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4010859Sandreas.sandberg@arm.com */
4110859Sandreas.sandberg@arm.com
4210859Sandreas.sandberg@arm.com#ifndef __MEM_RUBY_SYSTEM_RUBYPORT_HH__
4310859Sandreas.sandberg@arm.com#define __MEM_RUBY_SYSTEM_RUBYPORT_HH__
4410859Sandreas.sandberg@arm.com
4511840SCurtis.Dunham@arm.com#include <cassert>
4610859Sandreas.sandberg@arm.com#include <string>
4710859Sandreas.sandberg@arm.com
4811840SCurtis.Dunham@arm.com#include "mem/protocol/RequestStatus.hh"
4910859Sandreas.sandberg@arm.com#include "mem/ruby/buffers/MessageBuffer.hh"
5011462Sandreas.sandberg@arm.com#include "mem/ruby/system/System.hh"
5111462Sandreas.sandberg@arm.com#include "mem/mem_object.hh"
5211461Sandreas.sandberg@arm.com#include "mem/physical.hh"
5311461Sandreas.sandberg@arm.com#include "mem/tport.hh"
5411461Sandreas.sandberg@arm.com#include "params/RubyPort.hh"
5511461Sandreas.sandberg@arm.com
5611461Sandreas.sandberg@arm.comclass AbstractController;
5711461Sandreas.sandberg@arm.com
5811461Sandreas.sandberg@arm.comclass RubyPort : public MemObject
5911461Sandreas.sandberg@arm.com{
6011461Sandreas.sandberg@arm.com  public:
6111462Sandreas.sandberg@arm.com    class M5Port : public QueuedSlavePort
6211462Sandreas.sandberg@arm.com    {
6311461Sandreas.sandberg@arm.com      private:
6411461Sandreas.sandberg@arm.com
6511461Sandreas.sandberg@arm.com        SlavePacketQueue queue;
6611461Sandreas.sandberg@arm.com        RubyPort *ruby_port;
6711461Sandreas.sandberg@arm.com        RubySystem* ruby_system;
6811461Sandreas.sandberg@arm.com        bool access_phys_mem;
6911461Sandreas.sandberg@arm.com
7011461Sandreas.sandberg@arm.com      public:
7111461Sandreas.sandberg@arm.com        M5Port(const std::string &_name, RubyPort *_port,
7211461Sandreas.sandberg@arm.com               RubySystem*_system, bool _access_phys_mem, PortID id);
7311461Sandreas.sandberg@arm.com        void hitCallback(PacketPtr pkt);
7411461Sandreas.sandberg@arm.com        void evictionCallback(const Address& address);
7511461Sandreas.sandberg@arm.com
7611461Sandreas.sandberg@arm.com      protected:
7711461Sandreas.sandberg@arm.com        bool recvTimingReq(PacketPtr pkt);
7811461Sandreas.sandberg@arm.com        Tick recvAtomic(PacketPtr pkt);
7911461Sandreas.sandberg@arm.com        void recvFunctional(PacketPtr pkt);
8011461Sandreas.sandberg@arm.com        AddrRangeList getAddrRanges() const;
8111461Sandreas.sandberg@arm.com
8211461Sandreas.sandberg@arm.com      private:
8311461Sandreas.sandberg@arm.com        bool isPhysMemAddress(Addr addr) const;
8411461Sandreas.sandberg@arm.com    };
8511461Sandreas.sandberg@arm.com
8611461Sandreas.sandberg@arm.com    class PioPort : public QueuedMasterPort
8711461Sandreas.sandberg@arm.com    {
8811461Sandreas.sandberg@arm.com      private:
8911461Sandreas.sandberg@arm.com
9011461Sandreas.sandberg@arm.com        MasterPacketQueue queue;
9111461Sandreas.sandberg@arm.com        RubyPort *ruby_port;
9211461Sandreas.sandberg@arm.com
9311461Sandreas.sandberg@arm.com      public:
9411461Sandreas.sandberg@arm.com        PioPort(const std::string &_name, RubyPort *_port);
9511461Sandreas.sandberg@arm.com
9611461Sandreas.sandberg@arm.com      protected:
9711461Sandreas.sandberg@arm.com        bool recvTimingResp(PacketPtr pkt)
9811461Sandreas.sandberg@arm.com        { return ruby_port->recvTimingResp(pkt, id); }
9911461Sandreas.sandberg@arm.com    };
10011461Sandreas.sandberg@arm.com
10111461Sandreas.sandberg@arm.com    typedef RubyPortParams Params;
10211461Sandreas.sandberg@arm.com    RubyPort(const Params *p);
10311461Sandreas.sandberg@arm.com    virtual ~RubyPort() {}
10411461Sandreas.sandberg@arm.com
10511461Sandreas.sandberg@arm.com    void init();
10611461Sandreas.sandberg@arm.com
10711461Sandreas.sandberg@arm.com    BaseMasterPort &getMasterPort(const std::string &if_name,
10811461Sandreas.sandberg@arm.com                                  PortID idx = InvalidPortID);
10910859Sandreas.sandberg@arm.com    BaseSlavePort &getSlavePort(const std::string &if_name,
11010859Sandreas.sandberg@arm.com                                PortID idx = InvalidPortID);
11110859Sandreas.sandberg@arm.com
11211839SCurtis.Dunham@arm.com    virtual RequestStatus makeRequest(PacketPtr pkt) = 0;
11311839SCurtis.Dunham@arm.com    virtual int outstandingCount() const = 0;
11411461Sandreas.sandberg@arm.com    virtual bool isDeadlockEventScheduled() const = 0;
11510859Sandreas.sandberg@arm.com    virtual void descheduleDeadlockEvent() = 0;
11610859Sandreas.sandberg@arm.com
11710859Sandreas.sandberg@arm.com    //
11810859Sandreas.sandberg@arm.com    // Called by the controller to give the sequencer a pointer.
11910859Sandreas.sandberg@arm.com    // A pointer to the controller is needed for atomic support.
12010859Sandreas.sandberg@arm.com    //
12110859Sandreas.sandberg@arm.com    void setController(AbstractController* _cntrl) { m_controller = _cntrl; }
12210859Sandreas.sandberg@arm.com    uint32_t getId() { return m_version; }
12310905Sandreas.sandberg@arm.com    unsigned int drain(DrainManager *dm);
12410859Sandreas.sandberg@arm.com
12510859Sandreas.sandberg@arm.com  protected:
12610859Sandreas.sandberg@arm.com    const std::string m_name;
12710859Sandreas.sandberg@arm.com    void ruby_hit_callback(PacketPtr pkt);
12810859Sandreas.sandberg@arm.com    void testDrainComplete();
12910905Sandreas.sandberg@arm.com    void ruby_eviction_callback(const Address& address);
13010859Sandreas.sandberg@arm.com
13110859Sandreas.sandberg@arm.com    /**
13210859Sandreas.sandberg@arm.com     * Called by the PIO port when receiving a timing response.
13310859Sandreas.sandberg@arm.com     *
13410859Sandreas.sandberg@arm.com     * @param pkt Response packet
13510859Sandreas.sandberg@arm.com     * @param master_port_id Port id of the PIO port
13610859Sandreas.sandberg@arm.com     *
13710859Sandreas.sandberg@arm.com     * @return Whether successfully sent
13810859Sandreas.sandberg@arm.com     */
13910859Sandreas.sandberg@arm.com    bool recvTimingResp(PacketPtr pkt, PortID master_port_id);
14010859Sandreas.sandberg@arm.com
14110859Sandreas.sandberg@arm.com    uint32_t m_version;
14210859Sandreas.sandberg@arm.com    AbstractController* m_controller;
14310859Sandreas.sandberg@arm.com    MessageBuffer* m_mandatory_q_ptr;
14410859Sandreas.sandberg@arm.com    PioPort pio_port;
14510859Sandreas.sandberg@arm.com    bool m_usingRubyTester;
14610859Sandreas.sandberg@arm.com
14710859Sandreas.sandberg@arm.com  private:
14810859Sandreas.sandberg@arm.com    void addToRetryList(M5Port * port)
14910859Sandreas.sandberg@arm.com    {
15011461Sandreas.sandberg@arm.com        assert(std::find(retryList.begin(), retryList.end(), port) ==
15110859Sandreas.sandberg@arm.com               retryList.end());
15210859Sandreas.sandberg@arm.com        retryList.push_back(port);
15310859Sandreas.sandberg@arm.com    }
15410859Sandreas.sandberg@arm.com
15510859Sandreas.sandberg@arm.com    unsigned int getChildDrainCount(DrainManager *dm);
15610859Sandreas.sandberg@arm.com
15711461Sandreas.sandberg@arm.com    /** Vector of M5 Ports attached to this Ruby port. */
15810859Sandreas.sandberg@arm.com    typedef std::vector<M5Port*>::iterator CpuPortIter;
15910859Sandreas.sandberg@arm.com    std::vector<M5Port*> slave_ports;
16010859Sandreas.sandberg@arm.com    std::vector<PioPort*> master_ports;
16110859Sandreas.sandberg@arm.com
16210859Sandreas.sandberg@arm.com    DrainManager *drainManager;
16310859Sandreas.sandberg@arm.com
16411461Sandreas.sandberg@arm.com    RubySystem* ruby_system;
16510859Sandreas.sandberg@arm.com    System* system;
16610859Sandreas.sandberg@arm.com
16710859Sandreas.sandberg@arm.com    //
16810859Sandreas.sandberg@arm.com    // Based on similar code in the M5 bus.  Stores pointers to those ports
16910859Sandreas.sandberg@arm.com    // that should be called when the Sequencer becomes available after a stall.
17010859Sandreas.sandberg@arm.com    //
17111461Sandreas.sandberg@arm.com    std::vector<M5Port*> retryList;
17210859Sandreas.sandberg@arm.com
17310859Sandreas.sandberg@arm.com    bool access_phys_mem;
17410859Sandreas.sandberg@arm.com};
17510859Sandreas.sandberg@arm.com
17610859Sandreas.sandberg@arm.com#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__
17710859Sandreas.sandberg@arm.com