RubyPort.hh revision 8688
16876Ssteve.reinhardt@amd.com/* 26876Ssteve.reinhardt@amd.com * Copyright (c) 2009 Advanced Micro Devices, Inc. 36876Ssteve.reinhardt@amd.com * All rights reserved. 46876Ssteve.reinhardt@amd.com * 56876Ssteve.reinhardt@amd.com * Redistribution and use in source and binary forms, with or without 66876Ssteve.reinhardt@amd.com * modification, are permitted provided that the following conditions are 76876Ssteve.reinhardt@amd.com * met: redistributions of source code must retain the above copyright 86876Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer; 96876Ssteve.reinhardt@amd.com * redistributions in binary form must reproduce the above copyright 106876Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer in the 116876Ssteve.reinhardt@amd.com * documentation and/or other materials provided with the distribution; 126876Ssteve.reinhardt@amd.com * neither the name of the copyright holders nor the names of its 136876Ssteve.reinhardt@amd.com * contributors may be used to endorse or promote products derived from 146876Ssteve.reinhardt@amd.com * this software without specific prior written permission. 156876Ssteve.reinhardt@amd.com * 166876Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176876Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186876Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196876Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206876Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216876Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226876Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236876Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246876Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256876Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266876Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276876Ssteve.reinhardt@amd.com */ 286876Ssteve.reinhardt@amd.com 297039Snate@binkert.org#ifndef __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 307039Snate@binkert.org#define __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 316285Snate@binkert.org 327039Snate@binkert.org#include <cassert> 336285Snate@binkert.org#include <string> 346285Snate@binkert.org 356922SBrad.Beckmann@amd.com#include "mem/protocol/RequestStatus.hh" 367909Shestness@cs.utexas.edu#include "mem/ruby/system/System.hh" 378229Snate@binkert.org#include "mem/mem_object.hh" 388229Snate@binkert.org#include "mem/physical.hh" 397039Snate@binkert.org#include "mem/tport.hh" 406876Ssteve.reinhardt@amd.com#include "params/RubyPort.hh" 416876Ssteve.reinhardt@amd.com 426876Ssteve.reinhardt@amd.comclass MessageBuffer; 436876Ssteve.reinhardt@amd.comclass AbstractController; 446876Ssteve.reinhardt@amd.com 457039Snate@binkert.orgclass RubyPort : public MemObject 467039Snate@binkert.org{ 477039Snate@binkert.org public: 486882SBrad.Beckmann@amd.com class M5Port : public SimpleTimingPort 496882SBrad.Beckmann@amd.com { 507039Snate@binkert.org private: 516882SBrad.Beckmann@amd.com RubyPort *ruby_port; 528436SBrad.Beckmann@amd.com RubySystem* ruby_system; 537910SBrad.Beckmann@amd.com bool _onRetryList; 547915SBrad.Beckmann@amd.com bool access_phys_mem; 556882SBrad.Beckmann@amd.com 566882SBrad.Beckmann@amd.com public: 577915SBrad.Beckmann@amd.com M5Port(const std::string &_name, RubyPort *_port, 588436SBrad.Beckmann@amd.com RubySystem*_system, bool _access_phys_mem); 596882SBrad.Beckmann@amd.com bool sendTiming(PacketPtr pkt); 606882SBrad.Beckmann@amd.com void hitCallback(PacketPtr pkt); 617909Shestness@cs.utexas.edu unsigned deviceBlockSize() const; 627910SBrad.Beckmann@amd.com 637910SBrad.Beckmann@amd.com bool onRetryList() 647910SBrad.Beckmann@amd.com { return _onRetryList; } 657910SBrad.Beckmann@amd.com 667910SBrad.Beckmann@amd.com void onRetryList(bool newVal) 677910SBrad.Beckmann@amd.com { _onRetryList = newVal; } 686882SBrad.Beckmann@amd.com 696882SBrad.Beckmann@amd.com protected: 706882SBrad.Beckmann@amd.com virtual bool recvTiming(PacketPtr pkt); 716882SBrad.Beckmann@amd.com virtual Tick recvAtomic(PacketPtr pkt); 728436SBrad.Beckmann@amd.com virtual void recvFunctional(PacketPtr pkt); 736882SBrad.Beckmann@amd.com 746882SBrad.Beckmann@amd.com private: 756882SBrad.Beckmann@amd.com bool isPhysMemAddress(Addr addr); 768436SBrad.Beckmann@amd.com bool doFunctionalRead(PacketPtr pkt); 778436SBrad.Beckmann@amd.com bool doFunctionalWrite(PacketPtr pkt); 786882SBrad.Beckmann@amd.com }; 796882SBrad.Beckmann@amd.com 806882SBrad.Beckmann@amd.com friend class M5Port; 816882SBrad.Beckmann@amd.com 826882SBrad.Beckmann@amd.com class PioPort : public SimpleTimingPort 836882SBrad.Beckmann@amd.com { 847039Snate@binkert.org private: 856882SBrad.Beckmann@amd.com RubyPort *ruby_port; 866882SBrad.Beckmann@amd.com 876882SBrad.Beckmann@amd.com public: 887039Snate@binkert.org PioPort(const std::string &_name, RubyPort *_port); 896882SBrad.Beckmann@amd.com bool sendTiming(PacketPtr pkt); 906882SBrad.Beckmann@amd.com 916882SBrad.Beckmann@amd.com protected: 926882SBrad.Beckmann@amd.com virtual bool recvTiming(PacketPtr pkt); 936882SBrad.Beckmann@amd.com virtual Tick recvAtomic(PacketPtr pkt); 946882SBrad.Beckmann@amd.com }; 956882SBrad.Beckmann@amd.com 966882SBrad.Beckmann@amd.com friend class PioPort; 976882SBrad.Beckmann@amd.com 986882SBrad.Beckmann@amd.com struct SenderState : public Packet::SenderState 996882SBrad.Beckmann@amd.com { 1006882SBrad.Beckmann@amd.com M5Port* port; 1016882SBrad.Beckmann@amd.com Packet::SenderState *saved; 1026882SBrad.Beckmann@amd.com 1037039Snate@binkert.org SenderState(M5Port* _port, Packet::SenderState *sender_state = NULL) 1046882SBrad.Beckmann@amd.com : port(_port), saved(sender_state) 1056882SBrad.Beckmann@amd.com {} 1066882SBrad.Beckmann@amd.com }; 1076882SBrad.Beckmann@amd.com 1086876Ssteve.reinhardt@amd.com typedef RubyPortParams Params; 1096876Ssteve.reinhardt@amd.com RubyPort(const Params *p); 1106882SBrad.Beckmann@amd.com virtual ~RubyPort() {} 1116882SBrad.Beckmann@amd.com 1126882SBrad.Beckmann@amd.com void init(); 1136285Snate@binkert.org 1146876Ssteve.reinhardt@amd.com Port *getPort(const std::string &if_name, int idx); 1156876Ssteve.reinhardt@amd.com 1168615Snilay@cs.wisc.edu virtual RequestStatus makeRequest(PacketPtr pkt) = 0; 1178688Snilay@cs.wisc.edu virtual int outstandingCount() const = 0; 1188688Snilay@cs.wisc.edu virtual bool isDeadlockEventScheduled() const = 0; 1198688Snilay@cs.wisc.edu virtual void descheduleDeadlockEvent() = 0; 1206882SBrad.Beckmann@amd.com 1216882SBrad.Beckmann@amd.com // 1226882SBrad.Beckmann@amd.com // Called by the controller to give the sequencer a pointer. 1236882SBrad.Beckmann@amd.com // A pointer to the controller is needed for atomic support. 1246882SBrad.Beckmann@amd.com // 1256882SBrad.Beckmann@amd.com void setController(AbstractController* _cntrl) { m_controller = _cntrl; } 1268688Snilay@cs.wisc.edu int getId() { return m_version; } 1278688Snilay@cs.wisc.edu unsigned int drain(Event *de); 1286285Snate@binkert.org 1297039Snate@binkert.org protected: 1307055Snate@binkert.org const std::string m_name; 1317039Snate@binkert.org void ruby_hit_callback(PacketPtr pkt); 1327039Snate@binkert.org void hit(PacketPtr pkt); 1338688Snilay@cs.wisc.edu void testDrainComplete(); 1346285Snate@binkert.org 1357039Snate@binkert.org int m_version; 1367039Snate@binkert.org AbstractController* m_controller; 1377039Snate@binkert.org MessageBuffer* m_mandatory_q_ptr; 1386882SBrad.Beckmann@amd.com PioPort* pio_port; 1397910SBrad.Beckmann@amd.com bool m_usingRubyTester; 1406876Ssteve.reinhardt@amd.com 1417039Snate@binkert.org private: 1427910SBrad.Beckmann@amd.com void addToRetryList(M5Port * port) 1437910SBrad.Beckmann@amd.com { 1447910SBrad.Beckmann@amd.com if (!port->onRetryList()) { 1457910SBrad.Beckmann@amd.com port->onRetryList(true); 1467910SBrad.Beckmann@amd.com retryList.push_back(port); 1477910SBrad.Beckmann@amd.com waitingOnSequencer = true; 1487910SBrad.Beckmann@amd.com } 1497910SBrad.Beckmann@amd.com } 1507910SBrad.Beckmann@amd.com 1518688Snilay@cs.wisc.edu unsigned int getDrainCount(Event *de); 1528688Snilay@cs.wisc.edu 1536922SBrad.Beckmann@amd.com uint16_t m_port_id; 1546922SBrad.Beckmann@amd.com uint64_t m_request_cnt; 1556882SBrad.Beckmann@amd.com 1566893SBrad.Beckmann@amd.com M5Port* physMemPort; 1576893SBrad.Beckmann@amd.com 1588686Snilay@cs.wisc.edu /*! Vector of CPU Port attached to this Ruby port. */ 1598686Snilay@cs.wisc.edu typedef std::vector<M5Port*>::iterator CpuPortIter; 1608686Snilay@cs.wisc.edu std::vector<M5Port*> cpu_ports; 1618686Snilay@cs.wisc.edu 1628688Snilay@cs.wisc.edu Event *drainEvent; 1638688Snilay@cs.wisc.edu 1646893SBrad.Beckmann@amd.com PhysicalMemory* physmem; 1658436SBrad.Beckmann@amd.com RubySystem* ruby_system; 1667910SBrad.Beckmann@amd.com 1677910SBrad.Beckmann@amd.com // 1687910SBrad.Beckmann@amd.com // Based on similar code in the M5 bus. Stores pointers to those ports 1697910SBrad.Beckmann@amd.com // that should be called when the Sequencer becomes available after a stall. 1707910SBrad.Beckmann@amd.com // 1717910SBrad.Beckmann@amd.com std::list<M5Port*> retryList; 1727910SBrad.Beckmann@amd.com 1737910SBrad.Beckmann@amd.com bool waitingOnSequencer; 1747915SBrad.Beckmann@amd.com bool access_phys_mem; 1756285Snate@binkert.org}; 1766285Snate@binkert.org 1777039Snate@binkert.org#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 178