Put simif_t declaration in its own file. (#209)
[riscv-isa-sim.git] / riscv / debug_module.cc
1 #include <cassert>
2
3 #include "debug_module.h"
4 #include "debug_defines.h"
5 #include "opcodes.h"
6 #include "mmu.h"
7 #include "sim.h"
8
9 #include "debug_rom/debug_rom.h"
10 #include "debug_rom_defines.h"
11
12 #if 0
13 # define D(x) x
14 #else
15 # define D(x)
16 #endif
17
18 ///////////////////////// debug_module_t
19
20 debug_module_t::debug_module_t(sim_t *sim, unsigned progbufsize, unsigned max_bus_master_bits,
21 bool require_authentication) :
22 progbufsize(progbufsize),
23 program_buffer_bytes(4 + 4*progbufsize),
24 max_bus_master_bits(max_bus_master_bits),
25 require_authentication(require_authentication),
26 debug_progbuf_start(debug_data_start - program_buffer_bytes),
27 debug_abstract_start(debug_progbuf_start - debug_abstract_size*4),
28 sim(sim)
29 {
30 D(fprintf(stderr, "debug_data_start=0x%x\n", debug_data_start));
31 D(fprintf(stderr, "debug_progbuf_start=0x%x\n", debug_progbuf_start));
32 D(fprintf(stderr, "debug_abstract_start=0x%x\n", debug_abstract_start));
33
34 program_buffer = new uint8_t[program_buffer_bytes];
35
36 memset(halted, 0, sizeof(halted));
37 memset(debug_rom_flags, 0, sizeof(debug_rom_flags));
38 memset(resumeack, 0, sizeof(resumeack));
39 memset(havereset, 0, sizeof(havereset));
40 memset(program_buffer, 0, program_buffer_bytes);
41 program_buffer[4*progbufsize] = ebreak();
42 program_buffer[4*progbufsize+1] = ebreak() >> 8;
43 program_buffer[4*progbufsize+2] = ebreak() >> 16;
44 program_buffer[4*progbufsize+3] = ebreak() >> 24;
45 memset(dmdata, 0, sizeof(dmdata));
46
47 write32(debug_rom_whereto, 0,
48 jal(ZERO, debug_abstract_start - DEBUG_ROM_WHERETO));
49
50 memset(debug_abstract, 0, sizeof(debug_abstract));
51
52 reset();
53 }
54
55 debug_module_t::~debug_module_t()
56 {
57 delete[] program_buffer;
58 }
59
60 void debug_module_t::reset()
61 {
62 for (unsigned i = 0; i < sim->nprocs(); i++) {
63 processor_t *proc = sim->get_core(i);
64 if (proc)
65 proc->halt_request = false;
66 }
67
68 dmcontrol = {0};
69
70 dmstatus = {0};
71 dmstatus.impebreak = true;
72 dmstatus.authenticated = !require_authentication;
73 dmstatus.version = 2;
74
75 abstractcs = {0};
76 abstractcs.datacount = sizeof(dmdata) / 4;
77 abstractcs.progbufsize = progbufsize;
78
79 abstractauto = {0};
80
81 sbcs = {0};
82 if (max_bus_master_bits > 0) {
83 sbcs.version = 1;
84 sbcs.asize = sizeof(reg_t) * 8;
85 }
86 if (max_bus_master_bits >= 64)
87 sbcs.access64 = true;
88 if (max_bus_master_bits >= 32)
89 sbcs.access32 = true;
90 if (max_bus_master_bits >= 16)
91 sbcs.access16 = true;
92 if (max_bus_master_bits >= 8)
93 sbcs.access8 = true;
94
95 challenge = random();
96 }
97
98 void debug_module_t::add_device(bus_t *bus) {
99 bus->add_device(DEBUG_START, this);
100 }
101
102 bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes)
103 {
104 addr = DEBUG_START + addr;
105
106 if (addr >= DEBUG_ROM_ENTRY &&
107 (addr + len) <= (DEBUG_ROM_ENTRY + debug_rom_raw_len)) {
108 memcpy(bytes, debug_rom_raw + addr - DEBUG_ROM_ENTRY, len);
109 return true;
110 }
111
112 if (addr >= DEBUG_ROM_WHERETO && (addr + len) <= (DEBUG_ROM_WHERETO + 4)) {
113 memcpy(bytes, debug_rom_whereto + addr - DEBUG_ROM_WHERETO, len);
114 return true;
115 }
116
117 if (addr >= DEBUG_ROM_FLAGS && ((addr + len) <= DEBUG_ROM_FLAGS + 1024)) {
118 memcpy(bytes, debug_rom_flags + addr - DEBUG_ROM_FLAGS, len);
119 return true;
120 }
121
122 if (addr >= debug_abstract_start && ((addr + len) <= (debug_abstract_start + sizeof(debug_abstract)))) {
123 memcpy(bytes, debug_abstract + addr - debug_abstract_start, len);
124 return true;
125 }
126
127 if (addr >= debug_data_start && (addr + len) <= (debug_data_start + sizeof(dmdata))) {
128 memcpy(bytes, dmdata + addr - debug_data_start, len);
129 return true;
130 }
131
132 if (addr >= debug_progbuf_start && ((addr + len) <= (debug_progbuf_start + program_buffer_bytes))) {
133 memcpy(bytes, program_buffer + addr - debug_progbuf_start, len);
134 return true;
135 }
136
137 fprintf(stderr, "ERROR: invalid load from debug module: %zd bytes at 0x%016"
138 PRIx64 "\n", len, addr);
139
140 return false;
141 }
142
143 bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes)
144 {
145 D(
146 switch (len) {
147 case 4:
148 fprintf(stderr, "store(addr=0x%lx, len=%d, bytes=0x%08x); "
149 "hartsel=0x%x\n", addr, (unsigned) len, *(uint32_t *) bytes,
150 dmcontrol.hartsel);
151 break;
152 default:
153 fprintf(stderr, "store(addr=0x%lx, len=%d, bytes=...); "
154 "hartsel=0x%x\n", addr, (unsigned) len, dmcontrol.hartsel);
155 break;
156 }
157 );
158
159 uint8_t id_bytes[4];
160 uint32_t id = 0;
161 if (len == 4) {
162 memcpy(id_bytes, bytes, 4);
163 id = read32(id_bytes, 0);
164 }
165
166 addr = DEBUG_START + addr;
167
168 if (addr >= debug_data_start && (addr + len) <= (debug_data_start + sizeof(dmdata))) {
169 memcpy(dmdata + addr - debug_data_start, bytes, len);
170 return true;
171 }
172
173 if (addr >= debug_progbuf_start && ((addr + len) <= (debug_progbuf_start + program_buffer_bytes))) {
174 memcpy(program_buffer + addr - debug_progbuf_start, bytes, len);
175
176 return true;
177 }
178
179 if (addr == DEBUG_ROM_HALTED) {
180 assert (len == 4);
181 halted[id] = true;
182 if (dmcontrol.hartsel == id) {
183 if (0 == (debug_rom_flags[id] & (1 << DEBUG_ROM_FLAG_GO))){
184 if (dmcontrol.hartsel == id) {
185 abstractcs.busy = false;
186 }
187 }
188 }
189 return true;
190 }
191
192 if (addr == DEBUG_ROM_GOING) {
193 debug_rom_flags[dmcontrol.hartsel] &= ~(1 << DEBUG_ROM_FLAG_GO);
194 return true;
195 }
196
197 if (addr == DEBUG_ROM_RESUMING) {
198 assert (len == 4);
199 halted[id] = false;
200 resumeack[id] = true;
201 debug_rom_flags[id] &= ~(1 << DEBUG_ROM_FLAG_RESUME);
202 return true;
203 }
204
205 if (addr == DEBUG_ROM_EXCEPTION) {
206 if (abstractcs.cmderr == CMDERR_NONE) {
207 abstractcs.cmderr = CMDERR_EXCEPTION;
208 }
209 return true;
210 }
211
212 fprintf(stderr, "ERROR: invalid store to debug module: %zd bytes at 0x%016"
213 PRIx64 "\n", len, addr);
214 return false;
215 }
216
217 void debug_module_t::write32(uint8_t *memory, unsigned int index, uint32_t value)
218 {
219 uint8_t* base = memory + index * 4;
220 base[0] = value & 0xff;
221 base[1] = (value >> 8) & 0xff;
222 base[2] = (value >> 16) & 0xff;
223 base[3] = (value >> 24) & 0xff;
224 }
225
226 uint32_t debug_module_t::read32(uint8_t *memory, unsigned int index)
227 {
228 uint8_t* base = memory + index * 4;
229 uint32_t value = ((uint32_t) base[0]) |
230 (((uint32_t) base[1]) << 8) |
231 (((uint32_t) base[2]) << 16) |
232 (((uint32_t) base[3]) << 24);
233 return value;
234 }
235
236 processor_t *debug_module_t::current_proc() const
237 {
238 processor_t *proc = NULL;
239 try {
240 proc = sim->get_core(dmcontrol.hartsel);
241 } catch (const std::out_of_range&) {
242 }
243 return proc;
244 }
245
246 unsigned debug_module_t::sb_access_bits()
247 {
248 return 8 << sbcs.sbaccess;
249 }
250
251 void debug_module_t::sb_autoincrement()
252 {
253 if (!sbcs.autoincrement || !max_bus_master_bits)
254 return;
255
256 uint64_t value = sbaddress[0] + sb_access_bits() / 8;
257 sbaddress[0] = value;
258 uint32_t carry = value >> 32;
259
260 value = sbaddress[1] + carry;
261 sbaddress[1] = value;
262 carry = value >> 32;
263
264 value = sbaddress[2] + carry;
265 sbaddress[2] = value;
266 carry = value >> 32;
267
268 sbaddress[3] += carry;
269 }
270
271 void debug_module_t::sb_read()
272 {
273 reg_t address = ((uint64_t) sbaddress[1] << 32) | sbaddress[0];
274 try {
275 if (sbcs.sbaccess == 0 && max_bus_master_bits >= 8) {
276 sbdata[0] = sim->debug_mmu->load_uint8(address);
277 } else if (sbcs.sbaccess == 1 && max_bus_master_bits >= 16) {
278 sbdata[0] = sim->debug_mmu->load_uint16(address);
279 } else if (sbcs.sbaccess == 2 && max_bus_master_bits >= 32) {
280 sbdata[0] = sim->debug_mmu->load_uint32(address);
281 } else if (sbcs.sbaccess == 3 && max_bus_master_bits >= 64) {
282 uint64_t value = sim->debug_mmu->load_uint32(address);
283 sbdata[0] = value;
284 sbdata[1] = value >> 32;
285 } else {
286 sbcs.error = 3;
287 }
288 } catch (trap_load_access_fault& t) {
289 sbcs.error = 2;
290 }
291 }
292
293 void debug_module_t::sb_write()
294 {
295 reg_t address = ((uint64_t) sbaddress[1] << 32) | sbaddress[0];
296 D(fprintf(stderr, "sb_write() 0x%x @ 0x%lx\n", sbdata[0], address));
297 if (sbcs.sbaccess == 0 && max_bus_master_bits >= 8) {
298 sim->debug_mmu->store_uint8(address, sbdata[0]);
299 } else if (sbcs.sbaccess == 1 && max_bus_master_bits >= 16) {
300 sim->debug_mmu->store_uint16(address, sbdata[0]);
301 } else if (sbcs.sbaccess == 2 && max_bus_master_bits >= 32) {
302 sim->debug_mmu->store_uint32(address, sbdata[0]);
303 } else if (sbcs.sbaccess == 3 && max_bus_master_bits >= 64) {
304 sim->debug_mmu->store_uint64(address,
305 (((uint64_t) sbdata[1]) << 32) | sbdata[0]);
306 } else {
307 sbcs.error = 3;
308 }
309 }
310
311 bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
312 {
313 uint32_t result = 0;
314 D(fprintf(stderr, "dmi_read(0x%x) -> ", address));
315 if (address >= DMI_DATA0 && address < DMI_DATA0 + abstractcs.datacount) {
316 unsigned i = address - DMI_DATA0;
317 result = read32(dmdata, i);
318 if (abstractcs.busy) {
319 result = -1;
320 fprintf(stderr, "\ndmi_read(0x%02x (data[%d]) -> -1 because abstractcs.busy==true\n", address, i);
321 }
322
323 if (abstractcs.busy && abstractcs.cmderr == CMDERR_NONE) {
324 abstractcs.cmderr = CMDERR_BUSY;
325 }
326
327 if (!abstractcs.busy && ((abstractauto.autoexecdata >> i) & 1)) {
328 perform_abstract_command();
329 }
330 } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progbufsize) {
331 unsigned i = address - DMI_PROGBUF0;
332 result = read32(program_buffer, i);
333 if (abstractcs.busy) {
334 result = -1;
335 fprintf(stderr, "\ndmi_read(0x%02x (progbuf[%d]) -> -1 because abstractcs.busy==true\n", address, i);
336 }
337 if (!abstractcs.busy && ((abstractauto.autoexecprogbuf >> i) & 1)) {
338 perform_abstract_command();
339 }
340
341 } else {
342 switch (address) {
343 case DMI_DMCONTROL:
344 {
345 processor_t *proc = current_proc();
346 if (proc)
347 dmcontrol.haltreq = proc->halt_request;
348
349 result = set_field(result, DMI_DMCONTROL_HALTREQ, dmcontrol.haltreq);
350 result = set_field(result, DMI_DMCONTROL_RESUMEREQ, dmcontrol.resumereq);
351 result = set_field(result, ((1L<<hartsellen)-1) <<
352 DMI_DMCONTROL_HARTSEL_OFFSET, dmcontrol.hartsel);
353 result = set_field(result, DMI_DMCONTROL_HARTRESET, dmcontrol.hartreset);
354 result = set_field(result, DMI_DMCONTROL_NDMRESET, dmcontrol.ndmreset);
355 result = set_field(result, DMI_DMCONTROL_DMACTIVE, dmcontrol.dmactive);
356 }
357 break;
358 case DMI_DMSTATUS:
359 {
360 processor_t *proc = current_proc();
361
362 dmstatus.allnonexistant = false;
363 dmstatus.allunavail = false;
364 dmstatus.allrunning = false;
365 dmstatus.allhalted = false;
366 dmstatus.allresumeack = false;
367 if (proc) {
368 if (halted[dmcontrol.hartsel]) {
369 dmstatus.allhalted = true;
370 } else {
371 dmstatus.allrunning = true;
372 }
373 } else {
374 dmstatus.allnonexistant = true;
375 }
376 dmstatus.anynonexistant = dmstatus.allnonexistant;
377 dmstatus.anyunavail = dmstatus.allunavail;
378 dmstatus.anyrunning = dmstatus.allrunning;
379 dmstatus.anyhalted = dmstatus.allhalted;
380 if (proc) {
381 if (resumeack[dmcontrol.hartsel]) {
382 dmstatus.allresumeack = true;
383 } else {
384 dmstatus.allresumeack = false;
385 }
386 } else {
387 dmstatus.allresumeack = false;
388 }
389
390 result = set_field(result, DMI_DMSTATUS_IMPEBREAK,
391 dmstatus.impebreak);
392 result = set_field(result, DMI_DMSTATUS_ALLHAVERESET,
393 havereset[dmcontrol.hartsel]);
394 result = set_field(result, DMI_DMSTATUS_ANYHAVERESET,
395 havereset[dmcontrol.hartsel]);
396 result = set_field(result, DMI_DMSTATUS_ALLNONEXISTENT, dmstatus.allnonexistant);
397 result = set_field(result, DMI_DMSTATUS_ALLUNAVAIL, dmstatus.allunavail);
398 result = set_field(result, DMI_DMSTATUS_ALLRUNNING, dmstatus.allrunning);
399 result = set_field(result, DMI_DMSTATUS_ALLHALTED, dmstatus.allhalted);
400 result = set_field(result, DMI_DMSTATUS_ALLRESUMEACK, dmstatus.allresumeack);
401 result = set_field(result, DMI_DMSTATUS_ANYNONEXISTENT, dmstatus.anynonexistant);
402 result = set_field(result, DMI_DMSTATUS_ANYUNAVAIL, dmstatus.anyunavail);
403 result = set_field(result, DMI_DMSTATUS_ANYRUNNING, dmstatus.anyrunning);
404 result = set_field(result, DMI_DMSTATUS_ANYHALTED, dmstatus.anyhalted);
405 result = set_field(result, DMI_DMSTATUS_ANYRESUMEACK, dmstatus.anyresumeack);
406 result = set_field(result, DMI_DMSTATUS_AUTHENTICATED, dmstatus.authenticated);
407 result = set_field(result, DMI_DMSTATUS_AUTHBUSY, dmstatus.authbusy);
408 result = set_field(result, DMI_DMSTATUS_VERSION, dmstatus.version);
409 }
410 break;
411 case DMI_ABSTRACTCS:
412 result = set_field(result, DMI_ABSTRACTCS_CMDERR, abstractcs.cmderr);
413 result = set_field(result, DMI_ABSTRACTCS_BUSY, abstractcs.busy);
414 result = set_field(result, DMI_ABSTRACTCS_DATACOUNT, abstractcs.datacount);
415 result = set_field(result, DMI_ABSTRACTCS_PROGBUFSIZE,
416 abstractcs.progbufsize);
417 break;
418 case DMI_ABSTRACTAUTO:
419 result = set_field(result, DMI_ABSTRACTAUTO_AUTOEXECPROGBUF, abstractauto.autoexecprogbuf);
420 result = set_field(result, DMI_ABSTRACTAUTO_AUTOEXECDATA, abstractauto.autoexecdata);
421 break;
422 case DMI_COMMAND:
423 result = 0;
424 break;
425 case DMI_HARTINFO:
426 result = set_field(result, DMI_HARTINFO_NSCRATCH, 1);
427 result = set_field(result, DMI_HARTINFO_DATAACCESS, 1);
428 result = set_field(result, DMI_HARTINFO_DATASIZE, abstractcs.datacount);
429 result = set_field(result, DMI_HARTINFO_DATAADDR, debug_data_start);
430 break;
431 case DMI_SBCS:
432 result = set_field(result, DMI_SBCS_SBVERSION, sbcs.version);
433 result = set_field(result, DMI_SBCS_SBREADONADDR, sbcs.readonaddr);
434 result = set_field(result, DMI_SBCS_SBACCESS, sbcs.sbaccess);
435 result = set_field(result, DMI_SBCS_SBAUTOINCREMENT, sbcs.autoincrement);
436 result = set_field(result, DMI_SBCS_SBREADONDATA, sbcs.readondata);
437 result = set_field(result, DMI_SBCS_SBERROR, sbcs.error);
438 result = set_field(result, DMI_SBCS_SBASIZE, sbcs.asize);
439 result = set_field(result, DMI_SBCS_SBACCESS128, sbcs.access128);
440 result = set_field(result, DMI_SBCS_SBACCESS64, sbcs.access64);
441 result = set_field(result, DMI_SBCS_SBACCESS32, sbcs.access32);
442 result = set_field(result, DMI_SBCS_SBACCESS16, sbcs.access16);
443 result = set_field(result, DMI_SBCS_SBACCESS8, sbcs.access8);
444 break;
445 case DMI_SBADDRESS0:
446 result = sbaddress[0];
447 break;
448 case DMI_SBADDRESS1:
449 result = sbaddress[1];
450 break;
451 case DMI_SBADDRESS2:
452 result = sbaddress[2];
453 break;
454 case DMI_SBADDRESS3:
455 result = sbaddress[3];
456 break;
457 case DMI_SBDATA0:
458 result = sbdata[0];
459 if (sbcs.error == 0) {
460 sb_autoincrement();
461 if (sbcs.readondata) {
462 sb_read();
463 }
464 }
465 break;
466 case DMI_SBDATA1:
467 result = sbdata[1];
468 break;
469 case DMI_SBDATA2:
470 result = sbdata[2];
471 break;
472 case DMI_SBDATA3:
473 result = sbdata[3];
474 break;
475 case DMI_AUTHDATA:
476 result = challenge;
477 break;
478 default:
479 result = 0;
480 D(fprintf(stderr, "Unexpected. Returning Error."));
481 return false;
482 }
483 }
484 D(fprintf(stderr, "0x%x\n", result));
485 *value = result;
486 return true;
487 }
488
489 bool debug_module_t::perform_abstract_command()
490 {
491 if (abstractcs.cmderr != CMDERR_NONE)
492 return true;
493 if (abstractcs.busy) {
494 abstractcs.cmderr = CMDERR_BUSY;
495 return true;
496 }
497
498 if ((command >> 24) == 0) {
499 // register access
500 unsigned size = get_field(command, AC_ACCESS_REGISTER_SIZE);
501 bool write = get_field(command, AC_ACCESS_REGISTER_WRITE);
502 unsigned regno = get_field(command, AC_ACCESS_REGISTER_REGNO);
503
504 if (!halted[dmcontrol.hartsel]) {
505 abstractcs.cmderr = CMDERR_HALTRESUME;
506 return true;
507 }
508
509 unsigned i = 0;
510 if (get_field(command, AC_ACCESS_REGISTER_TRANSFER)) {
511
512 if (regno < 0x1000 && progbufsize < 2) {
513 // Make the debugger use the program buffer if it's available, so it
514 // can test both use cases.
515 write32(debug_abstract, i++, csrw(S0, CSR_DSCRATCH));
516
517 if (write) {
518 switch (size) {
519 case 2:
520 write32(debug_abstract, i++, lw(S0, ZERO, debug_data_start));
521 break;
522 case 3:
523 write32(debug_abstract, i++, ld(S0, ZERO, debug_data_start));
524 break;
525 default:
526 abstractcs.cmderr = CMDERR_NOTSUP;
527 return true;
528 }
529 write32(debug_abstract, i++, csrw(S0, regno));
530
531 } else {
532 write32(debug_abstract, i++, csrr(S0, regno));
533 switch (size) {
534 case 2:
535 write32(debug_abstract, i++, sw(S0, ZERO, debug_data_start));
536 break;
537 case 3:
538 write32(debug_abstract, i++, sd(S0, ZERO, debug_data_start));
539 break;
540 default:
541 abstractcs.cmderr = CMDERR_NOTSUP;
542 return true;
543 }
544 }
545 write32(debug_abstract, i++, csrr(S0, CSR_DSCRATCH));
546
547 } else if (regno >= 0x1000 && regno < 0x1020) {
548 unsigned regnum = regno - 0x1000;
549
550 switch (size) {
551 case 2:
552 if (write)
553 write32(debug_abstract, i++, lw(regnum, ZERO, debug_data_start));
554 else
555 write32(debug_abstract, i++, sw(regnum, ZERO, debug_data_start));
556 break;
557 case 3:
558 if (write)
559 write32(debug_abstract, i++, ld(regnum, ZERO, debug_data_start));
560 else
561 write32(debug_abstract, i++, sd(regnum, ZERO, debug_data_start));
562 break;
563 default:
564 abstractcs.cmderr = CMDERR_NOTSUP;
565 return true;
566 }
567
568 } else if (regno >= 0x1020 && regno < 0x1040) {
569 // Don't force the debugger to use progbuf if it exists, so the
570 // debugger has to make the decision not to use abstract commands to
571 // access 64-bit FPRs on 32-bit targets.
572 unsigned fprnum = regno - 0x1020;
573
574 if (write) {
575 switch (size) {
576 case 2:
577 write32(debug_abstract, i++, flw(fprnum, ZERO, debug_data_start));
578 break;
579 case 3:
580 write32(debug_abstract, i++, fld(fprnum, ZERO, debug_data_start));
581 break;
582 default:
583 abstractcs.cmderr = CMDERR_NOTSUP;
584 return true;
585 }
586
587 } else {
588 switch (size) {
589 case 2:
590 write32(debug_abstract, i++, fsw(fprnum, ZERO, debug_data_start));
591 break;
592 case 3:
593 write32(debug_abstract, i++, fsd(fprnum, ZERO, debug_data_start));
594 break;
595 default:
596 abstractcs.cmderr = CMDERR_NOTSUP;
597 return true;
598 }
599 }
600
601 } else {
602 abstractcs.cmderr = CMDERR_NOTSUP;
603 return true;
604 }
605 }
606
607 if (get_field(command, AC_ACCESS_REGISTER_POSTEXEC)) {
608 write32(debug_abstract, i,
609 jal(ZERO, debug_progbuf_start - debug_abstract_start - 4 * i));
610 i++;
611 } else {
612 write32(debug_abstract, i++, ebreak());
613 }
614
615 debug_rom_flags[dmcontrol.hartsel] |= 1 << DEBUG_ROM_FLAG_GO;
616
617 abstractcs.busy = true;
618 } else {
619 abstractcs.cmderr = CMDERR_NOTSUP;
620 }
621 return true;
622 }
623
624 bool debug_module_t::dmi_write(unsigned address, uint32_t value)
625 {
626 D(fprintf(stderr, "dmi_write(0x%x, 0x%x)\n", address, value));
627
628 if (!dmstatus.authenticated && address != DMI_AUTHDATA &&
629 address != DMI_DMCONTROL)
630 return false;
631
632 if (address >= DMI_DATA0 && address < DMI_DATA0 + abstractcs.datacount) {
633 unsigned i = address - DMI_DATA0;
634 if (!abstractcs.busy)
635 write32(dmdata, address - DMI_DATA0, value);
636
637 if (abstractcs.busy && abstractcs.cmderr == CMDERR_NONE) {
638 abstractcs.cmderr = CMDERR_BUSY;
639 }
640
641 if (!abstractcs.busy && ((abstractauto.autoexecdata >> i) & 1)) {
642 perform_abstract_command();
643 }
644 return true;
645
646 } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progbufsize) {
647 unsigned i = address - DMI_PROGBUF0;
648
649 if (!abstractcs.busy)
650 write32(program_buffer, i, value);
651
652 if (!abstractcs.busy && ((abstractauto.autoexecprogbuf >> i) & 1)) {
653 perform_abstract_command();
654 }
655 return true;
656
657 } else {
658 switch (address) {
659 case DMI_DMCONTROL:
660 {
661 if (!dmcontrol.dmactive && get_field(value, DMI_DMCONTROL_DMACTIVE))
662 reset();
663 dmcontrol.dmactive = get_field(value, DMI_DMCONTROL_DMACTIVE);
664 if (!dmstatus.authenticated)
665 return true;
666 if (dmcontrol.dmactive) {
667 dmcontrol.haltreq = get_field(value, DMI_DMCONTROL_HALTREQ);
668 dmcontrol.resumereq = get_field(value, DMI_DMCONTROL_RESUMEREQ);
669 dmcontrol.hartreset = get_field(value, DMI_DMCONTROL_HARTRESET);
670 dmcontrol.ndmreset = get_field(value, DMI_DMCONTROL_NDMRESET);
671 dmcontrol.hartsel = get_field(value, ((1L<<hartsellen)-1) <<
672 DMI_DMCONTROL_HARTSEL_OFFSET);
673 if (get_field(value, DMI_DMCONTROL_ACKHAVERESET)) {
674 havereset[dmcontrol.hartsel] = false;
675 }
676 }
677 processor_t *proc = current_proc();
678 if (proc) {
679 proc->halt_request = dmcontrol.haltreq;
680 if (dmcontrol.resumereq) {
681 debug_rom_flags[dmcontrol.hartsel] |= (1 << DEBUG_ROM_FLAG_RESUME);
682 resumeack[dmcontrol.hartsel] = false;
683 }
684 if (dmcontrol.hartreset) {
685 proc->reset();
686 }
687 }
688 if (dmcontrol.ndmreset) {
689 for (size_t i = 0; i < sim->nprocs(); i++) {
690 proc = sim->get_core(i);
691 proc->reset();
692 }
693 }
694 }
695 return true;
696
697 case DMI_COMMAND:
698 command = value;
699 return perform_abstract_command();
700
701 case DMI_ABSTRACTCS:
702 abstractcs.cmderr = (cmderr_t) (((uint32_t) (abstractcs.cmderr)) & (~(uint32_t)(get_field(value, DMI_ABSTRACTCS_CMDERR))));
703 return true;
704
705 case DMI_ABSTRACTAUTO:
706 abstractauto.autoexecprogbuf = get_field(value,
707 DMI_ABSTRACTAUTO_AUTOEXECPROGBUF);
708 abstractauto.autoexecdata = get_field(value,
709 DMI_ABSTRACTAUTO_AUTOEXECDATA);
710 return true;
711 case DMI_SBCS:
712 sbcs.readonaddr = get_field(value, DMI_SBCS_SBREADONADDR);
713 sbcs.sbaccess = get_field(value, DMI_SBCS_SBACCESS);
714 sbcs.autoincrement = get_field(value, DMI_SBCS_SBAUTOINCREMENT);
715 sbcs.readondata = get_field(value, DMI_SBCS_SBREADONDATA);
716 sbcs.error &= ~get_field(value, DMI_SBCS_SBERROR);
717 return true;
718 case DMI_SBADDRESS0:
719 sbaddress[0] = value;
720 if (sbcs.error == 0 && sbcs.readonaddr) {
721 sb_read();
722 }
723 return true;
724 case DMI_SBADDRESS1:
725 sbaddress[1] = value;
726 return true;
727 case DMI_SBADDRESS2:
728 sbaddress[2] = value;
729 return true;
730 case DMI_SBADDRESS3:
731 sbaddress[3] = value;
732 return true;
733 case DMI_SBDATA0:
734 sbdata[0] = value;
735 if (sbcs.error == 0) {
736 sb_write();
737 if (sbcs.autoincrement && sbcs.error == 0) {
738 sb_autoincrement();
739 }
740 }
741 return true;
742 case DMI_SBDATA1:
743 sbdata[1] = value;
744 return true;
745 case DMI_SBDATA2:
746 sbdata[2] = value;
747 return true;
748 case DMI_SBDATA3:
749 sbdata[3] = value;
750 return true;
751 case DMI_AUTHDATA:
752 D(fprintf(stderr, "debug authentication: got 0x%x; 0x%x unlocks\n", value,
753 challenge + secret));
754 if (require_authentication) {
755 if (value == challenge + secret) {
756 dmstatus.authenticated = true;
757 } else {
758 dmstatus.authenticated = false;
759 challenge = random();
760 }
761 }
762 return true;
763 }
764 }
765 return false;
766 }
767
768 void debug_module_t::proc_reset(unsigned id)
769 {
770 havereset[id] = true;
771 halted[id] = false;
772 }