blob: 21066e4711ab6ab243b00e1e8ce4d404aff9d41d [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>
Felix Singerb8db74a2022-08-19 00:19:26 +020019#include <stdbool.h>
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000020#include <stdlib.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
Felix Singerb8db74a2022-08-19 00:19:26 +020029bool force_boardenable = false;
30bool force_boardmismatch = false;
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000031
Thomas Heijligen4b918a12021-09-26 13:42:39 +020032#if defined(__i386__) || defined(__x86_64__)
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000033void probe_superio(void)
34{
Carl-Daniel Hailfingerf5e62cb2012-05-06 22:48:01 +000035 probe_superio_winbond();
36 /* ITE probe causes SMSC LPC47N217 to power off the serial UART.
37 * Always probe for SMSC first, and if a SMSC Super I/O is detected
38 * at a given I/O port, do _not_ probe that port with the ITE probe.
39 * This means SMSC probing must be done before ITE probing.
40 */
41 //probe_superio_smsc();
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +000042 probe_superio_ite();
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000043}
Carl-Daniel Hailfingerbfecef62011-04-27 14:34:08 +000044
45int superio_count = 0;
46#define SUPERIO_MAX_COUNT 3
47
48struct superio superios[SUPERIO_MAX_COUNT];
49
50int register_superio(struct superio s)
51{
52 if (superio_count == SUPERIO_MAX_COUNT)
53 return 1;
54 superios[superio_count++] = s;
55 return 0;
56}
57
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +000058#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +000059
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +000060int is_laptop = 0;
Felix Singerd1ab7d22022-08-19 03:03:47 +020061bool laptop_ok = false;
Michael Karcher8c1df282010-02-26 09:51:20 +000062
Nico Huberdd6e07a2026-02-21 17:55:26 +010063static void internal_chip_writeb(const struct par_master *, uint8_t val, chipaddr);
64static void internal_chip_writew(const struct par_master *, uint16_t val, chipaddr);
65static void internal_chip_writel(const struct par_master *, uint32_t val, chipaddr);
66static uint8_t internal_chip_readb(const struct par_master *, chipaddr);
67static uint16_t internal_chip_readw(const struct par_master *, chipaddr);
68static uint32_t internal_chip_readl(const struct par_master *, chipaddr);
69static void internal_chip_readn(const struct par_master *, uint8_t *buf, chipaddr, size_t len);
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +000070static const struct par_master par_master_internal = {
Thomas Heijligen43040f22022-06-23 14:38:35 +020071 .chip_readb = internal_chip_readb,
72 .chip_readw = internal_chip_readw,
73 .chip_readl = internal_chip_readl,
74 .chip_readn = internal_chip_readn,
75 .chip_writeb = internal_chip_writeb,
76 .chip_writew = internal_chip_writew,
77 .chip_writel = internal_chip_writel,
78 .chip_writen = fallback_chip_writen,
Nico Huber0e76d992023-01-12 20:22:55 +010079 .map_flash = physmap,
80 .unmap_flash = physunmap,
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +000081};
82
83enum chipbustype internal_buses_supported = BUS_NONE;
84
Felix Singerb8db74a2022-08-19 00:19:26 +020085static int get_params(bool *boardenable, bool *boardmismatch,
86 bool *force_laptop, bool *not_a_laptop,
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +110087 char **board_vendor, char **board_model)
Uwe Hermanna0869322009-05-14 20:41:57 +000088{
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +000089 char *arg;
Uwe Hermanna0869322009-05-14 20:41:57 +000090
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +110091 /* default values. */
Felix Singerb8db74a2022-08-19 00:19:26 +020092 *force_laptop = false;
93 *not_a_laptop = false;
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +110094 *board_vendor = NULL;
95 *board_model = NULL;
96
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +000097 arg = extract_programmer_param("boardenable");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +000098 if (arg && !strcmp(arg,"force")) {
Felix Singerb8db74a2022-08-19 00:19:26 +020099 *boardenable = true;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000100 } else if (arg && !strlen(arg)) {
101 msg_perr("Missing argument for boardenable.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000102 free(arg);
103 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000104 } else if (arg) {
105 msg_perr("Unknown argument for boardenable: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000106 free(arg);
107 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000108 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000109 free(arg);
Michael Karcher0bdc0922010-02-28 01:33:48 +0000110
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000111 arg = extract_programmer_param("boardmismatch");
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000112 if (arg && !strcmp(arg,"force")) {
Felix Singerb8db74a2022-08-19 00:19:26 +0200113 *boardmismatch = true;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000114 } else if (arg && !strlen(arg)) {
115 msg_perr("Missing argument for boardmismatch.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000116 free(arg);
117 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000118 } else if (arg) {
119 msg_perr("Unknown argument for boardmismatch: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000120 free(arg);
121 return 1;
Michael Karcher0bdc0922010-02-28 01:33:48 +0000122 }
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000123 free(arg);
124
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000125 arg = extract_programmer_param("laptop");
Stefan Taunera28087f2011-09-13 23:14:25 +0000126 if (arg && !strcmp(arg, "force_I_want_a_brick"))
Felix Singerb8db74a2022-08-19 00:19:26 +0200127 *force_laptop = true;
Stefan Taunera28087f2011-09-13 23:14:25 +0000128 else if (arg && !strcmp(arg, "this_is_not_a_laptop"))
Felix Singerb8db74a2022-08-19 00:19:26 +0200129 *not_a_laptop = true;
Stefan Taunera28087f2011-09-13 23:14:25 +0000130 else if (arg && !strlen(arg)) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000131 msg_perr("Missing argument for laptop.\n");
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000132 free(arg);
133 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000134 } else if (arg) {
135 msg_perr("Unknown argument for laptop: %s\n", arg);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000136 free(arg);
137 return 1;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000138 }
139 free(arg);
140
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000141 arg = extract_programmer_param("mainboard");
142 if (arg && strlen(arg)) {
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100143 if (board_parse_parameter(arg, board_vendor, board_model)) {
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000144 free(arg);
145 return 1;
146 }
Carl-Daniel Hailfinger2d927fb2012-01-04 00:48:27 +0000147 } else if (arg && !strlen(arg)) {
148 msg_perr("Missing argument for mainboard.\n");
149 free(arg);
150 return 1;
151 }
152 free(arg);
153
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100154 return 0;
155}
156
Nico Hubere3a26882023-01-11 21:45:51 +0100157static int internal_init(struct flashprog_programmer *const prog)
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100158{
159 int ret = 0;
Felix Singerb8db74a2022-08-19 00:19:26 +0200160 bool force_laptop;
161 bool not_a_laptop;
Edward O'Callaghand91ee2c2022-02-03 11:55:13 +1100162 char *board_vendor;
163 char *board_model;
164#if defined(__i386__) || defined(__x86_64__)
165 const char *cb_vendor = NULL;
166 const char *cb_model = NULL;
167#endif
168
169 ret = get_params(&force_boardenable, &force_boardmismatch,
170 &force_laptop, &not_a_laptop,
171 &board_vendor, &board_model);
172 if (ret)
173 return ret;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000174
Nico Huber89569d62023-01-12 23:31:40 +0100175 struct internal_data *const internal = malloc(sizeof(*internal));
176 if (!internal) {
177 msg_perr("Out of memory!\n");
178 ret = 1;
179 goto internal_init_exit;
180 }
181 if (register_shutdown(shutdown_free, internal)) {
182 ret = 1;
183 goto internal_init_exit;
184 }
Nico Huber47aa85c2026-02-21 14:57:20 +0100185 internal->rom_base = 0; /* Default to top aligned flash at 4 GB. */
Nico Huber89569d62023-01-12 23:31:40 +0100186 internal->max_rom_decode = 0;
187 prog->data = internal;
188
Edward O'Callaghanbd275812022-11-28 11:20:44 +1100189 /* Unconditionally reset global state from previous operation. */
190 laptop_ok = false;
191
Michael Karcherb9dbe482011-05-11 17:07:07 +0000192 /* Default to Parallel/LPC/FWH flash devices. If a known host controller
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000193 * is found, the host controller init routine sets the
194 * internal_buses_supported bitfield.
Michael Karcherb9dbe482011-05-11 17:07:07 +0000195 */
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000196 internal_buses_supported = BUS_NONSPI;
Michael Karcherb9dbe482011-05-11 17:07:07 +0000197
Nico Hubere3a26882023-01-11 21:45:51 +0100198 if (try_mtd(prog) == 0) {
Jacob Garber1c091d12019-08-12 11:14:14 -0600199 ret = 0;
200 goto internal_init_exit;
201 }
David Hendricksf9a30552015-05-23 20:30:30 -0700202
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000203 /* Initialize PCI access for flash enables */
Jacob Garber1c091d12019-08-12 11:14:14 -0600204 if (pci_init_common() != 0) {
205 ret = 1;
206 goto internal_init_exit;
207 }
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000208
Nico Huber47aa85c2026-02-21 14:57:20 +0100209 if (processor_flash_enable(prog)) {
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000210 msg_perr("Processor detection/init failed.\n"
211 "Aborting.\n");
Jacob Garber1c091d12019-08-12 11:14:14 -0600212 ret = 1;
213 goto internal_init_exit;
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000214 }
215
Thomas Heijligen4b918a12021-09-26 13:42:39 +0200216#if defined(__i386__) || defined(__x86_64__)
Peter Marheinedf3672d2022-01-19 17:11:09 +1100217 if (rget_io_perms()) {
218 ret = 1;
219 goto internal_init_exit;
220 }
221
Stefan Taunerfa9fa712012-09-24 21:29:29 +0000222 if ((cb_parse_table(&cb_vendor, &cb_model) == 0) && (board_vendor != NULL) && (board_model != NULL)) {
223 if (strcasecmp(board_vendor, cb_vendor) || strcasecmp(board_model, cb_model)) {
Stefan Taunerc6fa32d2013-01-04 22:54:07 +0000224 msg_pwarn("Warning: The mainboard IDs set by -p internal:mainboard (%s:%s) do not\n"
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000225 " match the current coreboot IDs of the mainboard (%s:%s).\n",
226 board_vendor, board_model, cb_vendor, cb_model);
Jacob Garber1c091d12019-08-12 11:14:14 -0600227 if (!force_boardmismatch) {
228 ret = 1;
229 goto internal_init_exit;
230 }
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000231 msg_pinfo("Continuing anyway.\n");
232 }
233 }
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000234
Nico Huber2e50cdc2018-09-23 20:20:26 +0200235 is_laptop = 2; /* Assume that we don't know by default. */
236
Michael Karcher6701ee82010-01-20 14:14:11 +0000237 dmi_init();
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000238
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000239 /* In case Super I/O probing would cause pretty explosions. */
Nico Huber7c717c32023-01-12 00:28:15 +0100240 board_handle_before_superio(prog);
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000241
Uwe Hermann43959702010-03-13 17:28:29 +0000242 /* Probe for the Super I/O chip and fill global struct superio. */
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000243 probe_superio();
Carl-Daniel Hailfingerb5b161b2010-06-04 19:05:39 +0000244#else
245 /* FIXME: Enable cbtable searching on all non-x86 platforms supported
246 * by coreboot.
247 * FIXME: Find a replacement for DMI on non-x86.
248 * FIXME: Enable Super I/O probing once port I/O is possible.
249 */
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000250#endif
Carl-Daniel Hailfinger14e100c2009-12-22 23:42:04 +0000251
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000252 /* Check laptop whitelist. */
Nico Huber7c717c32023-01-12 00:28:15 +0100253 board_handle_before_laptop(prog);
Carl-Daniel Hailfinger580d29a2011-05-05 07:12:40 +0000254
Nico Huber2e50cdc2018-09-23 20:20:26 +0200255 /*
256 * Disable all internal buses by default if we are not sure
257 * this isn't a laptop. Board-enables may override this,
258 * non-legacy buses (SPI and opaque atm) are probed anyway.
259 */
260 if (is_laptop && !(laptop_ok || force_laptop || (not_a_laptop && is_laptop == 2)))
261 internal_buses_supported = BUS_NONE;
Michael Karcher8c1df282010-02-26 09:51:20 +0000262
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000263 /* try to enable it. Failure IS an option, since not all motherboards
264 * really need this to be done, etc., etc.
265 */
Nico Huber929d2e12023-01-12 00:47:05 +0100266 ret = chipset_flash_enable(prog);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000267 if (ret == -2) {
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000268 msg_perr("WARNING: No chipset found. Flash detection "
269 "will most likely fail.\n");
Jacob Garber1c091d12019-08-12 11:14:14 -0600270 } else if (ret == ERROR_FATAL) {
271 goto internal_init_exit;
272 }
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000273
Thomas Heijligen4b918a12021-09-26 13:42:39 +0200274#if defined(__i386__) || defined(__x86_64__)
Vadim Girlin4dd0f902013-08-24 12:18:17 +0000275 /* Probe unconditionally for ITE Super I/O chips. This enables LPC->SPI translation on IT87* and
276 * parallel writes on IT8705F. Also, this handles the manual chip select for Gigabyte's DualBIOS. */
Nico Huber89569d62023-01-12 23:31:40 +0100277 init_superio_ite(prog);
Carl-Daniel Hailfinger01f3ef42010-03-25 02:50:40 +0000278
Nico Huber7c717c32023-01-12 00:28:15 +0100279 if (board_flash_enable(prog, board_vendor, board_model, cb_vendor, cb_model)) {
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000280 msg_perr("Aborting to be safe.\n");
Jacob Garber1c091d12019-08-12 11:14:14 -0600281 ret = 1;
282 goto internal_init_exit;
Stefan Taunerb4e06bd2012-08-20 00:24:22 +0000283 }
Stefan Taunerb0eee9b2015-01-10 09:32:50 +0000284#endif
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000285
Nico Huber89569d62023-01-12 23:31:40 +0100286 if (internal_buses_supported & BUS_NONSPI) {
287 register_par_master(&par_master_internal, internal_buses_supported,
Nico Huber47aa85c2026-02-21 14:57:20 +0100288 internal->rom_base, internal->max_rom_decode, NULL);
Nico Huber89569d62023-01-12 23:31:40 +0100289 }
Nico Huber2e50cdc2018-09-23 20:20:26 +0200290
291 /* Report if a non-whitelisted laptop is detected that likely uses a legacy bus. */
292 if (is_laptop && !laptop_ok) {
293 msg_pinfo("========================================================================\n");
294 if (is_laptop == 1) {
Nico Huberc3b02dc2023-08-12 01:13:45 +0200295 msg_pinfo("You seem to be running flashprog on an unknown laptop. Some\n"
Nico Huber2e50cdc2018-09-23 20:20:26 +0200296 "internal buses have been disabled for safety reasons.\n\n");
297 } else {
Nico Huberc3b02dc2023-08-12 01:13:45 +0200298 msg_pinfo("You may be running flashprog on an unknown laptop. We could not\n"
Nico Huber2e50cdc2018-09-23 20:20:26 +0200299 "detect this for sure because your vendor has not set up the SMBIOS\n"
300 "tables correctly. Some internal buses have been disabled for\n"
301 "safety reasons. You can enforce using all buses by adding\n"
302 " -p internal:laptop=this_is_not_a_laptop\n"
303 "to the command line, but please read the following warning if you\n"
304 "are not sure.\n\n");
305 }
306 msg_perr("Laptops, notebooks and netbooks are difficult to support and we\n"
307 "recommend to use the vendor flashing utility. The embedded controller\n"
308 "(EC) in these machines often interacts badly with flashing.\n"
Nico Huberc3b02dc2023-08-12 01:13:45 +0200309 "See the manpage and https://flashprog.org/Laptops for details.\n\n"
Nico Huber2e50cdc2018-09-23 20:20:26 +0200310 "If flash is shared with the EC, erase is guaranteed to brick your laptop\n"
311 "and write may brick your laptop.\n"
312 "Read and probe may irritate your EC and cause fan failure, backlight\n"
313 "failure and sudden poweroff.\n"
314 "You have been warned.\n"
315 "========================================================================\n");
316 }
317
Jacob Garber1c091d12019-08-12 11:14:14 -0600318 ret = 0;
319
320internal_init_exit:
321 free(board_vendor);
322 free(board_model);
323
324 return ret;
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000325}
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000326
Nico Huberdd6e07a2026-02-21 17:55:26 +0100327static void internal_chip_writeb(const struct par_master *par, uint8_t val, chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000328{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000329 mmio_writeb(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000330}
331
Nico Huberdd6e07a2026-02-21 17:55:26 +0100332static void internal_chip_writew(const struct par_master *par, uint16_t val, chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000333{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000334 mmio_writew(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000335}
336
Nico Huberdd6e07a2026-02-21 17:55:26 +0100337static void internal_chip_writel(const struct par_master *par, uint32_t val, chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000338{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000339 mmio_writel(val, (void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000340}
341
Nico Huberdd6e07a2026-02-21 17:55:26 +0100342static uint8_t internal_chip_readb(const struct par_master *par, const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000343{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000344 return mmio_readb((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000345}
346
Nico Huberdd6e07a2026-02-21 17:55:26 +0100347static uint16_t internal_chip_readw(const struct par_master *par, const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000348{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000349 return mmio_readw((void *) addr);
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000350}
351
Nico Huberdd6e07a2026-02-21 17:55:26 +0100352static uint32_t internal_chip_readl(const struct par_master *par, const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000353{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000354 return mmio_readl((void *) addr);
355}
356
Nico Huberdd6e07a2026-02-21 17:55:26 +0100357static void internal_chip_readn(const struct par_master *par, uint8_t *buf,
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000358 const chipaddr addr, size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000359{
Carl-Daniel Hailfingerccd71c22012-03-01 22:38:27 +0000360 mmio_readn((void *)addr, buf, len);
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000361 return;
362}
Thomas Heijligencc853d82021-05-04 15:32:17 +0200363
364const struct programmer_entry programmer_internal = {
365 .name = "internal",
366 .type = OTHER,
367 .devs.note = NULL,
368 .init = internal_init,
Thomas Heijligencc853d82021-05-04 15:32:17 +0200369};