blob: 620a4aac64adea3df9db0e6493ff7c002044b8e9 [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.
hailfingerabe249e2009-05-08 17:43:22 +000015 */
16
David Hendricks39a32412011-03-24 17:14:01 -070017#include <stdio.h>
Edward O'Callaghanb4300ca2019-09-03 16:15:21 +100018#include <strings.h>
hailfingerabe249e2009-05-08 17:43:22 +000019#include <string.h>
20#include <stdlib.h>
David Hendricks39a32412011-03-24 17:14:01 -070021#include <stdarg.h>
hailfingerabe249e2009-05-08 17:43:22 +000022#include "flash.h"
hailfinger428f6852010-07-27 22:41:39 +000023#include "programmer.h"
Mayur Panchalf4796862019-08-05 15:46:12 +100024#include "hwaccess.h"
hailfingerabe249e2009-05-08 17:43:22 +000025
hailfinger80422e22009-12-13 22:28:00 +000026#if NEED_PCI == 1
uwe922946a2011-07-13 11:22:03 +000027struct pci_dev *pci_dev_find_vendorclass(uint16_t vendor, uint16_t devclass)
hailfinger07e3ce02009-11-15 17:13:29 +000028{
29 struct pci_dev *temp;
30 struct pci_filter filter;
31 uint16_t tmp2;
32
33 pci_filter_init(NULL, &filter);
34 filter.vendor = vendor;
35
36 for (temp = pacc->devices; temp; temp = temp->next)
37 if (pci_filter_match(&filter, temp)) {
38 /* Read PCI class */
39 tmp2 = pci_read_word(temp, 0x0a);
uwe922946a2011-07-13 11:22:03 +000040 if (tmp2 == devclass)
hailfinger07e3ce02009-11-15 17:13:29 +000041 return temp;
42 }
43
44 return NULL;
45}
46
hailfingerabe249e2009-05-08 17:43:22 +000047struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device)
48{
49 struct pci_dev *temp;
50 struct pci_filter filter;
51
52 pci_filter_init(NULL, &filter);
53 filter.vendor = vendor;
54 filter.device = device;
55
56 for (temp = pacc->devices; temp; temp = temp->next)
57 if (pci_filter_match(&filter, temp))
58 return temp;
59
60 return NULL;
61}
62
63struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
64 uint16_t card_vendor, uint16_t card_device)
65{
66 struct pci_dev *temp;
67 struct pci_filter filter;
68
69 pci_filter_init(NULL, &filter);
70 filter.vendor = vendor;
71 filter.device = device;
72
73 for (temp = pacc->devices; temp; temp = temp->next)
74 if (pci_filter_match(&filter, temp)) {
75 if ((card_vendor ==
76 pci_read_word(temp, PCI_SUBSYSTEM_VENDOR_ID))
77 && (card_device ==
78 pci_read_word(temp, PCI_SUBSYSTEM_ID)))
79 return temp;
80 }
81
82 return NULL;
83}
hailfinger80422e22009-12-13 22:28:00 +000084#endif
hailfingerabe249e2009-05-08 17:43:22 +000085
hailfinger90c7d542010-05-31 15:27:27 +000086#if CONFIG_INTERNAL == 1
mkarcherf2620582010-02-28 01:33:48 +000087int force_boardenable = 0;
hailfingerf4aaccc2010-04-28 15:22:14 +000088int force_boardmismatch = 0;
hailfingerc236f9e2009-12-22 23:42:04 +000089
Edward O'Callaghan6707e1e2019-08-02 23:07:15 +100090#if IS_X86
hailfingerc236f9e2009-12-22 23:42:04 +000091void probe_superio(void)
92{
Edward O'Callaghan0742c412020-10-10 15:24:46 +110093 probe_superio_winbond();
94 /* ITE probe causes SMSC LPC47N217 to power off the serial UART.
95 * Always probe for SMSC first, and if a SMSC Super I/O is detected
96 * at a given I/O port, do _not_ probe that port with the ITE probe.
97 * This means SMSC probing must be done before ITE probing.
98 */
99 //probe_superio_smsc();
hailfinger94e090c2011-04-27 14:34:08 +0000100 probe_superio_ite();
hailfingerc236f9e2009-12-22 23:42:04 +0000101}
hailfinger94e090c2011-04-27 14:34:08 +0000102
103int superio_count = 0;
104#define SUPERIO_MAX_COUNT 3
105
106struct superio superios[SUPERIO_MAX_COUNT];
107
108int register_superio(struct superio s)
109{
110 if (superio_count == SUPERIO_MAX_COUNT)
111 return 1;
112 superios[superio_count++] = s;
113 return 0;
114}
115
hailfinger324a9cc2010-05-26 01:45:41 +0000116#endif
hailfingerc236f9e2009-12-22 23:42:04 +0000117
hailfinger324a9cc2010-05-26 01:45:41 +0000118int is_laptop = 0;
David Hendricks8e2e46e2012-09-20 22:21:54 -0700119int laptop_ok = 1; /* FIXME: proper whitelisting hasn't been added yet */
mkarcher287aa242010-02-26 09:51:20 +0000120
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700121static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
122 chipaddr addr);
123static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
124 chipaddr addr);
125static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
126 chipaddr addr);
127static uint8_t internal_chip_readb(const struct flashctx *flash,
128 const chipaddr addr);
129static uint16_t internal_chip_readw(const struct flashctx *flash,
130 const chipaddr addr);
131static uint32_t internal_chip_readl(const struct flashctx *flash,
132 const chipaddr addr);
133static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
134 const chipaddr addr, size_t len);
135
Paul Kocialkowskie0797d22017-11-13 22:06:40 +0100136#if defined (__FLASHROM_LITTLE_ENDIAN__)
Patrick Georgi0a9533a2017-02-03 19:28:38 +0100137static const struct par_master par_master_internal = {
hailfinger76bb7e92011-11-09 23:40:00 +0000138 .chip_readb = internal_chip_readb,
139 .chip_readw = internal_chip_readw,
140 .chip_readl = internal_chip_readl,
141 .chip_readn = internal_chip_readn,
142 .chip_writeb = internal_chip_writeb,
143 .chip_writew = internal_chip_writew,
144 .chip_writel = internal_chip_writel,
145 .chip_writen = fallback_chip_writen,
146};
Mike Frysingerf9fe0e42016-02-11 19:00:03 -0500147#endif
hailfinger76bb7e92011-11-09 23:40:00 +0000148
149enum chipbustype internal_buses_supported = BUS_NONE;
150
David Hendricks80f62d22010-10-08 11:09:35 -0700151enum chipbustype target_bus;
hailfinger80422e22009-12-13 22:28:00 +0000152
David Hendricksac1d25c2016-08-09 17:00:58 -0700153int internal_init(void)
uwebc526c82009-05-14 20:41:57 +0000154{
155 int ret = 0;
hailfingerf4aaccc2010-04-28 15:22:14 +0000156 int force_laptop = 0;
stefanct18a9eeb2011-09-13 23:14:25 +0000157 int not_a_laptop = 0;
Edward O'Callaghanb4a82892020-10-08 02:47:28 +1100158 char *board_vendor = NULL;
159 char *board_model = NULL;
Paul Kocialkowski171f8082017-11-13 22:12:33 +0100160#if IS_X86 || IS_ARM
Edward O'Callaghan481cce82019-05-31 15:03:50 +1000161 const char *cb_vendor = NULL;
162 const char *cb_model = NULL;
Louis Yung-Chieh Lo6b8f0462011-01-06 12:49:46 +0800163 int probe_target_bus_later = 0;
Mike Frysingerf9fe0e42016-02-11 19:00:03 -0500164#endif
Edward O'Callaghanb4a82892020-10-08 02:47:28 +1100165 char *arg;
uwebc526c82009-05-14 20:41:57 +0000166
hailfingerddeb4ac2010-07-08 10:13:37 +0000167 arg = extract_programmer_param("boardenable");
hailfingerf4aaccc2010-04-28 15:22:14 +0000168 if (arg && !strcmp(arg,"force")) {
169 force_boardenable = 1;
170 } else if (arg && !strlen(arg)) {
171 msg_perr("Missing argument for boardenable.\n");
hailfinger1ef766d2010-07-06 09:55:48 +0000172 free(arg);
173 return 1;
hailfingerf4aaccc2010-04-28 15:22:14 +0000174 } else if (arg) {
175 msg_perr("Unknown argument for boardenable: %s\n", arg);
hailfinger1ef766d2010-07-06 09:55:48 +0000176 free(arg);
177 return 1;
mkarcherf2620582010-02-28 01:33:48 +0000178 }
hailfingerf4aaccc2010-04-28 15:22:14 +0000179 free(arg);
mkarcherf2620582010-02-28 01:33:48 +0000180
hailfingerddeb4ac2010-07-08 10:13:37 +0000181 arg = extract_programmer_param("boardmismatch");
hailfingerf4aaccc2010-04-28 15:22:14 +0000182 if (arg && !strcmp(arg,"force")) {
183 force_boardmismatch = 1;
184 } else if (arg && !strlen(arg)) {
185 msg_perr("Missing argument for boardmismatch.\n");
hailfinger1ef766d2010-07-06 09:55:48 +0000186 free(arg);
187 return 1;
hailfingerf4aaccc2010-04-28 15:22:14 +0000188 } else if (arg) {
189 msg_perr("Unknown argument for boardmismatch: %s\n", arg);
hailfinger1ef766d2010-07-06 09:55:48 +0000190 free(arg);
191 return 1;
mkarcherf2620582010-02-28 01:33:48 +0000192 }
hailfingerf4aaccc2010-04-28 15:22:14 +0000193 free(arg);
194
hailfingerddeb4ac2010-07-08 10:13:37 +0000195 arg = extract_programmer_param("laptop");
stefanct18a9eeb2011-09-13 23:14:25 +0000196 if (arg && !strcmp(arg, "force_I_want_a_brick"))
hailfingerf4aaccc2010-04-28 15:22:14 +0000197 force_laptop = 1;
stefanct18a9eeb2011-09-13 23:14:25 +0000198 else if (arg && !strcmp(arg, "this_is_not_a_laptop"))
199 not_a_laptop = 1;
200 else if (arg && !strlen(arg)) {
hailfingerf4aaccc2010-04-28 15:22:14 +0000201 msg_perr("Missing argument for laptop.\n");
hailfinger1ef766d2010-07-06 09:55:48 +0000202 free(arg);
203 return 1;
hailfingerf4aaccc2010-04-28 15:22:14 +0000204 } else if (arg) {
205 msg_perr("Unknown argument for laptop: %s\n", arg);
hailfinger1ef766d2010-07-06 09:55:48 +0000206 free(arg);
207 return 1;
hailfingerf4aaccc2010-04-28 15:22:14 +0000208 }
209 free(arg);
210
Carl-Daniel Hailfingere5ec66e2016-08-03 16:10:19 -0700211 arg = extract_programmer_param("mainboard");
212 if (arg && strlen(arg)) {
Edward O'Callaghanf85623c2020-10-09 23:24:19 +1100213 if (board_parse_parameter(arg, &board_vendor, &board_model)) {
214 free(arg);
215 return 1;
216 }
Carl-Daniel Hailfingere5ec66e2016-08-03 16:10:19 -0700217 } else if (arg && !strlen(arg)) {
218 msg_perr("Missing argument for mainboard.\n");
219 free(arg);
220 return 1;
221 }
222 free(arg);
223
David Hendricks80f62d22010-10-08 11:09:35 -0700224 arg = extract_programmer_param("bus");
225 if (arg) {
226 if (!strcasecmp(arg,"parallel")) {
hailfingere1e41ea2011-07-27 07:13:06 +0000227 target_bus = BUS_PARALLEL;
David Hendricks80f62d22010-10-08 11:09:35 -0700228 } else if (!strcasecmp(arg,"lpc")) {
hailfingere1e41ea2011-07-27 07:13:06 +0000229 target_bus = BUS_LPC;
David Hendricks80f62d22010-10-08 11:09:35 -0700230 } else if (!strcasecmp(arg,"fwh")) {
hailfingere1e41ea2011-07-27 07:13:06 +0000231 target_bus = BUS_FWH;
David Hendricks80f62d22010-10-08 11:09:35 -0700232 } else if (!strcasecmp(arg,"spi")) {
hailfingere1e41ea2011-07-27 07:13:06 +0000233 target_bus = BUS_SPI;
David Hendricksa264f3e2012-05-24 20:21:03 -0700234 } else if (!strcasecmp(arg,"i2c")) {
235 target_bus = BUS_PROG;
David Hendricks80f62d22010-10-08 11:09:35 -0700236 } else {
David Hendricks89a45e52011-11-22 16:56:22 -0800237 msg_perr("Unsupported bus: %s\n", arg);
David Hendricks80f62d22010-10-08 11:09:35 -0700238 free(arg);
239 return 1;
240 }
241
242 free(arg);
Louis Yung-Chieh Lo6b8f0462011-01-06 12:49:46 +0800243 } else {
Paul Kocialkowski171f8082017-11-13 22:12:33 +0100244#if IS_X86 || IS_ARM
Louis Yung-Chieh Lo6b8f0462011-01-06 12:49:46 +0800245 /* The pacc must be initialized before access pci devices. */
246 probe_target_bus_later = 1;
Mike Frysingerf9fe0e42016-02-11 19:00:03 -0500247#endif
David Hendricks80f62d22010-10-08 11:09:35 -0700248 }
249
Edward O'Callaghan392d10d2020-10-08 02:52:10 +1100250 if (rget_io_perms()) {
251 ret = 1;
252 goto internal_init_exit;
253 }
hailfingerabe249e2009-05-08 17:43:22 +0000254
Paul Kocialkowski171f8082017-11-13 22:12:33 +0100255#if IS_X86
mkarcherd264e9e2011-05-11 17:07:07 +0000256 /* Default to Parallel/LPC/FWH flash devices. If a known host controller
hailfinger76bb7e92011-11-09 23:40:00 +0000257 * is found, the host controller init routine sets the
258 * internal_buses_supported bitfield.
mkarcherd264e9e2011-05-11 17:07:07 +0000259 */
hailfinger76bb7e92011-11-09 23:40:00 +0000260 internal_buses_supported = BUS_NONSPI;
mkarcherd264e9e2011-05-11 17:07:07 +0000261
hailfingerabe249e2009-05-08 17:43:22 +0000262 /* Initialize PCI access for flash enables */
Edward O'Callaghan392d10d2020-10-08 02:52:10 +1100263 if (pci_init_common() != 0) {
264 ret = 1;
265 goto internal_init_exit;
266 }
David Hendricksa0009742011-12-15 15:59:40 -0800267#else
268 internal_buses_supported = BUS_NONE;
David Hendrickscb2cec32011-03-24 18:44:49 -0700269#endif
hailfingerabe249e2009-05-08 17:43:22 +0000270
Paul Kocialkowski171f8082017-11-13 22:12:33 +0100271#if IS_ARM
David Hendricksfa3dba72013-06-18 13:11:50 -0700272 /*
Paul Kocialkowski171f8082017-11-13 22:12:33 +0100273 * FIXME: CrOS EC probing should not require this "IS_ARM"
David Hendricksfa3dba72013-06-18 13:11:50 -0700274 * and should not depend on the target bus. This is only to satisfy
275 * users and scripts who currently depend on the old "-p internal:bus="
276 * syntax or some default behavior.
277 *
278 * Once everything is finally updated, we should only rely on
David Hendricksb907de32014-08-11 16:47:09 -0700279 * alias == ALIAS_EC in order to call cros_ec_probe_*.
David Hendricksfa3dba72013-06-18 13:11:50 -0700280 *
281 * Also, ensure probing does not get confused when removing the
Paul Kocialkowski171f8082017-11-13 22:12:33 +0100282 * "#if IS_ARM" (see crbug.com/249568).
David Hendricksfa3dba72013-06-18 13:11:50 -0700283 */
284 if (!alias && probe_target_bus_later)
285 target_bus = BUS_SPI;
286
Doug Andersone5166f42013-06-17 14:45:55 -0700287 if (target_bus != BUS_SPI) {
Edward O'Callaghanfeda7452020-03-25 16:22:19 +1100288 if (!cros_ec_probe_dev())
David Hendricksa264f3e2012-05-24 20:21:03 -0700289 return 0;
290 }
David Hendricks5d428362013-06-13 18:22:29 -0700291#endif
Simon Glasscd597032013-05-23 17:18:44 -0700292
Edward O'Callaghan14883492020-10-08 03:01:57 +1100293 if (try_mtd() == 0) {
Edward O'Callaghan392d10d2020-10-08 02:52:10 +1100294 ret = 0;
295 goto internal_init_exit;
Edward O'Callaghan14883492020-10-08 03:01:57 +1100296 }
David Hendrickscebee892015-05-23 20:30:30 -0700297
Paul Kocialkowski171f8082017-11-13 22:12:33 +0100298#if IS_ARM || IS_MIPS && CONFIG_LINUX_SPI == 1
Louis Yung-Chieh Loa20b3932012-05-22 22:14:00 +0800299 /* On the ARM platform, we prefer /dev/spidev if it is supported.
300 * That means, if user specifies
301 *
302 * 1. -p internal programmer
303 * 2. without -p (the default programmer, which is internal too)
304 *
305 * This code would try to auto-detect the /dev/spidevX.Y.
Simon Glassec2ea1a2013-02-10 09:41:05 -0800306 * If failed, try processor_flash_enable() then.
Louis Yung-Chieh Loa20b3932012-05-22 22:14:00 +0800307 *
308 * The -p linux_spi still works because the programmer_init() would
309 * call the linux_spi_init() in flashrom.c.
310 */
David Hendricksac1d25c2016-08-09 17:00:58 -0700311 if (!programmer_init(PROGRAMMER_LINUX_SPI, NULL)) {
Louis Yung-Chieh Loa20b3932012-05-22 22:14:00 +0800312 return 0;
313 } else /* if failed, fall through */
314#endif
hailfinger586f4ae2010-06-04 19:05:39 +0000315 if (processor_flash_enable()) {
316 msg_perr("Processor detection/init failed.\n"
317 "Aborting.\n");
Edward O'Callaghan392d10d2020-10-08 02:52:10 +1100318 ret = 1;
319 goto internal_init_exit;
hailfinger586f4ae2010-06-04 19:05:39 +0000320 }
321
Edward O'Callaghan481cce82019-05-31 15:03:50 +1000322#if IS_X86 || IS_ARM
hailfinger586f4ae2010-06-04 19:05:39 +0000323 /* We look at the cbtable first to see if we need a
hailfingerabe249e2009-05-08 17:43:22 +0000324 * mainboard specific flash enable sequence.
325 */
Edward O'Callaghan481cce82019-05-31 15:03:50 +1000326 if ((cb_parse_table(&cb_vendor, &cb_model) == 0) && (board_vendor != NULL) && (board_model != NULL)) {
327 if (strcasecmp(board_vendor, cb_vendor) || strcasecmp(board_model, cb_model)) {
328 msg_pwarn("Warning: The mainboard IDs set by -p internal:mainboard (%s:%s) do not\n"
329 " match the current coreboot IDs of the mainboard (%s:%s).\n",
330 board_vendor, board_model, cb_vendor, cb_model);
Edward O'Callaghan392d10d2020-10-08 02:52:10 +1100331 if (!force_boardmismatch) {
332 ret = 1;
333 goto internal_init_exit;
334 }
Edward O'Callaghan481cce82019-05-31 15:03:50 +1000335 msg_pinfo("Continuing anyway.\n");
336 }
337 }
338#endif
hailfinger324a9cc2010-05-26 01:45:41 +0000339
Edward O'Callaghan481cce82019-05-31 15:03:50 +1000340#if IS_X86
Edward O'Callaghan26bf5c42019-08-02 23:28:03 +1000341 is_laptop = 2; /* Assume that we don't know by default. */
342
David Hendricks8e2e46e2012-09-20 22:21:54 -0700343 dmi_init();
hailfingerabe249e2009-05-08 17:43:22 +0000344
Louis Yung-Chieh Lo6b8f0462011-01-06 12:49:46 +0800345 if (probe_target_bus_later) {
346 /* read the target bus value from register. */
347 if (get_target_bus_from_chipset(&target_bus)) {
hailfinger969e2f32011-09-08 00:00:29 +0000348 msg_perr("Cannot get target bus from programmer.\n");
Louis Yung-Chieh Lo6b8f0462011-01-06 12:49:46 +0800349 return 1;
350 }
Louis Yung-Chieh Lo8381f152011-10-31 15:45:04 +0800351 msg_pdbg("get_target_bus_from_chipset() returns 0x%x.\n",
352 target_bus);
Louis Yung-Chieh Lo6b8f0462011-01-06 12:49:46 +0800353 }
354
hailfingere52e9f82011-05-05 07:12:40 +0000355 /* In case Super I/O probing would cause pretty explosions. */
356 board_handle_before_superio();
357
uwef6f94d42010-03-13 17:28:29 +0000358 /* Probe for the Super I/O chip and fill global struct superio. */
hailfingerc236f9e2009-12-22 23:42:04 +0000359 probe_superio();
hailfinger586f4ae2010-06-04 19:05:39 +0000360#else
361 /* FIXME: Enable cbtable searching on all non-x86 platforms supported
362 * by coreboot.
363 * FIXME: Find a replacement for DMI on non-x86.
364 * FIXME: Enable Super I/O probing once port I/O is possible.
365 */
hailfinger324a9cc2010-05-26 01:45:41 +0000366#endif
hailfingerc236f9e2009-12-22 23:42:04 +0000367
hailfingere52e9f82011-05-05 07:12:40 +0000368 /* Check laptop whitelist. */
369 board_handle_before_laptop();
370
Edward O'Callaghan26bf5c42019-08-02 23:28:03 +1000371 /*
372 * Disable all internal buses by default if we are not sure
373 * this isn't a laptop. Board-enables may override this,
374 * non-legacy buses (SPI and opaque atm) are probed anyway.
375 */
376 if (force_laptop || (not_a_laptop && (is_laptop == 2)))
377 internal_buses_supported = BUS_NONE;
mkarcher287aa242010-02-26 09:51:20 +0000378
Paul Kocialkowskie0797d22017-11-13 22:06:40 +0100379#if defined (__FLASHROM_LITTLE_ENDIAN__)
Paul Kocialkowski171f8082017-11-13 22:12:33 +0100380#if IS_X86 || IS_MIPS || IS_ARM
hailfingerabe249e2009-05-08 17:43:22 +0000381 /* try to enable it. Failure IS an option, since not all motherboards
382 * really need this to be done, etc., etc.
383 */
384 ret = chipset_flash_enable();
385 if (ret == -2) {
Edward O'Callaghanb4a82892020-10-08 02:47:28 +1100386 msg_perr("WARNING: No chipset found. Flash detection "
hailfingerf4aaccc2010-04-28 15:22:14 +0000387 "will most likely fail.\n");
Edward O'Callaghan392d10d2020-10-08 02:52:10 +1100388 } else if (ret == ERROR_FATAL) {
389 goto internal_init_exit;
390 }
hailfingerabe249e2009-05-08 17:43:22 +0000391
Edward O'Callaghan0742c412020-10-10 15:24:46 +1100392#if IS_X86
393 /* Probe unconditionally for ITE Super I/O chips. This enables LPC->SPI translation on IT87* and
394 * parallel writes on IT8705F. Also, this handles the manual chip select for Gigabyte's DualBIOS. */
395 init_superio_ite();
396
397 if (board_flash_enable(board_vendor, board_model, cb_vendor, cb_model)) {
398 msg_perr("Aborting to be safe.\n");
399 ret = 1;
400 goto internal_init_exit;
401 }
402#endif
403
Edward O'Callaghan26bf5c42019-08-02 23:28:03 +1000404 if (internal_buses_supported & BUS_NONSPI)
405 register_par_master(&par_master_internal, internal_buses_supported);
406
407 /* Report if a non-whitelisted laptop is detected that likely uses a legacy bus. */
408 if (is_laptop && !laptop_ok) {
Edward O'Callaghanb4a82892020-10-08 02:47:28 +1100409 msg_pinfo("========================================================================\n");
Edward O'Callaghan26bf5c42019-08-02 23:28:03 +1000410 if (is_laptop == 1) {
411 msg_pinfo("You seem to be running flashrom on an unknown laptop. Some\n"
412 "internal buses have been disabled for safety reasons.\n\n");
413 } else {
414 msg_pinfo("You may be running flashrom on an unknown laptop. We could not\n"
Edward O'Callaghanb4a82892020-10-08 02:47:28 +1100415 "detect this for sure because your vendor has not set up the SMBIOS\n"
416 "tables correctly. Some internal buses have been disabled for\n"
417 "safety reasons. You can enforce using all buses by adding\n"
418 " -p internal:laptop=this_is_not_a_laptop\n"
419 "to the command line, but please read the following warning if you\n"
420 "are not sure.\n\n");
Edward O'Callaghan26bf5c42019-08-02 23:28:03 +1000421 }
422 msg_perr("Laptops, notebooks and netbooks are difficult to support and we\n"
423 "recommend to use the vendor flashing utility. The embedded controller\n"
424 "(EC) in these machines often interacts badly with flashing.\n"
Edward O'Callaghanb4a82892020-10-08 02:47:28 +1100425 "See the manpage and https://flashrom.org/Laptops for details.\n\n"
Edward O'Callaghan26bf5c42019-08-02 23:28:03 +1000426 "If flash is shared with the EC, erase is guaranteed to brick your laptop\n"
427 "and write may brick your laptop.\n"
428 "Read and probe may irritate your EC and cause fan failure, backlight\n"
429 "failure and sudden poweroff.\n"
430 "You have been warned.\n"
431 "========================================================================\n");
432 }
Paul Kocialkowski171f8082017-11-13 22:12:33 +0100433#if IS_X86
David Hendricksc801adb2010-12-09 16:58:56 -0800434
David Hendrickse18bbc62010-12-28 17:50:05 -0800435 /* probe for programmers that bridge LPC <--> SPI */
David Hendricksba0827a2013-05-03 20:25:40 -0700436 if (target_bus == BUS_LPC || target_bus == BUS_FWH ||
437 (alias && alias->type == ALIAS_EC)) {
Duncan Laurie6a40fb92014-11-24 07:13:27 -0800438 /* Try to probe via kernel device first */
David Hendricksac1d25c2016-08-09 17:00:58 -0700439 if (!cros_ec_probe_dev()) {
440 buses_supported &= ~(BUS_LPC|BUS_SPI);
Duncan Laurie6a40fb92014-11-24 07:13:27 -0800441 return 0;
442 }
Edward O'Callaghan10849c72020-04-11 15:22:15 +1000443 if (wpce775x_probe_spi_flash(NULL) &&
Victor Dinga2c921c2020-08-18 18:55:20 +1000444 mec1308_probe_spi_flash() &&
Edward O'Callaghan0742c412020-10-10 15:24:46 +1100445 ene_probe_spi_flash())
David Hendricks5e79c9f2013-11-04 22:05:08 -0800446 return 1; /* EC not found */
447 else
448 return 0;
David Hendrickse18bbc62010-12-28 17:50:05 -0800449 }
450
hailfinger324a9cc2010-05-26 01:45:41 +0000451#endif
hailfingerddd5d7b2010-03-25 02:50:40 +0000452
David Hendricksac1d25c2016-08-09 17:00:58 -0700453 if (!(buses_supported & target_bus) &&
David Hendricksba0827a2013-05-03 20:25:40 -0700454 (!alias || (alias && alias->type == ALIAS_NONE))) {
455 /* User specified a target bus which is not supported on the
456 * platform or specified an alias which does not enable it.
457 */
David Hendricks3ba67132011-12-15 15:47:43 -0800458 msg_perr("Programmer does not support specified bus\n");
459 return 1;
460 }
461
hailfinger681638b2009-09-02 13:43:56 +0000462 /* Even if chipset init returns an error code, we don't want to abort.
463 * The error code might have been a warning only.
464 * Besides that, we don't check the board enable return code either.
465 */
hailfingerf4aaccc2010-04-28 15:22:14 +0000466 return 0;
hailfinger586f4ae2010-06-04 19:05:39 +0000467#else
468 msg_perr("Your platform is not supported yet for the internal "
469 "programmer due to missing\n"
470 "flash_base and top/bottom alignment information.\n"
471 "Aborting.\n");
472 return 1;
473#endif
474#else
475 /* FIXME: Remove this unconditional abort once all PCI drivers are
476 * converted to use little-endian accesses for memory BARs.
477 */
478 msg_perr("Your platform is not supported yet for the internal "
479 "programmer because it has\n"
480 "not been converted from native endian to little endian "
481 "access yet.\n"
482 "Aborting.\n");
483 return 1;
484#endif
Edward O'Callaghan392d10d2020-10-08 02:52:10 +1100485 ret = 0;
486
487internal_init_exit:
488 free(board_vendor);
489 free(board_model);
490
491 return ret;
hailfingerabe249e2009-05-08 17:43:22 +0000492}
hailfinger80422e22009-12-13 22:28:00 +0000493#endif
hailfingerabe249e2009-05-08 17:43:22 +0000494
Edward O'Callaghan1ea10ca2019-08-02 22:03:48 +1000495static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
496 chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000497{
hailfinger38da6812009-05-17 15:49:24 +0000498 mmio_writeb(val, (void *) addr);
hailfingerabe249e2009-05-08 17:43:22 +0000499}
500
Edward O'Callaghan1ea10ca2019-08-02 22:03:48 +1000501static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
502 chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000503{
hailfinger38da6812009-05-17 15:49:24 +0000504 mmio_writew(val, (void *) addr);
hailfingerabe249e2009-05-08 17:43:22 +0000505}
506
Edward O'Callaghan1ea10ca2019-08-02 22:03:48 +1000507static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
508 chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000509{
hailfinger38da6812009-05-17 15:49:24 +0000510 mmio_writel(val, (void *) addr);
hailfingerabe249e2009-05-08 17:43:22 +0000511}
512
Edward O'Callaghan1ea10ca2019-08-02 22:03:48 +1000513static uint8_t internal_chip_readb(const struct flashctx *flash,
514 const chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000515{
hailfinger38da6812009-05-17 15:49:24 +0000516 return mmio_readb((void *) addr);
hailfingerabe249e2009-05-08 17:43:22 +0000517}
518
Edward O'Callaghan1ea10ca2019-08-02 22:03:48 +1000519static uint16_t internal_chip_readw(const struct flashctx *flash,
520 const chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000521{
hailfinger38da6812009-05-17 15:49:24 +0000522 return mmio_readw((void *) addr);
hailfingerabe249e2009-05-08 17:43:22 +0000523}
524
Edward O'Callaghan1ea10ca2019-08-02 22:03:48 +1000525static uint32_t internal_chip_readl(const struct flashctx *flash,
526 const chipaddr addr)
hailfingerabe249e2009-05-08 17:43:22 +0000527{
hailfinger38da6812009-05-17 15:49:24 +0000528 return mmio_readl((void *) addr);
529}
530
Edward O'Callaghan1ea10ca2019-08-02 22:03:48 +1000531static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
532 const chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000533{
Carl-Daniel Hailfinger5b0c4652012-03-01 22:38:27 +0000534 mmio_readn((void *)addr, buf, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000535 return;
536}