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