switcheroo.py revision 9521
112863Sgabeblack@google.com# Copyright (c) 2012 ARM Limited 212863Sgabeblack@google.com# All rights reserved. 312863Sgabeblack@google.com# 412863Sgabeblack@google.com# The license below extends only to copyright in the software and shall 512863Sgabeblack@google.com# not be construed as granting a license to any other intellectual 612863Sgabeblack@google.com# property including but not limited to intellectual property relating 712863Sgabeblack@google.com# to a hardware implementation of the functionality of the software 812863Sgabeblack@google.com# licensed hereunder. You may use the software subject to the license 912863Sgabeblack@google.com# terms below provided that you ensure that this notice is replicated 1012863Sgabeblack@google.com# unmodified and in its entirety in all distributions of the software, 1112863Sgabeblack@google.com# modified or unmodified, in source code or in binary form. 1212863Sgabeblack@google.com# 1312863Sgabeblack@google.com# Redistribution and use in source and binary forms, with or without 1412863Sgabeblack@google.com# modification, are permitted provided that the following conditions are 1512863Sgabeblack@google.com# met: redistributions of source code must retain the above copyright 1612863Sgabeblack@google.com# notice, this list of conditions and the following disclaimer; 1712863Sgabeblack@google.com# redistributions in binary form must reproduce the above copyright 1812863Sgabeblack@google.com# notice, this list of conditions and the following disclaimer in the 1912863Sgabeblack@google.com# documentation and/or other materials provided with the distribution; 2012863Sgabeblack@google.com# neither the name of the copyright holders nor the names of its 2112863Sgabeblack@google.com# contributors may be used to endorse or promote products derived from 2212863Sgabeblack@google.com# this software without specific prior written permission. 2312863Sgabeblack@google.com# 2412863Sgabeblack@google.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2512863Sgabeblack@google.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2612863Sgabeblack@google.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2712863Sgabeblack@google.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2812863Sgabeblack@google.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2912863Sgabeblack@google.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3012863Sgabeblack@google.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3112863Sgabeblack@google.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3212863Sgabeblack@google.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3312950Sgabeblack@google.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3413046Sgabeblack@google.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3513035Sgabeblack@google.com# 3613035Sgabeblack@google.com# Authors: Andreas Sandberg 3713035Sgabeblack@google.com 3813053Sgabeblack@google.comimport m5 3912950Sgabeblack@google.comfrom m5.objects import * 4012950Sgabeblack@google.comm5.util.addToPath('../configs/common') 4112950Sgabeblack@google.comfrom Caches import * 4212950Sgabeblack@google.com 4313053Sgabeblack@google.comclass Sequential: 4413053Sgabeblack@google.com """Sequential CPU switcher. 4513053Sgabeblack@google.com 4613053Sgabeblack@google.com The sequential CPU switches between all CPUs in a system in 4713053Sgabeblack@google.com order. The CPUs in the system must have been prepared for 4813053Sgabeblack@google.com switching, which in practice means that only one CPU is switched 4913053Sgabeblack@google.com in. base_config.BaseFSSwitcheroo can be used to create such a 5012950Sgabeblack@google.com system. 5112863Sgabeblack@google.com """ 5212863Sgabeblack@google.com def __init__(self, cpus): 5313035Sgabeblack@google.com self.first_cpu = None 5413035Sgabeblack@google.com for (cpuno, cpu) in enumerate(cpus): 5513035Sgabeblack@google.com if not cpu.switched_out: 5613035Sgabeblack@google.com if self.first_cpu != None: 5713035Sgabeblack@google.com fatal("More than one CPU is switched in"); 5813035Sgabeblack@google.com self.first_cpu = cpuno 5913035Sgabeblack@google.com 6013035Sgabeblack@google.com if self.first_cpu == None: 6113035Sgabeblack@google.com fatal("The system contains no switched in CPUs") 6213035Sgabeblack@google.com 6313035Sgabeblack@google.com self.cur_cpu = self.first_cpu 6413035Sgabeblack@google.com self.cpus = cpus 6513035Sgabeblack@google.com 6613035Sgabeblack@google.com def next(self): 6713035Sgabeblack@google.com self.cur_cpu = (self.cur_cpu + 1) % len(self.cpus) 6813035Sgabeblack@google.com return self.cpus[self.cur_cpu] 6913035Sgabeblack@google.com 7012863Sgabeblack@google.com def first(self): 7112863Sgabeblack@google.com return self.cpus[self.first_cpu] 7212863Sgabeblack@google.com 7312863Sgabeblack@google.comdef run_test(root, switcher=None, freq=1000): 7412950Sgabeblack@google.com """Test runner for CPU switcheroo tests. 7512950Sgabeblack@google.com 7612863Sgabeblack@google.com The switcheroo test runner is used to switch CPUs in a system that 7713035Sgabeblack@google.com has been prepared for CPU switching. Such systems should have 7813035Sgabeblack@google.com multiple CPUs when they are instantiated, but only one should be 7912863Sgabeblack@google.com switched in. Such configurations can be created using the 8012863Sgabeblack@google.com base_config.BaseFSSwitcheroo class. 8112950Sgabeblack@google.com 8212982Sgabeblack@google.com A CPU switcher object is used to control switching. The default 8312982Sgabeblack@google.com switcher sequentially switches between all CPUs in a system, 8412950Sgabeblack@google.com starting with the CPU that is currently switched in. 8512863Sgabeblack@google.com 8612950Sgabeblack@google.com Unlike most other test runners, this one automatically configures 8712950Sgabeblack@google.com the memory mode of the system based on the first CPU the switcher 8812950Sgabeblack@google.com reports. 8912950Sgabeblack@google.com 9012950Sgabeblack@google.com Keyword Arguments: 9112950Sgabeblack@google.com switcher -- CPU switcher implementation. See Sequential for 9212950Sgabeblack@google.com an example implementation. 9312950Sgabeblack@google.com period -- Switching frequency in Hz. 9412950Sgabeblack@google.com """ 9512950Sgabeblack@google.com 9612950Sgabeblack@google.com if switcher == None: 9712950Sgabeblack@google.com switcher = Sequential(root.system.cpu) 9812950Sgabeblack@google.com 9912950Sgabeblack@google.com current_cpu = switcher.first() 10012950Sgabeblack@google.com system = root.system 10112950Sgabeblack@google.com system.mem_mode = type(current_cpu).memory_mode() 10212950Sgabeblack@google.com 10312950Sgabeblack@google.com # instantiate configuration 10412950Sgabeblack@google.com m5.instantiate() 10512950Sgabeblack@google.com 10612950Sgabeblack@google.com # Determine the switching period, this has to be done after 10712950Sgabeblack@google.com # instantiating the system since the time base must be fixed. 10812950Sgabeblack@google.com period = m5.ticks.fromSeconds(1.0 / freq) 10912863Sgabeblack@google.com while True: 11013035Sgabeblack@google.com exit_event = m5.simulate(period) 11113035Sgabeblack@google.com exit_cause = exit_event.getCause() 11213053Sgabeblack@google.com 11313053Sgabeblack@google.com if exit_cause == "simulate() limit reached": 11412863Sgabeblack@google.com next_cpu = switcher.next() 11512863Sgabeblack@google.com 11612950Sgabeblack@google.com print "Switching CPUs..." 11712950Sgabeblack@google.com print "Next CPU: %s" % type(next_cpu) 11812863Sgabeblack@google.com m5.drain(system) 11913045Sgabeblack@google.com if current_cpu != next_cpu: 12013045Sgabeblack@google.com m5.switchCpus(system, [ (current_cpu, next_cpu) ], 12113045Sgabeblack@google.com do_drain=False) 12213046Sgabeblack@google.com else: 12312982Sgabeblack@google.com print "Source CPU and destination CPU are the same, skipping..." 12412863Sgabeblack@google.com m5.resume(system) 12512863Sgabeblack@google.com current_cpu = next_cpu 12612863Sgabeblack@google.com elif exit_cause == "target called exit()" or \ 127 exit_cause == "m5_exit instruction encountered": 128 129 sys.exit(0) 130 else: 131 print "Test failed: Unknown exit cause: %s" % exit_cause 132 sys.exit(1) 133