16876Ssteve.reinhardt@amd.com/* 210089Sandreas.hansson@arm.com * Copyright (c) 2012-2013 ARM Limited 38922Swilliam.wang@arm.com * All rights reserved. 48922Swilliam.wang@arm.com * 58922Swilliam.wang@arm.com * The license below extends only to copyright in the software and shall 68922Swilliam.wang@arm.com * not be construed as granting a license to any other intellectual 78922Swilliam.wang@arm.com * property including but not limited to intellectual property relating 88922Swilliam.wang@arm.com * to a hardware implementation of the functionality of the software 98922Swilliam.wang@arm.com * licensed hereunder. You may use the software subject to the license 108922Swilliam.wang@arm.com * terms below provided that you ensure that this notice is replicated 118922Swilliam.wang@arm.com * unmodified and in its entirety in all distributions of the software, 128922Swilliam.wang@arm.com * modified or unmodified, in source code or in binary form. 138922Swilliam.wang@arm.com * 1411266SBrad.Beckmann@amd.com * Copyright (c) 2009-2013 Advanced Micro Devices, Inc. 158717Snilay@cs.wisc.edu * Copyright (c) 2011 Mark D. Hill and David A. Wood 166876Ssteve.reinhardt@amd.com * All rights reserved. 176876Ssteve.reinhardt@amd.com * 186876Ssteve.reinhardt@amd.com * Redistribution and use in source and binary forms, with or without 196876Ssteve.reinhardt@amd.com * modification, are permitted provided that the following conditions are 206876Ssteve.reinhardt@amd.com * met: redistributions of source code must retain the above copyright 216876Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer; 226876Ssteve.reinhardt@amd.com * redistributions in binary form must reproduce the above copyright 236876Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer in the 246876Ssteve.reinhardt@amd.com * documentation and/or other materials provided with the distribution; 256876Ssteve.reinhardt@amd.com * neither the name of the copyright holders nor the names of its 266876Ssteve.reinhardt@amd.com * contributors may be used to endorse or promote products derived from 276876Ssteve.reinhardt@amd.com * this software without specific prior written permission. 286876Ssteve.reinhardt@amd.com * 296876Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 306876Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316876Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 326876Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 336876Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 346876Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 356876Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 366876Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 376876Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 386876Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 396876Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 406876Ssteve.reinhardt@amd.com */ 416876Ssteve.reinhardt@amd.com 427039Snate@binkert.org#ifndef __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 437039Snate@binkert.org#define __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 446285Snate@binkert.org 457039Snate@binkert.org#include <cassert> 466285Snate@binkert.org#include <string> 476285Snate@binkert.org 4812395Sswapnilster@gmail.com#include "mem/ruby/common/MachineID.hh" 4910301Snilay@cs.wisc.edu#include "mem/ruby/network/MessageBuffer.hh" 5014184Sgabeblack@google.com#include "mem/ruby/protocol/RequestStatus.hh" 5111108Sdavid.hashe@amd.com#include "mem/ruby/system/RubySystem.hh" 527039Snate@binkert.org#include "mem/tport.hh" 536876Ssteve.reinhardt@amd.com#include "params/RubyPort.hh" 5413892Sgabeblack@google.com#include "sim/clocked_object.hh" 556876Ssteve.reinhardt@amd.com 566876Ssteve.reinhardt@amd.comclass AbstractController; 576876Ssteve.reinhardt@amd.com 5813892Sgabeblack@google.comclass RubyPort : public ClockedObject 597039Snate@binkert.org{ 607039Snate@binkert.org public: 6110090Snilay@cs.wisc.edu class MemMasterPort : public QueuedMasterPort 6210090Snilay@cs.wisc.edu { 6310090Snilay@cs.wisc.edu private: 6410713Sandreas.hansson@arm.com ReqPacketQueue reqQueue; 6510713Sandreas.hansson@arm.com SnoopRespPacketQueue snoopRespQueue; 6610090Snilay@cs.wisc.edu 6710090Snilay@cs.wisc.edu public: 6810090Snilay@cs.wisc.edu MemMasterPort(const std::string &_name, RubyPort *_port); 6910090Snilay@cs.wisc.edu 7010090Snilay@cs.wisc.edu protected: 7110090Snilay@cs.wisc.edu bool recvTimingResp(PacketPtr pkt); 7210090Snilay@cs.wisc.edu void recvRangeChange() {} 7310090Snilay@cs.wisc.edu }; 7410090Snilay@cs.wisc.edu 7510090Snilay@cs.wisc.edu class MemSlavePort : public QueuedSlavePort 766882SBrad.Beckmann@amd.com { 777039Snate@binkert.org private: 7810713Sandreas.hansson@arm.com RespPacketQueue queue; 7910525Snilay@cs.wisc.edu bool access_backing_store; 8011266SBrad.Beckmann@amd.com bool no_retry_on_stall; 816882SBrad.Beckmann@amd.com 826882SBrad.Beckmann@amd.com public: 8310090Snilay@cs.wisc.edu MemSlavePort(const std::string &_name, RubyPort *_port, 8411266SBrad.Beckmann@amd.com bool _access_backing_store, 8511266SBrad.Beckmann@amd.com PortID id, bool _no_retry_on_stall); 866882SBrad.Beckmann@amd.com void hitCallback(PacketPtr pkt); 8711025Snilay@cs.wisc.edu void evictionCallback(Addr address); 886882SBrad.Beckmann@amd.com 896882SBrad.Beckmann@amd.com protected: 9010089Sandreas.hansson@arm.com bool recvTimingReq(PacketPtr pkt); 9110090Snilay@cs.wisc.edu 9212395Sswapnilster@gmail.com Tick recvAtomic(PacketPtr pkt); 9310090Snilay@cs.wisc.edu 9410089Sandreas.hansson@arm.com void recvFunctional(PacketPtr pkt); 9510090Snilay@cs.wisc.edu 9610090Snilay@cs.wisc.edu AddrRangeList getAddrRanges() const 9710090Snilay@cs.wisc.edu { AddrRangeList ranges; return ranges; } 986882SBrad.Beckmann@amd.com 9911266SBrad.Beckmann@amd.com void addToRetryList(); 10011266SBrad.Beckmann@amd.com 1016882SBrad.Beckmann@amd.com private: 10210089Sandreas.hansson@arm.com bool isPhysMemAddress(Addr addr) const; 1036882SBrad.Beckmann@amd.com }; 1046882SBrad.Beckmann@amd.com 10510090Snilay@cs.wisc.edu class PioMasterPort : public QueuedMasterPort 1066882SBrad.Beckmann@amd.com { 1077039Snate@binkert.org private: 10810713Sandreas.hansson@arm.com ReqPacketQueue reqQueue; 10910713Sandreas.hansson@arm.com SnoopRespPacketQueue snoopRespQueue; 1108914Sandreas.hansson@arm.com 1116882SBrad.Beckmann@amd.com public: 11210090Snilay@cs.wisc.edu PioMasterPort(const std::string &_name, RubyPort *_port); 1136882SBrad.Beckmann@amd.com 1146882SBrad.Beckmann@amd.com protected: 11510090Snilay@cs.wisc.edu bool recvTimingResp(PacketPtr pkt); 11610090Snilay@cs.wisc.edu void recvRangeChange(); 1176882SBrad.Beckmann@amd.com }; 1186882SBrad.Beckmann@amd.com 11910090Snilay@cs.wisc.edu class PioSlavePort : public QueuedSlavePort 12010090Snilay@cs.wisc.edu { 12110090Snilay@cs.wisc.edu private: 12210713Sandreas.hansson@arm.com RespPacketQueue queue; 12310090Snilay@cs.wisc.edu 12410090Snilay@cs.wisc.edu public: 12510090Snilay@cs.wisc.edu PioSlavePort(const std::string &_name, RubyPort *_port); 12610090Snilay@cs.wisc.edu 12710090Snilay@cs.wisc.edu protected: 12810090Snilay@cs.wisc.edu bool recvTimingReq(PacketPtr pkt); 12910090Snilay@cs.wisc.edu 13012395Sswapnilster@gmail.com Tick recvAtomic(PacketPtr pkt); 13110090Snilay@cs.wisc.edu 13210090Snilay@cs.wisc.edu void recvFunctional(PacketPtr pkt) 13310090Snilay@cs.wisc.edu { panic("recvFunctional should never be called on pio slave port!"); } 13410090Snilay@cs.wisc.edu 13510090Snilay@cs.wisc.edu AddrRangeList getAddrRanges() const; 13610090Snilay@cs.wisc.edu }; 13710090Snilay@cs.wisc.edu 13810090Snilay@cs.wisc.edu struct SenderState : public Packet::SenderState 13910090Snilay@cs.wisc.edu { 14010090Snilay@cs.wisc.edu MemSlavePort *port; 14110090Snilay@cs.wisc.edu SenderState(MemSlavePort * _port) : port(_port) 14210090Snilay@cs.wisc.edu {} 14310090Snilay@cs.wisc.edu }; 14410090Snilay@cs.wisc.edu 1456876Ssteve.reinhardt@amd.com typedef RubyPortParams Params; 1466876Ssteve.reinhardt@amd.com RubyPort(const Params *p); 1476882SBrad.Beckmann@amd.com virtual ~RubyPort() {} 1486882SBrad.Beckmann@amd.com 14911169Sandreas.hansson@arm.com void init() override; 1506285Snate@binkert.org 15113784Sgabeblack@google.com Port &getPort(const std::string &if_name, 15213784Sgabeblack@google.com PortID idx=InvalidPortID) override; 1536876Ssteve.reinhardt@amd.com 1548615Snilay@cs.wisc.edu virtual RequestStatus makeRequest(PacketPtr pkt) = 0; 1558688Snilay@cs.wisc.edu virtual int outstandingCount() const = 0; 1568688Snilay@cs.wisc.edu virtual bool isDeadlockEventScheduled() const = 0; 1578688Snilay@cs.wisc.edu virtual void descheduleDeadlockEvent() = 0; 1586882SBrad.Beckmann@amd.com 1596882SBrad.Beckmann@amd.com // 1606882SBrad.Beckmann@amd.com // Called by the controller to give the sequencer a pointer. 1616882SBrad.Beckmann@amd.com // A pointer to the controller is needed for atomic support. 1626882SBrad.Beckmann@amd.com // 1636882SBrad.Beckmann@amd.com void setController(AbstractController* _cntrl) { m_controller = _cntrl; } 16410012Snilay@cs.wisc.edu uint32_t getId() { return m_version; } 16511168Sandreas.hansson@arm.com DrainState drain() override; 1666285Snate@binkert.org 16711308Santhony.gutierrez@amd.com bool isCPUSequencer() { return m_isCPUSequencer; } 16811308Santhony.gutierrez@amd.com 1697039Snate@binkert.org protected: 17011266SBrad.Beckmann@amd.com void trySendRetries(); 1717039Snate@binkert.org void ruby_hit_callback(PacketPtr pkt); 1728688Snilay@cs.wisc.edu void testDrainComplete(); 17311025Snilay@cs.wisc.edu void ruby_eviction_callback(Addr address); 1746285Snate@binkert.org 17510089Sandreas.hansson@arm.com /** 17610089Sandreas.hansson@arm.com * Called by the PIO port when receiving a timing response. 17710089Sandreas.hansson@arm.com * 17810089Sandreas.hansson@arm.com * @param pkt Response packet 17910089Sandreas.hansson@arm.com * @param master_port_id Port id of the PIO port 18010089Sandreas.hansson@arm.com * 18110089Sandreas.hansson@arm.com * @return Whether successfully sent 18210089Sandreas.hansson@arm.com */ 18310089Sandreas.hansson@arm.com bool recvTimingResp(PacketPtr pkt, PortID master_port_id); 18410089Sandreas.hansson@arm.com 18510919Sbrandon.potter@amd.com RubySystem *m_ruby_system; 18610012Snilay@cs.wisc.edu uint32_t m_version; 1877039Snate@binkert.org AbstractController* m_controller; 1887039Snate@binkert.org MessageBuffer* m_mandatory_q_ptr; 1897910SBrad.Beckmann@amd.com bool m_usingRubyTester; 19010467Sandreas.hansson@arm.com System* system; 1916876Ssteve.reinhardt@amd.com 19211346Santhony.gutierrez@amd.com std::vector<MemSlavePort *> slave_ports; 19311346Santhony.gutierrez@amd.com 1947039Snate@binkert.org private: 19511266SBrad.Beckmann@amd.com bool onRetryList(MemSlavePort * port) 19611266SBrad.Beckmann@amd.com { 19711266SBrad.Beckmann@amd.com return (std::find(retryList.begin(), retryList.end(), port) != 19811266SBrad.Beckmann@amd.com retryList.end()); 19911266SBrad.Beckmann@amd.com } 20010090Snilay@cs.wisc.edu void addToRetryList(MemSlavePort * port) 2017910SBrad.Beckmann@amd.com { 20211266SBrad.Beckmann@amd.com if (onRetryList(port)) return; 20310089Sandreas.hansson@arm.com retryList.push_back(port); 2047910SBrad.Beckmann@amd.com } 2057910SBrad.Beckmann@amd.com 20610090Snilay@cs.wisc.edu PioMasterPort pioMasterPort; 20710090Snilay@cs.wisc.edu PioSlavePort pioSlavePort; 20810090Snilay@cs.wisc.edu MemMasterPort memMasterPort; 20910090Snilay@cs.wisc.edu MemSlavePort memSlavePort; 21010090Snilay@cs.wisc.edu unsigned int gotAddrRanges; 21110090Snilay@cs.wisc.edu 2128922Swilliam.wang@arm.com /** Vector of M5 Ports attached to this Ruby port. */ 21310090Snilay@cs.wisc.edu typedef std::vector<MemSlavePort *>::iterator CpuPortIter; 21410090Snilay@cs.wisc.edu std::vector<PioMasterPort *> master_ports; 2158686Snilay@cs.wisc.edu 2167910SBrad.Beckmann@amd.com // 2177910SBrad.Beckmann@amd.com // Based on similar code in the M5 bus. Stores pointers to those ports 2187910SBrad.Beckmann@amd.com // that should be called when the Sequencer becomes available after a stall. 2197910SBrad.Beckmann@amd.com // 22010090Snilay@cs.wisc.edu std::vector<MemSlavePort *> retryList; 22111308Santhony.gutierrez@amd.com 22211308Santhony.gutierrez@amd.com bool m_isCPUSequencer; 2236285Snate@binkert.org}; 2246285Snate@binkert.org 2257039Snate@binkert.org#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 226