m5.c revision 9451:f56816facd25
17202Sgblack@eecs.umich.edu/*
212504Snikos.nikoleris@arm.com * Copyright (c) 2011 ARM Limited
39913Ssteve.reinhardt@amd.com * All rights reserved
47202Sgblack@eecs.umich.edu *
57202Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
67202Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
77202Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
87202Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
97202Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
107202Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
117202Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
127202Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
137202Sgblack@eecs.umich.edu *
147202Sgblack@eecs.umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan
157202Sgblack@eecs.umich.edu * All rights reserved.
167202Sgblack@eecs.umich.edu *
177202Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
187202Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
197202Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
207202Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
217202Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
227202Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
237202Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
247202Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
257202Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
267202Sgblack@eecs.umich.edu * this software without specific prior written permission.
277202Sgblack@eecs.umich.edu *
287202Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
297202Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
307202Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
317202Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
327202Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
337202Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
347202Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
357202Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
367202Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
377202Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
387202Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
397202Sgblack@eecs.umich.edu *
407202Sgblack@eecs.umich.edu * Authors: Nathan Binkert
417202Sgblack@eecs.umich.edu */
4211793Sbrandon.potter@amd.com
439913Ssteve.reinhardt@amd.com#ifdef linux
447202Sgblack@eecs.umich.edu#define _GNU_SOURCE
457202Sgblack@eecs.umich.edu#include <sched.h>
467202Sgblack@eecs.umich.edu#endif
477202Sgblack@eecs.umich.edu
487202Sgblack@eecs.umich.edu#include <err.h>
497202Sgblack@eecs.umich.edu#include <fcntl.h>
5012104Snathanael.premillieu@arm.com#include <inttypes.h>
517202Sgblack@eecs.umich.edu#include <stdio.h>
527202Sgblack@eecs.umich.edu#include <stdlib.h>
537202Sgblack@eecs.umich.edu#include <string.h>
5412106SRekai.GonzalezAlberquilla@arm.com#include <unistd.h>
5512106SRekai.GonzalezAlberquilla@arm.com
567202Sgblack@eecs.umich.edu#include "m5op.h"
577202Sgblack@eecs.umich.edu
5812106SRekai.GonzalezAlberquilla@arm.comchar *progname;
597202Sgblack@eecs.umich.educhar *command = "unspecified";
607202Sgblack@eecs.umich.eduvoid usage();
617202Sgblack@eecs.umich.edu
627202Sgblack@eecs.umich.eduvoid
6312106SRekai.GonzalezAlberquilla@arm.comparse_int_args(int argc, char *argv[], uint64_t ints[], int len)
647202Sgblack@eecs.umich.edu{
657202Sgblack@eecs.umich.edu    if (argc > len)
667202Sgblack@eecs.umich.edu        usage();
677202Sgblack@eecs.umich.edu
687202Sgblack@eecs.umich.edu// On 32 bit platforms we need to use strtoull to do the conversion
697202Sgblack@eecs.umich.edu#ifdef __LP64__
707202Sgblack@eecs.umich.edu#define strto64 strtoul
717202Sgblack@eecs.umich.edu#else
727202Sgblack@eecs.umich.edu#define strto64 strtoull
737202Sgblack@eecs.umich.edu#endif
747202Sgblack@eecs.umich.edu    int i;
757202Sgblack@eecs.umich.edu    for (i = 0; i < len; ++i)
767202Sgblack@eecs.umich.edu        ints[i] = (i < argc) ? strto64(argv[i], NULL, 0) : 0;
777202Sgblack@eecs.umich.edu
787202Sgblack@eecs.umich.edu#undef strto64
797202Sgblack@eecs.umich.edu}
807202Sgblack@eecs.umich.edu
817202Sgblack@eecs.umich.eduint
8212106SRekai.GonzalezAlberquilla@arm.comread_file(int dest_fid)
8312106SRekai.GonzalezAlberquilla@arm.com{
847202Sgblack@eecs.umich.edu    char buf[256*1024];
857202Sgblack@eecs.umich.edu    int offset = 0;
8612106SRekai.GonzalezAlberquilla@arm.com    int len;
877202Sgblack@eecs.umich.edu
887202Sgblack@eecs.umich.edu    // Touch all buffer pages to ensure they are mapped in the
897202Sgblack@eecs.umich.edu    // page table. This is required in the case of X86_FS, where
907202Sgblack@eecs.umich.edu    // Linux does demand paging.
9112106SRekai.GonzalezAlberquilla@arm.com    memset(buf, 0, sizeof(buf));
927202Sgblack@eecs.umich.edu
937202Sgblack@eecs.umich.edu    while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) {
947202Sgblack@eecs.umich.edu        write(dest_fid, buf, len);
957202Sgblack@eecs.umich.edu        offset += len;
967202Sgblack@eecs.umich.edu    }
977202Sgblack@eecs.umich.edu}
987202Sgblack@eecs.umich.edu
997202Sgblack@eecs.umich.eduint
1007202Sgblack@eecs.umich.eduwrite_file(const char *filename)
1017202Sgblack@eecs.umich.edu{
1027202Sgblack@eecs.umich.edu    fprintf(stderr, "opening %s\n", filename);
1037202Sgblack@eecs.umich.edu    int src_fid = open(filename, O_RDONLY);
1047202Sgblack@eecs.umich.edu
1057202Sgblack@eecs.umich.edu    if (src_fid < 0) {
1067202Sgblack@eecs.umich.edu        fprintf(stderr, "error opening %s\n", filename);
1077202Sgblack@eecs.umich.edu        return;
1087202Sgblack@eecs.umich.edu    }
1097202Sgblack@eecs.umich.edu
1107202Sgblack@eecs.umich.edu    char buf[256*1024];
1117202Sgblack@eecs.umich.edu    int offset = 0;
1127202Sgblack@eecs.umich.edu    int len;
1137202Sgblack@eecs.umich.edu    int bytes = 0;
1147202Sgblack@eecs.umich.edu
1157202Sgblack@eecs.umich.edu    memset(buf, 0, sizeof(buf));
1167202Sgblack@eecs.umich.edu
1177202Sgblack@eecs.umich.edu    while ((len = read(src_fid, buf, sizeof(buf))) > 0) {
1187202Sgblack@eecs.umich.edu        bytes += m5_writefile(buf, len, offset, filename);
1197202Sgblack@eecs.umich.edu        offset += len;
1207202Sgblack@eecs.umich.edu    }
1217202Sgblack@eecs.umich.edu    fprintf(stderr, "written %d bytes\n", bytes);
1227202Sgblack@eecs.umich.edu
1237202Sgblack@eecs.umich.edu    close(src_fid);
1247202Sgblack@eecs.umich.edu}
1257202Sgblack@eecs.umich.edu
1267202Sgblack@eecs.umich.eduvoid
1277202Sgblack@eecs.umich.edudo_exit(int argc, char *argv[])
1287202Sgblack@eecs.umich.edu{
1297202Sgblack@eecs.umich.edu    if (argc > 1)
1307202Sgblack@eecs.umich.edu        usage();
1317202Sgblack@eecs.umich.edu
1327202Sgblack@eecs.umich.edu    uint64_t ints[1];
1337202Sgblack@eecs.umich.edu    parse_int_args(argc, argv, ints, 1);
1347202Sgblack@eecs.umich.edu    m5_exit(ints[0]);
1357202Sgblack@eecs.umich.edu}
1367202Sgblack@eecs.umich.edu
1377202Sgblack@eecs.umich.eduvoid
1387202Sgblack@eecs.umich.edudo_reset_stats(int argc, char *argv[])
1397202Sgblack@eecs.umich.edu{
1407202Sgblack@eecs.umich.edu    uint64_t ints[2];
1417202Sgblack@eecs.umich.edu    parse_int_args(argc, argv, ints, 2);
1427202Sgblack@eecs.umich.edu    m5_reset_stats(ints[0], ints[1]);
14312104Snathanael.premillieu@arm.com}
1447202Sgblack@eecs.umich.edu
1457202Sgblack@eecs.umich.eduvoid
1467208Sgblack@eecs.umich.edudo_dump_stats(int argc, char *argv[])
1477208Sgblack@eecs.umich.edu{
14810037SARM gem5 Developers    uint64_t ints[2];
14910037SARM gem5 Developers    parse_int_args(argc, argv, ints, 2);
15010037SARM gem5 Developers    m5_dump_stats(ints[0], ints[1]);
15110037SARM gem5 Developers}
15212104Snathanael.premillieu@arm.com
15310037SARM gem5 Developersvoid
15412104Snathanael.premillieu@arm.comdo_dump_reset_stats(int argc, char *argv[])
15510037SARM gem5 Developers{
15612104Snathanael.premillieu@arm.com    uint64_t ints[2];
15710037SARM gem5 Developers    parse_int_args(argc, argv, ints, 2);
15810037SARM gem5 Developers    m5_dumpreset_stats(ints[0], ints[1]);
15910037SARM gem5 Developers}
16010037SARM gem5 Developers
16110037SARM gem5 Developersvoid
16210037SARM gem5 Developersdo_read_file(int argc, char *argv[])
16310037SARM gem5 Developers{
16410037SARM gem5 Developers    if (argc > 0)
16512104Snathanael.premillieu@arm.com        usage();
16610037SARM gem5 Developers
16712104Snathanael.premillieu@arm.com    read_file(STDOUT_FILENO);
16810037SARM gem5 Developers}
16912104Snathanael.premillieu@arm.com
17010037SARM gem5 Developersvoid
17110037SARM gem5 Developersdo_write_file(int argc, char *argv[])
17210037SARM gem5 Developers{
17310037SARM gem5 Developers    if (argc != 1)
1747306Sgblack@eecs.umich.edu        usage();
1757306Sgblack@eecs.umich.edu
1767306Sgblack@eecs.umich.edu    const char *filename = argv[0];
1777306Sgblack@eecs.umich.edu
1787306Sgblack@eecs.umich.edu    write_file(filename);
1797306Sgblack@eecs.umich.edu}
1807306Sgblack@eecs.umich.edu
1817306Sgblack@eecs.umich.eduvoid
1827306Sgblack@eecs.umich.edudo_exec_file(int argc, char *argv[])
1837332Sgblack@eecs.umich.edu{
1847332Sgblack@eecs.umich.edu    if (argc > 0)
1857332Sgblack@eecs.umich.edu        usage();
1867332Sgblack@eecs.umich.edu
18712104Snathanael.premillieu@arm.com    const char *destname = "/tmp/execfile";
1887332Sgblack@eecs.umich.edu
1897332Sgblack@eecs.umich.edu    int fid = open(destname, O_WRONLY, 0777);
1907332Sgblack@eecs.umich.edu    int len = read_file(fid);
1917332Sgblack@eecs.umich.edu    close(fid);
1927332Sgblack@eecs.umich.edu    if (len > 0) {
1937261Sgblack@eecs.umich.edu        execl(destname, "execfile", NULL);
1947208Sgblack@eecs.umich.edu        err(1, "execl failed!");
1957208Sgblack@eecs.umich.edu    }
1967208Sgblack@eecs.umich.edu}
19712104Snathanael.premillieu@arm.com
1987208Sgblack@eecs.umich.eduvoid
19912104Snathanael.premillieu@arm.comdo_checkpoint(int argc, char *argv[])
2007208Sgblack@eecs.umich.edu{
2017208Sgblack@eecs.umich.edu    uint64_t ints[2];
2027225Sgblack@eecs.umich.edu    parse_int_args(argc, argv, ints, 2);
2037225Sgblack@eecs.umich.edu    m5_checkpoint(ints[0], ints[1]);
2047233Sgblack@eecs.umich.edu}
2057233Sgblack@eecs.umich.edu
2067233Sgblack@eecs.umich.eduvoid
2077233Sgblack@eecs.umich.edudo_load_symbol(int argc, char *argv[])
20812104Snathanael.premillieu@arm.com{
2097233Sgblack@eecs.umich.edu    if (argc != 2)
21012104Snathanael.premillieu@arm.com        usage();
2117233Sgblack@eecs.umich.edu
21212104Snathanael.premillieu@arm.com    uint64_t addr = strtoul(argv[0], NULL, 0);
2137233Sgblack@eecs.umich.edu    char *symbol = argv[1];
2147233Sgblack@eecs.umich.edu    m5_loadsymbol(addr, symbol);
2157233Sgblack@eecs.umich.edu}
2167233Sgblack@eecs.umich.edu
2177233Sgblack@eecs.umich.eduvoid
2187241Sgblack@eecs.umich.edudo_initparam(int argc, char *argv[])
2197241Sgblack@eecs.umich.edu{
2207241Sgblack@eecs.umich.edu    if (argc != 0)
2217241Sgblack@eecs.umich.edu        usage();
22212104Snathanael.premillieu@arm.com
2237241Sgblack@eecs.umich.edu    uint64_t val = m5_initparam();
22412104Snathanael.premillieu@arm.com    printf("%"PRIu64, val);
2257241Sgblack@eecs.umich.edu}
22612104Snathanael.premillieu@arm.com
2277241Sgblack@eecs.umich.eduvoid
22812104Snathanael.premillieu@arm.comdo_sw99param(int argc, char *argv[])
2297241Sgblack@eecs.umich.edu{
2307241Sgblack@eecs.umich.edu    if (argc != 0)
2317241Sgblack@eecs.umich.edu        usage();
2327241Sgblack@eecs.umich.edu
2337238Sgblack@eecs.umich.edu    uint64_t param = m5_initparam();
2347238Sgblack@eecs.umich.edu
2357238Sgblack@eecs.umich.edu    // run-time, rampup-time, rampdown-time, warmup-time, connections
2367238Sgblack@eecs.umich.edu    printf("%"PRId64" %"PRId64" %"PRId64" %"PRId64" %"PRId64,
23712104Snathanael.premillieu@arm.com           (param >> 48) & 0xfff,
2387238Sgblack@eecs.umich.edu           (param >> 36) & 0xfff, (param >> 24) & 0xfff,
23912104Snathanael.premillieu@arm.com           (param >> 12) & 0xfff, (param >> 0) & 0xfff);
2407238Sgblack@eecs.umich.edu}
24112104Snathanael.premillieu@arm.com
2427238Sgblack@eecs.umich.edu#ifdef linux
2437238Sgblack@eecs.umich.eduvoid
2447238Sgblack@eecs.umich.edudo_pin(int argc, char *argv[])
2457238Sgblack@eecs.umich.edu{
2467331Sgblack@eecs.umich.edu    if (argc < 2)
2477331Sgblack@eecs.umich.edu        usage();
2487331Sgblack@eecs.umich.edu
2497331Sgblack@eecs.umich.edu    cpu_set_t mask;
25012104Snathanael.premillieu@arm.com    CPU_ZERO(&mask);
2517331Sgblack@eecs.umich.edu
25212104Snathanael.premillieu@arm.com    const char *sep = ",";
2537331Sgblack@eecs.umich.edu    char *target = strtok(argv[0], sep);
2547331Sgblack@eecs.umich.edu    while (target) {
2557331Sgblack@eecs.umich.edu        CPU_SET(atoi(target), &mask);
2567331Sgblack@eecs.umich.edu        target = strtok(NULL, sep);
2577331Sgblack@eecs.umich.edu    }
25810418Sandreas.hansson@arm.com
25910418Sandreas.hansson@arm.com    if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) < 0)
26010418Sandreas.hansson@arm.com        err(1, "setaffinity");
26110418Sandreas.hansson@arm.com
26212281Sgiacomo.travaglini@arm.com    execvp(argv[1], &argv[1]);
26310418Sandreas.hansson@arm.com    err(1, "execvp failed!");
26412104Snathanael.premillieu@arm.com}
26510418Sandreas.hansson@arm.com#endif
26610418Sandreas.hansson@arm.com
26710418Sandreas.hansson@arm.comstruct MainFunc
26810418Sandreas.hansson@arm.com{
26910418Sandreas.hansson@arm.com    char *name;
27010418Sandreas.hansson@arm.com    void (*func)(int argc, char *argv[]);
27110418Sandreas.hansson@arm.com    char *usage;
27210418Sandreas.hansson@arm.com};
27312104Snathanael.premillieu@arm.com
27410418Sandreas.hansson@arm.comstruct MainFunc mainfuncs[] = {
27512281Sgiacomo.travaglini@arm.com    { "exit",           do_exit,             "[delay]" },
27610418Sandreas.hansson@arm.com    { "resetstats",     do_reset_stats,      "[delay [period]]" },
27710418Sandreas.hansson@arm.com    { "dumpstats",      do_dump_stats,       "[delay [period]]" },
27810418Sandreas.hansson@arm.com    { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" },
27910418Sandreas.hansson@arm.com    { "readfile",       do_read_file,        "" },
28010037SARM gem5 Developers    { "writefile",      do_write_file,       "<filename>" },
28110037SARM gem5 Developers    { "execfile",       do_exec_file,        "" },
28210037SARM gem5 Developers    { "checkpoint",     do_checkpoint,       "[delay [period]]" },
28310037SARM gem5 Developers    { "loadsymbol",     do_load_symbol,      "<address> <symbol>" },
28412104Snathanael.premillieu@arm.com    { "initparam",      do_initparam,        "" },
28510037SARM gem5 Developers    { "sw99param",      do_sw99param,        "" },
28610037SARM gem5 Developers#ifdef linux
28710037SARM gem5 Developers    { "pin",            do_pin,              "<cpu> <program> [args ...]" }
28810037SARM gem5 Developers#endif
28910037SARM gem5 Developers};
2907253Sgblack@eecs.umich.eduint numfuncs = sizeof(mainfuncs) / sizeof(mainfuncs[0]);
2917253Sgblack@eecs.umich.edu
2927253Sgblack@eecs.umich.eduvoid
2937253Sgblack@eecs.umich.eduusage()
29412104Snathanael.premillieu@arm.com{
2957253Sgblack@eecs.umich.edu    int i;
29612104Snathanael.premillieu@arm.com
2977253Sgblack@eecs.umich.edu    for (i = 0; i < numfuncs; ++i) {
2987253Sgblack@eecs.umich.edu        char *header = i ? "" : "usage:";
2997253Sgblack@eecs.umich.edu        fprintf(stderr, "%-6s %s %s %s\n",
3007253Sgblack@eecs.umich.edu                header, progname, mainfuncs[i].name, mainfuncs[i].usage);
3017253Sgblack@eecs.umich.edu    }
3027232Sgblack@eecs.umich.edu    fprintf(stderr, "\n");
3037225Sgblack@eecs.umich.edu    fprintf(stderr, "All times in nanoseconds!\n");
3047225Sgblack@eecs.umich.edu
3057225Sgblack@eecs.umich.edu    exit(1);
30612104Snathanael.premillieu@arm.com}
3077232Sgblack@eecs.umich.edu
30812104Snathanael.premillieu@arm.comint
3097225Sgblack@eecs.umich.edumain(int argc, char *argv[])
3107225Sgblack@eecs.umich.edu{
3117225Sgblack@eecs.umich.edu    progname = argv[0];
3127225Sgblack@eecs.umich.edu    if (argc < 2)
3137232Sgblack@eecs.umich.edu        usage(1);
3147225Sgblack@eecs.umich.edu
3157225Sgblack@eecs.umich.edu    command = argv[1];
3167225Sgblack@eecs.umich.edu
31712104Snathanael.premillieu@arm.com    argv += 2;
3187232Sgblack@eecs.umich.edu    argc -= 2;
3197225Sgblack@eecs.umich.edu
32012104Snathanael.premillieu@arm.com    int i;
3217225Sgblack@eecs.umich.edu    for (i = 0; i < numfuncs; ++i) {
3227225Sgblack@eecs.umich.edu        if (strcmp(command, mainfuncs[i].name) != 0)
3237409Sgblack@eecs.umich.edu            continue;
3247409Sgblack@eecs.umich.edu
3257409Sgblack@eecs.umich.edu        mainfuncs[i].func(argc, argv);
3267409Sgblack@eecs.umich.edu        exit(0);
3277426Sgblack@eecs.umich.edu    }
3287409Sgblack@eecs.umich.edu
329    usage(1);
330}
331