xref: /aosp_15_r20/external/flashrom/jlink_spi.c (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
1 /*
2  * This file is part of the flashrom project.
3  *
4  * Copyright (C) 2016 Marc Schink <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16 
17 /*
18  * Driver for the J-Link hardware by SEGGER.
19  * See https://www.segger.com/ for more info.
20  */
21 
22 #include <stdlib.h>
23 #include <stdbool.h>
24 #include <stdint.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <libjaylink/libjaylink.h>
28 
29 #include "flash.h"
30 #include "programmer.h"
31 #include "spi.h"
32 
33 /*
34  * Maximum number of bytes that can be transferred at once via the JTAG
35  * interface, see jaylink_jtag_io().
36  */
37 #define JTAG_MAX_TRANSFER_SIZE	(32768 / 8)
38 
39 /*
40  * Default base frequency in Hz. Used when the base frequency can not be
41  * retrieved from the device.
42  */
43 #define DEFAULT_FREQ		16000000
44 
45 /*
46  * Default frequency divider. Used when the frequency divider can not be
47  * retrieved from the device.
48  */
49 #define DEFAULT_FREQ_DIV	4
50 
51 /* Minimum target voltage required for operation in mV. */
52 #define MIN_TARGET_VOLTAGE	1200
53 
54 enum cs_wiring {
55 	CS_RESET, /* nCS is wired to nRESET(pin 15) */
56 	CS_TRST, /* nCS is wired to nTRST(pin 3) */
57 	CS_TMS, /* nCS is wired to TMS/nCS(pin 7) */
58 };
59 
60 struct jlink_spi_data {
61 	struct jaylink_context *ctx;
62 	struct jaylink_device_handle *devh;
63 	enum cs_wiring cs;
64 	bool enable_target_power;
65 };
66 
assert_cs(struct jlink_spi_data * jlink_data)67 static bool assert_cs(struct jlink_spi_data *jlink_data)
68 {
69 	int ret;
70 
71 	if (jlink_data->cs == CS_RESET) {
72 		ret = jaylink_clear_reset(jlink_data->devh);
73 
74 		if (ret != JAYLINK_OK) {
75 			msg_perr("jaylink_clear_reset() failed: %s.\n", jaylink_strerror(ret));
76 			return false;
77 		}
78 	} else if (jlink_data->cs == CS_TRST) {
79 		ret = jaylink_jtag_clear_trst(jlink_data->devh);
80 
81 		if (ret != JAYLINK_OK) {
82 			msg_perr("jaylink_jtag_clear_trst() failed: %s.\n", jaylink_strerror(ret));
83 			return false;
84 		}
85 	} else {
86 		ret = jaylink_jtag_clear_tms(jlink_data->devh);
87 
88 		if (ret != JAYLINK_OK) {
89 			msg_perr("jaylink_jtag_clear_tms() failed: %s.\n", jaylink_strerror(ret));
90 			return false;
91 		}
92 	}
93 
94 	return true;
95 }
96 
deassert_cs(struct jlink_spi_data * jlink_data)97 static bool deassert_cs(struct jlink_spi_data *jlink_data)
98 {
99 	int ret;
100 
101 	if (jlink_data->cs == CS_RESET) {
102 		ret = jaylink_set_reset(jlink_data->devh);
103 
104 		if (ret != JAYLINK_OK) {
105 			msg_perr("jaylink_set_reset() failed: %s.\n", jaylink_strerror(ret));
106 			return false;
107 		}
108 	} else if (jlink_data->cs == CS_TRST) {
109 		ret = jaylink_jtag_set_trst(jlink_data->devh);
110 
111 		if (ret != JAYLINK_OK) {
112 			msg_perr("jaylink_jtag_set_trst() failed: %s.\n", jaylink_strerror(ret));
113 			return false;
114 		}
115 	} else {
116 		ret = jaylink_jtag_set_tms(jlink_data->devh);
117 
118 		if (ret != JAYLINK_OK) {
119 			msg_perr("jaylink_jtag_set_tms() failed: %s.\n", jaylink_strerror(ret));
120 			return false;
121 		}
122 	}
123 
124 	return true;
125 }
126 
jlink_spi_send_command(const struct flashctx * flash,unsigned int writecnt,unsigned int readcnt,const unsigned char * writearr,unsigned char * readarr)127 static int jlink_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
128 		const unsigned char *writearr, unsigned char *readarr)
129 {
130 	uint32_t length;
131 	uint8_t *buffer;
132 	static const uint8_t zeros[JTAG_MAX_TRANSFER_SIZE] = {0};
133 	struct jlink_spi_data *jlink_data = flash->mst->spi.data;
134 
135 	length = writecnt + readcnt;
136 
137 	if (length > JTAG_MAX_TRANSFER_SIZE)
138 		return SPI_INVALID_LENGTH;
139 
140 	buffer = malloc(length);
141 
142 	if (!buffer) {
143 		msg_perr("Memory allocation failed.\n");
144 		return SPI_GENERIC_ERROR;
145 	}
146 
147 	/* Reverse all bytes because the device transfers data LSB first. */
148 	reverse_bytes(buffer, writearr, writecnt);
149 
150 	memset(buffer + writecnt, 0x00, readcnt);
151 
152 	if (!assert_cs(jlink_data)) {
153 		free(buffer);
154 		return SPI_PROGRAMMER_ERROR;
155 	}
156 
157 	/* If CS is wired to TMS, TMS should remain zero. */
158 	const uint8_t *tms_buffer = jlink_data->cs == CS_TMS ? zeros : buffer;
159 
160 	int ret;
161 
162 	ret = jaylink_jtag_io(jlink_data->devh,
163 				tms_buffer, buffer, buffer, length * 8, JAYLINK_JTAG_VERSION_2);
164 
165 	if (ret != JAYLINK_OK) {
166 		msg_perr("jaylink_jtag_io() failed: %s.\n", jaylink_strerror(ret));
167 		free(buffer);
168 		return SPI_PROGRAMMER_ERROR;
169 	}
170 
171 	if (!deassert_cs(jlink_data)) {
172 		free(buffer);
173 		return SPI_PROGRAMMER_ERROR;
174 	}
175 
176 	/* Reverse all bytes because the device transfers data LSB first. */
177 	reverse_bytes(readarr, buffer + writecnt, readcnt);
178 	free(buffer);
179 
180 	return 0;
181 }
182 
jlink_spi_shutdown(void * data)183 static int jlink_spi_shutdown(void *data)
184 {
185 	struct jlink_spi_data *jlink_data = data;
186 
187 	if (jlink_data->enable_target_power) {
188 		int ret = jaylink_set_target_power(jlink_data->devh, false);
189 
190 		if (ret != JAYLINK_OK) {
191 			msg_perr("jaylink_set_target_power() failed: %s.\n",
192 				jaylink_strerror(ret));
193 		}
194 	}
195 
196 	if (jlink_data->devh)
197 		jaylink_close(jlink_data->devh);
198 
199 	jaylink_exit(jlink_data->ctx);
200 	/* jlink_data->ctx, jlink_data->devh are freed by jaylink_close and jaylink_exit */
201 	free(jlink_data);
202 	return 0;
203 }
204 
205 static const struct spi_master spi_master_jlink_spi = {
206 	/* Maximum data read size in one go (excluding opcode+address). */
207 	.max_data_read	= JTAG_MAX_TRANSFER_SIZE - 5,
208 	/* Maximum data write size in one go (excluding opcode+address). */
209 	.max_data_write	= JTAG_MAX_TRANSFER_SIZE - 5,
210 	.command	= jlink_spi_send_command,
211 	.read		= default_spi_read,
212 	.write_256	= default_spi_write_256,
213 	.features	= SPI_MASTER_4BA,
214 	.shutdown	= jlink_spi_shutdown,
215 };
216 
jlink_spi_init(const struct programmer_cfg * cfg)217 static int jlink_spi_init(const struct programmer_cfg *cfg)
218 {
219 	char *arg;
220 	unsigned long speed = 0;
221 	struct jaylink_context *jaylink_ctx = NULL;
222 	struct jaylink_device_handle *jaylink_devh = NULL;
223 	enum cs_wiring cs;
224 	struct jlink_spi_data *jlink_data = NULL;
225 	bool enable_target_power;
226 
227 	arg = extract_programmer_param_str(cfg, "spispeed");
228 
229 	if (arg) {
230 		char *endptr;
231 
232 		errno = 0;
233 		speed = strtoul(arg, &endptr, 10);
234 
235 		if (*endptr != '\0' || errno != 0) {
236 			msg_perr("Invalid SPI speed specified: %s.\n", arg);
237 			free(arg);
238 			return 1;
239 		}
240 
241 		if (speed < 1) {
242 			msg_perr("SPI speed must be at least 1 kHz.\n");
243 			free(arg);
244 			return 1;
245 		}
246 	}
247 
248 	free(arg);
249 
250 	int ret;
251 	bool use_serial_number;
252 	uint32_t serial_number;
253 
254 	arg = extract_programmer_param_str(cfg, "serial");
255 
256 	if (arg) {
257 		if (!strlen(arg)) {
258 			msg_perr("Empty serial number specified.\n");
259 			free(arg);
260 			return 1;
261 		}
262 
263 		ret = jaylink_parse_serial_number(arg, &serial_number);
264 
265 		if (ret == JAYLINK_ERR) {
266 			msg_perr("Invalid serial number specified: %s.\n", arg);
267 			free(arg);
268 			return 1;
269 		} if (ret != JAYLINK_OK) {
270 			msg_perr("jaylink_parse_serial_number() failed: %s.\n", jaylink_strerror(ret));
271 			free(arg);
272 			return 1;
273 		}
274 
275 		use_serial_number = true;
276 	} else {
277 		use_serial_number = false;
278 	}
279 
280 	free(arg);
281 
282 	cs = CS_RESET;
283 	arg = extract_programmer_param_str(cfg, "cs");
284 
285 	if (arg) {
286 		if (!strcasecmp(arg, "reset")) {
287 			cs = CS_RESET;
288 		} else if (!strcasecmp(arg, "trst")) {
289 			cs = CS_TRST;
290 		} else if (!strcasecmp(arg, "tms")) {
291 			cs = CS_TMS;
292 		} else {
293 			msg_perr("Invalid chip select pin specified: '%s'.\n", arg);
294 			free(arg);
295 			return 1;
296 		}
297 	}
298 
299 	free(arg);
300 
301 	if (cs == CS_RESET)
302 		msg_pdbg("Using RESET as chip select signal.\n");
303 	else if (cs == CS_TRST)
304 		msg_pdbg("Using TRST as chip select signal.\n");
305 	else
306 		msg_pdbg("Using TMS/CS as chip select signal.\n");
307 
308 	enable_target_power = false;
309 	arg = extract_programmer_param_str(cfg, "power");
310 
311 	if (arg) {
312 		if (!strcasecmp(arg, "on")) {
313 			enable_target_power = true;
314 		} else {
315 			msg_perr("Invalid value for 'power' argument: '%s'.\n", arg);
316 			free(arg);
317 			return 1;
318 		}
319 	}
320 
321 	free(arg);
322 
323 	ret = jaylink_init(&jaylink_ctx);
324 
325 	if (ret != JAYLINK_OK) {
326 		msg_perr("jaylink_init() failed: %s.\n", jaylink_strerror(ret));
327 		return 1;
328 	}
329 
330 	ret = jaylink_discovery_scan(jaylink_ctx, 0);
331 
332 	if (ret != JAYLINK_OK) {
333 		msg_perr("jaylink_discovery_scan() failed: %s.\n", jaylink_strerror(ret));
334 		goto init_err;
335 	}
336 
337 	struct jaylink_device **devs;
338 
339 	ret = jaylink_get_devices(jaylink_ctx, &devs, NULL);
340 
341 	if (ret != JAYLINK_OK) {
342 		msg_perr("jaylink_get_devices() failed: %s.\n", jaylink_strerror(ret));
343 		goto init_err;
344 	}
345 
346 	if (!use_serial_number)
347 		msg_pdbg("No device selected, using first device.\n");
348 
349 	size_t i;
350 	struct jaylink_device *dev;
351 	bool device_found = false;
352 
353 	for (i = 0; devs[i]; i++) {
354 		if (use_serial_number) {
355 			uint32_t tmp;
356 
357 			ret = jaylink_device_get_serial_number(devs[i], &tmp);
358 
359 			if (ret == JAYLINK_ERR_NOT_AVAILABLE) {
360 				continue;
361 			} else if (ret != JAYLINK_OK) {
362 				msg_pwarn("jaylink_device_get_serial_number() failed: %s.\n",
363 					jaylink_strerror(ret));
364 				continue;
365 			}
366 
367 			if (serial_number != tmp)
368 				continue;
369 		}
370 
371 		ret = jaylink_open(devs[i], &jaylink_devh);
372 
373 		if (ret == JAYLINK_OK) {
374 			dev = devs[i];
375 			device_found = true;
376 			break;
377 		}
378 
379 		jaylink_devh = NULL;
380 	}
381 
382 	jaylink_free_devices(devs, true);
383 
384 	if (!device_found) {
385 		msg_perr("No J-Link device found.\n");
386 		goto init_err;
387 	}
388 
389 	size_t length;
390 	char *firmware_version;
391 
392 	ret = jaylink_get_firmware_version(jaylink_devh, &firmware_version,
393 		&length);
394 
395 	if (ret != JAYLINK_OK) {
396 		msg_perr("jaylink_get_firmware_version() failed: %s.\n", jaylink_strerror(ret));
397 		goto init_err;
398 	} else if (length > 0) {
399 		msg_pdbg("Firmware: %s\n", firmware_version);
400 		free(firmware_version);
401 	}
402 
403 	ret = jaylink_device_get_serial_number(dev, &serial_number);
404 
405 	if (ret == JAYLINK_OK) {
406 		msg_pdbg("S/N: %" PRIu32 "\n", serial_number);
407 	} else if (ret == JAYLINK_ERR_NOT_AVAILABLE) {
408 		msg_pdbg("S/N: N/A\n");
409 	} else {
410 		msg_perr("jaylink_device_get_serial_number() failed: %s.\n", jaylink_strerror(ret));
411 		goto init_err;
412 	}
413 
414 	uint8_t caps[JAYLINK_DEV_EXT_CAPS_SIZE] = { 0 };
415 
416 	ret = jaylink_get_caps(jaylink_devh, caps);
417 
418 	if (ret != JAYLINK_OK) {
419 		msg_perr("jaylink_get_caps() failed: %s.\n", jaylink_strerror(ret));
420 		goto init_err;
421 	}
422 
423 	if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_EXT_CAPS)) {
424 		ret = jaylink_get_extended_caps(jaylink_devh, caps);
425 
426 		if (ret != JAYLINK_OK) {
427 			msg_perr("jaylink_get_extended_caps() failed: %s.\n", jaylink_strerror(ret));
428 			goto init_err;
429 		}
430 	}
431 
432 	if (enable_target_power) {
433 		if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) {
434 			msg_perr("Device does not support target power.\n");
435 			goto init_err;
436 		}
437 	}
438 
439 	uint32_t ifaces;
440 
441 	ret = jaylink_get_available_interfaces(jaylink_devh, &ifaces);
442 
443 	if (ret != JAYLINK_OK) {
444 		msg_perr("jaylink_get_available_interfaces() failed: %s.\n", jaylink_strerror(ret));
445 		goto init_err;
446 	}
447 
448 	if (!(ifaces & (1 << JAYLINK_TIF_JTAG))) {
449 		msg_perr("Device does not support JTAG interface.\n");
450 		goto init_err;
451 	}
452 
453 	ret = jaylink_select_interface(jaylink_devh, JAYLINK_TIF_JTAG, NULL);
454 
455 	if (ret != JAYLINK_OK) {
456 		msg_perr("jaylink_select_interface() failed: %s.\n", jaylink_strerror(ret));
457 		goto init_err;
458 	}
459 
460 	if (enable_target_power) {
461 		ret = jaylink_set_target_power(jaylink_devh, true);
462 
463 		if (ret != JAYLINK_OK) {
464 			msg_perr("jaylink_set_target_power() failed: %s.\n", jaylink_strerror(ret));
465 			goto init_err;
466 		}
467 
468 		/* Wait some time until the target is powered up. */
469 		internal_sleep(10000);
470 	}
471 
472 	struct jaylink_hardware_status hwstat;
473 
474 	ret = jaylink_get_hardware_status(jaylink_devh, &hwstat);
475 
476 	if (ret != JAYLINK_OK) {
477 		msg_perr("jaylink_get_hardware_status() failed: %s.\n", jaylink_strerror(ret));
478 		goto init_err;
479 	}
480 
481 	msg_pdbg("VTarget: %u.%03u V\n", hwstat.target_voltage / 1000,
482 		hwstat.target_voltage % 1000);
483 
484 	if (hwstat.target_voltage < MIN_TARGET_VOLTAGE) {
485 		msg_perr("Target voltage is below %u.%03u V. You need to attach VTref to the I/O voltage of "
486 			"the chip.\n", MIN_TARGET_VOLTAGE / 1000, MIN_TARGET_VOLTAGE % 1000);
487 		goto init_err;
488 	}
489 
490 	struct jaylink_speed device_speeds;
491 
492 	device_speeds.freq = DEFAULT_FREQ;
493 	device_speeds.div = DEFAULT_FREQ_DIV;
494 
495 	if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_SPEEDS)) {
496 		ret = jaylink_get_speeds(jaylink_devh, &device_speeds);
497 
498 		if (ret != JAYLINK_OK) {
499 			msg_perr("jaylink_get_speeds() failed: %s.\n", jaylink_strerror(ret));
500 			goto init_err;
501 		}
502 	}
503 
504 	device_speeds.freq /= 1000;
505 
506 	msg_pdbg("Maximum SPI speed: %" PRIu32 " kHz\n", device_speeds.freq / device_speeds.div);
507 
508 	if (!speed) {
509 		speed = device_speeds.freq / device_speeds.div;
510 		msg_pdbg("SPI speed not specified, using %lu kHz.\n", speed);
511 	}
512 
513 	if (speed > (device_speeds.freq / device_speeds.div)) {
514 		msg_perr("Specified SPI speed of %lu kHz is too high. Maximum is %" PRIu32 " kHz.\n", speed,
515 			device_speeds.freq / device_speeds.div);
516 		goto init_err;
517 	}
518 
519 	ret = jaylink_set_speed(jaylink_devh, speed);
520 
521 	if (ret != JAYLINK_OK) {
522 		msg_perr("jaylink_set_speed() failed: %s.\n", jaylink_strerror(ret));
523 		goto init_err;
524 	}
525 
526 	msg_pdbg("SPI speed: %lu kHz\n", speed);
527 
528 	jlink_data = calloc(1, sizeof(*jlink_data));
529 	if (!jlink_data) {
530 		msg_perr("Unable to allocate space for SPI master data\n");
531 		goto init_err;
532 	}
533 
534 	/* jaylink_ctx, jaylink_devh are allocated by jaylink_init and jaylink_open */
535 	jlink_data->ctx = jaylink_ctx;
536 	jlink_data->devh = jaylink_devh;
537 	jlink_data->cs = cs;
538 	jlink_data->enable_target_power = enable_target_power;
539 
540 	/* Ensure that the CS signal is not active initially. */
541 	if (!deassert_cs(jlink_data))
542 		goto init_err;
543 
544 	return register_spi_master(&spi_master_jlink_spi, jlink_data);
545 
546 init_err:
547 	if (jaylink_devh)
548 		jaylink_close(jaylink_devh);
549 
550 	jaylink_exit(jaylink_ctx);
551 
552 	/* jaylink_ctx, jaylink_devh are freed by jaylink_close and jaylink_exit */
553 	if (jlink_data)
554 		free(jlink_data);
555 
556 	return 1;
557 }
558 
559 const struct programmer_entry programmer_jlink_spi = {
560 	.name			= "jlink_spi",
561 	.type			= OTHER,
562 	.init			= jlink_spi_init,
563 	.devs.note		= "SEGGER J-Link and compatible devices\n",
564 };
565