blob: d03a75da3976092c61eacb8f1eacccdc52e24197 [file] [log] [blame]
hailfinger37b4fbf2009-06-23 11:33:43 +00001/*
2 * This file is part of the flashrom project.
3 *
stefanct69965b62011-09-15 23:38:14 +00004 * Copyright (C) 2009, 2011 Urja Rannikko <urjaman@gmail.com>
hailfinger37b4fbf2009-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.
16 *
hailfinger37b4fbf2009-06-23 11:33:43 +000017 */
18
hailfinger4f45a4f2009-08-12 13:32:56 +000019#include <stdio.h>
hailfinger37b4fbf2009-06-23 11:33:43 +000020#include <stdlib.h>
hailfinger4f45a4f2009-08-12 13:32:56 +000021#include <unistd.h>
hailfinger4f45a4f2009-08-12 13:32:56 +000022#include <string.h>
hailfinger37b4fbf2009-06-23 11:33:43 +000023#include <ctype.h>
24#include <fcntl.h>
hailfinger37b4fbf2009-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>
30#include <sys/stat.h>
31#include <errno.h>
hailfinger37b4fbf2009-06-23 11:33:43 +000032#include <inttypes.h>
33#include <termios.h>
hailfinger428f6852010-07-27 22:41:39 +000034#include "flash.h"
35#include "programmer.h"
stefanct69965b62011-09-15 23:38:14 +000036#include "chipdrivers.h"
Patrick Georgib9fe7f12017-04-11 20:35:19 +020037#include "serprog.h"
hailfingerbacbc8b2009-07-21 13:02:59 +000038
stefanctd9ac2212011-10-22 21:45:27 +000039#define MSGHEADER "serprog: "
hailfingerbacbc8b2009-07-21 13:02:59 +000040
dhendrix0ffc2eb2011-06-14 01:35:36 +000041/*
42 * FIXME: This prototype was added to help reduce diffs for the shutdown
43 * registration patch, which shifted many lines of code to place
44 * serprog_shutdown() before serprog_init(). It should be removed soon.
45 */
David Hendricks93784b42016-08-09 17:00:38 -070046static int serprog_shutdown(void *data);
dhendrix0ffc2eb2011-06-14 01:35:36 +000047
hailfingerbacbc8b2009-07-21 13:02:59 +000048static uint16_t sp_device_serbuf_size = 16;
49static uint16_t sp_device_opbuf_size = 300;
50/* Bitmap of supported commands */
51static uint8_t sp_cmdmap[32];
52
uwe3a3ab2f2010-03-25 23:18:41 +000053/* sp_prev_was_write used to detect writes with contiguous addresses
hailfingerbacbc8b2009-07-21 13:02:59 +000054 and combine them to write-n's */
55static int sp_prev_was_write = 0;
56/* sp_write_n_addr used as the starting addr of the currently
57 combined write-n operation */
58static uint32_t sp_write_n_addr;
59/* The maximum length of an write_n operation; 0 = write-n not supported */
60static uint32_t sp_max_write_n = 0;
61/* The maximum length of a read_n operation; 0 = 2^24 */
62static uint32_t sp_max_read_n = 0;
63
64/* A malloc'd buffer for combining the operation's data
65 and a counter that tells how much data is there. */
66static uint8_t *sp_write_n_buf;
67static uint32_t sp_write_n_bytes = 0;
68
69/* sp_streamed_* used for flow control checking */
70static int sp_streamed_transmit_ops = 0;
71static int sp_streamed_transmit_bytes = 0;
72
73/* sp_opbuf_usage used for counting the amount of
74 on-device operation buffer used */
75static int sp_opbuf_usage = 0;
76/* if true causes sp_docommand to automatically check
77 whether the command is supported before doing it */
78static int sp_check_avail_automatic = 0;
79
hailfingerbacbc8b2009-07-21 13:02:59 +000080static int sp_opensocket(char *ip, unsigned int port)
81{
82 int flag = 1;
83 struct hostent *hostPtr = NULL;
hailfinger3e454f32009-09-05 01:10:23 +000084 union { struct sockaddr_in si; struct sockaddr s; } sp = {};
hailfingerbacbc8b2009-07-21 13:02:59 +000085 int sock;
snelson0afd28b2010-01-10 01:06:23 +000086 msg_pdbg(MSGHEADER "IP %s port %d\n", ip, port);
hailfingerbacbc8b2009-07-21 13:02:59 +000087 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
88 if (sock < 0)
89 sp_die("Error: serprog cannot open socket");
90 hostPtr = gethostbyname(ip);
91 if (NULL == hostPtr) {
92 hostPtr = gethostbyaddr(ip, strlen(ip), AF_INET);
93 if (NULL == hostPtr)
94 sp_die("Error: cannot resolve");
95 }
hailfinger3e454f32009-09-05 01:10:23 +000096 sp.si.sin_family = AF_INET;
97 sp.si.sin_port = htons(port);
98 (void)memcpy(&sp.si.sin_addr, hostPtr->h_addr, hostPtr->h_length);
99 if (connect(sock, &sp.s, sizeof(sp.si)) < 0) {
hailfingerbacbc8b2009-07-21 13:02:59 +0000100 close(sock);
101 sp_die("Error: serprog cannot connect");
102 }
103 /* We are latency limited, and sometimes do write-write-read *
104 * (write-n) - so enable TCP_NODELAY. */
105 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
106 return sock;
107}
108
hailfingerbacbc8b2009-07-21 13:02:59 +0000109static int sp_sync_read_timeout(int loops)
110{
111 int i;
112 unsigned char c;
113 for (i = 0; i < loops; i++) {
114 ssize_t rv;
115 rv = read(sp_fd, &c, 1);
116 if (rv == 1)
117 return c;
118 if ((rv == -1) && (errno != EAGAIN))
119 sp_die("read");
120 usleep(10 * 1000); /* 10ms units */
121 }
122 return -1;
123}
124
uwe3a3ab2f2010-03-25 23:18:41 +0000125/* Synchronize: a bit tricky algorithm that tries to (and in my tests has *
hailfingerbacbc8b2009-07-21 13:02:59 +0000126 * always succeeded in) bring the serial protocol to known waiting-for- *
127 * command state - uses nonblocking read - rest of the driver uses *
128 * blocking read - TODO: add an alarm() timer for the rest of the app on *
129 * serial operations, though not such a big issue as the first thing to *
130 * do is synchronize (eg. check that device is alive). */
131static void sp_synchronize(void)
132{
133 int i;
134 int flags = fcntl(sp_fd, F_GETFL);
135 unsigned char buf[8];
136 flags |= O_NONBLOCK;
137 fcntl(sp_fd, F_SETFL, flags);
138 /* First sends 8 NOPs, then flushes the return data - should cause *
139 * the device serial parser to get to a sane state, unless if it *
140 * is waiting for a real long write-n. */
141 memset(buf, S_CMD_NOP, 8);
142 if (write(sp_fd, buf, 8) != 8)
143 sp_die("flush write");
144 /* A second should be enough to get all the answers to the buffer */
145 usleep(1000 * 1000);
146 sp_flush_incoming();
147
stefanct371e7e82011-07-07 19:56:58 +0000148 /* Then try up to 8 times to send syncnop and get the correct special *
149 * return of NAK+ACK. Timing note: up to 10 characters, 10*50ms = *
150 * up to 500ms per try, 8*0.5s = 4s; +1s (above) = up to 5s sync *
151 * attempt, ~1s if immediate success. */
hailfingerbacbc8b2009-07-21 13:02:59 +0000152 for (i = 0; i < 8; i++) {
153 int n;
154 unsigned char c = S_CMD_SYNCNOP;
155 if (write(sp_fd, &c, 1) != 1)
156 sp_die("sync write");
snelson0afd28b2010-01-10 01:06:23 +0000157 msg_pdbg(".");
hailfingerbacbc8b2009-07-21 13:02:59 +0000158 fflush(stdout);
159 for (n = 0; n < 10; n++) {
stefanct371e7e82011-07-07 19:56:58 +0000160 c = sp_sync_read_timeout(5); /* wait up to 50ms */
hailfingerbacbc8b2009-07-21 13:02:59 +0000161 if (c != S_NAK)
162 continue;
163 c = sp_sync_read_timeout(2);
164 if (c != S_ACK)
165 continue;
166 c = S_CMD_SYNCNOP;
167 if (write(sp_fd, &c, 1) != 1)
168 sp_die("sync write");
169 c = sp_sync_read_timeout(50);
170 if (c != S_NAK)
171 break; /* fail */
172 c = sp_sync_read_timeout(10);
173 if (c != S_ACK)
174 break; /* fail */
175 /* Ok, synchronized; back to blocking reads and return. */
176 flags &= ~O_NONBLOCK;
177 fcntl(sp_fd, F_SETFL, flags);
snelson0afd28b2010-01-10 01:06:23 +0000178 msg_pdbg("\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000179 return;
180 }
181 }
stefanctd9ac2212011-10-22 21:45:27 +0000182 msg_perr("Error: cannot synchronize protocol "
hailfingerbacbc8b2009-07-21 13:02:59 +0000183 "- check communications and reset device?\n");
184 exit(1);
185}
186
187static int sp_check_commandavail(uint8_t command)
188{
189 int byteoffs, bitoffs;
190 byteoffs = command / 8;
191 bitoffs = command % 8;
192 return (sp_cmdmap[byteoffs] & (1 << bitoffs)) ? 1 : 0;
193}
194
195static int sp_automatic_cmdcheck(uint8_t cmd)
196{
197 if ((sp_check_avail_automatic) && (sp_check_commandavail(cmd) == 0)) {
stefanctd9ac2212011-10-22 21:45:27 +0000198 msg_pdbg("Warning: Automatic command availability check failed "
199 "for cmd 0x%x - won't execute cmd\n", cmd);
hailfingerbacbc8b2009-07-21 13:02:59 +0000200 return 1;
201 }
202 return 0;
203}
204
205static int sp_docommand(uint8_t command, uint32_t parmlen,
stefanctd9ac2212011-10-22 21:45:27 +0000206 uint8_t *params, uint32_t retlen, void *retparms)
hailfingerbacbc8b2009-07-21 13:02:59 +0000207{
hailfingerbacbc8b2009-07-21 13:02:59 +0000208 unsigned char c;
209 if (sp_automatic_cmdcheck(command))
210 return 1;
stefanctd9ac2212011-10-22 21:45:27 +0000211 if (write(sp_fd, &command, 1) != 1)
212 sp_die("Error: cannot write op code");
213 if (write(sp_fd, params, parmlen) != (parmlen))
214 sp_die("Error: cannot write parameters");
hailfingerbacbc8b2009-07-21 13:02:59 +0000215 if (read(sp_fd, &c, 1) != 1)
216 sp_die("Error: cannot read from device");
stefanctd9ac2212011-10-22 21:45:27 +0000217 if (c == S_NAK)
218 return 1;
hailfingerbacbc8b2009-07-21 13:02:59 +0000219 if (c != S_ACK) {
snelson0afd28b2010-01-10 01:06:23 +0000220 msg_perr("Error: invalid response 0x%02X from device\n",c);
hailfingerbacbc8b2009-07-21 13:02:59 +0000221 exit(1);
222 }
223 if (retlen) {
224 int rd_bytes = 0;
225 do {
226 int r;
227 r = read(sp_fd, retparms + rd_bytes,
228 retlen - rd_bytes);
stefanctd9ac2212011-10-22 21:45:27 +0000229 if (r <= 0)
230 sp_die("Error: cannot read return parameters");
hailfingerbacbc8b2009-07-21 13:02:59 +0000231 rd_bytes += r;
232 } while (rd_bytes != retlen);
233 }
234 return 0;
235}
236
237static void sp_flush_stream(void)
238{
239 if (sp_streamed_transmit_ops)
240 do {
241 unsigned char c;
242 if (read(sp_fd, &c, 1) != 1) {
snelson0afd28b2010-01-10 01:06:23 +0000243 sp_die("Error: cannot read from device (flushing stream)");
hailfingerbacbc8b2009-07-21 13:02:59 +0000244 }
245 if (c == S_NAK) {
snelson0afd28b2010-01-10 01:06:23 +0000246 msg_perr("Error: NAK to a stream buffer operation\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000247 exit(1);
248 }
249 if (c != S_ACK) {
snelson0afd28b2010-01-10 01:06:23 +0000250 msg_perr("Error: Invalid reply 0x%02X from device\n", c);
hailfingerbacbc8b2009-07-21 13:02:59 +0000251 exit(1);
252 }
253 } while (--sp_streamed_transmit_ops);
254 sp_streamed_transmit_ops = 0;
255 sp_streamed_transmit_bytes = 0;
256}
257
258static int sp_stream_buffer_op(uint8_t cmd, uint32_t parmlen, uint8_t * parms)
259{
260 uint8_t *sp;
261 if (sp_automatic_cmdcheck(cmd))
262 return 1;
263 sp = malloc(1 + parmlen);
264 if (!sp) sp_die("Error: cannot malloc command buffer");
265 sp[0] = cmd;
266 memcpy(&(sp[1]), parms, parmlen);
267 if (sp_streamed_transmit_bytes >= (1 + parmlen + sp_device_serbuf_size))
268 sp_flush_stream();
269 if (write(sp_fd, sp, 1 + parmlen) != (1 + parmlen))
270 sp_die("Error: cannot write command");
271 free(sp);
272 sp_streamed_transmit_ops += 1;
273 sp_streamed_transmit_bytes += 1 + parmlen;
274 return 0;
275}
276
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700277static int serprog_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
hailfinger76bb7e92011-11-09 23:40:00 +0000278 const unsigned char *writearr,
279 unsigned char *readarr);
Patrick Georgif4f1e2f2017-03-10 17:38:40 +0100280static struct spi_master spi_master_serprog = {
stefanct69965b62011-09-15 23:38:14 +0000281 .type = SPI_CONTROLLER_SERPROG,
Edward O'Callaghana6673bd2019-06-24 15:22:28 +1000282 .features = SPI_MASTER_4BA,
stefanct69965b62011-09-15 23:38:14 +0000283 .max_data_read = MAX_DATA_READ_UNLIMITED,
284 .max_data_write = MAX_DATA_WRITE_UNLIMITED,
285 .command = serprog_spi_send_command,
286 .multicommand = default_spi_send_multicommand,
Edward O'Callaghand825ac02019-07-26 21:36:16 +1000287 .read = default_spi_read,
stefanct69965b62011-09-15 23:38:14 +0000288 .write_256 = default_spi_write_256,
289};
290
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700291static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
292 chipaddr addr);
293static uint8_t serprog_chip_readb(const struct flashctx *flash,
294 const chipaddr addr);
295static void serprog_chip_readn(const struct flashctx *flash, uint8_t *buf,
296 const chipaddr addr, size_t len);
297
Patrick Georgi0a9533a2017-02-03 19:28:38 +0100298static const struct par_master par_master_serprog = {
hailfinger76bb7e92011-11-09 23:40:00 +0000299 .chip_readb = serprog_chip_readb,
300 .chip_readw = fallback_chip_readw,
301 .chip_readl = fallback_chip_readl,
302 .chip_readn = serprog_chip_readn,
303 .chip_writeb = serprog_chip_writeb,
304 .chip_writew = fallback_chip_writew,
305 .chip_writel = fallback_chip_writel,
306 .chip_writen = fallback_chip_writen,
307};
308
309static enum chipbustype serprog_buses_supported = BUS_NONE;
310
David Hendricksac1d25c2016-08-09 17:00:58 -0700311int serprog_init(void)
hailfingerbacbc8b2009-07-21 13:02:59 +0000312{
313 uint16_t iface;
hailfingerbacbc8b2009-07-21 13:02:59 +0000314 unsigned char pgmname[17];
315 unsigned char rbuf[3];
316 unsigned char c;
hailfinger1ef766d2010-07-06 09:55:48 +0000317 char *device;
318 char *baudport;
319 int have_device = 0;
hailfingerbacbc8b2009-07-21 13:02:59 +0000320
hailfinger1ef766d2010-07-06 09:55:48 +0000321 /* the parameter is either of format "dev=/dev/device:baud" or "ip=ip:port" */
hailfingerddeb4ac2010-07-08 10:13:37 +0000322 device = extract_programmer_param("dev");
hailfinger1ef766d2010-07-06 09:55:48 +0000323 if (device && strlen(device)) {
324 baudport = strstr(device, ":");
325 if (baudport) {
326 /* Split device from baudrate. */
327 *baudport = '\0';
328 baudport++;
329 }
330 if (!baudport || !strlen(baudport)) {
331 msg_perr("Error: No baudrate specified.\n"
332 "Use flashrom -p serprog:dev=/dev/device:baud\n");
333 free(device);
stefanct69965b62011-09-15 23:38:14 +0000334 return 1;
hailfinger1ef766d2010-07-06 09:55:48 +0000335 }
336 if (strlen(device)) {
337 sp_fd = sp_openserport(device, atoi(baudport));
338 have_device++;
339 }
340 }
341 if (device && !strlen(device)) {
342 msg_perr("Error: No device specified.\n"
343 "Use flashrom -p serprog:dev=/dev/device:baud\n");
344 free(device);
345 return 1;
346 }
347 free(device);
hailfingerbacbc8b2009-07-21 13:02:59 +0000348
hailfingerddeb4ac2010-07-08 10:13:37 +0000349 device = extract_programmer_param("ip");
hailfinger1ef766d2010-07-06 09:55:48 +0000350 if (have_device && device) {
351 msg_perr("Error: Both host and device specified.\n"
352 "Please use either dev= or ip= but not both.\n");
353 free(device);
354 return 1;
355 }
356 if (device && strlen(device)) {
357 baudport = strstr(device, ":");
358 if (baudport) {
359 /* Split host from port. */
360 *baudport = '\0';
361 baudport++;
362 }
363 if (!baudport || !strlen(baudport)) {
364 msg_perr("Error: No port specified.\n"
365 "Use flashrom -p serprog:ip=ipaddr:port\n");
366 free(device);
stefanct69965b62011-09-15 23:38:14 +0000367 return 1;
hailfinger1ef766d2010-07-06 09:55:48 +0000368 }
369 if (strlen(device)) {
370 sp_fd = sp_opensocket(device, atoi(baudport));
371 have_device++;
372 }
373 }
374 if (device && !strlen(device)) {
375 msg_perr("Error: No host specified.\n"
376 "Use flashrom -p serprog:ip=ipaddr:port\n");
377 free(device);
378 return 1;
379 }
380 free(device);
381
382 if (!have_device) {
383 msg_perr("Error: Neither host nor device specified.\n"
384 "Use flashrom -p serprog:dev=/dev/device:baud or "
385 "flashrom -p serprog:ip=ipaddr:port\n");
386 return 1;
387 }
hailfingerbacbc8b2009-07-21 13:02:59 +0000388
dhendrix0ffc2eb2011-06-14 01:35:36 +0000389 if (register_shutdown(serprog_shutdown, NULL))
390 return 1;
391
snelson0afd28b2010-01-10 01:06:23 +0000392 msg_pdbg(MSGHEADER "connected - attempting to synchronize\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000393
394 sp_check_avail_automatic = 0;
395
396 sp_synchronize();
397
snelson0afd28b2010-01-10 01:06:23 +0000398 msg_pdbg(MSGHEADER "Synchronized\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000399
400 if (sp_docommand(S_CMD_Q_IFACE, 0, NULL, 2, &iface)) {
stefanctd9ac2212011-10-22 21:45:27 +0000401 msg_perr("Error: NAK to query interface version\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000402 return 1;
hailfingerbacbc8b2009-07-21 13:02:59 +0000403 }
404
405 if (iface != 1) {
stefanctd9ac2212011-10-22 21:45:27 +0000406 msg_perr("Error: Unknown interface version: %d\n", iface);
hailfinger76bb7e92011-11-09 23:40:00 +0000407 return 1;
hailfingerbacbc8b2009-07-21 13:02:59 +0000408 }
409
snelson0afd28b2010-01-10 01:06:23 +0000410 msg_pdbg(MSGHEADER "Interface version ok.\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000411
412 if (sp_docommand(S_CMD_Q_CMDMAP, 0, NULL, 32, sp_cmdmap)) {
snelson0afd28b2010-01-10 01:06:23 +0000413 msg_perr("Error: query command map not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000414 return 1;
hailfingerbacbc8b2009-07-21 13:02:59 +0000415 }
416
417 sp_check_avail_automatic = 1;
418
hailfinger76bb7e92011-11-09 23:40:00 +0000419 /* FIXME: This assumes that serprog device bustypes are always
420 * identical with flashrom bustype enums and that they all fit
421 * in a single byte.
422 */
stefanct69965b62011-09-15 23:38:14 +0000423 if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) {
424 msg_perr("Warning: NAK to query supported buses\n");
425 c = BUS_NONSPI; /* A reasonable default for now. */
hailfingerbacbc8b2009-07-21 13:02:59 +0000426 }
hailfinger76bb7e92011-11-09 23:40:00 +0000427 serprog_buses_supported = c;
428
stefanctd9ac2212011-10-22 21:45:27 +0000429 msg_pdbg(MSGHEADER "Bus support: parallel=%s, LPC=%s, FWH=%s, SPI=%s\n",
430 (c & BUS_PARALLEL) ? "on" : "off",
431 (c & BUS_LPC) ? "on" : "off",
432 (c & BUS_FWH) ? "on" : "off",
433 (c & BUS_SPI) ? "on" : "off");
stefanct69965b62011-09-15 23:38:14 +0000434 /* Check for the minimum operational set of commands. */
hailfinger76bb7e92011-11-09 23:40:00 +0000435 if (serprog_buses_supported & BUS_SPI) {
stefanct69965b62011-09-15 23:38:14 +0000436 uint8_t bt = BUS_SPI;
437 if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
438 msg_perr("Error: SPI operation not supported while the "
439 "bustype is SPI\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000440 return 1;
stefanct69965b62011-09-15 23:38:14 +0000441 }
442 /* Success of any of these commands is optional. We don't need
443 the programmer to tell us its limits, but if it doesn't, we
444 will assume stuff, so it's in the programmers best interest
445 to tell us. */
446 sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL);
447 if (!sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
448 uint32_t v;
449 v = ((unsigned int)(rbuf[0]) << 0);
450 v |= ((unsigned int)(rbuf[1]) << 8);
451 v |= ((unsigned int)(rbuf[2]) << 16);
452 if (v == 0)
453 v = (1 << 24) - 1; /* SPI-op maximum. */
Patrick Georgif4f1e2f2017-03-10 17:38:40 +0100454 spi_master_serprog.max_data_write = v;
stefanct69965b62011-09-15 23:38:14 +0000455 msg_pdbg(MSGHEADER "Maximum write-n length is %d\n", v);
456 }
457 if (!sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf)) {
458 uint32_t v;
459 v = ((unsigned int)(rbuf[0]) << 0);
460 v |= ((unsigned int)(rbuf[1]) << 8);
461 v |= ((unsigned int)(rbuf[2]) << 16);
462 if (v == 0)
463 v = (1 << 24) - 1; /* SPI-op maximum. */
Patrick Georgif4f1e2f2017-03-10 17:38:40 +0100464 spi_master_serprog.max_data_read = v;
stefanct69965b62011-09-15 23:38:14 +0000465 msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
466 }
hailfinger76bb7e92011-11-09 23:40:00 +0000467 bt = serprog_buses_supported;
stefanct69965b62011-09-15 23:38:14 +0000468 sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL);
hailfingerbacbc8b2009-07-21 13:02:59 +0000469 }
stefanct69965b62011-09-15 23:38:14 +0000470
hailfinger76bb7e92011-11-09 23:40:00 +0000471 if (serprog_buses_supported & BUS_NONSPI) {
stefanct69965b62011-09-15 23:38:14 +0000472 if (sp_check_commandavail(S_CMD_O_INIT) == 0) {
473 msg_perr("Error: Initialize operation buffer "
474 "not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000475 return 1;
stefanct69965b62011-09-15 23:38:14 +0000476 }
477
478 if (sp_check_commandavail(S_CMD_O_DELAY) == 0) {
479 msg_perr("Error: Write to opbuf: "
480 "delay not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000481 return 1;
stefanct69965b62011-09-15 23:38:14 +0000482 }
483
484 /* S_CMD_O_EXEC availability checked later. */
485
486 if (sp_check_commandavail(S_CMD_R_BYTE) == 0) {
487 msg_perr("Error: Single byte read not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000488 return 1;
stefanct69965b62011-09-15 23:38:14 +0000489 }
490 /* This could be translated to single byte reads (if missing),
491 * but now we don't support that. */
492 if (sp_check_commandavail(S_CMD_R_NBYTES) == 0) {
493 msg_perr("Error: Read n bytes not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000494 return 1;
stefanct69965b62011-09-15 23:38:14 +0000495 }
496 if (sp_check_commandavail(S_CMD_O_WRITEB) == 0) {
497 msg_perr("Error: Write to opbuf: "
498 "write byte not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000499 return 1;
stefanct69965b62011-09-15 23:38:14 +0000500 }
501
502 if (sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
503 msg_pdbg(MSGHEADER "Write-n not supported");
504 sp_max_write_n = 0;
505 } else {
506 sp_max_write_n = ((unsigned int)(rbuf[0]) << 0);
507 sp_max_write_n |= ((unsigned int)(rbuf[1]) << 8);
508 sp_max_write_n |= ((unsigned int)(rbuf[2]) << 16);
509 if (!sp_max_write_n) {
510 sp_max_write_n = (1 << 24);
511 }
512 msg_pdbg(MSGHEADER "Maximum write-n length is %d\n",
513 sp_max_write_n);
514 sp_write_n_buf = malloc(sp_max_write_n);
515 if (!sp_write_n_buf) {
516 msg_perr("Error: cannot allocate memory for "
517 "Write-n buffer\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000518 return 1;
stefanct69965b62011-09-15 23:38:14 +0000519 }
520 sp_write_n_bytes = 0;
521 }
522
523 if (sp_check_commandavail(S_CMD_Q_RDNMAXLEN) &&
524 (sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf) == 0)) {
525 sp_max_read_n = ((unsigned int)(rbuf[0]) << 0);
526 sp_max_read_n |= ((unsigned int)(rbuf[1]) << 8);
527 sp_max_read_n |= ((unsigned int)(rbuf[2]) << 16);
528 msg_pdbg(MSGHEADER "Maximum read-n length is %d\n",
529 sp_max_read_n ? sp_max_read_n : (1 << 24));
530 } else {
531 msg_pdbg(MSGHEADER "Maximum read-n length "
532 "not reported\n");
533 sp_max_read_n = 0;
534 }
535
hailfingerbacbc8b2009-07-21 13:02:59 +0000536 }
537
538 if (sp_docommand(S_CMD_Q_PGMNAME, 0, NULL, 16, pgmname)) {
snelson0afd28b2010-01-10 01:06:23 +0000539 msg_perr("Warning: NAK to query programmer name\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000540 strcpy((char *)pgmname, "(unknown)");
541 }
542 pgmname[16] = 0;
stefanctd9ac2212011-10-22 21:45:27 +0000543 msg_pinfo(MSGHEADER "Programmer name is \"%s\"\n", pgmname);
hailfingerbacbc8b2009-07-21 13:02:59 +0000544
545 if (sp_docommand(S_CMD_Q_SERBUF, 0, NULL, 2, &sp_device_serbuf_size)) {
snelson0afd28b2010-01-10 01:06:23 +0000546 msg_perr("Warning: NAK to query serial buffer size\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000547 }
stefanctd9ac2212011-10-22 21:45:27 +0000548 msg_pdbg(MSGHEADER "Serial buffer size is %d\n",
hailfingerbacbc8b2009-07-21 13:02:59 +0000549 sp_device_serbuf_size);
550
stefanct69965b62011-09-15 23:38:14 +0000551 if (sp_check_commandavail(S_CMD_O_INIT)) {
552 /* This would be inconsistent. */
553 if (sp_check_commandavail(S_CMD_O_EXEC) == 0) {
554 msg_perr("Error: Execute operation buffer not "
555 "supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000556 return 1;
hailfingerbacbc8b2009-07-21 13:02:59 +0000557 }
stefanct69965b62011-09-15 23:38:14 +0000558
559 if (sp_docommand(S_CMD_O_INIT, 0, NULL, 0, NULL)) {
560 msg_perr("Error: NAK to initialize operation buffer\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000561 return 1;
stefanct69965b62011-09-15 23:38:14 +0000562 }
563
564 if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2,
565 &sp_device_opbuf_size)) {
566 msg_perr("Warning: NAK to query operation buffer "
567 "size\n");
568 }
stefanctd9ac2212011-10-22 21:45:27 +0000569 msg_pdbg(MSGHEADER "operation buffer size is %d\n",
stefanct69965b62011-09-15 23:38:14 +0000570 sp_device_opbuf_size);
571 }
hailfingerbacbc8b2009-07-21 13:02:59 +0000572
573 sp_prev_was_write = 0;
574 sp_streamed_transmit_ops = 0;
575 sp_streamed_transmit_bytes = 0;
576 sp_opbuf_usage = 0;
hailfinger76bb7e92011-11-09 23:40:00 +0000577 if (serprog_buses_supported & BUS_SPI)
Patrick Georgif4f1e2f2017-03-10 17:38:40 +0100578 register_spi_master(&spi_master_serprog);
hailfinger76bb7e92011-11-09 23:40:00 +0000579 if (serprog_buses_supported & BUS_NONSPI)
Patrick Georgi0a9533a2017-02-03 19:28:38 +0100580 register_par_master(&par_master_serprog,
hailfinger76bb7e92011-11-09 23:40:00 +0000581 serprog_buses_supported & BUS_NONSPI);
hailfingerbacbc8b2009-07-21 13:02:59 +0000582 return 0;
583}
584
585/* Move an in flashrom buffer existing write-n operation to *
586 * the on-device operation buffer. */
587static void sp_pass_writen(void)
588{
589 unsigned char header[7];
snelson0afd28b2010-01-10 01:06:23 +0000590 msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n",
stefanctd9ac2212011-10-22 21:45:27 +0000591 sp_write_n_bytes, sp_write_n_addr);
hailfingerbacbc8b2009-07-21 13:02:59 +0000592 if (sp_streamed_transmit_bytes >=
593 (7 + sp_write_n_bytes + sp_device_serbuf_size))
594 sp_flush_stream();
595 /* In case it's just a single byte send it as a single write. */
596 if (sp_write_n_bytes == 1) {
597 sp_write_n_bytes = 0;
598 header[0] = (sp_write_n_addr >> 0) & 0xFF;
599 header[1] = (sp_write_n_addr >> 8) & 0xFF;
600 header[2] = (sp_write_n_addr >> 16) & 0xFF;
601 header[3] = sp_write_n_buf[0];
602 sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header);
603 sp_opbuf_usage += 5;
604 return;
605 }
606 header[0] = S_CMD_O_WRITEN;
607 header[1] = (sp_write_n_bytes >> 0) & 0xFF;
608 header[2] = (sp_write_n_bytes >> 8) & 0xFF;
609 header[3] = (sp_write_n_bytes >> 16) & 0xFF;
610 header[4] = (sp_write_n_addr >> 0) & 0xFF;
611 header[5] = (sp_write_n_addr >> 8) & 0xFF;
612 header[6] = (sp_write_n_addr >> 16) & 0xFF;
613 if (write(sp_fd, header, 7) != 7)
614 sp_die("Error: cannot write write-n command\n");
615 if (write(sp_fd, sp_write_n_buf, sp_write_n_bytes) !=
616 sp_write_n_bytes)
617 sp_die("Error: cannot write write-n data");
618 sp_streamed_transmit_bytes += 7 + sp_write_n_bytes;
619 sp_streamed_transmit_ops += 1;
620 sp_opbuf_usage += 7 + sp_write_n_bytes;
621 sp_write_n_bytes = 0;
622 sp_prev_was_write = 0;
623}
624
625static void sp_execute_opbuf_noflush(void)
626{
627 if ((sp_max_write_n) && (sp_write_n_bytes))
628 sp_pass_writen();
stepand0d220f2011-01-24 19:15:51 +0000629 sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL);
snelson0afd28b2010-01-10 01:06:23 +0000630 msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n",
hailfingerbacbc8b2009-07-21 13:02:59 +0000631 sp_opbuf_usage);
632 sp_opbuf_usage = 0;
633 sp_prev_was_write = 0;
634 return;
635}
636
637static void sp_execute_opbuf(void)
638{
639 sp_execute_opbuf_noflush();
640 sp_flush_stream();
641}
642
David Hendricks93784b42016-08-09 17:00:38 -0700643static int serprog_shutdown(void *data)
hailfingerbacbc8b2009-07-21 13:02:59 +0000644{
snelson0afd28b2010-01-10 01:06:23 +0000645 msg_pspew("%s\n", __func__);
hailfingerbacbc8b2009-07-21 13:02:59 +0000646 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
647 sp_execute_opbuf();
648 close(sp_fd);
649 if (sp_max_write_n)
650 free(sp_write_n_buf);
651 return 0;
652}
653
654static void sp_check_opbuf_usage(int bytes_to_be_added)
655{
656 if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) {
657 sp_execute_opbuf();
658 /* If this happens in the mid of an page load the page load *
uwe3a3ab2f2010-03-25 23:18:41 +0000659 * will probably fail. */
snelson0afd28b2010-01-10 01:06:23 +0000660 msg_pdbg(MSGHEADER "Warning: executed operation buffer due to size reasons\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000661 }
662}
663
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700664void serprog_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
hailfingerbacbc8b2009-07-21 13:02:59 +0000665{
snelson0afd28b2010-01-10 01:06:23 +0000666 msg_pspew("%s\n", __func__);
hailfingerbacbc8b2009-07-21 13:02:59 +0000667 if (sp_max_write_n) {
668 if ((sp_prev_was_write)
669 && (addr == (sp_write_n_addr + sp_write_n_bytes))) {
670 sp_write_n_buf[sp_write_n_bytes++] = val;
671 } else {
672 if ((sp_prev_was_write) && (sp_write_n_bytes))
673 sp_pass_writen();
674 sp_prev_was_write = 1;
675 sp_write_n_addr = addr;
676 sp_write_n_bytes = 1;
677 sp_write_n_buf[0] = val;
678 }
679 sp_check_opbuf_usage(7 + sp_write_n_bytes);
680 if (sp_write_n_bytes >= sp_max_write_n)
681 sp_pass_writen();
682 } else {
683 /* We will have to do single writeb ops. */
684 unsigned char writeb_parm[4];
685 sp_check_opbuf_usage(6);
686 writeb_parm[0] = (addr >> 0) & 0xFF;
687 writeb_parm[1] = (addr >> 8) & 0xFF;
688 writeb_parm[2] = (addr >> 16) & 0xFF;
689 writeb_parm[3] = val;
690 sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm);
691 sp_opbuf_usage += 5;
692 }
693}
694
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700695uint8_t serprog_chip_readb(const struct flashctx *flash, const chipaddr addr)
hailfingerbacbc8b2009-07-21 13:02:59 +0000696{
697 unsigned char c;
698 unsigned char buf[3];
699 /* Will stream the read operation - eg. add it to the stream buffer, *
700 * then flush the buffer, then read the read answer. */
701 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
702 sp_execute_opbuf_noflush();
703 buf[0] = ((addr >> 0) & 0xFF);
704 buf[1] = ((addr >> 8) & 0xFF);
705 buf[2] = ((addr >> 16) & 0xFF);
706 sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf);
707 sp_flush_stream();
708 if (read(sp_fd, &c, 1) != 1)
709 sp_die("readb byteread");
snelson0afd28b2010-01-10 01:06:23 +0000710 msg_pspew("%s addr=0x%lx returning 0x%02X\n", __func__, addr, c);
hailfingerbacbc8b2009-07-21 13:02:59 +0000711 return c;
712}
713
uwe3a3ab2f2010-03-25 23:18:41 +0000714/* Local version that really does the job, doesn't care of max_read_n. */
hailfingerbacbc8b2009-07-21 13:02:59 +0000715static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
716{
717 int rd_bytes = 0;
718 unsigned char sbuf[6];
snelson0afd28b2010-01-10 01:06:23 +0000719 msg_pspew("%s: addr=0x%lx len=%lu\n", __func__, addr, (unsigned long)len);
hailfingerbacbc8b2009-07-21 13:02:59 +0000720 /* Stream the read-n -- as above. */
721 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
722 sp_execute_opbuf_noflush();
723 sbuf[0] = ((addr >> 0) & 0xFF);
724 sbuf[1] = ((addr >> 8) & 0xFF);
725 sbuf[2] = ((addr >> 16) & 0xFF);
726 sbuf[3] = ((len >> 0) & 0xFF);
727 sbuf[4] = ((len >> 8) & 0xFF);
728 sbuf[5] = ((len >> 16) & 0xFF);
729 sp_stream_buffer_op(S_CMD_R_NBYTES, 6, sbuf);
730 sp_flush_stream();
731 do {
732 int r = read(sp_fd, buf + rd_bytes, len - rd_bytes);
733 if (r <= 0)
734 sp_die("Error: cannot read read-n data");
735 rd_bytes += r;
736 } while (rd_bytes != len);
737 return;
738}
739
740/* The externally called version that makes sure that max_read_n is obeyed. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700741void serprog_chip_readn(const struct flashctx *flash, uint8_t * buf, const chipaddr addr, size_t len)
hailfingerbacbc8b2009-07-21 13:02:59 +0000742{
743 size_t lenm = len;
744 chipaddr addrm = addr;
stefanctd9ac2212011-10-22 21:45:27 +0000745 while ((sp_max_read_n != 0) && (lenm > sp_max_read_n)) {
746 sp_do_read_n(&(buf[addrm-addr]), addrm, sp_max_read_n);
hailfingerbacbc8b2009-07-21 13:02:59 +0000747 addrm += sp_max_read_n;
748 lenm -= sp_max_read_n;
749 }
stefanctd9ac2212011-10-22 21:45:27 +0000750 if (lenm)
751 sp_do_read_n(&(buf[addrm-addr]), addrm, lenm);
hailfingerbacbc8b2009-07-21 13:02:59 +0000752}
753
stefanctd9ac2212011-10-22 21:45:27 +0000754void serprog_delay(int usecs)
hailfingerbacbc8b2009-07-21 13:02:59 +0000755{
756 unsigned char buf[4];
stefanctd9ac2212011-10-22 21:45:27 +0000757 msg_pspew("%s usecs=%d\n", __func__, usecs);
stefanct69965b62011-09-15 23:38:14 +0000758 if (!sp_check_commandavail(S_CMD_O_DELAY)) {
stefanct69965b62011-09-15 23:38:14 +0000759 msg_pdbg("Note: serprog_delay used, but the programmer doesn't "
760 "support delay\n");
stefanctd9ac2212011-10-22 21:45:27 +0000761 internal_delay(usecs);
stefanct69965b62011-09-15 23:38:14 +0000762 return;
763 }
hailfingerbacbc8b2009-07-21 13:02:59 +0000764 if ((sp_max_write_n) && (sp_write_n_bytes))
765 sp_pass_writen();
766 sp_check_opbuf_usage(5);
stefanctd9ac2212011-10-22 21:45:27 +0000767 buf[0] = ((usecs >> 0) & 0xFF);
768 buf[1] = ((usecs >> 8) & 0xFF);
769 buf[2] = ((usecs >> 16) & 0xFF);
770 buf[3] = ((usecs >> 24) & 0xFF);
hailfingerbacbc8b2009-07-21 13:02:59 +0000771 sp_stream_buffer_op(S_CMD_O_DELAY, 4, buf);
772 sp_opbuf_usage += 5;
773 sp_prev_was_write = 0;
774}
stefanct69965b62011-09-15 23:38:14 +0000775
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700776static int serprog_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
stefanct69965b62011-09-15 23:38:14 +0000777 const unsigned char *writearr,
778 unsigned char *readarr)
779{
780 unsigned char *parmbuf;
781 int ret;
782 msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
783 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
784 sp_execute_opbuf();
785 parmbuf = malloc(writecnt + 6);
786 if (!parmbuf)
787 sp_die("Error: cannot malloc SPI send param buffer");
788 parmbuf[0] = (writecnt >> 0) & 0xFF;
789 parmbuf[1] = (writecnt >> 8) & 0xFF;
790 parmbuf[2] = (writecnt >> 16) & 0xFF;
791 parmbuf[3] = (readcnt >> 0) & 0xFF;
792 parmbuf[4] = (readcnt >> 8) & 0xFF;
793 parmbuf[5] = (readcnt >> 16) & 0xFF;
794 memcpy(parmbuf + 6, writearr, writecnt);
795 ret = sp_docommand(S_CMD_O_SPIOP, writecnt + 6, parmbuf, readcnt,
796 readarr);
797 free(parmbuf);
798 return ret;
799}