blob: b179ea4cfceadcaa1c5d8d3499b27d71194b2b90 [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.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
Carl-Daniel Hailfingeref58a9c2009-08-12 13:32:56 +000022#include <stdio.h>
Urja Rannikko22915352009-06-23 11:33:43 +000023#include <stdlib.h>
Carl-Daniel Hailfingeref58a9c2009-08-12 13:32:56 +000024#include <unistd.h>
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +000025#include <strings.h>
Carl-Daniel Hailfingeref58a9c2009-08-12 13:32:56 +000026#include <string.h>
Urja Rannikko22915352009-06-23 11:33:43 +000027#include <ctype.h>
28#include <fcntl.h>
Urja Rannikko22915352009-06-23 11:33:43 +000029#include <sys/socket.h>
30#include <arpa/inet.h>
31#include <netinet/in.h>
32#include <netinet/tcp.h>
33#include <netdb.h>
34#include <sys/stat.h>
35#include <errno.h>
Urja Rannikko22915352009-06-23 11:33:43 +000036#include <inttypes.h>
37#include <termios.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"
Urja Rannikkof3196df2009-07-21 13:02:59 +000041
Stefan Tauner31019d42011-10-22 21:45:27 +000042#define MSGHEADER "serprog: "
Urja Rannikkof3196df2009-07-21 13:02:59 +000043
David Hendricks8bb20212011-06-14 01:35:36 +000044/*
45 * FIXME: This prototype was added to help reduce diffs for the shutdown
46 * registration patch, which shifted many lines of code to place
47 * serprog_shutdown() before serprog_init(). It should be removed soon.
48 */
49static int serprog_shutdown(void *data);
50
Urja Rannikkof3196df2009-07-21 13:02:59 +000051#define S_ACK 0x06
52#define S_NAK 0x15
53#define S_CMD_NOP 0x00 /* No operation */
54#define S_CMD_Q_IFACE 0x01 /* Query interface version */
55#define S_CMD_Q_CMDMAP 0x02 /* Query supported commands bitmap */
56#define S_CMD_Q_PGMNAME 0x03 /* Query programmer name */
57#define S_CMD_Q_SERBUF 0x04 /* Query Serial Buffer Size */
58#define S_CMD_Q_BUSTYPE 0x05 /* Query supported bustypes */
59#define S_CMD_Q_CHIPSIZE 0x06 /* Query supported chipsize (2^n format) */
60#define S_CMD_Q_OPBUF 0x07 /* Query operation buffer size */
Cristian Măgherușan-Stanciu9932c7b2011-07-07 19:56:58 +000061#define S_CMD_Q_WRNMAXLEN 0x08 /* Query opbuf-write-N maximum length */
Urja Rannikkof3196df2009-07-21 13:02:59 +000062#define S_CMD_R_BYTE 0x09 /* Read a single byte */
63#define S_CMD_R_NBYTES 0x0A /* Read n bytes */
64#define S_CMD_O_INIT 0x0B /* Initialize operation buffer */
65#define S_CMD_O_WRITEB 0x0C /* Write opbuf: Write byte with address */
66#define S_CMD_O_WRITEN 0x0D /* Write to opbuf: Write-N */
67#define S_CMD_O_DELAY 0x0E /* Write opbuf: udelay */
68#define S_CMD_O_EXEC 0x0F /* Execute operation buffer */
69#define S_CMD_SYNCNOP 0x10 /* Special no-operation that returns NAK+ACK */
70#define S_CMD_Q_RDNMAXLEN 0x11 /* Query read-n maximum length */
71#define S_CMD_S_BUSTYPE 0x12 /* Set used bustype(s). */
Urja Rannikkoc93f5f12011-09-15 23:38:14 +000072#define S_CMD_O_SPIOP 0x13 /* Perform SPI operation. */
Stefan Taunerb98f6eb2012-08-13 16:33:04 +000073#define S_CMD_S_SPI_FREQ 0x14 /* Set SPI clock frequency */
Urja Rannikkof3196df2009-07-21 13:02:59 +000074
Urja Rannikkof3196df2009-07-21 13:02:59 +000075static uint16_t sp_device_serbuf_size = 16;
76static uint16_t sp_device_opbuf_size = 300;
77/* Bitmap of supported commands */
78static uint8_t sp_cmdmap[32];
79
Uwe Hermann4e3d0b32010-03-25 23:18:41 +000080/* sp_prev_was_write used to detect writes with contiguous addresses
Urja Rannikkof3196df2009-07-21 13:02:59 +000081 and combine them to write-n's */
82static int sp_prev_was_write = 0;
83/* sp_write_n_addr used as the starting addr of the currently
84 combined write-n operation */
85static uint32_t sp_write_n_addr;
86/* The maximum length of an write_n operation; 0 = write-n not supported */
87static uint32_t sp_max_write_n = 0;
88/* The maximum length of a read_n operation; 0 = 2^24 */
89static uint32_t sp_max_read_n = 0;
90
91/* A malloc'd buffer for combining the operation's data
92 and a counter that tells how much data is there. */
93static uint8_t *sp_write_n_buf;
94static uint32_t sp_write_n_bytes = 0;
95
96/* sp_streamed_* used for flow control checking */
97static int sp_streamed_transmit_ops = 0;
98static int sp_streamed_transmit_bytes = 0;
99
100/* sp_opbuf_usage used for counting the amount of
101 on-device operation buffer used */
102static int sp_opbuf_usage = 0;
103/* if true causes sp_docommand to automatically check
104 whether the command is supported before doing it */
105static int sp_check_avail_automatic = 0;
106
Urja Rannikkof3196df2009-07-21 13:02:59 +0000107static int sp_opensocket(char *ip, unsigned int port)
108{
109 int flag = 1;
110 struct hostent *hostPtr = NULL;
Carl-Daniel Hailfinger6d125602009-09-05 01:10:23 +0000111 union { struct sockaddr_in si; struct sockaddr s; } sp = {};
Urja Rannikkof3196df2009-07-21 13:02:59 +0000112 int sock;
Sean Nelson74e8af52010-01-10 01:06:23 +0000113 msg_pdbg(MSGHEADER "IP %s port %d\n", ip, port);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000114 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000115 if (sock < 0) {
116 msg_perr("Error: serprog cannot open socket: %s\n", strerror(errno));
117 return -1;
118 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000119 hostPtr = gethostbyname(ip);
120 if (NULL == hostPtr) {
121 hostPtr = gethostbyaddr(ip, strlen(ip), AF_INET);
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000122 if (NULL == hostPtr) {
123 msg_perr("Error: cannot resolve %s\n", ip);
124 return -1;
125 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000126 }
Carl-Daniel Hailfinger6d125602009-09-05 01:10:23 +0000127 sp.si.sin_family = AF_INET;
128 sp.si.sin_port = htons(port);
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +0000129 (void)memcpy(&sp.si.sin_addr, hostPtr->h_addr_list[0], hostPtr->h_length);
Carl-Daniel Hailfinger6d125602009-09-05 01:10:23 +0000130 if (connect(sock, &sp.s, sizeof(sp.si)) < 0) {
Urja Rannikkof3196df2009-07-21 13:02:59 +0000131 close(sock);
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000132 msg_perr("Error: serprog cannot connect: %s\n", strerror(errno));
133 return -1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000134 }
135 /* We are latency limited, and sometimes do write-write-read *
136 * (write-n) - so enable TCP_NODELAY. */
137 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
138 return sock;
139}
140
Niklas Söderlund7145a502012-09-07 07:07:07 +0000141/* Returns 0 on success and places the character read into the location pointed to by c.
142 * Returns positive values on temporary errors and negative ones on permanent errors.
143 * An iteration of one loop takes up to 1ms. */
144static int sp_sync_read_timeout(unsigned int loops, unsigned char *c)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000145{
146 int i;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000147 for (i = 0; i < loops; i++) {
148 ssize_t rv;
Niklas Söderlund7145a502012-09-07 07:07:07 +0000149 rv = read(sp_fd, c, 1);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000150 if (rv == 1)
Niklas Söderlund7145a502012-09-07 07:07:07 +0000151 return 0;
152 if ((rv == -1) && (errno != EAGAIN)) {
153 msg_perr("read: %s\n", strerror(errno));
154 return -1;
155 }
156 usleep(1000); /* 1ms units */
Urja Rannikkof3196df2009-07-21 13:02:59 +0000157 }
Niklas Söderlund7145a502012-09-07 07:07:07 +0000158 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000159}
160
Uwe Hermann4e3d0b32010-03-25 23:18:41 +0000161/* Synchronize: a bit tricky algorithm that tries to (and in my tests has *
Urja Rannikkof3196df2009-07-21 13:02:59 +0000162 * always succeeded in) bring the serial protocol to known waiting-for- *
163 * command state - uses nonblocking read - rest of the driver uses *
164 * blocking read - TODO: add an alarm() timer for the rest of the app on *
165 * serial operations, though not such a big issue as the first thing to *
166 * do is synchronize (eg. check that device is alive). */
Niklas Söderlund7145a502012-09-07 07:07:07 +0000167static int sp_synchronize(void)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000168{
169 int i;
170 int flags = fcntl(sp_fd, F_GETFL);
171 unsigned char buf[8];
172 flags |= O_NONBLOCK;
173 fcntl(sp_fd, F_SETFL, flags);
174 /* First sends 8 NOPs, then flushes the return data - should cause *
175 * the device serial parser to get to a sane state, unless if it *
176 * is waiting for a real long write-n. */
177 memset(buf, S_CMD_NOP, 8);
Niklas Söderlund7145a502012-09-07 07:07:07 +0000178 if (write(sp_fd, buf, 8) != 8) {
179 msg_perr("flush write: %s\n", strerror(errno));
180 goto err_out;
181 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000182 /* A second should be enough to get all the answers to the buffer */
183 usleep(1000 * 1000);
184 sp_flush_incoming();
185
Cristian Măgherușan-Stanciu9932c7b2011-07-07 19:56:58 +0000186 /* Then try up to 8 times to send syncnop and get the correct special *
187 * return of NAK+ACK. Timing note: up to 10 characters, 10*50ms = *
188 * up to 500ms per try, 8*0.5s = 4s; +1s (above) = up to 5s sync *
189 * attempt, ~1s if immediate success. */
Urja Rannikkof3196df2009-07-21 13:02:59 +0000190 for (i = 0; i < 8; i++) {
191 int n;
192 unsigned char c = S_CMD_SYNCNOP;
Niklas Söderlund7145a502012-09-07 07:07:07 +0000193 if (write(sp_fd, &c, 1) != 1) {
194 msg_perr("sync write: %s\n", strerror(errno));
195 goto err_out;
196 }
Sean Nelson74e8af52010-01-10 01:06:23 +0000197 msg_pdbg(".");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000198 fflush(stdout);
199 for (n = 0; n < 10; n++) {
Niklas Söderlund7145a502012-09-07 07:07:07 +0000200 int ret = sp_sync_read_timeout(50, &c);
201 if (ret < 0)
202 goto err_out;
203 if (ret > 0 || c != S_NAK)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000204 continue;
Niklas Söderlund7145a502012-09-07 07:07:07 +0000205 ret = sp_sync_read_timeout(20, &c);
206 if (ret < 0)
207 goto err_out;
208 if (ret > 0 || c != S_ACK)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000209 continue;
210 c = S_CMD_SYNCNOP;
Niklas Söderlund7145a502012-09-07 07:07:07 +0000211 if (write(sp_fd, &c, 1) != 1) {
212 msg_perr("sync write: %s\n", strerror(errno));
213 return 1;
214 }
215 ret = sp_sync_read_timeout(500, &c);
216 if (ret < 0)
217 goto err_out;
218 if (ret > 0 || c != S_NAK)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000219 break; /* fail */
Niklas Söderlund7145a502012-09-07 07:07:07 +0000220 ret = sp_sync_read_timeout(100, &c);
221 if (ret > 0 || ret < 0)
222 goto err_out;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000223 if (c != S_ACK)
224 break; /* fail */
225 /* Ok, synchronized; back to blocking reads and return. */
226 flags &= ~O_NONBLOCK;
227 fcntl(sp_fd, F_SETFL, flags);
Sean Nelson74e8af52010-01-10 01:06:23 +0000228 msg_pdbg("\n");
Niklas Söderlund7145a502012-09-07 07:07:07 +0000229 return 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000230 }
231 }
Niklas Söderlund7145a502012-09-07 07:07:07 +0000232err_out:
233 msg_perr("Error: cannot synchronize protocol - check communications and reset device?\n");
234 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000235}
236
237static int sp_check_commandavail(uint8_t command)
238{
239 int byteoffs, bitoffs;
240 byteoffs = command / 8;
241 bitoffs = command % 8;
242 return (sp_cmdmap[byteoffs] & (1 << bitoffs)) ? 1 : 0;
243}
244
245static int sp_automatic_cmdcheck(uint8_t cmd)
246{
247 if ((sp_check_avail_automatic) && (sp_check_commandavail(cmd) == 0)) {
Stefan Tauner31019d42011-10-22 21:45:27 +0000248 msg_pdbg("Warning: Automatic command availability check failed "
249 "for cmd 0x%x - won't execute cmd\n", cmd);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000250 return 1;
251 }
252 return 0;
253}
254
255static int sp_docommand(uint8_t command, uint32_t parmlen,
Stefan Tauner31019d42011-10-22 21:45:27 +0000256 uint8_t *params, uint32_t retlen, void *retparms)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000257{
Urja Rannikkof3196df2009-07-21 13:02:59 +0000258 unsigned char c;
259 if (sp_automatic_cmdcheck(command))
260 return 1;
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000261 if (write(sp_fd, &command, 1) != 1) {
262 msg_perr("Error: cannot write op code: %s\n", strerror(errno));
263 return 1;
264 }
265 if (write(sp_fd, params, parmlen) != (parmlen)) {
266 msg_perr("Error: cannot write parameters: %s\n", strerror(errno));
267 return 1;
268 }
269 if (read(sp_fd, &c, 1) != 1) {
270 msg_perr("Error: cannot read from device: %s\n", strerror(errno));
271 return 1;
272 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000273 if (c == S_NAK)
274 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000275 if (c != S_ACK) {
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000276 msg_perr("Error: invalid response 0x%02X from device\n", c);
277 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000278 }
279 if (retlen) {
280 int rd_bytes = 0;
281 do {
282 int r;
283 r = read(sp_fd, retparms + rd_bytes,
284 retlen - rd_bytes);
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000285 if (r <= 0) {
286 msg_perr("Error: cannot read return parameters: %s\n", strerror(errno));
287 return 1;
288 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000289 rd_bytes += r;
290 } while (rd_bytes != retlen);
291 }
292 return 0;
293}
294
295static void sp_flush_stream(void)
296{
297 if (sp_streamed_transmit_ops)
298 do {
299 unsigned char c;
300 if (read(sp_fd, &c, 1) != 1) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000301 sp_die("Error: cannot read from device (flushing stream)");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000302 }
303 if (c == S_NAK) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000304 msg_perr("Error: NAK to a stream buffer operation\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000305 exit(1);
306 }
307 if (c != S_ACK) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000308 msg_perr("Error: Invalid reply 0x%02X from device\n", c);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000309 exit(1);
310 }
311 } while (--sp_streamed_transmit_ops);
312 sp_streamed_transmit_ops = 0;
313 sp_streamed_transmit_bytes = 0;
314}
315
316static int sp_stream_buffer_op(uint8_t cmd, uint32_t parmlen, uint8_t * parms)
317{
318 uint8_t *sp;
319 if (sp_automatic_cmdcheck(cmd))
320 return 1;
321 sp = malloc(1 + parmlen);
322 if (!sp) sp_die("Error: cannot malloc command buffer");
323 sp[0] = cmd;
324 memcpy(&(sp[1]), parms, parmlen);
325 if (sp_streamed_transmit_bytes >= (1 + parmlen + sp_device_serbuf_size))
326 sp_flush_stream();
327 if (write(sp_fd, sp, 1 + parmlen) != (1 + parmlen))
328 sp_die("Error: cannot write command");
329 free(sp);
330 sp_streamed_transmit_ops += 1;
331 sp_streamed_transmit_bytes += 1 + parmlen;
332 return 0;
333}
334
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000335static int serprog_spi_send_command(struct flashctx *flash,
336 unsigned int writecnt, unsigned int readcnt,
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000337 const unsigned char *writearr,
338 unsigned char *readarr);
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000339static int serprog_spi_read(struct flashctx *flash, uint8_t *buf,
Stefan Taunerc69c9c82011-11-23 09:13:48 +0000340 unsigned int start, unsigned int len);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000341static struct spi_programmer spi_programmer_serprog = {
342 .type = SPI_CONTROLLER_SERPROG,
343 .max_data_read = MAX_DATA_READ_UNLIMITED,
344 .max_data_write = MAX_DATA_WRITE_UNLIMITED,
345 .command = serprog_spi_send_command,
346 .multicommand = default_spi_send_multicommand,
347 .read = serprog_spi_read,
348 .write_256 = default_spi_write_256,
Nico Huber7bca1262012-06-15 22:28:12 +0000349 .write_aai = default_spi_write_aai,
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000350};
351
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000352static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
353 chipaddr addr);
354static uint8_t serprog_chip_readb(const struct flashctx *flash,
355 const chipaddr addr);
356static void serprog_chip_readn(const struct flashctx *flash, uint8_t *buf,
357 const chipaddr addr, size_t len);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000358static const struct par_programmer par_programmer_serprog = {
359 .chip_readb = serprog_chip_readb,
360 .chip_readw = fallback_chip_readw,
361 .chip_readl = fallback_chip_readl,
362 .chip_readn = serprog_chip_readn,
363 .chip_writeb = serprog_chip_writeb,
364 .chip_writew = fallback_chip_writew,
365 .chip_writel = fallback_chip_writel,
366 .chip_writen = fallback_chip_writen,
367};
368
369static enum chipbustype serprog_buses_supported = BUS_NONE;
370
Urja Rannikkof3196df2009-07-21 13:02:59 +0000371int serprog_init(void)
372{
373 uint16_t iface;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000374 unsigned char pgmname[17];
375 unsigned char rbuf[3];
376 unsigned char c;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000377 char *device;
378 char *baudport;
379 int have_device = 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000380
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000381 /* the parameter is either of format "dev=/dev/device:baud" or "ip=ip:port" */
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000382 device = extract_programmer_param("dev");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000383 if (device && strlen(device)) {
384 baudport = strstr(device, ":");
385 if (baudport) {
386 /* Split device from baudrate. */
387 *baudport = '\0';
388 baudport++;
389 }
390 if (!baudport || !strlen(baudport)) {
391 msg_perr("Error: No baudrate specified.\n"
392 "Use flashrom -p serprog:dev=/dev/device:baud\n");
393 free(device);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000394 return 1;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000395 }
396 if (strlen(device)) {
397 sp_fd = sp_openserport(device, atoi(baudport));
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000398 if (sp_fd < 0) {
399 free(device);
400 return 1;
401 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000402 have_device++;
403 }
404 }
405 if (device && !strlen(device)) {
406 msg_perr("Error: No device specified.\n"
407 "Use flashrom -p serprog:dev=/dev/device:baud\n");
408 free(device);
409 return 1;
410 }
411 free(device);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000412
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000413 device = extract_programmer_param("ip");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000414 if (have_device && device) {
415 msg_perr("Error: Both host and device specified.\n"
416 "Please use either dev= or ip= but not both.\n");
417 free(device);
418 return 1;
419 }
420 if (device && strlen(device)) {
421 baudport = strstr(device, ":");
422 if (baudport) {
423 /* Split host from port. */
424 *baudport = '\0';
425 baudport++;
426 }
427 if (!baudport || !strlen(baudport)) {
428 msg_perr("Error: No port specified.\n"
429 "Use flashrom -p serprog:ip=ipaddr:port\n");
430 free(device);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000431 return 1;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000432 }
433 if (strlen(device)) {
434 sp_fd = sp_opensocket(device, atoi(baudport));
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000435 if (sp_fd < 0) {
436 free(device);
437 return 1;
438 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000439 have_device++;
440 }
441 }
442 if (device && !strlen(device)) {
443 msg_perr("Error: No host specified.\n"
444 "Use flashrom -p serprog:ip=ipaddr:port\n");
445 free(device);
446 return 1;
447 }
448 free(device);
449
450 if (!have_device) {
451 msg_perr("Error: Neither host nor device specified.\n"
452 "Use flashrom -p serprog:dev=/dev/device:baud or "
453 "flashrom -p serprog:ip=ipaddr:port\n");
454 return 1;
455 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000456
David Hendricks8bb20212011-06-14 01:35:36 +0000457 if (register_shutdown(serprog_shutdown, NULL))
458 return 1;
459
Sean Nelson74e8af52010-01-10 01:06:23 +0000460 msg_pdbg(MSGHEADER "connected - attempting to synchronize\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000461
462 sp_check_avail_automatic = 0;
463
Niklas Söderlund7145a502012-09-07 07:07:07 +0000464 if (sp_synchronize())
465 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000466
Sean Nelson74e8af52010-01-10 01:06:23 +0000467 msg_pdbg(MSGHEADER "Synchronized\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000468
469 if (sp_docommand(S_CMD_Q_IFACE, 0, NULL, 2, &iface)) {
Stefan Tauner31019d42011-10-22 21:45:27 +0000470 msg_perr("Error: NAK to query interface version\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000471 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000472 }
473
474 if (iface != 1) {
Stefan Tauner31019d42011-10-22 21:45:27 +0000475 msg_perr("Error: Unknown interface version: %d\n", iface);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000476 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000477 }
478
Sean Nelson74e8af52010-01-10 01:06:23 +0000479 msg_pdbg(MSGHEADER "Interface version ok.\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000480
481 if (sp_docommand(S_CMD_Q_CMDMAP, 0, NULL, 32, sp_cmdmap)) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000482 msg_perr("Error: query command map not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000483 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000484 }
485
486 sp_check_avail_automatic = 1;
487
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000488 /* FIXME: This assumes that serprog device bustypes are always
489 * identical with flashrom bustype enums and that they all fit
490 * in a single byte.
491 */
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000492 if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) {
493 msg_perr("Warning: NAK to query supported buses\n");
494 c = BUS_NONSPI; /* A reasonable default for now. */
Urja Rannikkof3196df2009-07-21 13:02:59 +0000495 }
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000496 serprog_buses_supported = c;
497
Stefan Tauner31019d42011-10-22 21:45:27 +0000498 msg_pdbg(MSGHEADER "Bus support: parallel=%s, LPC=%s, FWH=%s, SPI=%s\n",
499 (c & BUS_PARALLEL) ? "on" : "off",
500 (c & BUS_LPC) ? "on" : "off",
501 (c & BUS_FWH) ? "on" : "off",
502 (c & BUS_SPI) ? "on" : "off");
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000503 /* Check for the minimum operational set of commands. */
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000504 if (serprog_buses_supported & BUS_SPI) {
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000505 uint8_t bt = BUS_SPI;
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000506 char *spispeed;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000507 if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
508 msg_perr("Error: SPI operation not supported while the "
509 "bustype is SPI\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000510 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000511 }
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000512 if (sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL))
513 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000514 /* Success of any of these commands is optional. We don't need
515 the programmer to tell us its limits, but if it doesn't, we
516 will assume stuff, so it's in the programmers best interest
517 to tell us. */
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000518 if (!sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
519 uint32_t v;
520 v = ((unsigned int)(rbuf[0]) << 0);
521 v |= ((unsigned int)(rbuf[1]) << 8);
522 v |= ((unsigned int)(rbuf[2]) << 16);
523 if (v == 0)
524 v = (1 << 24) - 1; /* SPI-op maximum. */
525 spi_programmer_serprog.max_data_write = v;
526 msg_pdbg(MSGHEADER "Maximum write-n length is %d\n", v);
527 }
528 if (!sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf)) {
529 uint32_t v;
530 v = ((unsigned int)(rbuf[0]) << 0);
531 v |= ((unsigned int)(rbuf[1]) << 8);
532 v |= ((unsigned int)(rbuf[2]) << 16);
533 if (v == 0)
534 v = (1 << 24) - 1; /* SPI-op maximum. */
535 spi_programmer_serprog.max_data_read = v;
536 msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
537 }
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000538 spispeed = extract_programmer_param("spispeed");
539 if (spispeed && strlen(spispeed)) {
540 uint32_t f_spi_req, f_spi;
541 uint8_t buf[4];
542 char *f_spi_suffix;
543
544 errno = 0;
545 f_spi_req = strtol(spispeed, &f_spi_suffix, 0);
546 if (errno != 0 || spispeed == f_spi_suffix) {
547 msg_perr("Error: Could not convert 'spispeed'.\n");
548 return 1;
549 }
550 if (strlen(f_spi_suffix) == 1) {
551 if (!strcasecmp(f_spi_suffix, "M"))
552 f_spi_req *= 1000000;
553 else if (!strcasecmp(f_spi_suffix, "k"))
554 f_spi_req *= 1000;
555 else {
556 msg_perr("Error: Garbage following 'spispeed' value.\n");
557 return 1;
558 }
559 } else if (strlen(f_spi_suffix) > 1) {
560 msg_perr("Error: Garbage following 'spispeed' value.\n");
561 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
569 if (sp_check_commandavail(S_CMD_S_SPI_FREQ) == 0)
570 msg_perr(MSGHEADER "Warning: Setting the SPI clock rate is not supported!\n");
571 else if (sp_docommand(S_CMD_S_SPI_FREQ, 4, buf, 4, buf)
572 == 0) {
573 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);
579 } else
580 msg_pdbg(MSGHEADER "Setting SPI clock rate to %u Hz failed!\n", f_spi_req);
581 }
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)) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000656 msg_perr("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)) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000663 msg_perr("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)) {
683 msg_perr("Warning: NAK to query operation buffer "
684 "size\n");
685 }
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);
688 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000689
690 sp_prev_was_write = 0;
691 sp_streamed_transmit_ops = 0;
692 sp_streamed_transmit_bytes = 0;
693 sp_opbuf_usage = 0;
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000694 if (serprog_buses_supported & BUS_SPI)
695 register_spi_programmer(&spi_programmer_serprog);
696 if (serprog_buses_supported & BUS_NONSPI)
697 register_par_programmer(&par_programmer_serprog,
698 serprog_buses_supported & BUS_NONSPI);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000699 return 0;
700}
701
702/* Move an in flashrom buffer existing write-n operation to *
703 * the on-device operation buffer. */
704static void sp_pass_writen(void)
705{
706 unsigned char header[7];
Sean Nelson74e8af52010-01-10 01:06:23 +0000707 msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n",
Stefan Tauner31019d42011-10-22 21:45:27 +0000708 sp_write_n_bytes, sp_write_n_addr);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000709 if (sp_streamed_transmit_bytes >=
710 (7 + sp_write_n_bytes + sp_device_serbuf_size))
711 sp_flush_stream();
712 /* In case it's just a single byte send it as a single write. */
713 if (sp_write_n_bytes == 1) {
714 sp_write_n_bytes = 0;
715 header[0] = (sp_write_n_addr >> 0) & 0xFF;
716 header[1] = (sp_write_n_addr >> 8) & 0xFF;
717 header[2] = (sp_write_n_addr >> 16) & 0xFF;
718 header[3] = sp_write_n_buf[0];
719 sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header);
720 sp_opbuf_usage += 5;
721 return;
722 }
723 header[0] = S_CMD_O_WRITEN;
724 header[1] = (sp_write_n_bytes >> 0) & 0xFF;
725 header[2] = (sp_write_n_bytes >> 8) & 0xFF;
726 header[3] = (sp_write_n_bytes >> 16) & 0xFF;
727 header[4] = (sp_write_n_addr >> 0) & 0xFF;
728 header[5] = (sp_write_n_addr >> 8) & 0xFF;
729 header[6] = (sp_write_n_addr >> 16) & 0xFF;
730 if (write(sp_fd, header, 7) != 7)
731 sp_die("Error: cannot write write-n command\n");
732 if (write(sp_fd, sp_write_n_buf, sp_write_n_bytes) !=
733 sp_write_n_bytes)
734 sp_die("Error: cannot write write-n data");
735 sp_streamed_transmit_bytes += 7 + sp_write_n_bytes;
736 sp_streamed_transmit_ops += 1;
737 sp_opbuf_usage += 7 + sp_write_n_bytes;
738 sp_write_n_bytes = 0;
739 sp_prev_was_write = 0;
740}
741
742static void sp_execute_opbuf_noflush(void)
743{
744 if ((sp_max_write_n) && (sp_write_n_bytes))
745 sp_pass_writen();
Peter Huewe73f8ec82011-01-24 19:15:51 +0000746 sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL);
Sean Nelson74e8af52010-01-10 01:06:23 +0000747 msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n",
Urja Rannikkof3196df2009-07-21 13:02:59 +0000748 sp_opbuf_usage);
749 sp_opbuf_usage = 0;
750 sp_prev_was_write = 0;
751 return;
752}
753
754static void sp_execute_opbuf(void)
755{
756 sp_execute_opbuf_noflush();
757 sp_flush_stream();
758}
759
David Hendricks8bb20212011-06-14 01:35:36 +0000760static int serprog_shutdown(void *data)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000761{
Sean Nelson74e8af52010-01-10 01:06:23 +0000762 msg_pspew("%s\n", __func__);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000763 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
764 sp_execute_opbuf();
Niklas Söderlund7145a502012-09-07 07:07:07 +0000765 /* FIXME: fix sockets on windows(?), especially closing */
766 serialport_shutdown(&sp_fd);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000767 if (sp_max_write_n)
768 free(sp_write_n_buf);
769 return 0;
770}
771
772static void sp_check_opbuf_usage(int bytes_to_be_added)
773{
774 if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) {
775 sp_execute_opbuf();
776 /* If this happens in the mid of an page load the page load *
Uwe Hermann4e3d0b32010-03-25 23:18:41 +0000777 * will probably fail. */
Sean Nelson74e8af52010-01-10 01:06:23 +0000778 msg_pdbg(MSGHEADER "Warning: executed operation buffer due to size reasons\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000779 }
780}
781
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000782static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
783 chipaddr addr)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000784{
Sean Nelson74e8af52010-01-10 01:06:23 +0000785 msg_pspew("%s\n", __func__);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000786 if (sp_max_write_n) {
787 if ((sp_prev_was_write)
788 && (addr == (sp_write_n_addr + sp_write_n_bytes))) {
789 sp_write_n_buf[sp_write_n_bytes++] = val;
790 } else {
791 if ((sp_prev_was_write) && (sp_write_n_bytes))
792 sp_pass_writen();
793 sp_prev_was_write = 1;
794 sp_write_n_addr = addr;
795 sp_write_n_bytes = 1;
796 sp_write_n_buf[0] = val;
797 }
798 sp_check_opbuf_usage(7 + sp_write_n_bytes);
799 if (sp_write_n_bytes >= sp_max_write_n)
800 sp_pass_writen();
801 } else {
802 /* We will have to do single writeb ops. */
803 unsigned char writeb_parm[4];
804 sp_check_opbuf_usage(6);
805 writeb_parm[0] = (addr >> 0) & 0xFF;
806 writeb_parm[1] = (addr >> 8) & 0xFF;
807 writeb_parm[2] = (addr >> 16) & 0xFF;
808 writeb_parm[3] = val;
809 sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm);
810 sp_opbuf_usage += 5;
811 }
812}
813
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000814static uint8_t serprog_chip_readb(const struct flashctx *flash,
815 const chipaddr addr)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000816{
817 unsigned char c;
818 unsigned char buf[3];
819 /* Will stream the read operation - eg. add it to the stream buffer, *
820 * then flush the buffer, then read the read answer. */
821 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
822 sp_execute_opbuf_noflush();
823 buf[0] = ((addr >> 0) & 0xFF);
824 buf[1] = ((addr >> 8) & 0xFF);
825 buf[2] = ((addr >> 16) & 0xFF);
826 sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf);
827 sp_flush_stream();
828 if (read(sp_fd, &c, 1) != 1)
829 sp_die("readb byteread");
Sean Nelson74e8af52010-01-10 01:06:23 +0000830 msg_pspew("%s addr=0x%lx returning 0x%02X\n", __func__, addr, c);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000831 return c;
832}
833
Uwe Hermann4e3d0b32010-03-25 23:18:41 +0000834/* Local version that really does the job, doesn't care of max_read_n. */
Urja Rannikkof3196df2009-07-21 13:02:59 +0000835static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
836{
837 int rd_bytes = 0;
838 unsigned char sbuf[6];
Sean Nelson74e8af52010-01-10 01:06:23 +0000839 msg_pspew("%s: addr=0x%lx len=%lu\n", __func__, addr, (unsigned long)len);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000840 /* Stream the read-n -- as above. */
841 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
842 sp_execute_opbuf_noflush();
843 sbuf[0] = ((addr >> 0) & 0xFF);
844 sbuf[1] = ((addr >> 8) & 0xFF);
845 sbuf[2] = ((addr >> 16) & 0xFF);
846 sbuf[3] = ((len >> 0) & 0xFF);
847 sbuf[4] = ((len >> 8) & 0xFF);
848 sbuf[5] = ((len >> 16) & 0xFF);
849 sp_stream_buffer_op(S_CMD_R_NBYTES, 6, sbuf);
850 sp_flush_stream();
851 do {
852 int r = read(sp_fd, buf + rd_bytes, len - rd_bytes);
853 if (r <= 0)
854 sp_die("Error: cannot read read-n data");
855 rd_bytes += r;
856 } while (rd_bytes != len);
857 return;
858}
859
860/* The externally called version that makes sure that max_read_n is obeyed. */
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000861static void serprog_chip_readn(const struct flashctx *flash, uint8_t * buf,
862 const chipaddr addr, size_t len)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000863{
864 size_t lenm = len;
865 chipaddr addrm = addr;
Stefan Tauner31019d42011-10-22 21:45:27 +0000866 while ((sp_max_read_n != 0) && (lenm > sp_max_read_n)) {
867 sp_do_read_n(&(buf[addrm-addr]), addrm, sp_max_read_n);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000868 addrm += sp_max_read_n;
869 lenm -= sp_max_read_n;
870 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000871 if (lenm)
872 sp_do_read_n(&(buf[addrm-addr]), addrm, lenm);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000873}
874
Stefan Tauner31019d42011-10-22 21:45:27 +0000875void serprog_delay(int usecs)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000876{
877 unsigned char buf[4];
Stefan Tauner31019d42011-10-22 21:45:27 +0000878 msg_pspew("%s usecs=%d\n", __func__, usecs);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000879 if (!sp_check_commandavail(S_CMD_O_DELAY)) {
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000880 msg_pdbg("Note: serprog_delay used, but the programmer doesn't "
881 "support delay\n");
Stefan Tauner31019d42011-10-22 21:45:27 +0000882 internal_delay(usecs);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000883 return;
884 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000885 if ((sp_max_write_n) && (sp_write_n_bytes))
886 sp_pass_writen();
887 sp_check_opbuf_usage(5);
Stefan Tauner31019d42011-10-22 21:45:27 +0000888 buf[0] = ((usecs >> 0) & 0xFF);
889 buf[1] = ((usecs >> 8) & 0xFF);
890 buf[2] = ((usecs >> 16) & 0xFF);
891 buf[3] = ((usecs >> 24) & 0xFF);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000892 sp_stream_buffer_op(S_CMD_O_DELAY, 4, buf);
893 sp_opbuf_usage += 5;
894 sp_prev_was_write = 0;
895}
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000896
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000897static int serprog_spi_send_command(struct flashctx *flash,
898 unsigned int writecnt, unsigned int readcnt,
899 const unsigned char *writearr,
900 unsigned char *readarr)
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000901{
902 unsigned char *parmbuf;
903 int ret;
904 msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
905 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
906 sp_execute_opbuf();
907 parmbuf = malloc(writecnt + 6);
908 if (!parmbuf)
909 sp_die("Error: cannot malloc SPI send param buffer");
910 parmbuf[0] = (writecnt >> 0) & 0xFF;
911 parmbuf[1] = (writecnt >> 8) & 0xFF;
912 parmbuf[2] = (writecnt >> 16) & 0xFF;
913 parmbuf[3] = (readcnt >> 0) & 0xFF;
914 parmbuf[4] = (readcnt >> 8) & 0xFF;
915 parmbuf[5] = (readcnt >> 16) & 0xFF;
916 memcpy(parmbuf + 6, writearr, writecnt);
917 ret = sp_docommand(S_CMD_O_SPIOP, writecnt + 6, parmbuf, readcnt,
918 readarr);
919 free(parmbuf);
920 return ret;
921}
922
923/* FIXME: This function is optimized so that it does not split each transaction
924 * into chip page_size long blocks unnecessarily like spi_read_chunked. This has
925 * the advantage that it is much faster for most chips, but breaks those with
926 * non-contiguous address space (like AT45DB161D). When spi_read_chunked is
927 * fixed this method can be removed. */
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000928static int serprog_spi_read(struct flashctx *flash, uint8_t *buf,
929 unsigned int start, unsigned int len)
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000930{
Stefan Taunerc69c9c82011-11-23 09:13:48 +0000931 unsigned int i, cur_len;
932 const unsigned int max_read = spi_programmer_serprog.max_data_read;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000933 for (i = 0; i < len; i += cur_len) {
934 int ret;
935 cur_len = min(max_read, (len - i));
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000936 ret = spi_nbyte_read(flash, start + i, buf + i, cur_len);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000937 if (ret)
938 return ret;
939 }
940 return 0;
941}