summaryrefslogtreecommitdiff
path: root/src/mem/rubymem.cc
diff options
context:
space:
mode:
authorNathan Binkert <nate@binkert.org>2009-07-06 15:49:47 -0700
committerNathan Binkert <nate@binkert.org>2009-07-06 15:49:47 -0700
commitda704f52e55dd2649e53bf233f948c897727f13d (patch)
tree150514b6e67a108c56ad771adeb908713b06df65 /src/mem/rubymem.cc
parenta7904e2cf341d5452c5622adfcbdcd268d4ab7d1 (diff)
downloadgem5-da704f52e55dd2649e53bf233f948c897727f13d.tar.xz
ruby: Fix RubyMemory to work with the newer ruby.
Diffstat (limited to 'src/mem/rubymem.cc')
-rw-r--r--src/mem/rubymem.cc157
1 files changed, 113 insertions, 44 deletions
diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc
index 83bac2fd5..62685a71b 100644
--- a/src/mem/rubymem.cc
+++ b/src/mem/rubymem.cc
@@ -33,9 +33,11 @@
#include "arch/isa_traits.hh"
#include "base/output.hh"
+#include "base/str.hh"
#include "base/types.hh"
#include "mem/ruby/common/Debug.hh"
-#include "mem/ruby/init.hh"
+#include "mem/ruby/libruby.hh"
+#include "mem/ruby/system/RubyPort.hh"
#include "mem/ruby/system/Sequencer.hh"
#include "mem/ruby/system/System.hh"
#include "mem/rubymem.hh"
@@ -45,33 +47,54 @@
using namespace std;
using namespace TheISA;
+map<int64_t, PacketPtr> RubyMemory::pending_requests;
+
RubyMemory::RubyMemory(const Params *p)
: PhysicalMemory(p)
{
- config_file = p->config_file;
- config_options = p->config_options;
- stats_file = p->stats_file;
- num_cpus = p->num_cpus;
ruby_clock = p->clock;
ruby_phase = p->phase;
- debug = p->debug;
- debug_file = p->debug_file;
+ ifstream config(p->config_file.c_str());
+
+ vector<RubyObjConf> sys_conf;
+ while (!config.eof()) {
+ char buffer[4096];
+ config.getline(buffer, sizeof(buffer));
+ string line = buffer;
+ if (line.empty())
+ continue;
+ vector<string> tokens;
+ tokenize(tokens, line, ' ');
+ assert(tokens.size() >= 2);
+ vector<string> argv;
+ for (size_t i=2; i<tokens.size(); i++) {
+ std::replace(tokens[i].begin(), tokens[i].end(), '%', ' ');
+ std::replace(tokens[i].begin(), tokens[i].end(), '#', '\n');
+ argv.push_back(tokens[i]);
+ }
+ sys_conf.push_back(RubyObjConf(tokens[0], tokens[1], argv));
+ tokens.clear();
+ argv.clear();
+ }
+
+ RubySystem::create(sys_conf);
+
+ for (int i = 0; i < params()->num_cpus; i++) {
+ RubyPort *p = RubySystem::getPort(csprintf("Sequencer_%d", i),
+ ruby_hit_callback);
+ ruby_ports.push_back(p);
+ }
}
void
RubyMemory::init()
{
- init_variables();
- g_NUM_PROCESSORS = num_cpus;
-
- init_simulator(this);
-
- if (debug) {
+ if (params()->debug) {
g_debug_ptr->setVerbosityString("high");
g_debug_ptr->setDebugTime(1);
- if (debug_file != "") {
- g_debug_ptr->setDebugOutputFile("ruby.debug");
+ if (!params()->debug_file.empty()) {
+ g_debug_ptr->setDebugOutputFile(params()->debug_file.c_str());
}
}
@@ -104,23 +127,21 @@ RubyMemory::init()
}
//called by rubyTickEvent
-void RubyMemory::tick() {
- g_eventQueue_ptr->triggerEvents(g_eventQueue_ptr->getTime() + 1);
- schedule(rubyTickEvent, curTick + ruby_clock); //dsm: clock_phase was added here. This is wrong, the phase is only added on the first tick
+void
+RubyMemory::tick()
+{
+ RubyEventQueue *eq = RubySystem::getEventQueue();
+ eq->triggerEvents(eq->getTime() + 1);
+ schedule(rubyTickEvent, curTick + ruby_clock);
}
-
-RubyMemory::~RubyMemory() {
- delete g_system_ptr;
+RubyMemory::~RubyMemory()
+{
}
void
-RubyMemory::hitCallback(Packet* pkt)
+RubyMemory::hitCallback(PacketPtr pkt, Port *port)
{
- RubyMemoryPort* port = m_packet_to_port_map[pkt];
- assert(port != NULL);
- m_packet_to_port_map.erase(pkt);
-
DPRINTF(MemoryAccess, "Hit callback\n");
bool needsResponse = pkt->needsResponse();
@@ -146,7 +167,7 @@ RubyMemory::getPort(const std::string &if_name, int idx)
// with places where this function is called from C++. I'd prefer
// to move all these into Python someday.
if (if_name == "functional") {
- return new RubyMemoryPort(csprintf("%s-functional", name()), this);
+ return new Port(csprintf("%s-functional", name()), this);
}
if (if_name != "port") {
@@ -161,22 +182,20 @@ RubyMemory::getPort(const std::string &if_name, int idx)
panic("RubyMemory::getPort: port %d already assigned", idx);
}
- RubyMemoryPort *port =
- new RubyMemoryPort(csprintf("%s-port%d", name(), idx), this);
+ Port *port = new Port(csprintf("%s-port%d", name(), idx), this);
ports[idx] = port;
return port;
}
-RubyMemory::RubyMemoryPort::RubyMemoryPort(const std::string &_name,
- RubyMemory *_memory)
+RubyMemory::Port::Port(const std::string &_name, RubyMemory *_memory)
: PhysicalMemory::MemoryPort::MemoryPort(_name, _memory)
{
ruby_mem = _memory;
}
bool
-RubyMemory::RubyMemoryPort::recvTiming(PacketPtr pkt)
+RubyMemory::Port::recvTiming(PacketPtr pkt)
{
DPRINTF(MemoryAccess, "Timing access caught\n");
@@ -197,33 +216,83 @@ RubyMemory::RubyMemoryPort::recvTiming(PacketPtr pkt)
return true;
}
- ruby_mem->m_packet_to_port_map[pkt] = this;
-
- Sequencer* sequencer = g_system_ptr->getSequencer(pkt->req->contextId());
+ // Save the port in the sender state object
+ pkt->senderState = new SenderState(this, pkt->senderState);
+
+ RubyRequestType type = RubyRequestType_NULL;
+ Addr pc = 0;
+ if (pkt->isRead()) {
+ if (pkt->req->isInstFetch()) {
+ type = RubyRequestType_IFETCH;
+ pc = pkt->req->getPC();
+ } else {
+ type = RubyRequestType_LD;
+ }
+ } else if (pkt->isWrite()) {
+ type = RubyRequestType_ST;
+ } else if (pkt->isReadWrite()) {
+ type = RubyRequestType_RMW;
+ }
- if ( ! sequencer->isReady(pkt) ) {
- DPRINTF(MemoryAccess, "Sequencer isn't ready yet!!\n");
- return false;
+ RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(),
+ pkt->getSize(), pc, type,
+ RubyAccessMode_Supervisor);
+
+ // Submit the ruby request
+ RubyPort *ruby_port = ruby_mem->ruby_ports[pkt->req->contextId()];
+ int64_t req_id = ruby_port->makeRequest(ruby_request);
+ if (req_id == -1) {
+ RubyMemory::SenderState *senderState =
+ safe_cast<RubyMemory::SenderState *>(pkt->senderState);
+
+ // pop the sender state from the packet
+ pkt->senderState = senderState->saved;
+ delete senderState;
+ return false;
}
- DPRINTF(MemoryAccess, "Issuing makeRequest\n");
+ // Save the request for the callback
+ RubyMemory::pending_requests[req_id] = pkt;
- sequencer->makeRequest(pkt);
return true;
}
void
-RubyMemory::RubyMemoryPort::sendTiming(PacketPtr pkt)
+ruby_hit_callback(int64_t req_id)
+{
+ typedef map<int64_t, PacketPtr> map_t;
+ map_t &prm = RubyMemory::pending_requests;
+
+ map_t::iterator i = prm.find(req_id);
+ if (i == prm.end())
+ panic("could not find pending request %d\n", req_id);
+
+ PacketPtr pkt = i->second;
+ prm.erase(i);
+
+ RubyMemory::SenderState *senderState =
+ safe_cast<RubyMemory::SenderState *>(pkt->senderState);
+ RubyMemory::Port *port = senderState->port;
+
+ // pop the sender state from the packet
+ pkt->senderState = senderState->saved;
+ delete senderState;
+
+ port->ruby_mem->hitCallback(pkt, port);
+}
+
+void
+RubyMemory::Port::sendTiming(PacketPtr pkt)
{
schedSendTiming(pkt, curTick + 1); //minimum latency, must be > 0
}
void RubyMemory::printConfigStats()
{
- std::ostream *os = simout.create(stats_file);
- g_system_ptr->printConfig(*os);
+ std::ostream *os = simout.create(params()->stats_file);
+ RubySystem::printConfig(*os);
*os << endl;
- g_system_ptr->printStats(*os);
+ RubySystem::printStats(*os);
}