1 2/* 3 * Copyright (c) 2006 The Regents of The University of Michigan 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright --- 98 unchanged lines hidden (view full) --- 107 return queuedRequests >= reqQueueLimit; 108} 109 110/** Function called by the port when the bus is receiving a Timing 111 * transaction.*/ 112bool 113Bridge::BridgePort::recvTiming(PacketPtr pkt) 114{ |
115 DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n", 116 pkt->getSrc(), pkt->getDest(), pkt->getAddr()); 117 118 DPRINTF(BusBridge, "Local queue size: %d outreq: %d outresp: %d\n", 119 sendQueue.size(), queuedRequests, outstandingResponses); 120 DPRINTF(BusBridge, "Remove queue size: %d outreq: %d outresp: %d\n", 121 otherPort->sendQueue.size(), otherPort->queuedRequests, 122 otherPort->outstandingResponses); --- 115 unchanged lines hidden (view full) --- 238 sendQueue.push_back(buf); 239} 240 241void 242Bridge::BridgePort::trySend() 243{ 244 assert(!sendQueue.empty()); 245 |
246 int pbs = peerBlockSize(); 247 |
248 PacketBuffer *buf = sendQueue.front(); 249 250 assert(buf->ready <= curTick); 251 252 PacketPtr pkt = buf->pkt; 253 |
254 if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite && |
255 pkt->result != Packet::Nacked && pkt->getOffset(pbs) && 256 pkt->getSize() != pbs) { 257 buf->partialWriteFix(this); 258 pkt = buf->pkt; |
259 } 260 261 DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n", 262 buf->origSrc, pkt->getDest(), pkt->getAddr()); 263 264 bool wasReq = pkt->isRequest(); 265 bool wasNacked = pkt->result == Packet::Nacked; 266 --- 22 unchanged lines hidden (view full) --- 289 // If there are more packets to send, schedule event to try again. 290 if (!sendQueue.empty()) { 291 buf = sendQueue.front(); 292 DPRINTF(BusBridge, "Scheduling next send\n"); 293 sendEvent.schedule(std::max(buf->ready, curTick + 1)); 294 } 295 } else { 296 DPRINTF(BusBridge, " unsuccessful\n"); |
297 buf->undoPartialWriteFix(); |
298 inRetry = true; 299 } 300 DPRINTF(BusBridge, "trySend: queue size: %d outreq: %d outstanding resp: %d\n", 301 sendQueue.size(), queuedRequests, outstandingResponses); 302} 303 304 305void --- 7 unchanged lines hidden (view full) --- 313 sendEvent.schedule(nextReady); 314} 315 316/** Function called by the port when the bus is receiving a Atomic 317 * transaction.*/ 318Tick 319Bridge::BridgePort::recvAtomic(PacketPtr pkt) 320{ |
321 int pbs = otherPort->peerBlockSize(); 322 Tick atomic_delay; |
323 // fix partial atomic writes... similar to the timing code that does the |
324 // same 325 if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite && 326 pkt->getOffset(pbs) && pkt->getSize() != pbs) { 327 PacketDataPtr data; 328 data = new uint8_t[pbs]; 329 PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq, 330 Packet::Broadcast, pbs); |
331 |
332 funcPkt->dataStatic(data); |
333 otherPort->sendFunctional(funcPkt); |
334 assert(funcPkt->result == Packet::Success); |
335 delete funcPkt; |
336 memcpy(data + pkt->getOffset(pbs), pkt->getPtr<uint8_t>(), 337 pkt->getSize()); 338 PacketPtr newPkt = new Packet(pkt->req, MemCmd::WriteInvalidateReq, 339 Packet::Broadcast, pbs); 340 pkt->dataDynamicArray(data); 341 atomic_delay = otherPort->sendAtomic(newPkt); 342 delete newPkt; 343 } else { 344 atomic_delay = otherPort->sendAtomic(pkt); |
345 } |
346 return atomic_delay + delay; |
347} 348 349/** Function called by the port when the bus is receiving a Functional 350 * transaction.*/ 351void 352Bridge::BridgePort::recvFunctional(PacketPtr pkt) 353{ 354 std::list<PacketBuffer*>::iterator i; --- 65 unchanged lines hidden (view full) --- 420 p->write_ack = write_ack; 421 p->fix_partial_write_a = fix_partial_write_a; 422 p->fix_partial_write_b = fix_partial_write_b; 423 return new Bridge(p); 424} 425 426REGISTER_SIM_OBJECT("Bridge", Bridge) 427 |