m5.c revision 9457
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 689191SAli.Saidi@ARM.com// On 32 bit platforms we need to use strtoull to do the conversion 699191SAli.Saidi@ARM.com#ifdef __LP64__ 709191SAli.Saidi@ARM.com#define strto64 strtoul 719191SAli.Saidi@ARM.com#else 729191SAli.Saidi@ARM.com#define strto64 strtoull 739191SAli.Saidi@ARM.com#endif 745754Snate@binkert.org int i; 755754Snate@binkert.org for (i = 0; i < len; ++i) 769191SAli.Saidi@ARM.com ints[i] = (i < argc) ? strto64(argv[i], NULL, 0) : 0; 779191SAli.Saidi@ARM.com 789191SAli.Saidi@ARM.com#undef strto64 795754Snate@binkert.org} 805754Snate@binkert.org 815754Snate@binkert.orgint 825754Snate@binkert.orgread_file(int dest_fid) 835754Snate@binkert.org{ 845754Snate@binkert.org char buf[256*1024]; 855754Snate@binkert.org int offset = 0; 865754Snate@binkert.org int len; 875754Snate@binkert.org 887517Shestness@cs.utexas.edu // Touch all buffer pages to ensure they are mapped in the 897517Shestness@cs.utexas.edu // page table. This is required in the case of X86_FS, where 907517Shestness@cs.utexas.edu // Linux does demand paging. 917517Shestness@cs.utexas.edu memset(buf, 0, sizeof(buf)); 927517Shestness@cs.utexas.edu 935754Snate@binkert.org while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) { 945754Snate@binkert.org write(dest_fid, buf, len); 955754Snate@binkert.org offset += len; 965754Snate@binkert.org } 975754Snate@binkert.org} 985754Snate@binkert.org 998734Sdam.sunwoo@arm.comint 1008734Sdam.sunwoo@arm.comwrite_file(const char *filename) 1018734Sdam.sunwoo@arm.com{ 1028734Sdam.sunwoo@arm.com fprintf(stderr, "opening %s\n", filename); 1038734Sdam.sunwoo@arm.com int src_fid = open(filename, O_RDONLY); 1048734Sdam.sunwoo@arm.com 1058734Sdam.sunwoo@arm.com if (src_fid < 0) { 1068734Sdam.sunwoo@arm.com fprintf(stderr, "error opening %s\n", filename); 1078734Sdam.sunwoo@arm.com return; 1088734Sdam.sunwoo@arm.com } 1098734Sdam.sunwoo@arm.com 1108734Sdam.sunwoo@arm.com char buf[256*1024]; 1118734Sdam.sunwoo@arm.com int offset = 0; 1128734Sdam.sunwoo@arm.com int len; 1138734Sdam.sunwoo@arm.com int bytes = 0; 1148734Sdam.sunwoo@arm.com 1158734Sdam.sunwoo@arm.com memset(buf, 0, sizeof(buf)); 1168734Sdam.sunwoo@arm.com 1178734Sdam.sunwoo@arm.com while ((len = read(src_fid, buf, sizeof(buf))) > 0) { 1188734Sdam.sunwoo@arm.com bytes += m5_writefile(buf, len, offset, filename); 1198734Sdam.sunwoo@arm.com offset += len; 1208734Sdam.sunwoo@arm.com } 1218734Sdam.sunwoo@arm.com fprintf(stderr, "written %d bytes\n", bytes); 1228734Sdam.sunwoo@arm.com 1238734Sdam.sunwoo@arm.com close(src_fid); 1248734Sdam.sunwoo@arm.com} 1258734Sdam.sunwoo@arm.com 1265754Snate@binkert.orgvoid 1275754Snate@binkert.orgdo_exit(int argc, char *argv[]) 1285754Snate@binkert.org{ 1295754Snate@binkert.org if (argc > 1) 1305754Snate@binkert.org usage(); 1315754Snate@binkert.org 1329191SAli.Saidi@ARM.com uint64_t ints[1]; 1339451SAndreas.Sandberg@ARM.com parse_int_args(argc, argv, ints, 1); 1349191SAli.Saidi@ARM.com m5_exit(ints[0]); 1355754Snate@binkert.org} 1365754Snate@binkert.org 1375754Snate@binkert.orgvoid 1389457Svilanova@ac.upc.edudo_fail(int argc, char *argv[]) 1399457Svilanova@ac.upc.edu{ 1409457Svilanova@ac.upc.edu if (argc < 1 || argc > 2) 1419457Svilanova@ac.upc.edu usage(); 1429457Svilanova@ac.upc.edu 1439457Svilanova@ac.upc.edu m5_fail((argc > 1) ? strtoul(argv[1], NULL, 0) : 0, strtoul(argv[0], NULL, 0)); 1449457Svilanova@ac.upc.edu} 1459457Svilanova@ac.upc.edu 1469457Svilanova@ac.upc.eduvoid 1475754Snate@binkert.orgdo_reset_stats(int argc, char *argv[]) 1485754Snate@binkert.org{ 1495754Snate@binkert.org uint64_t ints[2]; 1505754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1515754Snate@binkert.org m5_reset_stats(ints[0], ints[1]); 1525754Snate@binkert.org} 1535754Snate@binkert.org 1545754Snate@binkert.orgvoid 1555754Snate@binkert.orgdo_dump_stats(int argc, char *argv[]) 1565754Snate@binkert.org{ 1575754Snate@binkert.org uint64_t ints[2]; 1585754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1595754Snate@binkert.org m5_dump_stats(ints[0], ints[1]); 1605754Snate@binkert.org} 1615754Snate@binkert.org 1625754Snate@binkert.orgvoid 1635754Snate@binkert.orgdo_dump_reset_stats(int argc, char *argv[]) 1645754Snate@binkert.org{ 1655754Snate@binkert.org uint64_t ints[2]; 1665754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1675754Snate@binkert.org m5_dumpreset_stats(ints[0], ints[1]); 1685754Snate@binkert.org} 1695754Snate@binkert.org 1705754Snate@binkert.orgvoid 1715754Snate@binkert.orgdo_read_file(int argc, char *argv[]) 1725754Snate@binkert.org{ 1735754Snate@binkert.org if (argc > 0) 1745754Snate@binkert.org usage(); 1755754Snate@binkert.org 1765754Snate@binkert.org read_file(STDOUT_FILENO); 1775754Snate@binkert.org} 1785754Snate@binkert.org 1795754Snate@binkert.orgvoid 1808734Sdam.sunwoo@arm.comdo_write_file(int argc, char *argv[]) 1818734Sdam.sunwoo@arm.com{ 1828734Sdam.sunwoo@arm.com if (argc != 1) 1838734Sdam.sunwoo@arm.com usage(); 1848734Sdam.sunwoo@arm.com 1858734Sdam.sunwoo@arm.com const char *filename = argv[0]; 1868734Sdam.sunwoo@arm.com 1878734Sdam.sunwoo@arm.com write_file(filename); 1888734Sdam.sunwoo@arm.com} 1898734Sdam.sunwoo@arm.com 1908734Sdam.sunwoo@arm.comvoid 1915754Snate@binkert.orgdo_exec_file(int argc, char *argv[]) 1925754Snate@binkert.org{ 1935754Snate@binkert.org if (argc > 0) 1945754Snate@binkert.org usage(); 1955754Snate@binkert.org 1965754Snate@binkert.org const char *destname = "/tmp/execfile"; 1975754Snate@binkert.org 1985754Snate@binkert.org int fid = open(destname, O_WRONLY, 0777); 1995754Snate@binkert.org int len = read_file(fid); 2005754Snate@binkert.org close(fid); 2015754Snate@binkert.org if (len > 0) { 2025754Snate@binkert.org execl(destname, "execfile", NULL); 2035754Snate@binkert.org err(1, "execl failed!"); 2045754Snate@binkert.org } 2055754Snate@binkert.org} 2065754Snate@binkert.org 2075754Snate@binkert.orgvoid 2085754Snate@binkert.orgdo_checkpoint(int argc, char *argv[]) 2095754Snate@binkert.org{ 2105754Snate@binkert.org uint64_t ints[2]; 2115754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 2125754Snate@binkert.org m5_checkpoint(ints[0], ints[1]); 2135754Snate@binkert.org} 2145754Snate@binkert.org 2155754Snate@binkert.orgvoid 2165754Snate@binkert.orgdo_load_symbol(int argc, char *argv[]) 2175754Snate@binkert.org{ 2185754Snate@binkert.org if (argc != 2) 2195754Snate@binkert.org usage(); 2205754Snate@binkert.org 2215754Snate@binkert.org uint64_t addr = strtoul(argv[0], NULL, 0); 2225754Snate@binkert.org char *symbol = argv[1]; 2235754Snate@binkert.org m5_loadsymbol(addr, symbol); 2245754Snate@binkert.org} 2255754Snate@binkert.org 2265754Snate@binkert.orgvoid 2275754Snate@binkert.orgdo_initparam(int argc, char *argv[]) 2285754Snate@binkert.org{ 2295754Snate@binkert.org if (argc != 0) 2305754Snate@binkert.org usage(); 2315754Snate@binkert.org 2328659SAli.Saidi@ARM.com uint64_t val = m5_initparam(); 2338659SAli.Saidi@ARM.com printf("%"PRIu64, val); 2345754Snate@binkert.org} 2355754Snate@binkert.org 2365754Snate@binkert.orgvoid 2375754Snate@binkert.orgdo_sw99param(int argc, char *argv[]) 2385754Snate@binkert.org{ 2395754Snate@binkert.org if (argc != 0) 2405754Snate@binkert.org usage(); 2415754Snate@binkert.org 2425754Snate@binkert.org uint64_t param = m5_initparam(); 2435754Snate@binkert.org 2445754Snate@binkert.org // run-time, rampup-time, rampdown-time, warmup-time, connections 2459191SAli.Saidi@ARM.com printf("%"PRId64" %"PRId64" %"PRId64" %"PRId64" %"PRId64, 2469191SAli.Saidi@ARM.com (param >> 48) & 0xfff, 2475754Snate@binkert.org (param >> 36) & 0xfff, (param >> 24) & 0xfff, 2485754Snate@binkert.org (param >> 12) & 0xfff, (param >> 0) & 0xfff); 2495754Snate@binkert.org} 2505754Snate@binkert.org 2515755Snate@binkert.org#ifdef linux 2525755Snate@binkert.orgvoid 2535755Snate@binkert.orgdo_pin(int argc, char *argv[]) 2545755Snate@binkert.org{ 2555755Snate@binkert.org if (argc < 2) 2565755Snate@binkert.org usage(); 2575755Snate@binkert.org 2585755Snate@binkert.org cpu_set_t mask; 2595755Snate@binkert.org CPU_ZERO(&mask); 2605755Snate@binkert.org 2615755Snate@binkert.org const char *sep = ","; 2625755Snate@binkert.org char *target = strtok(argv[0], sep); 2635755Snate@binkert.org while (target) { 2645755Snate@binkert.org CPU_SET(atoi(target), &mask); 2655755Snate@binkert.org target = strtok(NULL, sep); 2665755Snate@binkert.org } 2675755Snate@binkert.org 2685755Snate@binkert.org if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) < 0) 2695755Snate@binkert.org err(1, "setaffinity"); 2705755Snate@binkert.org 2715755Snate@binkert.org execvp(argv[1], &argv[1]); 2725755Snate@binkert.org err(1, "execvp failed!"); 2735755Snate@binkert.org} 2745755Snate@binkert.org#endif 2755755Snate@binkert.org 2765754Snate@binkert.orgstruct MainFunc 2775754Snate@binkert.org{ 2785754Snate@binkert.org char *name; 2795754Snate@binkert.org void (*func)(int argc, char *argv[]); 2805754Snate@binkert.org char *usage; 2815754Snate@binkert.org}; 2825754Snate@binkert.org 2835754Snate@binkert.orgstruct MainFunc mainfuncs[] = { 2845754Snate@binkert.org { "exit", do_exit, "[delay]" }, 2859457Svilanova@ac.upc.edu { "fail", do_fail, "<code> [delay]" }, 2865754Snate@binkert.org { "resetstats", do_reset_stats, "[delay [period]]" }, 2875754Snate@binkert.org { "dumpstats", do_dump_stats, "[delay [period]]" }, 2885754Snate@binkert.org { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" }, 2898734Sdam.sunwoo@arm.com { "readfile", do_read_file, "" }, 2908734Sdam.sunwoo@arm.com { "writefile", do_write_file, "<filename>" }, 2918734Sdam.sunwoo@arm.com { "execfile", do_exec_file, "" }, 2925754Snate@binkert.org { "checkpoint", do_checkpoint, "[delay [period]]" }, 2935754Snate@binkert.org { "loadsymbol", do_load_symbol, "<address> <symbol>" }, 2945754Snate@binkert.org { "initparam", do_initparam, "" }, 2955754Snate@binkert.org { "sw99param", do_sw99param, "" }, 2965755Snate@binkert.org#ifdef linux 2975755Snate@binkert.org { "pin", do_pin, "<cpu> <program> [args ...]" } 2985755Snate@binkert.org#endif 2995754Snate@binkert.org}; 3005754Snate@binkert.orgint numfuncs = sizeof(mainfuncs) / sizeof(mainfuncs[0]); 301275Sbinkertn@umich.edu 302275Sbinkertn@umich.eduvoid 303275Sbinkertn@umich.eduusage() 304275Sbinkertn@umich.edu{ 3055754Snate@binkert.org int i; 3065754Snate@binkert.org 3075754Snate@binkert.org for (i = 0; i < numfuncs; ++i) { 3085754Snate@binkert.org char *header = i ? "" : "usage:"; 3095754Snate@binkert.org fprintf(stderr, "%-6s %s %s %s\n", 3105754Snate@binkert.org header, progname, mainfuncs[i].name, mainfuncs[i].usage); 3115754Snate@binkert.org } 3125754Snate@binkert.org fprintf(stderr, "\n"); 3135754Snate@binkert.org fprintf(stderr, "All times in nanoseconds!\n"); 3145754Snate@binkert.org 315275Sbinkertn@umich.edu exit(1); 316275Sbinkertn@umich.edu} 317275Sbinkertn@umich.edu 318275Sbinkertn@umich.eduint 319275Sbinkertn@umich.edumain(int argc, char *argv[]) 320275Sbinkertn@umich.edu{ 321275Sbinkertn@umich.edu progname = argv[0]; 322275Sbinkertn@umich.edu if (argc < 2) 3235754Snate@binkert.org usage(1); 324275Sbinkertn@umich.edu 325287Sbinkertn@umich.edu command = argv[1]; 326287Sbinkertn@umich.edu 3275754Snate@binkert.org argv += 2; 3285754Snate@binkert.org argc -= 2; 329287Sbinkertn@umich.edu 3305754Snate@binkert.org int i; 3315754Snate@binkert.org for (i = 0; i < numfuncs; ++i) { 3325754Snate@binkert.org if (strcmp(command, mainfuncs[i].name) != 0) 3335754Snate@binkert.org continue; 3345754Snate@binkert.org 3355754Snate@binkert.org mainfuncs[i].func(argc, argv); 3365754Snate@binkert.org exit(0); 337287Sbinkertn@umich.edu } 338287Sbinkertn@umich.edu 3395754Snate@binkert.org usage(1); 340275Sbinkertn@umich.edu} 341