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