int cmd_run(char **arg) { device_status_t status; address_t regs[DEVICE_NUM_REGS]; (void)arg; if (device_getregs(regs) < 0) { printc_err("warning: device: can't fetch registers\n"); } else { int i; for (i = 0; i < device_default->max_breakpoints; i++) { struct device_breakpoint *bp = &device_default->breakpoints[i]; if ((bp->flags & DEVICE_BP_ENABLED) && bp->type == DEVICE_BPTYPE_BREAK && bp->addr == regs[0]) break; } if (i < device_default->max_breakpoints) { printc("Stepping over breakpoint #%d at 0x%04x\n", i, regs[0]); device_ctl(DEVICE_CTL_STEP); } } if (device_ctl(DEVICE_CTL_RUN) < 0) { printc_err("run: failed to start CPU\n"); return -1; } printc("Running. Press Ctrl+C to interrupt...\n"); do { status = device_poll(); } while (status == DEVICE_STATUS_RUNNING); if (status == DEVICE_STATUS_INTR) printc("\n"); if (status == DEVICE_STATUS_ERROR) return -1; if (device_ctl(DEVICE_CTL_HALT) < 0) return -1; return cmd_regs(NULL); }
static int restart_program(struct gdb_data *data) { if (device_ctl(DEVICE_CTL_RESET) < 0) return gdb_send(data, "E00"); return gdb_send(data, "OK"); }
static int single_step(struct gdb_data *data, char *buf) { printc("Single stepping\n"); if (run_set_pc(data, buf) < 0 || device_ctl(DEVICE_CTL_STEP) < 0) gdb_send(data, "E00"); return run_final_status(data); }
static int run(struct gdb_data *data, char *buf) { printc("Running\n"); if (run_set_pc(data, buf) < 0 || device_ctl(DEVICE_CTL_RUN) < 0) return gdb_send(data, "E00"); for (;;) { device_status_t status = device_poll(); if (status == DEVICE_STATUS_ERROR) return gdb_send(data, "E00"); if (status == DEVICE_STATUS_HALTED) { printc("Target halted\n"); goto out; } if (status == DEVICE_STATUS_INTR) goto out; while (gdb_peek(data, 0)) { int c = gdb_getc(data); if (c < 0) return -1; if (c == 3) { printc("Interrupted by gdb\n"); goto out; } } } out: if (device_ctl(DEVICE_CTL_HALT) < 0) return gdb_send(data, "E00"); return run_final_status(data); }
int cmd_step(char **arg) { char *count_text = get_arg(arg); address_t count = 1; int i; if (count_text) { if (expr_eval(count_text, &count) < 0) { printc_err("step: can't parse count: %s\n", count_text); return -1; } } for (i = 0; i < count; i++) if (device_ctl(DEVICE_CTL_STEP) < 0) return -1; reader_set_repeat("step"); return cmd_regs(NULL); }
int cmd_erase(char **arg) { const char *type_text = get_arg(arg); const char *seg_text = get_arg(arg); device_erase_type_t type = DEVICE_ERASE_MAIN; address_t segment = 0; address_t total_size = 0; address_t segment_size = 0; if (seg_text && expr_eval(seg_text, &segment) < 0) { printc_err("erase: invalid expression: %s\n", seg_text); return -1; } if (type_text) { if (!strcasecmp(type_text, "all")) { type = DEVICE_ERASE_ALL; } else if (!strcasecmp(type_text, "segment")) { type = DEVICE_ERASE_SEGMENT; if (!seg_text) { printc_err("erase: expected segment " "address\n"); return -1; } } else if (!strcasecmp(type_text, "segrange")) { const char *total_text = get_arg(arg); const char *ss_text = get_arg(arg); if (!(total_text && ss_text)) { printc_err("erase: you must specify " "total and segment sizes\n"); return -1; } if (expr_eval(total_text, &total_size) < 0) { printc_err("erase: invalid expression: %s\n", total_text); return -1; } if (expr_eval(ss_text, &segment_size) < 0) { printc_err("erase: invalid expression: %s\n", ss_text); return -1; } if (segment_size > 0x200 || segment_size < 0x40) { printc_err("erase: invalid segment size: " "0x%x\n", segment_size); return -1; } } else { printc_err("erase: unknown erase type: %s\n", type_text); return -1; } } if (device_ctl(DEVICE_CTL_HALT) < 0) return -1; if (!segment_size) { printc("Erasing...\n"); return device_erase(type, segment); } else { printc("Erasing segments...\n"); while (total_size >= segment_size) { printc_dbg("Erasing 0x%04x...\n", segment); if (device_erase(DEVICE_ERASE_SEGMENT, segment) < 0) return -1; total_size -= segment_size; segment += segment_size; } } return 0; }
int cmd_reset(char **arg) { (void)arg; return device_ctl(DEVICE_CTL_RESET); }