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>
14 #include <helper/bits.h>
19 #define ERASE_SRAM 0x05
20 #define SRAM_ERASE_DONE 0x09
22 #define ADDRESS_INITIALIZATION 0x12
23 #define READ_USERCODE 0x13
24 #define CONFIG_ENABLE 0x15
25 #define TRANSFER_CONFIGURATION_DATA 0x17
26 #define CONFIG_DISABLE 0x3A
28 #define STATUS_REGISTER 0x41
29 #define ERASE_FLASH 0x75
30 #define ENABLE_2ND_FLASH 0x78
32 #define STAUS_MASK_MEMORY_ERASE BIT(5)
33 #define STAUS_MASK_SYSTEM_EDIT_MODE BIT(7)
35 struct gowin_pld_device
{
39 struct gowin_bit_file
{
40 struct raw_bit_file raw_file
;
43 uint16_t stored_checksum
;
52 static uint64_t gowin_read_fs_file_bitsequence(const char *bits
, int length
)
55 for (int i
= 0; i
< length
; i
++)
56 res
= (res
<< 1) | (*bits
++ == '1' ? 1 : 0);
60 static int gowin_add_byte_to_bit_file(struct gowin_bit_file
*bit_file
, uint8_t byte
)
62 if (bit_file
->raw_file
.length
+ 1 > bit_file
->capacity
) {
64 if (bit_file
->raw_file
.data
)
65 buffer
= realloc(bit_file
->raw_file
.data
, bit_file
->capacity
+ 8192);
67 buffer
= malloc(8192);
69 LOG_ERROR("Out of memory");
72 bit_file
->raw_file
.data
= buffer
;
73 bit_file
->capacity
+= 8192;
76 bit_file
->raw_file
.data
[bit_file
->raw_file
.length
++] = byte
;
81 static int gowin_read_fs_file_header(struct gowin_bit_file
*bit_file
, FILE *stream
)
86 int end_of_header
= 0;
87 while (!end_of_header
) {
89 char *line
= fgets(buffer
, 256, stream
);
90 if (!line
|| feof(stream
) || ferror(stream
))
96 size_t line_length
= strlen(line
);
97 if (line
[line_length
- 1] != '\n')
101 for (unsigned int i
= 0; i
< line_length
; i
+= 8) {
102 uint8_t byte
= gowin_read_fs_file_bitsequence(line
+ i
, 8);
103 int retval
= gowin_add_byte_to_bit_file(bit_file
, byte
);
104 if (retval
!= ERROR_OK
)
108 uint8_t key
= gowin_read_fs_file_bitsequence(line
, 8);
110 uint64_t value
= gowin_read_fs_file_bitsequence(line
, line_length
- 8);
113 bit_file
->id
= value
& 0xffffffff;
114 } else if (key
== 0x3B) {
116 bit_file
->crc_en
= (value
& BIT(23)) ? 1 : 0;
123 static int gowin_read_fs_file(struct gowin_bit_file
*bit_file
, const char *filename
)
125 FILE *input_file
= fopen(filename
, "r");
128 LOG_ERROR("Couldn't open %s: %s", filename
, strerror(errno
));
129 return ERROR_PLD_FILE_LOAD_FAILED
;
132 int retval
= gowin_read_fs_file_header(bit_file
, input_file
);
133 if (retval
!= ERROR_OK
) {
134 free(bit_file
->raw_file
.data
);
139 char digits_buffer
[9]; /* 8 + 1 trailing zero */
141 char *digits
= fgets(digits_buffer
, 9, input_file
);
142 if (feof(input_file
))
144 if (!digits
|| ferror(input_file
)) {
145 free(bit_file
->raw_file
.data
);
149 if (digits
[0] == '\n')
152 if (strlen(digits
) != 8) {
153 free(bit_file
->raw_file
.data
);
157 uint8_t byte
= gowin_read_fs_file_bitsequence(digits
, 8);
158 retval
= gowin_add_byte_to_bit_file(bit_file
, byte
);
159 if (retval
!= ERROR_OK
) {
160 free(bit_file
->raw_file
.data
);
170 static int gowin_read_file(struct gowin_bit_file
*bit_file
, const char *filename
, bool *is_fs
)
172 memset(bit_file
, 0, sizeof(struct gowin_bit_file
));
174 if (!filename
|| !bit_file
)
175 return ERROR_COMMAND_SYNTAX_ERROR
;
177 const char *file_suffix_pos
= strrchr(filename
, '.');
178 if (!file_suffix_pos
) {
179 LOG_ERROR("Unable to detect filename suffix");
180 return ERROR_PLD_FILE_LOAD_FAILED
;
183 /* check if binary .bin or ascii .fs */
184 if (strcasecmp(file_suffix_pos
, ".bin") == 0) {
186 return cpld_read_raw_bit_file(&bit_file
->raw_file
, filename
);
187 } else if (strcasecmp(file_suffix_pos
, ".fs") == 0) {
189 return gowin_read_fs_file(bit_file
, filename
);
192 LOG_ERROR("Filetype not supported, expecting .fs or .bin file");
193 return ERROR_PLD_FILE_LOAD_FAILED
;
196 static int gowin_set_instr(struct jtag_tap
*tap
, uint8_t new_instr
)
198 struct scan_field field
;
199 field
.num_bits
= tap
->ir_length
;
200 void *t
= calloc(DIV_ROUND_UP(field
.num_bits
, 8), 1);
202 LOG_ERROR("Out of memory");
206 buf_set_u32(t
, 0, field
.num_bits
, new_instr
);
207 field
.in_value
= NULL
;
208 jtag_add_ir_scan(tap
, &field
, TAP_IDLE
);
209 jtag_add_runtest(3, TAP_IDLE
);
214 static int gowin_read_register(struct jtag_tap
*tap
, uint32_t reg
, uint32_t *result
)
216 struct scan_field field
;
218 int retval
= gowin_set_instr(tap
, reg
);
219 if (retval
!= ERROR_OK
)
221 retval
= jtag_execute_queue();
222 if (retval
!= ERROR_OK
)
225 uint8_t buf
[4] = {0};
226 field
.check_mask
= NULL
;
227 field
.check_value
= NULL
;
229 field
.out_value
= buf
;
230 field
.in_value
= buf
;
232 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
233 retval
= jtag_execute_queue();
234 *result
= le_to_h_u32(buf
);
238 static int gowin_check_status_flag(struct jtag_tap
*tap
, uint32_t mask
, uint32_t flag
)
244 int retval
= gowin_read_register(tap
, STATUS_REGISTER
, &status
);
245 if (retval
!= ERROR_OK
)
247 if (retries
++ == 100000)
249 } while ((status
& mask
) != flag
);
254 static int gowin_enable_config(struct jtag_tap
*tap
)
256 int retval
= gowin_set_instr(tap
, CONFIG_ENABLE
);
257 if (retval
!= ERROR_OK
)
259 retval
= jtag_execute_queue();
260 if (retval
!= ERROR_OK
)
263 return gowin_check_status_flag(tap
, STAUS_MASK_SYSTEM_EDIT_MODE
, STAUS_MASK_SYSTEM_EDIT_MODE
);
266 static int gowin_disable_config(struct jtag_tap
*tap
)
268 int retval
= gowin_set_instr(tap
, CONFIG_DISABLE
);
269 if (retval
!= ERROR_OK
)
271 retval
= jtag_execute_queue();
272 if (retval
!= ERROR_OK
)
275 return gowin_check_status_flag(tap
, STAUS_MASK_SYSTEM_EDIT_MODE
, 0);
278 static int gowin_reload(struct jtag_tap
*tap
)
280 int retval
= gowin_set_instr(tap
, RELOAD
);
281 if (retval
!= ERROR_OK
)
283 retval
= gowin_set_instr(tap
, NO_OP
);
284 if (retval
!= ERROR_OK
)
286 return jtag_execute_queue();
289 static int gowin_runtest_idle(struct jtag_tap
*tap
, unsigned int frac_sec
)
291 int speed
= adapter_get_speed_khz() * 1000;
292 int cycles
= DIV_ROUND_UP(speed
, frac_sec
);
293 jtag_add_runtest(cycles
, TAP_IDLE
);
294 return jtag_execute_queue();
297 static int gowin_erase_sram(struct jtag_tap
*tap
, bool tx_erase_done
)
299 /* config is already enabled */
300 int retval
= gowin_set_instr(tap
, ERASE_SRAM
);
301 if (retval
!= ERROR_OK
)
303 retval
= gowin_set_instr(tap
, NO_OP
);
304 if (retval
!= ERROR_OK
)
307 /* Delay or Run Test 2~10ms */
308 /* 10 ms is worst case for GW2A-55 */
309 jtag_add_sleep(10000);
310 retval
= jtag_execute_queue();
311 if (retval
!= ERROR_OK
)
314 retval
= gowin_check_status_flag(tap
, STAUS_MASK_MEMORY_ERASE
,
315 STAUS_MASK_MEMORY_ERASE
);
316 if (retval
!= ERROR_OK
)
320 retval
= gowin_set_instr(tap
, SRAM_ERASE_DONE
);
321 if (retval
!= ERROR_OK
)
323 retval
= gowin_set_instr(tap
, NO_OP
);
324 if (retval
!= ERROR_OK
)
326 retval
= jtag_execute_queue();
327 if (retval
!= ERROR_OK
)
329 /* gen clock cycles in RUN/IDLE for 500us -> 1/500us = 2000/s */
330 retval
= gowin_runtest_idle(tap
, 2000);
331 if (retval
!= ERROR_OK
)
335 retval
= gowin_set_instr(tap
, NO_OP
);
336 if (retval
!= ERROR_OK
)
338 return jtag_execute_queue();
341 static int gowin_load_to_sram(struct pld_device
*pld_device
, const char *filename
)
346 struct gowin_pld_device
*gowin_info
= pld_device
->driver_priv
;
348 if (!gowin_info
|| !gowin_info
->tap
)
350 struct jtag_tap
*tap
= gowin_info
->tap
;
353 struct gowin_bit_file bit_file
;
354 int retval
= gowin_read_file(&bit_file
, filename
, &is_fs
);
355 if (retval
!= ERROR_OK
)
358 for (unsigned int i
= 0; i
< bit_file
.raw_file
.length
; i
++)
359 bit_file
.raw_file
.data
[i
] = flip_u32(bit_file
.raw_file
.data
[i
], 8);
362 retval
= gowin_read_register(tap
, IDCODE
, &id
);
363 if (retval
!= ERROR_OK
) {
364 free(bit_file
.raw_file
.data
);
368 if (is_fs
&& id
!= bit_file
.id
) {
369 free(bit_file
.raw_file
.data
);
370 LOG_ERROR("Id on device (0x%8.8" PRIx32
") and id in bit-stream (0x%8.8" PRIx32
") don't match.",
375 retval
= gowin_enable_config(tap
);
376 if (retval
!= ERROR_OK
) {
377 free(bit_file
.raw_file
.data
);
381 retval
= gowin_erase_sram(tap
, false);
382 if (retval
!= ERROR_OK
) {
383 free(bit_file
.raw_file
.data
);
387 retval
= gowin_set_instr(tap
, ADDRESS_INITIALIZATION
);
388 if (retval
!= ERROR_OK
) {
389 free(bit_file
.raw_file
.data
);
392 retval
= gowin_set_instr(tap
, TRANSFER_CONFIGURATION_DATA
);
393 if (retval
!= ERROR_OK
) {
394 free(bit_file
.raw_file
.data
);
398 /* scan out the bitstream */
399 struct scan_field field
;
400 field
.num_bits
= bit_file
.raw_file
.length
* 8;
401 field
.out_value
= bit_file
.raw_file
.data
;
402 field
.in_value
= bit_file
.raw_file
.data
;
403 jtag_add_dr_scan(gowin_info
->tap
, 1, &field
, TAP_IDLE
);
404 jtag_add_runtest(3, TAP_IDLE
);
406 retval
= jtag_execute_queue();
407 if (retval
!= ERROR_OK
) {
408 free(bit_file
.raw_file
.data
);
412 retval
= gowin_disable_config(tap
);
413 free(bit_file
.raw_file
.data
);
414 if (retval
!= ERROR_OK
)
417 retval
= gowin_set_instr(gowin_info
->tap
, NO_OP
);
418 if (retval
!= ERROR_OK
)
421 retval
= jtag_execute_queue();
426 static int gowin_read_register_command(struct pld_device
*pld_device
, uint32_t cmd
, uint32_t *value
)
431 struct gowin_pld_device
*gowin_info
= pld_device
->driver_priv
;
433 if (!gowin_info
|| !gowin_info
->tap
)
436 return gowin_read_register(gowin_info
->tap
, cmd
, value
);
439 static int gowin_reload_command(struct pld_device
*pld_device
)
444 struct gowin_pld_device
*gowin_info
= pld_device
->driver_priv
;
446 if (!gowin_info
|| !gowin_info
->tap
)
449 return gowin_reload(gowin_info
->tap
);
452 COMMAND_HANDLER(gowin_read_status_command_handler
)
457 return ERROR_COMMAND_SYNTAX_ERROR
;
459 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], dev_id
);
460 struct pld_device
*device
= get_pld_device_by_num(dev_id
);
462 command_print(CMD
, "pld device '#%s' is out of bounds", CMD_ARGV
[0]);
467 int retval
= gowin_read_register_command(device
, STATUS_REGISTER
, &status
);
469 if (retval
== ERROR_OK
)
470 command_print(CMD
, "0x%8.8" PRIx32
, status
);
475 COMMAND_HANDLER(gowin_read_user_register_command_handler
)
480 return ERROR_COMMAND_SYNTAX_ERROR
;
482 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], dev_id
);
483 struct pld_device
*device
= get_pld_device_by_num(dev_id
);
485 command_print(CMD
, "pld device '#%s' is out of bounds", CMD_ARGV
[0]);
489 uint32_t user_reg
= 0;
490 int retval
= gowin_read_register_command(device
, READ_USERCODE
, &user_reg
);
492 if (retval
== ERROR_OK
)
493 command_print(CMD
, "0x%8.8" PRIx32
, user_reg
);
498 COMMAND_HANDLER(gowin_reload_command_handler
)
503 return ERROR_COMMAND_SYNTAX_ERROR
;
505 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], dev_id
);
506 struct pld_device
*device
= get_pld_device_by_num(dev_id
);
508 command_print(CMD
, "pld device '#%s' is out of bounds", CMD_ARGV
[0]);
512 return gowin_reload_command(device
);
515 static const struct command_registration gowin_exec_command_handlers
[] = {
517 .name
= "read_status",
518 .mode
= COMMAND_EXEC
,
519 .handler
= gowin_read_status_command_handler
,
520 .help
= "reading status register from FPGA",
524 .mode
= COMMAND_EXEC
,
525 .handler
= gowin_read_user_register_command_handler
,
526 .help
= "reading user register from FPGA",
530 .mode
= COMMAND_EXEC
,
531 .handler
= gowin_reload_command_handler
,
532 .help
= "reloading bitstream from flash to SRAM",
535 COMMAND_REGISTRATION_DONE
538 static const struct command_registration gowin_command_handler
[] = {
542 .help
= "gowin specific commands",
544 .chain
= gowin_exec_command_handlers
546 COMMAND_REGISTRATION_DONE
549 PLD_DEVICE_COMMAND_HANDLER(gowin_pld_device_command
)
551 struct jtag_tap
*tap
;
553 struct gowin_pld_device
*gowin_info
;
556 return ERROR_COMMAND_SYNTAX_ERROR
;
558 tap
= jtag_tap_by_string(CMD_ARGV
[1]);
560 command_print(CMD
, "Tap: %s does not exist", CMD_ARGV
[1]);
564 gowin_info
= malloc(sizeof(struct gowin_pld_device
));
566 LOG_ERROR("Out of memory");
569 gowin_info
->tap
= tap
;
571 pld
->driver_priv
= gowin_info
;
576 struct pld_driver gowin_pld
= {
578 .commands
= gowin_command_handler
,
579 .pld_device_command
= &gowin_pld_device_command
,
580 .load
= &gowin_load_to_sram
,
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)