1/* 2 * Copyright (c) 2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 106 unchanged lines hidden (view full) --- 115 116DmaPort::DmaPort(DmaDevice *dev, Platform *p) 117 : Port(dev->name() + "-dmaport"), device(dev), platform(p), pendingCount(0) 118{ } 119 120bool 121DmaPort::recvTiming(Packet *pkt) 122{ |
123 124 125 if (pkt->result == Packet::Nacked) { 126 DPRINTF(DMA, "Received nacked Pkt %#x with State: %#x Addr: %#x\n", 127 pkt, pkt->senderState, pkt->getAddr()); 128 pkt->reinitNacked(); 129 sendDma(pkt, true); 130 } else if (pkt->senderState) { |
131 DmaReqState *state; |
132 DPRINTF(DMA, "Received response Pkt %#x with State: %#x Addr: %#x\n", 133 pkt, pkt->senderState, pkt->getAddr()); |
134 state = dynamic_cast<DmaReqState*>(pkt->senderState); |
135 pendingCount--; 136 137 assert(pendingCount >= 0); |
138 assert(state); |
139 140 state->numBytes += pkt->req->getSize(); 141 if (state->totBytes == state->numBytes) { 142 state->completionEvent->process(); 143 delete state; 144 } |
145 delete pkt->req; 146 delete pkt; 147 } else { |
148 panic("Got packet without sender state... huh?\n"); |
149 } 150 151 return true; 152} 153 154DmaDevice::DmaDevice(Params *p) 155 : PioDevice(p), dmaPort(NULL) 156{ } --- 5 unchanged lines hidden (view full) --- 162 bool result = true; 163 while (result && transmitList.size()) { 164 DPRINTF(DMA, "Retry on Packet %#x with senderState: %#x\n", 165 pkt, pkt->senderState); 166 result = sendTiming(pkt); 167 if (result) { 168 DPRINTF(DMA, "-- Done\n"); 169 transmitList.pop_front(); |
170 } else { 171 DPRINTF(DMA, "-- Failed, queued\n"); 172 } 173 } 174} 175 176 177void 178DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, 179 uint8_t *data) 180{ 181 assert(event); 182 |
183 DmaReqState *reqState = new DmaReqState(event, this, size); |
184 185 for (ChunkGenerator gen(addr, size, peerBlockSize()); 186 !gen.done(); gen.next()) { 187 Request *req = new Request(gen.addr(), gen.size(), 0); 188 Packet *pkt = new Packet(req, cmd, Packet::Broadcast); 189 190 // Increment the data pointer on a write 191 if (data) |
192 pkt->dataStatic(data + gen.complete()); |
193 |
194 pkt->senderState = reqState; |
195 |
196 assert(pendingCount >= 0); 197 pendingCount++; 198 sendDma(pkt); 199 } 200} 201 202 203void |
204DmaPort::sendDma(Packet *pkt, bool front) |
205{ 206 // some kind of selction between access methods 207 // more work is going to have to be done to make 208 // switching actually work 209 /* MemState state = device->platform->system->memState; 210 211 if (state == Timing) { */ |
212 DPRINTF(DMA, "Attempting to send Packet %#x with addr: %#x\n", 213 pkt, pkt->getAddr()); |
214 if (transmitList.size() || !sendTiming(pkt)) { |
215 if (front) 216 transmitList.push_front(pkt); 217 else 218 transmitList.push_back(pkt); |
219 DPRINTF(DMA, "-- Failed: queued\n"); 220 } else { 221 DPRINTF(DMA, "-- Done\n"); |
222 } 223 /* } else if (state == Atomic) { 224 sendAtomic(pkt); 225 if (pkt->senderState) { 226 DmaReqState *state = dynamic_cast<DmaReqState*>(pkt->senderState); 227 assert(state); |
228 state->completionEvent->schedule(curTick + (pkt->time - 229 pkt->req->getTime()) +1); 230 delete state; |
231 } 232 pendingCount--; 233 assert(pendingCount >= 0); 234 delete pkt->req; 235 delete pkt; 236 237 } else if (state == Functional) { 238 sendFunctional(pkt); --- 15 unchanged lines hidden --- |