source: trunk/82802ab.c @ 1474

Revision 1474, 6.7 KB checked in by hailfinger, 7 weeks 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 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19 */
20
21/*
22 * Datasheet:
23 *  - Name: Intel 82802AB/82802AC Firmware Hub (FWH)
24 *  - URL: http://www.intel.com/design/chipsets/datashts/290658.htm
25 *  - PDF: http://download.intel.com/design/chipsets/datashts/29065804.pdf
26 *  - Order number: 290658-004
27 */
28
29#include "flash.h"
30#include "chipdrivers.h"
31
32void print_status_82802ab(uint8_t status)
33{
34        msg_cdbg("%s", status & 0x80 ? "Ready:" : "Busy:");
35        msg_cdbg("%s", status & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:");
36        msg_cdbg("%s", status & 0x20 ? "BE ERROR:" : "BE OK:");
37        msg_cdbg("%s", status & 0x10 ? "PROG ERR:" : "PROG OK:");
38        msg_cdbg("%s", status & 0x8 ? "VP ERR:" : "VPP OK:");
39        msg_cdbg("%s", status & 0x4 ? "PROG SUSPEND:" : "PROG RUN/FINISH:");
40        msg_cdbg("%s", status & 0x2 ? "WP|TBL#|WP#,ABORT:" : "UNLOCK:");
41}
42
43int probe_82802ab(struct flashctx *flash)
44{
45        chipaddr bios = flash->virtual_memory;
46        uint8_t id1, id2, flashcontent1, flashcontent2;
47        int shifted = (flash->feature_bits & FEATURE_ADDR_SHIFTED) != 0;
48
49        /* Reset to get a clean state */
50        chip_writeb(flash, 0xFF, bios);
51        programmer_delay(10);
52
53        /* Enter ID mode */
54        chip_writeb(flash, 0x90, bios);
55        programmer_delay(10);
56
57        id1 = chip_readb(flash, bios + (0x00 << shifted));
58        id2 = chip_readb(flash, bios + (0x01 << shifted));
59
60        /* Leave ID mode */
61        chip_writeb(flash, 0xFF, bios);
62
63        programmer_delay(10);
64
65        msg_cdbg("%s: id1 0x%02x, id2 0x%02x", __func__, id1, id2);
66
67        if (!oddparity(id1))
68                msg_cdbg(", id1 parity violation");
69
70        /*
71         * Read the product ID location again. We should now see normal
72         * flash contents.
73         */
74        flashcontent1 = chip_readb(flash, bios + (0x00 << shifted));
75        flashcontent2 = chip_readb(flash, bios + (0x01 << shifted));
76
77        if (id1 == flashcontent1)
78                msg_cdbg(", id1 is normal flash content");
79        if (id2 == flashcontent2)
80                msg_cdbg(", id2 is normal flash content");
81
82        msg_cdbg("\n");
83        if (id1 != flash->manufacture_id || id2 != flash->model_id)
84                return 0;
85
86        if (flash->feature_bits & FEATURE_REGISTERMAP)
87                map_flash_registers(flash);
88
89        return 1;
90}
91
92uint8_t wait_82802ab(struct flashctx *flash)
93{
94        uint8_t status;
95        chipaddr bios = flash->virtual_memory;
96
97        chip_writeb(flash, 0x70, bios);
98        if ((chip_readb(flash, bios) & 0x80) == 0) {    // it's busy
99                while ((chip_readb(flash, bios) & 0x80) == 0) ;
100        }
101
102        status = chip_readb(flash, bios);
103
104        /* Reset to get a clean state */
105        chip_writeb(flash, 0xFF, bios);
106
107        return status;
108}
109
110int unlock_82802ab(struct flashctx *flash)
111{
112        int i;
113        //chipaddr wrprotect = flash->virtual_registers + page + 2;
114
115        for (i = 0; i < flash->total_size * 1024; i+= flash->page_size)
116                chip_writeb(flash, 0, flash->virtual_registers + i + 2);
117
118        return 0;
119}
120
121int erase_block_82802ab(struct flashctx *flash, unsigned int page,
122                        unsigned int pagesize)
123{
124        chipaddr bios = flash->virtual_memory;
125        uint8_t status;
126
127        // clear status register
128        chip_writeb(flash, 0x50, bios + page);
129
130        // now start it
131        chip_writeb(flash, 0x20, bios + page);
132        chip_writeb(flash, 0xd0, bios + page);
133        programmer_delay(10);
134
135        // now let's see what the register is
136        status = wait_82802ab(flash);
137        print_status_82802ab(status);
138
139        /* FIXME: Check the status register for errors. */
140        return 0;
141}
142
143/* chunksize is 1 */
144int write_82802ab(struct flashctx *flash, uint8_t *src, unsigned int start,
145                  unsigned int len)
146{
147        int i;
148        chipaddr dst = flash->virtual_memory + start;
149
150        for (i = 0; i < len; i++) {
151                /* transfer data from source to destination */
152                chip_writeb(flash, 0x40, dst);
153                chip_writeb(flash, *src++, dst++);
154                wait_82802ab(flash);
155        }
156
157        /* FIXME: Ignore errors for now. */
158        return 0;
159}
160
161int unlock_28f004s5(struct flashctx *flash)
162{
163        chipaddr bios = flash->virtual_memory;
164        uint8_t mcfg, bcfg, need_unlock = 0, can_unlock = 0;
165        int i;
166
167        /* Clear status register */
168        chip_writeb(flash, 0x50, bios);
169
170        /* Read identifier codes */
171        chip_writeb(flash, 0x90, bios);
172
173        /* Read master lock-bit */
174        mcfg = chip_readb(flash, bios + 0x3);
175        msg_cdbg("master lock is ");
176        if (mcfg) {
177                msg_cdbg("locked!\n");
178        } else {
179                msg_cdbg("unlocked!\n");
180                can_unlock = 1;
181        }
182
183        /* Read block lock-bits */
184        for (i = 0; i < flash->total_size * 1024; i+= (64 * 1024)) {
185                bcfg = chip_readb(flash, bios + i + 2); // read block lock config
186                msg_cdbg("block lock at %06x is %slocked!\n", i, bcfg ? "" : "un");
187                if (bcfg) {
188                        need_unlock = 1;
189                }
190        }
191
192        /* Reset chip */
193        chip_writeb(flash, 0xFF, bios);
194
195        /* Unlock: clear block lock-bits, if needed */
196        if (can_unlock && need_unlock) {
197                msg_cdbg("Unlock: ");
198                chip_writeb(flash, 0x60, bios);
199                chip_writeb(flash, 0xD0, bios);
200                chip_writeb(flash, 0xFF, bios);
201                msg_cdbg("Done!\n");
202        }
203
204        /* Error: master locked or a block is locked */
205        if (!can_unlock && need_unlock) {
206                msg_cerr("At least one block is locked and lockdown is active!\n");
207                return -1;
208        }
209
210        return 0;
211}
212
213int unlock_lh28f008bjt(struct flashctx *flash)
214{
215        chipaddr bios = flash->virtual_memory;
216        uint8_t mcfg, bcfg;
217        uint8_t need_unlock = 0, can_unlock = 0;
218        int i;
219
220        /* Wait if chip is busy */
221        wait_82802ab(flash);
222
223        /* Read identifier codes */
224        chip_writeb(flash, 0x90, bios);
225
226        /* Read master lock-bit */
227        mcfg = chip_readb(flash, bios + 0x3);
228        msg_cdbg("master lock is ");
229        if (mcfg) {
230                msg_cdbg("locked!\n");
231        } else {
232                msg_cdbg("unlocked!\n");
233                can_unlock = 1;
234        }
235
236        /* Read block lock-bits, 8 * 8 KB + 15 * 64 KB */
237        for (i = 0; i < flash->total_size * 1024;
238             i += (i >= (64 * 1024) ? 64 * 1024 : 8 * 1024)) {
239                bcfg = chip_readb(flash, bios + i + 2); /* read block lock config */
240                msg_cdbg("block lock at %06x is %slocked!\n", i,
241                         bcfg ? "" : "un");
242                if (bcfg)
243                        need_unlock = 1;
244        }
245
246        /* Reset chip */
247        chip_writeb(flash, 0xFF, bios);
248
249        /* Unlock: clear block lock-bits, if needed */
250        if (can_unlock && need_unlock) {
251                msg_cdbg("Unlock: ");
252                chip_writeb(flash, 0x60, bios);
253                chip_writeb(flash, 0xD0, bios);
254                chip_writeb(flash, 0xFF, bios);
255                wait_82802ab(flash);
256                msg_cdbg("Done!\n");
257        }
258
259        /* Error: master locked or a block is locked */
260        if (!can_unlock && need_unlock) {
261                msg_cerr("At least one block is locked and lockdown is active!\n");
262                return -1;
263        }
264
265        return 0;
266}
Note: See TracBrowser for help on using the repository browser.