2 * Copyright (c) 2012 ARM Limited
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.
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.
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.
37 * Authors: Andreas Hansson
40 #include "mem/addr_mapper.hh"
42 AddrMapper::AddrMapper(const AddrMapperParams
* p
)
44 masterPort(name() + "-master", *this),
45 slavePort(name() + "-slave", *this)
52 if (!slavePort
.isConnected() || !masterPort
.isConnected())
53 fatal("Address mapper is not connected on both sides.\n");
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());
63 AddrMapper::getMasterPort(const std::string
& if_name
, PortID idx
)
65 if (if_name
== "master") {
68 return MemObject::getMasterPort(if_name
, idx
);
73 AddrMapper::getSlavePort(const std::string
& if_name
, PortID idx
)
75 if (if_name
== "slave") {
78 return MemObject::getSlavePort(if_name
, idx
);
83 AddrMapper::recvFunctional(PacketPtr pkt
)
85 Addr orig_addr
= pkt
->getAddr();
86 pkt
->setAddr(remapAddr(orig_addr
));
87 masterPort
.sendFunctional(pkt
);
88 pkt
->setAddr(orig_addr
);
92 AddrMapper::recvFunctionalSnoop(PacketPtr pkt
)
94 Addr orig_addr
= pkt
->getAddr();
95 pkt
->setAddr(remapAddr(orig_addr
));
96 slavePort
.sendFunctionalSnoop(pkt
);
97 pkt
->setAddr(orig_addr
);
101 AddrMapper::recvAtomic(PacketPtr pkt
)
103 Addr orig_addr
= pkt
->getAddr();
104 pkt
->setAddr(remapAddr(orig_addr
));
105 Tick ret_tick
= masterPort
.sendAtomic(pkt
);
106 pkt
->setAddr(orig_addr
);
111 AddrMapper::recvAtomicSnoop(PacketPtr pkt
)
113 Addr orig_addr
= pkt
->getAddr();
114 pkt
->setAddr(remapAddr(orig_addr
));
115 Tick ret_tick
= slavePort
.sendAtomicSnoop(pkt
);
116 pkt
->setAddr(orig_addr
);
121 AddrMapper::recvTimingReq(PacketPtr pkt
)
123 Addr orig_addr
= pkt
->getAddr();
124 bool needsResponse
= pkt
->needsResponse();
125 bool memInhibitAsserted
= pkt
->memInhibitAsserted();
126 Packet::SenderState
* senderState
= pkt
->senderState
;
128 if (needsResponse
&& !memInhibitAsserted
) {
129 pkt
->senderState
= new AddrMapperSenderState(senderState
, orig_addr
);
132 pkt
->setAddr(remapAddr(orig_addr
));
134 // Attempt to send the packet (always succeeds for inhibited
136 bool successful
= masterPort
.sendTimingReq(pkt
);
138 // If not successful, restore the sender state
139 if (!successful
&& needsResponse
) {
140 delete pkt
->senderState
;
141 pkt
->senderState
= senderState
;
148 AddrMapper::recvTimingResp(PacketPtr pkt
)
150 AddrMapperSenderState
* receivedState
=
151 dynamic_cast<AddrMapperSenderState
*>(pkt
->senderState
);
153 // Restore initial sender state
154 if (receivedState
== NULL
)
155 panic("AddrMapper %s got a response without sender state\n",
158 Addr remapped_addr
= pkt
->getAddr();
160 // Restore the state and address
161 pkt
->senderState
= receivedState
->origSenderState
;
162 pkt
->setAddr(receivedState
->origAddr
);
164 // Attempt to send the packet
165 bool successful
= slavePort
.sendTimingResp(pkt
);
167 // If packet successfully sent, delete the sender state, otherwise
170 delete receivedState
;
172 // Don't delete anything and let the packet look like we did
174 pkt
->senderState
= receivedState
;
175 pkt
->setAddr(remapped_addr
);
181 AddrMapper::recvTimingSnoopReq(PacketPtr pkt
)
183 slavePort
.sendTimingSnoopReq(pkt
);
187 AddrMapper::recvTimingSnoopResp(PacketPtr pkt
)
189 return masterPort
.sendTimingSnoopResp(pkt
);
193 AddrMapper::isSnooping() const
195 if (slavePort
.isSnooping())
196 fatal("AddrMapper doesn't support remapping of snooping requests\n");
201 AddrMapper::deviceBlockSizeMaster()
203 return slavePort
.peerBlockSize();
207 AddrMapper::deviceBlockSizeSlave()
209 return masterPort
.peerBlockSize();
213 AddrMapper::recvRetryMaster()
215 slavePort
.sendRetry();
219 AddrMapper::recvRetrySlave()
221 masterPort
.sendRetry();
225 AddrMapper::recvRangeChange()
227 slavePort
.sendRangeChange();
230 RangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams
* p
) :
232 originalRanges(p
->original_ranges
),
233 remappedRanges(p
->remapped_ranges
)
235 if (originalRanges
.size() != remappedRanges
.size())
236 fatal("AddrMapper: original and shadowed range list must "
239 for (size_t x
= 0; x
< originalRanges
.size(); x
++) {
240 if (originalRanges
[x
].size() != remappedRanges
[x
].size())
241 fatal("AddrMapper: original and shadowed range list elements"
242 " aren't all of the same size\n");
247 RangeAddrMapperParams::create()
249 return new RangeAddrMapper(this);
253 RangeAddrMapper::remapAddr(Addr addr
) const
255 for (int i
= 0; i
< originalRanges
.size(); ++i
) {
256 if (originalRanges
[i
] == addr
) {
257 Addr offset
= addr
- originalRanges
[i
].start
;
258 return offset
+ remappedRanges
[i
].start
;
266 RangeAddrMapper::getAddrRanges() const
268 AddrRangeList ranges
;
269 AddrRangeList actualRanges
= masterPort
.getAddrRanges();
271 for (AddrRangeIter r
= actualRanges
.begin(); r
!= actualRanges
.end(); ++r
) {
272 AddrRange range
= *r
;
274 for (int j
= 0; j
< originalRanges
.size(); ++j
) {
275 if (range
.intersects(originalRanges
[j
]))
276 fatal("Cannot remap range that intersects the original"
277 " ranges but are not a subset.\n");
278 if (range
.isSubset(originalRanges
[j
])) {
280 Addr offset
= range
.start
- originalRanges
[j
].start
;
281 range
.start
-= offset
;
284 ranges
.push_back(range
);