Assert size only if Q_BUF_LEN is smaller UINT16_MAX
[fw/stlink] / src / stlink-usb.c
1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdint.h>
6 #include <time.h>
7 #include <sys/types.h>
8 #include <libusb-1.0/libusb.h>
9 #include "stlink-common.h"
10 #include "stlink-usb.h"
11
12 void _stlink_usb_close(stlink_t* sl) {
13     struct stlink_libusb * const handle = sl->backend_data;
14     // maybe we couldn't even get the usb device?
15     if (handle != NULL) {
16         if (handle->req_trans != NULL)
17             libusb_free_transfer(handle->req_trans);
18
19         if (handle->rep_trans != NULL)
20             libusb_free_transfer(handle->rep_trans);
21
22         if (handle->usb_handle != NULL)
23             libusb_close(handle->usb_handle);
24
25         libusb_exit(handle->libusb_ctx);
26         free(handle);
27     }
28 }
29
30
31 struct trans_ctx {
32 #define TRANS_FLAGS_IS_DONE (1 << 0)
33 #define TRANS_FLAGS_HAS_ERROR (1 << 1)
34     volatile unsigned long flags;
35 };
36
37 static void on_trans_done(struct libusb_transfer * trans) {
38     struct trans_ctx * const ctx = trans->user_data;
39
40     if (trans->status != LIBUSB_TRANSFER_COMPLETED)
41         ctx->flags |= TRANS_FLAGS_HAS_ERROR;
42
43     ctx->flags |= TRANS_FLAGS_IS_DONE;
44 }
45
46 int submit_wait(struct stlink_libusb *slu, struct libusb_transfer * trans) {
47     struct timeval start;
48     struct timeval now;
49     struct timeval diff;
50     struct trans_ctx trans_ctx;
51     enum libusb_error error;
52
53     trans_ctx.flags = 0;
54
55     /* brief intrusion inside the libusb interface */
56     trans->callback = on_trans_done;
57     trans->user_data = &trans_ctx;
58
59     if ((error = libusb_submit_transfer(trans))) {
60         printf("libusb_submit_transfer(%d)\n", error);
61         return -1;
62     }
63
64     gettimeofday(&start, NULL);
65
66     while (trans_ctx.flags == 0) {
67         struct timeval timeout;
68         timeout.tv_sec = 3;
69         timeout.tv_usec = 0;
70         if (libusb_handle_events_timeout(slu->libusb_ctx, &timeout)) {
71             printf("libusb_handle_events()\n");
72             return -1;
73         }
74
75         gettimeofday(&now, NULL);
76         timersub(&now, &start, &diff);
77         if (diff.tv_sec >= 3) {
78             printf("libusb_handle_events() timeout\n");
79             return -1;
80         }
81     }
82
83     if (trans_ctx.flags & TRANS_FLAGS_HAS_ERROR) {
84         printf("libusb_handle_events() | has_error\n");
85         return -1;
86     }
87
88     return 0;
89 }
90
91 ssize_t send_recv(struct stlink_libusb* handle,
92         unsigned char* txbuf, size_t txsize,
93         unsigned char* rxbuf, size_t rxsize) {
94     /* note: txbuf and rxbuf can point to the same area */
95
96     libusb_fill_bulk_transfer(handle->req_trans, handle->usb_handle,
97             handle->ep_req,
98             txbuf, txsize,
99             NULL, NULL,
100             0
101             );
102
103     printf("submit_wait(req)\n");
104
105     if (submit_wait(handle, handle->req_trans)) return -1;
106
107     /* send_only */
108     if (rxsize == 0) return 0;
109
110     /* read the response */
111
112     libusb_fill_bulk_transfer(handle->rep_trans, handle->usb_handle,
113             handle->ep_rep, rxbuf, rxsize, NULL, NULL, 0);
114
115     printf("submit_wait(rep)\n");
116
117     if (submit_wait(handle, handle->rep_trans)) return -1;
118
119     return handle->rep_trans->actual_length;
120 }
121
122 static inline int send_only
123 (struct stlink_libusb* handle, unsigned char* txbuf, size_t txsize) {
124     return send_recv(handle, txbuf, txsize, NULL, 0);
125 }
126
127
128 // KARL - fixme, common code! (or, one per backend)
129 // candidate for common code...
130
131
132 static int is_stlink_device(libusb_device * dev) {
133     struct libusb_device_descriptor desc;
134
135     if (libusb_get_device_descriptor(dev, &desc))
136         return 0;
137
138     printf("device: 0x%04x, 0x%04x\n", desc.idVendor, desc.idProduct);
139
140     if (desc.idVendor != USB_ST_VID)
141         return 0;
142
143     if (desc.idProduct != USB_STLINK_32L_PID)
144         return 0;
145
146     return 1;
147 }
148
149 void _stlink_usb_version(stlink_t *sl) {
150     struct stlink_libusb * const slu = sl->backend_data;
151     unsigned char* const buf = sl->q_buf;
152     ssize_t size;
153
154     memset(buf, 0, sizeof (sl->q_buf));
155     buf[0] = STLINK_GET_VERSION;
156     buf[1] = 0x80;
157
158     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 6);
159     if (size == -1) {
160         printf("[!] send_recv\n");
161         return;
162     }
163
164 #if 1 /* DEBUG */
165     {
166         ssize_t i;
167         for (i = 0; i < size; ++i) printf("%02x", buf[i]);
168         printf("\n");
169     }
170 #endif /* DEBUG */
171 }
172
173 void _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
174     struct stlink_libusb * const slu = sl->backend_data;
175     unsigned char* const buf = sl->q_buf;
176     unsigned char *cmd_buf = sl->c_buf;
177
178     memset(cmd_buf, 0, STLINK_CMD_SIZE);
179     cmd_buf[0] = STLINK_DEBUG_COMMAND;
180     cmd_buf[1] =  STLINK_DEBUG_WRITEMEM_32BIT;
181     write_uint32(cmd_buf + 2, addr);
182     write_uint16(cmd_buf + 6, len);
183     send_only(slu, cmd_buf, STLINK_CMD_SIZE);
184
185 #if Q_BUF_LEN < UINT16_MAX
186     assert(len < sizeof(sl->q_buf));  // makes a compiler warning? always true?
187 #endif
188     assert((len & 3) == 0); 
189     stlink_print_data(sl);
190     send_only(slu, buf, len);
191
192 }
193
194 void _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) {
195     struct stlink_libusb * const slu = sl->backend_data;
196     unsigned char* const buf = sl->q_buf;
197     unsigned char *cmd_buf = sl->c_buf;
198
199     memset(cmd_buf, 0, STLINK_CMD_SIZE);
200     cmd_buf[0] = STLINK_DEBUG_COMMAND;
201     cmd_buf[1] =  STLINK_DEBUG_WRITEMEM_8BIT;
202     write_uint32(cmd_buf + 2, addr);
203     write_uint16(cmd_buf + 6, len);
204     send_only(slu, cmd_buf, STLINK_CMD_SIZE);
205
206 #if Q_BUF_LEN < UINT16_MAX
207     assert(len < sizeof(sl->q_buf));  // makes a compiler warning? always true?
208 #endif
209     stlink_print_data(sl);
210     send_only(slu, buf, len);
211 }
212
213
214 int _stlink_usb_current_mode(stlink_t * sl) {
215     struct stlink_libusb * const slu = sl->backend_data;
216     unsigned char* const buf = sl->q_buf;
217     ssize_t size;
218     memset(buf, 0, sizeof (sl->q_buf));
219     buf[0] = STLINK_GET_CURRENT_MODE;
220     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2);
221     if (size == -1) {
222         printf("[!] send_recv\n");
223         return -1;
224     }
225     return sl->q_buf[0];
226 }
227
228 void _stlink_usb_core_id(stlink_t * sl) {
229     struct stlink_libusb * const slu = sl->backend_data;
230     unsigned char* const buf = sl->q_buf;
231     ssize_t size;
232
233     memset(buf, 0, sizeof (sl->q_buf));
234     buf[0] = STLINK_DEBUG_COMMAND;
235     buf[1] = STLINK_DEBUG_READCOREID;
236
237     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 4);
238     if (size == -1) {
239         printf("[!] send_recv\n");
240         return;
241     }
242
243     sl->core_id = read_uint32(buf, 0);
244 }
245
246 void _stlink_usb_status(stlink_t * sl) {
247     struct stlink_libusb * const slu = sl->backend_data;
248     unsigned char* const buf = sl->q_buf;
249     ssize_t size;
250
251     memset(buf, 0, sizeof (sl->q_buf));
252
253     buf[0] = STLINK_DEBUG_COMMAND;
254     buf[1] = STLINK_DEBUG_GETSTATUS;
255
256     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2);
257     if (size == -1) {
258         printf("[!] send_recv\n");
259         return;
260     }
261
262     /* todo: stlink_core_stat */
263
264     // FIXME - decode into sl->core_stat
265 #if 1 /* DEBUG */
266     printf("status == 0x%x\n", buf[0]);
267 #endif /* DEBUG */
268
269 }
270
271 void _stlink_usb_force_debug(stlink_t *sl) {
272     struct stlink_libusb *slu = sl->backend_data;
273     unsigned char* const buf = sl->q_buf;
274     ssize_t size;
275
276     memset(buf, 0, sizeof (sl->q_buf));
277
278     buf[0] = STLINK_DEBUG_COMMAND;
279     buf[1] = STLINK_DEBUG_FORCEDEBUG;
280     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2);
281     if (size == -1) {
282         printf("[!] send_recv\n");
283         return;
284     }
285 }
286
287
288 void _stlink_usb_enter_swd_mode(stlink_t * sl) {
289     struct stlink_libusb * const slu = sl->backend_data;
290     unsigned char* const buf = sl->q_buf;
291     ssize_t size;
292
293     memset(buf, 0, sizeof (sl->q_buf));
294
295     buf[0] = STLINK_DEBUG_COMMAND;
296     buf[1] = STLINK_SWD_ENTER;
297     buf[2] = STLINK_DEBUG_ENTER_SWD;
298
299     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2);
300     if (size == -1) {
301         printf("[!] send_recv\n");
302         return;
303     }
304 }
305
306 void _stlink_usb_exit_dfu_mode(stlink_t* sl) {
307     struct stlink_libusb * const slu = sl->backend_data;
308     unsigned char* const buf = sl->q_buf;
309     ssize_t size;
310
311     memset(buf, 0, sizeof (sl->q_buf));
312     buf[0] = STLINK_DFU_COMMAND;
313     buf[1] = STLINK_DFU_EXIT;
314
315     size = send_only(slu, buf, 16);
316     if (size == -1) {
317         printf("[!] send_recv\n");
318         return;
319     }
320 }
321
322 /**
323  * TODO - not convinced this does anything...
324  * @param sl
325  */
326 void _stlink_usb_reset(stlink_t * sl) {
327     struct stlink_libusb * const slu = sl->backend_data;
328     unsigned char* const buf = sl->q_buf;
329     ssize_t size;
330
331     memset(buf, 0, sizeof (sl->q_buf));
332     buf[0] = STLINK_DEBUG_COMMAND;
333     buf[1] = STLINK_DEBUG_RESETSYS;
334
335     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
336     if (size == -1) {
337         printf("[!] send_recv\n");
338         return;
339     }
340 }
341
342
343 void _stlink_usb_step(stlink_t* sl) {
344     struct stlink_libusb * const slu = sl->backend_data;
345     unsigned char* const buf = sl->q_buf;
346     ssize_t size;
347
348     memset(buf, 0, sizeof (sl->q_buf));
349     buf[0] = STLINK_DEBUG_COMMAND;
350     buf[1] = STLINK_DEBUG_STEPCORE;
351
352     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2);
353     if (size == -1) {
354         printf("[!] send_recv\n");
355         return;
356     }
357 }
358
359 /**
360  * This seems to do a good job of restarting things from the beginning?
361  * @param sl
362  */
363 void _stlink_usb_run(stlink_t* sl) {
364     struct stlink_libusb * const slu = sl->backend_data;
365     unsigned char* const buf = sl->q_buf;
366     ssize_t size;
367
368     memset(buf, 0, sizeof (sl->q_buf));
369     buf[0] = STLINK_DEBUG_COMMAND;
370     buf[1] = STLINK_DEBUG_RUNCORE;
371
372     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, 2);
373     if (size == -1) {
374         printf("[!] send_recv\n");
375         return;
376     }
377
378 }
379
380 void _stlink_usb_exit_debug_mode(stlink_t *sl) {
381     struct stlink_libusb * const slu = sl->backend_data;
382     unsigned char* const buf = sl->q_buf;
383     ssize_t size;
384
385     memset(buf, 0, sizeof (sl->q_buf));
386     buf[0] = STLINK_DEBUG_COMMAND;
387     buf[1] = STLINK_DEBUG_EXIT;
388
389     size = send_only(slu, buf, 16);
390     if (size == -1) {
391         printf("[!] send_only\n");
392         return;
393     }
394 }
395
396 void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
397     struct stlink_libusb * const slu = sl->backend_data;
398     unsigned char* const buf = sl->q_buf;
399     ssize_t size;
400
401 #if Q_BUF_LEN < UINT16_MAX
402     assert(len < sizeof(sl->q_buf));
403 #endif
404
405     memset(buf, 0, sizeof (sl->q_buf));
406     buf[0] = STLINK_DEBUG_COMMAND;
407     buf[1] = STLINK_DEBUG_READMEM_32BIT;
408     write_uint32(buf + 2, addr);
409     /* windows usb logs show only one byte is used for length ... */
410     // Presumably, this is because usb transfers can't be 16 bits worth of bytes long...
411     assert (len < 256);
412     buf[6] = (uint8_t) len;
413
414     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, len);
415     if (size == -1) {
416         printf("[!] send_recv\n");
417         return;
418     }
419
420     sl->q_len = (size_t) size;
421
422     stlink_print_data(sl);
423 }
424
425 void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) {
426     struct stlink_libusb * const slu = sl->backend_data;
427     unsigned char* const buf = sl->q_buf;
428     unsigned char* const cmd_buf = sl->c_buf;
429     ssize_t size;
430     int i;
431
432     memset(cmd_buf, 0, STLINK_CMD_SIZE);
433     cmd_buf[0] = STLINK_DEBUG_COMMAND;
434     cmd_buf[1] = STLINK_DEBUG_READALLREGS;
435     size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 84);
436     if (size == -1) {
437         printf("[!] send_recv\n");
438         return;
439     }
440     sl->q_len = (size_t) size;
441     stlink_print_data(sl);
442     for(i=0; i<16; i++)
443         regp->r[i]= read_uint32(sl->q_buf, i*4);
444     regp->xpsr       = read_uint32(sl->q_buf, 64);
445     regp->main_sp    = read_uint32(sl->q_buf, 68);
446     regp->process_sp = read_uint32(sl->q_buf, 72);
447     regp->rw         = read_uint32(sl->q_buf, 76);
448     regp->rw2        = read_uint32(sl->q_buf, 80);
449     if (sl->verbose < 2)
450         return;
451
452     DD(sl, "xpsr       = 0x%08x\n", read_uint32(sl->q_buf, 64));
453     DD(sl, "main_sp    = 0x%08x\n", read_uint32(sl->q_buf, 68));
454     DD(sl, "process_sp = 0x%08x\n", read_uint32(sl->q_buf, 72));
455     DD(sl, "rw         = 0x%08x\n", read_uint32(sl->q_buf, 76));
456     DD(sl, "rw2        = 0x%08x\n", read_uint32(sl->q_buf, 80));
457 }
458
459 void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) {
460     struct stlink_libusb * const slu = sl->backend_data;
461     unsigned char* const buf = sl->q_buf;
462     unsigned char* const cmd_buf = sl->c_buf;
463     ssize_t size;
464     uint32_t r;
465
466     memset(cmd_buf, 0, STLINK_CMD_SIZE);
467     cmd_buf[0] = STLINK_DEBUG_COMMAND;
468     cmd_buf[1] = STLINK_DEBUG_READREG;
469     cmd_buf[2] = (uint8_t) r_idx;
470     size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 4);
471     if (size == -1) {
472         printf("[!] send_recv\n");
473         return;
474     }
475     sl->q_len = (size_t) size;
476     stlink_print_data(sl);
477     r = read_uint32(sl->q_buf, 0);
478     DD(sl, "r_idx (%2d) = 0x%08x\n", r_idx, r);
479     
480     switch (r_idx) {
481     case 16:
482         regp->xpsr = r;
483         break;
484     case 17:
485         regp->main_sp = r;
486         break;
487     case 18:
488         regp->process_sp = r;
489         break;
490     case 19:
491         regp->rw = r; //XXX ?(primask, basemask etc.)
492         break;
493     case 20:
494         regp->rw2 = r; //XXX ?(primask, basemask etc.)
495         break;
496     default:
497         regp->r[r_idx] = r;
498     }
499 }
500
501 void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) {
502     struct stlink_libusb * const slu = sl->backend_data;
503     unsigned char* const buf = sl->q_buf;
504     unsigned char *cmd_buf = sl->c_buf;
505     ssize_t size;
506
507     memset(cmd_buf, 0, STLINK_CMD_SIZE);
508     cmd_buf[0] = STLINK_DEBUG_COMMAND;
509     cmd_buf[1] = STLINK_DEBUG_WRITEREG;
510     cmd_buf[2] = idx;
511     write_uint32(cmd_buf + 3, reg);
512     size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 2);
513     if (size == -1) {
514         printf("[!] send_recv\n");
515         return;
516     }
517     sl->q_len = (size_t) size;
518     stlink_print_data(sl);
519 }
520
521 stlink_backend_t _stlink_usb_backend = {
522     _stlink_usb_close,
523     _stlink_usb_exit_debug_mode,
524     _stlink_usb_enter_swd_mode,
525     NULL,  // no enter_jtag_mode here...
526     _stlink_usb_exit_dfu_mode,
527     _stlink_usb_core_id,
528     _stlink_usb_reset,
529     _stlink_usb_run,
530     _stlink_usb_status,
531     _stlink_usb_version,
532     _stlink_usb_read_mem32,
533     _stlink_usb_write_mem32,
534     _stlink_usb_write_mem8,
535     _stlink_usb_read_all_regs,
536     _stlink_usb_read_reg,
537     _stlink_usb_write_reg,
538     _stlink_usb_step,
539     _stlink_usb_current_mode,
540     _stlink_usb_force_debug
541 };
542
543
544 stlink_t* stlink_open_usb(const char *dev_name, const int verbose) {
545     stlink_t* sl = NULL;
546     struct stlink_libusb* slu = NULL;
547
548     sl = malloc(sizeof (stlink_t));
549     slu = malloc(sizeof (struct stlink_libusb));
550     if (sl == NULL) goto on_error;
551     if (slu == NULL) goto on_error;
552
553     sl->verbose = verbose;
554     
555     if (slu->libusb_ctx != NULL) {
556         fprintf(stderr, "reopening with an existing context? undefined behaviour!\n");
557         goto on_error;
558     } else {
559         if (libusb_init(&(slu->libusb_ctx))) {
560             fprintf(stderr, "failed to init libusb context, wrong version of libraries?\n");
561             goto on_error;
562         }
563     }
564
565     int error = -1;
566
567     libusb_device** devs = NULL;
568     libusb_device* dev;
569     ssize_t i;
570     ssize_t count;
571     int config;
572
573     count = libusb_get_device_list(slu->libusb_ctx, &devs);
574     if (count < 0) {
575         printf("libusb_get_device_list\n");
576         goto on_libusb_error;
577     }
578
579     for (i = 0; i < count; ++i) {
580         dev = devs[i];
581         if (is_stlink_device(dev)) break;
582     }
583     if (i == count) return NULL;
584
585     if (libusb_open(dev, &(slu->usb_handle))) {
586         printf("libusb_open()\n");
587         goto on_libusb_error;
588     }
589
590     if (libusb_get_configuration(slu->usb_handle, &config)) {
591         /* this may fail for a previous configured device */
592         printf("libusb_get_configuration()\n");
593         goto on_libusb_error;
594     }
595
596     if (config != 1) {
597         printf("setting new configuration (%d -> 1)\n", config);
598         if (libusb_set_configuration(slu->usb_handle, 1)) {
599             /* this may fail for a previous configured device */
600             printf("libusb_set_configuration()\n");
601             goto on_libusb_error;
602         }
603     }
604
605     if (libusb_claim_interface(slu->usb_handle, 0)) {
606         printf("libusb_claim_interface()\n");
607         goto on_libusb_error;
608     }
609
610     slu->req_trans = libusb_alloc_transfer(0);
611     if (slu->req_trans == NULL) {
612         printf("libusb_alloc_transfer\n");
613         goto on_libusb_error;
614     }
615
616     slu->rep_trans = libusb_alloc_transfer(0);
617     if (slu->rep_trans == NULL) {
618         printf("libusb_alloc_transfer\n");
619         goto on_libusb_error;
620     }
621
622     slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN;
623     slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
624
625     /* libusb_reset_device(slu->usb_handle); */
626
627     /* success */
628     error = 0;
629
630 on_libusb_error:
631     if (devs != NULL) {
632         libusb_free_device_list(devs, 1);
633         fprintf(stderr, "freed libusb device list\n");
634     }
635
636     if (error == -1) {
637         stlink_close(sl);
638         return NULL;
639     }
640
641     sl->backend = &_stlink_usb_backend;
642     sl->backend_data = slu;
643     /* success */
644     return sl;
645
646 on_error:
647     if (sl != NULL) free(sl);
648     if (slu != NULL) free(slu);
649     return 0;
650 }
651