DMASequencer.cc revision 6888
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 276285Snate@binkert.orgint64_t 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: 476285Snate@binkert.org assert(0); 486285Snate@binkert.org } 496285Snate@binkert.org 506368Sdrh5@cs.wisc.edu assert(!m_is_busy); // only support one outstanding DMA request 516285Snate@binkert.org m_is_busy = true; 526285Snate@binkert.org 536285Snate@binkert.org active_request.start_paddr = paddr; 546285Snate@binkert.org active_request.write = write; 556285Snate@binkert.org active_request.data = data; 566285Snate@binkert.org active_request.len = len; 576285Snate@binkert.org active_request.bytes_completed = 0; 586285Snate@binkert.org active_request.bytes_issued = 0; 596285Snate@binkert.org active_request.id = makeUniqueRequestID(); 606285Snate@binkert.org 616467Sdrh5@cs.wisc.edu SequencerMsg msg; 626285Snate@binkert.org msg.getPhysicalAddress() = Address(paddr); 636368Sdrh5@cs.wisc.edu msg.getLineAddress() = line_address(msg.getPhysicalAddress()); 646467Sdrh5@cs.wisc.edu msg.getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD; 656467Sdrh5@cs.wisc.edu int offset = paddr & m_data_block_mask; 666888SBrad.Beckmann@amd.com 676467Sdrh5@cs.wisc.edu msg.getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ? 686368Sdrh5@cs.wisc.edu len : 696467Sdrh5@cs.wisc.edu RubySystem::getBlockSizeBytes() - offset; 706888SBrad.Beckmann@amd.com 716888SBrad.Beckmann@amd.com if (write) { 726467Sdrh5@cs.wisc.edu msg.getDataBlk().setData(data, offset, msg.getLen()); 736888SBrad.Beckmann@amd.com } 746888SBrad.Beckmann@amd.com 756888SBrad.Beckmann@amd.com assert(m_mandatory_q_ptr != NULL); 766285Snate@binkert.org m_mandatory_q_ptr->enqueue(msg); 776285Snate@binkert.org active_request.bytes_issued += msg.getLen(); 786285Snate@binkert.org 796285Snate@binkert.org return active_request.id; 806285Snate@binkert.org} 816285Snate@binkert.org 826285Snate@binkert.orgvoid DMASequencer::issueNext() 836285Snate@binkert.org{ 846285Snate@binkert.org assert(m_is_busy == true); 856285Snate@binkert.org active_request.bytes_completed = active_request.bytes_issued; 866285Snate@binkert.org if (active_request.len == active_request.bytes_completed) { 876285Snate@binkert.org m_hit_callback(active_request.id); 886285Snate@binkert.org m_is_busy = false; 896285Snate@binkert.org return; 906285Snate@binkert.org } 916285Snate@binkert.org 926467Sdrh5@cs.wisc.edu SequencerMsg msg; 936368Sdrh5@cs.wisc.edu msg.getPhysicalAddress() = Address(active_request.start_paddr + 946368Sdrh5@cs.wisc.edu active_request.bytes_completed); 956888SBrad.Beckmann@amd.com 966368Sdrh5@cs.wisc.edu assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0); 976368Sdrh5@cs.wisc.edu msg.getLineAddress() = line_address(msg.getPhysicalAddress()); 986888SBrad.Beckmann@amd.com 996467Sdrh5@cs.wisc.edu msg.getType() = (active_request.write ? SequencerRequestType_ST : 1006467Sdrh5@cs.wisc.edu SequencerRequestType_LD); 1016888SBrad.Beckmann@amd.com 1026368Sdrh5@cs.wisc.edu msg.getLen() = (active_request.len - 1036368Sdrh5@cs.wisc.edu active_request.bytes_completed < RubySystem::getBlockSizeBytes() ? 1046368Sdrh5@cs.wisc.edu active_request.len - active_request.bytes_completed : 1056368Sdrh5@cs.wisc.edu RubySystem::getBlockSizeBytes()); 1066888SBrad.Beckmann@amd.com 1076285Snate@binkert.org if (active_request.write) { 1086368Sdrh5@cs.wisc.edu msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed], 1096368Sdrh5@cs.wisc.edu 0, msg.getLen()); 1106467Sdrh5@cs.wisc.edu msg.getType() = SequencerRequestType_ST; 1116285Snate@binkert.org } else { 1126467Sdrh5@cs.wisc.edu msg.getType() = SequencerRequestType_LD; 1136285Snate@binkert.org } 1146888SBrad.Beckmann@amd.com 1156888SBrad.Beckmann@amd.com assert(m_mandatory_q_ptr != NULL); 1166285Snate@binkert.org m_mandatory_q_ptr->enqueue(msg); 1176285Snate@binkert.org active_request.bytes_issued += msg.getLen(); 1186285Snate@binkert.org} 1196285Snate@binkert.org 1206285Snate@binkert.orgvoid DMASequencer::dataCallback(const DataBlock & dblk) 1216285Snate@binkert.org{ 1226285Snate@binkert.org assert(m_is_busy == true); 1236285Snate@binkert.org int len = active_request.bytes_issued - active_request.bytes_completed; 1246285Snate@binkert.org int offset = 0; 1256285Snate@binkert.org if (active_request.bytes_completed == 0) 1266368Sdrh5@cs.wisc.edu offset = active_request.start_paddr & m_data_block_mask; 1276368Sdrh5@cs.wisc.edu assert( active_request.write == false ); 1286368Sdrh5@cs.wisc.edu memcpy(&active_request.data[active_request.bytes_completed], 1296368Sdrh5@cs.wisc.edu dblk.getData(offset, len), len); 1306285Snate@binkert.org issueNext(); 1316285Snate@binkert.org} 1326285Snate@binkert.org 1336285Snate@binkert.orgvoid DMASequencer::ackCallback() 1346285Snate@binkert.org{ 1356285Snate@binkert.org issueNext(); 1366285Snate@binkert.org} 1376285Snate@binkert.org 1386285Snate@binkert.orgvoid DMASequencer::printConfig(ostream & out) 1396285Snate@binkert.org{ 1406285Snate@binkert.org 1416285Snate@binkert.org} 1426876Ssteve.reinhardt@amd.com 1436876Ssteve.reinhardt@amd.com 1446876Ssteve.reinhardt@amd.comDMASequencer * 1456876Ssteve.reinhardt@amd.comDMASequencerParams::create() 1466876Ssteve.reinhardt@amd.com{ 1476876Ssteve.reinhardt@amd.com return new DMASequencer(this); 1486876Ssteve.reinhardt@amd.com} 149