OpenOCD
linuxspidev.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /* Copyright (C) 2020 by Lup Yuen Lee <luppy@appkaki.com>
4  * Copyright (C) 2024 by Richard Pasek <rpasek@google.com>
5  */
6 
12 /* Uncomment to log SPI exchanges (very verbose, slows things down a lot)
13  *
14  * A quick note on interpreting SPI exchange messages:
15  *
16  * This implementation works by performing SPI exchanges with MOSI and MISO
17  * tied together with a 1K resistor. This combined signal becomes SWDIO.
18  *
19  * Since we are performing SPI exchanges, (reading and writing at the same
20  * time) this means when the target isn't driving SWDIO, what is written by
21  * the host should also be read by the host.
22  *
23  * On SWD writes:
24  * The TX and RX data should match except for the ACK bits from the target
25  * swd write reg exchange: len=6
26  * tx_buf=C5 02 40 00 02 2C
27  * rx_buf=C5 42 40 00 02 2C
28  * ^
29  * |
30  * ACK from target
31  *
32  * On SWD reads:
33  * Only the command byte should match
34  * swd read reg exchange: len=6
35  * tx_buf=B1 00 00 00 00 00
36  * rx_buf=B1 40 20 00 00 F8
37  * ^^
38  * ||
39  * Command packet from host
40  *
41  */
42 // #define LOG_SPI_EXCHANGE
43 
44 #ifdef HAVE_CONFIG_H
45 #include "config.h"
46 #endif
47 
48 #include <stdint.h>
49 #include <unistd.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <fcntl.h>
53 #include <sys/ioctl.h>
54 #include <linux/spi/spidev.h>
55 #include <jtag/adapter.h>
56 #include <jtag/swd.h>
57 #include <jtag/interface.h>
58 #include <jtag/commands.h>
59 
60 // Number of bits per SPI exchange
61 #define SPI_BITS 8
62 
63 // Time in uS after the last bit of transfer before deselecting the device
64 #define SPI_DESELECT_DELAY 0
65 
66 // Maximum number of SWD transactions to queue together in a SPI exchange
67 #define MAX_QUEUE_ENTRIES 64
68 
69 #define CMD_BITS 8
70 #define TURN_BITS 1
71 #define ACK_BITS 3
72 #define DATA_BITS 32
73 #define PARITY_BITS 1
74 
75 #define SWD_WR_BITS (CMD_BITS + TURN_BITS + ACK_BITS + TURN_BITS + DATA_BITS + PARITY_BITS)
76 #define SWD_RD_BITS (CMD_BITS + TURN_BITS + ACK_BITS + DATA_BITS + PARITY_BITS + TURN_BITS)
77 #define SWD_OP_BITS (MAX(SWD_WR_BITS, SWD_RD_BITS))
78 #define SWD_OP_BYTES (DIV_ROUND_UP(SWD_OP_BITS, SPI_BITS))
79 
80 #define AP_DELAY_CLOCKS 8
81 #define AP_DELAY_BYTES (DIV_ROUND_UP(AP_DELAY_CLOCKS, SPI_BITS))
82 
83 #define END_IDLE_CLOCKS 8
84 #define END_IDLE_BYTES (DIV_ROUND_UP(END_IDLE_CLOCKS, SPI_BITS))
85 
86 // File descriptor for SPI device
87 static int spi_fd = -1;
88 
89 // SPI Configuration
90 static char *spi_path;
91 static uint32_t spi_mode = SPI_MODE_3; // Note: SPI in LSB mode is not often supported. We'll flip LSB to MSB ourselves.
92 static uint32_t spi_speed;
93 
94 struct queue_info {
95  unsigned int buf_idx;
96  uint32_t *rx_ptr;
97 };
98 
99 static int queue_retval;
100 static unsigned int max_queue_entries;
101 static unsigned int queue_fill;
102 static unsigned int queue_buf_fill;
103 static unsigned int queue_buf_size;
104 static struct queue_info *queue_infos;
105 static uint8_t *queue_tx_buf;
106 static uint8_t *queue_rx_buf;
107 static uint8_t *tx_flip_buf;
108 
109 static int spidev_quit(void);
110 static int spidev_swd_switch_seq(enum swd_special_seq seq);
111 static int spidev_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk);
112 
113 static void spi_exchange(const uint8_t *tx_data, uint8_t *rx_data, unsigned int len)
114 {
115 #ifdef LOG_SPI_EXCHANGE
116  LOG_OUTPUT("exchange: len=%u\n", len);
117 #endif // LOG_SPI_EXCHANGE
118 
119  if (len == 0) {
120  LOG_DEBUG("exchange with no length");
121  return;
122  }
123 
124  if (!tx_data && !rx_data) {
125  LOG_DEBUG("exchange with no valid tx or rx pointers");
126  return;
127  }
128 
129  if (len > queue_buf_size) {
130  LOG_ERROR("exchange too large len=%u ", len);
131  return;
132  }
133 
134  if (tx_data) {
135  // Reverse LSB to MSB
136  for (unsigned int i = 0; i < len; i++)
137  tx_flip_buf[i] = flip_u32(tx_data[i], 8);
138 
139 #ifdef LOG_SPI_EXCHANGE
140  if (len != 0) {
141  LOG_OUTPUT(" tx_buf=");
142  for (unsigned int i = 0; i < len; i++)
143  LOG_OUTPUT("%.2" PRIx8 " ", tx_flip_buf[i]);
144  }
145  LOG_OUTPUT("\n");
146 #endif // LOG_SPI_EXCHANGE
147  }
148  // Transmit the MSB buffer to SPI device.
149  struct spi_ioc_transfer tr = {
150  /* The following must be cast to unsigned long to compile correctly on
151  * 32 and 64 bit machines (as is done in the spidev examples in Linux
152  * kernel code in tools/spi/).
153  */
154  .tx_buf = (unsigned long)(tx_data ? tx_flip_buf : NULL),
155  .rx_buf = (unsigned long)rx_data,
156  .len = len,
157  .delay_usecs = SPI_DESELECT_DELAY,
158  .speed_hz = spi_speed,
159  .bits_per_word = SPI_BITS,
160  };
161  int ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr);
162 
163  if (ret < 1) {
164  LOG_ERROR("exchange failed");
165  return;
166  }
167 
168  if (rx_data) {
169 #ifdef LOG_SPI_EXCHANGE
170  if (len != 0) {
171  LOG_OUTPUT(" rx_buf=");
172  for (unsigned int i = 0; i < len; i++)
173  LOG_OUTPUT("%.2" PRIx8 " ", rx_data[i]);
174  }
175  LOG_OUTPUT("\n");
176 #endif // LOG_SPI_EXCHANGE
177 
178  // Reverse MSB to LSB
179  for (unsigned int i = 0; i < len; i++)
180  rx_data[i] = flip_u32(rx_data[i], 8);
181  }
182 }
183 
184 static int spidev_speed(int speed)
185 {
186  uint32_t tmp_speed = speed;
187 
188  int ret = ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &tmp_speed);
189  if (ret == -1) {
190  LOG_ERROR("Failed to set SPI %d speed", speed);
191  return ERROR_FAIL;
192  }
193 
194  spi_speed = speed;
195 
196  return ERROR_OK;
197 }
198 
199 static int spidev_speed_div(int speed, int *khz)
200 {
201  *khz = speed / 1000;
202  return ERROR_OK;
203 }
204 
205 static int spidev_khz(int khz, int *jtag_speed)
206 {
207  if (khz == 0) {
208  LOG_DEBUG("RCLK not supported");
209  return ERROR_FAIL;
210  }
211 
212  *jtag_speed = khz * 1000;
213  return ERROR_OK;
214 }
215 
216 static void spidev_free_queue(void)
217 {
218  max_queue_entries = 0;
219  queue_buf_size = 0;
220 
221  free(queue_infos);
222  queue_infos = NULL;
223 
224  free(queue_tx_buf);
225  queue_tx_buf = NULL;
226 
227  free(queue_rx_buf);
228  queue_rx_buf = NULL;
229 
230  free(tx_flip_buf);
231  tx_flip_buf = NULL;
232 }
233 
234 static void spidev_clear_queue(void)
235 {
236  queue_fill = 0;
237  queue_buf_fill = 0;
238 
239  memset(queue_infos, 0, sizeof(struct queue_info) * max_queue_entries);
240  memset(queue_tx_buf, 0, queue_buf_size);
241  memset(queue_rx_buf, 0, queue_buf_size);
242  memset(tx_flip_buf, 0, queue_buf_size);
243 }
244 
245 static int spidev_alloc_queue(unsigned int new_queue_entries)
246 {
247  if (queue_fill || queue_buf_fill) {
248  LOG_ERROR("Can't realloc queue when queue is in use");
249  return ERROR_FAIL;
250  }
251 
252  unsigned int new_queue_buf_size =
253  (new_queue_entries * (SWD_OP_BYTES + AP_DELAY_BYTES)) + END_IDLE_BYTES;
254 
255  queue_infos = realloc(queue_infos, sizeof(struct queue_info) * new_queue_entries);
256  if (!queue_infos)
257  goto realloc_fail;
258 
259  queue_tx_buf = realloc(queue_tx_buf, new_queue_buf_size);
260  if (!queue_tx_buf)
261  goto realloc_fail;
262 
263  queue_rx_buf = realloc(queue_rx_buf, new_queue_buf_size);
264  if (!queue_rx_buf)
265  goto realloc_fail;
266 
267  tx_flip_buf = realloc(tx_flip_buf, new_queue_buf_size);
268  if (!tx_flip_buf)
269  goto realloc_fail;
270 
271  max_queue_entries = new_queue_entries;
272  queue_buf_size = new_queue_buf_size;
273 
275 
276  LOG_DEBUG("Set queue entries to %u (buffers %u bytes)", max_queue_entries, queue_buf_size);
277 
278  return ERROR_OK;
279 
280 realloc_fail:
282 
283  LOG_ERROR("Couldn't allocate queue. Out of memory.");
284  return ERROR_FAIL;
285 }
286 
287 static int spidev_init(void)
288 {
289  LOG_INFO("SPI SWD driver");
290 
291  if (spi_fd >= 0)
292  return ERROR_OK;
293 
294  if (!spi_path) {
295  LOG_ERROR("Path to spidev not set");
296  return ERROR_JTAG_INIT_FAILED;
297  }
298 
299  // Open SPI device.
300  spi_fd = open(spi_path, O_RDWR);
301  if (spi_fd < 0) {
302  LOG_ERROR("Failed to open SPI port at %s", spi_path);
303  goto out_error;
304  }
305 
306  int ret;
307  // Set SPI mode.
308 #ifdef SPI_IOC_WR_MODE32
309  ret = ioctl(spi_fd, SPI_IOC_WR_MODE32, &spi_mode);
310 #else
311  // Linux pre 3.15 does not support MODE32, use 8-bit ioctl
312  if (spi_mode & ~0xff) {
313  LOG_ERROR("SPI mode 0x%" PRIx32 ", system permits 8 bits only", spi_mode);
314  goto out_error;
315  }
316 
317  uint8_t mode = (uint8_t)spi_mode;
318  ret = ioctl(spi_fd, SPI_IOC_WR_MODE, &mode);
319 #endif
320  if (ret == -1) {
321  LOG_ERROR("Failed to set SPI mode 0x%" PRIx32, spi_mode);
322  goto out_error;
323  }
324 
325  // Set SPI bits per word.
326  uint32_t spi_bits = SPI_BITS;
327  ret = ioctl(spi_fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits);
328  if (ret == -1) {
329  LOG_ERROR("Failed to set SPI %" PRIu8 " bits per transfer", spi_bits);
330  goto out_error;
331  }
332 
333  LOG_INFO("Opened SPI device at %s in mode 0x%" PRIx32 " with %" PRIu8 " bits ",
334  spi_path, spi_mode, spi_bits);
335 
336  if (max_queue_entries == 0) {
338  if (ret != ERROR_OK)
339  goto out_error;
340  }
341 
342  return ERROR_OK;
343 
344 out_error:
345  spidev_quit();
346 
347  return ERROR_JTAG_INIT_FAILED;
348 }
349 
350 static int spidev_quit(void)
351 {
353 
354  if (spi_fd < 0)
355  return ERROR_OK;
356 
357  close(spi_fd);
358  spi_fd = -1;
359 
360  free(spi_path);
361  spi_path = NULL;
362 
363  return ERROR_OK;
364 }
365 
366 static int spidev_swd_init(void)
367 {
368  LOG_DEBUG("spidev_swd_init");
369  return ERROR_OK;
370 }
371 
372 static int spidev_swd_execute_queue(unsigned int end_idle_bytes)
373 {
374  LOG_DEBUG_IO("Executing %u queued transactions", queue_fill);
375 
376  if (queue_retval != ERROR_OK) {
377  LOG_DEBUG_IO("Skipping due to previous errors: %d", queue_retval);
378  goto skip;
379  }
380 
381  /* A transaction must be followed by another transaction or at least 8 idle
382  * cycles to ensure that data is clocked through the AP. Since the tx
383  * buffer is zeroed after each queue run, every byte added to the buffer
384  * fill will add on an additional 8 idle cycles.
385  */
386  queue_buf_fill += end_idle_bytes;
387 
389 
390  for (unsigned int queue_idx = 0; queue_idx < queue_fill; queue_idx++) {
391  unsigned int buf_idx = queue_infos[queue_idx].buf_idx;
392  uint8_t *tx_ptr = &queue_tx_buf[buf_idx];
393  uint8_t *rx_ptr = &queue_rx_buf[buf_idx];
394  uint8_t cmd = buf_get_u32(tx_ptr, 0, CMD_BITS);
395  bool read = cmd & SWD_CMD_RNW ? true : false;
396  int ack = buf_get_u32(rx_ptr, CMD_BITS + TURN_BITS, ACK_BITS);
397  uint32_t data = read ?
400 
401  // Devices do not reply to DP_TARGETSEL write cmd, ignore received ack
402  bool check_ack = swd_cmd_returns_ack(cmd);
403 
404  LOG_CUSTOM_LEVEL((check_ack && ack != SWD_ACK_OK) ? LOG_LVL_DEBUG : LOG_LVL_DEBUG_IO,
405  "%s%s %s %s reg %X = %08" PRIx32,
406  check_ack ? "" : "ack ignored ",
407  ack == SWD_ACK_OK ? "OK" :
408  ack == SWD_ACK_WAIT ? "WAIT" :
409  ack == SWD_ACK_FAULT ? "FAULT" : "JUNK",
410  cmd & SWD_CMD_APNDP ? "AP" : "DP",
411  read ? "read" : "write",
412  (cmd & SWD_CMD_A32) >> 1,
413  data);
414 
415  if (ack != SWD_ACK_OK && check_ack) {
417  goto skip;
418 
419  } else if (read) {
421 
422  if (parity != parity_u32(data)) {
423  LOG_ERROR("SWD Read data parity mismatch");
425  goto skip;
426  }
427 
428  if (queue_infos[queue_idx].rx_ptr)
429  *queue_infos[queue_idx].rx_ptr = data;
430  }
431  }
432 
433 skip:
435 
436  int retval = queue_retval;
438 
439  return retval;
440 }
441 
442 static int spidev_swd_run_queue(void)
443 {
444  /* Since we are unsure if another SWD transaction will follow the
445  * transactions we are just about to execute, we need to add on 8 idle
446  * cycles.
447  */
449 }
450 
451 static void spidev_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk)
452 {
453  unsigned int swd_op_bytes = DIV_ROUND_UP(SWD_OP_BITS + ap_delay_clk, SPI_BITS);
454 
455  if (queue_fill >= max_queue_entries ||
456  queue_buf_fill + swd_op_bytes + END_IDLE_BYTES > queue_buf_size) {
457  /* Not enough room in the queue. Run the queue. No idle bytes are
458  * needed because we are going to execute transactions right after
459  * the queue is emptied.
460  */
462  }
463 
464  if (queue_retval != ERROR_OK)
465  return;
466 
467  uint8_t *tx_ptr = &queue_tx_buf[queue_buf_fill];
468 
470 
471  buf_set_u32(tx_ptr, 0, CMD_BITS, cmd);
472 
473  if (cmd & SWD_CMD_RNW) {
474  // Queue a read transaction
476  } else {
477  // Queue a write transaction
478  buf_set_u32(tx_ptr,
480  buf_set_u32(tx_ptr,
482  }
483 
485 
486  /* Add idle cycles after AP accesses to avoid WAIT. Buffer is already
487  * zeroed so we just need to advance the pointer to add idle cycles.
488  */
489  queue_buf_fill += swd_op_bytes;
490 
491  queue_fill++;
492 }
493 
494 static int spidev_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
495 {
496  assert(cmd & SWD_CMD_RNW);
497  spidev_swd_queue_cmd(cmd, value, 0, ap_delay_clk);
498 
499  return ERROR_OK; /* TODO: return error instead of queuing it */
500 }
501 
502 static int spidev_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
503 {
504  assert(!(cmd & SWD_CMD_RNW));
505  spidev_swd_queue_cmd(cmd, NULL, value, ap_delay_clk);
506 
507  return ERROR_OK; /* TODO: return error instead of queuing it */
508 }
509 
511 {
512  switch (seq) {
513  case LINE_RESET:
514  LOG_DEBUG_IO("SWD line reset");
516  break;
517  case JTAG_TO_SWD:
518  LOG_DEBUG("JTAG-to-SWD");
520  break;
521  case JTAG_TO_DORMANT:
522  LOG_DEBUG("JTAG-to-DORMANT");
524  break;
525  case SWD_TO_JTAG:
526  LOG_DEBUG("SWD-to-JTAG");
528  break;
529  case SWD_TO_DORMANT:
530  LOG_DEBUG("SWD-to-DORMANT");
532  break;
533  case DORMANT_TO_SWD:
534  LOG_DEBUG("DORMANT-to-SWD");
536  break;
537  case DORMANT_TO_JTAG:
538  LOG_DEBUG("DORMANT-to-JTAG");
540  break;
541  default:
542  LOG_ERROR("Sequence %d not supported", seq);
543  return ERROR_FAIL;
544  }
545 
546  return ERROR_OK;
547 }
548 
549 COMMAND_HANDLER(spidev_handle_path_command)
550 {
551  if (CMD_ARGC != 1)
553 
554  free(spi_path);
555  spi_path = strdup(CMD_ARGV[0]);
556  if (!spi_path) {
557  LOG_ERROR("Out of memory");
558  return ERROR_FAIL;
559  }
560 
561  return ERROR_OK;
562 }
563 
564 COMMAND_HANDLER(spidev_handle_mode_command)
565 {
566  if (CMD_ARGC != 1)
568 
570  return ERROR_OK;
571 }
572 
573 COMMAND_HANDLER(spidev_handle_queue_entries_command)
574 {
575  uint32_t new_queue_entries;
576 
577  if (CMD_ARGC != 1)
579 
580  COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], new_queue_entries);
581 
582  return spidev_alloc_queue(new_queue_entries);
583 }
584 
585 const struct swd_driver spidev_swd = {
587  .switch_seq = spidev_swd_switch_seq,
588  .read_reg = spidev_swd_read_reg,
589  .write_reg = spidev_swd_write_reg,
590  .run = spidev_swd_run_queue,
591 };
592 
593 static const struct command_registration spidev_subcommand_handlers[] = {
594  {
595  .name = "path",
596  .handler = &spidev_handle_path_command,
597  .mode = COMMAND_CONFIG,
598  .help = "set the path to the spidev device",
599  .usage = "path_to_spidev",
600  },
601  {
602  .name = "mode",
603  .handler = &spidev_handle_mode_command,
604  .mode = COMMAND_CONFIG,
605  .help = "set the mode of the spi port with optional bit flags (default=3)",
606  .usage = "mode",
607  },
608  {
609  .name = "queue_entries",
610  .handler = &spidev_handle_queue_entries_command,
611  .mode = COMMAND_CONFIG,
612  .help = "set the queue entry size (default=64)",
613  .usage = "queue_entries",
614  },
616 };
617 
618 static const struct command_registration spidev_command_handlers[] = {
619  {
620  .name = "spidev",
621  .mode = COMMAND_ANY,
622  .help = "perform spidev management",
624  .usage = "",
625  },
627 };
628 
630  .name = "linuxspidev",
631  .transport_ids = TRANSPORT_SWD,
632  .transport_preferred_id = TRANSPORT_SWD,
633  .commands = spidev_command_handlers,
634 
635  .init = spidev_init,
636  .quit = spidev_quit,
637  .speed = spidev_speed,
638  .khz = spidev_khz,
639  .speed_div = spidev_speed_div,
640 
641  .swd_ops = &spidev_swd,
642 };
#define SWD_ACK_FAULT
Definition: arm_adi_v5.h:33
swd_special_seq
Definition: arm_adi_v5.h:236
@ DORMANT_TO_JTAG
Definition: arm_adi_v5.h:243
@ JTAG_TO_SWD
Definition: arm_adi_v5.h:238
@ DORMANT_TO_SWD
Definition: arm_adi_v5.h:242
@ LINE_RESET
Definition: arm_adi_v5.h:237
@ JTAG_TO_DORMANT
Definition: arm_adi_v5.h:239
@ SWD_TO_DORMANT
Definition: arm_adi_v5.h:241
@ SWD_TO_JTAG
Definition: arm_adi_v5.h:240
#define SWD_ACK_WAIT
Definition: arm_adi_v5.h:32
#define SWD_ACK_OK
Definition: arm_adi_v5.h:31
enum arm_mode mode
Definition: armv4_5.c:280
uint32_t flip_u32(uint32_t value, unsigned int num)
Inverts the ordering of bits inside a 32-bit word (e.g.
Definition: binarybuffer.c:165
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:104
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:34
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:161
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
Definition: command.h:445
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
@ COMMAND_CONFIG
Definition: command.h:41
@ COMMAND_ANY
Definition: command.h:42
#define ERROR_JTAG_INIT_FAILED
Definition: jtag.h:552
static const struct command_registration spidev_subcommand_handlers[]
Definition: linuxspidev.c:593
static int spi_fd
Definition: linuxspidev.c:87
#define SWD_OP_BITS
Definition: linuxspidev.c:77
#define END_IDLE_BYTES
Definition: linuxspidev.c:84
static void spidev_free_queue(void)
Definition: linuxspidev.c:216
static void spidev_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk)
Definition: linuxspidev.c:451
#define TURN_BITS
Definition: linuxspidev.c:70
static uint32_t spi_mode
Definition: linuxspidev.c:91
static int spidev_swd_init(void)
Definition: linuxspidev.c:366
#define ACK_BITS
Definition: linuxspidev.c:71
static int spidev_alloc_queue(unsigned int new_queue_entries)
Definition: linuxspidev.c:245
static uint8_t * queue_tx_buf
Definition: linuxspidev.c:105
static int spidev_swd_execute_queue(unsigned int end_idle_bytes)
Definition: linuxspidev.c:372
#define DATA_BITS
Definition: linuxspidev.c:72
const struct swd_driver spidev_swd
Definition: linuxspidev.c:585
#define SWD_OP_BYTES
Definition: linuxspidev.c:78
static uint8_t * queue_rx_buf
Definition: linuxspidev.c:106
static void spidev_clear_queue(void)
Definition: linuxspidev.c:234
static int spidev_quit(void)
Definition: linuxspidev.c:350
COMMAND_HANDLER(spidev_handle_path_command)
Definition: linuxspidev.c:549
static int queue_retval
Definition: linuxspidev.c:99
struct adapter_driver linuxspidev_adapter_driver
Definition: linuxspidev.c:629
#define AP_DELAY_BYTES
Definition: linuxspidev.c:81
static struct queue_info * queue_infos
Definition: linuxspidev.c:104
#define SPI_BITS
Definition: linuxspidev.c:61
static int spidev_khz(int khz, int *jtag_speed)
Definition: linuxspidev.c:205
static char * spi_path
Definition: linuxspidev.c:90
static unsigned int max_queue_entries
Definition: linuxspidev.c:100
#define MAX_QUEUE_ENTRIES
Definition: linuxspidev.c:67
static int spidev_init(void)
Definition: linuxspidev.c:287
static uint32_t spi_speed
Definition: linuxspidev.c:92
static int spidev_speed_div(int speed, int *khz)
Definition: linuxspidev.c:199
#define SPI_DESELECT_DELAY
Definition: linuxspidev.c:64
static uint8_t * tx_flip_buf
Definition: linuxspidev.c:107
static unsigned int queue_buf_fill
Definition: linuxspidev.c:102
static const struct command_registration spidev_command_handlers[]
Definition: linuxspidev.c:618
static int spidev_swd_switch_seq(enum swd_special_seq seq)
Definition: linuxspidev.c:510
static int spidev_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
Definition: linuxspidev.c:494
static unsigned int queue_fill
Definition: linuxspidev.c:101
static int spidev_speed(int speed)
Definition: linuxspidev.c:184
static void spi_exchange(const uint8_t *tx_data, uint8_t *rx_data, unsigned int len)
Definition: linuxspidev.c:113
#define PARITY_BITS
Definition: linuxspidev.c:73
static unsigned int queue_buf_size
Definition: linuxspidev.c:103
#define CMD_BITS
Definition: linuxspidev.c:69
static int spidev_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
Definition: linuxspidev.c:502
static int spidev_swd_run_queue(void)
Definition: linuxspidev.c:442
#define LOG_CUSTOM_LEVEL(level, expr ...)
Definition: log.h:132
#define LOG_OUTPUT(expr ...)
Definition: log.h:156
#define LOG_DEBUG_IO(expr ...)
Definition: log.h:116
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
@ LOG_LVL_DEBUG
Definition: log.h:55
@ LOG_LVL_DEBUG_IO
Definition: log.h:56
Represents a driver for a debugging interface.
Definition: interface.h:219
const char *const name
The name of the interface driver.
Definition: interface.h:221
const char * name
Definition: command.h:239
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:244
unsigned int buf_idx
Definition: linuxspidev.c:95
uint32_t * rx_ptr
Definition: linuxspidev.c:96
int(* init)(void)
Initialize the debug link so it can perform SWD operations.
Definition: swd.h:255
static const unsigned int swd_seq_dormant_to_swd_len
Definition: swd.h:190
static const uint8_t swd_seq_dormant_to_jtag[]
Dormant-to-JTAG sequence.
Definition: swd.h:230
#define SWD_CMD_A32
Definition: swd.h:19
static const uint8_t swd_seq_dormant_to_swd[]
Dormant-to-SWD sequence.
Definition: swd.h:171
static const uint8_t swd_seq_jtag_to_dormant[]
JTAG-to-dormant sequence.
Definition: swd.h:199
static bool swd_cmd_returns_ack(uint8_t cmd)
Test if we can rely on ACK returned by SWD command.
Definition: swd.h:58
#define SWD_CMD_PARK
Definition: swd.h:22
static int swd_ack_to_error_code(uint8_t ack)
Convert SWD ACK value returned from DP to OpenOCD error code.
Definition: swd.h:72
static const unsigned int swd_seq_jtag_to_swd_len
Definition: swd.h:125
static const unsigned int swd_seq_line_reset_len
Definition: swd.h:104
static const unsigned int swd_seq_dormant_to_jtag_len
Definition: swd.h:244
#define SWD_CMD_APNDP
Definition: swd.h:17
static const unsigned int swd_seq_swd_to_dormant_len
Definition: swd.h:159
#define SWD_CMD_START
Definition: swd.h:16
#define SWD_CMD_RNW
Definition: swd.h:18
static const uint8_t swd_seq_line_reset[]
SWD Line reset.
Definition: swd.h:98
static const uint8_t swd_seq_jtag_to_swd[]
JTAG-to-SWD sequence.
Definition: swd.h:115
static const uint8_t swd_seq_swd_to_jtag[]
SWD-to-JTAG sequence.
Definition: swd.h:136
static const unsigned int swd_seq_swd_to_jtag_len
Definition: swd.h:144
static const unsigned int swd_seq_jtag_to_dormant_len
Definition: swd.h:211
static const uint8_t swd_seq_swd_to_dormant[]
SWD-to-dormant sequence.
Definition: swd.h:153
#define true
Definition: system.h:59
#define TRANSPORT_SWD
Definition: transport.h:20
#define DIV_ROUND_UP(m, n)
Rounds m up to the nearest multiple of n using division.
Definition: types.h:79
static int parity_u32(uint32_t x)
Calculate the (even) parity of a 32-bit datum.
Definition: types.h:265
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1
static unsigned int parity(unsigned int v)
Definition: xscale.c:619