1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2022 by Daniel Anselmi *
6 ***************************************************************************/
12 #include <jtag/jtag.h>
13 #include <jtag/adapter.h>
17 #define JTAG_CONFIGURE 0x06
18 #define JTAG_SPI_BYPASS 0x05
21 struct gatemate_pld_device
{
25 struct gatemate_bit_file
{
26 struct raw_bit_file raw_file
;
30 static int gatemate_add_byte_to_bitfile(struct gatemate_bit_file
*bit_file
, uint8_t byte
)
32 const size_t chunk_size
= 8192;
33 if (bit_file
->raw_file
.length
+ 1 > bit_file
->capacity
) {
35 if (bit_file
->raw_file
.data
)
36 buffer
= realloc(bit_file
->raw_file
.data
, bit_file
->capacity
+ chunk_size
);
38 buffer
= malloc(chunk_size
);
40 LOG_ERROR("Out of memory");
43 bit_file
->raw_file
.data
= buffer
;
44 bit_file
->capacity
+= chunk_size
;
47 bit_file
->raw_file
.data
[bit_file
->raw_file
.length
++] = byte
;
52 static int gatemate_read_cfg_line(struct gatemate_bit_file
*bit_file
, const char *line_buffer
, size_t nread
)
54 for (size_t idx
= 0; idx
< nread
; ++idx
) {
55 if (line_buffer
[idx
] == ' ') {
57 } else if (line_buffer
[idx
] == 0) {
59 } else if (idx
+ 1 < nread
) {
60 if (isxdigit(line_buffer
[idx
]) && isxdigit(line_buffer
[idx
+ 1])) {
62 unhexify(&byte
, line_buffer
+ idx
, 2);
63 int retval
= gatemate_add_byte_to_bitfile(bit_file
, byte
);
64 if (retval
!= ERROR_OK
)
66 } else if (line_buffer
[idx
] == '/' && line_buffer
[idx
+ 1] == '/') {
71 LOG_ERROR("parsing failed");
78 static int gatemate_getline(char **buffer
, size_t *buf_size
, FILE *input_file
)
80 const size_t chunk_size
= 32;
86 if (read
+ 1 > *buf_size
) {
89 new_buffer
= realloc(*buffer
, *buf_size
+ chunk_size
);
91 new_buffer
= malloc(chunk_size
);
93 LOG_ERROR("Out of memory");
97 *buf_size
+= chunk_size
;
100 int c
= fgetc(input_file
);
101 if ((c
== EOF
&& read
) || (char)c
== '\n') {
102 (*buffer
)[read
++] = 0;
104 } else if (c
== EOF
) {
108 (*buffer
)[read
++] = (char)c
;
114 static int gatemate_read_cfg_file(struct gatemate_bit_file
*bit_file
, const char *filename
)
116 FILE *input_file
= fopen(filename
, "r");
119 LOG_ERROR("Couldn't open %s: %s", filename
, strerror(errno
));
120 return ERROR_PLD_FILE_LOAD_FAILED
;
123 int retval
= ERROR_OK
;
124 char *line_buffer
= NULL
;
125 size_t buffer_length
= 0;
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
);
134 if (retval
!= ERROR_OK
)
135 free(bit_file
->raw_file
.data
);
139 static int gatemate_read_file(struct gatemate_bit_file
*bit_file
, const char *filename
)
141 memset(bit_file
, 0, sizeof(struct gatemate_bit_file
));
143 if (!filename
|| !bit_file
)
144 return ERROR_COMMAND_SYNTAX_ERROR
;
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");
150 return ERROR_PLD_FILE_LOAD_FAILED
;
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
);
158 LOG_ERROR("Filetype not supported, expecting .bit or .cfg file");
159 return ERROR_PLD_FILE_LOAD_FAILED
;
162 static int gatemate_set_instr(struct jtag_tap
*tap
, uint8_t new_instr
)
164 struct scan_field field
;
165 field
.num_bits
= tap
->ir_length
;
166 void *t
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
168 LOG_ERROR("Out of memory");
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
);
175 jtag_add_runtest(3, TAP_IDLE
);
180 static int gatemate_load(struct pld_device
*pld_device
, const char *filename
)
185 struct gatemate_pld_device
*gatemate_info
= pld_device
->driver_priv
;
187 if (!gatemate_info
|| !gatemate_info
->tap
)
189 struct jtag_tap
*tap
= gatemate_info
->tap
;
191 struct gatemate_bit_file bit_file
;
192 int retval
= gatemate_read_file(&bit_file
, filename
);
193 if (retval
!= ERROR_OK
)
196 retval
= gatemate_set_instr(tap
, JTAG_CONFIGURE
);
197 if (retval
!= ERROR_OK
) {
198 free(bit_file
.raw_file
.data
);
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
);
208 retval
= jtag_execute_queue();
209 free(bit_file
.raw_file
.data
);
214 static int gatemate_has_jtagspi_instruction(struct pld_device
*device
, bool *has_instruction
)
216 *has_instruction
= true;
220 static int gatemate_connect_spi_to_jtag(struct pld_device
*pld_device
)
225 struct gatemate_pld_device
*pld_device_info
= pld_device
->driver_priv
;
226 if (!pld_device_info
)
229 struct jtag_tap
*tap
= pld_device_info
->tap
;
233 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) == JTAG_SPI_BYPASS
)
236 gatemate_set_instr(tap
, JTAG_SPI_BYPASS
);
238 return jtag_execute_queue();
241 static int gatemate_disconnect_spi_from_jtag(struct pld_device
*pld_device
)
246 struct gatemate_pld_device
*pld_device_info
= pld_device
->driver_priv
;
247 if (!pld_device_info
)
250 struct jtag_tap
*tap
= pld_device_info
->tap
;
254 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != JTAG_SPI_BYPASS
)
257 gatemate_set_instr(tap
, BYPASS
);
259 return jtag_execute_queue();
262 static int gatemate_get_stuff_bits(struct pld_device
*pld_device
, unsigned int *facing_read_bits
,
263 unsigned int *trailing_write_bits
)
268 *facing_read_bits
= 1;
269 *trailing_write_bits
= 1;
274 PLD_CREATE_COMMAND_HANDLER(gatemate_pld_create_command
)
277 return ERROR_COMMAND_SYNTAX_ERROR
;
279 if (strcmp(CMD_ARGV
[2], "-chain-position") != 0)
280 return ERROR_COMMAND_SYNTAX_ERROR
;
282 struct jtag_tap
*tap
= jtag_tap_by_string(CMD_ARGV
[3]);
284 command_print(CMD
, "Tap: %s does not exist", CMD_ARGV
[3]);
288 struct gatemate_pld_device
*gatemate_info
= malloc(sizeof(struct gatemate_pld_device
));
289 if (!gatemate_info
) {
290 LOG_ERROR("Out of memory");
293 gatemate_info
->tap
= tap
;
295 pld
->driver_priv
= gatemate_info
;
300 struct pld_driver gatemate_pld
= {
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
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)