OpenOCD
gatemate.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2022 by Daniel Anselmi *
5  * danselmi@gmx.ch *
6  ***************************************************************************/
7 
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11 
12 #include <jtag/jtag.h>
13 #include <jtag/adapter.h>
14 #include "pld.h"
15 #include "raw_bit.h"
16 
17 #define JTAG_CONFIGURE 0x06
18 #define JTAG_SPI_BYPASS 0x05
19 #define BYPASS 0x3F
20 
22  struct jtag_tap *tap;
23 };
24 
26  struct raw_bit_file raw_file;
27  size_t capacity;
28 };
29 
30 static int gatemate_add_byte_to_bitfile(struct gatemate_bit_file *bit_file, uint8_t byte)
31 {
32  const size_t chunk_size = 8192;
33  if (bit_file->raw_file.length + 1 > bit_file->capacity) {
34  uint8_t *buffer;
35  if (bit_file->raw_file.data)
36  buffer = realloc(bit_file->raw_file.data, bit_file->capacity + chunk_size);
37  else
38  buffer = malloc(chunk_size);
39  if (!buffer) {
40  LOG_ERROR("Out of memory");
41  return ERROR_FAIL;
42  }
43  bit_file->raw_file.data = buffer;
44  bit_file->capacity += chunk_size;
45  }
46 
47  bit_file->raw_file.data[bit_file->raw_file.length++] = byte;
48 
49  return ERROR_OK;
50 }
51 
52 static int gatemate_read_cfg_line(struct gatemate_bit_file *bit_file, const char *line_buffer, size_t nread)
53 {
54  for (size_t idx = 0; idx < nread; ++idx) {
55  if (line_buffer[idx] == ' ') {
56  continue;
57  } else if (line_buffer[idx] == 0) {
58  break;
59  } else if (idx + 1 < nread) {
60  if (isxdigit(line_buffer[idx]) && isxdigit(line_buffer[idx + 1])) {
61  uint8_t byte;
62  unhexify(&byte, line_buffer + idx, 2);
63  int retval = gatemate_add_byte_to_bitfile(bit_file, byte);
64  if (retval != ERROR_OK)
65  return retval;
66  } else if (line_buffer[idx] == '/' && line_buffer[idx + 1] == '/') {
67  break;
68  }
69  ++idx;
70  } else {
71  LOG_ERROR("parsing failed");
72  return ERROR_FAIL;
73  }
74  }
75  return ERROR_OK;
76 }
77 
78 static int gatemate_getline(char **buffer, size_t *buf_size, FILE *input_file)
79 {
80  const size_t chunk_size = 32;
81  if (!*buffer)
82  *buf_size = 0;
83 
84  size_t read = 0;
85  do {
86  if (read + 1 > *buf_size) {
87  char *new_buffer;
88  if (*buffer)
89  new_buffer = realloc(*buffer, *buf_size + chunk_size);
90  else
91  new_buffer = malloc(chunk_size);
92  if (!new_buffer) {
93  LOG_ERROR("Out of memory");
94  return -1;
95  }
96  *buffer = new_buffer;
97  *buf_size += chunk_size;
98  }
99 
100  int c = fgetc(input_file);
101  if ((c == EOF && read) || (char)c == '\n') {
102  (*buffer)[read++] = 0;
103  return read;
104  } else if (c == EOF) {
105  return -1;
106  }
107 
108  (*buffer)[read++] = (char)c;
109  } while (1);
110 
111  return -1;
112 }
113 
114 static int gatemate_read_cfg_file(struct gatemate_bit_file *bit_file, const char *filename)
115 {
116  FILE *input_file = fopen(filename, "r");
117 
118  if (!input_file) {
119  LOG_ERROR("Couldn't open %s: %s", filename, strerror(errno));
121  }
122 
123  int retval = ERROR_OK;
124  char *line_buffer = NULL;
125  size_t buffer_length = 0;
126  int nread;
127  while (((nread = gatemate_getline(&line_buffer, &buffer_length, input_file)) != -1) && (retval == ERROR_OK))
128  retval = gatemate_read_cfg_line(bit_file, line_buffer, (size_t)nread);
129 
130  if (line_buffer)
131  free(line_buffer);
132 
133  fclose(input_file);
134  if (retval != ERROR_OK)
135  free(bit_file->raw_file.data);
136  return retval;
137 }
138 
139 static int gatemate_read_file(struct gatemate_bit_file *bit_file, const char *filename)
140 {
141  memset(bit_file, 0, sizeof(struct gatemate_bit_file));
142 
143  if (!filename || !bit_file)
145 
146  /* check if binary .bit or ascii .cfg */
147  const char *file_suffix_pos = strrchr(filename, '.');
148  if (!file_suffix_pos) {
149  LOG_ERROR("Unable to detect filename suffix");
151  }
152 
153  if (strcasecmp(file_suffix_pos, ".bit") == 0)
154  return cpld_read_raw_bit_file(&bit_file->raw_file, filename);
155  else if (strcasecmp(file_suffix_pos, ".cfg") == 0)
156  return gatemate_read_cfg_file(bit_file, filename);
157 
158  LOG_ERROR("Filetype not supported, expecting .bit or .cfg file");
160 }
161 
162 static int gatemate_set_instr(struct jtag_tap *tap, uint8_t new_instr)
163 {
164  struct scan_field field;
165  field.num_bits = tap->ir_length;
166  void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
167  if (!t) {
168  LOG_ERROR("Out of memory");
169  return ERROR_FAIL;
170  }
171  field.out_value = t;
172  buf_set_u32(t, 0, field.num_bits, new_instr);
173  field.in_value = NULL;
174  jtag_add_ir_scan(tap, &field, TAP_IDLE);
176  free(t);
177  return ERROR_OK;
178 }
179 
180 static int gatemate_load(struct pld_device *pld_device, const char *filename)
181 {
182  if (!pld_device)
183  return ERROR_FAIL;
184 
185  struct gatemate_pld_device *gatemate_info = pld_device->driver_priv;
186 
187  if (!gatemate_info || !gatemate_info->tap)
188  return ERROR_FAIL;
189  struct jtag_tap *tap = gatemate_info->tap;
190 
191  struct gatemate_bit_file bit_file;
192  int retval = gatemate_read_file(&bit_file, filename);
193  if (retval != ERROR_OK)
194  return retval;
195 
196  retval = gatemate_set_instr(tap, JTAG_CONFIGURE);
197  if (retval != ERROR_OK) {
198  free(bit_file.raw_file.data);
199  return retval;
200  }
201 
202  struct scan_field field;
203  field.num_bits = bit_file.raw_file.length * 8;
204  field.out_value = bit_file.raw_file.data;
205  field.in_value = NULL;
206  jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
207 
208  retval = jtag_execute_queue();
209  free(bit_file.raw_file.data);
210 
211  return retval;
212 }
213 
214 static int gatemate_has_jtagspi_instruction(struct pld_device *device, bool *has_instruction)
215 {
216  *has_instruction = true;
217  return ERROR_OK;
218 }
219 
221 {
222  if (!pld_device)
223  return ERROR_FAIL;
224 
225  struct gatemate_pld_device *pld_device_info = pld_device->driver_priv;
226  if (!pld_device_info)
227  return ERROR_FAIL;
228 
229  struct jtag_tap *tap = pld_device_info->tap;
230  if (!tap)
231  return ERROR_FAIL;
232 
233  if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == JTAG_SPI_BYPASS)
234  return ERROR_OK;
235 
237 
238  return jtag_execute_queue();
239 }
240 
242 {
243  if (!pld_device)
244  return ERROR_FAIL;
245 
246  struct gatemate_pld_device *pld_device_info = pld_device->driver_priv;
247  if (!pld_device_info)
248  return ERROR_FAIL;
249 
250  struct jtag_tap *tap = pld_device_info->tap;
251  if (!tap)
252  return ERROR_FAIL;
253 
254  if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != JTAG_SPI_BYPASS)
255  return ERROR_OK;
256 
258 
259  return jtag_execute_queue();
260 }
261 
262 static int gatemate_get_stuff_bits(struct pld_device *pld_device, unsigned int *facing_read_bits,
263  unsigned int *trailing_write_bits)
264 {
265  if (!pld_device)
266  return ERROR_FAIL;
267 
268  *facing_read_bits = 1;
269  *trailing_write_bits = 1;
270 
271  return ERROR_OK;
272 }
273 
274 PLD_CREATE_COMMAND_HANDLER(gatemate_pld_create_command)
275 {
276  if (CMD_ARGC != 4)
278 
279  if (strcmp(CMD_ARGV[2], "-chain-position") != 0)
281 
282  struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);
283  if (!tap) {
284  command_print(CMD, "Tap: %s does not exist", CMD_ARGV[3]);
285  return ERROR_FAIL;
286  }
287 
288  struct gatemate_pld_device *gatemate_info = malloc(sizeof(struct gatemate_pld_device));
289  if (!gatemate_info) {
290  LOG_ERROR("Out of memory");
291  return ERROR_FAIL;
292  }
293  gatemate_info->tap = tap;
294 
295  pld->driver_priv = gatemate_info;
296 
297  return ERROR_OK;
298 }
299 
300 struct pld_driver gatemate_pld = {
301  .name = "gatemate",
302  .pld_create_command = &gatemate_pld_create_command,
303  .load = &gatemate_load,
304  .has_jtagspi_instruction = gatemate_has_jtagspi_instruction,
305  .connect_spi_to_jtag = gatemate_connect_spi_to_jtag,
306  .disconnect_spi_from_jtag = gatemate_disconnect_spi_from_jtag,
307  .get_stuff_bits = gatemate_get_stuff_bits,
308 };
static const struct device_t * device
Definition: at91rm9200.c:94
size_t unhexify(uint8_t *bin, const char *hex, size_t count)
Convert a string of hexadecimal pairs into its binary representation.
Definition: binarybuffer.c:342
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
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:443
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:141
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:156
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
static int gatemate_disconnect_spi_from_jtag(struct pld_device *pld_device)
Definition: gatemate.c:241
static int gatemate_add_byte_to_bitfile(struct gatemate_bit_file *bit_file, uint8_t byte)
Definition: gatemate.c:30
static int gatemate_get_stuff_bits(struct pld_device *pld_device, unsigned int *facing_read_bits, unsigned int *trailing_write_bits)
Definition: gatemate.c:262
static int gatemate_has_jtagspi_instruction(struct pld_device *device, bool *has_instruction)
Definition: gatemate.c:214
static int gatemate_getline(char **buffer, size_t *buf_size, FILE *input_file)
Definition: gatemate.c:78
static int gatemate_set_instr(struct jtag_tap *tap, uint8_t new_instr)
Definition: gatemate.c:162
#define JTAG_SPI_BYPASS
Definition: gatemate.c:18
static int gatemate_connect_spi_to_jtag(struct pld_device *pld_device)
Definition: gatemate.c:220
#define JTAG_CONFIGURE
Definition: gatemate.c:17
struct pld_driver gatemate_pld
Definition: gatemate.c:300
static int gatemate_read_cfg_line(struct gatemate_bit_file *bit_file, const char *line_buffer, size_t nread)
Definition: gatemate.c:52
static int gatemate_load(struct pld_device *pld_device, const char *filename)
Definition: gatemate.c:180
static int gatemate_read_file(struct gatemate_bit_file *bit_file, const char *filename)
Definition: gatemate.c:139
PLD_CREATE_COMMAND_HANDLER(gatemate_pld_create_command)
Definition: gatemate.c:274
#define BYPASS
Definition: gatemate.c:19
static int gatemate_read_cfg_file(struct gatemate_bit_file *bit_file, const char *filename)
Definition: gatemate.c:114
struct jtag_tap * jtag_tap_by_string(const char *s)
Definition: jtag/core.c:237
void jtag_add_runtest(unsigned int num_cycles, tap_state_t state)
Goes to TAP_IDLE (if we're not already there), cycle precisely num_cycles in the TAP_IDLE state,...
Definition: jtag/core.c:592
int jtag_execute_queue(void)
For software FIFO implementations, the queued commands can be executed during this call or earlier.
Definition: jtag/core.c:1037
void jtag_add_ir_scan(struct jtag_tap *active, struct scan_field *in_fields, tap_state_t state)
Generate an IR SCAN with a list of scan fields with one entry for each enabled TAP.
Definition: jtag/core.c:374
void jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
Generate a DR SCAN using the fields passed to the function.
Definition: jtag/core.c:451
The JTAG interface can be implemented with a software or hardware fifo.
@ TAP_IDLE
Definition: jtag.h:53
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define ERROR_OK
Definition: log.h:164
#define ERROR_PLD_FILE_LOAD_FAILED
Definition: pld.h:62
int cpld_read_raw_bit_file(struct raw_bit_file *bit_file, const char *filename)
Definition: raw_bit.c:19
size_t capacity
Definition: gatemate.c:27
struct raw_bit_file raw_file
Definition: gatemate.c:26
struct jtag_tap * tap
Definition: gatemate.c:22
Definition: jtag.h:101
uint8_t * cur_instr
current instruction
Definition: jtag.h:132
unsigned int ir_length
size of instruction register
Definition: jtag.h:110
Definition: pld.h:48
void * driver_priv
Definition: pld.h:50
Definition: pld.h:31
const char * name
Definition: pld.h:32
uint8_t * data
Definition: raw_bit.h:16
size_t length
Definition: raw_bit.h:15
This structure defines a single scan field in the scan.
Definition: jtag.h:87
uint8_t * in_value
A pointer to a 32-bit memory location for data scanned out.
Definition: jtag.h:93
const uint8_t * out_value
A pointer to value to be scanned into the device.
Definition: jtag.h:91
unsigned int num_bits
The number of bits this field specifies.
Definition: jtag.h:89
#define DIV_ROUND_UP(m, n)
Rounds m up to the nearest multiple of n using division.
Definition: types.h:79
#define NULL
Definition: usb.h:16