addr_mapper.cc revision 9294
112855Sgabeblack@google.com/* 212855Sgabeblack@google.com * Copyright (c) 2012 ARM Limited 312855Sgabeblack@google.com * All rights reserved 412855Sgabeblack@google.com * 512855Sgabeblack@google.com * The license below extends only to copyright in the software and shall 612855Sgabeblack@google.com * not be construed as granting a license to any other intellectual 712855Sgabeblack@google.com * property including but not limited to intellectual property relating 812855Sgabeblack@google.com * to a hardware implementation of the functionality of the software 912855Sgabeblack@google.com * licensed hereunder. You may use the software subject to the license 1012855Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated 1112855Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software, 1212855Sgabeblack@google.com * modified or unmodified, in source code or in binary form. 1312855Sgabeblack@google.com * 1412855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 1512855Sgabeblack@google.com * modification, are permitted provided that the following conditions are 1612855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 1712855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 1812855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1912855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 2012855Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 2112855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 2212855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 2312855Sgabeblack@google.com * this software without specific prior written permission. 2412855Sgabeblack@google.com * 2512855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2612855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2712855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2812855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2912855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3012855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3112855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3212855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3312855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3412855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3512855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3612855Sgabeblack@google.com * 3712855Sgabeblack@google.com * Authors: Andreas Hansson 3812855Sgabeblack@google.com */ 3912855Sgabeblack@google.com 4012855Sgabeblack@google.com#include "mem/addr_mapper.hh" 4112855Sgabeblack@google.com 4212855Sgabeblack@google.comAddrMapper::AddrMapper(const AddrMapperParams* p) 4312855Sgabeblack@google.com : MemObject(p), 4412855Sgabeblack@google.com masterPort(name() + "-master", *this), 4512855Sgabeblack@google.com slavePort(name() + "-slave", *this) 4612855Sgabeblack@google.com{ 4712855Sgabeblack@google.com} 4812855Sgabeblack@google.com 4912855Sgabeblack@google.comvoid 5012855Sgabeblack@google.comAddrMapper::init() 5112855Sgabeblack@google.com{ 5212855Sgabeblack@google.com if (!slavePort.isConnected() || !masterPort.isConnected()) 5312855Sgabeblack@google.com fatal("Address mapper is not connected on both sides.\n"); 5412855Sgabeblack@google.com 5512855Sgabeblack@google.com if ((slavePort.peerBlockSize() != masterPort.peerBlockSize()) && 5612855Sgabeblack@google.com slavePort.peerBlockSize() && masterPort.peerBlockSize()) 5712855Sgabeblack@google.com fatal("Slave port size %d, master port size %d \n " 5812855Sgabeblack@google.com "don't have the same block size... Not supported.\n", 5912855Sgabeblack@google.com slavePort.peerBlockSize(), masterPort.peerBlockSize()); 6012855Sgabeblack@google.com} 6112855Sgabeblack@google.com 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 Packet::SenderState* senderState = pkt->senderState; 127 128 if (needsResponse && !memInhibitAsserted) { 129 pkt->senderState = new AddrMapperSenderState(senderState, orig_addr); 130 } 131 132 pkt->setAddr(remapAddr(orig_addr)); 133 134 // Attempt to send the packet (always succeeds for inhibited 135 // packets) 136 bool successful = masterPort.sendTimingReq(pkt); 137 138 // If not successful, restore the sender state 139 if (!successful && needsResponse) { 140 delete pkt->senderState; 141 pkt->senderState = senderState; 142 } 143 144 return successful; 145} 146 147bool 148AddrMapper::recvTimingResp(PacketPtr pkt) 149{ 150 AddrMapperSenderState* receivedState = 151 dynamic_cast<AddrMapperSenderState*>(pkt->senderState); 152 153 // Restore initial sender state 154 if (receivedState == NULL) 155 panic("AddrMapper %s got a response without sender state\n", 156 name()); 157 158 Addr remapped_addr = pkt->getAddr(); 159 160 // Restore the state and address 161 pkt->senderState = receivedState->origSenderState; 162 pkt->setAddr(receivedState->origAddr); 163 164 // Attempt to send the packet 165 bool successful = slavePort.sendTimingResp(pkt); 166 167 // If packet successfully sent, delete the sender state, otherwise 168 // restore state 169 if (successful) { 170 delete receivedState; 171 } else { 172 // Don't delete anything and let the packet look like we did 173 // not touch it 174 pkt->senderState = receivedState; 175 pkt->setAddr(remapped_addr); 176 } 177 return successful; 178} 179 180void 181AddrMapper::recvTimingSnoopReq(PacketPtr pkt) 182{ 183 slavePort.sendTimingSnoopReq(pkt); 184} 185 186bool 187AddrMapper::recvTimingSnoopResp(PacketPtr pkt) 188{ 189 return masterPort.sendTimingSnoopResp(pkt); 190} 191 192bool 193AddrMapper::isSnooping() const 194{ 195 if (slavePort.isSnooping()) 196 fatal("AddrMapper doesn't support remapping of snooping requests\n"); 197 return false; 198} 199 200unsigned 201AddrMapper::deviceBlockSizeMaster() 202{ 203 return slavePort.peerBlockSize(); 204} 205 206unsigned 207AddrMapper::deviceBlockSizeSlave() 208{ 209 return masterPort.peerBlockSize(); 210} 211 212void 213AddrMapper::recvRetryMaster() 214{ 215 slavePort.sendRetry(); 216} 217 218void 219AddrMapper::recvRetrySlave() 220{ 221 masterPort.sendRetry(); 222} 223 224void 225AddrMapper::recvRangeChange() 226{ 227 slavePort.sendRangeChange(); 228} 229 230RangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams* p) : 231 AddrMapper(p), 232 originalRanges(p->original_ranges), 233 remappedRanges(p->remapped_ranges) 234{ 235 if (originalRanges.size() != remappedRanges.size()) 236 fatal("AddrMapper: original and shadowed range list must " 237 "be same size\n"); 238 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"); 243 } 244} 245 246RangeAddrMapper* 247RangeAddrMapperParams::create() 248{ 249 return new RangeAddrMapper(this); 250} 251 252Addr 253RangeAddrMapper::remapAddr(Addr addr) const 254{ 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; 259 } 260 } 261 262 return addr; 263} 264 265AddrRangeList 266RangeAddrMapper::getAddrRanges() const 267{ 268 AddrRangeList ranges; 269 AddrRangeList actualRanges = masterPort.getAddrRanges(); 270 271 for (AddrRangeIter r = actualRanges.begin(); r != actualRanges.end(); ++r) { 272 AddrRange range = *r; 273 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])) { 279 // range is a subset 280 Addr offset = range.start - originalRanges[j].start; 281 range.start -= offset; 282 range.end -= offset; 283 } 284 ranges.push_back(range); 285 } 286 } 287 288 return ranges; 289} 290 291 292