addr_mapper.cc (9542:683991c46ac8) addr_mapper.cc (9814:7ad2b0186a32)
1/*
2 * Copyright (c) 2012 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Andreas Hansson
38 */
39
40#include "mem/addr_mapper.hh"
41
42AddrMapper::AddrMapper(const AddrMapperParams* p)
43 : MemObject(p),
44 masterPort(name() + "-master", *this),
45 slavePort(name() + "-slave", *this)
46{
47}
48
49void
50AddrMapper::init()
51{
52 if (!slavePort.isConnected() || !masterPort.isConnected())
53 fatal("Address mapper is not connected on both sides.\n");
1/*
2 * Copyright (c) 2012 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Andreas Hansson
38 */
39
40#include "mem/addr_mapper.hh"
41
42AddrMapper::AddrMapper(const AddrMapperParams* p)
43 : MemObject(p),
44 masterPort(name() + "-master", *this),
45 slavePort(name() + "-slave", *this)
46{
47}
48
49void
50AddrMapper::init()
51{
52 if (!slavePort.isConnected() || !masterPort.isConnected())
53 fatal("Address mapper is not connected on both sides.\n");
54
55 if ((slavePort.peerBlockSize() != masterPort.peerBlockSize()) &&
56 slavePort.peerBlockSize() && masterPort.peerBlockSize())
57 fatal("Slave port size %d, master port size %d \n "
58 "don't have the same block size... Not supported.\n",
59 slavePort.peerBlockSize(), masterPort.peerBlockSize());
60}
61
62BaseMasterPort&
63AddrMapper::getMasterPort(const std::string& if_name, PortID idx)
64{
65 if (if_name == "master") {
66 return masterPort;
67 } else {
68 return MemObject::getMasterPort(if_name, idx);
69 }
70}
71
72BaseSlavePort&
73AddrMapper::getSlavePort(const std::string& if_name, PortID idx)
74{
75 if (if_name == "slave") {
76 return slavePort;
77 } else {
78 return MemObject::getSlavePort(if_name, idx);
79 }
80}
81
82void
83AddrMapper::recvFunctional(PacketPtr pkt)
84{
85 Addr orig_addr = pkt->getAddr();
86 pkt->setAddr(remapAddr(orig_addr));
87 masterPort.sendFunctional(pkt);
88 pkt->setAddr(orig_addr);
89}
90
91void
92AddrMapper::recvFunctionalSnoop(PacketPtr pkt)
93{
94 Addr orig_addr = pkt->getAddr();
95 pkt->setAddr(remapAddr(orig_addr));
96 slavePort.sendFunctionalSnoop(pkt);
97 pkt->setAddr(orig_addr);
98}
99
100Tick
101AddrMapper::recvAtomic(PacketPtr pkt)
102{
103 Addr orig_addr = pkt->getAddr();
104 pkt->setAddr(remapAddr(orig_addr));
105 Tick ret_tick = masterPort.sendAtomic(pkt);
106 pkt->setAddr(orig_addr);
107 return ret_tick;
108}
109
110Tick
111AddrMapper::recvAtomicSnoop(PacketPtr pkt)
112{
113 Addr orig_addr = pkt->getAddr();
114 pkt->setAddr(remapAddr(orig_addr));
115 Tick ret_tick = slavePort.sendAtomicSnoop(pkt);
116 pkt->setAddr(orig_addr);
117 return ret_tick;
118}
119
120bool
121AddrMapper::recvTimingReq(PacketPtr pkt)
122{
123 Addr orig_addr = pkt->getAddr();
124 bool needsResponse = pkt->needsResponse();
125 bool memInhibitAsserted = pkt->memInhibitAsserted();
126
127 if (needsResponse && !memInhibitAsserted) {
128 pkt->pushSenderState(new AddrMapperSenderState(orig_addr));
129 }
130
131 pkt->setAddr(remapAddr(orig_addr));
132
133 // Attempt to send the packet (always succeeds for inhibited
134 // packets)
135 bool successful = masterPort.sendTimingReq(pkt);
136
137 // If not successful, restore the sender state
138 if (!successful && needsResponse) {
139 delete pkt->popSenderState();
140 }
141
142 return successful;
143}
144
145bool
146AddrMapper::recvTimingResp(PacketPtr pkt)
147{
148 AddrMapperSenderState* receivedState =
149 dynamic_cast<AddrMapperSenderState*>(pkt->senderState);
150
151 // Restore initial sender state
152 if (receivedState == NULL)
153 panic("AddrMapper %s got a response without sender state\n",
154 name());
155
156 Addr remapped_addr = pkt->getAddr();
157
158 // Restore the state and address
159 pkt->senderState = receivedState->predecessor;
160 pkt->setAddr(receivedState->origAddr);
161
162 // Attempt to send the packet
163 bool successful = slavePort.sendTimingResp(pkt);
164
165 // If packet successfully sent, delete the sender state, otherwise
166 // restore state
167 if (successful) {
168 delete receivedState;
169 } else {
170 // Don't delete anything and let the packet look like we did
171 // not touch it
172 pkt->senderState = receivedState;
173 pkt->setAddr(remapped_addr);
174 }
175 return successful;
176}
177
178void
179AddrMapper::recvTimingSnoopReq(PacketPtr pkt)
180{
181 slavePort.sendTimingSnoopReq(pkt);
182}
183
184bool
185AddrMapper::recvTimingSnoopResp(PacketPtr pkt)
186{
187 return masterPort.sendTimingSnoopResp(pkt);
188}
189
190bool
191AddrMapper::isSnooping() const
192{
193 if (slavePort.isSnooping())
194 fatal("AddrMapper doesn't support remapping of snooping requests\n");
195 return false;
196}
197
54}
55
56BaseMasterPort&
57AddrMapper::getMasterPort(const std::string& if_name, PortID idx)
58{
59 if (if_name == "master") {
60 return masterPort;
61 } else {
62 return MemObject::getMasterPort(if_name, idx);
63 }
64}
65
66BaseSlavePort&
67AddrMapper::getSlavePort(const std::string& if_name, PortID idx)
68{
69 if (if_name == "slave") {
70 return slavePort;
71 } else {
72 return MemObject::getSlavePort(if_name, idx);
73 }
74}
75
76void
77AddrMapper::recvFunctional(PacketPtr pkt)
78{
79 Addr orig_addr = pkt->getAddr();
80 pkt->setAddr(remapAddr(orig_addr));
81 masterPort.sendFunctional(pkt);
82 pkt->setAddr(orig_addr);
83}
84
85void
86AddrMapper::recvFunctionalSnoop(PacketPtr pkt)
87{
88 Addr orig_addr = pkt->getAddr();
89 pkt->setAddr(remapAddr(orig_addr));
90 slavePort.sendFunctionalSnoop(pkt);
91 pkt->setAddr(orig_addr);
92}
93
94Tick
95AddrMapper::recvAtomic(PacketPtr pkt)
96{
97 Addr orig_addr = pkt->getAddr();
98 pkt->setAddr(remapAddr(orig_addr));
99 Tick ret_tick = masterPort.sendAtomic(pkt);
100 pkt->setAddr(orig_addr);
101 return ret_tick;
102}
103
104Tick
105AddrMapper::recvAtomicSnoop(PacketPtr pkt)
106{
107 Addr orig_addr = pkt->getAddr();
108 pkt->setAddr(remapAddr(orig_addr));
109 Tick ret_tick = slavePort.sendAtomicSnoop(pkt);
110 pkt->setAddr(orig_addr);
111 return ret_tick;
112}
113
114bool
115AddrMapper::recvTimingReq(PacketPtr pkt)
116{
117 Addr orig_addr = pkt->getAddr();
118 bool needsResponse = pkt->needsResponse();
119 bool memInhibitAsserted = pkt->memInhibitAsserted();
120
121 if (needsResponse && !memInhibitAsserted) {
122 pkt->pushSenderState(new AddrMapperSenderState(orig_addr));
123 }
124
125 pkt->setAddr(remapAddr(orig_addr));
126
127 // Attempt to send the packet (always succeeds for inhibited
128 // packets)
129 bool successful = masterPort.sendTimingReq(pkt);
130
131 // If not successful, restore the sender state
132 if (!successful && needsResponse) {
133 delete pkt->popSenderState();
134 }
135
136 return successful;
137}
138
139bool
140AddrMapper::recvTimingResp(PacketPtr pkt)
141{
142 AddrMapperSenderState* receivedState =
143 dynamic_cast<AddrMapperSenderState*>(pkt->senderState);
144
145 // Restore initial sender state
146 if (receivedState == NULL)
147 panic("AddrMapper %s got a response without sender state\n",
148 name());
149
150 Addr remapped_addr = pkt->getAddr();
151
152 // Restore the state and address
153 pkt->senderState = receivedState->predecessor;
154 pkt->setAddr(receivedState->origAddr);
155
156 // Attempt to send the packet
157 bool successful = slavePort.sendTimingResp(pkt);
158
159 // If packet successfully sent, delete the sender state, otherwise
160 // restore state
161 if (successful) {
162 delete receivedState;
163 } else {
164 // Don't delete anything and let the packet look like we did
165 // not touch it
166 pkt->senderState = receivedState;
167 pkt->setAddr(remapped_addr);
168 }
169 return successful;
170}
171
172void
173AddrMapper::recvTimingSnoopReq(PacketPtr pkt)
174{
175 slavePort.sendTimingSnoopReq(pkt);
176}
177
178bool
179AddrMapper::recvTimingSnoopResp(PacketPtr pkt)
180{
181 return masterPort.sendTimingSnoopResp(pkt);
182}
183
184bool
185AddrMapper::isSnooping() const
186{
187 if (slavePort.isSnooping())
188 fatal("AddrMapper doesn't support remapping of snooping requests\n");
189 return false;
190}
191
198unsigned
199AddrMapper::deviceBlockSizeMaster()
200{
201 return slavePort.peerBlockSize();
202}
203
204unsigned
205AddrMapper::deviceBlockSizeSlave()
206{
207 return masterPort.peerBlockSize();
208}
209
210void
211AddrMapper::recvRetryMaster()
212{
213 slavePort.sendRetry();
214}
215
216void
217AddrMapper::recvRetrySlave()
218{
219 masterPort.sendRetry();
220}
221
222void
223AddrMapper::recvRangeChange()
224{
225 slavePort.sendRangeChange();
226}
227
228RangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams* p) :
229 AddrMapper(p),
230 originalRanges(p->original_ranges),
231 remappedRanges(p->remapped_ranges)
232{
233 if (originalRanges.size() != remappedRanges.size())
234 fatal("AddrMapper: original and shadowed range list must "
235 "be same size\n");
236
237 for (size_t x = 0; x < originalRanges.size(); x++) {
238 if (originalRanges[x].size() != remappedRanges[x].size())
239 fatal("AddrMapper: original and shadowed range list elements"
240 " aren't all of the same size\n");
241 }
242}
243
244RangeAddrMapper*
245RangeAddrMapperParams::create()
246{
247 return new RangeAddrMapper(this);
248}
249
250Addr
251RangeAddrMapper::remapAddr(Addr addr) const
252{
253 for (int i = 0; i < originalRanges.size(); ++i) {
254 if (originalRanges[i].contains(addr)) {
255 Addr offset = addr - originalRanges[i].start();
256 return offset + remappedRanges[i].start();
257 }
258 }
259
260 return addr;
261}
262
263AddrRangeList
264RangeAddrMapper::getAddrRanges() const
265{
266 // Simply return the original ranges as given by the parameters
267 AddrRangeList ranges(originalRanges.begin(), originalRanges.end());
268 return ranges;
269}
270
271
192void
193AddrMapper::recvRetryMaster()
194{
195 slavePort.sendRetry();
196}
197
198void
199AddrMapper::recvRetrySlave()
200{
201 masterPort.sendRetry();
202}
203
204void
205AddrMapper::recvRangeChange()
206{
207 slavePort.sendRangeChange();
208}
209
210RangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams* p) :
211 AddrMapper(p),
212 originalRanges(p->original_ranges),
213 remappedRanges(p->remapped_ranges)
214{
215 if (originalRanges.size() != remappedRanges.size())
216 fatal("AddrMapper: original and shadowed range list must "
217 "be same size\n");
218
219 for (size_t x = 0; x < originalRanges.size(); x++) {
220 if (originalRanges[x].size() != remappedRanges[x].size())
221 fatal("AddrMapper: original and shadowed range list elements"
222 " aren't all of the same size\n");
223 }
224}
225
226RangeAddrMapper*
227RangeAddrMapperParams::create()
228{
229 return new RangeAddrMapper(this);
230}
231
232Addr
233RangeAddrMapper::remapAddr(Addr addr) const
234{
235 for (int i = 0; i < originalRanges.size(); ++i) {
236 if (originalRanges[i].contains(addr)) {
237 Addr offset = addr - originalRanges[i].start();
238 return offset + remappedRanges[i].start();
239 }
240 }
241
242 return addr;
243}
244
245AddrRangeList
246RangeAddrMapper::getAddrRanges() const
247{
248 // Simply return the original ranges as given by the parameters
249 AddrRangeList ranges(originalRanges.begin(), originalRanges.end());
250 return ranges;
251}
252
253