54 #include "arch/kernel_stats.hh"
55 #include "arch/pseudo_inst.hh"
56 #include "arch/utility.hh"
57 #include "arch/vtophys.hh"
60 #include "config/the_isa.hh"
64 #include "debug/Loader.hh"
65 #include "debug/PseudoInst.hh"
66 #include "debug/Quiesce.hh"
67 #include "debug/WorkItems.hh"
69 #include "params/BaseCPU.hh"
83 using namespace Stats;
84 using namespace TheISA;
86 namespace PseudoInst {
91 panic(
"Pseudo inst \"%s\" is only available in Full System mode.");
99 DPRINTF(PseudoInst,
"PseudoInst::pseudoInst(%i, %i)\n", func, subfunc);
106 for (
int i = 0;
i <
sizeof(args) /
sizeof(*args); ++
i) {
107 args[arg_num] =
getArgument(tc, arg_num,
sizeof(uint64_t),
false);
143 m5fail(tc, args[0], args[1]);
170 return writefile(tc, args[0], args[1], args[2], args[3]);
173 return readfile(tc, args[0], args[1], args[2]);
188 panic(
"M5 panic instruction called at %s\n", tc->
pcState());
203 warn(
"Unimplemented m5 op (0x%x)\n", func);
221 warn(
"Unhandled m5 op: 0x%x\n", func);
231 DPRINTF(PseudoInst,
"PseudoInst::arm()\n");
242 DPRINTF(PseudoInst,
"PseudoInst::quiesce()\n");
249 DPRINTF(PseudoInst,
"PseudoInst::quiesceSkip()\n");
256 DPRINTF(PseudoInst,
"PseudoInst::quiesceNs(%i)\n", ns);
263 DPRINTF(PseudoInst,
"PseudoInst::quiesceCycles(%i)\n", cycles);
270 DPRINTF(PseudoInst,
"PseudoInst::quiesceTime()\n");
279 DPRINTF(PseudoInst,
"PseudoInst::rpns()\n");
286 DPRINTF(PseudoInst,
"PseudoInst::wakeCPU(%i)\n", cpuid);
296 DPRINTF(PseudoInst,
"PseudoInst::m5exit(%i)\n", delay);
299 exitSimLoop(
"m5_exit instruction encountered", 0, when, 0,
true);
306 DPRINTF(PseudoInst,
"PseudoInst::m5fail(%i, %i)\n", delay, code);
308 exitSimLoop(
"m5_fail instruction encountered", code, when, 0,
true);
314 DPRINTF(PseudoInst,
"PseudoInst::loadsymbol()\n");
318 const string &filename = tc->
getCpuPtr()->system->params()->symbolfile;
319 if (filename.empty()) {
324 ifstream file(filename.c_str());
327 fatal(
"file error: Can't open symbol table file %s\n", filename);
329 while (!file.eof()) {
330 getline(file, buffer);
336 if (idx == string::npos)
339 string address =
"0x" + buffer.substr(0, idx);
345 string symbol = buffer.substr(idx + 3);
358 DPRINTF(Loader,
"Loaded symbol: %s @ %#llx\n", symbol, addr);
366 DPRINTF(PseudoInst,
"PseudoInst::addsymbol(0x%x, 0x%x)\n",
373 std::string symbol(symb);
375 DPRINTF(Loader,
"Loaded symbol: %s @ %#llx\n", symbol, addr);
384 DPRINTF(PseudoInst,
"PseudoInst::initParam() key:%s%s\n", (
char *)&key_str1,
394 const int len = 2 *
sizeof(uint64_t) + 1;
396 memset(key_str,
'\0', len);
398 assert(key_str2 == 0);
400 strncpy(key_str, (
char *)&key_str1,
sizeof(uint64_t));
403 if (strlen(key_str) ==
sizeof(uint64_t)) {
404 strncpy(key_str +
sizeof(uint64_t), (
char *)&key_str2,
407 assert(key_str2 == 0);
413 if (strcmp(key_str, InitParamKey::DEFAULT) == 0) {
414 val = tc->
getCpuPtr()->system->init_param;
415 }
else if (strcmp(key_str, InitParamKey::DIST_RANK) == 0) {
417 }
else if (strcmp(key_str, InitParamKey::DIST_SIZE) == 0) {
420 panic(
"Unknown key for initparam pseudo instruction:\"%s\"", key_str);
429 DPRINTF(PseudoInst,
"PseudoInst::resetstats(%i, %i)\n", delay, period);
430 if (!tc->
getCpuPtr()->params()->do_statistics_insts)
443 DPRINTF(PseudoInst,
"PseudoInst::dumpstats(%i, %i)\n", delay, period);
444 if (!tc->
getCpuPtr()->params()->do_statistics_insts)
457 DPRINTF(PseudoInst,
"PseudoInst::dumpresetstats(%i, %i)\n", delay, period);
458 if (!tc->
getCpuPtr()->params()->do_statistics_insts)
471 DPRINTF(PseudoInst,
"PseudoInst::m5checkpoint(%i, %i)\n", delay, period);
472 if (!tc->
getCpuPtr()->params()->do_checkpoint_insts)
485 DPRINTF(PseudoInst,
"PseudoInst::readfile(0x%x, 0x%x, 0x%x)\n",
499 int fd = ::open(file.c_str(), O_RDONLY, 0);
501 panic(
"could not open file %s\n", file);
503 if (::lseek(fd, offset, SEEK_SET) < 0)
504 panic(
"could not seek: %s", strerror(errno));
506 char *buf =
new char[
len];
509 int bytes = ::read(fd, p, len);
519 CopyIn(tc, vaddr, buf, result);
528 DPRINTF(PseudoInst,
"PseudoInst::writefile(0x%x, 0x%x, 0x%x, 0x%x)\n",
529 vaddr, len, offset, filename_addr);
533 std::string filename;
535 filename = std::string(fn);
545 out =
simout.
open(filename, ios::in | ios::out | ios::binary,
true);
550 panic(
"could not open file %s\n", filename);
556 char *buf =
new char[
len];
559 if (
os->fail() ||
os->bad())
560 panic(
"Error while doing writefile!\n");
572 DPRINTF(PseudoInst,
"PseudoInst::debugbreak()\n");
579 DPRINTF(PseudoInst,
"PseudoInst::switchcpu()\n");
586 DPRINTF(PseudoInst,
"PseudoInst::togglesync()\n");
598 DPRINTF(PseudoInst,
"PseudoInst::workbegin(%i, %i)\n", workid, threadid);
602 if (params->exit_on_work_items) {
603 exitSimLoop(
"workbegin", static_cast<int>(workid));
607 DPRINTF(WorkItems,
"Work Begin workid: %d, threadid %d\n", workid,
616 if (params->work_item_id == -1 || params->work_item_id == workid) {
621 if (params->work_cpus_ckpt_count != 0 &&
622 sys->
markWorkItem(cpuId) >= params->work_cpus_ckpt_count) {
629 if (systemWorkBeginCount == params->work_begin_ckpt_count) {
637 if (systemWorkBeginCount == params->work_begin_exit_count) {
644 if (cpuId == params->work_begin_cpu_id_exit) {
661 DPRINTF(PseudoInst,
"PseudoInst::workend(%i, %i)\n", workid, threadid);
665 if (params->exit_on_work_items) {
670 DPRINTF(WorkItems,
"Work End workid: %d, threadid %d\n", workid, threadid);
678 if (params->work_item_id == -1 || params->work_item_id == workid) {
683 if (params->work_cpus_ckpt_count != 0 &&
684 sys->
markWorkItem(cpuId) >= params->work_cpus_ckpt_count) {
691 if (params->work_end_ckpt_count != 0 &&
692 systemWorkEndCount == params->work_end_ckpt_count) {
700 if (params->work_end_exit_count != 0 &&
701 systemWorkEndCount == params->work_end_exit_count) {
void m5fail(ThreadContext *tc, Tick delay, uint64_t code)
std::ostream * stream() const
Get the output underlying output stream.
virtual System * getSystemPtr()=0
Cycles is a wrapper class for representing cycle counts, i.e.
void quiesceNs(ThreadContext *tc, uint64_t ns)
const std::string & name()
OutputStream * create(const std::string &name, bool binary=false, bool no_gz=false)
Creates a file in this directory (optionally compressed).
void arm(ThreadContext *tc)
const Params * params() const
void dumpresetstats(ThreadContext *tc, Tick delay, Tick period)
uint64_t incWorkItemsEnd()
Called by pseudo_inst to track the number of work items completed by this system. ...
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
uint64_t quiesceTime(ThreadContext *tc)
void quiesceSkip(ThreadContext *tc)
void m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
void workItemEnd(uint32_t tid, uint32_t workid)
uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
SymbolTable * debugSymbolTable
Global unified debugging symbol table (for target).
uint64_t writefile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset, Addr filename_addr)
virtual BaseCPU * getCpuPtr()=0
void quiesceCycles(ThreadContext *tc, uint64_t cycles)
virtual TheISA::PCState pcState()=0
void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
virtual Tick readLastSuspend()=0
static void toggleSync(ThreadContext *tc)
Trigger the master to start/stop synchronization.
ThreadContext is the external interface to all thread state for anything outside of the CPU...
void togglesync(ThreadContext *tc)
void quiesce()
Quiesce thread context.
uint64_t initParam(ThreadContext *tc, uint64_t key_str1, uint64_t key_str2)
Tick curTick()
The current simulated tick.
void quiesce(ThreadContext *tc)
static uint64_t sizeParam()
Getter for the dist size param.
void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
uint64_t Tick
Tick count type.
void switchcpu(ThreadContext *tc)
int markWorkItem(int index)
Called by pseudo_inst to mark the cpus actively executing work items.
static bool readyToCkpt(Tick delay, Tick period)
Initiate taking a checkpoint.
std::vector< ThreadContext * > threadContexts
void close(OutputStream *file)
Closes an output file and free the corresponding OutputFile.
bool insert(Addr address, std::string symbol)
static bool readyToExit(Tick delay)
Initiate the exit from the simulation.
virtual void activate()=0
Set the status to Active.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
#define ULL(N)
uint64_t constant
uint64_t pseudoInst(ThreadContext *tc, uint8_t func, uint8_t subfunc)
Execute a decoded M5 pseudo instruction.
SymbolTable * kernelSymtab
kernel symbol table
void debugbreak(ThreadContext *tc)
void m5PageFault(ThreadContext *tc)
void workbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid)
void resetstats(ThreadContext *tc, Tick delay, Tick period)
uint64_t readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
void m5Syscall(ThreadContext *tc)
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
uint64_t incWorkItemsBegin()
Called by pseudo_inst to track the number of work items started by this system.
void wakeCPU(ThreadContext *tc, uint64_t cpuid)
void workItemBegin(uint32_t tid, uint32_t workid)
void eat_white(std::string &s)
void CopyIn(ThreadContext *tc, Addr dest, const void *source, size_t cplen)
void dumpstats(ThreadContext *tc, Tick delay, Tick period)
virtual Tick readLastActivate()=0
virtual Status status() const =0
void schedStatEvent(bool dump, bool reset, Tick when, Tick repeat)
Schedule statistics dumping.
void quiesceTick(Tick resume)
Quiesce, suspend, and schedule activate at resume.
void m5exit(ThreadContext *tc, Tick delay)
static void panicFsOnlyPseudoInst(const char *name)
static uint64_t rankParam()
Getter for the dist rank param.
bool to_number(const std::string &value, Pixel &retval)
OutputStream * open(const std::string &name, std::ios_base::openmode mode, bool recreateable=true, bool no_gz=false)
Open a file in this directory (optionally compressed).
void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
void loadsymbol(ThreadContext *tc)
void workend(ThreadContext *tc, uint64_t workid, uint64_t threadid)
virtual TheISA::Kernel::Statistics * getKernelStats()=0
uint64_t rpns(ThreadContext *tc)