summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/hwstub/stub/main.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/utils/hwstub/stub/main.c b/utils/hwstub/stub/main.c
index e31c5d1b8b..8139615239 100644
--- a/utils/hwstub/stub/main.c
+++ b/utils/hwstub/stub/main.c
@@ -19,6 +19,7 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "stddef.h" 21#include "stddef.h"
22#include "config.h"
22#include "protocol.h" 23#include "protocol.h"
23#include "logf.h" 24#include "logf.h"
24#include "usb_ch9.h" 25#include "usb_ch9.h"
@@ -402,17 +403,35 @@ static void handle_exec(struct usb_ctrlrequest *req)
402 struct hwstub_exec_req_t *exec = (void *)usb_buffer; 403 struct hwstub_exec_req_t *exec = (void *)usb_buffer;
403 if(size != sizeof(struct hwstub_exec_req_t)) 404 if(size != sizeof(struct hwstub_exec_req_t))
404 return usb_drv_stall(EP_CONTROL, true, true); 405 return usb_drv_stall(EP_CONTROL, true, true);
405 usb_drv_send(EP_CONTROL, NULL, 0); 406 uint32_t addr = exec->dAddress;
406#if 0 407 if(exec->bmFlags & HWSTUB_EXEC_THUMB)
407 if(req->bRequest == HWSTUB_CALL) 408 addr |= 1;
408 ((void (*)(void))addr)(); 409 else
410 addr &= ~1;
411
412 if(exec->bmFlags & HWSTUB_EXEC_CALL)
413 {
414#ifdef CPU_ARM
415 /* in case of call, respond after return */
416 asm volatile("blx %0\n" : : "r"(addr) : "memory");
417 usb_drv_send(EP_CONTROL, NULL, 0);
418#else
419#warning call is unsupported on this platform
420 usb_drv_stall(EP_CONTROL, true, true);
421#endif
422 }
409 else 423 else
410 { 424 {
411 /* disconnect to make sure usb/dma won't interfere */ 425 /* in case of jump, respond immediately and disconnect usb */
426 usb_drv_send(EP_CONTROL, NULL, 0);
412 usb_drv_exit(); 427 usb_drv_exit();
428#ifdef CPU_ARM
413 asm volatile("bx %0\n" : : "r" (addr) : "memory"); 429 asm volatile("bx %0\n" : : "r" (addr) : "memory");
414 } 430#else
431#warning jump is unsupported on this platform
432 usb_drv_stall(EP_CONTROL, true, true);
415#endif 433#endif
434 }
416} 435}
417 436
418static void handle_class_intf_req(struct usb_ctrlrequest *req) 437static void handle_class_intf_req(struct usb_ctrlrequest *req)