bridge.hh (4432:5e55857abb01) bridge.hh (4433:4722c6787f69)
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Ali Saidi
29 * Steve Reinhardt
30 */
31
32/**
33 * @file
34 * Declaration of a simple bus bridge object with no buffering
35 */
36
37#ifndef __MEM_BRIDGE_HH__
38#define __MEM_BRIDGE_HH__
39
40#include <string>
41#include <list>
42#include <inttypes.h>
43#include <queue>
44
45#include "mem/mem_object.hh"
46#include "mem/packet.hh"
47#include "mem/port.hh"
48#include "sim/eventq.hh"
49
50class Bridge : public MemObject
51{
52 protected:
53 /** Declaration of the buses port type, one will be instantiated for each
54 of the interfaces connecting to the bus. */
55 class BridgePort : public Port
56 {
57 /** A pointer to the bridge to which this port belongs. */
58 Bridge *bridge;
59
60 /**
61 * Pointer to the port on the other side of the bridge
62 * (connected to the other bus).
63 */
64 BridgePort *otherPort;
65
66 /** Minimum delay though this bridge. */
67 Tick delay;
68
69 bool fixPartialWrite;
70
71 class PacketBuffer : public Packet::SenderState {
72
73 public:
74 Tick ready;
75 PacketPtr pkt;
76 Packet::SenderState *origSenderState;
77 short origSrc;
78 bool expectResponse;
79
80 bool partialWriteFixed;
81 PacketPtr oldPkt;
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Ali Saidi
29 * Steve Reinhardt
30 */
31
32/**
33 * @file
34 * Declaration of a simple bus bridge object with no buffering
35 */
36
37#ifndef __MEM_BRIDGE_HH__
38#define __MEM_BRIDGE_HH__
39
40#include <string>
41#include <list>
42#include <inttypes.h>
43#include <queue>
44
45#include "mem/mem_object.hh"
46#include "mem/packet.hh"
47#include "mem/port.hh"
48#include "sim/eventq.hh"
49
50class Bridge : public MemObject
51{
52 protected:
53 /** Declaration of the buses port type, one will be instantiated for each
54 of the interfaces connecting to the bus. */
55 class BridgePort : public Port
56 {
57 /** A pointer to the bridge to which this port belongs. */
58 Bridge *bridge;
59
60 /**
61 * Pointer to the port on the other side of the bridge
62 * (connected to the other bus).
63 */
64 BridgePort *otherPort;
65
66 /** Minimum delay though this bridge. */
67 Tick delay;
68
69 bool fixPartialWrite;
70
71 class PacketBuffer : public Packet::SenderState {
72
73 public:
74 Tick ready;
75 PacketPtr pkt;
76 Packet::SenderState *origSenderState;
77 short origSrc;
78 bool expectResponse;
79
80 bool partialWriteFixed;
81 PacketPtr oldPkt;
82 bool nacked;
82
83
83 PacketBuffer(PacketPtr _pkt, Tick t)
84 PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
84 : ready(t), pkt(_pkt),
85 origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
85 : ready(t), pkt(_pkt),
86 origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
86 expectResponse(_pkt->needsResponse()), partialWriteFixed(false)
87 expectResponse(_pkt->needsResponse() && !nack),
88 partialWriteFixed(false), nacked(nack)
89
87 {
90 {
88 if (!pkt->isResponse())
91 if (!pkt->isResponse() && !nack)
89 pkt->senderState = this;
90 }
91
92 void fixResponse(PacketPtr pkt)
93 {
94 assert(pkt->senderState == this);
95 pkt->setDest(origSrc);
96 pkt->senderState = origSenderState;
97 if (partialWriteFixed)
98 delete oldPkt;
99 }
100
101 void partialWriteFix(Port *port)
102 {
103 assert(!partialWriteFixed);
104 assert(expectResponse);
105
106 int pbs = port->peerBlockSize();
107 partialWriteFixed = true;
108 PacketDataPtr data;
109
110 data = new uint8_t[pbs];
111 PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq,
112 Packet::Broadcast, pbs);
113
114 funcPkt->dataStatic(data);
115 port->sendFunctional(funcPkt);
116 assert(funcPkt->result == Packet::Success);
117 delete funcPkt;
118
119 oldPkt = pkt;
120 memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(),
121 pkt->getSize());
122 pkt = new Packet(oldPkt->req, MemCmd::WriteInvalidateReq,
123 Packet::Broadcast, pbs);
124 pkt->dataDynamicArray(data);
125 pkt->senderState = oldPkt->senderState;
126 }
127
128 void undoPartialWriteFix()
129 {
130 if (!partialWriteFixed)
131 return;
132 delete pkt;
133 pkt = oldPkt;
134 partialWriteFixed = false;
135 }
136
137 };
138
139 /**
140 * Outbound packet queue. Packets are held in this queue for a
141 * specified delay to model the processing delay of the
142 * bridge.
143 */
144 std::list<PacketBuffer*> sendQueue;
145
146 int outstandingResponses;
92 pkt->senderState = this;
93 }
94
95 void fixResponse(PacketPtr pkt)
96 {
97 assert(pkt->senderState == this);
98 pkt->setDest(origSrc);
99 pkt->senderState = origSenderState;
100 if (partialWriteFixed)
101 delete oldPkt;
102 }
103
104 void partialWriteFix(Port *port)
105 {
106 assert(!partialWriteFixed);
107 assert(expectResponse);
108
109 int pbs = port->peerBlockSize();
110 partialWriteFixed = true;
111 PacketDataPtr data;
112
113 data = new uint8_t[pbs];
114 PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq,
115 Packet::Broadcast, pbs);
116
117 funcPkt->dataStatic(data);
118 port->sendFunctional(funcPkt);
119 assert(funcPkt->result == Packet::Success);
120 delete funcPkt;
121
122 oldPkt = pkt;
123 memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(),
124 pkt->getSize());
125 pkt = new Packet(oldPkt->req, MemCmd::WriteInvalidateReq,
126 Packet::Broadcast, pbs);
127 pkt->dataDynamicArray(data);
128 pkt->senderState = oldPkt->senderState;
129 }
130
131 void undoPartialWriteFix()
132 {
133 if (!partialWriteFixed)
134 return;
135 delete pkt;
136 pkt = oldPkt;
137 partialWriteFixed = false;
138 }
139
140 };
141
142 /**
143 * Outbound packet queue. Packets are held in this queue for a
144 * specified delay to model the processing delay of the
145 * bridge.
146 */
147 std::list<PacketBuffer*> sendQueue;
148
149 int outstandingResponses;
150 int queuedRequests;
147
148 /** Max queue size for outbound packets */
149 int queueLimit;
150
151 /**
152 * Is this side blocked from accepting outbound packets?
153 */
151
152 /** Max queue size for outbound packets */
153 int queueLimit;
154
155 /**
156 * Is this side blocked from accepting outbound packets?
157 */
154 bool queueFull() { return (sendQueue.size() == queueLimit); }
158 bool queueFull();
155
159
156 bool queueForSendTiming(PacketPtr pkt);
160 void queueForSendTiming(PacketPtr pkt);
157
158 void finishSend(PacketBuffer *buf);
159
161
162 void finishSend(PacketBuffer *buf);
163
164 void nackRequest(PacketPtr pkt);
165
160 /**
161 * Handle send event, scheduled when the packet at the head of
162 * the outbound queue is ready to transmit (for timing
163 * accesses only).
164 */
165 void trySend();
166
167 class SendEvent : public Event
168 {
169 BridgePort *port;
170
171 public:
172 SendEvent(BridgePort *p)
173 : Event(&mainEventQueue), port(p) {}
174
175 virtual void process() { port->trySend(); }
176
177 virtual const char *description() { return "bridge send event"; }
178 };
179
180 SendEvent sendEvent;
181
182 public:
183
184 /** Constructor for the BusPort.*/
185 BridgePort(const std::string &_name,
186 Bridge *_bridge, BridgePort *_otherPort,
187 int _delay, int _queueLimit, bool fix_partial_write);
188
189 protected:
190
191 /** When receiving a timing request from the peer port,
192 pass it to the bridge. */
193 virtual bool recvTiming(PacketPtr pkt);
194
195 /** When receiving a retry request from the peer port,
196 pass it to the bridge. */
197 virtual void recvRetry();
198
199 /** When receiving a Atomic requestfrom the peer port,
200 pass it to the bridge. */
201 virtual Tick recvAtomic(PacketPtr pkt);
202
203 /** When receiving a Functional request from the peer port,
204 pass it to the bridge. */
205 virtual void recvFunctional(PacketPtr pkt);
206
207 /** When receiving a status changefrom the peer port,
208 pass it to the bridge. */
209 virtual void recvStatusChange(Status status);
210
211 /** When receiving a address range request the peer port,
212 pass it to the bridge. */
213 virtual void getDeviceAddressRanges(AddrRangeList &resp,
214 AddrRangeList &snoop);
215 };
216
217 BridgePort portA, portB;
218
219 /** If this bridge should acknowledge writes. */
220 bool ackWrites;
221
222 public:
223
224 /** A function used to return the port associated with this bus object. */
225 virtual Port *getPort(const std::string &if_name, int idx = -1);
226
227 virtual void init();
228
229 Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack,
230 bool fix_partial_write_a, bool fix_partial_write_b);
231};
232
233#endif //__MEM_BUS_HH__
166 /**
167 * Handle send event, scheduled when the packet at the head of
168 * the outbound queue is ready to transmit (for timing
169 * accesses only).
170 */
171 void trySend();
172
173 class SendEvent : public Event
174 {
175 BridgePort *port;
176
177 public:
178 SendEvent(BridgePort *p)
179 : Event(&mainEventQueue), port(p) {}
180
181 virtual void process() { port->trySend(); }
182
183 virtual const char *description() { return "bridge send event"; }
184 };
185
186 SendEvent sendEvent;
187
188 public:
189
190 /** Constructor for the BusPort.*/
191 BridgePort(const std::string &_name,
192 Bridge *_bridge, BridgePort *_otherPort,
193 int _delay, int _queueLimit, bool fix_partial_write);
194
195 protected:
196
197 /** When receiving a timing request from the peer port,
198 pass it to the bridge. */
199 virtual bool recvTiming(PacketPtr pkt);
200
201 /** When receiving a retry request from the peer port,
202 pass it to the bridge. */
203 virtual void recvRetry();
204
205 /** When receiving a Atomic requestfrom the peer port,
206 pass it to the bridge. */
207 virtual Tick recvAtomic(PacketPtr pkt);
208
209 /** When receiving a Functional request from the peer port,
210 pass it to the bridge. */
211 virtual void recvFunctional(PacketPtr pkt);
212
213 /** When receiving a status changefrom the peer port,
214 pass it to the bridge. */
215 virtual void recvStatusChange(Status status);
216
217 /** When receiving a address range request the peer port,
218 pass it to the bridge. */
219 virtual void getDeviceAddressRanges(AddrRangeList &resp,
220 AddrRangeList &snoop);
221 };
222
223 BridgePort portA, portB;
224
225 /** If this bridge should acknowledge writes. */
226 bool ackWrites;
227
228 public:
229
230 /** A function used to return the port associated with this bus object. */
231 virtual Port *getPort(const std::string &if_name, int idx = -1);
232
233 virtual void init();
234
235 Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack,
236 bool fix_partial_write_a, bool fix_partial_write_b);
237};
238
239#endif //__MEM_BUS_HH__