devices.py revision 13636
111723Sar4jc@virginia.edu# Copyright (c) 2016-2017 ARM Limited 211723Sar4jc@virginia.edu# All rights reserved. 311723Sar4jc@virginia.edu# 411723Sar4jc@virginia.edu# The license below extends only to copyright in the software and shall 511723Sar4jc@virginia.edu# not be construed as granting a license to any other intellectual 611723Sar4jc@virginia.edu# property including but not limited to intellectual property relating 711723Sar4jc@virginia.edu# to a hardware implementation of the functionality of the software 811723Sar4jc@virginia.edu# licensed hereunder. You may use the software subject to the license 911723Sar4jc@virginia.edu# terms below provided that you ensure that this notice is replicated 1011723Sar4jc@virginia.edu# unmodified and in its entirety in all distributions of the software, 1111723Sar4jc@virginia.edu# modified or unmodified, in source code or in binary form. 1211723Sar4jc@virginia.edu# 1311723Sar4jc@virginia.edu# Redistribution and use in source and binary forms, with or without 1411723Sar4jc@virginia.edu# modification, are permitted provided that the following conditions are 1511723Sar4jc@virginia.edu# met: redistributions of source code must retain the above copyright 1611723Sar4jc@virginia.edu# notice, this list of conditions and the following disclaimer; 1711723Sar4jc@virginia.edu# redistributions in binary form must reproduce the above copyright 1811723Sar4jc@virginia.edu# notice, this list of conditions and the following disclaimer in the 1911723Sar4jc@virginia.edu# documentation and/or other materials provided with the distribution; 2011723Sar4jc@virginia.edu# neither the name of the copyright holders nor the names of its 2111723Sar4jc@virginia.edu# contributors may be used to endorse or promote products derived from 2211723Sar4jc@virginia.edu# this software without specific prior written permission. 2311723Sar4jc@virginia.edu# 2411723Sar4jc@virginia.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2511723Sar4jc@virginia.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2611723Sar4jc@virginia.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2711723Sar4jc@virginia.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2811723Sar4jc@virginia.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2911723Sar4jc@virginia.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3011723Sar4jc@virginia.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3111723Sar4jc@virginia.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3211723Sar4jc@virginia.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3311723Sar4jc@virginia.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3411723Sar4jc@virginia.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3511723Sar4jc@virginia.edu# 3611723Sar4jc@virginia.edu# Authors: Andreas Sandberg 3711723Sar4jc@virginia.edu# Gabor Dozsa 3811723Sar4jc@virginia.edu 3911723Sar4jc@virginia.edu# System components used by the bigLITTLE.py configuration script 4011723Sar4jc@virginia.edu 4111723Sar4jc@virginia.eduimport m5 4211723Sar4jc@virginia.edufrom m5.objects import * 4311723Sar4jc@virginia.edum5.util.addToPath('../../') 4411723Sar4jc@virginia.edufrom common.Caches import * 4511723Sar4jc@virginia.edufrom common import CpuConfig 4612334Sgabeblack@google.com 4712106SRekai.GonzalezAlberquilla@arm.comhave_kvm = "ArmV8KvmCPU" in CpuConfig.cpu_names() 4811723Sar4jc@virginia.edu 4911723Sar4jc@virginia.educlass L1I(L1_ICache): 5011723Sar4jc@virginia.edu tag_latency = 1 5111723Sar4jc@virginia.edu data_latency = 1 5211723Sar4jc@virginia.edu response_latency = 1 5311723Sar4jc@virginia.edu mshrs = 4 5411723Sar4jc@virginia.edu tgts_per_mshr = 8 5511723Sar4jc@virginia.edu size = '48kB' 5611723Sar4jc@virginia.edu assoc = 3 5711723Sar4jc@virginia.edu 5811723Sar4jc@virginia.edu 5911723Sar4jc@virginia.educlass L1D(L1_DCache): 6011723Sar4jc@virginia.edu tag_latency = 2 6111723Sar4jc@virginia.edu data_latency = 2 6211723Sar4jc@virginia.edu response_latency = 1 6311723Sar4jc@virginia.edu mshrs = 16 6411723Sar4jc@virginia.edu tgts_per_mshr = 16 6511723Sar4jc@virginia.edu size = '32kB' 6611723Sar4jc@virginia.edu assoc = 2 6711723Sar4jc@virginia.edu write_buffers = 16 6811723Sar4jc@virginia.edu 6911723Sar4jc@virginia.edu 7011723Sar4jc@virginia.educlass WalkCache(PageTableWalkerCache): 7111723Sar4jc@virginia.edu tag_latency = 4 7211723Sar4jc@virginia.edu data_latency = 4 7311723Sar4jc@virginia.edu response_latency = 4 7411723Sar4jc@virginia.edu mshrs = 6 7511723Sar4jc@virginia.edu tgts_per_mshr = 8 7611723Sar4jc@virginia.edu size = '1kB' 7711723Sar4jc@virginia.edu assoc = 8 7811723Sar4jc@virginia.edu write_buffers = 16 7911723Sar4jc@virginia.edu 8011723Sar4jc@virginia.edu 8112106SRekai.GonzalezAlberquilla@arm.comclass L2(L2Cache): 8212106SRekai.GonzalezAlberquilla@arm.com tag_latency = 12 8312106SRekai.GonzalezAlberquilla@arm.com data_latency = 12 8412106SRekai.GonzalezAlberquilla@arm.com response_latency = 5 8512106SRekai.GonzalezAlberquilla@arm.com mshrs = 32 8612106SRekai.GonzalezAlberquilla@arm.com tgts_per_mshr = 8 8711723Sar4jc@virginia.edu size = '1MB' 8811723Sar4jc@virginia.edu assoc = 16 8911723Sar4jc@virginia.edu write_buffers = 8 9011723Sar4jc@virginia.edu clusivity='mostly_excl' 9111723Sar4jc@virginia.edu 9211723Sar4jc@virginia.edu 9311723Sar4jc@virginia.educlass L3(Cache): 9411723Sar4jc@virginia.edu size = '16MB' 9511723Sar4jc@virginia.edu assoc = 16 9611723Sar4jc@virginia.edu tag_latency = 20 9711723Sar4jc@virginia.edu data_latency = 20 9811723Sar4jc@virginia.edu response_latency = 20 9912109SRekai.GonzalezAlberquilla@arm.com mshrs = 20 10012109SRekai.GonzalezAlberquilla@arm.com tgts_per_mshr = 12 10112109SRekai.GonzalezAlberquilla@arm.com clusivity='mostly_excl' 10212109SRekai.GonzalezAlberquilla@arm.com 10312109SRekai.GonzalezAlberquilla@arm.com 10412109SRekai.GonzalezAlberquilla@arm.comclass MemBus(SystemXBar): 10512109SRekai.GonzalezAlberquilla@arm.com badaddr_responder = BadAddr(warn_access="warn") 10612109SRekai.GonzalezAlberquilla@arm.com default = Self.badaddr_responder.pio 10712109SRekai.GonzalezAlberquilla@arm.com 10812109SRekai.GonzalezAlberquilla@arm.com 10912109SRekai.GonzalezAlberquilla@arm.comclass CpuCluster(SubSystem): 11012109SRekai.GonzalezAlberquilla@arm.com def __init__(self, system, num_cpus, cpu_clock, cpu_voltage, 11111723Sar4jc@virginia.edu cpu_type, l1i_type, l1d_type, wcache_type, l2_type): 11211723Sar4jc@virginia.edu super(CpuCluster, self).__init__() 11311723Sar4jc@virginia.edu self._cpu_type = cpu_type 11411723Sar4jc@virginia.edu self._l1i_type = l1i_type 11511723Sar4jc@virginia.edu self._l1d_type = l1d_type 11611723Sar4jc@virginia.edu self._wcache_type = wcache_type 11711723Sar4jc@virginia.edu self._l2_type = l2_type 11811723Sar4jc@virginia.edu 11911723Sar4jc@virginia.edu assert num_cpus > 0 12011723Sar4jc@virginia.edu 12111723Sar4jc@virginia.edu self.voltage_domain = VoltageDomain(voltage=cpu_voltage) 12211723Sar4jc@virginia.edu self.clk_domain = SrcClockDomain(clock=cpu_clock, 12311723Sar4jc@virginia.edu voltage_domain=self.voltage_domain) 12411723Sar4jc@virginia.edu 12511723Sar4jc@virginia.edu self.cpus = [ self._cpu_type(cpu_id=system.numCpus() + idx, 12611723Sar4jc@virginia.edu clk_domain=self.clk_domain) 12711723Sar4jc@virginia.edu for idx in range(num_cpus) ] 12811723Sar4jc@virginia.edu 12911723Sar4jc@virginia.edu for cpu in self.cpus: 13011723Sar4jc@virginia.edu cpu.createThreads() 13111723Sar4jc@virginia.edu cpu.createInterruptController() 13211723Sar4jc@virginia.edu cpu.socket_id = system.numCpuClusters() 13311723Sar4jc@virginia.edu system.addCpuCluster(self, num_cpus) 13411723Sar4jc@virginia.edu 13511723Sar4jc@virginia.edu def requireCaches(self): 13611723Sar4jc@virginia.edu return self._cpu_type.require_caches() 13711723Sar4jc@virginia.edu 138 def memoryMode(self): 139 return self._cpu_type.memory_mode() 140 141 def addL1(self): 142 for cpu in self.cpus: 143 l1i = None if self._l1i_type is None else self._l1i_type() 144 l1d = None if self._l1d_type is None else self._l1d_type() 145 iwc = None if self._wcache_type is None else self._wcache_type() 146 dwc = None if self._wcache_type is None else self._wcache_type() 147 cpu.addPrivateSplitL1Caches(l1i, l1d, iwc, dwc) 148 149 def addL2(self, clk_domain): 150 if self._l2_type is None: 151 return 152 self.toL2Bus = L2XBar(width=64, clk_domain=clk_domain) 153 self.l2 = self._l2_type() 154 for cpu in self.cpus: 155 cpu.connectAllPorts(self.toL2Bus) 156 self.toL2Bus.master = self.l2.cpu_side 157 158 def connectMemSide(self, bus): 159 bus.slave 160 try: 161 self.l2.mem_side = bus.slave 162 except AttributeError: 163 for cpu in self.cpus: 164 cpu.connectAllPorts(bus) 165 166 167class AtomicCluster(CpuCluster): 168 def __init__(self, system, num_cpus, cpu_clock, cpu_voltage="1.0V"): 169 cpu_config = [ CpuConfig.get("AtomicSimpleCPU"), None, None, None, None ] 170 super(AtomicCluster, self).__init__(system, num_cpus, cpu_clock, 171 cpu_voltage, *cpu_config) 172 def addL1(self): 173 pass 174 175class KvmCluster(CpuCluster): 176 def __init__(self, system, num_cpus, cpu_clock, cpu_voltage="1.0V"): 177 cpu_config = [ CpuConfig.get("ArmV8KvmCPU"), None, None, None, None ] 178 super(KvmCluster, self).__init__(system, num_cpus, cpu_clock, 179 cpu_voltage, *cpu_config) 180 def addL1(self): 181 pass 182 183 184class SimpleSystem(LinuxArmSystem): 185 cache_line_size = 64 186 187 def __init__(self, caches, mem_size, **kwargs): 188 super(SimpleSystem, self).__init__(**kwargs) 189 190 self.voltage_domain = VoltageDomain(voltage="1.0V") 191 self.clk_domain = SrcClockDomain(clock="1GHz", 192 voltage_domain=Parent.voltage_domain) 193 194 self.realview = VExpress_GEM5_V1() 195 196 self.gic_cpu_addr = self.realview.gic.cpu_addr 197 self.flags_addr = self.realview.realview_io.pio_addr + 0x30 198 199 self.membus = MemBus() 200 201 self.intrctrl = IntrControl() 202 self.terminal = Terminal() 203 self.vncserver = VncServer() 204 205 self.iobus = IOXBar() 206 # CPUs->PIO 207 self.iobridge = Bridge(delay='50ns') 208 # Device DMA -> MEM 209 mem_range = self.realview._mem_regions[0] 210 assert long(mem_range.size()) >= long(Addr(mem_size)) 211 self.mem_ranges = [ AddrRange(start=mem_range.start, size=mem_size) ] 212 self._caches = caches 213 if self._caches: 214 self.iocache = IOCache(addr_ranges=[self.mem_ranges[0]]) 215 else: 216 self.dmabridge = Bridge(delay='50ns', 217 ranges=[self.mem_ranges[0]]) 218 219 self._pci_devices = 0 220 self._clusters = [] 221 self._num_cpus = 0 222 223 def attach_pci(self, dev): 224 dev.pci_bus, dev.pci_dev, dev.pci_func = (0, self._pci_devices + 1, 0) 225 self._pci_devices += 1 226 self.realview.attachPciDevice(dev, self.iobus) 227 228 def connect(self): 229 self.iobridge.master = self.iobus.slave 230 self.iobridge.slave = self.membus.master 231 232 if self._caches: 233 self.iocache.mem_side = self.membus.slave 234 self.iocache.cpu_side = self.iobus.master 235 else: 236 self.dmabridge.master = self.membus.slave 237 self.dmabridge.slave = self.iobus.master 238 239 self.gic_cpu_addr = self.realview.gic.cpu_addr 240 self.realview.attachOnChipIO(self.membus, self.iobridge) 241 self.realview.attachIO(self.iobus) 242 self.system_port = self.membus.slave 243 244 def numCpuClusters(self): 245 return len(self._clusters) 246 247 def addCpuCluster(self, cpu_cluster, num_cpus): 248 assert cpu_cluster not in self._clusters 249 assert num_cpus > 0 250 self._clusters.append(cpu_cluster) 251 self._num_cpus += num_cpus 252 253 def numCpus(self): 254 return self._num_cpus 255 256 def addCaches(self, need_caches, last_cache_level): 257 if not need_caches: 258 # connect each cluster to the memory hierarchy 259 for cluster in self._clusters: 260 cluster.connectMemSide(self.membus) 261 return 262 263 cluster_mem_bus = self.membus 264 assert last_cache_level >= 1 and last_cache_level <= 3 265 for cluster in self._clusters: 266 cluster.addL1() 267 if last_cache_level > 1: 268 for cluster in self._clusters: 269 cluster.addL2(cluster.clk_domain) 270 if last_cache_level > 2: 271 max_clock_cluster = max(self._clusters, 272 key=lambda c: c.clk_domain.clock[0]) 273 self.l3 = L3(clk_domain=max_clock_cluster.clk_domain) 274 self.toL3Bus = L2XBar(width=64) 275 self.toL3Bus.master = self.l3.cpu_side 276 self.l3.mem_side = self.membus.slave 277 cluster_mem_bus = self.toL3Bus 278 279 # connect each cluster to the memory hierarchy 280 for cluster in self._clusters: 281 cluster.connectMemSide(cluster_mem_bus) 282