From: Maxime Coquelin Date: Fri, 11 Mar 2016 10:16:41 +0000 (+0100) Subject: Make the backends propagate errors X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=64a48c704ff802b3a08cbdf0dd729f4a7a39ea67;hp=89c3b1462b8c4b96e2071a87883aed5e030bbef9;p=fw%2Fstlink Make the backends propagate errors As the libusb returns errors, make the backends propagates them so that callers can decide to continue or stop task execution. Signed-off-by: Maxime Coquelin --- diff --git a/src/stlink-common.h b/src/stlink-common.h index fbbb2b4..467b9b9 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -556,30 +556,30 @@ extern "C" { typedef struct _stlink_backend { void (*close) (stlink_t * sl); - void (*exit_debug_mode) (stlink_t * sl); - void (*enter_swd_mode) (stlink_t * sl); - void (*enter_jtag_mode) (stlink_t * stl); - void (*exit_dfu_mode) (stlink_t * stl); - void (*core_id) (stlink_t * stl); - void (*reset) (stlink_t * stl); - void (*jtag_reset) (stlink_t * stl, int value); - void (*run) (stlink_t * stl); - void (*status) (stlink_t * stl); - void (*version) (stlink_t *sl); - void (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); - void (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - void (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); - void (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); - void (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); - void (*read_all_regs) (stlink_t *sl, reg * regp); - void (*read_reg) (stlink_t *sl, int r_idx, reg * regp); - void (*read_all_unsupported_regs) (stlink_t *sl, reg *regp); - void (*read_unsupported_reg) (stlink_t *sl, int r_idx, reg *regp); - void (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, reg *regp); - void (*write_reg) (stlink_t *sl, uint32_t reg, int idx); - void (*step) (stlink_t * stl); + int (*exit_debug_mode) (stlink_t * sl); + int (*enter_swd_mode) (stlink_t * sl); + int (*enter_jtag_mode) (stlink_t * stl); + int (*exit_dfu_mode) (stlink_t * stl); + int (*core_id) (stlink_t * stl); + int (*reset) (stlink_t * stl); + int (*jtag_reset) (stlink_t * stl, int value); + int (*run) (stlink_t * stl); + int (*status) (stlink_t * stl); + int (*version) (stlink_t *sl); + int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); + int (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*write_debug32) (stlink_t *sl, uint32_t addr, uint32_t data); + int (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); + int (*read_all_regs) (stlink_t *sl, reg * regp); + int (*read_reg) (stlink_t *sl, int r_idx, reg * regp); + int (*read_all_unsupported_regs) (stlink_t *sl, reg *regp); + int (*read_unsupported_reg) (stlink_t *sl, int r_idx, reg *regp); + int (*write_unsupported_reg) (stlink_t *sl, uint32_t value, int idx, reg *regp); + int (*write_reg) (stlink_t *sl, uint32_t reg, int idx); + int (*step) (stlink_t * stl); int (*current_mode) (stlink_t * stl); - void (*force_debug) (stlink_t *sl); + int (*force_debug) (stlink_t *sl); int32_t (*target_voltage) (stlink_t *sl); } stlink_backend_t; diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 3fdc0bd..03df7d8 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -403,13 +403,13 @@ void stlink_stat(stlink_t *stl, char *txt) { } -void _stlink_sg_version(stlink_t *stl) { +int _stlink_sg_version(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; clear_cdb(sl); sl->cdb_cmd_blk[0] = STLINK_GET_VERSION; stl->q_len = 6; sl->q_addr = 0; - stlink_q(stl); + return stlink_q(stl); } // Get stlink mode: @@ -422,44 +422,46 @@ int _stlink_sg_current_mode(stlink_t *stl) { sl->cdb_cmd_blk[0] = STLINK_GET_CURRENT_MODE; stl->q_len = 2; sl->q_addr = 0; - stlink_q(stl); + if (stlink_q(stl)) + return -1; + return stl->q_buf[0]; } // Exit the mass mode and enter the swd debug mode. -void _stlink_sg_enter_swd_mode(stlink_t *sl) { +int _stlink_sg_enter_swd_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_SWD; sl->q_len = 0; // >0 -> aboard - stlink_q(sl); + return stlink_q(sl); } // Exit the mass mode and enter the jtag debug mode. // (jtag is disabled in the discovery's stlink firmware) -void _stlink_sg_enter_jtag_mode(stlink_t *sl) { +int _stlink_sg_enter_jtag_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_enter_jtag_mode ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG; sl->q_len = 0; - stlink_q(sl); + return stlink_q(sl); } // XXX kernel driver performs reset, the device temporally disappears // Suspect this is no longer the case when we have ignore on? RECHECK -void _stlink_sg_exit_dfu_mode(stlink_t *sl) { +int _stlink_sg_exit_dfu_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_exit_dfu_mode ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[0] = STLINK_DFU_COMMAND; sg->cdb_cmd_blk[1] = STLINK_DFU_EXIT; sl->q_len = 0; // ?? - stlink_q(sl); + return stlink_q(sl); /* [135121.844564] sd 19:0:0:0: [sdb] Unhandled error code [135121.844569] sd 19:0:0:0: [sdb] Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK @@ -505,74 +507,91 @@ void _stlink_sg_exit_dfu_mode(stlink_t *sl) { */ } -void _stlink_sg_core_id(stlink_t *sl) { +int _stlink_sg_core_id(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; + int ret; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READCOREID; sl->q_len = 4; sg->q_addr = 0; - stlink_q(sl); + ret = stlink_q(sl); + if (ret) + return ret; + sl->core_id = read_uint32(sl->q_buf, 0); + return 0; } // Arm-core reset -> halted state. -void _stlink_sg_reset(stlink_t *sl) { +int _stlink_sg_reset(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_RESETSYS; sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "core reset"); + return 0; } // Arm-core reset -> halted state. -void _stlink_sg_jtag_reset(stlink_t *sl, int value) { +int _stlink_sg_jtag_reset(stlink_t *sl, int value) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_JTAG_DRIVE_NRST; sg->cdb_cmd_blk[2] = (value)?0:1; sl->q_len = 3; sg->q_addr = 2; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "core reset"); + + return 0; } // Arm-core status: halted or running. -void _stlink_sg_status(stlink_t *sl) { +int _stlink_sg_status(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS; sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + return stlink_q(sl); } // Force the core into the debug mode -> halted state. -void _stlink_sg_force_debug(stlink_t *sl) { +int _stlink_sg_force_debug(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_FORCEDEBUG; sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "force debug"); + return 0; } // Read all arm-core registers. -void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { +int _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READALLREGS; sl->q_len = 84; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_print_data(sl); // TODO - most of this should be re-extracted up.... @@ -590,27 +609,31 @@ void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { regp->rw = read_uint32(sl->q_buf, 76); regp->rw2 = read_uint32(sl->q_buf, 80); if (sl->verbose < 2) - return; + return 0; DLOG("xpsr = 0x%08x\n", regp->xpsr); DLOG("main_sp = 0x%08x\n", regp->main_sp); DLOG("process_sp = 0x%08x\n", regp->process_sp); DLOG("rw = 0x%08x\n", regp->rw); DLOG("rw2 = 0x%08x\n", regp->rw2); + + return 0; } // Read an arm-core register, the index must be in the range 0..20. // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 -void _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) { +int _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READREG; sg->cdb_cmd_blk[2] = r_idx; sl->q_len = 4; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71 | 72-75 | 76-79 | 80-83 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 @@ -638,13 +661,15 @@ void _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) { default: regp->r[r_idx] = r; } + + return 0; } // Write an arm-core register. Index: // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 -void _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { +int _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEREG; @@ -654,8 +679,11 @@ void _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { write_uint32(sg->cdb_cmd_blk + 3, reg); sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "write reg"); + return 0; } // Write a register of the debug module of the core. @@ -679,26 +707,33 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { // Force the core exit the debug mode. -void _stlink_sg_run(stlink_t *sl) { +int _stlink_sg_run(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE; sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "run core"); + + return 0; } // Step the arm-core. -void _stlink_sg_step(stlink_t *sl) { +int _stlink_sg_step(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_STEPCORE; sl->q_len = 2; sg->q_addr = 0; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_stat(sl, "step core"); + return 0; } // TODO test @@ -738,7 +773,7 @@ void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { // Read a "len" bytes to the sl->q_buf from the memory, max 6kB (6144 bytes) -void _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READMEM_32BIT; @@ -754,14 +789,19 @@ void _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { // (broken residue issue) sl->q_len = len; sg->q_addr = addr; - stlink_q(sl); + if (stlink_q(sl)) + return -1; + stlink_print_data(sl); + return 0; } // Write a "len" bytes from the sl->q_buf to the memory, max 64 Bytes. -void _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; + int ret; + clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_8BIT; // 2-5: addr @@ -770,16 +810,27 @@ void _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint16(sg->cdb_cmd_blk + 6, len); // this sends the command... - send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + ret = send_usb_mass_storage_command(sg->usb_handle, + sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + if (ret == -1) + return ret; + // This sends the data... - send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len); + ret = send_usb_data_only(sg->usb_handle, + sg->ep_req, sg->ep_rep, sl->q_buf, len); + if (ret == -1) + return ret; + stlink_print_data(sl); + return 0; } // Write a "len" bytes from the sl->q_buf to the memory, max Q_BUF_LEN bytes. -void _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; + int ret; + clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_32BIT; // 2-5: addr @@ -788,16 +839,24 @@ void _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { write_uint16(sg->cdb_cmd_blk + 6, len); // this sends the command... - send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + ret = send_usb_mass_storage_command(sg->usb_handle, + sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); + if (ret == -1) + return ret; + // This sends the data... - send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len); + ret = send_usb_data_only(sg->usb_handle, + sg->ep_req, sg->ep_rep, sl->q_buf, len); + if (ret == -1) + return ret; stlink_print_data(sl); + return 0; } // Write one DWORD data to memory -void _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { +int _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_JTAG_WRITEDEBUG_32BIT; @@ -805,36 +864,38 @@ void _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint32(sg->cdb_cmd_blk + 6, data); sl->q_len = 2; - stlink_q(sl); - + return stlink_q(sl); } // Read one DWORD data from memory -void _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { +int _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_JTAG_READDEBUG_32BIT; // 2-5: addr write_uint32(sg->cdb_cmd_blk + 2, addr); sl->q_len = 8; - stlink_q(sl); + if (stlink_q(sl)) + return -1; *data = read_uint32(sl->q_buf, 4); - return; + return 0; } // Exit the jtag or swd mode and enter the mass mode. -void _stlink_sg_exit_debug_mode(stlink_t *stl) { - +int _stlink_sg_exit_debug_mode(stlink_t *stl) +{ if (stl) { struct stlink_libsg* sl = stl->backend_data; clear_cdb(sl); sl->cdb_cmd_blk[1] = STLINK_DEBUG_EXIT; stl->q_len = 0; // >0 -> aboard - stlink_q(stl); + return stlink_q(stl); } + + return 0; } diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 927e44e..8e52c68 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -93,7 +93,7 @@ static int fill_command return i; } -void _stlink_usb_version(stlink_t *sl) { +int _stlink_usb_version(stlink_t *sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -106,8 +106,10 @@ void _stlink_usb_version(stlink_t *sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } int32_t _stlink_usb_target_voltage(stlink_t *sl) { @@ -138,7 +140,7 @@ int32_t _stlink_usb_target_voltage(stlink_t *sl) { return voltage; } -void _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { +int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const rdata = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -152,13 +154,13 @@ void _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } *data = read_uint32(rdata, 4); - return; + return 0; } -void _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { +int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const rdata = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -173,37 +175,54 @@ void _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; + int i, ret; - int i = fill_command(sl, SG_DXFER_TO_DEV, len); + i = fill_command(sl, SG_DXFER_TO_DEV, len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_WRITEMEM_32BIT; write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); - send_only(slu, 0, cmd, slu->cmd_len); + ret = send_only(slu, 0, cmd, slu->cmd_len); + if (ret == -1) + return ret; + + ret = send_only(slu, 1, data, len); + if (ret == -1) + return ret; - send_only(slu, 1, data, len); + return 0; } -void _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; + int i, ret; - int i = fill_command(sl, SG_DXFER_TO_DEV, 0); + i = fill_command(sl, SG_DXFER_TO_DEV, 0); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_WRITEMEM_8BIT; write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); - send_only(slu, 0, cmd, slu->cmd_len); - send_only(slu, 1, data, len); + ret = send_only(slu, 0, cmd, slu->cmd_len); + if (ret == -1) + return ret; + + ret = send_only(slu, 1, data, len); + if (ret == -1) + return ret; + + return 0; } @@ -224,7 +243,7 @@ int _stlink_usb_current_mode(stlink_t * sl) { return sl->q_buf[0]; } -void _stlink_usb_core_id(stlink_t * sl) { +int _stlink_usb_core_id(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; @@ -238,13 +257,14 @@ void _stlink_usb_core_id(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return -1; } sl->core_id = read_uint32(data, 0); + return 0; } -void _stlink_usb_status(stlink_t * sl) { +int _stlink_usb_status(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -258,12 +278,14 @@ void _stlink_usb_status(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } sl->q_len = (size_t) size; + + return 0; } -void _stlink_usb_force_debug(stlink_t *sl) { +int _stlink_usb_force_debug(stlink_t *sl) { struct stlink_libusb *slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -276,11 +298,13 @@ void _stlink_usb_force_debug(stlink_t *sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_enter_swd_mode(stlink_t * sl) { +int _stlink_usb_enter_swd_mode(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -294,11 +318,13 @@ void _stlink_usb_enter_swd_mode(stlink_t * sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_exit_dfu_mode(stlink_t* sl) { +int _stlink_usb_exit_dfu_mode(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -310,15 +336,17 @@ void _stlink_usb_exit_dfu_mode(stlink_t* sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } /** * TODO - not convinced this does anything... * @param sl */ -void _stlink_usb_reset(stlink_t * sl) { +int _stlink_usb_reset(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -332,12 +360,14 @@ void _stlink_usb_reset(stlink_t * sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_jtag_reset(stlink_t * sl, int value) { +int _stlink_usb_jtag_reset(stlink_t * sl, int value) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -352,12 +382,14 @@ void _stlink_usb_jtag_reset(stlink_t * sl, int value) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_step(stlink_t* sl) { +int _stlink_usb_step(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -371,15 +403,17 @@ void _stlink_usb_step(stlink_t* sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } /** * This seems to do a good job of restarting things from the beginning? * @param sl */ -void _stlink_usb_run(stlink_t* sl) { +int _stlink_usb_run(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -393,11 +427,13 @@ void _stlink_usb_run(stlink_t* sl) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } + + return 0; } -void _stlink_usb_exit_debug_mode(stlink_t *sl) { +int _stlink_usb_exit_debug_mode(stlink_t *sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -409,11 +445,13 @@ void _stlink_usb_exit_debug_mode(stlink_t *sl) { size = send_only(slu, 1, cmd, slu->cmd_len); if (size == -1) { printf("[!] send_only\n"); - return; + return size; } + + return 0; } -void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { +int _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -428,15 +466,16 @@ void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } sl->q_len = (size_t) size; stlink_print_data(sl); + return 0; } -void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { +int _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; @@ -449,7 +488,7 @@ void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } sl->q_len = (size_t) size; stlink_print_data(sl); @@ -461,16 +500,18 @@ void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) { regp->rw = read_uint32(sl->q_buf, 76); regp->rw2 = read_uint32(sl->q_buf, 80); if (sl->verbose < 2) - return; + return 0; DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, 64)); DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, 68)); DLOG("process_sp = 0x%08x\n", read_uint32(sl->q_buf, 72)); DLOG("rw = 0x%08x\n", read_uint32(sl->q_buf, 76)); DLOG("rw2 = 0x%08x\n", read_uint32(sl->q_buf, 80)); + + return 0; } -void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { +int _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -485,7 +526,7 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } sl->q_len = (size_t) size; stlink_print_data(sl); @@ -511,19 +552,27 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { default: regp->r[r_idx] = r; } + + return 0; } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ -void _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { +int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { uint32_t r; + int ret; sl->q_buf[0] = (unsigned char) r_idx; for (int i = 1; i < 4; i++) { sl->q_buf[i] = 0; } - _stlink_usb_write_mem32(sl, DCRSR, 4); + ret = _stlink_usb_write_mem32(sl, DCRSR, 4); + if (ret == -1) + return ret; + _stlink_usb_read_mem32(sl, DCRDR, 4); + if (ret == -1) + return ret; r = read_uint32(sl->q_buf, 0); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); @@ -542,22 +591,39 @@ void _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { regp->s[r_idx - 0x40] = r; break; } + + return 0; } -void _stlink_usb_read_all_unsupported_regs(stlink_t *sl, reg *regp) { - _stlink_usb_read_unsupported_reg(sl, 0x14, regp); - _stlink_usb_read_unsupported_reg(sl, 0x21, regp); +int _stlink_usb_read_all_unsupported_regs(stlink_t *sl, reg *regp) { + int ret; + + ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); + if (ret == -1) + return ret; + + ret = _stlink_usb_read_unsupported_reg(sl, 0x21, regp); + if (ret == -1) + return ret; for (int i = 0; i < 32; i++) { - _stlink_usb_read_unsupported_reg(sl, 0x40+i, regp); + ret = _stlink_usb_read_unsupported_reg(sl, 0x40+i, regp); + if (ret == -1) + return ret; } + + return 0; } /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ -void _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *regp) { +int _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, reg *regp) { + int ret; + if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ /* These are held in the same register */ - _stlink_usb_read_unsupported_reg(sl, 0x14, regp); + ret = _stlink_usb_read_unsupported_reg(sl, 0x14, regp); + if (ret == -1) + return ret; val = (uint8_t) (val>>24); @@ -581,17 +647,19 @@ void _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, re write_uint32(sl->q_buf, val); - _stlink_usb_write_mem32(sl, DCRDR, 4); + ret = _stlink_usb_write_mem32(sl, DCRDR, 4); + if (ret == -1) + return ret; sl->q_buf[0] = (unsigned char) r_idx; sl->q_buf[1] = 0; sl->q_buf[2] = 0x01; sl->q_buf[3] = 0; - _stlink_usb_write_mem32(sl, DCRSR, 4); + return _stlink_usb_write_mem32(sl, DCRSR, 4); } -void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { +int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -606,10 +674,12 @@ void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv\n"); - return; + return size; } sl->q_len = (size_t) size; stlink_print_data(sl); + + return 0; } stlink_backend_t _stlink_usb_backend = {