source: trunk/serprog.c @ 1474

Revision 1474, 26.1 KB checked in by hailfinger, 5 months ago (diff)

Add struct flashctx * parameter to all functions accessing flash chips.

All programmer access function prototypes except init have been made
static and moved to the respective file.

A few internal functions in flash chip drivers had chipaddr parameters
which are no longer needed.

The lines touched by flashctx changes have been adjusted to 80 columns
except in header files.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@…>
Acked-by: Michael Karcher <flashrom@…>

Line 
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 <stdio.h>
23#include <stdlib.h>
24#include <unistd.h>
25#include <string.h>
26#include <ctype.h>
27#include <fcntl.h>
28#include <sys/socket.h>
29#include <arpa/inet.h>
30#include <netinet/in.h>
31#include <netinet/tcp.h>
32#include <netdb.h>
33#include <sys/stat.h>
34#include <errno.h>
35#include <inttypes.h>
36#include <termios.h>
37#include "flash.h"
38#include "programmer.h"
39#include "chipdrivers.h"
40
41#define MSGHEADER "serprog: "
42
43/*
44 * FIXME: This prototype was added to help reduce diffs for the shutdown
45 * registration patch, which shifted many lines of code to place
46 * serprog_shutdown() before serprog_init(). It should be removed soon.
47 */
48static int serprog_shutdown(void *data);
49
50#define S_ACK 0x06
51#define S_NAK 0x15
52#define S_CMD_NOP               0x00    /* No operation                                 */
53#define S_CMD_Q_IFACE           0x01    /* Query interface version                      */
54#define S_CMD_Q_CMDMAP          0x02    /* Query supported commands bitmap              */
55#define S_CMD_Q_PGMNAME         0x03    /* Query programmer name                        */
56#define S_CMD_Q_SERBUF          0x04    /* Query Serial Buffer Size                     */
57#define S_CMD_Q_BUSTYPE         0x05    /* Query supported bustypes                     */
58#define S_CMD_Q_CHIPSIZE        0x06    /* Query supported chipsize (2^n format)        */
59#define S_CMD_Q_OPBUF           0x07    /* Query operation buffer size                  */
60#define S_CMD_Q_WRNMAXLEN       0x08    /* Query opbuf-write-N maximum length           */
61#define S_CMD_R_BYTE            0x09    /* Read a single byte                           */
62#define S_CMD_R_NBYTES          0x0A    /* Read n bytes                                 */
63#define S_CMD_O_INIT            0x0B    /* Initialize operation buffer                  */
64#define S_CMD_O_WRITEB          0x0C    /* Write opbuf: Write byte with address         */
65#define S_CMD_O_WRITEN          0x0D    /* Write to opbuf: Write-N                      */
66#define S_CMD_O_DELAY           0x0E    /* Write opbuf: udelay                          */
67#define S_CMD_O_EXEC            0x0F    /* Execute operation buffer                     */
68#define S_CMD_SYNCNOP           0x10    /* Special no-operation that returns NAK+ACK    */
69#define S_CMD_Q_RDNMAXLEN       0x11    /* Query read-n maximum length                  */
70#define S_CMD_S_BUSTYPE         0x12    /* Set used bustype(s).                         */
71#define S_CMD_O_SPIOP           0x13    /* Perform SPI operation.                       */
72
73static uint16_t sp_device_serbuf_size = 16;
74static uint16_t sp_device_opbuf_size = 300;
75/* Bitmap of supported commands */
76static uint8_t sp_cmdmap[32];
77
78/* sp_prev_was_write used to detect writes with contiguous addresses
79        and combine them to write-n's */
80static int sp_prev_was_write = 0;
81/* sp_write_n_addr used as the starting addr of the currently
82        combined write-n operation */
83static uint32_t sp_write_n_addr;
84/* The maximum length of an write_n operation; 0 = write-n not supported */
85static uint32_t sp_max_write_n = 0;
86/* The maximum length of a read_n operation; 0 = 2^24 */
87static uint32_t sp_max_read_n = 0;
88
89/* A malloc'd buffer for combining the operation's data
90        and a counter that tells how much data is there. */
91static uint8_t *sp_write_n_buf;
92static uint32_t sp_write_n_bytes = 0;
93
94/* sp_streamed_* used for flow control checking */
95static int sp_streamed_transmit_ops = 0;
96static int sp_streamed_transmit_bytes = 0;
97
98/* sp_opbuf_usage used for counting the amount of
99        on-device operation buffer used */
100static int sp_opbuf_usage = 0;
101/* if true causes sp_docommand to automatically check
102        whether the command is supported before doing it */
103static int sp_check_avail_automatic = 0;
104
105static int sp_opensocket(char *ip, unsigned int port)
106{
107        int flag = 1;
108        struct hostent *hostPtr = NULL;
109        union { struct sockaddr_in si; struct sockaddr s; } sp = {};
110        int sock;
111        msg_pdbg(MSGHEADER "IP %s port %d\n", ip, port);
112        sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
113        if (sock < 0)
114                sp_die("Error: serprog cannot open socket");
115        hostPtr = gethostbyname(ip);
116        if (NULL == hostPtr) {
117                hostPtr = gethostbyaddr(ip, strlen(ip), AF_INET);
118                if (NULL == hostPtr)
119                        sp_die("Error: cannot resolve");
120        }
121        sp.si.sin_family = AF_INET;
122        sp.si.sin_port = htons(port);
123        (void)memcpy(&sp.si.sin_addr, hostPtr->h_addr, hostPtr->h_length);
124        if (connect(sock, &sp.s, sizeof(sp.si)) < 0) {
125                close(sock);
126                sp_die("Error: serprog cannot connect");
127        }
128        /* We are latency limited, and sometimes do write-write-read    *
129         * (write-n) - so enable TCP_NODELAY.                           */
130        setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
131        return sock;
132}
133
134static int sp_sync_read_timeout(int loops)
135{
136        int i;
137        unsigned char c;
138        for (i = 0; i < loops; i++) {
139                ssize_t rv;
140                rv = read(sp_fd, &c, 1);
141                if (rv == 1)
142                        return c;
143                if ((rv == -1) && (errno != EAGAIN))
144                        sp_die("read");
145                usleep(10 * 1000);      /* 10ms units */
146        }
147        return -1;
148}
149
150/* Synchronize: a bit tricky algorithm that tries to (and in my tests has *
151 * always succeeded in) bring the serial protocol to known waiting-for-   *
152 * command state - uses nonblocking read - rest of the driver uses        *
153 * blocking read - TODO: add an alarm() timer for the rest of the app on  *
154 * serial operations, though not such a big issue as the first thing to   *
155 * do is synchronize (eg. check that device is alive).                    */
156static void sp_synchronize(void)
157{
158        int i;
159        int flags = fcntl(sp_fd, F_GETFL);
160        unsigned char buf[8];
161        flags |= O_NONBLOCK;
162        fcntl(sp_fd, F_SETFL, flags);
163        /* First sends 8 NOPs, then flushes the return data - should cause *
164         * the device serial parser to get to a sane state, unless if it   *
165         * is waiting for a real long write-n.                             */
166        memset(buf, S_CMD_NOP, 8);
167        if (write(sp_fd, buf, 8) != 8)
168                sp_die("flush write");
169        /* A second should be enough to get all the answers to the buffer */
170        usleep(1000 * 1000);
171        sp_flush_incoming();
172
173        /* Then try up to 8 times to send syncnop and get the correct special *
174         * return of NAK+ACK. Timing note: up to 10 characters, 10*50ms =     *
175         * up to 500ms per try, 8*0.5s = 4s; +1s (above) = up to 5s sync      *
176         * attempt, ~1s if immediate success.                                 */
177        for (i = 0; i < 8; i++) {
178                int n;
179                unsigned char c = S_CMD_SYNCNOP;
180                if (write(sp_fd, &c, 1) != 1)
181                        sp_die("sync write");
182                msg_pdbg(".");
183                fflush(stdout);
184                for (n = 0; n < 10; n++) {
185                        c = sp_sync_read_timeout(5);    /* wait up to 50ms */
186                        if (c != S_NAK)
187                                continue;
188                        c = sp_sync_read_timeout(2);
189                        if (c != S_ACK)
190                                continue;
191                        c = S_CMD_SYNCNOP;
192                        if (write(sp_fd, &c, 1) != 1)
193                                sp_die("sync write");
194                        c = sp_sync_read_timeout(50);
195                        if (c != S_NAK)
196                                break;  /* fail */
197                        c = sp_sync_read_timeout(10);
198                        if (c != S_ACK)
199                                break;  /* fail */
200                        /* Ok, synchronized; back to blocking reads and return. */
201                        flags &= ~O_NONBLOCK;
202                        fcntl(sp_fd, F_SETFL, flags);
203                        msg_pdbg("\n");
204                        return;
205                }
206        }
207        msg_perr("Error: cannot synchronize protocol "
208                "- check communications and reset device?\n");
209        exit(1);
210}
211
212static int sp_check_commandavail(uint8_t command)
213{
214        int byteoffs, bitoffs;
215        byteoffs = command / 8;
216        bitoffs = command % 8;
217        return (sp_cmdmap[byteoffs] & (1 << bitoffs)) ? 1 : 0;
218}
219
220static int sp_automatic_cmdcheck(uint8_t cmd)
221{
222        if ((sp_check_avail_automatic) && (sp_check_commandavail(cmd) == 0)) {
223                msg_pdbg("Warning: Automatic command availability check failed "
224                         "for cmd 0x%x - won't execute cmd\n", cmd);
225                return 1;
226                }
227        return 0;
228}
229
230static int sp_docommand(uint8_t command, uint32_t parmlen,
231                        uint8_t *params, uint32_t retlen, void *retparms)
232{
233        unsigned char c;
234        if (sp_automatic_cmdcheck(command))
235                return 1;
236        if (write(sp_fd, &command, 1) != 1)
237                sp_die("Error: cannot write op code");
238        if (write(sp_fd, params, parmlen) != (parmlen))
239                sp_die("Error: cannot write parameters");
240        if (read(sp_fd, &c, 1) != 1)
241                sp_die("Error: cannot read from device");
242        if (c == S_NAK)
243                return 1;
244        if (c != S_ACK) {
245                msg_perr("Error: invalid response 0x%02X from device\n",c);
246                exit(1);
247        }
248        if (retlen) {
249                int rd_bytes = 0;
250                do {
251                        int r;
252                        r = read(sp_fd, retparms + rd_bytes,
253                                 retlen - rd_bytes);
254                        if (r <= 0)
255                                sp_die("Error: cannot read return parameters");
256                        rd_bytes += r;
257                } while (rd_bytes != retlen);
258        }
259        return 0;
260}
261
262static void sp_flush_stream(void)
263{
264        if (sp_streamed_transmit_ops)
265                do {
266                        unsigned char c;
267                        if (read(sp_fd, &c, 1) != 1) {
268                                sp_die("Error: cannot read from device (flushing stream)");
269                        }
270                        if (c == S_NAK) {
271                                msg_perr("Error: NAK to a stream buffer operation\n");
272                                exit(1);
273                        }
274                        if (c != S_ACK) {
275                                msg_perr("Error: Invalid reply 0x%02X from device\n", c);
276                                exit(1);
277                        }
278                } while (--sp_streamed_transmit_ops);
279        sp_streamed_transmit_ops = 0;
280        sp_streamed_transmit_bytes = 0;
281}
282
283static int sp_stream_buffer_op(uint8_t cmd, uint32_t parmlen, uint8_t * parms)
284{
285        uint8_t *sp;
286        if (sp_automatic_cmdcheck(cmd))
287                return 1;
288        sp = malloc(1 + parmlen);
289        if (!sp) sp_die("Error: cannot malloc command buffer");
290        sp[0] = cmd;
291        memcpy(&(sp[1]), parms, parmlen);
292        if (sp_streamed_transmit_bytes >= (1 + parmlen + sp_device_serbuf_size))
293                sp_flush_stream();
294        if (write(sp_fd, sp, 1 + parmlen) != (1 + parmlen))
295                sp_die("Error: cannot write command");
296        free(sp);
297        sp_streamed_transmit_ops += 1;
298        sp_streamed_transmit_bytes += 1 + parmlen;
299        return 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_programmer spi_programmer_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};
317
318static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
319                                chipaddr addr);
320static uint8_t serprog_chip_readb(const struct flashctx *flash,
321                                  const chipaddr addr);
322static void serprog_chip_readn(const struct flashctx *flash, uint8_t *buf,
323                               const chipaddr addr, size_t len);
324static const struct par_programmer par_programmer_serprog = {
325                .chip_readb             = serprog_chip_readb,
326                .chip_readw             = fallback_chip_readw,
327                .chip_readl             = fallback_chip_readl,
328                .chip_readn             = serprog_chip_readn,
329                .chip_writeb            = serprog_chip_writeb,
330                .chip_writew            = fallback_chip_writew,
331                .chip_writel            = fallback_chip_writel,
332                .chip_writen            = fallback_chip_writen,
333};
334
335static enum chipbustype serprog_buses_supported = BUS_NONE;
336
337int serprog_init(void)
338{
339        uint16_t iface;
340        unsigned char pgmname[17];
341        unsigned char rbuf[3];
342        unsigned char c;
343        char *device;
344        char *baudport;
345        int have_device = 0;
346
347        /* the parameter is either of format "dev=/dev/device:baud" or "ip=ip:port" */
348        device = extract_programmer_param("dev");
349        if (device && strlen(device)) {
350                baudport = strstr(device, ":");
351                if (baudport) {
352                        /* Split device from baudrate. */
353                        *baudport = '\0';
354                        baudport++;
355                }
356                if (!baudport || !strlen(baudport)) {
357                        msg_perr("Error: No baudrate specified.\n"
358                                 "Use flashrom -p serprog:dev=/dev/device:baud\n");
359                        free(device);
360                        return 1;
361                }
362                if (strlen(device)) {
363                        sp_fd = sp_openserport(device, atoi(baudport));
364                        have_device++;
365                }
366        }
367        if (device && !strlen(device)) {
368                msg_perr("Error: No device specified.\n"
369                         "Use flashrom -p serprog:dev=/dev/device:baud\n");
370                free(device);
371                return 1;
372        }
373        free(device);
374
375        device = extract_programmer_param("ip");
376        if (have_device && device) {
377                msg_perr("Error: Both host and device specified.\n"
378                         "Please use either dev= or ip= but not both.\n");
379                free(device);
380                return 1;
381        }
382        if (device && strlen(device)) {
383                baudport = strstr(device, ":");
384                if (baudport) {
385                        /* Split host from port. */
386                        *baudport = '\0';
387                        baudport++;
388                }
389                if (!baudport || !strlen(baudport)) {
390                        msg_perr("Error: No port specified.\n"
391                                 "Use flashrom -p serprog:ip=ipaddr:port\n");
392                        free(device);
393                        return 1;
394                }
395                if (strlen(device)) {
396                        sp_fd = sp_opensocket(device, atoi(baudport));
397                        have_device++;
398                }
399        }
400        if (device && !strlen(device)) {
401                msg_perr("Error: No host specified.\n"
402                         "Use flashrom -p serprog:ip=ipaddr:port\n");
403                free(device);
404                return 1;
405        }
406        free(device);
407
408        if (!have_device) {
409                msg_perr("Error: Neither host nor device specified.\n"
410                         "Use flashrom -p serprog:dev=/dev/device:baud or "
411                         "flashrom -p serprog:ip=ipaddr:port\n");
412                return 1;
413        }
414
415        if (register_shutdown(serprog_shutdown, NULL))
416                return 1;
417
418        msg_pdbg(MSGHEADER "connected - attempting to synchronize\n");
419
420        sp_check_avail_automatic = 0;
421
422        sp_synchronize();
423
424        msg_pdbg(MSGHEADER "Synchronized\n");
425
426        if (sp_docommand(S_CMD_Q_IFACE, 0, NULL, 2, &iface)) {
427                msg_perr("Error: NAK to query interface version\n");
428                return 1;
429        }
430
431        if (iface != 1) {
432                msg_perr("Error: Unknown interface version: %d\n", iface);
433                return 1;
434        }
435
436        msg_pdbg(MSGHEADER "Interface version ok.\n");
437
438        if (sp_docommand(S_CMD_Q_CMDMAP, 0, NULL, 32, sp_cmdmap)) {
439                msg_perr("Error: query command map not supported\n");
440                return 1;
441        }
442
443        sp_check_avail_automatic = 1;
444
445        /* FIXME: This assumes that serprog device bustypes are always
446         * identical with flashrom bustype enums and that they all fit
447         * in a single byte.
448         */
449        if (sp_docommand(S_CMD_Q_BUSTYPE, 0, NULL, 1, &c)) {
450                msg_perr("Warning: NAK to query supported buses\n");
451                c = BUS_NONSPI; /* A reasonable default for now. */
452        }
453        serprog_buses_supported = c;
454
455        msg_pdbg(MSGHEADER "Bus support: parallel=%s, LPC=%s, FWH=%s, SPI=%s\n",
456                 (c & BUS_PARALLEL) ? "on" : "off",
457                 (c & BUS_LPC) ? "on" : "off",
458                 (c & BUS_FWH) ? "on" : "off",
459                 (c & BUS_SPI) ? "on" : "off");
460        /* Check for the minimum operational set of commands. */
461        if (serprog_buses_supported & BUS_SPI) {
462                uint8_t bt = BUS_SPI;
463                if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
464                        msg_perr("Error: SPI operation not supported while the "
465                                 "bustype is SPI\n");
466                        return 1;
467                }
468                /* Success of any of these commands is optional. We don't need
469                   the programmer to tell us its limits, but if it doesn't, we
470                   will assume stuff, so it's in the programmers best interest
471                   to tell us. */
472                sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL);
473                if (!sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
474                        uint32_t v;
475                        v = ((unsigned int)(rbuf[0]) << 0);
476                        v |= ((unsigned int)(rbuf[1]) << 8);
477                        v |= ((unsigned int)(rbuf[2]) << 16);
478                        if (v == 0)
479                                v = (1 << 24) - 1; /* SPI-op maximum. */
480                        spi_programmer_serprog.max_data_write = v;
481                        msg_pdbg(MSGHEADER "Maximum write-n length is %d\n", v);
482                }
483                if (!sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf)) {
484                        uint32_t v;
485                        v = ((unsigned int)(rbuf[0]) << 0);
486                        v |= ((unsigned int)(rbuf[1]) << 8);
487                        v |= ((unsigned int)(rbuf[2]) << 16);
488                        if (v == 0)
489                                v = (1 << 24) - 1; /* SPI-op maximum. */
490                        spi_programmer_serprog.max_data_read = v;
491                        msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
492                }
493                bt = serprog_buses_supported;
494                sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL);
495        }
496
497        if (serprog_buses_supported & BUS_NONSPI) {
498                if (sp_check_commandavail(S_CMD_O_INIT) == 0) {
499                        msg_perr("Error: Initialize operation buffer "
500                                 "not supported\n");
501                        return 1;
502                }
503
504                if (sp_check_commandavail(S_CMD_O_DELAY) == 0) {
505                        msg_perr("Error: Write to opbuf: "
506                                 "delay not supported\n");
507                        return 1;
508                }
509
510                /* S_CMD_O_EXEC availability checked later. */
511
512                if (sp_check_commandavail(S_CMD_R_BYTE) == 0) {
513                        msg_perr("Error: Single byte read not supported\n");
514                        return 1;
515                }
516                /* This could be translated to single byte reads (if missing),
517                 * but now we don't support that. */
518                if (sp_check_commandavail(S_CMD_R_NBYTES) == 0) {
519                        msg_perr("Error: Read n bytes not supported\n");
520                        return 1;
521                }
522                if (sp_check_commandavail(S_CMD_O_WRITEB) == 0) {
523                        msg_perr("Error: Write to opbuf: "
524                                 "write byte not supported\n");
525                        return 1;
526                }
527
528                if (sp_docommand(S_CMD_Q_WRNMAXLEN, 0, NULL, 3, rbuf)) {
529                        msg_pdbg(MSGHEADER "Write-n not supported");
530                        sp_max_write_n = 0;
531                } else {
532                        sp_max_write_n = ((unsigned int)(rbuf[0]) << 0);
533                        sp_max_write_n |= ((unsigned int)(rbuf[1]) << 8);
534                        sp_max_write_n |= ((unsigned int)(rbuf[2]) << 16);
535                        if (!sp_max_write_n) {
536                                sp_max_write_n = (1 << 24);
537                        }
538                        msg_pdbg(MSGHEADER "Maximum write-n length is %d\n",
539                                 sp_max_write_n);
540                        sp_write_n_buf = malloc(sp_max_write_n);
541                        if (!sp_write_n_buf) {
542                                msg_perr("Error: cannot allocate memory for "
543                                         "Write-n buffer\n");
544                                return 1;
545                        }
546                        sp_write_n_bytes = 0;
547                }
548
549                if (sp_check_commandavail(S_CMD_Q_RDNMAXLEN) &&
550                    (sp_docommand(S_CMD_Q_RDNMAXLEN, 0, NULL, 3, rbuf) == 0)) {
551                        sp_max_read_n = ((unsigned int)(rbuf[0]) << 0);
552                        sp_max_read_n |= ((unsigned int)(rbuf[1]) << 8);
553                        sp_max_read_n |= ((unsigned int)(rbuf[2]) << 16);
554                        msg_pdbg(MSGHEADER "Maximum read-n length is %d\n",
555                                 sp_max_read_n ? sp_max_read_n : (1 << 24));
556                } else {
557                        msg_pdbg(MSGHEADER "Maximum read-n length "
558                                 "not reported\n");
559                        sp_max_read_n = 0;
560                }
561
562        }
563
564        if (sp_docommand(S_CMD_Q_PGMNAME, 0, NULL, 16, pgmname)) {
565                msg_perr("Warning: NAK to query programmer name\n");
566                strcpy((char *)pgmname, "(unknown)");
567        }
568        pgmname[16] = 0;
569        msg_pinfo(MSGHEADER "Programmer name is \"%s\"\n", pgmname);
570
571        if (sp_docommand(S_CMD_Q_SERBUF, 0, NULL, 2, &sp_device_serbuf_size)) {
572                msg_perr("Warning: NAK to query serial buffer size\n");
573        }
574        msg_pdbg(MSGHEADER "Serial buffer size is %d\n",
575                     sp_device_serbuf_size);
576
577        if (sp_check_commandavail(S_CMD_O_INIT)) {
578                /* This would be inconsistent. */
579                if (sp_check_commandavail(S_CMD_O_EXEC) == 0) {
580                        msg_perr("Error: Execute operation buffer not "
581                                 "supported\n");
582                        return 1;
583                }
584
585                if (sp_docommand(S_CMD_O_INIT, 0, NULL, 0, NULL)) {
586                        msg_perr("Error: NAK to initialize operation buffer\n");
587                        return 1;
588                }
589
590                if (sp_docommand(S_CMD_Q_OPBUF, 0, NULL, 2,
591                    &sp_device_opbuf_size)) {
592                        msg_perr("Warning: NAK to query operation buffer "
593                                 "size\n");
594                }
595                msg_pdbg(MSGHEADER "operation buffer size is %d\n",
596                         sp_device_opbuf_size);
597        }
598
599        sp_prev_was_write = 0;
600        sp_streamed_transmit_ops = 0;
601        sp_streamed_transmit_bytes = 0;
602        sp_opbuf_usage = 0;
603        if (serprog_buses_supported & BUS_SPI)
604                register_spi_programmer(&spi_programmer_serprog);
605        if (serprog_buses_supported & BUS_NONSPI)
606                register_par_programmer(&par_programmer_serprog,
607                                        serprog_buses_supported & BUS_NONSPI);
608        return 0;
609}
610
611/* Move an in flashrom buffer existing write-n operation to     *
612 * the on-device operation buffer.                              */
613static void sp_pass_writen(void)
614{
615        unsigned char header[7];
616        msg_pspew(MSGHEADER "Passing write-n bytes=%d addr=0x%x\n",
617                  sp_write_n_bytes, sp_write_n_addr);
618        if (sp_streamed_transmit_bytes >=
619            (7 + sp_write_n_bytes + sp_device_serbuf_size))
620                sp_flush_stream();
621        /* In case it's just a single byte send it as a single write. */
622        if (sp_write_n_bytes == 1) {
623                sp_write_n_bytes = 0;
624                header[0] = (sp_write_n_addr >> 0) & 0xFF;
625                header[1] = (sp_write_n_addr >> 8) & 0xFF;
626                header[2] = (sp_write_n_addr >> 16) & 0xFF;
627                header[3] = sp_write_n_buf[0];
628                sp_stream_buffer_op(S_CMD_O_WRITEB, 4, header);
629                sp_opbuf_usage += 5;
630                return;
631        }
632        header[0] = S_CMD_O_WRITEN;
633        header[1] = (sp_write_n_bytes >> 0) & 0xFF;
634        header[2] = (sp_write_n_bytes >> 8) & 0xFF;
635        header[3] = (sp_write_n_bytes >> 16) & 0xFF;
636        header[4] = (sp_write_n_addr >> 0) & 0xFF;
637        header[5] = (sp_write_n_addr >> 8) & 0xFF;
638        header[6] = (sp_write_n_addr >> 16) & 0xFF;
639        if (write(sp_fd, header, 7) != 7)
640                sp_die("Error: cannot write write-n command\n");
641        if (write(sp_fd, sp_write_n_buf, sp_write_n_bytes) !=
642            sp_write_n_bytes)
643                sp_die("Error: cannot write write-n data");
644        sp_streamed_transmit_bytes += 7 + sp_write_n_bytes;
645        sp_streamed_transmit_ops += 1;
646        sp_opbuf_usage += 7 + sp_write_n_bytes;
647        sp_write_n_bytes = 0;
648        sp_prev_was_write = 0;
649}
650
651static void sp_execute_opbuf_noflush(void)
652{
653        if ((sp_max_write_n) && (sp_write_n_bytes))
654                sp_pass_writen();
655        sp_stream_buffer_op(S_CMD_O_EXEC, 0, NULL);
656        msg_pspew(MSGHEADER "Executed operation buffer of %d bytes\n",
657                     sp_opbuf_usage);
658        sp_opbuf_usage = 0;
659        sp_prev_was_write = 0;
660        return;
661}
662
663static void sp_execute_opbuf(void)
664{
665        sp_execute_opbuf_noflush();
666        sp_flush_stream();
667}
668
669static int serprog_shutdown(void *data)
670{
671        msg_pspew("%s\n", __func__);
672        if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
673                sp_execute_opbuf();
674        close(sp_fd);
675        if (sp_max_write_n)
676                free(sp_write_n_buf);
677        return 0;
678}
679
680static void sp_check_opbuf_usage(int bytes_to_be_added)
681{
682        if (sp_device_opbuf_size <= (sp_opbuf_usage + bytes_to_be_added)) {
683                sp_execute_opbuf();
684                /* If this happens in the mid of an page load the page load *
685                 * will probably fail.                                      */
686                msg_pdbg(MSGHEADER "Warning: executed operation buffer due to size reasons\n");
687        }
688}
689
690static void serprog_chip_writeb(const struct flashctx *flash, uint8_t val,
691                                chipaddr addr)
692{
693        msg_pspew("%s\n", __func__);
694        if (sp_max_write_n) {
695                if ((sp_prev_was_write)
696                    && (addr == (sp_write_n_addr + sp_write_n_bytes))) {
697                        sp_write_n_buf[sp_write_n_bytes++] = val;
698                } else {
699                        if ((sp_prev_was_write) && (sp_write_n_bytes))
700                                sp_pass_writen();
701                        sp_prev_was_write = 1;
702                        sp_write_n_addr = addr;
703                        sp_write_n_bytes = 1;
704                        sp_write_n_buf[0] = val;
705                }
706                sp_check_opbuf_usage(7 + sp_write_n_bytes);
707                if (sp_write_n_bytes >= sp_max_write_n)
708                        sp_pass_writen();
709        } else {
710                /* We will have to do single writeb ops. */
711                unsigned char writeb_parm[4];
712                sp_check_opbuf_usage(6);
713                writeb_parm[0] = (addr >> 0) & 0xFF;
714                writeb_parm[1] = (addr >> 8) & 0xFF;
715                writeb_parm[2] = (addr >> 16) & 0xFF;
716                writeb_parm[3] = val;
717                sp_stream_buffer_op(S_CMD_O_WRITEB, 4, writeb_parm);
718                sp_opbuf_usage += 5;
719        }
720}
721
722static uint8_t serprog_chip_readb(const struct flashctx *flash,
723                                  const chipaddr addr)
724{
725        unsigned char c;
726        unsigned char buf[3];
727        /* Will stream the read operation - eg. add it to the stream buffer, *
728         * then flush the buffer, then read the read answer.                 */
729        if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
730                sp_execute_opbuf_noflush();
731        buf[0] = ((addr >> 0) & 0xFF);
732        buf[1] = ((addr >> 8) & 0xFF);
733        buf[2] = ((addr >> 16) & 0xFF);
734        sp_stream_buffer_op(S_CMD_R_BYTE, 3, buf);
735        sp_flush_stream();
736        if (read(sp_fd, &c, 1) != 1)
737                sp_die("readb byteread");
738        msg_pspew("%s addr=0x%lx returning 0x%02X\n", __func__, addr, c);
739        return c;
740}
741
742/* Local version that really does the job, doesn't care of max_read_n. */
743static void sp_do_read_n(uint8_t * buf, const chipaddr addr, size_t len)
744{
745        int rd_bytes = 0;
746        unsigned char sbuf[6];
747        msg_pspew("%s: addr=0x%lx len=%lu\n", __func__, addr, (unsigned long)len);
748        /* Stream the read-n -- as above. */
749        if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
750                sp_execute_opbuf_noflush();
751        sbuf[0] = ((addr >> 0) & 0xFF);
752        sbuf[1] = ((addr >> 8) & 0xFF);
753        sbuf[2] = ((addr >> 16) & 0xFF);
754        sbuf[3] = ((len >> 0) & 0xFF);
755        sbuf[4] = ((len >> 8) & 0xFF);
756        sbuf[5] = ((len >> 16) & 0xFF);
757        sp_stream_buffer_op(S_CMD_R_NBYTES, 6, sbuf);
758        sp_flush_stream();
759        do {
760                int r = read(sp_fd, buf + rd_bytes, len - rd_bytes);
761                if (r <= 0)
762                        sp_die("Error: cannot read read-n data");
763                rd_bytes += r;
764        } while (rd_bytes != len);
765        return;
766}
767
768/* The externally called version that makes sure that max_read_n is obeyed. */
769static void serprog_chip_readn(const struct flashctx *flash, uint8_t * buf,
770                               const chipaddr addr, size_t len)
771{
772        size_t lenm = len;
773        chipaddr addrm = addr;
774        while ((sp_max_read_n != 0) && (lenm > sp_max_read_n)) {
775                sp_do_read_n(&(buf[addrm-addr]), addrm, sp_max_read_n);
776                addrm += sp_max_read_n;
777                lenm -= sp_max_read_n;
778        }
779        if (lenm)
780                sp_do_read_n(&(buf[addrm-addr]), addrm, lenm);
781}
782
783void serprog_delay(int usecs)
784{
785        unsigned char buf[4];
786        msg_pspew("%s usecs=%d\n", __func__, usecs);
787        if (!sp_check_commandavail(S_CMD_O_DELAY)) {
788                msg_pdbg("Note: serprog_delay used, but the programmer doesn't "
789                         "support delay\n");
790                internal_delay(usecs);
791                return;
792        }
793        if ((sp_max_write_n) && (sp_write_n_bytes))
794                sp_pass_writen();
795        sp_check_opbuf_usage(5);
796        buf[0] = ((usecs >> 0) & 0xFF);
797        buf[1] = ((usecs >> 8) & 0xFF);
798        buf[2] = ((usecs >> 16) & 0xFF);
799        buf[3] = ((usecs >> 24) & 0xFF);
800        sp_stream_buffer_op(S_CMD_O_DELAY, 4, buf);
801        sp_opbuf_usage += 5;
802        sp_prev_was_write = 0;
803}
804
805static int serprog_spi_send_command(struct flashctx *flash,
806                                    unsigned int writecnt, unsigned int readcnt,
807                                    const unsigned char *writearr,
808                                    unsigned char *readarr)
809{
810        unsigned char *parmbuf;
811        int ret;
812        msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
813        if ((sp_opbuf_usage) || (sp_max_write_n && sp_write_n_bytes))
814                sp_execute_opbuf();
815        parmbuf = malloc(writecnt + 6);
816        if (!parmbuf)
817                sp_die("Error: cannot malloc SPI send param buffer");
818        parmbuf[0] = (writecnt >> 0) & 0xFF;
819        parmbuf[1] = (writecnt >> 8) & 0xFF;
820        parmbuf[2] = (writecnt >> 16) & 0xFF;
821        parmbuf[3] = (readcnt >> 0) & 0xFF;
822        parmbuf[4] = (readcnt >> 8) & 0xFF;
823        parmbuf[5] = (readcnt >> 16) & 0xFF;
824        memcpy(parmbuf + 6, writearr, writecnt);
825        ret = sp_docommand(S_CMD_O_SPIOP, writecnt + 6, parmbuf, readcnt,
826                           readarr);
827        free(parmbuf);
828        return ret;
829}
830
831/* FIXME: This function is optimized so that it does not split each transaction
832 * into chip page_size long blocks unnecessarily like spi_read_chunked. This has
833 * the advantage that it is much faster for most chips, but breaks those with
834 * non-contiguous address space (like AT45DB161D). When spi_read_chunked is
835 * fixed this method can be removed. */
836static int serprog_spi_read(struct flashctx *flash, uint8_t *buf,
837                            unsigned int start, unsigned int len)
838{
839        unsigned int i, cur_len;
840        const unsigned int max_read = spi_programmer_serprog.max_data_read;
841        for (i = 0; i < len; i += cur_len) {
842                int ret;
843                cur_len = min(max_read, (len - i));
844                ret = spi_nbyte_read(flash, start + i, buf + i, cur_len);
845                if (ret)
846                        return ret;
847        }
848        return 0;
849}
Note: See TracBrowser for help on using the repository browser.