diff -r aeec9e157d06 -r 5e058187a133 configs/ruby/MESI_CMP_directory.py --- a/configs/ruby/MESI_CMP_directory.py Fri Apr 01 15:50:23 2011 -0700 +++ b/configs/ruby/MESI_CMP_directory.py Mon Apr 04 08:22:35 2011 -0500 @@ -47,7 +47,7 @@ def define_options(parser): return -def create_system(options, system, piobus, dma_devices): +def create_system(options, system, piobus, dma_devices, ruby_system): if buildEnv['PROTOCOL'] != 'MESI_CMP_directory': panic("This script requires the MESI_CMP_directory protocol to be built.") @@ -77,16 +77,19 @@ # l1i_cache = L1Cache(size = options.l1i_size, assoc = options.l1i_assoc, - start_index_bit = block_size_bits) + start_index_bit = block_size_bits, + ruby_system = ruby_system) l1d_cache = L1Cache(size = options.l1d_size, assoc = options.l1d_assoc, - start_index_bit = block_size_bits) + start_index_bit = block_size_bits, + ruby_system = ruby_system) cpu_seq = RubySequencer(version = i, icache = l1i_cache, dcache = l1d_cache, physMemPort = system.physmem.port, - physmem = system.physmem) + physmem = system.physmem, + ruby_system = ruby_system) if piobus != None: cpu_seq.pio_port = piobus.port @@ -113,7 +116,8 @@ # l2_cache = L2Cache(size = options.l2_size, assoc = options.l2_assoc, - start_index_bit = l2_index_start) + start_index_bit = l2_index_start, + ruby_system = ruby_system) l2_cntrl = L2Cache_Controller(version = i, L2cacheMemory = l2_cache) @@ -139,7 +143,9 @@ directory = \ RubyDirectoryMemory(version = i, size = \ - dir_size), + dir_size, + ruby_system = \ + ruby_system), memBuffer = mem_cntrl) exec("system.dir_cntrl%d = dir_cntrl" % i) diff -r aeec9e157d06 -r 5e058187a133 configs/ruby/Ruby.py --- a/configs/ruby/Ruby.py Fri Apr 01 15:50:23 2011 -0700 +++ b/configs/ruby/Ruby.py Mon Apr 04 08:22:35 2011 -0500 @@ -62,11 +62,13 @@ def create_system(options, system, piobus = None, dma_devices = []): + ruby = RubySystem(clock = options.clock) + protocol = buildEnv['PROTOCOL'] exec "import %s" % protocol try: (cpu_sequencers, dir_cntrls, all_cntrls) = \ - eval("%s.create_system(options, system, piobus, dma_devices)" \ + eval("%s.create_system(options, system, piobus, dma_devices, ruby)" \ % protocol) except: print "Error: could not create sytem for ruby protocol %s" % protocol @@ -85,11 +87,11 @@ raise if options.garnet_network == "fixed": - network = GarnetNetwork_d(topology = net_topology) + network = GarnetNetwork_d(ruby_system = ruby, topology = net_topology) elif options.garnet_network == "flexible": - network = GarnetNetwork(topology = net_topology) + network = GarnetNetwork(ruby_system = ruby, topology = net_topology) else: - network = SimpleNetwork(topology = net_topology) + network = SimpleNetwork(ruby_system = ruby, topology = net_topology) # # Loop through the directory controlers. @@ -121,14 +123,14 @@ long(system.physmem.range.first) + 1 assert(total_mem_size.value == physmem_size) - ruby_profiler = RubyProfiler(num_of_sequencers = len(cpu_sequencers)) - - ruby = RubySystem(clock = options.clock, - network = network, - profiler = ruby_profiler, - tracer = RubyTracer(), - mem_size = total_mem_size) + ruby_profiler = RubyProfiler(ruby_system = ruby, + num_of_sequencers = len(cpu_sequencers)) + ruby_tracer = RubyTracer(ruby_system = ruby) + exec("ruby.network = network") + exec("ruby.profiler = ruby_profiler") + exec("ruby.tracer = ruby_tracer") + ruby.mem_size = total_mem_size ruby.cpu_ruby_ports = cpu_sequencers ruby.random_seed = options.random_seed diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/network/Network.cc --- a/src/mem/ruby/network/Network.cc Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/network/Network.cc Mon Apr 04 08:22:35 2011 -0500 @@ -52,6 +52,7 @@ // Initialize the controller's network pointers m_topology_ptr->initNetworkPtr(this); + p->ruby_system->registerNetwork(this); } void diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/network/Network.py --- a/src/mem/ruby/network/Network.py Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/network/Network.py Mon Apr 04 08:22:35 2011 -0500 @@ -71,3 +71,4 @@ link_latency = Param.Int(1, "local memory latency ?? NetworkLinkLatency"); control_msg_size = Param.Int(8, ""); + ruby_system = Param.RubySystem(""); diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/profiler/Profiler.cc --- a/src/mem/ruby/profiler/Profiler.cc Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/profiler/Profiler.cc Mon Apr 04 08:22:35 2011 -0500 @@ -93,6 +93,8 @@ m_inst_profiler_ptr->setHotLines(m_hot_lines); m_inst_profiler_ptr->setAllInstructions(m_all_instructions); } + + p->ruby_system->registerProfiler(this); } Profiler::~Profiler() diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/profiler/Profiler.py --- a/src/mem/ruby/profiler/Profiler.py Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/profiler/Profiler.py Mon Apr 04 08:22:35 2011 -0500 @@ -36,3 +36,4 @@ hot_lines = Param.Bool(False, "") all_instructions = Param.Bool(False, "") num_of_sequencers = Param.Int("") + ruby_system = Param.RubySystem("") diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/recorder/Tracer.cc --- a/src/mem/ruby/recorder/Tracer.cc Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/recorder/Tracer.cc Mon Apr 04 08:22:35 2011 -0500 @@ -40,7 +40,7 @@ m_enabled = false; m_warmup_length = p->warmup_length; assert(m_warmup_length > 0); - RubySystem::m_tracer_ptr = this; + p->ruby_system->registerTracer(this); } void diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/recorder/Tracer.py --- a/src/mem/ruby/recorder/Tracer.py Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/recorder/Tracer.py Mon Apr 04 08:22:35 2011 -0500 @@ -34,3 +34,4 @@ type = 'RubyTracer' cxx_class = 'Tracer' warmup_length = Param.Int(100000, "") + ruby_system = Param.RubySystem("") diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/AbstractMemory.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/system/AbstractMemory.hh Mon Apr 04 08:22:35 2011 -0500 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Mark D. Hill and David A. Wood + * All rights reserved. + * + * 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. + */ + +#ifndef __MEM_RUBY_SYSTEM_ABSTRACTMEMORY_HH__ +#define __MEM_RUBY_SYSTEM_ABSTRACTMEMORY_HH__ + +#include "mem/protocol/AccessPermission.hh" +#include "mem/ruby/system/System.hh" +#include "params/RubyAbstractMemory.hh" +#include "sim/sim_object.hh" + +class AbstractMemory : public SimObject +{ + public: + typedef RubyAbstractMemoryParams Params; + AbstractMemory(const Params *p); + virtual AccessPermission getAccessPermissions(const Address& address); + virtual void makeFunctionalAccess(const Address& address, + RubyRequestType type, + char* value, + unsigned int size_in_bytes); +}; + +#endif // __MEM_RUBY_SYSTEM_ABSTRACTMEMORY_HH__ + diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/AbstractMemory.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/system/AbstractMemory.cc Mon Apr 04 08:22:35 2011 -0500 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Mark D. Hill and David A. Wood + * All rights reserved. + * + * 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. + */ + +#include "mem/ruby/system/AbstractMemory.hh" + +using namespace std; + +AbstractMemory * +RubyAbstractMemoryParams::create() +{ + return new AbstractMemory(this); +} + +AbstractMemory::AbstractMemory(const Params *p) + : SimObject(p) +{ + p->ruby_system->registerAbstractMemory(this); +} + +AccessPermission +AbstractMemory::getAccessPermissions(const Address& address) +{ + return AccessPermission_NotPresent; +} + +void +AbstractMemory::makeFunctionalAccess(const Address& address, + RubyRequestType type, + char* value, + unsigned int size_in_bytes) +{ + panic("Functional read not implemented.\n"); +} diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/AbstractMemory.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/system/AbstractMemory.py Mon Apr 04 08:22:35 2011 -0500 @@ -0,0 +1,57 @@ +# Copyright (c) 2009 Advanced Micro Devices, Inc. +# All rights reserved. +# +# 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: Steve Reinhardt +# Brad Beckmann + +from m5.params import * +from m5.proxy import * +from m5.SimObject import SimObject + +class RubyAbstractMemory(SimObject): + type = 'RubyAbstractMemory' + cxx_class = 'AbstractMemory' + ruby_system = Param.RubySystem(""); + +class RubyCache(RubyAbstractMemory): + type = 'RubyCache' + cxx_class = 'CacheMemory' + size = Param.MemorySize("capacity in bytes"); + latency = Param.Int(""); + assoc = Param.Int(""); + replacement_policy = Param.String("PSEUDO_LRU", ""); + start_index_bit = Param.Int(6, "index start, default 6 for 64-byte line"); + +class RubyDirectoryMemory(RubyAbstractMemory): + type = 'RubyDirectoryMemory' + cxx_class = 'DirectoryMemory' + version = Param.Int(0, "") + size = Param.MemorySize("1GB", "capacity in bytes") + use_map = Param.Bool(False, "enable sparse memory") + map_levels = Param.Int(4, "sparse memory map levels") + # the default value of the numa high bit is specified in the command line + # option and must be passed into the directory memory sim object + numa_high_bit = Param.Int("numa high bit") diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/Cache.py --- a/src/mem/ruby/system/Cache.py Fri Apr 01 15:50:23 2011 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -# Copyright (c) 2009 Advanced Micro Devices, Inc. -# All rights reserved. -# -# 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: Steve Reinhardt -# Brad Beckmann - -from m5.params import * -from m5.SimObject import SimObject -from Controller import RubyController - -class RubyCache(SimObject): - type = 'RubyCache' - cxx_class = 'CacheMemory' - size = Param.MemorySize("capacity in bytes"); - latency = Param.Int(""); - assoc = Param.Int(""); - replacement_policy = Param.String("PSEUDO_LRU", ""); - start_index_bit = Param.Int(6, "index start, default 6 for 64-byte line"); diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/CacheMemory.hh --- a/src/mem/ruby/system/CacheMemory.hh Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/CacheMemory.hh Mon Apr 04 08:22:35 2011 -0500 @@ -47,13 +47,13 @@ #include "mem/ruby/slicc_interface/AbstractCacheEntry.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" +#include "mem/ruby/system/AbstractMemory.hh" #include "mem/ruby/system/LRUPolicy.hh" #include "mem/ruby/system/PseudoLRUPolicy.hh" #include "mem/ruby/system/System.hh" #include "params/RubyCache.hh" -#include "sim/sim_object.hh" -class CacheMemory : public SimObject +class CacheMemory : public AbstractMemory { public: typedef RubyCacheParams Params; @@ -125,6 +125,11 @@ void setLocked (const Address& addr, int context); void clearLocked (const Address& addr); bool isLocked (const Address& addr, int context); + + AccessPermission getAccessPermissions(const Address& addr); + void makeFunctionalAccess(const Address& addr, RubyRequestType type, + char* value, unsigned int size_in_bytes); + // Print cache contents void print(std::ostream& out) const; void printData(std::ostream& out) const; @@ -172,4 +177,3 @@ }; #endif // __MEM_RUBY_SYSTEM_CACHEMEMORY_HH__ - diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/CacheMemory.cc --- a/src/mem/ruby/system/CacheMemory.cc Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/CacheMemory.cc Mon Apr 04 08:22:35 2011 -0500 @@ -46,7 +46,7 @@ } CacheMemory::CacheMemory(const Params *p) - : SimObject(p) + : AbstractMemory(p) { m_cache_size = p->size; m_latency = p->latency; @@ -485,3 +485,42 @@ return m_cache[cacheSet][loc]->m_locked == context; } +AccessPermission +CacheMemory::getAccessPermissions(const Address& address) +{ + Address line_address(address); + line_address.makeLineAddress(); + + Index cacheSet = addressToCacheSet(line_address); + int loc = findTagInSet(cacheSet, line_address); + + if(loc == -1) return AccessPermission_NotPresent; + return m_cache[cacheSet][loc]->m_Permission; +} + +void +CacheMemory::makeFunctionalAccess(const Address& address, RubyRequestType type, + char* value, unsigned int size_in_bytes) +{ + Address line_address(address); + line_address.makeLineAddress(); + + Index cacheSet = addressToCacheSet(line_address); + int loc = findTagInSet(cacheSet, line_address); + + if(loc == -1) return; + + AbstractCacheEntry* entry = m_cache[cacheSet][loc]; + unsigned startByte = address.getAddress() - line_address.getAddress(); + assert(size_in_bytes > 0); + + if (type == RubyRequestType_LD) { + for (unsigned i = 0; i < size_in_bytes; ++i) { + value[i] = entry->getDataBlk().getByte(i + startByte); + } + } else { + for (unsigned i = 0; i < size_in_bytes; ++i) { + entry->getDataBlk().setByte(i + startByte, value[i]); + } + } +} diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/DirectoryMemory.hh --- a/src/mem/ruby/system/DirectoryMemory.hh Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/DirectoryMemory.hh Mon Apr 04 08:22:35 2011 -0500 @@ -35,12 +35,13 @@ #include "mem/protocol/Directory_Entry.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Global.hh" +#include "mem/ruby/system/AbstractMemory.hh" #include "mem/ruby/system/MemoryVector.hh" #include "mem/ruby/system/SparseMemory.hh" #include "params/RubyDirectoryMemory.hh" #include "sim/sim_object.hh" -class DirectoryMemory : public SimObject +class DirectoryMemory : public AbstractMemory { public: typedef RubyDirectoryMemoryParams Params; @@ -61,6 +62,9 @@ Directory_Entry& lookup(PhysAddress address); void invalidateBlock(PhysAddress address); + AccessPermission getAccessPermissions(const Address& address); + void makeFunctionalAccess(const Address& address, RubyRequestType type, + char* value, unsigned int size_in_bytes); void print(std::ostream& out) const; void printStats(std::ostream& out) const; diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/DirectoryMemory.cc --- a/src/mem/ruby/system/DirectoryMemory.cc Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/DirectoryMemory.cc Mon Apr 04 08:22:35 2011 -0500 @@ -39,7 +39,7 @@ int DirectoryMemory::m_numa_high_bit = 0; DirectoryMemory::DirectoryMemory(const Params *p) - : SimObject(p) + : AbstractMemory(p) { m_version = p->version; m_size_bytes = p->size; @@ -235,6 +235,51 @@ #endif } +AccessPermission +DirectoryMemory::getAccessPermissions(const PhysAddress& address) +{ + if(isPresent(address)) + { + Directory_Entry entry = lookup(address); + return entry.m_Permission; + } + + return AccessPermission_NotPresent; +} + +void +DirectoryMemory::makeFunctionalAccess(const PhysAddress& address, + RubyRequestType type, + char* value, + unsigned int size_in_bytes) +{ + if(isPresent(address)) + { + Directory_Entry entry = lookup(address); + DataBlock block = entry.m_DataBlk; + + PhysAddress line_address(address); + line_address.makeLineAddress(); + + unsigned startByte = address.getAddress() - line_address.getAddress(); + + if(type == RubyRequestType_LD) + { + for (unsigned i = 0; i < size_in_bytes; ++i) + { + value[i] = block.getByte(i + startByte); + } + } + else + { + for (unsigned i = 0; i < size_in_bytes; ++i) + { + block.setByte(i + startByte, value[i]); + } + } + } +} + void DirectoryMemory::print(ostream& out) const { diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/DirectoryMemory.py --- a/src/mem/ruby/system/DirectoryMemory.py Fri Apr 01 15:50:23 2011 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -# Copyright (c) 2009 Advanced Micro Devices, Inc. -# All rights reserved. -# -# 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: Steve Reinhardt -# Brad Beckmann - -from m5.params import * -from m5.proxy import * -from m5.SimObject import SimObject - -class RubyDirectoryMemory(SimObject): - type = 'RubyDirectoryMemory' - cxx_class = 'DirectoryMemory' - version = Param.Int(0, "") - size = Param.MemorySize("1GB", "capacity in bytes") - use_map = Param.Bool(False, "enable sparse memory") - map_levels = Param.Int(4, "sparse memory map levels") - # the default value of the numa high bit is specified in the command line - # option and must be passed into the directory memory sim object - numa_high_bit = Param.Int("numa high bit") diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/RubyPort.hh --- a/src/mem/ruby/system/RubyPort.hh Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/RubyPort.hh Mon Apr 04 08:22:35 2011 -0500 @@ -36,6 +36,7 @@ #include "mem/physical.hh" #include "mem/protocol/RequestStatus.hh" #include "mem/ruby/slicc_interface/RubyRequest.hh" +#include "mem/ruby/system/AbstractMemory.hh" #include "mem/ruby/system/System.hh" #include "mem/tport.hh" #include "params/RubyPort.hh" @@ -50,12 +51,13 @@ { private: RubyPort *ruby_port; + RubySystem* ruby_system; bool _onRetryList; bool access_phys_mem; public: M5Port(const std::string &_name, RubyPort *_port, - bool _access_phys_mem); + RubySystem*_system, bool _access_phys_mem); bool sendTiming(PacketPtr pkt); void hitCallback(PacketPtr pkt); unsigned deviceBlockSize() const; @@ -69,9 +71,12 @@ protected: virtual bool recvTiming(PacketPtr pkt); virtual Tick recvAtomic(PacketPtr pkt); + virtual void recvFunctional(PacketPtr pkt); private: bool isPhysMemAddress(Addr addr); + bool doFunctionalRead(PacketPtr pkt); + bool doFunctionalWrite(PacketPtr pkt); }; friend class M5Port; @@ -145,6 +150,7 @@ M5Port* physMemPort; PhysicalMemory* physmem; + RubySystem* ruby_system; // // Based on similar code in the M5 bus. Stores pointers to those ports diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/RubyPort.cc --- a/src/mem/ruby/system/RubyPort.cc Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/RubyPort.cc Mon Apr 04 08:22:35 2011 -0500 @@ -32,6 +32,7 @@ #endif // X86_ISA #include "cpu/testers/rubytest/RubyTester.hh" #include "mem/physical.hh" +#include "mem/protocol/AccessPermission.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/system/RubyPort.hh" @@ -66,7 +67,7 @@ { if (if_name == "port") { return new M5Port(csprintf("%s-port%d", name(), idx), this, - access_phys_mem); + ruby_system, access_phys_mem); } if (if_name == "pio_port") { @@ -83,7 +84,7 @@ assert (physMemPort == NULL); physMemPort = new M5Port(csprintf("%s-physMemPort", name()), this, - access_phys_mem); + ruby_system, access_phys_mem); return physMemPort; } @@ -107,12 +108,13 @@ ruby_port = _port; } -RubyPort::M5Port::M5Port(const std::string &_name, - RubyPort *_port, bool _access_phys_mem) +RubyPort::M5Port::M5Port(const std::string &_name, RubyPort *_port, + RubySystem *_system, bool _access_phys_mem) : SimpleTimingPort(_name, _port) { DPRINTF(RubyPort, "creating port from ruby sequcner to cpu %s\n", _name); ruby_port = _port; + ruby_system = _system; _onRetryList = false; access_phys_mem = _access_phys_mem; } @@ -287,6 +289,119 @@ return false; } +bool +RubyPort::M5Port::doFunctionalRead(PacketPtr pkt) +{ + Address addr(pkt->getAddr()); + AccessPermission accessPerm = AccessPermission_NotPresent; + int num_memories = ruby_system->m_abs_mem_vec.size(); + + // In this loop, we try to figure which controller has a read only or + // a read write copy of the given address. Any copy would suffice for + // a functional read. + + for(int i = 0;i < num_memories;++i) + { + accessPerm = ruby_system->m_abs_mem_vec[i]->getAccessPermissions(addr); + if(accessPerm == AccessPermission_Read_Only || + accessPerm == AccessPermission_Read_Write) + { + char* data = (char*)(pkt->getPtr(true)); + unsigned int size_in_bytes = pkt->getSize(); + ruby_system->m_abs_mem_vec[i]-> + makeFunctionalAccess(addr, RubyRequestType_LD, + data, size_in_bytes); + return true; + } + } + return false; +} + +bool +RubyPort::M5Port::doFunctionalWrite(PacketPtr pkt) +{ + Address addr(pkt->getAddr()); + AccessPermission accessPerm = AccessPermission_NotPresent; + int num_memories = ruby_system->m_abs_mem_vec.size(); + + unsigned int num_rw = 0; + unsigned int num_busy = 0; + + // In this loop we count the number of controllers that have the given + // address in read only, read write and busy states. + for(int i = 0;i < num_memories;++i) + { + accessPerm = ruby_system->m_abs_mem_vec[i]->getAccessPermissions(addr); + + if(accessPerm == AccessPermission_Read_Write) num_rw++; + else if(accessPerm == AccessPermission_Busy) num_busy++; + } + + // If the number of read write copies is more than 1, then there is bug in + // coherence protocol. Otherwise, if all copies are in stable states, i.e. + // num_busy == 0, we update all the copies. If there is at least one copy + // in busy state, then we check if there is read write copy. If yes, then + // also we let the access go through. + + assert(num_rw <= 1); + if(num_busy == 0 || num_rw == 1) + { + char* data = (char*)(pkt->getPtr(true)); + unsigned int size_in_bytes = pkt->getSize(); + + for(int i = 0; i < num_memories;++i) + { + ruby_system->m_abs_mem_vec[i]-> + makeFunctionalAccess(addr, RubyRequestType_ST, + data, size_in_bytes); + } + return true; + } + return false; +} + +void +RubyPort::M5Port::recvFunctional(PacketPtr pkt) +{ + DPRINTF(MemoryAccess, + "Functional access caught for address %#x\n", pkt->getAddr()); + + // Check for pio requests and directly send them to the dedicated + // pio port. + if (!isPhysMemAddress(pkt->getAddr())) { + assert(ruby_port->pio_port != NULL); + DPRINTF(MemoryAccess, + "Request for address 0x%#x is assumed to be a pio request\n", + pkt->getAddr()); + panic("RubyPort::PioPort::recvFunctional() not implemented!\n"); + } + + bool accessMade = false; + pkt->pushLabel(ruby_port->m_name); + + if (!checkFunctional(pkt)) { + if (pkt->isRead()) { + accessMade = doFunctionalRead(pkt); + } else if (pkt->isWrite()) { + accessMade = doFunctionalWrite(pkt); + } else { + panic("RubyPort: unsupported functional command %s\n", + pkt->cmdString()); + } + } + + if(!accessMade) ruby_port->physMemPort->sendFunctional(pkt); + pkt->popLabel(); + + // turn packet around to go back to requester if response expected + if (pkt->needsResponse()) { + pkt->makeResponse(); + DPRINTF(RubyPort, "Sending packet back over port\n"); + sendFunctional(pkt); + } + DPRINTF(RubyPort, "Functional access done!\n"); +} + void RubyPort::ruby_hit_callback(PacketPtr pkt) { diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/RubySystem.py --- a/src/mem/ruby/system/RubySystem.py Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/RubySystem.py Mon Apr 04 08:22:35 2011 -0500 @@ -39,9 +39,6 @@ block_size_bytes = Param.Int(64, "default cache block size; must be a power of two"); mem_size = Param.MemorySize("total memory size of the system"); - network = Param.RubyNetwork("") - profiler = Param.RubyProfiler(""); - tracer = Param.RubyTracer(""); stats_filename = Param.String("ruby.stats", "file to which ruby dumps its stats") no_mem_vec = Param.Bool(False, "do not allocate Ruby's mem vector"); diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/SConscript --- a/src/mem/ruby/system/SConscript Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/SConscript Mon Apr 04 08:22:35 2011 -0500 @@ -33,13 +33,13 @@ if not env['RUBY']: Return() -SimObject('Cache.py') +SimObject('AbstractMemory.py') SimObject('Sequencer.py') -SimObject('DirectoryMemory.py') SimObject('MemoryControl.py') SimObject('WireBuffer.py') SimObject('RubySystem.py') +Source('AbstractMemory.cc') Source('DMASequencer.cc') Source('DirectoryMemory.cc') Source('SparseMemory.cc') diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/Sequencer.cc --- a/src/mem/ruby/system/Sequencer.cc Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/Sequencer.cc Mon Apr 04 08:22:35 2011 -0500 @@ -29,8 +29,6 @@ #include "base/str.hh" #include "base/misc.hh" #include "cpu/testers/rubytest/RubyTester.hh" -#include "mem/protocol/Protocol.hh" -#include "mem/protocol/Protocol.hh" #include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/common/SubBlock.hh" diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/Sequencer.py --- a/src/mem/ruby/system/Sequencer.py Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/Sequencer.py Mon Apr 04 08:22:35 2011 -0500 @@ -43,6 +43,7 @@ using_network_tester = Param.Bool(False, "") access_phys_mem = Param.Bool(True, "should the rubyport atomically update phys_mem") + ruby_system = Param.RubySystem("") class RubySequencer(RubyPort): type = 'RubySequencer' diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/System.hh --- a/src/mem/ruby/system/System.hh Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/System.hh Mon Apr 04 08:22:35 2011 -0500 @@ -42,6 +42,7 @@ #include "params/RubySystem.hh" #include "sim/sim_object.hh" +class AbstractMemory; class CacheRecorder; class MemoryVector; class Network; @@ -128,6 +129,11 @@ virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); + static void registerNetwork(Network*); + static void registerProfiler(Profiler*); + static void registerTracer(Tracer*); + void registerAbstractMemory(AbstractMemory*); + private: // Private copy constructor and assignment operator RubySystem(const RubySystem& obj); @@ -153,6 +159,7 @@ static Profiler* m_profiler_ptr; static Tracer* m_tracer_ptr; static MemoryVector* m_mem_vec_ptr; + std::vector m_abs_mem_vec; }; inline std::ostream& @@ -180,6 +187,3 @@ }; #endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__ - - - diff -r aeec9e157d06 -r 5e058187a133 src/mem/ruby/system/System.cc --- a/src/mem/ruby/system/System.cc Fri Apr 01 15:50:23 2011 -0700 +++ b/src/mem/ruby/system/System.cc Mon Apr 04 08:22:35 2011 -0500 @@ -74,10 +74,6 @@ m_memory_size_bits = floorLog2(m_memory_size_bytes); } - m_network_ptr = p->network; - m_profiler_ptr = p->profiler; - m_tracer_ptr = p->tracer; - g_eventQueue_ptr = new RubyEventQueue(p->eventq, m_clock); g_system_ptr = this; if (p->no_mem_vec) { @@ -100,6 +96,30 @@ m_profiler_ptr->clearStats(); } +void +RubySystem::registerNetwork(Network* network_ptr) +{ + m_network_ptr = network_ptr; +} + +void +RubySystem::registerProfiler(Profiler* profiler_ptr) +{ + m_profiler_ptr = profiler_ptr; +} + +void +RubySystem::registerTracer(Tracer* tracer_ptr) +{ + m_tracer_ptr = tracer_ptr; +} + +void +RubySystem::registerAbstractMemory(AbstractMemory* memory) +{ + m_abs_mem_vec.push_back(memory); +} + RubySystem::~RubySystem() { delete m_network_ptr;