addr_mapper.cc revision 11284
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 569294Sandreas.hansson@arm.comBaseMasterPort& 579294Sandreas.hansson@arm.comAddrMapper::getMasterPort(const std::string& if_name, PortID idx) 589259SAli.Saidi@ARM.com{ 599259SAli.Saidi@ARM.com if (if_name == "master") { 609259SAli.Saidi@ARM.com return masterPort; 619259SAli.Saidi@ARM.com } else { 629259SAli.Saidi@ARM.com return MemObject::getMasterPort(if_name, idx); 639259SAli.Saidi@ARM.com } 649259SAli.Saidi@ARM.com} 659259SAli.Saidi@ARM.com 669294Sandreas.hansson@arm.comBaseSlavePort& 679294Sandreas.hansson@arm.comAddrMapper::getSlavePort(const std::string& if_name, PortID idx) 689259SAli.Saidi@ARM.com{ 699259SAli.Saidi@ARM.com if (if_name == "slave") { 709259SAli.Saidi@ARM.com return slavePort; 719259SAli.Saidi@ARM.com } else { 729259SAli.Saidi@ARM.com return MemObject::getSlavePort(if_name, idx); 739259SAli.Saidi@ARM.com } 749259SAli.Saidi@ARM.com} 759259SAli.Saidi@ARM.com 769259SAli.Saidi@ARM.comvoid 779259SAli.Saidi@ARM.comAddrMapper::recvFunctional(PacketPtr pkt) 789259SAli.Saidi@ARM.com{ 799259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 809259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 819259SAli.Saidi@ARM.com masterPort.sendFunctional(pkt); 829259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 839259SAli.Saidi@ARM.com} 849259SAli.Saidi@ARM.com 859259SAli.Saidi@ARM.comvoid 869259SAli.Saidi@ARM.comAddrMapper::recvFunctionalSnoop(PacketPtr pkt) 879259SAli.Saidi@ARM.com{ 889259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 899259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 909259SAli.Saidi@ARM.com slavePort.sendFunctionalSnoop(pkt); 919259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 929259SAli.Saidi@ARM.com} 939259SAli.Saidi@ARM.com 949259SAli.Saidi@ARM.comTick 959259SAli.Saidi@ARM.comAddrMapper::recvAtomic(PacketPtr pkt) 969259SAli.Saidi@ARM.com{ 979259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 989259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 999259SAli.Saidi@ARM.com Tick ret_tick = masterPort.sendAtomic(pkt); 1009259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 1019259SAli.Saidi@ARM.com return ret_tick; 1029259SAli.Saidi@ARM.com} 1039259SAli.Saidi@ARM.com 1049259SAli.Saidi@ARM.comTick 1059259SAli.Saidi@ARM.comAddrMapper::recvAtomicSnoop(PacketPtr pkt) 1069259SAli.Saidi@ARM.com{ 1079259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 1089259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 1099259SAli.Saidi@ARM.com Tick ret_tick = slavePort.sendAtomicSnoop(pkt); 1109259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 1119259SAli.Saidi@ARM.com return ret_tick; 1129259SAli.Saidi@ARM.com} 1139259SAli.Saidi@ARM.com 1149259SAli.Saidi@ARM.combool 1159259SAli.Saidi@ARM.comAddrMapper::recvTimingReq(PacketPtr pkt) 1169259SAli.Saidi@ARM.com{ 1179259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 1189259SAli.Saidi@ARM.com bool needsResponse = pkt->needsResponse(); 11911284Sandreas.hansson@arm.com bool cacheResponding = pkt->cacheResponding(); 1209259SAli.Saidi@ARM.com 12111284Sandreas.hansson@arm.com if (needsResponse && !cacheResponding) { 1229542Sandreas.hansson@arm.com pkt->pushSenderState(new AddrMapperSenderState(orig_addr)); 1239259SAli.Saidi@ARM.com } 1249259SAli.Saidi@ARM.com 1259259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 1269259SAli.Saidi@ARM.com 12711284Sandreas.hansson@arm.com // Attempt to send the packet 1289259SAli.Saidi@ARM.com bool successful = masterPort.sendTimingReq(pkt); 1299259SAli.Saidi@ARM.com 13010862Spfistchr@student.ethz.ch // If not successful, restore the address and sender state 13110862Spfistchr@student.ethz.ch if (!successful) { 13210862Spfistchr@student.ethz.ch pkt->setAddr(orig_addr); 13310862Spfistchr@student.ethz.ch 13410862Spfistchr@student.ethz.ch if (needsResponse) { 13510862Spfistchr@student.ethz.ch delete pkt->popSenderState(); 13610862Spfistchr@student.ethz.ch } 1379259SAli.Saidi@ARM.com } 1389259SAli.Saidi@ARM.com 1399259SAli.Saidi@ARM.com return successful; 1409259SAli.Saidi@ARM.com} 1419259SAli.Saidi@ARM.com 1429259SAli.Saidi@ARM.combool 1439259SAli.Saidi@ARM.comAddrMapper::recvTimingResp(PacketPtr pkt) 1449259SAli.Saidi@ARM.com{ 1459259SAli.Saidi@ARM.com AddrMapperSenderState* receivedState = 1469259SAli.Saidi@ARM.com dynamic_cast<AddrMapperSenderState*>(pkt->senderState); 1479259SAli.Saidi@ARM.com 1489259SAli.Saidi@ARM.com // Restore initial sender state 1499259SAli.Saidi@ARM.com if (receivedState == NULL) 1509259SAli.Saidi@ARM.com panic("AddrMapper %s got a response without sender state\n", 1519259SAli.Saidi@ARM.com name()); 1529259SAli.Saidi@ARM.com 1539259SAli.Saidi@ARM.com Addr remapped_addr = pkt->getAddr(); 1549259SAli.Saidi@ARM.com 1559259SAli.Saidi@ARM.com // Restore the state and address 1569542Sandreas.hansson@arm.com pkt->senderState = receivedState->predecessor; 1579259SAli.Saidi@ARM.com pkt->setAddr(receivedState->origAddr); 1589259SAli.Saidi@ARM.com 1599259SAli.Saidi@ARM.com // Attempt to send the packet 1609259SAli.Saidi@ARM.com bool successful = slavePort.sendTimingResp(pkt); 1619259SAli.Saidi@ARM.com 1629259SAli.Saidi@ARM.com // If packet successfully sent, delete the sender state, otherwise 1639259SAli.Saidi@ARM.com // restore state 1649259SAli.Saidi@ARM.com if (successful) { 1659259SAli.Saidi@ARM.com delete receivedState; 1669259SAli.Saidi@ARM.com } else { 1679259SAli.Saidi@ARM.com // Don't delete anything and let the packet look like we did 1689259SAli.Saidi@ARM.com // not touch it 1699259SAli.Saidi@ARM.com pkt->senderState = receivedState; 1709259SAli.Saidi@ARM.com pkt->setAddr(remapped_addr); 1719259SAli.Saidi@ARM.com } 1729259SAli.Saidi@ARM.com return successful; 1739259SAli.Saidi@ARM.com} 1749259SAli.Saidi@ARM.com 1759259SAli.Saidi@ARM.comvoid 1769259SAli.Saidi@ARM.comAddrMapper::recvTimingSnoopReq(PacketPtr pkt) 1779259SAli.Saidi@ARM.com{ 1789259SAli.Saidi@ARM.com slavePort.sendTimingSnoopReq(pkt); 1799259SAli.Saidi@ARM.com} 1809259SAli.Saidi@ARM.com 1819259SAli.Saidi@ARM.combool 1829259SAli.Saidi@ARM.comAddrMapper::recvTimingSnoopResp(PacketPtr pkt) 1839259SAli.Saidi@ARM.com{ 1849259SAli.Saidi@ARM.com return masterPort.sendTimingSnoopResp(pkt); 1859259SAli.Saidi@ARM.com} 1869259SAli.Saidi@ARM.com 1879259SAli.Saidi@ARM.combool 1889259SAli.Saidi@ARM.comAddrMapper::isSnooping() const 1899259SAli.Saidi@ARM.com{ 1909294Sandreas.hansson@arm.com if (slavePort.isSnooping()) 1919259SAli.Saidi@ARM.com fatal("AddrMapper doesn't support remapping of snooping requests\n"); 1929259SAli.Saidi@ARM.com return false; 1939259SAli.Saidi@ARM.com} 1949259SAli.Saidi@ARM.com 1959259SAli.Saidi@ARM.comvoid 19610713Sandreas.hansson@arm.comAddrMapper::recvReqRetry() 1979259SAli.Saidi@ARM.com{ 19810713Sandreas.hansson@arm.com slavePort.sendRetryReq(); 1999259SAli.Saidi@ARM.com} 2009259SAli.Saidi@ARM.com 2019259SAli.Saidi@ARM.comvoid 20210713Sandreas.hansson@arm.comAddrMapper::recvRespRetry() 2039259SAli.Saidi@ARM.com{ 20410713Sandreas.hansson@arm.com masterPort.sendRetryResp(); 2059259SAli.Saidi@ARM.com} 2069259SAli.Saidi@ARM.com 2079259SAli.Saidi@ARM.comvoid 2089259SAli.Saidi@ARM.comAddrMapper::recvRangeChange() 2099259SAli.Saidi@ARM.com{ 2109259SAli.Saidi@ARM.com slavePort.sendRangeChange(); 2119259SAli.Saidi@ARM.com} 2129259SAli.Saidi@ARM.com 2139259SAli.Saidi@ARM.comRangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams* p) : 2149259SAli.Saidi@ARM.com AddrMapper(p), 2159259SAli.Saidi@ARM.com originalRanges(p->original_ranges), 2169259SAli.Saidi@ARM.com remappedRanges(p->remapped_ranges) 2179259SAli.Saidi@ARM.com{ 2189259SAli.Saidi@ARM.com if (originalRanges.size() != remappedRanges.size()) 2199259SAli.Saidi@ARM.com fatal("AddrMapper: original and shadowed range list must " 2209259SAli.Saidi@ARM.com "be same size\n"); 2219259SAli.Saidi@ARM.com 2229259SAli.Saidi@ARM.com for (size_t x = 0; x < originalRanges.size(); x++) { 2239259SAli.Saidi@ARM.com if (originalRanges[x].size() != remappedRanges[x].size()) 2249259SAli.Saidi@ARM.com fatal("AddrMapper: original and shadowed range list elements" 2259259SAli.Saidi@ARM.com " aren't all of the same size\n"); 2269259SAli.Saidi@ARM.com } 2279259SAli.Saidi@ARM.com} 2289259SAli.Saidi@ARM.com 2299259SAli.Saidi@ARM.comRangeAddrMapper* 2309259SAli.Saidi@ARM.comRangeAddrMapperParams::create() 2319259SAli.Saidi@ARM.com{ 2329259SAli.Saidi@ARM.com return new RangeAddrMapper(this); 2339259SAli.Saidi@ARM.com} 2349259SAli.Saidi@ARM.com 2359259SAli.Saidi@ARM.comAddr 2369259SAli.Saidi@ARM.comRangeAddrMapper::remapAddr(Addr addr) const 2379259SAli.Saidi@ARM.com{ 2389259SAli.Saidi@ARM.com for (int i = 0; i < originalRanges.size(); ++i) { 2399405Sandreas.hansson@arm.com if (originalRanges[i].contains(addr)) { 2409405Sandreas.hansson@arm.com Addr offset = addr - originalRanges[i].start(); 2419405Sandreas.hansson@arm.com return offset + remappedRanges[i].start(); 2429259SAli.Saidi@ARM.com } 2439259SAli.Saidi@ARM.com } 2449259SAli.Saidi@ARM.com 2459259SAli.Saidi@ARM.com return addr; 2469259SAli.Saidi@ARM.com} 2479259SAli.Saidi@ARM.com 2489259SAli.Saidi@ARM.comAddrRangeList 2499259SAli.Saidi@ARM.comRangeAddrMapper::getAddrRanges() const 2509259SAli.Saidi@ARM.com{ 2519406Sandreas.hansson@arm.com // Simply return the original ranges as given by the parameters 2529406Sandreas.hansson@arm.com AddrRangeList ranges(originalRanges.begin(), originalRanges.end()); 2539259SAli.Saidi@ARM.com return ranges; 2549259SAli.Saidi@ARM.com} 2559259SAli.Saidi@ARM.com 2569259SAli.Saidi@ARM.com 257