add BSD license
[riscv-isa-sim.git] / riscv / interactive.cc
1 // See LICENSE for license details.
2
3 #include "sim.h"
4 #include "htif.h"
5 #include <sys/mman.h>
6 #include <map>
7 #include <iostream>
8 #include <climits>
9 #include <assert.h>
10 #include <stdlib.h>
11
12 void sim_t::interactive()
13 {
14 putchar(':');
15 char s[128];
16 std::cin.getline(s,sizeof(s)-1);
17
18 char* p = strtok(s," ");
19 if(!p)
20 {
21 interactive_run_noisy(std::string("r"), std::vector<std::string>(1,"1"));
22 return;
23 }
24 std::string cmd = p;
25
26 std::vector<std::string> args;
27 while((p = strtok(NULL," ")))
28 args.push_back(p);
29
30
31 typedef void (sim_t::*interactive_func)(const std::string&, const std::vector<std::string>&);
32 std::map<std::string,interactive_func> funcs;
33
34 funcs["r"] = &sim_t::interactive_run_noisy;
35 funcs["rs"] = &sim_t::interactive_run_silent;
36 funcs["rp"] = &sim_t::interactive_run_proc_noisy;
37 funcs["rps"] = &sim_t::interactive_run_proc_silent;
38 funcs["reg"] = &sim_t::interactive_reg;
39 funcs["fregs"] = &sim_t::interactive_fregs;
40 funcs["fregd"] = &sim_t::interactive_fregd;
41 funcs["mem"] = &sim_t::interactive_mem;
42 funcs["str"] = &sim_t::interactive_str;
43 funcs["until"] = &sim_t::interactive_until;
44 funcs["while"] = &sim_t::interactive_until;
45 funcs["q"] = &sim_t::interactive_quit;
46
47 try
48 {
49 if(funcs.count(cmd))
50 (this->*funcs[cmd])(cmd, args);
51 }
52 catch(trap_t t) {}
53 }
54
55 void sim_t::interactive_run_noisy(const std::string& cmd, const std::vector<std::string>& args)
56 {
57 interactive_run(cmd,args,true);
58 }
59
60 void sim_t::interactive_run_silent(const std::string& cmd, const std::vector<std::string>& args)
61 {
62 interactive_run(cmd,args,false);
63 }
64
65 void sim_t::interactive_run(const std::string& cmd, const std::vector<std::string>& args, bool noisy)
66 {
67 if (args.size())
68 step_all(atoll(args[0].c_str()), 1, noisy);
69 else
70 while (1) step_all(1, 1, noisy);
71 }
72
73 void sim_t::interactive_run_proc_noisy(const std::string& cmd, const std::vector<std::string>& args)
74 {
75 interactive_run_proc(cmd,args,true);
76 }
77
78 void sim_t::interactive_run_proc_silent(const std::string& cmd, const std::vector<std::string>& args)
79 {
80 interactive_run_proc(cmd,args,false);
81 }
82
83 void sim_t::interactive_run_proc(const std::string& cmd, const std::vector<std::string>& a, bool noisy)
84 {
85 if(a.size() == 0)
86 return;
87
88 int p = atoi(a[0].c_str());
89 if(p >= (int)num_cores())
90 return;
91
92 if(a.size() == 2)
93 procs[p]->step(atoi(a[1].c_str()),noisy);
94 else
95 while (1) procs[p]->step(1, noisy);
96 }
97
98 void sim_t::interactive_quit(const std::string& cmd, const std::vector<std::string>& args)
99 {
100 exit(0);
101 }
102
103 reg_t sim_t::get_pc(const std::vector<std::string>& args)
104 {
105 if(args.size() != 1)
106 throw trap_illegal_instruction;
107
108 int p = atoi(args[0].c_str());
109 if(p >= (int)num_cores())
110 throw trap_illegal_instruction;
111
112 return procs[p]->pc;
113 }
114
115 reg_t sim_t::get_reg(const std::vector<std::string>& args)
116 {
117 if(args.size() != 2)
118 throw trap_illegal_instruction;
119
120 int p = atoi(args[0].c_str());
121 int r = atoi(args[1].c_str());
122 if(p >= (int)num_cores() || r >= NXPR)
123 throw trap_illegal_instruction;
124
125 return procs[p]->XPR[r];
126 }
127
128 reg_t sim_t::get_freg(const std::vector<std::string>& args)
129 {
130 if(args.size() != 2)
131 throw trap_illegal_instruction;
132
133 int p = atoi(args[0].c_str());
134 int r = atoi(args[1].c_str());
135 if(p >= (int)num_cores() || r >= NFPR)
136 throw trap_illegal_instruction;
137
138 return procs[p]->FPR[r];
139 }
140
141 void sim_t::interactive_reg(const std::string& cmd, const std::vector<std::string>& args)
142 {
143 printf("0x%016llx\n",(unsigned long long)get_reg(args));
144 }
145
146 union fpr
147 {
148 reg_t r;
149 float s;
150 double d;
151 };
152
153 void sim_t::interactive_fregs(const std::string& cmd, const std::vector<std::string>& args)
154 {
155 fpr f;
156 f.r = get_freg(args);
157 printf("%g\n",f.s);
158 }
159
160 void sim_t::interactive_fregd(const std::string& cmd, const std::vector<std::string>& args)
161 {
162 fpr f;
163 f.r = get_freg(args);
164 printf("%g\n",f.d);
165 }
166
167 reg_t sim_t::get_mem(const std::vector<std::string>& args)
168 {
169 if(args.size() != 1 && args.size() != 2)
170 throw trap_illegal_instruction;
171
172 std::string addr_str = args[0];
173 if(args.size() == 2)
174 {
175 int p = atoi(args[0].c_str());
176 if(p >= (int)num_cores())
177 throw trap_illegal_instruction;
178 mmu->set_sr(procs[p]->sr);
179 mmu->set_ptbr(procs[p]->mmu.get_ptbr());
180 addr_str = args[1];
181 }
182
183 reg_t addr = strtol(addr_str.c_str(),NULL,16), val;
184 if(addr == LONG_MAX)
185 addr = strtoul(addr_str.c_str(),NULL,16);
186
187 switch(addr % 8)
188 {
189 case 0:
190 val = mmu->load_uint64(addr);
191 break;
192 case 4:
193 val = mmu->load_uint32(addr);
194 break;
195 case 2:
196 case 6:
197 val = mmu->load_uint16(addr);
198 break;
199 default:
200 val = mmu->load_uint8(addr);
201 break;
202 }
203 return val;
204 }
205
206 void sim_t::interactive_mem(const std::string& cmd, const std::vector<std::string>& args)
207 {
208 printf("0x%016llx\n",(unsigned long long)get_mem(args));
209 }
210
211 void sim_t::interactive_str(const std::string& cmd, const std::vector<std::string>& args)
212 {
213 if(args.size() != 1)
214 throw trap_illegal_instruction;
215
216 reg_t addr = strtol(args[0].c_str(),NULL,16);
217
218 char ch;
219 while((ch = mmu->load_uint8(addr++)))
220 putchar(ch);
221
222 putchar('\n');
223 }
224
225 void sim_t::interactive_until(const std::string& cmd, const std::vector<std::string>& args)
226 {
227 if(args.size() < 3)
228 return;
229
230 std::string scmd = args[0];
231 reg_t val = strtol(args[args.size()-1].c_str(),NULL,16);
232 if(val == LONG_MAX)
233 val = strtoul(args[args.size()-1].c_str(),NULL,16);
234
235 std::vector<std::string> args2;
236 args2 = std::vector<std::string>(args.begin()+1,args.end()-1);
237
238 while (1)
239 {
240 reg_t current;
241 if(scmd == "reg")
242 current = get_reg(args2);
243 else if(scmd == "pc")
244 current = get_pc(args2);
245 else if(scmd == "mem")
246 current = get_mem(args2);
247 else
248 return;
249
250 if(cmd == "until" && current == val)
251 break;
252 if(cmd == "while" && current != val)
253 break;
254
255 step_all(1,1,false);
256 }
257 }