addr_mapper.cc revision 9542
19259SAli.Saidi@ARM.com/* 29259SAli.Saidi@ARM.com * Copyright (c) 2012 ARM Limited 39259SAli.Saidi@ARM.com * All rights reserved 49259SAli.Saidi@ARM.com * 59259SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall 69259SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual 79259SAli.Saidi@ARM.com * property including but not limited to intellectual property relating 89259SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software 99259SAli.Saidi@ARM.com * licensed hereunder. You may use the software subject to the license 109259SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated 119259SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software, 129259SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form. 139259SAli.Saidi@ARM.com * 149259SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 159259SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 169259SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 179259SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 189259SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 199259SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 209259SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 219259SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 229259SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 239259SAli.Saidi@ARM.com * this software without specific prior written permission. 249259SAli.Saidi@ARM.com * 259259SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 269259SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 279259SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 289259SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 299259SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 309259SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 319259SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 329259SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 339259SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 349259SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 359259SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 369259SAli.Saidi@ARM.com * 379259SAli.Saidi@ARM.com * Authors: Andreas Hansson 389259SAli.Saidi@ARM.com */ 399259SAli.Saidi@ARM.com 409259SAli.Saidi@ARM.com#include "mem/addr_mapper.hh" 419259SAli.Saidi@ARM.com 429259SAli.Saidi@ARM.comAddrMapper::AddrMapper(const AddrMapperParams* p) 439259SAli.Saidi@ARM.com : MemObject(p), 449259SAli.Saidi@ARM.com masterPort(name() + "-master", *this), 459259SAli.Saidi@ARM.com slavePort(name() + "-slave", *this) 469259SAli.Saidi@ARM.com{ 479259SAli.Saidi@ARM.com} 489259SAli.Saidi@ARM.com 499259SAli.Saidi@ARM.comvoid 509259SAli.Saidi@ARM.comAddrMapper::init() 519259SAli.Saidi@ARM.com{ 529259SAli.Saidi@ARM.com if (!slavePort.isConnected() || !masterPort.isConnected()) 539259SAli.Saidi@ARM.com fatal("Address mapper is not connected on both sides.\n"); 549259SAli.Saidi@ARM.com 559259SAli.Saidi@ARM.com if ((slavePort.peerBlockSize() != masterPort.peerBlockSize()) && 569259SAli.Saidi@ARM.com slavePort.peerBlockSize() && masterPort.peerBlockSize()) 579259SAli.Saidi@ARM.com fatal("Slave port size %d, master port size %d \n " 589259SAli.Saidi@ARM.com "don't have the same block size... Not supported.\n", 599259SAli.Saidi@ARM.com slavePort.peerBlockSize(), masterPort.peerBlockSize()); 609259SAli.Saidi@ARM.com} 619259SAli.Saidi@ARM.com 629294Sandreas.hansson@arm.comBaseMasterPort& 639294Sandreas.hansson@arm.comAddrMapper::getMasterPort(const std::string& if_name, PortID idx) 649259SAli.Saidi@ARM.com{ 659259SAli.Saidi@ARM.com if (if_name == "master") { 669259SAli.Saidi@ARM.com return masterPort; 679259SAli.Saidi@ARM.com } else { 689259SAli.Saidi@ARM.com return MemObject::getMasterPort(if_name, idx); 699259SAli.Saidi@ARM.com } 709259SAli.Saidi@ARM.com} 719259SAli.Saidi@ARM.com 729294Sandreas.hansson@arm.comBaseSlavePort& 739294Sandreas.hansson@arm.comAddrMapper::getSlavePort(const std::string& if_name, PortID idx) 749259SAli.Saidi@ARM.com{ 759259SAli.Saidi@ARM.com if (if_name == "slave") { 769259SAli.Saidi@ARM.com return slavePort; 779259SAli.Saidi@ARM.com } else { 789259SAli.Saidi@ARM.com return MemObject::getSlavePort(if_name, idx); 799259SAli.Saidi@ARM.com } 809259SAli.Saidi@ARM.com} 819259SAli.Saidi@ARM.com 829259SAli.Saidi@ARM.comvoid 839259SAli.Saidi@ARM.comAddrMapper::recvFunctional(PacketPtr pkt) 849259SAli.Saidi@ARM.com{ 859259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 869259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 879259SAli.Saidi@ARM.com masterPort.sendFunctional(pkt); 889259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 899259SAli.Saidi@ARM.com} 909259SAli.Saidi@ARM.com 919259SAli.Saidi@ARM.comvoid 929259SAli.Saidi@ARM.comAddrMapper::recvFunctionalSnoop(PacketPtr pkt) 939259SAli.Saidi@ARM.com{ 949259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 959259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 969259SAli.Saidi@ARM.com slavePort.sendFunctionalSnoop(pkt); 979259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 989259SAli.Saidi@ARM.com} 999259SAli.Saidi@ARM.com 1009259SAli.Saidi@ARM.comTick 1019259SAli.Saidi@ARM.comAddrMapper::recvAtomic(PacketPtr pkt) 1029259SAli.Saidi@ARM.com{ 1039259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 1049259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 1059259SAli.Saidi@ARM.com Tick ret_tick = masterPort.sendAtomic(pkt); 1069259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 1079259SAli.Saidi@ARM.com return ret_tick; 1089259SAli.Saidi@ARM.com} 1099259SAli.Saidi@ARM.com 1109259SAli.Saidi@ARM.comTick 1119259SAli.Saidi@ARM.comAddrMapper::recvAtomicSnoop(PacketPtr pkt) 1129259SAli.Saidi@ARM.com{ 1139259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 1149259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 1159259SAli.Saidi@ARM.com Tick ret_tick = slavePort.sendAtomicSnoop(pkt); 1169259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 1179259SAli.Saidi@ARM.com return ret_tick; 1189259SAli.Saidi@ARM.com} 1199259SAli.Saidi@ARM.com 1209259SAli.Saidi@ARM.combool 1219259SAli.Saidi@ARM.comAddrMapper::recvTimingReq(PacketPtr pkt) 1229259SAli.Saidi@ARM.com{ 1239259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 1249259SAli.Saidi@ARM.com bool needsResponse = pkt->needsResponse(); 1259259SAli.Saidi@ARM.com bool memInhibitAsserted = pkt->memInhibitAsserted(); 1269259SAli.Saidi@ARM.com 1279259SAli.Saidi@ARM.com if (needsResponse && !memInhibitAsserted) { 1289542Sandreas.hansson@arm.com pkt->pushSenderState(new AddrMapperSenderState(orig_addr)); 1299259SAli.Saidi@ARM.com } 1309259SAli.Saidi@ARM.com 1319259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 1329259SAli.Saidi@ARM.com 1339259SAli.Saidi@ARM.com // Attempt to send the packet (always succeeds for inhibited 1349259SAli.Saidi@ARM.com // packets) 1359259SAli.Saidi@ARM.com bool successful = masterPort.sendTimingReq(pkt); 1369259SAli.Saidi@ARM.com 1379259SAli.Saidi@ARM.com // If not successful, restore the sender state 1389259SAli.Saidi@ARM.com if (!successful && needsResponse) { 1399542Sandreas.hansson@arm.com delete pkt->popSenderState(); 1409259SAli.Saidi@ARM.com } 1419259SAli.Saidi@ARM.com 1429259SAli.Saidi@ARM.com return successful; 1439259SAli.Saidi@ARM.com} 1449259SAli.Saidi@ARM.com 1459259SAli.Saidi@ARM.combool 1469259SAli.Saidi@ARM.comAddrMapper::recvTimingResp(PacketPtr pkt) 1479259SAli.Saidi@ARM.com{ 1489259SAli.Saidi@ARM.com AddrMapperSenderState* receivedState = 1499259SAli.Saidi@ARM.com dynamic_cast<AddrMapperSenderState*>(pkt->senderState); 1509259SAli.Saidi@ARM.com 1519259SAli.Saidi@ARM.com // Restore initial sender state 1529259SAli.Saidi@ARM.com if (receivedState == NULL) 1539259SAli.Saidi@ARM.com panic("AddrMapper %s got a response without sender state\n", 1549259SAli.Saidi@ARM.com name()); 1559259SAli.Saidi@ARM.com 1569259SAli.Saidi@ARM.com Addr remapped_addr = pkt->getAddr(); 1579259SAli.Saidi@ARM.com 1589259SAli.Saidi@ARM.com // Restore the state and address 1599542Sandreas.hansson@arm.com pkt->senderState = receivedState->predecessor; 1609259SAli.Saidi@ARM.com pkt->setAddr(receivedState->origAddr); 1619259SAli.Saidi@ARM.com 1629259SAli.Saidi@ARM.com // Attempt to send the packet 1639259SAli.Saidi@ARM.com bool successful = slavePort.sendTimingResp(pkt); 1649259SAli.Saidi@ARM.com 1659259SAli.Saidi@ARM.com // If packet successfully sent, delete the sender state, otherwise 1669259SAli.Saidi@ARM.com // restore state 1679259SAli.Saidi@ARM.com if (successful) { 1689259SAli.Saidi@ARM.com delete receivedState; 1699259SAli.Saidi@ARM.com } else { 1709259SAli.Saidi@ARM.com // Don't delete anything and let the packet look like we did 1719259SAli.Saidi@ARM.com // not touch it 1729259SAli.Saidi@ARM.com pkt->senderState = receivedState; 1739259SAli.Saidi@ARM.com pkt->setAddr(remapped_addr); 1749259SAli.Saidi@ARM.com } 1759259SAli.Saidi@ARM.com return successful; 1769259SAli.Saidi@ARM.com} 1779259SAli.Saidi@ARM.com 1789259SAli.Saidi@ARM.comvoid 1799259SAli.Saidi@ARM.comAddrMapper::recvTimingSnoopReq(PacketPtr pkt) 1809259SAli.Saidi@ARM.com{ 1819259SAli.Saidi@ARM.com slavePort.sendTimingSnoopReq(pkt); 1829259SAli.Saidi@ARM.com} 1839259SAli.Saidi@ARM.com 1849259SAli.Saidi@ARM.combool 1859259SAli.Saidi@ARM.comAddrMapper::recvTimingSnoopResp(PacketPtr pkt) 1869259SAli.Saidi@ARM.com{ 1879259SAli.Saidi@ARM.com return masterPort.sendTimingSnoopResp(pkt); 1889259SAli.Saidi@ARM.com} 1899259SAli.Saidi@ARM.com 1909259SAli.Saidi@ARM.combool 1919259SAli.Saidi@ARM.comAddrMapper::isSnooping() const 1929259SAli.Saidi@ARM.com{ 1939294Sandreas.hansson@arm.com if (slavePort.isSnooping()) 1949259SAli.Saidi@ARM.com fatal("AddrMapper doesn't support remapping of snooping requests\n"); 1959259SAli.Saidi@ARM.com return false; 1969259SAli.Saidi@ARM.com} 1979259SAli.Saidi@ARM.com 1989259SAli.Saidi@ARM.comunsigned 1999259SAli.Saidi@ARM.comAddrMapper::deviceBlockSizeMaster() 2009259SAli.Saidi@ARM.com{ 2019259SAli.Saidi@ARM.com return slavePort.peerBlockSize(); 2029259SAli.Saidi@ARM.com} 2039259SAli.Saidi@ARM.com 2049259SAli.Saidi@ARM.comunsigned 2059259SAli.Saidi@ARM.comAddrMapper::deviceBlockSizeSlave() 2069259SAli.Saidi@ARM.com{ 2079259SAli.Saidi@ARM.com return masterPort.peerBlockSize(); 2089259SAli.Saidi@ARM.com} 2099259SAli.Saidi@ARM.com 2109259SAli.Saidi@ARM.comvoid 2119259SAli.Saidi@ARM.comAddrMapper::recvRetryMaster() 2129259SAli.Saidi@ARM.com{ 2139259SAli.Saidi@ARM.com slavePort.sendRetry(); 2149259SAli.Saidi@ARM.com} 2159259SAli.Saidi@ARM.com 2169259SAli.Saidi@ARM.comvoid 2179259SAli.Saidi@ARM.comAddrMapper::recvRetrySlave() 2189259SAli.Saidi@ARM.com{ 2199259SAli.Saidi@ARM.com masterPort.sendRetry(); 2209259SAli.Saidi@ARM.com} 2219259SAli.Saidi@ARM.com 2229259SAli.Saidi@ARM.comvoid 2239259SAli.Saidi@ARM.comAddrMapper::recvRangeChange() 2249259SAli.Saidi@ARM.com{ 2259259SAli.Saidi@ARM.com slavePort.sendRangeChange(); 2269259SAli.Saidi@ARM.com} 2279259SAli.Saidi@ARM.com 2289259SAli.Saidi@ARM.comRangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams* p) : 2299259SAli.Saidi@ARM.com AddrMapper(p), 2309259SAli.Saidi@ARM.com originalRanges(p->original_ranges), 2319259SAli.Saidi@ARM.com remappedRanges(p->remapped_ranges) 2329259SAli.Saidi@ARM.com{ 2339259SAli.Saidi@ARM.com if (originalRanges.size() != remappedRanges.size()) 2349259SAli.Saidi@ARM.com fatal("AddrMapper: original and shadowed range list must " 2359259SAli.Saidi@ARM.com "be same size\n"); 2369259SAli.Saidi@ARM.com 2379259SAli.Saidi@ARM.com for (size_t x = 0; x < originalRanges.size(); x++) { 2389259SAli.Saidi@ARM.com if (originalRanges[x].size() != remappedRanges[x].size()) 2399259SAli.Saidi@ARM.com fatal("AddrMapper: original and shadowed range list elements" 2409259SAli.Saidi@ARM.com " aren't all of the same size\n"); 2419259SAli.Saidi@ARM.com } 2429259SAli.Saidi@ARM.com} 2439259SAli.Saidi@ARM.com 2449259SAli.Saidi@ARM.comRangeAddrMapper* 2459259SAli.Saidi@ARM.comRangeAddrMapperParams::create() 2469259SAli.Saidi@ARM.com{ 2479259SAli.Saidi@ARM.com return new RangeAddrMapper(this); 2489259SAli.Saidi@ARM.com} 2499259SAli.Saidi@ARM.com 2509259SAli.Saidi@ARM.comAddr 2519259SAli.Saidi@ARM.comRangeAddrMapper::remapAddr(Addr addr) const 2529259SAli.Saidi@ARM.com{ 2539259SAli.Saidi@ARM.com for (int i = 0; i < originalRanges.size(); ++i) { 2549405Sandreas.hansson@arm.com if (originalRanges[i].contains(addr)) { 2559405Sandreas.hansson@arm.com Addr offset = addr - originalRanges[i].start(); 2569405Sandreas.hansson@arm.com return offset + remappedRanges[i].start(); 2579259SAli.Saidi@ARM.com } 2589259SAli.Saidi@ARM.com } 2599259SAli.Saidi@ARM.com 2609259SAli.Saidi@ARM.com return addr; 2619259SAli.Saidi@ARM.com} 2629259SAli.Saidi@ARM.com 2639259SAli.Saidi@ARM.comAddrRangeList 2649259SAli.Saidi@ARM.comRangeAddrMapper::getAddrRanges() const 2659259SAli.Saidi@ARM.com{ 2669406Sandreas.hansson@arm.com // Simply return the original ranges as given by the parameters 2679406Sandreas.hansson@arm.com AddrRangeList ranges(originalRanges.begin(), originalRanges.end()); 2689259SAli.Saidi@ARM.com return ranges; 2699259SAli.Saidi@ARM.com} 2709259SAli.Saidi@ARM.com 2719259SAli.Saidi@ARM.com 272