m5.c revision 8659
1/* 2 * Copyright (c) 2011 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2003-2005 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Nathan Binkert 41 */ 42 43#ifdef linux 44#define _GNU_SOURCE 45#include <sched.h> 46#endif 47 48#include <err.h> 49#include <fcntl.h> 50#include <inttypes.h> 51#include <stdio.h> 52#include <stdlib.h> 53#include <string.h> 54#include <unistd.h> 55 56#include "m5op.h" 57 58char *progname; 59char *command = "unspecified"; 60void usage(); 61 62void 63parse_int_args(int argc, char *argv[], uint64_t ints[], int len) 64{ 65 if (argc > len) 66 usage(); 67 68 int i; 69 for (i = 0; i < len; ++i) 70 ints[i] = (i < argc) ? strtoul(argv[i], NULL, 0) : 0; 71} 72 73int 74read_file(int dest_fid) 75{ 76 char buf[256*1024]; 77 int offset = 0; 78 int len; 79 80 // Touch all buffer pages to ensure they are mapped in the 81 // page table. This is required in the case of X86_FS, where 82 // Linux does demand paging. 83 memset(buf, 0, sizeof(buf)); 84 85 while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) { 86 write(dest_fid, buf, len); 87 offset += len; 88 } 89} 90 91void 92do_exit(int argc, char *argv[]) 93{ 94 if (argc > 1) 95 usage(); 96 97 m5_exit((argc > 0) ? strtoul(argv[0], NULL, 0) : 0); 98} 99 100void 101do_reset_stats(int argc, char *argv[]) 102{ 103 uint64_t ints[2]; 104 parse_int_args(argc, argv, ints, 2); 105 m5_reset_stats(ints[0], ints[1]); 106} 107 108void 109do_dump_stats(int argc, char *argv[]) 110{ 111 uint64_t ints[2]; 112 parse_int_args(argc, argv, ints, 2); 113 m5_dump_stats(ints[0], ints[1]); 114} 115 116void 117do_dump_reset_stats(int argc, char *argv[]) 118{ 119 uint64_t ints[2]; 120 parse_int_args(argc, argv, ints, 2); 121 m5_dumpreset_stats(ints[0], ints[1]); 122} 123 124void 125do_read_file(int argc, char *argv[]) 126{ 127 if (argc > 0) 128 usage(); 129 130 read_file(STDOUT_FILENO); 131} 132 133void 134do_exec_file(int argc, char *argv[]) 135{ 136 if (argc > 0) 137 usage(); 138 139 const char *destname = "/tmp/execfile"; 140 141 int fid = open(destname, O_WRONLY, 0777); 142 int len = read_file(fid); 143 close(fid); 144 if (len > 0) { 145 execl(destname, "execfile", NULL); 146 err(1, "execl failed!"); 147 } 148} 149 150void 151do_checkpoint(int argc, char *argv[]) 152{ 153 uint64_t ints[2]; 154 parse_int_args(argc, argv, ints, 2); 155 m5_checkpoint(ints[0], ints[1]); 156} 157 158void 159do_load_symbol(int argc, char *argv[]) 160{ 161 if (argc != 2) 162 usage(); 163 164 uint64_t addr = strtoul(argv[0], NULL, 0); 165 char *symbol = argv[1]; 166 m5_loadsymbol(addr, symbol); 167} 168 169void 170do_initparam(int argc, char *argv[]) 171{ 172 if (argc != 0) 173 usage(); 174 175 uint64_t val = m5_initparam(); 176 printf("%"PRIu64, val); 177} 178 179void 180do_sw99param(int argc, char *argv[]) 181{ 182 if (argc != 0) 183 usage(); 184 185 uint64_t param = m5_initparam(); 186 187 // run-time, rampup-time, rampdown-time, warmup-time, connections 188 printf("%d %d %d %d %d", (param >> 48) & 0xfff, 189 (param >> 36) & 0xfff, (param >> 24) & 0xfff, 190 (param >> 12) & 0xfff, (param >> 0) & 0xfff); 191} 192 193#ifdef linux 194void 195do_pin(int argc, char *argv[]) 196{ 197 if (argc < 2) 198 usage(); 199 200 cpu_set_t mask; 201 CPU_ZERO(&mask); 202 203 const char *sep = ","; 204 char *target = strtok(argv[0], sep); 205 while (target) { 206 CPU_SET(atoi(target), &mask); 207 target = strtok(NULL, sep); 208 } 209 210 if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) < 0) 211 err(1, "setaffinity"); 212 213 execvp(argv[1], &argv[1]); 214 err(1, "execvp failed!"); 215} 216#endif 217 218struct MainFunc 219{ 220 char *name; 221 void (*func)(int argc, char *argv[]); 222 char *usage; 223}; 224 225struct MainFunc mainfuncs[] = { 226 { "exit", do_exit, "[delay]" }, 227 { "resetstats", do_reset_stats, "[delay [period]]" }, 228 { "dumpstats", do_dump_stats, "[delay [period]]" }, 229 { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" }, 230 { "readfile", do_read_file, "[filename]" }, 231 { "execfile", do_exec_file, "<filename>" }, 232 { "checkpoint", do_checkpoint, "[delay [period]]" }, 233 { "loadsymbol", do_load_symbol, "<address> <symbol>" }, 234 { "initparam", do_initparam, "" }, 235 { "sw99param", do_sw99param, "" }, 236#ifdef linux 237 { "pin", do_pin, "<cpu> <program> [args ...]" } 238#endif 239}; 240int numfuncs = sizeof(mainfuncs) / sizeof(mainfuncs[0]); 241 242void 243usage() 244{ 245 int i; 246 247 for (i = 0; i < numfuncs; ++i) { 248 char *header = i ? "" : "usage:"; 249 fprintf(stderr, "%-6s %s %s %s\n", 250 header, progname, mainfuncs[i].name, mainfuncs[i].usage); 251 } 252 fprintf(stderr, "\n"); 253 fprintf(stderr, "All times in nanoseconds!\n"); 254 255 exit(1); 256} 257 258int 259main(int argc, char *argv[]) 260{ 261 progname = argv[0]; 262 if (argc < 2) 263 usage(1); 264 265 command = argv[1]; 266 267 argv += 2; 268 argc -= 2; 269 270 int i; 271 for (i = 0; i < numfuncs; ++i) { 272 if (strcmp(command, mainfuncs[i].name) != 0) 273 continue; 274 275 mainfuncs[i].func(argc, argv); 276 exit(0); 277 } 278 279 usage(1); 280} 281