Fix 2 trigger corner cases. (#229)
[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, DMI_DMCONTROL_HARTSELHI,
352 dmcontrol.hartsel >> DMI_DMCONTROL_HARTSELLO_LENGTH);
353 result = set_field(result, DMI_DMCONTROL_HARTSELLO, dmcontrol.hartsel);
354 result = set_field(result, DMI_DMCONTROL_HARTRESET, dmcontrol.hartreset);
355 result = set_field(result, DMI_DMCONTROL_NDMRESET, dmcontrol.ndmreset);
356 result = set_field(result, DMI_DMCONTROL_DMACTIVE, dmcontrol.dmactive);
357 }
358 break;
359 case DMI_DMSTATUS:
360 {
361 processor_t *proc = current_proc();
362
363 dmstatus.allnonexistant = false;
364 dmstatus.allunavail = false;
365 dmstatus.allrunning = false;
366 dmstatus.allhalted = false;
367 dmstatus.allresumeack = false;
368 if (proc) {
369 if (halted[dmcontrol.hartsel]) {
370 dmstatus.allhalted = true;
371 } else {
372 dmstatus.allrunning = true;
373 }
374 } else {
375 dmstatus.allnonexistant = true;
376 }
377 dmstatus.anynonexistant = dmstatus.allnonexistant;
378 dmstatus.anyunavail = dmstatus.allunavail;
379 dmstatus.anyrunning = dmstatus.allrunning;
380 dmstatus.anyhalted = dmstatus.allhalted;
381 if (proc) {
382 if (resumeack[dmcontrol.hartsel]) {
383 dmstatus.allresumeack = true;
384 } else {
385 dmstatus.allresumeack = false;
386 }
387 } else {
388 dmstatus.allresumeack = false;
389 }
390
391 result = set_field(result, DMI_DMSTATUS_IMPEBREAK,
392 dmstatus.impebreak);
393 result = set_field(result, DMI_DMSTATUS_ALLHAVERESET,
394 havereset[dmcontrol.hartsel]);
395 result = set_field(result, DMI_DMSTATUS_ANYHAVERESET,
396 havereset[dmcontrol.hartsel]);
397 result = set_field(result, DMI_DMSTATUS_ALLNONEXISTENT, dmstatus.allnonexistant);
398 result = set_field(result, DMI_DMSTATUS_ALLUNAVAIL, dmstatus.allunavail);
399 result = set_field(result, DMI_DMSTATUS_ALLRUNNING, dmstatus.allrunning);
400 result = set_field(result, DMI_DMSTATUS_ALLHALTED, dmstatus.allhalted);
401 result = set_field(result, DMI_DMSTATUS_ALLRESUMEACK, dmstatus.allresumeack);
402 result = set_field(result, DMI_DMSTATUS_ANYNONEXISTENT, dmstatus.anynonexistant);
403 result = set_field(result, DMI_DMSTATUS_ANYUNAVAIL, dmstatus.anyunavail);
404 result = set_field(result, DMI_DMSTATUS_ANYRUNNING, dmstatus.anyrunning);
405 result = set_field(result, DMI_DMSTATUS_ANYHALTED, dmstatus.anyhalted);
406 result = set_field(result, DMI_DMSTATUS_ANYRESUMEACK, dmstatus.anyresumeack);
407 result = set_field(result, DMI_DMSTATUS_AUTHENTICATED, dmstatus.authenticated);
408 result = set_field(result, DMI_DMSTATUS_AUTHBUSY, dmstatus.authbusy);
409 result = set_field(result, DMI_DMSTATUS_VERSION, dmstatus.version);
410 }
411 break;
412 case DMI_ABSTRACTCS:
413 result = set_field(result, DMI_ABSTRACTCS_CMDERR, abstractcs.cmderr);
414 result = set_field(result, DMI_ABSTRACTCS_BUSY, abstractcs.busy);
415 result = set_field(result, DMI_ABSTRACTCS_DATACOUNT, abstractcs.datacount);
416 result = set_field(result, DMI_ABSTRACTCS_PROGBUFSIZE,
417 abstractcs.progbufsize);
418 break;
419 case DMI_ABSTRACTAUTO:
420 result = set_field(result, DMI_ABSTRACTAUTO_AUTOEXECPROGBUF, abstractauto.autoexecprogbuf);
421 result = set_field(result, DMI_ABSTRACTAUTO_AUTOEXECDATA, abstractauto.autoexecdata);
422 break;
423 case DMI_COMMAND:
424 result = 0;
425 break;
426 case DMI_HARTINFO:
427 result = set_field(result, DMI_HARTINFO_NSCRATCH, 1);
428 result = set_field(result, DMI_HARTINFO_DATAACCESS, 1);
429 result = set_field(result, DMI_HARTINFO_DATASIZE, abstractcs.datacount);
430 result = set_field(result, DMI_HARTINFO_DATAADDR, debug_data_start);
431 break;
432 case DMI_SBCS:
433 result = set_field(result, DMI_SBCS_SBVERSION, sbcs.version);
434 result = set_field(result, DMI_SBCS_SBREADONADDR, sbcs.readonaddr);
435 result = set_field(result, DMI_SBCS_SBACCESS, sbcs.sbaccess);
436 result = set_field(result, DMI_SBCS_SBAUTOINCREMENT, sbcs.autoincrement);
437 result = set_field(result, DMI_SBCS_SBREADONDATA, sbcs.readondata);
438 result = set_field(result, DMI_SBCS_SBERROR, sbcs.error);
439 result = set_field(result, DMI_SBCS_SBASIZE, sbcs.asize);
440 result = set_field(result, DMI_SBCS_SBACCESS128, sbcs.access128);
441 result = set_field(result, DMI_SBCS_SBACCESS64, sbcs.access64);
442 result = set_field(result, DMI_SBCS_SBACCESS32, sbcs.access32);
443 result = set_field(result, DMI_SBCS_SBACCESS16, sbcs.access16);
444 result = set_field(result, DMI_SBCS_SBACCESS8, sbcs.access8);
445 break;
446 case DMI_SBADDRESS0:
447 result = sbaddress[0];
448 break;
449 case DMI_SBADDRESS1:
450 result = sbaddress[1];
451 break;
452 case DMI_SBADDRESS2:
453 result = sbaddress[2];
454 break;
455 case DMI_SBADDRESS3:
456 result = sbaddress[3];
457 break;
458 case DMI_SBDATA0:
459 result = sbdata[0];
460 if (sbcs.error == 0) {
461 sb_autoincrement();
462 if (sbcs.readondata) {
463 sb_read();
464 }
465 }
466 break;
467 case DMI_SBDATA1:
468 result = sbdata[1];
469 break;
470 case DMI_SBDATA2:
471 result = sbdata[2];
472 break;
473 case DMI_SBDATA3:
474 result = sbdata[3];
475 break;
476 case DMI_AUTHDATA:
477 result = challenge;
478 break;
479 default:
480 result = 0;
481 D(fprintf(stderr, "Unexpected. Returning Error."));
482 return false;
483 }
484 }
485 D(fprintf(stderr, "0x%x\n", result));
486 *value = result;
487 return true;
488 }
489
490 bool debug_module_t::perform_abstract_command()
491 {
492 if (abstractcs.cmderr != CMDERR_NONE)
493 return true;
494 if (abstractcs.busy) {
495 abstractcs.cmderr = CMDERR_BUSY;
496 return true;
497 }
498
499 if ((command >> 24) == 0) {
500 // register access
501 unsigned size = get_field(command, AC_ACCESS_REGISTER_SIZE);
502 bool write = get_field(command, AC_ACCESS_REGISTER_WRITE);
503 unsigned regno = get_field(command, AC_ACCESS_REGISTER_REGNO);
504
505 if (!halted[dmcontrol.hartsel]) {
506 abstractcs.cmderr = CMDERR_HALTRESUME;
507 return true;
508 }
509
510 unsigned i = 0;
511 if (get_field(command, AC_ACCESS_REGISTER_TRANSFER)) {
512
513 if (regno < 0x1000 && progbufsize < 2) {
514 // Make the debugger use the program buffer if it's available, so it
515 // can test both use cases.
516 write32(debug_abstract, i++, csrw(S0, CSR_DSCRATCH));
517
518 if (write) {
519 switch (size) {
520 case 2:
521 write32(debug_abstract, i++, lw(S0, ZERO, debug_data_start));
522 break;
523 case 3:
524 write32(debug_abstract, i++, ld(S0, ZERO, debug_data_start));
525 break;
526 default:
527 abstractcs.cmderr = CMDERR_NOTSUP;
528 return true;
529 }
530 write32(debug_abstract, i++, csrw(S0, regno));
531
532 } else {
533 write32(debug_abstract, i++, csrr(S0, regno));
534 switch (size) {
535 case 2:
536 write32(debug_abstract, i++, sw(S0, ZERO, debug_data_start));
537 break;
538 case 3:
539 write32(debug_abstract, i++, sd(S0, ZERO, debug_data_start));
540 break;
541 default:
542 abstractcs.cmderr = CMDERR_NOTSUP;
543 return true;
544 }
545 }
546 write32(debug_abstract, i++, csrr(S0, CSR_DSCRATCH));
547
548 } else if (regno >= 0x1000 && regno < 0x1020) {
549 unsigned regnum = regno - 0x1000;
550
551 switch (size) {
552 case 2:
553 if (write)
554 write32(debug_abstract, i++, lw(regnum, ZERO, debug_data_start));
555 else
556 write32(debug_abstract, i++, sw(regnum, ZERO, debug_data_start));
557 break;
558 case 3:
559 if (write)
560 write32(debug_abstract, i++, ld(regnum, ZERO, debug_data_start));
561 else
562 write32(debug_abstract, i++, sd(regnum, ZERO, debug_data_start));
563 break;
564 default:
565 abstractcs.cmderr = CMDERR_NOTSUP;
566 return true;
567 }
568
569 } else if (regno >= 0x1020 && regno < 0x1040) {
570 // Don't force the debugger to use progbuf if it exists, so the
571 // debugger has to make the decision not to use abstract commands to
572 // access 64-bit FPRs on 32-bit targets.
573 unsigned fprnum = regno - 0x1020;
574
575 if (write) {
576 switch (size) {
577 case 2:
578 write32(debug_abstract, i++, flw(fprnum, ZERO, debug_data_start));
579 break;
580 case 3:
581 write32(debug_abstract, i++, fld(fprnum, ZERO, debug_data_start));
582 break;
583 default:
584 abstractcs.cmderr = CMDERR_NOTSUP;
585 return true;
586 }
587
588 } else {
589 switch (size) {
590 case 2:
591 write32(debug_abstract, i++, fsw(fprnum, ZERO, debug_data_start));
592 break;
593 case 3:
594 write32(debug_abstract, i++, fsd(fprnum, ZERO, debug_data_start));
595 break;
596 default:
597 abstractcs.cmderr = CMDERR_NOTSUP;
598 return true;
599 }
600 }
601
602 } else {
603 abstractcs.cmderr = CMDERR_NOTSUP;
604 return true;
605 }
606 }
607
608 if (get_field(command, AC_ACCESS_REGISTER_POSTEXEC)) {
609 write32(debug_abstract, i,
610 jal(ZERO, debug_progbuf_start - debug_abstract_start - 4 * i));
611 i++;
612 } else {
613 write32(debug_abstract, i++, ebreak());
614 }
615
616 debug_rom_flags[dmcontrol.hartsel] |= 1 << DEBUG_ROM_FLAG_GO;
617
618 abstractcs.busy = true;
619 } else {
620 abstractcs.cmderr = CMDERR_NOTSUP;
621 }
622 return true;
623 }
624
625 bool debug_module_t::dmi_write(unsigned address, uint32_t value)
626 {
627 D(fprintf(stderr, "dmi_write(0x%x, 0x%x)\n", address, value));
628
629 if (!dmstatus.authenticated && address != DMI_AUTHDATA &&
630 address != DMI_DMCONTROL)
631 return false;
632
633 if (address >= DMI_DATA0 && address < DMI_DATA0 + abstractcs.datacount) {
634 unsigned i = address - DMI_DATA0;
635 if (!abstractcs.busy)
636 write32(dmdata, address - DMI_DATA0, value);
637
638 if (abstractcs.busy && abstractcs.cmderr == CMDERR_NONE) {
639 abstractcs.cmderr = CMDERR_BUSY;
640 }
641
642 if (!abstractcs.busy && ((abstractauto.autoexecdata >> i) & 1)) {
643 perform_abstract_command();
644 }
645 return true;
646
647 } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + progbufsize) {
648 unsigned i = address - DMI_PROGBUF0;
649
650 if (!abstractcs.busy)
651 write32(program_buffer, i, value);
652
653 if (!abstractcs.busy && ((abstractauto.autoexecprogbuf >> i) & 1)) {
654 perform_abstract_command();
655 }
656 return true;
657
658 } else {
659 switch (address) {
660 case DMI_DMCONTROL:
661 {
662 if (!dmcontrol.dmactive && get_field(value, DMI_DMCONTROL_DMACTIVE))
663 reset();
664 dmcontrol.dmactive = get_field(value, DMI_DMCONTROL_DMACTIVE);
665 if (!dmstatus.authenticated)
666 return true;
667 if (dmcontrol.dmactive) {
668 dmcontrol.haltreq = get_field(value, DMI_DMCONTROL_HALTREQ);
669 dmcontrol.resumereq = get_field(value, DMI_DMCONTROL_RESUMEREQ);
670 dmcontrol.hartreset = get_field(value, DMI_DMCONTROL_HARTRESET);
671 dmcontrol.ndmreset = get_field(value, DMI_DMCONTROL_NDMRESET);
672 dmcontrol.hartsel = get_field(value, DMI_DMCONTROL_HARTSELHI) <<
673 DMI_DMCONTROL_HARTSELLO_LENGTH;
674 dmcontrol.hartsel |= get_field(value, DMI_DMCONTROL_HARTSELLO);
675 dmcontrol.hartsel &= (1L<<hartsellen) - 1;
676 if (get_field(value, DMI_DMCONTROL_ACKHAVERESET)) {
677 havereset[dmcontrol.hartsel] = false;
678 }
679 }
680 processor_t *proc = current_proc();
681 if (proc) {
682 proc->halt_request = dmcontrol.haltreq;
683 if (dmcontrol.resumereq) {
684 debug_rom_flags[dmcontrol.hartsel] |= (1 << DEBUG_ROM_FLAG_RESUME);
685 resumeack[dmcontrol.hartsel] = false;
686 }
687 if (dmcontrol.hartreset) {
688 proc->reset();
689 }
690 }
691 if (dmcontrol.ndmreset) {
692 for (size_t i = 0; i < sim->nprocs(); i++) {
693 proc = sim->get_core(i);
694 proc->reset();
695 }
696 }
697 }
698 return true;
699
700 case DMI_COMMAND:
701 command = value;
702 return perform_abstract_command();
703
704 case DMI_ABSTRACTCS:
705 abstractcs.cmderr = (cmderr_t) (((uint32_t) (abstractcs.cmderr)) & (~(uint32_t)(get_field(value, DMI_ABSTRACTCS_CMDERR))));
706 return true;
707
708 case DMI_ABSTRACTAUTO:
709 abstractauto.autoexecprogbuf = get_field(value,
710 DMI_ABSTRACTAUTO_AUTOEXECPROGBUF);
711 abstractauto.autoexecdata = get_field(value,
712 DMI_ABSTRACTAUTO_AUTOEXECDATA);
713 return true;
714 case DMI_SBCS:
715 sbcs.readonaddr = get_field(value, DMI_SBCS_SBREADONADDR);
716 sbcs.sbaccess = get_field(value, DMI_SBCS_SBACCESS);
717 sbcs.autoincrement = get_field(value, DMI_SBCS_SBAUTOINCREMENT);
718 sbcs.readondata = get_field(value, DMI_SBCS_SBREADONDATA);
719 sbcs.error &= ~get_field(value, DMI_SBCS_SBERROR);
720 return true;
721 case DMI_SBADDRESS0:
722 sbaddress[0] = value;
723 if (sbcs.error == 0 && sbcs.readonaddr) {
724 sb_read();
725 }
726 return true;
727 case DMI_SBADDRESS1:
728 sbaddress[1] = value;
729 return true;
730 case DMI_SBADDRESS2:
731 sbaddress[2] = value;
732 return true;
733 case DMI_SBADDRESS3:
734 sbaddress[3] = value;
735 return true;
736 case DMI_SBDATA0:
737 sbdata[0] = value;
738 if (sbcs.error == 0) {
739 sb_write();
740 if (sbcs.autoincrement && sbcs.error == 0) {
741 sb_autoincrement();
742 }
743 }
744 return true;
745 case DMI_SBDATA1:
746 sbdata[1] = value;
747 return true;
748 case DMI_SBDATA2:
749 sbdata[2] = value;
750 return true;
751 case DMI_SBDATA3:
752 sbdata[3] = value;
753 return true;
754 case DMI_AUTHDATA:
755 D(fprintf(stderr, "debug authentication: got 0x%x; 0x%x unlocks\n", value,
756 challenge + secret));
757 if (require_authentication) {
758 if (value == challenge + secret) {
759 dmstatus.authenticated = true;
760 } else {
761 dmstatus.authenticated = false;
762 challenge = random();
763 }
764 }
765 return true;
766 }
767 }
768 return false;
769 }
770
771 void debug_module_t::proc_reset(unsigned id)
772 {
773 havereset[id] = true;
774 halted[id] = false;
775 }