DMASequencer.cc revision 6350
16019Shines@cs.fsu.edu
26019Shines@cs.fsu.edu#include "mem/ruby/system/DMASequencer.hh"
37101Sgblack@eecs.umich.edu#include "mem/ruby/buffers/MessageBuffer.hh"
47101Sgblack@eecs.umich.edu#include "mem/ruby/slicc_interface/AbstractController.hh"
57101Sgblack@eecs.umich.edu
67101Sgblack@eecs.umich.edu/* SLICC generated types */
77101Sgblack@eecs.umich.edu#include "mem/protocol/DMARequestMsg.hh"
87101Sgblack@eecs.umich.edu#include "mem/protocol/DMARequestType.hh"
97101Sgblack@eecs.umich.edu#include "mem/protocol/DMAResponseMsg.hh"
107101Sgblack@eecs.umich.edu#include "mem/ruby/system/System.hh"
117101Sgblack@eecs.umich.edu
127101Sgblack@eecs.umich.eduDMASequencer::DMASequencer(const string & name)
137101Sgblack@eecs.umich.edu  : RubyPort(name)
147101Sgblack@eecs.umich.edu{
156019Shines@cs.fsu.edu}
166019Shines@cs.fsu.edu
176019Shines@cs.fsu.eduvoid DMASequencer::init(const vector<string> & argv)
186019Shines@cs.fsu.edu{
196019Shines@cs.fsu.edu  m_version = -1;
206019Shines@cs.fsu.edu  m_controller = NULL;
216019Shines@cs.fsu.edu  for (size_t i=0;i<argv.size();i+=2) {
226019Shines@cs.fsu.edu    if (argv[i] == "controller")
236019Shines@cs.fsu.edu      m_controller = RubySystem::getController(argv[i+1]);
246019Shines@cs.fsu.edu    else if (argv[i] == "version")
256019Shines@cs.fsu.edu      m_version = atoi(argv[i+1].c_str());
266019Shines@cs.fsu.edu  }
276019Shines@cs.fsu.edu  assert(m_controller != NULL);
286019Shines@cs.fsu.edu  assert(m_version != -1);
296019Shines@cs.fsu.edu
306019Shines@cs.fsu.edu  m_mandatory_q_ptr = m_controller->getMandatoryQueue();
316019Shines@cs.fsu.edu  m_is_busy = false;
326019Shines@cs.fsu.edu}
336019Shines@cs.fsu.edu
346019Shines@cs.fsu.eduint64_t DMASequencer::makeRequest(const RubyRequest & request)
356019Shines@cs.fsu.edu{
366019Shines@cs.fsu.edu  uint64_t paddr = request.paddr;
376019Shines@cs.fsu.edu  uint8_t* data = request.data;
386019Shines@cs.fsu.edu  int len = request.len;
396019Shines@cs.fsu.edu  bool write = false;
406019Shines@cs.fsu.edu  switch(request.type) {
416019Shines@cs.fsu.edu  case RubyRequestType_LD:
426019Shines@cs.fsu.edu    write = false;
436019Shines@cs.fsu.edu    break;
446019Shines@cs.fsu.edu  case RubyRequestType_ST:
456019Shines@cs.fsu.edu    write = true;
466019Shines@cs.fsu.edu    break;
476019Shines@cs.fsu.edu  case RubyRequestType_NULL:
486019Shines@cs.fsu.edu  case RubyRequestType_IFETCH:
496268Sgblack@eecs.umich.edu  case RubyRequestType_Locked_Read:
506251Sgblack@eecs.umich.edu  case RubyRequestType_Locked_Write:
516269Sgblack@eecs.umich.edu    assert(0);
526269Sgblack@eecs.umich.edu  }
536749Sgblack@eecs.umich.edu
546251Sgblack@eecs.umich.edu  assert(!m_is_busy);
556251Sgblack@eecs.umich.edu  m_is_busy = true;
566251Sgblack@eecs.umich.edu
576251Sgblack@eecs.umich.edu  active_request.start_paddr = paddr;
586743Ssaidi@eecs.umich.edu  active_request.write = write;
596251Sgblack@eecs.umich.edu  active_request.data = data;
606741Sgblack@eecs.umich.edu  active_request.len = len;
616251Sgblack@eecs.umich.edu  active_request.bytes_completed = 0;
626251Sgblack@eecs.umich.edu  active_request.bytes_issued = 0;
636268Sgblack@eecs.umich.edu  active_request.id = makeUniqueRequestID();
646759SAli.Saidi@ARM.com
656251Sgblack@eecs.umich.edu  DMARequestMsg msg;
666251Sgblack@eecs.umich.edu  msg.getPhysicalAddress() = Address(paddr);
676019Shines@cs.fsu.edu  msg.getType() = write ? DMARequestType_WRITE : DMARequestType_READ;
686267Sgblack@eecs.umich.edu  msg.getOffset() = paddr & RubyConfig::dataBlockMask();
696267Sgblack@eecs.umich.edu  msg.getLen() = (msg.getOffset() + len) < RubySystem::getBlockSizeBytes() ?
706267Sgblack@eecs.umich.edu    (msg.getOffset() + len) :
717101Sgblack@eecs.umich.edu    RubySystem::getBlockSizeBytes() - msg.getOffset();
727101Sgblack@eecs.umich.edu  if (write) {
737101Sgblack@eecs.umich.edu    msg.getType() = DMARequestType_WRITE;
746019Shines@cs.fsu.edu    msg.getDataBlk().setData(data, 0, msg.getLen());
756251Sgblack@eecs.umich.edu  } else {
766251Sgblack@eecs.umich.edu    msg.getType() = DMARequestType_READ;
776251Sgblack@eecs.umich.edu  }
786251Sgblack@eecs.umich.edu  m_mandatory_q_ptr->enqueue(msg);
796251Sgblack@eecs.umich.edu  active_request.bytes_issued += msg.getLen();
806251Sgblack@eecs.umich.edu
816251Sgblack@eecs.umich.edu  return active_request.id;
826019Shines@cs.fsu.edu}
836251Sgblack@eecs.umich.edu
846019Shines@cs.fsu.eduvoid DMASequencer::issueNext()
856275Sgblack@eecs.umich.edu{
866275Sgblack@eecs.umich.edu  assert(m_is_busy == true);
876275Sgblack@eecs.umich.edu  active_request.bytes_completed = active_request.bytes_issued;
886275Sgblack@eecs.umich.edu  if (active_request.len == active_request.bytes_completed) {
896275Sgblack@eecs.umich.edu    m_hit_callback(active_request.id);
906251Sgblack@eecs.umich.edu    m_is_busy = false;
916019Shines@cs.fsu.edu    return;
926275Sgblack@eecs.umich.edu  }
936019Shines@cs.fsu.edu
946275Sgblack@eecs.umich.edu  DMARequestMsg msg;
956019Shines@cs.fsu.edu  msg.getPhysicalAddress() = Address(active_request.start_paddr + active_request.bytes_completed);
966251Sgblack@eecs.umich.edu  assert((msg.getPhysicalAddress().getAddress() & RubyConfig::dataBlockMask()) == 0);
976019Shines@cs.fsu.edu  msg.getOffset() = 0;
986251Sgblack@eecs.umich.edu  msg.getType() = active_request.write ? DMARequestType_WRITE : DMARequestType_READ;
996251Sgblack@eecs.umich.edu  msg.getLen() = active_request.len - active_request.bytes_completed < RubySystem::getBlockSizeBytes() ?
1006019Shines@cs.fsu.edu    active_request.len - active_request.bytes_completed :
1016251Sgblack@eecs.umich.edu    RubySystem::getBlockSizeBytes();
1026019Shines@cs.fsu.edu  if (active_request.write) {
1036251Sgblack@eecs.umich.edu    msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed], 0, msg.getLen());
1046019Shines@cs.fsu.edu    msg.getType() = DMARequestType_WRITE;
1056251Sgblack@eecs.umich.edu  } else {
1066251Sgblack@eecs.umich.edu    msg.getType() = DMARequestType_READ;
1076251Sgblack@eecs.umich.edu  }
1086019Shines@cs.fsu.edu  m_mandatory_q_ptr->enqueue(msg);
1096019Shines@cs.fsu.edu  active_request.bytes_issued += msg.getLen();
1106251Sgblack@eecs.umich.edu}
1116251Sgblack@eecs.umich.edu
1126251Sgblack@eecs.umich.eduvoid DMASequencer::dataCallback(const DataBlock & dblk)
1136019Shines@cs.fsu.edu{
1146019Shines@cs.fsu.edu  assert(m_is_busy == true);
1156251Sgblack@eecs.umich.edu  int len = active_request.bytes_issued - active_request.bytes_completed;
1166019Shines@cs.fsu.edu  int offset = 0;
1177103Sgblack@eecs.umich.edu  if (active_request.bytes_completed == 0)
1187103Sgblack@eecs.umich.edu    offset = active_request.start_paddr & RubyConfig::dataBlockMask();
1197103Sgblack@eecs.umich.edu  memcpy(&active_request.data[active_request.bytes_completed], dblk.getData(offset, len), len);
1207103Sgblack@eecs.umich.edu  issueNext();
1217103Sgblack@eecs.umich.edu}
1227103Sgblack@eecs.umich.edu
1237103Sgblack@eecs.umich.eduvoid DMASequencer::ackCallback()
1247103Sgblack@eecs.umich.edu{
1257103Sgblack@eecs.umich.edu  issueNext();
1267103Sgblack@eecs.umich.edu}
1277103Sgblack@eecs.umich.edu
1287103Sgblack@eecs.umich.eduvoid DMASequencer::printConfig(ostream & out)
1297103Sgblack@eecs.umich.edu{
1307103Sgblack@eecs.umich.edu
1317103Sgblack@eecs.umich.edu}
132