RubyPort.hh revision 8717
16876Ssteve.reinhardt@amd.com/* 26876Ssteve.reinhardt@amd.com * Copyright (c) 2009 Advanced Micro Devices, Inc. 38717Snilay@cs.wisc.edu * Copyright (c) 2011 Mark D. Hill and David A. Wood 46876Ssteve.reinhardt@amd.com * All rights reserved. 56876Ssteve.reinhardt@amd.com * 66876Ssteve.reinhardt@amd.com * Redistribution and use in source and binary forms, with or without 76876Ssteve.reinhardt@amd.com * modification, are permitted provided that the following conditions are 86876Ssteve.reinhardt@amd.com * met: redistributions of source code must retain the above copyright 96876Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer; 106876Ssteve.reinhardt@amd.com * redistributions in binary form must reproduce the above copyright 116876Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer in the 126876Ssteve.reinhardt@amd.com * documentation and/or other materials provided with the distribution; 136876Ssteve.reinhardt@amd.com * neither the name of the copyright holders nor the names of its 146876Ssteve.reinhardt@amd.com * contributors may be used to endorse or promote products derived from 156876Ssteve.reinhardt@amd.com * this software without specific prior written permission. 166876Ssteve.reinhardt@amd.com * 176876Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186876Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196876Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206876Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216876Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226876Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236876Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246876Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256876Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266876Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276876Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286876Ssteve.reinhardt@amd.com */ 296876Ssteve.reinhardt@amd.com 307039Snate@binkert.org#ifndef __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 317039Snate@binkert.org#define __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 326285Snate@binkert.org 337039Snate@binkert.org#include <cassert> 346285Snate@binkert.org#include <string> 356285Snate@binkert.org 366922SBrad.Beckmann@amd.com#include "mem/protocol/RequestStatus.hh" 377909Shestness@cs.utexas.edu#include "mem/ruby/system/System.hh" 388229Snate@binkert.org#include "mem/mem_object.hh" 398229Snate@binkert.org#include "mem/physical.hh" 407039Snate@binkert.org#include "mem/tport.hh" 416876Ssteve.reinhardt@amd.com#include "params/RubyPort.hh" 426876Ssteve.reinhardt@amd.com 436876Ssteve.reinhardt@amd.comclass MessageBuffer; 446876Ssteve.reinhardt@amd.comclass AbstractController; 456876Ssteve.reinhardt@amd.com 467039Snate@binkert.orgclass RubyPort : public MemObject 477039Snate@binkert.org{ 487039Snate@binkert.org public: 496882SBrad.Beckmann@amd.com class M5Port : public SimpleTimingPort 506882SBrad.Beckmann@amd.com { 517039Snate@binkert.org private: 526882SBrad.Beckmann@amd.com RubyPort *ruby_port; 538436SBrad.Beckmann@amd.com RubySystem* ruby_system; 547910SBrad.Beckmann@amd.com bool _onRetryList; 557915SBrad.Beckmann@amd.com bool access_phys_mem; 566882SBrad.Beckmann@amd.com 576882SBrad.Beckmann@amd.com public: 587915SBrad.Beckmann@amd.com M5Port(const std::string &_name, RubyPort *_port, 598436SBrad.Beckmann@amd.com RubySystem*_system, bool _access_phys_mem); 606882SBrad.Beckmann@amd.com bool sendTiming(PacketPtr pkt); 616882SBrad.Beckmann@amd.com void hitCallback(PacketPtr pkt); 628717Snilay@cs.wisc.edu void evictionCallback(const Address& address); 637909Shestness@cs.utexas.edu unsigned deviceBlockSize() const; 647910SBrad.Beckmann@amd.com 657910SBrad.Beckmann@amd.com bool onRetryList() 667910SBrad.Beckmann@amd.com { return _onRetryList; } 677910SBrad.Beckmann@amd.com 687910SBrad.Beckmann@amd.com void onRetryList(bool newVal) 697910SBrad.Beckmann@amd.com { _onRetryList = newVal; } 706882SBrad.Beckmann@amd.com 716882SBrad.Beckmann@amd.com protected: 726882SBrad.Beckmann@amd.com virtual bool recvTiming(PacketPtr pkt); 736882SBrad.Beckmann@amd.com virtual Tick recvAtomic(PacketPtr pkt); 748436SBrad.Beckmann@amd.com virtual void recvFunctional(PacketPtr pkt); 756882SBrad.Beckmann@amd.com 766882SBrad.Beckmann@amd.com private: 776882SBrad.Beckmann@amd.com bool isPhysMemAddress(Addr addr); 788436SBrad.Beckmann@amd.com bool doFunctionalRead(PacketPtr pkt); 798436SBrad.Beckmann@amd.com bool doFunctionalWrite(PacketPtr pkt); 806882SBrad.Beckmann@amd.com }; 816882SBrad.Beckmann@amd.com 826882SBrad.Beckmann@amd.com friend class M5Port; 836882SBrad.Beckmann@amd.com 846882SBrad.Beckmann@amd.com class PioPort : public SimpleTimingPort 856882SBrad.Beckmann@amd.com { 867039Snate@binkert.org private: 876882SBrad.Beckmann@amd.com RubyPort *ruby_port; 886882SBrad.Beckmann@amd.com 896882SBrad.Beckmann@amd.com public: 907039Snate@binkert.org PioPort(const std::string &_name, RubyPort *_port); 916882SBrad.Beckmann@amd.com bool sendTiming(PacketPtr pkt); 926882SBrad.Beckmann@amd.com 936882SBrad.Beckmann@amd.com protected: 946882SBrad.Beckmann@amd.com virtual bool recvTiming(PacketPtr pkt); 956882SBrad.Beckmann@amd.com virtual Tick recvAtomic(PacketPtr pkt); 966882SBrad.Beckmann@amd.com }; 976882SBrad.Beckmann@amd.com 986882SBrad.Beckmann@amd.com friend class PioPort; 996882SBrad.Beckmann@amd.com 1006882SBrad.Beckmann@amd.com struct SenderState : public Packet::SenderState 1016882SBrad.Beckmann@amd.com { 1026882SBrad.Beckmann@amd.com M5Port* port; 1036882SBrad.Beckmann@amd.com Packet::SenderState *saved; 1046882SBrad.Beckmann@amd.com 1057039Snate@binkert.org SenderState(M5Port* _port, Packet::SenderState *sender_state = NULL) 1066882SBrad.Beckmann@amd.com : port(_port), saved(sender_state) 1076882SBrad.Beckmann@amd.com {} 1086882SBrad.Beckmann@amd.com }; 1096882SBrad.Beckmann@amd.com 1106876Ssteve.reinhardt@amd.com typedef RubyPortParams Params; 1116876Ssteve.reinhardt@amd.com RubyPort(const Params *p); 1126882SBrad.Beckmann@amd.com virtual ~RubyPort() {} 1136882SBrad.Beckmann@amd.com 1146882SBrad.Beckmann@amd.com void init(); 1156285Snate@binkert.org 1166876Ssteve.reinhardt@amd.com Port *getPort(const std::string &if_name, int idx); 1176876Ssteve.reinhardt@amd.com 1188615Snilay@cs.wisc.edu virtual RequestStatus makeRequest(PacketPtr pkt) = 0; 1198688Snilay@cs.wisc.edu virtual int outstandingCount() const = 0; 1208688Snilay@cs.wisc.edu virtual bool isDeadlockEventScheduled() const = 0; 1218688Snilay@cs.wisc.edu virtual void descheduleDeadlockEvent() = 0; 1226882SBrad.Beckmann@amd.com 1236882SBrad.Beckmann@amd.com // 1246882SBrad.Beckmann@amd.com // Called by the controller to give the sequencer a pointer. 1256882SBrad.Beckmann@amd.com // A pointer to the controller is needed for atomic support. 1266882SBrad.Beckmann@amd.com // 1276882SBrad.Beckmann@amd.com void setController(AbstractController* _cntrl) { m_controller = _cntrl; } 1288688Snilay@cs.wisc.edu int getId() { return m_version; } 1298688Snilay@cs.wisc.edu unsigned int drain(Event *de); 1306285Snate@binkert.org 1317039Snate@binkert.org protected: 1327055Snate@binkert.org const std::string m_name; 1337039Snate@binkert.org void ruby_hit_callback(PacketPtr pkt); 1348688Snilay@cs.wisc.edu void testDrainComplete(); 1358717Snilay@cs.wisc.edu void ruby_eviction_callback(const Address& address); 1366285Snate@binkert.org 1377039Snate@binkert.org int m_version; 1387039Snate@binkert.org AbstractController* m_controller; 1397039Snate@binkert.org MessageBuffer* m_mandatory_q_ptr; 1406882SBrad.Beckmann@amd.com PioPort* pio_port; 1417910SBrad.Beckmann@amd.com bool m_usingRubyTester; 1426876Ssteve.reinhardt@amd.com 1437039Snate@binkert.org private: 1447910SBrad.Beckmann@amd.com void addToRetryList(M5Port * port) 1457910SBrad.Beckmann@amd.com { 1467910SBrad.Beckmann@amd.com if (!port->onRetryList()) { 1477910SBrad.Beckmann@amd.com port->onRetryList(true); 1487910SBrad.Beckmann@amd.com retryList.push_back(port); 1497910SBrad.Beckmann@amd.com waitingOnSequencer = true; 1507910SBrad.Beckmann@amd.com } 1517910SBrad.Beckmann@amd.com } 1527910SBrad.Beckmann@amd.com 1538688Snilay@cs.wisc.edu unsigned int getDrainCount(Event *de); 1548688Snilay@cs.wisc.edu 1556922SBrad.Beckmann@amd.com uint16_t m_port_id; 1566922SBrad.Beckmann@amd.com uint64_t m_request_cnt; 1576882SBrad.Beckmann@amd.com 1586893SBrad.Beckmann@amd.com M5Port* physMemPort; 1596893SBrad.Beckmann@amd.com 1608686Snilay@cs.wisc.edu /*! Vector of CPU Port attached to this Ruby port. */ 1618686Snilay@cs.wisc.edu typedef std::vector<M5Port*>::iterator CpuPortIter; 1628686Snilay@cs.wisc.edu std::vector<M5Port*> cpu_ports; 1638686Snilay@cs.wisc.edu 1648688Snilay@cs.wisc.edu Event *drainEvent; 1658688Snilay@cs.wisc.edu 1666893SBrad.Beckmann@amd.com PhysicalMemory* physmem; 1678436SBrad.Beckmann@amd.com RubySystem* ruby_system; 1687910SBrad.Beckmann@amd.com 1697910SBrad.Beckmann@amd.com // 1707910SBrad.Beckmann@amd.com // Based on similar code in the M5 bus. Stores pointers to those ports 1717910SBrad.Beckmann@amd.com // that should be called when the Sequencer becomes available after a stall. 1727910SBrad.Beckmann@amd.com // 1737910SBrad.Beckmann@amd.com std::list<M5Port*> retryList; 1747910SBrad.Beckmann@amd.com 1757910SBrad.Beckmann@amd.com bool waitingOnSequencer; 1767915SBrad.Beckmann@amd.com bool access_phys_mem; 1776285Snate@binkert.org}; 1786285Snate@binkert.org 1797039Snate@binkert.org#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 180