1/* 2 * Copyright (c) 2012 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Andreas Hansson 38 */ 39 40#ifndef __MEM_ADDR_MAPPER_HH__ 41#define __MEM_ADDR_MAPPER_HH__ 42 43#include "mem/port.hh" 44#include "params/AddrMapper.hh" 45#include "params/RangeAddrMapper.hh" 46#include "sim/sim_object.hh" 47 48/** 49 * An address mapper changes the packet addresses in going from the 50 * slave port side of the mapper to the master port side. When the 51 * slave port is queried for the address ranges, it also performs the 52 * necessary range updates. Note that snoop requests that travel from 53 * the master port (i.e. the memory side) to the slave port are 54 * currently not modified. 55 */ 56 57class AddrMapper : public SimObject 58{ 59 60 public: 61 62 AddrMapper(const AddrMapperParams* params); 63 64 virtual ~AddrMapper() { } 65 66 Port &getPort(const std::string &if_name, 67 PortID idx=InvalidPortID) override; 68 69 void init() override; 70 71 protected: 72 73 /** 74 * This function does the actual remapping of one address to another. 75 * It is pure virtual in this case to to allow any implementation 76 * required. 77 * @param addr the address to remap 78 * @return the new address (can be unchanged) 79 */ 80 virtual Addr remapAddr(Addr addr) const = 0; 81 82 class AddrMapperSenderState : public Packet::SenderState 83 { 84 85 public: 86 87 /** 88 * Construct a new sender state to remember the original address. 89 * 90 * @param _origAddr Address before remapping 91 */ 92 AddrMapperSenderState(Addr _origAddr) : origAddr(_origAddr) 93 { } 94 95 /** Destructor */ 96 ~AddrMapperSenderState() { } 97 98 /** The original address the packet was destined for */ 99 Addr origAddr; 100 101 }; 102 103 class MapperMasterPort : public MasterPort 104 { 105 106 public: 107 108 MapperMasterPort(const std::string& _name, AddrMapper& _mapper) 109 : MasterPort(_name, &_mapper), mapper(_mapper) 110 { } 111 112 protected: 113 114 void recvFunctionalSnoop(PacketPtr pkt) 115 { 116 mapper.recvFunctionalSnoop(pkt); 117 } 118 119 Tick recvAtomicSnoop(PacketPtr pkt) 120 { 121 return mapper.recvAtomicSnoop(pkt); 122 } 123 124 bool recvTimingResp(PacketPtr pkt) 125 { 126 return mapper.recvTimingResp(pkt); 127 } 128 129 void recvTimingSnoopReq(PacketPtr pkt) 130 { 131 mapper.recvTimingSnoopReq(pkt); 132 } 133 134 void recvRangeChange() 135 { 136 mapper.recvRangeChange(); 137 } 138 139 bool isSnooping() const 140 { 141 return mapper.isSnooping(); 142 } 143 144 void recvReqRetry() 145 { 146 mapper.recvReqRetry(); 147 } 148 149 private: 150 151 AddrMapper& mapper; 152 153 }; 154 155 /** Instance of master port, facing the memory side */ 156 MapperMasterPort masterPort; 157 158 class MapperSlavePort : public SlavePort 159 { 160 161 public: 162 163 MapperSlavePort(const std::string& _name, AddrMapper& _mapper) 164 : SlavePort(_name, &_mapper), mapper(_mapper) 165 { } 166 167 protected: 168 169 void recvFunctional(PacketPtr pkt) 170 { 171 mapper.recvFunctional(pkt); 172 } 173 174 Tick recvAtomic(PacketPtr pkt) 175 { 176 return mapper.recvAtomic(pkt); 177 } 178 179 bool recvTimingReq(PacketPtr pkt) 180 { 181 return mapper.recvTimingReq(pkt); 182 } 183 184 bool recvTimingSnoopResp(PacketPtr pkt) 185 { 186 return mapper.recvTimingSnoopResp(pkt); 187 } 188 189 AddrRangeList getAddrRanges() const 190 { 191 return mapper.getAddrRanges(); 192 } 193 194 void recvRespRetry() 195 { 196 mapper.recvRespRetry(); 197 } 198 199 private: 200 201 AddrMapper& mapper; 202 203 }; 204 205 /** Instance of slave port, i.e. on the CPU side */ 206 MapperSlavePort slavePort; 207 208 void recvFunctional(PacketPtr pkt); 209 210 void recvFunctionalSnoop(PacketPtr pkt); 211 212 Tick recvAtomic(PacketPtr pkt); 213 214 Tick recvAtomicSnoop(PacketPtr pkt); 215 216 bool recvTimingReq(PacketPtr pkt); 217 218 bool recvTimingResp(PacketPtr pkt); 219 220 void recvTimingSnoopReq(PacketPtr pkt); 221 222 bool recvTimingSnoopResp(PacketPtr pkt); 223 224 virtual AddrRangeList getAddrRanges() const = 0; 225 226 bool isSnooping() const; 227 228 void recvReqRetry(); 229 230 void recvRespRetry(); 231 232 void recvRangeChange(); 233}; 234 235/** 236 * Range address mapper that maps a set of original ranges to a set of 237 * remapped ranges, where a specific range is of the same size 238 * (original and remapped), only with an offset. It's useful for cases 239 * where memory is mapped to two different locations 240 */ 241class RangeAddrMapper : public AddrMapper 242{ 243 244 public: 245 246 RangeAddrMapper(const RangeAddrMapperParams* p); 247 248 ~RangeAddrMapper() { } 249 250 AddrRangeList getAddrRanges() const; 251 252 protected: 253 254 /** 255 * This contains a list of ranges the should be remapped. It must 256 * be the exact same length as remappedRanges which describes what 257 * manipulation should be done to each range. 258 */ 259 std::vector<AddrRange> originalRanges; 260 261 /** 262 * This contains a list of ranges that addresses should be 263 * remapped to. See the description for originalRanges above 264 */ 265 std::vector<AddrRange> remappedRanges; 266 267 Addr remapAddr(Addr addr) const; 268 269}; 270 271#endif //__MEM_ADDR_MAPPER_HH__ 272