dma_device.hh revision 9342:6fec8f26e56d
17202Sgblack@eecs.umich.edu/* 27202Sgblack@eecs.umich.edu * Copyright (c) 2012 ARM Limited 37202Sgblack@eecs.umich.edu * All rights reserved. 47202Sgblack@eecs.umich.edu * 57202Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67202Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77202Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87202Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97202Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107202Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117202Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127202Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137202Sgblack@eecs.umich.edu * 147202Sgblack@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan 157202Sgblack@eecs.umich.edu * All rights reserved. 167202Sgblack@eecs.umich.edu * 177202Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 187202Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 197202Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 207202Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 217202Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 227202Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 237202Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 247202Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 257202Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 267202Sgblack@eecs.umich.edu * this software without specific prior written permission. 277202Sgblack@eecs.umich.edu * 287202Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 297202Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 307202Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 317202Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 327202Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 337202Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 347202Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 357202Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 367202Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 377202Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 387202Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 397202Sgblack@eecs.umich.edu * 407202Sgblack@eecs.umich.edu * Authors: Ali Saidi 417202Sgblack@eecs.umich.edu * Nathan Binkert 427202Sgblack@eecs.umich.edu */ 437202Sgblack@eecs.umich.edu 447202Sgblack@eecs.umich.edu#ifndef __DEV_DMA_DEVICE_HH__ 457202Sgblack@eecs.umich.edu#define __DEV_DMA_DEVICE_HH__ 467202Sgblack@eecs.umich.edu 477202Sgblack@eecs.umich.edu#include <deque> 487202Sgblack@eecs.umich.edu 497202Sgblack@eecs.umich.edu#include "dev/io_device.hh" 507202Sgblack@eecs.umich.edu#include "params/DmaDevice.hh" 517202Sgblack@eecs.umich.edu#include "sim/drain.hh" 527202Sgblack@eecs.umich.edu 537202Sgblack@eecs.umich.educlass DmaPort : public MasterPort 547202Sgblack@eecs.umich.edu{ 557202Sgblack@eecs.umich.edu private: 567202Sgblack@eecs.umich.edu 577202Sgblack@eecs.umich.edu /** 587202Sgblack@eecs.umich.edu * Take the first packet of the transmit list and attempt to send 597202Sgblack@eecs.umich.edu * it as a timing request. If it is successful, schedule the 607202Sgblack@eecs.umich.edu * sending of the next packet, otherwise remember that we are 617202Sgblack@eecs.umich.edu * waiting for a retry. 627202Sgblack@eecs.umich.edu */ 637202Sgblack@eecs.umich.edu void trySendTimingReq(); 647202Sgblack@eecs.umich.edu 657202Sgblack@eecs.umich.edu /** 667202Sgblack@eecs.umich.edu * For timing, attempt to send the first item on the transmit 677202Sgblack@eecs.umich.edu * list, and if it is successful and there are more packets 687202Sgblack@eecs.umich.edu * waiting, then schedule the sending of the next packet. For 697202Sgblack@eecs.umich.edu * atomic, simply send and process everything on the transmit 707202Sgblack@eecs.umich.edu * list. 717202Sgblack@eecs.umich.edu */ 727202Sgblack@eecs.umich.edu void sendDma(); 737202Sgblack@eecs.umich.edu 747202Sgblack@eecs.umich.edu /** 757202Sgblack@eecs.umich.edu * Handle a response packet by updating the corresponding DMA 767202Sgblack@eecs.umich.edu * request state to reflect the bytes received, and also update 777202Sgblack@eecs.umich.edu * the pending request counter. If the DMA request that this 787202Sgblack@eecs.umich.edu * packet is part of is complete, then signal the completion event 797202Sgblack@eecs.umich.edu * if present, potentially with a delay added to it. 807202Sgblack@eecs.umich.edu * 817202Sgblack@eecs.umich.edu * @param pkt Response packet to handler 827202Sgblack@eecs.umich.edu * @param delay Additional delay for scheduling the completion event 837202Sgblack@eecs.umich.edu */ 847202Sgblack@eecs.umich.edu void handleResp(PacketPtr pkt, Tick delay = 0); 857202Sgblack@eecs.umich.edu 867202Sgblack@eecs.umich.edu struct DmaReqState : public Packet::SenderState 877202Sgblack@eecs.umich.edu { 887202Sgblack@eecs.umich.edu /** Event to call on the device when this transaction (all packets) 897202Sgblack@eecs.umich.edu * complete. */ 907202Sgblack@eecs.umich.edu Event *completionEvent; 917202Sgblack@eecs.umich.edu 927202Sgblack@eecs.umich.edu /** Total number of bytes that this transaction involves. */ 937202Sgblack@eecs.umich.edu const Addr totBytes; 947202Sgblack@eecs.umich.edu 957202Sgblack@eecs.umich.edu /** Number of bytes that have been acked for this transaction. */ 967202Sgblack@eecs.umich.edu Addr numBytes; 977202Sgblack@eecs.umich.edu 987202Sgblack@eecs.umich.edu /** Amount to delay completion of dma by */ 997202Sgblack@eecs.umich.edu const Tick delay; 1007202Sgblack@eecs.umich.edu 1017208Sgblack@eecs.umich.edu DmaReqState(Event *ce, Addr tb, Tick _delay) 1027208Sgblack@eecs.umich.edu : completionEvent(ce), totBytes(tb), numBytes(0), delay(_delay) 1037208Sgblack@eecs.umich.edu {} 1047208Sgblack@eecs.umich.edu }; 1057208Sgblack@eecs.umich.edu 1067208Sgblack@eecs.umich.edu /** The device that owns this port. */ 1077208Sgblack@eecs.umich.edu MemObject *device; 1087208Sgblack@eecs.umich.edu 1097208Sgblack@eecs.umich.edu /** Use a deque as we never do any insertion or removal in the middle */ 1107208Sgblack@eecs.umich.edu std::deque<PacketPtr> transmitList; 1117208Sgblack@eecs.umich.edu 1127208Sgblack@eecs.umich.edu /** Event used to schedule a future sending from the transmit list. */ 1137208Sgblack@eecs.umich.edu EventWrapper<DmaPort, &DmaPort::sendDma> sendEvent; 1147208Sgblack@eecs.umich.edu 1157208Sgblack@eecs.umich.edu /** The system that device/port are in. This is used to select which mode 1167208Sgblack@eecs.umich.edu * we are currently operating in. */ 1177208Sgblack@eecs.umich.edu System *sys; 1187208Sgblack@eecs.umich.edu 1197208Sgblack@eecs.umich.edu /** Id for all requests */ 1207208Sgblack@eecs.umich.edu const MasterID masterId; 1217208Sgblack@eecs.umich.edu 1227225Sgblack@eecs.umich.edu /** Number of outstanding packets the dma port has. */ 1237233Sgblack@eecs.umich.edu uint32_t pendingCount; 1247233Sgblack@eecs.umich.edu 1257233Sgblack@eecs.umich.edu /** If we need to drain, keep the drain event around until we're done 1267233Sgblack@eecs.umich.edu * here.*/ 1277233Sgblack@eecs.umich.edu DrainManager *drainManager; 1287233Sgblack@eecs.umich.edu 1297233Sgblack@eecs.umich.edu /** If the port is currently waiting for a retry before it can 1307233Sgblack@eecs.umich.edu * send whatever it is that it's sending. */ 1317233Sgblack@eecs.umich.edu bool inRetry; 1327233Sgblack@eecs.umich.edu 1337233Sgblack@eecs.umich.edu protected: 1347233Sgblack@eecs.umich.edu 1357233Sgblack@eecs.umich.edu bool recvTimingResp(PacketPtr pkt); 1367233Sgblack@eecs.umich.edu void recvRetry() ; 1377233Sgblack@eecs.umich.edu 1387233Sgblack@eecs.umich.edu void queueDma(PacketPtr pkt); 1397233Sgblack@eecs.umich.edu 1407233Sgblack@eecs.umich.edu public: 1417233Sgblack@eecs.umich.edu 1427233Sgblack@eecs.umich.edu DmaPort(MemObject *dev, System *s); 1437233Sgblack@eecs.umich.edu 1447233Sgblack@eecs.umich.edu void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, 1457233Sgblack@eecs.umich.edu uint8_t *data, Tick delay, Request::Flags flag = 0); 1467233Sgblack@eecs.umich.edu 1477233Sgblack@eecs.umich.edu bool dmaPending() const { return pendingCount > 0; } 1487233Sgblack@eecs.umich.edu 1497232Sgblack@eecs.umich.edu unsigned cacheBlockSize() const { return peerBlockSize(); } 1507225Sgblack@eecs.umich.edu unsigned int drain(DrainManager *drainManger); 1517225Sgblack@eecs.umich.edu}; 1527225Sgblack@eecs.umich.edu 1537225Sgblack@eecs.umich.educlass DmaDevice : public PioDevice 1547225Sgblack@eecs.umich.edu{ 1557225Sgblack@eecs.umich.edu protected: 1567232Sgblack@eecs.umich.edu DmaPort dmaPort; 1577225Sgblack@eecs.umich.edu 1587225Sgblack@eecs.umich.edu public: 1597225Sgblack@eecs.umich.edu typedef DmaDeviceParams Params; 1607225Sgblack@eecs.umich.edu DmaDevice(const Params *p); 1617232Sgblack@eecs.umich.edu virtual ~DmaDevice() { } 1627225Sgblack@eecs.umich.edu 1637225Sgblack@eecs.umich.edu void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, 1647232Sgblack@eecs.umich.edu Tick delay = 0) 1657225Sgblack@eecs.umich.edu { 1667225Sgblack@eecs.umich.edu dmaPort.dmaAction(MemCmd::WriteReq, addr, size, event, data, delay); 1677232Sgblack@eecs.umich.edu } 1687225Sgblack@eecs.umich.edu 1697225Sgblack@eecs.umich.edu void dmaRead(Addr addr, int size, Event *event, uint8_t *data, 1707225Sgblack@eecs.umich.edu Tick delay = 0) 1717225Sgblack@eecs.umich.edu { 1727225Sgblack@eecs.umich.edu dmaPort.dmaAction(MemCmd::ReadReq, addr, size, event, data, delay); 1737232Sgblack@eecs.umich.edu } 1747225Sgblack@eecs.umich.edu 1757225Sgblack@eecs.umich.edu bool dmaPending() const { return dmaPort.dmaPending(); } 1767225Sgblack@eecs.umich.edu 1777225Sgblack@eecs.umich.edu virtual void init(); 1787225Sgblack@eecs.umich.edu 1797225Sgblack@eecs.umich.edu unsigned int drain(DrainManager *drainManger); 1807232Sgblack@eecs.umich.edu 1817225Sgblack@eecs.umich.edu unsigned cacheBlockSize() const { return dmaPort.cacheBlockSize(); } 1827225Sgblack@eecs.umich.edu 1837225Sgblack@eecs.umich.edu virtual BaseMasterPort &getMasterPort(const std::string &if_name, 1847225Sgblack@eecs.umich.edu PortID idx = InvalidPortID); 1857225Sgblack@eecs.umich.edu 1867232Sgblack@eecs.umich.edu}; 1877225Sgblack@eecs.umich.edu 1887225Sgblack@eecs.umich.edu#endif // __DEV_DMA_DEVICE_HH__ 1897232Sgblack@eecs.umich.edu