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)