BaseCPU.py (14145:066ba9040e5e) BaseCPU.py (14147:638fe1150005)
1# Copyright (c) 2012-2013, 2015-2017 ARM Limited
2# All rights reserved.
3#
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.
12#
13# Copyright (c) 2005-2008 The Regents of The University of Michigan
14# Copyright (c) 2011 Regents of the University of California
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# Authors: Nathan Binkert
41# Rick Strong
42# Andreas Hansson
43# Glenn Bergmans
44
45from __future__ import print_function
46
47import sys
48
49from m5.SimObject import *
50from m5.defines import buildEnv
51from m5.params import *
52from m5.proxy import *
53from m5.util.fdthelper import *
54
55from m5.objects.ClockedObject import ClockedObject
56from m5.objects.XBar import L2XBar
57from m5.objects.InstTracer import InstTracer
58from m5.objects.CPUTracers import ExeTracer
59from m5.objects.SubSystem import SubSystem
60from m5.objects.ClockDomain import *
61from m5.objects.Platform import Platform
62
63default_tracer = ExeTracer()
64
65if buildEnv['TARGET_ISA'] == 'alpha':
66 from m5.objects.AlphaTLB import AlphaDTB as ArchDTB, AlphaITB as ArchITB
1# Copyright (c) 2012-2013, 2015-2017 ARM Limited
2# All rights reserved.
3#
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.
12#
13# Copyright (c) 2005-2008 The Regents of The University of Michigan
14# Copyright (c) 2011 Regents of the University of California
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# Authors: Nathan Binkert
41# Rick Strong
42# Andreas Hansson
43# Glenn Bergmans
44
45from __future__ import print_function
46
47import sys
48
49from m5.SimObject import *
50from m5.defines import buildEnv
51from m5.params import *
52from m5.proxy import *
53from m5.util.fdthelper import *
54
55from m5.objects.ClockedObject import ClockedObject
56from m5.objects.XBar import L2XBar
57from m5.objects.InstTracer import InstTracer
58from m5.objects.CPUTracers import ExeTracer
59from m5.objects.SubSystem import SubSystem
60from m5.objects.ClockDomain import *
61from m5.objects.Platform import Platform
62
63default_tracer = ExeTracer()
64
65if buildEnv['TARGET_ISA'] == 'alpha':
66 from m5.objects.AlphaTLB import AlphaDTB as ArchDTB, AlphaITB as ArchITB
67 from m5.objects.AlphaInterrupts import AlphaInterrupts
68 from m5.objects.AlphaISA import AlphaISA
69 default_isa_class = AlphaISA
67 from m5.objects.AlphaInterrupts import AlphaInterrupts as ArchInterrupts
68 from m5.objects.AlphaISA import AlphaISA as ArchISA
69 ArchInterruptsParam = VectorParam.AlphaInterrupts
70 ArchISAsParam = VectorParam.AlphaISA
70elif buildEnv['TARGET_ISA'] == 'sparc':
71 from m5.objects.SparcTLB import SparcTLB as ArchDTB, SparcTLB as ArchITB
71elif buildEnv['TARGET_ISA'] == 'sparc':
72 from m5.objects.SparcTLB import SparcTLB as ArchDTB, SparcTLB as ArchITB
72 from m5.objects.SparcInterrupts import SparcInterrupts
73 from m5.objects.SparcISA import SparcISA
74 default_isa_class = SparcISA
73 from m5.objects.SparcInterrupts import SparcInterrupts as ArchInterrupts
74 from m5.objects.SparcISA import SparcISA as ArchISA
75 ArchInterruptsParam = VectorParam.SparcInterrupts
76 ArchISAsParam = VectorParam.SparcISA
75elif buildEnv['TARGET_ISA'] == 'x86':
76 from m5.objects.X86TLB import X86TLB as ArchDTB, X86TLB as ArchITB
77elif buildEnv['TARGET_ISA'] == 'x86':
78 from m5.objects.X86TLB import X86TLB as ArchDTB, X86TLB as ArchITB
77 from m5.objects.X86LocalApic import X86LocalApic
78 from m5.objects.X86ISA import X86ISA
79 default_isa_class = X86ISA
79 from m5.objects.X86LocalApic import X86LocalApic as ArchInterrupts
80 from m5.objects.X86ISA import X86ISA as ArchISA
81 ArchInterruptsParam = VectorParam.X86LocalApic
82 ArchISAsParam = VectorParam.X86ISA
80elif buildEnv['TARGET_ISA'] == 'mips':
81 from m5.objects.MipsTLB import MipsTLB as ArchDTB, MipsTLB as ArchITB
83elif buildEnv['TARGET_ISA'] == 'mips':
84 from m5.objects.MipsTLB import MipsTLB as ArchDTB, MipsTLB as ArchITB
82 from m5.objects.MipsInterrupts import MipsInterrupts
83 from m5.objects.MipsISA import MipsISA
84 default_isa_class = MipsISA
85 from m5.objects.MipsInterrupts import MipsInterrupts as ArchInterrupts
86 from m5.objects.MipsISA import MipsISA as ArchISA
87 ArchInterruptsParam = VectorParam.MipsInterrupts
88 ArchISAsParam = VectorParam.MipsISA
85elif buildEnv['TARGET_ISA'] == 'arm':
86 from m5.objects.ArmTLB import ArmTLB as ArchDTB, ArmTLB as ArchITB
87 from m5.objects.ArmTLB import ArmStage2IMMU, ArmStage2DMMU
89elif buildEnv['TARGET_ISA'] == 'arm':
90 from m5.objects.ArmTLB import ArmTLB as ArchDTB, ArmTLB as ArchITB
91 from m5.objects.ArmTLB import ArmStage2IMMU, ArmStage2DMMU
88 from m5.objects.ArmInterrupts import ArmInterrupts
89 from m5.objects.ArmISA import ArmISA
90 default_isa_class = ArmISA
92 from m5.objects.ArmInterrupts import ArmInterrupts as ArchInterrupts
93 from m5.objects.ArmISA import ArmISA as ArchISA
94 ArchInterruptsParam = VectorParam.ArmInterrupts
95 ArchISAsParam = VectorParam.ArmISA
91elif buildEnv['TARGET_ISA'] == 'power':
92 from m5.objects.PowerTLB import PowerTLB as ArchDTB, PowerTLB as ArchITB
96elif buildEnv['TARGET_ISA'] == 'power':
97 from m5.objects.PowerTLB import PowerTLB as ArchDTB, PowerTLB as ArchITB
93 from m5.objects.PowerInterrupts import PowerInterrupts
94 from m5.objects.PowerISA import PowerISA
95 default_isa_class = PowerISA
98 from m5.objects.PowerInterrupts import PowerInterrupts as ArchInterrupts
99 from m5.objects.PowerISA import PowerISA as ArchISA
100 ArchInterruptsParam = VectorParam.PowerInterrupts
101 ArchISAsParam = VectorParam.PowerISA
96elif buildEnv['TARGET_ISA'] == 'riscv':
97 from m5.objects.RiscvTLB import RiscvTLB as ArchDTB, RiscvTLB as ArchITB
102elif buildEnv['TARGET_ISA'] == 'riscv':
103 from m5.objects.RiscvTLB import RiscvTLB as ArchDTB, RiscvTLB as ArchITB
98 from m5.objects.RiscvInterrupts import RiscvInterrupts
99 from m5.objects.RiscvISA import RiscvISA
100 default_isa_class = RiscvISA
104 from m5.objects.RiscvInterrupts import RiscvInterrupts as ArchInterrupts
105 from m5.objects.RiscvISA import RiscvISA as ArchISA
106 ArchInterruptsParam = VectorParam.RiscvInterrupts
107 ArchISAsParam = VectorParam.RiscvISA
108else:
109 print("Don't know what object types to use for ISA %s" %
110 buildEnv['TARGET_ISA'])
111 sys.exit(1)
101
102class BaseCPU(ClockedObject):
103 type = 'BaseCPU'
104 abstract = True
105 cxx_header = "cpu/base.hh"
106
107 cxx_exports = [
108 PyBindMethod("switchOut"),
109 PyBindMethod("takeOverFrom"),
110 PyBindMethod("switchedOut"),
111 PyBindMethod("flushTLBs"),
112 PyBindMethod("totalInsts"),
113 PyBindMethod("scheduleInstStop"),
114 PyBindMethod("scheduleLoadStop"),
115 PyBindMethod("getCurrentInstCount"),
116 ]
117
118 @classmethod
119 def memory_mode(cls):
120 """Which memory mode does this CPU require?"""
121 return 'invalid'
122
123 @classmethod
124 def require_caches(cls):
125 """Does the CPU model require caches?
126
127 Some CPU models might make assumptions that require them to
128 have caches.
129 """
130 return False
131
132 @classmethod
133 def support_take_over(cls):
134 """Does the CPU model support CPU takeOverFrom?"""
135 return False
136
137 def takeOverFrom(self, old_cpu):
138 self._ccObject.takeOverFrom(old_cpu._ccObject)
139
140
141 system = Param.System(Parent.any, "system object")
142 cpu_id = Param.Int(-1, "CPU identifier")
143 socket_id = Param.Unsigned(0, "Physical Socket identifier")
144 numThreads = Param.Unsigned(1, "number of HW thread contexts")
145 pwr_gating_latency = Param.Cycles(300,
146 "Latency to enter power gating state when all contexts are suspended")
147
148 power_gating_on_idle = Param.Bool(False, "Control whether the core goes "\
149 "to the OFF power state after all thread are disabled for "\
150 "pwr_gating_latency cycles")
151
152 function_trace = Param.Bool(False, "Enable function trace")
153 function_trace_start = Param.Tick(0, "Tick to start function trace")
154
155 checker = Param.BaseCPU(NULL, "checker CPU")
156
157 syscallRetryLatency = Param.Cycles(10000, "Cycles to wait until retry")
158
159 do_checkpoint_insts = Param.Bool(True,
160 "enable checkpoint pseudo instructions")
161 do_statistics_insts = Param.Bool(True,
162 "enable statistics pseudo instructions")
163
164 profile = Param.Latency('0ns', "trace the kernel stack")
165 do_quiesce = Param.Bool(True, "enable quiesce instructions")
166
167 wait_for_remote_gdb = Param.Bool(False,
168 "Wait for a remote GDB connection");
169
170 workload = VectorParam.Process([], "processes to run")
171
172 dtb = Param.BaseTLB(ArchDTB(), "Data TLB")
173 itb = Param.BaseTLB(ArchITB(), "Instruction TLB")
112
113class BaseCPU(ClockedObject):
114 type = 'BaseCPU'
115 abstract = True
116 cxx_header = "cpu/base.hh"
117
118 cxx_exports = [
119 PyBindMethod("switchOut"),
120 PyBindMethod("takeOverFrom"),
121 PyBindMethod("switchedOut"),
122 PyBindMethod("flushTLBs"),
123 PyBindMethod("totalInsts"),
124 PyBindMethod("scheduleInstStop"),
125 PyBindMethod("scheduleLoadStop"),
126 PyBindMethod("getCurrentInstCount"),
127 ]
128
129 @classmethod
130 def memory_mode(cls):
131 """Which memory mode does this CPU require?"""
132 return 'invalid'
133
134 @classmethod
135 def require_caches(cls):
136 """Does the CPU model require caches?
137
138 Some CPU models might make assumptions that require them to
139 have caches.
140 """
141 return False
142
143 @classmethod
144 def support_take_over(cls):
145 """Does the CPU model support CPU takeOverFrom?"""
146 return False
147
148 def takeOverFrom(self, old_cpu):
149 self._ccObject.takeOverFrom(old_cpu._ccObject)
150
151
152 system = Param.System(Parent.any, "system object")
153 cpu_id = Param.Int(-1, "CPU identifier")
154 socket_id = Param.Unsigned(0, "Physical Socket identifier")
155 numThreads = Param.Unsigned(1, "number of HW thread contexts")
156 pwr_gating_latency = Param.Cycles(300,
157 "Latency to enter power gating state when all contexts are suspended")
158
159 power_gating_on_idle = Param.Bool(False, "Control whether the core goes "\
160 "to the OFF power state after all thread are disabled for "\
161 "pwr_gating_latency cycles")
162
163 function_trace = Param.Bool(False, "Enable function trace")
164 function_trace_start = Param.Tick(0, "Tick to start function trace")
165
166 checker = Param.BaseCPU(NULL, "checker CPU")
167
168 syscallRetryLatency = Param.Cycles(10000, "Cycles to wait until retry")
169
170 do_checkpoint_insts = Param.Bool(True,
171 "enable checkpoint pseudo instructions")
172 do_statistics_insts = Param.Bool(True,
173 "enable statistics pseudo instructions")
174
175 profile = Param.Latency('0ns', "trace the kernel stack")
176 do_quiesce = Param.Bool(True, "enable quiesce instructions")
177
178 wait_for_remote_gdb = Param.Bool(False,
179 "Wait for a remote GDB connection");
180
181 workload = VectorParam.Process([], "processes to run")
182
183 dtb = Param.BaseTLB(ArchDTB(), "Data TLB")
184 itb = Param.BaseTLB(ArchITB(), "Instruction TLB")
174 if buildEnv['TARGET_ISA'] == 'sparc':
175 interrupts = VectorParam.SparcInterrupts(
176 [], "Interrupt Controller")
177 isa = VectorParam.SparcISA([], "ISA instance")
178 elif buildEnv['TARGET_ISA'] == 'alpha':
179 interrupts = VectorParam.AlphaInterrupts(
180 [], "Interrupt Controller")
181 isa = VectorParam.AlphaISA([], "ISA instance")
182 elif buildEnv['TARGET_ISA'] == 'x86':
183 interrupts = VectorParam.X86LocalApic([], "Interrupt Controller")
184 isa = VectorParam.X86ISA([], "ISA instance")
185 elif buildEnv['TARGET_ISA'] == 'mips':
186 interrupts = VectorParam.MipsInterrupts(
187 [], "Interrupt Controller")
188 isa = VectorParam.MipsISA([], "ISA instance")
189 elif buildEnv['TARGET_ISA'] == 'arm':
185 if buildEnv['TARGET_ISA'] == 'arm':
190 istage2_mmu = Param.ArmStage2MMU(ArmStage2IMMU(), "Stage 2 trans")
191 dstage2_mmu = Param.ArmStage2MMU(ArmStage2DMMU(), "Stage 2 trans")
186 istage2_mmu = Param.ArmStage2MMU(ArmStage2IMMU(), "Stage 2 trans")
187 dstage2_mmu = Param.ArmStage2MMU(ArmStage2DMMU(), "Stage 2 trans")
192 interrupts = VectorParam.ArmInterrupts(
193 [], "Interrupt Controller")
194 isa = VectorParam.ArmISA([], "ISA instance")
195 elif buildEnv['TARGET_ISA'] == 'power':
196 UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?")
188 elif buildEnv['TARGET_ISA'] == 'power':
189 UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?")
197 interrupts = VectorParam.PowerInterrupts(
198 [], "Interrupt Controller")
199 isa = VectorParam.PowerISA([], "ISA instance")
200 elif buildEnv['TARGET_ISA'] == 'riscv':
201 interrupts = VectorParam.RiscvInterrupts(
202 [], "Interrupt Controller")
203 isa = VectorParam.RiscvISA([], "ISA instance")
204 else:
205 print("Don't know what TLB to use for ISA %s" %
206 buildEnv['TARGET_ISA'])
207 sys.exit(1)
190 interrupts = ArchInterruptsParam([], "Interrupt Controller")
191 isa = ArchISAsParam([], "ISA instance")
208
209 max_insts_all_threads = Param.Counter(0,
210 "terminate when all threads have reached this inst count")
211 max_insts_any_thread = Param.Counter(0,
212 "terminate when any thread reaches this inst count")
213 simpoint_start_insts = VectorParam.Counter([],
214 "starting instruction counts of simpoints")
215 max_loads_all_threads = Param.Counter(0,
216 "terminate when all threads have reached this load count")
217 max_loads_any_thread = Param.Counter(0,
218 "terminate when any thread reaches this load count")
219 progress_interval = Param.Frequency('0Hz',
220 "frequency to print out the progress message")
221
222 switched_out = Param.Bool(False,
223 "Leave the CPU switched out after startup (used when switching " \
224 "between CPU models)")
225
226 tracer = Param.InstTracer(default_tracer, "Instruction tracer")
227
228 icache_port = MasterPort("Instruction Port")
229 dcache_port = MasterPort("Data Port")
230 _cached_ports = ['icache_port', 'dcache_port']
231
232 if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
233 _cached_ports += ["itb.walker.port", "dtb.walker.port"]
234
235 _uncached_slave_ports = []
236 _uncached_master_ports = []
237 if buildEnv['TARGET_ISA'] == 'x86':
238 _uncached_slave_ports += ["interrupts[0].pio",
239 "interrupts[0].int_slave"]
240 _uncached_master_ports += ["interrupts[0].int_master"]
241
242 def createInterruptController(self):
192
193 max_insts_all_threads = Param.Counter(0,
194 "terminate when all threads have reached this inst count")
195 max_insts_any_thread = Param.Counter(0,
196 "terminate when any thread reaches this inst count")
197 simpoint_start_insts = VectorParam.Counter([],
198 "starting instruction counts of simpoints")
199 max_loads_all_threads = Param.Counter(0,
200 "terminate when all threads have reached this load count")
201 max_loads_any_thread = Param.Counter(0,
202 "terminate when any thread reaches this load count")
203 progress_interval = Param.Frequency('0Hz',
204 "frequency to print out the progress message")
205
206 switched_out = Param.Bool(False,
207 "Leave the CPU switched out after startup (used when switching " \
208 "between CPU models)")
209
210 tracer = Param.InstTracer(default_tracer, "Instruction tracer")
211
212 icache_port = MasterPort("Instruction Port")
213 dcache_port = MasterPort("Data Port")
214 _cached_ports = ['icache_port', 'dcache_port']
215
216 if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
217 _cached_ports += ["itb.walker.port", "dtb.walker.port"]
218
219 _uncached_slave_ports = []
220 _uncached_master_ports = []
221 if buildEnv['TARGET_ISA'] == 'x86':
222 _uncached_slave_ports += ["interrupts[0].pio",
223 "interrupts[0].int_slave"]
224 _uncached_master_ports += ["interrupts[0].int_master"]
225
226 def createInterruptController(self):
243 if buildEnv['TARGET_ISA'] == 'sparc':
244 self.interrupts = [SparcInterrupts() for i in range(self.numThreads)]
245 elif buildEnv['TARGET_ISA'] == 'alpha':
246 self.interrupts = [AlphaInterrupts() for i in range(self.numThreads)]
247 elif buildEnv['TARGET_ISA'] == 'x86':
248 self.interrupts = [X86LocalApic() for i in range(self.numThreads)]
249 elif buildEnv['TARGET_ISA'] == 'mips':
250 self.interrupts = [MipsInterrupts() for i in range(self.numThreads)]
251 elif buildEnv['TARGET_ISA'] == 'arm':
252 self.interrupts = [ArmInterrupts() for i in range(self.numThreads)]
253 elif buildEnv['TARGET_ISA'] == 'power':
254 self.interrupts = [PowerInterrupts() for i in range(self.numThreads)]
255 elif buildEnv['TARGET_ISA'] == 'riscv':
256 self.interrupts = \
257 [RiscvInterrupts() for i in range(self.numThreads)]
258 else:
259 print("Don't know what Interrupt Controller to use for ISA %s" %
260 buildEnv['TARGET_ISA'])
261 sys.exit(1)
227 self.interrupts = [ArchInterrupts() for i in range(self.numThreads)]
262
263 def connectCachedPorts(self, bus):
264 for p in self._cached_ports:
265 exec('self.%s = bus.slave' % p)
266
267 def connectUncachedPorts(self, bus):
268 for p in self._uncached_slave_ports:
269 exec('self.%s = bus.master' % p)
270 for p in self._uncached_master_ports:
271 exec('self.%s = bus.slave' % p)
272
273 def connectAllPorts(self, cached_bus, uncached_bus = None):
274 self.connectCachedPorts(cached_bus)
275 if not uncached_bus:
276 uncached_bus = cached_bus
277 self.connectUncachedPorts(uncached_bus)
278
279 def addPrivateSplitL1Caches(self, ic, dc, iwc = None, dwc = None):
280 self.icache = ic
281 self.dcache = dc
282 self.icache_port = ic.cpu_side
283 self.dcache_port = dc.cpu_side
284 self._cached_ports = ['icache.mem_side', 'dcache.mem_side']
285 if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
286 if iwc and dwc:
287 self.itb_walker_cache = iwc
288 self.dtb_walker_cache = dwc
289 self.itb.walker.port = iwc.cpu_side
290 self.dtb.walker.port = dwc.cpu_side
291 self._cached_ports += ["itb_walker_cache.mem_side", \
292 "dtb_walker_cache.mem_side"]
293 else:
294 self._cached_ports += ["itb.walker.port", "dtb.walker.port"]
295
296 # Checker doesn't need its own tlb caches because it does
297 # functional accesses only
298 if self.checker != NULL:
299 self._cached_ports += ["checker.itb.walker.port", \
300 "checker.dtb.walker.port"]
301
302 def addTwoLevelCacheHierarchy(self, ic, dc, l2c, iwc=None, dwc=None,
303 xbar=None):
304 self.addPrivateSplitL1Caches(ic, dc, iwc, dwc)
305 self.toL2Bus = xbar if xbar else L2XBar()
306 self.connectCachedPorts(self.toL2Bus)
307 self.l2cache = l2c
308 self.toL2Bus.master = self.l2cache.cpu_side
309 self._cached_ports = ['l2cache.mem_side']
310
311 def createThreads(self):
312 # If no ISAs have been created, assume that the user wants the
313 # default ISA.
314 if len(self.isa) == 0:
228
229 def connectCachedPorts(self, bus):
230 for p in self._cached_ports:
231 exec('self.%s = bus.slave' % p)
232
233 def connectUncachedPorts(self, bus):
234 for p in self._uncached_slave_ports:
235 exec('self.%s = bus.master' % p)
236 for p in self._uncached_master_ports:
237 exec('self.%s = bus.slave' % p)
238
239 def connectAllPorts(self, cached_bus, uncached_bus = None):
240 self.connectCachedPorts(cached_bus)
241 if not uncached_bus:
242 uncached_bus = cached_bus
243 self.connectUncachedPorts(uncached_bus)
244
245 def addPrivateSplitL1Caches(self, ic, dc, iwc = None, dwc = None):
246 self.icache = ic
247 self.dcache = dc
248 self.icache_port = ic.cpu_side
249 self.dcache_port = dc.cpu_side
250 self._cached_ports = ['icache.mem_side', 'dcache.mem_side']
251 if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
252 if iwc and dwc:
253 self.itb_walker_cache = iwc
254 self.dtb_walker_cache = dwc
255 self.itb.walker.port = iwc.cpu_side
256 self.dtb.walker.port = dwc.cpu_side
257 self._cached_ports += ["itb_walker_cache.mem_side", \
258 "dtb_walker_cache.mem_side"]
259 else:
260 self._cached_ports += ["itb.walker.port", "dtb.walker.port"]
261
262 # Checker doesn't need its own tlb caches because it does
263 # functional accesses only
264 if self.checker != NULL:
265 self._cached_ports += ["checker.itb.walker.port", \
266 "checker.dtb.walker.port"]
267
268 def addTwoLevelCacheHierarchy(self, ic, dc, l2c, iwc=None, dwc=None,
269 xbar=None):
270 self.addPrivateSplitL1Caches(ic, dc, iwc, dwc)
271 self.toL2Bus = xbar if xbar else L2XBar()
272 self.connectCachedPorts(self.toL2Bus)
273 self.l2cache = l2c
274 self.toL2Bus.master = self.l2cache.cpu_side
275 self._cached_ports = ['l2cache.mem_side']
276
277 def createThreads(self):
278 # If no ISAs have been created, assume that the user wants the
279 # default ISA.
280 if len(self.isa) == 0:
315 self.isa = [ default_isa_class() for i in range(self.numThreads) ]
281 self.isa = [ ArchISA() for i in range(self.numThreads) ]
316 else:
317 if len(self.isa) != int(self.numThreads):
318 raise RuntimeError("Number of ISA instances doesn't "
319 "match thread count")
320 if self.checker != NULL:
321 self.checker.createThreads()
322
323 def addCheckerCpu(self):
324 pass
325
326 def createPhandleKey(self, thread):
327 # This method creates a unique key for this cpu as a function of a
328 # certain thread
329 return 'CPU-%d-%d-%d' % (self.socket_id, self.cpu_id, thread)
330
331 #Generate simple CPU Device Tree structure
332 def generateDeviceTree(self, state):
333 """Generate cpu nodes for each thread and the corresponding part of the
334 cpu-map node. Note that this implementation does not support clusters
335 of clusters. Note that GEM5 is not compatible with the official way of
336 numbering cores as defined in the Device Tree documentation. Where the
337 cpu_id needs to reset to 0 for each cluster by specification, GEM5
338 expects the cpu_id to be globally unique and incremental. This
339 generated node adheres the GEM5 way of doing things."""
340 if bool(self.switched_out):
341 return
342
343 cpus_node = FdtNode('cpus')
344 cpus_node.append(state.CPUCellsProperty())
345 #Special size override of 0
346 cpus_node.append(FdtPropertyWords('#size-cells', [0]))
347
348 # Generate cpu nodes
349 for i in range(int(self.numThreads)):
350 reg = (int(self.socket_id)<<8) + int(self.cpu_id) + i
351 node = FdtNode("cpu@%x" % reg)
352 node.append(FdtPropertyStrings("device_type", "cpu"))
353 node.appendCompatible(["gem5,arm-cpu"])
354 node.append(FdtPropertyWords("reg", state.CPUAddrCells(reg)))
355 platform, found = self.system.unproxy(self).find_any(Platform)
356 if found:
357 platform.annotateCpuDeviceNode(node, state)
358 else:
359 warn("Platform not found for device tree generation; " \
360 "system or multiple CPUs may not start")
361
362 freq = int(self.clk_domain.unproxy(self).clock[0].frequency)
363 node.append(FdtPropertyWords("clock-frequency", freq))
364
365 # Unique key for this CPU
366 phandle_key = self.createPhandleKey(i)
367 node.appendPhandle(phandle_key)
368 cpus_node.append(node)
369
370 yield cpus_node
282 else:
283 if len(self.isa) != int(self.numThreads):
284 raise RuntimeError("Number of ISA instances doesn't "
285 "match thread count")
286 if self.checker != NULL:
287 self.checker.createThreads()
288
289 def addCheckerCpu(self):
290 pass
291
292 def createPhandleKey(self, thread):
293 # This method creates a unique key for this cpu as a function of a
294 # certain thread
295 return 'CPU-%d-%d-%d' % (self.socket_id, self.cpu_id, thread)
296
297 #Generate simple CPU Device Tree structure
298 def generateDeviceTree(self, state):
299 """Generate cpu nodes for each thread and the corresponding part of the
300 cpu-map node. Note that this implementation does not support clusters
301 of clusters. Note that GEM5 is not compatible with the official way of
302 numbering cores as defined in the Device Tree documentation. Where the
303 cpu_id needs to reset to 0 for each cluster by specification, GEM5
304 expects the cpu_id to be globally unique and incremental. This
305 generated node adheres the GEM5 way of doing things."""
306 if bool(self.switched_out):
307 return
308
309 cpus_node = FdtNode('cpus')
310 cpus_node.append(state.CPUCellsProperty())
311 #Special size override of 0
312 cpus_node.append(FdtPropertyWords('#size-cells', [0]))
313
314 # Generate cpu nodes
315 for i in range(int(self.numThreads)):
316 reg = (int(self.socket_id)<<8) + int(self.cpu_id) + i
317 node = FdtNode("cpu@%x" % reg)
318 node.append(FdtPropertyStrings("device_type", "cpu"))
319 node.appendCompatible(["gem5,arm-cpu"])
320 node.append(FdtPropertyWords("reg", state.CPUAddrCells(reg)))
321 platform, found = self.system.unproxy(self).find_any(Platform)
322 if found:
323 platform.annotateCpuDeviceNode(node, state)
324 else:
325 warn("Platform not found for device tree generation; " \
326 "system or multiple CPUs may not start")
327
328 freq = int(self.clk_domain.unproxy(self).clock[0].frequency)
329 node.append(FdtPropertyWords("clock-frequency", freq))
330
331 # Unique key for this CPU
332 phandle_key = self.createPhandleKey(i)
333 node.appendPhandle(phandle_key)
334 cpus_node.append(node)
335
336 yield cpus_node