RubyPort.hh revision 8717:5c253f1031d7
1/* 2 * Copyright (c) 2009 Advanced Micro Devices, Inc. 3 * Copyright (c) 2011 Mark D. Hill and David A. Wood 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer; 10 * redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution; 13 * neither the name of the copyright holders nor the names of its 14 * contributors may be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#ifndef __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 31#define __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 32 33#include <cassert> 34#include <string> 35 36#include "mem/protocol/RequestStatus.hh" 37#include "mem/ruby/system/System.hh" 38#include "mem/mem_object.hh" 39#include "mem/physical.hh" 40#include "mem/tport.hh" 41#include "params/RubyPort.hh" 42 43class MessageBuffer; 44class AbstractController; 45 46class RubyPort : public MemObject 47{ 48 public: 49 class M5Port : public SimpleTimingPort 50 { 51 private: 52 RubyPort *ruby_port; 53 RubySystem* ruby_system; 54 bool _onRetryList; 55 bool access_phys_mem; 56 57 public: 58 M5Port(const std::string &_name, RubyPort *_port, 59 RubySystem*_system, bool _access_phys_mem); 60 bool sendTiming(PacketPtr pkt); 61 void hitCallback(PacketPtr pkt); 62 void evictionCallback(const Address& address); 63 unsigned deviceBlockSize() const; 64 65 bool onRetryList() 66 { return _onRetryList; } 67 68 void onRetryList(bool newVal) 69 { _onRetryList = newVal; } 70 71 protected: 72 virtual bool recvTiming(PacketPtr pkt); 73 virtual Tick recvAtomic(PacketPtr pkt); 74 virtual void recvFunctional(PacketPtr pkt); 75 76 private: 77 bool isPhysMemAddress(Addr addr); 78 bool doFunctionalRead(PacketPtr pkt); 79 bool doFunctionalWrite(PacketPtr pkt); 80 }; 81 82 friend class M5Port; 83 84 class PioPort : public SimpleTimingPort 85 { 86 private: 87 RubyPort *ruby_port; 88 89 public: 90 PioPort(const std::string &_name, RubyPort *_port); 91 bool sendTiming(PacketPtr pkt); 92 93 protected: 94 virtual bool recvTiming(PacketPtr pkt); 95 virtual Tick recvAtomic(PacketPtr pkt); 96 }; 97 98 friend class PioPort; 99 100 struct SenderState : public Packet::SenderState 101 { 102 M5Port* port; 103 Packet::SenderState *saved; 104 105 SenderState(M5Port* _port, Packet::SenderState *sender_state = NULL) 106 : port(_port), saved(sender_state) 107 {} 108 }; 109 110 typedef RubyPortParams Params; 111 RubyPort(const Params *p); 112 virtual ~RubyPort() {} 113 114 void init(); 115 116 Port *getPort(const std::string &if_name, int idx); 117 118 virtual RequestStatus makeRequest(PacketPtr pkt) = 0; 119 virtual int outstandingCount() const = 0; 120 virtual bool isDeadlockEventScheduled() const = 0; 121 virtual void descheduleDeadlockEvent() = 0; 122 123 // 124 // Called by the controller to give the sequencer a pointer. 125 // A pointer to the controller is needed for atomic support. 126 // 127 void setController(AbstractController* _cntrl) { m_controller = _cntrl; } 128 int getId() { return m_version; } 129 unsigned int drain(Event *de); 130 131 protected: 132 const std::string m_name; 133 void ruby_hit_callback(PacketPtr pkt); 134 void testDrainComplete(); 135 void ruby_eviction_callback(const Address& address); 136 137 int m_version; 138 AbstractController* m_controller; 139 MessageBuffer* m_mandatory_q_ptr; 140 PioPort* pio_port; 141 bool m_usingRubyTester; 142 143 private: 144 void addToRetryList(M5Port * port) 145 { 146 if (!port->onRetryList()) { 147 port->onRetryList(true); 148 retryList.push_back(port); 149 waitingOnSequencer = true; 150 } 151 } 152 153 unsigned int getDrainCount(Event *de); 154 155 uint16_t m_port_id; 156 uint64_t m_request_cnt; 157 158 M5Port* physMemPort; 159 160 /*! Vector of CPU Port attached to this Ruby port. */ 161 typedef std::vector<M5Port*>::iterator CpuPortIter; 162 std::vector<M5Port*> cpu_ports; 163 164 Event *drainEvent; 165 166 PhysicalMemory* physmem; 167 RubySystem* ruby_system; 168 169 // 170 // Based on similar code in the M5 bus. Stores pointers to those ports 171 // that should be called when the Sequencer becomes available after a stall. 172 // 173 std::list<M5Port*> retryList; 174 175 bool waitingOnSequencer; 176 bool access_phys_mem; 177}; 178 179#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__ 180