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