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