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 static int efinix_get_jtagspi_userircode(struct pld_device
*pld_device
, unsigned int *ir
)
258 PLD_CREATE_COMMAND_HANDLER(efinix_pld_create_command
)
260 if (CMD_ARGC
!= 4 && CMD_ARGC
!= 6)
261 return ERROR_COMMAND_SYNTAX_ERROR
;
263 if (strcmp(CMD_ARGV
[2], "-chain-position") != 0)
264 return ERROR_COMMAND_SYNTAX_ERROR
;
266 struct jtag_tap
*tap
= jtag_tap_by_string(CMD_ARGV
[3]);
268 command_print(CMD
, "Tap: %s does not exist", CMD_ARGV
[3]);
272 enum efinix_family_e family
= EFINIX_UNKNOWN
;
274 if (strcmp(CMD_ARGV
[4], "-family") != 0)
275 return ERROR_COMMAND_SYNTAX_ERROR
;
277 if (strcmp(CMD_ARGV
[5], "trion") == 0) {
278 family
= EFINIX_TRION
;
279 } else if (strcmp(CMD_ARGV
[5], "titanium") == 0) {
280 family
= EFINIX_TITANIUM
;
282 command_print(CMD
, "unknown family");
287 struct efinix_pld_device
*efinix_info
= malloc(sizeof(struct efinix_pld_device
));
289 LOG_ERROR("Out of memory");
292 efinix_info
->tap
= tap
;
293 efinix_info
->family
= family
;
295 pld
->driver_priv
= efinix_info
;
300 struct pld_driver efinix_pld
= {
302 .pld_create_command
= &efinix_pld_create_command
,
303 .load
= &efinix_load
,
304 .get_ipdbg_hub
= efinix_get_ipdbg_hub
,
305 .get_jtagspi_userircode
= efinix_get_jtagspi_userircode
,