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