summaryrefslogtreecommitdiff
path: root/src/mem/ruby/system/RubyPort.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/ruby/system/RubyPort.hh')
-rw-r--r--src/mem/ruby/system/RubyPort.hh90
1 files changed, 84 insertions, 6 deletions
diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh
index 20557669a..a03c4dce2 100644
--- a/src/mem/ruby/system/RubyPort.hh
+++ b/src/mem/ruby/system/RubyPort.hh
@@ -46,18 +46,81 @@ class AbstractController;
class RubyPort : public MemObject {
public:
+
+ class M5Port : public SimpleTimingPort
+ {
+
+ RubyPort *ruby_port;
+
+ public:
+ M5Port(const std::string &_name,
+ RubyPort *_port);
+ bool sendTiming(PacketPtr pkt);
+ void hitCallback(PacketPtr pkt);
+
+ protected:
+ virtual bool recvTiming(PacketPtr pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
+
+ private:
+ bool isPioAddress(Addr addr);
+ bool isPhysMemAddress(Addr addr);
+ };
+
+ friend class M5Port;
+
+ class PioPort : public SimpleTimingPort
+ {
+
+ RubyPort *ruby_port;
+
+ public:
+ PioPort(const std::string &_name,
+ RubyPort *_port);
+ bool sendTiming(PacketPtr pkt);
+
+ protected:
+ virtual bool recvTiming(PacketPtr pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
+ };
+
+ friend class PioPort;
+
+ struct SenderState : public Packet::SenderState
+ {
+ M5Port* port;
+ Packet::SenderState *saved;
+
+ SenderState(M5Port* _port,
+ Packet::SenderState *sender_state = NULL)
+ : port(_port), saved(sender_state)
+ {}
+ };
+
typedef RubyPortParams Params;
RubyPort(const Params *p);
- virtual ~RubyPort() {}
+ virtual ~RubyPort() {}
+
+ void init();
Port *getPort(const std::string &if_name, int idx);
- virtual int64_t makeRequest(const RubyRequest & request) = 0;
+ virtual int64_t makeRequest(const RubyRequest & request) = 0;
- void registerHitCallback(void (*hit_callback)(int64_t request_id)) {
- assert(m_hit_callback == NULL); // can't assign hit_callback twice
- m_hit_callback = hit_callback;
- }
+ void registerHitCallback(void (*hit_callback)(int64_t request_id)) {
+ //
+ // Can't assign hit_callback twice and by default it is set to the
+ // RubyPort's default callback function.
+ //
+ assert(m_hit_callback == ruby_hit_callback);
+ m_hit_callback = hit_callback;
+ }
+
+ //
+ // Called by the controller to give the sequencer a pointer.
+ // A pointer to the controller is needed for atomic support.
+ //
+ void setController(AbstractController* _cntrl) { m_controller = _cntrl; }
protected:
const string m_name;
@@ -87,11 +150,26 @@ protected:
int m_version;
AbstractController* m_controller;
MessageBuffer* m_mandatory_q_ptr;
+ PioPort* pio_port;
private:
static uint16_t m_num_ports;
uint16_t m_port_id;
uint64_t m_request_cnt;
+
+ struct RequestCookie {
+ Packet *pkt;
+ M5Port *m5Port;
+ RequestCookie(Packet *p, M5Port *m5p)
+ : pkt(p), m5Port(m5p)
+ {}
+ };
+
+ typedef std::map<int64_t, RequestCookie*> RequestMap;
+ static RequestMap pending_cpu_requests;
+ static void ruby_hit_callback(int64_t req_id);
+
+ FunctionalPort funcMemPort;
};
#endif