m5.c revision 11289
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 8611289Sgabor.dozsa@arm.comvoid 8711289Sgabor.dozsa@arm.comparse_str_args_to_regs(int argc, char *argv[], uint64_t regs[], int len) 8811289Sgabor.dozsa@arm.com{ 8911289Sgabor.dozsa@arm.com if (argc > 1 || strlen(argv[0]) > len * sizeof(uint64_t)) 9011289Sgabor.dozsa@arm.com usage(); 9111289Sgabor.dozsa@arm.com 9211289Sgabor.dozsa@arm.com int i; 9311289Sgabor.dozsa@arm.com for (i = 0; i < len; i++) 9411289Sgabor.dozsa@arm.com regs[i] = 0; 9511289Sgabor.dozsa@arm.com 9611289Sgabor.dozsa@arm.com if (argc == 0) 9711289Sgabor.dozsa@arm.com return; 9811289Sgabor.dozsa@arm.com 9911289Sgabor.dozsa@arm.com int n; 10011289Sgabor.dozsa@arm.com for (n = 0, i = 0; i < len && n < strlen(argv[0]); n++) { 10111289Sgabor.dozsa@arm.com *((char *)(®s[i]) + (n % 8)) = argv[0][n]; 10211289Sgabor.dozsa@arm.com if ((n % 8) == 7) 10311289Sgabor.dozsa@arm.com i++; 10411289Sgabor.dozsa@arm.com } 10511289Sgabor.dozsa@arm.com} 10611289Sgabor.dozsa@arm.com 1075754Snate@binkert.orgint 1085754Snate@binkert.orgread_file(int dest_fid) 1095754Snate@binkert.org{ 1105754Snate@binkert.org char buf[256*1024]; 1115754Snate@binkert.org int offset = 0; 1125754Snate@binkert.org int len; 1135754Snate@binkert.org 1147517Shestness@cs.utexas.edu // Touch all buffer pages to ensure they are mapped in the 1157517Shestness@cs.utexas.edu // page table. This is required in the case of X86_FS, where 1167517Shestness@cs.utexas.edu // Linux does demand paging. 1177517Shestness@cs.utexas.edu memset(buf, 0, sizeof(buf)); 1187517Shestness@cs.utexas.edu 1195754Snate@binkert.org while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) { 1205754Snate@binkert.org write(dest_fid, buf, len); 1215754Snate@binkert.org offset += len; 1225754Snate@binkert.org } 1235754Snate@binkert.org} 1245754Snate@binkert.org 1258734Sdam.sunwoo@arm.comint 1268734Sdam.sunwoo@arm.comwrite_file(const char *filename) 1278734Sdam.sunwoo@arm.com{ 1288734Sdam.sunwoo@arm.com fprintf(stderr, "opening %s\n", filename); 1298734Sdam.sunwoo@arm.com int src_fid = open(filename, O_RDONLY); 1308734Sdam.sunwoo@arm.com 1318734Sdam.sunwoo@arm.com if (src_fid < 0) { 1328734Sdam.sunwoo@arm.com fprintf(stderr, "error opening %s\n", filename); 1338734Sdam.sunwoo@arm.com return; 1348734Sdam.sunwoo@arm.com } 1358734Sdam.sunwoo@arm.com 1368734Sdam.sunwoo@arm.com char buf[256*1024]; 1378734Sdam.sunwoo@arm.com int offset = 0; 1388734Sdam.sunwoo@arm.com int len; 1398734Sdam.sunwoo@arm.com int bytes = 0; 1408734Sdam.sunwoo@arm.com 1418734Sdam.sunwoo@arm.com memset(buf, 0, sizeof(buf)); 1428734Sdam.sunwoo@arm.com 1438734Sdam.sunwoo@arm.com while ((len = read(src_fid, buf, sizeof(buf))) > 0) { 1448734Sdam.sunwoo@arm.com bytes += m5_writefile(buf, len, offset, filename); 1458734Sdam.sunwoo@arm.com offset += len; 1468734Sdam.sunwoo@arm.com } 1478734Sdam.sunwoo@arm.com fprintf(stderr, "written %d bytes\n", bytes); 1488734Sdam.sunwoo@arm.com 1498734Sdam.sunwoo@arm.com close(src_fid); 1508734Sdam.sunwoo@arm.com} 1518734Sdam.sunwoo@arm.com 1525754Snate@binkert.orgvoid 1535754Snate@binkert.orgdo_exit(int argc, char *argv[]) 1545754Snate@binkert.org{ 1555754Snate@binkert.org if (argc > 1) 1565754Snate@binkert.org usage(); 1575754Snate@binkert.org 1589191SAli.Saidi@ARM.com uint64_t ints[1]; 1599451SAndreas.Sandberg@ARM.com parse_int_args(argc, argv, ints, 1); 1609191SAli.Saidi@ARM.com m5_exit(ints[0]); 1615754Snate@binkert.org} 1625754Snate@binkert.org 1635754Snate@binkert.orgvoid 1649457Svilanova@ac.upc.edudo_fail(int argc, char *argv[]) 1659457Svilanova@ac.upc.edu{ 1669457Svilanova@ac.upc.edu if (argc < 1 || argc > 2) 1679457Svilanova@ac.upc.edu usage(); 1689457Svilanova@ac.upc.edu 1699949SAli.Saidi@ARM.com uint64_t ints[2] = {0,0}; 1709949SAli.Saidi@ARM.com parse_int_args(argc, argv, ints, argc); 1719949SAli.Saidi@ARM.com m5_fail(ints[1], ints[0]); 1729457Svilanova@ac.upc.edu} 1739457Svilanova@ac.upc.edu 1749457Svilanova@ac.upc.eduvoid 1755754Snate@binkert.orgdo_reset_stats(int argc, char *argv[]) 1765754Snate@binkert.org{ 1775754Snate@binkert.org uint64_t ints[2]; 1785754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1795754Snate@binkert.org m5_reset_stats(ints[0], ints[1]); 1805754Snate@binkert.org} 1815754Snate@binkert.org 1825754Snate@binkert.orgvoid 1835754Snate@binkert.orgdo_dump_stats(int argc, char *argv[]) 1845754Snate@binkert.org{ 1855754Snate@binkert.org uint64_t ints[2]; 1865754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1875754Snate@binkert.org m5_dump_stats(ints[0], ints[1]); 1885754Snate@binkert.org} 1895754Snate@binkert.org 1905754Snate@binkert.orgvoid 1915754Snate@binkert.orgdo_dump_reset_stats(int argc, char *argv[]) 1925754Snate@binkert.org{ 1935754Snate@binkert.org uint64_t ints[2]; 1945754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 1955754Snate@binkert.org m5_dumpreset_stats(ints[0], ints[1]); 1965754Snate@binkert.org} 1975754Snate@binkert.org 1985754Snate@binkert.orgvoid 1995754Snate@binkert.orgdo_read_file(int argc, char *argv[]) 2005754Snate@binkert.org{ 2015754Snate@binkert.org if (argc > 0) 2025754Snate@binkert.org usage(); 2035754Snate@binkert.org 2045754Snate@binkert.org read_file(STDOUT_FILENO); 2055754Snate@binkert.org} 2065754Snate@binkert.org 2075754Snate@binkert.orgvoid 2088734Sdam.sunwoo@arm.comdo_write_file(int argc, char *argv[]) 2098734Sdam.sunwoo@arm.com{ 2108734Sdam.sunwoo@arm.com if (argc != 1) 2118734Sdam.sunwoo@arm.com usage(); 2128734Sdam.sunwoo@arm.com 2138734Sdam.sunwoo@arm.com const char *filename = argv[0]; 2148734Sdam.sunwoo@arm.com 2158734Sdam.sunwoo@arm.com write_file(filename); 2168734Sdam.sunwoo@arm.com} 2178734Sdam.sunwoo@arm.com 2188734Sdam.sunwoo@arm.comvoid 2195754Snate@binkert.orgdo_exec_file(int argc, char *argv[]) 2205754Snate@binkert.org{ 2215754Snate@binkert.org if (argc > 0) 2225754Snate@binkert.org usage(); 2235754Snate@binkert.org 2245754Snate@binkert.org const char *destname = "/tmp/execfile"; 2255754Snate@binkert.org 2265754Snate@binkert.org int fid = open(destname, O_WRONLY, 0777); 2275754Snate@binkert.org int len = read_file(fid); 2285754Snate@binkert.org close(fid); 2295754Snate@binkert.org if (len > 0) { 2305754Snate@binkert.org execl(destname, "execfile", NULL); 2315754Snate@binkert.org err(1, "execl failed!"); 2325754Snate@binkert.org } 2335754Snate@binkert.org} 2345754Snate@binkert.org 2355754Snate@binkert.orgvoid 2365754Snate@binkert.orgdo_checkpoint(int argc, char *argv[]) 2375754Snate@binkert.org{ 2385754Snate@binkert.org uint64_t ints[2]; 2395754Snate@binkert.org parse_int_args(argc, argv, ints, 2); 2405754Snate@binkert.org m5_checkpoint(ints[0], ints[1]); 2415754Snate@binkert.org} 2425754Snate@binkert.org 2435754Snate@binkert.orgvoid 2445754Snate@binkert.orgdo_load_symbol(int argc, char *argv[]) 2455754Snate@binkert.org{ 2465754Snate@binkert.org if (argc != 2) 2475754Snate@binkert.org usage(); 2485754Snate@binkert.org 2495754Snate@binkert.org uint64_t addr = strtoul(argv[0], NULL, 0); 2505754Snate@binkert.org char *symbol = argv[1]; 2515754Snate@binkert.org m5_loadsymbol(addr, symbol); 2525754Snate@binkert.org} 2535754Snate@binkert.org 2545754Snate@binkert.orgvoid 2555754Snate@binkert.orgdo_initparam(int argc, char *argv[]) 2565754Snate@binkert.org{ 25711289Sgabor.dozsa@arm.com if (argc > 1) 2585754Snate@binkert.org usage(); 2595754Snate@binkert.org 26011289Sgabor.dozsa@arm.com uint64_t key_str[2]; 26111289Sgabor.dozsa@arm.com parse_str_args_to_regs(argc, argv, key_str, 2); 26211289Sgabor.dozsa@arm.com uint64_t val = m5_initparam(key_str[0], key_str[1]); 2638659SAli.Saidi@ARM.com printf("%"PRIu64, val); 2645754Snate@binkert.org} 2655754Snate@binkert.org 2665754Snate@binkert.orgvoid 2675754Snate@binkert.orgdo_sw99param(int argc, char *argv[]) 2685754Snate@binkert.org{ 2695754Snate@binkert.org if (argc != 0) 2705754Snate@binkert.org usage(); 2715754Snate@binkert.org 27211289Sgabor.dozsa@arm.com uint64_t param = m5_initparam(0, 0); 2735754Snate@binkert.org 2745754Snate@binkert.org // run-time, rampup-time, rampdown-time, warmup-time, connections 2759191SAli.Saidi@ARM.com printf("%"PRId64" %"PRId64" %"PRId64" %"PRId64" %"PRId64, 2769191SAli.Saidi@ARM.com (param >> 48) & 0xfff, 2775754Snate@binkert.org (param >> 36) & 0xfff, (param >> 24) & 0xfff, 2785754Snate@binkert.org (param >> 12) & 0xfff, (param >> 0) & 0xfff); 2795754Snate@binkert.org} 2805754Snate@binkert.org 2815755Snate@binkert.org#ifdef linux 2825755Snate@binkert.orgvoid 2835755Snate@binkert.orgdo_pin(int argc, char *argv[]) 2845755Snate@binkert.org{ 2855755Snate@binkert.org if (argc < 2) 2865755Snate@binkert.org usage(); 2875755Snate@binkert.org 2885755Snate@binkert.org cpu_set_t mask; 2895755Snate@binkert.org CPU_ZERO(&mask); 2905755Snate@binkert.org 2915755Snate@binkert.org const char *sep = ","; 2925755Snate@binkert.org char *target = strtok(argv[0], sep); 2935755Snate@binkert.org while (target) { 2945755Snate@binkert.org CPU_SET(atoi(target), &mask); 2955755Snate@binkert.org target = strtok(NULL, sep); 2965755Snate@binkert.org } 2975755Snate@binkert.org 2985755Snate@binkert.org if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) < 0) 2995755Snate@binkert.org err(1, "setaffinity"); 3005755Snate@binkert.org 3015755Snate@binkert.org execvp(argv[1], &argv[1]); 3025755Snate@binkert.org err(1, "execvp failed!"); 3035755Snate@binkert.org} 3045755Snate@binkert.org#endif 3055755Snate@binkert.org 3065754Snate@binkert.orgstruct MainFunc 3075754Snate@binkert.org{ 3085754Snate@binkert.org char *name; 3095754Snate@binkert.org void (*func)(int argc, char *argv[]); 3105754Snate@binkert.org char *usage; 3115754Snate@binkert.org}; 3125754Snate@binkert.org 3135754Snate@binkert.orgstruct MainFunc mainfuncs[] = { 3145754Snate@binkert.org { "exit", do_exit, "[delay]" }, 3159457Svilanova@ac.upc.edu { "fail", do_fail, "<code> [delay]" }, 3165754Snate@binkert.org { "resetstats", do_reset_stats, "[delay [period]]" }, 3175754Snate@binkert.org { "dumpstats", do_dump_stats, "[delay [period]]" }, 3185754Snate@binkert.org { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" }, 3198734Sdam.sunwoo@arm.com { "readfile", do_read_file, "" }, 3208734Sdam.sunwoo@arm.com { "writefile", do_write_file, "<filename>" }, 3218734Sdam.sunwoo@arm.com { "execfile", do_exec_file, "" }, 3225754Snate@binkert.org { "checkpoint", do_checkpoint, "[delay [period]]" }, 3235754Snate@binkert.org { "loadsymbol", do_load_symbol, "<address> <symbol>" }, 32411289Sgabor.dozsa@arm.com { "initparam", do_initparam, "[key] // key must be shorter than 16 chars" }, 3255754Snate@binkert.org { "sw99param", do_sw99param, "" }, 3265755Snate@binkert.org#ifdef linux 3275755Snate@binkert.org { "pin", do_pin, "<cpu> <program> [args ...]" } 3285755Snate@binkert.org#endif 3295754Snate@binkert.org}; 3305754Snate@binkert.orgint numfuncs = sizeof(mainfuncs) / sizeof(mainfuncs[0]); 331275Sbinkertn@umich.edu 332275Sbinkertn@umich.eduvoid 333275Sbinkertn@umich.eduusage() 334275Sbinkertn@umich.edu{ 3355754Snate@binkert.org int i; 3365754Snate@binkert.org 3375754Snate@binkert.org for (i = 0; i < numfuncs; ++i) { 3385754Snate@binkert.org char *header = i ? "" : "usage:"; 3395754Snate@binkert.org fprintf(stderr, "%-6s %s %s %s\n", 3405754Snate@binkert.org header, progname, mainfuncs[i].name, mainfuncs[i].usage); 3415754Snate@binkert.org } 3425754Snate@binkert.org fprintf(stderr, "\n"); 3435754Snate@binkert.org fprintf(stderr, "All times in nanoseconds!\n"); 3445754Snate@binkert.org 345275Sbinkertn@umich.edu exit(1); 346275Sbinkertn@umich.edu} 347275Sbinkertn@umich.edu 3489898Sandreas@sandberg.pp.sestatic void 3499898Sandreas@sandberg.pp.semap_m5_mem() 3509898Sandreas@sandberg.pp.se{ 3519898Sandreas@sandberg.pp.se#ifdef M5OP_ADDR 3529898Sandreas@sandberg.pp.se int fd; 3539898Sandreas@sandberg.pp.se 3549898Sandreas@sandberg.pp.se fd = open("/dev/mem", O_RDWR | O_SYNC); 3559898Sandreas@sandberg.pp.se if (fd == -1) { 3569898Sandreas@sandberg.pp.se perror("Can't open /dev/mem"); 3579898Sandreas@sandberg.pp.se exit(1); 3589898Sandreas@sandberg.pp.se } 3599898Sandreas@sandberg.pp.se 3609898Sandreas@sandberg.pp.se m5_mem = mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, M5OP_ADDR); 3619898Sandreas@sandberg.pp.se if (!m5_mem) { 3629898Sandreas@sandberg.pp.se perror("Can't mmap /dev/mem"); 3639898Sandreas@sandberg.pp.se exit(1); 3649898Sandreas@sandberg.pp.se } 3659898Sandreas@sandberg.pp.se#endif 3669898Sandreas@sandberg.pp.se} 3679898Sandreas@sandberg.pp.se 368275Sbinkertn@umich.eduint 369275Sbinkertn@umich.edumain(int argc, char *argv[]) 370275Sbinkertn@umich.edu{ 371275Sbinkertn@umich.edu progname = argv[0]; 372275Sbinkertn@umich.edu if (argc < 2) 3735754Snate@binkert.org usage(1); 374275Sbinkertn@umich.edu 3759898Sandreas@sandberg.pp.se map_m5_mem(); 3769898Sandreas@sandberg.pp.se 377287Sbinkertn@umich.edu command = argv[1]; 378287Sbinkertn@umich.edu 3795754Snate@binkert.org argv += 2; 3805754Snate@binkert.org argc -= 2; 381287Sbinkertn@umich.edu 3825754Snate@binkert.org int i; 3835754Snate@binkert.org for (i = 0; i < numfuncs; ++i) { 3845754Snate@binkert.org if (strcmp(command, mainfuncs[i].name) != 0) 3855754Snate@binkert.org continue; 3865754Snate@binkert.org 3875754Snate@binkert.org mainfuncs[i].func(argc, argv); 3885754Snate@binkert.org exit(0); 389287Sbinkertn@umich.edu } 390287Sbinkertn@umich.edu 3915754Snate@binkert.org usage(1); 392275Sbinkertn@umich.edu} 393