flashrom 

flashrom Svn Source Tree

Root/trunk/serprog.c

1/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2009, 2011 Urja Rannikko <urjaman@gmail.com>
5 * 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
22#include "platform.h"
23
24#include <stdio.h>
25#if ! IS_WINDOWS /* stuff (presumably) needed for sockets only */
26#include <stdlib.h>
27#include <unistd.h>
28#include <fcntl.h>
29#include <sys/socket.h>
30#include <arpa/inet.h>
31#include <netinet/in.h>
32#include <netinet/tcp.h>
33#include <netdb.h>
34#endif
35#if IS_WINDOWS
36#include <conio.h>
37#else
38#include <termios.h>
39#endif
40#include <string.h>
41#include <errno.h>
42#include "flash.h"
43#include "programmer.h"
44#include "chipdrivers.h"
45#include "serprog.h"
46
47#define MSGHEADER "serprog: "
48
49/*
50 * FIXME: This prototype was added to help reduce diffs for the shutdown
51 * registration patch, which shifted many lines of code to place
52 * serprog_shutdown() before serprog_init(). It should be removed soon.
53 */
54static int serprog_shutdown(void *data);
55
56static uint16_t sp_device_serbuf_size = 16;
57static uint16_t sp_device_opbuf_size = 300;
58/* Bitmap of supported commands */
59static uint8_t sp_cmdmap[32];
60
61/* sp_prev_was_write used to detect writes with contiguous addresses
62and combine them to write-n's */
63static int sp_prev_was_write = 0;
64/* sp_write_n_addr used as the starting addr of the currently
65combined write-n operation */
66static uint32_t sp_write_n_addr;
67/* The maximum length of an write_n operation; 0 = write-n not supported */
68static uint32_t sp_max_write_n = 0;
69/* The maximum length of a read_n operation; 0 = 2^24 */
70static uint32_t sp_max_read_n = 0;
71
72/* A malloc'd buffer for combining the operation's data
73and a counter that tells how much data is there. */
74static uint8_t *sp_write_n_buf;
75static uint32_t sp_write_n_bytes = 0;
76
77/* sp_streamed_* used for flow control checking */
78static int sp_streamed_transmit_ops = 0;
79static int sp_streamed_transmit_bytes = 0;
80
81/* sp_opbuf_usage used for counting the amount of
82on-device operation buffer used */
83static int sp_opbuf_usage = 0;
84/* if true causes sp_docommand to automatically check
85whether the command is supported before doing it */
86static int sp_check_avail_automatic = 0;
87
88#if ! IS_WINDOWS
89static int sp_opensocket(char *ip, unsigned int port)
90{
91int flag = 1;
92struct hostent *hostPtr = NULL;
93union { struct sockaddr_in si; struct sockaddr s; } sp = {};
94int sock;
95msg_pdbg(MSGHEADER "IP %s port %d\n", ip, port);
96sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
97if (sock < 0) {
98msg_perr("Error: serprog cannot open socket: %s\n", strerror(errno));
99return -1;
100}
101hostPtr = gethostbyname(ip);
102if (NULL == hostPtr) {
103hostPtr = gethostbyaddr(ip, strlen(ip), AF_INET);
104if (NULL == hostPtr) {
105close(sock);
106msg_perr("Error: cannot resolve %s\n", ip);
107return -1;
108}
109}
110sp.si.sin_family = AF_INET;
111sp.si.sin_port = htons(port);
112(void)memcpy(&sp.si.sin_addr, hostPtr->h_addr_list[0], hostPtr->h_length);
113if (connect(sock, &sp.s, sizeof(sp.si)) < 0) {
114close(sock);
115msg_perr("Error: serprog cannot connect: %s\n", strerror(errno));
116return -1;
117}
118/* We are latency limited, and sometimes do write-write-read *
119 * (write-n) - so enable TCP_NODELAY.*/
120if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int))) {
121close(sock);
122msg_perr("Error: serprog cannot set socket options: %s\n", strerror(errno));
123return -1;
124}
125return sock;
126}
127#endif
128
129/* Synchronize: a bit tricky algorithm that tries to (and in my tests has *
130 * always succeeded in) bring the serial protocol to known waiting-for- *
131 * command state - uses nonblocking I/O - rest of the driver uses *
132 * blocking read - TODO: add an alarm() timer for the rest of the app on *
133 * serial operations, though not such a big issue as the first thing to *
134 * do is synchronize (eg. check that device is alive). */
135static int sp_synchronize(void)
136{
137int i;
138unsigned char buf[8];
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. */
142memset(buf, S_CMD_NOP, 8);
143if (serialport_write_nonblock(buf, 8, 1, NULL) != 0) {
144goto err_out;
145}
146/* A second should be enough to get all the answers to the buffer */
147internal_delay(1000 * 1000);
148sp_flush_incoming();
149
150/* Then try up to 8 times to send syncnop and get the correct special *
151 * return of NAK+ACK. Timing note: up to 10 characters, 10*50ms = *
152 * up to 500ms per try, 8*0.5s = 4s; +1s (above) = up to 5s sync *
153 * attempt, ~1s if immediate success. */
154for (i = 0; i < 8; i++) {
155int n;
156unsigned char c = S_CMD_SYNCNOP;
157if (serialport_write_nonblock(&c, 1, 1, NULL) != 0) {
158goto err_out;
159}
160msg_pdbg(".");
161fflush(stdout);
162for (n = 0; n < 10; n++) {
163int ret = serialport_read_nonblock(&c, 1, 50, NULL);
164if (ret < 0)
165goto err_out;
166if (ret > 0 || c != S_NAK)
167continue;
168ret = serialport_read_nonblock(&c, 1, 20, NULL);
169if (ret < 0)
170goto err_out;
171if (ret > 0 || c != S_ACK)
172continue;
173c = S_CMD_SYNCNOP;
174if (serialport_write_nonblock(&c, 1, 1, NULL) != 0) {
175goto err_out;
176}
177ret = serialport_read_nonblock(&c, 1, 500, NULL);
178if (ret < 0)
179goto err_out;
180if (ret > 0 || c != S_NAK)
181break;/* fail */
182ret = serialport_read_nonblock(&c, 1, 100, NULL);
183if (ret > 0 || ret < 0)
184goto err_out;
185if (c != S_ACK)
186break;/* fail */
187msg_pdbg("\n");
188return 0;
189}
190}
191err_out:
192msg_perr("Error: cannot synchronize protocol - check communications and reset device?\n");
193return 1;
194}
195
196static int sp_check_commandavail(uint8_t command)
197{
198int byteoffs, bitoffs;
199byteoffs = command / 8;
200bitoffs = command % 8;
201return (sp_cmdmap[byteoffs] & (1 << bitoffs)) ? 1 : 0;
202}
203
204static int sp_automatic_cmdcheck(uint8_t cmd)
205{
206if ((sp_check_avail_automatic) && (sp_check_commandavail(cmd) == 0)) {
207msg_pdbg("Warning: Automatic command availability check failed "
208 "for cmd 0x%02x - won't execute cmd\n", cmd);
209return 1;
210}
211return 0;
212}
213
214static int sp_docommand(uint8_t command, uint32_t parmlen,
215uint8_t *params, uint32_t retlen, void *retparms)
216{
217unsigned char c;
218if (sp_automatic_cmdcheck(command))
219return 1;
220if (serialport_write(&command, 1) != 0) {
221msg_perr("Error: cannot write op code: %s\n", strerror(errno));
222return 1;
223}
224if (serialport_write(params, parmlen) != 0) {
225msg_perr("Error: cannot write parameters: %s\n", strerror(errno));
226return 1;
227}
228if (serialport_read(&c, 1) != 0) {
229msg_perr("Error: cannot read from device: %s\n", strerror(errno));
230return 1;
231}
232if (c == S_NAK)
233return 1;
234if (c != S_ACK) {
235msg_perr("Error: invalid response 0x%02X from device (to command 0x%02X)\n", c, command);
236return 1;
237}
238if (retlen) {
239if (serialport_read(retparms, retlen) != 0) {
240msg_perr("Error: cannot read return parameters: %s\n", strerror(errno));
241return 1;
242}
243}
244return 0;
245}
246
247static int sp_flush_stream(void)
248{
249if (sp_streamed_transmit_ops)
250do {
251unsigned char c;
252if (serialport_read(&c, 1) != 0) {
253msg_perr("Error: cannot read from device (flushing stream)");
254return 1;
255}
256if (c == S_NAK) {
257msg_perr("Error: NAK to a stream buffer operation\n");
258return 1;
259}
260if (c != S_ACK) {
261msg_perr("Error: Invalid reply 0x%02X from device\n", c);
262return 1;
263}
264} while (--sp_streamed_transmit_ops);
265sp_streamed_transmit_ops = 0;
266sp_streamed_transmit_bytes = 0;
267return 0;
268}
269
270static int sp_stream_buffer_op(uint8_t cmd, uint32_t parmlen, uint8_t *parms)
271{
272uint8_t *sp;
273if (sp_automatic_cmdcheck(cmd))
274return 1;
275
276sp = malloc(1 + parmlen);
277if (!sp) {
278msg_perr("Error: cannot malloc command buffer\n");
279return 1;
280}
281sp[0] = cmd;
282memcpy(&(sp[1]), parms, parmlen);
283
284if (sp_streamed_transmit_bytes >= (1 + parmlen + sp_device_serbuf_size)) {
285if (sp_flush_stream() != 0) {
286free(sp);
287return 1;
288}
289}
290if (serialport_write(sp, 1 + parmlen) != 0) {
291msg_perr("Error: cannot write command\n");
292free(sp);
293return 1;
294}
295sp_streamed_transmit_ops += 1;
296sp_streamed_transmit_bytes += 1 + parmlen;
297
298free(sp);
299return 0;
300}
301
302static int serprog_spi_send_command(struct flashctx *flash,
303 unsigned int writecnt, unsigned int readcnt,
304 const unsigned char *writearr,
305 unsigned char *readarr);
306static int serprog_spi_read(struct flashctx *flash, uint8_t *buf,
307 unsigned int start, unsigned int len);
308static struct spi_master spi_master_serprog = {
309.type= SPI_CONTROLLER_SERPROG,
310.max_data_read= MAX_DATA_READ_UNLIMITED,
311.max_data_write= MAX_DATA_WRITE_UNLIMITED,
312.command= serprog_spi_send_command,
313.multicommand= default_spi_send_multicommand,
314.read= serprog_spi_read,
315.write_256= default_spi_write_256,
316.write_aai= default_spi_write_aai,
317};
318
319static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
320chipaddr addr);
321static uint8_t serprog_chip_readb(const struct flashctx *flash,
322 const chipaddr addr);
323static void serprog_chip_readn(const struct flashctx *flash, uint8_t *buf,
324 const chipaddr addr, size_t len);
325static const struct par_master par_master_serprog = {
326.chip_readb= serprog_chip_readb,
327.chip_readw= fallback_chip_readw,
328.chip_readl= fallback_chip_readl,
329.chip_readn= serprog_chip_readn,
330.chip_writeb= serprog_chip_writeb,
331.chip_writew= fallback_chip_writew,
332.chip_writel= fallback_chip_writel,
333.chip_writen= fallback_chip_writen,
334};
335
336static enum chipbustype serprog_buses_supported = BUS_NONE;
337
338int serprog_init(void)
339{
340uint16_t iface;
341unsigned char pgmname[17];
342unsigned char rbuf[3];
343unsigned char c;
344char *device;
345int have_device = 0;
346
347/* the parameter is either of format "dev=/dev/device[:baud]" or "ip=ip:port" */
348device = extract_programmer_param("dev");
349if (device && strlen(device)) {
350char *baud_str = strstr(device, ":");
351if (baud_str != NULL) {
352/* Split device from baudrate. */
353*baud_str = '\0';
354baud_str++;
355}
356int baud;
357/* Convert baud string to value.
358 * baud_str is either NULL (if strstr can't find the colon), points to the \0 after the colon
359 * if no characters where given after the colon, or a string to convert... */
360if (baud_str == NULL || *baud_str == '\0') {
361baud = -1;
362msg_pdbg("No baudrate specified, using the hardware's defaults.\n");
363} else
364baud = atoi(baud_str); // FIXME: replace atoi with strtoul
365if (strlen(device) > 0) {
366sp_fd = sp_openserport(device, baud);
367if (sp_fd == SER_INV_FD) {
368free(device);
369return 1;
370}
371have_device++;
372}
373}
374
375#if !IS_WINDOWS
376if (device && !strlen(device)) {
377msg_perr("Error: No device specified.\n"
378 "Use flashrom -p serprog:dev=/dev/device[:baud]\n");
379free(device);
380return 1;
381}
382free(device);
383
384device = extract_programmer_param("ip");
385if (have_device && device) {
386msg_perr("Error: Both host and device specified.\n"
387 "Please use either dev= or ip= but not both.\n");
388free(device);
389return 1;
390}
391if (device && strlen(device)) {
392char *port = strstr(device, ":");
393if (port != NULL) {
394/* Split host from port. */
395*port = '\0';
396port++;
397}
398if (!port || !strlen(port)) {
399msg_perr("Error: No port specified.\n"
400 "Use flashrom -p serprog:ip=ipaddr:port\n");
401free(device);
402return 1;
403}
404if (strlen(device)) {
405sp_fd = sp_opensocket(device, atoi(port)); // FIXME: replace atoi with strtoul
406if (sp_fd < 0) {
407free(device);
408return 1;
409}
410have_device++;
411}
412}
413if (device && !strlen(device)) {
414msg_perr("Error: No host specified.\n"
415 "Use flashrom -p serprog:ip=ipaddr:port\n");
416free(device);
417return 1;
418}
419#endif
420free(device);
421
422if (!have_device) {
423#if IS_WINDOWS
424msg_perr("Error: No device specified.\n"
425 "Use flashrom -p serprog:dev=comN[:baud]\n");
426#else
427msg_perr("Error: Neither host nor device specified.\n"
428 "Use flashrom -p serprog:dev=/dev/device:baud or "
429 "flashrom -p serprog:ip=ipaddr:port\n");
430#endif
431return 1;
432}
433
434if (register_shutdown(serprog_shutdown, NULL))
435return 1;
436
437msg_pdbg(MSGHEADER "connected - attempting to synchronize\n");
438
439sp_check_avail_automatic = 0;
440
441if (sp_synchronize())
442return 1;
443
444msg_pdbg(MSGHEADER "Synchronized\n");
445
446if (sp_docommand(S_CMD_Q_IFACE, 0, NULL, 2, &iface)) {
447msg_perr("Error: NAK to query interface version\n");
448return 1;
449}
450
451if (iface != 1) {
452msg_perr("Error: Unknown interface version: %d\n", iface);
453return 1;
454}
455
456msg_pdbg(MSGHEADER "Interface version ok.\n");
457
458if (sp_docommand(S_CMD_Q_CMDMAP, 0, NULL, 32, sp_cmdmap)) {
459msg_perr("Error: query command map not supported\n");
460return 1;
461}
462
463sp_check_avail_automatic = 1;
464
465/* FIXME: This assumes that serprog device bustypes are always
466 * identical with flashrom bustype enums and that they all fit
467 * in a single byte.
468 */
469if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) {
470msg_pwarn("Warning: NAK to query supported buses\n");
471c = BUS_NONSPI;/* A reasonable default for now. */
472}
473serprog_buses_supported = c;
474
475msg_pdbg(MSGHEADER "Bus support: parallel=%s, LPC=%s, FWH=%s, SPI=%s\n",
476 (c & BUS_PARALLEL) ? "on" : "off",
477 (c & BUS_LPC) ? "on" : "off",
478 (c & BUS_FWH) ? "on" : "off",
479 (c & BUS_SPI) ? "on" : "off");
480/* Check for the minimum operational set of commands. */
481if (serprog_buses_supported & BUS_SPI) {
482uint8_t bt = BUS_SPI;
483char *spispeed;
484if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
485msg_perr("Error: SPI operation not supported while the "
486 "bustype is SPI\n");
487return 1;
488}
489if (sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL))
490return 1;
491/* Success of any of these commands is optional. We don't need
492 the programmer to tell us its limits, but if it doesn't, we
493 will assume stuff, so it's in the programmers best interest
494 to tell us. */
495if (!sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
496uint32_t v;
497v = ((unsigned int)(rbuf[0]) << 0);
498v |= ((unsigned int)(rbuf[1]) << 8);
499v |= ((unsigned int)(rbuf[2]) << 16);
500if (v == 0)
501v = (1 << 24) - 1; /* SPI-op maximum. */
502spi_master_serprog.max_data_write = v;
503msg_pdbg(MSGHEADER "Maximum write-n length is %d\n", v);
504}
505if (!sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf)) {
506uint32_t v;
507v = ((unsigned int)(rbuf[0]) << 0);
508v |= ((unsigned int)(rbuf[1]) << 8);
509v |= ((unsigned int)(rbuf[2]) << 16);
510if (v == 0)
511v = (1 << 24) - 1; /* SPI-op maximum. */
512spi_master_serprog.max_data_read = v;
513msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
514}
515spispeed = extract_programmer_param("spispeed");
516if (spispeed && strlen(spispeed)) {
517uint32_t f_spi_req, f_spi;
518uint8_t buf[4];
519char *f_spi_suffix;
520
521errno = 0;
522f_spi_req = strtol(spispeed, &f_spi_suffix, 0);
523if (errno != 0 || spispeed == f_spi_suffix) {
524msg_perr("Error: Could not convert 'spispeed'.\n");
525free(spispeed);
526return 1;
527}
528if (strlen(f_spi_suffix) == 1) {
529if (!strcasecmp(f_spi_suffix, "M"))
530f_spi_req *= 1000000;
531else if (!strcasecmp(f_spi_suffix, "k"))
532f_spi_req *= 1000;
533else {
534msg_perr("Error: Garbage following 'spispeed' value.\n");
535free(spispeed);
536return 1;
537}
538} else if (strlen(f_spi_suffix) > 1) {
539msg_perr("Error: Garbage following 'spispeed' value.\n");
540free(spispeed);
541return 1;
542}
543
544buf[0] = (f_spi_req >> (0 * 8)) & 0xFF;
545buf[1] = (f_spi_req >> (1 * 8)) & 0xFF;
546buf[2] = (f_spi_req >> (2 * 8)) & 0xFF;
547buf[3] = (f_spi_req >> (3 * 8)) & 0xFF;
548
549if (sp_check_commandavail(S_CMD_S_SPI_FREQ) == 0)
550msg_pwarn(MSGHEADER "Warning: Setting the SPI clock rate is not supported!\n");
551else if (sp_docommand(S_CMD_S_SPI_FREQ, 4, buf, 4, buf) == 0) {
552f_spi = buf[0];
553f_spi |= buf[1] << (1 * 8);
554f_spi |= buf[2] << (2 * 8);
555f_spi |= buf[3] << (3 * 8);
556msg_pdbg(MSGHEADER "Requested to set SPI clock frequency to %u Hz. "
557 "It was actually set to %u Hz\n", f_spi_req, f_spi);
558} else
559msg_pwarn(MSGHEADER "Setting SPI clock rate to %u Hz failed!\n", f_spi_req);
560}
561free(spispeed);
562bt = serprog_buses_supported;
563if (sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL))
564return 1;
565}
566
567if (serprog_buses_supported & BUS_NONSPI) {
568if (sp_check_commandavail(S_CMD_O_INIT) == 0) {
569msg_perr("Error: Initialize operation buffer "
570 "not supported\n");
571return 1;
572}
573
574if (sp_check_commandavail(S_CMD_O_DELAY) == 0) {
575msg_perr("Error: Write to opbuf: "
576 "delay not supported\n");
577return 1;
578}
579
580/* S_CMD_O_EXEC availability checked later. */
581
582if (sp_check_commandavail(S_CMD_R_BYTE) == 0) {
583msg_perr("Error: Single byte read not supported\n");
584return 1;
585}
586/* This could be translated to single byte reads (if missing),
587 * but now we don't support that. */
588if (sp_check_commandavail(S_CMD_R_NBYTES) == 0) {
589msg_perr("Error: Read n bytes not supported\n");
590return 1;
591}
592if (sp_check_commandavail(S_CMD_O_WRITEB) == 0) {
593msg_perr("Error: Write to opbuf: "
594 "write byte not supported\n");
595return 1;
596}
597
598if (sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
599msg_pdbg(MSGHEADER "Write-n not supported");
600sp_max_write_n = 0;
601} else {
602sp_max_write_n = ((unsigned int)(rbuf[0]) << 0);
603sp_max_write_n |= ((unsigned int)(rbuf[1]) << 8);
604sp_max_write_n |= ((unsigned int)(rbuf[2]) << 16);
605if (!sp_max_write_n) {
606sp_max_write_n = (1 << 24);
607}
608msg_pdbg(MSGHEADER "Maximum write-n length is %d\n",
609 sp_max_write_n);
610sp_write_n_buf = malloc(sp_max_write_n);
611if (!sp_write_n_buf) {
612msg_perr("Error: cannot allocate memory for "
613 "Write-n buffer\n");
614return 1;
615}
616sp_write_n_bytes = 0;
617}
618
619if (sp_check_commandavail(S_CMD_Q_RDNMAXLEN) &&
620 (sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf) == 0)) {
621sp_max_read_n = ((unsigned int)(rbuf[0]) << 0);
622sp_max_read_n |= ((unsigned int)(rbuf[1]) << 8);
623sp_max_read_n |= ((unsigned int)(rbuf[2]) << 16);
624msg_pdbg(MSGHEADER "Maximum read-n length is %d\n",
625 sp_max_read_n ? sp_max_read_n : (1 << 24));
626} else {
627msg_pdbg(MSGHEADER "Maximum read-n length "
628 "not reported\n");
629sp_max_read_n = 0;
630}
631
632}
633
634if (sp_docommand(S_CMD_Q_PGMNAME, 0, NULL, 16, pgmname)) {
635msg_pwarn("Warning: NAK to query programmer name\n");
636strcpy((char *)pgmname, "(unknown)");
637}
638pgmname[16] = 0;
639msg_pinfo(MSGHEADER "Programmer name is \"%s\"\n", pgmname);
640
641if (sp_docommand(S_CMD_Q_SERBUF, 0, NULL, 2, &sp_device_serbuf_size)) {
642msg_pwarn("Warning: NAK to query serial buffer size\n");
643}
644msg_pdbg(MSGHEADER "Serial buffer size is %d\n",
645 sp_device_serbuf_size);
646
647if (sp_check_commandavail(S_CMD_O_INIT)) {
648/* This would be inconsistent. */
649if (sp_check_commandavail(S_CMD_O_EXEC) == 0) {
650msg_perr("Error: Execute operation buffer not "
651 "supported\n");
652return 1;
653}
654
655if (sp_docommand(S_CMD_O_INIT, 0, NULL, 0, NULL)) {
656msg_perr("Error: NAK to initialize operation buffer\n");
657return 1;
658}
659
660if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2,
661 &sp_device_opbuf_size)) {
662msg_pwarn("Warning: NAK to query operation buffer size\n");
663}
664msg_pdbg(MSGHEADER "operation buffer size is %d\n",
665 sp_device_opbuf_size);
666 }
667
668if (sp_check_commandavail(S_CMD_S_PIN_STATE)) {
669uint8_t en = 1;
670if (sp_docommand(S_CMD_S_PIN_STATE, 1, &en, 0, NULL) != 0) {
671msg_perr("Error: could not enable output buffers\n");
672return 1;
673} else
674msg_pdbg(MSGHEADER "Output drivers enabled\n");
675} else
676msg_pdbg(MSGHEADER "Warning: Programmer does not support toggling its output drivers\n");
677sp_prev_was_write = 0;
678sp_streamed_transmit_ops = 0;
679sp_streamed_transmit_bytes = 0;
680sp_opbuf_usage = 0;
681if (serprog_buses_supported & BUS_SPI)
682register_spi_master(&spi_master_serprog);
683if (serprog_buses_supported & BUS_NONSPI)
684register_par_master(&par_master_serprog, serprog_buses_supported & BUS_NONSPI);
685return 0;
686}
687
688/* Move an in flashrom buffer existing write-n operation to the on-device operation buffer. */
689static int sp_pass_writen(void)
690{
691unsigned char header[7];
692msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n", sp_write_n_bytes, sp_write_n_addr);
693if (sp_streamed_transmit_bytes >= (7 + sp_write_n_bytes + sp_device_serbuf_size)) {
694if (sp_flush_stream() != 0) {
695return 1;
696}
697}
698/* In case it's just a single byte send it as a single write. */
699if (sp_write_n_bytes == 1) {
700sp_write_n_bytes = 0;
701header[0] = (sp_write_n_addr >> 0) & 0xFF;
702header[1] = (sp_write_n_addr >> 8) & 0xFF;
703header[2] = (sp_write_n_addr >> 16) & 0xFF;
704header[3] = sp_write_n_buf[0];
705if (sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header) != 0)
706return 1;
707sp_opbuf_usage += 5;
708return 0;
709}
710header[0] = S_CMD_O_WRITEN;
711header[1] = (sp_write_n_bytes >> 0) & 0xFF;
712header[2] = (sp_write_n_bytes >> 8) & 0xFF;
713header[3] = (sp_write_n_bytes >> 16) & 0xFF;
714header[4] = (sp_write_n_addr >> 0) & 0xFF;
715header[5] = (sp_write_n_addr >> 8) & 0xFF;
716header[6] = (sp_write_n_addr >> 16) & 0xFF;
717if (serialport_write(header, 7) != 0) {
718msg_perr(MSGHEADER "Error: cannot write write-n command\n");
719return 1;
720}
721if (serialport_write(sp_write_n_buf, sp_write_n_bytes) != 0) {
722msg_perr(MSGHEADER "Error: cannot write write-n data");
723return 1;
724}
725sp_streamed_transmit_bytes += 7 + sp_write_n_bytes;
726sp_streamed_transmit_ops += 1;
727sp_opbuf_usage += 7 + sp_write_n_bytes;
728sp_write_n_bytes = 0;
729sp_prev_was_write = 0;
730return 0;
731}
732
733static int sp_execute_opbuf_noflush(void)
734{
735if ((sp_max_write_n) && (sp_write_n_bytes)) {
736if (sp_pass_writen() != 0) {
737msg_perr("Error: could not transfer write buffer\n");
738return 1;
739}
740}
741if (sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL) != 0) {
742msg_perr("Error: could not execute command buffer\n");
743return 1;
744}
745msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n", sp_opbuf_usage);
746sp_opbuf_usage = 0;
747sp_prev_was_write = 0;
748return 0;
749}
750
751static int sp_execute_opbuf(void)
752{
753if (sp_execute_opbuf_noflush() != 0)
754return 1;
755if (sp_flush_stream() != 0)
756return 1;
757
758return 0;
759}
760
761static int serprog_shutdown(void *data)
762{
763if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
764if (sp_execute_opbuf() != 0)
765msg_pwarn("Could not flush command buffer.\n");
766if (sp_check_commandavail(S_CMD_S_PIN_STATE)) {
767uint8_t dis = 0;
768if (sp_docommand(S_CMD_S_PIN_STATE, 1, &dis, 0, NULL) == 0)
769msg_pdbg(MSGHEADER "Output drivers disabled\n");
770else
771msg_pwarn(MSGHEADER "%s: Warning: could not disable output buffers\n", __func__);
772}
773/* FIXME: fix sockets on windows(?), especially closing */
774serialport_shutdown(&sp_fd);
775if (sp_max_write_n)
776free(sp_write_n_buf);
777return 0;
778}
779
780static int sp_check_opbuf_usage(int bytes_to_be_added)
781{
782if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) {
783/* If this happens in the middle of a page load the page load will probably fail. */
784msg_pwarn(MSGHEADER "Warning: executed operation buffer due to size reasons\n");
785if (sp_execute_opbuf() != 0)
786return 1;
787}
788return 0;
789}
790
791static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
792chipaddr addr)
793{
794msg_pspew("%s\n", __func__);
795if (sp_max_write_n) {
796if ((sp_prev_was_write)
797 && (addr == (sp_write_n_addr + sp_write_n_bytes))) {
798sp_write_n_buf[sp_write_n_bytes++] = val;
799} else {
800if ((sp_prev_was_write) && (sp_write_n_bytes))
801sp_pass_writen();
802sp_prev_was_write = 1;
803sp_write_n_addr = addr;
804sp_write_n_bytes = 1;
805sp_write_n_buf[0] = val;
806}
807sp_check_opbuf_usage(7 + sp_write_n_bytes);
808if (sp_write_n_bytes >= sp_max_write_n)
809sp_pass_writen();
810} else {
811/* We will have to do single writeb ops. */
812unsigned char writeb_parm[4];
813sp_check_opbuf_usage(6);
814writeb_parm[0] = (addr >> 0) & 0xFF;
815writeb_parm[1] = (addr >> 8) & 0xFF;
816writeb_parm[2] = (addr >> 16) & 0xFF;
817writeb_parm[3] = val;
818sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm); // FIXME: return error
819sp_opbuf_usage += 5;
820}
821}
822
823static uint8_t serprog_chip_readb(const struct flashctx *flash,
824 const chipaddr addr)
825{
826unsigned char c;
827unsigned char buf[3];
828/* Will stream the read operation - eg. add it to the stream buffer, *
829 * then flush the buffer, then read the read answer. */
830if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
831sp_execute_opbuf_noflush();
832buf[0] = ((addr >> 0) & 0xFF);
833buf[1] = ((addr >> 8) & 0xFF);
834buf[2] = ((addr >> 16) & 0xFF);
835sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf); // FIXME: return error
836sp_flush_stream(); // FIXME: return error
837if (serialport_read(&c, 1) != 0)
838msg_perr(MSGHEADER "readb byteread"); // FIXME: return error
839msg_pspew("%s addr=0x%" PRIxPTR " returning 0x%02X\n", __func__, addr, c);
840return c;
841}
842
843/* Local version that really does the job, doesn't care of max_read_n. */
844static int sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
845{
846unsigned char sbuf[6];
847msg_pspew("%s: addr=0x%" PRIxPTR " len=%zu\n", __func__, addr, len);
848/* Stream the read-n -- as above. */
849if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
850sp_execute_opbuf_noflush();
851sbuf[0] = ((addr >> 0) & 0xFF);
852sbuf[1] = ((addr >> 8) & 0xFF);
853sbuf[2] = ((addr >> 16) & 0xFF);
854sbuf[3] = ((len >> 0) & 0xFF);
855sbuf[4] = ((len >> 8) & 0xFF);
856sbuf[5] = ((len >> 16) & 0xFF);
857sp_stream_buffer_op(S_CMD_R_NBYTES, 6, sbuf);
858if (sp_flush_stream() != 0)
859return 1;
860if (serialport_read(buf, len) != 0) {
861msg_perr(MSGHEADER "Error: cannot read read-n data");
862return 1;
863}
864return 0;
865}
866
867/* The externally called version that makes sure that max_read_n is obeyed. */
868static void serprog_chip_readn(const struct flashctx *flash, uint8_t * buf,
869 const chipaddr addr, size_t len)
870{
871size_t lenm = len;
872chipaddr addrm = addr;
873while ((sp_max_read_n != 0) && (lenm > sp_max_read_n)) {
874sp_do_read_n(&(buf[addrm-addr]), addrm, sp_max_read_n); // FIXME: return error
875addrm += sp_max_read_n;
876lenm -= sp_max_read_n;
877}
878if (lenm)
879sp_do_read_n(&(buf[addrm-addr]), addrm, lenm); // FIXME: return error
880}
881
882void serprog_delay(unsigned int usecs)
883{
884unsigned char buf[4];
885msg_pspew("%s usecs=%d\n", __func__, usecs);
886if (!sp_check_commandavail(S_CMD_O_DELAY)) {
887msg_pdbg2("serprog_delay used, but programmer doesn't support delays natively - emulating\n");
888internal_delay(usecs);
889return;
890}
891if ((sp_max_write_n) && (sp_write_n_bytes))
892sp_pass_writen();
893sp_check_opbuf_usage(5);
894buf[0] = ((usecs >> 0) & 0xFF);
895buf[1] = ((usecs >> 8) & 0xFF);
896buf[2] = ((usecs >> 16) & 0xFF);
897buf[3] = ((usecs >> 24) & 0xFF);
898sp_stream_buffer_op(S_CMD_O_DELAY, 4, buf);
899sp_opbuf_usage += 5;
900sp_prev_was_write = 0;
901}
902
903static int serprog_spi_send_command(struct flashctx *flash,
904 unsigned int writecnt, unsigned int readcnt,
905 const unsigned char *writearr,
906 unsigned char *readarr)
907{
908unsigned char *parmbuf;
909int ret;
910msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
911if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes)) {
912if (sp_execute_opbuf() != 0) {
913msg_perr("Error: could not execute command buffer before sending SPI commands.\n");
914return 1;
915}
916}
917
918parmbuf = malloc(writecnt + 6);
919if (!parmbuf) {
920msg_perr("Error: could not allocate SPI send param buffer.\n");
921return 1;
922}
923parmbuf[0] = (writecnt >> 0) & 0xFF;
924parmbuf[1] = (writecnt >> 8) & 0xFF;
925parmbuf[2] = (writecnt >> 16) & 0xFF;
926parmbuf[3] = (readcnt >> 0) & 0xFF;
927parmbuf[4] = (readcnt >> 8) & 0xFF;
928parmbuf[5] = (readcnt >> 16) & 0xFF;
929memcpy(parmbuf + 6, writearr, writecnt);
930ret = sp_docommand(S_CMD_O_SPIOP, writecnt + 6, parmbuf, readcnt,
931 readarr);
932free(parmbuf);
933return ret;
934}
935
936/* FIXME: This function is optimized so that it does not split each transaction
937 * into chip page_size long blocks unnecessarily like spi_read_chunked. This has
938 * the advantage that it is much faster for most chips, but breaks those with
939 * non-continuous reads. When spi_read_chunked is fixed this method can be removed. */
940static int serprog_spi_read(struct flashctx *flash, uint8_t *buf,
941 unsigned int start, unsigned int len)
942{
943unsigned int i, cur_len;
944const unsigned int max_read = spi_master_serprog.max_data_read;
945for (i = 0; i < len; i += cur_len) {
946int ret;
947cur_len = min(max_read, (len - i));
948ret = spi_nbyte_read(flash, start + i, buf + i, cur_len);
949if (ret)
950return ret;
951}
952return 0;
953}
954
955void *serprog_map(const char *descr, uintptr_t phys_addr, size_t len)
956{
957/* Serprog transmits 24 bits only and assumes the underlying implementation handles any remaining bits
958 * correctly (usually setting them to one either in software (for FWH/LPC) or relying on the fact that
959 * the hardware observes a subset of the address bits only). Combined with the standard mapping of
960 * flashrom this creates a 16 MB-wide window just below the 4 GB boundary where serprog can operate (as
961 * needed for non-SPI chips). Below we make sure that the requested range is within this window. */
962if ((phys_addr & 0xFF000000) == 0xFF000000) {
963return (void*)phys_addr;
964} else {
965msg_pwarn(MSGHEADER "requested mapping %s is incompatible: 0x%zx bytes at 0x%0*" PRIxPTR ".\n",
966 descr, len, PRIxPTR_WIDTH, phys_addr);
967return NULL;
968}
969}

Archive Download this file

Revision: HEAD