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