blob: dd86fd34ed9f35c4b037a2347054bc6cfa2ffcad [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
Urja Rannikkof3196df2009-07-21 13:02:59 +0000141static int sp_sync_read_timeout(int loops)
142{
143 int i;
144 unsigned char c;
145 for (i = 0; i < loops; i++) {
146 ssize_t rv;
147 rv = read(sp_fd, &c, 1);
148 if (rv == 1)
149 return c;
150 if ((rv == -1) && (errno != EAGAIN))
151 sp_die("read");
152 usleep(10 * 1000); /* 10ms units */
153 }
154 return -1;
155}
156
Uwe Hermann4e3d0b32010-03-25 23:18:41 +0000157/* Synchronize: a bit tricky algorithm that tries to (and in my tests has *
Urja Rannikkof3196df2009-07-21 13:02:59 +0000158 * always succeeded in) bring the serial protocol to known waiting-for- *
159 * command state - uses nonblocking read - rest of the driver uses *
160 * blocking read - TODO: add an alarm() timer for the rest of the app on *
161 * serial operations, though not such a big issue as the first thing to *
162 * do is synchronize (eg. check that device is alive). */
163static void sp_synchronize(void)
164{
165 int i;
166 int flags = fcntl(sp_fd, F_GETFL);
167 unsigned char buf[8];
168 flags |= O_NONBLOCK;
169 fcntl(sp_fd, F_SETFL, flags);
170 /* First sends 8 NOPs, then flushes the return data - should cause *
171 * the device serial parser to get to a sane state, unless if it *
172 * is waiting for a real long write-n. */
173 memset(buf, S_CMD_NOP, 8);
174 if (write(sp_fd, buf, 8) != 8)
175 sp_die("flush write");
176 /* A second should be enough to get all the answers to the buffer */
177 usleep(1000 * 1000);
178 sp_flush_incoming();
179
Cristian Măgherușan-Stanciu9932c7b2011-07-07 19:56:58 +0000180 /* Then try up to 8 times to send syncnop and get the correct special *
181 * return of NAK+ACK. Timing note: up to 10 characters, 10*50ms = *
182 * up to 500ms per try, 8*0.5s = 4s; +1s (above) = up to 5s sync *
183 * attempt, ~1s if immediate success. */
Urja Rannikkof3196df2009-07-21 13:02:59 +0000184 for (i = 0; i < 8; i++) {
185 int n;
186 unsigned char c = S_CMD_SYNCNOP;
187 if (write(sp_fd, &c, 1) != 1)
188 sp_die("sync write");
Sean Nelson74e8af52010-01-10 01:06:23 +0000189 msg_pdbg(".");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000190 fflush(stdout);
191 for (n = 0; n < 10; n++) {
Cristian Măgherușan-Stanciu9932c7b2011-07-07 19:56:58 +0000192 c = sp_sync_read_timeout(5); /* wait up to 50ms */
Urja Rannikkof3196df2009-07-21 13:02:59 +0000193 if (c != S_NAK)
194 continue;
195 c = sp_sync_read_timeout(2);
196 if (c != S_ACK)
197 continue;
198 c = S_CMD_SYNCNOP;
199 if (write(sp_fd, &c, 1) != 1)
200 sp_die("sync write");
201 c = sp_sync_read_timeout(50);
202 if (c != S_NAK)
203 break; /* fail */
204 c = sp_sync_read_timeout(10);
205 if (c != S_ACK)
206 break; /* fail */
207 /* Ok, synchronized; back to blocking reads and return. */
208 flags &= ~O_NONBLOCK;
209 fcntl(sp_fd, F_SETFL, flags);
Sean Nelson74e8af52010-01-10 01:06:23 +0000210 msg_pdbg("\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000211 return;
212 }
213 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000214 msg_perr("Error: cannot synchronize protocol "
Urja Rannikkof3196df2009-07-21 13:02:59 +0000215 "- check communications and reset device?\n");
216 exit(1);
217}
218
219static int sp_check_commandavail(uint8_t command)
220{
221 int byteoffs, bitoffs;
222 byteoffs = command / 8;
223 bitoffs = command % 8;
224 return (sp_cmdmap[byteoffs] & (1 << bitoffs)) ? 1 : 0;
225}
226
227static int sp_automatic_cmdcheck(uint8_t cmd)
228{
229 if ((sp_check_avail_automatic) && (sp_check_commandavail(cmd) == 0)) {
Stefan Tauner31019d42011-10-22 21:45:27 +0000230 msg_pdbg("Warning: Automatic command availability check failed "
231 "for cmd 0x%x - won't execute cmd\n", cmd);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000232 return 1;
233 }
234 return 0;
235}
236
237static int sp_docommand(uint8_t command, uint32_t parmlen,
Stefan Tauner31019d42011-10-22 21:45:27 +0000238 uint8_t *params, uint32_t retlen, void *retparms)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000239{
Urja Rannikkof3196df2009-07-21 13:02:59 +0000240 unsigned char c;
241 if (sp_automatic_cmdcheck(command))
242 return 1;
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000243 if (write(sp_fd, &command, 1) != 1) {
244 msg_perr("Error: cannot write op code: %s\n", strerror(errno));
245 return 1;
246 }
247 if (write(sp_fd, params, parmlen) != (parmlen)) {
248 msg_perr("Error: cannot write parameters: %s\n", strerror(errno));
249 return 1;
250 }
251 if (read(sp_fd, &c, 1) != 1) {
252 msg_perr("Error: cannot read from device: %s\n", strerror(errno));
253 return 1;
254 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000255 if (c == S_NAK)
256 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000257 if (c != S_ACK) {
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000258 msg_perr("Error: invalid response 0x%02X from device\n", c);
259 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000260 }
261 if (retlen) {
262 int rd_bytes = 0;
263 do {
264 int r;
265 r = read(sp_fd, retparms + rd_bytes,
266 retlen - rd_bytes);
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000267 if (r <= 0) {
268 msg_perr("Error: cannot read return parameters: %s\n", strerror(errno));
269 return 1;
270 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000271 rd_bytes += r;
272 } while (rd_bytes != retlen);
273 }
274 return 0;
275}
276
277static void sp_flush_stream(void)
278{
279 if (sp_streamed_transmit_ops)
280 do {
281 unsigned char c;
282 if (read(sp_fd, &c, 1) != 1) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000283 sp_die("Error: cannot read from device (flushing stream)");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000284 }
285 if (c == S_NAK) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000286 msg_perr("Error: NAK to a stream buffer operation\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000287 exit(1);
288 }
289 if (c != S_ACK) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000290 msg_perr("Error: Invalid reply 0x%02X from device\n", c);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000291 exit(1);
292 }
293 } while (--sp_streamed_transmit_ops);
294 sp_streamed_transmit_ops = 0;
295 sp_streamed_transmit_bytes = 0;
296}
297
298static int sp_stream_buffer_op(uint8_t cmd, uint32_t parmlen, uint8_t * parms)
299{
300 uint8_t *sp;
301 if (sp_automatic_cmdcheck(cmd))
302 return 1;
303 sp = malloc(1 + parmlen);
304 if (!sp) sp_die("Error: cannot malloc command buffer");
305 sp[0] = cmd;
306 memcpy(&(sp[1]), parms, parmlen);
307 if (sp_streamed_transmit_bytes >= (1 + parmlen + sp_device_serbuf_size))
308 sp_flush_stream();
309 if (write(sp_fd, sp, 1 + parmlen) != (1 + parmlen))
310 sp_die("Error: cannot write command");
311 free(sp);
312 sp_streamed_transmit_ops += 1;
313 sp_streamed_transmit_bytes += 1 + parmlen;
314 return 0;
315}
316
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000317static int serprog_spi_send_command(struct flashctx *flash,
318 unsigned int writecnt, unsigned int readcnt,
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000319 const unsigned char *writearr,
320 unsigned char *readarr);
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000321static int serprog_spi_read(struct flashctx *flash, uint8_t *buf,
Stefan Taunerc69c9c82011-11-23 09:13:48 +0000322 unsigned int start, unsigned int len);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000323static struct spi_programmer spi_programmer_serprog = {
324 .type = SPI_CONTROLLER_SERPROG,
325 .max_data_read = MAX_DATA_READ_UNLIMITED,
326 .max_data_write = MAX_DATA_WRITE_UNLIMITED,
327 .command = serprog_spi_send_command,
328 .multicommand = default_spi_send_multicommand,
329 .read = serprog_spi_read,
330 .write_256 = default_spi_write_256,
Nico Huber7bca1262012-06-15 22:28:12 +0000331 .write_aai = default_spi_write_aai,
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000332};
333
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000334static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
335 chipaddr addr);
336static uint8_t serprog_chip_readb(const struct flashctx *flash,
337 const chipaddr addr);
338static void serprog_chip_readn(const struct flashctx *flash, uint8_t *buf,
339 const chipaddr addr, size_t len);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000340static const struct par_programmer par_programmer_serprog = {
341 .chip_readb = serprog_chip_readb,
342 .chip_readw = fallback_chip_readw,
343 .chip_readl = fallback_chip_readl,
344 .chip_readn = serprog_chip_readn,
345 .chip_writeb = serprog_chip_writeb,
346 .chip_writew = fallback_chip_writew,
347 .chip_writel = fallback_chip_writel,
348 .chip_writen = fallback_chip_writen,
349};
350
351static enum chipbustype serprog_buses_supported = BUS_NONE;
352
Urja Rannikkof3196df2009-07-21 13:02:59 +0000353int serprog_init(void)
354{
355 uint16_t iface;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000356 unsigned char pgmname[17];
357 unsigned char rbuf[3];
358 unsigned char c;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000359 char *device;
360 char *baudport;
361 int have_device = 0;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000362
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000363 /* the parameter is either of format "dev=/dev/device:baud" or "ip=ip:port" */
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000364 device = extract_programmer_param("dev");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000365 if (device && strlen(device)) {
366 baudport = strstr(device, ":");
367 if (baudport) {
368 /* Split device from baudrate. */
369 *baudport = '\0';
370 baudport++;
371 }
372 if (!baudport || !strlen(baudport)) {
373 msg_perr("Error: No baudrate specified.\n"
374 "Use flashrom -p serprog:dev=/dev/device:baud\n");
375 free(device);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000376 return 1;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000377 }
378 if (strlen(device)) {
379 sp_fd = sp_openserport(device, atoi(baudport));
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000380 if (sp_fd < 0) {
381 free(device);
382 return 1;
383 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000384 have_device++;
385 }
386 }
387 if (device && !strlen(device)) {
388 msg_perr("Error: No device specified.\n"
389 "Use flashrom -p serprog:dev=/dev/device:baud\n");
390 free(device);
391 return 1;
392 }
393 free(device);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000394
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000395 device = extract_programmer_param("ip");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000396 if (have_device && device) {
397 msg_perr("Error: Both host and device specified.\n"
398 "Please use either dev= or ip= but not both.\n");
399 free(device);
400 return 1;
401 }
402 if (device && strlen(device)) {
403 baudport = strstr(device, ":");
404 if (baudport) {
405 /* Split host from port. */
406 *baudport = '\0';
407 baudport++;
408 }
409 if (!baudport || !strlen(baudport)) {
410 msg_perr("Error: No port specified.\n"
411 "Use flashrom -p serprog:ip=ipaddr:port\n");
412 free(device);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000413 return 1;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000414 }
415 if (strlen(device)) {
416 sp_fd = sp_opensocket(device, atoi(baudport));
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000417 if (sp_fd < 0) {
418 free(device);
419 return 1;
420 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000421 have_device++;
422 }
423 }
424 if (device && !strlen(device)) {
425 msg_perr("Error: No host specified.\n"
426 "Use flashrom -p serprog:ip=ipaddr:port\n");
427 free(device);
428 return 1;
429 }
430 free(device);
431
432 if (!have_device) {
433 msg_perr("Error: Neither host nor device specified.\n"
434 "Use flashrom -p serprog:dev=/dev/device:baud or "
435 "flashrom -p serprog:ip=ipaddr:port\n");
436 return 1;
437 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000438
David Hendricks8bb20212011-06-14 01:35:36 +0000439 if (register_shutdown(serprog_shutdown, NULL))
440 return 1;
441
Sean Nelson74e8af52010-01-10 01:06:23 +0000442 msg_pdbg(MSGHEADER "connected - attempting to synchronize\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000443
444 sp_check_avail_automatic = 0;
445
446 sp_synchronize();
447
Sean Nelson74e8af52010-01-10 01:06:23 +0000448 msg_pdbg(MSGHEADER "Synchronized\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000449
450 if (sp_docommand(S_CMD_Q_IFACE, 0, NULL, 2, &iface)) {
Stefan Tauner31019d42011-10-22 21:45:27 +0000451 msg_perr("Error: NAK to query interface version\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000452 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000453 }
454
455 if (iface != 1) {
Stefan Tauner31019d42011-10-22 21:45:27 +0000456 msg_perr("Error: Unknown interface version: %d\n", iface);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000457 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000458 }
459
Sean Nelson74e8af52010-01-10 01:06:23 +0000460 msg_pdbg(MSGHEADER "Interface version ok.\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000461
462 if (sp_docommand(S_CMD_Q_CMDMAP, 0, NULL, 32, sp_cmdmap)) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000463 msg_perr("Error: query command map not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000464 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000465 }
466
467 sp_check_avail_automatic = 1;
468
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000469 /* FIXME: This assumes that serprog device bustypes are always
470 * identical with flashrom bustype enums and that they all fit
471 * in a single byte.
472 */
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000473 if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) {
474 msg_perr("Warning: NAK to query supported buses\n");
475 c = BUS_NONSPI; /* A reasonable default for now. */
Urja Rannikkof3196df2009-07-21 13:02:59 +0000476 }
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000477 serprog_buses_supported = c;
478
Stefan Tauner31019d42011-10-22 21:45:27 +0000479 msg_pdbg(MSGHEADER "Bus support: parallel=%s, LPC=%s, FWH=%s, SPI=%s\n",
480 (c & BUS_PARALLEL) ? "on" : "off",
481 (c & BUS_LPC) ? "on" : "off",
482 (c & BUS_FWH) ? "on" : "off",
483 (c & BUS_SPI) ? "on" : "off");
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000484 /* Check for the minimum operational set of commands. */
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000485 if (serprog_buses_supported & BUS_SPI) {
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000486 uint8_t bt = BUS_SPI;
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000487 char *spispeed;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000488 if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
489 msg_perr("Error: SPI operation not supported while the "
490 "bustype is SPI\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000491 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000492 }
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000493 if (sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL))
494 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000495 /* Success of any of these commands is optional. We don't need
496 the programmer to tell us its limits, but if it doesn't, we
497 will assume stuff, so it's in the programmers best interest
498 to tell us. */
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000499 if (!sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
500 uint32_t v;
501 v = ((unsigned int)(rbuf[0]) << 0);
502 v |= ((unsigned int)(rbuf[1]) << 8);
503 v |= ((unsigned int)(rbuf[2]) << 16);
504 if (v == 0)
505 v = (1 << 24) - 1; /* SPI-op maximum. */
506 spi_programmer_serprog.max_data_write = v;
507 msg_pdbg(MSGHEADER "Maximum write-n length is %d\n", v);
508 }
509 if (!sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf)) {
510 uint32_t v;
511 v = ((unsigned int)(rbuf[0]) << 0);
512 v |= ((unsigned int)(rbuf[1]) << 8);
513 v |= ((unsigned int)(rbuf[2]) << 16);
514 if (v == 0)
515 v = (1 << 24) - 1; /* SPI-op maximum. */
516 spi_programmer_serprog.max_data_read = v;
517 msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
518 }
Stefan Taunerb98f6eb2012-08-13 16:33:04 +0000519 spispeed = extract_programmer_param("spispeed");
520 if (spispeed && strlen(spispeed)) {
521 uint32_t f_spi_req, f_spi;
522 uint8_t buf[4];
523 char *f_spi_suffix;
524
525 errno = 0;
526 f_spi_req = strtol(spispeed, &f_spi_suffix, 0);
527 if (errno != 0 || spispeed == f_spi_suffix) {
528 msg_perr("Error: Could not convert 'spispeed'.\n");
529 return 1;
530 }
531 if (strlen(f_spi_suffix) == 1) {
532 if (!strcasecmp(f_spi_suffix, "M"))
533 f_spi_req *= 1000000;
534 else if (!strcasecmp(f_spi_suffix, "k"))
535 f_spi_req *= 1000;
536 else {
537 msg_perr("Error: Garbage following 'spispeed' value.\n");
538 return 1;
539 }
540 } else if (strlen(f_spi_suffix) > 1) {
541 msg_perr("Error: Garbage following 'spispeed' value.\n");
542 return 1;
543 }
544
545 buf[0] = (f_spi_req >> (0 * 8)) & 0xFF;
546 buf[1] = (f_spi_req >> (1 * 8)) & 0xFF;
547 buf[2] = (f_spi_req >> (2 * 8)) & 0xFF;
548 buf[3] = (f_spi_req >> (3 * 8)) & 0xFF;
549
550 if (sp_check_commandavail(S_CMD_S_SPI_FREQ) == 0)
551 msg_perr(MSGHEADER "Warning: Setting the SPI clock rate is not supported!\n");
552 else if (sp_docommand(S_CMD_S_SPI_FREQ, 4, buf, 4, buf)
553 == 0) {
554 f_spi = buf[0];
555 f_spi |= buf[1] << (1 * 8);
556 f_spi |= buf[2] << (2 * 8);
557 f_spi |= buf[3] << (3 * 8);
558 msg_pdbg(MSGHEADER "Requested to set SPI clock frequency to %u Hz. "
559 "It was actually set to %u Hz\n", f_spi_req, f_spi);
560 } else
561 msg_pdbg(MSGHEADER "Setting SPI clock rate to %u Hz failed!\n", f_spi_req);
562 }
563 free(spispeed);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000564 bt = serprog_buses_supported;
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000565 if (sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL))
566 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000567 }
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000568
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000569 if (serprog_buses_supported & BUS_NONSPI) {
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000570 if (sp_check_commandavail(S_CMD_O_INIT) == 0) {
571 msg_perr("Error: Initialize operation buffer "
572 "not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000573 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000574 }
575
576 if (sp_check_commandavail(S_CMD_O_DELAY) == 0) {
577 msg_perr("Error: Write to opbuf: "
578 "delay not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000579 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000580 }
581
582 /* S_CMD_O_EXEC availability checked later. */
583
584 if (sp_check_commandavail(S_CMD_R_BYTE) == 0) {
585 msg_perr("Error: Single byte read not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000586 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000587 }
588 /* This could be translated to single byte reads (if missing),
589 * but now we don't support that. */
590 if (sp_check_commandavail(S_CMD_R_NBYTES) == 0) {
591 msg_perr("Error: Read n bytes not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000592 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000593 }
594 if (sp_check_commandavail(S_CMD_O_WRITEB) == 0) {
595 msg_perr("Error: Write to opbuf: "
596 "write byte not supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000597 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000598 }
599
600 if (sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
601 msg_pdbg(MSGHEADER "Write-n not supported");
602 sp_max_write_n = 0;
603 } else {
604 sp_max_write_n = ((unsigned int)(rbuf[0]) << 0);
605 sp_max_write_n |= ((unsigned int)(rbuf[1]) << 8);
606 sp_max_write_n |= ((unsigned int)(rbuf[2]) << 16);
607 if (!sp_max_write_n) {
608 sp_max_write_n = (1 << 24);
609 }
610 msg_pdbg(MSGHEADER "Maximum write-n length is %d\n",
611 sp_max_write_n);
612 sp_write_n_buf = malloc(sp_max_write_n);
613 if (!sp_write_n_buf) {
614 msg_perr("Error: cannot allocate memory for "
615 "Write-n buffer\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000616 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000617 }
618 sp_write_n_bytes = 0;
619 }
620
621 if (sp_check_commandavail(S_CMD_Q_RDNMAXLEN) &&
622 (sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf) == 0)) {
623 sp_max_read_n = ((unsigned int)(rbuf[0]) << 0);
624 sp_max_read_n |= ((unsigned int)(rbuf[1]) << 8);
625 sp_max_read_n |= ((unsigned int)(rbuf[2]) << 16);
626 msg_pdbg(MSGHEADER "Maximum read-n length is %d\n",
627 sp_max_read_n ? sp_max_read_n : (1 << 24));
628 } else {
629 msg_pdbg(MSGHEADER "Maximum read-n length "
630 "not reported\n");
631 sp_max_read_n = 0;
632 }
633
Urja Rannikkof3196df2009-07-21 13:02:59 +0000634 }
635
636 if (sp_docommand(S_CMD_Q_PGMNAME, 0, NULL, 16, pgmname)) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000637 msg_perr("Warning: NAK to query programmer name\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000638 strcpy((char *)pgmname, "(unknown)");
639 }
640 pgmname[16] = 0;
Stefan Tauner31019d42011-10-22 21:45:27 +0000641 msg_pinfo(MSGHEADER "Programmer name is \"%s\"\n", pgmname);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000642
643 if (sp_docommand(S_CMD_Q_SERBUF, 0, NULL, 2, &sp_device_serbuf_size)) {
Sean Nelson74e8af52010-01-10 01:06:23 +0000644 msg_perr("Warning: NAK to query serial buffer size\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000645 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000646 msg_pdbg(MSGHEADER "Serial buffer size is %d\n",
Urja Rannikkof3196df2009-07-21 13:02:59 +0000647 sp_device_serbuf_size);
648
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000649 if (sp_check_commandavail(S_CMD_O_INIT)) {
650 /* This would be inconsistent. */
651 if (sp_check_commandavail(S_CMD_O_EXEC) == 0) {
652 msg_perr("Error: Execute operation buffer not "
653 "supported\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000654 return 1;
Urja Rannikkof3196df2009-07-21 13:02:59 +0000655 }
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000656
657 if (sp_docommand(S_CMD_O_INIT, 0, NULL, 0, NULL)) {
658 msg_perr("Error: NAK to initialize operation buffer\n");
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000659 return 1;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000660 }
661
662 if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2,
663 &sp_device_opbuf_size)) {
664 msg_perr("Warning: NAK to query operation buffer "
665 "size\n");
666 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000667 msg_pdbg(MSGHEADER "operation buffer size is %d\n",
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000668 sp_device_opbuf_size);
669 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000670
671 sp_prev_was_write = 0;
672 sp_streamed_transmit_ops = 0;
673 sp_streamed_transmit_bytes = 0;
674 sp_opbuf_usage = 0;
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000675 if (serprog_buses_supported & BUS_SPI)
676 register_spi_programmer(&spi_programmer_serprog);
677 if (serprog_buses_supported & BUS_NONSPI)
678 register_par_programmer(&par_programmer_serprog,
679 serprog_buses_supported & BUS_NONSPI);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000680 return 0;
681}
682
683/* Move an in flashrom buffer existing write-n operation to *
684 * the on-device operation buffer. */
685static void sp_pass_writen(void)
686{
687 unsigned char header[7];
Sean Nelson74e8af52010-01-10 01:06:23 +0000688 msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n",
Stefan Tauner31019d42011-10-22 21:45:27 +0000689 sp_write_n_bytes, sp_write_n_addr);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000690 if (sp_streamed_transmit_bytes >=
691 (7 + sp_write_n_bytes + sp_device_serbuf_size))
692 sp_flush_stream();
693 /* In case it's just a single byte send it as a single write. */
694 if (sp_write_n_bytes == 1) {
695 sp_write_n_bytes = 0;
696 header[0] = (sp_write_n_addr >> 0) & 0xFF;
697 header[1] = (sp_write_n_addr >> 8) & 0xFF;
698 header[2] = (sp_write_n_addr >> 16) & 0xFF;
699 header[3] = sp_write_n_buf[0];
700 sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header);
701 sp_opbuf_usage += 5;
702 return;
703 }
704 header[0] = S_CMD_O_WRITEN;
705 header[1] = (sp_write_n_bytes >> 0) & 0xFF;
706 header[2] = (sp_write_n_bytes >> 8) & 0xFF;
707 header[3] = (sp_write_n_bytes >> 16) & 0xFF;
708 header[4] = (sp_write_n_addr >> 0) & 0xFF;
709 header[5] = (sp_write_n_addr >> 8) & 0xFF;
710 header[6] = (sp_write_n_addr >> 16) & 0xFF;
711 if (write(sp_fd, header, 7) != 7)
712 sp_die("Error: cannot write write-n command\n");
713 if (write(sp_fd, sp_write_n_buf, sp_write_n_bytes) !=
714 sp_write_n_bytes)
715 sp_die("Error: cannot write write-n data");
716 sp_streamed_transmit_bytes += 7 + sp_write_n_bytes;
717 sp_streamed_transmit_ops += 1;
718 sp_opbuf_usage += 7 + sp_write_n_bytes;
719 sp_write_n_bytes = 0;
720 sp_prev_was_write = 0;
721}
722
723static void sp_execute_opbuf_noflush(void)
724{
725 if ((sp_max_write_n) && (sp_write_n_bytes))
726 sp_pass_writen();
Peter Huewe73f8ec82011-01-24 19:15:51 +0000727 sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL);
Sean Nelson74e8af52010-01-10 01:06:23 +0000728 msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n",
Urja Rannikkof3196df2009-07-21 13:02:59 +0000729 sp_opbuf_usage);
730 sp_opbuf_usage = 0;
731 sp_prev_was_write = 0;
732 return;
733}
734
735static void sp_execute_opbuf(void)
736{
737 sp_execute_opbuf_noflush();
738 sp_flush_stream();
739}
740
David Hendricks8bb20212011-06-14 01:35:36 +0000741static int serprog_shutdown(void *data)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000742{
Sean Nelson74e8af52010-01-10 01:06:23 +0000743 msg_pspew("%s\n", __func__);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000744 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
745 sp_execute_opbuf();
746 close(sp_fd);
747 if (sp_max_write_n)
748 free(sp_write_n_buf);
749 return 0;
750}
751
752static void sp_check_opbuf_usage(int bytes_to_be_added)
753{
754 if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) {
755 sp_execute_opbuf();
756 /* If this happens in the mid of an page load the page load *
Uwe Hermann4e3d0b32010-03-25 23:18:41 +0000757 * will probably fail. */
Sean Nelson74e8af52010-01-10 01:06:23 +0000758 msg_pdbg(MSGHEADER "Warning: executed operation buffer due to size reasons\n");
Urja Rannikkof3196df2009-07-21 13:02:59 +0000759 }
760}
761
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000762static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
763 chipaddr addr)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000764{
Sean Nelson74e8af52010-01-10 01:06:23 +0000765 msg_pspew("%s\n", __func__);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000766 if (sp_max_write_n) {
767 if ((sp_prev_was_write)
768 && (addr == (sp_write_n_addr + sp_write_n_bytes))) {
769 sp_write_n_buf[sp_write_n_bytes++] = val;
770 } else {
771 if ((sp_prev_was_write) && (sp_write_n_bytes))
772 sp_pass_writen();
773 sp_prev_was_write = 1;
774 sp_write_n_addr = addr;
775 sp_write_n_bytes = 1;
776 sp_write_n_buf[0] = val;
777 }
778 sp_check_opbuf_usage(7 + sp_write_n_bytes);
779 if (sp_write_n_bytes >= sp_max_write_n)
780 sp_pass_writen();
781 } else {
782 /* We will have to do single writeb ops. */
783 unsigned char writeb_parm[4];
784 sp_check_opbuf_usage(6);
785 writeb_parm[0] = (addr >> 0) & 0xFF;
786 writeb_parm[1] = (addr >> 8) & 0xFF;
787 writeb_parm[2] = (addr >> 16) & 0xFF;
788 writeb_parm[3] = val;
789 sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm);
790 sp_opbuf_usage += 5;
791 }
792}
793
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000794static uint8_t serprog_chip_readb(const struct flashctx *flash,
795 const chipaddr addr)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000796{
797 unsigned char c;
798 unsigned char buf[3];
799 /* Will stream the read operation - eg. add it to the stream buffer, *
800 * then flush the buffer, then read the read answer. */
801 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
802 sp_execute_opbuf_noflush();
803 buf[0] = ((addr >> 0) & 0xFF);
804 buf[1] = ((addr >> 8) & 0xFF);
805 buf[2] = ((addr >> 16) & 0xFF);
806 sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf);
807 sp_flush_stream();
808 if (read(sp_fd, &c, 1) != 1)
809 sp_die("readb byteread");
Sean Nelson74e8af52010-01-10 01:06:23 +0000810 msg_pspew("%s addr=0x%lx returning 0x%02X\n", __func__, addr, c);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000811 return c;
812}
813
Uwe Hermann4e3d0b32010-03-25 23:18:41 +0000814/* Local version that really does the job, doesn't care of max_read_n. */
Urja Rannikkof3196df2009-07-21 13:02:59 +0000815static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
816{
817 int rd_bytes = 0;
818 unsigned char sbuf[6];
Sean Nelson74e8af52010-01-10 01:06:23 +0000819 msg_pspew("%s: addr=0x%lx len=%lu\n", __func__, addr, (unsigned long)len);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000820 /* Stream the read-n -- as above. */
821 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
822 sp_execute_opbuf_noflush();
823 sbuf[0] = ((addr >> 0) & 0xFF);
824 sbuf[1] = ((addr >> 8) & 0xFF);
825 sbuf[2] = ((addr >> 16) & 0xFF);
826 sbuf[3] = ((len >> 0) & 0xFF);
827 sbuf[4] = ((len >> 8) & 0xFF);
828 sbuf[5] = ((len >> 16) & 0xFF);
829 sp_stream_buffer_op(S_CMD_R_NBYTES, 6, sbuf);
830 sp_flush_stream();
831 do {
832 int r = read(sp_fd, buf + rd_bytes, len - rd_bytes);
833 if (r <= 0)
834 sp_die("Error: cannot read read-n data");
835 rd_bytes += r;
836 } while (rd_bytes != len);
837 return;
838}
839
840/* The externally called version that makes sure that max_read_n is obeyed. */
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000841static void serprog_chip_readn(const struct flashctx *flash, uint8_t * buf,
842 const chipaddr addr, size_t len)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000843{
844 size_t lenm = len;
845 chipaddr addrm = addr;
Stefan Tauner31019d42011-10-22 21:45:27 +0000846 while ((sp_max_read_n != 0) && (lenm > sp_max_read_n)) {
847 sp_do_read_n(&(buf[addrm-addr]), addrm, sp_max_read_n);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000848 addrm += sp_max_read_n;
849 lenm -= sp_max_read_n;
850 }
Stefan Tauner31019d42011-10-22 21:45:27 +0000851 if (lenm)
852 sp_do_read_n(&(buf[addrm-addr]), addrm, lenm);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000853}
854
Stefan Tauner31019d42011-10-22 21:45:27 +0000855void serprog_delay(int usecs)
Urja Rannikkof3196df2009-07-21 13:02:59 +0000856{
857 unsigned char buf[4];
Stefan Tauner31019d42011-10-22 21:45:27 +0000858 msg_pspew("%s usecs=%d\n", __func__, usecs);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000859 if (!sp_check_commandavail(S_CMD_O_DELAY)) {
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000860 msg_pdbg("Note: serprog_delay used, but the programmer doesn't "
861 "support delay\n");
Stefan Tauner31019d42011-10-22 21:45:27 +0000862 internal_delay(usecs);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000863 return;
864 }
Urja Rannikkof3196df2009-07-21 13:02:59 +0000865 if ((sp_max_write_n) && (sp_write_n_bytes))
866 sp_pass_writen();
867 sp_check_opbuf_usage(5);
Stefan Tauner31019d42011-10-22 21:45:27 +0000868 buf[0] = ((usecs >> 0) & 0xFF);
869 buf[1] = ((usecs >> 8) & 0xFF);
870 buf[2] = ((usecs >> 16) & 0xFF);
871 buf[3] = ((usecs >> 24) & 0xFF);
Urja Rannikkof3196df2009-07-21 13:02:59 +0000872 sp_stream_buffer_op(S_CMD_O_DELAY, 4, buf);
873 sp_opbuf_usage += 5;
874 sp_prev_was_write = 0;
875}
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000876
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000877static int serprog_spi_send_command(struct flashctx *flash,
878 unsigned int writecnt, unsigned int readcnt,
879 const unsigned char *writearr,
880 unsigned char *readarr)
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000881{
882 unsigned char *parmbuf;
883 int ret;
884 msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
885 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
886 sp_execute_opbuf();
887 parmbuf = malloc(writecnt + 6);
888 if (!parmbuf)
889 sp_die("Error: cannot malloc SPI send param buffer");
890 parmbuf[0] = (writecnt >> 0) & 0xFF;
891 parmbuf[1] = (writecnt >> 8) & 0xFF;
892 parmbuf[2] = (writecnt >> 16) & 0xFF;
893 parmbuf[3] = (readcnt >> 0) & 0xFF;
894 parmbuf[4] = (readcnt >> 8) & 0xFF;
895 parmbuf[5] = (readcnt >> 16) & 0xFF;
896 memcpy(parmbuf + 6, writearr, writecnt);
897 ret = sp_docommand(S_CMD_O_SPIOP, writecnt + 6, parmbuf, readcnt,
898 readarr);
899 free(parmbuf);
900 return ret;
901}
902
903/* FIXME: This function is optimized so that it does not split each transaction
904 * into chip page_size long blocks unnecessarily like spi_read_chunked. This has
905 * the advantage that it is much faster for most chips, but breaks those with
906 * non-contiguous address space (like AT45DB161D). When spi_read_chunked is
907 * fixed this method can be removed. */
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000908static int serprog_spi_read(struct flashctx *flash, uint8_t *buf,
909 unsigned int start, unsigned int len)
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000910{
Stefan Taunerc69c9c82011-11-23 09:13:48 +0000911 unsigned int i, cur_len;
912 const unsigned int max_read = spi_programmer_serprog.max_data_read;
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000913 for (i = 0; i < len; i += cur_len) {
914 int ret;
915 cur_len = min(max_read, (len - i));
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000916 ret = spi_nbyte_read(flash, start + i, buf + i, cur_len);
Urja Rannikkoc93f5f12011-09-15 23:38:14 +0000917 if (ret)
918 return ret;
919 }
920 return 0;
921}