io_device.cc revision 2541
12447SN/A/*
25254Sksewell@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
35254Sksewell@umich.edu * All rights reserved.
45254Sksewell@umich.edu *
52447SN/A * Redistribution and use in source and binary forms, with or without
65254Sksewell@umich.edu * modification, are permitted provided that the following conditions are
75254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
85254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
95254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
105254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
115254Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
125254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
135254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
145254Sksewell@umich.edu * this software without specific prior written permission.
155254Sksewell@umich.edu *
162447SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275254Sksewell@umich.edu */
282632Sstever@eecs.umich.edu
295254Sksewell@umich.edu#include "dev/io_device.hh"
305254Sksewell@umich.edu#include "sim/builder.hh"
315254Sksewell@umich.edu
322447SN/A
332447SN/APioPort::PioPort(PioDevice *dev, Platform *p)
342447SN/A        : device(dev), platform(p)
352447SN/A{ }
365222Sksewell@umich.edu
372597SN/A
384661Sksewell@umich.eduTick
392597SN/APioPort::recvAtomic(Packet &pkt)
406216Snate@binkert.org{
412980Sgblack@eecs.umich.edu    return device->recvAtomic(pkt);
424661Sksewell@umich.edu}
434661Sksewell@umich.edu
442980Sgblack@eecs.umich.eduvoid
452980Sgblack@eecs.umich.eduPioPort::recvFunctional(Packet &pkt)
462597SN/A{
472597SN/A    device->recvAtomic(pkt);
485222Sksewell@umich.edu}
494826Ssaidi@eecs.umich.edu
505254Sksewell@umich.eduvoid
515254Sksewell@umich.eduPioPort::getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
525254Sksewell@umich.edu{
535254Sksewell@umich.edu    snoop.clear();
542686Sksewell@umich.edu    device->addressRanges(resp);
552686Sksewell@umich.edu}
562686Sksewell@umich.edu
572686Sksewell@umich.edu
582686Sksewell@umich.eduPacket *
592686Sksewell@umich.eduPioPort::recvRetry()
602686Sksewell@umich.edu{
612686Sksewell@umich.edu    Packet* pkt = transmitList.front();
622686Sksewell@umich.edu    transmitList.pop_front();
632686Sksewell@umich.edu    return pkt;
642686Sksewell@umich.edu}
652972Sgblack@eecs.umich.edu
665222Sksewell@umich.edu
675222Sksewell@umich.eduvoid
685222Sksewell@umich.eduPioPort::SendEvent::process()
695222Sksewell@umich.edu{
705222Sksewell@umich.edu    if (port->Port::sendTiming(packet) == Success)
715222Sksewell@umich.edu        return;
725222Sksewell@umich.edu
735222Sksewell@umich.edu    port->transmitList.push_back(&packet);
745222Sksewell@umich.edu}
755222Sksewell@umich.edu
765222Sksewell@umich.edu
775222Sksewell@umich.edubool
785222Sksewell@umich.eduPioPort::recvTiming(Packet &pkt)
795222Sksewell@umich.edu{
805222Sksewell@umich.edu    device->recvAtomic(pkt);
814661Sksewell@umich.edu    sendTiming(pkt, pkt.time-pkt.req->getTime());
822972Sgblack@eecs.umich.edu    return Success;
832972Sgblack@eecs.umich.edu}
842972Sgblack@eecs.umich.edu
852972Sgblack@eecs.umich.eduPioDevice::~PioDevice()
862972Sgblack@eecs.umich.edu{
872972Sgblack@eecs.umich.edu    if (pioPort)
882972Sgblack@eecs.umich.edu        delete pioPort;
892972Sgblack@eecs.umich.edu}
902972Sgblack@eecs.umich.edu
912972Sgblack@eecs.umich.eduPioDevice::init()
922972Sgblack@eecs.umich.edu{
932972Sgblack@eecs.umich.edu    if (!pioPort)
942972Sgblack@eecs.umich.edu        panic("Pio port not connected to anything!");
952972Sgblack@eecs.umich.edu    pioPort->sendStatusChange(Port::RangeChange);
962972Sgblack@eecs.umich.edu}
975254Sksewell@umich.edu
985254Sksewell@umich.eduvoid
995254Sksewell@umich.eduBasicPioDevice::addressRanges(AddrRangeList &range_list)
1005254Sksewell@umich.edu{
1015222Sksewell@umich.edu    assert(pioSize != 0);
1025222Sksewell@umich.edu    range_list.clear();
1035222Sksewell@umich.edu    range_list.push_back(RangeSize(pioAddr, pioSize));
1044194Ssaidi@eecs.umich.edu}
1055222Sksewell@umich.edu
1065254Sksewell@umich.edu
1075254Sksewell@umich.eduDmaPort::DmaPort(DmaDevice *dev)
1085254Sksewell@umich.edu        : device(dev)
1095254Sksewell@umich.edu{ }
1105254Sksewell@umich.edu
1115254Sksewell@umich.edubool
1125254Sksewell@umich.eduDmaPort::recvTiming(Packet &pkt)
1135254Sksewell@umich.edu{
1145254Sksewell@umich.edu    completionEvent->schedule(curTick+1);
1155254Sksewell@umich.edu    completionEvent = NULL;
1165222Sksewell@umich.edu    return Success;
1175222Sksewell@umich.edu}
1185222Sksewell@umich.edu
1195222Sksewell@umich.eduDmaDevice::DmaDevice(Params *p)
1205222Sksewell@umich.edu    : PioDevice(p)
1215222Sksewell@umich.edu{
1225222Sksewell@umich.edu    dmaPort = new DmaPort(this);
1235222Sksewell@umich.edu}
1245222Sksewell@umich.edu
1255222Sksewell@umich.eduvoid
1265222Sksewell@umich.eduDmaPort::SendEvent::process()
1275222Sksewell@umich.edu{
1285222Sksewell@umich.edu    if (port->Port::sendTiming(packet) == Success)
1295222Sksewell@umich.edu        return;
1305222Sksewell@umich.edu
1315222Sksewell@umich.edu    port->transmitList.push_back(&packet);
1325222Sksewell@umich.edu}
1335222Sksewell@umich.edu
1345222Sksewell@umich.eduPacket *
1355222Sksewell@umich.eduDmaPort::recvRetry()
1365222Sksewell@umich.edu{
1375254Sksewell@umich.edu    Packet* pkt = transmitList.front();
1385254Sksewell@umich.edu    transmitList.pop_front();
1395254Sksewell@umich.edu    return pkt;
1405254Sksewell@umich.edu}
1415254Sksewell@umich.eduvoid
1422597SN/ADmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size,
1432447SN/A                     Event *event, uint8_t *data)
1442686Sksewell@umich.edu{
1452447SN/A
146    assert(event);
147
148    int prevSize = 0;
149    Packet basePkt;
150    Request baseReq(false);
151
152    basePkt.flags = 0;
153    basePkt.coherence = NULL;
154    basePkt.senderState = NULL;
155    basePkt.src = 0;
156    basePkt.dest = 0;
157    basePkt.cmd = cmd;
158    basePkt.result = Unknown;
159    basePkt.req = NULL;
160//    baseReq.nicReq = true;
161    baseReq.setTime(curTick);
162
163    completionEvent = event;
164
165    for (ChunkGenerator gen(addr, size, peerBlockSize());
166         !gen.done(); gen.next()) {
167            Packet *pkt = new Packet(basePkt);
168            Request *req = new Request(baseReq);
169            pkt->addr = gen.addr();
170            pkt->size = gen.size();
171            pkt->req = req;
172            pkt->req->setPaddr(pkt->addr);
173            pkt->req->setSize(pkt->size);
174            // Increment the data pointer on a write
175            pkt->data = data ? data + prevSize : NULL ;
176            prevSize += pkt->size;
177
178            sendDma(*pkt);
179    }
180}
181
182
183void
184DmaPort::sendDma(Packet &pkt)
185{
186   // some kind of selction between access methods
187   // more work is going to have to be done to make
188   // switching actually work
189  /* MemState state = device->platform->system->memState;
190
191   if (state == Timing) {
192       if (sendTiming(pkt) == Failure)
193           transmitList.push_back(&packet);
194   } else if (state == Atomic) {*/
195       sendAtomic(pkt);
196       completionEvent->schedule(pkt.time - pkt.req->getTime());
197       completionEvent = NULL;
198/*   } else if (state == Functional) {
199       sendFunctional(pkt);
200       // Is this correct???
201       completionEvent->schedule(pkt.req->responseTime - pkt.req->requestTime);
202       completionEvent == NULL;
203   } else
204       panic("Unknown memory command state.");
205  */
206}
207
208DmaDevice::~DmaDevice()
209{
210    if (dmaPort)
211        delete dmaPort;
212}
213
214
215