X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=riscv%2Finteractive.cc;h=dbcd22455d5fe6fdb75388946df176d7227ca6df;hb=a91d9f7d89abd6cda6fafb7b5e7cacf4b3590c29;hp=6117d01cb02cbc1308ca04c5d689b1e8012dc467;hpb=a68c33c2a4c6278e7cce58f8a668cb24f636d024;p=riscv-isa-sim.git diff --git a/riscv/interactive.cc b/riscv/interactive.cc index 6117d01..dbcd224 100644 --- a/riscv/interactive.cc +++ b/riscv/interactive.cc @@ -1,7 +1,9 @@ // See LICENSE for license details. +#include "decode.h" +#include "disasm.h" #include "sim.h" -#include "htif.h" +#include "mmu.h" #include #include #include @@ -14,6 +16,19 @@ #include #include #include +#include +#include + +DECLARE_TRAP(-1, interactive) + +processor_t *sim_t::get_core(const std::string& i) +{ + char *ptr; + unsigned long p = strtoul(i.c_str(), &ptr, 10); + if (*ptr || p >= procs.size()) + throw trap_interactive(); + return get_core(p); +} static std::string readline(int fd) { @@ -45,7 +60,27 @@ static std::string readline(int fd) void sim_t::interactive() { - while (true) + typedef void (sim_t::*interactive_func)(const std::string&, const std::vector&); + std::map funcs; + + funcs["run"] = &sim_t::interactive_run_noisy; + funcs["r"] = funcs["run"]; + funcs["rs"] = &sim_t::interactive_run_silent; + funcs["reg"] = &sim_t::interactive_reg; + funcs["freg"] = &sim_t::interactive_freg; + funcs["fregs"] = &sim_t::interactive_fregs; + funcs["fregd"] = &sim_t::interactive_fregd; + funcs["pc"] = &sim_t::interactive_pc; + funcs["mem"] = &sim_t::interactive_mem; + funcs["str"] = &sim_t::interactive_str; + funcs["until"] = &sim_t::interactive_until; + funcs["while"] = &sim_t::interactive_until; + funcs["quit"] = &sim_t::interactive_quit; + funcs["q"] = funcs["quit"]; + funcs["help"] = &sim_t::interactive_help; + funcs["h"] = funcs["help"]; + + while (!done()) { std::cerr << ": " << std::flush; std::string s = readline(2); @@ -56,37 +91,53 @@ void sim_t::interactive() if (!(ss >> cmd)) { - step(1, true); + set_procs_debug(true); + step(1); continue; } while (ss >> tmp) args.push_back(tmp); - typedef void (sim_t::*interactive_func)(const std::string&, const std::vector&); - std::map funcs; - - funcs["r"] = &sim_t::interactive_run_noisy; - funcs["rs"] = &sim_t::interactive_run_silent; - funcs["reg"] = &sim_t::interactive_reg; - funcs["fregs"] = &sim_t::interactive_fregs; - funcs["fregd"] = &sim_t::interactive_fregd; - funcs["mem"] = &sim_t::interactive_mem; - funcs["str"] = &sim_t::interactive_str; - funcs["until"] = &sim_t::interactive_until; - funcs["while"] = &sim_t::interactive_until; - funcs["q"] = &sim_t::interactive_quit; - try { if(funcs.count(cmd)) (this->*funcs[cmd])(cmd, args); + else + fprintf(stderr, "Unknown command %s\n", cmd.c_str()); } catch(trap_t t) {} } ctrlc_pressed = false; } +void sim_t::interactive_help(const std::string& cmd, const std::vector& args) +{ + std::cerr << + "Interactive commands:\n" + "reg [reg] # Display [reg] (all if omitted) in \n" + "fregs # Display single precision in \n" + "fregd # Display double precision in \n" + "pc # Show current PC in \n" + "mem # Show contents of physical memory\n" + "str # Show NUL-terminated C string\n" + "until reg # Stop when in hits \n" + "until pc # Stop when PC in hits \n" + "until mem # Stop when memory becomes \n" + "while reg # Run while in is \n" + "while pc # Run while PC in is \n" + "while mem # Run while memory is \n" + "run [count] # Resume noisy execution (until CTRL+C, or [count] insns)\n" + "r [count] Alias for run\n" + "rs [count] # Resume silent execution (until CTRL+C, or [count] insns)\n" + "quit # End the simulation\n" + "q Alias for quit\n" + "help # This screen!\n" + "h Alias for help\n" + "Note: Hitting enter is the same as: run 1\n" + << std::flush; +} + void sim_t::interactive_run_noisy(const std::string& cmd, const std::vector& args) { interactive_run(cmd,args,true); @@ -101,8 +152,9 @@ void sim_t::interactive_run(const std::string& cmd, const std::vector& args) @@ -113,80 +165,110 @@ void sim_t::interactive_quit(const std::string& cmd, const std::vector& args) { if(args.size() != 1) - throw trap_illegal_instruction; + throw trap_interactive(); - int p = atoi(args[0].c_str()); - if(p >= (int)num_cores()) - throw trap_illegal_instruction; + processor_t *p = get_core(args[0]); + return p->state.pc; +} - return procs[p]->pc; +void sim_t::interactive_pc(const std::string& cmd, const std::vector& args) +{ + fprintf(stderr, "0x%016" PRIx64 "\n", get_pc(args)); } reg_t sim_t::get_reg(const std::vector& args) { if(args.size() != 2) - throw trap_illegal_instruction; + throw trap_interactive(); + + processor_t *p = get_core(args[0]); + + unsigned long r = std::find(xpr_name, xpr_name + NXPR, args[1]) - xpr_name; + if (r == NXPR) { + char *ptr; + r = strtoul(args[1].c_str(), &ptr, 10); + if (*ptr) { + #define DECLARE_CSR(name, number) if (args[1] == #name) return p->get_csr(number); + #include "encoding.h" // generates if's for all csrs + r = NXPR; // else case (csr name not found) + #undef DECLARE_CSR + } + } - int p = atoi(args[0].c_str()); - int r = atoi(args[1].c_str()); - if(p >= (int)num_cores() || r >= NXPR) - throw trap_illegal_instruction; + if (r >= NXPR) + throw trap_interactive(); - return procs[p]->XPR[r]; + return p->state.XPR[r]; } -reg_t sim_t::get_freg(const std::vector& args) +freg_t sim_t::get_freg(const std::vector& args) { if(args.size() != 2) - throw trap_illegal_instruction; + throw trap_interactive(); - int p = atoi(args[0].c_str()); - int r = atoi(args[1].c_str()); - if(p >= (int)num_cores() || r >= NFPR) - throw trap_illegal_instruction; + processor_t *p = get_core(args[0]); + int r = std::find(fpr_name, fpr_name + NFPR, args[1]) - fpr_name; + if (r == NFPR) + r = atoi(args[1].c_str()); + if (r >= NFPR) + throw trap_interactive(); - return procs[p]->FPR[r]; + return p->state.FPR[r]; } void sim_t::interactive_reg(const std::string& cmd, const std::vector& args) { - printf("0x%016" PRIx64 "\n", get_reg(args)); + if (args.size() == 1) { + // Show all the regs! + processor_t *p = get_core(args[0]); + + for (int r = 0; r < NXPR; ++r) { + fprintf(stderr, "%-4s: 0x%016" PRIx64 " ", xpr_name[r], p->state.XPR[r]); + if ((r + 1) % 4 == 0) + fprintf(stderr, "\n"); + } + } else + fprintf(stderr, "0x%016" PRIx64 "\n", get_reg(args)); } union fpr { - reg_t r; + freg_t r; float s; double d; }; +void sim_t::interactive_freg(const std::string& cmd, const std::vector& args) +{ + freg_t r = get_freg(args); + fprintf(stderr, "0x%016" PRIx64 "%016" PRIx64 "\n", r.v[1], r.v[0]); +} + void sim_t::interactive_fregs(const std::string& cmd, const std::vector& args) { fpr f; f.r = get_freg(args); - printf("%g\n",f.s); + fprintf(stderr, "%g\n", isBoxedF32(f.r) ? (double)f.s : NAN); } void sim_t::interactive_fregd(const std::string& cmd, const std::vector& args) { fpr f; f.r = get_freg(args); - printf("%g\n",f.d); + fprintf(stderr, "%g\n", isBoxedF64(f.r) ? f.d : NAN); } reg_t sim_t::get_mem(const std::vector& args) { if(args.size() != 1 && args.size() != 2) - throw trap_illegal_instruction; + throw trap_interactive(); std::string addr_str = args[0]; + mmu_t* mmu = debug_mmu; if(args.size() == 2) { - int p = atoi(args[0].c_str()); - if(p >= (int)num_cores()) - throw trap_illegal_instruction; - mmu->set_sr(procs[p]->sr); - mmu->set_ptbr(procs[p]->mmu.get_ptbr()); + processor_t *p = get_core(args[0]); + mmu = p->get_mmu(); addr_str = args[1]; } @@ -215,18 +297,18 @@ reg_t sim_t::get_mem(const std::vector& args) void sim_t::interactive_mem(const std::string& cmd, const std::vector& args) { - printf("0x%016" PRIx64 "\n", get_mem(args)); + fprintf(stderr, "0x%016" PRIx64 "\n", get_mem(args)); } void sim_t::interactive_str(const std::string& cmd, const std::vector& args) { if(args.size() != 1) - throw trap_illegal_instruction; + throw trap_interactive(); reg_t addr = strtol(args[0].c_str(),NULL,16); char ch; - while((ch = mmu->load_uint8(addr++))) + while((ch = debug_mmu->load_uint8(addr++))) putchar(ch); putchar('\n'); @@ -258,13 +340,18 @@ void sim_t::interactive_until(const std::string& cmd, const std::vector*func)(args2); + try + { + reg_t current = (this->*func)(args2); - if (cmd_until == (current == val)) - break; - if (ctrlc_pressed) - break; + if (cmd_until == (current == val)) + break; + if (ctrlc_pressed) + break; + } + catch (trap_t t) {} - step(1, false); + set_procs_debug(false); + step(1); } }