bridge.cc (3662:9dacf0926b69) | bridge.cc (4432:5e55857abb01) |
---|---|
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 --- 29 unchanged lines hidden (view full) --- 38#include <algorithm> 39 40#include "base/trace.hh" 41#include "mem/bridge.hh" 42#include "sim/builder.hh" 43 44Bridge::BridgePort::BridgePort(const std::string &_name, 45 Bridge *_bridge, BridgePort *_otherPort, | 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 --- 29 unchanged lines hidden (view full) --- 38#include <algorithm> 39 40#include "base/trace.hh" 41#include "mem/bridge.hh" 42#include "sim/builder.hh" 43 44Bridge::BridgePort::BridgePort(const std::string &_name, 45 Bridge *_bridge, BridgePort *_otherPort, |
46 int _delay, int _queueLimit) | 46 int _delay, int _queueLimit, 47 bool fix_partial_write) |
47 : Port(_name), bridge(_bridge), otherPort(_otherPort), | 48 : Port(_name), bridge(_bridge), otherPort(_otherPort), |
48 delay(_delay), outstandingResponses(0), 49 queueLimit(_queueLimit), sendEvent(this) | 49 delay(_delay), fixPartialWrite(fix_partial_write), 50 outstandingResponses(0), queueLimit(_queueLimit), sendEvent(this) |
50{ 51} 52 53Bridge::Bridge(const std::string &n, int qsa, int qsb, | 51{ 52} 53 54Bridge::Bridge(const std::string &n, int qsa, int qsb, |
54 Tick _delay, int write_ack) | 55 Tick _delay, int write_ack, bool fix_partial_write_a, 56 bool fix_partial_write_b) |
55 : MemObject(n), | 57 : MemObject(n), |
56 portA(n + "-portA", this, &portB, _delay, qsa), 57 portB(n + "-portB", this, &portA, _delay, qsa), | 58 portA(n + "-portA", this, &portB, _delay, qsa, fix_partial_write_a), 59 portB(n + "-portB", this, &portA, _delay, qsa, fix_partial_write_b), |
58 ackWrites(write_ack) 59{ | 60 ackWrites(write_ack) 61{ |
62 if (ackWrites) 63 panic("No support for acknowledging writes\n"); |
|
60} 61 62Port * 63Bridge::getPort(const std::string &if_name, int idx) 64{ 65 BridgePort *port; 66 67 if (if_name == "side_a") --- 9 unchanged lines hidden (view full) --- 77} 78 79 80void 81Bridge::init() 82{ 83 // Make sure that both sides are connected to. 84 if (portA.getPeer() == NULL || portB.getPeer() == NULL) | 64} 65 66Port * 67Bridge::getPort(const std::string &if_name, int idx) 68{ 69 BridgePort *port; 70 71 if (if_name == "side_a") --- 9 unchanged lines hidden (view full) --- 81} 82 83 84void 85Bridge::init() 86{ 87 // Make sure that both sides are connected to. 88 if (portA.getPeer() == NULL || portB.getPeer() == NULL) |
85 panic("Both ports of bus bridge are not connected to a bus.\n"); | 89 fatal("Both ports of bus bridge are not connected to a bus.\n"); 90 91 if (portA.peerBlockSize() != portB.peerBlockSize()) 92 fatal("Busses don't have the same block size... Not supported.\n"); |
86} 87 88 89/** Function called by the port when the bus is receiving a Timing 90 * transaction.*/ 91bool 92Bridge::BridgePort::recvTiming(PacketPtr pkt) 93{ --- 8 unchanged lines hidden (view full) --- 102 return !queueFull(); 103 } 104} 105 106 107bool 108Bridge::BridgePort::queueForSendTiming(PacketPtr pkt) 109{ | 93} 94 95 96/** Function called by the port when the bus is receiving a Timing 97 * transaction.*/ 98bool 99Bridge::BridgePort::recvTiming(PacketPtr pkt) 100{ --- 8 unchanged lines hidden (view full) --- 109 return !queueFull(); 110 } 111} 112 113 114bool 115Bridge::BridgePort::queueForSendTiming(PacketPtr pkt) 116{ |
110 if (queueFull()) | 117 if (queueFull()) { 118 DPRINTF(BusBridge, "Queue full, returning false\n"); |
111 return false; | 119 return false; |
120 } |
|
112 113 if (pkt->isResponse()) { 114 // This is a response for a request we forwarded earlier. The 115 // corresponding PacketBuffer should be stored in the packet's 116 // senderState field. 117 PacketBuffer *buf = dynamic_cast<PacketBuffer*>(pkt->senderState); 118 assert(buf != NULL); 119 // set up new packet dest & senderState based on values saved --- 24 unchanged lines hidden (view full) --- 144} 145 146void 147Bridge::BridgePort::trySend() 148{ 149 assert(!sendQueue.empty()); 150 151 bool was_full = queueFull(); | 121 122 if (pkt->isResponse()) { 123 // This is a response for a request we forwarded earlier. The 124 // corresponding PacketBuffer should be stored in the packet's 125 // senderState field. 126 PacketBuffer *buf = dynamic_cast<PacketBuffer*>(pkt->senderState); 127 assert(buf != NULL); 128 // set up new packet dest & senderState based on values saved --- 24 unchanged lines hidden (view full) --- 153} 154 155void 156Bridge::BridgePort::trySend() 157{ 158 assert(!sendQueue.empty()); 159 160 bool was_full = queueFull(); |
161 int pbs = peerBlockSize(); |
|
152 153 PacketBuffer *buf = sendQueue.front(); 154 155 assert(buf->ready <= curTick); 156 157 PacketPtr pkt = buf->pkt; 158 | 162 163 PacketBuffer *buf = sendQueue.front(); 164 165 assert(buf->ready <= curTick); 166 167 PacketPtr pkt = buf->pkt; 168 |
169 pkt->flags &= ~SNOOP_COMMIT; //CLear it if it was set 170 171 if (pkt->cmd == MemCmd::WriteInvalidateReq && fixPartialWrite && 172 pkt->getOffset(pbs) && pkt->getSize() != pbs) { 173 buf->partialWriteFix(this); 174 pkt = buf->pkt; 175 } 176 |
|
159 DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n", 160 buf->origSrc, pkt->getDest(), pkt->getAddr()); 161 | 177 DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n", 178 buf->origSrc, pkt->getDest(), pkt->getAddr()); 179 |
162 pkt->flags &= ~SNOOP_COMMIT; //CLear it if it was set | 180 |
163 if (sendTiming(pkt)) { 164 // send successful 165 sendQueue.pop_front(); 166 buf->pkt = NULL; // we no longer own packet, so it's not safe to look at it 167 168 if (buf->expectResponse) { 169 // Must wait for response. We just need to count outstanding 170 // responses (in case we want to cap them); PacketBuffer --- 15 unchanged lines hidden (view full) --- 186 // Let things start sending again 187 if (was_full) { 188 DPRINTF(BusBridge, "Queue was full, sending retry\n"); 189 otherPort->sendRetry(); 190 } 191 192 } else { 193 DPRINTF(BusBridge, " unsuccessful\n"); | 181 if (sendTiming(pkt)) { 182 // send successful 183 sendQueue.pop_front(); 184 buf->pkt = NULL; // we no longer own packet, so it's not safe to look at it 185 186 if (buf->expectResponse) { 187 // Must wait for response. We just need to count outstanding 188 // responses (in case we want to cap them); PacketBuffer --- 15 unchanged lines hidden (view full) --- 204 // Let things start sending again 205 if (was_full) { 206 DPRINTF(BusBridge, "Queue was full, sending retry\n"); 207 otherPort->sendRetry(); 208 } 209 210 } else { 211 DPRINTF(BusBridge, " unsuccessful\n"); |
212 buf->undoPartialWriteFix(); |
|
194 } 195} 196 197 198void 199Bridge::BridgePort::recvRetry() 200{ 201 trySend(); --- 41 unchanged lines hidden (view full) --- 243} 244 245BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bridge) 246 247 Param<int> queue_size_a; 248 Param<int> queue_size_b; 249 Param<Tick> delay; 250 Param<bool> write_ack; | 213 } 214} 215 216 217void 218Bridge::BridgePort::recvRetry() 219{ 220 trySend(); --- 41 unchanged lines hidden (view full) --- 262} 263 264BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bridge) 265 266 Param<int> queue_size_a; 267 Param<int> queue_size_b; 268 Param<Tick> delay; 269 Param<bool> write_ack; |
270 Param<bool> fix_partial_write_a; 271 Param<bool> fix_partial_write_b; |
|
251 252END_DECLARE_SIM_OBJECT_PARAMS(Bridge) 253 254BEGIN_INIT_SIM_OBJECT_PARAMS(Bridge) 255 256 INIT_PARAM(queue_size_a, "The size of the queue for data coming into side a"), 257 INIT_PARAM(queue_size_b, "The size of the queue for data coming into side b"), 258 INIT_PARAM(delay, "The miminum delay to cross this bridge"), | 272 273END_DECLARE_SIM_OBJECT_PARAMS(Bridge) 274 275BEGIN_INIT_SIM_OBJECT_PARAMS(Bridge) 276 277 INIT_PARAM(queue_size_a, "The size of the queue for data coming into side a"), 278 INIT_PARAM(queue_size_b, "The size of the queue for data coming into side b"), 279 INIT_PARAM(delay, "The miminum delay to cross this bridge"), |
259 INIT_PARAM(write_ack, "Acknowledge any writes that are received.") | 280 INIT_PARAM(write_ack, "Acknowledge any writes that are received."), 281 INIT_PARAM(fix_partial_write_a, "Fixup any partial block writes that are received"), 282 INIT_PARAM(fix_partial_write_b, "Fixup any partial block writes that are received") |
260 261END_INIT_SIM_OBJECT_PARAMS(Bridge) 262 263CREATE_SIM_OBJECT(Bridge) 264{ 265 return new Bridge(getInstanceName(), queue_size_a, queue_size_b, delay, | 283 284END_INIT_SIM_OBJECT_PARAMS(Bridge) 285 286CREATE_SIM_OBJECT(Bridge) 287{ 288 return new Bridge(getInstanceName(), queue_size_a, queue_size_b, delay, |
266 write_ack); | 289 write_ack, fix_partial_write_a, fix_partial_write_b); |
267} 268 269REGISTER_SIM_OBJECT("Bridge", Bridge) | 290} 291 292REGISTER_SIM_OBJECT("Bridge", Bridge) |