base_config.py revision 9793
16313Sgblack@eecs.umich.edu# Copyright (c) 2012-2013 ARM Limited
27093Sgblack@eecs.umich.edu# All rights reserved.
37093Sgblack@eecs.umich.edu#
47093Sgblack@eecs.umich.edu# The license below extends only to copyright in the software and shall
57093Sgblack@eecs.umich.edu# not be construed as granting a license to any other intellectual
67093Sgblack@eecs.umich.edu# property including but not limited to intellectual property relating
77093Sgblack@eecs.umich.edu# to a hardware implementation of the functionality of the software
87093Sgblack@eecs.umich.edu# licensed hereunder.  You may use the software subject to the license
97093Sgblack@eecs.umich.edu# terms below provided that you ensure that this notice is replicated
107093Sgblack@eecs.umich.edu# unmodified and in its entirety in all distributions of the software,
117093Sgblack@eecs.umich.edu# modified or unmodified, in source code or in binary form.
127093Sgblack@eecs.umich.edu#
137093Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without
146313Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are
156313Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright
166313Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer;
176313Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright
186313Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the
196313Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution;
206313Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its
216313Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from
226313Sgblack@eecs.umich.edu# this software without specific prior written permission.
236313Sgblack@eecs.umich.edu#
246313Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
256313Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
266313Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
276313Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
286313Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
296313Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
306313Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
316313Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
326313Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
336313Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
346313Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
356313Sgblack@eecs.umich.edu#
366313Sgblack@eecs.umich.edu# Authors: Andreas Sandberg
376313Sgblack@eecs.umich.edu#          Andreas Hansson
386313Sgblack@eecs.umich.edu
396313Sgblack@eecs.umich.edufrom abc import ABCMeta, abstractmethod
406313Sgblack@eecs.umich.eduimport m5
416313Sgblack@eecs.umich.edufrom m5.objects import *
426313Sgblack@eecs.umich.edufrom m5.proxy import *
436313Sgblack@eecs.umich.edum5.util.addToPath('../configs/common')
447404SAli.Saidi@ARM.comimport FSConfig
456313Sgblack@eecs.umich.edufrom Caches import *
466333Sgblack@eecs.umich.edu
477404SAli.Saidi@ARM.com_have_kvm_support = 'BaseKvmCPU' in globals()
486313Sgblack@eecs.umich.edu
496313Sgblack@eecs.umich.educlass BaseSystem(object):
506333Sgblack@eecs.umich.edu    """Base system builder.
516313Sgblack@eecs.umich.edu
526313Sgblack@eecs.umich.edu    This class provides some basic functionality for creating an ARM
536313Sgblack@eecs.umich.edu    system with the usual peripherals (caches, GIC, etc.). It allows
546313Sgblack@eecs.umich.edu    customization by defining separate methods for different parts of
556313Sgblack@eecs.umich.edu    the initialization process.
566313Sgblack@eecs.umich.edu    """
576313Sgblack@eecs.umich.edu
586313Sgblack@eecs.umich.edu    __metaclass__ = ABCMeta
596333Sgblack@eecs.umich.edu
606718Sgblack@eecs.umich.edu    def __init__(self, mem_mode='timing', mem_class=SimpleMemory,
616718Sgblack@eecs.umich.edu                 cpu_class=TimingSimpleCPU, num_cpus=1, checker=False):
626718Sgblack@eecs.umich.edu        """Initialize a simple base system.
636718Sgblack@eecs.umich.edu
646718Sgblack@eecs.umich.edu        Keyword Arguments:
656718Sgblack@eecs.umich.edu          mem_mode -- String describing the memory mode (timing or atomic)
666718Sgblack@eecs.umich.edu          mem_class -- Memory controller class to use
676718Sgblack@eecs.umich.edu          cpu_class -- CPU class to use
686718Sgblack@eecs.umich.edu          num_cpus -- Number of CPUs to instantiate
696718Sgblack@eecs.umich.edu          checker -- Set to True to add checker CPUs
706718Sgblack@eecs.umich.edu        """
716718Sgblack@eecs.umich.edu        self.mem_mode = mem_mode
726718Sgblack@eecs.umich.edu        self.mem_class = mem_class
736718Sgblack@eecs.umich.edu        self.cpu_class = cpu_class
746718Sgblack@eecs.umich.edu        self.num_cpus = num_cpus
756718Sgblack@eecs.umich.edu        self.checker = checker
766718Sgblack@eecs.umich.edu
776718Sgblack@eecs.umich.edu    def create_cpus(self, cpu_clk_domain):
786718Sgblack@eecs.umich.edu        """Return a list of CPU objects to add to a system."""
796723Sgblack@eecs.umich.edu        cpus = [ self.cpu_class(clk_domain = cpu_clk_domain,
806723Sgblack@eecs.umich.edu                                cpu_id=i)
816723Sgblack@eecs.umich.edu                 for i in range(self.num_cpus) ]
826718Sgblack@eecs.umich.edu        if self.checker:
836718Sgblack@eecs.umich.edu            for c in cpus:
846718Sgblack@eecs.umich.edu                c.addCheckerCpu()
856718Sgblack@eecs.umich.edu        return cpus
866718Sgblack@eecs.umich.edu
876718Sgblack@eecs.umich.edu    def create_caches_private(self, cpu):
886718Sgblack@eecs.umich.edu        """Add private caches to a CPU.
896718Sgblack@eecs.umich.edu
906718Sgblack@eecs.umich.edu        Arguments:
916718Sgblack@eecs.umich.edu          cpu -- CPU instance to work on.
926313Sgblack@eecs.umich.edu        """
936313Sgblack@eecs.umich.edu        cpu.addPrivateSplitL1Caches(L1Cache(size='32kB', assoc=1),
947427Sgblack@eecs.umich.edu                                    L1Cache(size='32kB', assoc=4))
956313Sgblack@eecs.umich.edu
967405SAli.Saidi@ARM.com    def create_caches_shared(self, system):
977405SAli.Saidi@ARM.com        """Add shared caches to a system.
987405SAli.Saidi@ARM.com
997405SAli.Saidi@ARM.com        Arguments:
1006313Sgblack@eecs.umich.edu          system -- System to work on.
1016313Sgblack@eecs.umich.edu
1026313Sgblack@eecs.umich.edu        Returns:
1036313Sgblack@eecs.umich.edu          A bus that CPUs should use to connect to the shared cache.
1046718Sgblack@eecs.umich.edu        """
1056718Sgblack@eecs.umich.edu        system.toL2Bus = CoherentBus(clk_domain=system.cpu_clk_domain)
1066718Sgblack@eecs.umich.edu        system.l2c = L2Cache(clk_domain=system.cpu_clk_domain,
1076726Sgblack@eecs.umich.edu                             size='4MB', assoc=8)
1086726Sgblack@eecs.umich.edu        system.l2c.cpu_side = system.toL2Bus.master
1096718Sgblack@eecs.umich.edu        system.l2c.mem_side = system.membus.slave
1107310Sgblack@eecs.umich.edu        return system.toL2Bus
1117310Sgblack@eecs.umich.edu
1127310Sgblack@eecs.umich.edu    def init_cpu(self, system, cpu, sha_bus):
1137310Sgblack@eecs.umich.edu        """Initialize a CPU.
1147310Sgblack@eecs.umich.edu
1157310Sgblack@eecs.umich.edu        Arguments:
1167310Sgblack@eecs.umich.edu          system -- System to work on.
1177310Sgblack@eecs.umich.edu          cpu -- CPU to initialize.
1187310Sgblack@eecs.umich.edu        """
1197310Sgblack@eecs.umich.edu        if not cpu.switched_out:
1207310Sgblack@eecs.umich.edu            self.create_caches_private(cpu)
1217310Sgblack@eecs.umich.edu            cpu.createInterruptController()
1227310Sgblack@eecs.umich.edu            cpu.connectAllPorts(sha_bus if sha_bus != None else system.membus,
1237310Sgblack@eecs.umich.edu                                system.membus)
1247310Sgblack@eecs.umich.edu
1257310Sgblack@eecs.umich.edu    def init_kvm(self, system):
1267310Sgblack@eecs.umich.edu        """Do KVM-specific system initialization.
1277310Sgblack@eecs.umich.edu
1287310Sgblack@eecs.umich.edu        Arguments:
1297310Sgblack@eecs.umich.edu          system -- System to work on.
1307310Sgblack@eecs.umich.edu        """
1316718Sgblack@eecs.umich.edu        system.vm = KvmVM()
1326313Sgblack@eecs.umich.edu
1336313Sgblack@eecs.umich.edu    def init_system(self, system):
1346313Sgblack@eecs.umich.edu        """Initialize a system.
1356313Sgblack@eecs.umich.edu
1366313Sgblack@eecs.umich.edu        Arguments:
1376313Sgblack@eecs.umich.edu          system -- System to initialize.
1386313Sgblack@eecs.umich.edu        """
1396313Sgblack@eecs.umich.edu        self.create_clk_src(system)
1407614Sminkyu.jeong@arm.com        system.cpu = self.create_cpus(system.cpu_clk_domain)
1417614Sminkyu.jeong@arm.com
1427614Sminkyu.jeong@arm.com        if _have_kvm_support and \
1437614Sminkyu.jeong@arm.com                any([isinstance(c, BaseKvmCPU) for c in system.cpu]):
1447614Sminkyu.jeong@arm.com            self.init_kvm(system)
1457614Sminkyu.jeong@arm.com
1467614Sminkyu.jeong@arm.com        sha_bus = self.create_caches_shared(system)
1477614Sminkyu.jeong@arm.com        for cpu in system.cpu:
1487614Sminkyu.jeong@arm.com            self.init_cpu(system, cpu, sha_bus)
1497614Sminkyu.jeong@arm.com
1507614Sminkyu.jeong@arm.com    def create_clk_src(self,system):
1517614Sminkyu.jeong@arm.com        # Create system clock domain. This provides clock value to every
1527614Sminkyu.jeong@arm.com        # clocked object that lies beneath it unless explicitly overwritten
1537614Sminkyu.jeong@arm.com        # by a different clock domain.
1547614Sminkyu.jeong@arm.com        system.clk_domain = SrcClockDomain(clock = '1GHz')
1557614Sminkyu.jeong@arm.com
1567614Sminkyu.jeong@arm.com        # Create a seperate clock domain for components that should
1577614Sminkyu.jeong@arm.com        # run at CPUs frequency
1587614Sminkyu.jeong@arm.com        system.cpu_clk_domain = SrcClockDomain(clock = '2GHz')
1597614Sminkyu.jeong@arm.com
1607614Sminkyu.jeong@arm.com    @abstractmethod
1617614Sminkyu.jeong@arm.com    def create_system(self):
1627614Sminkyu.jeong@arm.com        """Create an return an initialized system."""
1637614Sminkyu.jeong@arm.com        pass
1647614Sminkyu.jeong@arm.com
1657614Sminkyu.jeong@arm.com    @abstractmethod
1667614Sminkyu.jeong@arm.com    def create_root(self):
1677614Sminkyu.jeong@arm.com        """Create and return a simulation root using the system
1687614Sminkyu.jeong@arm.com        defined by this class."""
1697614Sminkyu.jeong@arm.com        pass
1707614Sminkyu.jeong@arm.com
1717614Sminkyu.jeong@arm.comclass BaseSESystem(BaseSystem):
1727614Sminkyu.jeong@arm.com    """Basic syscall-emulation builder."""
1737614Sminkyu.jeong@arm.com
1747614Sminkyu.jeong@arm.com    def __init__(self, **kwargs):
1757614Sminkyu.jeong@arm.com        BaseSystem.__init__(self, **kwargs)
1767614Sminkyu.jeong@arm.com
1777614Sminkyu.jeong@arm.com    def init_system(self, system):
1787614Sminkyu.jeong@arm.com        BaseSystem.init_system(self, system)
1797614Sminkyu.jeong@arm.com
1806678Sgblack@eecs.umich.edu    def create_system(self):
1817733SAli.Saidi@ARM.com        system = System(physmem = self.mem_class(),
1827733SAli.Saidi@ARM.com                        membus = CoherentBus(),
1837733SAli.Saidi@ARM.com                        mem_mode = self.mem_mode)
1847733SAli.Saidi@ARM.com        system.system_port = system.membus.slave
1856678Sgblack@eecs.umich.edu        system.physmem.port = system.membus.master
1866678Sgblack@eecs.umich.edu        self.init_system(system)
1877733SAli.Saidi@ARM.com        return system
1887733SAli.Saidi@ARM.com
1897733SAli.Saidi@ARM.com    def create_root(self):
1907733SAli.Saidi@ARM.com        system = self.create_system()
1917733SAli.Saidi@ARM.com        m5.ticks.setGlobalFrequency('1THz')
1927733SAli.Saidi@ARM.com        return Root(full_system=False, system=system)
1936313Sgblack@eecs.umich.edu
1946313Sgblack@eecs.umich.educlass BaseSESystemUniprocessor(BaseSESystem):
1956313Sgblack@eecs.umich.edu    """Basic syscall-emulation builder for uniprocessor systems.
1967400SAli.Saidi@ARM.com
1977400SAli.Saidi@ARM.com    Note: This class is only really needed to provide backwards
1987400SAli.Saidi@ARM.com    compatibility in existing test cases.
1997400SAli.Saidi@ARM.com    """
2006313Sgblack@eecs.umich.edu
2016313Sgblack@eecs.umich.edu    def __init__(self, **kwargs):
2026313Sgblack@eecs.umich.edu        BaseSESystem.__init__(self, **kwargs)
2036313Sgblack@eecs.umich.edu
2046313Sgblack@eecs.umich.edu    def create_caches_private(self, cpu):
2056313Sgblack@eecs.umich.edu        # The atomic SE configurations do not use caches
206        if self.mem_mode == "timing":
207            # @todo We might want to revisit these rather enthusiastic L1 sizes
208            cpu.addTwoLevelCacheHierarchy(L1Cache(size='128kB'),
209                                          L1Cache(size='256kB'),
210                                          L2Cache(size='2MB'))
211
212    def create_caches_shared(self, system):
213        return None
214
215class BaseFSSystem(BaseSystem):
216    """Basic full system builder."""
217
218    def __init__(self, **kwargs):
219        BaseSystem.__init__(self, **kwargs)
220
221    def init_system(self, system):
222        BaseSystem.init_system(self, system)
223
224        # create the iocache, which by default runs at the system clock
225        system.iocache = IOCache(addr_ranges=system.mem_ranges)
226        system.iocache.cpu_side = system.iobus.master
227        system.iocache.mem_side = system.membus.slave
228
229    def create_root(self):
230        system = self.create_system()
231        m5.ticks.setGlobalFrequency('1THz')
232        return Root(full_system=True, system=system)
233
234class BaseFSSystemUniprocessor(BaseFSSystem):
235    """Basic full system builder for uniprocessor systems.
236
237    Note: This class is only really needed to provide backwards
238    compatibility in existing test cases.
239    """
240
241    def __init__(self, **kwargs):
242        BaseFSSystem.__init__(self, **kwargs)
243
244    def create_caches_private(self, cpu):
245        cpu.addTwoLevelCacheHierarchy(L1Cache(size='32kB', assoc=1),
246                                      L1Cache(size='32kB', assoc=4),
247                                      L2Cache(size='4MB', assoc=8))
248
249    def create_caches_shared(self, system):
250        return None
251
252class BaseFSSwitcheroo(BaseFSSystem):
253    """Uniprocessor system prepared for CPU switching"""
254
255    def __init__(self, cpu_classes, **kwargs):
256        BaseFSSystem.__init__(self, **kwargs)
257        self.cpu_classes = tuple(cpu_classes)
258
259    def create_cpus(self, cpu_clk_domain):
260        cpus = [ cclass(clk_domain = cpu_clk_domain,
261                        cpu_id=0,
262                        switched_out=True)
263                 for cclass in self.cpu_classes ]
264        cpus[0].switched_out = False
265        return cpus
266