diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc index 94f5d9bc3..fa24e5215 100644 --- a/arch/alpha/isa_desc +++ b/arch/alpha/isa_desc @@ -2540,6 +2540,9 @@ decode OPCODE default Unknown::unknown() { 0x43: m5checkpoint({{ AlphaPseudo::m5checkpoint(xc->xcBase()); }}, IsNonSpeculative); + 0x50: m5readfile({{ + AlphaPseudo::readfile(xc->xcBase()); + }}, IsNonSpeculative); } } diff --git a/arch/alpha/pseudo_inst.cc b/arch/alpha/pseudo_inst.cc index f4201ab09..e23dc8baa 100644 --- a/arch/alpha/pseudo_inst.cc +++ b/arch/alpha/pseudo_inst.cc @@ -26,15 +26,20 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include #include "arch/alpha/pseudo_inst.hh" +#include "arch/alpha/vtophys.hh" +#include "cpu/base_cpu.hh" #include "cpu/exec_context.hh" #include "sim/param.hh" #include "sim/serialize.hh" #include "sim/sim_exit.hh" #include "sim/stat_control.hh" #include "sim/stats.hh" +#include "sim/system.hh" using namespace std; using namespace Stats; @@ -149,6 +154,43 @@ namespace AlphaPseudo Checkpoint::setup(when, repeat); } + void + readfile(ExecContext *xc) + { + const string &file = xc->cpu->system->readfile; + if (file.empty()) { + xc->regs.intRegFile[0] = ULL(0); + return; + } + + Addr vaddr = xc->regs.intRegFile[16]; + uint64_t len = xc->regs.intRegFile[17]; + uint64_t offset = xc->regs.intRegFile[18]; + uint64_t result = 0; + + int fd = ::open(file.c_str(), O_RDONLY, 0); + if (fd < 0) + panic("could not open file %s\n", file); + + char *buf = new char[len]; + char *p = buf; + while (len > 0) { + int bytes = ::pread(fd, p, len, offset); + if (bytes <= 0) + break; + + p += bytes; + offset += bytes; + result += bytes; + len -= bytes; + } + + close(fd); + CopyIn(xc, vaddr, buf, result); + delete [] buf; + xc->regs.intRegFile[0] = result; + } + class Context : public ParamContext { public: diff --git a/arch/alpha/pseudo_inst.hh b/arch/alpha/pseudo_inst.hh index e59487397..22e5d43ae 100644 --- a/arch/alpha/pseudo_inst.hh +++ b/arch/alpha/pseudo_inst.hh @@ -47,4 +47,5 @@ namespace AlphaPseudo void dumpstats(ExecContext *xc); void dumpresetstats(ExecContext *xc); void m5checkpoint(ExecContext *xc); + void readfile(ExecContext *xc); } diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index 6d7324688..e4405b2e5 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -324,6 +324,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) Param boot_osflags; VectorParam binned_fns; + Param readfile; + END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem) @@ -338,7 +340,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem) INIT_PARAM(pal_code, "file that contains palcode"), INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", "a"), - INIT_PARAM(binned_fns, "functions to be broken down and binned") + INIT_PARAM(binned_fns, "functions to be broken down and binned"), + INIT_PARAM_DFLT(readfile, "file to read startup script from", "") END_INIT_SIM_OBJECT_PARAMS(LinuxSystem) @@ -349,6 +352,7 @@ CREATE_SIM_OBJECT(LinuxSystem) physmem, kernel_code, console_code, pal_code, boot_osflags, bin, binned_fns); + sys->readfile = readfile; return sys; } diff --git a/sim/system.hh b/sim/system.hh index baf82a5b5..da974cfdd 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -96,6 +96,8 @@ class System : public SimObject std::vector execContexts; + std::string readfile; + virtual int registerExecContext(ExecContext *xc); virtual void replaceExecContext(int xcIndex, ExecContext *xc);