blob: 4d58eb96df9a42aaaa201d5434f98961925b1682 [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 Hailfinger1c6d2ff2012-08-27 00:44:42 +000021#include <strings.h>
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000022#include <string.h>
23#include <stdlib.h>
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000024#include "flash.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000025#include "programmer.h"
Patrick Georgi32508eb2012-07-20 20:35:14 +000026#include "hwaccess.h"
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000027
Christian Ruppert0cdb0312009-05-14 18:57:26 +000028struct pci_dev *pci_dev_find_filter(struct pci_filter filter)
29{
30 struct pci_dev *temp;
31
32 for (temp = pacc->devices; temp; temp = temp->next)
33 if (pci_filter_match(&filter, temp))
34 return temp;
35
36 return NULL;
37}
38
Uwe Hermann24c35e42011-07-13 11:22:03 +000039struct pci_dev *pci_dev_find_vendorclass(uint16_t vendor, uint16_t devclass)
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000040{
41 struct pci_dev *temp;
42 struct pci_filter filter;
43 uint16_t tmp2;
44
45 pci_filter_init(NULL, &filter);
46 filter.vendor = vendor;
47
48 for (temp = pacc->devices; temp; temp = temp->next)
49 if (pci_filter_match(&filter, temp)) {
50 /* Read PCI class */
51 tmp2 = pci_read_word(temp, 0x0a);
Uwe Hermann24c35e42011-07-13 11:22:03 +000052 if (tmp2 == devclass)
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000053 return temp;
54 }
55
56 return NULL;
57}
58
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000059struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device)
60{
61 struct pci_dev *temp;
62 struct pci_filter filter;
63
64 pci_filter_init(NULL, &filter);
65 filter.vendor = vendor;
66 filter.device = device;
67
68 for (temp = pacc->devices; temp; temp = temp->next)
69 if (pci_filter_match(&filter, temp))
70 return temp;
71
72 return NULL;
73}
74
75struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
76 uint16_t card_vendor, uint16_t card_device)
77{
78 struct pci_dev *temp;
79 struct pci_filter filter;
80
81 pci_filter_init(NULL, &filter);
82 filter.vendor = vendor;
83 filter.device = device;
84
85 for (temp = pacc->devices; temp; temp = temp->next)
86 if (pci_filter_match(&filter, temp)) {
87 if ((card_vendor ==
88 pci_read_word(temp, PCI_SUBSYSTEM_VENDOR_ID))
89 && (card_device ==
90 pci_read_word(temp, PCI_SUBSYSTEM_ID)))
91 return temp;
92 }
93
94 return NULL;
95}
96
Michael Karcher0bdc0922010-02-28 01:33:48 +000097int force_boardenable = 0;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +000098int force_boardmismatch = 0;
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000099
Nico Huberc8801732017-12-01 18:19:43 +0000100#if IS_X86
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000101void probe_superio(void)
102{
Carl-Daniel Hailfingerf5e62cb2012-05-06 22:48:01 +0000103 probe_superio_winbond();
104 /* ITE probe causes SMSC LPC47N217 to power off the serial UART.
105 * Always probe for SMSC first, and if a SMSC Super I/O is detected
106 * at a given I/O port, do _not_ probe that port with the ITE probe.
107 * This means SMSC probing must be done before ITE probing.
108 */
109 //probe_superio_smsc();
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +0000110 probe_superio_ite();
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000111}
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +0000112
113int superio_count = 0;
114#define SUPERIO_MAX_COUNT 3
115
116struct superio superios[SUPERIO_MAX_COUNT];
117
118int register_superio(struct superio s)
119{
120 if (superio_count == SUPERIO_MAX_COUNT)
121 return 1;
122 superios[superio_count++] = s;
123 return 0;
124}
125
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000126#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000127
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000128int is_laptop = 0;
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000129int laptop_ok = 0;
Michael Karcher8c1df282010-02-26 09:51:20 +0000130
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000131static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
132 chipaddr addr);
133static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
134 chipaddr addr);
135static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
136 chipaddr addr);
137static uint8_t internal_chip_readb(const struct flashctx *flash,
138 const chipaddr addr);
139static uint16_t internal_chip_readw(const struct flashctx *flash,
140 const chipaddr addr);
141static uint32_t internal_chip_readl(const struct flashctx *flash,
142 const chipaddr addr);
143static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
144 const chipaddr addr, size_t len);
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000145static const struct par_master par_master_internal = {
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000146 .chip_readb = internal_chip_readb,
147 .chip_readw = internal_chip_readw,
148 .chip_readl = internal_chip_readl,
149 .chip_readn = internal_chip_readn,
150 .chip_writeb = internal_chip_writeb,
151 .chip_writew = internal_chip_writew,
152 .chip_writel = internal_chip_writel,
153 .chip_writen = fallback_chip_writen,
154};
155
156enum chipbustype internal_buses_supported = BUS_NONE;
157
Uwe Hermanna0869322009-05-14 20:41:57 +0000158int internal_init(void)
159{
160 int ret = 0;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000161 int force_laptop = 0;
Stefan Taunera28087f2011-09-13 23:14:25 +0000162 int not_a_laptop = 0;
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000163 const char *board_vendor = NULL;
164 const char *board_model = NULL;
Nico Huberc8801732017-12-01 18:19:43 +0000165#if IS_X86
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000166 const char *cb_vendor = NULL;
167 const char *cb_model = NULL;
Carl-Daniel Hailfinger11990da2013-07-13 23:21:05 +0000168#endif
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000169 char *arg;
Uwe Hermanna0869322009-05-14 20:41:57 +0000170
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000171 arg = extract_programmer_param("boardenable");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000172 if (arg && !strcmp(arg,"force")) {
173 force_boardenable = 1;
174 } else if (arg && !strlen(arg)) {
175 msg_perr("Missing argument for boardenable.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000176 free(arg);
177 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000178 } else if (arg) {
179 msg_perr("Unknown argument for boardenable: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000180 free(arg);
181 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000182 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000183 free(arg);
Michael Karcher0bdc0922010-02-28 01:33:48 +0000184
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000185 arg = extract_programmer_param("boardmismatch");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000186 if (arg && !strcmp(arg,"force")) {
187 force_boardmismatch = 1;
188 } else if (arg && !strlen(arg)) {
189 msg_perr("Missing argument for boardmismatch.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000190 free(arg);
191 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000192 } else if (arg) {
193 msg_perr("Unknown argument for boardmismatch: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000194 free(arg);
195 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000196 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000197 free(arg);
198
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000199 arg = extract_programmer_param("laptop");
Stefan Taunera28087f2011-09-13 23:14:25 +0000200 if (arg && !strcmp(arg, "force_I_want_a_brick"))
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000201 force_laptop = 1;
Stefan Taunera28087f2011-09-13 23:14:25 +0000202 else if (arg && !strcmp(arg, "this_is_not_a_laptop"))
203 not_a_laptop = 1;
204 else if (arg && !strlen(arg)) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000205 msg_perr("Missing argument for laptop.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000206 free(arg);
207 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000208 } else if (arg) {
209 msg_perr("Unknown argument for laptop: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000210 free(arg);
211 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000212 }
213 free(arg);
214
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000215 arg = extract_programmer_param("mainboard");
216 if (arg && strlen(arg)) {
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000217 if (board_parse_parameter(arg, &board_vendor, &board_model)) {
218 free(arg);
219 return 1;
220 }
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000221 } else if (arg && !strlen(arg)) {
222 msg_perr("Missing argument for mainboard.\n");
223 free(arg);
224 return 1;
225 }
226 free(arg);
227
Carl-Daniel Hailfingerd6bb8282012-07-21 17:27:08 +0000228 if (rget_io_perms())
229 return 1;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000230
Michael Karcherb9dbe482011-05-11 17:07:07 +0000231 /* Default to Parallel/LPC/FWH flash devices. If a known host controller
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000232 * is found, the host controller init routine sets the
233 * internal_buses_supported bitfield.
Michael Karcherb9dbe482011-05-11 17:07:07 +0000234 */
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000235 internal_buses_supported = BUS_NONSPI;
Michael Karcherb9dbe482011-05-11 17:07:07 +0000236
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000237 /* Initialize PCI access for flash enables */
Stefan Tauner55619552013-01-04 22:24:58 +0000238 if (pci_init_common() != 0)
239 return 1;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000240
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000241 if (processor_flash_enable()) {
242 msg_perr("Processor detection/init failed.\n"
243 "Aborting.\n");
244 return 1;
245 }
246
Nico Huberc8801732017-12-01 18:19:43 +0000247#if IS_X86
Stefan Taunerfa9fa712012-09-24 21:29:29 +0000248 if ((cb_parse_table(&cb_vendor, &cb_model) == 0) && (board_vendor != NULL) && (board_model != NULL)) {
249 if (strcasecmp(board_vendor, cb_vendor) || strcasecmp(board_model, cb_model)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000250 msg_pwarn("Warning: The mainboard IDs set by -p internal:mainboard (%s:%s) do not\n"
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000251 " match the current coreboot IDs of the mainboard (%s:%s).\n",
252 board_vendor, board_model, cb_vendor, cb_model);
253 if (!force_boardmismatch)
254 return 1;
255 msg_pinfo("Continuing anyway.\n");
256 }
257 }
Carl-Daniel Hailfinger11990da2013-07-13 23:21:05 +0000258#endif
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000259
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000260#if IS_X86
Michael Karcher6701ee82010-01-20 14:14:11 +0000261 dmi_init();
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000262
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000263 /* In case Super I/O probing would cause pretty explosions. */
264 board_handle_before_superio();
265
Uwe Hermann43959702010-03-13 17:28:29 +0000266 /* Probe for the Super I/O chip and fill global struct superio. */
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000267 probe_superio();
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000268#else
269 /* FIXME: Enable cbtable searching on all non-x86 platforms supported
270 * by coreboot.
271 * FIXME: Find a replacement for DMI on non-x86.
272 * FIXME: Enable Super I/O probing once port I/O is possible.
273 */
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000274#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000275
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000276 /* Check laptop whitelist. */
277 board_handle_before_laptop();
278
279 /* Warn if a non-whitelisted laptop is detected. */
280 if (is_laptop && !laptop_ok) {
Stefan Taunera34d7192011-07-26 00:54:42 +0000281 msg_perr("========================================================================\n");
282 if (is_laptop == 1) {
283 msg_perr("WARNING! You seem to be running flashrom on an unsupported laptop.\n");
284 } else {
285 msg_perr("WARNING! You may be running flashrom on an unsupported laptop. We could\n"
286 "not detect this for sure because your vendor has not setup the SMBIOS\n"
287 "tables correctly. You can enforce execution by adding\n"
Stefan Taunera28087f2011-09-13 23:14:25 +0000288 "'-p internal:laptop=this_is_not_a_laptop' to the command line, but\n"
Stefan Taunera34d7192011-07-26 00:54:42 +0000289 "please read the following warning if you are not sure.\n\n");
290 }
291 msg_perr("Laptops, notebooks and netbooks are difficult to support and we\n"
292 "recommend to use the vendor flashing utility. The embedded controller\n"
293 "(EC) in these machines often interacts badly with flashing.\n"
Stefan Tauner4c723152016-01-14 22:47:55 +0000294 "See the manpage and https://flashrom.org/Laptops for details.\n\n"
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000295 "If flash is shared with the EC, erase is guaranteed to brick your laptop\n"
296 "and write may brick your laptop.\n"
297 "Read and probe may irritate your EC and cause fan failure, backlight\n"
298 "failure and sudden poweroff.\n"
299 "You have been warned.\n"
300 "========================================================================\n");
Stefan Taunera34d7192011-07-26 00:54:42 +0000301
Stefan Taunera28087f2011-09-13 23:14:25 +0000302 if (force_laptop || (not_a_laptop && (is_laptop == 2))) {
303 msg_perr("Proceeding anyway because user forced us to.\n");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000304 } else {
305 msg_perr("Aborting.\n");
Niklas Söderlund2a95e872012-07-30 19:42:33 +0000306 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000307 }
308 }
Michael Karcher8c1df282010-02-26 09:51:20 +0000309
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000310 /* try to enable it. Failure IS an option, since not all motherboards
311 * really need this to be done, etc., etc.
312 */
313 ret = chipset_flash_enable();
314 if (ret == -2) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000315 msg_perr("WARNING: No chipset found. Flash detection "
316 "will most likely fail.\n");
Tadas Slotkusad470342011-09-03 17:15:00 +0000317 } else if (ret == ERROR_FATAL)
318 return ret;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000319
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000320#if IS_X86
Vadim Girlin4dd0f902013-08-24 12:18:17 +0000321 /* Probe unconditionally for ITE Super I/O chips. This enables LPC->SPI translation on IT87* and
322 * parallel writes on IT8705F. Also, this handles the manual chip select for Gigabyte's DualBIOS. */
Carl-Daniel Hailfinger76d4b372010-07-10 16:56:32 +0000323 init_superio_ite();
Carl-Daniel Hailfinger01f3ef42010-03-25 02:50:40 +0000324
Stefan Taunerfa9fa712012-09-24 21:29:29 +0000325 if (board_flash_enable(board_vendor, board_model, cb_vendor, cb_model)) {
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000326 msg_perr("Aborting to be safe.\n");
327 return 1;
328 }
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000329#endif
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000330
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000331 register_par_master(&par_master_internal, internal_buses_supported);
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000332 return 0;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000333}
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000334
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000335static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
336 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000337{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000338 mmio_writeb(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000339}
340
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000341static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
342 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000343{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000344 mmio_writew(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000345}
346
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000347static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
348 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000349{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000350 mmio_writel(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000351}
352
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000353static uint8_t internal_chip_readb(const struct flashctx *flash,
354 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000355{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000356 return mmio_readb((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000357}
358
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000359static uint16_t internal_chip_readw(const struct flashctx *flash,
360 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000361{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000362 return mmio_readw((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000363}
364
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000365static uint32_t internal_chip_readl(const struct flashctx *flash,
366 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000367{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000368 return mmio_readl((void *) addr);
369}
370
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000371static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
372 const chipaddr addr, size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000373{
Carl-Daniel Hailfingerccd71c22012-03-01 22:38:27 +0000374 mmio_readn((void *)addr, buf, len);
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000375 return;
376}