OpenOCD
intel.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 <helper/system.h>
15 #include <helper/log.h>
16 
17 #include "pld.h"
18 #include "raw_bit.h"
19 
20 #define BYPASS 0x3FF
21 #define USER0 0x00C
22 #define USER1 0x00E
23 
31 };
32 
34  struct jtag_tap *tap;
35  unsigned int boundary_scan_length;
36  int checkpos;
38 };
39 
40 static int intel_check_config(struct intel_pld_device *intel_info)
41 {
42  if (intel_info->boundary_scan_length == 0) {
43  LOG_ERROR("unknown boundary scan length. Please specify with 'intel set_bscan'.");
44  return ERROR_FAIL;
45  }
46 
47  if (intel_info->checkpos >= 0 && (unsigned int)intel_info->checkpos >= intel_info->boundary_scan_length) {
48  LOG_ERROR("checkpos has to be smaller than scan length %d < %u",
49  intel_info->checkpos, intel_info->boundary_scan_length);
50  return ERROR_FAIL;
51  }
52 
53  return ERROR_OK;
54 }
55 
56 static int intel_read_file(struct raw_bit_file *bit_file, const char *filename)
57 {
58  if (!filename || !bit_file)
60 
61  /* check if binary .bin or ascii .bit/.hex */
62  const char *file_ending_pos = strrchr(filename, '.');
63  if (!file_ending_pos) {
64  LOG_ERROR("Unable to detect filename suffix");
66  }
67 
68  if (strcasecmp(file_ending_pos, ".rbf") == 0)
69  return cpld_read_raw_bit_file(bit_file, filename);
70 
71  LOG_ERROR("Unable to detect filetype");
73 }
74 
75 static int intel_set_instr(struct jtag_tap *tap, uint16_t new_instr)
76 {
77  struct scan_field field;
78  field.num_bits = tap->ir_length;
79  void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
80  if (!t) {
81  LOG_ERROR("Out of memory");
82  return ERROR_FAIL;
83  }
84  field.out_value = t;
85  buf_set_u32(t, 0, field.num_bits, new_instr);
86  field.in_value = NULL;
87  jtag_add_ir_scan(tap, &field, TAP_IDLE);
88  free(t);
89  return ERROR_OK;
90 }
91 
92 
93 static int intel_load(struct pld_device *pld_device, const char *filename)
94 {
95  unsigned int speed = adapter_get_speed_khz();
96  if (speed < 1)
97  speed = 1;
98 
99  unsigned int cycles = DIV_ROUND_UP(speed, 200);
100  if (cycles < 1)
101  cycles = 1;
102 
104  return ERROR_FAIL;
105 
106  struct intel_pld_device *intel_info = pld_device->driver_priv;
107  if (!intel_info || !intel_info->tap)
108  return ERROR_FAIL;
109  struct jtag_tap *tap = intel_info->tap;
110 
111  int retval = intel_check_config(intel_info);
112  if (retval != ERROR_OK)
113  return retval;
114 
115  struct raw_bit_file bit_file;
116  retval = intel_read_file(&bit_file, filename);
117  if (retval != ERROR_OK)
118  return retval;
119 
120  retval = intel_set_instr(tap, 0x002);
121  if (retval != ERROR_OK) {
122  free(bit_file.data);
123  return retval;
124  }
125  jtag_add_runtest(speed, TAP_IDLE);
126  retval = jtag_execute_queue();
127  if (retval != ERROR_OK) {
128  free(bit_file.data);
129  return retval;
130  }
131 
132  /* shift in the bitstream */
133  struct scan_field field;
134  field.num_bits = bit_file.length * 8;
135  field.out_value = bit_file.data;
136  field.in_value = NULL;
137 
138  jtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE);
139  retval = jtag_execute_queue();
140  free(bit_file.data);
141  if (retval != ERROR_OK)
142  return retval;
143 
144  retval = intel_set_instr(tap, 0x004);
145  if (retval != ERROR_OK)
146  return retval;
147  jtag_add_runtest(cycles, TAP_IDLE);
148  retval = jtag_execute_queue();
149  if (retval != ERROR_OK)
150  return retval;
151 
152  if (intel_info->boundary_scan_length != 0) {
153  uint8_t *buf = calloc(DIV_ROUND_UP(intel_info->boundary_scan_length, 8), 1);
154  if (!buf) {
155  LOG_ERROR("Out of memory");
156  return ERROR_FAIL;
157  }
158 
159  field.num_bits = intel_info->boundary_scan_length;
160  field.out_value = buf;
161  field.in_value = buf;
162  jtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE);
163  retval = jtag_execute_queue();
164  if (retval != ERROR_OK) {
165  free(buf);
166  return retval;
167  }
168 
169  if (intel_info->checkpos != -1)
170  retval = ((buf[intel_info->checkpos / 8] & (1 << (intel_info->checkpos % 8)))) ?
172  free(buf);
173  if (retval != ERROR_OK) {
174  LOG_ERROR("Check failed");
175  return ERROR_FAIL;
176  }
177  } else {
178  LOG_INFO("unable to check. Please specify with position 'intel set_check_pos'.");
179  }
180 
181  retval = intel_set_instr(tap, 0x003);
182  if (retval != ERROR_OK)
183  return retval;
184  switch (intel_info->family) {
185  case INTEL_CYCLONEIII:
186  case INTEL_CYCLONEIV:
187  jtag_add_runtest(5 * speed + 512, TAP_IDLE);
188  break;
189  case INTEL_CYCLONEV:
190  jtag_add_runtest(5 * speed + 512, TAP_IDLE);
191  break;
192  case INTEL_CYCLONE10:
193  jtag_add_runtest(DIV_ROUND_UP(512ul * speed, 125ul) + 512, TAP_IDLE);
194  break;
195  case INTEL_ARRIAII:
196  jtag_add_runtest(DIV_ROUND_UP(64ul * speed, 125ul) + 512, TAP_IDLE);
197  break;
198  case INTEL_UNKNOWN:
199  LOG_ERROR("unknown family");
200  return ERROR_FAIL;
201  }
202 
203  retval = intel_set_instr(tap, BYPASS);
204  if (retval != ERROR_OK)
205  return retval;
206  jtag_add_runtest(speed, TAP_IDLE);
207  return jtag_execute_queue();
208 }
209 
210 static int intel_get_ipdbg_hub(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub)
211 {
212  if (!pld_device)
213  return ERROR_FAIL;
214 
215  struct intel_pld_device *pld_device_info = pld_device->driver_priv;
216 
217  if (!pld_device_info || !pld_device_info->tap)
218  return ERROR_FAIL;
219 
220  hub->tap = pld_device_info->tap;
221 
222  if (user_num == 0) {
223  hub->user_ir_code = USER0;
224  } else if (user_num == 1) {
225  hub->user_ir_code = USER1;
226  } else {
227  LOG_ERROR("intel devices only have user register 0 & 1");
228  return ERROR_FAIL;
229  }
230  return ERROR_OK;
231 }
232 
233 static int intel_get_jtagspi_userircode(struct pld_device *pld_device, unsigned int *ir)
234 {
235  *ir = USER1;
236  return ERROR_OK;
237 }
238 
239 COMMAND_HANDLER(intel_set_bscan_command_handler)
240 {
241  unsigned int boundary_scan_length;
242 
243  if (CMD_ARGC != 2)
245 
247  if (!pld_device) {
248  command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
249  return ERROR_FAIL;
250  }
251 
252  COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], boundary_scan_length);
253 
254  struct intel_pld_device *intel_info = pld_device->driver_priv;
255 
256  if (!intel_info)
257  return ERROR_FAIL;
258 
260 
261  return ERROR_OK;
262 }
263 
264 COMMAND_HANDLER(intel_set_check_pos_command_handler)
265 {
266  int checkpos;
267 
268  if (CMD_ARGC != 2)
270 
272  if (!pld_device) {
273  command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
274  return ERROR_FAIL;
275  }
276 
277  COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], checkpos);
278 
279  struct intel_pld_device *intel_info = pld_device->driver_priv;
280 
281  if (!intel_info)
282  return ERROR_FAIL;
283 
284  intel_info->checkpos = checkpos;
285 
286  return ERROR_OK;
287 }
288 
289 PLD_CREATE_COMMAND_HANDLER(intel_pld_create_command)
290 {
291  if (CMD_ARGC != 6)
293 
294  if (strcmp(CMD_ARGV[2], "-chain-position") != 0)
296 
297  struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);
298  if (!tap) {
299  command_print(CMD, "Tap: %s does not exist", CMD_ARGV[3]);
300  return ERROR_FAIL;
301  }
302 
303  enum intel_family_e family = INTEL_UNKNOWN;
304 
305  if (strcmp(CMD_ARGV[4], "-family") != 0)
307 
308  if (strcmp(CMD_ARGV[5], "cycloneiii") == 0) {
309  family = INTEL_CYCLONEIII;
310  } else if (strcmp(CMD_ARGV[5], "cycloneiv") == 0) {
311  family = INTEL_CYCLONEIV;
312  } else if (strcmp(CMD_ARGV[5], "cyclonev") == 0) {
313  family = INTEL_CYCLONEV;
314  } else if (strcmp(CMD_ARGV[5], "cyclone10") == 0) {
315  family = INTEL_CYCLONE10;
316  } else if (strcmp(CMD_ARGV[5], "arriaii") == 0) {
317  family = INTEL_ARRIAII;
318  } else {
319  command_print(CMD, "unknown family");
320  return ERROR_FAIL;
321  }
322 
323  struct intel_pld_device *intel_info = malloc(sizeof(struct intel_pld_device));
324  if (!intel_info) {
325  LOG_ERROR("Out of memory");
326  return ERROR_FAIL;
327  }
328 
329  intel_info->tap = tap;
330  intel_info->boundary_scan_length = 0;
331  intel_info->checkpos = -1;
332  intel_info->family = family;
333 
334  pld->driver_priv = intel_info;
335 
336  return ERROR_OK;
337 }
338 
339 static const struct command_registration intel_exec_command_handlers[] = {
340  {
341  .name = "set_bscan",
342  .mode = COMMAND_ANY,
343  .handler = intel_set_bscan_command_handler,
344  .help = "set boundary scan register length of FPGA",
345  .usage = "pld_name len",
346  }, {
347  .name = "set_check_pos",
348  .mode = COMMAND_ANY,
349  .handler = intel_set_check_pos_command_handler,
350  .help = "set check_pos of FPGA",
351  .usage = "pld_name pos",
352  },
354 };
355 
356 static const struct command_registration intel_command_handler[] = {
357  {
358  .name = "intel",
359  .mode = COMMAND_ANY,
360  .help = "intel specific commands",
361  .usage = "",
363  },
365 };
366 
367 struct pld_driver intel_pld = {
368  .name = "intel",
369  .commands = intel_command_handler,
370  .pld_create_command = &intel_pld_create_command,
371  .load = &intel_load,
372  .get_ipdbg_hub = intel_get_ipdbg_hub,
373  .get_jtagspi_userircode = intel_get_jtagspi_userircode,
374 };
unsigned int adapter_get_speed_khz(void)
Retrieves the clock speed of the adapter in kHz.
Definition: adapter.c:207
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
#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:442
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:253
@ COMMAND_ANY
Definition: command.h:42
intel_family_e
Definition: intel.c:24
@ INTEL_CYCLONEIII
Definition: intel.c:25
@ INTEL_CYCLONEV
Definition: intel.c:27
@ INTEL_UNKNOWN
Definition: intel.c:30
@ INTEL_CYCLONE10
Definition: intel.c:28
@ INTEL_CYCLONEIV
Definition: intel.c:26
@ INTEL_ARRIAII
Definition: intel.c:29
#define USER0
Definition: intel.c:21
struct pld_driver intel_pld
Definition: intel.c:367
#define USER1
Definition: intel.c:22
static int intel_load(struct pld_device *pld_device, const char *filename)
Definition: intel.c:93
static const struct command_registration intel_exec_command_handlers[]
Definition: intel.c:339
static int intel_get_jtagspi_userircode(struct pld_device *pld_device, unsigned int *ir)
Definition: intel.c:233
PLD_CREATE_COMMAND_HANDLER(intel_pld_create_command)
Definition: intel.c:289
static int intel_read_file(struct raw_bit_file *bit_file, const char *filename)
Definition: intel.c:56
static int intel_set_instr(struct jtag_tap *tap, uint16_t new_instr)
Definition: intel.c:75
static const struct command_registration intel_command_handler[]
Definition: intel.c:356
COMMAND_HANDLER(intel_set_bscan_command_handler)
Definition: intel.c:239
#define BYPASS
Definition: intel.c:20
static int intel_get_ipdbg_hub(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub)
Definition: intel.c:210
static int intel_check_config(struct intel_pld_device *intel_info)
Definition: intel.c:40
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_DRPAUSE
Definition: jtag.h:44
@ TAP_IDLE
Definition: jtag.h:53
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define ERROR_OK
Definition: log.h:164
struct pld_device * get_pld_device_by_name_or_numstr(const char *str)
Definition: pld.c:56
#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
const char * name
Definition: command.h:235
unsigned int boundary_scan_length
Definition: intel.c:35
enum intel_family_e family
Definition: intel.c:37
struct jtag_tap * tap
Definition: intel.c:34
int checkpos
Definition: intel.c:36
Definition: jtag.h:101
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
unsigned int user_ir_code
Definition: pld.h:20
struct jtag_tap * tap
Definition: pld.h:19
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