blob: 4dd366cbee681c800f92952ac0eefac8dd0e050e [file] [log] [blame]
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +00001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2008 coresystems GmbH
5 * Copyright (C) 2010 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 "flash.h"
Carl-Daniel Hailfingeref3ac8a2014-08-03 13:05:34 +000023#include "chipdrivers.h"
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +000024
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +000025static uint8_t w39_idmode_readb(struct flashctx *flash, unsigned int offset)
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +000026{
27 chipaddr bios = flash->virtual_memory;
28 uint8_t val;
29
30 /* Product Identification Entry */
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +000031 chip_writeb(flash, 0xAA, bios + 0x5555);
32 chip_writeb(flash, 0x55, bios + 0x2AAA);
33 chip_writeb(flash, 0x90, bios + 0x5555);
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +000034 programmer_delay(10);
35
36 /* Read something, maybe hardware lock bits */
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +000037 val = chip_readb(flash, bios + offset);
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +000038
39 /* Product Identification Exit */
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +000040 chip_writeb(flash, 0xAA, bios + 0x5555);
41 chip_writeb(flash, 0x55, bios + 0x2AAA);
42 chip_writeb(flash, 0xF0, bios + 0x5555);
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +000043 programmer_delay(10);
44
45 return val;
46}
47
48static int printlock_w39_tblwp(uint8_t lock)
49{
50 msg_cdbg("Hardware bootblock locking (#TBL) is %sactive.\n",
51 (lock & (1 << 2)) ? "" : "not ");
52 msg_cdbg("Hardware remaining chip locking (#WP) is %sactive..\n",
53 (lock & (1 << 3)) ? "" : "not ");
54 if (lock & ((1 << 2) | (1 << 3)))
55 return -1;
56
57 return 0;
58}
59
Kyösti Mälkkic31243e2012-10-28 01:50:08 +000060static int printlock_w39_single_bootblock(uint8_t lock, uint16_t kB)
61{
62 msg_cdbg("Software %d kB bootblock locking is %sactive.\n", kB, (lock & 0x03) ? "" : "not ");
63 if (lock & 0x03)
64 return -1;
65
66 return 0;
67}
68
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +000069static int printlock_w39_bootblock_64k16k(uint8_t lock)
70{
71 msg_cdbg("Software 64 kB bootblock locking is %sactive.\n",
72 (lock & (1 << 0)) ? "" : "not ");
73 msg_cdbg("Software 16 kB bootblock locking is %sactive.\n",
74 (lock & (1 << 1)) ? "" : "not ");
75 if (lock & ((1 << 1) | (1 << 0)))
76 return -1;
77
78 return 0;
79}
80
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +000081static int printlock_w39_common(struct flashctx *flash, unsigned int offset)
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +000082{
83 uint8_t lock;
84
85 lock = w39_idmode_readb(flash, offset);
86 msg_cdbg("Lockout bits:\n");
87 return printlock_w39_tblwp(lock);
88}
89
Kyösti Mälkkic31243e2012-10-28 01:50:08 +000090int printlock_w39f010(struct flashctx *flash)
91{
92 uint8_t lock;
93 int ret;
94
95 lock = w39_idmode_readb(flash, 0x00002);
96 msg_cdbg("Bottom boot block:\n");
97 ret = printlock_w39_single_bootblock(lock, 16);
98
99 lock = w39_idmode_readb(flash, 0x1fff2);
100 msg_cdbg("Top boot block:\n");
101 ret |= printlock_w39_single_bootblock(lock, 16);
102
103 return ret;
104}
105
106int printlock_w39l010(struct flashctx *flash)
107{
108 uint8_t lock;
109 int ret;
110
111 lock = w39_idmode_readb(flash, 0x00002);
112 msg_cdbg("Bottom boot block:\n");
113 ret = printlock_w39_single_bootblock(lock, 8);
114
115 lock = w39_idmode_readb(flash, 0x1fff2);
116 msg_cdbg("Top boot block:\n");
117 ret |= printlock_w39_single_bootblock(lock, 8);
118
119 return ret;
120}
121
122int printlock_w39l020(struct flashctx *flash)
123{
124 uint8_t lock;
125 int ret;
126
127 lock = w39_idmode_readb(flash, 0x00002);
128 msg_cdbg("Bottom boot block:\n");
129 ret = printlock_w39_bootblock_64k16k(lock);
130
131 lock = w39_idmode_readb(flash, 0x3fff2);
132 msg_cdbg("Top boot block:\n");
133 ret |= printlock_w39_bootblock_64k16k(lock);
134
135 return ret;
136}
137
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000138int printlock_w39l040(struct flashctx *flash)
Michael Karcher19e0aac2011-03-06 17:58:05 +0000139{
140 uint8_t lock;
141 int ret;
142
143 lock = w39_idmode_readb(flash, 0x00002);
144 msg_cdbg("Bottom boot block:\n");
145 ret = printlock_w39_bootblock_64k16k(lock);
146
147 lock = w39_idmode_readb(flash, 0x7fff2);
148 msg_cdbg("Top boot block:\n");
149 ret |= printlock_w39_bootblock_64k16k(lock);
150
151 return ret;
152}
153
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000154int printlock_w39v040a(struct flashctx *flash)
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000155{
156 uint8_t lock;
157 int ret = 0;
158
159 /* The W39V040A datasheet contradicts itself on the lock register
160 * location: 0x00002 and 0x7fff2 are both mentioned. Pick the one
161 * which is similar to the other chips of the same family.
162 */
163 lock = w39_idmode_readb(flash, 0x7fff2);
164 msg_cdbg("Lockout bits:\n");
165
166 ret = printlock_w39_tblwp(lock);
167 ret |= printlock_w39_bootblock_64k16k(lock);
168
169 return ret;
170}
171
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000172int printlock_w39v040b(struct flashctx *flash)
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000173{
174 return printlock_w39_common(flash, 0x7fff2);
175}
176
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000177int printlock_w39v040c(struct flashctx *flash)
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000178{
179 /* Typo in the datasheet? The other chips use 0x7fff2. */
180 return printlock_w39_common(flash, 0xfff2);
181}
182
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000183int printlock_w39v040fa(struct flashctx *flash)
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000184{
185 int ret = 0;
186
187 ret = printlock_w39v040a(flash);
Carl-Daniel Hailfingeref3ac8a2014-08-03 13:05:34 +0000188 ret |= printlock_regspace2_uniform_64k(flash);
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000189
190 return ret;
191}
192
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000193int printlock_w39v040fb(struct flashctx *flash)
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000194{
195 int ret = 0;
196
197 ret = printlock_w39v040b(flash);
Carl-Daniel Hailfingeref3ac8a2014-08-03 13:05:34 +0000198 ret |= printlock_regspace2_uniform_64k(flash);
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000199
200 return ret;
201}
202
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000203int printlock_w39v040fc(struct flashctx *flash)
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000204{
205 int ret = 0;
206
207 /* W39V040C and W39V040FC use different WP/TBL offsets. */
208 ret = printlock_w39_common(flash, 0x7fff2);
Carl-Daniel Hailfingeref3ac8a2014-08-03 13:05:34 +0000209 ret |= printlock_regspace2_uniform_64k(flash);
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000210
211 return ret;
212}
213
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000214int printlock_w39v080a(struct flashctx *flash)
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000215{
216 return printlock_w39_common(flash, 0xffff2);
217}
218
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000219int printlock_w39v080fa(struct flashctx *flash)
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000220{
221 int ret = 0;
222
223 ret = printlock_w39v080a(flash);
Carl-Daniel Hailfingeref3ac8a2014-08-03 13:05:34 +0000224 ret |= printlock_regspace2_uniform_64k(flash);
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000225
226 return ret;
227}
228
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000229int printlock_w39v080fa_dual(struct flashctx *flash)
Carl-Daniel Hailfinger91882402010-12-05 16:33:59 +0000230{
231 msg_cinfo("Block locking for W39V080FA in dual mode is "
232 "undocumented.\n");
233 /* Better safe than sorry. */
234 return -1;
235}
236
David Borgf5a30f62012-04-15 13:16:32 +0000237int printlock_at49f(struct flashctx *flash)
238{
239 uint8_t lock = w39_idmode_readb(flash, 0x00002);
240 msg_cdbg("Hardware bootblock lockout is %sactive.\n",
241 (lock & 0x01) ? "" : "not ");
242 return 0;
243}