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