addr_mapper.cc revision 9406
14120Sgblack@eecs.umich.edu/* 24120Sgblack@eecs.umich.edu * Copyright (c) 2012 ARM Limited 34120Sgblack@eecs.umich.edu * All rights reserved 44120Sgblack@eecs.umich.edu * 57087Snate@binkert.org * The license below extends only to copyright in the software and shall 67087Snate@binkert.org * not be construed as granting a license to any other intellectual 77087Snate@binkert.org * property including but not limited to intellectual property relating 87087Snate@binkert.org * to a hardware implementation of the functionality of the software 97087Snate@binkert.org * licensed hereunder. You may use the software subject to the license 107087Snate@binkert.org * terms below provided that you ensure that this notice is replicated 117087Snate@binkert.org * unmodified and in its entirety in all distributions of the software, 127087Snate@binkert.org * modified or unmodified, in source code or in binary form. 134120Sgblack@eecs.umich.edu * 147087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 157087Snate@binkert.org * modification, are permitted provided that the following conditions are 167087Snate@binkert.org * met: redistributions of source code must retain the above copyright 177087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 187087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 197087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 207087Snate@binkert.org * documentation and/or other materials provided with the distribution; 217087Snate@binkert.org * neither the name of the copyright holders nor the names of its 224120Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 237087Snate@binkert.org * this software without specific prior written permission. 244120Sgblack@eecs.umich.edu * 254120Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 264120Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 274120Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 284120Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 294120Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 304120Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 314120Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 324120Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 334120Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 344120Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 354120Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 364120Sgblack@eecs.umich.edu * 374120Sgblack@eecs.umich.edu * Authors: Andreas Hansson 384120Sgblack@eecs.umich.edu */ 394120Sgblack@eecs.umich.edu 404120Sgblack@eecs.umich.edu#include "mem/addr_mapper.hh" 414120Sgblack@eecs.umich.edu 424120Sgblack@eecs.umich.eduAddrMapper::AddrMapper(const AddrMapperParams* p) 435124Sgblack@eecs.umich.edu : MemObject(p), 445237Sgblack@eecs.umich.edu masterPort(name() + "-master", *this), 455124Sgblack@eecs.umich.edu slavePort(name() + "-slave", *this) 4610687SAndreas.Sandberg@ARM.com{ 475124Sgblack@eecs.umich.edu} 488953Sgblack@eecs.umich.edu 495086Sgblack@eecs.umich.eduvoid 506022Sgblack@eecs.umich.eduAddrMapper::init() 515086Sgblack@eecs.umich.edu{ 525086Sgblack@eecs.umich.edu if (!slavePort.isConnected() || !masterPort.isConnected()) 535086Sgblack@eecs.umich.edu fatal("Address mapper is not connected on both sides.\n"); 545086Sgblack@eecs.umich.edu 555086Sgblack@eecs.umich.edu if ((slavePort.peerBlockSize() != masterPort.peerBlockSize()) && 565245Sgblack@eecs.umich.edu slavePort.peerBlockSize() && masterPort.peerBlockSize()) 575245Sgblack@eecs.umich.edu fatal("Slave port size %d, master port size %d \n " 585358Sgblack@eecs.umich.edu "don't have the same block size... Not supported.\n", 595086Sgblack@eecs.umich.edu slavePort.peerBlockSize(), masterPort.peerBlockSize()); 605124Sgblack@eecs.umich.edu} 615895Sgblack@eecs.umich.edu 625236Sgblack@eecs.umich.eduBaseMasterPort& 635360Sgblack@eecs.umich.eduAddrMapper::getMasterPort(const std::string& if_name, PortID idx) 645360Sgblack@eecs.umich.edu{ 655357Sgblack@eecs.umich.edu if (if_name == "master") { 665237Sgblack@eecs.umich.edu return masterPort; 675124Sgblack@eecs.umich.edu } else { 685245Sgblack@eecs.umich.edu return MemObject::getMasterPort(if_name, idx); 695124Sgblack@eecs.umich.edu } 705124Sgblack@eecs.umich.edu} 715086Sgblack@eecs.umich.edu 7211175Sandreas.hansson@arm.comBaseSlavePort& 7310194SGeoffrey.Blake@arm.comAddrMapper::getSlavePort(const std::string& if_name, PortID idx) 745124Sgblack@eecs.umich.edu{ 755124Sgblack@eecs.umich.edu if (if_name == "slave") { 765357Sgblack@eecs.umich.edu return slavePort; 775357Sgblack@eecs.umich.edu } else { 785360Sgblack@eecs.umich.edu return MemObject::getSlavePort(if_name, idx); 795360Sgblack@eecs.umich.edu } 805360Sgblack@eecs.umich.edu} 815360Sgblack@eecs.umich.edu 828752Sgblack@eecs.umich.eduvoid 835236Sgblack@eecs.umich.eduAddrMapper::recvFunctional(PacketPtr pkt) 847912Shestness@cs.utexas.edu{ 857912Shestness@cs.utexas.edu Addr orig_addr = pkt->getAddr(); 865236Sgblack@eecs.umich.edu pkt->setAddr(remapAddr(orig_addr)); 8711175Sandreas.hansson@arm.com masterPort.sendFunctional(pkt); 885242Sgblack@eecs.umich.edu pkt->setAddr(orig_addr); 899423SAndreas.Sandberg@arm.com} 905242Sgblack@eecs.umich.edu 9111175Sandreas.hansson@arm.comvoid 925242Sgblack@eecs.umich.eduAddrMapper::recvFunctionalSnoop(PacketPtr pkt) 935124Sgblack@eecs.umich.edu{ 949818Snilay@cs.wisc.edu Addr orig_addr = pkt->getAddr(); 955124Sgblack@eecs.umich.edu pkt->setAddr(remapAddr(orig_addr)); 9610905Sandreas.sandberg@arm.com slavePort.sendFunctionalSnoop(pkt); 975124Sgblack@eecs.umich.edu pkt->setAddr(orig_addr); 985124Sgblack@eecs.umich.edu} 995124Sgblack@eecs.umich.edu 1008953Sgblack@eecs.umich.eduTick 1018953Sgblack@eecs.umich.eduAddrMapper::recvAtomic(PacketPtr pkt) 1028953Sgblack@eecs.umich.edu{ 10312140Sswapnilster@gmail.com Addr orig_addr = pkt->getAddr(); 10412140Sswapnilster@gmail.com pkt->setAddr(remapAddr(orig_addr)); 10512140Sswapnilster@gmail.com Tick ret_tick = masterPort.sendAtomic(pkt); 10612140Sswapnilster@gmail.com pkt->setAddr(orig_addr); 10712140Sswapnilster@gmail.com return ret_tick; 10812140Sswapnilster@gmail.com} 1096141Sgblack@eecs.umich.edu 1106141Sgblack@eecs.umich.eduTick 1115895Sgblack@eecs.umich.eduAddrMapper::recvAtomicSnoop(PacketPtr pkt) 1126023Snate@binkert.org{ 1135895Sgblack@eecs.umich.edu Addr orig_addr = pkt->getAddr(); 1145140Sgblack@eecs.umich.edu pkt->setAddr(remapAddr(orig_addr)); 1155124Sgblack@eecs.umich.edu Tick ret_tick = slavePort.sendAtomicSnoop(pkt); 1165245Sgblack@eecs.umich.edu pkt->setAddr(orig_addr); 1178953Sgblack@eecs.umich.edu return ret_tick; 1188953Sgblack@eecs.umich.edu} 1198953Sgblack@eecs.umich.edu 1208953Sgblack@eecs.umich.edubool 1218953Sgblack@eecs.umich.eduAddrMapper::recvTimingReq(PacketPtr pkt) 1228953Sgblack@eecs.umich.edu{ 1238953Sgblack@eecs.umich.edu Addr orig_addr = pkt->getAddr(); 1248953Sgblack@eecs.umich.edu bool needsResponse = pkt->needsResponse(); 1256023Snate@binkert.org bool memInhibitAsserted = pkt->memInhibitAsserted(); 1266022Sgblack@eecs.umich.edu Packet::SenderState* senderState = pkt->senderState; 1276023Snate@binkert.org 1288888Sgeoffrey.blake@arm.com if (needsResponse && !memInhibitAsserted) { 1298888Sgeoffrey.blake@arm.com pkt->senderState = new AddrMapperSenderState(senderState, orig_addr); 1308888Sgeoffrey.blake@arm.com } 1318888Sgeoffrey.blake@arm.com 1325245Sgblack@eecs.umich.edu pkt->setAddr(remapAddr(orig_addr)); 1339738Sandreas@sandberg.pp.se 1349738Sandreas@sandberg.pp.se // Attempt to send the packet (always succeeds for inhibited 1359738Sandreas@sandberg.pp.se // packets) 1369738Sandreas@sandberg.pp.se bool successful = masterPort.sendTimingReq(pkt); 1379738Sandreas@sandberg.pp.se 1389738Sandreas@sandberg.pp.se // If not successful, restore the sender state 1399738Sandreas@sandberg.pp.se if (!successful && needsResponse) { 1409738Sandreas@sandberg.pp.se delete pkt->senderState; 1419738Sandreas@sandberg.pp.se pkt->senderState = senderState; 1429738Sandreas@sandberg.pp.se } 1439738Sandreas@sandberg.pp.se 1449738Sandreas@sandberg.pp.se return successful; 1459738Sandreas@sandberg.pp.se} 1469738Sandreas@sandberg.pp.se 1479738Sandreas@sandberg.pp.sebool 1489738Sandreas@sandberg.pp.seAddrMapper::recvTimingResp(PacketPtr pkt) 1496022Sgblack@eecs.umich.edu{ 1506022Sgblack@eecs.umich.edu AddrMapperSenderState* receivedState = 15112140Sswapnilster@gmail.com dynamic_cast<AddrMapperSenderState*>(pkt->senderState); 15212140Sswapnilster@gmail.com 15312140Sswapnilster@gmail.com // Restore initial sender state 15412140Sswapnilster@gmail.com if (receivedState == NULL) 15512140Sswapnilster@gmail.com panic("AddrMapper %s got a response without sender state\n", 1565124Sgblack@eecs.umich.edu name()); 15711168Sandreas.hansson@arm.com 15811168Sandreas.hansson@arm.com Addr remapped_addr = pkt->getAddr(); 1598864Snilay@cs.wisc.edu 1608922Swilliam.wang@arm.com // Restore the state and address 1618922Swilliam.wang@arm.com pkt->senderState = receivedState->origSenderState; 1628922Swilliam.wang@arm.com pkt->setAddr(receivedState->origAddr); 1638922Swilliam.wang@arm.com 1648922Swilliam.wang@arm.com // Attempt to send the packet 1658922Swilliam.wang@arm.com bool successful = slavePort.sendTimingResp(pkt); 1668922Swilliam.wang@arm.com 1678922Swilliam.wang@arm.com // If packet successfully sent, delete the sender state, otherwise 1688922Swilliam.wang@arm.com // restore state 1698922Swilliam.wang@arm.com if (successful) { 17011175Sandreas.hansson@arm.com delete receivedState; 1715124Sgblack@eecs.umich.edu } else { 1725086Sgblack@eecs.umich.edu // Don't delete anything and let the packet look like we did 1735086Sgblack@eecs.umich.edu // not touch it 1744120Sgblack@eecs.umich.edu 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].contains(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 // Simply return the original ranges as given by the parameters 269 AddrRangeList ranges(originalRanges.begin(), originalRanges.end()); 270 return ranges; 271} 272 273 274