blob: f1048d97f13c0a5aefee9681b23df26da85eb11e [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"
Miriam Polzer1cea5c32020-12-23 17:28:38 +010021#include "platform.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000022#include "programmer.h"
Patrick Georgi32508eb2012-07-20 20:35:14 +000023#include "hwaccess.h"
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000024
Uwe Hermann24c35e42011-07-13 11:22:03 +000025struct pci_dev *pci_dev_find_vendorclass(uint16_t vendor, uint16_t devclass)
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000026{
27 struct pci_dev *temp;
28 struct pci_filter filter;
29 uint16_t tmp2;
30
31 pci_filter_init(NULL, &filter);
32 filter.vendor = vendor;
33
34 for (temp = pacc->devices; temp; temp = temp->next)
35 if (pci_filter_match(&filter, temp)) {
36 /* Read PCI class */
37 tmp2 = pci_read_word(temp, 0x0a);
Nico Huber380090f2022-05-23 01:45:11 +020038 if (tmp2 == devclass) {
39 pci_fill_info(temp, PCI_FILL_IDENT);
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000040 return temp;
Nico Huber380090f2022-05-23 01:45:11 +020041 }
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000042 }
43
44 return NULL;
45}
46
Carl-Daniel Hailfinger702218d2009-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
Nico Huber380090f2022-05-23 01:45:11 +020056 for (temp = pacc->devices; temp; temp = temp->next) {
57 if (pci_filter_match(&filter, temp)) {
58 pci_fill_info(temp, PCI_FILL_IDENT);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000059 return temp;
Nico Huber380090f2022-05-23 01:45:11 +020060 }
61 }
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000062
63 return NULL;
64}
65
66struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
67 uint16_t card_vendor, uint16_t card_device)
68{
69 struct pci_dev *temp;
70 struct pci_filter filter;
71
72 pci_filter_init(NULL, &filter);
73 filter.vendor = vendor;
74 filter.device = device;
75
76 for (temp = pacc->devices; temp; temp = temp->next)
77 if (pci_filter_match(&filter, temp)) {
78 if ((card_vendor ==
79 pci_read_word(temp, PCI_SUBSYSTEM_VENDOR_ID))
80 && (card_device ==
Nico Huber380090f2022-05-23 01:45:11 +020081 pci_read_word(temp, PCI_SUBSYSTEM_ID))) {
82 pci_fill_info(temp, PCI_FILL_IDENT);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000083 return temp;
Nico Huber380090f2022-05-23 01:45:11 +020084 }
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000085 }
86
87 return NULL;
88}
89
Michael Karcher0bdc0922010-02-28 01:33:48 +000090int force_boardenable = 0;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +000091int force_boardmismatch = 0;
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000092
Nico Huberc8801732017-12-01 18:19:43 +000093#if IS_X86
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000094void probe_superio(void)
95{
Carl-Daniel Hailfingerf5e62cb2012-05-06 22:48:01 +000096 probe_superio_winbond();
97 /* ITE probe causes SMSC LPC47N217 to power off the serial UART.
98 * Always probe for SMSC first, and if a SMSC Super I/O is detected
99 * at a given I/O port, do _not_ probe that port with the ITE probe.
100 * This means SMSC probing must be done before ITE probing.
101 */
102 //probe_superio_smsc();
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +0000103 probe_superio_ite();
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000104}
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +0000105
106int superio_count = 0;
107#define SUPERIO_MAX_COUNT 3
108
109struct superio superios[SUPERIO_MAX_COUNT];
110
111int register_superio(struct superio s)
112{
113 if (superio_count == SUPERIO_MAX_COUNT)
114 return 1;
115 superios[superio_count++] = s;
116 return 0;
117}
118
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000119#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000120
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000121int is_laptop = 0;
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000122int laptop_ok = 0;
Michael Karcher8c1df282010-02-26 09:51:20 +0000123
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000124static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
125 chipaddr addr);
126static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
127 chipaddr addr);
128static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
129 chipaddr addr);
130static uint8_t internal_chip_readb(const struct flashctx *flash,
131 const chipaddr addr);
132static uint16_t internal_chip_readw(const struct flashctx *flash,
133 const chipaddr addr);
134static uint32_t internal_chip_readl(const struct flashctx *flash,
135 const chipaddr addr);
136static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
137 const chipaddr addr, size_t len);
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000138static const struct par_master par_master_internal = {
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000139 .chip_readb = internal_chip_readb,
140 .chip_readw = internal_chip_readw,
141 .chip_readl = internal_chip_readl,
142 .chip_readn = internal_chip_readn,
143 .chip_writeb = internal_chip_writeb,
144 .chip_writew = internal_chip_writew,
145 .chip_writel = internal_chip_writel,
146 .chip_writen = fallback_chip_writen,
147};
148
149enum chipbustype internal_buses_supported = BUS_NONE;
150
Uwe Hermanna0869322009-05-14 20:41:57 +0000151int internal_init(void)
152{
153 int ret = 0;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000154 int force_laptop = 0;
Stefan Taunera28087f2011-09-13 23:14:25 +0000155 int not_a_laptop = 0;
Jacob Garber1c091d12019-08-12 11:14:14 -0600156 char *board_vendor = NULL;
157 char *board_model = NULL;
Nico Huberc8801732017-12-01 18:19:43 +0000158#if IS_X86
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000159 const char *cb_vendor = NULL;
160 const char *cb_model = NULL;
Carl-Daniel Hailfinger11990da2013-07-13 23:21:05 +0000161#endif
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000162 char *arg;
Uwe Hermanna0869322009-05-14 20:41:57 +0000163
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000164 arg = extract_programmer_param("boardenable");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000165 if (arg && !strcmp(arg,"force")) {
166 force_boardenable = 1;
167 } else if (arg && !strlen(arg)) {
168 msg_perr("Missing argument for boardenable.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000169 free(arg);
170 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000171 } else if (arg) {
172 msg_perr("Unknown argument for boardenable: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000173 free(arg);
174 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000175 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000176 free(arg);
Michael Karcher0bdc0922010-02-28 01:33:48 +0000177
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000178 arg = extract_programmer_param("boardmismatch");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000179 if (arg && !strcmp(arg,"force")) {
180 force_boardmismatch = 1;
181 } else if (arg && !strlen(arg)) {
182 msg_perr("Missing argument for boardmismatch.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000183 free(arg);
184 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000185 } else if (arg) {
186 msg_perr("Unknown argument for boardmismatch: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000187 free(arg);
188 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000189 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000190 free(arg);
191
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000192 arg = extract_programmer_param("laptop");
Stefan Taunera28087f2011-09-13 23:14:25 +0000193 if (arg && !strcmp(arg, "force_I_want_a_brick"))
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000194 force_laptop = 1;
Stefan Taunera28087f2011-09-13 23:14:25 +0000195 else if (arg && !strcmp(arg, "this_is_not_a_laptop"))
196 not_a_laptop = 1;
197 else if (arg && !strlen(arg)) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000198 msg_perr("Missing argument for laptop.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000199 free(arg);
200 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000201 } else if (arg) {
202 msg_perr("Unknown argument for laptop: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000203 free(arg);
204 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000205 }
206 free(arg);
207
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000208 arg = extract_programmer_param("mainboard");
209 if (arg && strlen(arg)) {
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000210 if (board_parse_parameter(arg, &board_vendor, &board_model)) {
211 free(arg);
212 return 1;
213 }
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000214 } else if (arg && !strlen(arg)) {
215 msg_perr("Missing argument for mainboard.\n");
216 free(arg);
217 return 1;
218 }
219 free(arg);
220
Jacob Garber1c091d12019-08-12 11:14:14 -0600221 if (rget_io_perms()) {
222 ret = 1;
223 goto internal_init_exit;
224 }
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000225
Michael Karcherb9dbe482011-05-11 17:07:07 +0000226 /* Default to Parallel/LPC/FWH flash devices. If a known host controller
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000227 * is found, the host controller init routine sets the
228 * internal_buses_supported bitfield.
Michael Karcherb9dbe482011-05-11 17:07:07 +0000229 */
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000230 internal_buses_supported = BUS_NONSPI;
Michael Karcherb9dbe482011-05-11 17:07:07 +0000231
Jacob Garber1c091d12019-08-12 11:14:14 -0600232 if (try_mtd() == 0) {
233 ret = 0;
234 goto internal_init_exit;
235 }
David Hendricksf9a30552015-05-23 20:30:30 -0700236
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000237 /* Initialize PCI access for flash enables */
Jacob Garber1c091d12019-08-12 11:14:14 -0600238 if (pci_init_common() != 0) {
239 ret = 1;
240 goto internal_init_exit;
241 }
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000242
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000243 if (processor_flash_enable()) {
244 msg_perr("Processor detection/init failed.\n"
245 "Aborting.\n");
Jacob Garber1c091d12019-08-12 11:14:14 -0600246 ret = 1;
247 goto internal_init_exit;
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000248 }
249
Nico Huberc8801732017-12-01 18:19:43 +0000250#if IS_X86
Stefan Taunerfa9fa712012-09-24 21:29:29 +0000251 if ((cb_parse_table(&cb_vendor, &cb_model) == 0) && (board_vendor != NULL) && (board_model != NULL)) {
252 if (strcasecmp(board_vendor, cb_vendor) || strcasecmp(board_model, cb_model)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000253 msg_pwarn("Warning: The mainboard IDs set by -p internal:mainboard (%s:%s) do not\n"
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000254 " match the current coreboot IDs of the mainboard (%s:%s).\n",
255 board_vendor, board_model, cb_vendor, cb_model);
Jacob Garber1c091d12019-08-12 11:14:14 -0600256 if (!force_boardmismatch) {
257 ret = 1;
258 goto internal_init_exit;
259 }
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000260 msg_pinfo("Continuing anyway.\n");
261 }
262 }
Carl-Daniel Hailfinger11990da2013-07-13 23:21:05 +0000263#endif
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000264
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000265#if IS_X86
Nico Huber2e50cdc2018-09-23 20:20:26 +0200266 is_laptop = 2; /* Assume that we don't know by default. */
267
Michael Karcher6701ee82010-01-20 14:14:11 +0000268 dmi_init();
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000269
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000270 /* In case Super I/O probing would cause pretty explosions. */
271 board_handle_before_superio();
272
Uwe Hermann43959702010-03-13 17:28:29 +0000273 /* Probe for the Super I/O chip and fill global struct superio. */
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000274 probe_superio();
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000275#else
276 /* FIXME: Enable cbtable searching on all non-x86 platforms supported
277 * by coreboot.
278 * FIXME: Find a replacement for DMI on non-x86.
279 * FIXME: Enable Super I/O probing once port I/O is possible.
280 */
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000281#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000282
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000283 /* Check laptop whitelist. */
284 board_handle_before_laptop();
285
Nico Huber2e50cdc2018-09-23 20:20:26 +0200286 /*
287 * Disable all internal buses by default if we are not sure
288 * this isn't a laptop. Board-enables may override this,
289 * non-legacy buses (SPI and opaque atm) are probed anyway.
290 */
291 if (is_laptop && !(laptop_ok || force_laptop || (not_a_laptop && is_laptop == 2)))
292 internal_buses_supported = BUS_NONE;
Michael Karcher8c1df282010-02-26 09:51:20 +0000293
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000294 /* try to enable it. Failure IS an option, since not all motherboards
295 * really need this to be done, etc., etc.
296 */
297 ret = chipset_flash_enable();
298 if (ret == -2) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000299 msg_perr("WARNING: No chipset found. Flash detection "
300 "will most likely fail.\n");
Jacob Garber1c091d12019-08-12 11:14:14 -0600301 } else if (ret == ERROR_FATAL) {
302 goto internal_init_exit;
303 }
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000304
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000305#if IS_X86
Vadim Girlin4dd0f902013-08-24 12:18:17 +0000306 /* Probe unconditionally for ITE Super I/O chips. This enables LPC->SPI translation on IT87* and
307 * parallel writes on IT8705F. Also, this handles the manual chip select for Gigabyte's DualBIOS. */
Carl-Daniel Hailfinger76d4b372010-07-10 16:56:32 +0000308 init_superio_ite();
Carl-Daniel Hailfinger01f3ef42010-03-25 02:50:40 +0000309
Stefan Taunerfa9fa712012-09-24 21:29:29 +0000310 if (board_flash_enable(board_vendor, board_model, cb_vendor, cb_model)) {
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000311 msg_perr("Aborting to be safe.\n");
Jacob Garber1c091d12019-08-12 11:14:14 -0600312 ret = 1;
313 goto internal_init_exit;
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000314 }
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000315#endif
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000316
Nico Huber2e50cdc2018-09-23 20:20:26 +0200317 if (internal_buses_supported & BUS_NONSPI)
318 register_par_master(&par_master_internal, internal_buses_supported);
319
320 /* Report if a non-whitelisted laptop is detected that likely uses a legacy bus. */
321 if (is_laptop && !laptop_ok) {
322 msg_pinfo("========================================================================\n");
323 if (is_laptop == 1) {
324 msg_pinfo("You seem to be running flashrom on an unknown laptop. Some\n"
325 "internal buses have been disabled for safety reasons.\n\n");
326 } else {
327 msg_pinfo("You may be running flashrom on an unknown laptop. We could not\n"
328 "detect this for sure because your vendor has not set up the SMBIOS\n"
329 "tables correctly. Some internal buses have been disabled for\n"
330 "safety reasons. You can enforce using all buses by adding\n"
331 " -p internal:laptop=this_is_not_a_laptop\n"
332 "to the command line, but please read the following warning if you\n"
333 "are not sure.\n\n");
334 }
335 msg_perr("Laptops, notebooks and netbooks are difficult to support and we\n"
336 "recommend to use the vendor flashing utility. The embedded controller\n"
337 "(EC) in these machines often interacts badly with flashing.\n"
338 "See the manpage and https://flashrom.org/Laptops for details.\n\n"
339 "If flash is shared with the EC, erase is guaranteed to brick your laptop\n"
340 "and write may brick your laptop.\n"
341 "Read and probe may irritate your EC and cause fan failure, backlight\n"
342 "failure and sudden poweroff.\n"
343 "You have been warned.\n"
344 "========================================================================\n");
345 }
346
Jacob Garber1c091d12019-08-12 11:14:14 -0600347 ret = 0;
348
349internal_init_exit:
350 free(board_vendor);
351 free(board_model);
352
353 return ret;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000354}
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000355
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000356static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
357 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000358{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000359 mmio_writeb(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000360}
361
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000362static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
363 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000364{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000365 mmio_writew(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000366}
367
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000368static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
369 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000370{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000371 mmio_writel(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000372}
373
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000374static uint8_t internal_chip_readb(const struct flashctx *flash,
375 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000376{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000377 return mmio_readb((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000378}
379
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000380static uint16_t internal_chip_readw(const struct flashctx *flash,
381 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000382{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000383 return mmio_readw((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000384}
385
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000386static uint32_t internal_chip_readl(const struct flashctx *flash,
387 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000388{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000389 return mmio_readl((void *) addr);
390}
391
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000392static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
393 const chipaddr addr, size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000394{
Carl-Daniel Hailfingerccd71c22012-03-01 22:38:27 +0000395 mmio_readn((void *)addr, buf, len);
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000396 return;
397}