blob: fa4579857b6469ed52c0c1231bfd71828aa856bb [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"
Thomas Heijligen74b4aa02021-12-14 17:52:30 +010022#include "hwaccess_physmap.h"
Thomas Heijligend96c97c2021-11-02 21:03:00 +010023#include "platform/pci.h"
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000024
Peter Marheinedf3672d2022-01-19 17:11:09 +110025#if defined(__i386__) || defined(__x86_64__)
26#include "hwaccess_x86_io.h"
27#endif
28
Uwe Hermann24c35e42011-07-13 11:22:03 +000029struct pci_dev *pci_dev_find_vendorclass(uint16_t vendor, uint16_t devclass)
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000030{
31 struct pci_dev *temp;
32 struct pci_filter filter;
33 uint16_t tmp2;
34
35 pci_filter_init(NULL, &filter);
36 filter.vendor = vendor;
37
38 for (temp = pacc->devices; temp; temp = temp->next)
39 if (pci_filter_match(&filter, temp)) {
40 /* Read PCI class */
41 tmp2 = pci_read_word(temp, 0x0a);
Nico Huber380090f2022-05-23 01:45:11 +020042 if (tmp2 == devclass) {
43 pci_fill_info(temp, PCI_FILL_IDENT);
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000044 return temp;
Nico Huber380090f2022-05-23 01:45:11 +020045 }
Carl-Daniel Hailfinger9f46cfc2009-11-15 17:13:29 +000046 }
47
48 return NULL;
49}
50
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000051struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device)
52{
53 struct pci_dev *temp;
54 struct pci_filter filter;
55
56 pci_filter_init(NULL, &filter);
57 filter.vendor = vendor;
58 filter.device = device;
59
Nico Huber380090f2022-05-23 01:45:11 +020060 for (temp = pacc->devices; temp; temp = temp->next) {
61 if (pci_filter_match(&filter, temp)) {
62 pci_fill_info(temp, PCI_FILL_IDENT);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000063 return temp;
Nico Huber380090f2022-05-23 01:45:11 +020064 }
65 }
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000066
67 return NULL;
68}
69
70struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
71 uint16_t card_vendor, uint16_t card_device)
72{
73 struct pci_dev *temp;
74 struct pci_filter filter;
75
76 pci_filter_init(NULL, &filter);
77 filter.vendor = vendor;
78 filter.device = device;
79
80 for (temp = pacc->devices; temp; temp = temp->next)
81 if (pci_filter_match(&filter, temp)) {
82 if ((card_vendor ==
83 pci_read_word(temp, PCI_SUBSYSTEM_VENDOR_ID))
84 && (card_device ==
Nico Huber380090f2022-05-23 01:45:11 +020085 pci_read_word(temp, PCI_SUBSYSTEM_ID))) {
86 pci_fill_info(temp, PCI_FILL_IDENT);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000087 return temp;
Nico Huber380090f2022-05-23 01:45:11 +020088 }
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000089 }
90
91 return NULL;
92}
93
Michael Karcher0bdc0922010-02-28 01:33:48 +000094int force_boardenable = 0;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +000095int force_boardmismatch = 0;
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000096
Thomas Heijligen4b918a12021-09-26 13:42:39 +020097#if defined(__i386__) || defined(__x86_64__)
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000098void probe_superio(void)
99{
Carl-Daniel Hailfingerf5e62cb2012-05-06 22:48:01 +0000100 probe_superio_winbond();
101 /* ITE probe causes SMSC LPC47N217 to power off the serial UART.
102 * Always probe for SMSC first, and if a SMSC Super I/O is detected
103 * at a given I/O port, do _not_ probe that port with the ITE probe.
104 * This means SMSC probing must be done before ITE probing.
105 */
106 //probe_superio_smsc();
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +0000107 probe_superio_ite();
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000108}
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +0000109
110int superio_count = 0;
111#define SUPERIO_MAX_COUNT 3
112
113struct superio superios[SUPERIO_MAX_COUNT];
114
115int register_superio(struct superio s)
116{
117 if (superio_count == SUPERIO_MAX_COUNT)
118 return 1;
119 superios[superio_count++] = s;
120 return 0;
121}
122
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000123#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000124
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000125int is_laptop = 0;
Felix Singerd1ab7d22022-08-19 03:03:47 +0200126bool laptop_ok = false;
Michael Karcher8c1df282010-02-26 09:51:20 +0000127
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000128static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
129 chipaddr addr);
130static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
131 chipaddr addr);
132static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
133 chipaddr addr);
134static uint8_t internal_chip_readb(const struct flashctx *flash,
135 const chipaddr addr);
136static uint16_t internal_chip_readw(const struct flashctx *flash,
137 const chipaddr addr);
138static uint32_t internal_chip_readl(const struct flashctx *flash,
139 const chipaddr addr);
140static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
141 const chipaddr addr, size_t len);
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000142static const struct par_master par_master_internal = {
Thomas Heijligen43040f22022-06-23 14:38:35 +0200143 .chip_readb = internal_chip_readb,
144 .chip_readw = internal_chip_readw,
145 .chip_readl = internal_chip_readl,
146 .chip_readn = internal_chip_readn,
147 .chip_writeb = internal_chip_writeb,
148 .chip_writew = internal_chip_writew,
149 .chip_writel = internal_chip_writel,
150 .chip_writen = fallback_chip_writen,
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000151};
152
153enum chipbustype internal_buses_supported = BUS_NONE;
154
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100155static int get_params(int *boardenable, int *boardmismatch,
156 int *force_laptop, int *not_a_laptop,
157 char **board_vendor, char **board_model)
Uwe Hermanna0869322009-05-14 20:41:57 +0000158{
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000159 char *arg;
Uwe Hermanna0869322009-05-14 20:41:57 +0000160
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100161 /* default values. */
162 *force_laptop = 0;
163 *not_a_laptop = 0;
164 *board_vendor = NULL;
165 *board_model = NULL;
166
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000167 arg = extract_programmer_param("boardenable");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000168 if (arg && !strcmp(arg,"force")) {
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100169 *boardenable = 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000170 } else if (arg && !strlen(arg)) {
171 msg_perr("Missing argument for boardenable.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000172 free(arg);
173 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000174 } else if (arg) {
175 msg_perr("Unknown argument for boardenable: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000176 free(arg);
177 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000178 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000179 free(arg);
Michael Karcher0bdc0922010-02-28 01:33:48 +0000180
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000181 arg = extract_programmer_param("boardmismatch");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000182 if (arg && !strcmp(arg,"force")) {
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100183 *boardmismatch = 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000184 } else if (arg && !strlen(arg)) {
185 msg_perr("Missing argument for boardmismatch.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000186 free(arg);
187 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000188 } else if (arg) {
189 msg_perr("Unknown argument for boardmismatch: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000190 free(arg);
191 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000192 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000193 free(arg);
194
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000195 arg = extract_programmer_param("laptop");
Stefan Taunera28087f2011-09-13 23:14:25 +0000196 if (arg && !strcmp(arg, "force_I_want_a_brick"))
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100197 *force_laptop = 1;
Stefan Taunera28087f2011-09-13 23:14:25 +0000198 else if (arg && !strcmp(arg, "this_is_not_a_laptop"))
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100199 *not_a_laptop = 1;
Stefan Taunera28087f2011-09-13 23:14:25 +0000200 else if (arg && !strlen(arg)) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000201 msg_perr("Missing argument for laptop.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000202 free(arg);
203 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000204 } else if (arg) {
205 msg_perr("Unknown argument for laptop: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000206 free(arg);
207 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000208 }
209 free(arg);
210
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000211 arg = extract_programmer_param("mainboard");
212 if (arg && strlen(arg)) {
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100213 if (board_parse_parameter(arg, board_vendor, board_model)) {
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000214 free(arg);
215 return 1;
216 }
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000217 } else if (arg && !strlen(arg)) {
218 msg_perr("Missing argument for mainboard.\n");
219 free(arg);
220 return 1;
221 }
222 free(arg);
223
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100224 return 0;
225}
226
227static int internal_init(void)
228{
229 int ret = 0;
230 int force_laptop;
231 int not_a_laptop;
232 char *board_vendor;
233 char *board_model;
234#if defined(__i386__) || defined(__x86_64__)
235 const char *cb_vendor = NULL;
236 const char *cb_model = NULL;
237#endif
238
239 ret = get_params(&force_boardenable, &force_boardmismatch,
240 &force_laptop, &not_a_laptop,
241 &board_vendor, &board_model);
242 if (ret)
243 return ret;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000244
Edward O'Callaghanbd275812022-11-28 11:20:44 +1100245 /* Unconditionally reset global state from previous operation. */
246 laptop_ok = false;
247
Michael Karcherb9dbe482011-05-11 17:07:07 +0000248 /* Default to Parallel/LPC/FWH flash devices. If a known host controller
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000249 * is found, the host controller init routine sets the
250 * internal_buses_supported bitfield.
Michael Karcherb9dbe482011-05-11 17:07:07 +0000251 */
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000252 internal_buses_supported = BUS_NONSPI;
Michael Karcherb9dbe482011-05-11 17:07:07 +0000253
Jacob Garber1c091d12019-08-12 11:14:14 -0600254 if (try_mtd() == 0) {
255 ret = 0;
256 goto internal_init_exit;
257 }
David Hendricksf9a30552015-05-23 20:30:30 -0700258
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000259 /* Initialize PCI access for flash enables */
Jacob Garber1c091d12019-08-12 11:14:14 -0600260 if (pci_init_common() != 0) {
261 ret = 1;
262 goto internal_init_exit;
263 }
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000264
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000265 if (processor_flash_enable()) {
266 msg_perr("Processor detection/init failed.\n"
267 "Aborting.\n");
Jacob Garber1c091d12019-08-12 11:14:14 -0600268 ret = 1;
269 goto internal_init_exit;
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000270 }
271
Thomas Heijligen4b918a12021-09-26 13:42:39 +0200272#if defined(__i386__) || defined(__x86_64__)
Peter Marheinedf3672d2022-01-19 17:11:09 +1100273 if (rget_io_perms()) {
274 ret = 1;
275 goto internal_init_exit;
276 }
277
Stefan Taunerfa9fa712012-09-24 21:29:29 +0000278 if ((cb_parse_table(&cb_vendor, &cb_model) == 0) && (board_vendor != NULL) && (board_model != NULL)) {
279 if (strcasecmp(board_vendor, cb_vendor) || strcasecmp(board_model, cb_model)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000280 msg_pwarn("Warning: The mainboard IDs set by -p internal:mainboard (%s:%s) do not\n"
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000281 " match the current coreboot IDs of the mainboard (%s:%s).\n",
282 board_vendor, board_model, cb_vendor, cb_model);
Jacob Garber1c091d12019-08-12 11:14:14 -0600283 if (!force_boardmismatch) {
284 ret = 1;
285 goto internal_init_exit;
286 }
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000287 msg_pinfo("Continuing anyway.\n");
288 }
289 }
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000290
Nico Huber2e50cdc2018-09-23 20:20:26 +0200291 is_laptop = 2; /* Assume that we don't know by default. */
292
Michael Karcher6701ee82010-01-20 14:14:11 +0000293 dmi_init();
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000294
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000295 /* In case Super I/O probing would cause pretty explosions. */
296 board_handle_before_superio();
297
Uwe Hermann43959702010-03-13 17:28:29 +0000298 /* Probe for the Super I/O chip and fill global struct superio. */
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000299 probe_superio();
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000300#else
301 /* FIXME: Enable cbtable searching on all non-x86 platforms supported
302 * by coreboot.
303 * FIXME: Find a replacement for DMI on non-x86.
304 * FIXME: Enable Super I/O probing once port I/O is possible.
305 */
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000306#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000307
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000308 /* Check laptop whitelist. */
309 board_handle_before_laptop();
310
Nico Huber2e50cdc2018-09-23 20:20:26 +0200311 /*
312 * Disable all internal buses by default if we are not sure
313 * this isn't a laptop. Board-enables may override this,
314 * non-legacy buses (SPI and opaque atm) are probed anyway.
315 */
316 if (is_laptop && !(laptop_ok || force_laptop || (not_a_laptop && is_laptop == 2)))
317 internal_buses_supported = BUS_NONE;
Michael Karcher8c1df282010-02-26 09:51:20 +0000318
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000319 /* try to enable it. Failure IS an option, since not all motherboards
320 * really need this to be done, etc., etc.
321 */
322 ret = chipset_flash_enable();
323 if (ret == -2) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000324 msg_perr("WARNING: No chipset found. Flash detection "
325 "will most likely fail.\n");
Jacob Garber1c091d12019-08-12 11:14:14 -0600326 } else if (ret == ERROR_FATAL) {
327 goto internal_init_exit;
328 }
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000329
Thomas Heijligen4b918a12021-09-26 13:42:39 +0200330#if defined(__i386__) || defined(__x86_64__)
Vadim Girlin4dd0f902013-08-24 12:18:17 +0000331 /* Probe unconditionally for ITE Super I/O chips. This enables LPC->SPI translation on IT87* and
332 * parallel writes on IT8705F. Also, this handles the manual chip select for Gigabyte's DualBIOS. */
Carl-Daniel Hailfinger76d4b372010-07-10 16:56:32 +0000333 init_superio_ite();
Carl-Daniel Hailfinger01f3ef42010-03-25 02:50:40 +0000334
Stefan Taunerfa9fa712012-09-24 21:29:29 +0000335 if (board_flash_enable(board_vendor, board_model, cb_vendor, cb_model)) {
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000336 msg_perr("Aborting to be safe.\n");
Jacob Garber1c091d12019-08-12 11:14:14 -0600337 ret = 1;
338 goto internal_init_exit;
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000339 }
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000340#endif
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000341
Nico Huber2e50cdc2018-09-23 20:20:26 +0200342 if (internal_buses_supported & BUS_NONSPI)
Anastasia Klimchukb91a2032021-05-21 09:40:58 +1000343 register_par_master(&par_master_internal, internal_buses_supported, NULL);
Nico Huber2e50cdc2018-09-23 20:20:26 +0200344
345 /* Report if a non-whitelisted laptop is detected that likely uses a legacy bus. */
346 if (is_laptop && !laptop_ok) {
347 msg_pinfo("========================================================================\n");
348 if (is_laptop == 1) {
349 msg_pinfo("You seem to be running flashrom on an unknown laptop. Some\n"
350 "internal buses have been disabled for safety reasons.\n\n");
351 } else {
352 msg_pinfo("You may be running flashrom on an unknown laptop. We could not\n"
353 "detect this for sure because your vendor has not set up the SMBIOS\n"
354 "tables correctly. Some internal buses have been disabled for\n"
355 "safety reasons. You can enforce using all buses by adding\n"
356 " -p internal:laptop=this_is_not_a_laptop\n"
357 "to the command line, but please read the following warning if you\n"
358 "are not sure.\n\n");
359 }
360 msg_perr("Laptops, notebooks and netbooks are difficult to support and we\n"
361 "recommend to use the vendor flashing utility. The embedded controller\n"
362 "(EC) in these machines often interacts badly with flashing.\n"
363 "See the manpage and https://flashrom.org/Laptops for details.\n\n"
364 "If flash is shared with the EC, erase is guaranteed to brick your laptop\n"
365 "and write may brick your laptop.\n"
366 "Read and probe may irritate your EC and cause fan failure, backlight\n"
367 "failure and sudden poweroff.\n"
368 "You have been warned.\n"
369 "========================================================================\n");
370 }
371
Jacob Garber1c091d12019-08-12 11:14:14 -0600372 ret = 0;
373
374internal_init_exit:
375 free(board_vendor);
376 free(board_model);
377
378 return ret;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000379}
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000380
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000381static void internal_chip_writeb(const struct flashctx *flash, uint8_t val,
382 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000383{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000384 mmio_writeb(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000385}
386
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000387static void internal_chip_writew(const struct flashctx *flash, uint16_t val,
388 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000389{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000390 mmio_writew(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000391}
392
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000393static void internal_chip_writel(const struct flashctx *flash, uint32_t val,
394 chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000395{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000396 mmio_writel(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000397}
398
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000399static uint8_t internal_chip_readb(const struct flashctx *flash,
400 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000401{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000402 return mmio_readb((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000403}
404
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000405static uint16_t internal_chip_readw(const struct flashctx *flash,
406 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000407{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000408 return mmio_readw((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000409}
410
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000411static uint32_t internal_chip_readl(const struct flashctx *flash,
412 const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000413{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000414 return mmio_readl((void *) addr);
415}
416
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000417static void internal_chip_readn(const struct flashctx *flash, uint8_t *buf,
418 const chipaddr addr, size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000419{
Carl-Daniel Hailfingerccd71c22012-03-01 22:38:27 +0000420 mmio_readn((void *)addr, buf, len);
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000421 return;
422}
Thomas Heijligencc853d82021-05-04 15:32:17 +0200423
424const struct programmer_entry programmer_internal = {
425 .name = "internal",
426 .type = OTHER,
427 .devs.note = NULL,
428 .init = internal_init,
429 .map_flash_region = physmap,
430 .unmap_flash_region = physunmap,
431 .delay = internal_delay,
432};