BaseCPU.py revision 9384
11689SN/A# Copyright (c) 2012 ARM Limited
22326SN/A# All rights reserved.
31689SN/A#
41689SN/A# The license below extends only to copyright in the software and shall
51689SN/A# not be construed as granting a license to any other intellectual
61689SN/A# property including but not limited to intellectual property relating
71689SN/A# to a hardware implementation of the functionality of the software
81689SN/A# licensed hereunder.  You may use the software subject to the license
91689SN/A# terms below provided that you ensure that this notice is replicated
101689SN/A# unmodified and in its entirety in all distributions of the software,
111689SN/A# modified or unmodified, in source code or in binary form.
121689SN/A#
131689SN/A# Copyright (c) 2005-2008 The Regents of The University of Michigan
141689SN/A# Copyright (c) 2011 Regents of the University of California
151689SN/A# All rights reserved.
161689SN/A#
171689SN/A# Redistribution and use in source and binary forms, with or without
181689SN/A# modification, are permitted provided that the following conditions are
191689SN/A# met: redistributions of source code must retain the above copyright
201689SN/A# notice, this list of conditions and the following disclaimer;
211689SN/A# redistributions in binary form must reproduce the above copyright
221689SN/A# notice, this list of conditions and the following disclaimer in the
231689SN/A# documentation and/or other materials provided with the distribution;
241689SN/A# neither the name of the copyright holders nor the names of its
251689SN/A# contributors may be used to endorse or promote products derived from
261689SN/A# this software without specific prior written permission.
272665Ssaidi@eecs.umich.edu#
282665Ssaidi@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
291689SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
301689SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
311060SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
321060SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
331689SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
341060SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
351060SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
361060SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
371060SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382292SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
391717SN/A#
401060SN/A# Authors: Nathan Binkert
412292SN/A#          Rick Strong
421681SN/A#          Andreas Hansson
431681SN/A
442292SN/Aimport sys
452326SN/A
461061SN/Afrom m5.defines import buildEnv
471060SN/Afrom m5.params import *
481061SN/Afrom m5.proxy import *
492292SN/A
502292SN/Afrom Bus import CoherentBus
512292SN/Afrom InstTracer import InstTracer
522292SN/Afrom ExeTracer import ExeTracer
532820Sktlim@umich.edufrom MemObject import MemObject
542292SN/A
552820Sktlim@umich.edudefault_tracer = ExeTracer()
562820Sktlim@umich.edu
572307SN/Aif buildEnv['TARGET_ISA'] == 'alpha':
582307SN/A    from AlphaTLB import AlphaDTB, AlphaITB
591060SN/A    from AlphaInterrupts import AlphaInterrupts
602292SN/A    from AlphaISA import AlphaISA
612292SN/A    isa_class = AlphaISA
622292SN/Aelif buildEnv['TARGET_ISA'] == 'sparc':
631060SN/A    from SparcTLB import SparcTLB
641060SN/A    from SparcInterrupts import SparcInterrupts
651060SN/A    from SparcISA import SparcISA
661060SN/A    isa_class = SparcISA
671060SN/Aelif buildEnv['TARGET_ISA'] == 'x86':
681060SN/A    from X86TLB import X86TLB
691681SN/A    from X86LocalApic import X86LocalApic
702292SN/A    from X86ISA import X86ISA
711681SN/A    isa_class = X86ISA
722292SN/Aelif buildEnv['TARGET_ISA'] == 'mips':
732292SN/A    from MipsTLB import MipsTLB
742292SN/A    from MipsInterrupts import MipsInterrupts
752292SN/A    from MipsISA import MipsISA
762292SN/A    isa_class = MipsISA
772292SN/Aelif buildEnv['TARGET_ISA'] == 'arm':
782292SN/A    from ArmTLB import ArmTLB
792820Sktlim@umich.edu    from ArmInterrupts import ArmInterrupts
802820Sktlim@umich.edu    from ArmISA import ArmISA
812292SN/A    isa_class = ArmISA
822292SN/Aelif buildEnv['TARGET_ISA'] == 'power':
832820Sktlim@umich.edu    from PowerTLB import PowerTLB
842820Sktlim@umich.edu    from PowerInterrupts import PowerInterrupts
852292SN/A    from PowerISA import PowerISA
862292SN/A    isa_class = PowerISA
872292SN/A
882292SN/Aclass BaseCPU(MemObject):
892292SN/A    type = 'BaseCPU'
902292SN/A    abstract = True
912292SN/A    cxx_header = "cpu/base.hh"
922292SN/A
931060SN/A    @classmethod
941060SN/A    def export_methods(cls, code):
951681SN/A        code('''
961062SN/A    void switchOut();
972292SN/A    void takeOverFrom(BaseCPU *cpu);
981062SN/A''')
992301SN/A
1002301SN/A    def takeOverFrom(self, old_cpu):
1011062SN/A        self._ccObject.takeOverFrom(old_cpu._ccObject)
1022727Sktlim@umich.edu
1031062SN/A
1041062SN/A    system = Param.System(Parent.any, "system object")
1051062SN/A    cpu_id = Param.Int(-1, "CPU identifier")
1061062SN/A    numThreads = Param.Unsigned(1, "number of HW thread contexts")
1071062SN/A
1081062SN/A    function_trace = Param.Bool(False, "Enable function trace")
1091062SN/A    function_trace_start = Param.Tick(0, "Tick to start function trace")
1101062SN/A
1111062SN/A    checker = Param.BaseCPU(NULL, "checker CPU")
1121062SN/A
1131062SN/A    do_checkpoint_insts = Param.Bool(True,
1141062SN/A        "enable checkpoint pseudo instructions")
1151062SN/A    do_statistics_insts = Param.Bool(True,
1161062SN/A        "enable statistics pseudo instructions")
1171062SN/A
1181062SN/A    profile = Param.Latency('0ns', "trace the kernel stack")
1191062SN/A    do_quiesce = Param.Bool(True, "enable quiesce instructions")
1201062SN/A
1211062SN/A    workload = VectorParam.Process([], "processes to run")
1221062SN/A
1231062SN/A    if buildEnv['TARGET_ISA'] == 'sparc':
1241062SN/A        dtb = Param.SparcTLB(SparcTLB(), "Data TLB")
1251062SN/A        itb = Param.SparcTLB(SparcTLB(), "Instruction TLB")
1261062SN/A        interrupts = Param.SparcInterrupts(
1271062SN/A                NULL, "Interrupt Controller")
1281062SN/A        isa = VectorParam.SparcISA([ isa_class() ], "ISA instance")
1291062SN/A    elif buildEnv['TARGET_ISA'] == 'alpha':
1301062SN/A        dtb = Param.AlphaTLB(AlphaDTB(), "Data TLB")
1311062SN/A        itb = Param.AlphaTLB(AlphaITB(), "Instruction TLB")
1321062SN/A        interrupts = Param.AlphaInterrupts(
1331062SN/A                NULL, "Interrupt Controller")
1341062SN/A        isa = VectorParam.AlphaISA([ isa_class() ], "ISA instance")
1351062SN/A    elif buildEnv['TARGET_ISA'] == 'x86':
1361062SN/A        dtb = Param.X86TLB(X86TLB(), "Data TLB")
1371062SN/A        itb = Param.X86TLB(X86TLB(), "Instruction TLB")
1381062SN/A        interrupts = Param.X86LocalApic(NULL, "Interrupt Controller")
1391062SN/A        isa = VectorParam.X86ISA([ isa_class() ], "ISA instance")
1401062SN/A    elif buildEnv['TARGET_ISA'] == 'mips':
1411062SN/A        dtb = Param.MipsTLB(MipsTLB(), "Data TLB")
1421062SN/A        itb = Param.MipsTLB(MipsTLB(), "Instruction TLB")
1431062SN/A        interrupts = Param.MipsInterrupts(
1442292SN/A                NULL, "Interrupt Controller")
1452292SN/A        isa = VectorParam.MipsISA([ isa_class() ], "ISA instance")
1462292SN/A    elif buildEnv['TARGET_ISA'] == 'arm':
1472292SN/A        dtb = Param.ArmTLB(ArmTLB(), "Data TLB")
1481062SN/A        itb = Param.ArmTLB(ArmTLB(), "Instruction TLB")
1491062SN/A        interrupts = Param.ArmInterrupts(
1501062SN/A                NULL, "Interrupt Controller")
1511062SN/A        isa = VectorParam.ArmISA([ isa_class() ], "ISA instance")
1521062SN/A    elif buildEnv['TARGET_ISA'] == 'power':
1531062SN/A        UnifiedTLB = Param.Bool(True, "Is this a Unified TLB?")
1541062SN/A        dtb = Param.PowerTLB(PowerTLB(), "Data TLB")
1552292SN/A        itb = Param.PowerTLB(PowerTLB(), "Instruction TLB")
1562292SN/A        interrupts = Param.PowerInterrupts(
1572292SN/A                NULL, "Interrupt Controller")
1582292SN/A        isa = VectorParam.PowerISA([ isa_class() ], "ISA instance")
1592292SN/A    else:
1602292SN/A        print "Don't know what TLB to use for ISA %s" % \
1612292SN/A            buildEnv['TARGET_ISA']
1622292SN/A        sys.exit(1)
1632292SN/A
1642292SN/A    max_insts_all_threads = Param.Counter(0,
1652301SN/A        "terminate when all threads have reached this inst count")
1662727Sktlim@umich.edu    max_insts_any_thread = Param.Counter(0,
1672727Sktlim@umich.edu        "terminate when any thread reaches this inst count")
1682727Sktlim@umich.edu    max_loads_all_threads = Param.Counter(0,
1692727Sktlim@umich.edu        "terminate when all threads have reached this load count")
1702727Sktlim@umich.edu    max_loads_any_thread = Param.Counter(0,
1712727Sktlim@umich.edu        "terminate when any thread reaches this load count")
1722727Sktlim@umich.edu    progress_interval = Param.Frequency('0Hz',
1732727Sktlim@umich.edu        "frequency to print out the progress message")
1742727Sktlim@umich.edu
1752727Sktlim@umich.edu    defer_registration = Param.Bool(False,
1762727Sktlim@umich.edu        "defer registration with system (for sampling)")
1772727Sktlim@umich.edu
1782727Sktlim@umich.edu    tracer = Param.InstTracer(default_tracer, "Instruction tracer")
1792727Sktlim@umich.edu
1802727Sktlim@umich.edu    icache_port = MasterPort("Instruction Port")
1812301SN/A    dcache_port = MasterPort("Data Port")
1822301SN/A    _cached_ports = ['icache_port', 'dcache_port']
1832301SN/A
1842727Sktlim@umich.edu    if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
1852301SN/A        _cached_ports += ["itb.walker.port", "dtb.walker.port"]
1862727Sktlim@umich.edu
1872301SN/A    _uncached_slave_ports = []
1882301SN/A    _uncached_master_ports = []
1892301SN/A    if buildEnv['TARGET_ISA'] == 'x86':
1902727Sktlim@umich.edu        _uncached_slave_ports += ["interrupts.pio", "interrupts.int_slave"]
1912301SN/A        _uncached_master_ports += ["interrupts.int_master"]
1922727Sktlim@umich.edu
1932301SN/A    def createInterruptController(self):
1942301SN/A        if buildEnv['TARGET_ISA'] == 'sparc':
1952301SN/A            self.interrupts = SparcInterrupts()
1962727Sktlim@umich.edu        elif buildEnv['TARGET_ISA'] == 'alpha':
1972301SN/A            self.interrupts = AlphaInterrupts()
1982727Sktlim@umich.edu        elif buildEnv['TARGET_ISA'] == 'x86':
1992301SN/A            _localApic = X86LocalApic(pio_addr=0x2000000000000000)
2002301SN/A            self.interrupts = _localApic
2012301SN/A        elif buildEnv['TARGET_ISA'] == 'mips':
2022727Sktlim@umich.edu            self.interrupts = MipsInterrupts()
2032301SN/A        elif buildEnv['TARGET_ISA'] == 'arm':
2042301SN/A            self.interrupts = ArmInterrupts()
2052301SN/A        elif buildEnv['TARGET_ISA'] == 'power':
2062301SN/A            self.interrupts = PowerInterrupts()
2072727Sktlim@umich.edu        else:
2082727Sktlim@umich.edu            print "Don't know what Interrupt Controller to use for ISA %s" % \
2092727Sktlim@umich.edu                buildEnv['TARGET_ISA']
2102727Sktlim@umich.edu            sys.exit(1)
2112727Sktlim@umich.edu
2122727Sktlim@umich.edu    def connectCachedPorts(self, bus):
2132727Sktlim@umich.edu        for p in self._cached_ports:
2142727Sktlim@umich.edu            exec('self.%s = bus.slave' % p)
2152727Sktlim@umich.edu
2162301SN/A    def connectUncachedPorts(self, bus):
2172301SN/A        for p in self._uncached_slave_ports:
2182301SN/A            exec('self.%s = bus.master' % p)
2192301SN/A        for p in self._uncached_master_ports:
2202301SN/A            exec('self.%s = bus.slave' % p)
2212727Sktlim@umich.edu
2222301SN/A    def connectAllPorts(self, cached_bus, uncached_bus = None):
2232326SN/A        self.connectCachedPorts(cached_bus)
2242301SN/A        if not uncached_bus:
2252301SN/A            uncached_bus = cached_bus
2262301SN/A        self.connectUncachedPorts(uncached_bus)
2272727Sktlim@umich.edu
2282301SN/A    def addPrivateSplitL1Caches(self, ic, dc, iwc = None, dwc = None):
2292326SN/A        self.icache = ic
2302301SN/A        self.dcache = dc
2312301SN/A        self.icache_port = ic.cpu_side
2322301SN/A        self.dcache_port = dc.cpu_side
2332727Sktlim@umich.edu        self._cached_ports = ['icache.mem_side', 'dcache.mem_side']
2342301SN/A        if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
2352326SN/A            if iwc and dwc:
2362301SN/A                self.itb_walker_cache = iwc
2372301SN/A                self.dtb_walker_cache = dwc
2382301SN/A                self.itb.walker.port = iwc.cpu_side
2392727Sktlim@umich.edu                self.dtb.walker.port = dwc.cpu_side
2402301SN/A                self._cached_ports += ["itb_walker_cache.mem_side", \
2412326SN/A                                       "dtb_walker_cache.mem_side"]
2422301SN/A            else:
2432301SN/A                self._cached_ports += ["itb.walker.port", "dtb.walker.port"]
2442301SN/A
2452727Sktlim@umich.edu            # Checker doesn't need its own tlb caches because it does
2462301SN/A            # functional accesses only
2472326SN/A            if self.checker != NULL:
2482301SN/A                self._cached_ports += ["checker.itb.walker.port", \
2492301SN/A                                       "checker.dtb.walker.port"]
2502727Sktlim@umich.edu
2512301SN/A    def addTwoLevelCacheHierarchy(self, ic, dc, l2c, iwc = None, dwc = None):
2522326SN/A        self.addPrivateSplitL1Caches(ic, dc, iwc, dwc)
2532301SN/A        # Override the default bus clock of 1 GHz and uses the CPU
2542326SN/A        # clock for the L1-to-L2 bus, and also set a width of 32 bytes
2552301SN/A        # (256-bits), which is four times that of the default bus.
2562301SN/A        self.toL2Bus = CoherentBus(clock = Parent.clock, width = 32)
2572727Sktlim@umich.edu        self.connectCachedPorts(self.toL2Bus)
2582301SN/A        self.l2cache = l2c
2592326SN/A        self.toL2Bus.master = self.l2cache.cpu_side
2602301SN/A        self._cached_ports = ['l2cache.mem_side']
2612326SN/A
2622301SN/A    def createThreads(self):
2632301SN/A        self.isa = [ isa_class() for i in xrange(self.numThreads) ]
2642727Sktlim@umich.edu        if self.checker != NULL:
2652326SN/A            self.checker.createThreads()
2661062SN/A
2671062SN/A    def addCheckerCpu(self):
2681681SN/A        pass
2691060SN/A