dma_interface_impl.hh
来自「linux下基于c++的处理器仿真平台。具有处理器流水线」· HH 代码 · 共 188 行
HH
188 行
/* * Copyright (c) 2002, 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator, developed by Nathan Binkert, * Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions * from Ron Dreslinski, Dave Greene, Lisa Hsu, Kevin Lim, Ali Saidi, * and Andrew Schultz. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. *//** * @file * Definitions of a wrapper for introducing DMA to the memory hierarchy. */#include "mem/bus/dma_interface.hh"#include "mem/bus/dma_bus_interface.hh"#include "base/trace.hh"using namespace std;template <class BusType>DMAInterface<BusType>::DMAInterface(const std::string &name, BusType *header_bus, BusType *payload_bus, int header_size, bool dma_no_allocate) : SimObject(name), headerSize(header_size), completionEvent(NULL), headerSplit(false){ doData = false; if (header_bus != payload_bus) { header = new DMABusInterface<BusType>(name + ".header", header_bus, this, blkSize, dma_no_allocate); headerSplit = true; } payload = new DMABusInterface<BusType>(name + ".payload", payload_bus, this, blkSize, dma_no_allocate);}template <class BusType>DMAInterface<BusType>::~DMAInterface(){ if (header) delete header; if (payload) delete payload;}template <class BusType>void DMAInterface<BusType>::regStats() { using namespace Stats; totalSmallTransactions .name(name() + ".small_transactions") .desc("Total number of transactions less than the block size.") ; totalLargeTransactions .name(name() + ".large_transactions") .desc("Total number of transactions greater than the block size.") ; totalTransactions .name(name() + ".requests") .desc("Total number of dma requests made") ; totalTransactions = totalSmallTransactions + totalLargeTransactions; totalPacketsSent .name(name() + ".packets_sent") .desc("number of packets sent(blocks)") ; totalPacketLatency .name(name() + ".total_cycle_latency") .desc("sum of all latencies") ; avgPacketLatency .name(name() + ".round_trip_latency") .desc("Average Round-Trip latency") ; avgPacketLatency = totalPacketLatency / totalPacketsSent; totalBytesSent .name(name() + ".bytes_transfered") .desc("Total bytes sent") ; totalSmallTransactionLatency .name(name() + ".small_transaction_latency") .desc("The total cycle latency of all small transactions.") ; totalLargeTransactionLatency .name(name() + ".large_transaction_latency") .desc("The total cycle latency of all large transactions.") ; totalTransactionLatency .name(name() + ".transaction_latency") .desc("The total cycle latency of all transactions.") ; totalTransactionLatency = totalSmallTransactionLatency + totalLargeTransactionLatency; avgSmallTransactionLatency .name(name() + ".avg_small_transaction_latency") .desc("The average latency of small transactions.") ; avgSmallTransactionLatency = totalSmallTransactionLatency / totalSmallTransactions; avgLargeTransactionLatency .name(name() + ".avg_large_transaction_latency") .desc("The average latency of large transactions.") ; avgLargeTransactionLatency = totalLargeTransactionLatency / totalLargeTransactions; avgTransactionLatency .name(name() + ".avg_transaction_latency") .desc("The average latency of all transactions.") ; avgTransactionLatency = totalTransactionLatency / totalTransactions; }template <class BusType>voidDMAInterface<BusType>::doDMA(MemCmd cmd, Addr addr, int size, Tick start, Event *event, bool nic_req, uint8_t *data){ assert(!busy()); completionEvent = event; // event to schedule when completed transfer transactionStart = start; smallTransaction = size <= blkSize; DPRINTF(DMA, "DMA Interface do DMA addr=%#x, size=%d, start=%+d\n", addr, size, start - curTick); if (smallTransaction) { ++totalSmallTransactions; } else { ++totalLargeTransactions; } count = 1; int header_size = 0; if (headerSplit) { header_size = headerSize * blkSize; if (size <= header_size) { // just send the whole transfer to the header interface. header->doDMA(cmd, addr, size, start, data, nic_req); return; } // do not send the last partial transfer block header_size = header_size - blkOffset(addr); header->doDMA(cmd, addr, header_size, start, data, nic_req); count = 2; } // We can't get here unless we have remaining bytes to send assert(size - header_size > 0); payload->doDMA(cmd, addr + header_size, size - header_size, start, data + header_size, nic_req);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?