source: trunk/at25.c @ 1474

Revision 1474, 9.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) 2010 Carl-Daniel Hailfinger
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; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18 */
19
20#include "flash.h"
21#include "chipdrivers.h"
22#include "spi.h"
23
24/* Prettyprint the status register. Works for Atmel A25/A26 series. */
25
26static void spi_prettyprint_status_register_atmel_at25_srpl(uint8_t status)
27{
28        msg_cdbg("Chip status register: Sector Protection Register Lock (SRPL) "
29                 "is %sset\n", (status & (1 << 7)) ? "" : "not ");
30}
31
32static void spi_prettyprint_status_register_atmel_at25_epewpp(uint8_t status)
33{
34        msg_cdbg("Chip status register: Erase/Program Error (EPE) "
35                 "is %sset\n", (status & (1 << 5)) ? "" : "not ");
36        msg_cdbg("Chip status register: WP# pin (WPP) "
37                 "is %sasserted\n", (status & (1 << 4)) ? "not " : "");
38}
39
40static void spi_prettyprint_status_register_atmel_at25_swp(uint8_t status)
41{
42        msg_cdbg("Chip status register: Software Protection Status (SWP): ");
43        switch (status & (3 << 2)) {
44        case 0x0 << 2:
45                msg_cdbg("no sectors are protected\n");
46                break;
47        case 0x1 << 2:
48                msg_cdbg("some sectors are protected\n");
49                /* FIXME: Read individual Sector Protection Registers. */
50                break;
51        case 0x3 << 2:
52                msg_cdbg("all sectors are protected\n");
53                break;
54        default:
55                msg_cdbg("reserved for future use\n");
56                break;
57        }
58}
59
60int spi_prettyprint_status_register_at25df(struct flashctx *flash)
61{
62        uint8_t status;
63
64        status = spi_read_status_register(flash);
65        msg_cdbg("Chip status register is %02x\n", status);
66
67        spi_prettyprint_status_register_atmel_at25_srpl(status);
68        spi_prettyprint_status_register_bit(status, 6);
69        spi_prettyprint_status_register_atmel_at25_epewpp(status);
70        spi_prettyprint_status_register_atmel_at25_swp(status);
71        spi_prettyprint_status_register_welwip(status);
72        return 0;
73}
74
75int spi_prettyprint_status_register_at25df_sec(struct flashctx *flash)
76{
77        /* FIXME: We should check the security lockdown. */
78        msg_cdbg("Ignoring security lockdown (if present)\n");
79        msg_cdbg("Ignoring status register byte 2\n");
80        return spi_prettyprint_status_register_at25df(flash);
81}
82
83int spi_prettyprint_status_register_at25f(struct flashctx *flash)
84{
85        uint8_t status;
86
87        status = spi_read_status_register(flash);
88        msg_cdbg("Chip status register is %02x\n", status);
89
90        spi_prettyprint_status_register_atmel_at25_srpl(status);
91        spi_prettyprint_status_register_bit(status, 6);
92        spi_prettyprint_status_register_atmel_at25_epewpp(status);
93        spi_prettyprint_status_register_bit(status, 3);
94        msg_cdbg("Chip status register: Block Protect 0 (BP0) is "
95                 "%sset, %s sectors are protected\n",
96                 (status & (1 << 2)) ? "" : "not ",
97                 (status & (1 << 2)) ? "all" : "no");
98        spi_prettyprint_status_register_welwip(status);
99        return 0;
100}
101
102int spi_prettyprint_status_register_at25fs010(struct flashctx *flash)
103{
104        uint8_t status;
105
106        status = spi_read_status_register(flash);
107        msg_cdbg("Chip status register is %02x\n", status);
108
109        msg_cdbg("Chip status register: Status Register Write Protect (WPEN) "
110                 "is %sset\n", (status & (1 << 7)) ? "" : "not ");
111        msg_cdbg("Chip status register: Bit 6 / Block Protect 4 (BP4) is "
112                 "%sset\n", (status & (1 << 6)) ? "" : "not ");
113        msg_cdbg("Chip status register: Bit 5 / Block Protect 3 (BP3) is "
114                 "%sset\n", (status & (1 << 5)) ? "" : "not ");
115        msg_cdbg("Chip status register: Bit 4 is "
116                 "%sset\n", (status & (1 << 4)) ? "" : "not ");
117        msg_cdbg("Chip status register: Bit 3 / Block Protect 1 (BP1) is "
118                 "%sset\n", (status & (1 << 3)) ? "" : "not ");
119        msg_cdbg("Chip status register: Bit 2 / Block Protect 0 (BP0) is "
120                 "%sset\n", (status & (1 << 2)) ? "" : "not ");
121        /* FIXME: Pretty-print detailed sector protection status. */
122        spi_prettyprint_status_register_welwip(status);
123        return 0;
124}
125
126int spi_prettyprint_status_register_at25fs040(struct flashctx *flash)
127{
128        uint8_t status;
129
130        status = spi_read_status_register(flash);
131        msg_cdbg("Chip status register is %02x\n", status);
132
133        msg_cdbg("Chip status register: Status Register Write Protect (WPEN) "
134                 "is %sset\n", (status & (1 << 7)) ? "" : "not ");
135        msg_cdbg("Chip status register: Bit 6 / Block Protect 4 (BP4) is "
136                 "%sset\n", (status & (1 << 6)) ? "" : "not ");
137        msg_cdbg("Chip status register: Bit 5 / Block Protect 3 (BP3) is "
138                 "%sset\n", (status & (1 << 5)) ? "" : "not ");
139        msg_cdbg("Chip status register: Bit 4 / Block Protect 2 (BP2) is "
140                 "%sset\n", (status & (1 << 4)) ? "" : "not ");
141        msg_cdbg("Chip status register: Bit 3 / Block Protect 1 (BP1) is "
142                 "%sset\n", (status & (1 << 3)) ? "" : "not ");
143        msg_cdbg("Chip status register: Bit 2 / Block Protect 0 (BP0) is "
144                 "%sset\n", (status & (1 << 2)) ? "" : "not ");
145        /* FIXME: Pretty-print detailed sector protection status. */
146        spi_prettyprint_status_register_welwip(status);
147        return 0;
148}
149
150int spi_prettyprint_status_register_atmel_at26df081a(struct flashctx *flash)
151{
152        uint8_t status;
153
154        status = spi_read_status_register(flash);
155        msg_cdbg("Chip status register is %02x\n", status);
156
157        spi_prettyprint_status_register_atmel_at25_srpl(status);
158        msg_cdbg("Chip status register: Sequential Program Mode Status (SPM) "
159                 "is %sset\n", (status & (1 << 6)) ? "" : "not ");
160        spi_prettyprint_status_register_atmel_at25_epewpp(status);
161        spi_prettyprint_status_register_atmel_at25_swp(status);
162        spi_prettyprint_status_register_welwip(status);
163        return 0;
164}
165
166int spi_disable_blockprotect_at25df(struct flashctx *flash)
167{
168        uint8_t status;
169        int result;
170
171        status = spi_read_status_register(flash);
172        /* If block protection is disabled, stop here. */
173        if ((status & (3 << 2)) == 0)
174                return 0;
175
176        msg_cdbg("Some block protection in effect, disabling\n");
177        if (status & (1 << 7)) {
178                msg_cdbg("Need to disable Sector Protection Register Lock\n");
179                if ((status & (1 << 4)) == 0) {
180                        msg_cerr("WP# pin is active, disabling "
181                                 "write protection is impossible.\n");
182                        return 1;
183                }
184                /* All bits except bit 7 (SPRL) are readonly. */
185                result = spi_write_status_register(flash, status & ~(1 << 7));
186                if (result) {
187                        msg_cerr("spi_write_status_register failed\n");
188                        return result;
189                }
190               
191        }
192        /* Global unprotect. Make sure to mask SPRL as well. */
193        result = spi_write_status_register(flash, status & ~0xbc);
194        if (result) {
195                msg_cerr("spi_write_status_register failed\n");
196                return result;
197        }
198        status = spi_read_status_register(flash);
199        if ((status & (3 << 2)) != 0) {
200                msg_cerr("Block protection could not be disabled!\n");
201                return 1;
202        }
203        return 0;
204}
205
206int spi_disable_blockprotect_at25df_sec(struct flashctx *flash)
207{
208        /* FIXME: We should check the security lockdown. */
209        msg_cinfo("Ignoring security lockdown (if present)\n");
210        return spi_disable_blockprotect_at25df(flash);
211}
212
213int spi_disable_blockprotect_at25f(struct flashctx *flash)
214{
215        /* spi_disable_blockprotect_at25df is not really the right way to do
216         * this, but the side effects of said function work here as well.
217         */
218        return spi_disable_blockprotect_at25df(flash);
219}
220
221int spi_disable_blockprotect_at25fs010(struct flashctx *flash)
222{
223        uint8_t status;
224        int result;
225
226        status = spi_read_status_register(flash);
227        /* If block protection is disabled, stop here. */
228        if ((status & 0x6c) == 0)
229                return 0;
230
231        msg_cdbg("Some block protection in effect, disabling\n");
232        if (status & (1 << 7)) {
233                msg_cdbg("Need to disable Status Register Write Protect\n");
234                /* Clear bit 7 (WPEN). */
235                result = spi_write_status_register(flash, status & ~(1 << 7));
236                if (result) {
237                        msg_cerr("spi_write_status_register failed\n");
238                        return result;
239                }
240        }
241        /* Global unprotect. Make sure to mask WPEN as well. */
242        result = spi_write_status_register(flash, status & ~0xec);
243        if (result) {
244                msg_cerr("spi_write_status_register failed\n");
245                return result;
246        }
247        status = spi_read_status_register(flash);
248        if ((status & 0x6c) != 0) {
249                msg_cerr("Block protection could not be disabled!\n");
250                return 1;
251        }
252        return 0;
253}
254
255int spi_disable_blockprotect_at25fs040(struct flashctx *flash)
256{
257        uint8_t status;
258        int result;
259
260        status = spi_read_status_register(flash);
261        /* If block protection is disabled, stop here. */
262        if ((status & 0x7c) == 0)
263                return 0;
264
265        msg_cdbg("Some block protection in effect, disabling\n");
266        if (status & (1 << 7)) {
267                msg_cdbg("Need to disable Status Register Write Protect\n");
268                /* Clear bit 7 (WPEN). */
269                result = spi_write_status_register(flash, status & ~(1 << 7));
270                if (result) {
271                        msg_cerr("spi_write_status_register failed\n");
272                        return result;
273                }
274        }
275        /* Global unprotect. Make sure to mask WPEN as well. */
276        result = spi_write_status_register(flash, status & ~0xfc);
277        if (result) {
278                msg_cerr("spi_write_status_register failed\n");
279                return result;
280        }
281        status = spi_read_status_register(flash);
282        if ((status & 0x7c) != 0) {
283                msg_cerr("Block protection could not be disabled!\n");
284                return 1;
285        }
286        return 0;
287}
Note: See TracBrowser for help on using the repository browser.