blob: aa93d6c85732553cd83385bf938343a50a1e9810 [file] [log] [blame]
hailfingerabe249e2009-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
David Hendricks39a32412011-03-24 17:14:01 -070021#include <stdio.h>
hailfingerabe249e2009-05-08 17:43:22 +000022#include <string.h>
23#include <stdlib.h>
David Hendricks39a32412011-03-24 17:14:01 -070024#include <stdarg.h>
hailfingerabe249e2009-05-08 17:43:22 +000025#include "flash.h"
hailfinger428f6852010-07-27 22:41:39 +000026#include "programmer.h"
hailfingerabe249e2009-05-08 17:43:22 +000027
hailfinger80422e22009-12-13 22:28:00 +000028#if NEED_PCI == 1
uwe6934c4a2009-05-14 18:57:26 +000029struct pci_dev *pci_dev_find_filter(struct pci_filter filter)
30{
31 struct pci_dev *temp;
32
33 for (temp = pacc->devices; temp; temp = temp->next)
34 if (pci_filter_match(&filter, temp))
35 return temp;
36
37 return NULL;
38}
39
uwe922946a2011-07-13 11:22:03 +000040struct pci_dev *pci_dev_find_vendorclass(uint16_t vendor, uint16_t devclass)
hailfinger07e3ce02009-11-15 17:13:29 +000041{
42 struct pci_dev *temp;
43 struct pci_filter filter;
44 uint16_t tmp2;
45
46 pci_filter_init(NULL, &filter);
47 filter.vendor = vendor;
48
49 for (temp = pacc->devices; temp; temp = temp->next)
50 if (pci_filter_match(&filter, temp)) {
51 /* Read PCI class */
52 tmp2 = pci_read_word(temp, 0x0a);
uwe922946a2011-07-13 11:22:03 +000053 if (tmp2 == devclass)
hailfinger07e3ce02009-11-15 17:13:29 +000054 return temp;
55 }
56
57 return NULL;
58}
59
hailfingerabe249e2009-05-08 17:43:22 +000060struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device)
61{
62 struct pci_dev *temp;
63 struct pci_filter filter;
64
65 pci_filter_init(NULL, &filter);
66 filter.vendor = vendor;
67 filter.device = device;
68
69 for (temp = pacc->devices; temp; temp = temp->next)
70 if (pci_filter_match(&filter, temp))
71 return temp;
72
73 return NULL;
74}
75
76struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
77 uint16_t card_vendor, uint16_t card_device)
78{
79 struct pci_dev *temp;
80 struct pci_filter filter;
81
82 pci_filter_init(NULL, &filter);
83 filter.vendor = vendor;
84 filter.device = device;
85
86 for (temp = pacc->devices; temp; temp = temp->next)
87 if (pci_filter_match(&filter, temp)) {
88 if ((card_vendor ==
89 pci_read_word(temp, PCI_SUBSYSTEM_VENDOR_ID))
90 && (card_device ==
91 pci_read_word(temp, PCI_SUBSYSTEM_ID)))
92 return temp;
93 }
94
95 return NULL;
96}
hailfinger80422e22009-12-13 22:28:00 +000097#endif
hailfingerabe249e2009-05-08 17:43:22 +000098
hailfinger90c7d542010-05-31 15:27:27 +000099#if CONFIG_INTERNAL == 1
mkarcherf2620582010-02-28 01:33:48 +0000100int force_boardenable = 0;
hailfingerf4aaccc2010-04-28 15:22:14 +0000101int force_boardmismatch = 0;
hailfingerc236f9e2009-12-22 23:42:04 +0000102
hailfinger324a9cc2010-05-26 01:45:41 +0000103#if defined(__i386__) || defined(__x86_64__)
hailfingerc236f9e2009-12-22 23:42:04 +0000104void probe_superio(void)
105{
hailfinger94e090c2011-04-27 14:34:08 +0000106 probe_superio_ite();
uwef6f94d42010-03-13 17:28:29 +0000107#if 0
108 /* Winbond Super I/O code is not yet available. */
hailfingerc236f9e2009-12-22 23:42:04 +0000109 if (superio.vendor == SUPERIO_VENDOR_NONE)
110 superio = probe_superio_winbond();
111#endif
112}
hailfinger94e090c2011-04-27 14:34:08 +0000113
114int superio_count = 0;
115#define SUPERIO_MAX_COUNT 3
116
117struct superio superios[SUPERIO_MAX_COUNT];
118
119int register_superio(struct superio s)
120{
121 if (superio_count == SUPERIO_MAX_COUNT)
122 return 1;
123 superios[superio_count++] = s;
124 return 0;
125}
126
hailfinger324a9cc2010-05-26 01:45:41 +0000127#endif
hailfingerc236f9e2009-12-22 23:42:04 +0000128
hailfinger324a9cc2010-05-26 01:45:41 +0000129int is_laptop = 0;
hailfingere52e9f82011-05-05 07:12:40 +0000130int laptop_ok = 0;
mkarcher287aa242010-02-26 09:51:20 +0000131
dhendrix0ffc2eb2011-06-14 01:35:36 +0000132static int internal_shutdown(void *data)
133{
134 release_io_perms();
135 return 0;
136}
David Hendricks80f62d22010-10-08 11:09:35 -0700137enum chipbustype target_bus;
hailfinger80422e22009-12-13 22:28:00 +0000138
David Hendricks6fae52e2011-03-24 18:50:18 -0700139#if NEED_PCI == 1
David Hendricks39a32412011-03-24 17:14:01 -0700140#define BUFSIZE 256
141static char buffer[BUFSIZE];
142
143static void
144pci_error(char *msg, ...)
145{
146 va_list args;
147
148 va_start(args, msg);
149 vsnprintf(buffer, BUFSIZE, msg, args);
150 va_end(args);
151
152 msg_perr("pcilib: %s\n", buffer);
153
154 /* libpci requires us to exit. TODO cleanup? */
155 exit(1);
156}
157
158static void
159pci_warning(char *msg, ...)
160{
161 va_list args;
162
163 va_start(args, msg);
164 vsnprintf(buffer, BUFSIZE, msg, args);
165 va_end(args);
166
167 msg_pinfo("pcilib: %s\n", buffer);
168}
169
170static void
171pci_debug(char *msg, ...)
172{
173 va_list args;
174
175 va_start(args, msg);
176 vsnprintf(buffer, BUFSIZE, msg, args);
177 va_end(args);
178
179 msg_pdbg("pcilib: %s\n", buffer);
180}
181#endif
dhendrix0ffc2eb2011-06-14 01:35:36 +0000182
uwebc526c82009-05-14 20:41:57 +0000183int internal_init(void)
184{
uweca168f82010-09-20 17:23:38 +0000185#if __FLASHROM_LITTLE_ENDIAN__
uwebc526c82009-05-14 20:41:57 +0000186 int ret = 0;
uweca168f82010-09-20 17:23:38 +0000187#endif
hailfingerf4aaccc2010-04-28 15:22:14 +0000188 int force_laptop = 0;
189 char *arg;
Louis Yung-Chieh Lo6b8f0462011-01-06 12:49:46 +0800190 int probe_target_bus_later = 0;
uwebc526c82009-05-14 20:41:57 +0000191
hailfingerddeb4ac2010-07-08 10:13:37 +0000192 arg = extract_programmer_param("boardenable");
hailfingerf4aaccc2010-04-28 15:22:14 +0000193 if (arg && !strcmp(arg,"force")) {
194 force_boardenable = 1;
195 } else if (arg && !strlen(arg)) {
196 msg_perr("Missing argument for boardenable.\n");
hailfinger1ef766d2010-07-06 09:55:48 +0000197 free(arg);
198 return 1;
hailfingerf4aaccc2010-04-28 15:22:14 +0000199 } else if (arg) {
200 msg_perr("Unknown argument for boardenable: %s\n", arg);
hailfinger1ef766d2010-07-06 09:55:48 +0000201 free(arg);
202 return 1;
mkarcherf2620582010-02-28 01:33:48 +0000203 }
hailfingerf4aaccc2010-04-28 15:22:14 +0000204 free(arg);
mkarcherf2620582010-02-28 01:33:48 +0000205
hailfingerddeb4ac2010-07-08 10:13:37 +0000206 arg = extract_programmer_param("boardmismatch");
hailfingerf4aaccc2010-04-28 15:22:14 +0000207 if (arg && !strcmp(arg,"force")) {
208 force_boardmismatch = 1;
209 } else if (arg && !strlen(arg)) {
210 msg_perr("Missing argument for boardmismatch.\n");
hailfinger1ef766d2010-07-06 09:55:48 +0000211 free(arg);
212 return 1;
hailfingerf4aaccc2010-04-28 15:22:14 +0000213 } else if (arg) {
214 msg_perr("Unknown argument for boardmismatch: %s\n", arg);
hailfinger1ef766d2010-07-06 09:55:48 +0000215 free(arg);
216 return 1;
mkarcherf2620582010-02-28 01:33:48 +0000217 }
hailfingerf4aaccc2010-04-28 15:22:14 +0000218 free(arg);
219
hailfingerddeb4ac2010-07-08 10:13:37 +0000220 arg = extract_programmer_param("laptop");
hailfingerf4aaccc2010-04-28 15:22:14 +0000221 if (arg && !strcmp(arg,"force_I_want_a_brick")) {
222 force_laptop = 1;
223 } else if (arg && !strlen(arg)) {
224 msg_perr("Missing argument for laptop.\n");
hailfinger1ef766d2010-07-06 09:55:48 +0000225 free(arg);
226 return 1;
hailfingerf4aaccc2010-04-28 15:22:14 +0000227 } else if (arg) {
228 msg_perr("Unknown argument for laptop: %s\n", arg);
hailfinger1ef766d2010-07-06 09:55:48 +0000229 free(arg);
230 return 1;
hailfingerf4aaccc2010-04-28 15:22:14 +0000231 }
232 free(arg);
233
David Hendricks80f62d22010-10-08 11:09:35 -0700234 arg = extract_programmer_param("bus");
235 if (arg) {
236 if (!strcasecmp(arg,"parallel")) {
hailfingere1e41ea2011-07-27 07:13:06 +0000237 target_bus = BUS_PARALLEL;
David Hendricks80f62d22010-10-08 11:09:35 -0700238 } else if (!strcasecmp(arg,"lpc")) {
hailfingere1e41ea2011-07-27 07:13:06 +0000239 target_bus = BUS_LPC;
David Hendricks80f62d22010-10-08 11:09:35 -0700240 } else if (!strcasecmp(arg,"fwh")) {
hailfingere1e41ea2011-07-27 07:13:06 +0000241 target_bus = BUS_FWH;
David Hendricks80f62d22010-10-08 11:09:35 -0700242 } else if (!strcasecmp(arg,"spi")) {
hailfingere1e41ea2011-07-27 07:13:06 +0000243 target_bus = BUS_SPI;
David Hendricks80f62d22010-10-08 11:09:35 -0700244 } else {
David Hendricks80f62d22010-10-08 11:09:35 -0700245 free(arg);
246 return 1;
247 }
248
249 free(arg);
Louis Yung-Chieh Lo6b8f0462011-01-06 12:49:46 +0800250 } else {
251 /* The pacc must be initialized before access pci devices. */
252 probe_target_bus_later = 1;
David Hendricks80f62d22010-10-08 11:09:35 -0700253 }
254
hailfinger0668eba2009-05-14 21:41:10 +0000255 get_io_perms();
dhendrix0ffc2eb2011-06-14 01:35:36 +0000256 if (register_shutdown(internal_shutdown, NULL))
257 return 1;
hailfingerabe249e2009-05-08 17:43:22 +0000258
mkarcherd264e9e2011-05-11 17:07:07 +0000259 /* Default to Parallel/LPC/FWH flash devices. If a known host controller
260 * is found, the init routine sets the buses_supported bitfield.
261 */
hailfingere1e41ea2011-07-27 07:13:06 +0000262 buses_supported = BUS_NONSPI;
mkarcherd264e9e2011-05-11 17:07:07 +0000263
David Hendrickscb2cec32011-03-24 18:44:49 -0700264#if defined(__i386__) || defined(__x86_64__)
hailfingerabe249e2009-05-08 17:43:22 +0000265 /* Initialize PCI access for flash enables */
266 pacc = pci_alloc(); /* Get the pci_access structure */
David Hendricks39a32412011-03-24 17:14:01 -0700267 pacc->error = pci_error;
268 pacc->warning = pci_warning;
269 pacc->debug = pci_debug;
270
hailfingerabe249e2009-05-08 17:43:22 +0000271 /* Set all options you want -- here we stick with the defaults */
272 pci_init(pacc); /* Initialize the PCI library */
273 pci_scan_bus(pacc); /* We want to get the list of devices */
David Hendrickscb2cec32011-03-24 18:44:49 -0700274#endif
hailfingerabe249e2009-05-08 17:43:22 +0000275
hailfinger586f4ae2010-06-04 19:05:39 +0000276 if (processor_flash_enable()) {
277 msg_perr("Processor detection/init failed.\n"
278 "Aborting.\n");
279 return 1;
280 }
281
282#if defined(__i386__) || defined(__x86_64__)
283 /* We look at the cbtable first to see if we need a
hailfingerabe249e2009-05-08 17:43:22 +0000284 * mainboard specific flash enable sequence.
285 */
286 coreboot_init();
hailfinger324a9cc2010-05-26 01:45:41 +0000287
David Hendricks8e806e62011-07-12 16:45:59 -0700288 /* FIXME: Removed to avoid annoying laptop warnings */
289 //dmi_init();
hailfingerabe249e2009-05-08 17:43:22 +0000290
Louis Yung-Chieh Lo6b8f0462011-01-06 12:49:46 +0800291 if (probe_target_bus_later) {
292 /* read the target bus value from register. */
293 if (get_target_bus_from_chipset(&target_bus)) {
hailfinger969e2f32011-09-08 00:00:29 +0000294 msg_perr("Cannot get target bus from programmer.\n");
Louis Yung-Chieh Lo6b8f0462011-01-06 12:49:46 +0800295 return 1;
296 }
Louis Yung-Chieh Lo8381f152011-10-31 15:45:04 +0800297 msg_pdbg("get_target_bus_from_chipset() returns 0x%x.\n",
298 target_bus);
Louis Yung-Chieh Lo6b8f0462011-01-06 12:49:46 +0800299 }
300
hailfingere52e9f82011-05-05 07:12:40 +0000301 /* In case Super I/O probing would cause pretty explosions. */
302 board_handle_before_superio();
303
uwef6f94d42010-03-13 17:28:29 +0000304 /* Probe for the Super I/O chip and fill global struct superio. */
hailfingerc236f9e2009-12-22 23:42:04 +0000305 probe_superio();
David Hendrickscf239a82011-03-24 19:06:23 -0700306
307#elif defined(__arm__)
308 /* We look at the cbtable first to see if we need a
309 * mainboard specific flash enable sequence.
310 */
311 coreboot_init();
312
hailfinger586f4ae2010-06-04 19:05:39 +0000313#else
314 /* FIXME: Enable cbtable searching on all non-x86 platforms supported
315 * by coreboot.
316 * FIXME: Find a replacement for DMI on non-x86.
317 * FIXME: Enable Super I/O probing once port I/O is possible.
318 */
hailfinger324a9cc2010-05-26 01:45:41 +0000319#endif
hailfingerc236f9e2009-12-22 23:42:04 +0000320
hailfingere52e9f82011-05-05 07:12:40 +0000321 /* Check laptop whitelist. */
322 board_handle_before_laptop();
323
324 /* Warn if a non-whitelisted laptop is detected. */
325 if (is_laptop && !laptop_ok) {
stefanct674e81e2011-07-26 00:54:42 +0000326 msg_perr("========================================================================\n");
327 if (is_laptop == 1) {
328 msg_perr("WARNING! You seem to be running flashrom on an unsupported laptop.\n");
329 } else {
330 msg_perr("WARNING! You may be running flashrom on an unsupported laptop. We could\n"
331 "not detect this for sure because your vendor has not setup the SMBIOS\n"
332 "tables correctly. You can enforce execution by adding\n"
333 "'-p internal:laptop=force_I_want_a_brick' to the command line, but\n"
334 "please read the following warning if you are not sure.\n\n");
335 }
336 msg_perr("Laptops, notebooks and netbooks are difficult to support and we\n"
337 "recommend to use the vendor flashing utility. The embedded controller\n"
338 "(EC) in these machines often interacts badly with flashing.\n"
hailfingerf4aaccc2010-04-28 15:22:14 +0000339 "See http://www.flashrom.org/Laptops for details.\n\n"
340 "If flash is shared with the EC, erase is guaranteed to brick your laptop\n"
341 "and write may brick your laptop.\n"
342 "Read and probe may irritate your EC and cause fan failure, backlight\n"
343 "failure and sudden poweroff.\n"
344 "You have been warned.\n"
345 "========================================================================\n");
stefanct674e81e2011-07-26 00:54:42 +0000346
hailfingerf4aaccc2010-04-28 15:22:14 +0000347 if (force_laptop) {
348 msg_perr("Proceeding anyway because user specified "
349 "laptop=force_I_want_a_brick\n");
350 } else {
351 msg_perr("Aborting.\n");
352 exit(1);
353 }
354 }
mkarcher287aa242010-02-26 09:51:20 +0000355
hailfinger586f4ae2010-06-04 19:05:39 +0000356#if __FLASHROM_LITTLE_ENDIAN__
David Hendricks351c9962011-03-25 11:44:35 -0700357#if defined(__i386__) || defined(__x86_64__) || defined (__mips__)
hailfingerabe249e2009-05-08 17:43:22 +0000358 /* try to enable it. Failure IS an option, since not all motherboards
359 * really need this to be done, etc., etc.
360 */
361 ret = chipset_flash_enable();
362 if (ret == -2) {
hailfingerf4aaccc2010-04-28 15:22:14 +0000363 msg_perr("WARNING: No chipset found. Flash detection "
364 "will most likely fail.\n");
uwe97e8e272011-09-03 17:15:00 +0000365 } else if (ret == ERROR_FATAL)
366 return ret;
David Hendricks351c9962011-03-25 11:44:35 -0700367#endif
hailfingerabe249e2009-05-08 17:43:22 +0000368
hailfinger324a9cc2010-05-26 01:45:41 +0000369#if defined(__i386__) || defined(__x86_64__)
hailfingerc73ce6e2010-07-10 16:56:32 +0000370 /* Probe unconditionally for IT87* LPC->SPI translation and for
371 * IT87* Parallel write enable.
372 */
373 init_superio_ite();
David Hendricksc801adb2010-12-09 16:58:56 -0800374
David Hendrickse18bbc62010-12-28 17:50:05 -0800375 /* probe for programmers that bridge LPC <--> SPI */
hailfingere1e41ea2011-07-27 07:13:06 +0000376 if (target_bus == BUS_LPC ||
377 target_bus == BUS_FWH) {
David Hendricks91040832011-07-08 20:01:09 -0700378 /* note: it85xx init done along with it87* init */
David Hendrickse18bbc62010-12-28 17:50:05 -0800379 wpce775x_probe_spi_flash(NULL);
David Hendricks46d32e32011-01-19 16:01:52 -0800380 mec1308_probe_spi_flash(NULL);
David Hendrickse18bbc62010-12-28 17:50:05 -0800381 }
382
hailfinger324a9cc2010-05-26 01:45:41 +0000383#endif
hailfingerddd5d7b2010-03-25 02:50:40 +0000384
hailfingerabe249e2009-05-08 17:43:22 +0000385 board_flash_enable(lb_vendor, lb_part);
386
hailfinger681638b2009-09-02 13:43:56 +0000387 /* Even if chipset init returns an error code, we don't want to abort.
388 * The error code might have been a warning only.
389 * Besides that, we don't check the board enable return code either.
390 */
David Hendrickscf239a82011-03-24 19:06:23 -0700391#if defined(__i386__) || defined(__x86_64__) || defined (__mips) || defined (__arm__)
hailfingerf4aaccc2010-04-28 15:22:14 +0000392 return 0;
hailfinger586f4ae2010-06-04 19:05:39 +0000393#else
394 msg_perr("Your platform is not supported yet for the internal "
395 "programmer due to missing\n"
396 "flash_base and top/bottom alignment information.\n"
397 "Aborting.\n");
398 return 1;
399#endif
400#else
401 /* FIXME: Remove this unconditional abort once all PCI drivers are
402 * converted to use little-endian accesses for memory BARs.
403 */
404 msg_perr("Your platform is not supported yet for the internal "
405 "programmer because it has\n"
406 "not been converted from native endian to little endian "
407 "access yet.\n"
408 "Aborting.\n");
409 return 1;
410#endif
hailfingerabe249e2009-05-08 17:43:22 +0000411}
hailfinger80422e22009-12-13 22:28:00 +0000412#endif
hailfingerabe249e2009-05-08 17:43:22 +0000413
hailfinger82719632009-05-16 21:22:56 +0000414void internal_chip_writeb(uint8_t val, chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000415{
hailfinger38da6812009-05-17 15:49:24 +0000416 mmio_writeb(val, (void *) addr);
hailfingerabe249e2009-05-08 17:43:22 +0000417}
418
hailfinger82719632009-05-16 21:22:56 +0000419void internal_chip_writew(uint16_t val, chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000420{
hailfinger38da6812009-05-17 15:49:24 +0000421 mmio_writew(val, (void *) addr);
hailfingerabe249e2009-05-08 17:43:22 +0000422}
423
hailfinger82719632009-05-16 21:22:56 +0000424void internal_chip_writel(uint32_t val, chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000425{
hailfinger38da6812009-05-17 15:49:24 +0000426 mmio_writel(val, (void *) addr);
hailfingerabe249e2009-05-08 17:43:22 +0000427}
428
hailfinger82719632009-05-16 21:22:56 +0000429uint8_t internal_chip_readb(const chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000430{
hailfinger38da6812009-05-17 15:49:24 +0000431 return mmio_readb((void *) addr);
hailfingerabe249e2009-05-08 17:43:22 +0000432}
433
hailfinger82719632009-05-16 21:22:56 +0000434uint16_t internal_chip_readw(const chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000435{
hailfinger38da6812009-05-17 15:49:24 +0000436 return mmio_readw((void *) addr);
hailfingerabe249e2009-05-08 17:43:22 +0000437}
438
hailfinger82719632009-05-16 21:22:56 +0000439uint32_t internal_chip_readl(const chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000440{
hailfinger38da6812009-05-17 15:49:24 +0000441 return mmio_readl((void *) addr);
442}
443
hailfinger9d987ef2009-06-05 18:32:07 +0000444void internal_chip_readn(uint8_t *buf, const chipaddr addr, size_t len)
445{
446 memcpy(buf, (void *)addr, len);
447 return;
448}