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