BaseCPU.py revision 14147:638fe1150005
14486Sbinkertn@umich.edu# Copyright (c) 2012-2013, 2015-2017 ARM Limited 24486Sbinkertn@umich.edu# All rights reserved. 34486Sbinkertn@umich.edu# 44486Sbinkertn@umich.edu# The license below extends only to copyright in the software and shall 54486Sbinkertn@umich.edu# not be construed as granting a license to any other intellectual 64486Sbinkertn@umich.edu# property including but not limited to intellectual property relating 74486Sbinkertn@umich.edu# to a hardware implementation of the functionality of the software 84486Sbinkertn@umich.edu# licensed hereunder. You may use the software subject to the license 94486Sbinkertn@umich.edu# terms below provided that you ensure that this notice is replicated 104486Sbinkertn@umich.edu# unmodified and in its entirety in all distributions of the software, 114486Sbinkertn@umich.edu# modified or unmodified, in source code or in binary form. 124486Sbinkertn@umich.edu# 134486Sbinkertn@umich.edu# Copyright (c) 2005-2008 The Regents of The University of Michigan 144486Sbinkertn@umich.edu# Copyright (c) 2011 Regents of the University of California 154486Sbinkertn@umich.edu# All rights reserved. 164486Sbinkertn@umich.edu# 174486Sbinkertn@umich.edu# Redistribution and use in source and binary forms, with or without 184486Sbinkertn@umich.edu# modification, are permitted provided that the following conditions are 194486Sbinkertn@umich.edu# met: redistributions of source code must retain the above copyright 204486Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer; 214486Sbinkertn@umich.edu# redistributions in binary form must reproduce the above copyright 224486Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer in the 234486Sbinkertn@umich.edu# documentation and/or other materials provided with the distribution; 244486Sbinkertn@umich.edu# neither the name of the copyright holders nor the names of its 254486Sbinkertn@umich.edu# contributors may be used to endorse or promote products derived from 264486Sbinkertn@umich.edu# this software without specific prior written permission. 274486Sbinkertn@umich.edu# 284486Sbinkertn@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 296654Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 303102SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 313102SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 321681SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 333223SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 348887Sgeoffrey.blake@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 354486Sbinkertn@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362817SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372817SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 389341SAndreas.Sandberg@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 399341SAndreas.Sandberg@arm.com# 402932SN/A# Authors: Nathan Binkert 411681SN/A# Rick Strong 424597Sbinkertn@umich.edu# Andreas Hansson 431681SN/A# Glenn Bergmans 449184Sandreas.hansson@arm.com 459184Sandreas.hansson@arm.comfrom __future__ import print_function 469184Sandreas.hansson@arm.com 479184Sandreas.hansson@arm.comimport sys 489184Sandreas.hansson@arm.com 492932SN/Afrom m5.SimObject import * 502932SN/Afrom m5.defines import buildEnv 519184Sandreas.hansson@arm.comfrom m5.params import * 529184Sandreas.hansson@arm.comfrom m5.proxy import * 539184Sandreas.hansson@arm.comfrom m5.util.fdthelper import * 549184Sandreas.hansson@arm.com 559184Sandreas.hansson@arm.comfrom m5.objects.ClockedObject import ClockedObject 562932SN/Afrom m5.objects.XBar import L2XBar 571681SN/Afrom m5.objects.InstTracer import InstTracer 589184Sandreas.hansson@arm.comfrom m5.objects.CPUTracers import ExeTracer 599184Sandreas.hansson@arm.comfrom m5.objects.SubSystem import SubSystem 609184Sandreas.hansson@arm.comfrom m5.objects.ClockDomain import * 619184Sandreas.hansson@arm.comfrom m5.objects.Platform import Platform 622932SN/A 631681SN/Adefault_tracer = ExeTracer() 649184Sandreas.hansson@arm.com 652932SN/Aif buildEnv['TARGET_ISA'] == 'alpha': 669184Sandreas.hansson@arm.com from m5.objects.AlphaTLB import AlphaDTB as ArchDTB, AlphaITB as ArchITB 672932SN/A from m5.objects.AlphaInterrupts import AlphaInterrupts as ArchInterrupts 689184Sandreas.hansson@arm.com from m5.objects.AlphaISA import AlphaISA as ArchISA 692932SN/A ArchInterruptsParam = VectorParam.AlphaInterrupts 702932SN/A ArchISAsParam = VectorParam.AlphaISA 712932SN/Aelif buildEnv['TARGET_ISA'] == 'sparc': 722932SN/A from m5.objects.SparcTLB import SparcTLB as ArchDTB, SparcTLB as ArchITB 732932SN/A from m5.objects.SparcInterrupts import SparcInterrupts as ArchInterrupts 743223SN/A from m5.objects.SparcISA import SparcISA as ArchISA 752932SN/A ArchInterruptsParam = VectorParam.SparcInterrupts 769184Sandreas.hansson@arm.com ArchISAsParam = VectorParam.SparcISA 771681SN/Aelif buildEnv['TARGET_ISA'] == 'x86': 789184Sandreas.hansson@arm.com from m5.objects.X86TLB import X86TLB as ArchDTB, X86TLB as ArchITB 792932SN/A from m5.objects.X86LocalApic import X86LocalApic as ArchInterrupts 802932SN/A from m5.objects.X86ISA import X86ISA as ArchISA 819184Sandreas.hansson@arm.com ArchInterruptsParam = VectorParam.X86LocalApic 829184Sandreas.hansson@arm.com ArchISAsParam = VectorParam.X86ISA 831681SN/Aelif buildEnv['TARGET_ISA'] == 'mips': 842932SN/A from m5.objects.MipsTLB import MipsTLB as ArchDTB, MipsTLB as ArchITB 852932SN/A from m5.objects.MipsInterrupts import MipsInterrupts as ArchInterrupts 861681SN/A from m5.objects.MipsISA import MipsISA as ArchISA 872932SN/A ArchInterruptsParam = VectorParam.MipsInterrupts 882932SN/A ArchISAsParam = VectorParam.MipsISA 892932SN/Aelif buildEnv['TARGET_ISA'] == 'arm': 902932SN/A from m5.objects.ArmTLB import ArmTLB as ArchDTB, ArmTLB as ArchITB 912932SN/A from m5.objects.ArmTLB import ArmStage2IMMU, ArmStage2DMMU 922932SN/A from m5.objects.ArmInterrupts import ArmInterrupts as ArchInterrupts 932932SN/A from m5.objects.ArmISA import ArmISA as ArchISA 943223SN/A ArchInterruptsParam = VectorParam.ArmInterrupts 952932SN/A ArchISAsParam = VectorParam.ArmISA 962932SN/Aelif buildEnv['TARGET_ISA'] == 'power': 971681SN/A from m5.objects.PowerTLB import PowerTLB as ArchDTB, PowerTLB as ArchITB 982932SN/A from m5.objects.PowerInterrupts import PowerInterrupts as ArchInterrupts 992932SN/A from m5.objects.PowerISA import PowerISA as ArchISA 1002873SN/A ArchInterruptsParam = VectorParam.PowerInterrupts 1012932SN/A ArchISAsParam = VectorParam.PowerISA 1021681SN/Aelif buildEnv['TARGET_ISA'] == 'riscv': 1032932SN/A from m5.objects.RiscvTLB import RiscvTLB as ArchDTB, RiscvTLB as ArchITB 1042932SN/A from m5.objects.RiscvInterrupts import RiscvInterrupts as ArchInterrupts 1058199SAli.Saidi@ARM.com from m5.objects.RiscvISA import RiscvISA as ArchISA 1068199SAli.Saidi@ARM.com ArchInterruptsParam = VectorParam.RiscvInterrupts 1078199SAli.Saidi@ARM.com ArchISAsParam = VectorParam.RiscvISA 1088519SAli.Saidi@ARM.comelse: 1098519SAli.Saidi@ARM.com print("Don't know what object types to use for ISA %s" % 1102932SN/A buildEnv['TARGET_ISA']) 1112932SN/A sys.exit(1) 1121681SN/A 1132932SN/Aclass BaseCPU(ClockedObject): 1141681SN/A type = 'BaseCPU' 1152932SN/A abstract = True 1162932SN/A cxx_header = "cpu/base.hh" 1172932SN/A 1182932SN/A cxx_exports = [ 1192932SN/A PyBindMethod("switchOut"), 1201681SN/A PyBindMethod("takeOverFrom"), 1212932SN/A PyBindMethod("switchedOut"), 1221681SN/A PyBindMethod("flushTLBs"), 1234597Sbinkertn@umich.edu PyBindMethod("totalInsts"), 1244597Sbinkertn@umich.edu PyBindMethod("scheduleInstStop"), 1254597Sbinkertn@umich.edu PyBindMethod("scheduleLoadStop"), 1264597Sbinkertn@umich.edu PyBindMethod("getCurrentInstCount"), 1274597Sbinkertn@umich.edu ] 1284597Sbinkertn@umich.edu 1294597Sbinkertn@umich.edu @classmethod 1304597Sbinkertn@umich.edu def memory_mode(cls): 1314597Sbinkertn@umich.edu """Which memory mode does this CPU require?""" 1324303SN/A return 'invalid' 1338727Snilay@cs.wisc.edu 1348727Snilay@cs.wisc.edu @classmethod 1358887Sgeoffrey.blake@arm.com def require_caches(cls): 1368887Sgeoffrey.blake@arm.com """Does the CPU model require caches? 1378887Sgeoffrey.blake@arm.com 1388887Sgeoffrey.blake@arm.com Some CPU models might make assumptions that require them to 1398887Sgeoffrey.blake@arm.com have caches. 1408887Sgeoffrey.blake@arm.com """ 1418887Sgeoffrey.blake@arm.com return False 1428887Sgeoffrey.blake@arm.com 1438887Sgeoffrey.blake@arm.com @classmethod 1448887Sgeoffrey.blake@arm.com def support_take_over(cls): 1458887Sgeoffrey.blake@arm.com """Does the CPU model support CPU takeOverFrom?""" 1469132Satgutier@umich.edu return False 1478887Sgeoffrey.blake@arm.com 1488887Sgeoffrey.blake@arm.com def takeOverFrom(self, old_cpu): 1498887Sgeoffrey.blake@arm.com self._ccObject.takeOverFrom(old_cpu._ccObject) 1508887Sgeoffrey.blake@arm.com 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") 185 if buildEnv['TARGET_ISA'] == 'arm': 186 istage2_mmu = Param.ArmStage2MMU(ArmStage2IMMU(), "Stage 2 trans") 187 dstage2_mmu = Param.ArmStage2MMU(ArmStage2DMMU(), "Stage 2 trans") 188 elif buildEnv['TARGET_ISA'] == 'power': 189 UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?") 190 interrupts = ArchInterruptsParam([], "Interrupt Controller") 191 isa = ArchISAsParam([], "ISA instance") 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): 227 self.interrupts = [ArchInterrupts() for i in range(self.numThreads)] 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: 281 self.isa = [ ArchISA() for i in range(self.numThreads) ] 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 337