m5.c revision 8659
1278Sbinkertn@umich.edu/* 28659SAli.Saidi@ARM.com * Copyright (c) 2011 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> 465755Snate@binkert.org#endif 475755Snate@binkert.org 485754Snate@binkert.org#include <err.h> 495754Snate@binkert.org#include <fcntl.h> 508229Snate@binkert.org#include <inttypes.h> 51275Sbinkertn@umich.edu#include <stdio.h> 52275Sbinkertn@umich.edu#include <stdlib.h> 53275Sbinkertn@umich.edu#include <string.h> 542358Sktlim@umich.edu#include <unistd.h> 55275Sbinkertn@umich.edu 56275Sbinkertn@umich.edu#include "m5op.h" 57275Sbinkertn@umich.edu 58275Sbinkertn@umich.educhar *progname; 595754Snate@binkert.orgchar *command = "unspecified"; 605754Snate@binkert.orgvoid usage(); 615754Snate@binkert.org 625754Snate@binkert.orgvoid 635754Snate@binkert.orgparse_int_args(int argc, char *argv[], uint64_t ints[], int len) 645754Snate@binkert.org{ 655754Snate@binkert.org if (argc > len) 665754Snate@binkert.org usage(); 675754Snate@binkert.org 685754Snate@binkert.org int i; 695754Snate@binkert.org for (i = 0; i < len; ++i) 705754Snate@binkert.org ints[i] = (i < argc) ? strtoul(argv[i], NULL, 0) : 0; 715754Snate@binkert.org} 725754Snate@binkert.org 735754Snate@binkert.orgint 745754Snate@binkert.orgread_file(int dest_fid) 755754Snate@binkert.org{ 765754Snate@binkert.org char buf[256*1024]; 775754Snate@binkert.org int offset = 0; 785754Snate@binkert.org int len; 795754Snate@binkert.org 807517Shestness@cs.utexas.edu // Touch all buffer pages to ensure they are mapped in the 817517Shestness@cs.utexas.edu // page table. This is required in the case of X86_FS, where 827517Shestness@cs.utexas.edu // Linux does demand paging. 837517Shestness@cs.utexas.edu memset(buf, 0, sizeof(buf)); 847517Shestness@cs.utexas.edu 855754Snate@binkert.org while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) { 865754Snate@binkert.org write(dest_fid, buf, len); 875754Snate@binkert.org offset += len; 885754Snate@binkert.org } 895754Snate@binkert.org} 905754Snate@binkert.org 915754Snate@binkert.orgvoid 925754Snate@binkert.orgdo_exit(int argc, char *argv[]) 935754Snate@binkert.org{ 945754Snate@binkert.org if (argc > 1) 955754Snate@binkert.org usage(); 965754Snate@binkert.org 975754Snate@binkert.org m5_exit((argc > 0) ? strtoul(argv[0], NULL, 0) : 0); 985754Snate@binkert.org} 995754Snate@binkert.org 1005754Snate@binkert.orgvoid 1015754Snate@binkert.orgdo_reset_stats(int argc, char *argv[]) 1025754Snate@binkert.org{ 1035754Snate@binkert.org uint64_t ints[2]; 1045754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1055754Snate@binkert.org m5_reset_stats(ints[0], ints[1]); 1065754Snate@binkert.org} 1075754Snate@binkert.org 1085754Snate@binkert.orgvoid 1095754Snate@binkert.orgdo_dump_stats(int argc, char *argv[]) 1105754Snate@binkert.org{ 1115754Snate@binkert.org uint64_t ints[2]; 1125754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1135754Snate@binkert.org m5_dump_stats(ints[0], ints[1]); 1145754Snate@binkert.org} 1155754Snate@binkert.org 1165754Snate@binkert.orgvoid 1175754Snate@binkert.orgdo_dump_reset_stats(int argc, char *argv[]) 1185754Snate@binkert.org{ 1195754Snate@binkert.org uint64_t ints[2]; 1205754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1215754Snate@binkert.org m5_dumpreset_stats(ints[0], ints[1]); 1225754Snate@binkert.org} 1235754Snate@binkert.org 1245754Snate@binkert.orgvoid 1255754Snate@binkert.orgdo_read_file(int argc, char *argv[]) 1265754Snate@binkert.org{ 1275754Snate@binkert.org if (argc > 0) 1285754Snate@binkert.org usage(); 1295754Snate@binkert.org 1305754Snate@binkert.org read_file(STDOUT_FILENO); 1315754Snate@binkert.org} 1325754Snate@binkert.org 1335754Snate@binkert.orgvoid 1345754Snate@binkert.orgdo_exec_file(int argc, char *argv[]) 1355754Snate@binkert.org{ 1365754Snate@binkert.org if (argc > 0) 1375754Snate@binkert.org usage(); 1385754Snate@binkert.org 1395754Snate@binkert.org const char *destname = "/tmp/execfile"; 1405754Snate@binkert.org 1415754Snate@binkert.org int fid = open(destname, O_WRONLY, 0777); 1425754Snate@binkert.org int len = read_file(fid); 1435754Snate@binkert.org close(fid); 1445754Snate@binkert.org if (len > 0) { 1455754Snate@binkert.org execl(destname, "execfile", NULL); 1465754Snate@binkert.org err(1, "execl failed!"); 1475754Snate@binkert.org } 1485754Snate@binkert.org} 1495754Snate@binkert.org 1505754Snate@binkert.orgvoid 1515754Snate@binkert.orgdo_checkpoint(int argc, char *argv[]) 1525754Snate@binkert.org{ 1535754Snate@binkert.org uint64_t ints[2]; 1545754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1555754Snate@binkert.org m5_checkpoint(ints[0], ints[1]); 1565754Snate@binkert.org} 1575754Snate@binkert.org 1585754Snate@binkert.orgvoid 1595754Snate@binkert.orgdo_load_symbol(int argc, char *argv[]) 1605754Snate@binkert.org{ 1615754Snate@binkert.org if (argc != 2) 1625754Snate@binkert.org usage(); 1635754Snate@binkert.org 1645754Snate@binkert.org uint64_t addr = strtoul(argv[0], NULL, 0); 1655754Snate@binkert.org char *symbol = argv[1]; 1665754Snate@binkert.org m5_loadsymbol(addr, symbol); 1675754Snate@binkert.org} 1685754Snate@binkert.org 1695754Snate@binkert.orgvoid 1705754Snate@binkert.orgdo_initparam(int argc, char *argv[]) 1715754Snate@binkert.org{ 1725754Snate@binkert.org if (argc != 0) 1735754Snate@binkert.org usage(); 1745754Snate@binkert.org 1758659SAli.Saidi@ARM.com uint64_t val = m5_initparam(); 1768659SAli.Saidi@ARM.com printf("%"PRIu64, val); 1775754Snate@binkert.org} 1785754Snate@binkert.org 1795754Snate@binkert.orgvoid 1805754Snate@binkert.orgdo_sw99param(int argc, char *argv[]) 1815754Snate@binkert.org{ 1825754Snate@binkert.org if (argc != 0) 1835754Snate@binkert.org usage(); 1845754Snate@binkert.org 1855754Snate@binkert.org uint64_t param = m5_initparam(); 1865754Snate@binkert.org 1875754Snate@binkert.org // run-time, rampup-time, rampdown-time, warmup-time, connections 1885754Snate@binkert.org printf("%d %d %d %d %d", (param >> 48) & 0xfff, 1895754Snate@binkert.org (param >> 36) & 0xfff, (param >> 24) & 0xfff, 1905754Snate@binkert.org (param >> 12) & 0xfff, (param >> 0) & 0xfff); 1915754Snate@binkert.org} 1925754Snate@binkert.org 1935755Snate@binkert.org#ifdef linux 1945755Snate@binkert.orgvoid 1955755Snate@binkert.orgdo_pin(int argc, char *argv[]) 1965755Snate@binkert.org{ 1975755Snate@binkert.org if (argc < 2) 1985755Snate@binkert.org usage(); 1995755Snate@binkert.org 2005755Snate@binkert.org cpu_set_t mask; 2015755Snate@binkert.org CPU_ZERO(&mask); 2025755Snate@binkert.org 2035755Snate@binkert.org const char *sep = ","; 2045755Snate@binkert.org char *target = strtok(argv[0], sep); 2055755Snate@binkert.org while (target) { 2065755Snate@binkert.org CPU_SET(atoi(target), &mask); 2075755Snate@binkert.org target = strtok(NULL, sep); 2085755Snate@binkert.org } 2095755Snate@binkert.org 2105755Snate@binkert.org if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) < 0) 2115755Snate@binkert.org err(1, "setaffinity"); 2125755Snate@binkert.org 2135755Snate@binkert.org execvp(argv[1], &argv[1]); 2145755Snate@binkert.org err(1, "execvp failed!"); 2155755Snate@binkert.org} 2165755Snate@binkert.org#endif 2175755Snate@binkert.org 2185754Snate@binkert.orgstruct MainFunc 2195754Snate@binkert.org{ 2205754Snate@binkert.org char *name; 2215754Snate@binkert.org void (*func)(int argc, char *argv[]); 2225754Snate@binkert.org char *usage; 2235754Snate@binkert.org}; 2245754Snate@binkert.org 2255754Snate@binkert.orgstruct MainFunc mainfuncs[] = { 2265754Snate@binkert.org { "exit", do_exit, "[delay]" }, 2275754Snate@binkert.org { "resetstats", do_reset_stats, "[delay [period]]" }, 2285754Snate@binkert.org { "dumpstats", do_dump_stats, "[delay [period]]" }, 2295754Snate@binkert.org { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" }, 2305754Snate@binkert.org { "readfile", do_read_file, "[filename]" }, 2315754Snate@binkert.org { "execfile", do_exec_file, "<filename>" }, 2325754Snate@binkert.org { "checkpoint", do_checkpoint, "[delay [period]]" }, 2335754Snate@binkert.org { "loadsymbol", do_load_symbol, "<address> <symbol>" }, 2345754Snate@binkert.org { "initparam", do_initparam, "" }, 2355754Snate@binkert.org { "sw99param", do_sw99param, "" }, 2365755Snate@binkert.org#ifdef linux 2375755Snate@binkert.org { "pin", do_pin, "<cpu> <program> [args ...]" } 2385755Snate@binkert.org#endif 2395754Snate@binkert.org}; 2405754Snate@binkert.orgint numfuncs = sizeof(mainfuncs) / sizeof(mainfuncs[0]); 241275Sbinkertn@umich.edu 242275Sbinkertn@umich.eduvoid 243275Sbinkertn@umich.eduusage() 244275Sbinkertn@umich.edu{ 2455754Snate@binkert.org int i; 2465754Snate@binkert.org 2475754Snate@binkert.org for (i = 0; i < numfuncs; ++i) { 2485754Snate@binkert.org char *header = i ? "" : "usage:"; 2495754Snate@binkert.org fprintf(stderr, "%-6s %s %s %s\n", 2505754Snate@binkert.org header, progname, mainfuncs[i].name, mainfuncs[i].usage); 2515754Snate@binkert.org } 2525754Snate@binkert.org fprintf(stderr, "\n"); 2535754Snate@binkert.org fprintf(stderr, "All times in nanoseconds!\n"); 2545754Snate@binkert.org 255275Sbinkertn@umich.edu exit(1); 256275Sbinkertn@umich.edu} 257275Sbinkertn@umich.edu 258275Sbinkertn@umich.eduint 259275Sbinkertn@umich.edumain(int argc, char *argv[]) 260275Sbinkertn@umich.edu{ 261275Sbinkertn@umich.edu progname = argv[0]; 262275Sbinkertn@umich.edu if (argc < 2) 2635754Snate@binkert.org usage(1); 264275Sbinkertn@umich.edu 265287Sbinkertn@umich.edu command = argv[1]; 266287Sbinkertn@umich.edu 2675754Snate@binkert.org argv += 2; 2685754Snate@binkert.org argc -= 2; 269287Sbinkertn@umich.edu 2705754Snate@binkert.org int i; 2715754Snate@binkert.org for (i = 0; i < numfuncs; ++i) { 2725754Snate@binkert.org if (strcmp(command, mainfuncs[i].name) != 0) 2735754Snate@binkert.org continue; 2745754Snate@binkert.org 2755754Snate@binkert.org mainfuncs[i].func(argc, argv); 2765754Snate@binkert.org exit(0); 277287Sbinkertn@umich.edu } 278287Sbinkertn@umich.edu 2795754Snate@binkert.org usage(1); 280275Sbinkertn@umich.edu} 281