42 |
RS_GETLINE, |
RS_GETLINE, |
43 |
RS_CHKSUM1, |
RS_CHKSUM1, |
44 |
RS_CHKSUM2, |
RS_CHKSUM2, |
|
RS_CONTINUE |
|
45 |
}; |
}; |
46 |
/* XXX: This is not thread safe. Do we care? */ |
/* XXX: This is not thread safe. Do we care? */ |
47 |
static int gdbserver_fd = -1; |
static int gdbserver_fd = -1; |
48 |
|
|
49 |
typedef struct GDBState { |
typedef struct GDBState { |
50 |
enum RSState state; |
enum RSState state; /* parsing state */ |
51 |
int fd; |
int fd; |
52 |
char line_buf[4096]; |
char line_buf[4096]; |
53 |
int line_buf_index; |
int line_buf_index; |
54 |
int line_csum; |
int line_csum; |
55 |
|
#ifdef CONFIG_USER_ONLY |
56 |
|
int running_state; |
57 |
|
#endif |
58 |
} GDBState; |
} GDBState; |
59 |
|
|
60 |
#ifdef CONFIG_USER_ONLY |
#ifdef CONFIG_USER_ONLY |
433 |
env->npc = addr + 4; |
env->npc = addr + 4; |
434 |
#endif |
#endif |
435 |
} |
} |
436 |
return RS_CONTINUE; |
#ifdef CONFIG_USER_ONLY |
437 |
|
s->running_state = 1; |
438 |
|
#else |
439 |
|
vm_start(); |
440 |
|
#endif |
441 |
|
return RS_IDLE; |
442 |
case 's': |
case 's': |
443 |
if (*p != '\0') { |
if (*p != '\0') { |
444 |
addr = strtoul(p, (char **)&p, 16); |
addr = strtoul(p, (char **)&p, 16); |
452 |
#endif |
#endif |
453 |
} |
} |
454 |
cpu_single_step(env, 1); |
cpu_single_step(env, 1); |
455 |
return RS_CONTINUE; |
#ifdef CONFIG_USER_ONLY |
456 |
|
s->running_state = 1; |
457 |
|
#else |
458 |
|
vm_start(); |
459 |
|
#endif |
460 |
|
return RS_IDLE; |
461 |
case 'g': |
case 'g': |
462 |
reg_size = cpu_gdb_read_registers(env, mem_buf); |
reg_size = cpu_gdb_read_registers(env, mem_buf); |
463 |
memtohex(buf, mem_buf, reg_size); |
memtohex(buf, mem_buf, reg_size); |
568 |
/* when the CPU is running, we cannot do anything except stop |
/* when the CPU is running, we cannot do anything except stop |
569 |
it when receiving a char */ |
it when receiving a char */ |
570 |
vm_stop(EXCP_INTERRUPT); |
vm_stop(EXCP_INTERRUPT); |
571 |
} else { |
} else |
572 |
#endif |
#endif |
573 |
|
{ |
574 |
switch(s->state) { |
switch(s->state) { |
575 |
case RS_IDLE: |
case RS_IDLE: |
576 |
if (ch == '$') { |
if (ch == '$') { |
608 |
s->state = gdb_handle_packet(s, env, s->line_buf); |
s->state = gdb_handle_packet(s, env, s->line_buf); |
609 |
} |
} |
610 |
break; |
break; |
|
case RS_CONTINUE: |
|
|
#ifndef CONFIG_USER_ONLY |
|
|
vm_start(); |
|
|
s->state = RS_IDLE; |
|
|
#endif |
|
|
break; |
|
611 |
} |
} |
|
#ifndef CONFIG_USER_ONLY |
|
612 |
} |
} |
|
#endif |
|
613 |
} |
} |
614 |
|
|
615 |
#ifdef CONFIG_USER_ONLY |
#ifdef CONFIG_USER_ONLY |
635 |
put_packet(s, buf); |
put_packet(s, buf); |
636 |
} |
} |
637 |
|
|
|
/* TODO: How do we terminate this loop? */ |
|
638 |
sig = 0; |
sig = 0; |
639 |
s->state = RS_IDLE; |
s->state = RS_IDLE; |
640 |
while (s->state != RS_CONTINUE) |
s->running_state = 0; |
641 |
{ |
while (s->running_state == 0) { |
642 |
n = read (s->fd, buf, 256); |
n = read (s->fd, buf, 256); |
643 |
if (n > 0) |
if (n > 0) |
644 |
{ |
{ |
653 |
connection before continuing. */ |
connection before continuing. */ |
654 |
return sig; |
return sig; |
655 |
} |
} |
656 |
} |
} |
657 |
return sig; |
return sig; |
658 |
} |
} |
659 |
#else |
#else |