diff -r 64f72f39823f -r 635fcea8621c src/arch/arm/isa/formats/m5ops.isa --- a/src/arch/arm/isa/formats/m5ops.isa Mon Jan 09 19:27:27 2012 -0600 +++ b/src/arch/arm/isa/formats/m5ops.isa Mon Jan 09 19:27:30 2012 -0600 @@ -64,6 +64,7 @@ case 0x42: return new Dumpresetstats(machInst); case 0x43: return new M5checkpoint(machInst); #if FULL_SYSTEM + case 0x4F: return new M5writefile(machInst); case 0x50: return new M5readfile(machInst); #endif case 0x51: return new M5break(machInst); diff -r 64f72f39823f -r 635fcea8621c src/arch/arm/isa/insts/m5ops.isa --- a/src/arch/arm/isa/insts/m5ops.isa Mon Jan 09 19:27:27 2012 -0600 +++ b/src/arch/arm/isa/insts/m5ops.isa Mon Jan 09 19:27:30 2012 -0600 @@ -265,6 +265,24 @@ decoder_output += BasicConstructor.subst(m5readfileIop) exec_output += PredOpExecute.subst(m5readfileIop) + m5writefileCode = ''' +#if FULL_SYSTEM + int n = 4; + uint64_t offset = getArgument(xc->tcBase(), n, sizeof(uint64_t), false); + n = 6; + Addr filenameAddr = getArgument(xc->tcBase(), n, sizeof(Addr), false); + R0 = PseudoInst::writefile(xc->tcBase(), R0, join32to64(R3,R2), offset, + filenameAddr); +#endif + ''' + m5writefileIop = InstObjParams("m5writefile", "M5writefile", "PredOp", + { "code": m5writefileCode, + "predicate_test": predicateTest }, + ["IsNonSpeculative"]) + header_output += BasicDeclare.subst(m5writefileIop) + decoder_output += BasicConstructor.subst(m5writefileIop) + exec_output += PredOpExecute.subst(m5writefileIop) + m5breakIop = InstObjParams("m5break", "M5break", "PredOp", { "code": "PseudoInst::debugbreak(xc->tcBase());", "predicate_test": predicateTest }, diff -r 64f72f39823f -r 635fcea8621c src/base/output.hh --- a/src/base/output.hh Mon Jan 09 19:27:27 2012 -0600 +++ b/src/base/output.hh Mon Jan 09 19:27:30 2012 -0600 @@ -73,6 +73,13 @@ */ std::ostream *checkForStdio(const std::string &name) const; + public: + /** Constructor. */ + OutputDirectory(); + + /** Destructor. */ + ~OutputDirectory(); + /** Opens a file (optionally compressed). * * Will open a file as a compressed stream if filename ends in .gz. @@ -84,13 +91,6 @@ std::ostream *openFile(const std::string &filename, std::ios_base::openmode mode = std::ios::trunc); - public: - /** Constructor. */ - OutputDirectory(); - - /** Destructor. */ - ~OutputDirectory(); - /** * Sets name of this directory. * @param dir name of this directory diff -r 64f72f39823f -r 635fcea8621c src/sim/pseudo_inst.hh --- a/src/sim/pseudo_inst.hh Mon Jan 09 19:27:27 2012 -0600 +++ b/src/sim/pseudo_inst.hh Mon Jan 09 19:27:30 2012 -0600 @@ -55,6 +55,8 @@ uint64_t quiesceTime(ThreadContext *tc); uint64_t readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset); +uint64_t writefile(ThreadContext *tc, Addr vaddr, uint64_t len, + uint64_t offset, Addr filenameAddr); void loadsymbol(ThreadContext *xc); void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr); uint64_t initParam(ThreadContext *xc); diff -r 64f72f39823f -r 635fcea8621c src/sim/pseudo_inst.cc --- a/src/sim/pseudo_inst.cc Mon Jan 09 19:27:27 2012 -0600 +++ b/src/sim/pseudo_inst.cc Mon Jan 09 19:27:30 2012 -0600 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 ARM Limited + * Copyright (c) 2010-2011 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -50,6 +50,7 @@ #include "arch/vtophys.hh" #include "base/debug.hh" +#include "base/output.hh" #include "config/full_system.hh" #include "config/the_isa.hh" #include "cpu/base.hh" @@ -358,6 +359,46 @@ return result; } +uint64_t +writefile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset, + Addr filename_addr) +{ + ostream *os; + + // copy out target filename + char fn[100]; + std::string filename; + CopyStringOut(tc, fn, filename_addr, 100); + filename = std::string(fn); + + if (offset == 0) { + // create a new file (truncate) + os = simout.create(filename, true); + } else { + // do not truncate file if offset is non-zero + os = simout.openFile(simout.directory() + filename, + ios::out | ios::binary); + } + if (!os) + panic("could not open file %s\n", filename); + + // seek to offset + os->seekp(offset); + + // copy out data and write to file + char *buf = new char[len]; + CopyOut(tc, buf, vaddr, len); + os->write(buf, len); + if (os->fail() || os->bad()) + panic("Error while doing writefile!\n"); + + simout.close(os); + + delete [] buf; + + return len; +} + #endif void diff -r 64f72f39823f -r 635fcea8621c util/m5/m5.c --- a/util/m5/m5.c Mon Jan 09 19:27:27 2012 -0600 +++ b/util/m5/m5.c Mon Jan 09 19:27:30 2012 -0600 @@ -88,6 +88,33 @@ } } +int +write_file(const char *filename) +{ + fprintf(stderr, "opening %s\n", filename); + int src_fid = open(filename, O_RDONLY); + + if (src_fid < 0) { + fprintf(stderr, "error opening %s\n", filename); + return; + } + + char buf[256*1024]; + int offset = 0; + int len; + int bytes = 0; + + memset(buf, 0, sizeof(buf)); + + while ((len = read(src_fid, buf, sizeof(buf))) > 0) { + bytes += m5_writefile(buf, len, offset, filename); + offset += len; + } + fprintf(stderr, "written %d bytes\n", bytes); + + close(src_fid); +} + void do_exit(int argc, char *argv[]) { @@ -131,6 +158,17 @@ } void +do_write_file(int argc, char *argv[]) +{ + if (argc != 1) + usage(); + + const char *filename = argv[0]; + + write_file(filename); +} + +void do_exec_file(int argc, char *argv[]) { if (argc > 0) @@ -227,8 +265,9 @@ { "resetstats", do_reset_stats, "[delay [period]]" }, { "dumpstats", do_dump_stats, "[delay [period]]" }, { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" }, - { "readfile", do_read_file, "[filename]" }, - { "execfile", do_exec_file, "" }, + { "readfile", do_read_file, "" }, + { "writefile", do_write_file, "" }, + { "execfile", do_exec_file, "" }, { "checkpoint", do_checkpoint, "[delay [period]]" }, { "loadsymbol", do_load_symbol, "
" }, { "initparam", do_initparam, "" }, diff -r 64f72f39823f -r 635fcea8621c util/m5/m5op.h --- a/util/m5/m5op.h Mon Jan 09 19:27:27 2012 -0600 +++ b/util/m5/m5op.h Mon Jan 09 19:27:30 2012 -0600 @@ -49,6 +49,7 @@ void m5_dump_stats(uint64_t ns_delay, uint64_t ns_period); void m5_dumpreset_stats(uint64_t ns_delay, uint64_t ns_period); uint64_t m5_readfile(void *buffer, uint64_t len, uint64_t offset); +uint64_t m5_writefile(void *buffer, uint64_t len, uint64_t offset, const char *filename); void m5_debugbreak(void); void m5_switchcpu(void); void m5_addsymbol(uint64_t addr, char *symbol); diff -r 64f72f39823f -r 635fcea8621c util/m5/m5op_arm.S --- a/util/m5/m5op_arm.S Mon Jan 09 19:27:27 2012 -0600 +++ b/util/m5/m5op_arm.S Mon Jan 09 19:27:30 2012 -0600 @@ -80,6 +80,7 @@ #define DUMPRST_STATS INST(m5_op, 0, 0, dumprststats_func) #define CHECKPOINT INST(m5_op, 0, 0, ckpt_func) #define READFILE INST(m5_op, 0, 0, readfile_func) +#define WRITEFILE INST(m5_op, 0, 0, writefile_func) #define DEBUGBREAK INST(m5_op, 0, 0, debugbreak_func) #define SWITCHCPU INST(m5_op, 0, 0, switchcpu_func) #define ADDSYMBOL INST(m5_op, 0, 0, addsymbol_func) @@ -121,6 +122,7 @@ SIMPLE_OP(m5_dumpreset_stats, DUMPRST_STATS) SIMPLE_OP(m5_checkpoint, CHECKPOINT) SIMPLE_OP(m5_readfile, READFILE) +SIMPLE_OP(m5_writefile, WRITEFILE) SIMPLE_OP(m5_debugbreak, DEBUGBREAK) SIMPLE_OP(m5_switchcpu, SWITCHCPU) SIMPLE_OP(m5_addsymbol, ADDSYMBOL) diff -r 64f72f39823f -r 635fcea8621c util/m5/m5ops.h --- a/util/m5/m5ops.h Mon Jan 09 19:27:27 2012 -0600 +++ b/util/m5/m5ops.h Mon Jan 09 19:27:30 2012 -0600 @@ -46,6 +46,7 @@ #define dumpstats_func 0x41 #define dumprststats_func 0x42 #define ckpt_func 0x43 +#define writefile_func 0x4F #define readfile_func 0x50 #define debugbreak_func 0x51 #define switchcpu_func 0x52