1278Sbinkertn@umich.edu/*
212003Sandreas.sandberg@arm.com * Copyright (c) 2011, 2017 ARM Limited
38659SAli.Saidi@ARM.com * All rights reserved
48659SAli.Saidi@ARM.com *
58659SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall
68659SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual
78659SAli.Saidi@ARM.com * property including but not limited to intellectual property relating
88659SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software
98659SAli.Saidi@ARM.com * licensed hereunder.  You may use the software subject to the license
108659SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated
118659SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software,
128659SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form.
138659SAli.Saidi@ARM.com *
141762Sstever@eecs.umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan
15278Sbinkertn@umich.edu * All rights reserved.
16278Sbinkertn@umich.edu *
17278Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without
18278Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are
19278Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright
20278Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer;
21278Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright
22278Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the
23278Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution;
24278Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its
25278Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from
26278Sbinkertn@umich.edu * this software without specific prior written permission.
27278Sbinkertn@umich.edu *
28278Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29278Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30278Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31278Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32278Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33278Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34278Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35278Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36278Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37278Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38278Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665Ssaidi@eecs.umich.edu *
402665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
41278Sbinkertn@umich.edu */
42278Sbinkertn@umich.edu
435755Snate@binkert.org#ifdef linux
445755Snate@binkert.org#define _GNU_SOURCE
455755Snate@binkert.org#include <sched.h>
4612023Sbrandon.potter@amd.com
475755Snate@binkert.org#endif
485755Snate@binkert.org
495754Snate@binkert.org#include <err.h>
505754Snate@binkert.org#include <fcntl.h>
518229Snate@binkert.org#include <inttypes.h>
52275Sbinkertn@umich.edu#include <stdio.h>
53275Sbinkertn@umich.edu#include <stdlib.h>
54275Sbinkertn@umich.edu#include <string.h>
559898Sandreas@sandberg.pp.se#include <sys/mman.h>
569898Sandreas@sandberg.pp.se#include <sys/stat.h>
579898Sandreas@sandberg.pp.se#include <sys/types.h>
582358Sktlim@umich.edu#include <unistd.h>
59275Sbinkertn@umich.edu
6012161Sandreas.sandberg@arm.com#include <gem5/m5ops.h>
6112464Sjang.hanhwi@gmail.com#include "m5_mmap.h"
629898Sandreas@sandberg.pp.se
63275Sbinkertn@umich.educhar *progname;
645754Snate@binkert.orgchar *command = "unspecified";
655754Snate@binkert.orgvoid usage();
665754Snate@binkert.org
675754Snate@binkert.orgvoid
685754Snate@binkert.orgparse_int_args(int argc, char *argv[], uint64_t ints[], int len)
695754Snate@binkert.org{
705754Snate@binkert.org    if (argc > len)
715754Snate@binkert.org        usage();
725754Snate@binkert.org
739191SAli.Saidi@ARM.com// On 32 bit platforms we need to use strtoull to do the conversion
749191SAli.Saidi@ARM.com#ifdef __LP64__
759191SAli.Saidi@ARM.com#define strto64 strtoul
769191SAli.Saidi@ARM.com#else
779191SAli.Saidi@ARM.com#define strto64 strtoull
789191SAli.Saidi@ARM.com#endif
795754Snate@binkert.org    int i;
805754Snate@binkert.org    for (i = 0; i < len; ++i)
819191SAli.Saidi@ARM.com        ints[i] = (i < argc) ? strto64(argv[i], NULL, 0) : 0;
829191SAli.Saidi@ARM.com
839191SAli.Saidi@ARM.com#undef strto64
845754Snate@binkert.org}
855754Snate@binkert.org
8611289Sgabor.dozsa@arm.comvoid
8711289Sgabor.dozsa@arm.comparse_str_args_to_regs(int argc, char *argv[], uint64_t regs[], int len)
8811289Sgabor.dozsa@arm.com{
8911372Sgabor.dozsa@arm.com    if (argc > 1 || (argc > 0 && strlen(argv[0]) > len * sizeof(uint64_t)))
9011289Sgabor.dozsa@arm.com        usage();
9111289Sgabor.dozsa@arm.com
9211289Sgabor.dozsa@arm.com    int i;
9311289Sgabor.dozsa@arm.com    for (i = 0; i < len; i++)
9411289Sgabor.dozsa@arm.com        regs[i] = 0;
9511289Sgabor.dozsa@arm.com
9611289Sgabor.dozsa@arm.com    if (argc == 0)
9711289Sgabor.dozsa@arm.com        return;
9811289Sgabor.dozsa@arm.com
9911289Sgabor.dozsa@arm.com    int n;
10011289Sgabor.dozsa@arm.com    for (n = 0, i = 0; i < len && n < strlen(argv[0]); n++) {
10111289Sgabor.dozsa@arm.com        *((char *)(&regs[i]) + (n % 8)) = argv[0][n];
10211289Sgabor.dozsa@arm.com        if ((n % 8) == 7)
10311289Sgabor.dozsa@arm.com            i++;
10411289Sgabor.dozsa@arm.com    }
10511289Sgabor.dozsa@arm.com}
10611289Sgabor.dozsa@arm.com
1075754Snate@binkert.orgint
1085754Snate@binkert.orgread_file(int dest_fid)
1095754Snate@binkert.org{
11012003Sandreas.sandberg@arm.com    uint8_t buf[256*1024];
1115754Snate@binkert.org    int offset = 0;
11212003Sandreas.sandberg@arm.com    int len, ret;
1135754Snate@binkert.org
1147517Shestness@cs.utexas.edu    // Touch all buffer pages to ensure they are mapped in the
1157517Shestness@cs.utexas.edu    // page table. This is required in the case of X86_FS, where
1167517Shestness@cs.utexas.edu    // Linux does demand paging.
1177517Shestness@cs.utexas.edu    memset(buf, 0, sizeof(buf));
1187517Shestness@cs.utexas.edu
11912160Sandreas.sandberg@arm.com    while ((len = m5_read_file(buf, sizeof(buf), offset)) > 0) {
12012003Sandreas.sandberg@arm.com        uint8_t *base = buf;
1215754Snate@binkert.org        offset += len;
12212003Sandreas.sandberg@arm.com        do {
12312003Sandreas.sandberg@arm.com            ret = write(dest_fid, base, len);
12412003Sandreas.sandberg@arm.com            if (ret < 0) {
12512003Sandreas.sandberg@arm.com                perror("Failed to write file");
12612003Sandreas.sandberg@arm.com                exit(2);
12712003Sandreas.sandberg@arm.com            } else if (ret == 0) {
12812003Sandreas.sandberg@arm.com                fprintf(stderr, "Failed to write file: "
12912003Sandreas.sandberg@arm.com                        "Unhandled short write\n");
13012003Sandreas.sandberg@arm.com                exit(2);
13112003Sandreas.sandberg@arm.com            }
13212003Sandreas.sandberg@arm.com
13312003Sandreas.sandberg@arm.com            base += ret;
13412003Sandreas.sandberg@arm.com            len -= ret;
13512003Sandreas.sandberg@arm.com        } while (len);
1365754Snate@binkert.org    }
13712003Sandreas.sandberg@arm.com
13812003Sandreas.sandberg@arm.com    return offset;
1395754Snate@binkert.org}
1405754Snate@binkert.org
14111998Sandreas.sandberg@arm.comvoid
14212198Sgabeblack@google.comwrite_file(const char *filename, const char *host_filename)
1438734Sdam.sunwoo@arm.com{
1448734Sdam.sunwoo@arm.com    fprintf(stderr, "opening %s\n", filename);
1458734Sdam.sunwoo@arm.com    int src_fid = open(filename, O_RDONLY);
1468734Sdam.sunwoo@arm.com
1478734Sdam.sunwoo@arm.com    if (src_fid < 0) {
1488734Sdam.sunwoo@arm.com        fprintf(stderr, "error opening %s\n", filename);
1498734Sdam.sunwoo@arm.com        return;
1508734Sdam.sunwoo@arm.com    }
1518734Sdam.sunwoo@arm.com
1528734Sdam.sunwoo@arm.com    char buf[256*1024];
1538734Sdam.sunwoo@arm.com    int offset = 0;
1548734Sdam.sunwoo@arm.com    int len;
1558734Sdam.sunwoo@arm.com    int bytes = 0;
1568734Sdam.sunwoo@arm.com
1578734Sdam.sunwoo@arm.com    memset(buf, 0, sizeof(buf));
1588734Sdam.sunwoo@arm.com
1598734Sdam.sunwoo@arm.com    while ((len = read(src_fid, buf, sizeof(buf))) > 0) {
16012198Sgabeblack@google.com        bytes += m5_write_file(buf, len, offset, host_filename);
1618734Sdam.sunwoo@arm.com        offset += len;
1628734Sdam.sunwoo@arm.com    }
1638734Sdam.sunwoo@arm.com    fprintf(stderr, "written %d bytes\n", bytes);
1648734Sdam.sunwoo@arm.com
1658734Sdam.sunwoo@arm.com    close(src_fid);
1668734Sdam.sunwoo@arm.com}
1678734Sdam.sunwoo@arm.com
1685754Snate@binkert.orgvoid
1695754Snate@binkert.orgdo_exit(int argc, char *argv[])
1705754Snate@binkert.org{
1715754Snate@binkert.org    if (argc > 1)
1725754Snate@binkert.org        usage();
1735754Snate@binkert.org
1749191SAli.Saidi@ARM.com    uint64_t ints[1];
1759451SAndreas.Sandberg@ARM.com    parse_int_args(argc, argv, ints, 1);
1769191SAli.Saidi@ARM.com    m5_exit(ints[0]);
1775754Snate@binkert.org}
1785754Snate@binkert.org
1795754Snate@binkert.orgvoid
1809457Svilanova@ac.upc.edudo_fail(int argc, char *argv[])
1819457Svilanova@ac.upc.edu{
1829457Svilanova@ac.upc.edu    if (argc < 1 || argc > 2)
1839457Svilanova@ac.upc.edu        usage();
1849457Svilanova@ac.upc.edu
1859949SAli.Saidi@ARM.com    uint64_t ints[2] = {0,0};
1869949SAli.Saidi@ARM.com    parse_int_args(argc, argv, ints, argc);
1879949SAli.Saidi@ARM.com    m5_fail(ints[1], ints[0]);
1889457Svilanova@ac.upc.edu}
1899457Svilanova@ac.upc.edu
1909457Svilanova@ac.upc.eduvoid
1915754Snate@binkert.orgdo_reset_stats(int argc, char *argv[])
1925754Snate@binkert.org{
1935754Snate@binkert.org    uint64_t ints[2];
1945754Snate@binkert.org    parse_int_args(argc, argv, ints, 2);
1955754Snate@binkert.org    m5_reset_stats(ints[0], ints[1]);
1965754Snate@binkert.org}
1975754Snate@binkert.org
1985754Snate@binkert.orgvoid
1995754Snate@binkert.orgdo_dump_stats(int argc, char *argv[])
2005754Snate@binkert.org{
2015754Snate@binkert.org    uint64_t ints[2];
2025754Snate@binkert.org    parse_int_args(argc, argv, ints, 2);
2035754Snate@binkert.org    m5_dump_stats(ints[0], ints[1]);
2045754Snate@binkert.org}
2055754Snate@binkert.org
2065754Snate@binkert.orgvoid
2075754Snate@binkert.orgdo_dump_reset_stats(int argc, char *argv[])
2085754Snate@binkert.org{
2095754Snate@binkert.org    uint64_t ints[2];
2105754Snate@binkert.org    parse_int_args(argc, argv, ints, 2);
21112160Sandreas.sandberg@arm.com    m5_dump_reset_stats(ints[0], ints[1]);
2125754Snate@binkert.org}
2135754Snate@binkert.org
2145754Snate@binkert.orgvoid
2155754Snate@binkert.orgdo_read_file(int argc, char *argv[])
2165754Snate@binkert.org{
2175754Snate@binkert.org    if (argc > 0)
2185754Snate@binkert.org        usage();
2195754Snate@binkert.org
2205754Snate@binkert.org    read_file(STDOUT_FILENO);
2215754Snate@binkert.org}
2225754Snate@binkert.org
2235754Snate@binkert.orgvoid
2248734Sdam.sunwoo@arm.comdo_write_file(int argc, char *argv[])
2258734Sdam.sunwoo@arm.com{
22612198Sgabeblack@google.com    if (argc != 1 && argc != 2)
2278734Sdam.sunwoo@arm.com        usage();
2288734Sdam.sunwoo@arm.com
2298734Sdam.sunwoo@arm.com    const char *filename = argv[0];
23012198Sgabeblack@google.com    const char *host_filename = (argc == 2) ? argv[1] : argv[0];
2318734Sdam.sunwoo@arm.com
23212198Sgabeblack@google.com    write_file(filename, host_filename);
2338734Sdam.sunwoo@arm.com}
2348734Sdam.sunwoo@arm.com
2358734Sdam.sunwoo@arm.comvoid
2365754Snate@binkert.orgdo_exec_file(int argc, char *argv[])
2375754Snate@binkert.org{
2385754Snate@binkert.org    if (argc > 0)
2395754Snate@binkert.org        usage();
2405754Snate@binkert.org
2415754Snate@binkert.org    const char *destname = "/tmp/execfile";
2425754Snate@binkert.org
2435754Snate@binkert.org    int fid = open(destname, O_WRONLY, 0777);
2445754Snate@binkert.org    int len = read_file(fid);
2455754Snate@binkert.org    close(fid);
2465754Snate@binkert.org    if (len > 0) {
2475754Snate@binkert.org        execl(destname, "execfile", NULL);
2485754Snate@binkert.org        err(1, "execl failed!");
2495754Snate@binkert.org    }
2505754Snate@binkert.org}
2515754Snate@binkert.org
2525754Snate@binkert.orgvoid
2535754Snate@binkert.orgdo_checkpoint(int argc, char *argv[])
2545754Snate@binkert.org{
2555754Snate@binkert.org    uint64_t ints[2];
2565754Snate@binkert.org    parse_int_args(argc, argv, ints, 2);
2575754Snate@binkert.org    m5_checkpoint(ints[0], ints[1]);
2585754Snate@binkert.org}
2595754Snate@binkert.org
2605754Snate@binkert.orgvoid
26112001Sandreas.sandberg@arm.comdo_addsymbol(int argc, char *argv[])
2625754Snate@binkert.org{
2635754Snate@binkert.org    if (argc != 2)
2645754Snate@binkert.org        usage();
2655754Snate@binkert.org
2665754Snate@binkert.org    uint64_t addr = strtoul(argv[0], NULL, 0);
2675754Snate@binkert.org    char *symbol = argv[1];
26812160Sandreas.sandberg@arm.com    m5_add_symbol(addr, symbol);
2695754Snate@binkert.org}
2705754Snate@binkert.org
27112002Sandreas.sandberg@arm.com
27212002Sandreas.sandberg@arm.comvoid
27312002Sandreas.sandberg@arm.comdo_loadsymbol(int argc, char *argv[])
27412002Sandreas.sandberg@arm.com{
27512002Sandreas.sandberg@arm.com    if (argc > 0)
27612002Sandreas.sandberg@arm.com        usage();
27712002Sandreas.sandberg@arm.com
27812160Sandreas.sandberg@arm.com    m5_load_symbol();
27912002Sandreas.sandberg@arm.com}
28012002Sandreas.sandberg@arm.com
2815754Snate@binkert.orgvoid
2825754Snate@binkert.orgdo_initparam(int argc, char *argv[])
2835754Snate@binkert.org{
28411289Sgabor.dozsa@arm.com    if (argc > 1)
2855754Snate@binkert.org        usage();
2865754Snate@binkert.org
28711289Sgabor.dozsa@arm.com    uint64_t key_str[2];
28811289Sgabor.dozsa@arm.com    parse_str_args_to_regs(argc, argv, key_str, 2);
28912160Sandreas.sandberg@arm.com    uint64_t val = m5_init_param(key_str[0], key_str[1]);
2908659SAli.Saidi@ARM.com    printf("%"PRIu64, val);
2915754Snate@binkert.org}
2925754Snate@binkert.org
2935754Snate@binkert.orgvoid
2945754Snate@binkert.orgdo_sw99param(int argc, char *argv[])
2955754Snate@binkert.org{
2965754Snate@binkert.org    if (argc != 0)
2975754Snate@binkert.org        usage();
2985754Snate@binkert.org
29912160Sandreas.sandberg@arm.com    uint64_t param = m5_init_param(0, 0);
3005754Snate@binkert.org
3015754Snate@binkert.org    // run-time, rampup-time, rampdown-time, warmup-time, connections
3029191SAli.Saidi@ARM.com    printf("%"PRId64" %"PRId64" %"PRId64" %"PRId64" %"PRId64,
3039191SAli.Saidi@ARM.com           (param >> 48) & 0xfff,
3045754Snate@binkert.org           (param >> 36) & 0xfff, (param >> 24) & 0xfff,
3055754Snate@binkert.org           (param >> 12) & 0xfff, (param >> 0) & 0xfff);
3065754Snate@binkert.org}
3075754Snate@binkert.org
3085755Snate@binkert.org#ifdef linux
3095755Snate@binkert.orgvoid
3105755Snate@binkert.orgdo_pin(int argc, char *argv[])
3115755Snate@binkert.org{
3125755Snate@binkert.org    if (argc < 2)
3135755Snate@binkert.org        usage();
3145755Snate@binkert.org
31511320Ssteve.reinhardt@amd.com    cpu_set_t mask;
3165755Snate@binkert.org    CPU_ZERO(&mask);
3175755Snate@binkert.org
3185755Snate@binkert.org    const char *sep = ",";
3195755Snate@binkert.org    char *target = strtok(argv[0], sep);
3205755Snate@binkert.org    while (target) {
3215755Snate@binkert.org        CPU_SET(atoi(target), &mask);
3225755Snate@binkert.org        target = strtok(NULL, sep);
32311320Ssteve.reinhardt@amd.com    }
3245755Snate@binkert.org
3255755Snate@binkert.org    if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) < 0)
3265755Snate@binkert.org        err(1, "setaffinity");
3275755Snate@binkert.org
3285755Snate@binkert.org    execvp(argv[1], &argv[1]);
3295755Snate@binkert.org    err(1, "execvp failed!");
3305755Snate@binkert.org}
3315755Snate@binkert.org#endif
3325755Snate@binkert.org
3335754Snate@binkert.orgstruct MainFunc
3345754Snate@binkert.org{
3355754Snate@binkert.org    char *name;
3365754Snate@binkert.org    void (*func)(int argc, char *argv[]);
3375754Snate@binkert.org    char *usage;
3385754Snate@binkert.org};
3395754Snate@binkert.org
3405754Snate@binkert.orgstruct MainFunc mainfuncs[] = {
3415754Snate@binkert.org    { "exit",           do_exit,             "[delay]" },
3429457Svilanova@ac.upc.edu    { "fail",           do_fail,             "<code> [delay]" },
3435754Snate@binkert.org    { "resetstats",     do_reset_stats,      "[delay [period]]" },
3445754Snate@binkert.org    { "dumpstats",      do_dump_stats,       "[delay [period]]" },
3455754Snate@binkert.org    { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" },
3468734Sdam.sunwoo@arm.com    { "readfile",       do_read_file,        "" },
34712198Sgabeblack@google.com    { "writefile",      do_write_file,       "<filename> [host filename]" },
3488734Sdam.sunwoo@arm.com    { "execfile",       do_exec_file,        "" },
3495754Snate@binkert.org    { "checkpoint",     do_checkpoint,       "[delay [period]]" },
35012001Sandreas.sandberg@arm.com    { "addsymbol",      do_addsymbol,        "<address> <symbol>" },
35112002Sandreas.sandberg@arm.com    { "loadsymbol",     do_loadsymbol,       "" },
35212023Sbrandon.potter@amd.com    { "initparam",      do_initparam,        "[key] // key must be shorter"
35312023Sbrandon.potter@amd.com                                             " than 16 chars" },
3545754Snate@binkert.org    { "sw99param",      do_sw99param,        "" },
3555755Snate@binkert.org#ifdef linux
3565755Snate@binkert.org    { "pin",            do_pin,              "<cpu> <program> [args ...]" }
3575755Snate@binkert.org#endif
3585754Snate@binkert.org};
3595754Snate@binkert.orgint numfuncs = sizeof(mainfuncs) / sizeof(mainfuncs[0]);
360275Sbinkertn@umich.edu
361275Sbinkertn@umich.eduvoid
362275Sbinkertn@umich.eduusage()
363275Sbinkertn@umich.edu{
3645754Snate@binkert.org    int i;
3655754Snate@binkert.org
3665754Snate@binkert.org    for (i = 0; i < numfuncs; ++i) {
3675754Snate@binkert.org        char *header = i ? "" : "usage:";
3685754Snate@binkert.org        fprintf(stderr, "%-6s %s %s %s\n",
3695754Snate@binkert.org                header, progname, mainfuncs[i].name, mainfuncs[i].usage);
3705754Snate@binkert.org    }
3715754Snate@binkert.org    fprintf(stderr, "\n");
3725754Snate@binkert.org    fprintf(stderr, "All times in nanoseconds!\n");
3735754Snate@binkert.org
374275Sbinkertn@umich.edu    exit(1);
375275Sbinkertn@umich.edu}
376275Sbinkertn@umich.edu
377275Sbinkertn@umich.eduint
378275Sbinkertn@umich.edumain(int argc, char *argv[])
379275Sbinkertn@umich.edu{
380275Sbinkertn@umich.edu    progname = argv[0];
381275Sbinkertn@umich.edu    if (argc < 2)
3825754Snate@binkert.org        usage(1);
383275Sbinkertn@umich.edu
3849898Sandreas@sandberg.pp.se    map_m5_mem();
3859898Sandreas@sandberg.pp.se
386287Sbinkertn@umich.edu    command = argv[1];
387287Sbinkertn@umich.edu
3885754Snate@binkert.org    argv += 2;
3895754Snate@binkert.org    argc -= 2;
390287Sbinkertn@umich.edu
3915754Snate@binkert.org    int i;
3925754Snate@binkert.org    for (i = 0; i < numfuncs; ++i) {
3935754Snate@binkert.org        if (strcmp(command, mainfuncs[i].name) != 0)
3945754Snate@binkert.org            continue;
3955754Snate@binkert.org
3965754Snate@binkert.org        mainfuncs[i].func(argc, argv);
3975754Snate@binkert.org        exit(0);
398287Sbinkertn@umich.edu    }
399287Sbinkertn@umich.edu
4005754Snate@binkert.org    usage(1);
401275Sbinkertn@umich.edu}
402