diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2009-04-06 10:19:36 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2009-04-06 10:19:36 -0700 |
commit | d080581db1f9ee4e1e6d07d2b01c13c67908a391 (patch) | |
tree | cc484b289fa5a30c4631f9faa1d8b456bffeebfc /util | |
parent | 7a7c4c5fca83a8d47c7e71c9c080a882ebe204a9 (diff) | |
parent | 639cb0a42d953ee32bc7e96b0cdfa96cd40e9fc1 (diff) | |
download | gem5-d080581db1f9ee4e1e6d07d2b01c13c67908a391.tar.xz |
Merge ARM into the head. ARM will compile but may not actually work.
Diffstat (limited to 'util')
-rw-r--r-- | util/batch/jobfile.py | 539 | ||||
-rw-r--r-- | util/m5/Makefile.x86 (renamed from util/stats/orderdict.py) | 63 | ||||
-rw-r--r-- | util/m5/m5.c | 317 | ||||
-rw-r--r-- | util/m5/m5op.h | 26 | ||||
-rw-r--r-- | util/m5/m5op_alpha.S | 180 | ||||
-rw-r--r-- | util/m5/m5op_x86.S | 66 | ||||
-rw-r--r-- | util/m5/m5ops.h | 68 | ||||
-rw-r--r-- | util/mkblankimage.sh | 219 | ||||
-rw-r--r-- | util/pbs/jobfile.py | 539 | ||||
-rw-r--r-- | util/style.py | 79 | ||||
-rw-r--r-- | util/term/term.c | 65 | ||||
-rwxr-xr-x | util/tracediff | 71 |
12 files changed, 779 insertions, 1453 deletions
diff --git a/util/batch/jobfile.py b/util/batch/jobfile.py deleted file mode 100644 index b78d7f3e1..000000000 --- a/util/batch/jobfile.py +++ /dev/null @@ -1,539 +0,0 @@ -# Copyright (c) 2006 The Regents of The University of Michigan -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Kevin Lim - -import sys - -class ternary(object): - def __new__(cls, *args): - if len(args) > 1: - raise TypeError, \ - '%s() takes at most 1 argument (%d given)' % \ - (cls.__name__, len(args)) - - if args: - if not isinstance(args[0], (bool, ternary)): - raise TypeError, \ - '%s() argument must be True, False, or Any' % \ - cls.__name__ - return args[0] - return super(ternary, cls).__new__(cls) - - def __bool__(self): - return True - - def __neg__(self): - return self - - def __eq__(self, other): - return True - - def __ne__(self, other): - return False - - def __str__(self): - return 'Any' - - def __repr__(self): - return 'Any' - -Any = ternary() - -class Flags(dict): - def __init__(self, *args, **kwargs): - super(Flags, self).__init__() - self.update(*args, **kwargs) - - def __getattr__(self, attr): - return self[attr] - - def __setattr__(self, attr, value): - self[attr] = value - - def __setitem__(self, item, value): - return super(Flags, self).__setitem__(item, ternary(value)) - - def __getitem__(self, item): - if item not in self: - return False - return super(Flags, self).__getitem__(item) - - def update(self, *args, **kwargs): - for arg in args: - if isinstance(arg, Flags): - super(Flags, self).update(arg) - elif isinstance(arg, dict): - for key,val in kwargs.iteritems(): - self[key] = val - else: - raise AttributeError, \ - 'flags not of type %s or %s, but %s' % \ - (Flags, dict, type(arg)) - - for key,val in kwargs.iteritems(): - self[key] = val - - def match(self, *args, **kwargs): - match = Flags(*args, **kwargs) - - for key,value in match.iteritems(): - if self[key] != value: - return False - - return True - -def crossproduct(items): - if not isinstance(items, (list, tuple)): - raise AttributeError, 'crossproduct works only on sequences' - - if not items: - yield None - return - - current = items[0] - remainder = items[1:] - - if not hasattr(current, '__iter__'): - current = [ current ] - - for item in current: - for rem in crossproduct(remainder): - data = [ item ] - if rem: - data += rem - yield data - -def flatten(items): - if not isinstance(items, (list, tuple)): - yield items - return - - for item in items: - for flat in flatten(item): - yield flat - -class Data(object): - def __init__(self, name, desc, **kwargs): - self.name = name - self.desc = desc - self.system = None - self.flags = Flags() - self.env = {} - for k,v in kwargs.iteritems(): - setattr(self, k, v) - - def update(self, obj): - if not isinstance(obj, Data): - raise AttributeError, "can only update from Data object" - - self.env.update(obj.env) - self.flags.update(obj.flags) - if obj.system: - if self.system and self.system != obj.system: - raise AttributeError, \ - "conflicting values for system: '%s'/'%s'" % \ - (self.system, obj.system) - self.system = obj.system - - def printinfo(self): - if self.name: - print 'name: %s' % self.name - if self.desc: - print 'desc: %s' % self.desc - if self.system: - print 'system: %s' % self.system - - def printverbose(self): - print 'flags:' - keys = self.flags.keys() - keys.sort() - for key in keys: - print ' %s = %s' % (key, self.flags[key]) - print 'env:' - keys = self.env.keys() - keys.sort() - for key in keys: - print ' %s = %s' % (key, self.env[key]) - print - - def __str__(self): - return self.name - -class Job(Data): - def __init__(self, options): - super(Job, self).__init__('', '') - self.setoptions(options) - - self.checkpoint = False - opts = [] - for opt in options: - cpt = opt.group.checkpoint - if not cpt: - self.checkpoint = True - continue - if isinstance(cpt, Option): - opt = cpt.clone(suboptions=False) - else: - opt = opt.clone(suboptions=False) - - opts.append(opt) - - if not opts: - self.checkpoint = False - - if self.checkpoint: - self.checkpoint = Job(opts) - - def clone(self): - return Job(self.options) - - def __getattribute__(self, attr): - if attr == 'name': - names = [ ] - for opt in self.options: - if opt.name: - names.append(opt.name) - return ':'.join(names) - - if attr == 'desc': - descs = [ ] - for opt in self.options: - if opt.desc: - descs.append(opt.desc) - return ', '.join(descs) - - return super(Job, self).__getattribute__(attr) - - def setoptions(self, options): - config = options[0].config - for opt in options: - if opt.config != config: - raise AttributeError, \ - "All options are not from the same Configuration" - - self.config = config - self.groups = [ opt.group for opt in options ] - self.options = options - - self.update(self.config) - for group in self.groups: - self.update(group) - - for option in self.options: - self.update(option) - if option._suboption: - self.update(option._suboption) - - def printinfo(self): - super(Job, self).printinfo() - if self.checkpoint: - print 'checkpoint: %s' % self.checkpoint.name - print 'config: %s' % self.config.name - print 'groups: %s' % [ g.name for g in self.groups ] - print 'options: %s' % [ o.name for o in self.options ] - super(Job, self).printverbose() - -class SubOption(Data): - def __init__(self, name, desc, **kwargs): - super(SubOption, self).__init__(name, desc, **kwargs) - self.number = None - -class Option(Data): - def __init__(self, name, desc, **kwargs): - super(Option, self).__init__(name, desc, **kwargs) - self._suboptions = [] - self._suboption = None - self.number = None - - def __getattribute__(self, attr): - if attr == 'name': - name = self.__dict__[attr] - if self._suboption is not None: - name = '%s:%s' % (name, self._suboption.name) - return name - - if attr == 'desc': - desc = [ self.__dict__[attr] ] - if self._suboption is not None and self._suboption.desc: - desc.append(self._suboption.desc) - return ', '.join(desc) - - - return super(Option, self).__getattribute__(attr) - - def suboption(self, name, desc, **kwargs): - subo = SubOption(name, desc, **kwargs) - subo.config = self.config - subo.group = self.group - subo.option = self - subo.number = len(self._suboptions) - self._suboptions.append(subo) - return subo - - def clone(self, suboptions=True): - option = Option(self.__dict__['name'], self.__dict__['desc']) - option.update(self) - option.group = self.group - option.config = self.config - option.number = self.number - if suboptions: - option._suboptions.extend(self._suboptions) - option._suboption = self._suboption - return option - - def subopts(self): - if not self._suboptions: - return [ self ] - - subopts = [] - for subo in self._suboptions: - option = self.clone() - option._suboption = subo - subopts.append(option) - - return subopts - - def printinfo(self): - super(Option, self).printinfo() - print 'config: %s' % self.config.name - super(Option, self).printverbose() - -class Group(Data): - def __init__(self, name, desc, **kwargs): - super(Group, self).__init__(name, desc, **kwargs) - self._options = [] - self.checkpoint = False - self.number = None - - def option(self, name, desc, **kwargs): - opt = Option(name, desc, **kwargs) - opt.config = self.config - opt.group = self - opt.number = len(self._options) - self._options.append(opt) - return opt - - def options(self): - return self._options - - def subopts(self): - subopts = [] - for opt in self._options: - for subo in opt.subopts(): - subopts.append(subo) - return subopts - - def printinfo(self): - super(Group, self).printinfo() - print 'config: %s' % self.config.name - print 'options: %s' % [ o.name for o in self._options ] - super(Group, self).printverbose() - -class Configuration(Data): - def __init__(self, name, desc, **kwargs): - super(Configuration, self).__init__(name, desc, **kwargs) - self._groups = [] - self._posfilters = [] - self._negfilters = [] - - def group(self, name, desc, **kwargs): - grp = Group(name, desc, **kwargs) - grp.config = self - grp.number = len(self._groups) - self._groups.append(grp) - return grp - - def groups(self, flags=Flags(), sign=True): - if not flags: - return self._groups - - return [ grp for grp in self._groups if sign ^ grp.flags.match(flags) ] - - def checkchildren(self, kids): - for kid in kids: - if kid.config != self: - raise AttributeError, "child from the wrong configuration" - - def sortgroups(self, groups): - groups = [ (grp.number, grp) for grp in groups ] - groups.sort() - return [ grp[1] for grp in groups ] - - def options(self, groups = None, checkpoint = False): - if groups is None: - groups = self._groups - self.checkchildren(groups) - groups = self.sortgroups(groups) - if checkpoint: - groups = [ grp for grp in groups if grp.checkpoint ] - optgroups = [ g.options() for g in groups ] - else: - optgroups = [ g.subopts() for g in groups ] - for options in crossproduct(optgroups): - for opt in options: - cpt = opt.group.checkpoint - if not isinstance(cpt, bool) and cpt != opt: - if checkpoint: - break - else: - yield options - else: - if checkpoint: - yield options - - def addfilter(self, filt, pos=True): - import re - filt = re.compile(filt) - if pos: - self._posfilters.append(filt) - else: - self._negfilters.append(filt) - - def jobfilter(self, job): - for filt in self._negfilters: - if filt.match(job.name): - return False - - if not self._posfilters: - return True - - for filt in self._posfilters: - if filt.match(job.name): - return True - - return False - - def checkpoints(self, groups = None): - for options in self.options(groups, True): - job = Job(options) - if self.jobfilter(job): - yield job - - def jobs(self, groups = None): - for options in self.options(groups, False): - job = Job(options) - if self.jobfilter(job): - yield job - - def alljobs(self, groups = None): - for options in self.options(groups, True): - yield Job(options) - for options in self.options(groups, False): - yield Job(options) - - def find(self, jobname): - for job in self.alljobs(): - if job.name == jobname: - return job - else: - raise AttributeError, "job '%s' not found" % jobname - - def job(self, options): - self.checkchildren(options) - options = [ (opt.group.number, opt) for opt in options ] - options.sort() - options = [ opt[1] for opt in options ] - job = Job(options) - return job - - def printinfo(self): - super(Configuration, self).printinfo() - print 'groups: %s' % [ g.name for g in self._grouips ] - super(Configuration, self).printverbose() - -def JobFile(jobfile): - from os.path import expanduser, isfile, join as joinpath - filename = expanduser(jobfile) - - # Can't find filename in the current path, search sys.path - if not isfile(filename): - for path in sys.path: - testname = joinpath(path, filename) - if isfile(testname): - filename = testname - break - else: - raise AttributeError, \ - "Could not find file '%s'" % jobfile - - data = {} - execfile(filename, data) - if 'conf' not in data: - raise ImportError, 'cannot import name conf from %s' % jobfile - conf = data['conf'] - import jobfile - if not isinstance(conf, Configuration): - raise AttributeError, \ - 'conf in jobfile: %s (%s) is not type %s' % \ - (jobfile, type(conf), Configuration) - return conf - -if __name__ == '__main__': - from jobfile import * - import sys - - usage = 'Usage: %s [-b] [-c] [-v] <jobfile>' % sys.argv[0] - - try: - import getopt - opts, args = getopt.getopt(sys.argv[1:], '-bcv') - except getopt.GetoptError: - sys.exit(usage) - - if len(args) != 1: - raise AttributeError, usage - - both = False - checkpoint = False - verbose = False - for opt,arg in opts: - if opt == '-b': - both = True - checkpoint = True - if opt == '-c': - checkpoint = True - if opt == '-v': - verbose = True - - jobfile = args[0] - conf = JobFile(jobfile) - - if both: - gen = conf.alljobs() - elif checkpoint: - gen = conf.checkpoints() - else: - gen = conf.jobs() - - for job in gen: - if not verbose: - cpt = '' - if job.checkpoint: - cpt = job.checkpoint.name - print job.name, cpt - else: - job.printinfo() diff --git a/util/stats/orderdict.py b/util/m5/Makefile.x86 index 3f755d299..e2d5d3722 100644 --- a/util/stats/orderdict.py +++ b/util/m5/Makefile.x86 @@ -1,4 +1,4 @@ -# Copyright (c) 2005 The Regents of The University of Michigan +# Copyright (c) 2005-2006 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -25,56 +25,25 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Nathan Binkert +# Ali Saidi -__all__ = [ 'orderdict' ] +CC=gcc +AS=as +LD=ld -class orderdict(dict): - def __init__(self, d = {}): - self._keys = d.keys() - super(orderdict, self).__init__(d) +CFLAGS=-O2 +OBJS=m5.o m5op_x86.o - def __setitem__(self, key, item): - super(orderdict, self).__setitem__(key, item) - if not hasattr(self, '_keys'): - self._keys = [key,] - if key not in self._keys: - self._keys.append(key) +all: m5 - def __delitem__(self, key): - super(orderdict, self).__delitem__(key) - self._keys.remove(key) +%.o: %.S + $(CC) $(CFLAGS) -o $@ -c $< - def clear(self): - super(orderdict, self).clear() - self._keys = [] +%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< - def items(self): - for i in self._keys: - yield i, self[i] +m5: $(OBJS) + $(CC) -o $@ $(OBJS) - def keys(self): - return self._keys - - def popitem(self): - if len(self._keys) == 0: - raise KeyError('dictionary is empty') - else: - key = self._keys[-1] - val = self[key] - del self[key] - return key, val - - def setdefault(self, key, failobj = None): - super(orderdict, self).setdefault(key, failobj) - if key not in self._keys: - self._keys.append(key) - - def update(self, d): - for key in d.keys(): - if not self.has_key(key): - self._keys.append(key) - super(orderdict, self).update(d) - - def values(self): - for i in self._keys: - yield self[i] +clean: + rm -f *.o m5 diff --git a/util/m5/m5.c b/util/m5/m5.c index b103796a8..7747fc0bc 100644 --- a/util/m5/m5.c +++ b/util/m5/m5.c @@ -28,7 +28,14 @@ * Authors: Nathan Binkert */ +#ifdef linux +#define _GNU_SOURCE +#include <sched.h> +#endif + #include <inttypes.h> +#include <err.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -37,154 +44,220 @@ #include "m5op.h" char *progname; +char *command = "unspecified"; +void usage(); void -usage() +parse_int_args(int argc, char *argv[], uint64_t ints[], int len) { - printf("usage: m5 initparam\n" - " m5 sw99param\n" - " m5 exit [delay]\n" - " m5 resetstats [delay [period]]\n" - " m5 dumpstats [delay [period]]\n" - " m5 dumpresetstats [delay [period]]\n" - " m5 checkpoint [delay [period]]\n" - " m5 readfile\n" - "\n" - "All times in nanoseconds!\n"); - exit(1); -} + if (argc > len) + usage(); -#define COMPARE(X) (strcmp(X, command) == 0) + int i; + for (i = 0; i < len; ++i) + ints[i] = (i < argc) ? strtoul(argv[i], NULL, 0) : 0; +} int -main(int argc, char *argv[]) +read_file(int dest_fid) { - char *command; - uint64_t param; - uint64_t arg1 = 0; - uint64_t arg2 = 0; + char buf[256*1024]; + int offset = 0; + int len; - progname = argv[0]; - if (argc < 2) + while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) { + write(dest_fid, buf, len); + offset += len; + } +} + +void +do_exit(int argc, char *argv[]) +{ + if (argc > 1) usage(); - command = argv[1]; + m5_exit((argc > 0) ? strtoul(argv[0], NULL, 0) : 0); +} - if (COMPARE("initparam")) { - if (argc != 2) - usage(); +void +do_reset_stats(int argc, char *argv[]) +{ + uint64_t ints[2]; + parse_int_args(argc, argv, ints, 2); + m5_reset_stats(ints[0], ints[1]); +} - printf("%ld", m5_initparam()); - return 0; - } +void +do_dump_stats(int argc, char *argv[]) +{ + uint64_t ints[2]; + parse_int_args(argc, argv, ints, 2); + m5_dump_stats(ints[0], ints[1]); +} - if (COMPARE("sw99param")) { - if (argc != 2) - usage(); +void +do_dump_reset_stats(int argc, char *argv[]) +{ + uint64_t ints[2]; + parse_int_args(argc, argv, ints, 2); + m5_dumpreset_stats(ints[0], ints[1]); +} - param = m5_initparam(); - // run-time, rampup-time, rampdown-time, warmup-time, connections - printf("%d %d %d %d %d", (param >> 48) & 0xfff, - (param >> 36) & 0xfff, (param >> 24) & 0xfff, - (param >> 12) & 0xfff, (param >> 0) & 0xfff); +void +do_read_file(int argc, char *argv[]) +{ + if (argc > 0) + usage(); - return 0; - } + read_file(STDOUT_FILENO); +} - if (COMPARE("exit")) { - switch (argc) { - case 3: - arg1 = strtoul(argv[2], NULL, 0); - case 2: - m5_exit(arg1); - return 0; - - default: - usage(); - } - } +void +do_exec_file(int argc, char *argv[]) +{ + if (argc > 0) + usage(); - if (COMPARE("resetstats")) { - switch (argc) { - case 4: - arg2 = strtoul(argv[3], NULL, 0); - case 3: - arg1 = strtoul(argv[2], NULL, 0); - case 2: - m5_reset_stats(arg1, arg2); - return 0; - - default: - usage(); - } - } + const char *destname = "/tmp/execfile"; - if (COMPARE("dumpstats")) { - switch (argc) { - case 4: - arg2 = strtoul(argv[3], NULL, 0); - case 3: - arg1 = strtoul(argv[2], NULL, 0); - case 2: - m5_dump_stats(arg1, arg2); - return 0; - - default: - usage(); - } + int fid = open(destname, O_WRONLY, 0777); + int len = read_file(fid); + close(fid); + if (len > 0) { + execl(destname, "execfile", NULL); + err(1, "execl failed!"); } +} - if (COMPARE("dumpresetstats")) { - switch (argc) { - case 4: - arg2 = strtoul(argv[3], NULL, 0); - case 3: - arg1 = strtoul(argv[2], NULL, 0); - case 2: - m5_dumpreset_stats(arg1, arg2); - return 0; - - default: - usage(); - } - } +void +do_checkpoint(int argc, char *argv[]) +{ + uint64_t ints[2]; + parse_int_args(argc, argv, ints, 2); + m5_checkpoint(ints[0], ints[1]); +} + +void +do_load_symbol(int argc, char *argv[]) +{ + if (argc != 2) + usage(); - if (COMPARE("readfile")) { - char buf[256*1024]; - int offset = 0; - int len; + uint64_t addr = strtoul(argv[0], NULL, 0); + char *symbol = argv[1]; + m5_loadsymbol(addr, symbol); +} - if (argc != 2) - usage(); +void +do_initparam(int argc, char *argv[]) +{ + if (argc != 0) + usage(); - while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) { - write(STDOUT_FILENO, buf, len); - offset += len; - } + + printf("%ld", m5_initparam()); +} - return 0; - } +void +do_sw99param(int argc, char *argv[]) +{ + if (argc != 0) + usage(); + + uint64_t param = m5_initparam(); + + // run-time, rampup-time, rampdown-time, warmup-time, connections + printf("%d %d %d %d %d", (param >> 48) & 0xfff, + (param >> 36) & 0xfff, (param >> 24) & 0xfff, + (param >> 12) & 0xfff, (param >> 0) & 0xfff); +} + +#ifdef linux +void +do_pin(int argc, char *argv[]) +{ + if (argc < 2) + usage(); + + cpu_set_t mask; + CPU_ZERO(&mask); + + const char *sep = ","; + char *target = strtok(argv[0], sep); + while (target) { + CPU_SET(atoi(target), &mask); + target = strtok(NULL, sep); + } + + if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) < 0) + err(1, "setaffinity"); + + execvp(argv[1], &argv[1]); + err(1, "execvp failed!"); +} +#endif + +struct MainFunc +{ + char *name; + void (*func)(int argc, char *argv[]); + char *usage; +}; - if (COMPARE("checkpoint")) { - switch (argc) { - case 4: - arg2 = strtoul(argv[3], NULL, 0); - case 3: - arg1 = strtoul(argv[2], NULL, 0); - case 2: - m5_checkpoint(arg1, arg2); - return 0; - - default: - usage(); - } - - return 0; +struct MainFunc mainfuncs[] = { + { "exit", do_exit, "[delay]" }, + { "resetstats", do_reset_stats, "[delay [period]]" }, + { "dumpstats", do_dump_stats, "[delay [period]]" }, + { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" }, + { "readfile", do_read_file, "[filename]" }, + { "execfile", do_exec_file, "<filename>" }, + { "checkpoint", do_checkpoint, "[delay [period]]" }, + { "loadsymbol", do_load_symbol, "<address> <symbol>" }, + { "initparam", do_initparam, "" }, + { "sw99param", do_sw99param, "" }, +#ifdef linux + { "pin", do_pin, "<cpu> <program> [args ...]" } +#endif +}; +int numfuncs = sizeof(mainfuncs) / sizeof(mainfuncs[0]); + +void +usage() +{ + int i; + + for (i = 0; i < numfuncs; ++i) { + char *header = i ? "" : "usage:"; + fprintf(stderr, "%-6s %s %s %s\n", + header, progname, mainfuncs[i].name, mainfuncs[i].usage); } + fprintf(stderr, "\n"); + fprintf(stderr, "All times in nanoseconds!\n"); + + exit(1); +} - if (COMPARE("loadsymbol")) { - m5_loadsymbol(arg1); - return 0; +int +main(int argc, char *argv[]) +{ + progname = argv[0]; + if (argc < 2) + usage(1); + + command = argv[1]; + + argv += 2; + argc -= 2; + + int i; + for (i = 0; i < numfuncs; ++i) { + if (strcmp(command, mainfuncs[i].name) != 0) + continue; + + mainfuncs[i].func(argc, argv); + exit(0); } - usage(); + + usage(1); } diff --git a/util/m5/m5op.h b/util/m5/m5op.h index f4e6bb0f1..b8f13da35 100644 --- a/util/m5/m5op.h +++ b/util/m5/m5op.h @@ -39,6 +39,8 @@ void quiesce(void); void quiesceNs(uint64_t ns); void quiesceCycle(uint64_t cycles); uint64_t quiesceTime(void); +uint64_t rpns(); +void wakeCPU(uint64_t cpuid); void m5_exit(uint64_t ns_delay); uint64_t m5_initparam(void); @@ -51,7 +53,27 @@ void m5_debugbreak(void); void m5_switchcpu(void); void m5_addsymbol(uint64_t addr, char *symbol); void m5_panic(void); -void m5_anbegin(uint64_t s); -void m5_anwait(uint64_t s, uint64_t w); + +// These operations are for critical path annotation +void m5a_bsm(char *sm, const void *id, int flags); +void m5a_esm(char *sm); +void m5a_begin(int flags, char *st); +void m5a_end(void); +void m5a_q(const void *id, char *q, int count); +void m5a_dq(const void *id, char *q, int count); +void m5a_wf(const void *id, char *q, char *sm, int count); +void m5a_we(const void *id, char *q, char *sm, int count); +void m5a_ws(const void *id, char *q, char *sm); +void m5a_sq(const void *id, char *q, int count, int flags); +void m5a_aq(const void *id, char *q, int count); +void m5a_pq(const void *id, char *q, int count); +void m5a_l(char *lsm, const void *id, char *sm); +void m5a_identify(uint64_t id); +uint64_t m5a_getid(void); + +#define M5_AN_FL_NONE 0x0 +#define M5_AN_FL_BAD 0x2 +#define M5_AN_FL_LINK 0x10 +#define M5_AN_FL_RESET 0x20 #endif // __M5OP_H__ diff --git a/util/m5/m5op_alpha.S b/util/m5/m5op_alpha.S index c5d0e65f8..9e8c49338 100644 --- a/util/m5/m5op_alpha.S +++ b/util/m5/m5op_alpha.S @@ -48,11 +48,19 @@ func: #define END(func) \ .end func -#define ARM(reg) INST(m5_op, reg, 0, arm_func) +#define SIMPLE_OP(_f, _o) \ + LEAF(_f) \ + _o; \ + RET; \ + END(_f) + +#define ARM(reg) INST(m5_op, reg, 0, arm_func) #define QUIESCE INST(m5_op, 0, 0, quiesce_func) #define QUIESCENS(r1) INST(m5_op, r1, 0, quiescens_func) #define QUIESCECYC(r1) INST(m5_op, r1, 0, quiescecycle_func) #define QUIESCETIME INST(m5_op, 0, 0, quiescetime_func) +#define RPNS INST(m5_op, 0, 0, rpns_func) +#define WAKE_CPU(r1) INST(m5_op, r1, 0, wakecpu_func) #define M5EXIT(reg) INST(m5_op, reg, 0, exit_func) #define INITPARAM(reg) INST(m5_op, reg, 0, initparam_func) #define LOADSYMBOL(reg) INST(m5_op, reg, 0, loadsymbol_func) @@ -65,125 +73,61 @@ func: #define SWITCHCPU INST(m5_op, 0, 0, switchcpu_func) #define ADDSYMBOL(r1,r2) INST(m5_op, r1, r2, addsymbol_func) #define PANIC INST(m5_op, 0, 0, panic_func) -#define AN_BEGIN(r1) INST(m5_op, r1, 0, anbegin_func) -#define AN_WAIT(r1,r2) INST(m5_op, r1, r2, anwait_func) - - .set noreorder - - .align 4 -LEAF(arm) - ARM(16) - RET -END(arm) - - .align 4 -LEAF(quiesce) - QUIESCE - RET -END(quiesce) - - .align 4 -LEAF(quiesceNs) - QUIESCENS(16) - RET -END(quiesceNs) - - .align 4 -LEAF(quiesceCycle) - QUIESCECYC(16) - RET -END(quiesceCycle) - - .align 4 -LEAF(quiesceTime) - QUIESCETIME - RET -END(quiesceTime) - - .align 4 -LEAF(m5_exit) - M5EXIT(16) - RET -END(m5_exit) - - .align 4 -LEAF(m5_initparam) - INITPARAM(0) - RET -END(m5_initparam) - - .align 4 -LEAF(m5_loadsymbol) - LOADSYMBOL(0) - RET -END(m5_loadsymbol) - .align 4 -LEAF(m5_reset_stats) - RESET_STATS(16, 17) - RET -END(m5_reset_stats) +#define AN_BSM INST(m5_op, an_bsm, 0, annotate_func) +#define AN_ESM INST(m5_op, an_esm, 0, annotate_func) +#define AN_BEGIN INST(m5_op, an_begin, 0, annotate_func) +#define AN_END INST(m5_op, an_end, 0, annotate_func) +#define AN_Q INST(m5_op, an_q, 0, annotate_func) +#define AN_RQ INST(m5_op, an_rq, 0, annotate_func) +#define AN_DQ INST(m5_op, an_dq, 0, annotate_func) +#define AN_WF INST(m5_op, an_wf, 0, annotate_func) +#define AN_WE INST(m5_op, an_we, 0, annotate_func) +#define AN_WS INST(m5_op, an_ws, 0, annotate_func) +#define AN_SQ INST(m5_op, an_sq, 0, annotate_func) +#define AN_AQ INST(m5_op, an_aq, 0, annotate_func) +#define AN_PQ INST(m5_op, an_pq, 0, annotate_func) +#define AN_L INST(m5_op, an_l, 0, annotate_func) +#define AN_IDENTIFY INST(m5_op, an_identify, 0, annotate_func) +#define AN_GETID INST(m5_op, an_getid, 0, annotate_func) - .align 4 -LEAF(m5_dump_stats) - DUMP_STATS(16, 17) - RET -END(m5_dump_stats) - .align 4 -LEAF(m5_dumpreset_stats) - DUMPRST_STATS(16, 17) - RET -END(m5_dumpreset_stats) - - .align 4 -LEAF(m5_checkpoint) - CHECKPOINT(16, 17) - RET -END(m5_checkpoint) - - .align 4 -LEAF(m5_readfile) - READFILE - RET -END(m5_readfile) - - .align 4 -LEAF(m5_debugbreak) - DEBUGBREAK - RET -END(m5_debugbreak) - - .align 4 -LEAF(m5_switchcpu) - SWITCHCPU - RET -END(m5_switchcpu) - - .align 4 -LEAF(m5_addsymbol) - ADDSYMBOL(16, 17) - RET -END(m5_addsymbol) - - .align 4 -LEAF(m5_panic) - PANIC - RET -END(m5_panic) - - - .align 4 -LEAF(m5_anbegin) - AN_BEGIN(16) - RET -END(m5_anbegin) - - - .align 4 -LEAF(m5_anwait) - AN_WAIT(16,17) - RET -END(m5_anwait) + .set noreorder +SIMPLE_OP(arm, ARM(16)) +SIMPLE_OP(quiesce, QUIESCE) +SIMPLE_OP(quiesceNs, QUIESCENS(16)) +SIMPLE_OP(quiesceCycle, QUIESCECYC(16)) +SIMPLE_OP(quiesceTime, QUIESCETIME) +SIMPLE_OP(rpns, RPNS) +SIMPLE_OP(wakeCPU, WAKE_CPU(16)) +SIMPLE_OP(m5_exit, M5EXIT(16)) +SIMPLE_OP(m5_initparam, INITPARAM(0)) +SIMPLE_OP(m5_loadsymbol, LOADSYMBOL(0)) +SIMPLE_OP(m5_reset_stats, RESET_STATS(16, 17)) +SIMPLE_OP(m5_dump_stats, DUMP_STATS(16, 17)) +SIMPLE_OP(m5_dumpreset_stats, DUMPRST_STATS(16, 17)) +SIMPLE_OP(m5_checkpoint, CHECKPOINT(16, 17)) +SIMPLE_OP(m5_readfile, READFILE) +SIMPLE_OP(m5_debugbreak, DEBUGBREAK) +SIMPLE_OP(m5_switchcpu, SWITCHCPU) +SIMPLE_OP(m5_addsymbol, ADDSYMBOL(16, 17)) +SIMPLE_OP(m5_panic, PANIC) + +SIMPLE_OP(m5a_bsm, AN_BSM) +SIMPLE_OP(m5a_esm, AN_ESM) +SIMPLE_OP(m5a_begin, AN_BEGIN) +SIMPLE_OP(m5a_end, AN_END) +SIMPLE_OP(m5a_q, AN_Q) +SIMPLE_OP(m5a_rq, AN_RQ) +SIMPLE_OP(m5a_dq, AN_DQ) +SIMPLE_OP(m5a_wf, AN_WF) +SIMPLE_OP(m5a_we, AN_WE) +SIMPLE_OP(m5a_ws, AN_WS) +SIMPLE_OP(m5a_sq, AN_SQ) +SIMPLE_OP(m5a_aq, AN_AQ) +SIMPLE_OP(m5a_pq, AN_PQ) +SIMPLE_OP(m5a_l, AN_L) +SIMPLE_OP(m5a_identify, AN_IDENTIFY) +SIMPLE_OP(m5a_getid, AN_GETID) diff --git a/util/m5/m5op_x86.S b/util/m5/m5op_x86.S new file mode 100644 index 000000000..e85051d98 --- /dev/null +++ b/util/m5/m5op_x86.S @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2003-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Nathan Binkert + * Ali Saidi + */ + +#include "m5ops.h" + +#define TWO_BYTE_OP(name, number) \ + .globl name; \ + .func name; \ +name: \ + .byte 0x0F, 0x04; \ + .word number; \ + ret; \ + .endfunc; + +TWO_BYTE_OP(arm, arm_func) +TWO_BYTE_OP(quiesce, quiesce_func) +TWO_BYTE_OP(quiesceNs, quiescens_func) +TWO_BYTE_OP(quiesceCycle, quiescecycle_func) +TWO_BYTE_OP(quiesceTime, quiescetime_func) +TWO_BYTE_OP(rpns, rpns_func) +TWO_BYTE_OP(m5_exit, exit_func) +TWO_BYTE_OP(m5_initparam, initparam_func) +TWO_BYTE_OP(m5_loadsymbol, loadsymbol_func) +TWO_BYTE_OP(m5_reset_stats, resetstats_func) +TWO_BYTE_OP(m5_dump_stats, dumpstats_func) +TWO_BYTE_OP(m5_dumpreset_stats, dumprststats_func) +TWO_BYTE_OP(m5_checkpoint, ckpt_func) +TWO_BYTE_OP(m5_readfile, readfile_func) +TWO_BYTE_OP(m5_debugbreak, debugbreak_func) +TWO_BYTE_OP(m5_switchcpu, switchcpu_func) +TWO_BYTE_OP(m5_addsymbol, addsymbol_func) +TWO_BYTE_OP(m5_panic, panic_func) +TWO_BYTE_OP(m5_reserved1_func, reserved1_func) +TWO_BYTE_OP(m5_reserved2_func, reserved2_func) +TWO_BYTE_OP(m5_reserved3_func, reserved3_func) +TWO_BYTE_OP(m5_reserved4_func, reserved4_func) +TWO_BYTE_OP(m5_reserved5_func, reserved5_func) diff --git a/util/m5/m5ops.h b/util/m5/m5ops.h index ce0b39b29..7f26fd4d8 100644 --- a/util/m5/m5ops.h +++ b/util/m5/m5ops.h @@ -29,26 +29,50 @@ * Ali Saidi */ -#define arm_func 0x00 -#define quiesce_func 0x01 -#define quiescens_func 0x02 -#define quiescecycle_func 0x03 -#define quiescetime_func 0x04 -#define ivlb 0x10 // obsolete -#define ivle 0x11 // obsolete -#define exit_old_func 0x20 // deprecated! -#define exit_func 0x21 -#define initparam_func 0x30 -#define loadsymbol_func 0x31 -#define resetstats_func 0x40 -#define dumpstats_func 0x41 -#define dumprststats_func 0x42 -#define ckpt_func 0x43 -#define readfile_func 0x50 -#define debugbreak_func 0x51 -#define switchcpu_func 0x52 -#define addsymbol_func 0x53 -#define panic_func 0x54 -#define anbegin_func 0x55 -#define anwait_func 0x56 +#define arm_func 0x00 +#define quiesce_func 0x01 +#define quiescens_func 0x02 +#define quiescecycle_func 0x03 +#define quiescetime_func 0x04 +#define rpns_func 0x07 +#define wakecpu_func 0x09 +#define deprecated1_func 0x10 // obsolete ivlb +#define deprecated2_func 0x11 // obsolete ivle +#define deprecated3_func 0x20 // deprecated exit function +#define exit_func 0x21 +#define initparam_func 0x30 +#define loadsymbol_func 0x31 +#define resetstats_func 0x40 +#define dumpstats_func 0x41 +#define dumprststats_func 0x42 +#define ckpt_func 0x43 +#define readfile_func 0x50 +#define debugbreak_func 0x51 +#define switchcpu_func 0x52 +#define addsymbol_func 0x53 +#define panic_func 0x54 + +#define reserved2_func 0x56 // Reserved for user +#define reserved3_func 0x57 // Reserved for user +#define reserved4_func 0x58 // Reserved for user +#define reserved5_func 0x59 // Reserved for user + +// These operations are for critical path annotation +#define annotate_func 0x55 +#define an_bsm 0x1 +#define an_esm 0x2 +#define an_begin 0x3 +#define an_end 0x4 +#define an_q 0x6 +#define an_dq 0x7 +#define an_wf 0x8 +#define an_we 0x9 +#define an_rq 0xA +#define an_ws 0xB +#define an_sq 0xC +#define an_aq 0xD +#define an_pq 0xE +#define an_l 0xF +#define an_identify 0x10 +#define an_getid 0x11 diff --git a/util/mkblankimage.sh b/util/mkblankimage.sh new file mode 100644 index 000000000..43a3cca29 --- /dev/null +++ b/util/mkblankimage.sh @@ -0,0 +1,219 @@ +#!/bin/sh +# +# makeblankimage.sh +# Make a blank M5 disk image +# + +while getopts "m" OPT +do + case "$OPT" in + m) MOUNT_IT=1 + esac +done + +DEBUG=0 + +if [ $DEBUG -ne 0 ]; then + set -x -e + OUTPUT="" +else + OUTPUT="> /dev/null 2>&1" +fi + +abort() { + echo $@ + exec /bin/false +} + +find_prog() { + PROG_PATH=`which $1` + if [ $? -ne 0 ]; then + abort "Unable to find program $1, check your PATH variable" + fi + echo $PROG_PATH +} + +run_priv() { + if [ "$HAVE_SUDO" = "y" ]; then + eval $SUDO $@ $OUTPUT + else + eval $@ $OUTPUT + fi + + if [ $? -ne 0 ]; then + abort "Failed to run $@ as root" + fi +} + +usage() { + abort "Usage: $0 [root-path to copy] [extra ownership commands ...]" +} + +# Setup PATH to look in the sbins +export PATH=$PATH:/sbin:/usr/sbin + +# Get all of the programs needed, or exit +DD=`find_prog dd` +SFDISK=`find_prog sfdisk` +LOSETUP=`find_prog losetup` +SUDO=`find_prog sudo` +MKE2FS=`find_prog mke2fs` +MKDIR=`find_prog mkdir` +MOUNT=`find_prog mount` +UMOUNT=`find_prog umount` +WHOAMI=`find_prog whoami` +CP=`find_prog cp` +CHOWN=`find_prog chown` + +# Prompt for the root password, if needed +CUR_USER=`$WHOAMI` + +if [ $# -ge 1 ]; then + if [ ! $MOUNT_IT ]; then + ROOT_PATH=$1 + + if [ ! -d $ROOT_PATH ]; then + usage + fi + else + ROOT_PATH="" + fi +else + ROOT_PATH="" +fi + +if [ ! "$CUR_USER" = "root" ]; then + echo -n "Do you have sudo access? [y/n] " + read HAVE_SUDO + + if [ ! "$HAVE_SUDO" = "y" ]; then + abort "You must have sudo access or run this script as root" + fi +fi + +echo -n "How large do you want this disk image (in MB): " +read USER_SIZE_MB + +# size in bytes = SIZE_MB * 1024 * 1024 +# size in blocks = SIZE_BYTE / 512 +let BLK_SIZE=$USER_SIZE_MB*1024*2 + +let MAX_LBA=16383*16*63 + +if [ $BLK_SIZE -ge $MAX_LBA ]; then + CYLS=16383 + HEADS=16 + SECTORS=63 +else + # Set Sectors + if [ $BLK_SIZE -ge 63 ]; then + SECTORS=63 + else + SECTORS=$BLK_SIZE + fi + + # Set Heads + let HEAD_SIZE=$BLK_SIZE/$SECTORS + + if [ $HEAD_SIZE -ge 16 ]; then + HEADS=16 + else + HEADS=$BLK_SIZE + fi + + # Set Cylinders + let SEC_HEAD=$SECTORS*$HEADS + let CYLS=$BLK_SIZE/$SEC_HEAD +fi + +# Recalculate number of sectors +let BLK_SIZE=$CYLS*$HEADS*$SECTORS + +# Get the name of the file and directory to build in +echo -n "What directory would you like to build the image in? " +read IMAGE_DIR + +if [ ! -d $IMAGE_DIR ]; then + abort "The directory $IMAGE_DIR does not exist" +fi + +echo -n "What would you like to name the image? " +read IMAGE_NAME + +IMAGE_FILE=$IMAGE_DIR/$IMAGE_NAME + +# DD the blank image +echo +echo "dd'ing the blank image (this make take a while)..." +eval $DD if=/dev/zero of=$IMAGE_FILE bs=512 count=$BLK_SIZE $OUTPUT +if [ $? -ne 0 ]; then + abort "Unable to create the blank image $IMAGE_NAME in $IMAGE_DIR" +fi + +# losetup the image with no offset to do the fdisk +echo +echo "Binding the image and partitioning..." +run_priv $LOSETUP /dev/loop0 $IMAGE_FILE +if [ $? -ne 0 ]; then + abort "losetup to /dev/loop0 failed, make sure nothing is setup on loop0 (check by typing 'mount') " +fi + +# fdisk the image +run_priv $SFDISK --no-reread -D -C $CYLS -H $HEADS -S $SECTORS /dev/loop0 <<EOF +0, +; +; +; +EOF + +# Un-losetup the image +run_priv $LOSETUP -d /dev/loop0 + +# Mount the image with an offset and make the filesystem +echo +echo "Remounting image and formatting..." +let BASE_OFFSET=63*512 + +run_priv $LOSETUP -o $BASE_OFFSET /dev/loop0 $IMAGE_FILE + +run_priv $MKE2FS /dev/loop0 + +# If a root path was specified then copy the root path into the image +if [ ! -z "$ROOT_PATH" ]; then + echo "Copying root from $ROOT_PATH to image file" + + run_priv $MKDIR -p /tmp/mnt + + run_priv $MOUNT /dev/loop0 /tmp/mnt + + run_priv $CP -a $ROOT_PATH/* /tmp/mnt + + run_priv $CHOWN -R root.root /tmp/mnt + + # run extra permissions while disk is mounted + TOPDIR=`pwd` + cd /tmp/mnt + i=2 + while [ $i -le $# ]; do + run_priv ${!i} + let i=i+1 + done + cd $TOPDIR + + run_priv $UMOUNT /tmp/mnt +fi + +run_priv $LOSETUP -d /dev/loop0 + + +if [ $MOUNT_IT -eq 1 ]; then + run_priv mount -o loop,offset=$BASE_OFFSET $IMAGE_FILE /tmp/mnt +else + echo + echo "Disk image creation complete." + echo "To mount the image, run the following commands:" + echo "# $MOUNT -o loop,offset=$BASE_OFFSET $IMAGE_FILE /mount/point" + echo + echo "And to unmount the image, run:" + echo "# $UMOUNT /mount/point" +fi; diff --git a/util/pbs/jobfile.py b/util/pbs/jobfile.py deleted file mode 100644 index fd19b3bf5..000000000 --- a/util/pbs/jobfile.py +++ /dev/null @@ -1,539 +0,0 @@ -# Copyright (c) 2005-2006 The Regents of The University of Michigan -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Nathan Binkert - -import sys - -class ternary(object): - def __new__(cls, *args): - if len(args) > 1: - raise TypeError, \ - '%s() takes at most 1 argument (%d given)' % \ - (cls.__name__, len(args)) - - if args: - if not isinstance(args[0], (bool, ternary)): - raise TypeError, \ - '%s() argument must be True, False, or Any' % \ - cls.__name__ - return args[0] - return super(ternary, cls).__new__(cls) - - def __bool__(self): - return True - - def __neg__(self): - return self - - def __eq__(self, other): - return True - - def __ne__(self, other): - return False - - def __str__(self): - return 'Any' - - def __repr__(self): - return 'Any' - -Any = ternary() - -class Flags(dict): - def __init__(self, *args, **kwargs): - super(Flags, self).__init__() - self.update(*args, **kwargs) - - def __getattr__(self, attr): - return self[attr] - - def __setattr__(self, attr, value): - self[attr] = value - - def __setitem__(self, item, value): - return super(Flags, self).__setitem__(item, ternary(value)) - - def __getitem__(self, item): - if item not in self: - return False - return super(Flags, self).__getitem__(item) - - def update(self, *args, **kwargs): - for arg in args: - if isinstance(arg, Flags): - super(Flags, self).update(arg) - elif isinstance(arg, dict): - for key,val in kwargs.iteritems(): - self[key] = val - else: - raise AttributeError, \ - 'flags not of type %s or %s, but %s' % \ - (Flags, dict, type(arg)) - - for key,val in kwargs.iteritems(): - self[key] = val - - def match(self, *args, **kwargs): - match = Flags(*args, **kwargs) - - for key,value in match.iteritems(): - if self[key] != value: - return False - - return True - -def crossproduct(items): - if not isinstance(items, (list, tuple)): - raise AttributeError, 'crossproduct works only on sequences' - - if not items: - yield None - return - - current = items[0] - remainder = items[1:] - - if not hasattr(current, '__iter__'): - current = [ current ] - - for item in current: - for rem in crossproduct(remainder): - data = [ item ] - if rem: - data += rem - yield data - -def flatten(items): - if not isinstance(items, (list, tuple)): - yield items - return - - for item in items: - for flat in flatten(item): - yield flat - -class Data(object): - def __init__(self, name, desc, **kwargs): - self.name = name - self.desc = desc - self.system = None - self.flags = Flags() - self.env = {} - for k,v in kwargs.iteritems(): - setattr(self, k, v) - - def update(self, obj): - if not isinstance(obj, Data): - raise AttributeError, "can only update from Data object" - - self.env.update(obj.env) - self.flags.update(obj.flags) - if obj.system: - if self.system and self.system != obj.system: - raise AttributeError, \ - "conflicting values for system: '%s'/'%s'" % \ - (self.system, obj.system) - self.system = obj.system - - def printinfo(self): - if self.name: - print 'name: %s' % self.name - if self.desc: - print 'desc: %s' % self.desc - if self.system: - print 'system: %s' % self.system - - def printverbose(self): - print 'flags:' - keys = self.flags.keys() - keys.sort() - for key in keys: - print ' %s = %s' % (key, self.flags[key]) - print 'env:' - keys = self.env.keys() - keys.sort() - for key in keys: - print ' %s = %s' % (key, self.env[key]) - print - - def __str__(self): - return self.name - -class Job(Data): - def __init__(self, options): - super(Job, self).__init__('', '') - self.setoptions(options) - - self.checkpoint = False - opts = [] - for opt in options: - cpt = opt.group.checkpoint - if not cpt: - self.checkpoint = True - continue - if isinstance(cpt, Option): - opt = cpt.clone(suboptions=False) - else: - opt = opt.clone(suboptions=False) - - opts.append(opt) - - if not opts: - self.checkpoint = False - - if self.checkpoint: - self.checkpoint = Job(opts) - - def clone(self): - return Job(self.options) - - def __getattribute__(self, attr): - if attr == 'name': - names = [ ] - for opt in self.options: - if opt.name: - names.append(opt.name) - return ':'.join(names) - - if attr == 'desc': - descs = [ ] - for opt in self.options: - if opt.desc: - descs.append(opt.desc) - return ', '.join(descs) - - return super(Job, self).__getattribute__(attr) - - def setoptions(self, options): - config = options[0].config - for opt in options: - if opt.config != config: - raise AttributeError, \ - "All options are not from the same Configuration" - - self.config = config - self.groups = [ opt.group for opt in options ] - self.options = options - - self.update(self.config) - for group in self.groups: - self.update(group) - - for option in self.options: - self.update(option) - if option._suboption: - self.update(option._suboption) - - def printinfo(self): - super(Job, self).printinfo() - if self.checkpoint: - print 'checkpoint: %s' % self.checkpoint.name - print 'config: %s' % self.config.name - print 'groups: %s' % [ g.name for g in self.groups ] - print 'options: %s' % [ o.name for o in self.options ] - super(Job, self).printverbose() - -class SubOption(Data): - def __init__(self, name, desc, **kwargs): - super(SubOption, self).__init__(name, desc, **kwargs) - self.number = None - -class Option(Data): - def __init__(self, name, desc, **kwargs): - super(Option, self).__init__(name, desc, **kwargs) - self._suboptions = [] - self._suboption = None - self.number = None - - def __getattribute__(self, attr): - if attr == 'name': - name = self.__dict__[attr] - if self._suboption is not None: - name = '%s:%s' % (name, self._suboption.name) - return name - - if attr == 'desc': - desc = [ self.__dict__[attr] ] - if self._suboption is not None and self._suboption.desc: - desc.append(self._suboption.desc) - return ', '.join(desc) - - - return super(Option, self).__getattribute__(attr) - - def suboption(self, name, desc, **kwargs): - subo = SubOption(name, desc, **kwargs) - subo.config = self.config - subo.group = self.group - subo.option = self - subo.number = len(self._suboptions) - self._suboptions.append(subo) - return subo - - def clone(self, suboptions=True): - option = Option(self.__dict__['name'], self.__dict__['desc']) - option.update(self) - option.group = self.group - option.config = self.config - option.number = self.number - if suboptions: - option._suboptions.extend(self._suboptions) - option._suboption = self._suboption - return option - - def subopts(self): - if not self._suboptions: - return [ self ] - - subopts = [] - for subo in self._suboptions: - option = self.clone() - option._suboption = subo - subopts.append(option) - - return subopts - - def printinfo(self): - super(Option, self).printinfo() - print 'config: %s' % self.config.name - super(Option, self).printverbose() - -class Group(Data): - def __init__(self, name, desc, **kwargs): - super(Group, self).__init__(name, desc, **kwargs) - self._options = [] - self.checkpoint = False - self.number = None - - def option(self, name, desc, **kwargs): - opt = Option(name, desc, **kwargs) - opt.config = self.config - opt.group = self - opt.number = len(self._options) - self._options.append(opt) - return opt - - def options(self): - return self._options - - def subopts(self): - subopts = [] - for opt in self._options: - for subo in opt.subopts(): - subopts.append(subo) - return subopts - - def printinfo(self): - super(Group, self).printinfo() - print 'config: %s' % self.config.name - print 'options: %s' % [ o.name for o in self._options ] - super(Group, self).printverbose() - -class Configuration(Data): - def __init__(self, name, desc, **kwargs): - super(Configuration, self).__init__(name, desc, **kwargs) - self._groups = [] - self._posfilters = [] - self._negfilters = [] - - def group(self, name, desc, **kwargs): - grp = Group(name, desc, **kwargs) - grp.config = self - grp.number = len(self._groups) - self._groups.append(grp) - return grp - - def groups(self, flags=Flags(), sign=True): - if not flags: - return self._groups - - return [ grp for grp in self._groups if sign ^ grp.flags.match(flags) ] - - def checkchildren(self, kids): - for kid in kids: - if kid.config != self: - raise AttributeError, "child from the wrong configuration" - - def sortgroups(self, groups): - groups = [ (grp.number, grp) for grp in groups ] - groups.sort() - return [ grp[1] for grp in groups ] - - def options(self, groups = None, checkpoint = False): - if groups is None: - groups = self._groups - self.checkchildren(groups) - groups = self.sortgroups(groups) - if checkpoint: - groups = [ grp for grp in groups if grp.checkpoint ] - optgroups = [ g.options() for g in groups ] - else: - optgroups = [ g.subopts() for g in groups ] - for options in crossproduct(optgroups): - for opt in options: - cpt = opt.group.checkpoint - if not isinstance(cpt, bool) and cpt != opt: - if checkpoint: - break - else: - yield options - else: - if checkpoint: - yield options - - def addfilter(self, filt, pos=True): - import re - filt = re.compile(filt) - if pos: - self._posfilters.append(filt) - else: - self._negfilters.append(filt) - - def jobfilter(self, job): - for filt in self._negfilters: - if filt.match(job.name): - return False - - if not self._posfilters: - return True - - for filt in self._posfilters: - if filt.match(job.name): - return True - - return False - - def checkpoints(self, groups = None): - for options in self.options(groups, True): - job = Job(options) - if self.jobfilter(job): - yield job - - def jobs(self, groups = None): - for options in self.options(groups, False): - job = Job(options) - if self.jobfilter(job): - yield job - - def alljobs(self, groups = None): - for options in self.options(groups, True): - yield Job(options) - for options in self.options(groups, False): - yield Job(options) - - def find(self, jobname): - for job in self.alljobs(): - if job.name == jobname: - return job - else: - raise AttributeError, "job '%s' not found" % jobname - - def job(self, options): - self.checkchildren(options) - options = [ (opt.group.number, opt) for opt in options ] - options.sort() - options = [ opt[1] for opt in options ] - job = Job(options) - return job - - def printinfo(self): - super(Configuration, self).printinfo() - print 'groups: %s' % [ g.name for g in self._grouips ] - super(Configuration, self).printverbose() - -def JobFile(jobfile): - from os.path import expanduser, isfile, join as joinpath - filename = expanduser(jobfile) - - # Can't find filename in the current path, search sys.path - if not isfile(filename): - for path in sys.path: - testname = joinpath(path, filename) - if isfile(testname): - filename = testname - break - else: - raise AttributeError, \ - "Could not find file '%s'" % jobfile - - data = {} - execfile(filename, data) - if 'conf' not in data: - raise ImportError, 'cannot import name conf from %s' % jobfile - conf = data['conf'] - import jobfile - if not isinstance(conf, Configuration): - raise AttributeError, \ - 'conf in jobfile: %s (%s) is not type %s' % \ - (jobfile, type(conf), Configuration) - return conf - -if __name__ == '__main__': - from jobfile import * - import sys - - usage = 'Usage: %s [-b] [-c] [-v] <jobfile>' % sys.argv[0] - - try: - import getopt - opts, args = getopt.getopt(sys.argv[1:], '-bcv') - except getopt.GetoptError: - sys.exit(usage) - - if len(args) != 1: - raise AttributeError, usage - - both = False - checkpoint = False - verbose = False - for opt,arg in opts: - if opt == '-b': - both = True - checkpoint = True - if opt == '-c': - checkpoint = True - if opt == '-v': - verbose = True - - jobfile = args[0] - conf = JobFile(jobfile) - - if both: - gen = conf.alljobs() - elif checkpoint: - gen = conf.checkpoints() - else: - gen = conf.jobs() - - for job in gen: - if not verbose: - cpt = '' - if job.checkpoint: - cpt = job.checkpoint.name - print job.name, cpt - else: - job.printinfo() diff --git a/util/style.py b/util/style.py index a6a2377ae..fa9a30b54 100644 --- a/util/style.py +++ b/util/style.py @@ -1,5 +1,6 @@ #! /usr/bin/env python -# Copyright (c) 2007 The Regents of The University of Michigan +# Copyright (c) 2006 The Regents of The University of Michigan +# Copyright (c) 2007 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -260,35 +261,42 @@ def modified_lines(old_data, new_data, max_lines): break return modified -def check_whitespace(ui, repo, hooktype, node, parent1, parent2): - from mercurial import mdiff +def do_check_whitespace(ui, repo, *files, **args): + """check files for proper m5 style guidelines""" + from mercurial import mdiff, util - if hooktype != 'pretxncommit': - raise AttributeError, \ - "This hook is only meant for pretxncommit, not %s" % hooktype + if files: + files = frozenset(files) + + def skip(name): + return files and name in files - tabsize = 8 - verbose = ui.configbool('style', 'verbose', False) def prompt(name, fixonly=None): - result = ui.prompt("(a)bort, (i)gnore, or (f)ix?", "^[aif]$", "a") + if args.get('auto', False): + result = 'f' + else: + result = ui.prompt("(a)bort, (i)gnore, or (f)ix?", "^[aif]$", "a") if result == 'a': return True elif result == 'i': pass elif result == 'f': - fixwhite(repo.wjoin(name), tabsize, fixonly) + fixwhite(repo.wjoin(name), args['tabsize'], fixonly) else: - raise RepoError, "Invalid response: '%s'" % result + raise util.Abort(_("Invalid response: '%s'") % result) return False modified, added, removed, deleted, unknown, ignore, clean = repo.status() for fname in added: + if skip(fname): + continue + ok = True for line,num in checkwhite(repo.wjoin(fname)): ui.write("invalid whitespace in %s:%d\n" % (fname, num)) - if verbose: + if ui.verbose: ui.write(">>%s<<\n" % line[-1]) ok = False @@ -296,21 +304,31 @@ def check_whitespace(ui, repo, hooktype, node, parent1, parent2): if prompt(fname): return True - wctx = repo.workingctx() + try: + wctx = repo.workingctx() + except: + from mercurial import context + wctx = context.workingctx(repo) + for fname in modified: + if skip(fname): + continue + if not whitespace_file(fname): continue fctx = wctx.filectx(fname) pctx = fctx.parents() - assert len(pctx) in (1, 2) file_data = fctx.data() lines = mdiff.splitnewlines(file_data) - mod_lines = modified_lines(pctx[0].data(), file_data, len(lines)) - if len(pctx) == 2: - m2 = modified_lines(pctx[1].data(), file_data, len(lines)) - mod_lines = mod_lines & m2 # only the lines that are new in both + if len(pctx) in (1, 2): + mod_lines = modified_lines(pctx[0].data(), file_data, len(lines)) + if len(pctx) == 2: + m2 = modified_lines(pctx[1].data(), file_data, len(lines)) + mod_lines = mod_lines & m2 # only the lines that are new in both + else: + mod_lines = xrange(0, len(lines)) fixonly = set() for i,line in enumerate(lines): @@ -321,7 +339,7 @@ def check_whitespace(ui, repo, hooktype, node, parent1, parent2): continue ui.write("invalid whitespace: %s:%d\n" % (fname, i+1)) - if verbose: + if ui.verbose: ui.write(">>%s<<\n" % line[:-1]) fixonly.add(i) @@ -329,6 +347,14 @@ def check_whitespace(ui, repo, hooktype, node, parent1, parent2): if prompt(fname, fixonly): return True +def check_whitespace(ui, repo, hooktype, node, parent1, parent2): + if hooktype != 'pretxncommit': + raise AttributeError, \ + "This hook is only meant for pretxncommit, not %s" % hooktype + + args = { 'tabsize' : 8 } + do_check_whitespace(ui, repo, **args) + def check_format(ui, repo, hooktype, node, parent1, parent2): if hooktype != 'pretxncommit': raise AttributeError, \ @@ -350,10 +376,23 @@ def check_format(ui, repo, hooktype, node, parent1, parent2): elif result.startswith('a'): return True else: - raise RepoError, "Invalid response: '%s'" % result + raise util.Abort(_("Invalid response: '%s'") % result) return False +try: + from mercurial.i18n import _ +except ImportError: + def _(arg): + return arg + +cmdtable = { + '^m5style' : + ( do_check_whitespace, + [ ('a', 'auto', False, _("automatically fix whitespace")), + ('t', 'tabsize', 8, _("Number of spaces TAB indents")) ], + _('hg m5check [-t <tabsize>] [FILE]...')), +} if __name__ == '__main__': import getopt diff --git a/util/term/term.c b/util/term/term.c index 597966159..54924c0e1 100644 --- a/util/term/term.c +++ b/util/term/term.c @@ -46,16 +46,16 @@ #include <unistd.h> #include <fcntl.h> -ssize_t atomicio(ssize_t (*)(), int, void *, size_t); -void readwrite(int); -int remote_connect(char *, char *, struct addrinfo); +ssize_t atomicio(ssize_t (*)(), int, void *, size_t); +void readwrite(int); +int remote_connect(char *, char *, struct addrinfo); -struct termios saved_ios; -void raw_term(); -void restore_term(); +struct termios saved_ios; +void raw_term(); +void restore_term(); -char progname[256]; -void usage(int); +char progname[256]; +void usage(int); int main(int argc, char *argv[]) @@ -139,54 +139,63 @@ remote_connect(char *host, char *port, struct addrinfo hints) /* * readwrite() - * Loop that polls on the network file descriptor and stdin. + * Loop that selects on the network file descriptor and stdin. + * Changed from poll() by Ali Saidi to make work on Mac OS X >= 10.4 */ void readwrite(int nfd) { - struct pollfd pfd[2]; + fd_set read_fds; char buf[BUFSIZ]; - int wfd = fileno(stdin), n, ret; + int wfd = fileno(stdin), n, ret, max_fd; int lfd = fileno(stdout); int escape = 0; + struct timeval timeout; - /* Setup Network FD */ - pfd[0].fd = nfd; - pfd[0].events = POLLIN; + if (nfd == -1) + return; - /* Setup STDIN FD */ - pfd[1].fd = wfd; - pfd[1].events = POLLIN; + max_fd = nfd + 1; - while (pfd[0].fd != -1) { - if ((n = poll(pfd, 2, -1)) < 0) { + while (1) { + FD_ZERO(&read_fds); + FD_SET(wfd, &read_fds); + FD_SET(nfd, &read_fds); + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + n = select(max_fd, &read_fds, NULL, NULL, &timeout); + if (n < 0) { close(nfd); - err(1, "Polling Error"); + perror("Select Error:"); } - if (n == 0) + if (n == 0) { + if (read(nfd, buf, 0) < 0) + return; + continue; + } + + if (read(nfd, buf, 0) < 0) return; - if (pfd[0].revents & POLLIN) { + if (FD_ISSET(nfd, &read_fds)) { if ((n = read(nfd, buf, sizeof(buf))) < 0) return; else if (n == 0) { shutdown(nfd, SHUT_RD); - pfd[0].fd = -1; - pfd[0].events = 0; + return; } else { if ((ret = atomicio(write, lfd, buf, n)) != n) return; } } - if (pfd[1].revents & POLLIN) { + if (FD_ISSET(wfd, &read_fds)) { if ((n = read(wfd, buf, sizeof(buf))) < 0) return; else if (n == 0) { shutdown(nfd, SHUT_WR); - pfd[1].fd = -1; - pfd[1].events = 0; } else { if (escape) { char buf2[] = "~"; @@ -208,7 +217,7 @@ readwrite(int nfd) return; } } - } + } // while } void diff --git a/util/tracediff b/util/tracediff index 3633fdb48..5349c303d 100755 --- a/util/tracediff +++ b/util/tracediff @@ -28,7 +28,9 @@ # Authors: Steve Reinhardt # Script to simplify using rundiff on trace outputs from two -# invocations of m5. +# invocations of m5. Takes a common m5 command line with embedded +# alternatives and executes the two alternative commands in separate +# subdirectories with output piped to rundiff. # # ******Note that you need to enable some trace flags in the args in order # to do anything useful!****** @@ -40,6 +42,10 @@ # of the '|' is appended to the respective command lines. Note that # you'll have to quote the arg or escape the '|' with a backslash # so that the shell doesn't think you're doing a pipe. +# - Arguments with '#' characters are split at those characters, +# processed for alternatives ('|'s) as independent terms, then +# pasted back into a single argument (without the '#'s). (Sort of +# inspired by the C preprocessor '##' token pasting operator.) # # In other words, the arguments should look like the command line you # want to run, with "|" used to list the alternatives for the parts @@ -47,34 +53,67 @@ # # For example: # -# % tracediff m5.opt --opt1 "--opt2|--opt3" --opt4 +# % tracediff m5.opt --opt1 '--opt2|--opt3' --opt4 # would compare these two runs: # m5.opt --opt1 --opt2 --opt4 # m5.opt --opt1 --opt3 --opt4 # -# If you want to compare two different simulator binaries, put a '|' -# in the first script argument ("path1/m5.opt|path2/m5.opt"). If you -# want to add arguments to one run only, just put a '|' in with text -# only on one side ("--onlyOn1|"). You can do this with multiple -# arguments together too ("|-a -b -c" adds three args to the second +# % tracediff 'path1|path2#/m5.opt' --opt1 --opt2 +# would compare these two runs: +# path1/m5.opt --opt1 --opt2 +# path2/m5.opt --opt1 --opt2 +# +# If you want to add arguments to one run only, just put a '|' in with +# text only on one side ('--onlyOn1|'). You can do this with multiple +# arguments together too ('|-a -b -c' adds three args to the second # run only). # +# The '-n' argument to tracediff allows you to preview the two +# generated command lines without running them. +# use FindBin; -if (@ARGV < 2) { - die "Usage: tracediff \"sim1|sim2\" [common-arg \"arg1|arg2\" ...]\n"; +$dryrun = 0; + +if (@ARGV >= 1 && $ARGV[0] eq '-n') { + $dryrun = 1; + shift @ARGV; +} + +if (@ARGV < 1) { + die "Usage: tracediff [-n] \"sim1|sim2\" [common-arg \"arg1|arg2\" ...]\n"; } foreach $arg (@ARGV) { - @pair = split('\|', $arg, -1); # -1 enables null trailing fields - if ($#pair > 0) { - push @cmd1, $pair[0]; - push @cmd2, $pair[1]; - } else { - push @cmd1, $arg; - push @cmd2, $arg; + $a1 = $a2 = ''; + @subargs = split('#', $arg); + foreach $subarg (@subargs) { + if ($subarg eq '') { + next; + } + @pair = split('\|', $subarg, -1); # -1 enables null trailing fields + if (@pair == 1) { + $a1 .= $subarg; + $a2 .= $subarg; + } elsif (@pair == 2) { + $a1 .= $pair[0]; + $a2 .= $pair[1]; + } else { + print 'Parse error: too many |s in ', $arg, "\n"; + exit(1); + } } + + push @cmd1, $a1; + push @cmd2, $a2; +} + + +if ($dryrun) { + print "CMD1: ", join(' ', @cmd1), "\n"; + print "CMD2: ", join(' ', @cmd2), "\n"; + exit(0); } # First two args are the two simulator binaries to compare |