/*
- * Copyright (c) 2010-2012 ARM Limited
+ * Copyright (c) 2010-2012, 2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
#include "arch/kernel_stats.hh"
#include "arch/utility.hh"
#include "arch/vtophys.hh"
+#include "arch/pseudo_inst.hh"
#include "base/debug.hh"
#include "base/output.hh"
#include "config/the_isa.hh"
#include "debug/PseudoInst.hh"
#include "debug/Quiesce.hh"
#include "debug/WorkItems.hh"
+#include "dev/net/dist_iface.hh"
#include "params/BaseCPU.hh"
#include "sim/full_system.hh"
+#include "sim/initparam_keys.hh"
+#include "sim/process.hh"
#include "sim/pseudo_inst.hh"
#include "sim/serialize.hh"
#include "sim/sim_events.hh"
break;
case 0x30: // initparam_func
- return initParam(tc);
+ return initParam(tc, args[0], args[1]);
case 0x31: // loadsymbol_func
loadsymbol(tc);
warn("Unimplemented m5 op (0x%x)\n", func);
break;
+ /* SE mode functions */
+ case 0x60: // syscall_func
+ m5Syscall(tc);
+ break;
+
+ case 0x61: // pagefault_func
+ m5PageFault(tc);
+ break;
+
default:
warn("Unhandled m5 op: 0x%x\n", func);
break;
BaseCPU *cpu = tc->getCpuPtr();
- if (!cpu->params()->do_quiesce || ns == 0)
+ if (!cpu->params()->do_quiesce)
return;
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
BaseCPU *cpu = tc->getCpuPtr();
- if (!cpu->params()->do_quiesce || cycles == 0)
+ if (!cpu->params()->do_quiesce)
return;
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
m5exit(ThreadContext *tc, Tick delay)
{
DPRINTF(PseudoInst, "PseudoInst::m5exit(%i)\n", delay);
- Tick when = curTick() + delay * SimClock::Int::ns;
- exitSimLoop("m5_exit instruction encountered", 0, when);
+ if (DistIface::readyToExit(delay)) {
+ Tick when = curTick() + delay * SimClock::Int::ns;
+ exitSimLoop("m5_exit instruction encountered", 0, when, 0, true);
+ }
}
void
{
DPRINTF(PseudoInst, "PseudoInst::m5fail(%i, %i)\n", delay, code);
Tick when = curTick() + delay * SimClock::Int::ns;
- exitSimLoop("m5_fail instruction encountered", code, when);
+ exitSimLoop("m5_fail instruction encountered", code, when, 0, true);
}
void
}
uint64_t
-initParam(ThreadContext *tc)
+initParam(ThreadContext *tc, uint64_t key_str1, uint64_t key_str2)
{
- DPRINTF(PseudoInst, "PseudoInst::initParam()\n");
+ DPRINTF(PseudoInst, "PseudoInst::initParam() key:%s%s\n", (char *)&key_str1,
+ (char *)&key_str2);
if (!FullSystem) {
panicFsOnlyPseudoInst("initParam");
return 0;
}
- return tc->getCpuPtr()->system->init_param;
+ // The key parameter string is passed in via two 64-bit registers. We copy
+ // out the characters from the 64-bit integer variables here and concatenate
+ // them in the key_str character buffer
+ const int len = 2 * sizeof(uint64_t) + 1;
+ char key_str[len];
+ memset(key_str, '\0', len);
+ if (key_str1 == 0) {
+ assert(key_str2 == 0);
+ } else {
+ strncpy(key_str, (char *)&key_str1, sizeof(uint64_t));
+ }
+
+ if (strlen(key_str) == sizeof(uint64_t)) {
+ strncpy(key_str + sizeof(uint64_t), (char *)&key_str2,
+ sizeof(uint64_t));
+ } else {
+ assert(key_str2 == 0);
+ }
+
+ // Compare the key parameter with the known values to select the return
+ // value
+ uint64_t val;
+ if (strcmp(key_str, InitParamKey::DEFAULT) == 0) {
+ val = tc->getCpuPtr()->system->init_param;
+ } else if (strcmp(key_str, InitParamKey::DIST_RANK) == 0) {
+ val = DistIface::rankParam();
+ } else if (strcmp(key_str, InitParamKey::DIST_SIZE) == 0) {
+ val = DistIface::sizeParam();
+ } else {
+ panic("Unknown key for initparam pseudo instruction:\"%s\"", key_str);
+ }
+ return val;
}
if (!tc->getCpuPtr()->params()->do_checkpoint_insts)
return;
- Tick when = curTick() + delay * SimClock::Int::ns;
- Tick repeat = period * SimClock::Int::ns;
-
- exitSimLoop("checkpoint", 0, when, repeat);
+ if (DistIface::readyToCkpt(delay, period)) {
+ Tick when = curTick() + delay * SimClock::Int::ns;
+ Tick repeat = period * SimClock::Int::ns;
+ exitSimLoop("checkpoint", 0, when, repeat);
+ }
}
uint64_t
if (offset == 0) {
// create a new file (truncate)
- os = simout.create(filename, true);
+ os = simout.create(filename, true, true);
} else {
// do not truncate file if offset is non-zero
// (ios::in flag is required as well to keep the existing data
// intact, otherwise existing data will be zeroed out.)
os = simout.openFile(simout.directory() + filename,
- ios::in | ios::out | ios::binary);
+ ios::in | ios::out | ios::binary, true);
}
if (!os)
panic("could not open file %s\n", filename);
workbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid)
{
DPRINTF(PseudoInst, "PseudoInst::workbegin(%i, %i)\n", workid, threadid);
- tc->getCpuPtr()->workItemBegin();
System *sys = tc->getSystemPtr();
const System::Params *params = sys->params();
- sys->workItemBegin(threadid, workid);
- DPRINTF(WorkItems, "Work Begin workid: %d, threadid %d\n", workid,
+ if (params->exit_on_work_items) {
+ exitSimLoop("workbegin", static_cast<int>(workid));
+ return;
+ }
+
+ DPRINTF(WorkItems, "Work Begin workid: %d, threadid %d\n", workid,
threadid);
+ tc->getCpuPtr()->workItemBegin();
+ sys->workItemBegin(threadid, workid);
//
// If specified, determine if this is the specific work item the user
workend(ThreadContext *tc, uint64_t workid, uint64_t threadid)
{
DPRINTF(PseudoInst, "PseudoInst::workend(%i, %i)\n", workid, threadid);
- tc->getCpuPtr()->workItemEnd();
System *sys = tc->getSystemPtr();
const System::Params *params = sys->params();
- sys->workItemEnd(threadid, workid);
+
+ if (params->exit_on_work_items) {
+ exitSimLoop("workend", static_cast<int>(workid));
+ return;
+ }
DPRINTF(WorkItems, "Work End workid: %d, threadid %d\n", workid, threadid);
+ tc->getCpuPtr()->workItemEnd();
+ sys->workItemEnd(threadid, workid);
//
// If specified, determine if this is the specific work item the user