changeset fc28f3ca5b21 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=fc28f3ca5b21
description:
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.
diffstat:
src/mem/AddrMapper.py | 70 +++++++++++
src/mem/SConscript | 2 +
src/mem/addr_mapper.cc | 295 +++++++++++++++++++++++++++++++++++++++++++++++++
src/mem/addr_mapper.hh | 294 ++++++++++++++++++++++++++++++++++++++++++++++++
src/mem/packet.hh | 9 +
5 files changed, 670 insertions(+), 0 deletions(-)
diffs (truncated from 707 to 300 lines):
diff -r baa17ba80e06 -r fc28f3ca5b21 src/mem/AddrMapper.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/AddrMapper.py Tue Sep 25 11:49:40 2012 -0500
@@ -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")
diff -r baa17ba80e06 -r fc28f3ca5b21 src/mem/SConscript
--- a/src/mem/SConscript Tue Sep 25 11:49:40 2012 -0500
+++ b/src/mem/SConscript Tue Sep 25 11:49:40 2012 -0500
@@ -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')
diff -r baa17ba80e06 -r fc28f3ca5b21 src/mem/addr_mapper.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/addr_mapper.cc Tue Sep 25 11:49:40 2012 -0500
@@ -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();
+}
+
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev