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.
38 #include "mem/addr_mapper.hh"
40 AddrMapper::AddrMapper(const AddrMapperParams
* p
)
42 memSidePort(name() + "-mem_side_port", *this),
43 cpuSidePort(name() + "-cpu_side_port", *this)
50 if (!cpuSidePort
.isConnected() || !memSidePort
.isConnected())
51 fatal("Address mapper is not connected on both sides.\n");
55 AddrMapper::getPort(const std::string
&if_name
, PortID idx
)
57 if (if_name
== "mem_side_port") {
59 } else if (if_name
== "cpu_side_port") {
62 return SimObject::getPort(if_name
, idx
);
67 AddrMapper::recvFunctional(PacketPtr pkt
)
69 Addr orig_addr
= pkt
->getAddr();
70 pkt
->setAddr(remapAddr(orig_addr
));
71 memSidePort
.sendFunctional(pkt
);
72 pkt
->setAddr(orig_addr
);
76 AddrMapper::recvFunctionalSnoop(PacketPtr pkt
)
78 Addr orig_addr
= pkt
->getAddr();
79 pkt
->setAddr(remapAddr(orig_addr
));
80 cpuSidePort
.sendFunctionalSnoop(pkt
);
81 pkt
->setAddr(orig_addr
);
85 AddrMapper::recvAtomic(PacketPtr pkt
)
87 Addr orig_addr
= pkt
->getAddr();
88 pkt
->setAddr(remapAddr(orig_addr
));
89 Tick ret_tick
= memSidePort
.sendAtomic(pkt
);
90 pkt
->setAddr(orig_addr
);
95 AddrMapper::recvAtomicSnoop(PacketPtr pkt
)
97 Addr orig_addr
= pkt
->getAddr();
98 pkt
->setAddr(remapAddr(orig_addr
));
99 Tick ret_tick
= cpuSidePort
.sendAtomicSnoop(pkt
);
100 pkt
->setAddr(orig_addr
);
105 AddrMapper::recvTimingReq(PacketPtr pkt
)
107 Addr orig_addr
= pkt
->getAddr();
108 bool needsResponse
= pkt
->needsResponse();
109 bool cacheResponding
= pkt
->cacheResponding();
111 if (needsResponse
&& !cacheResponding
) {
112 pkt
->pushSenderState(new AddrMapperSenderState(orig_addr
));
115 pkt
->setAddr(remapAddr(orig_addr
));
117 // Attempt to send the packet
118 bool successful
= memSidePort
.sendTimingReq(pkt
);
120 // If not successful, restore the address and sender state
122 pkt
->setAddr(orig_addr
);
125 delete pkt
->popSenderState();
133 AddrMapper::recvTimingResp(PacketPtr pkt
)
135 AddrMapperSenderState
* receivedState
=
136 dynamic_cast<AddrMapperSenderState
*>(pkt
->senderState
);
138 // Restore initial sender state
139 if (receivedState
== NULL
)
140 panic("AddrMapper %s got a response without sender state\n",
143 Addr remapped_addr
= pkt
->getAddr();
145 // Restore the state and address
146 pkt
->senderState
= receivedState
->predecessor
;
147 pkt
->setAddr(receivedState
->origAddr
);
149 // Attempt to send the packet
150 bool successful
= cpuSidePort
.sendTimingResp(pkt
);
152 // If packet successfully sent, delete the sender state, otherwise
155 delete receivedState
;
157 // Don't delete anything and let the packet look like we did
159 pkt
->senderState
= receivedState
;
160 pkt
->setAddr(remapped_addr
);
166 AddrMapper::recvTimingSnoopReq(PacketPtr pkt
)
168 cpuSidePort
.sendTimingSnoopReq(pkt
);
172 AddrMapper::recvTimingSnoopResp(PacketPtr pkt
)
174 return memSidePort
.sendTimingSnoopResp(pkt
);
178 AddrMapper::isSnooping() const
180 if (cpuSidePort
.isSnooping())
181 fatal("AddrMapper doesn't support remapping of snooping requests\n");
186 AddrMapper::recvReqRetry()
188 cpuSidePort
.sendRetryReq();
192 AddrMapper::recvRespRetry()
194 memSidePort
.sendRetryResp();
198 AddrMapper::recvRangeChange()
200 cpuSidePort
.sendRangeChange();
203 RangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams
* p
) :
205 originalRanges(p
->original_ranges
),
206 remappedRanges(p
->remapped_ranges
)
208 if (originalRanges
.size() != remappedRanges
.size())
209 fatal("AddrMapper: original and shadowed range list must "
212 for (size_t x
= 0; x
< originalRanges
.size(); x
++) {
213 if (originalRanges
[x
].size() != remappedRanges
[x
].size())
214 fatal("AddrMapper: original and shadowed range list elements"
215 " aren't all of the same size\n");
220 RangeAddrMapperParams::create()
222 return new RangeAddrMapper(this);
226 RangeAddrMapper::remapAddr(Addr addr
) const
228 for (int i
= 0; i
< originalRanges
.size(); ++i
) {
229 if (originalRanges
[i
].contains(addr
)) {
230 Addr offset
= addr
- originalRanges
[i
].start();
231 return offset
+ remappedRanges
[i
].start();
239 RangeAddrMapper::getAddrRanges() const
241 // Simply return the original ranges as given by the parameters
242 AddrRangeList
ranges(originalRanges
.begin(), originalRanges
.end());