RubyPort.hh revision 6893
16876Ssteve.reinhardt@amd.com
26876Ssteve.reinhardt@amd.com/*
36876Ssteve.reinhardt@amd.com * Copyright (c) 2009 Advanced Micro Devices, Inc.
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
306285Snate@binkert.org#ifndef RUBYPORT_H
316285Snate@binkert.org#define RUBYPORT_H
326285Snate@binkert.org
336285Snate@binkert.org#include "mem/ruby/libruby.hh"
346285Snate@binkert.org#include <string>
356285Snate@binkert.org#include <assert.h>
366285Snate@binkert.org
376876Ssteve.reinhardt@amd.com#include "mem/mem_object.hh"
386876Ssteve.reinhardt@amd.com#include "mem/tport.hh"
396893SBrad.Beckmann@amd.com#include "mem/physical.hh"
406876Ssteve.reinhardt@amd.com
416876Ssteve.reinhardt@amd.com#include "params/RubyPort.hh"
426876Ssteve.reinhardt@amd.com
436285Snate@binkert.orgusing namespace std;
446285Snate@binkert.org
456876Ssteve.reinhardt@amd.comclass MessageBuffer;
466876Ssteve.reinhardt@amd.comclass AbstractController;
476876Ssteve.reinhardt@amd.com
486876Ssteve.reinhardt@amd.comclass RubyPort : public MemObject {
496285Snate@binkert.orgpublic:
506882SBrad.Beckmann@amd.com
516882SBrad.Beckmann@amd.com    class M5Port : public SimpleTimingPort
526882SBrad.Beckmann@amd.com    {
536882SBrad.Beckmann@amd.com
546882SBrad.Beckmann@amd.com        RubyPort *ruby_port;
556882SBrad.Beckmann@amd.com
566882SBrad.Beckmann@amd.com      public:
576882SBrad.Beckmann@amd.com        M5Port(const std::string &_name,
586882SBrad.Beckmann@amd.com               RubyPort *_port);
596882SBrad.Beckmann@amd.com        bool sendTiming(PacketPtr pkt);
606882SBrad.Beckmann@amd.com        void hitCallback(PacketPtr pkt);
616882SBrad.Beckmann@amd.com
626882SBrad.Beckmann@amd.com      protected:
636882SBrad.Beckmann@amd.com        virtual bool recvTiming(PacketPtr pkt);
646882SBrad.Beckmann@amd.com        virtual Tick recvAtomic(PacketPtr pkt);
656882SBrad.Beckmann@amd.com
666882SBrad.Beckmann@amd.com      private:
676882SBrad.Beckmann@amd.com        bool isPhysMemAddress(Addr addr);
686882SBrad.Beckmann@amd.com    };
696882SBrad.Beckmann@amd.com
706882SBrad.Beckmann@amd.com    friend class M5Port;
716882SBrad.Beckmann@amd.com
726882SBrad.Beckmann@amd.com    class PioPort : public SimpleTimingPort
736882SBrad.Beckmann@amd.com    {
746882SBrad.Beckmann@amd.com
756882SBrad.Beckmann@amd.com        RubyPort *ruby_port;
766882SBrad.Beckmann@amd.com
776882SBrad.Beckmann@amd.com      public:
786882SBrad.Beckmann@amd.com        PioPort(const std::string &_name,
796882SBrad.Beckmann@amd.com                RubyPort *_port);
806882SBrad.Beckmann@amd.com        bool sendTiming(PacketPtr pkt);
816882SBrad.Beckmann@amd.com
826882SBrad.Beckmann@amd.com      protected:
836882SBrad.Beckmann@amd.com        virtual bool recvTiming(PacketPtr pkt);
846882SBrad.Beckmann@amd.com        virtual Tick recvAtomic(PacketPtr pkt);
856882SBrad.Beckmann@amd.com    };
866882SBrad.Beckmann@amd.com
876882SBrad.Beckmann@amd.com    friend class PioPort;
886882SBrad.Beckmann@amd.com
896882SBrad.Beckmann@amd.com    struct SenderState : public Packet::SenderState
906882SBrad.Beckmann@amd.com    {
916882SBrad.Beckmann@amd.com        M5Port* port;
926882SBrad.Beckmann@amd.com        Packet::SenderState *saved;
936882SBrad.Beckmann@amd.com
946882SBrad.Beckmann@amd.com        SenderState(M5Port* _port,
956882SBrad.Beckmann@amd.com                    Packet::SenderState *sender_state = NULL)
966882SBrad.Beckmann@amd.com            : port(_port), saved(sender_state)
976882SBrad.Beckmann@amd.com        {}
986882SBrad.Beckmann@amd.com    };
996882SBrad.Beckmann@amd.com
1006876Ssteve.reinhardt@amd.com    typedef RubyPortParams Params;
1016876Ssteve.reinhardt@amd.com    RubyPort(const Params *p);
1026882SBrad.Beckmann@amd.com    virtual ~RubyPort() {}
1036882SBrad.Beckmann@amd.com
1046882SBrad.Beckmann@amd.com    void init();
1056285Snate@binkert.org
1066876Ssteve.reinhardt@amd.com    Port *getPort(const std::string &if_name, int idx);
1076876Ssteve.reinhardt@amd.com
1086882SBrad.Beckmann@amd.com    virtual int64_t makeRequest(const RubyRequest & request) = 0;
1096285Snate@binkert.org
1106882SBrad.Beckmann@amd.com    void registerHitCallback(void (*hit_callback)(int64_t request_id)) {
1116882SBrad.Beckmann@amd.com        //
1126882SBrad.Beckmann@amd.com        // Can't assign hit_callback twice and by default it is set to the
1136882SBrad.Beckmann@amd.com        // RubyPort's default callback function.
1146882SBrad.Beckmann@amd.com        //
1156882SBrad.Beckmann@amd.com        assert(m_hit_callback == ruby_hit_callback);
1166882SBrad.Beckmann@amd.com        m_hit_callback = hit_callback;
1176882SBrad.Beckmann@amd.com    }
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
1256285Snate@binkert.orgprotected:
1266285Snate@binkert.org  const string m_name;
1276285Snate@binkert.org  void (*m_hit_callback)(int64_t);
1286285Snate@binkert.org
1296285Snate@binkert.org  int64_t makeUniqueRequestID() {
1306285Snate@binkert.org    // The request ID is generated by combining the port ID with a request count
1316285Snate@binkert.org    // so that request IDs can be formed concurrently by multiple threads.
1326285Snate@binkert.org    // IDs are formed as follows:
1336285Snate@binkert.org    //
1346285Snate@binkert.org    //
1356285Snate@binkert.org    //   0        PortID                         Request Count
1366285Snate@binkert.org    // +----+---------------+-----------------------------------------------------+
1376285Snate@binkert.org    // | 63 |     62-48     |                         47-0                        |
1386285Snate@binkert.org    // +----+---------------+-----------------------------------------------------+
1396285Snate@binkert.org    //
1406285Snate@binkert.org    //
1416285Snate@binkert.org    //  This limits the system to a maximum of 2^11 == 2048 components
1426285Snate@binkert.org    //  and 2^48 ~= 3x10^14 requests per component
1436285Snate@binkert.org
1446285Snate@binkert.org    int64_t id = (static_cast<uint64_t>(m_port_id) << 48) | m_request_cnt;
1456285Snate@binkert.org    m_request_cnt++;
1466285Snate@binkert.org    // assert((m_request_cnt & (1<<48)) == 0);
1476285Snate@binkert.org    return id;
1486285Snate@binkert.org  }
1496285Snate@binkert.org
1506876Ssteve.reinhardt@amd.com  int m_version;
1516876Ssteve.reinhardt@amd.com  AbstractController* m_controller;
1526876Ssteve.reinhardt@amd.com  MessageBuffer* m_mandatory_q_ptr;
1536882SBrad.Beckmann@amd.com    PioPort* pio_port;
1546876Ssteve.reinhardt@amd.com
1556285Snate@binkert.orgprivate:
1566285Snate@binkert.org  static uint16_t m_num_ports;
1576285Snate@binkert.org  uint16_t m_port_id;
1586285Snate@binkert.org  uint64_t m_request_cnt;
1596882SBrad.Beckmann@amd.com
1606882SBrad.Beckmann@amd.com    struct RequestCookie {
1616882SBrad.Beckmann@amd.com        Packet *pkt;
1626882SBrad.Beckmann@amd.com        M5Port *m5Port;
1636882SBrad.Beckmann@amd.com        RequestCookie(Packet *p, M5Port *m5p)
1646882SBrad.Beckmann@amd.com            : pkt(p), m5Port(m5p)
1656882SBrad.Beckmann@amd.com        {}
1666882SBrad.Beckmann@amd.com    };
1676882SBrad.Beckmann@amd.com
1686882SBrad.Beckmann@amd.com    typedef std::map<int64_t, RequestCookie*> RequestMap;
1696882SBrad.Beckmann@amd.com    static RequestMap pending_cpu_requests;
1706882SBrad.Beckmann@amd.com    static void ruby_hit_callback(int64_t req_id);
1716882SBrad.Beckmann@amd.com
1726893SBrad.Beckmann@amd.com    M5Port* physMemPort;
1736893SBrad.Beckmann@amd.com
1746893SBrad.Beckmann@amd.com    PhysicalMemory* physmem;
1756285Snate@binkert.org};
1766285Snate@binkert.org
1776285Snate@binkert.org#endif
178