blob: 24a51acda9533a0b0f8d72bc7878f7a60bb35700 [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;
aarya885917c2022-03-10 09:16:44 +0530303 if (parms)
304 memcpy(&(sp[1]), parms, parmlen);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000305
306 if (sp_streamed_transmit_bytes >= (1 + parmlen + sp_device_serbuf_size)) {
307 if (sp_flush_stream() != 0) {
308 free(sp);
309 return 1;
310 }
311 }
312 if (serialport_write(sp, 1 + parmlen) != 0) {
313 msg_perr("Error: cannot write command\n");
314 free(sp);
315 return 1;
316 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000317 sp_streamed_transmit_ops += 1;
318 sp_streamed_transmit_bytes += 1 + parmlen;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000319
320 free(sp);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000321 return 0;
322}
323
Edward O'Callaghan5eca4272020-04-12 17:27:53 +1000324static int serprog_spi_send_command(const struct flashctx *flash,
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000325 unsigned int writecnt, unsigned int readcnt,
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000326 const unsigned char *writearr,
327 unsigned char *readarr);
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000328static struct spi_master spi_master_serprog = {
Nico Huber1cf407b2017-11-10 20:18:23 +0100329 .features = SPI_MASTER_4BA,
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000330 .max_data_read = MAX_DATA_READ_UNLIMITED,
331 .max_data_write = MAX_DATA_WRITE_UNLIMITED,
332 .command = serprog_spi_send_command,
333 .multicommand = default_spi_send_multicommand,
Urja Rannikko731316a2017-06-15 13:32:01 +0300334 .read = default_spi_read,
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000335 .write_256 = default_spi_write_256,
Nico Huber7bca1262012-06-15 22:28:12 +0000336 .write_aai = default_spi_write_aai,
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000337};
338
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000339static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
340 chipaddr addr);
341static uint8_t serprog_chip_readb(const struct flashctx *flash,
342 const chipaddr addr);
343static void serprog_chip_readn(const struct flashctx *flash, uint8_t *buf,
344 const chipaddr addr, size_t len);
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000345static const struct par_master par_master_serprog = {
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000346 .chip_readb = serprog_chip_readb,
347 .chip_readw = fallback_chip_readw,
348 .chip_readl = fallback_chip_readl,
349 .chip_readn = serprog_chip_readn,
350 .chip_writeb = serprog_chip_writeb,
351 .chip_writew = fallback_chip_writew,
352 .chip_writel = fallback_chip_writel,
353 .chip_writen = fallback_chip_writen,
354};
355
356static enum chipbustype serprog_buses_supported = BUS_NONE;
357
Thomas Heijligencc853d82021-05-04 15:32:17 +0200358static int serprog_init(void)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000359{
360 uint16_t iface;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000361 unsigned char pgmname[17];
362 unsigned char rbuf[3];
363 unsigned char c;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000364 char *device;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000365 int have_device = 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000366
Stefan Tauner72587f82016-01-04 03:05:15 +0000367 /* the parameter is either of format "dev=/dev/device[:baud]" or "ip=ip:port" */
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000368 device = extract_programmer_param("dev");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000369 if (device && strlen(device)) {
Stefan Tauner72587f82016-01-04 03:05:15 +0000370 char *baud_str = strstr(device, ":");
371 if (baud_str != NULL) {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000372 /* Split device from baudrate. */
Stefan Tauner72587f82016-01-04 03:05:15 +0000373 *baud_str = '\0';
374 baud_str++;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000375 }
Stefan Tauner72587f82016-01-04 03:05:15 +0000376 int baud;
377 /* Convert baud string to value.
378 * baud_str is either NULL (if strstr can't find the colon), points to the \0 after the colon
379 * if no characters where given after the colon, or a string to convert... */
380 if (baud_str == NULL || *baud_str == '\0') {
381 baud = -1;
382 msg_pdbg("No baudrate specified, using the hardware's defaults.\n");
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000383 } else {
Stefan Tauner72587f82016-01-04 03:05:15 +0000384 baud = atoi(baud_str); // FIXME: replace atoi with strtoul
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000385 }
Stefan Tauner72587f82016-01-04 03:05:15 +0000386 if (strlen(device) > 0) {
387 sp_fd = sp_openserport(device, baud);
Stefan Tauneracfc4c62012-11-30 16:46:45 +0000388 if (sp_fd == SER_INV_FD) {
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000389 free(device);
390 return 1;
391 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000392 have_device++;
393 }
394 }
Urja Rannikko27b431b2016-01-04 03:05:23 +0000395
396#if !IS_WINDOWS
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000397 if (device && !strlen(device)) {
398 msg_perr("Error: No device specified.\n"
Stefan Tauner72587f82016-01-04 03:05:15 +0000399 "Use flashrom -p serprog:dev=/dev/device[:baud]\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000400 free(device);
401 return 1;
402 }
403 free(device);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000404
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000405 device = extract_programmer_param("ip");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000406 if (have_device && device) {
407 msg_perr("Error: Both host and device specified.\n"
408 "Please use either dev= or ip= but not both.\n");
409 free(device);
410 return 1;
411 }
412 if (device && strlen(device)) {
Stefan Tauner72587f82016-01-04 03:05:15 +0000413 char *port = strstr(device, ":");
414 if (port != NULL) {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000415 /* Split host from port. */
Stefan Tauner72587f82016-01-04 03:05:15 +0000416 *port = '\0';
417 port++;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000418 }
Stefan Tauner72587f82016-01-04 03:05:15 +0000419 if (!port || !strlen(port)) {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000420 msg_perr("Error: No port specified.\n"
421 "Use flashrom -p serprog:ip=ipaddr:port\n");
422 free(device);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000423 return 1;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000424 }
425 if (strlen(device)) {
Stefan Tauner72587f82016-01-04 03:05:15 +0000426 sp_fd = sp_opensocket(device, atoi(port)); // FIXME: replace atoi with strtoul
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000427 if (sp_fd < 0) {
428 free(device);
429 return 1;
430 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000431 have_device++;
432 }
433 }
434 if (device && !strlen(device)) {
435 msg_perr("Error: No host specified.\n"
436 "Use flashrom -p serprog:ip=ipaddr:port\n");
437 free(device);
438 return 1;
439 }
Urja Rannikko27b431b2016-01-04 03:05:23 +0000440#endif
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000441 free(device);
442
443 if (!have_device) {
Urja Rannikko27b431b2016-01-04 03:05:23 +0000444#if IS_WINDOWS
445 msg_perr("Error: No device specified.\n"
446 "Use flashrom -p serprog:dev=comN[:baud]\n");
447#else
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000448 msg_perr("Error: Neither host nor device specified.\n"
449 "Use flashrom -p serprog:dev=/dev/device:baud or "
450 "flashrom -p serprog:ip=ipaddr:port\n");
Urja Rannikko27b431b2016-01-04 03:05:23 +0000451#endif
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000452 return 1;
453 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000454
David Hendricks8bb20212011-06-14 01:35:36 +0000455 if (register_shutdown(serprog_shutdown, NULL))
456 return 1;
457
Sean Nelson74e8af52010-01-10 01:06:23 +0000458 msg_pdbg(MSGHEADER "connected - attempting to synchronize\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000459
460 sp_check_avail_automatic = 0;
461
Niklas Söderlund7145a502012-09-07 07:07:07 +0000462 if (sp_synchronize())
463 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000464
Sean Nelson74e8af52010-01-10 01:06:23 +0000465 msg_pdbg(MSGHEADER "Synchronized\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000466
467 if (sp_docommand(S_CMD_Q_IFACE, 0, NULL, 2, &iface)) {
Stefan Tauner31019d42011-10-22 21:45:27 +0000468 msg_perr("Error: NAK to query interface version\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000469 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000470 }
471
472 if (iface != 1) {
Stefan Tauner31019d42011-10-22 21:45:27 +0000473 msg_perr("Error: Unknown interface version: %d\n", iface);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000474 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000475 }
476
Sean Nelson74e8af52010-01-10 01:06:23 +0000477 msg_pdbg(MSGHEADER "Interface version ok.\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000478
479 if (sp_docommand(S_CMD_Q_CMDMAP, 0, NULL, 32, sp_cmdmap)) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000480 msg_perr("Error: query command map not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000481 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000482 }
483
484 sp_check_avail_automatic = 1;
485
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000486 /* FIXME: This assumes that serprog device bustypes are always
487 * identical with flashrom bustype enums and that they all fit
488 * in a single byte.
489 */
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000490 if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000491 msg_pwarn("Warning: NAK to query supported buses\n");
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000492 c = BUS_NONSPI; /* A reasonable default for now. */
Urja Rannikkof3196df2009-07-21 13:02:59 +0000493 }
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000494 serprog_buses_supported = c;
495
Stefan Tauner31019d42011-10-22 21:45:27 +0000496 msg_pdbg(MSGHEADER "Bus support: parallel=%s, LPC=%s, FWH=%s, SPI=%s\n",
497 (c & BUS_PARALLEL) ? "on" : "off",
498 (c & BUS_LPC) ? "on" : "off",
499 (c & BUS_FWH) ? "on" : "off",
500 (c & BUS_SPI) ? "on" : "off");
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000501 /* Check for the minimum operational set of commands. */
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000502 if (serprog_buses_supported & BUS_SPI) {
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000503 uint8_t bt = BUS_SPI;
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000504 char *spispeed;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000505 if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
506 msg_perr("Error: SPI operation not supported while the "
507 "bustype is SPI\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000508 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000509 }
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000510 if (sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL))
511 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000512 /* Success of any of these commands is optional. We don't need
513 the programmer to tell us its limits, but if it doesn't, we
514 will assume stuff, so it's in the programmers best interest
515 to tell us. */
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000516 if (!sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
517 uint32_t v;
518 v = ((unsigned int)(rbuf[0]) << 0);
519 v |= ((unsigned int)(rbuf[1]) << 8);
520 v |= ((unsigned int)(rbuf[2]) << 16);
521 if (v == 0)
522 v = (1 << 24) - 1; /* SPI-op maximum. */
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000523 spi_master_serprog.max_data_write = v;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000524 msg_pdbg(MSGHEADER "Maximum write-n length is %d\n", v);
525 }
526 if (!sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf)) {
527 uint32_t v;
528 v = ((unsigned int)(rbuf[0]) << 0);
529 v |= ((unsigned int)(rbuf[1]) << 8);
530 v |= ((unsigned int)(rbuf[2]) << 16);
531 if (v == 0)
532 v = (1 << 24) - 1; /* SPI-op maximum. */
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000533 spi_master_serprog.max_data_read = v;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000534 msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
535 }
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000536 spispeed = extract_programmer_param("spispeed");
537 if (spispeed && strlen(spispeed)) {
538 uint32_t f_spi_req, f_spi;
539 uint8_t buf[4];
540 char *f_spi_suffix;
541
542 errno = 0;
543 f_spi_req = strtol(spispeed, &f_spi_suffix, 0);
544 if (errno != 0 || spispeed == f_spi_suffix) {
545 msg_perr("Error: Could not convert 'spispeed'.\n");
Stefan Taunere34e3e82013-01-01 00:06:51 +0000546 free(spispeed);
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000547 return 1;
548 }
549 if (strlen(f_spi_suffix) == 1) {
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000550 if (!strcasecmp(f_spi_suffix, "M")) {
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000551 f_spi_req *= 1000000;
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000552 } else if (!strcasecmp(f_spi_suffix, "k")) {
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000553 f_spi_req *= 1000;
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000554 } else {
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000555 msg_perr("Error: Garbage following 'spispeed' value.\n");
Stefan Taunere34e3e82013-01-01 00:06:51 +0000556 free(spispeed);
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000557 return 1;
558 }
559 } else if (strlen(f_spi_suffix) > 1) {
560 msg_perr("Error: Garbage following 'spispeed' value.\n");
Stefan Taunere34e3e82013-01-01 00:06:51 +0000561 free(spispeed);
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000562 return 1;
563 }
564
565 buf[0] = (f_spi_req >> (0 * 8)) & 0xFF;
566 buf[1] = (f_spi_req >> (1 * 8)) & 0xFF;
567 buf[2] = (f_spi_req >> (2 * 8)) & 0xFF;
568 buf[3] = (f_spi_req >> (3 * 8)) & 0xFF;
569
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000570 if (sp_check_commandavail(S_CMD_S_SPI_FREQ) == 0) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000571 msg_pwarn(MSGHEADER "Warning: Setting the SPI clock rate is not supported!\n");
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000572 } else if (sp_docommand(S_CMD_S_SPI_FREQ, 4, buf, 4, buf) == 0) {
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000573 f_spi = buf[0];
574 f_spi |= buf[1] << (1 * 8);
575 f_spi |= buf[2] << (2 * 8);
576 f_spi |= buf[3] << (3 * 8);
577 msg_pdbg(MSGHEADER "Requested to set SPI clock frequency to %u Hz. "
578 "It was actually set to %u Hz\n", f_spi_req, f_spi);
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000579 } else {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000580 msg_pwarn(MSGHEADER "Setting SPI clock rate to %u Hz failed!\n", f_spi_req);
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000581 }
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000582 }
583 free(spispeed);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000584 bt = serprog_buses_supported;
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000585 if (sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL))
586 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000587 }
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000588
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000589 if (serprog_buses_supported & BUS_NONSPI) {
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000590 if (sp_check_commandavail(S_CMD_O_INIT) == 0) {
591 msg_perr("Error: Initialize operation buffer "
592 "not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000593 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000594 }
595
596 if (sp_check_commandavail(S_CMD_O_DELAY) == 0) {
597 msg_perr("Error: Write to opbuf: "
598 "delay not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000599 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000600 }
601
602 /* S_CMD_O_EXEC availability checked later. */
603
604 if (sp_check_commandavail(S_CMD_R_BYTE) == 0) {
605 msg_perr("Error: Single byte read not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000606 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000607 }
608 /* This could be translated to single byte reads (if missing),
609 * but now we don't support that. */
610 if (sp_check_commandavail(S_CMD_R_NBYTES) == 0) {
611 msg_perr("Error: Read n bytes not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000612 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000613 }
614 if (sp_check_commandavail(S_CMD_O_WRITEB) == 0) {
615 msg_perr("Error: Write to opbuf: "
616 "write byte not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000617 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000618 }
619
620 if (sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
621 msg_pdbg(MSGHEADER "Write-n not supported");
622 sp_max_write_n = 0;
623 } else {
624 sp_max_write_n = ((unsigned int)(rbuf[0]) << 0);
625 sp_max_write_n |= ((unsigned int)(rbuf[1]) << 8);
626 sp_max_write_n |= ((unsigned int)(rbuf[2]) << 16);
627 if (!sp_max_write_n) {
628 sp_max_write_n = (1 << 24);
629 }
630 msg_pdbg(MSGHEADER "Maximum write-n length is %d\n",
631 sp_max_write_n);
632 sp_write_n_buf = malloc(sp_max_write_n);
633 if (!sp_write_n_buf) {
634 msg_perr("Error: cannot allocate memory for "
635 "Write-n buffer\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000636 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000637 }
638 sp_write_n_bytes = 0;
639 }
640
641 if (sp_check_commandavail(S_CMD_Q_RDNMAXLEN) &&
642 (sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf) == 0)) {
643 sp_max_read_n = ((unsigned int)(rbuf[0]) << 0);
644 sp_max_read_n |= ((unsigned int)(rbuf[1]) << 8);
645 sp_max_read_n |= ((unsigned int)(rbuf[2]) << 16);
646 msg_pdbg(MSGHEADER "Maximum read-n length is %d\n",
647 sp_max_read_n ? sp_max_read_n : (1 << 24));
648 } else {
649 msg_pdbg(MSGHEADER "Maximum read-n length "
650 "not reported\n");
651 sp_max_read_n = 0;
652 }
653
Urja Rannikkof3196df2009-07-21 13:02:59 +0000654 }
655
656 if (sp_docommand(S_CMD_Q_PGMNAME, 0, NULL, 16, pgmname)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000657 msg_pwarn("Warning: NAK to query programmer name\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000658 strcpy((char *)pgmname, "(unknown)");
659 }
660 pgmname[16] = 0;
Stefan Tauner31019d42011-10-22 21:45:27 +0000661 msg_pinfo(MSGHEADER "Programmer name is \"%s\"\n", pgmname);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000662
663 if (sp_docommand(S_CMD_Q_SERBUF, 0, NULL, 2, &sp_device_serbuf_size)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000664 msg_pwarn("Warning: NAK to query serial buffer size\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000665 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000666 msg_pdbg(MSGHEADER "Serial buffer size is %d\n",
Urja Rannikkof3196df2009-07-21 13:02:59 +0000667 sp_device_serbuf_size);
668
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000669 if (sp_check_commandavail(S_CMD_O_INIT)) {
670 /* This would be inconsistent. */
671 if (sp_check_commandavail(S_CMD_O_EXEC) == 0) {
672 msg_perr("Error: Execute operation buffer not "
673 "supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000674 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000675 }
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000676
677 if (sp_docommand(S_CMD_O_INIT, 0, NULL, 0, NULL)) {
678 msg_perr("Error: NAK to initialize operation buffer\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000679 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000680 }
681
682 if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2,
683 &sp_device_opbuf_size)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000684 msg_pwarn("Warning: NAK to query operation buffer size\n");
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000685 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000686 msg_pdbg(MSGHEADER "operation buffer size is %d\n",
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000687 sp_device_opbuf_size);
Elyes HAOUAS124ef382018-03-27 12:15:09 +0200688 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000689
Stefan Tauner92fefc92012-10-27 00:34:23 +0000690 if (sp_check_commandavail(S_CMD_S_PIN_STATE)) {
691 uint8_t en = 1;
692 if (sp_docommand(S_CMD_S_PIN_STATE, 1, &en, 0, NULL) != 0) {
693 msg_perr("Error: could not enable output buffers\n");
694 return 1;
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000695 } else {
Stefan Tauner92fefc92012-10-27 00:34:23 +0000696 msg_pdbg(MSGHEADER "Output drivers enabled\n");
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000697 }
698 } else {
Stefan Tauner92fefc92012-10-27 00:34:23 +0000699 msg_pdbg(MSGHEADER "Warning: Programmer does not support toggling its output drivers\n");
Anastasia Klimchukf02db802021-05-24 10:07:56 +1000700 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000701 sp_prev_was_write = 0;
702 sp_streamed_transmit_ops = 0;
703 sp_streamed_transmit_bytes = 0;
704 sp_opbuf_usage = 0;
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000705 if (serprog_buses_supported & BUS_SPI)
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000706 register_spi_master(&spi_master_serprog);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000707 if (serprog_buses_supported & BUS_NONSPI)
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000708 register_par_master(&par_master_serprog, serprog_buses_supported & BUS_NONSPI);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000709 return 0;
710}
711
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000712/* Move an in flashrom buffer existing write-n operation to the on-device operation buffer. */
713static int sp_pass_writen(void)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000714{
715 unsigned char header[7];
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000716 msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n", sp_write_n_bytes, sp_write_n_addr);
717 if (sp_streamed_transmit_bytes >= (7 + sp_write_n_bytes + sp_device_serbuf_size)) {
718 if (sp_flush_stream() != 0) {
719 return 1;
720 }
721 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000722 /* In case it's just a single byte send it as a single write. */
723 if (sp_write_n_bytes == 1) {
724 sp_write_n_bytes = 0;
725 header[0] = (sp_write_n_addr >> 0) & 0xFF;
726 header[1] = (sp_write_n_addr >> 8) & 0xFF;
727 header[2] = (sp_write_n_addr >> 16) & 0xFF;
728 header[3] = sp_write_n_buf[0];
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000729 if (sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header) != 0)
730 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000731 sp_opbuf_usage += 5;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000732 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000733 }
734 header[0] = S_CMD_O_WRITEN;
735 header[1] = (sp_write_n_bytes >> 0) & 0xFF;
736 header[2] = (sp_write_n_bytes >> 8) & 0xFF;
737 header[3] = (sp_write_n_bytes >> 16) & 0xFF;
738 header[4] = (sp_write_n_addr >> 0) & 0xFF;
739 header[5] = (sp_write_n_addr >> 8) & 0xFF;
740 header[6] = (sp_write_n_addr >> 16) & 0xFF;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000741 if (serialport_write(header, 7) != 0) {
742 msg_perr(MSGHEADER "Error: cannot write write-n command\n");
743 return 1;
744 }
745 if (serialport_write(sp_write_n_buf, sp_write_n_bytes) != 0) {
746 msg_perr(MSGHEADER "Error: cannot write write-n data");
747 return 1;
748 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000749 sp_streamed_transmit_bytes += 7 + sp_write_n_bytes;
750 sp_streamed_transmit_ops += 1;
751 sp_opbuf_usage += 7 + sp_write_n_bytes;
752 sp_write_n_bytes = 0;
753 sp_prev_was_write = 0;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000754 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000755}
756
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000757static int sp_execute_opbuf_noflush(void)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000758{
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000759 if ((sp_max_write_n) && (sp_write_n_bytes)) {
760 if (sp_pass_writen() != 0) {
761 msg_perr("Error: could not transfer write buffer\n");
762 return 1;
763 }
764 }
765 if (sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL) != 0) {
766 msg_perr("Error: could not execute command buffer\n");
767 return 1;
768 }
769 msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n", sp_opbuf_usage);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000770 sp_opbuf_usage = 0;
771 sp_prev_was_write = 0;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000772 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000773}
774
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000775static int sp_execute_opbuf(void)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000776{
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000777 if (sp_execute_opbuf_noflush() != 0)
778 return 1;
779 if (sp_flush_stream() != 0)
780 return 1;
781
782 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000783}
784
David Hendricks8bb20212011-06-14 01:35:36 +0000785static int serprog_shutdown(void *data)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000786{
Urja Rannikkof3196df2009-07-21 13:02:59 +0000787 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000788 if (sp_execute_opbuf() != 0)
789 msg_pwarn("Could not flush command buffer.\n");
Stefan Tauner92fefc92012-10-27 00:34:23 +0000790 if (sp_check_commandavail(S_CMD_S_PIN_STATE)) {
791 uint8_t dis = 0;
792 if (sp_docommand(S_CMD_S_PIN_STATE, 1, &dis, 0, NULL) == 0)
793 msg_pdbg(MSGHEADER "Output drivers disabled\n");
794 else
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000795 msg_pwarn(MSGHEADER "%s: Warning: could not disable output buffers\n", __func__);
Stefan Tauner92fefc92012-10-27 00:34:23 +0000796 }
Niklas Söderlund7145a502012-09-07 07:07:07 +0000797 /* FIXME: fix sockets on windows(?), especially closing */
798 serialport_shutdown(&sp_fd);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000799 if (sp_max_write_n)
800 free(sp_write_n_buf);
801 return 0;
802}
803
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000804static int sp_check_opbuf_usage(int bytes_to_be_added)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000805{
806 if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) {
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000807 /* If this happens in the middle of a page load the page load will probably fail. */
808 msg_pwarn(MSGHEADER "Warning: executed operation buffer due to size reasons\n");
809 if (sp_execute_opbuf() != 0)
810 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000811 }
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000812 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000813}
814
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000815static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
816 chipaddr addr)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000817{
Sean Nelson74e8af52010-01-10 01:06:23 +0000818 msg_pspew("%s\n", __func__);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000819 if (sp_max_write_n) {
820 if ((sp_prev_was_write)
821 && (addr == (sp_write_n_addr + sp_write_n_bytes))) {
822 sp_write_n_buf[sp_write_n_bytes++] = val;
823 } else {
824 if ((sp_prev_was_write) && (sp_write_n_bytes))
825 sp_pass_writen();
826 sp_prev_was_write = 1;
827 sp_write_n_addr = addr;
828 sp_write_n_bytes = 1;
829 sp_write_n_buf[0] = val;
830 }
831 sp_check_opbuf_usage(7 + sp_write_n_bytes);
832 if (sp_write_n_bytes >= sp_max_write_n)
833 sp_pass_writen();
834 } else {
835 /* We will have to do single writeb ops. */
836 unsigned char writeb_parm[4];
837 sp_check_opbuf_usage(6);
838 writeb_parm[0] = (addr >> 0) & 0xFF;
839 writeb_parm[1] = (addr >> 8) & 0xFF;
840 writeb_parm[2] = (addr >> 16) & 0xFF;
841 writeb_parm[3] = val;
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000842 sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm); // FIXME: return error
Urja Rannikkof3196df2009-07-21 13:02:59 +0000843 sp_opbuf_usage += 5;
844 }
845}
846
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000847static uint8_t serprog_chip_readb(const struct flashctx *flash,
848 const chipaddr addr)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000849{
850 unsigned char c;
851 unsigned char buf[3];
852 /* Will stream the read operation - eg. add it to the stream buffer, *
853 * then flush the buffer, then read the read answer. */
854 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
855 sp_execute_opbuf_noflush();
856 buf[0] = ((addr >> 0) & 0xFF);
857 buf[1] = ((addr >> 8) & 0xFF);
858 buf[2] = ((addr >> 16) & 0xFF);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000859 sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf); // FIXME: return error
860 sp_flush_stream(); // FIXME: return error
Stefan Tauner79587f52013-04-01 00:45:51 +0000861 if (serialport_read(&c, 1) != 0)
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000862 msg_perr(MSGHEADER "readb byteread"); // FIXME: return error
Stefan Taunerc2333752013-07-13 23:31:37 +0000863 msg_pspew("%s addr=0x%" PRIxPTR " returning 0x%02X\n", __func__, addr, c);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000864 return c;
865}
866
Uwe Hermann4e3d0b32010-03-25 23:18:41 +0000867/* Local version that really does the job, doesn't care of max_read_n. */
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000868static int sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000869{
Urja Rannikkof3196df2009-07-21 13:02:59 +0000870 unsigned char sbuf[6];
Stefan Tauner0554ca52013-07-25 22:54:25 +0000871 msg_pspew("%s: addr=0x%" PRIxPTR " len=%zu\n", __func__, addr, len);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000872 /* Stream the read-n -- as above. */
873 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
874 sp_execute_opbuf_noflush();
875 sbuf[0] = ((addr >> 0) & 0xFF);
876 sbuf[1] = ((addr >> 8) & 0xFF);
877 sbuf[2] = ((addr >> 16) & 0xFF);
878 sbuf[3] = ((len >> 0) & 0xFF);
879 sbuf[4] = ((len >> 8) & 0xFF);
880 sbuf[5] = ((len >> 16) & 0xFF);
881 sp_stream_buffer_op(S_CMD_R_NBYTES, 6, sbuf);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000882 if (sp_flush_stream() != 0)
883 return 1;
884 if (serialport_read(buf, len) != 0) {
885 msg_perr(MSGHEADER "Error: cannot read read-n data");
886 return 1;
887 }
888 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000889}
890
891/* The externally called version that makes sure that max_read_n is obeyed. */
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000892static void serprog_chip_readn(const struct flashctx *flash, uint8_t * buf,
893 const chipaddr addr, size_t len)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000894{
895 size_t lenm = len;
896 chipaddr addrm = addr;
Stefan Tauner31019d42011-10-22 21:45:27 +0000897 while ((sp_max_read_n != 0) && (lenm > sp_max_read_n)) {
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000898 sp_do_read_n(&(buf[addrm-addr]), addrm, sp_max_read_n); // FIXME: return error
Urja Rannikkof3196df2009-07-21 13:02:59 +0000899 addrm += sp_max_read_n;
900 lenm -= sp_max_read_n;
901 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000902 if (lenm)
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000903 sp_do_read_n(&(buf[addrm-addr]), addrm, lenm); // FIXME: return error
Urja Rannikkof3196df2009-07-21 13:02:59 +0000904}
905
Thomas Heijligencc853d82021-05-04 15:32:17 +0200906static void serprog_delay(unsigned int usecs)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000907{
908 unsigned char buf[4];
Stefan Tauner31019d42011-10-22 21:45:27 +0000909 msg_pspew("%s usecs=%d\n", __func__, usecs);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000910 if (!sp_check_commandavail(S_CMD_O_DELAY)) {
Stefan Taunerd7d423b2012-10-20 09:13:16 +0000911 msg_pdbg2("serprog_delay used, but programmer doesn't support delays natively - emulating\n");
Stefan Tauner31019d42011-10-22 21:45:27 +0000912 internal_delay(usecs);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000913 return;
914 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000915 if ((sp_max_write_n) && (sp_write_n_bytes))
916 sp_pass_writen();
917 sp_check_opbuf_usage(5);
Stefan Tauner31019d42011-10-22 21:45:27 +0000918 buf[0] = ((usecs >> 0) & 0xFF);
919 buf[1] = ((usecs >> 8) & 0xFF);
920 buf[2] = ((usecs >> 16) & 0xFF);
921 buf[3] = ((usecs >> 24) & 0xFF);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000922 sp_stream_buffer_op(S_CMD_O_DELAY, 4, buf);
923 sp_opbuf_usage += 5;
924 sp_prev_was_write = 0;
925}
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000926
Edward O'Callaghan5eca4272020-04-12 17:27:53 +1000927static int serprog_spi_send_command(const struct flashctx *flash,
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000928 unsigned int writecnt, unsigned int readcnt,
929 const unsigned char *writearr,
930 unsigned char *readarr)
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000931{
932 unsigned char *parmbuf;
933 int ret;
934 msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000935 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes)) {
936 if (sp_execute_opbuf() != 0) {
937 msg_perr("Error: could not execute command buffer before sending SPI commands.\n");
938 return 1;
939 }
940 }
941
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000942 parmbuf = malloc(writecnt + 6);
Stefan Taunerbdead0d2013-08-24 02:10:18 +0000943 if (!parmbuf) {
944 msg_perr("Error: could not allocate SPI send param buffer.\n");
945 return 1;
946 }
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000947 parmbuf[0] = (writecnt >> 0) & 0xFF;
948 parmbuf[1] = (writecnt >> 8) & 0xFF;
949 parmbuf[2] = (writecnt >> 16) & 0xFF;
950 parmbuf[3] = (readcnt >> 0) & 0xFF;
951 parmbuf[4] = (readcnt >> 8) & 0xFF;
952 parmbuf[5] = (readcnt >> 16) & 0xFF;
953 memcpy(parmbuf + 6, writearr, writecnt);
954 ret = sp_docommand(S_CMD_O_SPIOP, writecnt + 6, parmbuf, readcnt,
955 readarr);
956 free(parmbuf);
957 return ret;
958}
959
Thomas Heijligencc853d82021-05-04 15:32:17 +0200960static void *serprog_map(const char *descr, uintptr_t phys_addr, size_t len)
Urja Rannikko0b4ffd52015-06-29 23:24:23 +0000961{
962 /* Serprog transmits 24 bits only and assumes the underlying implementation handles any remaining bits
963 * correctly (usually setting them to one either in software (for FWH/LPC) or relying on the fact that
964 * the hardware observes a subset of the address bits only). Combined with the standard mapping of
965 * flashrom this creates a 16 MB-wide window just below the 4 GB boundary where serprog can operate (as
966 * needed for non-SPI chips). Below we make sure that the requested range is within this window. */
967 if ((phys_addr & 0xFF000000) == 0xFF000000) {
968 return (void*)phys_addr;
Urja Rannikko0b4ffd52015-06-29 23:24:23 +0000969 }
Elyes HAOUASec819d62019-06-09 17:50:51 +0200970 msg_pwarn(MSGHEADER "requested mapping %s is incompatible: 0x%zx bytes at 0x%0*" PRIxPTR ".\n",
971 descr, len, PRIxPTR_WIDTH, phys_addr);
972 return NULL;
Urja Rannikko0b4ffd52015-06-29 23:24:23 +0000973}
Thomas Heijligencc853d82021-05-04 15:32:17 +0200974
975const struct programmer_entry programmer_serprog = {
976 .name = "serprog",
977 .type = OTHER,
978 /* FIXME */
979 .devs.note = "All programmer devices speaking the serprog protocol\n",
980 .init = serprog_init,
981 .map_flash_region = serprog_map,
982 .unmap_flash_region = fallback_unmap,
983 .delay = serprog_delay,
984};