m5.c revision 8229
1278Sbinkertn@umich.edu/*
21762Sstever@eecs.umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan
3278Sbinkertn@umich.edu * All rights reserved.
4278Sbinkertn@umich.edu *
5278Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without
6278Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are
7278Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright
8278Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer;
9278Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright
10278Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the
11278Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution;
12278Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its
13278Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from
14278Sbinkertn@umich.edu * this software without specific prior written permission.
15278Sbinkertn@umich.edu *
16278Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17278Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18278Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19278Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20278Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21278Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22278Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23278Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24278Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25278Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26278Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
29278Sbinkertn@umich.edu */
30278Sbinkertn@umich.edu
315755Snate@binkert.org#ifdef linux
325755Snate@binkert.org#define _GNU_SOURCE
335755Snate@binkert.org#include <sched.h>
345755Snate@binkert.org#endif
355755Snate@binkert.org
365754Snate@binkert.org#include <err.h>
375754Snate@binkert.org#include <fcntl.h>
388229Snate@binkert.org#include <inttypes.h>
39275Sbinkertn@umich.edu#include <stdio.h>
40275Sbinkertn@umich.edu#include <stdlib.h>
41275Sbinkertn@umich.edu#include <string.h>
422358Sktlim@umich.edu#include <unistd.h>
43275Sbinkertn@umich.edu
44275Sbinkertn@umich.edu#include "m5op.h"
45275Sbinkertn@umich.edu
46275Sbinkertn@umich.educhar *progname;
475754Snate@binkert.orgchar *command = "unspecified";
485754Snate@binkert.orgvoid usage();
495754Snate@binkert.org
505754Snate@binkert.orgvoid
515754Snate@binkert.orgparse_int_args(int argc, char *argv[], uint64_t ints[], int len)
525754Snate@binkert.org{
535754Snate@binkert.org    if (argc > len)
545754Snate@binkert.org        usage();
555754Snate@binkert.org
565754Snate@binkert.org    int i;
575754Snate@binkert.org    for (i = 0; i < len; ++i)
585754Snate@binkert.org        ints[i] = (i < argc) ? strtoul(argv[i], NULL, 0) : 0;
595754Snate@binkert.org}
605754Snate@binkert.org
615754Snate@binkert.orgint
625754Snate@binkert.orgread_file(int dest_fid)
635754Snate@binkert.org{
645754Snate@binkert.org    char buf[256*1024];
655754Snate@binkert.org    int offset = 0;
665754Snate@binkert.org    int len;
675754Snate@binkert.org
687517Shestness@cs.utexas.edu    // Touch all buffer pages to ensure they are mapped in the
697517Shestness@cs.utexas.edu    // page table. This is required in the case of X86_FS, where
707517Shestness@cs.utexas.edu    // Linux does demand paging.
717517Shestness@cs.utexas.edu    memset(buf, 0, sizeof(buf));
727517Shestness@cs.utexas.edu
735754Snate@binkert.org    while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) {
745754Snate@binkert.org        write(dest_fid, buf, len);
755754Snate@binkert.org        offset += len;
765754Snate@binkert.org    }
775754Snate@binkert.org}
785754Snate@binkert.org
795754Snate@binkert.orgvoid
805754Snate@binkert.orgdo_exit(int argc, char *argv[])
815754Snate@binkert.org{
825754Snate@binkert.org    if (argc > 1)
835754Snate@binkert.org        usage();
845754Snate@binkert.org
855754Snate@binkert.org    m5_exit((argc > 0) ? strtoul(argv[0], NULL, 0) : 0);
865754Snate@binkert.org}
875754Snate@binkert.org
885754Snate@binkert.orgvoid
895754Snate@binkert.orgdo_reset_stats(int argc, char *argv[])
905754Snate@binkert.org{
915754Snate@binkert.org    uint64_t ints[2];
925754Snate@binkert.org    parse_int_args(argc, argv, ints, 2);
935754Snate@binkert.org    m5_reset_stats(ints[0], ints[1]);
945754Snate@binkert.org}
955754Snate@binkert.org
965754Snate@binkert.orgvoid
975754Snate@binkert.orgdo_dump_stats(int argc, char *argv[])
985754Snate@binkert.org{
995754Snate@binkert.org    uint64_t ints[2];
1005754Snate@binkert.org    parse_int_args(argc, argv, ints, 2);
1015754Snate@binkert.org    m5_dump_stats(ints[0], ints[1]);
1025754Snate@binkert.org}
1035754Snate@binkert.org
1045754Snate@binkert.orgvoid
1055754Snate@binkert.orgdo_dump_reset_stats(int argc, char *argv[])
1065754Snate@binkert.org{
1075754Snate@binkert.org    uint64_t ints[2];
1085754Snate@binkert.org    parse_int_args(argc, argv, ints, 2);
1095754Snate@binkert.org    m5_dumpreset_stats(ints[0], ints[1]);
1105754Snate@binkert.org}
1115754Snate@binkert.org
1125754Snate@binkert.orgvoid
1135754Snate@binkert.orgdo_read_file(int argc, char *argv[])
1145754Snate@binkert.org{
1155754Snate@binkert.org    if (argc > 0)
1165754Snate@binkert.org        usage();
1175754Snate@binkert.org
1185754Snate@binkert.org    read_file(STDOUT_FILENO);
1195754Snate@binkert.org}
1205754Snate@binkert.org
1215754Snate@binkert.orgvoid
1225754Snate@binkert.orgdo_exec_file(int argc, char *argv[])
1235754Snate@binkert.org{
1245754Snate@binkert.org    if (argc > 0)
1255754Snate@binkert.org        usage();
1265754Snate@binkert.org
1275754Snate@binkert.org    const char *destname = "/tmp/execfile";
1285754Snate@binkert.org
1295754Snate@binkert.org    int fid = open(destname, O_WRONLY, 0777);
1305754Snate@binkert.org    int len = read_file(fid);
1315754Snate@binkert.org    close(fid);
1325754Snate@binkert.org    if (len > 0) {
1335754Snate@binkert.org        execl(destname, "execfile", NULL);
1345754Snate@binkert.org        err(1, "execl failed!");
1355754Snate@binkert.org    }
1365754Snate@binkert.org}
1375754Snate@binkert.org
1385754Snate@binkert.orgvoid
1395754Snate@binkert.orgdo_checkpoint(int argc, char *argv[])
1405754Snate@binkert.org{
1415754Snate@binkert.org    uint64_t ints[2];
1425754Snate@binkert.org    parse_int_args(argc, argv, ints, 2);
1435754Snate@binkert.org    m5_checkpoint(ints[0], ints[1]);
1445754Snate@binkert.org}
1455754Snate@binkert.org
1465754Snate@binkert.orgvoid
1475754Snate@binkert.orgdo_load_symbol(int argc, char *argv[])
1485754Snate@binkert.org{
1495754Snate@binkert.org    if (argc != 2)
1505754Snate@binkert.org        usage();
1515754Snate@binkert.org
1525754Snate@binkert.org    uint64_t addr = strtoul(argv[0], NULL, 0);
1535754Snate@binkert.org    char *symbol = argv[1];
1545754Snate@binkert.org    m5_loadsymbol(addr, symbol);
1555754Snate@binkert.org}
1565754Snate@binkert.org
1575754Snate@binkert.orgvoid
1585754Snate@binkert.orgdo_initparam(int argc, char *argv[])
1595754Snate@binkert.org{
1605754Snate@binkert.org    if (argc != 0)
1615754Snate@binkert.org        usage();
1625754Snate@binkert.org
1635754Snate@binkert.org
1645754Snate@binkert.org    printf("%ld", m5_initparam());
1655754Snate@binkert.org}
1665754Snate@binkert.org
1675754Snate@binkert.orgvoid
1685754Snate@binkert.orgdo_sw99param(int argc, char *argv[])
1695754Snate@binkert.org{
1705754Snate@binkert.org    if (argc != 0)
1715754Snate@binkert.org        usage();
1725754Snate@binkert.org
1735754Snate@binkert.org    uint64_t param = m5_initparam();
1745754Snate@binkert.org
1755754Snate@binkert.org    // run-time, rampup-time, rampdown-time, warmup-time, connections
1765754Snate@binkert.org    printf("%d %d %d %d %d", (param >> 48) & 0xfff,
1775754Snate@binkert.org           (param >> 36) & 0xfff, (param >> 24) & 0xfff,
1785754Snate@binkert.org           (param >> 12) & 0xfff, (param >> 0) & 0xfff);
1795754Snate@binkert.org}
1805754Snate@binkert.org
1815755Snate@binkert.org#ifdef linux
1825755Snate@binkert.orgvoid
1835755Snate@binkert.orgdo_pin(int argc, char *argv[])
1845755Snate@binkert.org{
1855755Snate@binkert.org    if (argc < 2)
1865755Snate@binkert.org        usage();
1875755Snate@binkert.org
1885755Snate@binkert.org    cpu_set_t mask;
1895755Snate@binkert.org    CPU_ZERO(&mask);
1905755Snate@binkert.org
1915755Snate@binkert.org    const char *sep = ",";
1925755Snate@binkert.org    char *target = strtok(argv[0], sep);
1935755Snate@binkert.org    while (target) {
1945755Snate@binkert.org        CPU_SET(atoi(target), &mask);
1955755Snate@binkert.org        target = strtok(NULL, sep);
1965755Snate@binkert.org    }
1975755Snate@binkert.org
1985755Snate@binkert.org    if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) < 0)
1995755Snate@binkert.org        err(1, "setaffinity");
2005755Snate@binkert.org
2015755Snate@binkert.org    execvp(argv[1], &argv[1]);
2025755Snate@binkert.org    err(1, "execvp failed!");
2035755Snate@binkert.org}
2045755Snate@binkert.org#endif
2055755Snate@binkert.org
2065754Snate@binkert.orgstruct MainFunc
2075754Snate@binkert.org{
2085754Snate@binkert.org    char *name;
2095754Snate@binkert.org    void (*func)(int argc, char *argv[]);
2105754Snate@binkert.org    char *usage;
2115754Snate@binkert.org};
2125754Snate@binkert.org
2135754Snate@binkert.orgstruct MainFunc mainfuncs[] = {
2145754Snate@binkert.org    { "exit",           do_exit,             "[delay]" },
2155754Snate@binkert.org    { "resetstats",     do_reset_stats,      "[delay [period]]" },
2165754Snate@binkert.org    { "dumpstats",      do_dump_stats,       "[delay [period]]" },
2175754Snate@binkert.org    { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" },
2185754Snate@binkert.org    { "readfile",       do_read_file,        "[filename]" },
2195754Snate@binkert.org    { "execfile",       do_exec_file,        "<filename>" },
2205754Snate@binkert.org    { "checkpoint",     do_checkpoint,       "[delay [period]]" },
2215754Snate@binkert.org    { "loadsymbol",     do_load_symbol,      "<address> <symbol>" },
2225754Snate@binkert.org    { "initparam",      do_initparam,        "" },
2235754Snate@binkert.org    { "sw99param",      do_sw99param,        "" },
2245755Snate@binkert.org#ifdef linux
2255755Snate@binkert.org    { "pin",            do_pin,              "<cpu> <program> [args ...]" }
2265755Snate@binkert.org#endif
2275754Snate@binkert.org};
2285754Snate@binkert.orgint numfuncs = sizeof(mainfuncs) / sizeof(mainfuncs[0]);
229275Sbinkertn@umich.edu
230275Sbinkertn@umich.eduvoid
231275Sbinkertn@umich.eduusage()
232275Sbinkertn@umich.edu{
2335754Snate@binkert.org    int i;
2345754Snate@binkert.org
2355754Snate@binkert.org    for (i = 0; i < numfuncs; ++i) {
2365754Snate@binkert.org        char *header = i ? "" : "usage:";
2375754Snate@binkert.org        fprintf(stderr, "%-6s %s %s %s\n",
2385754Snate@binkert.org                header, progname, mainfuncs[i].name, mainfuncs[i].usage);
2395754Snate@binkert.org    }
2405754Snate@binkert.org    fprintf(stderr, "\n");
2415754Snate@binkert.org    fprintf(stderr, "All times in nanoseconds!\n");
2425754Snate@binkert.org
243275Sbinkertn@umich.edu    exit(1);
244275Sbinkertn@umich.edu}
245275Sbinkertn@umich.edu
246275Sbinkertn@umich.eduint
247275Sbinkertn@umich.edumain(int argc, char *argv[])
248275Sbinkertn@umich.edu{
249275Sbinkertn@umich.edu    progname = argv[0];
250275Sbinkertn@umich.edu    if (argc < 2)
2515754Snate@binkert.org        usage(1);
252275Sbinkertn@umich.edu
253287Sbinkertn@umich.edu    command = argv[1];
254287Sbinkertn@umich.edu
2555754Snate@binkert.org    argv += 2;
2565754Snate@binkert.org    argc -= 2;
257287Sbinkertn@umich.edu
2585754Snate@binkert.org    int i;
2595754Snate@binkert.org    for (i = 0; i < numfuncs; ++i) {
2605754Snate@binkert.org        if (strcmp(command, mainfuncs[i].name) != 0)
2615754Snate@binkert.org            continue;
2625754Snate@binkert.org
2635754Snate@binkert.org        mainfuncs[i].func(argc, argv);
2645754Snate@binkert.org        exit(0);
265287Sbinkertn@umich.edu    }
266287Sbinkertn@umich.edu
2675754Snate@binkert.org    usage(1);
268275Sbinkertn@umich.edu}
269