blob: 12c0ba38926cdfe25a2d5f44a08b1fe28adb8a44 [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.
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000015 */
16
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +000017#include <strings.h>
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000018#include <string.h>
19#include <stdlib.h>
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000020#include "flash.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000021#include "programmer.h"
Patrick Georgi32508eb2012-07-20 20:35:14 +000022#include "hwaccess.h"
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000023
Uwe Hermann24c35e42011-07-13 11:22:03 +000024struct pci_dev *pci_dev_find_vendorclass(uint16_t vendor, uint16_t devclass)
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000025{
26 struct pci_dev *temp;
27 struct pci_filter filter;
28 uint16_t tmp2;
29
30 pci_filter_init(NULL, &filter);
31 filter.vendor = vendor;
32
33 for (temp = pacc->devices; temp; temp = temp->next)
34 if (pci_filter_match(&filter, temp)) {
35 /* Read PCI class */
36 tmp2 = pci_read_word(temp, 0x0a);
Uwe Hermann24c35e42011-07-13 11:22:03 +000037 if (tmp2 == devclass)
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000038 return temp;
39 }
40
41 return NULL;
42}
43
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000044struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device)
45{
46 struct pci_dev *temp;
47 struct pci_filter filter;
48
49 pci_filter_init(NULL, &filter);
50 filter.vendor = vendor;
51 filter.device = device;
52
53 for (temp = pacc->devices; temp; temp = temp->next)
54 if (pci_filter_match(&filter, temp))
55 return temp;
56
57 return NULL;
58}
59
60struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
61 uint16_t card_vendor, uint16_t card_device)
62{
63 struct pci_dev *temp;
64 struct pci_filter filter;
65
66 pci_filter_init(NULL, &filter);
67 filter.vendor = vendor;
68 filter.device = device;
69
70 for (temp = pacc->devices; temp; temp = temp->next)
71 if (pci_filter_match(&filter, temp)) {
72 if ((card_vendor ==
73 pci_read_word(temp, PCI_SUBSYSTEM_VENDOR_ID))
74 && (card_device ==
75 pci_read_word(temp, PCI_SUBSYSTEM_ID)))
76 return temp;
77 }
78
79 return NULL;
80}
81
Michael Karcher0bdc0922010-02-28 01:33:48 +000082int force_boardenable = 0;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +000083int force_boardmismatch = 0;
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000084
Nico Huberc8801732017-12-01 18:19:43 +000085#if IS_X86
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000086void probe_superio(void)
87{
Carl-Daniel Hailfingerf5e62cb2012-05-06 22:48:01 +000088 probe_superio_winbond();
89 /* ITE probe causes SMSC LPC47N217 to power off the serial UART.
90 * Always probe for SMSC first, and if a SMSC Super I/O is detected
91 * at a given I/O port, do _not_ probe that port with the ITE probe.
92 * This means SMSC probing must be done before ITE probing.
93 */
94 //probe_superio_smsc();
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +000095 probe_superio_ite();
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000096}
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +000097
98int superio_count = 0;
99#define SUPERIO_MAX_COUNT 3
100
101struct superio superios[SUPERIO_MAX_COUNT];
102
103int register_superio(struct superio s)
104{
105 if (superio_count == SUPERIO_MAX_COUNT)
106 return 1;
107 superios[superio_count++] = s;
108 return 0;
109}
110
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000111#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000112
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000113int is_laptop = 0;
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000114int laptop_ok = 0;
Michael Karcher8c1df282010-02-26 09:51:20 +0000115
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000116static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
117 chipaddr addr);
118static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
119 chipaddr addr);
120static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
121 chipaddr addr);
122static uint8_t internal_chip_readb(const struct flashctx *flash,
123 const chipaddr addr);
124static uint16_t internal_chip_readw(const struct flashctx *flash,
125 const chipaddr addr);
126static uint32_t internal_chip_readl(const struct flashctx *flash,
127 const chipaddr addr);
128static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
129 const chipaddr addr, size_t len);
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000130static const struct par_master par_master_internal = {
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000131 .chip_readb = internal_chip_readb,
132 .chip_readw = internal_chip_readw,
133 .chip_readl = internal_chip_readl,
134 .chip_readn = internal_chip_readn,
135 .chip_writeb = internal_chip_writeb,
136 .chip_writew = internal_chip_writew,
137 .chip_writel = internal_chip_writel,
138 .chip_writen = fallback_chip_writen,
139};
140
141enum chipbustype internal_buses_supported = BUS_NONE;
142
Uwe Hermanna0869322009-05-14 20:41:57 +0000143int internal_init(void)
144{
145 int ret = 0;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000146 int force_laptop = 0;
Stefan Taunera28087f2011-09-13 23:14:25 +0000147 int not_a_laptop = 0;
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000148 const char *board_vendor = NULL;
149 const char *board_model = NULL;
Nico Huberc8801732017-12-01 18:19:43 +0000150#if IS_X86
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000151 const char *cb_vendor = NULL;
152 const char *cb_model = NULL;
Carl-Daniel Hailfinger11990da2013-07-13 23:21:05 +0000153#endif
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000154 char *arg;
Uwe Hermanna0869322009-05-14 20:41:57 +0000155
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000156 arg = extract_programmer_param("boardenable");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000157 if (arg && !strcmp(arg,"force")) {
158 force_boardenable = 1;
159 } else if (arg && !strlen(arg)) {
160 msg_perr("Missing argument for boardenable.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000161 free(arg);
162 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000163 } else if (arg) {
164 msg_perr("Unknown argument for boardenable: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000165 free(arg);
166 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000167 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000168 free(arg);
Michael Karcher0bdc0922010-02-28 01:33:48 +0000169
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000170 arg = extract_programmer_param("boardmismatch");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000171 if (arg && !strcmp(arg,"force")) {
172 force_boardmismatch = 1;
173 } else if (arg && !strlen(arg)) {
174 msg_perr("Missing argument for boardmismatch.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000175 free(arg);
176 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000177 } else if (arg) {
178 msg_perr("Unknown argument for boardmismatch: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000179 free(arg);
180 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000181 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000182 free(arg);
183
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000184 arg = extract_programmer_param("laptop");
Stefan Taunera28087f2011-09-13 23:14:25 +0000185 if (arg && !strcmp(arg, "force_I_want_a_brick"))
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000186 force_laptop = 1;
Stefan Taunera28087f2011-09-13 23:14:25 +0000187 else if (arg && !strcmp(arg, "this_is_not_a_laptop"))
188 not_a_laptop = 1;
189 else if (arg && !strlen(arg)) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000190 msg_perr("Missing argument for laptop.\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 laptop: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000195 free(arg);
196 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000197 }
198 free(arg);
199
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000200 arg = extract_programmer_param("mainboard");
201 if (arg && strlen(arg)) {
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000202 if (board_parse_parameter(arg, &board_vendor, &board_model)) {
203 free(arg);
204 return 1;
205 }
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000206 } else if (arg && !strlen(arg)) {
207 msg_perr("Missing argument for mainboard.\n");
208 free(arg);
209 return 1;
210 }
211 free(arg);
212
Carl-Daniel Hailfingerd6bb8282012-07-21 17:27:08 +0000213 if (rget_io_perms())
214 return 1;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000215
Michael Karcherb9dbe482011-05-11 17:07:07 +0000216 /* Default to Parallel/LPC/FWH flash devices. If a known host controller
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000217 * is found, the host controller init routine sets the
218 * internal_buses_supported bitfield.
Michael Karcherb9dbe482011-05-11 17:07:07 +0000219 */
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000220 internal_buses_supported = BUS_NONSPI;
Michael Karcherb9dbe482011-05-11 17:07:07 +0000221
David Hendricksf9a30552015-05-23 20:30:30 -0700222 if (try_mtd() == 0)
223 return 0;
224
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000225 /* Initialize PCI access for flash enables */
Stefan Tauner55619552013-01-04 22:24:58 +0000226 if (pci_init_common() != 0)
227 return 1;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000228
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000229 if (processor_flash_enable()) {
230 msg_perr("Processor detection/init failed.\n"
231 "Aborting.\n");
232 return 1;
233 }
234
Nico Huberc8801732017-12-01 18:19:43 +0000235#if IS_X86
Stefan Taunerfa9fa712012-09-24 21:29:29 +0000236 if ((cb_parse_table(&cb_vendor, &cb_model) == 0) && (board_vendor != NULL) && (board_model != NULL)) {
237 if (strcasecmp(board_vendor, cb_vendor) || strcasecmp(board_model, cb_model)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000238 msg_pwarn("Warning: The mainboard IDs set by -p internal:mainboard (%s:%s) do not\n"
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000239 " match the current coreboot IDs of the mainboard (%s:%s).\n",
240 board_vendor, board_model, cb_vendor, cb_model);
241 if (!force_boardmismatch)
242 return 1;
243 msg_pinfo("Continuing anyway.\n");
244 }
245 }
Carl-Daniel Hailfinger11990da2013-07-13 23:21:05 +0000246#endif
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000247
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000248#if IS_X86
Nico Huber2e50cdc2018-09-23 20:20:26 +0200249 is_laptop = 2; /* Assume that we don't know by default. */
250
Michael Karcher6701ee82010-01-20 14:14:11 +0000251 dmi_init();
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000252
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000253 /* In case Super I/O probing would cause pretty explosions. */
254 board_handle_before_superio();
255
Uwe Hermann43959702010-03-13 17:28:29 +0000256 /* Probe for the Super I/O chip and fill global struct superio. */
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000257 probe_superio();
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000258#else
259 /* FIXME: Enable cbtable searching on all non-x86 platforms supported
260 * by coreboot.
261 * FIXME: Find a replacement for DMI on non-x86.
262 * FIXME: Enable Super I/O probing once port I/O is possible.
263 */
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000264#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000265
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000266 /* Check laptop whitelist. */
267 board_handle_before_laptop();
268
Nico Huber2e50cdc2018-09-23 20:20:26 +0200269 /*
270 * Disable all internal buses by default if we are not sure
271 * this isn't a laptop. Board-enables may override this,
272 * non-legacy buses (SPI and opaque atm) are probed anyway.
273 */
274 if (is_laptop && !(laptop_ok || force_laptop || (not_a_laptop && is_laptop == 2)))
275 internal_buses_supported = BUS_NONE;
Michael Karcher8c1df282010-02-26 09:51:20 +0000276
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000277 /* try to enable it. Failure IS an option, since not all motherboards
278 * really need this to be done, etc., etc.
279 */
280 ret = chipset_flash_enable();
281 if (ret == -2) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000282 msg_perr("WARNING: No chipset found. Flash detection "
283 "will most likely fail.\n");
Tadas Slotkusad470342011-09-03 17:15:00 +0000284 } else if (ret == ERROR_FATAL)
285 return ret;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000286
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000287#if IS_X86
Vadim Girlin4dd0f902013-08-24 12:18:17 +0000288 /* Probe unconditionally for ITE Super I/O chips. This enables LPC->SPI translation on IT87* and
289 * parallel writes on IT8705F. Also, this handles the manual chip select for Gigabyte's DualBIOS. */
Carl-Daniel Hailfinger76d4b372010-07-10 16:56:32 +0000290 init_superio_ite();
Carl-Daniel Hailfinger01f3ef42010-03-25 02:50:40 +0000291
Stefan Taunerfa9fa712012-09-24 21:29:29 +0000292 if (board_flash_enable(board_vendor, board_model, cb_vendor, cb_model)) {
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000293 msg_perr("Aborting to be safe.\n");
294 return 1;
295 }
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000296#endif
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000297
Nico Huber2e50cdc2018-09-23 20:20:26 +0200298 if (internal_buses_supported & BUS_NONSPI)
299 register_par_master(&par_master_internal, internal_buses_supported);
300
301 /* Report if a non-whitelisted laptop is detected that likely uses a legacy bus. */
302 if (is_laptop && !laptop_ok) {
303 msg_pinfo("========================================================================\n");
304 if (is_laptop == 1) {
305 msg_pinfo("You seem to be running flashrom on an unknown laptop. Some\n"
306 "internal buses have been disabled for safety reasons.\n\n");
307 } else {
308 msg_pinfo("You may be running flashrom on an unknown laptop. We could not\n"
309 "detect this for sure because your vendor has not set up the SMBIOS\n"
310 "tables correctly. Some internal buses have been disabled for\n"
311 "safety reasons. You can enforce using all buses by adding\n"
312 " -p internal:laptop=this_is_not_a_laptop\n"
313 "to the command line, but please read the following warning if you\n"
314 "are not sure.\n\n");
315 }
316 msg_perr("Laptops, notebooks and netbooks are difficult to support and we\n"
317 "recommend to use the vendor flashing utility. The embedded controller\n"
318 "(EC) in these machines often interacts badly with flashing.\n"
319 "See the manpage and https://flashrom.org/Laptops for details.\n\n"
320 "If flash is shared with the EC, erase is guaranteed to brick your laptop\n"
321 "and write may brick your laptop.\n"
322 "Read and probe may irritate your EC and cause fan failure, backlight\n"
323 "failure and sudden poweroff.\n"
324 "You have been warned.\n"
325 "========================================================================\n");
326 }
327
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000328 return 0;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000329}
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000330
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000331static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
332 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000333{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000334 mmio_writeb(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000335}
336
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000337static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
338 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000339{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000340 mmio_writew(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000341}
342
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000343static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
344 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000345{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000346 mmio_writel(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000347}
348
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000349static uint8_t internal_chip_readb(const struct flashctx *flash,
350 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000351{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000352 return mmio_readb((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000353}
354
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000355static uint16_t internal_chip_readw(const struct flashctx *flash,
356 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000357{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000358 return mmio_readw((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000359}
360
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000361static uint32_t internal_chip_readl(const struct flashctx *flash,
362 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000363{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000364 return mmio_readl((void *) addr);
365}
366
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000367static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
368 const chipaddr addr, size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000369{
Carl-Daniel Hailfingerccd71c22012-03-01 22:38:27 +0000370 mmio_readn((void *)addr, buf, len);
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000371 return;
372}