mem: Add a gasket that allows memory ranges to be re-mapped.
For example if DRAM is at two locations and mirrored this patch allows the mirroring to occur.
This commit is contained in:
parent
0c99d21ad7
commit
396600de10
5 changed files with 670 additions and 0 deletions
70
src/mem/AddrMapper.py
Normal file
70
src/mem/AddrMapper.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
# Copyright (c) 2012 ARM Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
# not be construed as granting a license to any other intellectual
|
||||
# property including but not limited to intellectual property relating
|
||||
# to a hardware implementation of the functionality of the software
|
||||
# licensed hereunder. You may use the software subject to the license
|
||||
# terms below provided that you ensure that this notice is replicated
|
||||
# unmodified and in its entirety in all distributions of the software,
|
||||
# modified or unmodified, in source code or in binary form.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met: redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer;
|
||||
# redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution;
|
||||
# neither the name of the copyright holders nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Andreas Hansson
|
||||
|
||||
from m5.params import *
|
||||
from MemObject import MemObject
|
||||
|
||||
# An address mapper changes the packet addresses in going from the
|
||||
# slave port side of the mapper to the master port side. When the
|
||||
# slave port is queried for the address ranges, it also performs the
|
||||
# necessary range updates. Note that snoop requests that travel from
|
||||
# the master port (i.e. the memory side) to the slave port are
|
||||
# currently not modified.
|
||||
class AddrMapper(MemObject):
|
||||
type = 'AddrMapper'
|
||||
abstract = True
|
||||
|
||||
# one port in each direction
|
||||
master = MasterPort("Master port")
|
||||
slave = SlavePort("Slave port")
|
||||
|
||||
|
||||
# Range address mapper that maps a set of original ranges to a set of
|
||||
# remapped ranges, where a specific range is of the same size
|
||||
# (original and remapped), only with an offset.
|
||||
class RangeAddrMapper(AddrMapper):
|
||||
type = 'RangeAddrMapper'
|
||||
|
||||
# These two vectors should be the exact same length and each range
|
||||
# should be the exact same size. Each range in original_ranges is
|
||||
# mapped to the corresponding element in the remapped_ranges. Note
|
||||
# that the same range can occur multiple times in the remapped
|
||||
# ranges for address aliasing.
|
||||
original_ranges = VectorParam.AddrRange(
|
||||
"Ranges of memory that should me remapped")
|
||||
remapped_ranges = VectorParam.AddrRange(
|
||||
"Ranges of memory that are being mapped to")
|
|
@ -30,11 +30,13 @@
|
|||
|
||||
Import('*')
|
||||
|
||||
SimObject('AddrMapper.py')
|
||||
SimObject('Bridge.py')
|
||||
SimObject('Bus.py')
|
||||
SimObject('CommMonitor.py')
|
||||
SimObject('MemObject.py')
|
||||
|
||||
Source('addr_mapper.cc')
|
||||
Source('bridge.cc')
|
||||
Source('bus.cc')
|
||||
Source('coherent_bus.cc')
|
||||
|
|
295
src/mem/addr_mapper.cc
Normal file
295
src/mem/addr_mapper.cc
Normal file
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
* Copyright (c) 2012 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Andreas Hansson
|
||||
*/
|
||||
|
||||
#include "mem/addr_mapper.hh"
|
||||
|
||||
AddrMapper::AddrMapper(const AddrMapperParams* p)
|
||||
: MemObject(p),
|
||||
masterPort(name() + "-master", *this),
|
||||
slavePort(name() + "-slave", *this)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AddrMapper::init()
|
||||
{
|
||||
if (!slavePort.isConnected() || !masterPort.isConnected())
|
||||
fatal("Address mapper is not connected on both sides.\n");
|
||||
|
||||
if ((slavePort.peerBlockSize() != masterPort.peerBlockSize()) &&
|
||||
slavePort.peerBlockSize() && masterPort.peerBlockSize())
|
||||
fatal("Slave port size %d, master port size %d \n "
|
||||
"don't have the same block size... Not supported.\n",
|
||||
slavePort.peerBlockSize(), masterPort.peerBlockSize());
|
||||
}
|
||||
|
||||
MasterPort&
|
||||
AddrMapper::getMasterPort(const std::string& if_name, int idx)
|
||||
{
|
||||
if (if_name == "master") {
|
||||
return masterPort;
|
||||
} else {
|
||||
return MemObject::getMasterPort(if_name, idx);
|
||||
}
|
||||
}
|
||||
|
||||
SlavePort&
|
||||
AddrMapper::getSlavePort(const std::string& if_name, int idx)
|
||||
{
|
||||
if (if_name == "slave") {
|
||||
return slavePort;
|
||||
} else {
|
||||
return MemObject::getSlavePort(if_name, idx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AddrMapper::recvFunctional(PacketPtr pkt)
|
||||
{
|
||||
Addr orig_addr = pkt->getAddr();
|
||||
pkt->setAddr(remapAddr(orig_addr));
|
||||
masterPort.sendFunctional(pkt);
|
||||
pkt->setAddr(orig_addr);
|
||||
}
|
||||
|
||||
void
|
||||
AddrMapper::recvFunctionalSnoop(PacketPtr pkt)
|
||||
{
|
||||
Addr orig_addr = pkt->getAddr();
|
||||
pkt->setAddr(remapAddr(orig_addr));
|
||||
slavePort.sendFunctionalSnoop(pkt);
|
||||
pkt->setAddr(orig_addr);
|
||||
}
|
||||
|
||||
Tick
|
||||
AddrMapper::recvAtomic(PacketPtr pkt)
|
||||
{
|
||||
Addr orig_addr = pkt->getAddr();
|
||||
pkt->setAddr(remapAddr(orig_addr));
|
||||
Tick ret_tick = masterPort.sendAtomic(pkt);
|
||||
pkt->setAddr(orig_addr);
|
||||
return ret_tick;
|
||||
}
|
||||
|
||||
Tick
|
||||
AddrMapper::recvAtomicSnoop(PacketPtr pkt)
|
||||
{
|
||||
Addr orig_addr = pkt->getAddr();
|
||||
pkt->setAddr(remapAddr(orig_addr));
|
||||
Tick ret_tick = slavePort.sendAtomicSnoop(pkt);
|
||||
pkt->setAddr(orig_addr);
|
||||
return ret_tick;
|
||||
}
|
||||
|
||||
bool
|
||||
AddrMapper::recvTimingReq(PacketPtr pkt)
|
||||
{
|
||||
Addr orig_addr = pkt->getAddr();
|
||||
bool needsResponse = pkt->needsResponse();
|
||||
bool memInhibitAsserted = pkt->memInhibitAsserted();
|
||||
Packet::SenderState* senderState = pkt->senderState;
|
||||
|
||||
if (needsResponse && !memInhibitAsserted) {
|
||||
pkt->senderState = new AddrMapperSenderState(senderState, orig_addr);
|
||||
}
|
||||
|
||||
pkt->setAddr(remapAddr(orig_addr));
|
||||
|
||||
// Attempt to send the packet (always succeeds for inhibited
|
||||
// packets)
|
||||
bool successful = masterPort.sendTimingReq(pkt);
|
||||
|
||||
// If not successful, restore the sender state
|
||||
if (!successful && needsResponse) {
|
||||
delete pkt->senderState;
|
||||
pkt->senderState = senderState;
|
||||
}
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
bool
|
||||
AddrMapper::recvTimingResp(PacketPtr pkt)
|
||||
{
|
||||
AddrMapperSenderState* receivedState =
|
||||
dynamic_cast<AddrMapperSenderState*>(pkt->senderState);
|
||||
|
||||
// Restore initial sender state
|
||||
if (receivedState == NULL)
|
||||
panic("AddrMapper %s got a response without sender state\n",
|
||||
name());
|
||||
|
||||
Addr remapped_addr = pkt->getAddr();
|
||||
|
||||
// Restore the state and address
|
||||
pkt->senderState = receivedState->origSenderState;
|
||||
pkt->setAddr(receivedState->origAddr);
|
||||
|
||||
// Attempt to send the packet
|
||||
bool successful = slavePort.sendTimingResp(pkt);
|
||||
|
||||
// If packet successfully sent, delete the sender state, otherwise
|
||||
// restore state
|
||||
if (successful) {
|
||||
delete receivedState;
|
||||
} else {
|
||||
// Don't delete anything and let the packet look like we did
|
||||
// not touch it
|
||||
pkt->senderState = receivedState;
|
||||
pkt->setAddr(remapped_addr);
|
||||
}
|
||||
return successful;
|
||||
}
|
||||
|
||||
void
|
||||
AddrMapper::recvTimingSnoopReq(PacketPtr pkt)
|
||||
{
|
||||
slavePort.sendTimingSnoopReq(pkt);
|
||||
}
|
||||
|
||||
bool
|
||||
AddrMapper::recvTimingSnoopResp(PacketPtr pkt)
|
||||
{
|
||||
return masterPort.sendTimingSnoopResp(pkt);
|
||||
}
|
||||
|
||||
bool
|
||||
AddrMapper::isSnooping() const
|
||||
{
|
||||
if (slavePort.getMasterPort().isSnooping())
|
||||
fatal("AddrMapper doesn't support remapping of snooping requests\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned
|
||||
AddrMapper::deviceBlockSizeMaster()
|
||||
{
|
||||
return slavePort.peerBlockSize();
|
||||
}
|
||||
|
||||
unsigned
|
||||
AddrMapper::deviceBlockSizeSlave()
|
||||
{
|
||||
return masterPort.peerBlockSize();
|
||||
}
|
||||
|
||||
void
|
||||
AddrMapper::recvRetryMaster()
|
||||
{
|
||||
slavePort.sendRetry();
|
||||
}
|
||||
|
||||
void
|
||||
AddrMapper::recvRetrySlave()
|
||||
{
|
||||
masterPort.sendRetry();
|
||||
}
|
||||
|
||||
void
|
||||
AddrMapper::recvRangeChange()
|
||||
{
|
||||
slavePort.sendRangeChange();
|
||||
}
|
||||
|
||||
RangeAddrMapper::RangeAddrMapper(const RangeAddrMapperParams* p) :
|
||||
AddrMapper(p),
|
||||
originalRanges(p->original_ranges),
|
||||
remappedRanges(p->remapped_ranges)
|
||||
{
|
||||
if (originalRanges.size() != remappedRanges.size())
|
||||
fatal("AddrMapper: original and shadowed range list must "
|
||||
"be same size\n");
|
||||
|
||||
for (size_t x = 0; x < originalRanges.size(); x++) {
|
||||
if (originalRanges[x].size() != remappedRanges[x].size())
|
||||
fatal("AddrMapper: original and shadowed range list elements"
|
||||
" aren't all of the same size\n");
|
||||
}
|
||||
}
|
||||
|
||||
RangeAddrMapper*
|
||||
RangeAddrMapperParams::create()
|
||||
{
|
||||
return new RangeAddrMapper(this);
|
||||
}
|
||||
|
||||
Addr
|
||||
RangeAddrMapper::remapAddr(Addr addr) const
|
||||
{
|
||||
for (int i = 0; i < originalRanges.size(); ++i) {
|
||||
if (originalRanges[i] == addr) {
|
||||
Addr offset = addr - originalRanges[i].start;
|
||||
return offset + remappedRanges[i].start;
|
||||
}
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
AddrRangeList
|
||||
RangeAddrMapper::getAddrRanges() const
|
||||
{
|
||||
AddrRangeList ranges;
|
||||
AddrRangeList actualRanges = masterPort.getSlavePort().getAddrRanges();
|
||||
|
||||
for (AddrRangeIter r = actualRanges.begin(); r != actualRanges.end(); ++r) {
|
||||
AddrRange range = *r;
|
||||
|
||||
for (int j = 0; j < originalRanges.size(); ++j) {
|
||||
if ((range.start < originalRanges[j].start &&
|
||||
range.end >= originalRanges[j].start) ||
|
||||
(range.start < originalRanges[j].end &&
|
||||
range.end >= originalRanges[j].end))
|
||||
fatal("Cannot remap range that intersects the original"
|
||||
" ranges but are not a subset.\n");
|
||||
if (range.start >= originalRanges[j].start &&
|
||||
range.end <= originalRanges[j].end) {
|
||||
// range is a subset
|
||||
Addr offset = range.start - originalRanges[j].start;
|
||||
range.start -= offset;
|
||||
range.end -= offset;
|
||||
}
|
||||
ranges.push_back(range);
|
||||
}
|
||||
}
|
||||
|
||||
return ranges;
|
||||
}
|
||||
|
||||
|
294
src/mem/addr_mapper.hh
Normal file
294
src/mem/addr_mapper.hh
Normal file
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
* Copyright (c) 2012 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Andreas Hansson
|
||||
*/
|
||||
|
||||
#ifndef __MEM_ADDR_MAPPER_HH__
|
||||
#define __MEM_ADDR_MAPPER_HH__
|
||||
|
||||
#include "mem/mem_object.hh"
|
||||
#include "params/AddrMapper.hh"
|
||||
#include "params/RangeAddrMapper.hh"
|
||||
|
||||
/**
|
||||
* An address mapper changes the packet addresses in going from the
|
||||
* slave port side of the mapper to the master port side. When the
|
||||
* slave port is queried for the address ranges, it also performs the
|
||||
* necessary range updates. Note that snoop requests that travel from
|
||||
* the master port (i.e. the memory side) to the slave port are
|
||||
* currently not modified.
|
||||
*/
|
||||
|
||||
class AddrMapper : public MemObject
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
AddrMapper(const AddrMapperParams* params);
|
||||
|
||||
virtual ~AddrMapper() { }
|
||||
|
||||
virtual MasterPort& getMasterPort(const std::string& if_name,
|
||||
int idx = -1);
|
||||
|
||||
virtual SlavePort& getSlavePort(const std::string& if_name,
|
||||
int idx = -1);
|
||||
|
||||
virtual void init();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* This function does the actual remapping of one address to another.
|
||||
* It is pure virtual in this case to to allow any implementation
|
||||
* required.
|
||||
* @param addr the address to remap
|
||||
* @return the new address (can be unchanged)
|
||||
*/
|
||||
virtual Addr remapAddr(Addr addr) const = 0;
|
||||
|
||||
class AddrMapperSenderState : public Packet::SenderState
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Construct a new sender state and remember the original one
|
||||
* so that we can implement a stack.
|
||||
*
|
||||
* @param _origSenderState Sender state to remember
|
||||
* @param _origAddr Address before remapping
|
||||
*/
|
||||
AddrMapperSenderState(SenderState* _origSenderState,
|
||||
Addr _origAddr)
|
||||
: origSenderState(_origSenderState), origAddr(_origAddr)
|
||||
{ }
|
||||
|
||||
/** Destructor */
|
||||
~AddrMapperSenderState() { }
|
||||
|
||||
/** Pointer to old sender state of packet */
|
||||
SenderState* origSenderState;
|
||||
|
||||
/** The original address the packet was destined for */
|
||||
Addr origAddr;
|
||||
|
||||
};
|
||||
|
||||
class MapperMasterPort : public MasterPort
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
MapperMasterPort(const std::string& _name, AddrMapper& _mapper)
|
||||
: MasterPort(_name, &_mapper), mapper(_mapper)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
void recvFunctionalSnoop(PacketPtr pkt)
|
||||
{
|
||||
mapper.recvFunctionalSnoop(pkt);
|
||||
}
|
||||
|
||||
Tick recvAtomicSnoop(PacketPtr pkt)
|
||||
{
|
||||
return mapper.recvAtomicSnoop(pkt);
|
||||
}
|
||||
|
||||
bool recvTimingResp(PacketPtr pkt)
|
||||
{
|
||||
return mapper.recvTimingResp(pkt);
|
||||
}
|
||||
|
||||
void recvTimingSnoopReq(PacketPtr pkt)
|
||||
{
|
||||
mapper.recvTimingSnoopReq(pkt);
|
||||
}
|
||||
|
||||
void recvRangeChange()
|
||||
{
|
||||
mapper.recvRangeChange();
|
||||
}
|
||||
|
||||
bool isSnooping() const
|
||||
{
|
||||
return mapper.isSnooping();
|
||||
}
|
||||
|
||||
unsigned deviceBlockSize() const
|
||||
{
|
||||
return mapper.deviceBlockSizeMaster();
|
||||
}
|
||||
|
||||
void recvRetry()
|
||||
{
|
||||
mapper.recvRetryMaster();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
AddrMapper& mapper;
|
||||
|
||||
};
|
||||
|
||||
/** Instance of master port, facing the memory side */
|
||||
MapperMasterPort masterPort;
|
||||
|
||||
class MapperSlavePort : public SlavePort
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
MapperSlavePort(const std::string& _name, AddrMapper& _mapper)
|
||||
: SlavePort(_name, &_mapper), mapper(_mapper)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
void recvFunctional(PacketPtr pkt)
|
||||
{
|
||||
mapper.recvFunctional(pkt);
|
||||
}
|
||||
|
||||
Tick recvAtomic(PacketPtr pkt)
|
||||
{
|
||||
return mapper.recvAtomic(pkt);
|
||||
}
|
||||
|
||||
bool recvTimingReq(PacketPtr pkt)
|
||||
{
|
||||
return mapper.recvTimingReq(pkt);
|
||||
}
|
||||
|
||||
bool recvTimingSnoopResp(PacketPtr pkt)
|
||||
{
|
||||
return mapper.recvTimingSnoopResp(pkt);
|
||||
}
|
||||
|
||||
unsigned deviceBlockSize() const
|
||||
{
|
||||
return mapper.deviceBlockSizeSlave();
|
||||
}
|
||||
|
||||
AddrRangeList getAddrRanges() const
|
||||
{
|
||||
return mapper.getAddrRanges();
|
||||
}
|
||||
|
||||
void recvRetry()
|
||||
{
|
||||
mapper.recvRetrySlave();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
AddrMapper& mapper;
|
||||
|
||||
};
|
||||
|
||||
/** Instance of slave port, i.e. on the CPU side */
|
||||
MapperSlavePort slavePort;
|
||||
|
||||
void recvFunctional(PacketPtr pkt);
|
||||
|
||||
void recvFunctionalSnoop(PacketPtr pkt);
|
||||
|
||||
Tick recvAtomic(PacketPtr pkt);
|
||||
|
||||
Tick recvAtomicSnoop(PacketPtr pkt);
|
||||
|
||||
bool recvTimingReq(PacketPtr pkt);
|
||||
|
||||
bool recvTimingResp(PacketPtr pkt);
|
||||
|
||||
void recvTimingSnoopReq(PacketPtr pkt);
|
||||
|
||||
bool recvTimingSnoopResp(PacketPtr pkt);
|
||||
|
||||
unsigned deviceBlockSizeMaster();
|
||||
|
||||
unsigned deviceBlockSizeSlave();
|
||||
|
||||
virtual AddrRangeList getAddrRanges() const = 0;
|
||||
|
||||
bool isSnooping() const;
|
||||
|
||||
void recvRetryMaster();
|
||||
|
||||
void recvRetrySlave();
|
||||
|
||||
void recvRangeChange();
|
||||
};
|
||||
|
||||
/**
|
||||
* Range address mapper that maps a set of original ranges to a set of
|
||||
* remapped ranges, where a specific range is of the same size
|
||||
* (original and remapped), only with an offset. It's useful for cases
|
||||
* where memory is mapped to two different locations
|
||||
*/
|
||||
class RangeAddrMapper : public AddrMapper
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
RangeAddrMapper(const RangeAddrMapperParams* p);
|
||||
|
||||
~RangeAddrMapper() { }
|
||||
|
||||
AddrRangeList getAddrRanges() const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* This contains a list of ranges the should be remapped. It must
|
||||
* be the exact same length as remappedRanges which describes what
|
||||
* manipulation should be done to each range.
|
||||
*/
|
||||
std::vector<AddrRange> originalRanges;
|
||||
|
||||
/**
|
||||
* This contains a list of ranges that addresses should be
|
||||
* remapped to. See the description for originalRanges above
|
||||
*/
|
||||
std::vector<AddrRange> remappedRanges;
|
||||
|
||||
Addr remapAddr(Addr addr) const;
|
||||
|
||||
};
|
||||
|
||||
#endif //__MEM_ADDR_MAPPER_HH__
|
|
@ -491,6 +491,15 @@ class Packet : public Printable
|
|||
void clearDest() { dest = InvalidPortID; }
|
||||
|
||||
Addr getAddr() const { assert(flags.isSet(VALID_ADDR)); return addr; }
|
||||
/**
|
||||
* Update the address of this packet mid-transaction. This is used
|
||||
* by the address mapper to change an already set address to a new
|
||||
* one based on the system configuration. It is intended to remap
|
||||
* an existing address, so it asserts that the current address is
|
||||
* valid.
|
||||
*/
|
||||
void setAddr(Addr _addr) { assert(flags.isSet(VALID_ADDR)); addr = _addr; }
|
||||
|
||||
unsigned getSize() const { assert(flags.isSet(VALID_SIZE)); return size; }
|
||||
Addr getOffset(int blkSize) const { return getAddr() & (Addr)(blkSize - 1); }
|
||||
|
||||
|
|
Loading…
Reference in a new issue