RubyPort.hh revision 8874
12SN/A/* 21762SN/A * Copyright (c) 2009 Advanced Micro Devices, Inc. 32SN/A * Copyright (c) 2011 Mark D. Hill and David A. Wood 42SN/A * All rights reserved. 52SN/A * 62SN/A * Redistribution and use in source and binary forms, with or without 72SN/A * modification, are permitted provided that the following conditions are 82SN/A * met: redistributions of source code must retain the above copyright 92SN/A * notice, this list of conditions and the following disclaimer; 102SN/A * redistributions in binary form must reproduce the above copyright 112SN/A * notice, this list of conditions and the following disclaimer in the 122SN/A * documentation and/or other materials provided with the distribution; 132SN/A * neither the name of the copyright holders nor the names of its 142SN/A * contributors may be used to endorse or promote products derived from 152SN/A * this software without specific prior written permission. 162SN/A * 172SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272665SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665SN/A */ 292665SN/A 302SN/A#ifndef __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 312SN/A#define __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 322SN/A 332SN/A#include <cassert> 341298SN/A#include <string> 351298SN/A 361259SN/A#include "mem/protocol/RequestStatus.hh" 372SN/A#include "mem/ruby/system/System.hh" 382SN/A#include "mem/mem_object.hh" 39146SN/A#include "mem/physical.hh" 40146SN/A#include "mem/tport.hh" 417632SBrad.Beckmann@amd.com#include "params/RubyPort.hh" 428232Snate@binkert.org 433348SN/Aclass MessageBuffer; 448229Snate@binkert.orgclass AbstractController; 453348SN/A 463348SN/Aclass RubyPort : public MemObject 4756SN/A{ 48695SN/A public: 492SN/A class M5Port : public SimpleTimingPort 502SN/A { 512SN/A private: 521298SN/A RubyPort *ruby_port; 531298SN/A RubySystem* ruby_system; 543187SN/A bool _onRetryList; 553349SN/A bool access_phys_mem; 563187SN/A 574898SN/A public: 584898SN/A M5Port(const std::string &_name, RubyPort *_port, 594898SN/A RubySystem*_system, bool _access_phys_mem); 604898SN/A bool sendNextCycle(PacketPtr pkt); 614898SN/A void hitCallback(PacketPtr pkt); 624898SN/A void evictionCallback(const Address& address); 634898SN/A unsigned deviceBlockSize() const; 643187SN/A 653187SN/A bool onRetryList() 663187SN/A { return _onRetryList; } 673187SN/A 683349SN/A void onRetryList(bool newVal) 693187SN/A { _onRetryList = newVal; } 704895SN/A 714895SN/A protected: 724895SN/A virtual bool recvTiming(PacketPtr pkt); 737823Ssteve.reinhardt@amd.com virtual Tick recvAtomic(PacketPtr pkt); 743187SN/A virtual void recvFunctional(PacketPtr pkt); 753187SN/A 763187SN/A private: 773349SN/A bool isPhysMemAddress(Addr addr); 783187SN/A bool doFunctionalRead(PacketPtr pkt); 793204SN/A bool doFunctionalWrite(PacketPtr pkt); 807823Ssteve.reinhardt@amd.com }; 813340SN/A 823262SN/A friend class M5Port; 833204SN/A 843187SN/A class PioPort : public SimpleTimingPort 853187SN/A { 863187SN/A private: 878711Sandreas.hansson@arm.com RubyPort *ruby_port; 883187SN/A 893187SN/A public: 903187SN/A PioPort(const std::string &_name, RubyPort *_port); 913187SN/A bool sendNextCycle(PacketPtr pkt); 923187SN/A 933187SN/A protected: 943187SN/A virtual bool recvTiming(PacketPtr pkt); 953187SN/A virtual Tick recvAtomic(PacketPtr pkt); 963187SN/A }; 973262SN/A 983349SN/A friend class PioPort; 993262SN/A 1003262SN/A struct SenderState : public Packet::SenderState 1013262SN/A { 1023262SN/A M5Port* port; 1033262SN/A Packet::SenderState *saved; 1047544SN/A 1057544SN/A SenderState(M5Port* _port, Packet::SenderState *sender_state = NULL) 1067544SN/A : port(_port), saved(sender_state) 1077544SN/A {} 1087544SN/A }; 1097544SN/A 1107544SN/A typedef RubyPortParams Params; 1117544SN/A RubyPort(const Params *p); 1123262SN/A virtual ~RubyPort() {} 1133262SN/A 1147544SN/A void init(); 1157544SN/A 1167544SN/A Port *getPort(const std::string &if_name, int idx); 1177544SN/A 1183262SN/A virtual RequestStatus makeRequest(PacketPtr pkt) = 0; 1193262SN/A virtual int outstandingCount() const = 0; 1203262SN/A virtual bool isDeadlockEventScheduled() const = 0; 1213262SN/A virtual void descheduleDeadlockEvent() = 0; 1225034SN/A 1235034SN/A // 1242SN/A // Called by the controller to give the sequencer a pointer. 1253187SN/A // A pointer to the controller is needed for atomic support. 1263187SN/A // 1273187SN/A void setController(AbstractController* _cntrl) { m_controller = _cntrl; } 1283187SN/A int getId() { return m_version; } 1293187SN/A unsigned int drain(Event *de); 1305034SN/A 1315034SN/A protected: 1325034SN/A const std::string m_name; 1335034SN/A void ruby_hit_callback(PacketPtr pkt); 1347544SN/A void testDrainComplete(); 1355034SN/A void ruby_eviction_callback(const Address& address); 1365034SN/A 1375034SN/A int m_version; 1385034SN/A AbstractController* m_controller; 1395034SN/A MessageBuffer* m_mandatory_q_ptr; 1408436SBrad.Beckmann@amd.com PioPort pio_port; 1418436SBrad.Beckmann@amd.com bool m_usingRubyTester; 1422SN/A 1437544SN/A private: 1447544SN/A void addToRetryList(M5Port * port) 1453187SN/A { 1465034SN/A if (!port->onRetryList()) { 1472SN/A port->onRetryList(true); 1482SN/A retryList.push_back(port); 1492SN/A waitingOnSequencer = true; 1502SN/A } 1512SN/A } 1522SN/A 1532SN/A unsigned int getDrainCount(Event *de); 1548436SBrad.Beckmann@amd.com 1555606SN/A uint16_t m_port_id; 1561298SN/A uint64_t m_request_cnt; 1573187SN/A 1587544SN/A PioPort physMemPort; 1593187SN/A 1603187SN/A /*! Vector of CPU Port attached to this Ruby port. */ 1613187SN/A typedef std::vector<M5Port*>::iterator CpuPortIter; 1623187SN/A std::vector<M5Port*> cpu_ports; 1633187SN/A 1643187SN/A Event *drainEvent; 1653187SN/A 1663187SN/A PhysicalMemory* physmem; 1673187SN/A RubySystem* ruby_system; 1683187SN/A 1693187SN/A // 1703187SN/A // Based on similar code in the M5 bus. Stores pointers to those ports 1713187SN/A // that should be called when the Sequencer becomes available after a stall. 1723187SN/A // 1733187SN/A std::list<M5Port*> retryList; 1743187SN/A 1753187SN/A bool waitingOnSequencer; 1763187SN/A bool access_phys_mem; 1773187SN/A}; 1783187SN/A 1793187SN/A#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 1804579SN/A