DMASequencer.cc revision 6369:82ac95f4d9f0
110381Sdam.sunwoo@arm.com 210381Sdam.sunwoo@arm.com#include "mem/ruby/system/DMASequencer.hh" 310381Sdam.sunwoo@arm.com#include "mem/ruby/buffers/MessageBuffer.hh" 410381Sdam.sunwoo@arm.com#include "mem/ruby/slicc_interface/AbstractController.hh" 510381Sdam.sunwoo@arm.com 610381Sdam.sunwoo@arm.com/* SLICC generated types */ 710381Sdam.sunwoo@arm.com#include "mem/protocol/DMARequestMsg.hh" 810381Sdam.sunwoo@arm.com#include "mem/protocol/DMARequestType.hh" 910381Sdam.sunwoo@arm.com#include "mem/protocol/DMAResponseMsg.hh" 1010381Sdam.sunwoo@arm.com#include "mem/ruby/system/System.hh" 1110381Sdam.sunwoo@arm.com 1210381Sdam.sunwoo@arm.comDMASequencer::DMASequencer(const string & name) 1310381Sdam.sunwoo@arm.com : RubyPort(name) 1410381Sdam.sunwoo@arm.com{ 1510381Sdam.sunwoo@arm.com} 1610381Sdam.sunwoo@arm.com 1710381Sdam.sunwoo@arm.comvoid DMASequencer::init(const vector<string> & argv) 1810381Sdam.sunwoo@arm.com{ 1910381Sdam.sunwoo@arm.com m_version = -1; 2010381Sdam.sunwoo@arm.com m_controller = NULL; 2110381Sdam.sunwoo@arm.com for (size_t i=0;i<argv.size();i+=2) { 2210381Sdam.sunwoo@arm.com if (argv[i] == "controller") 2310381Sdam.sunwoo@arm.com m_controller = RubySystem::getController(argv[i+1]); 2410381Sdam.sunwoo@arm.com else if (argv[i] == "version") 2510381Sdam.sunwoo@arm.com m_version = atoi(argv[i+1].c_str()); 2610381Sdam.sunwoo@arm.com } 2710381Sdam.sunwoo@arm.com assert(m_controller != NULL); 2810381Sdam.sunwoo@arm.com assert(m_version != -1); 2910381Sdam.sunwoo@arm.com 3010381Sdam.sunwoo@arm.com m_mandatory_q_ptr = m_controller->getMandatoryQueue(); 3110381Sdam.sunwoo@arm.com m_is_busy = false; 3210381Sdam.sunwoo@arm.com m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits()); 3310381Sdam.sunwoo@arm.com} 3410381Sdam.sunwoo@arm.com 3510381Sdam.sunwoo@arm.comint64_t DMASequencer::makeRequest(const RubyRequest & request) 3610381Sdam.sunwoo@arm.com{ 3710381Sdam.sunwoo@arm.com uint64_t paddr = request.paddr; 3810381Sdam.sunwoo@arm.com uint8_t* data = request.data; 3910381Sdam.sunwoo@arm.com int len = request.len; 4010381Sdam.sunwoo@arm.com bool write = false; 4110381Sdam.sunwoo@arm.com switch(request.type) { 4210381Sdam.sunwoo@arm.com case RubyRequestType_LD: 4310381Sdam.sunwoo@arm.com write = false; 4411168Sandreas.hansson@arm.com break; 4511168Sandreas.hansson@arm.com case RubyRequestType_ST: 4611359Sandreas@sandberg.pp.se write = true; 4710381Sdam.sunwoo@arm.com break; 4810381Sdam.sunwoo@arm.com case RubyRequestType_NULL: 4910381Sdam.sunwoo@arm.com case RubyRequestType_IFETCH: 5010381Sdam.sunwoo@arm.com case RubyRequestType_Locked_Read: 5110381Sdam.sunwoo@arm.com case RubyRequestType_Locked_Write: 5210381Sdam.sunwoo@arm.com case RubyRequestType_RMW_Read: 5310381Sdam.sunwoo@arm.com case RubyRequestType_RMW_Write: 5410381Sdam.sunwoo@arm.com assert(0); 5510381Sdam.sunwoo@arm.com } 5610381Sdam.sunwoo@arm.com 5710381Sdam.sunwoo@arm.com assert(!m_is_busy); // only support one outstanding DMA request 5810381Sdam.sunwoo@arm.com m_is_busy = true; 5910381Sdam.sunwoo@arm.com 6010381Sdam.sunwoo@arm.com active_request.start_paddr = paddr; 6110381Sdam.sunwoo@arm.com active_request.write = write; 6210381Sdam.sunwoo@arm.com active_request.data = data; 6310381Sdam.sunwoo@arm.com active_request.len = len; 6411168Sandreas.hansson@arm.com active_request.bytes_completed = 0; 6510381Sdam.sunwoo@arm.com active_request.bytes_issued = 0; 6610381Sdam.sunwoo@arm.com active_request.id = makeUniqueRequestID(); 6710381Sdam.sunwoo@arm.com 6810381Sdam.sunwoo@arm.com DMARequestMsg msg; 6910381Sdam.sunwoo@arm.com msg.getPhysicalAddress() = Address(paddr); 7010381Sdam.sunwoo@arm.com msg.getLineAddress() = line_address(msg.getPhysicalAddress()); 7110381Sdam.sunwoo@arm.com msg.getType() = write ? DMARequestType_WRITE : DMARequestType_READ; 7210381Sdam.sunwoo@arm.com msg.getOffset() = paddr & m_data_block_mask; 7311168Sandreas.hansson@arm.com msg.getLen() = (msg.getOffset() + len) <= RubySystem::getBlockSizeBytes() ? 7410381Sdam.sunwoo@arm.com len : 7510381Sdam.sunwoo@arm.com RubySystem::getBlockSizeBytes() - msg.getOffset(); 7610381Sdam.sunwoo@arm.com if (write) { 7710381Sdam.sunwoo@arm.com msg.getType() = DMARequestType_WRITE; 7810381Sdam.sunwoo@arm.com msg.getDataBlk().setData(data, msg.getOffset(), msg.getLen()); 7910381Sdam.sunwoo@arm.com } else { 8010381Sdam.sunwoo@arm.com msg.getType() = DMARequestType_READ; 8110381Sdam.sunwoo@arm.com } 8210381Sdam.sunwoo@arm.com m_mandatory_q_ptr->enqueue(msg); 8310381Sdam.sunwoo@arm.com active_request.bytes_issued += msg.getLen(); 8410381Sdam.sunwoo@arm.com 8510381Sdam.sunwoo@arm.com return active_request.id; 8610381Sdam.sunwoo@arm.com} 8710381Sdam.sunwoo@arm.com 8810381Sdam.sunwoo@arm.comvoid DMASequencer::issueNext() 8910381Sdam.sunwoo@arm.com{ 9010381Sdam.sunwoo@arm.com assert(m_is_busy == true); 9110381Sdam.sunwoo@arm.com active_request.bytes_completed = active_request.bytes_issued; 9210381Sdam.sunwoo@arm.com if (active_request.len == active_request.bytes_completed) { 9310381Sdam.sunwoo@arm.com m_hit_callback(active_request.id); 9410381Sdam.sunwoo@arm.com m_is_busy = false; 9510381Sdam.sunwoo@arm.com return; 9610381Sdam.sunwoo@arm.com } 9710381Sdam.sunwoo@arm.com 9810381Sdam.sunwoo@arm.com DMARequestMsg msg; 9910381Sdam.sunwoo@arm.com msg.getPhysicalAddress() = Address(active_request.start_paddr + 10010381Sdam.sunwoo@arm.com active_request.bytes_completed); 10111359Sandreas@sandberg.pp.se assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0); 10210381Sdam.sunwoo@arm.com msg.getLineAddress() = line_address(msg.getPhysicalAddress()); 10310381Sdam.sunwoo@arm.com msg.getOffset() = 0; 10410381Sdam.sunwoo@arm.com msg.getType() = (active_request.write ? DMARequestType_WRITE : 10510381Sdam.sunwoo@arm.com DMARequestType_READ); 10610381Sdam.sunwoo@arm.com msg.getLen() = (active_request.len - 10710381Sdam.sunwoo@arm.com active_request.bytes_completed < RubySystem::getBlockSizeBytes() ? 10810381Sdam.sunwoo@arm.com active_request.len - active_request.bytes_completed : 10910381Sdam.sunwoo@arm.com RubySystem::getBlockSizeBytes()); 11010381Sdam.sunwoo@arm.com if (active_request.write) { 11110381Sdam.sunwoo@arm.com msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed], 11210381Sdam.sunwoo@arm.com 0, msg.getLen()); 11310381Sdam.sunwoo@arm.com msg.getType() = DMARequestType_WRITE; 11411168Sandreas.hansson@arm.com } else { 11510381Sdam.sunwoo@arm.com msg.getType() = DMARequestType_READ; 11610381Sdam.sunwoo@arm.com } 11710381Sdam.sunwoo@arm.com m_mandatory_q_ptr->enqueue(msg); 11810381Sdam.sunwoo@arm.com active_request.bytes_issued += msg.getLen(); 11910381Sdam.sunwoo@arm.com} 12010381Sdam.sunwoo@arm.com 12110381Sdam.sunwoo@arm.comvoid DMASequencer::dataCallback(const DataBlock & dblk) 122{ 123 assert(m_is_busy == true); 124 int len = active_request.bytes_issued - active_request.bytes_completed; 125 int offset = 0; 126 if (active_request.bytes_completed == 0) 127 offset = active_request.start_paddr & m_data_block_mask; 128 assert( active_request.write == false ); 129 memcpy(&active_request.data[active_request.bytes_completed], 130 dblk.getData(offset, len), len); 131 issueNext(); 132} 133 134void DMASequencer::ackCallback() 135{ 136 issueNext(); 137} 138 139void DMASequencer::printConfig(ostream & out) 140{ 141 142} 143