gdb: can now interrupt execution on both sides

This commit is contained in:
Daniel Beer 2010-03-23 14:37:53 +13:00
parent 1fea148de4
commit ae1006f3ea
5 changed files with 65 additions and 41 deletions

4
bsl.c
View File

@ -202,9 +202,9 @@ static int bsl_control(device_ctl_t type)
return -1;
}
static int bsl_wait(int blocking)
static device_status_t bsl_wait(int blocking)
{
return 0;
return DEVICE_STATUS_HALTED;
}
static int bsl_breakpoint(u_int16_t addr)

View File

@ -33,10 +33,17 @@ typedef enum {
DEVICE_CTL_ERASE
} device_ctl_t;
typedef enum {
DEVICE_STATUS_HALTED,
DEVICE_STATUS_RUNNING,
DEVICE_STATUS_INTR,
DEVICE_STATUS_ERROR
} device_status_t;
struct device {
void (*close)(void);
int (*control)(device_ctl_t action);
int (*wait)(int blocking);
device_status_t (*wait)(int blocking);
int (*breakpoint)(u_int16_t addr);
int (*getregs)(u_int16_t *regs);
int (*setregs)(const u_int16_t *regs);

10
fet.c
View File

@ -602,23 +602,23 @@ static int do_erase(void)
return 0;
}
static int fet_wait(int blocking)
static device_status_t fet_wait(int blocking)
{
do {
/* Without this delay, breakpoints can get lost. */
if (usleep(500000) < 0)
break;
return DEVICE_STATUS_INTR;
if (xfer(C_STATE, NULL, 0, 1, 0) < 0) {
fprintf(stderr, "fet: polling failed\n");
return -1;
return DEVICE_STATUS_ERROR;
}
if (!(fet_reply.argv[0] & FET_POLL_RUNNING))
return 0;
return DEVICE_STATUS_HALTED;
} while (blocking);
return 1;
return DEVICE_STATUS_RUNNING;
}
static int fet_control(device_ctl_t action)

9
gdb.c
View File

@ -388,18 +388,21 @@ static int run(char *buf)
}
for (;;) {
int status = gdb_device->wait(0);
device_status_t status = gdb_device->wait(0);
if (status < 0) {
if (status == DEVICE_STATUS_ERROR) {
gdb_send("E00");
return run_final_status();
}
if (!status) {
if (status == DEVICE_STATUS_HALTED) {
printf("Target halted\n");
goto out;
}
if (status == DEVICE_STATUS_INTR)
goto out;
while (gdb_peek()) {
int c = gdb_getc();

74
sim.c
View File

@ -511,52 +511,66 @@ static int sim_control(device_ctl_t action)
case DEVICE_CTL_RUN_BP:
run_mode = RUN_TO_BREAKPOINT;
ctrlc_reset();
return 0;
case DEVICE_CTL_RUN:
run_mode = RUN_FREE;
ctrlc_reset();
return 0;
}
return -1;
}
static int sim_wait(int blocking)
static int run_burst(void)
{
int i = 100000;
int i = 1000000;
if (run_mode != RUN_HALTED) {
ctrlc_reset();
while (i) {
if (run_mode == RUN_TO_BREAKPOINT &&
sim_regs[MSP430_REG_PC] == run_breakpoint) {
run_mode = RUN_HALTED;
return 0;
}
if (sim_regs[MSP430_REG_SR] & MSP430_SR_CPUOFF) {
run_mode = RUN_HALTED;
printf("CPU disabled\n");
return 0;
}
if (ctrlc_check())
break;
if (step_cpu() < 0) {
run_mode = RUN_HALTED;
return -1;
}
if (!blocking)
i--;
while (i--) {
if (run_mode == RUN_TO_BREAKPOINT &&
sim_regs[MSP430_REG_PC] == run_breakpoint) {
printf("Breakpoint reached\n");
run_mode = RUN_HALTED;
return 0;
}
return 1;
if (sim_regs[MSP430_REG_SR] & MSP430_SR_CPUOFF) {
run_mode = RUN_HALTED;
printf("CPU disabled\n");
return 0;
}
if (step_cpu() < 0) {
run_mode = RUN_HALTED;
return -1;
}
}
return 0;
return 1;
}
static device_status_t sim_wait(int blocking)
{
if (run_mode != RUN_HALTED) {
do {
int ret = run_burst();
if (ret < 0)
return DEVICE_STATUS_ERROR;
if (!ret)
return DEVICE_STATUS_HALTED;
if (ctrlc_check()) {
ctrlc_reset();
return DEVICE_STATUS_INTR;
}
} while (blocking);
return DEVICE_STATUS_RUNNING;
}
return DEVICE_STATUS_HALTED;
}
static int sim_breakpoint(u_int16_t addr)