m5.c revision 9949
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> 549898Sandreas@sandberg.pp.se#include <sys/mman.h> 559898Sandreas@sandberg.pp.se#include <sys/stat.h> 569898Sandreas@sandberg.pp.se#include <sys/types.h> 572358Sktlim@umich.edu#include <unistd.h> 58275Sbinkertn@umich.edu 59275Sbinkertn@umich.edu#include "m5op.h" 60275Sbinkertn@umich.edu 619898Sandreas@sandberg.pp.sevoid *m5_mem = NULL; 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 865754Snate@binkert.orgint 875754Snate@binkert.orgread_file(int dest_fid) 885754Snate@binkert.org{ 895754Snate@binkert.org char buf[256*1024]; 905754Snate@binkert.org int offset = 0; 915754Snate@binkert.org int len; 925754Snate@binkert.org 937517Shestness@cs.utexas.edu // Touch all buffer pages to ensure they are mapped in the 947517Shestness@cs.utexas.edu // page table. This is required in the case of X86_FS, where 957517Shestness@cs.utexas.edu // Linux does demand paging. 967517Shestness@cs.utexas.edu memset(buf, 0, sizeof(buf)); 977517Shestness@cs.utexas.edu 985754Snate@binkert.org while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) { 995754Snate@binkert.org write(dest_fid, buf, len); 1005754Snate@binkert.org offset += len; 1015754Snate@binkert.org } 1025754Snate@binkert.org} 1035754Snate@binkert.org 1048734Sdam.sunwoo@arm.comint 1058734Sdam.sunwoo@arm.comwrite_file(const char *filename) 1068734Sdam.sunwoo@arm.com{ 1078734Sdam.sunwoo@arm.com fprintf(stderr, "opening %s\n", filename); 1088734Sdam.sunwoo@arm.com int src_fid = open(filename, O_RDONLY); 1098734Sdam.sunwoo@arm.com 1108734Sdam.sunwoo@arm.com if (src_fid < 0) { 1118734Sdam.sunwoo@arm.com fprintf(stderr, "error opening %s\n", filename); 1128734Sdam.sunwoo@arm.com return; 1138734Sdam.sunwoo@arm.com } 1148734Sdam.sunwoo@arm.com 1158734Sdam.sunwoo@arm.com char buf[256*1024]; 1168734Sdam.sunwoo@arm.com int offset = 0; 1178734Sdam.sunwoo@arm.com int len; 1188734Sdam.sunwoo@arm.com int bytes = 0; 1198734Sdam.sunwoo@arm.com 1208734Sdam.sunwoo@arm.com memset(buf, 0, sizeof(buf)); 1218734Sdam.sunwoo@arm.com 1228734Sdam.sunwoo@arm.com while ((len = read(src_fid, buf, sizeof(buf))) > 0) { 1238734Sdam.sunwoo@arm.com bytes += m5_writefile(buf, len, offset, filename); 1248734Sdam.sunwoo@arm.com offset += len; 1258734Sdam.sunwoo@arm.com } 1268734Sdam.sunwoo@arm.com fprintf(stderr, "written %d bytes\n", bytes); 1278734Sdam.sunwoo@arm.com 1288734Sdam.sunwoo@arm.com close(src_fid); 1298734Sdam.sunwoo@arm.com} 1308734Sdam.sunwoo@arm.com 1315754Snate@binkert.orgvoid 1325754Snate@binkert.orgdo_exit(int argc, char *argv[]) 1335754Snate@binkert.org{ 1345754Snate@binkert.org if (argc > 1) 1355754Snate@binkert.org usage(); 1365754Snate@binkert.org 1379191SAli.Saidi@ARM.com uint64_t ints[1]; 1389451SAndreas.Sandberg@ARM.com parse_int_args(argc, argv, ints, 1); 1399191SAli.Saidi@ARM.com m5_exit(ints[0]); 1405754Snate@binkert.org} 1415754Snate@binkert.org 1425754Snate@binkert.orgvoid 1439457Svilanova@ac.upc.edudo_fail(int argc, char *argv[]) 1449457Svilanova@ac.upc.edu{ 1459457Svilanova@ac.upc.edu if (argc < 1 || argc > 2) 1469457Svilanova@ac.upc.edu usage(); 1479457Svilanova@ac.upc.edu 1489949SAli.Saidi@ARM.com uint64_t ints[2] = {0,0}; 1499949SAli.Saidi@ARM.com parse_int_args(argc, argv, ints, argc); 1509949SAli.Saidi@ARM.com m5_fail(ints[1], ints[0]); 1519457Svilanova@ac.upc.edu} 1529457Svilanova@ac.upc.edu 1539457Svilanova@ac.upc.eduvoid 1545754Snate@binkert.orgdo_reset_stats(int argc, char *argv[]) 1555754Snate@binkert.org{ 1565754Snate@binkert.org uint64_t ints[2]; 1575754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1585754Snate@binkert.org m5_reset_stats(ints[0], ints[1]); 1595754Snate@binkert.org} 1605754Snate@binkert.org 1615754Snate@binkert.orgvoid 1625754Snate@binkert.orgdo_dump_stats(int argc, char *argv[]) 1635754Snate@binkert.org{ 1645754Snate@binkert.org uint64_t ints[2]; 1655754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1665754Snate@binkert.org m5_dump_stats(ints[0], ints[1]); 1675754Snate@binkert.org} 1685754Snate@binkert.org 1695754Snate@binkert.orgvoid 1705754Snate@binkert.orgdo_dump_reset_stats(int argc, char *argv[]) 1715754Snate@binkert.org{ 1725754Snate@binkert.org uint64_t ints[2]; 1735754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1745754Snate@binkert.org m5_dumpreset_stats(ints[0], ints[1]); 1755754Snate@binkert.org} 1765754Snate@binkert.org 1775754Snate@binkert.orgvoid 1785754Snate@binkert.orgdo_read_file(int argc, char *argv[]) 1795754Snate@binkert.org{ 1805754Snate@binkert.org if (argc > 0) 1815754Snate@binkert.org usage(); 1825754Snate@binkert.org 1835754Snate@binkert.org read_file(STDOUT_FILENO); 1845754Snate@binkert.org} 1855754Snate@binkert.org 1865754Snate@binkert.orgvoid 1878734Sdam.sunwoo@arm.comdo_write_file(int argc, char *argv[]) 1888734Sdam.sunwoo@arm.com{ 1898734Sdam.sunwoo@arm.com if (argc != 1) 1908734Sdam.sunwoo@arm.com usage(); 1918734Sdam.sunwoo@arm.com 1928734Sdam.sunwoo@arm.com const char *filename = argv[0]; 1938734Sdam.sunwoo@arm.com 1948734Sdam.sunwoo@arm.com write_file(filename); 1958734Sdam.sunwoo@arm.com} 1968734Sdam.sunwoo@arm.com 1978734Sdam.sunwoo@arm.comvoid 1985754Snate@binkert.orgdo_exec_file(int argc, char *argv[]) 1995754Snate@binkert.org{ 2005754Snate@binkert.org if (argc > 0) 2015754Snate@binkert.org usage(); 2025754Snate@binkert.org 2035754Snate@binkert.org const char *destname = "/tmp/execfile"; 2045754Snate@binkert.org 2055754Snate@binkert.org int fid = open(destname, O_WRONLY, 0777); 2065754Snate@binkert.org int len = read_file(fid); 2075754Snate@binkert.org close(fid); 2085754Snate@binkert.org if (len > 0) { 2095754Snate@binkert.org execl(destname, "execfile", NULL); 2105754Snate@binkert.org err(1, "execl failed!"); 2115754Snate@binkert.org } 2125754Snate@binkert.org} 2135754Snate@binkert.org 2145754Snate@binkert.orgvoid 2155754Snate@binkert.orgdo_checkpoint(int argc, char *argv[]) 2165754Snate@binkert.org{ 2175754Snate@binkert.org uint64_t ints[2]; 2185754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 2195754Snate@binkert.org m5_checkpoint(ints[0], ints[1]); 2205754Snate@binkert.org} 2215754Snate@binkert.org 2225754Snate@binkert.orgvoid 2235754Snate@binkert.orgdo_load_symbol(int argc, char *argv[]) 2245754Snate@binkert.org{ 2255754Snate@binkert.org if (argc != 2) 2265754Snate@binkert.org usage(); 2275754Snate@binkert.org 2285754Snate@binkert.org uint64_t addr = strtoul(argv[0], NULL, 0); 2295754Snate@binkert.org char *symbol = argv[1]; 2305754Snate@binkert.org m5_loadsymbol(addr, symbol); 2315754Snate@binkert.org} 2325754Snate@binkert.org 2335754Snate@binkert.orgvoid 2345754Snate@binkert.orgdo_initparam(int argc, char *argv[]) 2355754Snate@binkert.org{ 2365754Snate@binkert.org if (argc != 0) 2375754Snate@binkert.org usage(); 2385754Snate@binkert.org 2398659SAli.Saidi@ARM.com uint64_t val = m5_initparam(); 2408659SAli.Saidi@ARM.com printf("%"PRIu64, val); 2415754Snate@binkert.org} 2425754Snate@binkert.org 2435754Snate@binkert.orgvoid 2445754Snate@binkert.orgdo_sw99param(int argc, char *argv[]) 2455754Snate@binkert.org{ 2465754Snate@binkert.org if (argc != 0) 2475754Snate@binkert.org usage(); 2485754Snate@binkert.org 2495754Snate@binkert.org uint64_t param = m5_initparam(); 2505754Snate@binkert.org 2515754Snate@binkert.org // run-time, rampup-time, rampdown-time, warmup-time, connections 2529191SAli.Saidi@ARM.com printf("%"PRId64" %"PRId64" %"PRId64" %"PRId64" %"PRId64, 2539191SAli.Saidi@ARM.com (param >> 48) & 0xfff, 2545754Snate@binkert.org (param >> 36) & 0xfff, (param >> 24) & 0xfff, 2555754Snate@binkert.org (param >> 12) & 0xfff, (param >> 0) & 0xfff); 2565754Snate@binkert.org} 2575754Snate@binkert.org 2585755Snate@binkert.org#ifdef linux 2595755Snate@binkert.orgvoid 2605755Snate@binkert.orgdo_pin(int argc, char *argv[]) 2615755Snate@binkert.org{ 2625755Snate@binkert.org if (argc < 2) 2635755Snate@binkert.org usage(); 2645755Snate@binkert.org 2655755Snate@binkert.org cpu_set_t mask; 2665755Snate@binkert.org CPU_ZERO(&mask); 2675755Snate@binkert.org 2685755Snate@binkert.org const char *sep = ","; 2695755Snate@binkert.org char *target = strtok(argv[0], sep); 2705755Snate@binkert.org while (target) { 2715755Snate@binkert.org CPU_SET(atoi(target), &mask); 2725755Snate@binkert.org target = strtok(NULL, sep); 2735755Snate@binkert.org } 2745755Snate@binkert.org 2755755Snate@binkert.org if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) < 0) 2765755Snate@binkert.org err(1, "setaffinity"); 2775755Snate@binkert.org 2785755Snate@binkert.org execvp(argv[1], &argv[1]); 2795755Snate@binkert.org err(1, "execvp failed!"); 2805755Snate@binkert.org} 2815755Snate@binkert.org#endif 2825755Snate@binkert.org 2835754Snate@binkert.orgstruct MainFunc 2845754Snate@binkert.org{ 2855754Snate@binkert.org char *name; 2865754Snate@binkert.org void (*func)(int argc, char *argv[]); 2875754Snate@binkert.org char *usage; 2885754Snate@binkert.org}; 2895754Snate@binkert.org 2905754Snate@binkert.orgstruct MainFunc mainfuncs[] = { 2915754Snate@binkert.org { "exit", do_exit, "[delay]" }, 2929457Svilanova@ac.upc.edu { "fail", do_fail, "<code> [delay]" }, 2935754Snate@binkert.org { "resetstats", do_reset_stats, "[delay [period]]" }, 2945754Snate@binkert.org { "dumpstats", do_dump_stats, "[delay [period]]" }, 2955754Snate@binkert.org { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" }, 2968734Sdam.sunwoo@arm.com { "readfile", do_read_file, "" }, 2978734Sdam.sunwoo@arm.com { "writefile", do_write_file, "<filename>" }, 2988734Sdam.sunwoo@arm.com { "execfile", do_exec_file, "" }, 2995754Snate@binkert.org { "checkpoint", do_checkpoint, "[delay [period]]" }, 3005754Snate@binkert.org { "loadsymbol", do_load_symbol, "<address> <symbol>" }, 3015754Snate@binkert.org { "initparam", do_initparam, "" }, 3025754Snate@binkert.org { "sw99param", do_sw99param, "" }, 3035755Snate@binkert.org#ifdef linux 3045755Snate@binkert.org { "pin", do_pin, "<cpu> <program> [args ...]" } 3055755Snate@binkert.org#endif 3065754Snate@binkert.org}; 3075754Snate@binkert.orgint numfuncs = sizeof(mainfuncs) / sizeof(mainfuncs[0]); 308275Sbinkertn@umich.edu 309275Sbinkertn@umich.eduvoid 310275Sbinkertn@umich.eduusage() 311275Sbinkertn@umich.edu{ 3125754Snate@binkert.org int i; 3135754Snate@binkert.org 3145754Snate@binkert.org for (i = 0; i < numfuncs; ++i) { 3155754Snate@binkert.org char *header = i ? "" : "usage:"; 3165754Snate@binkert.org fprintf(stderr, "%-6s %s %s %s\n", 3175754Snate@binkert.org header, progname, mainfuncs[i].name, mainfuncs[i].usage); 3185754Snate@binkert.org } 3195754Snate@binkert.org fprintf(stderr, "\n"); 3205754Snate@binkert.org fprintf(stderr, "All times in nanoseconds!\n"); 3215754Snate@binkert.org 322275Sbinkertn@umich.edu exit(1); 323275Sbinkertn@umich.edu} 324275Sbinkertn@umich.edu 3259898Sandreas@sandberg.pp.sestatic void 3269898Sandreas@sandberg.pp.semap_m5_mem() 3279898Sandreas@sandberg.pp.se{ 3289898Sandreas@sandberg.pp.se#ifdef M5OP_ADDR 3299898Sandreas@sandberg.pp.se int fd; 3309898Sandreas@sandberg.pp.se 3319898Sandreas@sandberg.pp.se fd = open("/dev/mem", O_RDWR | O_SYNC); 3329898Sandreas@sandberg.pp.se if (fd == -1) { 3339898Sandreas@sandberg.pp.se perror("Can't open /dev/mem"); 3349898Sandreas@sandberg.pp.se exit(1); 3359898Sandreas@sandberg.pp.se } 3369898Sandreas@sandberg.pp.se 3379898Sandreas@sandberg.pp.se m5_mem = mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, M5OP_ADDR); 3389898Sandreas@sandberg.pp.se if (!m5_mem) { 3399898Sandreas@sandberg.pp.se perror("Can't mmap /dev/mem"); 3409898Sandreas@sandberg.pp.se exit(1); 3419898Sandreas@sandberg.pp.se } 3429898Sandreas@sandberg.pp.se#endif 3439898Sandreas@sandberg.pp.se} 3449898Sandreas@sandberg.pp.se 345275Sbinkertn@umich.eduint 346275Sbinkertn@umich.edumain(int argc, char *argv[]) 347275Sbinkertn@umich.edu{ 348275Sbinkertn@umich.edu progname = argv[0]; 349275Sbinkertn@umich.edu if (argc < 2) 3505754Snate@binkert.org usage(1); 351275Sbinkertn@umich.edu 3529898Sandreas@sandberg.pp.se map_m5_mem(); 3539898Sandreas@sandberg.pp.se 354287Sbinkertn@umich.edu command = argv[1]; 355287Sbinkertn@umich.edu 3565754Snate@binkert.org argv += 2; 3575754Snate@binkert.org argc -= 2; 358287Sbinkertn@umich.edu 3595754Snate@binkert.org int i; 3605754Snate@binkert.org for (i = 0; i < numfuncs; ++i) { 3615754Snate@binkert.org if (strcmp(command, mainfuncs[i].name) != 0) 3625754Snate@binkert.org continue; 3635754Snate@binkert.org 3645754Snate@binkert.org mainfuncs[i].func(argc, argv); 3655754Snate@binkert.org exit(0); 366287Sbinkertn@umich.edu } 367287Sbinkertn@umich.edu 3685754Snate@binkert.org usage(1); 369275Sbinkertn@umich.edu} 370