addr_mapper.cc (13784:1941dc118243) addr_mapper.cc (13892:0182a0601f66)
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)
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),
43 : SimObject(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
56Port &
57AddrMapper::getPort(const std::string &if_name, PortID idx)
58{
59 if (if_name == "master") {
60 return masterPort;
61 } else if (if_name == "slave") {
62 return slavePort;
63 } else {
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
56Port &
57AddrMapper::getPort(const std::string &if_name, PortID idx)
58{
59 if (if_name == "master") {
60 return masterPort;
61 } else if (if_name == "slave") {
62 return slavePort;
63 } else {
64 return MemObject::getPort(if_name, idx);
64 return SimObject::getPort(if_name, idx);
65 }
66}
67
68void
69AddrMapper::recvFunctional(PacketPtr pkt)
70{
71 Addr orig_addr = pkt->getAddr();
72 pkt->setAddr(remapAddr(orig_addr));
73 masterPort.sendFunctional(pkt);
74 pkt->setAddr(orig_addr);
75}
76
77void
78AddrMapper::recvFunctionalSnoop(PacketPtr pkt)
79{
80 Addr orig_addr = pkt->getAddr();
81 pkt->setAddr(remapAddr(orig_addr));
82 slavePort.sendFunctionalSnoop(pkt);
83 pkt->setAddr(orig_addr);
84}
85
86Tick
87AddrMapper::recvAtomic(PacketPtr pkt)
88{
89 Addr orig_addr = pkt->getAddr();
90 pkt->setAddr(remapAddr(orig_addr));
91 Tick ret_tick = masterPort.sendAtomic(pkt);
92 pkt->setAddr(orig_addr);
93 return ret_tick;
94}
95
96Tick
97AddrMapper::recvAtomicSnoop(PacketPtr pkt)
98{
99 Addr orig_addr = pkt->getAddr();
100 pkt->setAddr(remapAddr(orig_addr));
101 Tick ret_tick = slavePort.sendAtomicSnoop(pkt);
102 pkt->setAddr(orig_addr);
103 return ret_tick;
104}
105
106bool
107AddrMapper::recvTimingReq(PacketPtr pkt)
108{
109 Addr orig_addr = pkt->getAddr();
110 bool needsResponse = pkt->needsResponse();
111 bool cacheResponding = pkt->cacheResponding();
112
113 if (needsResponse && !cacheResponding) {
114 pkt->pushSenderState(new AddrMapperSenderState(orig_addr));
115 }
116
117 pkt->setAddr(remapAddr(orig_addr));
118
119 // Attempt to send the packet
120 bool successful = masterPort.sendTimingReq(pkt);
121
122 // If not successful, restore the address and sender state
123 if (!successful) {
124 pkt->setAddr(orig_addr);
125
126 if (needsResponse) {
127 delete pkt->popSenderState();
128 }
129 }
130
131 return successful;
132}
133
134bool
135AddrMapper::recvTimingResp(PacketPtr pkt)
136{
137 AddrMapperSenderState* receivedState =
138 dynamic_cast<AddrMapperSenderState*>(pkt->senderState);
139
140 // Restore initial sender state
141 if (receivedState == NULL)
142 panic("AddrMapper %s got a response without sender state\n",
143 name());
144
145 Addr remapped_addr = pkt->getAddr();
146
147 // Restore the state and address
148 pkt->senderState = receivedState->predecessor;
149 pkt->setAddr(receivedState->origAddr);
150
151 // Attempt to send the packet
152 bool successful = slavePort.sendTimingResp(pkt);
153
154 // If packet successfully sent, delete the sender state, otherwise
155 // restore state
156 if (successful) {
157 delete receivedState;
158 } else {
159 // Don't delete anything and let the packet look like we did
160 // not touch it
161 pkt->senderState = receivedState;
162 pkt->setAddr(remapped_addr);
163 }
164 return successful;
165}
166
167void
168AddrMapper::recvTimingSnoopReq(PacketPtr pkt)
169{
170 slavePort.sendTimingSnoopReq(pkt);
171}
172
173bool
174AddrMapper::recvTimingSnoopResp(PacketPtr pkt)
175{
176 return masterPort.sendTimingSnoopResp(pkt);
177}
178
179bool
180AddrMapper::isSnooping() const
181{
182 if (slavePort.isSnooping())
183 fatal("AddrMapper doesn't support remapping of snooping requests\n");
184 return false;
185}
186
187void
188AddrMapper::recvReqRetry()
189{
190 slavePort.sendRetryReq();
191}
192
193void
194AddrMapper::recvRespRetry()
195{
196 masterPort.sendRetryResp();
197}
198
199void
200AddrMapper::recvRangeChange()
201{
202 slavePort.sendRangeChange();
203}
204
205RangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams* p) :
206 AddrMapper(p),
207 originalRanges(p->original_ranges),
208 remappedRanges(p->remapped_ranges)
209{
210 if (originalRanges.size() != remappedRanges.size())
211 fatal("AddrMapper: original and shadowed range list must "
212 "be same size\n");
213
214 for (size_t x = 0; x < originalRanges.size(); x++) {
215 if (originalRanges[x].size() != remappedRanges[x].size())
216 fatal("AddrMapper: original and shadowed range list elements"
217 " aren't all of the same size\n");
218 }
219}
220
221RangeAddrMapper*
222RangeAddrMapperParams::create()
223{
224 return new RangeAddrMapper(this);
225}
226
227Addr
228RangeAddrMapper::remapAddr(Addr addr) const
229{
230 for (int i = 0; i < originalRanges.size(); ++i) {
231 if (originalRanges[i].contains(addr)) {
232 Addr offset = addr - originalRanges[i].start();
233 return offset + remappedRanges[i].start();
234 }
235 }
236
237 return addr;
238}
239
240AddrRangeList
241RangeAddrMapper::getAddrRanges() const
242{
243 // Simply return the original ranges as given by the parameters
244 AddrRangeList ranges(originalRanges.begin(), originalRanges.end());
245 return ranges;
246}
247
248
65 }
66}
67
68void
69AddrMapper::recvFunctional(PacketPtr pkt)
70{
71 Addr orig_addr = pkt->getAddr();
72 pkt->setAddr(remapAddr(orig_addr));
73 masterPort.sendFunctional(pkt);
74 pkt->setAddr(orig_addr);
75}
76
77void
78AddrMapper::recvFunctionalSnoop(PacketPtr pkt)
79{
80 Addr orig_addr = pkt->getAddr();
81 pkt->setAddr(remapAddr(orig_addr));
82 slavePort.sendFunctionalSnoop(pkt);
83 pkt->setAddr(orig_addr);
84}
85
86Tick
87AddrMapper::recvAtomic(PacketPtr pkt)
88{
89 Addr orig_addr = pkt->getAddr();
90 pkt->setAddr(remapAddr(orig_addr));
91 Tick ret_tick = masterPort.sendAtomic(pkt);
92 pkt->setAddr(orig_addr);
93 return ret_tick;
94}
95
96Tick
97AddrMapper::recvAtomicSnoop(PacketPtr pkt)
98{
99 Addr orig_addr = pkt->getAddr();
100 pkt->setAddr(remapAddr(orig_addr));
101 Tick ret_tick = slavePort.sendAtomicSnoop(pkt);
102 pkt->setAddr(orig_addr);
103 return ret_tick;
104}
105
106bool
107AddrMapper::recvTimingReq(PacketPtr pkt)
108{
109 Addr orig_addr = pkt->getAddr();
110 bool needsResponse = pkt->needsResponse();
111 bool cacheResponding = pkt->cacheResponding();
112
113 if (needsResponse && !cacheResponding) {
114 pkt->pushSenderState(new AddrMapperSenderState(orig_addr));
115 }
116
117 pkt->setAddr(remapAddr(orig_addr));
118
119 // Attempt to send the packet
120 bool successful = masterPort.sendTimingReq(pkt);
121
122 // If not successful, restore the address and sender state
123 if (!successful) {
124 pkt->setAddr(orig_addr);
125
126 if (needsResponse) {
127 delete pkt->popSenderState();
128 }
129 }
130
131 return successful;
132}
133
134bool
135AddrMapper::recvTimingResp(PacketPtr pkt)
136{
137 AddrMapperSenderState* receivedState =
138 dynamic_cast<AddrMapperSenderState*>(pkt->senderState);
139
140 // Restore initial sender state
141 if (receivedState == NULL)
142 panic("AddrMapper %s got a response without sender state\n",
143 name());
144
145 Addr remapped_addr = pkt->getAddr();
146
147 // Restore the state and address
148 pkt->senderState = receivedState->predecessor;
149 pkt->setAddr(receivedState->origAddr);
150
151 // Attempt to send the packet
152 bool successful = slavePort.sendTimingResp(pkt);
153
154 // If packet successfully sent, delete the sender state, otherwise
155 // restore state
156 if (successful) {
157 delete receivedState;
158 } else {
159 // Don't delete anything and let the packet look like we did
160 // not touch it
161 pkt->senderState = receivedState;
162 pkt->setAddr(remapped_addr);
163 }
164 return successful;
165}
166
167void
168AddrMapper::recvTimingSnoopReq(PacketPtr pkt)
169{
170 slavePort.sendTimingSnoopReq(pkt);
171}
172
173bool
174AddrMapper::recvTimingSnoopResp(PacketPtr pkt)
175{
176 return masterPort.sendTimingSnoopResp(pkt);
177}
178
179bool
180AddrMapper::isSnooping() const
181{
182 if (slavePort.isSnooping())
183 fatal("AddrMapper doesn't support remapping of snooping requests\n");
184 return false;
185}
186
187void
188AddrMapper::recvReqRetry()
189{
190 slavePort.sendRetryReq();
191}
192
193void
194AddrMapper::recvRespRetry()
195{
196 masterPort.sendRetryResp();
197}
198
199void
200AddrMapper::recvRangeChange()
201{
202 slavePort.sendRangeChange();
203}
204
205RangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams* p) :
206 AddrMapper(p),
207 originalRanges(p->original_ranges),
208 remappedRanges(p->remapped_ranges)
209{
210 if (originalRanges.size() != remappedRanges.size())
211 fatal("AddrMapper: original and shadowed range list must "
212 "be same size\n");
213
214 for (size_t x = 0; x < originalRanges.size(); x++) {
215 if (originalRanges[x].size() != remappedRanges[x].size())
216 fatal("AddrMapper: original and shadowed range list elements"
217 " aren't all of the same size\n");
218 }
219}
220
221RangeAddrMapper*
222RangeAddrMapperParams::create()
223{
224 return new RangeAddrMapper(this);
225}
226
227Addr
228RangeAddrMapper::remapAddr(Addr addr) const
229{
230 for (int i = 0; i < originalRanges.size(); ++i) {
231 if (originalRanges[i].contains(addr)) {
232 Addr offset = addr - originalRanges[i].start();
233 return offset + remappedRanges[i].start();
234 }
235 }
236
237 return addr;
238}
239
240AddrRangeList
241RangeAddrMapper::getAddrRanges() const
242{
243 // Simply return the original ranges as given by the parameters
244 AddrRangeList ranges(originalRanges.begin(), originalRanges.end());
245 return ranges;
246}
247
248