1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2006 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
6 ***************************************************************************/
14 #include <helper/log.h>
15 #include <helper/replacements.h>
16 #include <helper/time_support.h>
19 static struct pld_driver
*pld_drivers
[] = {
29 static struct pld_device
*pld_devices
;
31 struct pld_device
*get_pld_device_by_num(int num
)
36 for (p
= pld_devices
; p
; p
= p
->next
) {
38 LOG_WARNING("DEPRECATED: use pld name \"%s\" instead of number %d", p
->name
, num
);
46 struct pld_device
*get_pld_device_by_name(const char *name
)
48 for (struct pld_device
*p
= pld_devices
; p
; p
= p
->next
) {
49 if (strcmp(p
->name
, name
) == 0)
56 struct pld_device
*get_pld_device_by_name_or_numstr(const char *str
)
58 struct pld_device
*dev
= get_pld_device_by_name(str
);
63 unsigned long dev_num
= strtoul(str
, &end
, 0);
64 if (*end
|| dev_num
> INT_MAX
) {
65 LOG_ERROR("Invalid argument");
69 return get_pld_device_by_num(dev_num
);
73 int pld_has_jtagspi_instruction(struct pld_device
*pld_device
, bool *has_instruction
)
75 *has_instruction
= false; /* default is using a proxy bitstream */
80 struct pld_driver
*pld_driver
= pld_device
->driver
;
82 LOG_ERROR("pld device has no associated driver");
86 if (pld_driver
->has_jtagspi_instruction
)
87 return pld_driver
->has_jtagspi_instruction(pld_device
, has_instruction
);
88 /* else, take the default (proxy bitstream) */
92 int pld_get_jtagspi_userircode(struct pld_device
*pld_device
, unsigned int *ir
)
97 struct pld_driver
*pld_driver
= pld_device
->driver
;
99 LOG_ERROR("pld device has no associated driver");
103 if (pld_driver
->get_jtagspi_userircode
)
104 return pld_driver
->get_jtagspi_userircode(pld_device
, ir
);
109 int pld_get_jtagspi_stuff_bits(struct pld_device
*pld_device
, unsigned int *facing_read_bits
,
110 unsigned int *trailing_write_bits
)
115 struct pld_driver
*pld_driver
= pld_device
->driver
;
117 LOG_ERROR("pld device has no associated driver");
121 if (pld_driver
->get_stuff_bits
)
122 return pld_driver
->get_stuff_bits(pld_device
, facing_read_bits
, trailing_write_bits
);
127 int pld_connect_spi_to_jtag(struct pld_device
*pld_device
)
132 struct pld_driver
*pld_driver
= pld_device
->driver
;
134 LOG_ERROR("pld device has no associated driver");
138 if (pld_driver
->connect_spi_to_jtag
)
139 return pld_driver
->connect_spi_to_jtag(pld_device
);
144 int pld_disconnect_spi_from_jtag(struct pld_device
*pld_device
)
149 struct pld_driver
*pld_driver
= pld_device
->driver
;
151 LOG_ERROR("pld device has no associated driver");
155 if (pld_driver
->disconnect_spi_from_jtag
)
156 return pld_driver
->disconnect_spi_from_jtag(pld_device
);
161 COMMAND_HANDLER(handle_pld_create_command
)
164 return ERROR_COMMAND_SYNTAX_ERROR
;
166 struct pld_driver
*pld_driver
= NULL
;
168 for (int i
= 0; pld_drivers
[i
]; i
++) {
169 if (strcmp(CMD_ARGV
[1], pld_drivers
[i
]->name
) == 0) {
170 pld_driver
= pld_drivers
[i
];
176 LOG_ERROR("pld driver '%s' not found", CMD_ARGV
[1]);
177 return ERROR_FAIL
; /* exit(-1); */
180 if (get_pld_device_by_name(CMD_ARGV
[0])) {
181 LOG_ERROR("pld device with name '%s' already exists", CMD_ARGV
[0]);
185 struct pld_device
*pld_device
= malloc(sizeof(struct pld_device
));
187 LOG_ERROR("Out of memory");
191 pld_device
->driver
= pld_driver
;
192 pld_device
->next
= NULL
;
194 int retval
= CALL_COMMAND_HANDLER(pld_driver
->pld_create_command
, pld_device
);
195 if (retval
!= ERROR_OK
) {
196 LOG_ERROR("'%s' driver rejected pld device",
201 pld_device
->name
= strdup(CMD_ARGV
[0]);
202 if (!pld_device
->name
) {
203 LOG_ERROR("Out of memory");
208 /* register pld specific commands */
209 if (pld_driver
->commands
) {
210 retval
= register_commands(CMD_CTX
, NULL
, pld_driver
->commands
);
211 if (retval
!= ERROR_OK
) {
212 LOG_ERROR("couldn't register '%s' commands", CMD_ARGV
[1]);
213 free(pld_device
->name
);
220 /* find last pld device */
221 struct pld_device
*p
= pld_devices
;
222 for (; p
&& p
->next
; p
= p
->next
)
225 p
->next
= pld_device
;
227 pld_devices
= pld_device
;
233 COMMAND_HANDLER(handle_pld_devices_command
)
235 struct pld_device
*p
;
239 command_print(CMD
, "no pld devices configured");
243 for (p
= pld_devices
; p
; p
= p
->next
)
244 command_print(CMD
, "#%i: %s (driver: %s)", i
++, p
->name
, p
->driver
->name
);
249 COMMAND_HANDLER(handle_pld_load_command
)
252 struct timeval start
, end
, duration
;
253 struct pld_device
*p
;
255 gettimeofday(&start
, NULL
);
258 return ERROR_COMMAND_SYNTAX_ERROR
;
260 p
= get_pld_device_by_name_or_numstr(CMD_ARGV
[0]);
262 command_print(CMD
, "pld device '#%s' is out of bounds or unknown", CMD_ARGV
[0]);
266 struct stat input_stat
;
267 if (stat(CMD_ARGV
[1], &input_stat
) == -1) {
268 LOG_ERROR("couldn't stat() %s: %s", CMD_ARGV
[1], strerror(errno
));
269 return ERROR_PLD_FILE_LOAD_FAILED
;
272 if (S_ISDIR(input_stat
.st_mode
)) {
273 LOG_ERROR("%s is a directory", CMD_ARGV
[1]);
274 return ERROR_PLD_FILE_LOAD_FAILED
;
277 if (input_stat
.st_size
== 0) {
278 LOG_ERROR("Empty file %s", CMD_ARGV
[1]);
279 return ERROR_PLD_FILE_LOAD_FAILED
;
282 retval
= p
->driver
->load(p
, CMD_ARGV
[1]);
283 if (retval
!= ERROR_OK
) {
284 command_print(CMD
, "failed loading file %s to pld device %s",
285 CMD_ARGV
[1], CMD_ARGV
[0]);
288 gettimeofday(&end
, NULL
);
289 timeval_subtract(&duration
, &end
, &start
);
291 command_print(CMD
, "loaded file %s to pld device %s in %jis %jius",
292 CMD_ARGV
[1], CMD_ARGV
[0],
293 (intmax_t)duration
.tv_sec
, (intmax_t)duration
.tv_usec
);
299 static const struct command_registration pld_exec_command_handlers
[] = {
302 .handler
= handle_pld_devices_command
,
303 .mode
= COMMAND_EXEC
,
304 .help
= "list configured pld devices",
309 .handler
= handle_pld_load_command
,
310 .mode
= COMMAND_EXEC
,
311 .help
= "load configuration file into PLD",
312 .usage
= "pld_name filename",
314 COMMAND_REGISTRATION_DONE
317 static int pld_init(struct command_context
*cmd_ctx
)
322 return register_commands(cmd_ctx
, "pld", pld_exec_command_handlers
);
325 COMMAND_HANDLER(handle_pld_init_command
)
328 return ERROR_COMMAND_SYNTAX_ERROR
;
330 static bool pld_initialized
;
331 if (pld_initialized
) {
332 LOG_INFO("'pld init' has already been called");
335 pld_initialized
= true;
337 LOG_DEBUG("Initializing PLDs...");
338 return pld_init(CMD_CTX
);
341 static const struct command_registration pld_config_command_handlers
[] = {
344 .mode
= COMMAND_CONFIG
,
345 .handler
= handle_pld_create_command
,
346 .help
= "create a PLD device",
347 .usage
= "name.pld driver_name [driver_args ... ]",
351 .mode
= COMMAND_CONFIG
,
352 .handler
= handle_pld_init_command
,
353 .help
= "initialize PLD devices",
356 COMMAND_REGISTRATION_DONE
358 static const struct command_registration pld_command_handler
[] = {
362 .help
= "programmable logic device commands",
364 .chain
= pld_config_command_handlers
,
366 COMMAND_REGISTRATION_DONE
368 int pld_register_commands(struct command_context
*cmd_ctx
)
370 return register_commands(cmd_ctx
, NULL
, pld_command_handler
);
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)