diff -r ac4da9f8ea80 -r 8b30f9e7df95 configs/example/ruby_direct_test.py --- a/configs/example/ruby_direct_test.py Fri Jun 10 22:15:34 2011 -0400 +++ b/configs/example/ruby_direct_test.py Sun Jun 12 16:41:28 2011 -0500 @@ -97,7 +97,7 @@ options.requests, generator = generator) -system.ruby = Ruby.create_system(options, system) +Ruby.create_system(options, system) assert(options.num_cpus == len(system.ruby._cpu_ruby_ports)) diff -r ac4da9f8ea80 -r 8b30f9e7df95 configs/example/ruby_fs.py --- a/configs/example/ruby_fs.py Fri Jun 10 22:15:34 2011 -0400 +++ b/configs/example/ruby_fs.py Sun Jun 12 16:41:28 2011 -0500 @@ -117,10 +117,7 @@ else: fatal("incapable of building non-alpha or non-x86 full system!") -system.ruby = Ruby.create_system(options, - system, - system.piobus, - system._dma_devices) +Ruby.create_system(options, system, system.piobus, system._dma_devices) system.cpu = [CPUClass(cpu_id=i) for i in xrange(options.num_cpus)] diff -r ac4da9f8ea80 -r 8b30f9e7df95 configs/example/ruby_mem_test.py --- a/configs/example/ruby_mem_test.py Fri Jun 10 22:15:34 2011 -0400 +++ b/configs/example/ruby_mem_test.py Sun Jun 12 16:41:28 2011 -0500 @@ -55,6 +55,8 @@ help="Progress message interval " "[default: %default]") parser.add_option("--num-dmas", type="int", default=0, help="# of dma testers") +parser.add_option("--functional", type="int", default=0, + help="percentage of accesses that should be functional") # # Add the ruby specific and protocol specific options @@ -90,12 +92,12 @@ sys.exit(1) # -# Currently ruby does not support atomic, functional, or uncacheable accesses +# Currently ruby does not support atomic or uncacheable accesses # cpus = [ MemTest(atomic = False, \ max_loads = options.maxloads, \ issue_dmas = False, \ - percent_functional = 0, \ + percent_functional = options.functional, \ percent_uncacheable = 0, \ progress_interval = options.progress) \ for i in xrange(options.num_cpus) ] @@ -116,7 +118,7 @@ else: dmas = [] -system.ruby = Ruby.create_system(options, \ +Ruby.create_system(options, \ system, \ dma_devices = dmas) diff -r ac4da9f8ea80 -r 8b30f9e7df95 configs/example/ruby_network_test.py --- a/configs/example/ruby_network_test.py Fri Jun 10 22:15:34 2011 -0400 +++ b/configs/example/ruby_network_test.py Sun Jun 12 16:41:28 2011 -0500 @@ -105,7 +105,7 @@ system = System(cpu = cpus, physmem = PhysicalMemory()) -system.ruby = Ruby.create_system(options, system) +Ruby.create_system(options, system) i = 0 for ruby_port in system.ruby._cpu_ruby_ports: diff -r ac4da9f8ea80 -r 8b30f9e7df95 configs/example/ruby_random_test.py --- a/configs/example/ruby_random_test.py Fri Jun 10 22:15:34 2011 -0400 +++ b/configs/example/ruby_random_test.py Sun Jun 12 16:41:28 2011 -0500 @@ -99,7 +99,7 @@ # system = System(tester = tester, physmem = PhysicalMemory()) -system.ruby = Ruby.create_system(options, system) +Ruby.create_system(options, system) assert(options.num_cpus == len(system.ruby._cpu_ruby_ports)) diff -r ac4da9f8ea80 -r 8b30f9e7df95 configs/ruby/MESI_CMP_directory.py --- a/configs/ruby/MESI_CMP_directory.py Fri Jun 10 22:15:34 2011 -0400 +++ b/configs/ruby/MESI_CMP_directory.py Sun Jun 12 16:41:28 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.") @@ -79,22 +79,26 @@ # 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) l1_cntrl = L1Cache_Controller(version = i, cntrl_id = cntrl_count, L1IcacheMemory = l1i_cache, L1DcacheMemory = l1d_cache, - l2_select_num_bits = l2_bits) + l2_select_num_bits = l2_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) l1_cntrl.sequencer = cpu_seq @@ -119,11 +123,13 @@ # 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, cntrl_id = cntrl_count, - L2cacheMemory = l2_cache) + L2cacheMemory = l2_cache, + ruby_system = ruby_system) exec("system.l2_cntrl%d = l2_cntrl" % i) l2_cntrl_nodes.append(l2_cntrl) @@ -148,9 +154,11 @@ cntrl_id = cntrl_count, directory = \ RubyDirectoryMemory(version = i, - size = \ - dir_size), - memBuffer = mem_cntrl) + size = dir_size, + ruby_system = \ + ruby_system), + memBuffer = mem_cntrl, + ruby_system = ruby_system) exec("system.dir_cntrl%d = dir_cntrl" % i) dir_cntrl_nodes.append(dir_cntrl) diff -r ac4da9f8ea80 -r 8b30f9e7df95 configs/ruby/MI_example.py --- a/configs/ruby/MI_example.py Fri Jun 10 22:15:34 2011 -0400 +++ b/configs/ruby/MI_example.py Sun Jun 12 16:41:28 2011 -0500 @@ -41,7 +41,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'] != 'MI_example': panic("This script requires the MI_example protocol to be built.") @@ -73,20 +73,23 @@ # cache = Cache(size = options.l1d_size, assoc = options.l1d_assoc, - start_index_bit = block_size_bits) + start_index_bit = block_size_bits, + ruby_system = ruby_system) # # Only one unified L1 cache exists. Can cache instructions and data. # l1_cntrl = L1Cache_Controller(version = i, cntrl_id = cntrl_count, - cacheMemory = cache) + cacheMemory = cache, + ruby_system = ruby_system) cpu_seq = RubySequencer(version = i, icache = cache, dcache = cache, physMemPort = system.physmem.port, - physmem = system.physmem) + physmem = system.physmem, + ruby_system = ruby_system) l1_cntrl.sequencer = cpu_seq @@ -122,10 +125,12 @@ RubyDirectoryMemory( \ version = i, size = dir_size, + ruby_system = ruby_system, use_map = options.use_map, map_levels = \ options.map_levels), - memBuffer = mem_cntrl) + memBuffer = mem_cntrl, + ruby_system = ruby_system) exec("system.dir_cntrl%d = dir_cntrl" % i) dir_cntrl_nodes.append(dir_cntrl) diff -r ac4da9f8ea80 -r 8b30f9e7df95 configs/ruby/MOESI_CMP_directory.py --- a/configs/ruby/MOESI_CMP_directory.py Fri Jun 10 22:15:34 2011 -0400 +++ b/configs/ruby/MOESI_CMP_directory.py Sun Jun 12 16:41:28 2011 -0500 @@ -47,8 +47,8 @@ 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'] != 'MOESI_CMP_directory': panic("This script requires the MOESI_CMP_directory protocol to be built.") @@ -79,22 +79,26 @@ # 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) l1_cntrl = L1Cache_Controller(version = i, cntrl_id = cntrl_count, L1IcacheMemory = l1i_cache, L1DcacheMemory = l1d_cache, - l2_select_num_bits = l2_bits) + l2_select_num_bits = l2_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) l1_cntrl.sequencer = cpu_seq @@ -118,11 +122,13 @@ # 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, cntrl_id = cntrl_count, - L2cacheMemory = l2_cache) + L2cacheMemory = l2_cache, + ruby_system = ruby_system) exec("system.l2_cntrl%d = l2_cntrl" % i) l2_cntrl_nodes.append(l2_cntrl) @@ -147,9 +153,11 @@ cntrl_id = cntrl_count, directory = \ RubyDirectoryMemory(version = i, - size = \ - dir_size), - memBuffer = mem_cntrl) + size = dir_size, + ruby_system = \ + ruby_system), + memBuffer = mem_cntrl, + ruby_system = ruby_system) exec("system.dir_cntrl%d = dir_cntrl" % i) dir_cntrl_nodes.append(dir_cntrl) diff -r ac4da9f8ea80 -r 8b30f9e7df95 configs/ruby/MOESI_CMP_token.py --- a/configs/ruby/MOESI_CMP_token.py Fri Jun 10 22:15:34 2011 -0400 +++ b/configs/ruby/MOESI_CMP_token.py Sun Jun 12 16:41:28 2011 -0500 @@ -54,7 +54,7 @@ parser.add_option("--allow-atomic-migration", action="store_true", help="allow migratory sharing for atomic only accessed blocks") -def create_system(options, system, piobus, dma_devices): +def create_system(options, system, piobus, dma_devices, ruby_system): if buildEnv['PROTOCOL'] != 'MOESI_CMP_token': panic("This script requires the MOESI_CMP_token protocol to be built.") @@ -92,10 +92,12 @@ # 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) l1_cntrl = L1Cache_Controller(version = i, cntrl_id = cntrl_count, @@ -110,13 +112,15 @@ dynamic_timeout_enabled = \ not options.disable_dyn_timeouts, no_mig_atomic = not \ - options.allow_atomic_migration) + options.allow_atomic_migration, + 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) l1_cntrl.sequencer = cpu_seq @@ -140,12 +144,14 @@ # 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, cntrl_id = cntrl_count, L2cacheMemory = l2_cache, - N_tokens = n_tokens) + N_tokens = n_tokens, + ruby_system = ruby_system) exec("system.l2_cntrl%d = l2_cntrl" % i) l2_cntrl_nodes.append(l2_cntrl) @@ -170,10 +176,12 @@ cntrl_id = cntrl_count, directory = \ RubyDirectoryMemory(version = i, - size = \ - dir_size), + size = dir_size, + ruby_system = \ + ruby_system), memBuffer = mem_cntrl, - l2_select_num_bits = l2_bits) + l2_select_num_bits = l2_bits, + ruby_system = ruby_system) exec("system.dir_cntrl%d = dir_cntrl" % i) dir_cntrl_nodes.append(dir_cntrl) diff -r ac4da9f8ea80 -r 8b30f9e7df95 configs/ruby/MOESI_hammer.py --- a/configs/ruby/MOESI_hammer.py Fri Jun 10 22:15:34 2011 -0400 +++ b/configs/ruby/MOESI_hammer.py Sun Jun 12 16:41:28 2011 -0500 @@ -58,8 +58,8 @@ parser.add_option("--dir-on", action="store_true", help="Hammer: enable Full-bit Directory") -def create_system(options, system, piobus, dma_devices): - +def create_system(options, system, piobus, dma_devices, ruby_system): + if buildEnv['PROTOCOL'] != 'MOESI_hammer': panic("This script requires the MOESI_hammer protocol to be built.") @@ -88,13 +88,16 @@ # 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) l2_cache = L2Cache(size = options.l2_size, assoc = options.l2_assoc, - start_index_bit = block_size_bits) + start_index_bit = block_size_bits, + ruby_system = ruby_system) l1_cntrl = L1Cache_Controller(version = i, cntrl_id = cntrl_count, @@ -102,13 +105,15 @@ L1DcacheMemory = l1d_cache, L2cacheMemory = l2_cache, no_mig_atomic = not \ - options.allow_atomic_migration) + options.allow_atomic_migration, + 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) l1_cntrl.sequencer = cpu_seq @@ -165,7 +170,8 @@ dir_size.value = mem_module_size pf = ProbeFilter(size = pf_size, assoc = 4, - start_index_bit = pf_start_bit) + start_index_bit = pf_start_bit, + ruby_system = ruby_system) dir_cntrl = Directory_Controller(version = i, cntrl_id = cntrl_count, @@ -173,6 +179,7 @@ RubyDirectoryMemory( \ version = i, size = dir_size, + ruby_system = ruby_system, use_map = options.use_map, map_levels = \ options.map_levels, @@ -181,7 +188,8 @@ probeFilter = pf, memBuffer = mem_cntrl, probe_filter_enabled = options.pf_on, - full_bit_dir_enabled = options.dir_on) + full_bit_dir_enabled = options.dir_on, + ruby_system = ruby_system) if options.recycle_latency: dir_cntrl.recycle_latency = options.recycle_latency diff -r ac4da9f8ea80 -r 8b30f9e7df95 configs/ruby/Ruby.py --- a/configs/ruby/Ruby.py Fri Jun 10 22:15:34 2011 -0400 +++ b/configs/ruby/Ruby.py Sun Jun 12 16:41:28 2011 -0500 @@ -62,11 +62,15 @@ def create_system(options, system, piobus = None, dma_devices = []): + system.ruby = RubySystem(clock = options.clock) + ruby = system.ruby + 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 @@ -105,7 +109,7 @@ print "Error: could not create topology %s" % options.topology raise - network = NetworkClass(topology = net_topology) + network = NetworkClass(ruby_system = ruby, topology = net_topology) # # Loop through the directory controlers. @@ -137,15 +141,13 @@ long(system.physmem.range.first) + 1 assert(total_mem_size.value == physmem_size) - ruby_profiler = RubyProfiler(num_of_sequencers = len(cpu_sequencers)) + ruby_profiler = RubyProfiler(ruby_system = ruby, + num_of_sequencers = len(cpu_sequencers)) + ruby_tracer = RubyTracer(ruby_system = ruby) - ruby = RubySystem(clock = options.clock, - network = network, - profiler = ruby_profiler, - tracer = RubyTracer(), - mem_size = total_mem_size) - + 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 - - return ruby diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/cpu/testers/memtest/memtest.hh --- a/src/cpu/testers/memtest/memtest.hh Fri Jun 10 22:15:34 2011 -0400 +++ b/src/cpu/testers/memtest/memtest.hh Sun Jun 12 16:41:28 2011 -0500 @@ -174,6 +174,7 @@ Tick noResponseCycles; uint64_t numReads; + uint64_t numWrites; uint64_t maxLoads; bool atomic; diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/cpu/testers/memtest/memtest.cc --- a/src/cpu/testers/memtest/memtest.cc Fri Jun 10 22:15:34 2011 -0400 +++ b/src/cpu/testers/memtest/memtest.cc Sun Jun 12 16:41:28 2011 -0500 @@ -162,6 +162,7 @@ // set up counters noResponseCycles = 0; numReads = 0; + numWrites = 0; schedule(tickEvent, 0); accessRetry = false; @@ -217,28 +218,36 @@ assert(removeAddr != outstandingAddrs.end()); outstandingAddrs.erase(removeAddr); - if (pkt->isRead()) { - if (memcmp(pkt_data, data, pkt->getSize()) != 0) { - panic("%s: read of %x (blk %x) @ cycle %d " - "returns %x, expected %x\n", name(), - req->getPaddr(), blockAddr(req->getPaddr()), curTick(), - *pkt_data, *data); + if (pkt->isError()) { + DPRINTF(MemTest, "Functional Access failed for %x at %x\n", + pkt->isWrite() ? "write" : "read", + req->getPaddr(), blockAddr(req->getPaddr())); + } else { + if (pkt->isRead()) { + if (memcmp(pkt_data, data, pkt->getSize()) != 0) { + panic("%s: read of %x (blk %x) @ cycle %d " + "returns %x, expected %x\n", name(), + req->getPaddr(), blockAddr(req->getPaddr()), curTick(), + *pkt_data, *data); + } + + numReads++; + numReadsStat++; + + if (numReads == (uint64_t)nextProgressMessage) { + ccprintf(cerr, "%s: completed %d read, %d write accesses @%d\n", + name(), numReads, numWrites, curTick()); + nextProgressMessage += progressInterval; + } + + if (maxLoads != 0 && numReads >= maxLoads) + exitSimLoop("maximum number of loads reached"); + } else { + assert(pkt->isWrite()); + funcPort.writeBlob(req->getPaddr(), pkt_data, req->getSize()); + numWrites++; + numWritesStat++; } - - numReads++; - numReadsStat++; - - if (numReads == (uint64_t)nextProgressMessage) { - ccprintf(cerr, "%s: completed %d read accesses @%d\n", - name(), numReads, curTick()); - nextProgressMessage += progressInterval; - } - - if (maxLoads != 0 && numReads >= maxLoads) - exitSimLoop("maximum number of loads reached"); - } else { - assert(pkt->isWrite()); - numWritesStat++; } noResponseCycles = 0; @@ -392,8 +401,6 @@ MemTestSenderState *state = new MemTestSenderState(result); pkt->senderState = state; - funcPort.writeBlob(req->getPaddr(), pkt_data, req->getSize()); - if (do_functional) { cachePort.sendFunctional(pkt); completeRequest(pkt); diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/packet.hh --- a/src/mem/packet.hh Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/packet.hh Sun Jun 12 16:41:28 2011 -0500 @@ -103,6 +103,7 @@ NetworkNackError, // nacked at network layer (not by protocol) InvalidDestError, // packet dest field invalid BadAddressError, // memory address invalid + FunctionalAccessError, // unable to fulfill functional request // Fake simulator-only commands PrintReq, // Print state matching address FlushReq, //request for a cache flush @@ -617,6 +618,14 @@ makeResponse(); } + void + makeFunctionalResponse(bool success) + { + makeResponse(); + if (!success) + cmd = MemCmd::commandInfo[MemCmd::FunctionalAccessError].response; + } + /** * Take a request packet that has been returned as NACKED and * modify it so that it can be sent out again. Only packets that diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/packet.cc --- a/src/mem/packet.cc Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/packet.cc Sun Jun 12 16:41:28 2011 -0500 @@ -148,10 +148,12 @@ { SET2(IsResponse, IsError), InvalidCmd, "InvalidDestError" }, /* BadAddressError -- memory address invalid */ { SET2(IsResponse, IsError), InvalidCmd, "BadAddressError" }, + /* FunctionalAccessError */ + { SET2(IsResponse, IsError), FunctionalAccessError, "FunctionalAccessError" }, /* PrintReq */ { SET2(IsRequest, IsPrint), InvalidCmd, "PrintReq" }, /* Flush Request */ - { SET3(IsRequest, IsFlush, NeedsExclusive), InvalidCmd, "FlushReq" } + { SET3(IsRequest, IsFlush, NeedsExclusive), InvalidCmd, "FlushReq" }, }; bool diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/protocol/MOESI_CMP_directory-L1cache.sm --- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm Sun Jun 12 16:41:28 2011 -0500 @@ -197,14 +197,17 @@ AccessPermission getAccessPermission(Address addr) { TBE tbe := TBEs[addr]; if(is_valid(tbe)) { + DPRINTF(RubySlicc, "%s\n", L1Cache_State_to_permission(tbe.TBEState)); return L1Cache_State_to_permission(tbe.TBEState); } Entry cache_entry := getCacheEntry(addr); if(is_valid(cache_entry)) { + DPRINTF(RubySlicc, "%s\n", L1Cache_State_to_permission(cache_entry.CacheState)); return L1Cache_State_to_permission(cache_entry.CacheState); } + DPRINTF(RubySlicc, "AccessPermission_NotPresent\n"); return AccessPermission:NotPresent; } diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/protocol/MOESI_CMP_directory-L2cache.sm --- a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm Sun Jun 12 16:41:28 2011 -0500 @@ -502,14 +502,22 @@ AccessPermission getAccessPermission(Address addr) { TBE tbe := TBEs[addr]; if(is_valid(tbe)) { + DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(tbe.TBEState)); return L2Cache_State_to_permission(tbe.TBEState); } Entry cache_entry := getCacheEntry(addr); if(is_valid(cache_entry)) { + DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(cache_entry.CacheState)); return L2Cache_State_to_permission(cache_entry.CacheState); } + else if (localDirectory.isTagPresent(addr)) { + DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(localDirectory[addr].DirState)); + return L2Cache_State_to_permission(localDirectory[addr].DirState); + } + + DPRINTF(RubySlicc, "AccessPermission_NotPresent\n"); return AccessPermission:NotPresent; } diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/protocol/MOESI_CMP_directory-dir.sm --- a/src/mem/protocol/MOESI_CMP_directory-dir.sm Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/protocol/MOESI_CMP_directory-dir.sm Sun Jun 12 16:41:28 2011 -0500 @@ -50,16 +50,16 @@ // STATES state_declaration(State, desc="Directory states", default="Directory_State_I") { // Base states - I, AccessPermission:Invalid, desc="Invalid"; + I, AccessPermission:Read_Write, desc="Invalid"; S, AccessPermission:Read_Only, desc="Shared"; - O, AccessPermission:Read_Only, desc="Owner"; - M, AccessPermission:Read_Write, desc="Modified"; + O, AccessPermission:Invalid, desc="Owner"; + M, AccessPermission:Invalid, desc="Modified"; IS, AccessPermission:Busy, desc="Blocked, was in idle"; SS, AccessPermission:Read_Only, desc="Blocked, was in shared"; - OO, AccessPermission:Read_Only, desc="Blocked, was in owned"; - MO, AccessPermission:Read_Only, desc="Blocked, going to owner or maybe modified"; - MM, AccessPermission:Read_Only, desc="Blocked, going to modified"; + OO, AccessPermission:Busy, desc="Blocked, was in owned"; + MO, AccessPermission:Busy, desc="Blocked, going to owner or maybe modified"; + MM, AccessPermission:Busy, desc="Blocked, going to modified"; MM_DMA, AccessPermission:Busy, desc="Blocked, going to I"; MI, AccessPermission:Busy, desc="Blocked on a writeback"; @@ -173,9 +173,11 @@ AccessPermission getAccessPermission(Address addr) { if (directory.isPresent(addr)) { + DPRINTF(RubySlicc, "%s\n", Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState)); return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState); } + DPRINTF(RubySlicc, "AccessPermission_NotPresent\n"); return AccessPermission:NotPresent; } @@ -468,7 +470,7 @@ // implementation. We include the data in the "dataless" // message so we can assert the clean data matches the datablock // in memory - assert(getDirectoryEntry(in_msg.Address).DataBlk == in_msg.DataBlk); + //assert(getDirectoryEntry(in_msg.Address).DataBlk == in_msg.DataBlk); } } diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/protocol/MOESI_hammer-cache.sm --- a/src/mem/protocol/MOESI_hammer-cache.sm Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/protocol/MOESI_hammer-cache.sm Sun Jun 12 16:41:28 2011 -0500 @@ -1134,7 +1134,7 @@ assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "Cached Data Block: %s, Msg Data Block: %s\n", cache_entry.DataBlk, in_msg.DataBlk); - assert(cache_entry.DataBlk == in_msg.DataBlk); + //assert(cache_entry.DataBlk == in_msg.DataBlk); cache_entry.DataBlk := in_msg.DataBlk; cache_entry.Dirty := in_msg.Dirty || cache_entry.Dirty; } diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/protocol/MOESI_hammer-dir.sm --- a/src/mem/protocol/MOESI_hammer-dir.sm Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/protocol/MOESI_hammer-dir.sm Sun Jun 12 16:41:28 2011 -0500 @@ -69,12 +69,12 @@ S_R, AccessPermission:Read_Only, desc="Was Not Owner or Sharer, replacing probe filter entry"; NO_R, AccessPermission:Invalid, desc="Was Not Owner or Sharer, replacing probe filter entry"; - NO_B, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked"; + NO_B, AccessPermission:Busy, "NO^B", desc="Not Owner, Blocked"; NO_B_X, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked, next queued request GETX"; NO_B_S, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked, next queued request GETS"; NO_B_S_W, AccessPermission:Invalid, "NO^B", desc="Not Owner, Blocked, forwarded merged GETS, waiting for responses"; O_B, AccessPermission:Invalid, "O^B", desc="Owner, Blocked"; - NO_B_W, AccessPermission:Invalid, desc="Not Owner, Blocked, waiting for Dram"; + NO_B_W, AccessPermission:Busy, desc="Not Owner, Blocked, waiting for Dram"; O_B_W, AccessPermission:Invalid, desc="Owner, Blocked, waiting for Dram"; NO_W, AccessPermission:Invalid, desc="Not Owner, waiting for Dram"; O_W, AccessPermission:Invalid, desc="Owner, waiting for Dram"; @@ -85,7 +85,7 @@ NO_DW_W, AccessPermission:Invalid, desc="Not Owner, Dma Write waiting for Dram"; O_DR_B_W, AccessPermission:Invalid, desc="Owner, Dma Read waiting for Dram and cache responses"; O_DR_B, AccessPermission:Invalid, desc="Owner, Dma Read waiting for cache responses"; - WB, AccessPermission:Invalid, desc="Blocked on a writeback"; + WB, AccessPermission:Busy, desc="Blocked on a writeback"; WB_O_W, AccessPermission:Invalid, desc="Blocked on memory write, will go to O"; WB_E_W, AccessPermission:Invalid, desc="Blocked on memory write, will go to E"; @@ -1233,7 +1233,7 @@ // implementation. We include the data in the "dataless" // message so we can assert the clean data matches the datablock // in memory - assert(getDirectoryEntry(address).DataBlk == in_msg.DataBlk); + //assert(getDirectoryEntry(address).DataBlk == in_msg.DataBlk); } } diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/network/Network.cc --- a/src/mem/ruby/network/Network.cc Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/network/Network.cc Sun Jun 12 16:41:28 2011 -0500 @@ -48,6 +48,7 @@ // Initialize the controller's network pointers m_topology_ptr->initNetworkPtr(this); + p->ruby_system->registerNetwork(this); } void diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/network/Network.py --- a/src/mem/ruby/network/Network.py Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/network/Network.py Sun Jun 12 16:41:28 2011 -0500 @@ -48,3 +48,4 @@ number_of_virtual_networks = Param.Int(10, ""); topology = Param.Topology(""); control_msg_size = Param.Int(8, ""); + ruby_system = Param.RubySystem(""); diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/profiler/Profiler.cc --- a/src/mem/ruby/profiler/Profiler.cc Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/profiler/Profiler.cc Sun Jun 12 16:41:28 2011 -0500 @@ -92,6 +92,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 ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/profiler/Profiler.py --- a/src/mem/ruby/profiler/Profiler.py Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/profiler/Profiler.py Sun Jun 12 16:41:28 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 ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/recorder/Tracer.cc --- a/src/mem/ruby/recorder/Tracer.cc Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/recorder/Tracer.cc Sun Jun 12 16:41:28 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 ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/recorder/Tracer.py --- a/src/mem/ruby/recorder/Tracer.py Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/recorder/Tracer.py Sun Jun 12 16:41:28 2011 -0500 @@ -34,3 +34,4 @@ type = 'RubyTracer' cxx_class = 'Tracer' warmup_length = Param.Int(100000, "") + ruby_system = Param.RubySystem("") diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/slicc_interface/AbstractController.hh --- a/src/mem/ruby/slicc_interface/AbstractController.hh Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/slicc_interface/AbstractController.hh Sun Jun 12 16:41:28 2011 -0500 @@ -37,6 +37,7 @@ #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/network/Network.hh" +#include "mem/ruby/system/System.hh" #include "params/RubyController.hh" #include "sim/sim_object.hh" @@ -47,7 +48,7 @@ { public: typedef RubyControllerParams Params; - AbstractController(const Params *p) : SimObject(p) {} + AbstractController(const Params *p); const Params *params() const { return (const Params *)_params; } // returns the number of controllers created of the specific subtype @@ -61,6 +62,7 @@ virtual void blockOnQueue(Address, MessageBuffer*) = 0; virtual void unblock(Address) = 0; virtual void initNetworkPtr(Network* net_ptr) = 0; + virtual AccessPermission getAccessPermission(Address addr) = 0; virtual void print(std::ostream & out) const = 0; virtual void printStats(std::ostream & out) const = 0; @@ -68,9 +70,6 @@ virtual void wakeup() = 0; // virtual void dumpStats(std::ostream & out) = 0; virtual void clearStats() = 0; - - private: - virtual AccessPermission getAccessPermission(Address addr) = 0; }; #endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__ diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/slicc_interface/AbstractController.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/slicc_interface/AbstractController.cc Sun Jun 12 16:41:28 2011 -0500 @@ -0,0 +1,7 @@ +#include "mem/ruby/slicc_interface/AbstractController.hh" +#include "debug/RubySlicc.hh" + +AbstractController::AbstractController(const Params *p) : SimObject(p) +{ + p->ruby_system->registerAbstractController(this); +} diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/slicc_interface/Controller.py --- a/src/mem/ruby/slicc_interface/Controller.py Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/slicc_interface/Controller.py Sun Jun 12 16:41:28 2011 -0500 @@ -41,3 +41,4 @@ buffer_size = Param.Int(0, "max buffer size 0 means infinite") recycle_latency = Param.Int(10, "") number_of_TBEs = Param.Int(256, "") + ruby_system = Param.RubySystem(""); diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/slicc_interface/SConscript --- a/src/mem/ruby/slicc_interface/SConscript Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/slicc_interface/SConscript Sun Jun 12 16:41:28 2011 -0500 @@ -35,6 +35,7 @@ SimObject('Controller.py') +Source('AbstractController.cc') Source('AbstractEntry.cc') Source('AbstractCacheEntry.cc') Source('RubyRequest.cc') diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/AbstractMemory.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/system/AbstractMemory.hh Sun Jun 12 16:41:28 2011 -0500 @@ -0,0 +1,49 @@ +/* + * 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 getAccessPermission(const Address& address) = 0; + virtual void makeFunctionalAccess(const Address& address, + RubyRequestType type, + uint8* value, + unsigned int size_in_bytes); +}; + +#endif // __MEM_RUBY_SYSTEM_ABSTRACTMEMORY_HH__ diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/AbstractMemory.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/system/AbstractMemory.cc Sun Jun 12 16:41:28 2011 -0500 @@ -0,0 +1,46 @@ +/* + * 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::AbstractMemory(const Params *p) + : SimObject(p) +{ + p->ruby_system->registerAbstractMemory(this); +} + +void +AbstractMemory::makeFunctionalAccess(const Address& address, + RubyRequestType type, + uint8* value, + unsigned int size_in_bytes) +{ + panic("Functional read not implemented.\n"); +} diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/AbstractMemory.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mem/ruby/system/AbstractMemory.py Sun Jun 12 16:41:28 2011 -0500 @@ -0,0 +1,58 @@ +# 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(""); + abstract = True + +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 ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/Cache.py --- a/src/mem/ruby/system/Cache.py Fri Jun 10 22:15:34 2011 -0400 +++ /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 ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/CacheMemory.hh --- a/src/mem/ruby/system/CacheMemory.hh Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/system/CacheMemory.hh Sun Jun 12 16:41:28 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 getAccessPermission(const Address& addr); + void makeFunctionalAccess(const Address& addr, RubyRequestType type, + uint8* 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 ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/CacheMemory.cc --- a/src/mem/ruby/system/CacheMemory.cc Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/system/CacheMemory.cc Sun Jun 12 16:41:28 2011 -0500 @@ -47,7 +47,7 @@ } CacheMemory::CacheMemory(const Params *p) - : SimObject(p) + : AbstractMemory(p) { m_cache_size = p->size; m_latency = p->latency; @@ -486,3 +486,43 @@ return m_cache[cacheSet][loc]->m_locked == context; } +AccessPermission +CacheMemory::getAccessPermission(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, + uint8* 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(); + + DPRINTF(RubyCache, "%s\n", entry->getDataBlk()); + 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]); + } + DPRINTF(RubyCache, "%s\n", entry->getDataBlk()); + } +} diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/DirectoryMemory.hh --- a/src/mem/ruby/system/DirectoryMemory.hh Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/system/DirectoryMemory.hh Sun Jun 12 16:41:28 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 getAccessPermission(const Address& address); + void makeFunctionalAccess(const Address& address, RubyRequestType type, + uint8* value, unsigned int size_in_bytes); void print(std::ostream& out) const; void printStats(std::ostream& out) const; diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/DirectoryMemory.cc --- a/src/mem/ruby/system/DirectoryMemory.cc Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/system/DirectoryMemory.cc Sun Jun 12 16:41:28 2011 -0500 @@ -40,7 +40,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; @@ -156,7 +156,7 @@ assert(isPresent(address)); Directory_Entry* entry; uint64 idx; - DPRINTF(RubyCache, "address: %s\n", address); + DPRINTF(RubyCache, "Looking up address: %s\n", address); if (m_use_map) { if (m_sparseMemory->exist(address)) { @@ -166,6 +166,7 @@ // Note: SparseMemory internally creates a new Directory Entry m_sparseMemory->add(address); entry = m_sparseMemory->lookup(address); + entry->changePermission(AccessPermission_Read_Write); } } else { idx = mapAddressToLocalIdx(address); @@ -175,6 +176,7 @@ if (entry == NULL) { entry = new Directory_Entry(); entry->getDataBlk().assign(m_ram->getBlockPtr(address)); + entry->changePermission(AccessPermission_Read_Only); m_entries[idx] = entry; } } @@ -236,6 +238,52 @@ #endif } +AccessPermission +DirectoryMemory::getAccessPermission(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, + uint8* value, + unsigned int size_in_bytes) +{ + if(isPresent(address)) + { + Directory_Entry& entry = lookup(address); + + PhysAddress line_address(address); + line_address.makeLineAddress(); + + unsigned startByte = address.getAddress() - line_address.getAddress(); + + DPRINTF(RubyCache, "%s\n", entry.m_DataBlk); + if(type == RubyRequestType_LD) + { + for (unsigned i = 0; i < size_in_bytes; ++i) + { + value[i] = entry.m_DataBlk.getByte(i + startByte); + } + } + else + { + for (unsigned i = 0; i < size_in_bytes; ++i) + { + entry.m_DataBlk.setByte(i + startByte, value[i]); + value[i] = entry.m_DataBlk.getByte(i + startByte); + } + DPRINTF(RubyCache, "%s\n", entry.m_DataBlk); + } + } +} + void DirectoryMemory::print(ostream& out) const { diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/DirectoryMemory.py --- a/src/mem/ruby/system/DirectoryMemory.py Fri Jun 10 22:15:34 2011 -0400 +++ /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 ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/RubyPort.hh --- a/src/mem/ruby/system/RubyPort.hh Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/system/RubyPort.hh Sun Jun 12 16:41:28 2011 -0500 @@ -34,6 +34,7 @@ #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/mem_object.hh" #include "mem/physical.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 ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/RubyPort.cc --- a/src/mem/ruby/system/RubyPort.cc Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/system/RubyPort.cc Sun Jun 12 16:41:28 2011 -0500 @@ -31,8 +31,8 @@ #include "arch/x86/insts/microldstop.hh" #endif // X86_ISA #include "cpu/testers/rubytest/RubyTester.hh" -#include "debug/MemoryAccess.hh" #include "debug/Ruby.hh" +#include "mem/protocol/AccessPermission.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/system/RubyPort.hh" #include "mem/physical.hh" @@ -54,6 +54,8 @@ m_usingRubyTester = p->using_ruby_tester; access_phys_mem = p->access_phys_mem; + + ruby_system = p->ruby_system; } void @@ -68,7 +70,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") { @@ -85,7 +87,7 @@ assert (physMemPort == NULL); physMemPort = new M5Port(csprintf("%s-physMemPort", name()), this, - access_phys_mem); + ruby_system, access_phys_mem); return physMemPort; } @@ -109,12 +111,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; } @@ -289,6 +292,129 @@ 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 valid copy would suffice + // for a functional read. + + DPRINTF(RubyPort, "Functional Read request for %s\n",addr); + for(int i = 0;i < num_memories;++i) + { + accessPerm = ruby_system->m_abs_mem_vec[i]->getAccessPermission(addr); + if(accessPerm == AccessPermission_Read_Only || + accessPerm == AccessPermission_Read_Write) + { + uint8* data = 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()); + Address line_addr = line_address(addr); + AccessPermission accessPerm = AccessPermission_NotPresent; + int num_memories = ruby_system->m_abs_mem_vec.size(); + int num_controllers = ruby_system->m_abs_cntrl_vec.size(); + + DPRINTF(RubyPort, "Functional Write request for %s\n",addr); + + unsigned int num_ro = 0; + 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_controllers;++i) + { + accessPerm = ruby_system->m_abs_cntrl_vec[i]-> + getAccessPermission(line_addr); + if(accessPerm == AccessPermission_Read_Only) num_ro++; + else 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. + + DPRINTF(RubyPort, "num_busy = %d, num_ro = %d, num_rw = %d\n", + num_busy, num_ro, num_rw); + assert(num_rw <= 1); + if((num_busy == 0 && num_ro > 0) || num_rw == 1) + { + uint8* data = 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(RubyPort, "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(RubyPort, "Request for address 0x%#x is 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); + if(accessMade) { + ruby_port->physMemPort->sendFunctional(pkt); + } + } else { + panic("RubyPort: unsupported functional command %s\n", + pkt->cmdString()); + } + } + + pkt->popLabel(); + // turn packet around to go back to requester if response expected + if (pkt->needsResponse()) { + pkt->makeFunctionalResponse(accessMade); + DPRINTF(RubyPort, "Sending packet back over port\n"); + sendFunctional(pkt); + } + DPRINTF(RubyPort, "Functional access %s!\n", + accessMade ? "successful":"failed"); +} + void RubyPort::ruby_hit_callback(PacketPtr pkt) { diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/RubySystem.py --- a/src/mem/ruby/system/RubySystem.py Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/system/RubySystem.py Sun Jun 12 16:41:28 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 ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/SConscript --- a/src/mem/ruby/system/SConscript Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/system/SConscript Sun Jun 12 16:41:28 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 ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/Sequencer.py --- a/src/mem/ruby/system/Sequencer.py Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/system/Sequencer.py Sun Jun 12 16:41:28 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 ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/System.hh --- a/src/mem/ruby/system/System.hh Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/system/System.hh Sun Jun 12 16:41:28 2011 -0500 @@ -39,9 +39,12 @@ #include "mem/ruby/common/Global.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/ruby/system/RubyPort.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" #include "params/RubySystem.hh" #include "sim/sim_object.hh" +class AbstractController; +class AbstractMemory; class CacheRecorder; class MemoryVector; class Network; @@ -128,6 +131,12 @@ virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); + void registerNetwork(Network*); + void registerProfiler(Profiler*); + void registerTracer(Tracer*); + void registerAbstractMemory(AbstractMemory*); + void registerAbstractController(AbstractController*); + private: // Private copy constructor and assignment operator RubySystem(const RubySystem& obj); @@ -153,6 +162,8 @@ static Profiler* m_profiler_ptr; static Tracer* m_tracer_ptr; static MemoryVector* m_mem_vec_ptr; + std::vector m_abs_mem_vec; + std::vector m_abs_cntrl_vec; }; inline std::ostream& @@ -180,6 +191,3 @@ }; #endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__ - - - diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/ruby/system/System.cc --- a/src/mem/ruby/system/System.cc Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/ruby/system/System.cc Sun Jun 12 16:41:28 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,36 @@ 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); +} + +void +RubySystem::registerAbstractController(AbstractController* cntrl) +{ + m_abs_cntrl_vec.push_back(cntrl); +} + RubySystem::~RubySystem() { delete m_network_ptr; diff -r ac4da9f8ea80 -r 8b30f9e7df95 src/mem/slicc/ast/MemberExprAST.py --- a/src/mem/slicc/ast/MemberExprAST.py Fri Jun 10 22:15:34 2011 -0400 +++ b/src/mem/slicc/ast/MemberExprAST.py Sun Jun 12 16:41:28 2011 -0500 @@ -49,10 +49,15 @@ code.fix(fix) # Verify that this is a valid field name for this type - if self.field not in return_type.data_members: - self.error("Invalid object field: " + - "Type '%s' does not have data member %s" % \ - (return_type, self.field)) - - # Return the type of the field - return return_type.data_members[self.field].type + if self.field in return_type.data_members: + # Return the type of the field + return return_type.data_members[self.field].type + else: + if "interface" in return_type: + interface_type = self.symtab.find(return_type["interface"]); + if self.field in interface_type.data_members: + # Return the type of the field + return interface_type.data_members[self.field].type + self.error("Invalid object field: " + + "Type '%s' does not have data member %s" % \ + (return_type, self.field))