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 --- 76 unchanged lines hidden (view full) --- 85/** Function called by the port when the bus is receiving a Timing 86 * transaction.*/ 87bool 88Bridge::BridgePort::recvTiming(Packet *pkt) 89{ 90 DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n", 91 pkt->getSrc(), pkt->getDest(), pkt->getAddr()); 92 |
93 return otherPort->queueForSendTiming(pkt); 94} 95 96 97bool 98Bridge::BridgePort::queueForSendTiming(Packet *pkt) 99{ 100 if (queueFull()) 101 return false; 102 103 if (pkt->isResponse()) { |
104 // This is a response for a request we forwarded earlier. The 105 // corresponding PacketBuffer should be stored in the packet's 106 // senderState field. 107 PacketBuffer *buf = dynamic_cast<PacketBuffer*>(pkt->senderState); 108 assert(buf != NULL); 109 // set up new packet dest & senderState based on values saved 110 // from original request 111 buf->fixResponse(pkt); |
112 DPRINTF(BusBridge, "restoring sender state: %#X, from packet buffer: %#X\n", 113 pkt->senderState, buf); |
114 DPRINTF(BusBridge, " is response, new dest %d\n", pkt->getDest()); 115 delete buf; 116 } 117 |
118 Tick readyTime = curTick + delay; 119 PacketBuffer *buf = new PacketBuffer(pkt, readyTime); |
120 DPRINTF(BusBridge, "old sender state: %#X, new sender state: %#X\n", 121 buf->origSenderState, buf); |
122 123 // If we're about to put this packet at the head of the queue, we 124 // need to schedule an event to do the transmit. Otherwise there 125 // should already be an event scheduled for sending the head 126 // packet. 127 if (sendQueue.empty()) { 128 sendEvent.schedule(readyTime); 129 } 130 131 sendQueue.push_back(buf); 132 |
133 return true; 134} 135 |
136void |
137Bridge::BridgePort::trySend() 138{ 139 assert(!sendQueue.empty()); 140 |
141 bool was_full = queueFull(); 142 |
143 PacketBuffer *buf = sendQueue.front(); 144 145 assert(buf->ready <= curTick); 146 147 Packet *pkt = buf->pkt; 148 149 DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n", 150 buf->origSrc, pkt->getDest(), pkt->getAddr()); 151 152 if (sendTiming(pkt)) { 153 // send successful 154 sendQueue.pop_front(); 155 buf->pkt = NULL; // we no longer own packet, so it's not safe to look at it |
156 157 if (buf->expectResponse) { 158 // Must wait for response. We just need to count outstanding 159 // responses (in case we want to cap them); PacketBuffer 160 // pointer will be recovered on response. 161 ++outstandingResponses; 162 DPRINTF(BusBridge, " successful: awaiting response (%d)\n", 163 outstandingResponses); 164 } else { 165 // no response expected... deallocate packet buffer now. 166 DPRINTF(BusBridge, " successful: no response expected\n"); 167 delete buf; 168 } 169 170 // If there are more packets to send, schedule event to try again. 171 if (!sendQueue.empty()) { 172 buf = sendQueue.front(); 173 sendEvent.schedule(std::max(buf->ready, curTick + 1)); 174 } 175 // Let things start sending again 176 if (was_full) { 177 DPRINTF(BusBridge, "Queue was full, sending retry\n"); 178 otherPort->sendRetry(); 179 } 180 |
181 } else { 182 DPRINTF(BusBridge, " unsuccessful\n"); 183 } 184} 185 186 |
187void |
188Bridge::BridgePort::recvRetry() 189{ |
190 trySend(); |
191} 192 193/** Function called by the port when the bus is receiving a Atomic 194 * transaction.*/ 195Tick 196Bridge::BridgePort::recvAtomic(Packet *pkt) 197{ 198 return otherPort->sendAtomic(pkt) + delay; --- 17 unchanged lines hidden (view full) --- 216 otherPort->sendFunctional(pkt); 217 } 218} 219 220/** Function called by the port when the bus is receiving a status change.*/ 221void 222Bridge::BridgePort::recvStatusChange(Port::Status status) 223{ |
224 otherPort->sendStatusChange(status); 225} 226 227void 228Bridge::BridgePort::getDeviceAddressRanges(AddrRangeList &resp, 229 AddrRangeList &snoop) 230{ 231 otherPort->getPeerAddressRanges(resp, snoop); --- 27 unchanged lines hidden --- |