1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2022 by Daniel Anselmi *
6 ***************************************************************************/
12 #include <jtag/jtag.h>
24 enum efinix_family_e
{
30 #define TRAILING_ZEROS 4000
31 #define RUNTEST_START_CYCLES 100
32 #define RUNTEST_FINISH_CYCLES 100
34 struct efinix_device
{
39 struct efinix_pld_device
{
41 enum efinix_family_e family
;
44 static int efinix_read_bit_file(struct raw_bit_file
*bit_file
, const char *filename
)
46 FILE *input_file
= fopen(filename
, "r");
48 LOG_ERROR("couldn't open %s: %s", filename
, strerror(errno
));
49 return ERROR_PLD_FILE_LOAD_FAILED
;
52 fseek(input_file
, 0, SEEK_END
);
53 long length
= ftell(input_file
);
54 fseek(input_file
, 0, SEEK_SET
);
56 if (length
< 0 || ((length
% 3))) {
58 LOG_ERROR("Failed to get length from file %s: %s", filename
, strerror(errno
));
59 return ERROR_PLD_FILE_LOAD_FAILED
;
61 bit_file
->length
= DIV_ROUND_UP(length
, 3);
63 bit_file
->data
= malloc(bit_file
->length
);
64 if (!bit_file
->data
) {
66 LOG_ERROR("Out of memory");
67 return ERROR_PLD_FILE_LOAD_FAILED
;
70 bool end_detected
= false;
72 for (size_t idx
= 0; !end_detected
&& idx
< bit_file
->length
; ++idx
) {
73 size_t read_count
= fread(buffer
, sizeof(char), 3, input_file
);
74 end_detected
= feof(input_file
);
75 if ((read_count
== 3 && buffer
[2] != '\n') ||
76 (read_count
!= 3 && !end_detected
) ||
77 (read_count
!= 2 && end_detected
)) {
80 bit_file
->data
= NULL
;
81 LOG_ERROR("unexpected line length");
82 return ERROR_PLD_FILE_LOAD_FAILED
;
85 if (!isxdigit(buffer
[0]) || !isxdigit(buffer
[1])) {
88 bit_file
->data
= NULL
;
89 LOG_ERROR("unexpected char in hex string");
90 return ERROR_PLD_FILE_LOAD_FAILED
;
92 unhexify(&bit_file
->data
[idx
], buffer
, 2);
100 static int efinix_read_file(struct raw_bit_file
*bit_file
, const char *filename
)
102 if (!filename
|| !bit_file
)
103 return ERROR_COMMAND_SYNTAX_ERROR
;
105 /* check if binary .bin or ascii .bit/.hex */
106 const char *file_ending_pos
= strrchr(filename
, '.');
107 if (!file_ending_pos
) {
108 LOG_ERROR("Unable to detect filename suffix");
109 return ERROR_PLD_FILE_LOAD_FAILED
;
112 if (strcasecmp(file_ending_pos
, ".bin") == 0) {
113 return cpld_read_raw_bit_file(bit_file
, filename
);
114 } else if ((strcasecmp(file_ending_pos
, ".bit") == 0) ||
115 (strcasecmp(file_ending_pos
, ".hex") == 0)) {
116 return efinix_read_bit_file(bit_file
, filename
);
119 LOG_ERROR("Unable to detect filetype");
120 return ERROR_PLD_FILE_LOAD_FAILED
;
123 static int efinix_set_instr(struct jtag_tap
*tap
, uint8_t new_instr
)
125 struct scan_field field
;
126 field
.num_bits
= tap
->ir_length
;
127 void *t
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
129 LOG_ERROR("Out of memory");
133 buf_set_u32(t
, 0, field
.num_bits
, new_instr
);
134 field
.in_value
= NULL
;
135 jtag_add_ir_scan(tap
, &field
, TAP_IDLE
);
140 static int efinix_load(struct pld_device
*pld_device
, const char *filename
)
142 struct raw_bit_file bit_file
;
143 struct scan_field field
[2];
145 if (!pld_device
|| !pld_device
->driver_priv
)
148 struct efinix_pld_device
*efinix_info
= pld_device
->driver_priv
;
149 if (!efinix_info
|| !efinix_info
->tap
)
151 struct jtag_tap
*tap
= efinix_info
->tap
;
155 int retval
= efinix_set_instr(tap
, PROGRAM
);
156 if (retval
!= ERROR_OK
)
158 jtag_add_runtest(RUNTEST_START_CYCLES
, TAP_IDLE
);
159 retval
= efinix_set_instr(tap
, PROGRAM
); /* fix for T20 */
160 if (retval
!= ERROR_OK
)
162 retval
= jtag_execute_queue();
163 if (retval
!= ERROR_OK
)
166 retval
= efinix_read_file(&bit_file
, filename
);
167 if (retval
!= ERROR_OK
)
170 for (size_t i
= 0; i
< bit_file
.length
; i
++)
171 bit_file
.data
[i
] = flip_u32(bit_file
.data
[i
], 8);
173 /* shift in the bitstream */
174 field
[0].num_bits
= bit_file
.length
* 8;
175 field
[0].out_value
= bit_file
.data
;
176 field
[0].in_value
= NULL
;
178 /* followed by zeros */
179 field
[1].num_bits
= TRAILING_ZEROS
;
180 uint8_t *buf
= calloc(TRAILING_ZEROS
/ 8, 1);
183 LOG_ERROR("Out of memory");
186 field
[1].out_value
= buf
;
187 field
[1].in_value
= NULL
;
189 jtag_add_dr_scan(tap
, 2, field
, TAP_DRPAUSE
);
190 retval
= jtag_execute_queue();
193 if (retval
!= ERROR_OK
)
196 retval
= efinix_set_instr(tap
, ENTERUSER
);
197 if (retval
!= ERROR_OK
)
200 /* entering RUN/TEST for 100 cycles */
201 jtag_add_runtest(RUNTEST_FINISH_CYCLES
, TAP_IDLE
);
202 retval
= jtag_execute_queue();
207 static int efinix_get_ipdbg_hub(int user_num
, struct pld_device
*pld_device
, struct pld_ipdbg_hub
*hub
)
212 struct efinix_pld_device
*pld_device_info
= pld_device
->driver_priv
;
214 if (!pld_device_info
|| !pld_device_info
->tap
)
217 hub
->tap
= pld_device_info
->tap
;
219 if (pld_device_info
->family
== EFINIX_UNKNOWN
) {
220 LOG_ERROR("family unknown, please specify for 'pld create'");
223 int num_user
= 2; /* trion */
224 if (pld_device_info
->family
== EFINIX_TITANIUM
)
227 if (user_num
> num_user
) {
228 LOG_ERROR("Devices has only user register 1 to %d", num_user
);
234 hub
->user_ir_code
= USER1
;
237 hub
->user_ir_code
= USER2
;
240 hub
->user_ir_code
= USER3
;
243 hub
->user_ir_code
= USER4
;
246 LOG_ERROR("efinix devices only have user register 1 to %d", num_user
);
252 PLD_CREATE_COMMAND_HANDLER(efinix_pld_create_command
)
254 if (CMD_ARGC
!= 4 && CMD_ARGC
!= 6)
255 return ERROR_COMMAND_SYNTAX_ERROR
;
257 if (strcmp(CMD_ARGV
[2], "-chain-position") != 0)
258 return ERROR_COMMAND_SYNTAX_ERROR
;
260 struct jtag_tap
*tap
= jtag_tap_by_string(CMD_ARGV
[3]);
262 command_print(CMD
, "Tap: %s does not exist", CMD_ARGV
[3]);
266 enum efinix_family_e family
= EFINIX_UNKNOWN
;
268 if (strcmp(CMD_ARGV
[4], "-family") != 0)
269 return ERROR_COMMAND_SYNTAX_ERROR
;
271 if (strcmp(CMD_ARGV
[5], "trion") == 0) {
272 family
= EFINIX_TRION
;
273 } else if (strcmp(CMD_ARGV
[5], "titanium") == 0) {
274 family
= EFINIX_TITANIUM
;
276 command_print(CMD
, "unknown family");
281 struct efinix_pld_device
*efinix_info
= malloc(sizeof(struct efinix_pld_device
));
283 LOG_ERROR("Out of memory");
286 efinix_info
->tap
= tap
;
287 efinix_info
->family
= family
;
289 pld
->driver_priv
= efinix_info
;
294 struct pld_driver efinix_pld
= {
296 .pld_create_command
= &efinix_pld_create_command
,
297 .load
= &efinix_load
,
298 .get_ipdbg_hub
= efinix_get_ipdbg_hub
,
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)