configs: Remove Python 2.7 glue code
[gem5.git] / configs / common / CacheConfig.py
1 # Copyright (c) 2012-2013, 2015-2016 ARM Limited
2 # Copyright (c) 2020 Barkhausen Institut
3 # All rights reserved
4 #
5 # The license below extends only to copyright in the software and shall
6 # not be construed as granting a license to any other intellectual
7 # property including but not limited to intellectual property relating
8 # to a hardware implementation of the functionality of the software
9 # licensed hereunder. You may use the software subject to the license
10 # terms below provided that you ensure that this notice is replicated
11 # unmodified and in its entirety in all distributions of the software,
12 # modified or unmodified, in source code or in binary form.
13 #
14 # Copyright (c) 2010 Advanced Micro Devices, Inc.
15 # All rights reserved.
16 #
17 # Redistribution and use in source and binary forms, with or without
18 # modification, are permitted provided that the following conditions are
19 # met: redistributions of source code must retain the above copyright
20 # notice, this list of conditions and the following disclaimer;
21 # redistributions in binary form must reproduce the above copyright
22 # notice, this list of conditions and the following disclaimer in the
23 # documentation and/or other materials provided with the distribution;
24 # neither the name of the copyright holders nor the names of its
25 # contributors may be used to endorse or promote products derived from
26 # this software without specific prior written permission.
27 #
28 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
40 # Configure the M5 cache hierarchy config in one place
41 #
42
43 import m5
44 from m5.objects import *
45 from common.Caches import *
46 from common import ObjectList
47
48 def _get_hwp(hwp_option):
49 if hwp_option == None:
50 return NULL
51
52 hwpClass = ObjectList.hwp_list.get(hwp_option)
53 return hwpClass()
54
55 def _get_cache_opts(level, options):
56 opts = {}
57
58 size_attr = '{}_size'.format(level)
59 if hasattr(options, size_attr):
60 opts['size'] = getattr(options, size_attr)
61
62 assoc_attr = '{}_assoc'.format(level)
63 if hasattr(options, assoc_attr):
64 opts['assoc'] = getattr(options, assoc_attr)
65
66 prefetcher_attr = '{}_hwp_type'.format(level)
67 if hasattr(options, prefetcher_attr):
68 opts['prefetcher'] = _get_hwp(getattr(options, prefetcher_attr))
69
70 return opts
71
72 def config_cache(options, system):
73 if options.external_memory_system and (options.caches or options.l2cache):
74 print("External caches and internal caches are exclusive options.\n")
75 sys.exit(1)
76
77 if options.external_memory_system:
78 ExternalCache = ExternalCacheFactory(options.external_memory_system)
79
80 if options.cpu_type == "O3_ARM_v7a_3":
81 try:
82 import cores.arm.O3_ARM_v7a as core
83 except:
84 print("O3_ARM_v7a_3 is unavailable. Did you compile the O3 model?")
85 sys.exit(1)
86
87 dcache_class, icache_class, l2_cache_class, walk_cache_class = \
88 core.O3_ARM_v7a_DCache, core.O3_ARM_v7a_ICache, \
89 core.O3_ARM_v7aL2, \
90 core.O3_ARM_v7aWalkCache
91 elif options.cpu_type == "HPI":
92 try:
93 import cores.arm.HPI as core
94 except:
95 print("HPI is unavailable.")
96 sys.exit(1)
97
98 dcache_class, icache_class, l2_cache_class, walk_cache_class = \
99 core.HPI_DCache, core.HPI_ICache, core.HPI_L2, core.HPI_WalkCache
100 else:
101 dcache_class, icache_class, l2_cache_class, walk_cache_class = \
102 L1_DCache, L1_ICache, L2Cache, None
103
104 if buildEnv['TARGET_ISA'] in ['x86', 'riscv']:
105 walk_cache_class = PageTableWalkerCache
106
107 # Set the cache line size of the system
108 system.cache_line_size = options.cacheline_size
109
110 # If elastic trace generation is enabled, make sure the memory system is
111 # minimal so that compute delays do not include memory access latencies.
112 # Configure the compulsory L1 caches for the O3CPU, do not configure
113 # any more caches.
114 if options.l2cache and options.elastic_trace_en:
115 fatal("When elastic trace is enabled, do not configure L2 caches.")
116
117 if options.l2cache:
118 # Provide a clock for the L2 and the L1-to-L2 bus here as they
119 # are not connected using addTwoLevelCacheHierarchy. Use the
120 # same clock as the CPUs.
121 system.l2 = l2_cache_class(clk_domain=system.cpu_clk_domain,
122 **_get_cache_opts('l2', options))
123
124 system.tol2bus = L2XBar(clk_domain = system.cpu_clk_domain)
125 system.l2.cpu_side = system.tol2bus.master
126 system.l2.mem_side = system.membus.slave
127
128 if options.memchecker:
129 system.memchecker = MemChecker()
130
131 for i in range(options.num_cpus):
132 if options.caches:
133 icache = icache_class(**_get_cache_opts('l1i', options))
134 dcache = dcache_class(**_get_cache_opts('l1d', options))
135
136 # If we have a walker cache specified, instantiate two
137 # instances here
138 if walk_cache_class:
139 iwalkcache = walk_cache_class()
140 dwalkcache = walk_cache_class()
141 else:
142 iwalkcache = None
143 dwalkcache = None
144
145 if options.memchecker:
146 dcache_mon = MemCheckerMonitor(warn_only=True)
147 dcache_real = dcache
148
149 # Do not pass the memchecker into the constructor of
150 # MemCheckerMonitor, as it would create a copy; we require
151 # exactly one MemChecker instance.
152 dcache_mon.memchecker = system.memchecker
153
154 # Connect monitor
155 dcache_mon.mem_side = dcache.cpu_side
156
157 # Let CPU connect to monitors
158 dcache = dcache_mon
159
160 # When connecting the caches, the clock is also inherited
161 # from the CPU in question
162 system.cpu[i].addPrivateSplitL1Caches(icache, dcache,
163 iwalkcache, dwalkcache)
164
165 if options.memchecker:
166 # The mem_side ports of the caches haven't been connected yet.
167 # Make sure connectAllPorts connects the right objects.
168 system.cpu[i].dcache = dcache_real
169 system.cpu[i].dcache_mon = dcache_mon
170
171 elif options.external_memory_system:
172 # These port names are presented to whatever 'external' system
173 # gem5 is connecting to. Its configuration will likely depend
174 # on these names. For simplicity, we would advise configuring
175 # it to use this naming scheme; if this isn't possible, change
176 # the names below.
177 if buildEnv['TARGET_ISA'] in ['x86', 'arm', 'riscv']:
178 system.cpu[i].addPrivateSplitL1Caches(
179 ExternalCache("cpu%d.icache" % i),
180 ExternalCache("cpu%d.dcache" % i),
181 ExternalCache("cpu%d.itb_walker_cache" % i),
182 ExternalCache("cpu%d.dtb_walker_cache" % i))
183 else:
184 system.cpu[i].addPrivateSplitL1Caches(
185 ExternalCache("cpu%d.icache" % i),
186 ExternalCache("cpu%d.dcache" % i))
187
188 system.cpu[i].createInterruptController()
189 if options.l2cache:
190 system.cpu[i].connectAllPorts(system.tol2bus, system.membus)
191 elif options.external_memory_system:
192 system.cpu[i].connectUncachedPorts(system.membus)
193 else:
194 system.cpu[i].connectAllPorts(system.membus)
195
196 return system
197
198 # ExternalSlave provides a "port", but when that port connects to a cache,
199 # the connecting CPU SimObject wants to refer to its "cpu_side".
200 # The 'ExternalCache' class provides this adaptation by rewriting the name,
201 # eliminating distracting changes elsewhere in the config code.
202 class ExternalCache(ExternalSlave):
203 def __getattr__(cls, attr):
204 if (attr == "cpu_side"):
205 attr = "port"
206 return super(ExternalSlave, cls).__getattr__(attr)
207
208 def __setattr__(cls, attr, value):
209 if (attr == "cpu_side"):
210 attr = "port"
211 return super(ExternalSlave, cls).__setattr__(attr, value)
212
213 def ExternalCacheFactory(port_type):
214 def make(name):
215 return ExternalCache(port_data=name, port_type=port_type,
216 addr_ranges=[AllMemory])
217 return make