source: trunk/jedec.c @ 1474

Revision 1474, 14.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@…>

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2000 Silicon Integrated System Corporation
5 * Copyright (C) 2006 Giampiero Giancipoli <gianci@email.it>
6 * Copyright (C) 2006 coresystems GmbH <info@coresystems.de>
7 * Copyright (C) 2007 Carl-Daniel Hailfinger
8 * Copyright (C) 2009 Sean Nelson <audiohacked@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
23 */
24
25#include "flash.h"
26
27#define MAX_REFLASH_TRIES 0x10
28#define MASK_FULL 0xffff
29#define MASK_2AA 0x7ff
30#define MASK_AAA 0xfff
31
32/* Check one byte for odd parity */
33uint8_t oddparity(uint8_t val)
34{
35        val = (val ^ (val >> 4)) & 0xf;
36        val = (val ^ (val >> 2)) & 0x3;
37        return (val ^ (val >> 1)) & 0x1;
38}
39
40static void toggle_ready_jedec_common(const struct flashctx *flash,
41                                      chipaddr dst, int delay)
42{
43        unsigned int i = 0;
44        uint8_t tmp1, tmp2;
45
46        tmp1 = chip_readb(flash, dst) & 0x40;
47
48        while (i++ < 0xFFFFFFF) {
49                if (delay)
50                        programmer_delay(delay);
51                tmp2 = chip_readb(flash, dst) & 0x40;
52                if (tmp1 == tmp2) {
53                        break;
54                }
55                tmp1 = tmp2;
56        }
57        if (i > 0x100000)
58                msg_cdbg("%s: excessive loops, i=0x%x\n", __func__, i);
59}
60
61void toggle_ready_jedec(const struct flashctx *flash, chipaddr dst)
62{
63        toggle_ready_jedec_common(flash, dst, 0);
64}
65
66/* Some chips require a minimum delay between toggle bit reads.
67 * The Winbond W39V040C wants 50 ms between reads on sector erase toggle,
68 * but experiments show that 2 ms are already enough. Pick a safety factor
69 * of 4 and use an 8 ms delay.
70 * Given that erase is slow on all chips, it is recommended to use
71 * toggle_ready_jedec_slow in erase functions.
72 */
73static void toggle_ready_jedec_slow(const struct flashctx *flash, chipaddr dst)
74{
75        toggle_ready_jedec_common(flash, dst, 8 * 1000);
76}
77
78void data_polling_jedec(const struct flashctx *flash, chipaddr dst,
79                        uint8_t data)
80{
81        unsigned int i = 0;
82        uint8_t tmp;
83
84        data &= 0x80;
85
86        while (i++ < 0xFFFFFFF) {
87                tmp = chip_readb(flash, dst) & 0x80;
88                if (tmp == data) {
89                        break;
90                }
91        }
92        if (i > 0x100000)
93                msg_cdbg("%s: excessive loops, i=0x%x\n", __func__, i);
94}
95
96static unsigned int getaddrmask(struct flashctx *flash)
97{
98        switch (flash->feature_bits & FEATURE_ADDR_MASK) {
99        case FEATURE_ADDR_FULL:
100                return MASK_FULL;
101                break;
102        case FEATURE_ADDR_2AA:
103                return MASK_2AA;
104                break;
105        case FEATURE_ADDR_AAA:
106                return MASK_AAA;
107                break;
108        default:
109                msg_cerr("%s called with unknown mask\n", __func__);
110                return 0;
111                break;
112        }
113}
114
115static void start_program_jedec_common(struct flashctx *flash,
116                                       unsigned int mask)
117{
118        chipaddr bios = flash->virtual_memory;
119        chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
120        chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
121        chip_writeb(flash, 0xA0, bios + (0x5555 & mask));
122}
123
124static int probe_jedec_common(struct flashctx *flash, unsigned int mask)
125{
126        chipaddr bios = flash->virtual_memory;
127        uint8_t id1, id2;
128        uint32_t largeid1, largeid2;
129        uint32_t flashcontent1, flashcontent2;
130        int probe_timing_enter, probe_timing_exit;
131
132        if (flash->probe_timing > 0) 
133                probe_timing_enter = probe_timing_exit = flash->probe_timing;
134        else if (flash->probe_timing == TIMING_ZERO) { /* No delay. */
135                probe_timing_enter = probe_timing_exit = 0;
136        } else if (flash->probe_timing == TIMING_FIXME) { /* == _IGNORED */
137                msg_cdbg("Chip lacks correct probe timing information, "
138                             "using default 10mS/40uS. ");
139                probe_timing_enter = 10000;
140                probe_timing_exit = 40;
141        } else {
142                msg_cerr("Chip has negative value in probe_timing, failing "
143                       "without chip access\n");
144                return 0;
145        }
146
147        /* Earlier probes might have been too fast for the chip to enter ID
148         * mode completely. Allow the chip to finish this before seeing a
149         * reset command.
150         */
151        if (probe_timing_enter)
152                programmer_delay(probe_timing_enter);
153        /* Reset chip to a clean slate */
154        if ((flash->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET)
155        {
156                chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
157                if (probe_timing_exit)
158                        programmer_delay(10);
159                chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
160                if (probe_timing_exit)
161                        programmer_delay(10);
162        }
163        chip_writeb(flash, 0xF0, bios + (0x5555 & mask));
164        if (probe_timing_exit)
165                programmer_delay(probe_timing_exit);
166
167        /* Issue JEDEC Product ID Entry command */
168        chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
169        if (probe_timing_enter)
170                programmer_delay(10);
171        chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
172        if (probe_timing_enter)
173                programmer_delay(10);
174        chip_writeb(flash, 0x90, bios + (0x5555 & mask));
175        if (probe_timing_enter)
176                programmer_delay(probe_timing_enter);
177
178        /* Read product ID */
179        id1 = chip_readb(flash, bios);
180        id2 = chip_readb(flash, bios + 0x01);
181        largeid1 = id1;
182        largeid2 = id2;
183
184        /* Check if it is a continuation ID, this should be a while loop. */
185        if (id1 == 0x7F) {
186                largeid1 <<= 8;
187                id1 = chip_readb(flash, bios + 0x100);
188                largeid1 |= id1;
189        }
190        if (id2 == 0x7F) {
191                largeid2 <<= 8;
192                id2 = chip_readb(flash, bios + 0x101);
193                largeid2 |= id2;
194        }
195
196        /* Issue JEDEC Product ID Exit command */
197        if ((flash->feature_bits & FEATURE_RESET_MASK) == FEATURE_LONG_RESET)
198        {
199                chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
200                if (probe_timing_exit)
201                        programmer_delay(10);
202                chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
203                if (probe_timing_exit)
204                        programmer_delay(10);
205        }
206        chip_writeb(flash, 0xF0, bios + (0x5555 & mask));
207        if (probe_timing_exit)
208                programmer_delay(probe_timing_exit);
209
210        msg_cdbg("%s: id1 0x%02x, id2 0x%02x", __func__, largeid1, largeid2);
211        if (!oddparity(id1))
212                msg_cdbg(", id1 parity violation");
213
214        /* Read the product ID location again. We should now see normal flash contents. */
215        flashcontent1 = chip_readb(flash, bios);
216        flashcontent2 = chip_readb(flash, bios + 0x01);
217
218        /* Check if it is a continuation ID, this should be a while loop. */
219        if (flashcontent1 == 0x7F) {
220                flashcontent1 <<= 8;
221                flashcontent1 |= chip_readb(flash, bios + 0x100);
222        }
223        if (flashcontent2 == 0x7F) {
224                flashcontent2 <<= 8;
225                flashcontent2 |= chip_readb(flash, bios + 0x101);
226        }
227
228        if (largeid1 == flashcontent1)
229                msg_cdbg(", id1 is normal flash content");
230        if (largeid2 == flashcontent2)
231                msg_cdbg(", id2 is normal flash content");
232
233        msg_cdbg("\n");
234        if (largeid1 != flash->manufacture_id || largeid2 != flash->model_id)
235                return 0;
236
237        if (flash->feature_bits & FEATURE_REGISTERMAP)
238                map_flash_registers(flash);
239
240        return 1;
241}
242
243static int erase_sector_jedec_common(struct flashctx *flash, unsigned int page,
244                                     unsigned int pagesize, unsigned int mask)
245{
246        chipaddr bios = flash->virtual_memory;
247        int delay_us = 0;
248        if(flash->probe_timing != TIMING_ZERO)
249                delay_us = 10;
250
251        /*  Issue the Sector Erase command   */
252        chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
253        programmer_delay(delay_us);
254        chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
255        programmer_delay(delay_us);
256        chip_writeb(flash, 0x80, bios + (0x5555 & mask));
257        programmer_delay(delay_us);
258
259        chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
260        programmer_delay(delay_us);
261        chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
262        programmer_delay(delay_us);
263        chip_writeb(flash, 0x30, bios + page);
264        programmer_delay(delay_us);
265
266        /* wait for Toggle bit ready         */
267        toggle_ready_jedec_slow(flash, bios);
268
269        /* FIXME: Check the status register for errors. */
270        return 0;
271}
272
273static int erase_block_jedec_common(struct flashctx *flash, unsigned int block,
274                                    unsigned int blocksize, unsigned int mask)
275{
276        chipaddr bios = flash->virtual_memory;
277        int delay_us = 0;
278        if(flash->probe_timing != TIMING_ZERO)
279                delay_us = 10;
280
281        /*  Issue the Sector Erase command   */
282        chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
283        programmer_delay(delay_us);
284        chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
285        programmer_delay(delay_us);
286        chip_writeb(flash, 0x80, bios + (0x5555 & mask));
287        programmer_delay(delay_us);
288
289        chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
290        programmer_delay(delay_us);
291        chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
292        programmer_delay(delay_us);
293        chip_writeb(flash, 0x50, bios + block);
294        programmer_delay(delay_us);
295
296        /* wait for Toggle bit ready         */
297        toggle_ready_jedec_slow(flash, bios);
298
299        /* FIXME: Check the status register for errors. */
300        return 0;
301}
302
303static int erase_chip_jedec_common(struct flashctx *flash, unsigned int mask)
304{
305        chipaddr bios = flash->virtual_memory;
306        int delay_us = 0;
307        if(flash->probe_timing != TIMING_ZERO)
308                delay_us = 10;
309
310        /*  Issue the JEDEC Chip Erase command   */
311        chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
312        programmer_delay(delay_us);
313        chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
314        programmer_delay(delay_us);
315        chip_writeb(flash, 0x80, bios + (0x5555 & mask));
316        programmer_delay(delay_us);
317
318        chip_writeb(flash, 0xAA, bios + (0x5555 & mask));
319        programmer_delay(delay_us);
320        chip_writeb(flash, 0x55, bios + (0x2AAA & mask));
321        programmer_delay(delay_us);
322        chip_writeb(flash, 0x10, bios + (0x5555 & mask));
323        programmer_delay(delay_us);
324
325        toggle_ready_jedec_slow(flash, bios);
326
327        /* FIXME: Check the status register for errors. */
328        return 0;
329}
330
331static int write_byte_program_jedec_common(struct flashctx *flash, uint8_t *src,
332                                           chipaddr dst, unsigned int mask)
333{
334        int tried = 0, failed = 0;
335        chipaddr bios = flash->virtual_memory;
336
337        /* If the data is 0xFF, don't program it and don't complain. */
338        if (*src == 0xFF) {
339                return 0;
340        }
341
342retry:
343        /* Issue JEDEC Byte Program command */
344        start_program_jedec_common(flash, mask);
345
346        /* transfer data from source to destination */
347        chip_writeb(flash, *src, dst);
348        toggle_ready_jedec(flash, bios);
349
350        if (chip_readb(flash, dst) != *src && tried++ < MAX_REFLASH_TRIES) {
351                goto retry;
352        }
353
354        if (tried >= MAX_REFLASH_TRIES)
355                failed = 1;
356
357        return failed;
358}
359
360/* chunksize is 1 */
361int write_jedec_1(struct flashctx *flash, uint8_t *src, unsigned int start,
362                  unsigned int len)
363{
364        int i, failed = 0;
365        chipaddr dst = flash->virtual_memory + start;
366        chipaddr olddst;
367        unsigned int mask;
368
369        mask = getaddrmask(flash);
370
371        olddst = dst;
372        for (i = 0; i < len; i++) {
373                if (write_byte_program_jedec_common(flash, src, dst, mask))
374                        failed = 1;
375                dst++, src++;
376        }
377        if (failed)
378                msg_cerr(" writing sector at 0x%lx failed!\n", olddst);
379
380        return failed;
381}
382
383int write_page_write_jedec_common(struct flashctx *flash, uint8_t *src,
384                                  unsigned int start, unsigned int page_size)
385{
386        int i, tried = 0, failed;
387        uint8_t *s = src;
388        chipaddr bios = flash->virtual_memory;
389        chipaddr dst = bios + start;
390        chipaddr d = dst;
391        unsigned int mask;
392
393        mask = getaddrmask(flash);
394
395retry:
396        /* Issue JEDEC Start Program command */
397        start_program_jedec_common(flash, mask);
398
399        /* transfer data from source to destination */
400        for (i = 0; i < page_size; i++) {
401                /* If the data is 0xFF, don't program it */
402                if (*src != 0xFF)
403                        chip_writeb(flash, *src, dst);
404                dst++;
405                src++;
406        }
407
408        toggle_ready_jedec(flash, dst - 1);
409
410        dst = d;
411        src = s;
412        failed = verify_range(flash, src, start, page_size, NULL);
413
414        if (failed && tried++ < MAX_REFLASH_TRIES) {
415                msg_cerr("retrying.\n");
416                goto retry;
417        }
418        if (failed) {
419                msg_cerr(" page 0x%lx failed!\n",
420                        (d - bios) / page_size);
421        }
422        return failed;
423}
424
425/* chunksize is page_size */
426/*
427 * Write a part of the flash chip.
428 * FIXME: Use the chunk code from Michael Karcher instead.
429 * This function is a slightly modified copy of spi_write_chunked.
430 * Each page is written separately in chunks with a maximum size of chunksize.
431 */
432int write_jedec(struct flashctx *flash, uint8_t *buf, unsigned int start,
433                int unsigned len)
434{
435        unsigned int i, starthere, lenhere;
436        /* FIXME: page_size is the wrong variable. We need max_writechunk_size
437         * in struct flashctx to do this properly. All chips using
438         * write_jedec have page_size set to max_writechunk_size, so
439         * we're OK for now.
440         */
441        unsigned int page_size = flash->page_size;
442
443        /* Warning: This loop has a very unusual condition and body.
444         * The loop needs to go through each page with at least one affected
445         * byte. The lowest page number is (start / page_size) since that
446         * division rounds down. The highest page number we want is the page
447         * where the last byte of the range lives. That last byte has the
448         * address (start + len - 1), thus the highest page number is
449         * (start + len - 1) / page_size. Since we want to include that last
450         * page as well, the loop condition uses <=.
451         */
452        for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
453                /* Byte position of the first byte in the range in this page. */
454                /* starthere is an offset to the base address of the chip. */
455                starthere = max(start, i * page_size);
456                /* Length of bytes in the range in this page. */
457                lenhere = min(start + len, (i + 1) * page_size) - starthere;
458
459                if (write_page_write_jedec_common(flash, buf + starthere - start, starthere, lenhere))
460                        return 1;
461        }
462
463        return 0;
464}
465
466/* erase chip with block_erase() prototype */
467int erase_chip_block_jedec(struct flashctx *flash, unsigned int addr,
468                           unsigned int blocksize)
469{
470        unsigned int mask;
471
472        mask = getaddrmask(flash);
473        if ((addr != 0) || (blocksize != flash->total_size * 1024)) {
474                msg_cerr("%s called with incorrect arguments\n",
475                        __func__);
476                return -1;
477        }
478        return erase_chip_jedec_common(flash, mask);
479}
480
481int probe_jedec(struct flashctx *flash)
482{
483        unsigned int mask;
484
485        mask = getaddrmask(flash);
486        return probe_jedec_common(flash, mask);
487}
488
489int erase_sector_jedec(struct flashctx *flash, unsigned int page,
490                       unsigned int size)
491{
492        unsigned int mask;
493
494        mask = getaddrmask(flash);
495        return erase_sector_jedec_common(flash, page, size, mask);
496}
497
498int erase_block_jedec(struct flashctx *flash, unsigned int page,
499                      unsigned int size)
500{
501        unsigned int mask;
502
503        mask = getaddrmask(flash);
504        return erase_block_jedec_common(flash, page, size, mask);
505}
506
507int erase_chip_jedec(struct flashctx *flash)
508{
509        unsigned int mask;
510
511        mask = getaddrmask(flash);
512        return erase_chip_jedec_common(flash, mask);
513}
Note: See TracBrowser for help on using the repository browser.