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