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