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;
}
-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:
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
*/
}
-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....
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
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;
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.
// 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
// 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;
// (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
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
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;
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;
}
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;
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) {
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;
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;
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;
}
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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);
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;
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);
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);
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);
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;
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 = {