blob: 5716e6412458e02c80466b10a4b189df9aed171e [file] [log] [blame]
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +00001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2009 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; 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
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000021#include <string.h>
22#include <stdlib.h>
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000023#include "flash.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000024#include "programmer.h"
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000025
Carl-Daniel Hailfinger66ef4e52009-12-13 22:28:00 +000026#if NEED_PCI == 1
Christian Ruppert0cdb0312009-05-14 18:57:26 +000027struct pci_dev *pci_dev_find_filter(struct pci_filter filter)
28{
29 struct pci_dev *temp;
30
31 for (temp = pacc->devices; temp; temp = temp->next)
32 if (pci_filter_match(&filter, temp))
33 return temp;
34
35 return NULL;
36}
37
Uwe Hermann24c35e42011-07-13 11:22:03 +000038struct pci_dev *pci_dev_find_vendorclass(uint16_t vendor, uint16_t devclass)
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000039{
40 struct pci_dev *temp;
41 struct pci_filter filter;
42 uint16_t tmp2;
43
44 pci_filter_init(NULL, &filter);
45 filter.vendor = vendor;
46
47 for (temp = pacc->devices; temp; temp = temp->next)
48 if (pci_filter_match(&filter, temp)) {
49 /* Read PCI class */
50 tmp2 = pci_read_word(temp, 0x0a);
Uwe Hermann24c35e42011-07-13 11:22:03 +000051 if (tmp2 == devclass)
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000052 return temp;
53 }
54
55 return NULL;
56}
57
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000058struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device)
59{
60 struct pci_dev *temp;
61 struct pci_filter filter;
62
63 pci_filter_init(NULL, &filter);
64 filter.vendor = vendor;
65 filter.device = device;
66
67 for (temp = pacc->devices; temp; temp = temp->next)
68 if (pci_filter_match(&filter, temp))
69 return temp;
70
71 return NULL;
72}
73
74struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
75 uint16_t card_vendor, uint16_t card_device)
76{
77 struct pci_dev *temp;
78 struct pci_filter filter;
79
80 pci_filter_init(NULL, &filter);
81 filter.vendor = vendor;
82 filter.device = device;
83
84 for (temp = pacc->devices; temp; temp = temp->next)
85 if (pci_filter_match(&filter, temp)) {
86 if ((card_vendor ==
87 pci_read_word(temp, PCI_SUBSYSTEM_VENDOR_ID))
88 && (card_device ==
89 pci_read_word(temp, PCI_SUBSYSTEM_ID)))
90 return temp;
91 }
92
93 return NULL;
94}
Carl-Daniel Hailfinger66ef4e52009-12-13 22:28:00 +000095#endif
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000096
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +000097#if CONFIG_INTERNAL == 1
Michael Karcher0bdc0922010-02-28 01:33:48 +000098int force_boardenable = 0;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +000099int force_boardmismatch = 0;
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000100
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000101#if defined(__i386__) || defined(__x86_64__)
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000102void probe_superio(void)
103{
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +0000104 probe_superio_ite();
Uwe Hermann43959702010-03-13 17:28:29 +0000105#if 0
106 /* Winbond Super I/O code is not yet available. */
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000107 if (superio.vendor == SUPERIO_VENDOR_NONE)
108 superio = probe_superio_winbond();
109#endif
110}
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +0000111
112int superio_count = 0;
113#define SUPERIO_MAX_COUNT 3
114
115struct superio superios[SUPERIO_MAX_COUNT];
116
117int register_superio(struct superio s)
118{
119 if (superio_count == SUPERIO_MAX_COUNT)
120 return 1;
121 superios[superio_count++] = s;
122 return 0;
123}
124
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000125#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000126
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000127int is_laptop = 0;
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000128int laptop_ok = 0;
Michael Karcher8c1df282010-02-26 09:51:20 +0000129
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000130static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
131 chipaddr addr);
132static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
133 chipaddr addr);
134static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
135 chipaddr addr);
136static uint8_t internal_chip_readb(const struct flashctx *flash,
137 const chipaddr addr);
138static uint16_t internal_chip_readw(const struct flashctx *flash,
139 const chipaddr addr);
140static uint32_t internal_chip_readl(const struct flashctx *flash,
141 const chipaddr addr);
142static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
143 const chipaddr addr, size_t len);
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000144static const struct par_programmer par_programmer_internal = {
145 .chip_readb = internal_chip_readb,
146 .chip_readw = internal_chip_readw,
147 .chip_readl = internal_chip_readl,
148 .chip_readn = internal_chip_readn,
149 .chip_writeb = internal_chip_writeb,
150 .chip_writew = internal_chip_writew,
151 .chip_writel = internal_chip_writel,
152 .chip_writen = fallback_chip_writen,
153};
154
155enum chipbustype internal_buses_supported = BUS_NONE;
156
David Hendricks8bb20212011-06-14 01:35:36 +0000157static int internal_shutdown(void *data)
158{
159 release_io_perms();
160 return 0;
161}
162
Uwe Hermanna0869322009-05-14 20:41:57 +0000163int internal_init(void)
164{
Peter Lemenkov0a6f9ca2010-09-20 17:23:38 +0000165#if __FLASHROM_LITTLE_ENDIAN__
Uwe Hermanna0869322009-05-14 20:41:57 +0000166 int ret = 0;
Peter Lemenkov0a6f9ca2010-09-20 17:23:38 +0000167#endif
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000168 int force_laptop = 0;
Stefan Taunera28087f2011-09-13 23:14:25 +0000169 int not_a_laptop = 0;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000170 char *arg;
Uwe Hermanna0869322009-05-14 20:41:57 +0000171
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000172 arg = extract_programmer_param("boardenable");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000173 if (arg && !strcmp(arg,"force")) {
174 force_boardenable = 1;
175 } else if (arg && !strlen(arg)) {
176 msg_perr("Missing argument for boardenable.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000177 free(arg);
178 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000179 } else if (arg) {
180 msg_perr("Unknown argument for boardenable: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000181 free(arg);
182 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000183 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000184 free(arg);
Michael Karcher0bdc0922010-02-28 01:33:48 +0000185
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000186 arg = extract_programmer_param("boardmismatch");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000187 if (arg && !strcmp(arg,"force")) {
188 force_boardmismatch = 1;
189 } else if (arg && !strlen(arg)) {
190 msg_perr("Missing argument for boardmismatch.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000191 free(arg);
192 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000193 } else if (arg) {
194 msg_perr("Unknown argument for boardmismatch: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000195 free(arg);
196 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000197 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000198 free(arg);
199
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000200 arg = extract_programmer_param("laptop");
Stefan Taunera28087f2011-09-13 23:14:25 +0000201 if (arg && !strcmp(arg, "force_I_want_a_brick"))
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000202 force_laptop = 1;
Stefan Taunera28087f2011-09-13 23:14:25 +0000203 else if (arg && !strcmp(arg, "this_is_not_a_laptop"))
204 not_a_laptop = 1;
205 else if (arg && !strlen(arg)) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000206 msg_perr("Missing argument for laptop.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000207 free(arg);
208 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000209 } else if (arg) {
210 msg_perr("Unknown argument for laptop: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000211 free(arg);
212 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000213 }
214 free(arg);
215
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000216 arg = extract_programmer_param("mainboard");
217 if (arg && strlen(arg)) {
218 lb_vendor_dev_from_string(arg);
219 } else if (arg && !strlen(arg)) {
220 msg_perr("Missing argument for mainboard.\n");
221 free(arg);
222 return 1;
223 }
224 free(arg);
225
Carl-Daniel Hailfinger3b7e75a2009-05-14 21:41:10 +0000226 get_io_perms();
David Hendricks8bb20212011-06-14 01:35:36 +0000227 if (register_shutdown(internal_shutdown, NULL))
228 return 1;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000229
Michael Karcherb9dbe482011-05-11 17:07:07 +0000230 /* Default to Parallel/LPC/FWH flash devices. If a known host controller
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000231 * is found, the host controller init routine sets the
232 * internal_buses_supported bitfield.
Michael Karcherb9dbe482011-05-11 17:07:07 +0000233 */
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000234 internal_buses_supported = BUS_NONSPI;
Michael Karcherb9dbe482011-05-11 17:07:07 +0000235
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000236 /* Initialize PCI access for flash enables */
237 pacc = pci_alloc(); /* Get the pci_access structure */
238 /* Set all options you want -- here we stick with the defaults */
239 pci_init(pacc); /* Initialize the PCI library */
240 pci_scan_bus(pacc); /* We want to get the list of devices */
241
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000242 if (processor_flash_enable()) {
243 msg_perr("Processor detection/init failed.\n"
244 "Aborting.\n");
245 return 1;
246 }
247
248#if defined(__i386__) || defined(__x86_64__)
249 /* We look at the cbtable first to see if we need a
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000250 * mainboard specific flash enable sequence.
251 */
252 coreboot_init();
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000253
Michael Karcher6701ee82010-01-20 14:14:11 +0000254 dmi_init();
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000255
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000256 /* In case Super I/O probing would cause pretty explosions. */
257 board_handle_before_superio();
258
Uwe Hermann43959702010-03-13 17:28:29 +0000259 /* Probe for the Super I/O chip and fill global struct superio. */
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000260 probe_superio();
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000261#else
262 /* FIXME: Enable cbtable searching on all non-x86 platforms supported
263 * by coreboot.
264 * FIXME: Find a replacement for DMI on non-x86.
265 * FIXME: Enable Super I/O probing once port I/O is possible.
266 */
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000267#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000268
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000269 /* Check laptop whitelist. */
270 board_handle_before_laptop();
271
272 /* Warn if a non-whitelisted laptop is detected. */
273 if (is_laptop && !laptop_ok) {
Stefan Taunera34d7192011-07-26 00:54:42 +0000274 msg_perr("========================================================================\n");
275 if (is_laptop == 1) {
276 msg_perr("WARNING! You seem to be running flashrom on an unsupported laptop.\n");
277 } else {
278 msg_perr("WARNING! You may be running flashrom on an unsupported laptop. We could\n"
279 "not detect this for sure because your vendor has not setup the SMBIOS\n"
280 "tables correctly. You can enforce execution by adding\n"
Stefan Taunera28087f2011-09-13 23:14:25 +0000281 "'-p internal:laptop=this_is_not_a_laptop' to the command line, but\n"
Stefan Taunera34d7192011-07-26 00:54:42 +0000282 "please read the following warning if you are not sure.\n\n");
283 }
284 msg_perr("Laptops, notebooks and netbooks are difficult to support and we\n"
285 "recommend to use the vendor flashing utility. The embedded controller\n"
286 "(EC) in these machines often interacts badly with flashing.\n"
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000287 "See http://www.flashrom.org/Laptops for details.\n\n"
288 "If flash is shared with the EC, erase is guaranteed to brick your laptop\n"
289 "and write may brick your laptop.\n"
290 "Read and probe may irritate your EC and cause fan failure, backlight\n"
291 "failure and sudden poweroff.\n"
292 "You have been warned.\n"
293 "========================================================================\n");
Stefan Taunera34d7192011-07-26 00:54:42 +0000294
Stefan Taunera28087f2011-09-13 23:14:25 +0000295 if (force_laptop || (not_a_laptop && (is_laptop == 2))) {
296 msg_perr("Proceeding anyway because user forced us to.\n");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000297 } else {
298 msg_perr("Aborting.\n");
299 exit(1);
300 }
301 }
Michael Karcher8c1df282010-02-26 09:51:20 +0000302
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000303#if __FLASHROM_LITTLE_ENDIAN__
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000304 /* try to enable it. Failure IS an option, since not all motherboards
305 * really need this to be done, etc., etc.
306 */
307 ret = chipset_flash_enable();
308 if (ret == -2) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000309 msg_perr("WARNING: No chipset found. Flash detection "
310 "will most likely fail.\n");
Tadas Slotkusad470342011-09-03 17:15:00 +0000311 } else if (ret == ERROR_FATAL)
312 return ret;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000313
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000314#if defined(__i386__) || defined(__x86_64__)
Carl-Daniel Hailfinger76d4b372010-07-10 16:56:32 +0000315 /* Probe unconditionally for IT87* LPC->SPI translation and for
316 * IT87* Parallel write enable.
317 */
318 init_superio_ite();
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000319#endif
Carl-Daniel Hailfinger01f3ef42010-03-25 02:50:40 +0000320
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000321 board_flash_enable(lb_vendor, lb_part);
322
Carl-Daniel Hailfinger9246ff42009-09-02 13:43:56 +0000323 /* Even if chipset init returns an error code, we don't want to abort.
324 * The error code might have been a warning only.
325 * Besides that, we don't check the board enable return code either.
326 */
Vladimir 'phcoder' Serbinenko5cfc94a2010-09-29 23:37:24 +0000327#if defined(__i386__) || defined(__x86_64__) || defined (__mips)
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000328 register_par_programmer(&par_programmer_internal, internal_buses_supported);
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000329 return 0;
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000330#else
331 msg_perr("Your platform is not supported yet for the internal "
332 "programmer due to missing\n"
333 "flash_base and top/bottom alignment information.\n"
334 "Aborting.\n");
335 return 1;
336#endif
337#else
338 /* FIXME: Remove this unconditional abort once all PCI drivers are
339 * converted to use little-endian accesses for memory BARs.
340 */
341 msg_perr("Your platform is not supported yet for the internal "
342 "programmer because it has\n"
343 "not been converted from native endian to little endian "
344 "access yet.\n"
345 "Aborting.\n");
346 return 1;
347#endif
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000348}
Carl-Daniel Hailfinger66ef4e52009-12-13 22:28:00 +0000349#endif
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000350
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000351static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
352 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000353{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000354 mmio_writeb(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000355}
356
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000357static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
358 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000359{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000360 mmio_writew(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000361}
362
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000363static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
364 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000365{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000366 mmio_writel(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000367}
368
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000369static uint8_t internal_chip_readb(const struct flashctx *flash,
370 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000371{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000372 return mmio_readb((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000373}
374
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000375static uint16_t internal_chip_readw(const struct flashctx *flash,
376 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000377{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000378 return mmio_readw((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000379}
380
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000381static uint32_t internal_chip_readl(const struct flashctx *flash,
382 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000383{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000384 return mmio_readl((void *) addr);
385}
386
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000387static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
388 const chipaddr addr, size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000389{
390 memcpy(buf, (void *)addr, len);
391 return;
392}