addr_mapper.cc revision 9279
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 629259SAli.Saidi@ARM.comMasterPort& 639259SAli.Saidi@ARM.comAddrMapper::getMasterPort(const std::string& if_name, int 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 729259SAli.Saidi@ARM.comSlavePort& 739259SAli.Saidi@ARM.comAddrMapper::getSlavePort(const std::string& if_name, int 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 Packet::SenderState* senderState = pkt->senderState; 1279259SAli.Saidi@ARM.com 1289259SAli.Saidi@ARM.com if (needsResponse && !memInhibitAsserted) { 1299259SAli.Saidi@ARM.com pkt->senderState = new AddrMapperSenderState(senderState, orig_addr); 1309259SAli.Saidi@ARM.com } 1319259SAli.Saidi@ARM.com 1329259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 1339259SAli.Saidi@ARM.com 1349259SAli.Saidi@ARM.com // Attempt to send the packet (always succeeds for inhibited 1359259SAli.Saidi@ARM.com // packets) 1369259SAli.Saidi@ARM.com bool successful = masterPort.sendTimingReq(pkt); 1379259SAli.Saidi@ARM.com 1389259SAli.Saidi@ARM.com // If not successful, restore the sender state 1399259SAli.Saidi@ARM.com if (!successful && needsResponse) { 1409259SAli.Saidi@ARM.com delete pkt->senderState; 1419259SAli.Saidi@ARM.com pkt->senderState = senderState; 1429259SAli.Saidi@ARM.com } 1439259SAli.Saidi@ARM.com 1449259SAli.Saidi@ARM.com return successful; 1459259SAli.Saidi@ARM.com} 1469259SAli.Saidi@ARM.com 1479259SAli.Saidi@ARM.combool 1489259SAli.Saidi@ARM.comAddrMapper::recvTimingResp(PacketPtr pkt) 1499259SAli.Saidi@ARM.com{ 1509259SAli.Saidi@ARM.com AddrMapperSenderState* receivedState = 1519259SAli.Saidi@ARM.com dynamic_cast<AddrMapperSenderState*>(pkt->senderState); 1529259SAli.Saidi@ARM.com 1539259SAli.Saidi@ARM.com // Restore initial sender state 1549259SAli.Saidi@ARM.com if (receivedState == NULL) 1559259SAli.Saidi@ARM.com panic("AddrMapper %s got a response without sender state\n", 1569259SAli.Saidi@ARM.com name()); 1579259SAli.Saidi@ARM.com 1589259SAli.Saidi@ARM.com Addr remapped_addr = pkt->getAddr(); 1599259SAli.Saidi@ARM.com 1609259SAli.Saidi@ARM.com // Restore the state and address 1619259SAli.Saidi@ARM.com pkt->senderState = receivedState->origSenderState; 1629259SAli.Saidi@ARM.com pkt->setAddr(receivedState->origAddr); 1639259SAli.Saidi@ARM.com 1649259SAli.Saidi@ARM.com // Attempt to send the packet 1659259SAli.Saidi@ARM.com bool successful = slavePort.sendTimingResp(pkt); 1669259SAli.Saidi@ARM.com 1679259SAli.Saidi@ARM.com // If packet successfully sent, delete the sender state, otherwise 1689259SAli.Saidi@ARM.com // restore state 1699259SAli.Saidi@ARM.com if (successful) { 1709259SAli.Saidi@ARM.com delete receivedState; 1719259SAli.Saidi@ARM.com } else { 1729259SAli.Saidi@ARM.com // Don't delete anything and let the packet look like we did 1739259SAli.Saidi@ARM.com // not touch it 1749259SAli.Saidi@ARM.com pkt->senderState = receivedState; 1759259SAli.Saidi@ARM.com pkt->setAddr(remapped_addr); 1769259SAli.Saidi@ARM.com } 1779259SAli.Saidi@ARM.com return successful; 1789259SAli.Saidi@ARM.com} 1799259SAli.Saidi@ARM.com 1809259SAli.Saidi@ARM.comvoid 1819259SAli.Saidi@ARM.comAddrMapper::recvTimingSnoopReq(PacketPtr pkt) 1829259SAli.Saidi@ARM.com{ 1839259SAli.Saidi@ARM.com slavePort.sendTimingSnoopReq(pkt); 1849259SAli.Saidi@ARM.com} 1859259SAli.Saidi@ARM.com 1869259SAli.Saidi@ARM.combool 1879259SAli.Saidi@ARM.comAddrMapper::recvTimingSnoopResp(PacketPtr pkt) 1889259SAli.Saidi@ARM.com{ 1899259SAli.Saidi@ARM.com return masterPort.sendTimingSnoopResp(pkt); 1909259SAli.Saidi@ARM.com} 1919259SAli.Saidi@ARM.com 1929259SAli.Saidi@ARM.combool 1939259SAli.Saidi@ARM.comAddrMapper::isSnooping() const 1949259SAli.Saidi@ARM.com{ 1959259SAli.Saidi@ARM.com if (slavePort.getMasterPort().isSnooping()) 1969259SAli.Saidi@ARM.com fatal("AddrMapper doesn't support remapping of snooping requests\n"); 1979259SAli.Saidi@ARM.com return false; 1989259SAli.Saidi@ARM.com} 1999259SAli.Saidi@ARM.com 2009259SAli.Saidi@ARM.comunsigned 2019259SAli.Saidi@ARM.comAddrMapper::deviceBlockSizeMaster() 2029259SAli.Saidi@ARM.com{ 2039259SAli.Saidi@ARM.com return slavePort.peerBlockSize(); 2049259SAli.Saidi@ARM.com} 2059259SAli.Saidi@ARM.com 2069259SAli.Saidi@ARM.comunsigned 2079259SAli.Saidi@ARM.comAddrMapper::deviceBlockSizeSlave() 2089259SAli.Saidi@ARM.com{ 2099259SAli.Saidi@ARM.com return masterPort.peerBlockSize(); 2109259SAli.Saidi@ARM.com} 2119259SAli.Saidi@ARM.com 2129259SAli.Saidi@ARM.comvoid 2139259SAli.Saidi@ARM.comAddrMapper::recvRetryMaster() 2149259SAli.Saidi@ARM.com{ 2159259SAli.Saidi@ARM.com slavePort.sendRetry(); 2169259SAli.Saidi@ARM.com} 2179259SAli.Saidi@ARM.com 2189259SAli.Saidi@ARM.comvoid 2199259SAli.Saidi@ARM.comAddrMapper::recvRetrySlave() 2209259SAli.Saidi@ARM.com{ 2219259SAli.Saidi@ARM.com masterPort.sendRetry(); 2229259SAli.Saidi@ARM.com} 2239259SAli.Saidi@ARM.com 2249259SAli.Saidi@ARM.comvoid 2259259SAli.Saidi@ARM.comAddrMapper::recvRangeChange() 2269259SAli.Saidi@ARM.com{ 2279259SAli.Saidi@ARM.com slavePort.sendRangeChange(); 2289259SAli.Saidi@ARM.com} 2299259SAli.Saidi@ARM.com 2309259SAli.Saidi@ARM.comRangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams* p) : 2319259SAli.Saidi@ARM.com AddrMapper(p), 2329259SAli.Saidi@ARM.com originalRanges(p->original_ranges), 2339259SAli.Saidi@ARM.com remappedRanges(p->remapped_ranges) 2349259SAli.Saidi@ARM.com{ 2359259SAli.Saidi@ARM.com if (originalRanges.size() != remappedRanges.size()) 2369259SAli.Saidi@ARM.com fatal("AddrMapper: original and shadowed range list must " 2379259SAli.Saidi@ARM.com "be same size\n"); 2389259SAli.Saidi@ARM.com 2399259SAli.Saidi@ARM.com for (size_t x = 0; x < originalRanges.size(); x++) { 2409259SAli.Saidi@ARM.com if (originalRanges[x].size() != remappedRanges[x].size()) 2419259SAli.Saidi@ARM.com fatal("AddrMapper: original and shadowed range list elements" 2429259SAli.Saidi@ARM.com " aren't all of the same size\n"); 2439259SAli.Saidi@ARM.com } 2449259SAli.Saidi@ARM.com} 2459259SAli.Saidi@ARM.com 2469259SAli.Saidi@ARM.comRangeAddrMapper* 2479259SAli.Saidi@ARM.comRangeAddrMapperParams::create() 2489259SAli.Saidi@ARM.com{ 2499259SAli.Saidi@ARM.com return new RangeAddrMapper(this); 2509259SAli.Saidi@ARM.com} 2519259SAli.Saidi@ARM.com 2529259SAli.Saidi@ARM.comAddr 2539259SAli.Saidi@ARM.comRangeAddrMapper::remapAddr(Addr addr) const 2549259SAli.Saidi@ARM.com{ 2559259SAli.Saidi@ARM.com for (int i = 0; i < originalRanges.size(); ++i) { 2569259SAli.Saidi@ARM.com if (originalRanges[i] == addr) { 2579259SAli.Saidi@ARM.com Addr offset = addr - originalRanges[i].start; 2589259SAli.Saidi@ARM.com return offset + remappedRanges[i].start; 2599259SAli.Saidi@ARM.com } 2609259SAli.Saidi@ARM.com } 2619259SAli.Saidi@ARM.com 2629259SAli.Saidi@ARM.com return addr; 2639259SAli.Saidi@ARM.com} 2649259SAli.Saidi@ARM.com 2659259SAli.Saidi@ARM.comAddrRangeList 2669259SAli.Saidi@ARM.comRangeAddrMapper::getAddrRanges() const 2679259SAli.Saidi@ARM.com{ 2689259SAli.Saidi@ARM.com AddrRangeList ranges; 2699259SAli.Saidi@ARM.com AddrRangeList actualRanges = masterPort.getSlavePort().getAddrRanges(); 2709259SAli.Saidi@ARM.com 2719259SAli.Saidi@ARM.com for (AddrRangeIter r = actualRanges.begin(); r != actualRanges.end(); ++r) { 2729259SAli.Saidi@ARM.com AddrRange range = *r; 2739259SAli.Saidi@ARM.com 2749259SAli.Saidi@ARM.com for (int j = 0; j < originalRanges.size(); ++j) { 2759279Sandreas.hansson@arm.com if (range.intersects(originalRanges[j])) 2769259SAli.Saidi@ARM.com fatal("Cannot remap range that intersects the original" 2779259SAli.Saidi@ARM.com " ranges but are not a subset.\n"); 2789279Sandreas.hansson@arm.com if (range.isSubset(originalRanges[j])) { 2799259SAli.Saidi@ARM.com // range is a subset 2809259SAli.Saidi@ARM.com Addr offset = range.start - originalRanges[j].start; 2819259SAli.Saidi@ARM.com range.start -= offset; 2829259SAli.Saidi@ARM.com range.end -= offset; 2839259SAli.Saidi@ARM.com } 2849259SAli.Saidi@ARM.com ranges.push_back(range); 2859259SAli.Saidi@ARM.com } 2869259SAli.Saidi@ARM.com } 2879259SAli.Saidi@ARM.com 2889259SAli.Saidi@ARM.com return ranges; 2899259SAli.Saidi@ARM.com} 2909259SAli.Saidi@ARM.com 2919259SAli.Saidi@ARM.com 292