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