switcheroo.py revision 12575
110201SAndrew.Bardsley@arm.com# Copyright (c) 2012 ARM Limited 210201SAndrew.Bardsley@arm.com# All rights reserved. 310201SAndrew.Bardsley@arm.com# 410201SAndrew.Bardsley@arm.com# The license below extends only to copyright in the software and shall 510201SAndrew.Bardsley@arm.com# not be construed as granting a license to any other intellectual 610201SAndrew.Bardsley@arm.com# property including but not limited to intellectual property relating 710201SAndrew.Bardsley@arm.com# to a hardware implementation of the functionality of the software 810201SAndrew.Bardsley@arm.com# licensed hereunder. You may use the software subject to the license 910201SAndrew.Bardsley@arm.com# terms below provided that you ensure that this notice is replicated 1010201SAndrew.Bardsley@arm.com# unmodified and in its entirety in all distributions of the software, 1110201SAndrew.Bardsley@arm.com# modified or unmodified, in source code or in binary form. 1210201SAndrew.Bardsley@arm.com# 1310201SAndrew.Bardsley@arm.com# Redistribution and use in source and binary forms, with or without 1410201SAndrew.Bardsley@arm.com# modification, are permitted provided that the following conditions are 1510201SAndrew.Bardsley@arm.com# met: redistributions of source code must retain the above copyright 1610201SAndrew.Bardsley@arm.com# notice, this list of conditions and the following disclaimer; 1710201SAndrew.Bardsley@arm.com# redistributions in binary form must reproduce the above copyright 1810201SAndrew.Bardsley@arm.com# notice, this list of conditions and the following disclaimer in the 1910201SAndrew.Bardsley@arm.com# documentation and/or other materials provided with the distribution; 2010201SAndrew.Bardsley@arm.com# neither the name of the copyright holders nor the names of its 2110201SAndrew.Bardsley@arm.com# contributors may be used to endorse or promote products derived from 2210201SAndrew.Bardsley@arm.com# this software without specific prior written permission. 2310201SAndrew.Bardsley@arm.com# 2410201SAndrew.Bardsley@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2510201SAndrew.Bardsley@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2610201SAndrew.Bardsley@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2710201SAndrew.Bardsley@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2810201SAndrew.Bardsley@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2910201SAndrew.Bardsley@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3010201SAndrew.Bardsley@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3110201SAndrew.Bardsley@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3210201SAndrew.Bardsley@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3310201SAndrew.Bardsley@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3410201SAndrew.Bardsley@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3510201SAndrew.Bardsley@arm.com# 3610201SAndrew.Bardsley@arm.com# Authors: Andreas Sandberg 3710201SAndrew.Bardsley@arm.com 3810201SAndrew.Bardsley@arm.comfrom __future__ import print_function 3910201SAndrew.Bardsley@arm.com 4010201SAndrew.Bardsley@arm.comimport m5 4110201SAndrew.Bardsley@arm.comimport _m5 4210201SAndrew.Bardsley@arm.comfrom m5.objects import * 4310201SAndrew.Bardsley@arm.comm5.util.addToPath('../configs/') 4410201SAndrew.Bardsley@arm.comfrom common.Caches import * 4510201SAndrew.Bardsley@arm.com 4610201SAndrew.Bardsley@arm.comclass Sequential: 4710201SAndrew.Bardsley@arm.com """Sequential CPU switcher. 4810201SAndrew.Bardsley@arm.com 4910201SAndrew.Bardsley@arm.com The sequential CPU switches between all CPUs in a system in 5010201SAndrew.Bardsley@arm.com order. The CPUs in the system must have been prepared for 5110201SAndrew.Bardsley@arm.com switching, which in practice means that only one CPU is switched 5210201SAndrew.Bardsley@arm.com in. base_config.BaseFSSwitcheroo can be used to create such a 5310201SAndrew.Bardsley@arm.com system. 5410201SAndrew.Bardsley@arm.com """ 5510201SAndrew.Bardsley@arm.com def __init__(self, cpus): 5610201SAndrew.Bardsley@arm.com self.first_cpu = None 5710201SAndrew.Bardsley@arm.com for (cpuno, cpu) in enumerate(cpus): 5810201SAndrew.Bardsley@arm.com if not cpu.switched_out: 5910201SAndrew.Bardsley@arm.com if self.first_cpu != None: 6010201SAndrew.Bardsley@arm.com fatal("More than one CPU is switched in"); 6110201SAndrew.Bardsley@arm.com self.first_cpu = cpuno 6210201SAndrew.Bardsley@arm.com 6310201SAndrew.Bardsley@arm.com if self.first_cpu == None: 6410201SAndrew.Bardsley@arm.com fatal("The system contains no switched in CPUs") 6510201SAndrew.Bardsley@arm.com 6610201SAndrew.Bardsley@arm.com self.cur_cpu = self.first_cpu 6710201SAndrew.Bardsley@arm.com self.cpus = cpus 6810201SAndrew.Bardsley@arm.com 6910201SAndrew.Bardsley@arm.com def next(self): 7010201SAndrew.Bardsley@arm.com self.cur_cpu = (self.cur_cpu + 1) % len(self.cpus) 7110201SAndrew.Bardsley@arm.com return self.cpus[self.cur_cpu] 7210201SAndrew.Bardsley@arm.com 7310201SAndrew.Bardsley@arm.com def first(self): 7410201SAndrew.Bardsley@arm.com return self.cpus[self.first_cpu] 7510201SAndrew.Bardsley@arm.com 7610201SAndrew.Bardsley@arm.comdef run_test(root, switcher=None, freq=1000, verbose=False): 7710201SAndrew.Bardsley@arm.com """Test runner for CPU switcheroo tests. 7810201SAndrew.Bardsley@arm.com 7910201SAndrew.Bardsley@arm.com The switcheroo test runner is used to switch CPUs in a system that 8010201SAndrew.Bardsley@arm.com has been prepared for CPU switching. Such systems should have 8110201SAndrew.Bardsley@arm.com multiple CPUs when they are instantiated, but only one should be 8210201SAndrew.Bardsley@arm.com switched in. Such configurations can be created using the 8310201SAndrew.Bardsley@arm.com base_config.BaseFSSwitcheroo class. 8410201SAndrew.Bardsley@arm.com 8510201SAndrew.Bardsley@arm.com A CPU switcher object is used to control switching. The default 8610201SAndrew.Bardsley@arm.com switcher sequentially switches between all CPUs in a system, 8710201SAndrew.Bardsley@arm.com starting with the CPU that is currently switched in. 8810201SAndrew.Bardsley@arm.com 8910201SAndrew.Bardsley@arm.com Unlike most other test runners, this one automatically configures 9010201SAndrew.Bardsley@arm.com the memory mode of the system based on the first CPU the switcher 9110201SAndrew.Bardsley@arm.com reports. 9210201SAndrew.Bardsley@arm.com 9310201SAndrew.Bardsley@arm.com Keyword Arguments: 9410201SAndrew.Bardsley@arm.com switcher -- CPU switcher implementation. See Sequential for 9510201SAndrew.Bardsley@arm.com an example implementation. 9610201SAndrew.Bardsley@arm.com period -- Switching frequency in Hz. 9710201SAndrew.Bardsley@arm.com verbose -- Enable output at each switch (suppressed by default). 9810201SAndrew.Bardsley@arm.com """ 9910201SAndrew.Bardsley@arm.com 10010201SAndrew.Bardsley@arm.com if switcher == None: 10110201SAndrew.Bardsley@arm.com switcher = Sequential(root.system.cpu) 10210201SAndrew.Bardsley@arm.com 10310201SAndrew.Bardsley@arm.com current_cpu = switcher.first() 10410201SAndrew.Bardsley@arm.com system = root.system 10510201SAndrew.Bardsley@arm.com system.mem_mode = type(current_cpu).memory_mode() 10610201SAndrew.Bardsley@arm.com 10710201SAndrew.Bardsley@arm.com # Suppress "Entering event queue" messages since we get tons of them. 10810201SAndrew.Bardsley@arm.com # Worse yet, they include the timestamp, which makes them highly 10910201SAndrew.Bardsley@arm.com # variable and unsuitable for comparing as test outputs. 11010201SAndrew.Bardsley@arm.com if not verbose: 11110201SAndrew.Bardsley@arm.com _m5.core.setLogLevel(_m5.core.LogLevel.WARN) 11210201SAndrew.Bardsley@arm.com 113 # instantiate configuration 114 m5.instantiate() 115 116 # Determine the switching period, this has to be done after 117 # instantiating the system since the time base must be fixed. 118 period = m5.ticks.fromSeconds(1.0 / freq) 119 while True: 120 exit_event = m5.simulate(period) 121 exit_cause = exit_event.getCause() 122 123 if exit_cause == "simulate() limit reached": 124 next_cpu = switcher.next() 125 126 if verbose: 127 print("Switching CPUs...") 128 print("Next CPU: %s" % type(next_cpu)) 129 m5.drain() 130 if current_cpu != next_cpu: 131 m5.switchCpus(system, [ (current_cpu, next_cpu) ], 132 verbose=verbose) 133 else: 134 print("Source CPU and destination CPU are the same," 135 " skipping...") 136 current_cpu = next_cpu 137 elif exit_cause == "target called exit()" or \ 138 exit_cause == "m5_exit instruction encountered": 139 140 sys.exit(0) 141 else: 142 print("Test failed: Unknown exit cause: %s" % exit_cause) 143 sys.exit(1) 144