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