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) 4313892Sgabeblack@google.com : SimObject(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 5613784Sgabeblack@google.comPort & 5713784Sgabeblack@google.comAddrMapper::getPort(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; 6113784Sgabeblack@google.com } else if (if_name == "slave") { 629259SAli.Saidi@ARM.com return slavePort; 639259SAli.Saidi@ARM.com } else { 6413892Sgabeblack@google.com return SimObject::getPort(if_name, idx); 659259SAli.Saidi@ARM.com } 669259SAli.Saidi@ARM.com} 679259SAli.Saidi@ARM.com 689259SAli.Saidi@ARM.comvoid 699259SAli.Saidi@ARM.comAddrMapper::recvFunctional(PacketPtr pkt) 709259SAli.Saidi@ARM.com{ 719259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 729259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 739259SAli.Saidi@ARM.com masterPort.sendFunctional(pkt); 749259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 759259SAli.Saidi@ARM.com} 769259SAli.Saidi@ARM.com 779259SAli.Saidi@ARM.comvoid 789259SAli.Saidi@ARM.comAddrMapper::recvFunctionalSnoop(PacketPtr pkt) 799259SAli.Saidi@ARM.com{ 809259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 819259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 829259SAli.Saidi@ARM.com slavePort.sendFunctionalSnoop(pkt); 839259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 849259SAli.Saidi@ARM.com} 859259SAli.Saidi@ARM.com 869259SAli.Saidi@ARM.comTick 879259SAli.Saidi@ARM.comAddrMapper::recvAtomic(PacketPtr pkt) 889259SAli.Saidi@ARM.com{ 899259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 909259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 919259SAli.Saidi@ARM.com Tick ret_tick = masterPort.sendAtomic(pkt); 929259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 939259SAli.Saidi@ARM.com return ret_tick; 949259SAli.Saidi@ARM.com} 959259SAli.Saidi@ARM.com 969259SAli.Saidi@ARM.comTick 979259SAli.Saidi@ARM.comAddrMapper::recvAtomicSnoop(PacketPtr pkt) 989259SAli.Saidi@ARM.com{ 999259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 1009259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 1019259SAli.Saidi@ARM.com Tick ret_tick = slavePort.sendAtomicSnoop(pkt); 1029259SAli.Saidi@ARM.com pkt->setAddr(orig_addr); 1039259SAli.Saidi@ARM.com return ret_tick; 1049259SAli.Saidi@ARM.com} 1059259SAli.Saidi@ARM.com 1069259SAli.Saidi@ARM.combool 1079259SAli.Saidi@ARM.comAddrMapper::recvTimingReq(PacketPtr pkt) 1089259SAli.Saidi@ARM.com{ 1099259SAli.Saidi@ARM.com Addr orig_addr = pkt->getAddr(); 1109259SAli.Saidi@ARM.com bool needsResponse = pkt->needsResponse(); 11111284Sandreas.hansson@arm.com bool cacheResponding = pkt->cacheResponding(); 1129259SAli.Saidi@ARM.com 11311284Sandreas.hansson@arm.com if (needsResponse && !cacheResponding) { 1149542Sandreas.hansson@arm.com pkt->pushSenderState(new AddrMapperSenderState(orig_addr)); 1159259SAli.Saidi@ARM.com } 1169259SAli.Saidi@ARM.com 1179259SAli.Saidi@ARM.com pkt->setAddr(remapAddr(orig_addr)); 1189259SAli.Saidi@ARM.com 11911284Sandreas.hansson@arm.com // Attempt to send the packet 1209259SAli.Saidi@ARM.com bool successful = masterPort.sendTimingReq(pkt); 1219259SAli.Saidi@ARM.com 12210862Spfistchr@student.ethz.ch // If not successful, restore the address and sender state 12310862Spfistchr@student.ethz.ch if (!successful) { 12410862Spfistchr@student.ethz.ch pkt->setAddr(orig_addr); 12510862Spfistchr@student.ethz.ch 12610862Spfistchr@student.ethz.ch if (needsResponse) { 12710862Spfistchr@student.ethz.ch delete pkt->popSenderState(); 12810862Spfistchr@student.ethz.ch } 1299259SAli.Saidi@ARM.com } 1309259SAli.Saidi@ARM.com 1319259SAli.Saidi@ARM.com return successful; 1329259SAli.Saidi@ARM.com} 1339259SAli.Saidi@ARM.com 1349259SAli.Saidi@ARM.combool 1359259SAli.Saidi@ARM.comAddrMapper::recvTimingResp(PacketPtr pkt) 1369259SAli.Saidi@ARM.com{ 1379259SAli.Saidi@ARM.com AddrMapperSenderState* receivedState = 1389259SAli.Saidi@ARM.com dynamic_cast<AddrMapperSenderState*>(pkt->senderState); 1399259SAli.Saidi@ARM.com 1409259SAli.Saidi@ARM.com // Restore initial sender state 1419259SAli.Saidi@ARM.com if (receivedState == NULL) 1429259SAli.Saidi@ARM.com panic("AddrMapper %s got a response without sender state\n", 1439259SAli.Saidi@ARM.com name()); 1449259SAli.Saidi@ARM.com 1459259SAli.Saidi@ARM.com Addr remapped_addr = pkt->getAddr(); 1469259SAli.Saidi@ARM.com 1479259SAli.Saidi@ARM.com // Restore the state and address 1489542Sandreas.hansson@arm.com pkt->senderState = receivedState->predecessor; 1499259SAli.Saidi@ARM.com pkt->setAddr(receivedState->origAddr); 1509259SAli.Saidi@ARM.com 1519259SAli.Saidi@ARM.com // Attempt to send the packet 1529259SAli.Saidi@ARM.com bool successful = slavePort.sendTimingResp(pkt); 1539259SAli.Saidi@ARM.com 1549259SAli.Saidi@ARM.com // If packet successfully sent, delete the sender state, otherwise 1559259SAli.Saidi@ARM.com // restore state 1569259SAli.Saidi@ARM.com if (successful) { 1579259SAli.Saidi@ARM.com delete receivedState; 1589259SAli.Saidi@ARM.com } else { 1599259SAli.Saidi@ARM.com // Don't delete anything and let the packet look like we did 1609259SAli.Saidi@ARM.com // not touch it 1619259SAli.Saidi@ARM.com pkt->senderState = receivedState; 1629259SAli.Saidi@ARM.com pkt->setAddr(remapped_addr); 1639259SAli.Saidi@ARM.com } 1649259SAli.Saidi@ARM.com return successful; 1659259SAli.Saidi@ARM.com} 1669259SAli.Saidi@ARM.com 1679259SAli.Saidi@ARM.comvoid 1689259SAli.Saidi@ARM.comAddrMapper::recvTimingSnoopReq(PacketPtr pkt) 1699259SAli.Saidi@ARM.com{ 1709259SAli.Saidi@ARM.com slavePort.sendTimingSnoopReq(pkt); 1719259SAli.Saidi@ARM.com} 1729259SAli.Saidi@ARM.com 1739259SAli.Saidi@ARM.combool 1749259SAli.Saidi@ARM.comAddrMapper::recvTimingSnoopResp(PacketPtr pkt) 1759259SAli.Saidi@ARM.com{ 1769259SAli.Saidi@ARM.com return masterPort.sendTimingSnoopResp(pkt); 1779259SAli.Saidi@ARM.com} 1789259SAli.Saidi@ARM.com 1799259SAli.Saidi@ARM.combool 1809259SAli.Saidi@ARM.comAddrMapper::isSnooping() const 1819259SAli.Saidi@ARM.com{ 1829294Sandreas.hansson@arm.com if (slavePort.isSnooping()) 1839259SAli.Saidi@ARM.com fatal("AddrMapper doesn't support remapping of snooping requests\n"); 1849259SAli.Saidi@ARM.com return false; 1859259SAli.Saidi@ARM.com} 1869259SAli.Saidi@ARM.com 1879259SAli.Saidi@ARM.comvoid 18810713Sandreas.hansson@arm.comAddrMapper::recvReqRetry() 1899259SAli.Saidi@ARM.com{ 19010713Sandreas.hansson@arm.com slavePort.sendRetryReq(); 1919259SAli.Saidi@ARM.com} 1929259SAli.Saidi@ARM.com 1939259SAli.Saidi@ARM.comvoid 19410713Sandreas.hansson@arm.comAddrMapper::recvRespRetry() 1959259SAli.Saidi@ARM.com{ 19610713Sandreas.hansson@arm.com masterPort.sendRetryResp(); 1979259SAli.Saidi@ARM.com} 1989259SAli.Saidi@ARM.com 1999259SAli.Saidi@ARM.comvoid 2009259SAli.Saidi@ARM.comAddrMapper::recvRangeChange() 2019259SAli.Saidi@ARM.com{ 2029259SAli.Saidi@ARM.com slavePort.sendRangeChange(); 2039259SAli.Saidi@ARM.com} 2049259SAli.Saidi@ARM.com 2059259SAli.Saidi@ARM.comRangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams* p) : 2069259SAli.Saidi@ARM.com AddrMapper(p), 2079259SAli.Saidi@ARM.com originalRanges(p->original_ranges), 2089259SAli.Saidi@ARM.com remappedRanges(p->remapped_ranges) 2099259SAli.Saidi@ARM.com{ 2109259SAli.Saidi@ARM.com if (originalRanges.size() != remappedRanges.size()) 2119259SAli.Saidi@ARM.com fatal("AddrMapper: original and shadowed range list must " 2129259SAli.Saidi@ARM.com "be same size\n"); 2139259SAli.Saidi@ARM.com 2149259SAli.Saidi@ARM.com for (size_t x = 0; x < originalRanges.size(); x++) { 2159259SAli.Saidi@ARM.com if (originalRanges[x].size() != remappedRanges[x].size()) 2169259SAli.Saidi@ARM.com fatal("AddrMapper: original and shadowed range list elements" 2179259SAli.Saidi@ARM.com " aren't all of the same size\n"); 2189259SAli.Saidi@ARM.com } 2199259SAli.Saidi@ARM.com} 2209259SAli.Saidi@ARM.com 2219259SAli.Saidi@ARM.comRangeAddrMapper* 2229259SAli.Saidi@ARM.comRangeAddrMapperParams::create() 2239259SAli.Saidi@ARM.com{ 2249259SAli.Saidi@ARM.com return new RangeAddrMapper(this); 2259259SAli.Saidi@ARM.com} 2269259SAli.Saidi@ARM.com 2279259SAli.Saidi@ARM.comAddr 2289259SAli.Saidi@ARM.comRangeAddrMapper::remapAddr(Addr addr) const 2299259SAli.Saidi@ARM.com{ 2309259SAli.Saidi@ARM.com for (int i = 0; i < originalRanges.size(); ++i) { 2319405Sandreas.hansson@arm.com if (originalRanges[i].contains(addr)) { 2329405Sandreas.hansson@arm.com Addr offset = addr - originalRanges[i].start(); 2339405Sandreas.hansson@arm.com return offset + remappedRanges[i].start(); 2349259SAli.Saidi@ARM.com } 2359259SAli.Saidi@ARM.com } 2369259SAli.Saidi@ARM.com 2379259SAli.Saidi@ARM.com return addr; 2389259SAli.Saidi@ARM.com} 2399259SAli.Saidi@ARM.com 2409259SAli.Saidi@ARM.comAddrRangeList 2419259SAli.Saidi@ARM.comRangeAddrMapper::getAddrRanges() const 2429259SAli.Saidi@ARM.com{ 2439406Sandreas.hansson@arm.com // Simply return the original ranges as given by the parameters 2449406Sandreas.hansson@arm.com AddrRangeList ranges(originalRanges.begin(), originalRanges.end()); 2459259SAli.Saidi@ARM.com return ranges; 2469259SAli.Saidi@ARM.com} 2479259SAli.Saidi@ARM.com 2489259SAli.Saidi@ARM.com 249