blob: 65bb5b076582e1e1d75d081b75cf7c44febe6fe1 [file] [log] [blame]
Urja Rannikko22915352009-06-23 11:33:43 +00001/*
2 * This file is part of the flashrom project.
3 *
Urja Rannikkoc93f5f12011-09-15 23:38:14 +00004 * Copyright (C) 2009, 2011 Urja Rannikko <urjaman@gmail.com>
Urja Rannikko22915352009-06-23 11:33:43 +00005 * Copyright (C) 2009 Carl-Daniel Hailfinger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
Urja Rannikko22915352009-06-23 11:33:43 +000016 */
17
Stefan Taunerb0eee9b2015-01-10 09:32:50 +000018#include "platform.h"
19
Carl-Daniel Hailfingeref58a9c2009-08-12 13:32:56 +000020#include <stdio.h>
Stefan Taunerb0eee9b2015-01-10 09:32:50 +000021#if ! IS_WINDOWS /* stuff (presumably) needed for sockets only */
Urja Rannikko22915352009-06-23 11:33:43 +000022#include <stdlib.h>
Carl-Daniel Hailfingeref58a9c2009-08-12 13:32:56 +000023#include <unistd.h>
Urja Rannikko22915352009-06-23 11:33:43 +000024#include <fcntl.h>
Urja Rannikko22915352009-06-23 11:33:43 +000025#include <sys/socket.h>
26#include <arpa/inet.h>
27#include <netinet/in.h>
28#include <netinet/tcp.h>
29#include <netdb.h>
Stefan Tauner52b6e9d2013-04-01 00:46:05 +000030#endif
Stefan Taunerb0eee9b2015-01-10 09:32:50 +000031#if IS_WINDOWS
Stefan Tauner52b6e9d2013-04-01 00:46:05 +000032#include <conio.h>
33#else
Urja Rannikko22915352009-06-23 11:33:43 +000034#include <termios.h>
Stefan Tauner52b6e9d2013-04-01 00:46:05 +000035#endif
36#include <string.h>
37#include <errno.h>
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000038#include "flash.h"
39#include "programmer.h"
Urja Rannikkoc93f5f12011-09-15 23:38:14 +000040#include "chipdrivers.h"
Felix Singer100be2c2021-10-13 13:40:07 +020041
42/* According to Serial Flasher Protocol Specification - version 1 */
43#define S_ACK 0x06
44#define S_NAK 0x15
45#define S_CMD_NOP 0x00 /* No operation */
46#define S_CMD_Q_IFACE 0x01 /* Query interface version */
47#define S_CMD_Q_CMDMAP 0x02 /* Query supported commands bitmap */
48#define S_CMD_Q_PGMNAME 0x03 /* Query programmer name */
49#define S_CMD_Q_SERBUF 0x04 /* Query Serial Buffer Size */
50#define S_CMD_Q_BUSTYPE 0x05 /* Query supported bustypes */
51#define S_CMD_Q_CHIPSIZE 0x06 /* Query supported chipsize (2^n format) */
52#define S_CMD_Q_OPBUF 0x07 /* Query operation buffer size */
53#define S_CMD_Q_WRNMAXLEN 0x08 /* Query Write to opbuf: Write-N maximum length */
54#define S_CMD_R_BYTE 0x09 /* Read a single byte */
55#define S_CMD_R_NBYTES 0x0A /* Read n bytes */
56#define S_CMD_O_INIT 0x0B /* Initialize operation buffer */
57#define S_CMD_O_WRITEB 0x0C /* Write opbuf: Write byte with address */
58#define S_CMD_O_WRITEN 0x0D /* Write to opbuf: Write-N */
59#define S_CMD_O_DELAY 0x0E /* Write opbuf: udelay */
60#define S_CMD_O_EXEC 0x0F /* Execute operation buffer */
61#define S_CMD_SYNCNOP 0x10 /* Special no-operation that returns NAK+ACK */
62#define S_CMD_Q_RDNMAXLEN 0x11 /* Query read-n maximum length */
63#define S_CMD_S_BUSTYPE 0x12 /* Set used bustype(s). */
64#define S_CMD_O_SPIOP 0x13 /* Perform SPI operation. */
65#define S_CMD_S_SPI_FREQ 0x14 /* Set SPI clock frequency */
66#define S_CMD_S_PIN_STATE 0x15 /* Enable/disable output drivers */
Urja Rannikkof3196df2009-07-21 13:02:59 +000067
Stefan Tauner31019d42011-10-22 21:45:27 +000068#define MSGHEADER "serprog: "
Urja Rannikkof3196df2009-07-21 13:02:59 +000069
David Hendricks8bb20212011-06-14 01:35:36 +000070/*
71 * FIXME: This prototype was added to help reduce diffs for the shutdown
72 * registration patch, which shifted many lines of code to place
73 * serprog_shutdown() before serprog_init(). It should be removed soon.
74 */
75static int serprog_shutdown(void *data);
76
Urja Rannikkof3196df2009-07-21 13:02:59 +000077static uint16_t sp_device_serbuf_size = 16;
78static uint16_t sp_device_opbuf_size = 300;
79/* Bitmap of supported commands */
80static uint8_t sp_cmdmap[32];
81
Uwe Hermann4e3d0b32010-03-25 23:18:41 +000082/* sp_prev_was_write used to detect writes with contiguous addresses
Urja Rannikkof3196df2009-07-21 13:02:59 +000083 and combine them to write-n's */
84static int sp_prev_was_write = 0;
85/* sp_write_n_addr used as the starting addr of the currently
86 combined write-n operation */
87static uint32_t sp_write_n_addr;
88/* The maximum length of an write_n operation; 0 = write-n not supported */
89static uint32_t sp_max_write_n = 0;
90/* The maximum length of a read_n operation; 0 = 2^24 */
91static uint32_t sp_max_read_n = 0;
92
93/* A malloc'd buffer for combining the operation's data
94 and a counter that tells how much data is there. */
95static uint8_t *sp_write_n_buf;
96static uint32_t sp_write_n_bytes = 0;
97
98/* sp_streamed_* used for flow control checking */
Nico Huber519be662018-12-23 20:03:35 +010099static unsigned int sp_streamed_transmit_ops = 0;
100static unsigned int sp_streamed_transmit_bytes = 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000101
102/* sp_opbuf_usage used for counting the amount of
103 on-device operation buffer used */
104static int sp_opbuf_usage = 0;
105/* if true causes sp_docommand to automatically check
106 whether the command is supported before doing it */
107static int sp_check_avail_automatic = 0;
108
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000109#if ! IS_WINDOWS
Urja Rannikkof3196df2009-07-21 13:02:59 +0000110static int sp_opensocket(char *ip, unsigned int port)
111{
112 int flag = 1;
113 struct hostent *hostPtr = NULL;
Carl-Daniel Hailfinger6d125602009-09-05 01:10:23 +0000114 union { struct sockaddr_in si; struct sockaddr s; } sp = {};
Urja Rannikkof3196df2009-07-21 13:02:59 +0000115 int sock;
Sean Nelson74e8af52010-01-10 01:06:23 +0000116 msg_pdbg(MSGHEADER "IP %s port %d\n", ip, port);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000117 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000118 if (sock < 0) {
119 msg_perr("Error: serprog cannot open socket: %s\n", strerror(errno));
120 return -1;
121 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000122 hostPtr = gethostbyname(ip);
123 if (NULL == hostPtr) {
124 hostPtr = gethostbyaddr(ip, strlen(ip), AF_INET);
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000125 if (NULL == hostPtr) {
Stefan Reinauerb8792872014-04-26 16:12:03 +0000126 close(sock);
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000127 msg_perr("Error: cannot resolve %s\n", ip);
128 return -1;
129 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000130 }
Carl-Daniel Hailfinger6d125602009-09-05 01:10:23 +0000131 sp.si.sin_family = AF_INET;
132 sp.si.sin_port = htons(port);
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +0000133 (void)memcpy(&sp.si.sin_addr, hostPtr->h_addr_list[0], hostPtr->h_length);
Carl-Daniel Hailfinger6d125602009-09-05 01:10:23 +0000134 if (connect(sock, &sp.s, sizeof(sp.si)) < 0) {
Urja Rannikkof3196df2009-07-21 13:02:59 +0000135 close(sock);
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000136 msg_perr("Error: serprog cannot connect: %s\n", strerror(errno));
137 return -1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000138 }
139 /* We are latency limited, and sometimes do write-write-read *
140 * (write-n) - so enable TCP_NODELAY. */
Stefan Reinauer907c3eb2014-04-26 16:12:31 +0000141 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int))) {
142 close(sock);
143 msg_perr("Error: serprog cannot set socket options: %s\n", strerror(errno));
144 return -1;
145 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000146 return sock;
147}
Stefan Tauner52b6e9d2013-04-01 00:46:05 +0000148#endif
Urja Rannikkof3196df2009-07-21 13:02:59 +0000149
Uwe Hermann4e3d0b32010-03-25 23:18:41 +0000150/* Synchronize: a bit tricky algorithm that tries to (and in my tests has *
Urja Rannikkof3196df2009-07-21 13:02:59 +0000151 * always succeeded in) bring the serial protocol to known waiting-for- *
Stefan Taunerae3d8372013-04-01 00:45:45 +0000152 * command state - uses nonblocking I/O - rest of the driver uses *
Urja Rannikkof3196df2009-07-21 13:02:59 +0000153 * blocking read - TODO: add an alarm() timer for the rest of the app on *
154 * serial operations, though not such a big issue as the first thing to *
155 * do is synchronize (eg. check that device is alive). */
Niklas Söderlund7145a502012-09-07 07:07:07 +0000156static int sp_synchronize(void)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000157{
158 int i;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000159 unsigned char buf[8];
Urja Rannikkof3196df2009-07-21 13:02:59 +0000160 /* First sends 8 NOPs, then flushes the return data - should cause *
161 * the device serial parser to get to a sane state, unless if it *
162 * is waiting for a real long write-n. */
163 memset(buf, S_CMD_NOP, 8);
Stefan Taunerae3d8372013-04-01 00:45:45 +0000164 if (serialport_write_nonblock(buf, 8, 1, NULL) != 0) {
Niklas Söderlund7145a502012-09-07 07:07:07 +0000165 goto err_out;
166 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000167 /* A second should be enough to get all the answers to the buffer */
Stefan Tauner79587f52013-04-01 00:45:51 +0000168 internal_delay(1000 * 1000);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000169 sp_flush_incoming();
170
Cristian Măgherușan-Stanciu9932c7b2011-07-07 19:56:58 +0000171 /* Then try up to 8 times to send syncnop and get the correct special *
172 * return of NAK+ACK. Timing note: up to 10 characters, 10*50ms = *
173 * up to 500ms per try, 8*0.5s = 4s; +1s (above) = up to 5s sync *
174 * attempt, ~1s if immediate success. */
Urja Rannikkof3196df2009-07-21 13:02:59 +0000175 for (i = 0; i < 8; i++) {
176 int n;
177 unsigned char c = S_CMD_SYNCNOP;
Stefan Taunerae3d8372013-04-01 00:45:45 +0000178 if (serialport_write_nonblock(&c, 1, 1, NULL) != 0) {
Niklas Söderlund7145a502012-09-07 07:07:07 +0000179 goto err_out;
180 }
Sean Nelson74e8af52010-01-10 01:06:23 +0000181 msg_pdbg(".");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000182 fflush(stdout);
183 for (n = 0; n < 10; n++) {
Stefan Tauner00e16082013-04-01 00:45:38 +0000184 int ret = serialport_read_nonblock(&c, 1, 50, NULL);
Niklas Söderlund7145a502012-09-07 07:07:07 +0000185 if (ret < 0)
186 goto err_out;
187 if (ret > 0 || c != S_NAK)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000188 continue;
Stefan Tauner00e16082013-04-01 00:45:38 +0000189 ret = serialport_read_nonblock(&c, 1, 20, NULL);
Niklas Söderlund7145a502012-09-07 07:07:07 +0000190 if (ret < 0)
191 goto err_out;
192 if (ret > 0 || c != S_ACK)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000193 continue;
194 c = S_CMD_SYNCNOP;
Stefan Taunerae3d8372013-04-01 00:45:45 +0000195 if (serialport_write_nonblock(&c, 1, 1, NULL) != 0) {
196 goto err_out;
Niklas Söderlund7145a502012-09-07 07:07:07 +0000197 }
Stefan Tauner00e16082013-04-01 00:45:38 +0000198 ret = serialport_read_nonblock(&c, 1, 500, NULL);
Niklas Söderlund7145a502012-09-07 07:07:07 +0000199 if (ret < 0)
200 goto err_out;
201 if (ret > 0 || c != S_NAK)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000202 break; /* fail */
Stefan Tauner00e16082013-04-01 00:45:38 +0000203 ret = serialport_read_nonblock(&c, 1, 100, NULL);
Niklas Söderlund7145a502012-09-07 07:07:07 +0000204 if (ret > 0 || ret < 0)
205 goto err_out;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000206 if (c != S_ACK)
207 break; /* fail */
Sean Nelson74e8af52010-01-10 01:06:23 +0000208 msg_pdbg("\n");
Niklas Söderlund7145a502012-09-07 07:07:07 +0000209 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000210 }
211 }
Niklas Söderlund7145a502012-09-07 07:07:07 +0000212err_out:
213 msg_perr("Error: cannot synchronize protocol - check communications and reset device?\n");
214 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000215}
216
217static int sp_check_commandavail(uint8_t command)
218{
219 int byteoffs, bitoffs;
220 byteoffs = command / 8;
221 bitoffs = command % 8;
222 return (sp_cmdmap[byteoffs] & (1 << bitoffs)) ? 1 : 0;
223}
224
225static int sp_automatic_cmdcheck(uint8_t cmd)
226{
227 if ((sp_check_avail_automatic) && (sp_check_commandavail(cmd) == 0)) {
Stefan Tauner31019d42011-10-22 21:45:27 +0000228 msg_pdbg("Warning: Automatic command availability check failed "
Stefan Taunere34e3e82013-01-01 00:06:51 +0000229 "for cmd 0x%02x - won't execute cmd\n", cmd);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000230 return 1;
231 }
232 return 0;
233}
234
235static int sp_docommand(uint8_t command, uint32_t parmlen,
Stefan Tauner31019d42011-10-22 21:45:27 +0000236 uint8_t *params, uint32_t retlen, void *retparms)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000237{
Urja Rannikkof3196df2009-07-21 13:02:59 +0000238 unsigned char c;
239 if (sp_automatic_cmdcheck(command))
240 return 1;
Stefan Tauner79587f52013-04-01 00:45:51 +0000241 if (serialport_write(&command, 1) != 0) {
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000242 msg_perr("Error: cannot write op code: %s\n", strerror(errno));
243 return 1;
244 }
Stefan Tauner79587f52013-04-01 00:45:51 +0000245 if (serialport_write(params, parmlen) != 0) {
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000246 msg_perr("Error: cannot write parameters: %s\n", strerror(errno));
247 return 1;
248 }
Stefan Tauner79587f52013-04-01 00:45:51 +0000249 if (serialport_read(&c, 1) != 0) {
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000250 msg_perr("Error: cannot read from device: %s\n", strerror(errno));
251 return 1;
252 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000253 if (c == S_NAK)
254 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000255 if (c != S_ACK) {
Stefan Tauner23e10b82016-01-23 16:16:49 +0000256 msg_perr("Error: invalid response 0x%02X from device (to command 0x%02X)\n", c, command);
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000257 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000258 }
259 if (retlen) {
Stefan Tauner79587f52013-04-01 00:45:51 +0000260 if (serialport_read(retparms, retlen) != 0) {
261 msg_perr("Error: cannot read return parameters: %s\n", strerror(errno));
262 return 1;
263 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000264 }
265 return 0;
266}
267
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000268static int sp_flush_stream(void)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000269{
270 if (sp_streamed_transmit_ops)
271 do {
272 unsigned char c;
Stefan Tauner79587f52013-04-01 00:45:51 +0000273 if (serialport_read(&c, 1) != 0) {
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000274 msg_perr("Error: cannot read from device (flushing stream)");
275 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000276 }
277 if (c == S_NAK) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000278 msg_perr("Error: NAK to a stream buffer operation\n");
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000279 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000280 }
281 if (c != S_ACK) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000282 msg_perr("Error: Invalid reply 0x%02X from device\n", c);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000283 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000284 }
285 } while (--sp_streamed_transmit_ops);
286 sp_streamed_transmit_ops = 0;
287 sp_streamed_transmit_bytes = 0;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000288 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000289}
290
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000291static int sp_stream_buffer_op(uint8_t cmd, uint32_t parmlen, uint8_t *parms)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000292{
293 uint8_t *sp;
294 if (sp_automatic_cmdcheck(cmd))
295 return 1;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000296
Urja Rannikkof3196df2009-07-21 13:02:59 +0000297 sp = malloc(1 + parmlen);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000298 if (!sp) {
299 msg_perr("Error: cannot malloc command buffer\n");
300 return 1;
301 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000302 sp[0] = cmd;
303 memcpy(&(sp[1]), parms, parmlen);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000304
305 if (sp_streamed_transmit_bytes >= (1 + parmlen + sp_device_serbuf_size)) {
306 if (sp_flush_stream() != 0) {
307 free(sp);
308 return 1;
309 }
310 }
311 if (serialport_write(sp, 1 + parmlen) != 0) {
312 msg_perr("Error: cannot write command\n");
313 free(sp);
314 return 1;
315 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000316 sp_streamed_transmit_ops += 1;
317 sp_streamed_transmit_bytes += 1 + parmlen;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000318
319 free(sp);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000320 return 0;
321}
322
Edward O'Callaghan5eca4272020-04-12 17:27:53 +1000323static int serprog_spi_send_command(const struct flashctx *flash,
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000324 unsigned int writecnt, unsigned int readcnt,
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000325 const unsigned char *writearr,
326 unsigned char *readarr);
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000327static struct spi_master spi_master_serprog = {
Nico Huber1cf407b2017-11-10 20:18:23 +0100328 .features = SPI_MASTER_4BA,
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000329 .max_data_read = MAX_DATA_READ_UNLIMITED,
330 .max_data_write = MAX_DATA_WRITE_UNLIMITED,
331 .command = serprog_spi_send_command,
332 .multicommand = default_spi_send_multicommand,
Urja Rannikko731316a2017-06-15 13:32:01 +0300333 .read = default_spi_read,
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000334 .write_256 = default_spi_write_256,
Nico Huber7bca1262012-06-15 22:28:12 +0000335 .write_aai = default_spi_write_aai,
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000336};
337
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000338static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
339 chipaddr addr);
340static uint8_t serprog_chip_readb(const struct flashctx *flash,
341 const chipaddr addr);
342static void serprog_chip_readn(const struct flashctx *flash, uint8_t *buf,
343 const chipaddr addr, size_t len);
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000344static const struct par_master par_master_serprog = {
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000345 .chip_readb = serprog_chip_readb,
346 .chip_readw = fallback_chip_readw,
347 .chip_readl = fallback_chip_readl,
348 .chip_readn = serprog_chip_readn,
349 .chip_writeb = serprog_chip_writeb,
350 .chip_writew = fallback_chip_writew,
351 .chip_writel = fallback_chip_writel,
352 .chip_writen = fallback_chip_writen,
353};
354
355static enum chipbustype serprog_buses_supported = BUS_NONE;
356
Thomas Heijligencc853d82021-05-04 15:32:17 +0200357static int serprog_init(void)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000358{
359 uint16_t iface;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000360 unsigned char pgmname[17];
361 unsigned char rbuf[3];
362 unsigned char c;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000363 char *device;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000364 int have_device = 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000365
Stefan Tauner72587f82016-01-04 03:05:15 +0000366 /* the parameter is either of format "dev=/dev/device[:baud]" or "ip=ip:port" */
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000367 device = extract_programmer_param("dev");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000368 if (device && strlen(device)) {
Stefan Tauner72587f82016-01-04 03:05:15 +0000369 char *baud_str = strstr(device, ":");
370 if (baud_str != NULL) {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000371 /* Split device from baudrate. */
Stefan Tauner72587f82016-01-04 03:05:15 +0000372 *baud_str = '\0';
373 baud_str++;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000374 }
Stefan Tauner72587f82016-01-04 03:05:15 +0000375 int baud;
376 /* Convert baud string to value.
377 * baud_str is either NULL (if strstr can't find the colon), points to the \0 after the colon
378 * if no characters where given after the colon, or a string to convert... */
379 if (baud_str == NULL || *baud_str == '\0') {
380 baud = -1;
381 msg_pdbg("No baudrate specified, using the hardware's defaults.\n");
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000382 } else {
Stefan Tauner72587f82016-01-04 03:05:15 +0000383 baud = atoi(baud_str); // FIXME: replace atoi with strtoul
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000384 }
Stefan Tauner72587f82016-01-04 03:05:15 +0000385 if (strlen(device) > 0) {
386 sp_fd = sp_openserport(device, baud);
Stefan Tauneracfc4c62012-11-30 16:46:45 +0000387 if (sp_fd == SER_INV_FD) {
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000388 free(device);
389 return 1;
390 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000391 have_device++;
392 }
393 }
Urja Rannikko27b431b2016-01-04 03:05:23 +0000394
395#if !IS_WINDOWS
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000396 if (device && !strlen(device)) {
397 msg_perr("Error: No device specified.\n"
Stefan Tauner72587f82016-01-04 03:05:15 +0000398 "Use flashrom -p serprog:dev=/dev/device[:baud]\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000399 free(device);
400 return 1;
401 }
402 free(device);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000403
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000404 device = extract_programmer_param("ip");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000405 if (have_device && device) {
406 msg_perr("Error: Both host and device specified.\n"
407 "Please use either dev= or ip= but not both.\n");
408 free(device);
409 return 1;
410 }
411 if (device && strlen(device)) {
Stefan Tauner72587f82016-01-04 03:05:15 +0000412 char *port = strstr(device, ":");
413 if (port != NULL) {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000414 /* Split host from port. */
Stefan Tauner72587f82016-01-04 03:05:15 +0000415 *port = '\0';
416 port++;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000417 }
Stefan Tauner72587f82016-01-04 03:05:15 +0000418 if (!port || !strlen(port)) {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000419 msg_perr("Error: No port specified.\n"
420 "Use flashrom -p serprog:ip=ipaddr:port\n");
421 free(device);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000422 return 1;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000423 }
424 if (strlen(device)) {
Stefan Tauner72587f82016-01-04 03:05:15 +0000425 sp_fd = sp_opensocket(device, atoi(port)); // FIXME: replace atoi with strtoul
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000426 if (sp_fd < 0) {
427 free(device);
428 return 1;
429 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000430 have_device++;
431 }
432 }
433 if (device && !strlen(device)) {
434 msg_perr("Error: No host specified.\n"
435 "Use flashrom -p serprog:ip=ipaddr:port\n");
436 free(device);
437 return 1;
438 }
Urja Rannikko27b431b2016-01-04 03:05:23 +0000439#endif
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000440 free(device);
441
442 if (!have_device) {
Urja Rannikko27b431b2016-01-04 03:05:23 +0000443#if IS_WINDOWS
444 msg_perr("Error: No device specified.\n"
445 "Use flashrom -p serprog:dev=comN[:baud]\n");
446#else
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000447 msg_perr("Error: Neither host nor device specified.\n"
448 "Use flashrom -p serprog:dev=/dev/device:baud or "
449 "flashrom -p serprog:ip=ipaddr:port\n");
Urja Rannikko27b431b2016-01-04 03:05:23 +0000450#endif
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000451 return 1;
452 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000453
David Hendricks8bb20212011-06-14 01:35:36 +0000454 if (register_shutdown(serprog_shutdown, NULL))
455 return 1;
456
Sean Nelson74e8af52010-01-10 01:06:23 +0000457 msg_pdbg(MSGHEADER "connected - attempting to synchronize\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000458
459 sp_check_avail_automatic = 0;
460
Niklas Söderlund7145a502012-09-07 07:07:07 +0000461 if (sp_synchronize())
462 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000463
Sean Nelson74e8af52010-01-10 01:06:23 +0000464 msg_pdbg(MSGHEADER "Synchronized\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000465
466 if (sp_docommand(S_CMD_Q_IFACE, 0, NULL, 2, &iface)) {
Stefan Tauner31019d42011-10-22 21:45:27 +0000467 msg_perr("Error: NAK to query interface version\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000468 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000469 }
470
471 if (iface != 1) {
Stefan Tauner31019d42011-10-22 21:45:27 +0000472 msg_perr("Error: Unknown interface version: %d\n", iface);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000473 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000474 }
475
Sean Nelson74e8af52010-01-10 01:06:23 +0000476 msg_pdbg(MSGHEADER "Interface version ok.\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000477
478 if (sp_docommand(S_CMD_Q_CMDMAP, 0, NULL, 32, sp_cmdmap)) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000479 msg_perr("Error: query command map not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000480 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000481 }
482
483 sp_check_avail_automatic = 1;
484
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000485 /* FIXME: This assumes that serprog device bustypes are always
486 * identical with flashrom bustype enums and that they all fit
487 * in a single byte.
488 */
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000489 if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000490 msg_pwarn("Warning: NAK to query supported buses\n");
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000491 c = BUS_NONSPI; /* A reasonable default for now. */
Urja Rannikkof3196df2009-07-21 13:02:59 +0000492 }
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000493 serprog_buses_supported = c;
494
Stefan Tauner31019d42011-10-22 21:45:27 +0000495 msg_pdbg(MSGHEADER "Bus support: parallel=%s, LPC=%s, FWH=%s, SPI=%s\n",
496 (c & BUS_PARALLEL) ? "on" : "off",
497 (c & BUS_LPC) ? "on" : "off",
498 (c & BUS_FWH) ? "on" : "off",
499 (c & BUS_SPI) ? "on" : "off");
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000500 /* Check for the minimum operational set of commands. */
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000501 if (serprog_buses_supported & BUS_SPI) {
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000502 uint8_t bt = BUS_SPI;
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000503 char *spispeed;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000504 if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
505 msg_perr("Error: SPI operation not supported while the "
506 "bustype is SPI\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000507 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000508 }
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000509 if (sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL))
510 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000511 /* Success of any of these commands is optional. We don't need
512 the programmer to tell us its limits, but if it doesn't, we
513 will assume stuff, so it's in the programmers best interest
514 to tell us. */
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000515 if (!sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
516 uint32_t v;
517 v = ((unsigned int)(rbuf[0]) << 0);
518 v |= ((unsigned int)(rbuf[1]) << 8);
519 v |= ((unsigned int)(rbuf[2]) << 16);
520 if (v == 0)
521 v = (1 << 24) - 1; /* SPI-op maximum. */
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000522 spi_master_serprog.max_data_write = v;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000523 msg_pdbg(MSGHEADER "Maximum write-n length is %d\n", v);
524 }
525 if (!sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf)) {
526 uint32_t v;
527 v = ((unsigned int)(rbuf[0]) << 0);
528 v |= ((unsigned int)(rbuf[1]) << 8);
529 v |= ((unsigned int)(rbuf[2]) << 16);
530 if (v == 0)
531 v = (1 << 24) - 1; /* SPI-op maximum. */
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000532 spi_master_serprog.max_data_read = v;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000533 msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
534 }
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000535 spispeed = extract_programmer_param("spispeed");
536 if (spispeed && strlen(spispeed)) {
537 uint32_t f_spi_req, f_spi;
538 uint8_t buf[4];
539 char *f_spi_suffix;
540
541 errno = 0;
542 f_spi_req = strtol(spispeed, &f_spi_suffix, 0);
543 if (errno != 0 || spispeed == f_spi_suffix) {
544 msg_perr("Error: Could not convert 'spispeed'.\n");
Stefan Taunere34e3e82013-01-01 00:06:51 +0000545 free(spispeed);
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000546 return 1;
547 }
548 if (strlen(f_spi_suffix) == 1) {
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000549 if (!strcasecmp(f_spi_suffix, "M")) {
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000550 f_spi_req *= 1000000;
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000551 } else if (!strcasecmp(f_spi_suffix, "k")) {
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000552 f_spi_req *= 1000;
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000553 } else {
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000554 msg_perr("Error: Garbage following 'spispeed' value.\n");
Stefan Taunere34e3e82013-01-01 00:06:51 +0000555 free(spispeed);
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000556 return 1;
557 }
558 } else if (strlen(f_spi_suffix) > 1) {
559 msg_perr("Error: Garbage following 'spispeed' value.\n");
Stefan Taunere34e3e82013-01-01 00:06:51 +0000560 free(spispeed);
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000561 return 1;
562 }
563
564 buf[0] = (f_spi_req >> (0 * 8)) & 0xFF;
565 buf[1] = (f_spi_req >> (1 * 8)) & 0xFF;
566 buf[2] = (f_spi_req >> (2 * 8)) & 0xFF;
567 buf[3] = (f_spi_req >> (3 * 8)) & 0xFF;
568
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000569 if (sp_check_commandavail(S_CMD_S_SPI_FREQ) == 0) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000570 msg_pwarn(MSGHEADER "Warning: Setting the SPI clock rate is not supported!\n");
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000571 } else if (sp_docommand(S_CMD_S_SPI_FREQ, 4, buf, 4, buf) == 0) {
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000572 f_spi = buf[0];
573 f_spi |= buf[1] << (1 * 8);
574 f_spi |= buf[2] << (2 * 8);
575 f_spi |= buf[3] << (3 * 8);
576 msg_pdbg(MSGHEADER "Requested to set SPI clock frequency to %u Hz. "
577 "It was actually set to %u Hz\n", f_spi_req, f_spi);
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000578 } else {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000579 msg_pwarn(MSGHEADER "Setting SPI clock rate to %u Hz failed!\n", f_spi_req);
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000580 }
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000581 }
582 free(spispeed);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000583 bt = serprog_buses_supported;
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000584 if (sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL))
585 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000586 }
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000587
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000588 if (serprog_buses_supported & BUS_NONSPI) {
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000589 if (sp_check_commandavail(S_CMD_O_INIT) == 0) {
590 msg_perr("Error: Initialize operation buffer "
591 "not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000592 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000593 }
594
595 if (sp_check_commandavail(S_CMD_O_DELAY) == 0) {
596 msg_perr("Error: Write to opbuf: "
597 "delay not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000598 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000599 }
600
601 /* S_CMD_O_EXEC availability checked later. */
602
603 if (sp_check_commandavail(S_CMD_R_BYTE) == 0) {
604 msg_perr("Error: Single byte read not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000605 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000606 }
607 /* This could be translated to single byte reads (if missing),
608 * but now we don't support that. */
609 if (sp_check_commandavail(S_CMD_R_NBYTES) == 0) {
610 msg_perr("Error: Read n bytes not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000611 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000612 }
613 if (sp_check_commandavail(S_CMD_O_WRITEB) == 0) {
614 msg_perr("Error: Write to opbuf: "
615 "write byte not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000616 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000617 }
618
619 if (sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
620 msg_pdbg(MSGHEADER "Write-n not supported");
621 sp_max_write_n = 0;
622 } else {
623 sp_max_write_n = ((unsigned int)(rbuf[0]) << 0);
624 sp_max_write_n |= ((unsigned int)(rbuf[1]) << 8);
625 sp_max_write_n |= ((unsigned int)(rbuf[2]) << 16);
626 if (!sp_max_write_n) {
627 sp_max_write_n = (1 << 24);
628 }
629 msg_pdbg(MSGHEADER "Maximum write-n length is %d\n",
630 sp_max_write_n);
631 sp_write_n_buf = malloc(sp_max_write_n);
632 if (!sp_write_n_buf) {
633 msg_perr("Error: cannot allocate memory for "
634 "Write-n buffer\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000635 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000636 }
637 sp_write_n_bytes = 0;
638 }
639
640 if (sp_check_commandavail(S_CMD_Q_RDNMAXLEN) &&
641 (sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf) == 0)) {
642 sp_max_read_n = ((unsigned int)(rbuf[0]) << 0);
643 sp_max_read_n |= ((unsigned int)(rbuf[1]) << 8);
644 sp_max_read_n |= ((unsigned int)(rbuf[2]) << 16);
645 msg_pdbg(MSGHEADER "Maximum read-n length is %d\n",
646 sp_max_read_n ? sp_max_read_n : (1 << 24));
647 } else {
648 msg_pdbg(MSGHEADER "Maximum read-n length "
649 "not reported\n");
650 sp_max_read_n = 0;
651 }
652
Urja Rannikkof3196df2009-07-21 13:02:59 +0000653 }
654
655 if (sp_docommand(S_CMD_Q_PGMNAME, 0, NULL, 16, pgmname)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000656 msg_pwarn("Warning: NAK to query programmer name\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000657 strcpy((char *)pgmname, "(unknown)");
658 }
659 pgmname[16] = 0;
Stefan Tauner31019d42011-10-22 21:45:27 +0000660 msg_pinfo(MSGHEADER "Programmer name is \"%s\"\n", pgmname);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000661
662 if (sp_docommand(S_CMD_Q_SERBUF, 0, NULL, 2, &sp_device_serbuf_size)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000663 msg_pwarn("Warning: NAK to query serial buffer size\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000664 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000665 msg_pdbg(MSGHEADER "Serial buffer size is %d\n",
Urja Rannikkof3196df2009-07-21 13:02:59 +0000666 sp_device_serbuf_size);
667
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000668 if (sp_check_commandavail(S_CMD_O_INIT)) {
669 /* This would be inconsistent. */
670 if (sp_check_commandavail(S_CMD_O_EXEC) == 0) {
671 msg_perr("Error: Execute operation buffer not "
672 "supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000673 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000674 }
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000675
676 if (sp_docommand(S_CMD_O_INIT, 0, NULL, 0, NULL)) {
677 msg_perr("Error: NAK to initialize operation buffer\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000678 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000679 }
680
681 if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2,
682 &sp_device_opbuf_size)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000683 msg_pwarn("Warning: NAK to query operation buffer size\n");
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000684 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000685 msg_pdbg(MSGHEADER "operation buffer size is %d\n",
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000686 sp_device_opbuf_size);
Elyes HAOUAS124ef382018-03-27 12:15:09 +0200687 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000688
Stefan Tauner92fefc92012-10-27 00:34:23 +0000689 if (sp_check_commandavail(S_CMD_S_PIN_STATE)) {
690 uint8_t en = 1;
691 if (sp_docommand(S_CMD_S_PIN_STATE, 1, &en, 0, NULL) != 0) {
692 msg_perr("Error: could not enable output buffers\n");
693 return 1;
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000694 } else {
Stefan Tauner92fefc92012-10-27 00:34:23 +0000695 msg_pdbg(MSGHEADER "Output drivers enabled\n");
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000696 }
697 } else {
Stefan Tauner92fefc92012-10-27 00:34:23 +0000698 msg_pdbg(MSGHEADER "Warning: Programmer does not support toggling its output drivers\n");
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000699 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000700 sp_prev_was_write = 0;
701 sp_streamed_transmit_ops = 0;
702 sp_streamed_transmit_bytes = 0;
703 sp_opbuf_usage = 0;
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000704 if (serprog_buses_supported & BUS_SPI)
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000705 register_spi_master(&spi_master_serprog);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000706 if (serprog_buses_supported & BUS_NONSPI)
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000707 register_par_master(&par_master_serprog, serprog_buses_supported & BUS_NONSPI);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000708 return 0;
709}
710
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000711/* Move an in flashrom buffer existing write-n operation to the on-device operation buffer. */
712static int sp_pass_writen(void)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000713{
714 unsigned char header[7];
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000715 msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n", sp_write_n_bytes, sp_write_n_addr);
716 if (sp_streamed_transmit_bytes >= (7 + sp_write_n_bytes + sp_device_serbuf_size)) {
717 if (sp_flush_stream() != 0) {
718 return 1;
719 }
720 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000721 /* In case it's just a single byte send it as a single write. */
722 if (sp_write_n_bytes == 1) {
723 sp_write_n_bytes = 0;
724 header[0] = (sp_write_n_addr >> 0) & 0xFF;
725 header[1] = (sp_write_n_addr >> 8) & 0xFF;
726 header[2] = (sp_write_n_addr >> 16) & 0xFF;
727 header[3] = sp_write_n_buf[0];
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000728 if (sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header) != 0)
729 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000730 sp_opbuf_usage += 5;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000731 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000732 }
733 header[0] = S_CMD_O_WRITEN;
734 header[1] = (sp_write_n_bytes >> 0) & 0xFF;
735 header[2] = (sp_write_n_bytes >> 8) & 0xFF;
736 header[3] = (sp_write_n_bytes >> 16) & 0xFF;
737 header[4] = (sp_write_n_addr >> 0) & 0xFF;
738 header[5] = (sp_write_n_addr >> 8) & 0xFF;
739 header[6] = (sp_write_n_addr >> 16) & 0xFF;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000740 if (serialport_write(header, 7) != 0) {
741 msg_perr(MSGHEADER "Error: cannot write write-n command\n");
742 return 1;
743 }
744 if (serialport_write(sp_write_n_buf, sp_write_n_bytes) != 0) {
745 msg_perr(MSGHEADER "Error: cannot write write-n data");
746 return 1;
747 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000748 sp_streamed_transmit_bytes += 7 + sp_write_n_bytes;
749 sp_streamed_transmit_ops += 1;
750 sp_opbuf_usage += 7 + sp_write_n_bytes;
751 sp_write_n_bytes = 0;
752 sp_prev_was_write = 0;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000753 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000754}
755
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000756static int sp_execute_opbuf_noflush(void)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000757{
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000758 if ((sp_max_write_n) && (sp_write_n_bytes)) {
759 if (sp_pass_writen() != 0) {
760 msg_perr("Error: could not transfer write buffer\n");
761 return 1;
762 }
763 }
764 if (sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL) != 0) {
765 msg_perr("Error: could not execute command buffer\n");
766 return 1;
767 }
768 msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n", sp_opbuf_usage);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000769 sp_opbuf_usage = 0;
770 sp_prev_was_write = 0;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000771 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000772}
773
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000774static int sp_execute_opbuf(void)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000775{
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000776 if (sp_execute_opbuf_noflush() != 0)
777 return 1;
778 if (sp_flush_stream() != 0)
779 return 1;
780
781 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000782}
783
David Hendricks8bb20212011-06-14 01:35:36 +0000784static int serprog_shutdown(void *data)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000785{
Urja Rannikkof3196df2009-07-21 13:02:59 +0000786 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000787 if (sp_execute_opbuf() != 0)
788 msg_pwarn("Could not flush command buffer.\n");
Stefan Tauner92fefc92012-10-27 00:34:23 +0000789 if (sp_check_commandavail(S_CMD_S_PIN_STATE)) {
790 uint8_t dis = 0;
791 if (sp_docommand(S_CMD_S_PIN_STATE, 1, &dis, 0, NULL) == 0)
792 msg_pdbg(MSGHEADER "Output drivers disabled\n");
793 else
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000794 msg_pwarn(MSGHEADER "%s: Warning: could not disable output buffers\n", __func__);
Stefan Tauner92fefc92012-10-27 00:34:23 +0000795 }
Niklas Söderlund7145a502012-09-07 07:07:07 +0000796 /* FIXME: fix sockets on windows(?), especially closing */
797 serialport_shutdown(&sp_fd);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000798 if (sp_max_write_n)
799 free(sp_write_n_buf);
800 return 0;
801}
802
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000803static int sp_check_opbuf_usage(int bytes_to_be_added)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000804{
805 if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) {
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000806 /* If this happens in the middle of a page load the page load will probably fail. */
807 msg_pwarn(MSGHEADER "Warning: executed operation buffer due to size reasons\n");
808 if (sp_execute_opbuf() != 0)
809 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000810 }
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000811 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000812}
813
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000814static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
815 chipaddr addr)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000816{
Sean Nelson74e8af52010-01-10 01:06:23 +0000817 msg_pspew("%s\n", __func__);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000818 if (sp_max_write_n) {
819 if ((sp_prev_was_write)
820 && (addr == (sp_write_n_addr + sp_write_n_bytes))) {
821 sp_write_n_buf[sp_write_n_bytes++] = val;
822 } else {
823 if ((sp_prev_was_write) && (sp_write_n_bytes))
824 sp_pass_writen();
825 sp_prev_was_write = 1;
826 sp_write_n_addr = addr;
827 sp_write_n_bytes = 1;
828 sp_write_n_buf[0] = val;
829 }
830 sp_check_opbuf_usage(7 + sp_write_n_bytes);
831 if (sp_write_n_bytes >= sp_max_write_n)
832 sp_pass_writen();
833 } else {
834 /* We will have to do single writeb ops. */
835 unsigned char writeb_parm[4];
836 sp_check_opbuf_usage(6);
837 writeb_parm[0] = (addr >> 0) & 0xFF;
838 writeb_parm[1] = (addr >> 8) & 0xFF;
839 writeb_parm[2] = (addr >> 16) & 0xFF;
840 writeb_parm[3] = val;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000841 sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm); // FIXME: return error
Urja Rannikkof3196df2009-07-21 13:02:59 +0000842 sp_opbuf_usage += 5;
843 }
844}
845
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000846static uint8_t serprog_chip_readb(const struct flashctx *flash,
847 const chipaddr addr)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000848{
849 unsigned char c;
850 unsigned char buf[3];
851 /* Will stream the read operation - eg. add it to the stream buffer, *
852 * then flush the buffer, then read the read answer. */
853 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
854 sp_execute_opbuf_noflush();
855 buf[0] = ((addr >> 0) & 0xFF);
856 buf[1] = ((addr >> 8) & 0xFF);
857 buf[2] = ((addr >> 16) & 0xFF);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000858 sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf); // FIXME: return error
859 sp_flush_stream(); // FIXME: return error
Stefan Tauner79587f52013-04-01 00:45:51 +0000860 if (serialport_read(&c, 1) != 0)
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000861 msg_perr(MSGHEADER "readb byteread"); // FIXME: return error
Stefan Taunerc2333752013-07-13 23:31:37 +0000862 msg_pspew("%s addr=0x%" PRIxPTR " returning 0x%02X\n", __func__, addr, c);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000863 return c;
864}
865
Uwe Hermann4e3d0b32010-03-25 23:18:41 +0000866/* Local version that really does the job, doesn't care of max_read_n. */
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000867static int sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000868{
Urja Rannikkof3196df2009-07-21 13:02:59 +0000869 unsigned char sbuf[6];
Stefan Tauner0554ca52013-07-25 22:54:25 +0000870 msg_pspew("%s: addr=0x%" PRIxPTR " len=%zu\n", __func__, addr, len);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000871 /* Stream the read-n -- as above. */
872 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
873 sp_execute_opbuf_noflush();
874 sbuf[0] = ((addr >> 0) & 0xFF);
875 sbuf[1] = ((addr >> 8) & 0xFF);
876 sbuf[2] = ((addr >> 16) & 0xFF);
877 sbuf[3] = ((len >> 0) & 0xFF);
878 sbuf[4] = ((len >> 8) & 0xFF);
879 sbuf[5] = ((len >> 16) & 0xFF);
880 sp_stream_buffer_op(S_CMD_R_NBYTES, 6, sbuf);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000881 if (sp_flush_stream() != 0)
882 return 1;
883 if (serialport_read(buf, len) != 0) {
884 msg_perr(MSGHEADER "Error: cannot read read-n data");
885 return 1;
886 }
887 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000888}
889
890/* The externally called version that makes sure that max_read_n is obeyed. */
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000891static void serprog_chip_readn(const struct flashctx *flash, uint8_t * buf,
892 const chipaddr addr, size_t len)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000893{
894 size_t lenm = len;
895 chipaddr addrm = addr;
Stefan Tauner31019d42011-10-22 21:45:27 +0000896 while ((sp_max_read_n != 0) && (lenm > sp_max_read_n)) {
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000897 sp_do_read_n(&(buf[addrm-addr]), addrm, sp_max_read_n); // FIXME: return error
Urja Rannikkof3196df2009-07-21 13:02:59 +0000898 addrm += sp_max_read_n;
899 lenm -= sp_max_read_n;
900 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000901 if (lenm)
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000902 sp_do_read_n(&(buf[addrm-addr]), addrm, lenm); // FIXME: return error
Urja Rannikkof3196df2009-07-21 13:02:59 +0000903}
904
Thomas Heijligencc853d82021-05-04 15:32:17 +0200905static void serprog_delay(unsigned int usecs)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000906{
907 unsigned char buf[4];
Stefan Tauner31019d42011-10-22 21:45:27 +0000908 msg_pspew("%s usecs=%d\n", __func__, usecs);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000909 if (!sp_check_commandavail(S_CMD_O_DELAY)) {
Stefan Taunerd7d423b2012-10-20 09:13:16 +0000910 msg_pdbg2("serprog_delay used, but programmer doesn't support delays natively - emulating\n");
Stefan Tauner31019d42011-10-22 21:45:27 +0000911 internal_delay(usecs);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000912 return;
913 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000914 if ((sp_max_write_n) && (sp_write_n_bytes))
915 sp_pass_writen();
916 sp_check_opbuf_usage(5);
Stefan Tauner31019d42011-10-22 21:45:27 +0000917 buf[0] = ((usecs >> 0) & 0xFF);
918 buf[1] = ((usecs >> 8) & 0xFF);
919 buf[2] = ((usecs >> 16) & 0xFF);
920 buf[3] = ((usecs >> 24) & 0xFF);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000921 sp_stream_buffer_op(S_CMD_O_DELAY, 4, buf);
922 sp_opbuf_usage += 5;
923 sp_prev_was_write = 0;
924}
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000925
Edward O'Callaghan5eca4272020-04-12 17:27:53 +1000926static int serprog_spi_send_command(const struct flashctx *flash,
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000927 unsigned int writecnt, unsigned int readcnt,
928 const unsigned char *writearr,
929 unsigned char *readarr)
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000930{
931 unsigned char *parmbuf;
932 int ret;
933 msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000934 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes)) {
935 if (sp_execute_opbuf() != 0) {
936 msg_perr("Error: could not execute command buffer before sending SPI commands.\n");
937 return 1;
938 }
939 }
940
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000941 parmbuf = malloc(writecnt + 6);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000942 if (!parmbuf) {
943 msg_perr("Error: could not allocate SPI send param buffer.\n");
944 return 1;
945 }
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000946 parmbuf[0] = (writecnt >> 0) & 0xFF;
947 parmbuf[1] = (writecnt >> 8) & 0xFF;
948 parmbuf[2] = (writecnt >> 16) & 0xFF;
949 parmbuf[3] = (readcnt >> 0) & 0xFF;
950 parmbuf[4] = (readcnt >> 8) & 0xFF;
951 parmbuf[5] = (readcnt >> 16) & 0xFF;
952 memcpy(parmbuf + 6, writearr, writecnt);
953 ret = sp_docommand(S_CMD_O_SPIOP, writecnt + 6, parmbuf, readcnt,
954 readarr);
955 free(parmbuf);
956 return ret;
957}
958
Thomas Heijligencc853d82021-05-04 15:32:17 +0200959static void *serprog_map(const char *descr, uintptr_t phys_addr, size_t len)
Urja Rannikko0b4ffd52015-06-29 23:24:23 +0000960{
961 /* Serprog transmits 24 bits only and assumes the underlying implementation handles any remaining bits
962 * correctly (usually setting them to one either in software (for FWH/LPC) or relying on the fact that
963 * the hardware observes a subset of the address bits only). Combined with the standard mapping of
964 * flashrom this creates a 16 MB-wide window just below the 4 GB boundary where serprog can operate (as
965 * needed for non-SPI chips). Below we make sure that the requested range is within this window. */
966 if ((phys_addr & 0xFF000000) == 0xFF000000) {
967 return (void*)phys_addr;
Urja Rannikko0b4ffd52015-06-29 23:24:23 +0000968 }
Elyes HAOUASec819d62019-06-09 17:50:51 +0200969 msg_pwarn(MSGHEADER "requested mapping %s is incompatible: 0x%zx bytes at 0x%0*" PRIxPTR ".\n",
970 descr, len, PRIxPTR_WIDTH, phys_addr);
971 return NULL;
Urja Rannikko0b4ffd52015-06-29 23:24:23 +0000972}
Thomas Heijligencc853d82021-05-04 15:32:17 +0200973
974const struct programmer_entry programmer_serprog = {
975 .name = "serprog",
976 .type = OTHER,
977 /* FIXME */
978 .devs.note = "All programmer devices speaking the serprog protocol\n",
979 .init = serprog_init,
980 .map_flash_region = serprog_map,
981 .unmap_flash_region = fallback_unmap,
982 .delay = serprog_delay,
983};