1 # Copyright (c) 2012-2013, 2015-2016 ARM Limited
4 # The license below extends only to copyright in the software and shall
5 # not be construed as granting a license to any other intellectual
6 # property including but not limited to intellectual property relating
7 # to a hardware implementation of the functionality of the software
8 # licensed hereunder. You may use the software subject to the license
9 # terms below provided that you ensure that this notice is replicated
10 # unmodified and in its entirety in all distributions of the software,
11 # modified or unmodified, in source code or in binary form.
13 # Copyright (c) 2010 Advanced Micro Devices, Inc.
14 # All rights reserved.
16 # Redistribution and use in source and binary forms, with or without
17 # modification, are permitted provided that the following conditions are
18 # met: redistributions of source code must retain the above copyright
19 # notice, this list of conditions and the following disclaimer;
20 # redistributions in binary form must reproduce the above copyright
21 # notice, this list of conditions and the following disclaimer in the
22 # documentation and/or other materials provided with the distribution;
23 # neither the name of the copyright holders nor the names of its
24 # contributors may be used to endorse or promote products derived from
25 # this software without specific prior written permission.
27 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 # Configure the M5 cache hierarchy config in one place
44 from __future__
import print_function
47 from m5
.objects
import *
50 def config_cache(options
, system
):
51 if options
.external_memory_system
and (options
.caches
or options
.l2cache
):
52 print("External caches and internal caches are exclusive options.\n")
55 if options
.external_memory_system
:
56 ExternalCache
= ExternalCacheFactory(options
.external_memory_system
)
58 if options
.cpu_type
== "O3_ARM_v7a_3":
60 from cores
.arm
.O3_ARM_v7a
import *
62 print("O3_ARM_v7a_3 is unavailable. Did you compile the O3 model?")
65 dcache_class
, icache_class
, l2_cache_class
, walk_cache_class
= \
66 O3_ARM_v7a_DCache
, O3_ARM_v7a_ICache
, O3_ARM_v7aL2
, \
69 dcache_class
, icache_class
, l2_cache_class
, walk_cache_class
= \
70 L1_DCache
, L1_ICache
, L2Cache
, None
72 if buildEnv
['TARGET_ISA'] == 'x86':
73 walk_cache_class
= PageTableWalkerCache
75 # Set the cache line size of the system
76 system
.cache_line_size
= options
.cacheline_size
78 # If elastic trace generation is enabled, make sure the memory system is
79 # minimal so that compute delays do not include memory access latencies.
80 # Configure the compulsory L1 caches for the O3CPU, do not configure
82 if options
.l2cache
and options
.elastic_trace_en
:
83 fatal("When elastic trace is enabled, do not configure L2 caches.")
86 # Provide a clock for the L2 and the L1-to-L2 bus here as they
87 # are not connected using addTwoLevelCacheHierarchy. Use the
88 # same clock as the CPUs.
89 system
.l2
= l2_cache_class(clk_domain
=system
.cpu_clk_domain
,
91 assoc
=options
.l2_assoc
)
93 system
.tol2bus
= L2XBar(clk_domain
= system
.cpu_clk_domain
)
94 system
.l2
.cpu_side
= system
.tol2bus
.master
95 system
.l2
.mem_side
= system
.membus
.slave
97 if options
.memchecker
:
98 system
.memchecker
= MemChecker()
100 for i
in xrange(options
.num_cpus
):
102 icache
= icache_class(size
=options
.l1i_size
,
103 assoc
=options
.l1i_assoc
)
104 dcache
= dcache_class(size
=options
.l1d_size
,
105 assoc
=options
.l1d_assoc
)
107 # If we have a walker cache specified, instantiate two
110 iwalkcache
= walk_cache_class()
111 dwalkcache
= walk_cache_class()
116 if options
.memchecker
:
117 dcache_mon
= MemCheckerMonitor(warn_only
=True)
120 # Do not pass the memchecker into the constructor of
121 # MemCheckerMonitor, as it would create a copy; we require
122 # exactly one MemChecker instance.
123 dcache_mon
.memchecker
= system
.memchecker
126 dcache_mon
.mem_side
= dcache
.cpu_side
128 # Let CPU connect to monitors
131 # When connecting the caches, the clock is also inherited
132 # from the CPU in question
133 system
.cpu
[i
].addPrivateSplitL1Caches(icache
, dcache
,
134 iwalkcache
, dwalkcache
)
136 if options
.memchecker
:
137 # The mem_side ports of the caches haven't been connected yet.
138 # Make sure connectAllPorts connects the right objects.
139 system
.cpu
[i
].dcache
= dcache_real
140 system
.cpu
[i
].dcache_mon
= dcache_mon
142 elif options
.external_memory_system
:
143 # These port names are presented to whatever 'external' system
144 # gem5 is connecting to. Its configuration will likely depend
145 # on these names. For simplicity, we would advise configuring
146 # it to use this naming scheme; if this isn't possible, change
148 if buildEnv
['TARGET_ISA'] in ['x86', 'arm']:
149 system
.cpu
[i
].addPrivateSplitL1Caches(
150 ExternalCache("cpu%d.icache" % i
),
151 ExternalCache("cpu%d.dcache" % i
),
152 ExternalCache("cpu%d.itb_walker_cache" % i
),
153 ExternalCache("cpu%d.dtb_walker_cache" % i
))
155 system
.cpu
[i
].addPrivateSplitL1Caches(
156 ExternalCache("cpu%d.icache" % i
),
157 ExternalCache("cpu%d.dcache" % i
))
159 system
.cpu
[i
].createInterruptController()
161 system
.cpu
[i
].connectAllPorts(system
.tol2bus
, system
.membus
)
162 elif options
.external_memory_system
:
163 system
.cpu
[i
].connectUncachedPorts(system
.membus
)
165 system
.cpu
[i
].connectAllPorts(system
.membus
)
169 # ExternalSlave provides a "port", but when that port connects to a cache,
170 # the connecting CPU SimObject wants to refer to its "cpu_side".
171 # The 'ExternalCache' class provides this adaptation by rewriting the name,
172 # eliminating distracting changes elsewhere in the config code.
173 class ExternalCache(ExternalSlave
):
174 def __getattr__(cls
, attr
):
175 if (attr
== "cpu_side"):
177 return super(ExternalSlave
, cls
).__getattr
__(attr
)
179 def __setattr__(cls
, attr
, value
):
180 if (attr
== "cpu_side"):
182 return super(ExternalSlave
, cls
).__setattr
__(attr
, value
)
184 def ExternalCacheFactory(port_type
):
186 return ExternalCache(port_data
=name
, port_type
=port_type
,
187 addr_ranges
=[AllMemory
])