diff options
Diffstat (limited to 'utils/hwstub/stub/main.c')
-rw-r--r-- | utils/hwstub/stub/main.c | 31 |
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 | ||
418 | static void handle_class_intf_req(struct usb_ctrlrequest *req) | 437 | static void handle_class_intf_req(struct usb_ctrlrequest *req) |