cpt_upgrader.py revision 9056:0e38b529c387
1360SN/A#!/usr/bin/env python 210850SGiacomo.Gabrielli@arm.com 310796Sbrandon.potter@amd.com# Copyright (c) 2012 ARM Limited 410027SChris.Adeniyi-Jones@arm.com# All rights reserved 510027SChris.Adeniyi-Jones@arm.com# 610027SChris.Adeniyi-Jones@arm.com# The license below extends only to copyright in the software and shall 710027SChris.Adeniyi-Jones@arm.com# not be construed as granting a license to any other intellectual 810027SChris.Adeniyi-Jones@arm.com# property including but not limited to intellectual property relating 910027SChris.Adeniyi-Jones@arm.com# to a hardware implementation of the functionality of the software 1010027SChris.Adeniyi-Jones@arm.com# licensed hereunder. You may use the software subject to the license 1110027SChris.Adeniyi-Jones@arm.com# terms below provided that you ensure that this notice is replicated 1210027SChris.Adeniyi-Jones@arm.com# unmodified and in its entirety in all distributions of the software, 1310027SChris.Adeniyi-Jones@arm.com# modified or unmodified, in source code or in binary form. 1410027SChris.Adeniyi-Jones@arm.com# 151458SN/A# Redistribution and use in source and binary forms, with or without 16360SN/A# modification, are permitted provided that the following conditions are 17360SN/A# met: redistributions of source code must retain the above copyright 18360SN/A# notice, this list of conditions and the following disclaimer; 19360SN/A# redistributions in binary form must reproduce the above copyright 20360SN/A# notice, this list of conditions and the following disclaimer in the 21360SN/A# documentation and/or other materials provided with the distribution; 22360SN/A# neither the name of the copyright holders nor the names of its 23360SN/A# contributors may be used to endorse or promote products derived from 24360SN/A# this software without specific prior written permission. 25360SN/A# 26360SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27360SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28360SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29360SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30360SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31360SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32360SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33360SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34360SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35360SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36360SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37360SN/A# 38360SN/A# Authors: Ali Saidi 39360SN/A# 402665Ssaidi@eecs.umich.edu 412665Ssaidi@eecs.umich.edu# This python code is used to migrate checkpoints that were created in one 422665Ssaidi@eecs.umich.edu# version of the simulator to newer version. As features are added or bugs are 43360SN/A# fixed some of the state that needs to be checkpointed can change. If you have 44360SN/A# many historic checkpoints that you use, manually editing them to fix them is 451354SN/A# both time consuming and error-prone. 461354SN/A 47360SN/A# This script provides a way to migrate checkpoints to the newer repository in 4812018Sandreas.sandberg@arm.com# a programatic way. It can be imported into another script or used on the 4912018Sandreas.sandberg@arm.com# command line. From the command line the script will either migrate every 5012018Sandreas.sandberg@arm.com# checkpoint it finds recursively (-r option) or a single checkpoint. When a 5112018Sandreas.sandberg@arm.com# change is made to the gem5 repository that breaks previous checkpoints a 5212018Sandreas.sandberg@arm.com# from_N() method should be implemented here and the gem5CheckpointVersion 5312018Sandreas.sandberg@arm.com# variable in src/sim/serialize.hh should be incremented. For each version 5412018Sandreas.sandberg@arm.com# between the checkpoints current version and the new version the from_N() 552064SN/A# method will be run, passing in a ConfigParser object which contains the open 5612018Sandreas.sandberg@arm.com# file. As these operations can be isa specific the method can verify the isa 5712018Sandreas.sandberg@arm.com# and use regexes to find the correct sections that need to be updated. 5812018Sandreas.sandberg@arm.com 5912018Sandreas.sandberg@arm.com 6012018Sandreas.sandberg@arm.comimport ConfigParser 6112018Sandreas.sandberg@arm.comimport sys, os 6211799Sbrandon.potter@amd.comimport os.path as osp 6312018Sandreas.sandberg@arm.com 6412018Sandreas.sandberg@arm.comdef from_0(cpt): 6512018Sandreas.sandberg@arm.com pass 6612018Sandreas.sandberg@arm.com 6712018Sandreas.sandberg@arm.com# An example of a translator 6812018Sandreas.sandberg@arm.comdef from_1(cpt): 6911799Sbrandon.potter@amd.com if cpt.get('root','isa') == 'arm': 70360SN/A for sec in cpt.sections(): 71360SN/A import re 72360SN/A # Search for all the execution contexts 73360SN/A if re.search('.*sys.*\.cpu.*\.x.\..*', sec): 74360SN/A # Update each one 75360SN/A mr = cpt.get(sec, 'miscRegs').split() 761809SN/A #mr.insert(21,0) 7711800Sbrandon.potter@amd.com #mr.insert(26,0) 7811392Sbrandon.potter@amd.com cpt.set(sec, 'miscRegs', ' '.join(str(x) for x in mr)) 791809SN/A 8011392Sbrandon.potter@amd.commigrations = [] 8113902Sbrandon.potter@amd.commigrations.append(from_0) 8213570Sbrandon.potter@amd.commigrations.append(from_1) 8313902Sbrandon.potter@amd.com 8411383Sbrandon.potter@amd.comverbose_print = False 8513568Sbrandon.potter@amd.com 863113Sgblack@eecs.umich.edudef verboseprint(*args): 8713902Sbrandon.potter@amd.com if not verbose_print: 8811799Sbrandon.potter@amd.com return 8911759Sbrandon.potter@amd.com for arg in args: 9013902Sbrandon.potter@amd.com print arg, 9111812Sbaz21@cam.ac.uk print 9211812Sbaz21@cam.ac.uk 9313902Sbrandon.potter@amd.comdef process_file(path, **kwargs): 9411799Sbrandon.potter@amd.com if not osp.isfile(path): 958229Snate@binkert.org import errno 9613570Sbrandon.potter@amd.com raise IOError(ennro.ENOENT, "No such file", path) 978229Snate@binkert.org 9811594Santhony.gutierrez@amd.com verboseprint("Processing file %s...." % path) 997075Snate@binkert.org 1008229Snate@binkert.org if kwargs.get('backup', True): 10111856Sbrandon.potter@amd.com import shutil 1027075Snate@binkert.org shutil.copyfile(path, path + '.bak') 103360SN/A 10412461Sgabeblack@google.com cpt = ConfigParser.SafeConfigParser() 10511886Sbrandon.potter@amd.com 10611800Sbrandon.potter@amd.com # gem5 is case sensitive with paramaters 10711392Sbrandon.potter@amd.com cpt.optionxform = str 10812334Sgabeblack@google.com 1091354SN/A # Read the current data 1106216Snate@binkert.org cpt_file = file(path, 'r') 1116658Snate@binkert.org cpt.readfp(cpt_file) 1122474SN/A cpt_file.close() 1132680Sktlim@umich.edu 1148229Snate@binkert.org # Make sure we know what we're starting from 11511886Sbrandon.potter@amd.com if not cpt.has_option('root','cpt_ver'): 11610496Ssteve.reinhardt@amd.com raise LookupError("cannot determine version of checkpoint") 11711911SBrandon.Potter@amd.com 1188229Snate@binkert.org cpt_ver = cpt.getint('root','cpt_ver') 11911794Sbrandon.potter@amd.com 12011886Sbrandon.potter@amd.com # If the current checkpoint is longer than the migrations list, we have a problem 12110497Ssteve.reinhardt@amd.com # and someone didn't update this file 12211794Sbrandon.potter@amd.com if cpt_ver > len(migrations): 123360SN/A raise ValueError("upgrade script is too old and needs updating") 12413629SAndrea.Mondelli@ucf.edu 12513629SAndrea.Mondelli@ucf.edu verboseprint("\t...file is at version %#x" % cpt_ver) 12613629SAndrea.Mondelli@ucf.edu 12713629SAndrea.Mondelli@ucf.edu if cpt_ver == len(migrations): 128360SN/A verboseprint("\t...nothing to do") 129360SN/A return 130360SN/A 131360SN/A # Walk through every function from now until the end fixing the checkpoint 132360SN/A for v in xrange(cpt_ver,len(migrations)): 133360SN/A verboseprint("\t...migrating to version %#x" % (v + 1)) 134360SN/A migrations[v](cpt) 135360SN/A cpt.set('root','cpt_ver', str(v + 1)) 136360SN/A 137378SN/A # Write the old data back 1381706SN/A verboseprint("\t...completed") 13911851Sbrandon.potter@amd.com cpt.write(file(path, 'w')) 140378SN/A 141378SN/A 142378SN/Aif __name__ == '__main__': 143378SN/A from optparse import OptionParser 144378SN/A parser = OptionParser("usage: %prog [options] <filename or directory>") 1451706SN/A parser.add_option("-r", "--recurse", action="store_true", 14611851Sbrandon.potter@amd.com help="Recurse through all subdirectories modifying "\ 147360SN/A "each checkpoint that is found") 14811760Sbrandon.potter@amd.com parser.add_option("-N", "--no-backup", action="store_false", 14911760Sbrandon.potter@amd.com dest="backup", default=True, 15011851Sbrandon.potter@amd.com help="Do no backup each checkpoint before modifying it") 15111760Sbrandon.potter@amd.com parser.add_option("-v", "--verbose", action="store_true", 1526109Ssanchezd@stanford.edu help="Print out debugging information as") 1531706SN/A 15411851Sbrandon.potter@amd.com (options, args) = parser.parse_args() 155378SN/A if len(args) != 1: 1566109Ssanchezd@stanford.edu parser.error("You must specify a checkpoint file to modify or a "\ 1576109Ssanchezd@stanford.edu "directory of checkpoints to recursively update") 15811851Sbrandon.potter@amd.com 1596109Ssanchezd@stanford.edu verbose_print = options.verbose 16011886Sbrandon.potter@amd.com 16111886Sbrandon.potter@amd.com # Deal with shell variables and ~ 16211886Sbrandon.potter@amd.com path = osp.expandvars(osp.expanduser(args[0])) 16311886Sbrandon.potter@amd.com 164378SN/A # Process a single file if we have it 1651706SN/A if osp.isfile(path): 16611851Sbrandon.potter@amd.com process_file(path, **vars(options)) 167378SN/A # Process an entire directory 1685748SSteve.Reinhardt@amd.com elif osp.isdir(path): 1695748SSteve.Reinhardt@amd.com cpt_file = osp.join(path, 'm5.cpt') 17011851Sbrandon.potter@amd.com if options.recurse: 171378SN/A # Visit very file and see if it matches 172378SN/A for root,dirs,files in os.walk(path): 1731706SN/A for name in files: 17411851Sbrandon.potter@amd.com if name == 'm5.cpt': 175378SN/A process_file(osp.join(root,name), **vars(options)) 176378SN/A for dir in dirs: 1771706SN/A pass 17811851Sbrandon.potter@amd.com # Maybe someone passed a cpt.XXXXXXX directory and not m5.cpt 179378SN/A elif osp.isfile(cpt_file): 1804118Sgblack@eecs.umich.edu process_file(cpt_file, **vars(options)) 1814118Sgblack@eecs.umich.edu else: 18211851Sbrandon.potter@amd.com print "Error: checkpoint file not found at in %s " % path, 1834118Sgblack@eecs.umich.edu print "and recurse not specified" 184378SN/A sys.exit(1) 1851706SN/A sys.exit(0) 18611851Sbrandon.potter@amd.com 187378SN/A