RubyPort.hh revision 8686
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"
368092Snilay@cs.wisc.edu#include "mem/ruby/slicc_interface/RubyRequest.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);
627909Shestness@cs.utexas.edu        unsigned deviceBlockSize() const;
637910SBrad.Beckmann@amd.com
647910SBrad.Beckmann@amd.com        bool onRetryList()
657910SBrad.Beckmann@amd.com        { return _onRetryList; }
667910SBrad.Beckmann@amd.com
677910SBrad.Beckmann@amd.com        void onRetryList(bool newVal)
687910SBrad.Beckmann@amd.com        { _onRetryList = newVal; }
696882SBrad.Beckmann@amd.com
706882SBrad.Beckmann@amd.com      protected:
716882SBrad.Beckmann@amd.com        virtual bool recvTiming(PacketPtr pkt);
726882SBrad.Beckmann@amd.com        virtual Tick recvAtomic(PacketPtr pkt);
738436SBrad.Beckmann@amd.com        virtual void recvFunctional(PacketPtr pkt);
746882SBrad.Beckmann@amd.com
756882SBrad.Beckmann@amd.com      private:
766882SBrad.Beckmann@amd.com        bool isPhysMemAddress(Addr addr);
778436SBrad.Beckmann@amd.com        bool doFunctionalRead(PacketPtr pkt);
788436SBrad.Beckmann@amd.com        bool doFunctionalWrite(PacketPtr pkt);
796882SBrad.Beckmann@amd.com    };
806882SBrad.Beckmann@amd.com
816882SBrad.Beckmann@amd.com    friend class M5Port;
826882SBrad.Beckmann@amd.com
836882SBrad.Beckmann@amd.com    class PioPort : public SimpleTimingPort
846882SBrad.Beckmann@amd.com    {
857039Snate@binkert.org      private:
866882SBrad.Beckmann@amd.com        RubyPort *ruby_port;
876882SBrad.Beckmann@amd.com
886882SBrad.Beckmann@amd.com      public:
897039Snate@binkert.org        PioPort(const std::string &_name, RubyPort *_port);
906882SBrad.Beckmann@amd.com        bool sendTiming(PacketPtr pkt);
916882SBrad.Beckmann@amd.com
926882SBrad.Beckmann@amd.com      protected:
936882SBrad.Beckmann@amd.com        virtual bool recvTiming(PacketPtr pkt);
946882SBrad.Beckmann@amd.com        virtual Tick recvAtomic(PacketPtr pkt);
956882SBrad.Beckmann@amd.com    };
966882SBrad.Beckmann@amd.com
976882SBrad.Beckmann@amd.com    friend class PioPort;
986882SBrad.Beckmann@amd.com
996882SBrad.Beckmann@amd.com    struct SenderState : public Packet::SenderState
1006882SBrad.Beckmann@amd.com    {
1016882SBrad.Beckmann@amd.com        M5Port* port;
1026882SBrad.Beckmann@amd.com        Packet::SenderState *saved;
1036882SBrad.Beckmann@amd.com
1047039Snate@binkert.org        SenderState(M5Port* _port, Packet::SenderState *sender_state = NULL)
1056882SBrad.Beckmann@amd.com            : port(_port), saved(sender_state)
1066882SBrad.Beckmann@amd.com        {}
1076882SBrad.Beckmann@amd.com    };
1086882SBrad.Beckmann@amd.com
1096876Ssteve.reinhardt@amd.com    typedef RubyPortParams Params;
1106876Ssteve.reinhardt@amd.com    RubyPort(const Params *p);
1116882SBrad.Beckmann@amd.com    virtual ~RubyPort() {}
1126882SBrad.Beckmann@amd.com
1136882SBrad.Beckmann@amd.com    void init();
1146285Snate@binkert.org
1156876Ssteve.reinhardt@amd.com    Port *getPort(const std::string &if_name, int idx);
1166876Ssteve.reinhardt@amd.com
1178615Snilay@cs.wisc.edu    virtual RequestStatus makeRequest(PacketPtr pkt) = 0;
1186882SBrad.Beckmann@amd.com
1196882SBrad.Beckmann@amd.com    //
1206882SBrad.Beckmann@amd.com    // Called by the controller to give the sequencer a pointer.
1216882SBrad.Beckmann@amd.com    // A pointer to the controller is needed for atomic support.
1226882SBrad.Beckmann@amd.com    //
1236882SBrad.Beckmann@amd.com    void setController(AbstractController* _cntrl) { m_controller = _cntrl; }
1246285Snate@binkert.org
1257039Snate@binkert.org  protected:
1267055Snate@binkert.org    const std::string m_name;
1277039Snate@binkert.org    void ruby_hit_callback(PacketPtr pkt);
1287039Snate@binkert.org    void hit(PacketPtr pkt);
1296285Snate@binkert.org
1307039Snate@binkert.org    int m_version;
1317039Snate@binkert.org    AbstractController* m_controller;
1327039Snate@binkert.org    MessageBuffer* m_mandatory_q_ptr;
1336882SBrad.Beckmann@amd.com    PioPort* pio_port;
1347910SBrad.Beckmann@amd.com    bool m_usingRubyTester;
1356876Ssteve.reinhardt@amd.com
1367039Snate@binkert.org  private:
1377910SBrad.Beckmann@amd.com    void addToRetryList(M5Port * port)
1387910SBrad.Beckmann@amd.com    {
1397910SBrad.Beckmann@amd.com        if (!port->onRetryList()) {
1407910SBrad.Beckmann@amd.com            port->onRetryList(true);
1417910SBrad.Beckmann@amd.com            retryList.push_back(port);
1427910SBrad.Beckmann@amd.com            waitingOnSequencer = true;
1437910SBrad.Beckmann@amd.com        }
1447910SBrad.Beckmann@amd.com    }
1457910SBrad.Beckmann@amd.com
1466922SBrad.Beckmann@amd.com    uint16_t m_port_id;
1476922SBrad.Beckmann@amd.com    uint64_t m_request_cnt;
1486882SBrad.Beckmann@amd.com
1496893SBrad.Beckmann@amd.com    M5Port* physMemPort;
1506893SBrad.Beckmann@amd.com
1518686Snilay@cs.wisc.edu    /*! Vector of CPU Port attached to this Ruby port. */
1528686Snilay@cs.wisc.edu    typedef std::vector<M5Port*>::iterator CpuPortIter;
1538686Snilay@cs.wisc.edu    std::vector<M5Port*> cpu_ports;
1548686Snilay@cs.wisc.edu
1556893SBrad.Beckmann@amd.com    PhysicalMemory* physmem;
1568436SBrad.Beckmann@amd.com    RubySystem* ruby_system;
1577910SBrad.Beckmann@amd.com
1587910SBrad.Beckmann@amd.com    //
1597910SBrad.Beckmann@amd.com    // Based on similar code in the M5 bus.  Stores pointers to those ports
1607910SBrad.Beckmann@amd.com    // that should be called when the Sequencer becomes available after a stall.
1617910SBrad.Beckmann@amd.com    //
1627910SBrad.Beckmann@amd.com    std::list<M5Port*> retryList;
1637910SBrad.Beckmann@amd.com
1647910SBrad.Beckmann@amd.com    bool waitingOnSequencer;
1657915SBrad.Beckmann@amd.com    bool access_phys_mem;
1666285Snate@binkert.org};
1676285Snate@binkert.org
1687039Snate@binkert.org#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__
169