From 12db50c89584938839e035da47d206250cbfd7c2 Mon Sep 17 00:00:00 2001 From: Nikos Nikoleris Date: Mon, 13 Mar 2017 18:19:08 +0000 Subject: [PATCH] ruby: Add support for address ranges in the directory Previously the directory covered a flat address range that always started from address 0. This change adds a vector of address ranges with interleaving and hashing that each directory keeps track of and the necessary flexibility to support systems with non continuous memory ranges. Change-Id: I6ea1c629bdf4c5137b7d9c89dbaf6c826adfd977 Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/2903 Reviewed-by: Bradford Beckmann Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power --- configs/ruby/GPU_RfO.py | 36 +++++---- configs/ruby/Garnet_standalone.py | 23 +----- configs/ruby/MESI_Three_Level.py | 25 +------ configs/ruby/MESI_Two_Level.py | 23 +----- configs/ruby/MI_example.py | 18 +---- configs/ruby/MOESI_AMD_Base.py | 37 +++++---- configs/ruby/MOESI_CMP_directory.py | 24 +----- configs/ruby/MOESI_CMP_token.py | 25 ++----- configs/ruby/MOESI_hammer.py | 28 ++----- configs/ruby/Ruby.py | 45 +++++++---- src/base/addr_range.hh | 51 ++++++++++++- src/mem/protocol/GPU_RfO-TCCdir.sm | 30 ++++---- src/mem/protocol/GPU_VIPER-TCC.sm | 12 +-- src/mem/protocol/GPU_VIPER_Region-TCC.sm | 4 +- src/mem/protocol/Garnet_standalone-cache.sm | 7 +- src/mem/protocol/MESI_Two_Level-L2cache.sm | 9 ++- src/mem/protocol/MESI_Two_Level-dma.sm | 5 +- src/mem/protocol/MI_example-cache.sm | 5 +- src/mem/protocol/MI_example-dma.sm | 5 +- src/mem/protocol/MOESI_AMD_Base-CorePair.sm | 37 +++++---- src/mem/protocol/MOESI_AMD_Base-L3cache.sm | 26 ++++--- .../MOESI_AMD_Base-Region-CorePair.sm | 29 ++++--- src/mem/protocol/MOESI_AMD_Base-Region-dir.sm | 6 +- .../protocol/MOESI_AMD_Base-RegionBuffer.sm | 36 +++++---- src/mem/protocol/MOESI_AMD_Base-RegionDir.sm | 9 ++- .../protocol/MOESI_AMD_Base-probeFilter.sm | 9 ++- .../protocol/MOESI_CMP_directory-L2cache.sm | 19 ++--- src/mem/protocol/MOESI_CMP_directory-dma.sm | 7 +- src/mem/protocol/MOESI_CMP_token-L1cache.sm | 9 ++- src/mem/protocol/MOESI_CMP_token-L2cache.sm | 9 ++- src/mem/protocol/MOESI_CMP_token-dir.sm | 7 +- src/mem/protocol/MOESI_CMP_token-dma.sm | 5 +- src/mem/protocol/MOESI_hammer-cache.sm | 23 +++--- src/mem/protocol/MOESI_hammer-dma.sm | 5 +- .../protocol/RubySlicc_ComponentMapping.sm | 5 -- src/mem/ruby/network/Network.cc | 40 ++++++++++ src/mem/ruby/network/Network.hh | 39 +++++++++- .../slicc_interface/AbstractController.cc | 23 +++++- .../slicc_interface/AbstractController.hh | 40 +++++++++- src/mem/ruby/slicc_interface/Controller.py | 14 ++++ .../RubySlicc_ComponentMapping.hh | 40 ---------- src/mem/ruby/structures/DirectoryMemory.cc | 75 ++++++++----------- src/mem/ruby/structures/DirectoryMemory.hh | 34 +++++++-- src/mem/ruby/structures/DirectoryMemory.py | 20 +++-- src/mem/slicc/symbols/Type.py | 15 ++++ 45 files changed, 577 insertions(+), 416 deletions(-) diff --git a/configs/ruby/GPU_RfO.py b/configs/ruby/GPU_RfO.py index 71e21d932..832ea4422 100644 --- a/configs/ruby/GPU_RfO.py +++ b/configs/ruby/GPU_RfO.py @@ -371,24 +371,14 @@ class L3Cntrl(L3Cache_Controller, CntrlBase): self.probeToL3 = probe_to_l3 self.respToL3 = resp_to_l3 -class DirMem(RubyDirectoryMemory, CntrlBase): - def create(self, options, ruby_system, system): - self.version = self.versionCount() - - phys_mem_size = AddrRange(options.mem_size).size() - mem_module_size = phys_mem_size / options.num_dirs - dir_size = MemorySize('0B') - dir_size.value = mem_module_size - self.size = dir_size - class DirCntrl(Directory_Controller, CntrlBase): - def create(self, options, ruby_system, system): + def create(self, options, dir_ranges, ruby_system, system): self.version = self.versionCount() self.response_latency = 30 - self.directory = DirMem() - self.directory.create(options, ruby_system, system) + self.addr_ranges = dir_ranges + self.directory = RubyDirectoryMemory() self.L3CacheMemory = L3Cache() self.L3CacheMemory.create(options, ruby_system, system) @@ -467,10 +457,28 @@ def create_system(options, full_system, system, dma_devices, ruby_system): # This is the base crossbar that connects the L3s, Dirs, and cpu/gpu # Clusters mainCluster = Cluster(extBW = 512, intBW = 512) # 1 TB/s + + if options.numa_high_bit: + numa_bit = options.numa_high_bit + else: + # if the numa_bit is not specified, set the directory bits as the + # lowest bits above the block offset bits, and the numa_bit as the + # highest of those directory bits + dir_bits = int(math.log(options.num_dirs, 2)) + block_size_bits = int(math.log(options.cacheline_size, 2)) + numa_bit = block_size_bits + dir_bits - 1 + for i in xrange(options.num_dirs): + dir_ranges = [] + for r in system.mem_ranges: + addr_range = m5.objects.AddrRange(r.start, size = r.size(), + intlvHighBit = numa_bit, + intlvBits = dir_bits, + intlvMatch = i) + dir_ranges.append(addr_range) dir_cntrl = DirCntrl(TCC_select_num_bits = TCC_bits) - dir_cntrl.create(options, ruby_system, system) + dir_cntrl.create(options, dir_ranges, ruby_system, system) dir_cntrl.number_of_TBEs = 2560 * options.num_compute_units #Enough TBEs for all TCP TBEs diff --git a/configs/ruby/Garnet_standalone.py b/configs/ruby/Garnet_standalone.py index 2897e73a4..5c173ce17 100644 --- a/configs/ruby/Garnet_standalone.py +++ b/configs/ruby/Garnet_standalone.py @@ -32,7 +32,7 @@ import m5 from m5.objects import * from m5.defines import buildEnv from m5.util import addToPath -from Ruby import create_topology +from Ruby import create_topology, create_directories # # Declare caches used by the protocol @@ -59,7 +59,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system): # Therefore the l1 controller nodes must be listed before # the directory nodes and directory nodes before dma nodes, etc. l1_cntrl_nodes = [] - dir_cntrl_nodes = [] # # Must create the individual controllers before the network to ensure the @@ -101,23 +100,9 @@ def create_system(options, full_system, system, dma_ports, ruby_system): l1_cntrl.forwardFromCache = MessageBuffer() - phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges)) - assert(phys_mem_size % options.num_dirs == 0) - mem_module_size = phys_mem_size / options.num_dirs - - for i in xrange(options.num_dirs): - dir_size = MemorySize('0B') - dir_size.value = mem_module_size - - dir_cntrl = Directory_Controller(version = i, - directory = \ - RubyDirectoryMemory(version = i, - size = dir_size), - ruby_system = ruby_system) - - exec("ruby_system.dir_cntrl%d = dir_cntrl" % i) - dir_cntrl_nodes.append(dir_cntrl) - + dir_cntrl_nodes = create_directories(options, system.mem_ranges, + ruby_system) + for dir_cntrl in dir_cntrl_nodes: # Connect the directory controllers and the network dir_cntrl.requestToDir = MessageBuffer() dir_cntrl.forwardToDir = MessageBuffer() diff --git a/configs/ruby/MESI_Three_Level.py b/configs/ruby/MESI_Three_Level.py index 1d4b6ebf6..5d9d5b2f8 100644 --- a/configs/ruby/MESI_Three_Level.py +++ b/configs/ruby/MESI_Three_Level.py @@ -33,7 +33,7 @@ import math import m5 from m5.objects import * from m5.defines import buildEnv -from Ruby import create_topology +from Ruby import create_topology, create_directories from Ruby import send_evicts # @@ -66,7 +66,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system): l0_cntrl_nodes = [] l1_cntrl_nodes = [] l2_cntrl_nodes = [] - dir_cntrl_nodes = [] dma_cntrl_nodes = [] assert (options.num_cpus % options.num_clusters == 0) @@ -194,31 +193,15 @@ def create_system(options, full_system, system, dma_ports, ruby_system): l2_cntrl.responseToL2Cache = MessageBuffer() l2_cntrl.responseToL2Cache.slave = ruby_system.network.master - phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges)) - assert(phys_mem_size % options.num_dirs == 0) - mem_module_size = phys_mem_size / options.num_dirs - # Run each of the ruby memory controllers at a ratio of the frequency of # the ruby system # clk_divider value is a fix to pass regression. ruby_system.memctrl_clk_domain = DerivedClockDomain( clk_domain = ruby_system.clk_domain, clk_divider = 3) - for i in xrange(options.num_dirs): - # - # Create the Ruby objects associated with the directory controller - # - dir_size = MemorySize('0B') - dir_size.value = mem_module_size - - dir_cntrl = Directory_Controller(version = i, - directory = RubyDirectoryMemory(version = i, size = dir_size), - transitions_per_cycle = options.ports, - ruby_system = ruby_system) - - exec("ruby_system.dir_cntrl%d = dir_cntrl" % i) - dir_cntrl_nodes.append(dir_cntrl) - + dir_cntrl_nodes = create_directories(options, system.mem_ranges, + ruby_system) + for dir_cntrl in dir_cntrl_nodes: # Connect the directory controllers and the network dir_cntrl.requestToDir = MessageBuffer() dir_cntrl.requestToDir.slave = ruby_system.network.master diff --git a/configs/ruby/MESI_Two_Level.py b/configs/ruby/MESI_Two_Level.py index 4cfa54bd8..844c62af4 100644 --- a/configs/ruby/MESI_Two_Level.py +++ b/configs/ruby/MESI_Two_Level.py @@ -31,7 +31,7 @@ import math import m5 from m5.objects import * from m5.defines import buildEnv -from Ruby import create_topology +from Ruby import create_topology, create_directories from Ruby import send_evicts # @@ -57,7 +57,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system): # l1_cntrl_nodes = [] l2_cntrl_nodes = [] - dir_cntrl_nodes = [] dma_cntrl_nodes = [] # @@ -167,11 +166,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system): l2_cntrl.responseToL2Cache.slave = ruby_system.network.master - phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges)) - assert(phys_mem_size % options.num_dirs == 0) - mem_module_size = phys_mem_size / options.num_dirs - - # Run each of the ruby memory controllers at a ratio of the frequency of # the ruby system # clk_divider value is a fix to pass regression. @@ -179,18 +173,9 @@ def create_system(options, full_system, system, dma_ports, ruby_system): clk_domain = ruby_system.clk_domain, clk_divider = 3) - for i in xrange(options.num_dirs): - dir_size = MemorySize('0B') - dir_size.value = mem_module_size - - dir_cntrl = Directory_Controller(version = i, - directory = RubyDirectoryMemory(version = i, size = dir_size), - transitions_per_cycle = options.ports, - ruby_system = ruby_system) - - exec("ruby_system.dir_cntrl%d = dir_cntrl" % i) - dir_cntrl_nodes.append(dir_cntrl) - + dir_cntrl_nodes = create_directories(options, system.mem_ranges, + ruby_system) + for dir_cntrl in dir_cntrl_nodes: # Connect the directory controllers and the network dir_cntrl.requestToDir = MessageBuffer() dir_cntrl.requestToDir.slave = ruby_system.network.master diff --git a/configs/ruby/MI_example.py b/configs/ruby/MI_example.py index 24b0f9716..eb881e55c 100644 --- a/configs/ruby/MI_example.py +++ b/configs/ruby/MI_example.py @@ -31,7 +31,7 @@ import math import m5 from m5.objects import * from m5.defines import buildEnv -from Ruby import create_topology +from Ruby import create_topology, create_directories from Ruby import send_evicts # @@ -55,7 +55,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system): # listed before the directory nodes and directory nodes before dma nodes, etc. # l1_cntrl_nodes = [] - dir_cntrl_nodes = [] dma_cntrl_nodes = [] # @@ -126,18 +125,9 @@ def create_system(options, full_system, system, dma_ports, ruby_system): clk_domain=ruby_system.clk_domain, clk_divider=3) - for i in xrange(options.num_dirs): - dir_size = MemorySize('0B') - dir_size.value = mem_module_size - dir_cntrl = Directory_Controller(version = i, - directory = RubyDirectoryMemory( - version = i, size = dir_size), - transitions_per_cycle = options.ports, - ruby_system = ruby_system) - - exec("ruby_system.dir_cntrl%d = dir_cntrl" % i) - dir_cntrl_nodes.append(dir_cntrl) - + dir_cntrl_nodes = create_directories(options, system.mem_ranges, + ruby_system) + for dir_cntrl in dir_cntrl_nodes: # Connect the directory controllers and the network dir_cntrl.requestToDir = MessageBuffer(ordered = True) dir_cntrl.requestToDir.slave = ruby_system.network.master diff --git a/configs/ruby/MOESI_AMD_Base.py b/configs/ruby/MOESI_AMD_Base.py index f1b3d792b..cdbb6f600 100644 --- a/configs/ruby/MOESI_AMD_Base.py +++ b/configs/ruby/MOESI_AMD_Base.py @@ -166,24 +166,14 @@ class L3Cntrl(L3Cache_Controller, CntrlBase): self.probeToL3 = probe_to_l3 self.respToL3 = resp_to_l3 -class DirMem(RubyDirectoryMemory, CntrlBase): - def create(self, options, ruby_system, system): - self.version = self.versionCount() - - phys_mem_size = AddrRange(options.mem_size).size() - mem_module_size = phys_mem_size / options.num_dirs - dir_size = MemorySize('0B') - dir_size.value = mem_module_size - self.size = dir_size - class DirCntrl(Directory_Controller, CntrlBase): - def create(self, options, ruby_system, system): + def create(self, options, dir_ranges, ruby_system, system): self.version = self.versionCount() self.response_latency = 30 - self.directory = DirMem() - self.directory.create(options, ruby_system, system) + self.addr_ranges = dir_ranges + self.directory = RubyDirectoryMemory() self.L3CacheMemory = L3Cache() self.L3CacheMemory.create(options, ruby_system, system) @@ -245,10 +235,29 @@ def create_system(options, full_system, system, dma_devices, ruby_system): # This is the base crossbar that connects the L3s, Dirs, and cpu # Cluster mainCluster = Cluster(extBW = 512, intBW = 512) # 1 TB/s + + if options.numa_high_bit: + numa_bit = options.numa_high_bit + else: + # if the numa_bit is not specified, set the directory bits as the + # lowest bits above the block offset bits, and the numa_bit as the + # highest of those directory bits + dir_bits = int(math.log(options.num_dirs, 2)) + block_size_bits = int(math.log(options.cacheline_size, 2)) + numa_bit = block_size_bits + dir_bits - 1 + for i in xrange(options.num_dirs): + dir_ranges = [] + for r in system.mem_ranges: + addr_range = m5.objects.AddrRange(r.start, size = r.size(), + intlvHighBit = numa_bit, + intlvBits = dir_bits, + intlvMatch = i) + dir_ranges.append(addr_range) + dir_cntrl = DirCntrl(TCC_select_num_bits = 0) - dir_cntrl.create(options, ruby_system, system) + dir_cntrl.create(options, dir_ranges, ruby_system, system) # Connect the Directory controller to the ruby network dir_cntrl.requestFromCores = MessageBuffer(ordered = True) diff --git a/configs/ruby/MOESI_CMP_directory.py b/configs/ruby/MOESI_CMP_directory.py index a72b5b20e..cbb061d32 100644 --- a/configs/ruby/MOESI_CMP_directory.py +++ b/configs/ruby/MOESI_CMP_directory.py @@ -31,7 +31,7 @@ import math import m5 from m5.objects import * from m5.defines import buildEnv -from Ruby import create_topology +from Ruby import create_topology, create_directories from Ruby import send_evicts # @@ -57,7 +57,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system): # l1_cntrl_nodes = [] l2_cntrl_nodes = [] - dir_cntrl_nodes = [] dma_cntrl_nodes = [] # @@ -158,12 +157,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system): l2_cntrl.responseToL2Cache.slave = ruby_system.network.master l2_cntrl.triggerQueue = MessageBuffer(ordered = True) - - phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges)) - assert(phys_mem_size % options.num_dirs == 0) - mem_module_size = phys_mem_size / options.num_dirs - - # Run each of the ruby memory controllers at a ratio of the frequency of # the ruby system. # clk_divider value is a fix to pass regression. @@ -171,19 +164,10 @@ def create_system(options, full_system, system, dma_ports, ruby_system): clk_domain=ruby_system.clk_domain, clk_divider=3) - for i in xrange(options.num_dirs): - dir_size = MemorySize('0B') - dir_size.value = mem_module_size - - dir_cntrl = Directory_Controller(version = i, - directory = RubyDirectoryMemory( - version = i, size = dir_size), - transitions_per_cycle = options.ports, - ruby_system = ruby_system) - - exec("ruby_system.dir_cntrl%d = dir_cntrl" % i) - dir_cntrl_nodes.append(dir_cntrl) + dir_cntrl_nodes = create_directories(options, system.mem_ranges, + ruby_system) + for dir_cntrl in dir_cntrl_nodes: # Connect the directory controllers and the network dir_cntrl.requestToDir = MessageBuffer() dir_cntrl.requestToDir.slave = ruby_system.network.master diff --git a/configs/ruby/MOESI_CMP_token.py b/configs/ruby/MOESI_CMP_token.py index 7161544b7..7c9871970 100644 --- a/configs/ruby/MOESI_CMP_token.py +++ b/configs/ruby/MOESI_CMP_token.py @@ -31,7 +31,7 @@ import math import m5 from m5.objects import * from m5.defines import buildEnv -from Ruby import create_topology +from Ruby import create_topology, create_directories from Ruby import send_evicts # @@ -70,7 +70,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system): # l1_cntrl_nodes = [] l2_cntrl_nodes = [] - dir_cntrl_nodes = [] dma_cntrl_nodes = [] # @@ -184,10 +183,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system): l2_cntrl.persistentToL2Cache.slave = ruby_system.network.master - phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges)) - assert(phys_mem_size % options.num_dirs == 0) - mem_module_size = phys_mem_size / options.num_dirs - # Run each of the ruby memory controllers at a ratio of the frequency of # the ruby system # clk_divider value is a fix to pass regression. @@ -195,20 +190,10 @@ def create_system(options, full_system, system, dma_ports, ruby_system): clk_domain=ruby_system.clk_domain, clk_divider=3) - for i in xrange(options.num_dirs): - dir_size = MemorySize('0B') - dir_size.value = mem_module_size - - dir_cntrl = Directory_Controller(version = i, - directory = RubyDirectoryMemory( - version = i, size = dir_size), - l2_select_num_bits = l2_bits, - transitions_per_cycle = options.ports, - ruby_system = ruby_system) - - exec("ruby_system.dir_cntrl%d = dir_cntrl" % i) - dir_cntrl_nodes.append(dir_cntrl) - + dir_cntrl_nodes = create_directories(options, system.mem_ranges, + ruby_system) + for dir_cntrl in dir_cntrl_nodes: + dir_cntrl.l2_select_num_bits = l2_bits # Connect the directory controllers and the network dir_cntrl.requestToDir = MessageBuffer() dir_cntrl.requestToDir.slave = ruby_system.network.master diff --git a/configs/ruby/MOESI_hammer.py b/configs/ruby/MOESI_hammer.py index 6a1cfd70b..9f615f931 100644 --- a/configs/ruby/MOESI_hammer.py +++ b/configs/ruby/MOESI_hammer.py @@ -31,7 +31,7 @@ import math import m5 from m5.objects import * from m5.defines import buildEnv -from Ruby import create_topology +from Ruby import create_topology, create_directories from Ruby import send_evicts # @@ -65,7 +65,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system): # listed before the directory nodes and directory nodes before dma nodes, etc. # l1_cntrl_nodes = [] - dir_cntrl_nodes = [] dma_cntrl_nodes = [] # @@ -143,10 +142,6 @@ def create_system(options, full_system, system, dma_ports, ruby_system): l1_cntrl.responseToCache.slave = ruby_system.network.master - phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges)) - assert(phys_mem_size % options.num_dirs == 0) - mem_module_size = phys_mem_size / options.num_dirs - # # determine size and index bits for probe filter # By default, the probe filter size is configured to be twice the @@ -177,28 +172,19 @@ def create_system(options, full_system, system, dma_ports, ruby_system): clk_domain=ruby_system.clk_domain, clk_divider=3) - for i in xrange(options.num_dirs): - dir_size = MemorySize('0B') - dir_size.value = mem_module_size - + dir_cntrl_nodes = create_directories(options, system.mem_ranges, + ruby_system) + for dir_cntrl in dir_cntrl_nodes: pf = ProbeFilter(size = pf_size, assoc = 4, start_index_bit = pf_start_bit) - dir_cntrl = Directory_Controller(version = i, - directory = RubyDirectoryMemory( - version = i, size = dir_size), - probeFilter = pf, - probe_filter_enabled = options.pf_on, - full_bit_dir_enabled = options.dir_on, - transitions_per_cycle = options.ports, - ruby_system = ruby_system) + dir_cntrl.probeFilter = pf + dir_cntrl.probe_filter_enabled = options.pf_on + dir_cntrl.full_bit_dir_enabled = options.dir_on if options.recycle_latency: dir_cntrl.recycle_latency = options.recycle_latency - exec("ruby_system.dir_cntrl%d = dir_cntrl" % i) - dir_cntrl_nodes.append(dir_cntrl) - # Connect the directory controller to the network dir_cntrl.forwardFromDir = MessageBuffer() dir_cntrl.forwardFromDir.master = ruby_system.network.slave diff --git a/configs/ruby/Ruby.py b/configs/ruby/Ruby.py index 8f5edb807..71f6eef7c 100644 --- a/configs/ruby/Ruby.py +++ b/configs/ruby/Ruby.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012 ARM Limited +# Copyright (c) 2012, 2017 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -84,16 +84,6 @@ def define_options(parser): def setup_memory_controllers(system, ruby, dir_cntrls, options): ruby.block_size_bytes = options.cacheline_size ruby.memory_size_bits = 48 - block_size_bits = int(math.log(options.cacheline_size, 2)) - - if options.numa_high_bit: - numa_bit = options.numa_high_bit - else: - # if the numa_bit is not specified, set the directory bits as the - # lowest bits above the block offset bits, and the numa_bit as the - # highest of those directory bits - dir_bits = int(math.log(options.num_dirs, 2)) - numa_bit = block_size_bits + dir_bits - 1 index = 0 mem_ctrls = [] @@ -104,8 +94,6 @@ def setup_memory_controllers(system, ruby, dir_cntrls, options): # for each address range as the abstract memory can handle only one # contiguous address range as of now. for dir_cntrl in dir_cntrls: - dir_cntrl.directory.numa_high_bit = numa_bit - crossbar = None if len(system.mem_ranges) > 1: crossbar = IOXBar() @@ -208,6 +196,37 @@ def create_system(options, full_system, system, piobus = None, dma_ports = []): ruby.phys_mem = SimpleMemory(range=system.mem_ranges[0], in_addr_map=False) +def create_directories(options, mem_ranges, ruby_system): + dir_cntrl_nodes = [] + if options.numa_high_bit: + numa_bit = options.numa_high_bit + else: + # if the numa_bit is not specified, set the directory bits as the + # lowest bits above the block offset bits, and the numa_bit as the + # highest of those directory bits + dir_bits = int(math.log(options.num_dirs, 2)) + block_size_bits = int(math.log(options.cacheline_size, 2)) + numa_bit = block_size_bits + dir_bits - 1 + + for i in xrange(options.num_dirs): + dir_ranges = [] + for r in mem_ranges: + addr_range = m5.objects.AddrRange(r.start, size = r.size(), + intlvHighBit = numa_bit, + intlvBits = dir_bits, + intlvMatch = i) + dir_ranges.append(addr_range) + + dir_cntrl = Directory_Controller() + dir_cntrl.version = i + dir_cntrl.directory = RubyDirectoryMemory() + dir_cntrl.ruby_system = ruby_system + dir_cntrl.addr_ranges = dir_ranges + + exec("ruby_system.dir_cntrl%d = dir_cntrl" % i) + dir_cntrl_nodes.append(dir_cntrl) + return dir_cntrl_nodes + def send_evicts(options): # currently, 2 scenarios warrant forwarding evictions to the CPU: # 1. The O3 model must keep the LSQ coherent with the caches diff --git a/src/base/addr_range.hh b/src/base/addr_range.hh index 1137efa28..ac1cbd05a 100644 --- a/src/base/addr_range.hh +++ b/src/base/addr_range.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014 ARM Limited + * Copyright (c) 2012, 2014, 2017 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -346,6 +346,55 @@ class AddrRange return false; } + /** + * Remove the interleaving bits from an input address. + * + * This function returns a new address that doesn't have the bits + * that are use to determine which of the interleaved ranges it + * belongs to. + * + * e.g., if the input address is: + * ------------------------------- + * | prefix | intlvBits | suffix | + * ------------------------------- + * this function will return: + * ------------------------------- + * | 0 | prefix | suffix | + * ------------------------------- + * + * @param the input address + * @return the address without the interleaved bits + */ + inline Addr removeIntlvBits(const Addr &a) const + { + const auto intlv_low_bit = intlvHighBit - intlvBits + 1; + return insertBits(a >> intlvBits, intlv_low_bit - 1, 0, a); + } + + /** + * Determine the offset of an address within the range. + * + * This function returns the offset of the given address from the + * starting address discarding any bits that are used for + * interleaving. This way we can convert the input address to a + * new unique address in a continuous range that starts from 0. + * + * @param the input address + * @return the flat offset in the address range + */ + Addr getOffset(const Addr& a) const + { + bool in_range = a >= _start && a <= _end; + if (!in_range) { + return MaxAddr; + } + if (interleaved()) { + return removeIntlvBits(a) - removeIntlvBits(_start); + } else { + return a - _start; + } + } + /** * Less-than operator used to turn an STL map into a binary search * tree of non-overlapping address ranges. diff --git a/src/mem/protocol/GPU_RfO-TCCdir.sm b/src/mem/protocol/GPU_RfO-TCCdir.sm index 8f58d6ebb..b1430f127 100644 --- a/src/mem/protocol/GPU_RfO-TCCdir.sm +++ b/src/mem/protocol/GPU_RfO-TCCdir.sm @@ -248,7 +248,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L void unset_cache_entry(); void set_tbe(TBE b); void unset_tbe(); - + MachineID mapAddressToMachine(Addr addr, MachineType mtype); bool presentOrAvail(Addr addr) { return directory.isTagPresent(addr) || directory.cacheAvail(addr); @@ -765,7 +765,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L out_msg.addr := address; out_msg.Type := CoherenceRequestType:RdBlk; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; } } @@ -775,7 +775,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L out_msg.addr := address; out_msg.Type := CoherenceRequestType:RdBlkS; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; } } @@ -785,7 +785,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L out_msg.addr := address; out_msg.Type := CoherenceRequestType:RdBlkM; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; } } @@ -818,7 +818,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L enqueue(requestToNB_out, CPURequestMsg, issue_latency) { out_msg.addr := address; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.Type := CoherenceRequestType:VicDirty; if (cache_entry.CacheState == State:O) { @@ -834,7 +834,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L enqueue(requestToNB_out, CPURequestMsg, issue_latency) { out_msg.addr := address; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.Type := CoherenceRequestType:VicClean; if (cache_entry.CacheState == State:S) { @@ -1093,7 +1093,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // TCC, L3 respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; out_msg.Hit := false; out_msg.Ntsl := true; @@ -1107,7 +1107,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and TCC respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; out_msg.Ntsl := true; out_msg.Hit := false; @@ -1121,7 +1121,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and TCC respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; // only true if sending back data i think out_msg.Hit := false; out_msg.Ntsl := false; @@ -1138,7 +1138,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := getDataBlock(address); if (is_valid(tbe)) { out_msg.Dirty := tbe.Dirty; @@ -1157,7 +1157,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := getDataBlock(address); if (is_valid(tbe)) { out_msg.Dirty := tbe.Dirty; @@ -1172,7 +1172,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L enqueue(requestToNB_out, CPURequestMsg, issue_latency) { out_msg.addr := address; out_msg.Type := CoherenceRequestType:WrCancel; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Requestor := machineID; out_msg.MessageSize := MessageSizeType:Request_Control; } @@ -1387,7 +1387,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L action(uu_sendUnblock, "uu", desc="state changed, unblock") { enqueue(unblockToNB_out, UnblockMsg, issue_latency) { out_msg.addr := address; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Unblock_Control; DPRINTF(RubySlicc, "%s\n", out_msg); } @@ -1510,7 +1510,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L enqueue(responseToNB_out, ResponseMsg, issue_latency) { out_msg.addr := address; out_msg.Type := CoherenceResponseType:StaleNotif; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Sender := machineID; out_msg.MessageSize := MessageSizeType:Response_Control; } @@ -1521,7 +1521,7 @@ machine(MachineType:TCCdir, "AMD read-for-ownership directory for TCC (aka GPU L out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUData; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; if (tbe.Shared) { diff --git a/src/mem/protocol/GPU_VIPER-TCC.sm b/src/mem/protocol/GPU_VIPER-TCC.sm index f62df9f4f..e21e98030 100644 --- a/src/mem/protocol/GPU_VIPER-TCC.sm +++ b/src/mem/protocol/GPU_VIPER-TCC.sm @@ -366,7 +366,7 @@ machine(MachineType:TCC, "TCC Cache") } enqueue(unblockToNB_out, UnblockMsg, 1) { out_msg.addr := address; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Unblock_Control; DPRINTF(RubySlicc, "%s\n", out_msg); } @@ -380,7 +380,7 @@ machine(MachineType:TCC, "TCC Cache") out_msg.addr := address; out_msg.Type := in_msg.Type; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Shared := false; // unneeded for this request out_msg.MessageSize := in_msg.MessageSize; DPRINTF(RubySlicc, "%s\n", out_msg); @@ -479,7 +479,7 @@ machine(MachineType:TCC, "TCC Cache") out_msg.addr := address; out_msg.Requestor := machineID; out_msg.WTRequestor := in_msg.Requestor; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Data; out_msg.Type := CoherenceRequestType:WriteThrough; out_msg.Dirty := true; @@ -494,7 +494,7 @@ machine(MachineType:TCC, "TCC Cache") out_msg.addr := address; out_msg.Requestor := machineID; out_msg.WTRequestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Data; out_msg.Type := CoherenceRequestType:WriteThrough; out_msg.Dirty := true; @@ -509,7 +509,7 @@ machine(MachineType:TCC, "TCC Cache") out_msg.addr := address; out_msg.Requestor := machineID; out_msg.WTRequestor := in_msg.Requestor; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Data; out_msg.Type := CoherenceRequestType:Atomic; out_msg.Dirty := true; @@ -523,7 +523,7 @@ machine(MachineType:TCC, "TCC Cache") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // TCC, L3 respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; out_msg.Hit := false; out_msg.Ntsl := true; diff --git a/src/mem/protocol/GPU_VIPER_Region-TCC.sm b/src/mem/protocol/GPU_VIPER_Region-TCC.sm index c3aef15a3..b1b599207 100644 --- a/src/mem/protocol/GPU_VIPER_Region-TCC.sm +++ b/src/mem/protocol/GPU_VIPER_Region-TCC.sm @@ -384,7 +384,7 @@ machine(MachineType:TCC, "TCC Cache") } enqueue(unblockToNB_out, UnblockMsg, 1) { out_msg.addr := address; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Unblock_Control; DPRINTF(RubySlicc, "%s\n", out_msg); } @@ -555,7 +555,7 @@ machine(MachineType:TCC, "TCC Cache") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // TCC, L3 respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; out_msg.Hit := false; out_msg.Ntsl := true; diff --git a/src/mem/protocol/Garnet_standalone-cache.sm b/src/mem/protocol/Garnet_standalone-cache.sm index 301c6d17b..a34c7676d 100644 --- a/src/mem/protocol/Garnet_standalone-cache.sm +++ b/src/mem/protocol/Garnet_standalone-cache.sm @@ -69,6 +69,7 @@ machine(MachineType:L1Cache, "Garnet_standalone L1 Cache") // FUNCTIONS Tick clockEdge(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); // cpu/testers/networktest/networktest.cc generates packets of the type // ReadReq, INST_FETCH, and WriteReq. @@ -148,7 +149,7 @@ machine(MachineType:L1Cache, "Garnet_standalone L1 Cache") out_msg.addr := address; out_msg.Type := CoherenceRequestType:MSG; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); // To send broadcasts in vnet0 (to emulate broadcast-based protocols), // replace the above line by the following: @@ -163,7 +164,7 @@ machine(MachineType:L1Cache, "Garnet_standalone L1 Cache") out_msg.addr := address; out_msg.Type := CoherenceRequestType:MSG; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Control; } } @@ -173,7 +174,7 @@ machine(MachineType:L1Cache, "Garnet_standalone L1 Cache") out_msg.addr := address; out_msg.Type := CoherenceRequestType:MSG; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Data; } } diff --git a/src/mem/protocol/MESI_Two_Level-L2cache.sm b/src/mem/protocol/MESI_Two_Level-L2cache.sm index d7a88c199..5a8cfae6d 100644 --- a/src/mem/protocol/MESI_Two_Level-L2cache.sm +++ b/src/mem/protocol/MESI_Two_Level-L2cache.sm @@ -158,6 +158,7 @@ machine(MachineType:L2Cache, "MESI Directory L2 Cache CMP") void unset_tbe(); void wakeUpBuffers(Addr a); void profileMsgDelay(int virtualNetworkType, Cycles c); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); // inclusive cache, returns L2 entries only Entry getCacheEntry(Addr addr), return_by_pointer="yes" { @@ -400,7 +401,7 @@ machine(MachineType:L2Cache, "MESI Directory L2 Cache CMP") out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETS; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Control; } } @@ -425,7 +426,7 @@ machine(MachineType:L2Cache, "MESI Directory L2 Cache CMP") out_msg.addr := address; out_msg.Type := CoherenceResponseType:MEMORY_DATA; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := cache_entry.DataBlk; out_msg.Dirty := cache_entry.Dirty; out_msg.MessageSize := MessageSizeType:Response_Data; @@ -437,7 +438,7 @@ machine(MachineType:L2Cache, "MESI Directory L2 Cache CMP") out_msg.addr := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Response_Control; } } @@ -448,7 +449,7 @@ machine(MachineType:L2Cache, "MESI Directory L2 Cache CMP") out_msg.addr := address; out_msg.Type := CoherenceResponseType:MEMORY_DATA; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; out_msg.MessageSize := MessageSizeType:Response_Data; diff --git a/src/mem/protocol/MESI_Two_Level-dma.sm b/src/mem/protocol/MESI_Two_Level-dma.sm index ecda3bd03..73a1fa216 100644 --- a/src/mem/protocol/MESI_Two_Level-dma.sm +++ b/src/mem/protocol/MESI_Two_Level-dma.sm @@ -69,6 +69,7 @@ machine(MachineType:DMA, "DMA Controller") TBETable TBEs, template="", constructor="m_number_of_TBEs"; Tick clockEdge(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); State getState(TBE tbe, Addr addr) { if (is_valid(tbe)) { @@ -138,7 +139,7 @@ machine(MachineType:DMA, "DMA Controller") out_msg.Type := CoherenceRequestType:DMA_READ; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -151,7 +152,7 @@ machine(MachineType:DMA, "DMA Controller") out_msg.Type := CoherenceRequestType:DMA_WRITE; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm index 0e3e6e1eb..b8036c123 100644 --- a/src/mem/protocol/MI_example-cache.sm +++ b/src/mem/protocol/MI_example-cache.sm @@ -110,6 +110,7 @@ machine(MachineType:L1Cache, "MI Example L1 Cache") void set_tbe(TBE b); void unset_tbe(); void profileMsgDelay(int virtualNetworkType, Cycles b); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); Entry getCacheEntry(Addr address), return_by_pointer="yes" { return static_cast(Entry, "pointer", cacheMemory.lookup(address)); @@ -272,7 +273,7 @@ machine(MachineType:L1Cache, "MI Example L1 Cache") out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETX; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Control; } } @@ -283,7 +284,7 @@ machine(MachineType:L1Cache, "MI Example L1 Cache") out_msg.addr := address; out_msg.Type := CoherenceRequestType:PUTX; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := cache_entry.DataBlk; out_msg.MessageSize := MessageSizeType:Data; } diff --git a/src/mem/protocol/MI_example-dma.sm b/src/mem/protocol/MI_example-dma.sm index aebdce81c..85d0b7f7d 100644 --- a/src/mem/protocol/MI_example-dma.sm +++ b/src/mem/protocol/MI_example-dma.sm @@ -69,6 +69,7 @@ machine(MachineType:DMA, "DMA Controller") TBETable TBEs, template="", constructor="m_number_of_TBEs"; Tick clockEdge(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); State getState(TBE tbe, Addr addr) { if (is_valid(tbe)) { @@ -138,7 +139,7 @@ machine(MachineType:DMA, "DMA Controller") out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -153,7 +154,7 @@ machine(MachineType:DMA, "DMA Controller") out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } diff --git a/src/mem/protocol/MOESI_AMD_Base-CorePair.sm b/src/mem/protocol/MOESI_AMD_Base-CorePair.sm index 76fe77230..b77f3723a 100644 --- a/src/mem/protocol/MOESI_AMD_Base-CorePair.sm +++ b/src/mem/protocol/MOESI_AMD_Base-CorePair.sm @@ -230,6 +230,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") void wakeUpAllBuffers(); void wakeUpBuffers(Addr a); Cycles curCycle(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); // END STRUCTURE DEFINITIONS @@ -690,7 +691,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceRequestType:RdBlk; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); DPRINTF(RubySlicc,"%s\n",out_msg.Destination); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.InitialRequestTime := curCycle(); @@ -702,7 +703,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceRequestType:RdBlkM; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.InitialRequestTime := curCycle(); } @@ -713,7 +714,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceRequestType:RdBlkS; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.InitialRequestTime := curCycle(); } @@ -726,7 +727,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") assert(is_valid(cache_entry)); out_msg.DataBlk := cache_entry.DataBlk; assert(cache_entry.Dirty); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.Type := CoherenceRequestType:VicDirty; out_msg.InitialRequestTime := curCycle(); @@ -742,7 +743,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") enqueue(requestNetwork_out, CPURequestMsg, issue_latency) { out_msg.addr := address; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.Type := CoherenceRequestType:VicClean; out_msg.InitialRequestTime := curCycle(); @@ -1104,7 +1105,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:StaleNotif; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Response_Control; DPRINTF(RubySlicc, "%s\n", out_msg); } @@ -1117,7 +1118,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUData; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; if (tbe.Shared) { @@ -1137,7 +1138,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; out_msg.Hit := false; out_msg.Ntsl := true; @@ -1151,7 +1153,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; out_msg.Ntsl := true; out_msg.Hit := false; @@ -1165,7 +1168,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); assert(addressInCore(address) || is_valid(tbe)); out_msg.Dirty := false; // only true if sending back data i think out_msg.Hit := true; @@ -1180,7 +1184,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); if (addressInCore(address)) { out_msg.Hit := true; } else { @@ -1199,7 +1204,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := cache_entry.DataBlk; assert(cache_entry.Dirty); out_msg.Dirty := true; @@ -1215,7 +1221,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := cache_entry.DataBlk; assert(cache_entry.Dirty); out_msg.Dirty := true; @@ -1231,7 +1238,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := tbe.DataBlk; assert(tbe.Dirty); out_msg.Dirty := true; @@ -1249,7 +1256,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") action(uu_sendUnblock, "uu", desc="state changed, unblock") { enqueue(unblockNetwork_out, UnblockMsg, issue_latency) { out_msg.addr := address; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Unblock_Control; DPRINTF(RubySlicc, "%s\n", out_msg); } diff --git a/src/mem/protocol/MOESI_AMD_Base-L3cache.sm b/src/mem/protocol/MOESI_AMD_Base-L3cache.sm index 479cf4e78..9035ae87a 100644 --- a/src/mem/protocol/MOESI_AMD_Base-L3cache.sm +++ b/src/mem/protocol/MOESI_AMD_Base-L3cache.sm @@ -155,7 +155,7 @@ machine(MachineType:L3Cache, "L3") void unset_tbe(); void wakeUpAllBuffers(); void wakeUpBuffers(Addr a); - + MachineID mapAddressToMachine(Addr addr, MachineType mtype); // FUNCTION DEFINITIONS Tick clockEdge(); @@ -405,7 +405,7 @@ machine(MachineType:L3Cache, "L3") out_msg.addr := address; out_msg.Type := in_msg.Type; out_msg.Requestor := in_msg.Requestor; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Shared := false; // unneeded for this request out_msg.MessageSize := in_msg.MessageSize; DPRINTF(RubySlicc, "%s\n", out_msg); @@ -433,7 +433,7 @@ machine(MachineType:L3Cache, "L3") out_msg.addr := address; out_msg.Type := CoherenceRequestType:VicDirty; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; } } @@ -455,7 +455,8 @@ machine(MachineType:L3Cache, "L3") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; out_msg.Hit := false; out_msg.Ntsl := true; @@ -469,7 +470,8 @@ machine(MachineType:L3Cache, "L3") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; out_msg.Hit := true; out_msg.Ntsl := false; @@ -483,7 +485,8 @@ machine(MachineType:L3Cache, "L3") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; out_msg.Hit := false; out_msg.Ntsl := false; @@ -497,7 +500,8 @@ machine(MachineType:L3Cache, "L3") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := cache_entry.DataBlk; assert(cache_entry.Dirty); out_msg.Dirty := true; @@ -512,7 +516,7 @@ machine(MachineType:L3Cache, "L3") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := tbe.DataBlk; assert(tbe.Dirty); out_msg.Dirty := true; @@ -528,7 +532,7 @@ machine(MachineType:L3Cache, "L3") out_msg.addr := address; out_msg.Type := CoherenceRequestType:WrCancel; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; } } @@ -571,7 +575,7 @@ machine(MachineType:L3Cache, "L3") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUData; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; if (tbe.Shared) { @@ -595,7 +599,7 @@ machine(MachineType:L3Cache, "L3") action(uu_sendUnblock, "uu", desc="state changed, unblock") { enqueue(unblockNetwork_out, UnblockMsg, l3_request_latency) { out_msg.addr := address; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Unblock_Control; DPRINTF(RubySlicc, "%s\n", out_msg); } diff --git a/src/mem/protocol/MOESI_AMD_Base-Region-CorePair.sm b/src/mem/protocol/MOESI_AMD_Base-Region-CorePair.sm index fd84447a2..6046b6f9f 100644 --- a/src/mem/protocol/MOESI_AMD_Base-Region-CorePair.sm +++ b/src/mem/protocol/MOESI_AMD_Base-Region-CorePair.sm @@ -237,6 +237,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") void wakeUpAllBuffers(); void wakeUpBuffers(Addr a); Cycles curCycle(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); // END STRUCTURE DEFINITIONS @@ -1119,7 +1120,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:StaleNotif; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Response_Control; DPRINTF(RubySlicc, "%s\n", out_msg); } @@ -1201,7 +1202,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUData; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; if (tbe.Shared) { @@ -1221,7 +1222,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; out_msg.Hit := false; out_msg.Ntsl := true; @@ -1236,7 +1238,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; out_msg.Ntsl := true; out_msg.Hit := false; @@ -1252,7 +1255,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); assert(addressInCore(address) || is_valid(tbe)); out_msg.Dirty := false; // only true if sending back data i think out_msg.Hit := true; @@ -1268,7 +1272,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); if (addressInCore(address)) { out_msg.Hit := true; } else { @@ -1288,7 +1293,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := cache_entry.DataBlk; assert(cache_entry.Dirty); out_msg.Dirty := true; @@ -1305,7 +1311,8 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := cache_entry.DataBlk; assert(cache_entry.Dirty); out_msg.Dirty := true; @@ -1323,7 +1330,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := tbe.DataBlk; assert(tbe.Dirty); out_msg.Dirty := true; @@ -1358,7 +1365,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") enqueue(responseNetwork_out, ResponseMsg, issue_latency) { out_msg.addr := address; out_msg.Type := CoherenceResponseType:CPUCancelWB; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Sender := machineID; out_msg.MessageSize := MessageSizeType:Response_Control; } @@ -1372,7 +1379,7 @@ machine(MachineType:CorePair, "CP-like Core Coherence") action(uu_sendUnblock, "uu", desc="state changed, unblock") { enqueue(unblockNetwork_out, UnblockMsg, issue_latency) { out_msg.addr := address; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Unblock_Control; out_msg.wasValid := isValid(address); DPRINTF(RubySlicc, "%s\n", out_msg); diff --git a/src/mem/protocol/MOESI_AMD_Base-Region-dir.sm b/src/mem/protocol/MOESI_AMD_Base-Region-dir.sm index 52d87fb8b..328e1a5da 100644 --- a/src/mem/protocol/MOESI_AMD_Base-Region-dir.sm +++ b/src/mem/protocol/MOESI_AMD_Base-Region-dir.sm @@ -817,7 +817,7 @@ machine(MachineType:Directory, "AMD_Base-like protocol") enqueue(responseNetwork_out, ResponseMsg, response_latency_regionDir) { out_msg.addr := address; out_msg.Type := CoherenceResponseType:DirReadyAck; - out_msg.Destination.add(map_Address_to_RegionDir(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.Sender := machineID; out_msg.MessageSize := MessageSizeType:Writeback_Control; } @@ -1205,10 +1205,10 @@ machine(MachineType:Directory, "AMD_Base-like protocol") out_msg.addr := address; out_msg.Type := in_msg.Type; out_msg.Requestor := in_msg.Requestor; - out_msg.Destination.add(map_Address_to_RegionDir(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.Shared := in_msg.Shared; out_msg.MessageSize := in_msg.MessageSize; - DPRINTF(RubySlicc, "out dest: %s\n", map_Address_to_RegionDir(address)); + DPRINTF(RubySlicc, "out dest: %s\n", mapAddressToMachine(address, MachineType:RegionDir)); } } } diff --git a/src/mem/protocol/MOESI_AMD_Base-RegionBuffer.sm b/src/mem/protocol/MOESI_AMD_Base-RegionBuffer.sm index 89f7d6fcb..ab424e1b9 100644 --- a/src/mem/protocol/MOESI_AMD_Base-RegionBuffer.sm +++ b/src/mem/protocol/MOESI_AMD_Base-RegionBuffer.sm @@ -197,6 +197,7 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") void wakeUpAllBuffers(); void wakeUpBuffers(Addr a); Cycles curCycle(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); int blockBits, default="RubySystem::getBlockSizeBits()"; int blockBytes, default="RubySystem::getBlockSizeBytes()"; @@ -493,7 +494,7 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.Dirty := in_msg.Dirty; out_msg.Requestor := in_msg.Requestor; out_msg.WTRequestor := in_msg.WTRequestor; - out_msg.Destination.add(map_Address_to_Directory(in_msg.addr)); + out_msg.Destination.add(mapAddressToMachine(in_msg.addr, MachineType:Directory)); out_msg.Shared := in_msg.Shared; out_msg.MessageSize := in_msg.MessageSize; out_msg.Private := true; @@ -591,7 +592,7 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.WTRequestor := in_msg.WTRequestor; out_msg.InitialRequestTime := curCycle(); // will this always be ok? probably not for multisocket - out_msg.Destination.add(map_Address_to_RegionDir(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.MessageSize := MessageSizeType:Request_Control; DPRINTF(RubySlicc, "Private request %s\n", out_msg); } @@ -613,7 +614,7 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.WTRequestor := in_msg.WTRequestor; out_msg.InitialRequestTime := curCycle(); // will this always be ok? probably not for multisocket - out_msg.Destination.add(map_Address_to_RegionDir(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.MessageSize := MessageSizeType:Request_Control; } cache_entry.ProbeRequestTime := curCycle(); @@ -628,7 +629,8 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.addr := getRegionBase(address); // use the actual address so the demand request can be fulfilled out_msg.Type := CoherenceRequestType:CleanWbRequest; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_RegionDir(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.Dirty := tbe.dirty; APPEND_TRANSITION_COMMENT(getRegionBase(address)); @@ -647,7 +649,7 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.WTRequestor := in_msg.WTRequestor; out_msg.InitialRequestTime := curCycle(); // will this always be ok? probably not for multisocket - out_msg.Destination.add(map_Address_to_RegionDir(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.MessageSize := MessageSizeType:Request_Control; } cache_entry.ProbeRequestTime := curCycle(); @@ -663,7 +665,8 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.addr := getRegionBase(address); out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_RegionDir(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.MessageSize := MessageSizeType:Response_Control; } } @@ -675,7 +678,8 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.addr := tbe.DemandAddress; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := getPeer(machineID,address); - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; // only true if sending back data i think out_msg.Hit := false; out_msg.Ntsl := false; @@ -695,7 +699,8 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; out_msg.NotCached := true; - out_msg.Destination.add(map_Address_to_RegionDir(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.MessageSize := MessageSizeType:Response_Control; out_msg.Dirty := tbe.dirty; } @@ -706,7 +711,8 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.addr := getRegionBase(address); out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_RegionDir(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.MessageSize := MessageSizeType:Response_Control; } } @@ -717,7 +723,8 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.Type := CoherenceResponseType:CPUPrbResp; out_msg.Sender := machineID; out_msg.NotCached := true; - out_msg.Destination.add(map_Address_to_RegionDir(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.MessageSize := MessageSizeType:Response_Control; } } @@ -727,7 +734,8 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.addr := getRegionBase(address); out_msg.Type := CoherenceResponseType:PrivateAck; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_RegionDir(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.MessageSize := MessageSizeType:Response_Control; } } @@ -739,7 +747,8 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.addr := getRegionBase(address); out_msg.Type := CoherenceResponseType:RegionWbAck; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_RegionDir(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir)); out_msg.MessageSize := MessageSizeType:Response_Control; } } @@ -810,7 +819,8 @@ machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol") out_msg.addr := in_msg.DemandAddress; out_msg.Type := CoherenceResponseType:CPUPrbResp; // L3 and CPUs respond in same way to probes out_msg.Sender := getPeer(machineID,address); - out_msg.Destination.add(map_Address_to_Directory(address)); // will this always be ok? probably not for multisocket + // will this always be ok? probably not for multisocket + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := false; // only true if sending back data i think out_msg.Hit := false; out_msg.Ntsl := false; diff --git a/src/mem/protocol/MOESI_AMD_Base-RegionDir.sm b/src/mem/protocol/MOESI_AMD_Base-RegionDir.sm index b392311c5..0ad335740 100644 --- a/src/mem/protocol/MOESI_AMD_Base-RegionDir.sm +++ b/src/mem/protocol/MOESI_AMD_Base-RegionDir.sm @@ -171,6 +171,7 @@ machine(MachineType:RegionDir, "Region Directory for AMD_Base-like protocol") void wakeUpAllBuffers(); void wakeUpBuffers(Addr a); Cycles curCycle(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); int blockBits, default="RubySystem::getBlockSizeBits()"; int blockBytes, default="RubySystem::getBlockSizeBytes()"; @@ -479,7 +480,7 @@ machine(MachineType:RegionDir, "Region Directory for AMD_Base-like protocol") out_msg.Dirty := in_msg.Dirty; out_msg.Requestor := getCoreMachine(in_msg.Requestor,address); out_msg.WTRequestor := in_msg.WTRequestor; - out_msg.Destination.add(map_Address_to_Directory(in_msg.addr)); + out_msg.Destination.add(mapAddressToMachine(in_msg.addr, MachineType:Directory)); out_msg.Shared := in_msg.Shared; out_msg.MessageSize := in_msg.MessageSize; out_msg.Private := in_msg.Private; @@ -505,7 +506,7 @@ machine(MachineType:RegionDir, "Region Directory for AMD_Base-like protocol") out_msg.Dirty := in_msg.Dirty; out_msg.Requestor := getCoreMachine(in_msg.Requestor,address); out_msg.WTRequestor := in_msg.WTRequestor; - out_msg.Destination.add(map_Address_to_Directory(in_msg.addr)); + out_msg.Destination.add(mapAddressToMachine(in_msg.addr, MachineType:Directory)); out_msg.Shared := in_msg.Shared; out_msg.MessageSize := in_msg.MessageSize; out_msg.Private := in_msg.Private; @@ -532,7 +533,7 @@ machine(MachineType:RegionDir, "Region Directory for AMD_Base-like protocol") out_msg.Dirty := in_msg.Dirty; out_msg.Requestor := getCoreMachine(in_msg.Requestor,address); out_msg.WTRequestor := in_msg.WTRequestor; - out_msg.Destination.add(map_Address_to_Directory(in_msg.addr)); + out_msg.Destination.add(mapAddressToMachine(in_msg.addr, MachineType:Directory)); out_msg.Shared := in_msg.Shared; out_msg.MessageSize := in_msg.MessageSize; out_msg.Private := in_msg.Private; @@ -562,7 +563,7 @@ machine(MachineType:RegionDir, "Region Directory for AMD_Base-like protocol") out_msg.Dirty := in_msg.Dirty; out_msg.Requestor := getCoreMachine(in_msg.Requestor,address); out_msg.WTRequestor := in_msg.WTRequestor; - out_msg.Destination.add(map_Address_to_Directory(in_msg.addr)); + out_msg.Destination.add(mapAddressToMachine(in_msg.addr, MachineType:Directory)); out_msg.Shared := in_msg.Shared; out_msg.MessageSize := in_msg.MessageSize; out_msg.Private := in_msg.Private; diff --git a/src/mem/protocol/MOESI_AMD_Base-probeFilter.sm b/src/mem/protocol/MOESI_AMD_Base-probeFilter.sm index f545c2fa7..88d73d18b 100644 --- a/src/mem/protocol/MOESI_AMD_Base-probeFilter.sm +++ b/src/mem/protocol/MOESI_AMD_Base-probeFilter.sm @@ -201,6 +201,7 @@ machine(MachineType:Directory, "AMD Baseline protocol") void wakeUpAllBuffers(); void wakeUpBuffers(Addr a); Cycles curCycle(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); Entry getDirectoryEntry(Addr addr), return_by_pointer="yes" { Entry dir_entry := static_cast(Entry, "pointer", directory.lookup(addr)); @@ -652,7 +653,7 @@ machine(MachineType:Directory, "AMD Baseline protocol") out_msg.Destination.add(mapAddressToRange(address,MachineType:TCC, TCC_select_low_bit, TCC_select_num_bits)); } else { - out_msg.Destination.add(map_Address_to_TCCdir(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:TCCdir)); } } out_msg.Destination.remove(in_msg.Requestor); @@ -686,7 +687,7 @@ machine(MachineType:Directory, "AMD Baseline protocol") if (noTCCdir) { //Don't need to notify TCC about reads } else { - out_msg.Destination.add(map_Address_to_TCCdir(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:TCCdir)); tbe.NumPendingAcks := tbe.NumPendingAcks + 1; } if (noTCCdir && CAB_TCC) { @@ -724,7 +725,7 @@ machine(MachineType:Directory, "AMD Baseline protocol") if (noTCCdir) { //Don't need to notify TCC about reads } else { - out_msg.Destination.add(map_Address_to_TCCdir(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:TCCdir)); tbe.NumPendingAcks := tbe.NumPendingAcks + 1; } if (noTCCdir && CAB_TCC) { @@ -765,7 +766,7 @@ machine(MachineType:Directory, "AMD Baseline protocol") out_msg.Destination.add(mapAddressToRange(address,MachineType:TCC, TCC_select_low_bit, TCC_select_num_bits)); } else { - out_msg.Destination.add(map_Address_to_TCCdir(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:TCCdir)); } } out_msg.Destination.remove(in_msg.Requestor); diff --git a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm index 4db262cb0..6d71367ca 100644 --- a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm +++ b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm @@ -233,6 +233,7 @@ machine(MachineType:L2Cache, "Token protocol") void unset_cache_entry(); void set_tbe(TBE b); void unset_tbe(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); Entry getCacheEntry(Addr address), return_by_pointer="yes" { return static_cast(Entry, "pointer", L2cache[address]); @@ -730,7 +731,7 @@ machine(MachineType:L2Cache, "Token protocol") out_msg.Type := CoherenceRequestType:GETS; out_msg.RequestorMachine := MachineType:L2Cache; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; } } @@ -743,7 +744,7 @@ machine(MachineType:L2Cache, "Token protocol") out_msg.Type := CoherenceRequestType:GETX; out_msg.RequestorMachine := MachineType:L2Cache; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; } } @@ -755,7 +756,7 @@ machine(MachineType:L2Cache, "Token protocol") out_msg.Type := CoherenceRequestType:PUTX; out_msg.RequestorMachine := MachineType:L2Cache; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -766,7 +767,7 @@ machine(MachineType:L2Cache, "Token protocol") out_msg.Type := CoherenceRequestType:PUTO; out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:L2Cache; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -778,7 +779,7 @@ machine(MachineType:L2Cache, "Token protocol") out_msg.Type := CoherenceRequestType:PUTO_SHARERS; out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:L2Cache; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -1147,7 +1148,7 @@ machine(MachineType:L2Cache, "Token protocol") enqueue(responseNetwork_out, ResponseMsg, response_latency) { out_msg.addr := address; out_msg.Type := CoherenceResponseType:UNBLOCK; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; out_msg.MessageSize := MessageSizeType:Unblock_Control; @@ -1159,7 +1160,7 @@ machine(MachineType:L2Cache, "Token protocol") enqueue(responseNetwork_out, ResponseMsg, response_latency) { out_msg.addr := address; out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; out_msg.MessageSize := MessageSizeType:Unblock_Control; @@ -1432,7 +1433,7 @@ machine(MachineType:L2Cache, "Token protocol") out_msg.addr := address; out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := tbe.Dirty; if (tbe.Dirty) { out_msg.Type := CoherenceResponseType:WRITEBACK_DIRTY_DATA; @@ -1561,7 +1562,7 @@ machine(MachineType:L2Cache, "Token protocol") enqueue(responseNetwork_out, ResponseMsg, response_latency) { out_msg.addr := address; out_msg.Type := CoherenceResponseType:DMA_ACK; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:L2Cache; out_msg.MessageSize := MessageSizeType:Unblock_Control; diff --git a/src/mem/protocol/MOESI_CMP_directory-dma.sm b/src/mem/protocol/MOESI_CMP_directory-dma.sm index b9da0d0dc..f3f91671f 100644 --- a/src/mem/protocol/MOESI_CMP_directory-dma.sm +++ b/src/mem/protocol/MOESI_CMP_directory-dma.sm @@ -78,6 +78,7 @@ machine(MachineType:DMA, "DMA Controller") void set_tbe(TBE b); void unset_tbe(); void wakeUpAllBuffers(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); State getState(TBE tbe, Addr addr) { return cur_state; @@ -161,7 +162,7 @@ machine(MachineType:DMA, "DMA Controller") out_msg.Type := CoherenceRequestType:DMA_READ; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:DMA; out_msg.MessageSize := MessageSizeType:Writeback_Control; @@ -176,7 +177,7 @@ machine(MachineType:DMA, "DMA Controller") out_msg.Type := CoherenceRequestType:DMA_WRITE; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Requestor := machineID; out_msg.RequestorMachine := MachineType:DMA; out_msg.MessageSize := MessageSizeType:Writeback_Control; @@ -209,7 +210,7 @@ machine(MachineType:DMA, "DMA Controller") enqueue(respToDirectory_out, ResponseMsg, response_latency) { out_msg.addr := address; out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:DMA; out_msg.MessageSize := MessageSizeType:Writeback_Control; diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm index 7961aa3be..db06fb591 100644 --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -193,6 +193,7 @@ machine(MachineType:L1Cache, "Token protocol") void wakeUpAllBuffers(); void wakeUpBuffers(Addr a); Cycles curCycle(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); TBETable L1_TBEs, template="", constructor="m_number_of_TBEs"; @@ -766,7 +767,7 @@ machine(MachineType:L1Cache, "Token protocol") MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := tbe.Prefetch; out_msg.AccessMode := tbe.AccessMode; @@ -888,7 +889,7 @@ machine(MachineType:L1Cache, "Token protocol") MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := tbe.Prefetch; out_msg.AccessMode := tbe.AccessMode; @@ -992,7 +993,7 @@ machine(MachineType:L1Cache, "Token protocol") out_msg.addr := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Tokens := in_msg.Tokens; out_msg.MessageSize := in_msg.MessageSize; out_msg.DataBlk := in_msg.DataBlk; @@ -1458,7 +1459,7 @@ machine(MachineType:L1Cache, "Token protocol") MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Persistent_Control; } starving := false; diff --git a/src/mem/protocol/MOESI_CMP_token-L2cache.sm b/src/mem/protocol/MOESI_CMP_token-L2cache.sm index c9995011d..7911179c2 100644 --- a/src/mem/protocol/MOESI_CMP_token-L2cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L2cache.sm @@ -152,6 +152,7 @@ machine(MachineType:L2Cache, "Token protocol") Tick clockEdge(); void set_cache_entry(AbstractCacheEntry b); void unset_cache_entry(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); Entry getCacheEntry(Addr address), return_by_pointer="yes" { Entry cache_entry := static_cast(Entry, "pointer", L2cache.lookup(address)); @@ -522,7 +523,7 @@ machine(MachineType:L2Cache, "Token protocol") //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address)); //out_msg.Destination.remove(map_L1CacheMachId_to_L2Cache(address, in_msg.Requestor)); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.AccessMode := in_msg.AccessMode; out_msg.Prefetch := in_msg.Prefetch; @@ -541,7 +542,7 @@ machine(MachineType:L2Cache, "Token protocol") out_msg.addr := address; out_msg.Type := in_msg.Type; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Tokens := in_msg.Tokens; out_msg.MessageSize := in_msg.MessageSize; out_msg.DataBlk := in_msg.DataBlk; @@ -557,7 +558,7 @@ machine(MachineType:L2Cache, "Token protocol") out_msg.addr := address; out_msg.Type := CoherenceResponseType:ACK; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Tokens := cache_entry.Tokens; out_msg.MessageSize := MessageSizeType:Writeback_Control; } @@ -570,7 +571,7 @@ machine(MachineType:L2Cache, "Token protocol") enqueue(responseNetwork_out, ResponseMsg, l2_response_latency) { out_msg.addr := address; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Tokens := cache_entry.Tokens; out_msg.DataBlk := cache_entry.DataBlk; out_msg.Dirty := cache_entry.Dirty; diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm index c3a585b96..1a749b18d 100644 --- a/src/mem/protocol/MOESI_CMP_token-dir.sm +++ b/src/mem/protocol/MOESI_CMP_token-dir.sm @@ -176,6 +176,7 @@ machine(MachineType:Directory, "Token protocol") Tick cyclesToTicks(Cycles c); void set_tbe(TBE b); void unset_tbe(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); Entry getDirectoryEntry(Addr addr), return_by_pointer="yes" { Entry dir_entry := static_cast(Entry, "pointer", directory[addr]); @@ -475,7 +476,7 @@ machine(MachineType:Directory, "Token protocol") MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := PrefetchBit:No; out_msg.AccessMode := RubyAccessMode:Supervisor; @@ -543,7 +544,7 @@ machine(MachineType:Directory, "Token protocol") MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Persistent_Control; out_msg.Prefetch := PrefetchBit:No; out_msg.AccessMode := RubyAccessMode:Supervisor; @@ -724,7 +725,7 @@ machine(MachineType:Directory, "Token protocol") MachineType:L2Cache, l2_select_low_bit, l2_select_num_bits, intToID(0))); - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Persistent_Control; } starving := false; diff --git a/src/mem/protocol/MOESI_CMP_token-dma.sm b/src/mem/protocol/MOESI_CMP_token-dma.sm index 01152100b..e48b871f2 100644 --- a/src/mem/protocol/MOESI_CMP_token-dma.sm +++ b/src/mem/protocol/MOESI_CMP_token-dma.sm @@ -71,6 +71,7 @@ machine(MachineType:DMA, "DMA Controller") TBETable TBEs, template="", constructor="m_number_of_TBEs"; Tick clockEdge(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); State getState(TBE tbe, Addr addr) { if (is_valid(tbe)) { @@ -140,7 +141,7 @@ machine(MachineType:DMA, "DMA Controller") out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -155,7 +156,7 @@ machine(MachineType:DMA, "DMA Controller") out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm index 9b2e4cab3..9cbd277d4 100644 --- a/src/mem/protocol/MOESI_hammer-cache.sm +++ b/src/mem/protocol/MOESI_hammer-cache.sm @@ -188,6 +188,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") void wakeUpAllBuffers(); void wakeUpBuffers(Addr a); Cycles curCycle(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); Entry getCacheEntry(Addr address), return_by_pointer="yes" { Entry L2cache_entry := static_cast(Entry, "pointer", L2cache.lookup(address)); @@ -554,7 +555,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETS; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.InitialRequestTime := curCycle(); @@ -569,7 +570,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETX; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.InitialRequestTime := curCycle(); @@ -585,7 +586,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETX; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.InitialRequestTime := curCycle(); } @@ -601,7 +602,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") out_msg.addr := address; out_msg.Type := CoherenceRequestType:GETF; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Request_Control; out_msg.InitialRequestTime := curCycle(); @@ -661,7 +662,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") out_msg.addr := address; out_msg.Type := CoherenceRequestType:PUT; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -671,7 +672,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") out_msg.addr := address; out_msg.Type := CoherenceRequestType:PUTF; out_msg.Requestor := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -826,7 +827,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") out_msg.addr := address; out_msg.Type := CoherenceResponseType:UNBLOCK; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Unblock_Control; } } @@ -836,7 +837,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") out_msg.addr := address; out_msg.Type := CoherenceResponseType:UNBLOCKM; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Unblock_Control; } } @@ -848,7 +849,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") out_msg.Type := CoherenceResponseType:UNBLOCKS; out_msg.Sender := machineID; out_msg.CurOwner := tbe.CurOwner; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Unblock_Control; } } @@ -1126,7 +1127,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") assert(is_valid(tbe)); out_msg.addr := address; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.Dirty := tbe.Dirty; if (tbe.Dirty) { out_msg.Type := CoherenceResponseType:WB_DIRTY; @@ -1157,7 +1158,7 @@ machine(MachineType:L1Cache, "AMD Hammer-like protocol") assert(is_valid(tbe)); out_msg.addr := address; out_msg.Sender := machineID; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.DataBlk := tbe.DataBlk; out_msg.Dirty := tbe.Dirty; if (tbe.Dirty) { diff --git a/src/mem/protocol/MOESI_hammer-dma.sm b/src/mem/protocol/MOESI_hammer-dma.sm index 0e4b4f663..6a4c5ace4 100644 --- a/src/mem/protocol/MOESI_hammer-dma.sm +++ b/src/mem/protocol/MOESI_hammer-dma.sm @@ -69,6 +69,7 @@ machine(MachineType:DMA, "DMA Controller") TBETable TBEs, template="", constructor="m_number_of_TBEs"; Tick clockEdge(); + MachineID mapAddressToMachine(Addr addr, MachineType mtype); State getState(TBE tbe, Addr addr) { if (is_valid(tbe)) { @@ -138,7 +139,7 @@ machine(MachineType:DMA, "DMA Controller") out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -153,7 +154,7 @@ machine(MachineType:DMA, "DMA Controller") out_msg.Requestor := machineID; out_msg.DataBlk := in_msg.DataBlk; out_msg.Len := in_msg.Len; - out_msg.Destination.add(map_Address_to_Directory(address)); + out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory)); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } diff --git a/src/mem/protocol/RubySlicc_ComponentMapping.sm b/src/mem/protocol/RubySlicc_ComponentMapping.sm index e1d7c4399..673c99f22 100644 --- a/src/mem/protocol/RubySlicc_ComponentMapping.sm +++ b/src/mem/protocol/RubySlicc_ComponentMapping.sm @@ -36,11 +36,6 @@ MachineID mapAddressToRange(Addr addr, MachineType type, int low, int high, NodeID n); NetDest broadcast(MachineType type); MachineID map_Address_to_DMA(Addr addr); -MachineID map_Address_to_Directory(Addr addr); -MachineID map_Address_to_RegionDir(Addr addr); -NodeID map_Address_to_DirectoryNode(Addr addr); -MachineID map_Address_to_TCCdir(Addr addr); -NodeID map_Address_to_TCCdirNode(Addr addr); NodeID machineIDToNodeID(MachineID machID); NodeID machineIDToVersion(MachineID machID); MachineType machineIDToMachineType(MachineID machID); diff --git a/src/mem/ruby/network/Network.cc b/src/mem/ruby/network/Network.cc index e9b28a731..1761218b0 100644 --- a/src/mem/ruby/network/Network.cc +++ b/src/mem/ruby/network/Network.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2017 ARM Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. * @@ -29,6 +41,7 @@ #include "mem/ruby/network/Network.hh" #include "base/misc.hh" +#include "mem/ruby/common/MachineID.hh" #include "mem/ruby/network/BasicLink.hh" #include "mem/ruby/system/RubySystem.hh" @@ -73,6 +86,15 @@ Network::Network(const Params *p) BasicExtLink *ext_link = (*i); AbstractController *abs_cntrl = ext_link->params()->ext_node; abs_cntrl->initNetworkPtr(this); + const AddrRangeList &ranges = abs_cntrl->getAddrRanges(); + if (!ranges.empty()) { + MachineID mid = abs_cntrl->getMachineID(); + AddrMapNode addr_map_node = { + .id = mid.getNum(), + .ranges = ranges + }; + addrMap.emplace(mid.getType(), addr_map_node); + } } // Register a callback function for combining the statistics @@ -172,3 +194,21 @@ Network::setFromNetQueue(NodeID id, bool ordered, int network_num, } m_fromNetQueues[id][network_num] = b; } + +NodeID +Network::addressToNodeID(Addr addr, MachineType mtype) +{ + // Look through the address maps for entries with matching machine + // type to get the responsible node for this address. + const auto &matching_ranges = addrMap.equal_range(mtype); + for (auto it = matching_ranges.first; it != matching_ranges.second; it++) { + AddrMapNode &node = it->second; + auto &ranges = node.ranges; + for (AddrRange &range: ranges) { + if (range.contains(addr)) { + return node.id; + } + } + } + return MachineType_base_count(mtype); +} diff --git a/src/mem/ruby/network/Network.hh b/src/mem/ruby/network/Network.hh index 4c0d4edfc..7f5ed2aae 100644 --- a/src/mem/ruby/network/Network.hh +++ b/src/mem/ruby/network/Network.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2017 ARM Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. * @@ -42,13 +54,17 @@ #include #include +#include #include +#include "base/addr_range.hh" +#include "base/types.hh" +#include "mem/packet.hh" #include "mem/protocol/LinkDirection.hh" #include "mem/protocol/MessageSizeType.hh" +#include "mem/ruby/common/MachineID.hh" #include "mem/ruby/common/TypeDefines.hh" #include "mem/ruby/network/Topology.hh" -#include "mem/packet.hh" #include "params/RubyNetwork.hh" #include "sim/clocked_object.hh" @@ -102,6 +118,20 @@ class Network : public ClockedObject virtual uint32_t functionalWrite(Packet *pkt) { fatal("Functional write not implemented.\n"); } + /** + * Map an address to the correct NodeID + * + * This function traverses the global address map to find the + * NodeID that corresponds to the given address and the type of + * the destination. For example for a request to a directory this + * function will return the NodeID of the right directory. + * + * @param the destination address + * @param the type of the destination + * @return the NodeID of the destination + */ + NodeID addressToNodeID(Addr addr, MachineType mtype); + protected: // Private copy constructor and assignment operator Network(const Network& obj); @@ -137,6 +167,13 @@ class Network : public ClockedObject void process() {ctr->collateStats();} }; + + // Global address map + struct AddrMapNode { + NodeID id; + AddrRangeList ranges; + }; + std::unordered_multimap addrMap; }; inline std::ostream& diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc index 19dca9028..0bc88eefa 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2017 ARM Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2011-2014 Mark D. Hill and David A. Wood * All rights reserved. * @@ -43,7 +55,8 @@ AbstractController::AbstractController(const Params *p) m_number_of_TBEs(p->number_of_TBEs), m_transitions_per_cycle(p->transitions_per_cycle), m_buffer_size(p->buffer_size), m_recycle_latency(p->recycle_latency), - memoryPort(csprintf("%s.memory", name()), this, "") + memoryPort(csprintf("%s.memory", name()), this, ""), + addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()) { if (m_version == 0) { // Combine the statistics from all controllers @@ -347,6 +360,14 @@ AbstractController::recvTimingResp(PacketPtr pkt) delete pkt; } +MachineID +AbstractController::mapAddressToMachine(Addr addr, MachineType mtype) const +{ + NodeID node = m_net_ptr->addressToNodeID(addr, mtype); + MachineID mach = {mtype, node}; + return mach; +} + bool AbstractController::MemoryPort::recvTimingResp(PacketPtr pkt) { diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index e4562145f..354dc80aa 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2017 ARM Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2009-2014 Mark D. Hill and David A. Wood * All rights reserved. * @@ -33,8 +45,12 @@ #include #include +#include "base/addr_range.hh" #include "base/callback.hh" +#include "mem/mem_object.hh" +#include "mem/packet.hh" #include "mem/protocol/AccessPermission.hh" +#include "mem/qport.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/common/DataBlock.hh" @@ -42,10 +58,7 @@ #include "mem/ruby/common/MachineID.hh" #include "mem/ruby/network/MessageBuffer.hh" #include "mem/ruby/system/CacheRecorder.hh" -#include "mem/packet.hh" -#include "mem/qport.hh" #include "params/RubyController.hh" -#include "mem/mem_object.hh" class Network; class GPUCoalescer; @@ -123,6 +136,8 @@ class AbstractController : public MemObject, public Consumer const DataBlock &block, int size); void recvTimingResp(PacketPtr pkt); + const AddrRangeList &getAddrRanges() const { return addrRanges; } + public: MachineID getMachineID() const { return m_machineID; } @@ -130,6 +145,21 @@ class AbstractController : public MemObject, public Consumer Stats::Histogram& getDelayVCHist(uint32_t index) { return *(m_delayVCHistogram[index]); } + /** + * Map an address to the correct MachineID + * + * This function querries the network for the NodeID of the + * destination for a given request using its address and the type + * of the destination. For example for a request with a given + * address to a directory it will return the MachineID of the + * authorative directory. + * + * @param the destination address + * @param the type of the destination + * @return the MachineID of the destination + */ + MachineID mapAddressToMachine(Addr addr, MachineType mtype) const; + protected: //! Profiles original cache requests including PUTs void profileRequest(const std::string &request); @@ -223,6 +253,10 @@ class AbstractController : public MemObject, public Consumer SenderState(MachineID _id) : id(_id) {} }; + + private: + /** The address range to which the controller responds on the CPU side. */ + const AddrRangeList addrRanges; }; #endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__ diff --git a/src/mem/ruby/slicc_interface/Controller.py b/src/mem/ruby/slicc_interface/Controller.py index ba7d17c7c..39a0ea912 100644 --- a/src/mem/ruby/slicc_interface/Controller.py +++ b/src/mem/ruby/slicc_interface/Controller.py @@ -1,3 +1,15 @@ +# Copyright (c) 2017 ARM Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# # Copyright (c) 2009 Advanced Micro Devices, Inc. # All rights reserved. # @@ -37,6 +49,8 @@ class RubyController(MemObject): cxx_header = "mem/ruby/slicc_interface/AbstractController.hh" abstract = True version = Param.Int("") + addr_ranges = VectorParam.AddrRange([AllMemory], "Address range this " + "controller responds to") cluster_id = Param.UInt32(0, "Id of this controller's cluster") transitions_per_cycle = \ diff --git a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh index cdedc2e14..dfc2c73fc 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh @@ -35,46 +35,6 @@ #include "mem/ruby/common/NetDest.hh" #include "mem/ruby/structures/DirectoryMemory.hh" -// used to determine the home directory -// returns a value between 0 and total_directories_within_the_system -inline NodeID -map_Address_to_DirectoryNode(Addr addr) -{ - return DirectoryMemory::mapAddressToDirectoryVersion(addr); -} - -inline NodeID -map_Address_to_TCCdirNode(Addr addr) -{ - return DirectoryMemory::mapAddressToDirectoryVersion(addr); -} - -// used to determine the home directory -// returns a value between 0 and total_directories_within_the_system -inline MachineID -map_Address_to_Directory(Addr addr) -{ - MachineID mach = - {MachineType_Directory, map_Address_to_DirectoryNode(addr)}; - return mach; -} - -inline MachineID -map_Address_to_RegionDir(Addr addr) -{ - MachineID mach = {MachineType_RegionDir, - map_Address_to_DirectoryNode(addr)}; - return mach; -} - -inline MachineID -map_Address_to_TCCdir(Addr addr) -{ - MachineID mach = - {MachineType_TCCdir, map_Address_to_TCCdirNode(addr)}; - return mach; -} - inline NetDest broadcast(MachineType type) { diff --git a/src/mem/ruby/structures/DirectoryMemory.cc b/src/mem/ruby/structures/DirectoryMemory.cc index ee77931d7..551e3f57f 100644 --- a/src/mem/ruby/structures/DirectoryMemory.cc +++ b/src/mem/ruby/structures/DirectoryMemory.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2017 ARM Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * Copyright (c) 2017 Google Inc. * All rights reserved. @@ -31,6 +43,7 @@ #include "mem/ruby/structures/DirectoryMemory.hh" +#include "base/addr_range.hh" #include "base/intmath.hh" #include "debug/RubyCache.hh" #include "debug/RubyStats.hh" @@ -40,25 +53,15 @@ using namespace std; -int DirectoryMemory::m_num_directories = 0; -int DirectoryMemory::m_num_directories_bits = 0; -int DirectoryMemory::m_numa_high_bit = 0; - DirectoryMemory::DirectoryMemory(const Params *p) - : SimObject(p) + : SimObject(p), addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()) { - m_version = p->version; - // In X86, there is an IO gap in the 3-4GB range. - if (p->system->getArch() == Arch::X86ISA && p->size > 0xc0000000){ - // We need to add 1GB to the size for the gap - m_size_bytes = p->size + 0x40000000; - } - else { - m_size_bytes = p->size; + m_size_bytes = 0; + for (const auto &r: addrRanges) { + m_size_bytes += r.size(); } m_size_bits = floorLog2(m_size_bytes); m_num_entries = 0; - m_numa_high_bit = p->numa_high_bit; } void @@ -68,14 +71,6 @@ DirectoryMemory::init() m_entries = new AbstractEntry*[m_num_entries]; for (int i = 0; i < m_num_entries; i++) m_entries[i] = NULL; - - m_num_directories++; - m_num_directories_bits = ceilLog2(m_num_directories); - - if (m_numa_high_bit == 0) { - m_numa_high_bit = RubySystem::getMemorySizeBits() - 1; - } - assert(m_numa_high_bit != 0); } DirectoryMemory::~DirectoryMemory() @@ -89,37 +84,29 @@ DirectoryMemory::~DirectoryMemory() delete [] m_entries; } -uint64_t -DirectoryMemory::mapAddressToDirectoryVersion(Addr address) -{ - if (m_num_directories_bits == 0) - return 0; - - uint64_t ret = bitSelect(address, - m_numa_high_bit - m_num_directories_bits + 1, - m_numa_high_bit); - return ret; -} - bool DirectoryMemory::isPresent(Addr address) { - bool ret = (mapAddressToDirectoryVersion(address) == m_version); - return ret; + for (const auto& r: addrRanges) { + if (r.contains(address)) { + return true; + } + } + return false; } uint64_t DirectoryMemory::mapAddressToLocalIdx(Addr address) { - uint64_t ret; - if (m_num_directories_bits > 0) { - ret = bitRemove(address, m_numa_high_bit - m_num_directories_bits + 1, - m_numa_high_bit); - } else { - ret = address; + uint64_t ret = 0; + for (const auto& r: addrRanges) { + if (r.contains(address)) { + ret += r.getOffset(address); + break; + } + ret += r.size(); } - - return ret >> (RubySystem::getBlockSizeBits()); + return ret >> RubySystem::getBlockSizeBits(); } AbstractEntry* diff --git a/src/mem/ruby/structures/DirectoryMemory.hh b/src/mem/ruby/structures/DirectoryMemory.hh index 98403808b..36defd5e9 100644 --- a/src/mem/ruby/structures/DirectoryMemory.hh +++ b/src/mem/ruby/structures/DirectoryMemory.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2017 ARM Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. * @@ -32,6 +44,7 @@ #include #include +#include "base/addr_range.hh" #include "mem/protocol/DirectoryRequestType.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/slicc_interface/AbstractEntry.hh" @@ -47,8 +60,18 @@ class DirectoryMemory : public SimObject void init(); + /** + * Return the index in the directory based on an address + * + * This function transforms an address which belongs to a not + * necessarily continuous vector of address ranges into a flat + * address that we use to index in the directory + * + * @param an input address + * @return the corresponding index in the directory + * + */ uint64_t mapAddressToLocalIdx(Addr address); - static uint64_t mapAddressToDirectoryVersion(Addr address); uint64_t getSize() { return m_size_bytes; } @@ -72,11 +95,12 @@ class DirectoryMemory : public SimObject uint64_t m_size_bytes; uint64_t m_size_bits; uint64_t m_num_entries; - int m_version; - static int m_num_directories; - static int m_num_directories_bits; - static int m_numa_high_bit; + /** + * The address range for which the directory responds. Normally + * this is all possible memory addresses. + */ + const AddrRangeList addrRanges; }; inline std::ostream& diff --git a/src/mem/ruby/structures/DirectoryMemory.py b/src/mem/ruby/structures/DirectoryMemory.py index 2518380b2..ab9c7235f 100644 --- a/src/mem/ruby/structures/DirectoryMemory.py +++ b/src/mem/ruby/structures/DirectoryMemory.py @@ -1,3 +1,15 @@ +# Copyright (c) 2017 ARM Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# # Copyright (c) 2009 Advanced Micro Devices, Inc. # All rights reserved. # @@ -35,9 +47,5 @@ class RubyDirectoryMemory(SimObject): type = 'RubyDirectoryMemory' cxx_class = 'DirectoryMemory' cxx_header = "mem/ruby/structures/DirectoryMemory.hh" - version = Param.Int(0, "") - size = Param.MemorySize("1GB", "capacity in bytes") - # 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") - system = Param.System(Parent.any, "system object") + addr_ranges = VectorParam.AddrRange( + Parent.addr_ranges, "Address range this directory responds to") diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py index bd92e20c9..e62758305 100644 --- a/src/mem/slicc/symbols/Type.py +++ b/src/mem/slicc/symbols/Type.py @@ -459,6 +459,7 @@ out << "${{dm.ident}} = " << printAddress(m_${{dm.ident}}) << " ";''') code('#include "mem/protocol/AccessPermission.hh"') if self.isMachineType: + code('#include ') code('#include "base/misc.hh"') code('#include "mem/ruby/common/Address.hh"') code('#include "mem/ruby/common/TypeDefines.hh"') @@ -498,6 +499,20 @@ std::string ${{self.c_ident}}_to_string(const ${{self.c_ident}}& obj); ${{self.c_ident}} &operator++(${{self.c_ident}} &e); ''') + if self.isMachineType: + code(''' + +// define a hash function for the MachineType class +namespace std { +template<> +struct hash { + std::size_t operator()(const MachineType &mtype) const { + return hash()(static_cast(mtype)); + } +}; +} + +''') # MachineType hack used to set the base component id for each Machine if self.isMachineType: code(''' -- 2.30.2