blob: 1ba76c8a1369886b99a0c8053499c5977fd26430 [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>
Edward O'Callaghanb4300ca2019-09-03 16:15:21 +100022#include <strings.h>
hailfinger4f45a4f2009-08-12 13:32:56 +000023#include <string.h>
hailfinger37b4fbf2009-06-23 11:33:43 +000024#include <ctype.h>
25#include <fcntl.h>
hailfinger37b4fbf2009-06-23 11:33:43 +000026#include <sys/socket.h>
27#include <arpa/inet.h>
28#include <netinet/in.h>
29#include <netinet/tcp.h>
30#include <netdb.h>
31#include <sys/stat.h>
32#include <errno.h>
hailfinger37b4fbf2009-06-23 11:33:43 +000033#include <inttypes.h>
34#include <termios.h>
hailfinger428f6852010-07-27 22:41:39 +000035#include "flash.h"
36#include "programmer.h"
stefanct69965b62011-09-15 23:38:14 +000037#include "chipdrivers.h"
Patrick Georgib9fe7f12017-04-11 20:35:19 +020038#include "serprog.h"
hailfingerbacbc8b2009-07-21 13:02:59 +000039
stefanctd9ac2212011-10-22 21:45:27 +000040#define MSGHEADER "serprog: "
hailfingerbacbc8b2009-07-21 13:02:59 +000041
dhendrix0ffc2eb2011-06-14 01:35:36 +000042/*
43 * FIXME: This prototype was added to help reduce diffs for the shutdown
44 * registration patch, which shifted many lines of code to place
45 * serprog_shutdown() before serprog_init(). It should be removed soon.
46 */
David Hendricks93784b42016-08-09 17:00:38 -070047static int serprog_shutdown(void *data);
dhendrix0ffc2eb2011-06-14 01:35:36 +000048
hailfingerbacbc8b2009-07-21 13:02:59 +000049static uint16_t sp_device_serbuf_size = 16;
50static uint16_t sp_device_opbuf_size = 300;
51/* Bitmap of supported commands */
52static uint8_t sp_cmdmap[32];
53
uwe3a3ab2f2010-03-25 23:18:41 +000054/* sp_prev_was_write used to detect writes with contiguous addresses
hailfingerbacbc8b2009-07-21 13:02:59 +000055 and combine them to write-n's */
56static int sp_prev_was_write = 0;
57/* sp_write_n_addr used as the starting addr of the currently
58 combined write-n operation */
59static uint32_t sp_write_n_addr;
60/* The maximum length of an write_n operation; 0 = write-n not supported */
61static uint32_t sp_max_write_n = 0;
62/* The maximum length of a read_n operation; 0 = 2^24 */
63static uint32_t sp_max_read_n = 0;
64
65/* A malloc'd buffer for combining the operation's data
66 and a counter that tells how much data is there. */
67static uint8_t *sp_write_n_buf;
68static uint32_t sp_write_n_bytes = 0;
69
70/* sp_streamed_* used for flow control checking */
71static int sp_streamed_transmit_ops = 0;
72static int sp_streamed_transmit_bytes = 0;
73
74/* sp_opbuf_usage used for counting the amount of
75 on-device operation buffer used */
76static int sp_opbuf_usage = 0;
77/* if true causes sp_docommand to automatically check
78 whether the command is supported before doing it */
79static int sp_check_avail_automatic = 0;
80
hailfingerbacbc8b2009-07-21 13:02:59 +000081static int sp_opensocket(char *ip, unsigned int port)
82{
83 int flag = 1;
84 struct hostent *hostPtr = NULL;
hailfinger3e454f32009-09-05 01:10:23 +000085 union { struct sockaddr_in si; struct sockaddr s; } sp = {};
hailfingerbacbc8b2009-07-21 13:02:59 +000086 int sock;
snelson0afd28b2010-01-10 01:06:23 +000087 msg_pdbg(MSGHEADER "IP %s port %d\n", ip, port);
hailfingerbacbc8b2009-07-21 13:02:59 +000088 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
89 if (sock < 0)
90 sp_die("Error: serprog cannot open socket");
91 hostPtr = gethostbyname(ip);
92 if (NULL == hostPtr) {
93 hostPtr = gethostbyaddr(ip, strlen(ip), AF_INET);
94 if (NULL == hostPtr)
95 sp_die("Error: cannot resolve");
96 }
hailfinger3e454f32009-09-05 01:10:23 +000097 sp.si.sin_family = AF_INET;
98 sp.si.sin_port = htons(port);
Edward O'Callaghan9987ad42019-09-03 15:58:56 +100099 (void)memcpy(&sp.si.sin_addr, hostPtr->h_addr_list[0], hostPtr->h_length);
hailfinger3e454f32009-09-05 01:10:23 +0000100 if (connect(sock, &sp.s, sizeof(sp.si)) < 0) {
hailfingerbacbc8b2009-07-21 13:02:59 +0000101 close(sock);
102 sp_die("Error: serprog cannot connect");
103 }
104 /* We are latency limited, and sometimes do write-write-read *
105 * (write-n) - so enable TCP_NODELAY. */
106 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
107 return sock;
108}
109
hailfingerbacbc8b2009-07-21 13:02:59 +0000110static int sp_sync_read_timeout(int loops)
111{
112 int i;
113 unsigned char c;
114 for (i = 0; i < loops; i++) {
115 ssize_t rv;
116 rv = read(sp_fd, &c, 1);
117 if (rv == 1)
118 return c;
119 if ((rv == -1) && (errno != EAGAIN))
120 sp_die("read");
121 usleep(10 * 1000); /* 10ms units */
122 }
123 return -1;
124}
125
uwe3a3ab2f2010-03-25 23:18:41 +0000126/* Synchronize: a bit tricky algorithm that tries to (and in my tests has *
hailfingerbacbc8b2009-07-21 13:02:59 +0000127 * always succeeded in) bring the serial protocol to known waiting-for- *
128 * command state - uses nonblocking read - rest of the driver uses *
129 * blocking read - TODO: add an alarm() timer for the rest of the app on *
130 * serial operations, though not such a big issue as the first thing to *
131 * do is synchronize (eg. check that device is alive). */
132static void sp_synchronize(void)
133{
134 int i;
135 int flags = fcntl(sp_fd, F_GETFL);
136 unsigned char buf[8];
137 flags |= O_NONBLOCK;
138 fcntl(sp_fd, F_SETFL, flags);
139 /* First sends 8 NOPs, then flushes the return data - should cause *
140 * the device serial parser to get to a sane state, unless if it *
141 * is waiting for a real long write-n. */
142 memset(buf, S_CMD_NOP, 8);
143 if (write(sp_fd, buf, 8) != 8)
144 sp_die("flush write");
145 /* A second should be enough to get all the answers to the buffer */
146 usleep(1000 * 1000);
147 sp_flush_incoming();
148
stefanct371e7e82011-07-07 19:56:58 +0000149 /* Then try up to 8 times to send syncnop and get the correct special *
150 * return of NAK+ACK. Timing note: up to 10 characters, 10*50ms = *
151 * up to 500ms per try, 8*0.5s = 4s; +1s (above) = up to 5s sync *
152 * attempt, ~1s if immediate success. */
hailfingerbacbc8b2009-07-21 13:02:59 +0000153 for (i = 0; i < 8; i++) {
154 int n;
155 unsigned char c = S_CMD_SYNCNOP;
156 if (write(sp_fd, &c, 1) != 1)
157 sp_die("sync write");
snelson0afd28b2010-01-10 01:06:23 +0000158 msg_pdbg(".");
hailfingerbacbc8b2009-07-21 13:02:59 +0000159 fflush(stdout);
160 for (n = 0; n < 10; n++) {
stefanct371e7e82011-07-07 19:56:58 +0000161 c = sp_sync_read_timeout(5); /* wait up to 50ms */
hailfingerbacbc8b2009-07-21 13:02:59 +0000162 if (c != S_NAK)
163 continue;
164 c = sp_sync_read_timeout(2);
165 if (c != S_ACK)
166 continue;
167 c = S_CMD_SYNCNOP;
168 if (write(sp_fd, &c, 1) != 1)
169 sp_die("sync write");
170 c = sp_sync_read_timeout(50);
171 if (c != S_NAK)
172 break; /* fail */
173 c = sp_sync_read_timeout(10);
174 if (c != S_ACK)
175 break; /* fail */
176 /* Ok, synchronized; back to blocking reads and return. */
177 flags &= ~O_NONBLOCK;
178 fcntl(sp_fd, F_SETFL, flags);
snelson0afd28b2010-01-10 01:06:23 +0000179 msg_pdbg("\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000180 return;
181 }
182 }
stefanctd9ac2212011-10-22 21:45:27 +0000183 msg_perr("Error: cannot synchronize protocol "
hailfingerbacbc8b2009-07-21 13:02:59 +0000184 "- check communications and reset device?\n");
185 exit(1);
186}
187
188static int sp_check_commandavail(uint8_t command)
189{
190 int byteoffs, bitoffs;
191 byteoffs = command / 8;
192 bitoffs = command % 8;
193 return (sp_cmdmap[byteoffs] & (1 << bitoffs)) ? 1 : 0;
194}
195
196static int sp_automatic_cmdcheck(uint8_t cmd)
197{
198 if ((sp_check_avail_automatic) && (sp_check_commandavail(cmd) == 0)) {
stefanctd9ac2212011-10-22 21:45:27 +0000199 msg_pdbg("Warning: Automatic command availability check failed "
200 "for cmd 0x%x - won't execute cmd\n", cmd);
hailfingerbacbc8b2009-07-21 13:02:59 +0000201 return 1;
202 }
203 return 0;
204}
205
206static int sp_docommand(uint8_t command, uint32_t parmlen,
stefanctd9ac2212011-10-22 21:45:27 +0000207 uint8_t *params, uint32_t retlen, void *retparms)
hailfingerbacbc8b2009-07-21 13:02:59 +0000208{
hailfingerbacbc8b2009-07-21 13:02:59 +0000209 unsigned char c;
210 if (sp_automatic_cmdcheck(command))
211 return 1;
stefanctd9ac2212011-10-22 21:45:27 +0000212 if (write(sp_fd, &command, 1) != 1)
213 sp_die("Error: cannot write op code");
214 if (write(sp_fd, params, parmlen) != (parmlen))
215 sp_die("Error: cannot write parameters");
hailfingerbacbc8b2009-07-21 13:02:59 +0000216 if (read(sp_fd, &c, 1) != 1)
217 sp_die("Error: cannot read from device");
stefanctd9ac2212011-10-22 21:45:27 +0000218 if (c == S_NAK)
219 return 1;
hailfingerbacbc8b2009-07-21 13:02:59 +0000220 if (c != S_ACK) {
snelson0afd28b2010-01-10 01:06:23 +0000221 msg_perr("Error: invalid response 0x%02X from device\n",c);
hailfingerbacbc8b2009-07-21 13:02:59 +0000222 exit(1);
223 }
224 if (retlen) {
225 int rd_bytes = 0;
226 do {
227 int r;
228 r = read(sp_fd, retparms + rd_bytes,
229 retlen - rd_bytes);
stefanctd9ac2212011-10-22 21:45:27 +0000230 if (r <= 0)
231 sp_die("Error: cannot read return parameters");
hailfingerbacbc8b2009-07-21 13:02:59 +0000232 rd_bytes += r;
233 } while (rd_bytes != retlen);
234 }
235 return 0;
236}
237
238static void sp_flush_stream(void)
239{
240 if (sp_streamed_transmit_ops)
241 do {
242 unsigned char c;
243 if (read(sp_fd, &c, 1) != 1) {
snelson0afd28b2010-01-10 01:06:23 +0000244 sp_die("Error: cannot read from device (flushing stream)");
hailfingerbacbc8b2009-07-21 13:02:59 +0000245 }
246 if (c == S_NAK) {
snelson0afd28b2010-01-10 01:06:23 +0000247 msg_perr("Error: NAK to a stream buffer operation\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000248 exit(1);
249 }
250 if (c != S_ACK) {
snelson0afd28b2010-01-10 01:06:23 +0000251 msg_perr("Error: Invalid reply 0x%02X from device\n", c);
hailfingerbacbc8b2009-07-21 13:02:59 +0000252 exit(1);
253 }
254 } while (--sp_streamed_transmit_ops);
255 sp_streamed_transmit_ops = 0;
256 sp_streamed_transmit_bytes = 0;
257}
258
259static int sp_stream_buffer_op(uint8_t cmd, uint32_t parmlen, uint8_t * parms)
260{
261 uint8_t *sp;
262 if (sp_automatic_cmdcheck(cmd))
263 return 1;
264 sp = malloc(1 + parmlen);
265 if (!sp) sp_die("Error: cannot malloc command buffer");
266 sp[0] = cmd;
267 memcpy(&(sp[1]), parms, parmlen);
268 if (sp_streamed_transmit_bytes >= (1 + parmlen + sp_device_serbuf_size))
269 sp_flush_stream();
270 if (write(sp_fd, sp, 1 + parmlen) != (1 + parmlen))
271 sp_die("Error: cannot write command");
272 free(sp);
273 sp_streamed_transmit_ops += 1;
274 sp_streamed_transmit_bytes += 1 + parmlen;
275 return 0;
276}
277
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700278static int serprog_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
hailfinger76bb7e92011-11-09 23:40:00 +0000279 const unsigned char *writearr,
280 unsigned char *readarr);
Patrick Georgif4f1e2f2017-03-10 17:38:40 +0100281static struct spi_master spi_master_serprog = {
stefanct69965b62011-09-15 23:38:14 +0000282 .type = SPI_CONTROLLER_SERPROG,
Edward O'Callaghana6673bd2019-06-24 15:22:28 +1000283 .features = SPI_MASTER_4BA,
stefanct69965b62011-09-15 23:38:14 +0000284 .max_data_read = MAX_DATA_READ_UNLIMITED,
285 .max_data_write = MAX_DATA_WRITE_UNLIMITED,
286 .command = serprog_spi_send_command,
287 .multicommand = default_spi_send_multicommand,
Edward O'Callaghand825ac02019-07-26 21:36:16 +1000288 .read = default_spi_read,
stefanct69965b62011-09-15 23:38:14 +0000289 .write_256 = default_spi_write_256,
290};
291
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700292static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
293 chipaddr addr);
294static uint8_t serprog_chip_readb(const struct flashctx *flash,
295 const chipaddr addr);
296static void serprog_chip_readn(const struct flashctx *flash, uint8_t *buf,
297 const chipaddr addr, size_t len);
298
Patrick Georgi0a9533a2017-02-03 19:28:38 +0100299static const struct par_master par_master_serprog = {
hailfinger76bb7e92011-11-09 23:40:00 +0000300 .chip_readb = serprog_chip_readb,
301 .chip_readw = fallback_chip_readw,
302 .chip_readl = fallback_chip_readl,
303 .chip_readn = serprog_chip_readn,
304 .chip_writeb = serprog_chip_writeb,
305 .chip_writew = fallback_chip_writew,
306 .chip_writel = fallback_chip_writel,
307 .chip_writen = fallback_chip_writen,
308};
309
310static enum chipbustype serprog_buses_supported = BUS_NONE;
311
David Hendricksac1d25c2016-08-09 17:00:58 -0700312int serprog_init(void)
hailfingerbacbc8b2009-07-21 13:02:59 +0000313{
314 uint16_t iface;
hailfingerbacbc8b2009-07-21 13:02:59 +0000315 unsigned char pgmname[17];
316 unsigned char rbuf[3];
317 unsigned char c;
hailfinger1ef766d2010-07-06 09:55:48 +0000318 char *device;
319 char *baudport;
320 int have_device = 0;
hailfingerbacbc8b2009-07-21 13:02:59 +0000321
hailfinger1ef766d2010-07-06 09:55:48 +0000322 /* the parameter is either of format "dev=/dev/device:baud" or "ip=ip:port" */
hailfingerddeb4ac2010-07-08 10:13:37 +0000323 device = extract_programmer_param("dev");
hailfinger1ef766d2010-07-06 09:55:48 +0000324 if (device && strlen(device)) {
325 baudport = strstr(device, ":");
326 if (baudport) {
327 /* Split device from baudrate. */
328 *baudport = '\0';
329 baudport++;
330 }
331 if (!baudport || !strlen(baudport)) {
332 msg_perr("Error: No baudrate specified.\n"
333 "Use flashrom -p serprog:dev=/dev/device:baud\n");
334 free(device);
stefanct69965b62011-09-15 23:38:14 +0000335 return 1;
hailfinger1ef766d2010-07-06 09:55:48 +0000336 }
337 if (strlen(device)) {
338 sp_fd = sp_openserport(device, atoi(baudport));
339 have_device++;
340 }
341 }
342 if (device && !strlen(device)) {
343 msg_perr("Error: No device specified.\n"
344 "Use flashrom -p serprog:dev=/dev/device:baud\n");
345 free(device);
346 return 1;
347 }
348 free(device);
hailfingerbacbc8b2009-07-21 13:02:59 +0000349
hailfingerddeb4ac2010-07-08 10:13:37 +0000350 device = extract_programmer_param("ip");
hailfinger1ef766d2010-07-06 09:55:48 +0000351 if (have_device && device) {
352 msg_perr("Error: Both host and device specified.\n"
353 "Please use either dev= or ip= but not both.\n");
354 free(device);
355 return 1;
356 }
357 if (device && strlen(device)) {
358 baudport = strstr(device, ":");
359 if (baudport) {
360 /* Split host from port. */
361 *baudport = '\0';
362 baudport++;
363 }
364 if (!baudport || !strlen(baudport)) {
365 msg_perr("Error: No port specified.\n"
366 "Use flashrom -p serprog:ip=ipaddr:port\n");
367 free(device);
stefanct69965b62011-09-15 23:38:14 +0000368 return 1;
hailfinger1ef766d2010-07-06 09:55:48 +0000369 }
370 if (strlen(device)) {
371 sp_fd = sp_opensocket(device, atoi(baudport));
372 have_device++;
373 }
374 }
375 if (device && !strlen(device)) {
376 msg_perr("Error: No host specified.\n"
377 "Use flashrom -p serprog:ip=ipaddr:port\n");
378 free(device);
379 return 1;
380 }
381 free(device);
382
383 if (!have_device) {
384 msg_perr("Error: Neither host nor device specified.\n"
385 "Use flashrom -p serprog:dev=/dev/device:baud or "
386 "flashrom -p serprog:ip=ipaddr:port\n");
387 return 1;
388 }
hailfingerbacbc8b2009-07-21 13:02:59 +0000389
dhendrix0ffc2eb2011-06-14 01:35:36 +0000390 if (register_shutdown(serprog_shutdown, NULL))
391 return 1;
392
snelson0afd28b2010-01-10 01:06:23 +0000393 msg_pdbg(MSGHEADER "connected - attempting to synchronize\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000394
395 sp_check_avail_automatic = 0;
396
397 sp_synchronize();
398
snelson0afd28b2010-01-10 01:06:23 +0000399 msg_pdbg(MSGHEADER "Synchronized\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000400
401 if (sp_docommand(S_CMD_Q_IFACE, 0, NULL, 2, &iface)) {
stefanctd9ac2212011-10-22 21:45:27 +0000402 msg_perr("Error: NAK to query interface version\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000403 return 1;
hailfingerbacbc8b2009-07-21 13:02:59 +0000404 }
405
406 if (iface != 1) {
stefanctd9ac2212011-10-22 21:45:27 +0000407 msg_perr("Error: Unknown interface version: %d\n", iface);
hailfinger76bb7e92011-11-09 23:40:00 +0000408 return 1;
hailfingerbacbc8b2009-07-21 13:02:59 +0000409 }
410
snelson0afd28b2010-01-10 01:06:23 +0000411 msg_pdbg(MSGHEADER "Interface version ok.\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000412
413 if (sp_docommand(S_CMD_Q_CMDMAP, 0, NULL, 32, sp_cmdmap)) {
snelson0afd28b2010-01-10 01:06:23 +0000414 msg_perr("Error: query command map not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000415 return 1;
hailfingerbacbc8b2009-07-21 13:02:59 +0000416 }
417
418 sp_check_avail_automatic = 1;
419
hailfinger76bb7e92011-11-09 23:40:00 +0000420 /* FIXME: This assumes that serprog device bustypes are always
421 * identical with flashrom bustype enums and that they all fit
422 * in a single byte.
423 */
stefanct69965b62011-09-15 23:38:14 +0000424 if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) {
425 msg_perr("Warning: NAK to query supported buses\n");
426 c = BUS_NONSPI; /* A reasonable default for now. */
hailfingerbacbc8b2009-07-21 13:02:59 +0000427 }
hailfinger76bb7e92011-11-09 23:40:00 +0000428 serprog_buses_supported = c;
429
stefanctd9ac2212011-10-22 21:45:27 +0000430 msg_pdbg(MSGHEADER "Bus support: parallel=%s, LPC=%s, FWH=%s, SPI=%s\n",
431 (c & BUS_PARALLEL) ? "on" : "off",
432 (c & BUS_LPC) ? "on" : "off",
433 (c & BUS_FWH) ? "on" : "off",
434 (c & BUS_SPI) ? "on" : "off");
stefanct69965b62011-09-15 23:38:14 +0000435 /* Check for the minimum operational set of commands. */
hailfinger76bb7e92011-11-09 23:40:00 +0000436 if (serprog_buses_supported & BUS_SPI) {
stefanct69965b62011-09-15 23:38:14 +0000437 uint8_t bt = BUS_SPI;
438 if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
439 msg_perr("Error: SPI operation not supported while the "
440 "bustype is SPI\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000441 return 1;
stefanct69965b62011-09-15 23:38:14 +0000442 }
443 /* Success of any of these commands is optional. We don't need
444 the programmer to tell us its limits, but if it doesn't, we
445 will assume stuff, so it's in the programmers best interest
446 to tell us. */
447 sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL);
448 if (!sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
449 uint32_t v;
450 v = ((unsigned int)(rbuf[0]) << 0);
451 v |= ((unsigned int)(rbuf[1]) << 8);
452 v |= ((unsigned int)(rbuf[2]) << 16);
453 if (v == 0)
454 v = (1 << 24) - 1; /* SPI-op maximum. */
Patrick Georgif4f1e2f2017-03-10 17:38:40 +0100455 spi_master_serprog.max_data_write = v;
stefanct69965b62011-09-15 23:38:14 +0000456 msg_pdbg(MSGHEADER "Maximum write-n length is %d\n", v);
457 }
458 if (!sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf)) {
459 uint32_t v;
460 v = ((unsigned int)(rbuf[0]) << 0);
461 v |= ((unsigned int)(rbuf[1]) << 8);
462 v |= ((unsigned int)(rbuf[2]) << 16);
463 if (v == 0)
464 v = (1 << 24) - 1; /* SPI-op maximum. */
Patrick Georgif4f1e2f2017-03-10 17:38:40 +0100465 spi_master_serprog.max_data_read = v;
stefanct69965b62011-09-15 23:38:14 +0000466 msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
467 }
hailfinger76bb7e92011-11-09 23:40:00 +0000468 bt = serprog_buses_supported;
stefanct69965b62011-09-15 23:38:14 +0000469 sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL);
hailfingerbacbc8b2009-07-21 13:02:59 +0000470 }
stefanct69965b62011-09-15 23:38:14 +0000471
hailfinger76bb7e92011-11-09 23:40:00 +0000472 if (serprog_buses_supported & BUS_NONSPI) {
stefanct69965b62011-09-15 23:38:14 +0000473 if (sp_check_commandavail(S_CMD_O_INIT) == 0) {
474 msg_perr("Error: Initialize operation buffer "
475 "not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000476 return 1;
stefanct69965b62011-09-15 23:38:14 +0000477 }
478
479 if (sp_check_commandavail(S_CMD_O_DELAY) == 0) {
480 msg_perr("Error: Write to opbuf: "
481 "delay not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000482 return 1;
stefanct69965b62011-09-15 23:38:14 +0000483 }
484
485 /* S_CMD_O_EXEC availability checked later. */
486
487 if (sp_check_commandavail(S_CMD_R_BYTE) == 0) {
488 msg_perr("Error: Single byte read not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000489 return 1;
stefanct69965b62011-09-15 23:38:14 +0000490 }
491 /* This could be translated to single byte reads (if missing),
492 * but now we don't support that. */
493 if (sp_check_commandavail(S_CMD_R_NBYTES) == 0) {
494 msg_perr("Error: Read n bytes not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000495 return 1;
stefanct69965b62011-09-15 23:38:14 +0000496 }
497 if (sp_check_commandavail(S_CMD_O_WRITEB) == 0) {
498 msg_perr("Error: Write to opbuf: "
499 "write byte not supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000500 return 1;
stefanct69965b62011-09-15 23:38:14 +0000501 }
502
503 if (sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
504 msg_pdbg(MSGHEADER "Write-n not supported");
505 sp_max_write_n = 0;
506 } else {
507 sp_max_write_n = ((unsigned int)(rbuf[0]) << 0);
508 sp_max_write_n |= ((unsigned int)(rbuf[1]) << 8);
509 sp_max_write_n |= ((unsigned int)(rbuf[2]) << 16);
510 if (!sp_max_write_n) {
511 sp_max_write_n = (1 << 24);
512 }
513 msg_pdbg(MSGHEADER "Maximum write-n length is %d\n",
514 sp_max_write_n);
515 sp_write_n_buf = malloc(sp_max_write_n);
516 if (!sp_write_n_buf) {
517 msg_perr("Error: cannot allocate memory for "
518 "Write-n buffer\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000519 return 1;
stefanct69965b62011-09-15 23:38:14 +0000520 }
521 sp_write_n_bytes = 0;
522 }
523
524 if (sp_check_commandavail(S_CMD_Q_RDNMAXLEN) &&
525 (sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf) == 0)) {
526 sp_max_read_n = ((unsigned int)(rbuf[0]) << 0);
527 sp_max_read_n |= ((unsigned int)(rbuf[1]) << 8);
528 sp_max_read_n |= ((unsigned int)(rbuf[2]) << 16);
529 msg_pdbg(MSGHEADER "Maximum read-n length is %d\n",
530 sp_max_read_n ? sp_max_read_n : (1 << 24));
531 } else {
532 msg_pdbg(MSGHEADER "Maximum read-n length "
533 "not reported\n");
534 sp_max_read_n = 0;
535 }
536
hailfingerbacbc8b2009-07-21 13:02:59 +0000537 }
538
539 if (sp_docommand(S_CMD_Q_PGMNAME, 0, NULL, 16, pgmname)) {
snelson0afd28b2010-01-10 01:06:23 +0000540 msg_perr("Warning: NAK to query programmer name\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000541 strcpy((char *)pgmname, "(unknown)");
542 }
543 pgmname[16] = 0;
stefanctd9ac2212011-10-22 21:45:27 +0000544 msg_pinfo(MSGHEADER "Programmer name is \"%s\"\n", pgmname);
hailfingerbacbc8b2009-07-21 13:02:59 +0000545
546 if (sp_docommand(S_CMD_Q_SERBUF, 0, NULL, 2, &sp_device_serbuf_size)) {
snelson0afd28b2010-01-10 01:06:23 +0000547 msg_perr("Warning: NAK to query serial buffer size\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000548 }
stefanctd9ac2212011-10-22 21:45:27 +0000549 msg_pdbg(MSGHEADER "Serial buffer size is %d\n",
hailfingerbacbc8b2009-07-21 13:02:59 +0000550 sp_device_serbuf_size);
551
stefanct69965b62011-09-15 23:38:14 +0000552 if (sp_check_commandavail(S_CMD_O_INIT)) {
553 /* This would be inconsistent. */
554 if (sp_check_commandavail(S_CMD_O_EXEC) == 0) {
555 msg_perr("Error: Execute operation buffer not "
556 "supported\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000557 return 1;
hailfingerbacbc8b2009-07-21 13:02:59 +0000558 }
stefanct69965b62011-09-15 23:38:14 +0000559
560 if (sp_docommand(S_CMD_O_INIT, 0, NULL, 0, NULL)) {
561 msg_perr("Error: NAK to initialize operation buffer\n");
hailfinger76bb7e92011-11-09 23:40:00 +0000562 return 1;
stefanct69965b62011-09-15 23:38:14 +0000563 }
564
565 if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2,
566 &sp_device_opbuf_size)) {
567 msg_perr("Warning: NAK to query operation buffer "
568 "size\n");
569 }
stefanctd9ac2212011-10-22 21:45:27 +0000570 msg_pdbg(MSGHEADER "operation buffer size is %d\n",
stefanct69965b62011-09-15 23:38:14 +0000571 sp_device_opbuf_size);
572 }
hailfingerbacbc8b2009-07-21 13:02:59 +0000573
574 sp_prev_was_write = 0;
575 sp_streamed_transmit_ops = 0;
576 sp_streamed_transmit_bytes = 0;
577 sp_opbuf_usage = 0;
hailfinger76bb7e92011-11-09 23:40:00 +0000578 if (serprog_buses_supported & BUS_SPI)
Patrick Georgif4f1e2f2017-03-10 17:38:40 +0100579 register_spi_master(&spi_master_serprog);
hailfinger76bb7e92011-11-09 23:40:00 +0000580 if (serprog_buses_supported & BUS_NONSPI)
Patrick Georgi0a9533a2017-02-03 19:28:38 +0100581 register_par_master(&par_master_serprog,
hailfinger76bb7e92011-11-09 23:40:00 +0000582 serprog_buses_supported & BUS_NONSPI);
hailfingerbacbc8b2009-07-21 13:02:59 +0000583 return 0;
584}
585
586/* Move an in flashrom buffer existing write-n operation to *
587 * the on-device operation buffer. */
588static void sp_pass_writen(void)
589{
590 unsigned char header[7];
snelson0afd28b2010-01-10 01:06:23 +0000591 msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n",
stefanctd9ac2212011-10-22 21:45:27 +0000592 sp_write_n_bytes, sp_write_n_addr);
hailfingerbacbc8b2009-07-21 13:02:59 +0000593 if (sp_streamed_transmit_bytes >=
594 (7 + sp_write_n_bytes + sp_device_serbuf_size))
595 sp_flush_stream();
596 /* In case it's just a single byte send it as a single write. */
597 if (sp_write_n_bytes == 1) {
598 sp_write_n_bytes = 0;
599 header[0] = (sp_write_n_addr >> 0) & 0xFF;
600 header[1] = (sp_write_n_addr >> 8) & 0xFF;
601 header[2] = (sp_write_n_addr >> 16) & 0xFF;
602 header[3] = sp_write_n_buf[0];
603 sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header);
604 sp_opbuf_usage += 5;
605 return;
606 }
607 header[0] = S_CMD_O_WRITEN;
608 header[1] = (sp_write_n_bytes >> 0) & 0xFF;
609 header[2] = (sp_write_n_bytes >> 8) & 0xFF;
610 header[3] = (sp_write_n_bytes >> 16) & 0xFF;
611 header[4] = (sp_write_n_addr >> 0) & 0xFF;
612 header[5] = (sp_write_n_addr >> 8) & 0xFF;
613 header[6] = (sp_write_n_addr >> 16) & 0xFF;
614 if (write(sp_fd, header, 7) != 7)
615 sp_die("Error: cannot write write-n command\n");
616 if (write(sp_fd, sp_write_n_buf, sp_write_n_bytes) !=
617 sp_write_n_bytes)
618 sp_die("Error: cannot write write-n data");
619 sp_streamed_transmit_bytes += 7 + sp_write_n_bytes;
620 sp_streamed_transmit_ops += 1;
621 sp_opbuf_usage += 7 + sp_write_n_bytes;
622 sp_write_n_bytes = 0;
623 sp_prev_was_write = 0;
624}
625
626static void sp_execute_opbuf_noflush(void)
627{
628 if ((sp_max_write_n) && (sp_write_n_bytes))
629 sp_pass_writen();
stepand0d220f2011-01-24 19:15:51 +0000630 sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL);
snelson0afd28b2010-01-10 01:06:23 +0000631 msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n",
hailfingerbacbc8b2009-07-21 13:02:59 +0000632 sp_opbuf_usage);
633 sp_opbuf_usage = 0;
634 sp_prev_was_write = 0;
635 return;
636}
637
638static void sp_execute_opbuf(void)
639{
640 sp_execute_opbuf_noflush();
641 sp_flush_stream();
642}
643
David Hendricks93784b42016-08-09 17:00:38 -0700644static int serprog_shutdown(void *data)
hailfingerbacbc8b2009-07-21 13:02:59 +0000645{
snelson0afd28b2010-01-10 01:06:23 +0000646 msg_pspew("%s\n", __func__);
hailfingerbacbc8b2009-07-21 13:02:59 +0000647 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
648 sp_execute_opbuf();
649 close(sp_fd);
650 if (sp_max_write_n)
651 free(sp_write_n_buf);
652 return 0;
653}
654
655static void sp_check_opbuf_usage(int bytes_to_be_added)
656{
657 if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) {
658 sp_execute_opbuf();
659 /* If this happens in the mid of an page load the page load *
uwe3a3ab2f2010-03-25 23:18:41 +0000660 * will probably fail. */
snelson0afd28b2010-01-10 01:06:23 +0000661 msg_pdbg(MSGHEADER "Warning: executed operation buffer due to size reasons\n");
hailfingerbacbc8b2009-07-21 13:02:59 +0000662 }
663}
664
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700665void serprog_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
hailfingerbacbc8b2009-07-21 13:02:59 +0000666{
snelson0afd28b2010-01-10 01:06:23 +0000667 msg_pspew("%s\n", __func__);
hailfingerbacbc8b2009-07-21 13:02:59 +0000668 if (sp_max_write_n) {
669 if ((sp_prev_was_write)
670 && (addr == (sp_write_n_addr + sp_write_n_bytes))) {
671 sp_write_n_buf[sp_write_n_bytes++] = val;
672 } else {
673 if ((sp_prev_was_write) && (sp_write_n_bytes))
674 sp_pass_writen();
675 sp_prev_was_write = 1;
676 sp_write_n_addr = addr;
677 sp_write_n_bytes = 1;
678 sp_write_n_buf[0] = val;
679 }
680 sp_check_opbuf_usage(7 + sp_write_n_bytes);
681 if (sp_write_n_bytes >= sp_max_write_n)
682 sp_pass_writen();
683 } else {
684 /* We will have to do single writeb ops. */
685 unsigned char writeb_parm[4];
686 sp_check_opbuf_usage(6);
687 writeb_parm[0] = (addr >> 0) & 0xFF;
688 writeb_parm[1] = (addr >> 8) & 0xFF;
689 writeb_parm[2] = (addr >> 16) & 0xFF;
690 writeb_parm[3] = val;
691 sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm);
692 sp_opbuf_usage += 5;
693 }
694}
695
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700696uint8_t serprog_chip_readb(const struct flashctx *flash, const chipaddr addr)
hailfingerbacbc8b2009-07-21 13:02:59 +0000697{
698 unsigned char c;
699 unsigned char buf[3];
700 /* Will stream the read operation - eg. add it to the stream buffer, *
701 * then flush the buffer, then read the read answer. */
702 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
703 sp_execute_opbuf_noflush();
704 buf[0] = ((addr >> 0) & 0xFF);
705 buf[1] = ((addr >> 8) & 0xFF);
706 buf[2] = ((addr >> 16) & 0xFF);
707 sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf);
708 sp_flush_stream();
709 if (read(sp_fd, &c, 1) != 1)
710 sp_die("readb byteread");
snelson0afd28b2010-01-10 01:06:23 +0000711 msg_pspew("%s addr=0x%lx returning 0x%02X\n", __func__, addr, c);
hailfingerbacbc8b2009-07-21 13:02:59 +0000712 return c;
713}
714
uwe3a3ab2f2010-03-25 23:18:41 +0000715/* Local version that really does the job, doesn't care of max_read_n. */
hailfingerbacbc8b2009-07-21 13:02:59 +0000716static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
717{
718 int rd_bytes = 0;
719 unsigned char sbuf[6];
snelson0afd28b2010-01-10 01:06:23 +0000720 msg_pspew("%s: addr=0x%lx len=%lu\n", __func__, addr, (unsigned long)len);
hailfingerbacbc8b2009-07-21 13:02:59 +0000721 /* Stream the read-n -- as above. */
722 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
723 sp_execute_opbuf_noflush();
724 sbuf[0] = ((addr >> 0) & 0xFF);
725 sbuf[1] = ((addr >> 8) & 0xFF);
726 sbuf[2] = ((addr >> 16) & 0xFF);
727 sbuf[3] = ((len >> 0) & 0xFF);
728 sbuf[4] = ((len >> 8) & 0xFF);
729 sbuf[5] = ((len >> 16) & 0xFF);
730 sp_stream_buffer_op(S_CMD_R_NBYTES, 6, sbuf);
731 sp_flush_stream();
732 do {
733 int r = read(sp_fd, buf + rd_bytes, len - rd_bytes);
734 if (r <= 0)
735 sp_die("Error: cannot read read-n data");
736 rd_bytes += r;
737 } while (rd_bytes != len);
738 return;
739}
740
741/* The externally called version that makes sure that max_read_n is obeyed. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700742void serprog_chip_readn(const struct flashctx *flash, uint8_t * buf, const chipaddr addr, size_t len)
hailfingerbacbc8b2009-07-21 13:02:59 +0000743{
744 size_t lenm = len;
745 chipaddr addrm = addr;
stefanctd9ac2212011-10-22 21:45:27 +0000746 while ((sp_max_read_n != 0) && (lenm > sp_max_read_n)) {
747 sp_do_read_n(&(buf[addrm-addr]), addrm, sp_max_read_n);
hailfingerbacbc8b2009-07-21 13:02:59 +0000748 addrm += sp_max_read_n;
749 lenm -= sp_max_read_n;
750 }
stefanctd9ac2212011-10-22 21:45:27 +0000751 if (lenm)
752 sp_do_read_n(&(buf[addrm-addr]), addrm, lenm);
hailfingerbacbc8b2009-07-21 13:02:59 +0000753}
754
stefanctd9ac2212011-10-22 21:45:27 +0000755void serprog_delay(int usecs)
hailfingerbacbc8b2009-07-21 13:02:59 +0000756{
757 unsigned char buf[4];
stefanctd9ac2212011-10-22 21:45:27 +0000758 msg_pspew("%s usecs=%d\n", __func__, usecs);
stefanct69965b62011-09-15 23:38:14 +0000759 if (!sp_check_commandavail(S_CMD_O_DELAY)) {
stefanct69965b62011-09-15 23:38:14 +0000760 msg_pdbg("Note: serprog_delay used, but the programmer doesn't "
761 "support delay\n");
stefanctd9ac2212011-10-22 21:45:27 +0000762 internal_delay(usecs);
stefanct69965b62011-09-15 23:38:14 +0000763 return;
764 }
hailfingerbacbc8b2009-07-21 13:02:59 +0000765 if ((sp_max_write_n) && (sp_write_n_bytes))
766 sp_pass_writen();
767 sp_check_opbuf_usage(5);
stefanctd9ac2212011-10-22 21:45:27 +0000768 buf[0] = ((usecs >> 0) & 0xFF);
769 buf[1] = ((usecs >> 8) & 0xFF);
770 buf[2] = ((usecs >> 16) & 0xFF);
771 buf[3] = ((usecs >> 24) & 0xFF);
hailfingerbacbc8b2009-07-21 13:02:59 +0000772 sp_stream_buffer_op(S_CMD_O_DELAY, 4, buf);
773 sp_opbuf_usage += 5;
774 sp_prev_was_write = 0;
775}
stefanct69965b62011-09-15 23:38:14 +0000776
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700777static int serprog_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
stefanct69965b62011-09-15 23:38:14 +0000778 const unsigned char *writearr,
779 unsigned char *readarr)
780{
781 unsigned char *parmbuf;
782 int ret;
783 msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
784 if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
785 sp_execute_opbuf();
786 parmbuf = malloc(writecnt + 6);
787 if (!parmbuf)
788 sp_die("Error: cannot malloc SPI send param buffer");
789 parmbuf[0] = (writecnt >> 0) & 0xFF;
790 parmbuf[1] = (writecnt >> 8) & 0xFF;
791 parmbuf[2] = (writecnt >> 16) & 0xFF;
792 parmbuf[3] = (readcnt >> 0) & 0xFF;
793 parmbuf[4] = (readcnt >> 8) & 0xFF;
794 parmbuf[5] = (readcnt >> 16) & 0xFF;
795 memcpy(parmbuf + 6, writearr, writecnt);
796 ret = sp_docommand(S_CMD_O_SPIOP, writecnt + 6, parmbuf, readcnt,
797 readarr);
798 free(parmbuf);
799 return ret;
800}