19447SAndreas.Sandberg@ARM.com# Copyright (c) 2012 ARM Limited
29447SAndreas.Sandberg@ARM.com# All rights reserved.
39447SAndreas.Sandberg@ARM.com#
49447SAndreas.Sandberg@ARM.com# The license below extends only to copyright in the software and shall
59447SAndreas.Sandberg@ARM.com# not be construed as granting a license to any other intellectual
69447SAndreas.Sandberg@ARM.com# property including but not limited to intellectual property relating
79447SAndreas.Sandberg@ARM.com# to a hardware implementation of the functionality of the software
89447SAndreas.Sandberg@ARM.com# licensed hereunder.  You may use the software subject to the license
99447SAndreas.Sandberg@ARM.com# terms below provided that you ensure that this notice is replicated
109447SAndreas.Sandberg@ARM.com# unmodified and in its entirety in all distributions of the software,
119447SAndreas.Sandberg@ARM.com# modified or unmodified, in source code or in binary form.
129447SAndreas.Sandberg@ARM.com#
139447SAndreas.Sandberg@ARM.com# Redistribution and use in source and binary forms, with or without
149447SAndreas.Sandberg@ARM.com# modification, are permitted provided that the following conditions are
159447SAndreas.Sandberg@ARM.com# met: redistributions of source code must retain the above copyright
169447SAndreas.Sandberg@ARM.com# notice, this list of conditions and the following disclaimer;
179447SAndreas.Sandberg@ARM.com# redistributions in binary form must reproduce the above copyright
189447SAndreas.Sandberg@ARM.com# notice, this list of conditions and the following disclaimer in the
199447SAndreas.Sandberg@ARM.com# documentation and/or other materials provided with the distribution;
209447SAndreas.Sandberg@ARM.com# neither the name of the copyright holders nor the names of its
219447SAndreas.Sandberg@ARM.com# contributors may be used to endorse or promote products derived from
229447SAndreas.Sandberg@ARM.com# this software without specific prior written permission.
239447SAndreas.Sandberg@ARM.com#
249447SAndreas.Sandberg@ARM.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
259447SAndreas.Sandberg@ARM.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
269447SAndreas.Sandberg@ARM.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
279447SAndreas.Sandberg@ARM.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
289447SAndreas.Sandberg@ARM.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
299447SAndreas.Sandberg@ARM.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
309447SAndreas.Sandberg@ARM.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
319447SAndreas.Sandberg@ARM.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
329447SAndreas.Sandberg@ARM.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
339447SAndreas.Sandberg@ARM.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
349447SAndreas.Sandberg@ARM.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
359447SAndreas.Sandberg@ARM.com#
369447SAndreas.Sandberg@ARM.com# Authors: Andreas Sandberg
379447SAndreas.Sandberg@ARM.com
3812575Sgiacomo.travaglini@arm.comfrom __future__ import print_function
3912575Sgiacomo.travaglini@arm.com
409447SAndreas.Sandberg@ARM.comimport m5
4111802Sandreas.sandberg@arm.comimport _m5
429447SAndreas.Sandberg@ARM.comfrom m5.objects import *
4311682Sandreas.hansson@arm.comm5.util.addToPath('../configs/')
4411682Sandreas.hansson@arm.comfrom common.Caches import *
459447SAndreas.Sandberg@ARM.com
469447SAndreas.Sandberg@ARM.comclass Sequential:
479447SAndreas.Sandberg@ARM.com    """Sequential CPU switcher.
489447SAndreas.Sandberg@ARM.com
499447SAndreas.Sandberg@ARM.com    The sequential CPU switches between all CPUs in a system in
509447SAndreas.Sandberg@ARM.com    order. The CPUs in the system must have been prepared for
519447SAndreas.Sandberg@ARM.com    switching, which in practice means that only one CPU is switched
529447SAndreas.Sandberg@ARM.com    in. base_config.BaseFSSwitcheroo can be used to create such a
539447SAndreas.Sandberg@ARM.com    system.
549447SAndreas.Sandberg@ARM.com    """
559447SAndreas.Sandberg@ARM.com    def __init__(self, cpus):
569447SAndreas.Sandberg@ARM.com        self.first_cpu = None
579447SAndreas.Sandberg@ARM.com        for (cpuno, cpu) in enumerate(cpus):
589447SAndreas.Sandberg@ARM.com            if not cpu.switched_out:
599447SAndreas.Sandberg@ARM.com                if self.first_cpu != None:
609447SAndreas.Sandberg@ARM.com                    fatal("More than one CPU is switched in");
619447SAndreas.Sandberg@ARM.com                self.first_cpu = cpuno
629447SAndreas.Sandberg@ARM.com
639447SAndreas.Sandberg@ARM.com        if self.first_cpu == None:
649447SAndreas.Sandberg@ARM.com            fatal("The system contains no switched in CPUs")
659447SAndreas.Sandberg@ARM.com
669447SAndreas.Sandberg@ARM.com        self.cur_cpu = self.first_cpu
679447SAndreas.Sandberg@ARM.com        self.cpus = cpus
689447SAndreas.Sandberg@ARM.com
699447SAndreas.Sandberg@ARM.com    def next(self):
709447SAndreas.Sandberg@ARM.com        self.cur_cpu = (self.cur_cpu + 1) % len(self.cpus)
719447SAndreas.Sandberg@ARM.com        return self.cpus[self.cur_cpu]
729447SAndreas.Sandberg@ARM.com
739447SAndreas.Sandberg@ARM.com    def first(self):
749447SAndreas.Sandberg@ARM.com        return self.cpus[self.first_cpu]
759447SAndreas.Sandberg@ARM.com
769980Ssteve.reinhardt@amd.comdef run_test(root, switcher=None, freq=1000, verbose=False):
779447SAndreas.Sandberg@ARM.com    """Test runner for CPU switcheroo tests.
789447SAndreas.Sandberg@ARM.com
799447SAndreas.Sandberg@ARM.com    The switcheroo test runner is used to switch CPUs in a system that
809447SAndreas.Sandberg@ARM.com    has been prepared for CPU switching. Such systems should have
819447SAndreas.Sandberg@ARM.com    multiple CPUs when they are instantiated, but only one should be
829447SAndreas.Sandberg@ARM.com    switched in. Such configurations can be created using the
839447SAndreas.Sandberg@ARM.com    base_config.BaseFSSwitcheroo class.
849447SAndreas.Sandberg@ARM.com
859447SAndreas.Sandberg@ARM.com    A CPU switcher object is used to control switching. The default
869447SAndreas.Sandberg@ARM.com    switcher sequentially switches between all CPUs in a system,
879447SAndreas.Sandberg@ARM.com    starting with the CPU that is currently switched in.
889447SAndreas.Sandberg@ARM.com
899447SAndreas.Sandberg@ARM.com    Unlike most other test runners, this one automatically configures
909447SAndreas.Sandberg@ARM.com    the memory mode of the system based on the first CPU the switcher
919447SAndreas.Sandberg@ARM.com    reports.
929447SAndreas.Sandberg@ARM.com
939447SAndreas.Sandberg@ARM.com    Keyword Arguments:
949447SAndreas.Sandberg@ARM.com      switcher -- CPU switcher implementation. See Sequential for
959447SAndreas.Sandberg@ARM.com                  an example implementation.
969447SAndreas.Sandberg@ARM.com      period -- Switching frequency in Hz.
979980Ssteve.reinhardt@amd.com      verbose -- Enable output at each switch (suppressed by default).
989447SAndreas.Sandberg@ARM.com    """
999447SAndreas.Sandberg@ARM.com
1009447SAndreas.Sandberg@ARM.com    if switcher == None:
1019447SAndreas.Sandberg@ARM.com        switcher = Sequential(root.system.cpu)
1029447SAndreas.Sandberg@ARM.com
1039447SAndreas.Sandberg@ARM.com    current_cpu = switcher.first()
1049447SAndreas.Sandberg@ARM.com    system = root.system
1059521SAndreas.Sandberg@ARM.com    system.mem_mode = type(current_cpu).memory_mode()
1069447SAndreas.Sandberg@ARM.com
1079980Ssteve.reinhardt@amd.com    # Suppress "Entering event queue" messages since we get tons of them.
1089980Ssteve.reinhardt@amd.com    # Worse yet, they include the timestamp, which makes them highly
1099980Ssteve.reinhardt@amd.com    # variable and unsuitable for comparing as test outputs.
11011880Sandreas.sandberg@arm.com    if not verbose:
11111988Sandreas.sandberg@arm.com        _m5.core.setLogLevel(_m5.core.LogLevel.WARN)
1129980Ssteve.reinhardt@amd.com
1139447SAndreas.Sandberg@ARM.com    # instantiate configuration
1149447SAndreas.Sandberg@ARM.com    m5.instantiate()
1159447SAndreas.Sandberg@ARM.com
1169447SAndreas.Sandberg@ARM.com    # Determine the switching period, this has to be done after
1179447SAndreas.Sandberg@ARM.com    # instantiating the system since the time base must be fixed.
1189447SAndreas.Sandberg@ARM.com    period = m5.ticks.fromSeconds(1.0 / freq)
1199447SAndreas.Sandberg@ARM.com    while True:
1209447SAndreas.Sandberg@ARM.com        exit_event = m5.simulate(period)
1219447SAndreas.Sandberg@ARM.com        exit_cause = exit_event.getCause()
1229447SAndreas.Sandberg@ARM.com
1239447SAndreas.Sandberg@ARM.com        if exit_cause == "simulate() limit reached":
1249447SAndreas.Sandberg@ARM.com            next_cpu = switcher.next()
1259447SAndreas.Sandberg@ARM.com
1269980Ssteve.reinhardt@amd.com            if verbose:
12712575Sgiacomo.travaglini@arm.com                print("Switching CPUs...")
12812575Sgiacomo.travaglini@arm.com                print("Next CPU: %s" % type(next_cpu))
12910912Sandreas.sandberg@arm.com            m5.drain()
1309447SAndreas.Sandberg@ARM.com            if current_cpu != next_cpu:
1319521SAndreas.Sandberg@ARM.com                m5.switchCpus(system, [ (current_cpu, next_cpu) ],
13210912Sandreas.sandberg@arm.com                              verbose=verbose)
1339447SAndreas.Sandberg@ARM.com            else:
13412575Sgiacomo.travaglini@arm.com                print("Source CPU and destination CPU are the same,"
13512575Sgiacomo.travaglini@arm.com                    " skipping...")
1369447SAndreas.Sandberg@ARM.com            current_cpu = next_cpu
1379447SAndreas.Sandberg@ARM.com        elif exit_cause == "target called exit()" or \
1389447SAndreas.Sandberg@ARM.com                exit_cause == "m5_exit instruction encountered":
1399447SAndreas.Sandberg@ARM.com
1409447SAndreas.Sandberg@ARM.com            sys.exit(0)
1419447SAndreas.Sandberg@ARM.com        else:
14212575Sgiacomo.travaglini@arm.com            print("Test failed: Unknown exit cause: %s" % exit_cause)
1439447SAndreas.Sandberg@ARM.com            sys.exit(1)
144