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