dma_device.cc revision 2384
1955SN/A/*
2955SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
35871Snate@binkert.org * All rights reserved.
41762SN/A *
5955SN/A * Redistribution and use in source and binary forms, with or without
6955SN/A * modification, are permitted provided that the following conditions are
7955SN/A * met: redistributions of source code must retain the above copyright
8955SN/A * notice, this list of conditions and the following disclaimer;
9955SN/A * redistributions in binary form must reproduce the above copyright
10955SN/A * notice, this list of conditions and the following disclaimer in the
11955SN/A * documentation and/or other materials provided with the distribution;
12955SN/A * neither the name of the copyright holders nor the names of its
13955SN/A * contributors may be used to endorse or promote products derived from
14955SN/A * this software without specific prior written permission.
15955SN/A *
16955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27955SN/A */
28955SN/A
292665Ssaidi@eecs.umich.edu#include "dev/io_device.hh"
302665Ssaidi@eecs.umich.edu#include "sim/builder.hh"
315863Snate@binkert.org
32955SN/Avoid
33955SN/APioPort::SendEvent::process()
34955SN/A{
35955SN/A    if (port->sendTiming(packet) == Success)
36955SN/A        return;
372632Sstever@eecs.umich.edu
382632Sstever@eecs.umich.edu    port->transmitList.push_back(&packet);
392632Sstever@eecs.umich.edu}
402632Sstever@eecs.umich.edu
41955SN/APioDevice::PioDevice(const std::string &name, Platform *p)
422632Sstever@eecs.umich.edu    : SimObject(name), platform(p)
432632Sstever@eecs.umich.edu{
442761Sstever@eecs.umich.edu    pioPort = new PioPort(this);
452632Sstever@eecs.umich.edu}
462632Sstever@eecs.umich.edu
472632Sstever@eecs.umich.edu
482761Sstever@eecs.umich.edubool
492761Sstever@eecs.umich.eduPioDevice::recvTiming(Packet &pkt)
502761Sstever@eecs.umich.edu{
512632Sstever@eecs.umich.edu    device->recvAtomic(pkt);
522632Sstever@eecs.umich.edu    sendTiming(pkt, pkt.responseTime-pkt.requestTime);
532761Sstever@eecs.umich.edu    return Success;
542761Sstever@eecs.umich.edu}
552761Sstever@eecs.umich.edu
562761Sstever@eecs.umich.eduPioDevice::~PioDevice()
572761Sstever@eecs.umich.edu{
582632Sstever@eecs.umich.edu    if (pioPort)
592632Sstever@eecs.umich.edu        delete pioInterface;
602632Sstever@eecs.umich.edu}
612632Sstever@eecs.umich.edu
622632Sstever@eecs.umich.eduvoid
632632Sstever@eecs.umich.eduDmaPort::sendDma(Packet &pkt)
642632Sstever@eecs.umich.edu{
65955SN/A    device->platform->system->memoryMode()
66955SN/A    {
67955SN/A        case MemAtomic:
685863Snate@binkert.org    }
695863Snate@binkert.org}
705863Snate@binkert.org
715863Snate@binkert.orgDmaDevice::DmaDevice(const std::string &name, Platform *p)
725863Snate@binkert.org    : PioDevice(name, p)
735863Snate@binkert.org{
745863Snate@binkert.org    dmaPort = new dmaPort(this);
755863Snate@binkert.org}
765863Snate@binkert.org
775863Snate@binkert.orgvoid
785863Snate@binkert.orgDmaPort::dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size,
795863Snate@binkert.org                     Event *event, uint8_t *data = NULL)
805863Snate@binkert.org{
815863Snate@binkert.org
825863Snate@binkert.org    assert(event);
835863Snate@binkert.org
845863Snate@binkert.org    int prevSize = 0;
855863Snate@binkert.org    Packet basePkt;
865863Snate@binkert.org    Request baseReq;
875863Snate@binkert.org
885863Snate@binkert.org    basePkt.flags = 0;
895863Snate@binkert.org    basePkt.coherence = NULL;
905863Snate@binkert.org    basePkt.senderState = NULL;
915863Snate@binkert.org    basePkt.src = 0;
925863Snate@binkert.org    basePkt.dest = 0;
935863Snate@binkert.org    basePkt.cmd = cmd;
945863Snate@binkert.org    basePkt.result = Unknown;
955863Snate@binkert.org    basePkt.request = NULL;
965863Snate@binkert.org    baseReq.nicReq = true;
975863Snate@binkert.org    baseReq.time = curTick;
985863Snate@binkert.org
99955SN/A    completionEvent = event;
1005396Ssaidi@eecs.umich.edu
1015863Snate@binkert.org    for (ChunkGenerator gen(addr, size, sendBlockSizeQuery()); !gen.done(); gen.next()) {
1025863Snate@binkert.org            Packet *pkt = new Packet(basePkt);
1034202Sbinkertn@umich.edu            Request *req = new Request(baseReq);
1045863Snate@binkert.org            pkt->addr = gen.addr();
1055863Snate@binkert.org            pkt->size = gen.size();
1065863Snate@binkert.org            pkt->req = req;
1075863Snate@binkert.org            pkt->req->paddr = pkt->addr;
108955SN/A            pkt->req->size = pkt->size;
1095273Sstever@gmail.com            // Increment the data pointer on a write
1105871Snate@binkert.org            pkt->data = data ? data + prevSize : NULL ;
1115273Sstever@gmail.com            prevSize = pkt->size;
1125871Snate@binkert.org
1135863Snate@binkert.org            sendDma(*pkt);
1145863Snate@binkert.org    }
1155863Snate@binkert.org}
1165871Snate@binkert.org
1175872Snate@binkert.org
1185872Snate@binkert.orgvoid
1195872Snate@binkert.orgDmaPort::sendDma(Packet &pkt)
1205871Snate@binkert.org{
1215871Snate@binkert.org   // some kind of selction between access methods
1225871Snate@binkert.org   // more work is going to have to be done to make
1235871Snate@binkert.org   // switching actually work
1245871Snate@binkert.org   MemState state = device->platform->system->memState;
1255871Snate@binkert.org
1265871Snate@binkert.org   if (state == Timing) {
1275871Snate@binkert.org       if (sendTiming(pkt) == Failure)
1285871Snate@binkert.org           transmitList.push_back(&packet);
1295871Snate@binkert.org   } else if (state == Atomic) {
1305871Snate@binkert.org       sendAtomic(pkt);
1315871Snate@binkert.org       completionEvent->schedule(pkt.responseTime - pkt.requestTime);
1325871Snate@binkert.org       completionEvent == NULL;
1335871Snate@binkert.org   } else if (state == Functional) {
1345863Snate@binkert.org       sendFunctional(pkt);
1355227Ssaidi@eecs.umich.edu       // Is this correct???
1365396Ssaidi@eecs.umich.edu       completionEvent->schedule(pkt.responseTime - pkt.requestTime);
1375396Ssaidi@eecs.umich.edu       completionEvent == NULL;
1385396Ssaidi@eecs.umich.edu   } else
1395396Ssaidi@eecs.umich.edu       panic("Unknown memory command state.");
1405396Ssaidi@eecs.umich.edu
1415396Ssaidi@eecs.umich.edu}
1425396Ssaidi@eecs.umich.edu
1435396Ssaidi@eecs.umich.eduDmaDevice::~DmaDevice()
1445588Ssaidi@eecs.umich.edu{
1455396Ssaidi@eecs.umich.edu    if (dmaInterface)
1465396Ssaidi@eecs.umich.edu        delete dmaInterface;
1475396Ssaidi@eecs.umich.edu}
1485396Ssaidi@eecs.umich.edu
1495396Ssaidi@eecs.umich.edu
1505396Ssaidi@eecs.umich.edu