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