comparison gdb_remote.c @ 2107:f80c6111e1ae

Move some debugger state to a per-CPU structure. Add m command for returning to main CPU from sub CPU
author Michael Pavone <pavone@retrodev.com>
date Sat, 12 Feb 2022 15:20:43 -0800
parents 3a46ff899fa6
children 8554751f17b5
comparison
equal deleted inserted replaced
2106:d2989e32c026 2107:f80c6111e1ae
48 int cont = 0; 48 int cont = 0;
49 int expect_break_response=0; 49 int expect_break_response=0;
50 uint32_t resume_pc; 50 uint32_t resume_pc;
51 51
52 52
53 static uint16_t branch_t;
54 static uint16_t branch_f;
55
56 static bp_def * breakpoints = NULL;
57 static uint32_t bp_index = 0;
58
59
60 void hex_32(uint32_t num, char * out) 53 void hex_32(uint32_t num, char * out)
61 { 54 {
62 for (int32_t shift = 28; shift >= 0; shift -= 4) 55 for (int32_t shift = 28; shift >= 0; shift -= 4)
63 { 56 {
64 uint8_t nibble = num >> shift & 0xF; 57 uint8_t nibble = num >> shift & 0xF;
169 162
170 void gdb_run_command(m68k_context * context, uint32_t pc, char * command) 163 void gdb_run_command(m68k_context * context, uint32_t pc, char * command)
171 { 164 {
172 char send_buf[512]; 165 char send_buf[512];
173 dfprintf(stderr, "Received command %s\n", command); 166 dfprintf(stderr, "Received command %s\n", command);
167 debug_root *root = find_root(context);
168 if (!root) {
169 fatal_error("Could not find debug root for CPU %p\n", context);
170 }
174 switch(*command) 171 switch(*command)
175 { 172 {
176 173
177 case 'c': 174 case 'c':
178 if (*(command+1) != 0) { 175 if (*(command+1) != 0) {
200 after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1); 197 after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1);
201 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { 198 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) {
202 after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1); 199 after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1);
203 } else if(m68k_is_branch(&inst)) { 200 } else if(m68k_is_branch(&inst)) {
204 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { 201 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) {
205 branch_f = after; 202 root->branch_f = after;
206 branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; 203 root->branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF;
207 insert_breakpoint(context, branch_t, gdb_debug_enter); 204 insert_breakpoint(context, root->branch_t, gdb_debug_enter);
208 } else if(inst.op == M68K_DBCC && inst.extra.cond != COND_FALSE) { 205 } else if(inst.op == M68K_DBCC && inst.extra.cond != COND_FALSE) {
209 branch_t = after; 206 root->branch_t = after;
210 branch_f = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; 207 root->branch_f = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF;
211 insert_breakpoint(context, branch_f, gdb_debug_enter); 208 insert_breakpoint(context, root->branch_f, gdb_debug_enter);
212 } else { 209 } else {
213 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; 210 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF;
214 } 211 }
215 } 212 }
216 insert_breakpoint(context, after, gdb_debug_enter); 213 insert_breakpoint(context, after, gdb_debug_enter);
231 uint8_t type = command[1]; 228 uint8_t type = command[1];
232 if (type < '2') { 229 if (type < '2') {
233 uint32_t address = strtoul(command+3, NULL, 16); 230 uint32_t address = strtoul(command+3, NULL, 16);
234 insert_breakpoint(context, address, gdb_debug_enter); 231 insert_breakpoint(context, address, gdb_debug_enter);
235 bp_def *new_bp = malloc(sizeof(bp_def)); 232 bp_def *new_bp = malloc(sizeof(bp_def));
236 new_bp->next = breakpoints; 233 new_bp->next = root->breakpoints;
237 new_bp->address = address; 234 new_bp->address = address;
238 new_bp->index = bp_index++; 235 new_bp->index = root->bp_index++;
239 breakpoints = new_bp; 236 root->breakpoints = new_bp;
240 gdb_send_command("OK"); 237 gdb_send_command("OK");
241 } else { 238 } else {
242 //watchpoints are not currently supported 239 //watchpoints are not currently supported
243 gdb_send_command(""); 240 gdb_send_command("");
244 } 241 }
247 case 'z': { 244 case 'z': {
248 uint8_t type = command[1]; 245 uint8_t type = command[1];
249 if (type < '2') { 246 if (type < '2') {
250 uint32_t address = strtoul(command+3, NULL, 16); 247 uint32_t address = strtoul(command+3, NULL, 16);
251 remove_breakpoint(context, address); 248 remove_breakpoint(context, address);
252 bp_def **found = find_breakpoint(&breakpoints, address); 249 bp_def **found = find_breakpoint(&root->breakpoints, address);
253 if (*found) 250 if (*found)
254 { 251 {
255 bp_def * to_remove = *found; 252 bp_def * to_remove = *found;
256 *found = to_remove->next; 253 *found = to_remove->next;
257 free(to_remove); 254 free(to_remove);
428 after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1); 425 after = (read_dma_value(context->aregs[7]/2) << 16) | read_dma_value(context->aregs[7]/2 + 1);
429 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { 426 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) {
430 after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1); 427 after = (read_dma_value((context->aregs[7]+2)/2) << 16) | read_dma_value((context->aregs[7]+2)/2 + 1);
431 } else if(m68k_is_branch(&inst)) { 428 } else if(m68k_is_branch(&inst)) {
432 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { 429 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) {
433 branch_f = after; 430 root->branch_f = after;
434 branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; 431 root->branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF;
435 insert_breakpoint(context, branch_t, gdb_debug_enter); 432 insert_breakpoint(context, root->branch_t, gdb_debug_enter);
436 } else if(inst.op == M68K_DBCC && inst.extra.cond != COND_FALSE) { 433 } else if(inst.op == M68K_DBCC && inst.extra.cond != COND_FALSE) {
437 branch_t = after; 434 root->branch_t = after;
438 branch_f = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; 435 root->branch_f = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF;
439 insert_breakpoint(context, branch_f, gdb_debug_enter); 436 insert_breakpoint(context, root->branch_f, gdb_debug_enter);
440 } else { 437 } else {
441 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; 438 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF;
442 } 439 }
443 } 440 }
444 insert_breakpoint(context, after, gdb_debug_enter); 441 insert_breakpoint(context, after, gdb_debug_enter);
471 dfprintf(stderr, "Entered debugger at address %X\n", pc); 468 dfprintf(stderr, "Entered debugger at address %X\n", pc);
472 if (expect_break_response) { 469 if (expect_break_response) {
473 gdb_send_command("S05"); 470 gdb_send_command("S05");
474 expect_break_response = 0; 471 expect_break_response = 0;
475 } 472 }
476 if ((pc & 0xFFFFFF) == branch_t) { 473 debug_root *root = find_root(context);
477 bp_def ** f_bp = find_breakpoint(&breakpoints, branch_f); 474 if (!root) {
475 fatal_error("Could not find debug root for CPU %p\n", context);
476 }
477 if ((pc & 0xFFFFFF) == root->branch_t) {
478 bp_def ** f_bp = find_breakpoint(&root->breakpoints, root->branch_f);
478 if (!*f_bp) { 479 if (!*f_bp) {
479 remove_breakpoint(context, branch_f); 480 remove_breakpoint(context, root->branch_f);
480 } 481 }
481 branch_t = branch_f = 0; 482 root->branch_t = root->branch_f = 0;
482 } else if((pc & 0xFFFFFF) == branch_f) { 483 } else if((pc & 0xFFFFFF) == root->branch_f) {
483 bp_def ** t_bp = find_breakpoint(&breakpoints, branch_t); 484 bp_def ** t_bp = find_breakpoint(&root->breakpoints, root->branch_t);
484 if (!*t_bp) { 485 if (!*t_bp) {
485 remove_breakpoint(context, branch_t); 486 remove_breakpoint(context, root->branch_t);
486 } 487 }
487 branch_t = branch_f = 0; 488 root->branch_t = root->branch_f = 0;
488 } 489 }
489 //Check if this is a user set breakpoint, or just a temporary one 490 //Check if this is a user set breakpoint, or just a temporary one
490 bp_def ** this_bp = find_breakpoint(&breakpoints, pc & 0xFFFFFF); 491 bp_def ** this_bp = find_breakpoint(&root->breakpoints, pc & 0xFFFFFF);
491 if (!*this_bp) { 492 if (!*this_bp) {
492 remove_breakpoint(context, pc & 0xFFFFFF); 493 remove_breakpoint(context, pc & 0xFFFFFF);
493 } 494 }
494 resume_pc = pc; 495 resume_pc = pc;
495 cont = 0; 496 cont = 0;