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

Reply via email to