Support arm core cpuid register decoding
[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, sizeof (sl->q_buf));
159     if (size == -1) {
160         printf("[!] send_recv\n");
161         return;
162     }
163
164 #if 1 /* DEBUG */
165     {
166         unsigned int 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     DD(sl, "oops! no write32 support yet, wanted to write %d bytes to %#x\n",
175             len, addr);
176 }
177
178 void _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) {
179     DD(sl, "oops! no write8 support yet, wanted to write %d bytes to %#x\n",
180             len, addr);
181 }
182
183
184 int _stlink_usb_current_mode(stlink_t * sl) {
185     struct stlink_libusb * const slu = sl->backend_data;
186     unsigned char* const buf = sl->q_buf;
187     ssize_t size;
188     memset(buf, 0, sizeof (sl->q_buf));
189     buf[0] = STLINK_GET_CURRENT_MODE;
190     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
191     if (size == -1) {
192         printf("[!] send_recv\n");
193         return -1;
194     }
195     return sl->q_buf[0];
196 }
197
198 void _stlink_usb_core_id(stlink_t * sl) {
199     struct stlink_libusb * const slu = sl->backend_data;
200     unsigned char* const buf = sl->q_buf;
201     ssize_t size;
202
203     memset(buf, 0, sizeof (sl->q_buf));
204     buf[0] = STLINK_DEBUG_COMMAND;
205     buf[1] = STLINK_DEBUG_READCOREID;
206
207     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
208     if (size == -1) {
209         printf("[!] send_recv\n");
210         return;
211     }
212
213     sl->core_id = read_uint32(buf, 0);
214 }
215
216 void _stlink_usb_status(stlink_t * sl) {
217     struct stlink_libusb * const slu = sl->backend_data;
218     unsigned char* const buf = sl->q_buf;
219     ssize_t size;
220
221     memset(buf, 0, sizeof (sl->q_buf));
222
223     buf[0] = STLINK_DEBUG_COMMAND;
224     buf[1] = STLINK_DEBUG_GETSTATUS;
225
226     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
227     if (size == -1) {
228         printf("[!] send_recv\n");
229         return;
230     }
231
232     /* todo: stlink_core_stat */
233
234     // FIXME - decode into sl->core_stat
235 #if 1 /* DEBUG */
236     printf("status == 0x%x\n", buf[0]);
237 #endif /* DEBUG */
238
239 }
240
241 void _stlink_usb_force_debug(stlink_t *sl) {
242     struct stlink_libusb *slu = sl->backend_data;
243     unsigned char* const buf = sl->q_buf;
244     ssize_t size;
245
246     memset(buf, 0, sizeof (sl->q_buf));
247
248     buf[0] = STLINK_DEBUG_COMMAND;
249     buf[1] = STLINK_DEBUG_FORCEDEBUG;
250     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
251     if (size == -1) {
252         printf("[!] send_recv\n");
253         return;
254     }
255 }
256
257
258 void _stlink_usb_enter_swd_mode(stlink_t * sl) {
259     struct stlink_libusb * const slu = sl->backend_data;
260     unsigned char* const buf = sl->q_buf;
261     ssize_t size;
262
263     memset(buf, 0, sizeof (sl->q_buf));
264
265     buf[0] = STLINK_DEBUG_COMMAND;
266     buf[1] = STLINK_SWD_ENTER;
267     buf[2] = STLINK_DEBUG_ENTER_SWD;
268
269     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
270     if (size == -1) {
271         printf("[!] send_recv\n");
272         return;
273     }
274 }
275
276 void _stlink_usb_exit_dfu_mode(stlink_t* sl) {
277     struct stlink_libusb * const slu = sl->backend_data;
278     unsigned char* const buf = sl->q_buf;
279     ssize_t size;
280
281     memset(buf, 0, sizeof (sl->q_buf));
282     buf[0] = STLINK_DFU_COMMAND;
283     buf[1] = STLINK_DFU_EXIT;
284
285     size = send_only(slu, buf, 16);
286     if (size == -1) {
287         printf("[!] send_recv\n");
288         return;
289     }
290 }
291
292 void _stlink_usb_reset(stlink_t * sl) {
293     struct stlink_libusb * const slu = sl->backend_data;
294     unsigned char* const buf = sl->q_buf;
295     ssize_t size;
296
297     memset(buf, 0, sizeof (sl->q_buf));
298     buf[0] = STLINK_DEBUG_COMMAND;
299     buf[1] = STLINK_DEBUG_RESETSYS;
300
301     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
302     if (size == -1) {
303         printf("[!] send_recv\n");
304         return;
305     }
306 }
307
308
309 void _stlink_usb_step(stlink_t* sl) {
310     struct stlink_libusb * const slu = sl->backend_data;
311     unsigned char* const buf = sl->q_buf;
312     ssize_t size;
313
314     memset(buf, 0, sizeof (sl->q_buf));
315     buf[0] = STLINK_DEBUG_COMMAND;
316     buf[1] = STLINK_DEBUG_STEPCORE;
317
318     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
319     if (size == -1) {
320         printf("[!] send_recv\n");
321         return;
322     }
323 }
324
325 void _stlink_usb_run(stlink_t* sl) {
326     struct stlink_libusb * const slu = sl->backend_data;
327     unsigned char* const buf = sl->q_buf;
328     ssize_t size;
329
330     memset(buf, 0, sizeof (sl->q_buf));
331     buf[0] = STLINK_DEBUG_COMMAND;
332     buf[1] = STLINK_DEBUG_RUNCORE;
333
334     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
335     if (size == -1) {
336         printf("[!] send_recv\n");
337         return;
338     }
339
340 }
341
342 void _stlink_usb_exit_debug_mode(stlink_t *sl) {
343     struct stlink_libusb * const slu = sl->backend_data;
344     unsigned char* const buf = sl->q_buf;
345     ssize_t size;
346
347     memset(buf, 0, sizeof (sl->q_buf));
348     buf[0] = STLINK_DEBUG_COMMAND;
349     buf[1] = STLINK_DEBUG_EXIT;
350
351     size = send_only(slu, buf, 16);
352     if (size == -1) {
353         printf("[!] send_only\n");
354         return;
355     }
356 }
357
358 void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
359     struct stlink_libusb * const slu = sl->backend_data;
360     unsigned char* const buf = sl->q_buf;
361     ssize_t size;
362
363     /* assume len < sizeof(sl->q_buf) */
364     assert(len < sizeof(sl->q_buf));  // makes a compiler warning? always true?
365
366     memset(buf, 0, sizeof (sl->q_buf));
367     buf[0] = STLINK_DEBUG_COMMAND;
368     buf[1] = STLINK_DEBUG_READMEM_32BIT;
369     write_uint32(buf + 2, addr);
370     /* windows usb logs show only one byte is used for length ... */
371     // Presumably, this is because usb transfers can't be 16 bits worth of bytes long...
372     assert (len < 256);
373     buf[6] = (uint8_t) len;
374
375     size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
376     if (size == -1) {
377         printf("[!] send_recv\n");
378         return;
379     }
380
381     sl->q_len = (size_t) size;
382
383     stlink_print_data(sl);
384 }
385
386 void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) {
387     DD(sl, "oops! read_all_regs not implemented for USB!\n");
388 }
389
390 void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) {
391     DD(sl, "oops! read_reg not implemented for USB! Wanted to read reg %d\n",
392             r_idx);
393 }
394
395 void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) {
396     DD(sl, "oops! write_reg not implemented for USB! Wanted to write %#x to %d\n",
397             reg, idx);
398 }
399
400
401
402 stlink_backend_t _stlink_usb_backend = {
403     _stlink_usb_close,
404     _stlink_usb_exit_debug_mode,
405     _stlink_usb_enter_swd_mode,
406     NULL,  // no enter_jtag_mode here...
407     _stlink_usb_exit_dfu_mode,
408     _stlink_usb_core_id,
409     _stlink_usb_reset,
410     _stlink_usb_run,
411     _stlink_usb_status,
412     _stlink_usb_version,
413     _stlink_usb_read_mem32,
414     _stlink_usb_write_mem32,
415     _stlink_usb_write_mem8,
416     _stlink_usb_read_all_regs,
417     _stlink_usb_read_reg,
418     _stlink_usb_write_reg,
419     _stlink_usb_step,
420     _stlink_usb_current_mode,
421     _stlink_usb_force_debug
422 };
423
424
425 stlink_t* stlink_open_usb(const char *dev_name, const int verbose) {
426     stlink_t* sl = NULL;
427     struct stlink_libusb* slu = NULL;
428
429     sl = malloc(sizeof (stlink_t));
430     slu = malloc(sizeof (struct stlink_libusb));
431     if (sl == NULL) goto on_error;
432     if (slu == NULL) goto on_error;
433
434     sl->verbose = verbose;
435     
436     if (slu->libusb_ctx != NULL) {
437         fprintf(stderr, "reopening with an existing context? undefined behaviour!\n");
438         goto on_error;
439     } else {
440         if (libusb_init(&(slu->libusb_ctx))) {
441             fprintf(stderr, "failed to init libusb context, wrong version of libraries?\n");
442             goto on_error;
443         }
444     }
445
446     int error = -1;
447
448     libusb_device** devs = NULL;
449     libusb_device* dev;
450     ssize_t i;
451     ssize_t count;
452     int config;
453
454     count = libusb_get_device_list(slu->libusb_ctx, &devs);
455     if (count < 0) {
456         printf("libusb_get_device_list\n");
457         goto on_libusb_error;
458     }
459
460     for (i = 0; i < count; ++i) {
461         dev = devs[i];
462         if (is_stlink_device(dev)) break;
463     }
464     if (i == count) return NULL;
465
466     if (libusb_open(dev, &(slu->usb_handle))) {
467         printf("libusb_open()\n");
468         goto on_libusb_error;
469     }
470
471     if (libusb_get_configuration(slu->usb_handle, &config)) {
472         /* this may fail for a previous configured device */
473         printf("libusb_get_configuration()\n");
474         goto on_libusb_error;
475     }
476
477     if (config != 1) {
478         printf("setting new configuration (%d -> 1)\n", config);
479         if (libusb_set_configuration(slu->usb_handle, 1)) {
480             /* this may fail for a previous configured device */
481             printf("libusb_set_configuration()\n");
482             goto on_libusb_error;
483         }
484     }
485
486     if (libusb_claim_interface(slu->usb_handle, 0)) {
487         printf("libusb_claim_interface()\n");
488         goto on_libusb_error;
489     }
490
491     slu->req_trans = libusb_alloc_transfer(0);
492     if (slu->req_trans == NULL) {
493         printf("libusb_alloc_transfer\n");
494         goto on_libusb_error;
495     }
496
497     slu->rep_trans = libusb_alloc_transfer(0);
498     if (slu->rep_trans == NULL) {
499         printf("libusb_alloc_transfer\n");
500         goto on_libusb_error;
501     }
502
503     slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN;
504     slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
505
506     /* libusb_reset_device(slu->usb_handle); */
507
508     /* success */
509     error = 0;
510
511 on_libusb_error:
512     if (devs != NULL) {
513         libusb_free_device_list(devs, 1);
514         fprintf(stderr, "freed libusb device list\n");
515     }
516
517     if (error == -1) {
518         stlink_close(sl);
519         return NULL;
520     }
521
522     sl->backend = &_stlink_usb_backend;
523     sl->backend_data = slu;
524     /* success */
525     return sl;
526
527 on_error:
528     if (sl != NULL) free(sl);
529     if (slu != NULL) free(slu);
530     return 0;
531 }
532