DMASequencer.cc revision 6922
16285Snate@binkert.org 26285Snate@binkert.org#include "mem/ruby/system/DMASequencer.hh" 36285Snate@binkert.org#include "mem/ruby/buffers/MessageBuffer.hh" 46285Snate@binkert.org#include "mem/ruby/slicc_interface/AbstractController.hh" 56285Snate@binkert.org 66285Snate@binkert.org/* SLICC generated types */ 76467Sdrh5@cs.wisc.edu#include "mem/protocol/SequencerMsg.hh" 86467Sdrh5@cs.wisc.edu#include "mem/protocol/SequencerRequestType.hh" 96285Snate@binkert.org#include "mem/ruby/system/System.hh" 106285Snate@binkert.org 116888SBrad.Beckmann@amd.com// 126888SBrad.Beckmann@amd.com// Fix me: This code needs comments! 136888SBrad.Beckmann@amd.com// 146888SBrad.Beckmann@amd.com 156876Ssteve.reinhardt@amd.comDMASequencer::DMASequencer(const Params *p) 166876Ssteve.reinhardt@amd.com : RubyPort(p) 176285Snate@binkert.org{ 186285Snate@binkert.org} 196285Snate@binkert.org 206876Ssteve.reinhardt@amd.comvoid DMASequencer::init() 216285Snate@binkert.org{ 226888SBrad.Beckmann@amd.com RubyPort::init(); 236285Snate@binkert.org m_is_busy = false; 246368Sdrh5@cs.wisc.edu m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits()); 256285Snate@binkert.org} 266285Snate@binkert.org 276922SBrad.Beckmann@amd.comRequestStatus DMASequencer::makeRequest(const RubyRequest & request) 286285Snate@binkert.org{ 296285Snate@binkert.org uint64_t paddr = request.paddr; 306285Snate@binkert.org uint8_t* data = request.data; 316285Snate@binkert.org int len = request.len; 326285Snate@binkert.org bool write = false; 336285Snate@binkert.org switch(request.type) { 346285Snate@binkert.org case RubyRequestType_LD: 356285Snate@binkert.org write = false; 366285Snate@binkert.org break; 376285Snate@binkert.org case RubyRequestType_ST: 386285Snate@binkert.org write = true; 396285Snate@binkert.org break; 406285Snate@binkert.org case RubyRequestType_NULL: 416285Snate@binkert.org case RubyRequestType_IFETCH: 426350Spdudnik@gmail.com case RubyRequestType_Locked_Read: 436350Spdudnik@gmail.com case RubyRequestType_Locked_Write: 446355Spdudnik@gmail.com case RubyRequestType_RMW_Read: 456355Spdudnik@gmail.com case RubyRequestType_RMW_Write: 466433Sdrh5@cs.wisc.edu case RubyRequestType_NUM: 476922SBrad.Beckmann@amd.com panic("DMASequencer::makeRequest does not support the RubyRequestType"); 486922SBrad.Beckmann@amd.com return RequestStatus_NULL; 496285Snate@binkert.org } 506285Snate@binkert.org 516368Sdrh5@cs.wisc.edu assert(!m_is_busy); // only support one outstanding DMA request 526285Snate@binkert.org m_is_busy = true; 536285Snate@binkert.org 546285Snate@binkert.org active_request.start_paddr = paddr; 556285Snate@binkert.org active_request.write = write; 566285Snate@binkert.org active_request.data = data; 576285Snate@binkert.org active_request.len = len; 586285Snate@binkert.org active_request.bytes_completed = 0; 596285Snate@binkert.org active_request.bytes_issued = 0; 606922SBrad.Beckmann@amd.com active_request.pkt = request.pkt; 616285Snate@binkert.org 626467Sdrh5@cs.wisc.edu SequencerMsg msg; 636285Snate@binkert.org msg.getPhysicalAddress() = Address(paddr); 646368Sdrh5@cs.wisc.edu msg.getLineAddress() = line_address(msg.getPhysicalAddress()); 656467Sdrh5@cs.wisc.edu msg.getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD; 666467Sdrh5@cs.wisc.edu int offset = paddr & m_data_block_mask; 676888SBrad.Beckmann@amd.com 686467Sdrh5@cs.wisc.edu msg.getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ? 696368Sdrh5@cs.wisc.edu len : 706467Sdrh5@cs.wisc.edu RubySystem::getBlockSizeBytes() - offset; 716888SBrad.Beckmann@amd.com 726888SBrad.Beckmann@amd.com if (write) { 736467Sdrh5@cs.wisc.edu msg.getDataBlk().setData(data, offset, msg.getLen()); 746888SBrad.Beckmann@amd.com } 756888SBrad.Beckmann@amd.com 766888SBrad.Beckmann@amd.com assert(m_mandatory_q_ptr != NULL); 776285Snate@binkert.org m_mandatory_q_ptr->enqueue(msg); 786285Snate@binkert.org active_request.bytes_issued += msg.getLen(); 796285Snate@binkert.org 806922SBrad.Beckmann@amd.com return RequestStatus_Issued; 816285Snate@binkert.org} 826285Snate@binkert.org 836285Snate@binkert.orgvoid DMASequencer::issueNext() 846285Snate@binkert.org{ 856285Snate@binkert.org assert(m_is_busy == true); 866285Snate@binkert.org active_request.bytes_completed = active_request.bytes_issued; 876285Snate@binkert.org if (active_request.len == active_request.bytes_completed) { 886922SBrad.Beckmann@amd.com ruby_hit_callback(active_request.pkt); 896285Snate@binkert.org m_is_busy = false; 906285Snate@binkert.org return; 916285Snate@binkert.org } 926285Snate@binkert.org 936467Sdrh5@cs.wisc.edu SequencerMsg msg; 946368Sdrh5@cs.wisc.edu msg.getPhysicalAddress() = Address(active_request.start_paddr + 956922SBrad.Beckmann@amd.com active_request.bytes_completed); 966888SBrad.Beckmann@amd.com 976368Sdrh5@cs.wisc.edu assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0); 986368Sdrh5@cs.wisc.edu msg.getLineAddress() = line_address(msg.getPhysicalAddress()); 996888SBrad.Beckmann@amd.com 1006467Sdrh5@cs.wisc.edu msg.getType() = (active_request.write ? SequencerRequestType_ST : 1016467Sdrh5@cs.wisc.edu SequencerRequestType_LD); 1026888SBrad.Beckmann@amd.com 1036368Sdrh5@cs.wisc.edu msg.getLen() = (active_request.len - 1046368Sdrh5@cs.wisc.edu active_request.bytes_completed < RubySystem::getBlockSizeBytes() ? 1056368Sdrh5@cs.wisc.edu active_request.len - active_request.bytes_completed : 1066368Sdrh5@cs.wisc.edu RubySystem::getBlockSizeBytes()); 1076888SBrad.Beckmann@amd.com 1086285Snate@binkert.org if (active_request.write) { 1096368Sdrh5@cs.wisc.edu msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed], 1106368Sdrh5@cs.wisc.edu 0, msg.getLen()); 1116467Sdrh5@cs.wisc.edu msg.getType() = SequencerRequestType_ST; 1126285Snate@binkert.org } else { 1136467Sdrh5@cs.wisc.edu msg.getType() = SequencerRequestType_LD; 1146285Snate@binkert.org } 1156888SBrad.Beckmann@amd.com 1166888SBrad.Beckmann@amd.com assert(m_mandatory_q_ptr != NULL); 1176285Snate@binkert.org m_mandatory_q_ptr->enqueue(msg); 1186285Snate@binkert.org active_request.bytes_issued += msg.getLen(); 1196285Snate@binkert.org} 1206285Snate@binkert.org 1216285Snate@binkert.orgvoid DMASequencer::dataCallback(const DataBlock & dblk) 1226285Snate@binkert.org{ 1236285Snate@binkert.org assert(m_is_busy == true); 1246285Snate@binkert.org int len = active_request.bytes_issued - active_request.bytes_completed; 1256285Snate@binkert.org int offset = 0; 1266285Snate@binkert.org if (active_request.bytes_completed == 0) 1276368Sdrh5@cs.wisc.edu offset = active_request.start_paddr & m_data_block_mask; 1286368Sdrh5@cs.wisc.edu assert( active_request.write == false ); 1296368Sdrh5@cs.wisc.edu memcpy(&active_request.data[active_request.bytes_completed], 1306368Sdrh5@cs.wisc.edu dblk.getData(offset, len), len); 1316285Snate@binkert.org issueNext(); 1326285Snate@binkert.org} 1336285Snate@binkert.org 1346285Snate@binkert.orgvoid DMASequencer::ackCallback() 1356285Snate@binkert.org{ 1366285Snate@binkert.org issueNext(); 1376285Snate@binkert.org} 1386285Snate@binkert.org 1396285Snate@binkert.orgvoid DMASequencer::printConfig(ostream & out) 1406285Snate@binkert.org{ 1416285Snate@binkert.org 1426285Snate@binkert.org} 1436876Ssteve.reinhardt@amd.com 1446876Ssteve.reinhardt@amd.com 1456876Ssteve.reinhardt@amd.comDMASequencer * 1466876Ssteve.reinhardt@amd.comDMASequencerParams::create() 1476876Ssteve.reinhardt@amd.com{ 1486876Ssteve.reinhardt@amd.com return new DMASequencer(this); 1496876Ssteve.reinhardt@amd.com} 150