addr_mapper.hh revision 9542
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/mem_object.hh" 44#include "params/AddrMapper.hh" 45#include "params/RangeAddrMapper.hh" 46 47/** 48 * An address mapper changes the packet addresses in going from the 49 * slave port side of the mapper to the master port side. When the 50 * slave port is queried for the address ranges, it also performs the 51 * necessary range updates. Note that snoop requests that travel from 52 * the master port (i.e. the memory side) to the slave port are 53 * currently not modified. 54 */ 55 56class AddrMapper : public MemObject 57{ 58 59 public: 60 61 AddrMapper(const AddrMapperParams* params); 62 63 virtual ~AddrMapper() { } 64 65 virtual BaseMasterPort& getMasterPort(const std::string& if_name, 66 PortID idx = InvalidPortID); 67 68 virtual BaseSlavePort& getSlavePort(const std::string& if_name, 69 PortID idx = InvalidPortID); 70 71 virtual void init(); 72 73 protected: 74 75 /** 76 * This function does the actual remapping of one address to another. 77 * It is pure virtual in this case to to allow any implementation 78 * required. 79 * @param addr the address to remap 80 * @return the new address (can be unchanged) 81 */ 82 virtual Addr remapAddr(Addr addr) const = 0; 83 84 class AddrMapperSenderState : public Packet::SenderState 85 { 86 87 public: 88 89 /** 90 * Construct a new sender state to remember the original address. 91 * 92 * @param _origAddr Address before remapping 93 */ 94 AddrMapperSenderState(Addr _origAddr) : origAddr(_origAddr) 95 { } 96 97 /** Destructor */ 98 ~AddrMapperSenderState() { } 99 100 /** The original address the packet was destined for */ 101 Addr origAddr; 102 103 }; 104 105 class MapperMasterPort : public MasterPort 106 { 107 108 public: 109 110 MapperMasterPort(const std::string& _name, AddrMapper& _mapper) 111 : MasterPort(_name, &_mapper), mapper(_mapper) 112 { } 113 114 protected: 115 116 void recvFunctionalSnoop(PacketPtr pkt) 117 { 118 mapper.recvFunctionalSnoop(pkt); 119 } 120 121 Tick recvAtomicSnoop(PacketPtr pkt) 122 { 123 return mapper.recvAtomicSnoop(pkt); 124 } 125 126 bool recvTimingResp(PacketPtr pkt) 127 { 128 return mapper.recvTimingResp(pkt); 129 } 130 131 void recvTimingSnoopReq(PacketPtr pkt) 132 { 133 mapper.recvTimingSnoopReq(pkt); 134 } 135 136 void recvRangeChange() 137 { 138 mapper.recvRangeChange(); 139 } 140 141 bool isSnooping() const 142 { 143 return mapper.isSnooping(); 144 } 145 146 unsigned deviceBlockSize() const 147 { 148 return mapper.deviceBlockSizeMaster(); 149 } 150 151 void recvRetry() 152 { 153 mapper.recvRetryMaster(); 154 } 155 156 private: 157 158 AddrMapper& mapper; 159 160 }; 161 162 /** Instance of master port, facing the memory side */ 163 MapperMasterPort masterPort; 164 165 class MapperSlavePort : public SlavePort 166 { 167 168 public: 169 170 MapperSlavePort(const std::string& _name, AddrMapper& _mapper) 171 : SlavePort(_name, &_mapper), mapper(_mapper) 172 { } 173 174 protected: 175 176 void recvFunctional(PacketPtr pkt) 177 { 178 mapper.recvFunctional(pkt); 179 } 180 181 Tick recvAtomic(PacketPtr pkt) 182 { 183 return mapper.recvAtomic(pkt); 184 } 185 186 bool recvTimingReq(PacketPtr pkt) 187 { 188 return mapper.recvTimingReq(pkt); 189 } 190 191 bool recvTimingSnoopResp(PacketPtr pkt) 192 { 193 return mapper.recvTimingSnoopResp(pkt); 194 } 195 196 unsigned deviceBlockSize() const 197 { 198 return mapper.deviceBlockSizeSlave(); 199 } 200 201 AddrRangeList getAddrRanges() const 202 { 203 return mapper.getAddrRanges(); 204 } 205 206 void recvRetry() 207 { 208 mapper.recvRetrySlave(); 209 } 210 211 private: 212 213 AddrMapper& mapper; 214 215 }; 216 217 /** Instance of slave port, i.e. on the CPU side */ 218 MapperSlavePort slavePort; 219 220 void recvFunctional(PacketPtr pkt); 221 222 void recvFunctionalSnoop(PacketPtr pkt); 223 224 Tick recvAtomic(PacketPtr pkt); 225 226 Tick recvAtomicSnoop(PacketPtr pkt); 227 228 bool recvTimingReq(PacketPtr pkt); 229 230 bool recvTimingResp(PacketPtr pkt); 231 232 void recvTimingSnoopReq(PacketPtr pkt); 233 234 bool recvTimingSnoopResp(PacketPtr pkt); 235 236 unsigned deviceBlockSizeMaster(); 237 238 unsigned deviceBlockSizeSlave(); 239 240 virtual AddrRangeList getAddrRanges() const = 0; 241 242 bool isSnooping() const; 243 244 void recvRetryMaster(); 245 246 void recvRetrySlave(); 247 248 void recvRangeChange(); 249}; 250 251/** 252 * Range address mapper that maps a set of original ranges to a set of 253 * remapped ranges, where a specific range is of the same size 254 * (original and remapped), only with an offset. It's useful for cases 255 * where memory is mapped to two different locations 256 */ 257class RangeAddrMapper : public AddrMapper 258{ 259 260 public: 261 262 RangeAddrMapper(const RangeAddrMapperParams* p); 263 264 ~RangeAddrMapper() { } 265 266 AddrRangeList getAddrRanges() const; 267 268 protected: 269 270 /** 271 * This contains a list of ranges the should be remapped. It must 272 * be the exact same length as remappedRanges which describes what 273 * manipulation should be done to each range. 274 */ 275 std::vector<AddrRange> originalRanges; 276 277 /** 278 * This contains a list of ranges that addresses should be 279 * remapped to. See the description for originalRanges above 280 */ 281 std::vector<AddrRange> remappedRanges; 282 283 Addr remapAddr(Addr addr) const; 284 285}; 286 287#endif //__MEM_ADDR_MAPPER_HH__ 288