blob: b999065d51056bdf7ab44a87aa8b337ed0a6b193 [file] [log] [blame]
rminnich8d3ff912003-10-25 17:01:29 +00001/*
uweb25f1ea2007-08-29 17:52:32 +00002 * This file is part of the flashrom project.
rminnich8d3ff912003-10-25 17:01:29 +00003 *
uwe555dd972007-09-09 20:21:05 +00004 * Copyright (C) 2000 Silicon Integrated System Corporation
5 * Copyright (C) 2004 Tyan Corp <yhlu@tyan.com>
uwe4475e902009-05-19 14:14:21 +00006 * Copyright (C) 2005-2008 coresystems GmbH
hailfinger23060112009-05-08 12:49:03 +00007 * Copyright (C) 2008,2009 Carl-Daniel Hailfinger
Edward O'Callaghan0949b782019-11-10 23:23:20 +11008 * Copyright (C) 2016 secunet Security Networks AG
9 * (Written by Nico Huber <nico.huber@secunet.com> for secunet)
rminnich8d3ff912003-10-25 17:01:29 +000010 *
uweb25f1ea2007-08-29 17:52:32 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
rminnich8d3ff912003-10-25 17:01:29 +000015 *
uweb25f1ea2007-08-29 17:52:32 +000016 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
rminnich8d3ff912003-10-25 17:01:29 +000020 */
21
hailfingera83a5fe2010-05-30 22:24:40 +000022#include <stdio.h>
stepan1da96c02006-11-21 23:48:51 +000023#include <sys/types.h>
oxygene50275892010-09-30 17:03:32 +000024#ifndef __LIBPAYLOAD__
25#include <fcntl.h>
stepan1da96c02006-11-21 23:48:51 +000026#include <sys/stat.h>
oxygene50275892010-09-30 17:03:32 +000027#endif
rminnich8d3ff912003-10-25 17:01:29 +000028#include <string.h>
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +100029#include <unistd.h>
rminnich8d3ff912003-10-25 17:01:29 +000030#include <stdlib.h>
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +100031#include <errno.h>
hailfingerf76cc322010-11-09 22:00:31 +000032#include <ctype.h>
ollie6a600992005-11-26 21:55:36 +000033#include <getopt.h>
hailfinger3b471632010-03-27 16:36:40 +000034#if HAVE_UTSNAME == 1
35#include <sys/utsname.h>
36#endif
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -070037
38#include "action_descriptor.h"
rminnich8d3ff912003-10-25 17:01:29 +000039#include "flash.h"
hailfinger66966da2009-06-15 14:14:48 +000040#include "flashchips.h"
hailfinger428f6852010-07-27 22:41:39 +000041#include "programmer.h"
Duncan Laurie25a4ca22019-04-25 12:08:52 -070042#include "spi.h"
Edward O'Callaghan99974452020-10-13 13:28:33 +110043#include "chipdrivers.h"
rminnich8d3ff912003-10-25 17:01:29 +000044
krause2eb76212011-01-17 07:50:42 +000045const char flashrom_version[] = FLASHROM_VERSION;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100046const char *chip_to_probe = NULL;
hailfinger80422e22009-12-13 22:28:00 +000047
David Hendricks9ba79fb2015-04-03 12:06:16 -070048/* Set if any erase/write operation is to be done. This will be used to
49 * decide if final verification is needed. */
50static int content_has_changed = 0;
51
David Hendricks1ed1d352011-11-23 17:54:37 -080052/* error handling stuff */
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +110053static enum error_action access_denied_action = error_ignore;
David Hendricks1ed1d352011-11-23 17:54:37 -080054
55int ignore_error(int err) {
56 int rc = 0;
57
58 switch(err) {
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +110059 case SPI_ACCESS_DENIED:
David Hendricks1ed1d352011-11-23 17:54:37 -080060 if (access_denied_action == error_ignore)
61 rc = 1;
62 break;
63 default:
64 break;
65 }
66
67 return rc;
68}
69
hailfinger969e2f32011-09-08 00:00:29 +000070static enum programmer programmer = PROGRAMMER_INVALID;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100071static const char *programmer_param = NULL;
stepan782fb172007-04-06 11:58:03 +000072
uwee15beb92010-08-08 17:01:18 +000073/*
hailfinger80422e22009-12-13 22:28:00 +000074 * Programmers supporting multiple buses can have differing size limits on
75 * each bus. Store the limits for each bus in a common struct.
76 */
hailfinger1ff33dc2010-07-03 11:02:10 +000077struct decode_sizes max_rom_decode;
78
79/* If nonzero, used as the start address of bottom-aligned flash. */
80unsigned long flashbase;
hailfinger80422e22009-12-13 22:28:00 +000081
hailfinger5828baf2010-07-03 12:14:25 +000082/* Is writing allowed with this programmer? */
83int programmer_may_write;
84
hailfingerabe249e2009-05-08 17:43:22 +000085const struct programmer_entry programmer_table[] = {
hailfinger90c7d542010-05-31 15:27:27 +000086#if CONFIG_INTERNAL == 1
hailfingerabe249e2009-05-08 17:43:22 +000087 {
hailfinger3548a9a2009-08-12 14:34:35 +000088 .name = "internal",
Edward O'Callaghan0949b782019-11-10 23:23:20 +110089 .type = OTHER,
90 .devs.note = NULL,
hailfinger6c69ab02009-05-11 15:46:43 +000091 .init = internal_init,
hailfinger11ae3c42009-05-11 14:13:25 +000092 .map_flash_region = physmap,
93 .unmap_flash_region = physunmap,
hailfingere5829f62009-06-05 17:48:08 +000094 .delay = internal_delay,
David Hendricks55cdd9c2015-11-25 14:37:26 -080095
96 /*
97 * "Internal" implies in-system programming on a live system, so
98 * handle with paranoia to catch errors early. If something goes
99 * wrong then hopefully the system will still be recoverable.
100 */
101 .paranoid = 1,
hailfingerabe249e2009-05-08 17:43:22 +0000102 },
hailfinger80422e22009-12-13 22:28:00 +0000103#endif
stepan927d4e22007-04-04 22:45:58 +0000104
hailfinger90c7d542010-05-31 15:27:27 +0000105#if CONFIG_DUMMY == 1
hailfingera9df33c2009-05-09 00:54:55 +0000106 {
hailfinger3548a9a2009-08-12 14:34:35 +0000107 .name = "dummy",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100108 .type = OTHER,
109 /* FIXME */
110 .devs.note = "Dummy device, does nothing and logs all accesses\n",
hailfinger6c69ab02009-05-11 15:46:43 +0000111 .init = dummy_init,
hailfinger11ae3c42009-05-11 14:13:25 +0000112 .map_flash_region = dummy_map,
113 .unmap_flash_region = dummy_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000114 .delay = internal_delay,
hailfingera9df33c2009-05-09 00:54:55 +0000115 },
hailfinger571a6b32009-09-16 10:09:21 +0000116#endif
hailfingera9df33c2009-05-09 00:54:55 +0000117
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000118#if CONFIG_MEC1308 == 1
119 {
120 .name = "mec1308",
121 .type = OTHER,
122 .devs.note = "Microchip MEC1308 Embedded Controller.\n",
123 .init = mec1308_init,
124 .map_flash_region = fallback_map,
125 .unmap_flash_region = fallback_unmap,
126 .delay = internal_delay,
127 },
128#endif
129
hailfinger90c7d542010-05-31 15:27:27 +0000130#if CONFIG_NIC3COM == 1
uwe0f5a3a22009-05-13 11:36:06 +0000131 {
hailfinger3548a9a2009-08-12 14:34:35 +0000132 .name = "nic3com",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100133 .type = PCI,
134 .devs.dev = nics_3com,
uwe0f5a3a22009-05-13 11:36:06 +0000135 .init = nic3com_init,
uwe3e656bd2009-05-17 23:12:17 +0000136 .map_flash_region = fallback_map,
137 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000138 .delay = internal_delay,
uwe0f5a3a22009-05-13 11:36:06 +0000139 },
hailfinger571a6b32009-09-16 10:09:21 +0000140#endif
uwe0f5a3a22009-05-13 11:36:06 +0000141
hailfinger90c7d542010-05-31 15:27:27 +0000142#if CONFIG_NICREALTEK == 1
hailfinger5aa36982010-05-21 21:54:07 +0000143 {
hailfinger0d703d42011-03-07 01:08:09 +0000144 /* This programmer works for Realtek RTL8139 and SMC 1211. */
uwe8d342eb2011-07-28 08:13:25 +0000145 .name = "nicrealtek",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100146 .type = PCI,
147 .devs.dev = nics_realtek,
uwe8d342eb2011-07-28 08:13:25 +0000148 .init = nicrealtek_init,
149 .map_flash_region = fallback_map,
150 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000151 .delay = internal_delay,
hailfinger5aa36982010-05-21 21:54:07 +0000152 },
hailfinger5aa36982010-05-21 21:54:07 +0000153#endif
154
hailfingerf0a368f2010-06-07 22:37:54 +0000155#if CONFIG_NICNATSEMI == 1
156 {
uwe8d342eb2011-07-28 08:13:25 +0000157 .name = "nicnatsemi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100158 .type = PCI,
159 .devs.dev = nics_natsemi,
uwe8d342eb2011-07-28 08:13:25 +0000160 .init = nicnatsemi_init,
161 .map_flash_region = fallback_map,
162 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000163 .delay = internal_delay,
hailfingerf0a368f2010-06-07 22:37:54 +0000164 },
165#endif
hailfinger5aa36982010-05-21 21:54:07 +0000166
hailfinger90c7d542010-05-31 15:27:27 +0000167#if CONFIG_GFXNVIDIA == 1
uweff4576d2009-09-30 18:29:55 +0000168 {
169 .name = "gfxnvidia",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100170 .type = PCI,
171 .devs.dev = gfx_nvidia,
uweff4576d2009-09-30 18:29:55 +0000172 .init = gfxnvidia_init,
uweff4576d2009-09-30 18:29:55 +0000173 .map_flash_region = fallback_map,
174 .unmap_flash_region = fallback_unmap,
uweff4576d2009-09-30 18:29:55 +0000175 .delay = internal_delay,
176 },
177#endif
178
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000179#if CONFIG_RAIDEN_DEBUG_SPI == 1
180 {
181 .name = "raiden_debug_spi",
182 .type = USB,
183 .devs.dev = devs_raiden,
184 .init = raiden_debug_spi_init,
185 .map_flash_region = fallback_map,
186 .unmap_flash_region = fallback_unmap,
187 .delay = internal_delay,
188 },
189#endif
190
hailfinger90c7d542010-05-31 15:27:27 +0000191#if CONFIG_DRKAISER == 1
ruikda922a12009-05-17 19:39:27 +0000192 {
uwee2f95ef2009-09-02 23:00:46 +0000193 .name = "drkaiser",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100194 .type = PCI,
195 .devs.dev = drkaiser_pcidev,
uwee2f95ef2009-09-02 23:00:46 +0000196 .init = drkaiser_init,
uwee2f95ef2009-09-02 23:00:46 +0000197 .map_flash_region = fallback_map,
198 .unmap_flash_region = fallback_unmap,
uwee2f95ef2009-09-02 23:00:46 +0000199 .delay = internal_delay,
200 },
hailfinger571a6b32009-09-16 10:09:21 +0000201#endif
uwee2f95ef2009-09-02 23:00:46 +0000202
hailfinger90c7d542010-05-31 15:27:27 +0000203#if CONFIG_SATASII == 1
uwee2f95ef2009-09-02 23:00:46 +0000204 {
hailfinger3548a9a2009-08-12 14:34:35 +0000205 .name = "satasii",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100206 .type = PCI,
207 .devs.dev = satas_sii,
ruikda922a12009-05-17 19:39:27 +0000208 .init = satasii_init,
uwe3e656bd2009-05-17 23:12:17 +0000209 .map_flash_region = fallback_map,
210 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000211 .delay = internal_delay,
ruikda922a12009-05-17 19:39:27 +0000212 },
hailfinger571a6b32009-09-16 10:09:21 +0000213#endif
ruikda922a12009-05-17 19:39:27 +0000214
hailfinger90c7d542010-05-31 15:27:27 +0000215#if CONFIG_ATAHPT == 1
uwe7e627c82010-02-21 21:17:00 +0000216 {
217 .name = "atahpt",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100218 .type = PCI,
219 .devs.dev = ata_hpt,
uwe7e627c82010-02-21 21:17:00 +0000220 .init = atahpt_init,
uwe7e627c82010-02-21 21:17:00 +0000221 .map_flash_region = fallback_map,
222 .unmap_flash_region = fallback_unmap,
uwe7e627c82010-02-21 21:17:00 +0000223 .delay = internal_delay,
224 },
225#endif
226
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000227#if CONFIG_ATAVIA == 1
228 {
229 .name = "atavia",
230 .type = PCI,
231 .devs.dev = ata_via,
232 .init = atavia_init,
233 .map_flash_region = atavia_map,
234 .unmap_flash_region = fallback_unmap,
235 .delay = internal_delay,
236 },
237#endif
238
239#if CONFIG_ATAPROMISE == 1
240 {
241 .name = "atapromise",
242 .type = PCI,
243 .devs.dev = ata_promise,
244 .init = atapromise_init,
245 .map_flash_region = atapromise_map,
246 .unmap_flash_region = fallback_unmap,
247 .delay = internal_delay,
248 },
249#endif
250
251#if CONFIG_IT8212 == 1
252 {
253 .name = "it8212",
254 .type = PCI,
255 .devs.dev = devs_it8212,
256 .init = it8212_init,
257 .map_flash_region = fallback_map,
258 .unmap_flash_region = fallback_unmap,
259 .delay = internal_delay,
260 },
261#endif
262
hailfinger90c7d542010-05-31 15:27:27 +0000263#if CONFIG_FT2232_SPI == 1
hailfingerf31da3d2009-06-16 21:08:06 +0000264 {
hailfinger90c7d542010-05-31 15:27:27 +0000265 .name = "ft2232_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100266 .type = USB,
Nikolai Artemievc347a852020-04-29 12:17:08 +1000267 .devs.dev = devs_ft2232spi,
hailfingerf31da3d2009-06-16 21:08:06 +0000268 .init = ft2232_spi_init,
hailfinger6fe23d62009-08-12 11:39:29 +0000269 .map_flash_region = fallback_map,
270 .unmap_flash_region = fallback_unmap,
hailfingerf31da3d2009-06-16 21:08:06 +0000271 .delay = internal_delay,
272 },
hailfingerd9dcfbd2009-08-19 13:27:58 +0000273#endif
hailfinger6fe23d62009-08-12 11:39:29 +0000274
hailfinger90c7d542010-05-31 15:27:27 +0000275#if CONFIG_SERPROG == 1
hailfinger37b4fbf2009-06-23 11:33:43 +0000276 {
hailfinger3548a9a2009-08-12 14:34:35 +0000277 .name = "serprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100278 .type = OTHER,
279 /* FIXME */
280 .devs.note = "All programmer devices speaking the serprog protocol\n",
hailfinger37b4fbf2009-06-23 11:33:43 +0000281 .init = serprog_init,
Edward O'Callaghan62018182020-10-03 00:16:48 +1000282 .map_flash_region = serprog_map,
hailfinger37b4fbf2009-06-23 11:33:43 +0000283 .unmap_flash_region = fallback_unmap,
hailfinger37b4fbf2009-06-23 11:33:43 +0000284 .delay = serprog_delay,
285 },
hailfinger74d88a72009-08-12 16:17:41 +0000286#endif
hailfingerf31da3d2009-06-16 21:08:06 +0000287
hailfinger90c7d542010-05-31 15:27:27 +0000288#if CONFIG_BUSPIRATE_SPI == 1
hailfinger9c5add72009-11-24 00:20:03 +0000289 {
hailfinger90c7d542010-05-31 15:27:27 +0000290 .name = "buspirate_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100291 .type = OTHER,
292 /* FIXME */
293 .devs.note = "Dangerous Prototypes Bus Pirate\n",
hailfinger9c5add72009-11-24 00:20:03 +0000294 .init = buspirate_spi_init,
hailfinger9c5add72009-11-24 00:20:03 +0000295 .map_flash_region = fallback_map,
296 .unmap_flash_region = fallback_unmap,
hailfinger9c5add72009-11-24 00:20:03 +0000297 .delay = internal_delay,
298 },
299#endif
300
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000301#if CONFIG_DEDIPROG == 1
Anton Staafb2647882014-09-17 15:13:43 -0700302 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000303 .name = "dediprog",
Brian J. Nemecb42d6c12020-07-23 03:07:38 -0700304 .type = USB,
Edward O'Callaghanac1678b2020-07-27 15:55:45 +1000305 .devs.dev = devs_dediprog,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000306 .init = dediprog_init,
Anton Staafb2647882014-09-17 15:13:43 -0700307 .map_flash_region = fallback_map,
308 .unmap_flash_region = fallback_unmap,
309 .delay = internal_delay,
310 },
311#endif
312
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000313#if CONFIG_DEVELOPERBOX_SPI == 1
hailfingerdfb32a02010-01-19 11:15:48 +0000314 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000315 .name = "developerbox",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100316 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000317 .devs.dev = devs_developerbox_spi,
318 .init = developerbox_spi_init,
319 .map_flash_region = fallback_map,
320 .unmap_flash_region = fallback_unmap,
321 .delay = internal_delay,
322 },
323#endif
324
325#if CONFIG_ENE_LPC == 1
326 {
327 .name = "ene_lpc",
328 .type = OTHER,
329 .devs.note = "ENE LPC interface keyboard controller\n",
330 .init = ene_lpc_init,
hailfingerdfb32a02010-01-19 11:15:48 +0000331 .map_flash_region = fallback_map,
332 .unmap_flash_region = fallback_unmap,
hailfingerdfb32a02010-01-19 11:15:48 +0000333 .delay = internal_delay,
334 },
335#endif
336
hailfinger52c4fa02010-07-21 10:26:01 +0000337#if CONFIG_RAYER_SPI == 1
338 {
339 .name = "rayer_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100340 .type = OTHER,
341 /* FIXME */
342 .devs.note = "RayeR parallel port programmer\n",
hailfinger52c4fa02010-07-21 10:26:01 +0000343 .init = rayer_spi_init,
hailfinger52c4fa02010-07-21 10:26:01 +0000344 .map_flash_region = fallback_map,
345 .unmap_flash_region = fallback_unmap,
hailfinger52c4fa02010-07-21 10:26:01 +0000346 .delay = internal_delay,
347 },
348#endif
349
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000350#if CONFIG_PONY_SPI == 1
351 {
352 .name = "pony_spi",
353 .type = OTHER,
354 /* FIXME */
355 .devs.note = "Programmers compatible with SI-Prog, serbang or AJAWe\n",
356 .init = pony_spi_init,
357 .map_flash_region = fallback_map,
358 .unmap_flash_region = fallback_unmap,
359 .delay = internal_delay,
360 },
361#endif
362
hailfinger7949b652011-05-08 00:24:18 +0000363#if CONFIG_NICINTEL == 1
364 {
365 .name = "nicintel",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100366 .type = PCI,
367 .devs.dev = nics_intel,
hailfinger7949b652011-05-08 00:24:18 +0000368 .init = nicintel_init,
hailfinger7949b652011-05-08 00:24:18 +0000369 .map_flash_region = fallback_map,
370 .unmap_flash_region = fallback_unmap,
hailfinger7949b652011-05-08 00:24:18 +0000371 .delay = internal_delay,
372 },
373#endif
374
uwe6764e922010-09-03 18:21:21 +0000375#if CONFIG_NICINTEL_SPI == 1
376 {
uwe8d342eb2011-07-28 08:13:25 +0000377 .name = "nicintel_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100378 .type = PCI,
379 .devs.dev = nics_intel_spi,
uwe8d342eb2011-07-28 08:13:25 +0000380 .init = nicintel_spi_init,
381 .map_flash_region = fallback_map,
382 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000383 .delay = internal_delay,
uwe6764e922010-09-03 18:21:21 +0000384 },
385#endif
386
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000387#if CONFIG_NICINTEL_EEPROM == 1
388 {
389 .name = "nicintel_eeprom",
390 .type = PCI,
391 .devs.dev = nics_intel_ee,
392 .init = nicintel_ee_init,
393 .map_flash_region = fallback_map,
394 .unmap_flash_region = fallback_unmap,
395 .delay = internal_delay,
396 },
397#endif
398
hailfingerfb1f31f2010-12-03 14:48:11 +0000399#if CONFIG_OGP_SPI == 1
400 {
uwe8d342eb2011-07-28 08:13:25 +0000401 .name = "ogp_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100402 .type = PCI,
403 .devs.dev = ogp_spi,
uwe8d342eb2011-07-28 08:13:25 +0000404 .init = ogp_spi_init,
405 .map_flash_region = fallback_map,
406 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000407 .delay = internal_delay,
hailfingerfb1f31f2010-12-03 14:48:11 +0000408 },
409#endif
410
hailfinger935365d2011-02-04 21:37:59 +0000411#if CONFIG_SATAMV == 1
412 {
413 .name = "satamv",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100414 .type = PCI,
415 .devs.dev = satas_mv,
hailfinger935365d2011-02-04 21:37:59 +0000416 .init = satamv_init,
hailfinger935365d2011-02-04 21:37:59 +0000417 .map_flash_region = fallback_map,
418 .unmap_flash_region = fallback_unmap,
hailfinger935365d2011-02-04 21:37:59 +0000419 .delay = internal_delay,
420 },
421#endif
422
David Hendrickscebee892015-05-23 20:30:30 -0700423#if CONFIG_LINUX_MTD == 1
424 {
425 .name = "linux_mtd",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100426 .type = OTHER,
427 .devs.note = "Device files /dev/mtd*\n",
David Hendrickscebee892015-05-23 20:30:30 -0700428 .init = linux_mtd_init,
429 .map_flash_region = fallback_map,
430 .unmap_flash_region = fallback_unmap,
431 .delay = internal_delay,
432 },
433#endif
434
uwe7df6dda2011-09-03 18:37:52 +0000435#if CONFIG_LINUX_SPI == 1
436 {
437 .name = "linux_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100438 .type = OTHER,
439 .devs.note = "Device files /dev/spidev*.*\n",
uwe7df6dda2011-09-03 18:37:52 +0000440 .init = linux_spi_init,
441 .map_flash_region = fallback_map,
442 .unmap_flash_region = fallback_unmap,
uwe7df6dda2011-09-03 18:37:52 +0000443 .delay = internal_delay,
444 },
445#endif
446
Shiyu Sun9dde7162020-04-16 17:32:55 +1000447#if CONFIG_LSPCON_I2C_SPI == 1
448 {
449 .name = "lspcon_i2c_spi",
450 .type = OTHER,
451 .devs.note = "Device files /dev/i2c-*.\n",
452 .init = lspcon_i2c_spi_init,
453 .map_flash_region = fallback_map,
454 .unmap_flash_region = fallback_unmap,
455 .delay = internal_delay,
456 },
457#endif
458
Edward O'Callaghan97dd9262020-03-26 00:00:41 +1100459#if CONFIG_REALTEK_MST_I2C_SPI == 1
460 {
461 .name = "realtek_mst_i2c_spi",
462 .type = OTHER,
463 .devs.note = "Device files /dev/i2c-*.\n",
464 .init = realtek_mst_i2c_spi_init,
465 .map_flash_region = fallback_map,
466 .unmap_flash_region = fallback_unmap,
467 .delay = internal_delay,
468 },
469#endif
470
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000471#if CONFIG_USBBLASTER_SPI == 1
472 {
473 .name = "usbblaster_spi",
474 .type = USB,
475 .devs.dev = devs_usbblasterspi,
476 .init = usbblaster_spi_init,
477 .map_flash_region = fallback_map,
478 .unmap_flash_region = fallback_unmap,
479 .delay = internal_delay,
480 },
481#endif
482
483#if CONFIG_MSTARDDC_SPI == 1
484 {
485 .name = "mstarddc_spi",
486 .type = OTHER,
487 .devs.note = "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
488 .init = mstarddc_spi_init,
489 .map_flash_region = fallback_map,
490 .unmap_flash_region = fallback_unmap,
491 .delay = internal_delay,
492 },
493#endif
494
495#if CONFIG_PICKIT2_SPI == 1
496 {
497 .name = "pickit2_spi",
498 .type = USB,
499 .devs.dev = devs_pickit2_spi,
500 .init = pickit2_spi_init,
501 .map_flash_region = fallback_map,
502 .unmap_flash_region = fallback_unmap,
503 .delay = internal_delay,
504 },
505#endif
506
507#if CONFIG_CH341A_SPI == 1
508 {
509 .name = "ch341a_spi",
510 .type = USB,
511 .devs.dev = devs_ch341a_spi,
512 .init = ch341a_spi_init,
513 .map_flash_region = fallback_map,
514 .unmap_flash_region = fallback_unmap,
515 .delay = ch341a_spi_delay,
516 },
517#endif
518
519#if CONFIG_DIGILENT_SPI == 1
520 {
521 .name = "digilent_spi",
522 .type = USB,
523 .devs.dev = devs_digilent_spi,
524 .init = digilent_spi_init,
525 .map_flash_region = fallback_map,
526 .unmap_flash_region = fallback_unmap,
527 .delay = internal_delay,
528 },
529#endif
530
531#if CONFIG_JLINK_SPI == 1
532 {
533 .name = "jlink_spi",
534 .type = OTHER,
535 .init = jlink_spi_init,
536 .devs.note = "SEGGER J-Link and compatible devices\n",
537 .map_flash_region = fallback_map,
538 .unmap_flash_region = fallback_unmap,
539 .delay = internal_delay,
540 },
541#endif
542
543#if CONFIG_NI845X_SPI == 1
544 {
545 .name = "ni845x_spi",
546 .type = OTHER, // choose other because NI-845x uses own USB implementation
547 .devs.note = "National Instruments USB-845x\n",
548 .init = ni845x_spi_init,
549 .map_flash_region = fallback_map,
550 .unmap_flash_region = fallback_unmap,
551 .delay = internal_delay,
552 },
553#endif
554
555#if CONFIG_STLINKV3_SPI == 1
556 {
557 .name = "stlinkv3_spi",
558 .type = USB,
559 .devs.dev = devs_stlinkv3_spi,
560 .init = stlinkv3_spi_init,
561 .map_flash_region = fallback_map,
562 .unmap_flash_region = fallback_unmap,
563 .delay = internal_delay,
564 },
565#endif
566
Edward O'Callaghand8f72232020-09-30 14:21:42 +1000567#if CONFIG_GOOGLE_EC == 1
568 {
569 .name = "google_ec",
570 .type = OTHER,
571 .devs.note = "Google EC.\n",
572 .init = cros_ec_probe_dev,
573 .map_flash_region = fallback_map,
574 .unmap_flash_region = fallback_unmap,
575 .delay = internal_delay,
576 },
577#endif
578
Edward O'Callaghanda29ca82020-10-20 00:49:47 +1100579#if CONFIG_CROS_ALIAS == 1
580 {
581 .name = "ec",
582 .type = OTHER,
583 .devs.note = "Google EC alias mechanism.\n",
584 .init = cros_ec_alias_init,
585 .map_flash_region = physmap, /* TODO(b/171934191) */
586 .unmap_flash_region = physunmap, /* TODO(b/171934191) */
587 .delay = internal_delay,
588
589 /*
590 * "ec" implies in-system programming on a live system, so
591 * handle with paranoia to catch errors early. If something goes
592 * wrong then hopefully the system will still be recoverable.
593 */
594 .paranoid = 1,
595 },
Edward O'Callaghan5b16a082020-10-20 16:30:16 +1100596
597 {
598 .name = "host",
599 .type = OTHER,
600 .devs.note = "Google host alias mechanism.\n",
601 .init = cros_host_alias_init,
602 .map_flash_region = physmap,
603 .unmap_flash_region = physunmap,
604 .delay = internal_delay,
605
606 /*
607 * "Internal" implies in-system programming on a live system, so
608 * handle with paranoia to catch errors early. If something goes
609 * wrong then hopefully the system will still be recoverable.
610 */
611 .paranoid = 1,
612 },
Edward O'Callaghanda29ca82020-10-20 00:49:47 +1100613#endif
614
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100615 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000616};
stepan927d4e22007-04-04 22:45:58 +0000617
hailfingerf31cbdc2010-11-10 15:25:18 +0000618#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000619static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000620/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000621static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700622 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000623 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000624} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000625/* Initialize to 0 to make sure nobody registers a shutdown function before
626 * programmer init.
627 */
628static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000629
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700630static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000631
hailfingerdc6f7972010-02-14 01:20:28 +0000632/* Register a function to be executed on programmer shutdown.
633 * The advantage over atexit() is that you can supply a void pointer which will
634 * be used as parameter to the registered function upon programmer shutdown.
635 * This pointer can point to arbitrary data used by said function, e.g. undo
636 * information for GPIO settings etc. If unneeded, set data=NULL.
637 * Please note that the first (void *data) belongs to the function signature of
638 * the function passed as first parameter.
639 */
David Hendricks93784b42016-08-09 17:00:38 -0700640int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000641{
642 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000643 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000644 SHUTDOWN_MAXFN);
645 return 1;
646 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000647 if (!may_register_shutdown) {
648 msg_perr("Tried to register a shutdown function before "
649 "programmer init.\n");
650 return 1;
651 }
hailfingerdc6f7972010-02-14 01:20:28 +0000652 shutdown_fn[shutdown_fn_count].func = function;
653 shutdown_fn[shutdown_fn_count].data = data;
654 shutdown_fn_count++;
655
656 return 0;
657}
658
Nikolai Artemiev55f7a332020-11-05 13:54:27 +1100659int register_chip_restore(chip_restore_fn_cb_t func,
660 struct flashctx *flash, uint8_t status)
661{
662 if (flash->chip_restore_fn_count >= MAX_CHIP_RESTORE_FUNCTIONS) {
663 msg_perr("Tried to register more than %i chip restore"
664 " functions.\n", MAX_CHIP_RESTORE_FUNCTIONS);
665 return 1;
666 }
667 flash->chip_restore_fn[flash->chip_restore_fn_count].func = func;
668 flash->chip_restore_fn[flash->chip_restore_fn_count].status = status;
669 flash->chip_restore_fn_count++;
670
671 return 0;
672}
673
674static int deregister_chip_restore(struct flashctx *flash)
675{
676 int rc = 0;
677
678 while (flash->chip_restore_fn_count > 0) {
679 int i = --flash->chip_restore_fn_count;
680 rc |= flash->chip_restore_fn[i].func(
681 flash, flash->chip_restore_fn[i].status);
682 }
683
684 return rc;
685}
686
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000687int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000688{
hailfinger1ef766d2010-07-06 09:55:48 +0000689 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000690
691 if (prog >= PROGRAMMER_INVALID) {
692 msg_perr("Invalid programmer specified!\n");
693 return -1;
694 }
695 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000696 /* Initialize all programmer specific data. */
697 /* Default to unlimited decode sizes. */
698 max_rom_decode = (const struct decode_sizes) {
699 .parallel = 0xffffffff,
700 .lpc = 0xffffffff,
701 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000702 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000703 };
hailfinger1ff33dc2010-07-03 11:02:10 +0000704 /* Default to top aligned flash at 4 GB. */
705 flashbase = 0;
706 /* Registering shutdown functions is now allowed. */
707 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000708 /* Default to allowing writes. Broken programmers set this to 0. */
709 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000710
711 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000712 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700713 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000714 if (programmer_param && strlen(programmer_param)) {
715 if (ret != 0) {
716 /* It is quite possible that any unhandled programmer parameter would have been valid,
717 * but an error in actual programmer init happened before the parameter was evaluated.
718 */
719 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
720 programmer_param);
721 } else {
722 /* Actual programmer init was successful, but the user specified an invalid or unusable
723 * (for the current programmer configuration) parameter.
724 */
725 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
726 msg_perr("Aborting.\n");
727 ret = ERROR_FATAL;
728 }
729 }
hailfinger1ef766d2010-07-06 09:55:48 +0000730 return ret;
uweabe92a52009-05-16 22:36:00 +0000731}
732
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000733/** Calls registered shutdown functions and resets internal programmer-related variables.
734 * Calling it is safe even without previous initialization, but further interactions with programmer support
735 * require a call to programmer_init() (afterwards).
736 *
737 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700738int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000739{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000740 int ret = 0;
741
hailfinger1ff33dc2010-07-03 11:02:10 +0000742 /* Registering shutdown functions is no longer allowed. */
743 may_register_shutdown = 0;
744 while (shutdown_fn_count > 0) {
745 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700746 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000747 }
Edward O'Callaghancf9c40f2020-10-19 20:02:39 +1100748
749 programmer_param = NULL;
750 registered_master_count = 0;
751
dhendrix0ffc2eb2011-06-14 01:35:36 +0000752 return ret;
uweabe92a52009-05-16 22:36:00 +0000753}
754
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000755void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000756{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000757 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
758 return ret;
uweabe92a52009-05-16 22:36:00 +0000759}
760
761void programmer_unmap_flash_region(void *virt_addr, size_t len)
762{
763 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000764 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000765}
766
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700767void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000768{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100769 flash->mst->par.chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000770}
771
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700772void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000773{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100774 flash->mst->par.chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000775}
776
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700777void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000778{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100779 flash->mst->par.chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000780}
781
Stuart langleyc98e43f2020-03-26 20:27:36 +1100782void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000783{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100784 flash->mst->par.chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000785}
786
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700787uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000788{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100789 return flash->mst->par.chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000790}
791
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700792uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000793{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100794 return flash->mst->par.chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000795}
796
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700797uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000798{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100799 return flash->mst->par.chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000800}
801
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000802void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
803 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000804{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100805 flash->mst->par.chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000806}
807
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000808void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000809{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000810 if (usecs > 0)
811 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000812}
813
Edward O'Callaghana820b212020-09-17 22:53:26 +1000814int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
815 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000816{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700817 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000818
hailfinger23060112009-05-08 12:49:03 +0000819 return 0;
820}
821
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000822/* This is a somewhat hacked function similar in some ways to strtok().
823 * It will look for needle with a subsequent '=' in haystack, return a copy of
824 * needle and remove everything from the first occurrence of needle to the next
825 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000826 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000827char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000828{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000829 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000830 char *opt = NULL;
831 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000832 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000833
hailfingerf4aaccc2010-04-28 15:22:14 +0000834 needlelen = strlen(needle);
835 if (!needlelen) {
836 msg_gerr("%s: empty needle! Please report a bug at "
837 "flashrom@flashrom.org\n", __func__);
838 return NULL;
839 }
840 /* No programmer parameters given. */
841 if (*haystack == NULL)
842 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000843 param_pos = strstr(*haystack, needle);
844 do {
845 if (!param_pos)
846 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000847 /* Needle followed by '='? */
848 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000849 /* Beginning of the string? */
850 if (param_pos == *haystack)
851 break;
852 /* After a delimiter? */
853 if (strchr(delim, *(param_pos - 1)))
854 break;
855 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000856 /* Continue searching. */
857 param_pos++;
858 param_pos = strstr(param_pos, needle);
859 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000860
hailfinger6e5a52a2009-11-24 18:27:10 +0000861 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000862 /* Get the string after needle and '='. */
863 opt_pos = param_pos + needlelen + 1;
864 optlen = strcspn(opt_pos, delim);
865 /* Return an empty string if the parameter was empty. */
866 opt = malloc(optlen + 1);
867 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000868 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000869 exit(1);
870 }
hailfinger1ef766d2010-07-06 09:55:48 +0000871 strncpy(opt, opt_pos, optlen);
872 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000873 rest = opt_pos + optlen;
874 /* Skip all delimiters after the current parameter. */
875 rest += strspn(rest, delim);
876 memmove(param_pos, rest, strlen(rest) + 1);
877 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000878 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000879
hailfinger1ef766d2010-07-06 09:55:48 +0000880 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000881}
882
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000883char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000884{
885 return extract_param(&programmer_param, param_name, ",");
886}
887
stefancte1c5acf2011-07-04 07:27:17 +0000888/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700889static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000890{
891 unsigned int usable_erasefunctions = 0;
892 int k;
893 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
894 if (!check_block_eraser(flash, k, 0))
895 usable_erasefunctions++;
896 }
897 return usable_erasefunctions;
898}
899
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000900static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700901{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000902 int ret = 0, failcount = 0;
903 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700904 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000905 if (wantbuf[i] != havebuf[i]) {
906 /* Only print the first failure. */
907 if (!failcount++)
908 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
909 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700910 }
911 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000912 if (failcount) {
913 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
914 start, start + len - 1, failcount);
915 ret = -1;
916 }
917 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700918}
919
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000920/* start is an offset to the base address of the flash chip */
921static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
922{
923 int ret;
924 uint8_t *cmpbuf = malloc(len);
925 const uint8_t erased_value = ERASED_VALUE(flash);
926
927 if (!cmpbuf) {
928 msg_gerr("Could not allocate memory!\n");
929 exit(1);
930 }
931 memset(cmpbuf, erased_value, len);
932 ret = verify_range(flash, cmpbuf, start, len);
933 free(cmpbuf);
934 return ret;
935}
936
uwee15beb92010-08-08 17:01:18 +0000937/*
hailfinger7af3d192009-11-25 17:05:52 +0000938 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000939 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000940 * @start offset to the base address of the flash chip
941 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000942 * @return 0 for success, -1 for failure
943 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000944int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000945{
hailfinger7af83692009-06-15 17:23:36 +0000946 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000947 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000948
Patrick Georgif3fa2992017-02-02 16:24:44 +0100949 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000950 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000951 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000952 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000953
954 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000955 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000956 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000957 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000958 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000959 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000960
Patrick Georgif3fa2992017-02-02 16:24:44 +0100961 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000962 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000963 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100964 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000965 ret = -1;
966 goto out_free;
967 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700968 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700969 if (programmer_table[programmer].paranoid) {
970 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800971
Simon Glass4e305f42015-01-08 06:29:04 -0700972 /* limit chunksize in order to catch errors early */
973 for (i = 0, chunksize = 0; i < len; i += chunksize) {
974 int tmp;
Douglas Anderson81e58f12021-02-01 13:16:08 -0800975 int chk_acc = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -0800976
Douglas Anderson81e58f12021-02-01 13:16:08 -0800977 /*
978 * Let's work in chunks of at least 4096 bytes at a
979 * time to balance reacting fast but still avoiding the
980 * overhead of working at a smaller size if page_size is
981 * something like 256 bytes.
982 */
983 chunksize = max(flash->chip->page_size, 4096);
984 chunksize = min(chunksize, len - i);
985
986 /*
987 * If we don't have access to some part of this chunk
988 * then bring the size back down to page_size.
989 */
990 if (flash->chip->check_access) {
991 chk_acc = flash->chip->check_access(flash, start + i, chunksize, 0);
992 if (chk_acc) {
993 chunksize = min(chunksize, flash->chip->page_size);
994 chk_acc = flash->chip->check_access(flash, start + i, chunksize, 0);
995 }
996 }
997
Patrick Georgif3fa2992017-02-02 16:24:44 +0100998 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700999 if (tmp) {
1000 ret = tmp;
1001 if (ignore_error(tmp))
1002 continue;
1003 else
1004 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -08001005 }
Simon Glass4e305f42015-01-08 06:29:04 -07001006
Duncan Laurie25a4ca22019-04-25 12:08:52 -07001007 /*
1008 * Check write access permission and do not compare chunks
1009 * where flashrom does not have write access to the region.
1010 */
Douglas Anderson81e58f12021-02-01 13:16:08 -08001011 if (chk_acc && ignore_error(chk_acc))
1012 continue;
Duncan Laurie25a4ca22019-04-25 12:08:52 -07001013
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001014 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -07001015 if (failcount)
1016 break;
David Hendricks1ed1d352011-11-23 17:54:37 -08001017 }
Simon Glass4e305f42015-01-08 06:29:04 -07001018 } else {
1019 int tmp;
1020
1021 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +01001022 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -07001023 if (tmp && !ignore_error(tmp)) {
1024 ret = tmp;
1025 goto out_free;
1026 }
1027
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001028 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +00001029 }
1030
hailfinger5be6c0f2009-07-23 01:42:56 +00001031 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +00001032 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +00001033 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +00001034 ret = -1;
1035 }
hailfinger7af83692009-06-15 17:23:36 +00001036
1037out_free:
1038 free(readbuf);
1039 return ret;
1040}
1041
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001042/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1043static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001044 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001045{
1046 unsigned int i, j, limit;
1047 for (j = 0; j < len / gran; j++) {
1048 limit = min (gran, len - j * gran);
1049 /* Are 'have' and 'want' identical? */
1050 if (!memcmp(have + j * gran, want + j * gran, limit))
1051 continue;
1052 /* have needs to be in erased state. */
1053 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001054 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001055 return 1;
1056 }
1057 return 0;
1058}
1059
uwee15beb92010-08-08 17:01:18 +00001060/*
hailfingerb247c7a2010-03-08 00:42:32 +00001061 * Check if the buffer @have can be programmed to the content of @want without
1062 * erasing. This is only possible if all chunks of size @gran are either kept
1063 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001064 *
hailfingerb437e282010-11-04 01:04:27 +00001065 * Warning: This function assumes that @have and @want point to naturally
1066 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001067 *
1068 * @have buffer with current content
1069 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001070 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001071 * @gran write granularity (enum, not count)
1072 * @return 0 if no erase is needed, 1 otherwise
1073 */
Edward O'Callaghanaccf9ff2021-01-22 01:33:03 +11001074static int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001075 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001076{
hailfingerb91c08c2011-08-15 19:54:20 +00001077 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001078 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001079
hailfingerb247c7a2010-03-08 00:42:32 +00001080 switch (gran) {
1081 case write_gran_1bit:
1082 for (i = 0; i < len; i++)
1083 if ((have[i] & want[i]) != want[i]) {
1084 result = 1;
1085 break;
1086 }
1087 break;
1088 case write_gran_1byte:
1089 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001090 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001091 result = 1;
1092 break;
1093 }
1094 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001095 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001096 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001097 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001098 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001099 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001100 break;
1101 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001102 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001103 break;
1104 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001105 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001106 break;
1107 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001108 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001109 break;
1110 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001111 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001112 break;
1113 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001114 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001115 break;
1116 case write_gran_1byte_implicit_erase:
1117 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1118 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001119 break;
hailfingerb437e282010-11-04 01:04:27 +00001120 default:
1121 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1122 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001123 }
1124 return result;
1125}
1126
hailfingerb437e282010-11-04 01:04:27 +00001127/**
1128 * Check if the buffer @have needs to be programmed to get the content of @want.
1129 * If yes, return 1 and fill in first_start with the start address of the
1130 * write operation and first_len with the length of the first to-be-written
1131 * chunk. If not, return 0 and leave first_start and first_len undefined.
1132 *
1133 * Warning: This function assumes that @have and @want point to naturally
1134 * aligned regions.
1135 *
1136 * @have buffer with current content
1137 * @want buffer with desired content
1138 * @len length of the checked area
1139 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001140 * @first_start offset of the first byte which needs to be written (passed in
1141 * value is increased by the offset of the first needed write
1142 * relative to have/want or unchanged if no write is needed)
1143 * @return length of the first contiguous area which needs to be written
1144 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001145 *
1146 * FIXME: This function needs a parameter which tells it about coalescing
1147 * in relation to the max write length of the programmer and the max write
1148 * length of the chip.
1149 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001150static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001151 unsigned int *first_start,
1152 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001153{
stefanctc5eb8a92011-11-23 09:13:48 +00001154 int need_write = 0;
1155 unsigned int rel_start = 0, first_len = 0;
1156 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001157
hailfingerb437e282010-11-04 01:04:27 +00001158 switch (gran) {
1159 case write_gran_1bit:
1160 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001161 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001162 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001163 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001164 case write_gran_128bytes:
1165 stride = 128;
1166 break;
hailfingerb437e282010-11-04 01:04:27 +00001167 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001168 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001169 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001170 case write_gran_264bytes:
1171 stride = 264;
1172 break;
1173 case write_gran_512bytes:
1174 stride = 512;
1175 break;
1176 case write_gran_528bytes:
1177 stride = 528;
1178 break;
1179 case write_gran_1024bytes:
1180 stride = 1024;
1181 break;
1182 case write_gran_1056bytes:
1183 stride = 1056;
1184 break;
hailfingerb437e282010-11-04 01:04:27 +00001185 default:
1186 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1187 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001188 /* Claim that no write was needed. A write with unknown
1189 * granularity is too dangerous to try.
1190 */
1191 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001192 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001193 for (i = 0; i < len / stride; i++) {
1194 limit = min(stride, len - i * stride);
1195 /* Are 'have' and 'want' identical? */
1196 if (memcmp(have + i * stride, want + i * stride, limit)) {
1197 if (!need_write) {
1198 /* First location where have and want differ. */
1199 need_write = 1;
1200 rel_start = i * stride;
1201 }
1202 } else {
1203 if (need_write) {
1204 /* First location where have and want
1205 * do not differ anymore.
1206 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001207 break;
1208 }
1209 }
1210 }
hailfingerffb7f382010-12-06 13:05:44 +00001211 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001212 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001213 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001214 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001215}
1216
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001217/* Returns the number of busses commonly supported by the current programmer and flash chip where the latter
1218 * can not be completely accessed due to size/address limits of the programmer. */
1219unsigned int count_max_decode_exceedings(const struct flashctx *flash)
hailfingeraec9c962009-10-31 01:53:09 +00001220{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001221 unsigned int limitexceeded = 0;
1222 uint32_t size = flash->chip->total_size * 1024;
1223 enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
uwe8d342eb2011-07-28 08:13:25 +00001224
1225 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001226 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001227 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001228 "size %u kB of chipset/board/programmer "
1229 "for %s interface, "
1230 "probe/read/erase/write may fail. ", size / 1024,
1231 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001232 }
hailfingere1e41ea2011-07-27 07:13:06 +00001233 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001234 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001235 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001236 "size %u kB of chipset/board/programmer "
1237 "for %s interface, "
1238 "probe/read/erase/write may fail. ", size / 1024,
1239 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001240 }
hailfingere1e41ea2011-07-27 07:13:06 +00001241 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001242 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001243 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001244 "size %u kB of chipset/board/programmer "
1245 "for %s interface, "
1246 "probe/read/erase/write may fail. ", size / 1024,
1247 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001248 }
hailfingere1e41ea2011-07-27 07:13:06 +00001249 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001250 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001251 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001252 "size %u kB of chipset/board/programmer "
1253 "for %s interface, "
1254 "probe/read/erase/write may fail. ", size / 1024,
1255 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001256 }
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001257 return limitexceeded;
hailfingeraec9c962009-10-31 01:53:09 +00001258}
1259
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001260void unmap_flash(struct flashctx *flash)
1261{
1262 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1263 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1264 flash->physical_registers = 0;
1265 flash->virtual_registers = (chipaddr)ERROR_PTR;
1266 }
1267
1268 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1269 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1270 flash->physical_memory = 0;
1271 flash->virtual_memory = (chipaddr)ERROR_PTR;
1272 }
1273}
1274
1275int map_flash(struct flashctx *flash)
1276{
1277 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1278 flash->virtual_memory = (chipaddr)ERROR_PTR;
1279 flash->virtual_registers = (chipaddr)ERROR_PTR;
1280
1281 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1282 * These are used for various probing-related hacks that would not map successfully anyway and should be
1283 * removed ASAP. */
1284 if (flash->chip->total_size == 0)
1285 return 0;
1286
1287 const chipsize_t size = flash->chip->total_size * 1024;
1288 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1289 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1290 if (addr == ERROR_PTR) {
1291 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1292 flash->chip->name, PRIxPTR_WIDTH, base);
1293 return 1;
1294 }
1295 flash->physical_memory = base;
1296 flash->virtual_memory = (chipaddr)addr;
1297
1298 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1299 * completely different on some chips and programmers, or not mappable at all.
1300 * Ignore these problems for now and always report success. */
1301 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1302 base = 0xffffffff - size - 0x400000 + 1;
1303 addr = programmer_map_flash_region("flash chip registers", base, size);
1304 if (addr == ERROR_PTR) {
1305 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1306 flash->chip->name, PRIxPTR_WIDTH, base);
1307 return 0;
1308 }
1309 flash->physical_registers = base;
1310 flash->virtual_registers = (chipaddr)addr;
1311 }
1312 return 0;
1313}
1314
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001315/*
1316 * Return a string corresponding to the bustype parameter.
1317 * Memory is obtained with malloc() and must be freed with free() by the caller.
1318 */
1319char *flashbuses_to_text(enum chipbustype bustype)
1320{
1321 char *ret = calloc(1, 1);
1322 /*
1323 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1324 * will cease to exist and should be eliminated here as well.
1325 */
1326 if (bustype == BUS_NONSPI) {
1327 ret = strcat_realloc(ret, "Non-SPI, ");
1328 } else {
1329 if (bustype & BUS_PARALLEL)
1330 ret = strcat_realloc(ret, "Parallel, ");
1331 if (bustype & BUS_LPC)
1332 ret = strcat_realloc(ret, "LPC, ");
1333 if (bustype & BUS_FWH)
1334 ret = strcat_realloc(ret, "FWH, ");
1335 if (bustype & BUS_SPI)
1336 ret = strcat_realloc(ret, "SPI, ");
1337 if (bustype & BUS_PROG)
1338 ret = strcat_realloc(ret, "Programmer-specific, ");
1339 if (bustype == BUS_NONE)
1340 ret = strcat_realloc(ret, "None, ");
1341 }
1342 /* Kill last comma. */
1343 ret[strlen(ret) - 2] = '\0';
1344 ret = realloc(ret, strlen(ret) + 1);
1345 return ret;
1346}
1347
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001348int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001349{
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001350 const struct flashchip *chip;
hailfingeraec9c962009-10-31 01:53:09 +00001351 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001352 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001353
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001354 for (chip = flashchips + startchip; chip && chip->name; chip++) {
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001355 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001356 continue;
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001357 buses_common = mst->buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001358 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001359 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001360 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001361 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001362 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001363 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001364 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001365 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001366 continue;
1367 }
stepan782fb172007-04-06 11:58:03 +00001368
hailfinger48ed3e22011-05-04 00:39:50 +00001369 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001370 flash->chip = calloc(1, sizeof(struct flashchip));
1371 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001372 msg_gerr("Out of memory!\n");
1373 exit(1);
1374 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001375 memcpy(flash->chip, chip, sizeof(struct flashchip));
1376 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001377
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001378 if (map_flash(flash) != 0)
1379 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001380
Edward O'Callaghana820b212020-09-17 22:53:26 +10001381 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1382 * is only called with force=1 after normal probing failed.
1383 */
stugec1e55fe2008-07-02 17:15:47 +00001384 if (force)
1385 break;
stepanc98b80b2006-03-16 16:57:41 +00001386
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001387 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001388 goto notfound;
1389
hailfinger48ed3e22011-05-04 00:39:50 +00001390 /* If this is the first chip found, accept it.
1391 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001392 * a non-generic match. SFDP and CFI are generic matches.
1393 * startchip==0 means this call to probe_flash() is the first
1394 * one for this programmer interface (master) and thus no other chip has
1395 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001396 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001397 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1398 msg_cinfo("===\n"
1399 "SFDP has autodetected a flash chip which is "
1400 "not natively supported by flashrom yet.\n");
1401 if (count_usable_erasers(flash) == 0)
1402 msg_cinfo("The standard operations read and "
1403 "verify should work, but to support "
1404 "erase, write and all other "
1405 "possible features");
1406 else
1407 msg_cinfo("All standard operations (read, "
1408 "verify, erase and write) should "
1409 "work, but to support all possible "
1410 "features");
1411
1412 msg_cinfo(" we need to add them manually.\n"
1413 "You can help us by mailing us the output of the following command to "
1414 "flashrom@flashrom.org:\n"
1415 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1416 "Thanks for your help!\n"
1417 "===\n");
1418 }
stugec1e55fe2008-07-02 17:15:47 +00001419
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001420 /* First flash chip detected on this bus. */
1421 if (startchip == 0)
1422 break;
1423 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001424 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001425 break;
1426 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001427notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001428 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001429 free(flash->chip);
1430 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001431 }
uwebe4477b2007-08-23 16:08:21 +00001432
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001433 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001434 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001435
Edward O'Callaghan53ff4ad2020-12-16 20:36:28 +11001436 /* Fill fallback layout covering the whole chip. */
1437 struct single_layout *const fallback = &flash->fallback_layout;
1438 fallback->base.entries = &fallback->entry;
1439 fallback->base.num_entries = 1;
1440 fallback->entry.start = 0;
1441 fallback->entry.end = flash->chip->total_size * 1024 - 1;
1442 fallback->entry.included = true;
1443 fallback->entry.name = strdup("complete flash");
1444 if (!fallback->entry.name) {
1445 msg_cerr("Failed to probe chip: %s\n", strerror(errno));
1446 return -1;
1447 }
stepan3e7aeae2011-01-19 06:21:54 +00001448
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001449 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001450 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1451 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001452 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001453#if CONFIG_INTERNAL == 1
1454 if (programmer_table[programmer].map_flash_region == physmap)
1455 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1456 PRIxPTR_WIDTH, flash->physical_memory);
1457 else
1458#endif
1459 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001460
Edward O'Callaghana820b212020-09-17 22:53:26 +10001461 /* Flash registers may more likely not be mapped if the chip was forced.
1462 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001463 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001464 if (flash->chip->printlock)
1465 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001466
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001467 /* Get out of the way for later runs. */
1468 unmap_flash(flash);
1469
hailfinger48ed3e22011-05-04 00:39:50 +00001470 /* Return position of matching chip. */
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001471 return chip - flashchips;
rminnich8d3ff912003-10-25 17:01:29 +00001472}
1473
uwe8d342eb2011-07-28 08:13:25 +00001474int read_buf_from_file(unsigned char *buf, unsigned long size,
1475 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001476{
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001477#ifdef __LIBPAYLOAD__
1478 msg_gerr("Error: No file I/O support in libpayload\n");
1479 return 1;
1480#else
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001481 int ret = 0;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001482
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001483 FILE *image;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001484 if (!strncmp(filename, "-", sizeof("-")))
1485 image = fdopen(STDIN_FILENO, "rb");
1486 else
1487 image = fopen(filename, "rb");
1488 if (image == NULL) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001489 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger771fc182010-10-15 00:01:14 +00001490 return 1;
1491 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001492
1493 struct stat image_stat;
hailfinger771fc182010-10-15 00:01:14 +00001494 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001495 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001496 ret = 1;
1497 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001498 }
Nikolai Artemieve1f8f602021-02-12 11:44:32 +11001499 if ((image_stat.st_size != (__off_t)size) &&
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001500 (strncmp(filename, "-", sizeof("-")))) {
Daniel Campellocb88c9a2021-04-13 19:23:47 -06001501 msg_gerr("Error: Image size (%jd B) doesn't match the expected size (%lu B)!\n",
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001502 (intmax_t)image_stat.st_size, size);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001503 ret = 1;
1504 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001505 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001506
1507 unsigned long numbytes = fread(buf, 1, size, image);
hailfinger771fc182010-10-15 00:01:14 +00001508 if (numbytes != size) {
1509 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1510 "wanted %ld!\n", numbytes, size);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001511 ret = 1;
hailfinger771fc182010-10-15 00:01:14 +00001512 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001513out:
1514 (void)fclose(image);
1515 return ret;
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001516#endif
hailfinger771fc182010-10-15 00:01:14 +00001517}
1518
Daniel Campellocb88c9a2021-04-13 19:23:47 -06001519/**
1520 * @brief Reads content to buffer from one or more files.
1521 *
1522 * Reads content to supplied buffer from files. If a filename is specified for
1523 * individual regions using the partial read syntax ('-i <region>[:<filename>]')
1524 * then this will read file data into the corresponding region in the
1525 * supplied buffer.
1526 *
1527 * @param flashctx Flash context to be used.
1528 * @param buf Chip-sized buffer to write data to
1529 * @return 0 on success
1530 */
1531static int read_buf_from_include_args(const struct flashctx *const flash,
1532 unsigned char *buf)
1533{
1534 const struct flashrom_layout *const layout = get_layout(flash);
1535 const struct romentry *entry = NULL;
1536
1537 /*
1538 * Content will be read from -i args, so they must not overlap since
1539 * we need to know exactly what content to write to the ROM.
1540 */
1541 if (included_regions_overlap(layout)) {
Daniel Campello2fdc8372021-04-16 17:52:51 -06001542 msg_gerr("Error: Included regions must not overlap when writing.\n");
Daniel Campellocb88c9a2021-04-13 19:23:47 -06001543 return 1;
1544 }
1545
1546 while ((entry = layout_next_included(layout, entry))) {
1547 if (!entry->file)
1548 continue;
1549 if (read_buf_from_file(buf + entry->start,
1550 entry->end - entry->start + 1, entry->file))
1551 return 1;
1552 }
1553 return 0;
1554}
1555
1556/**
1557 * @brief Writes passed data buffer into a file
1558 *
1559 * @param buf Buffer with data to write
1560 * @param size Size of buffer
1561 * @param filename File path to write to
1562 * @return 0 on success
1563 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001564int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001565{
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001566#ifdef __LIBPAYLOAD__
1567 msg_gerr("Error: No file I/O support in libpayload\n");
1568 return 1;
1569#else
hailfingerd219a232009-01-28 00:27:54 +00001570 FILE *image;
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001571 int ret = 0;
hailfingerde345862009-06-01 22:07:52 +00001572
1573 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001574 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001575 return 1;
1576 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001577 if (!strncmp(filename, "-", sizeof("-")))
1578 image = fdopen(STDOUT_FILENO, "wb");
1579 else
1580 image = fopen(filename, "wb");
1581 if (image == NULL) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001582 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger23060112009-05-08 12:49:03 +00001583 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001584 }
hailfingerd219a232009-01-28 00:27:54 +00001585
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001586 unsigned long numbytes = fwrite(buf, 1, size, image);
hailfinger42a850a2010-07-13 23:56:13 +00001587 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001588 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001589 ret = 1;
1590 goto out;
hailfinger42a850a2010-07-13 23:56:13 +00001591 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001592 if (fflush(image)) {
1593 msg_gerr("Error: flushing file \"%s\" failed: %s\n", filename, strerror(errno));
1594 ret = 1;
1595 }
1596 // Try to fsync() only regular files and if that function is available at all (e.g. not on MinGW).
1597#if defined(_POSIX_FSYNC) && (_POSIX_FSYNC != -1)
1598 struct stat image_stat;
1599 if (fstat(fileno(image), &image_stat) != 0) {
1600 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1601 ret = 1;
1602 goto out;
1603 }
1604 if (S_ISREG(image_stat.st_mode)) {
1605 if (fsync(fileno(image))) {
1606 msg_gerr("Error: fsyncing file \"%s\" failed: %s\n", filename, strerror(errno));
1607 ret = 1;
1608 }
1609 }
1610#endif
1611out:
1612 if (fclose(image)) {
1613 msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
1614 ret = 1;
1615 }
1616 return ret;
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001617#endif
hailfingerd219a232009-01-28 00:27:54 +00001618}
1619
Daniel Campellocb88c9a2021-04-13 19:23:47 -06001620/**
1621 * @brief Writes content from buffer to one or more files.
1622 *
1623 * Writes content from supplied buffer to files. If a filename is specified for
1624 * individual regions using the partial read syntax ('-i <region>[:<filename>]')
1625 * then this will write files using data from the corresponding region in the
1626 * supplied buffer.
1627 *
1628 * @param flashctx Flash context to be used.
1629 * @param buf Chip-sized buffer to read data from
1630 * @return 0 on success
1631 */
1632static int write_buf_to_include_args(const struct flashctx *const flash,
1633 unsigned char *buf)
1634{
1635#ifdef __LIBPAYLOAD__
1636 msg_gerr("Error: No file I/O support in libpayload\n");
1637 return 1;
1638#else
1639 const struct flashrom_layout *const layout = get_layout(flash);
1640 const struct romentry *entry = NULL;
1641
1642 while ((entry = layout_next_included(layout, entry))) {
1643 if (!entry->file)
1644 continue;
1645 if (write_buf_to_file(buf + entry->start,
1646 entry->end - entry->start + 1, entry->file))
1647 return 1;
1648 }
1649
1650 return 0;
1651#endif
1652}
1653
David Hendrickse3451942013-03-21 17:23:29 -07001654/*
1655 * read_flash - wrapper for flash->read() with additional high-level policy
1656 *
1657 * @flash flash chip
1658 * @buf buffer to store data in
1659 * @start start address
1660 * @len number of bytes to read
1661 *
1662 * This wrapper simplifies most cases when the flash chip needs to be read
1663 * since policy decisions such as non-fatal error handling is centralized.
1664 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001665int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001666 unsigned int start, unsigned int len)
1667{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001668 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001669
Patrick Georgif3fa2992017-02-02 16:24:44 +01001670 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001671 return -1;
1672
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001673 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1674
Patrick Georgif3fa2992017-02-02 16:24:44 +01001675 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001676 if (ret) {
1677 if (ignore_error(ret)) {
1678 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1679 start, start + len - 1);
1680 ret = 0;
1681 } else {
1682 msg_gdbg("failed to read 0x%x-0x%x\n",
1683 start, start + len - 1);
1684 }
1685 }
1686
1687 return ret;
1688}
1689
David Hendricks7c8a1612013-04-26 19:14:44 -07001690/*
1691 * write_flash - wrapper for flash->write() with additional high-level policy
1692 *
1693 * @flash flash chip
1694 * @buf buffer to write to flash
1695 * @start start address in flash
1696 * @len number of bytes to write
1697 *
1698 * TODO: Look up regions that are write-protected and avoid attempt to write
1699 * to them at all.
1700 */
Edward O'Callaghanaccf9ff2021-01-22 01:33:03 +11001701static int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001702 unsigned int start, unsigned int len)
1703{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001704 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001705 return -1;
1706
Patrick Georgif3fa2992017-02-02 16:24:44 +01001707 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001708}
1709
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06001710static int read_by_layout(struct flashctx *, uint8_t *);
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001711int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001712{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001713 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001714 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001715 int ret = 0;
1716
1717 msg_cinfo("Reading flash... ");
1718 if (!buf) {
1719 msg_gerr("Memory allocation failed!\n");
1720 msg_cinfo("FAILED.\n");
1721 return 1;
1722 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001723
1724 /* To support partial read, fill buffer to all 0xFF at beginning to make
1725 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001726 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001727
Patrick Georgif3fa2992017-02-02 16:24:44 +01001728 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001729 msg_cerr("No read function available for this flash chip.\n");
1730 ret = 1;
1731 goto out_free;
1732 }
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06001733 if (read_by_layout(flash, buf)) {
1734 msg_cerr("Read operation failed!\n");
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001735 ret = 1;
1736 goto out_free;
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06001737 }
Daniel Campellocb88c9a2021-04-13 19:23:47 -06001738 if (write_buf_to_include_args(flash, buf)) {
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06001739 ret = 1;
1740 goto out_free;
hailfinger42a850a2010-07-13 23:56:13 +00001741 }
1742
David Hendricksdf29a832013-06-28 14:33:51 -07001743 if (filename)
1744 ret = write_buf_to_file(buf, size, filename);
hailfinger42a850a2010-07-13 23:56:13 +00001745out_free:
1746 free(buf);
Edward O'Callaghan6b2ff8a2020-12-11 14:33:23 +11001747 msg_cinfo("%s.\n", ret ? "FAILED" : "done");
hailfinger42a850a2010-07-13 23:56:13 +00001748 return ret;
1749}
1750
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001751/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001752static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001753{
hailfingerb91c08c2011-08-15 19:54:20 +00001754 int i, j, k;
1755 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001756
1757 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1758 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001759 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001760
1761 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1762 /* Blocks with zero size are bugs in flashchips.c. */
1763 if (eraser.eraseblocks[i].count &&
1764 !eraser.eraseblocks[i].size) {
1765 msg_gerr("ERROR: Flash chip %s erase function "
1766 "%i region %i has size 0. Please report"
1767 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001768 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001769 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001770 }
1771 /* Blocks with zero count are bugs in flashchips.c. */
1772 if (!eraser.eraseblocks[i].count &&
1773 eraser.eraseblocks[i].size) {
1774 msg_gerr("ERROR: Flash chip %s erase function "
1775 "%i region %i has count 0. Please report"
1776 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001777 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001778 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001779 }
1780 done += eraser.eraseblocks[i].count *
1781 eraser.eraseblocks[i].size;
1782 }
hailfinger9fed35d2010-01-19 06:42:46 +00001783 /* Empty eraseblock definition with erase function. */
1784 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001785 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001786 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001787 if (!done)
1788 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001789 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001790 msg_gerr("ERROR: Flash chip %s erase function %i "
1791 "region walking resulted in 0x%06x bytes total,"
1792 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001793 " flashrom@flashrom.org\n", chip->name, k,
1794 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001795 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001796 }
hailfinger9fed35d2010-01-19 06:42:46 +00001797 if (!eraser.block_erase)
1798 continue;
1799 /* Check if there are identical erase functions for different
1800 * layouts. That would imply "magic" erase functions. The
1801 * easiest way to check this is with function pointers.
1802 */
uwef6f94d42010-03-13 17:28:29 +00001803 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001804 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001805 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001806 msg_gerr("ERROR: Flash chip %s erase function "
1807 "%i and %i are identical. Please report"
1808 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001809 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001810 ret = 1;
1811 }
uwef6f94d42010-03-13 17:28:29 +00001812 }
hailfinger45177872010-01-18 08:14:43 +00001813 }
hailfinger9fed35d2010-01-19 06:42:46 +00001814 return ret;
hailfinger45177872010-01-18 08:14:43 +00001815}
1816
Edward O'Callaghanbef74c22020-12-04 16:23:54 +11001817static int check_block_eraser(const struct flashctx *flash, int k, int log)
1818{
1819 struct block_eraser eraser = flash->chip->block_erasers[k];
1820
1821 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1822 if (log)
1823 msg_cdbg("not defined. ");
1824 return 1;
1825 }
1826 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1827 if (log)
1828 msg_cdbg("eraseblock layout is known, but matching "
1829 "block erase function is not implemented. ");
1830 return 1;
1831 }
1832 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1833 if (log)
1834 msg_cdbg("block erase function found, but "
1835 "eraseblock layout is not defined. ");
1836 return 1;
1837 }
1838 // TODO: Once erase functions are annotated with allowed buses, check that as well.
1839 return 0;
1840}
1841
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06001842/**
1843 * @brief Reads the included layout regions into a buffer.
1844 *
1845 * If there is no layout set in the given flash context, the whole chip will
1846 * be read.
1847 *
1848 * @param flashctx Flash context to be used.
1849 * @param buffer Buffer of full chip size to read into.
1850 * @return 0 on success,
1851 * 1 if any read fails.
1852 */
1853static int read_by_layout(struct flashctx *const flashctx, uint8_t *const buffer)
1854{
1855 const struct flashrom_layout *const layout = get_layout(flashctx);
1856 const struct romentry *entry = NULL;
1857 int required_erase_size = get_required_erase_size(flashctx);
1858
1859 while ((entry = layout_next_included(layout, entry))) {
1860 unsigned int rounded_start, rounded_len;
1861
1862 if (round_to_erasable_block_boundary(required_erase_size, entry,
1863 &rounded_start, &rounded_len))
1864 return 1;
1865 if (read_flash(flashctx, buffer + rounded_start, rounded_start,
1866 rounded_len))
1867 return 1;
1868 }
1869 return 0;
1870}
1871
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001872typedef int (*erasefn_t)(struct flashctx *, unsigned int addr, unsigned int len);
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001873/**
1874 * @private
1875 *
1876 * For read-erase-write, `curcontents` and `newcontents` shall point
1877 * to buffers of the chip's size. Both are supposed to be prefilled
1878 * with at least the included layout regions of the current flash
1879 * contents (`curcontents`) and the data to be written to the flash
1880 * (`newcontents`).
1881 *
1882 * For erase, `curcontents` and `newcontents` shall be NULL-pointers.
1883 *
1884 * The `chipoff_t` values are used internally by `walk_by_layout()`.
1885 */
1886struct walk_info {
1887 uint8_t *curcontents;
1888 const uint8_t *newcontents;
1889 chipoff_t erase_start;
1890 chipoff_t erase_len;
1891};
Edward O'Callaghan5e9e5712020-12-10 11:11:56 +11001892typedef int (*per_blockfn_t)(struct flashctx *, struct walk_info *const, erasefn_t);
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001893
Edward O'Callaghanecc0b202020-12-10 11:35:11 +11001894/*
1895 * Function to process processing units accumulated in the action descriptor.
1896 *
1897 * @flash pointer to the flash context to operate on
1898 * @per_blockfn helper function which can erase and program a section of the
1899 * flash chip. It receives the flash context, offset and length
1900 * of the area to erase/program, before and after contents (to
1901 * decide what exactly needs to be erased and or programmed)
1902 * and a pointer to the erase function which can operate on the
1903 * proper granularity.
1904 * @descriptor action descriptor including pointers to before and after
1905 * contents and an array of processing actions to take.
1906 *
1907 * Returns zero on success or an error code.
1908 */
1909static int walk_eraseregions(struct flashctx *flash,
1910 const per_blockfn_t per_blockfn,
1911 struct action_descriptor *descriptor)
1912{
1913 struct processing_unit *pu;
1914 int rc = 0;
1915 static int print_comma;
1916
1917 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1918 unsigned base = pu->offset;
1919 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
Edward O'Callaghan17361062020-12-12 17:31:59 +11001920 struct block_eraser *const eraser = &flash->chip->block_erasers[pu->block_eraser_index];
Edward O'Callaghanecc0b202020-12-10 11:35:11 +11001921
1922 while (base < top) {
1923
1924 if (print_comma)
1925 msg_cdbg(", ");
1926 else
1927 print_comma = 1;
1928
1929 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1930
1931 struct walk_info info = {
1932 .curcontents = descriptor->oldcontents,
1933 .newcontents = descriptor->newcontents,
1934 .erase_start = base,
1935 .erase_len = pu->block_size,
1936 };
Edward O'Callaghan17361062020-12-12 17:31:59 +11001937 rc = per_blockfn(flash, &info, eraser->block_erase);
Edward O'Callaghanecc0b202020-12-10 11:35:11 +11001938
1939 if (rc) {
1940 if (ignore_error(rc))
1941 rc = 0;
1942 else
1943 return rc;
1944 }
1945 base += pu->block_size;
1946 }
1947 }
1948 msg_cdbg("\n");
1949 return rc;
1950}
1951
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001952static int erase_and_write_block_helper(struct flashctx *flash,
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001953 struct walk_info *const info,
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001954 erasefn_t erasefn)
hailfingerb437e282010-11-04 01:04:27 +00001955{
stefanctc5eb8a92011-11-23 09:13:48 +00001956 unsigned int starthere = 0, lenhere = 0;
Edward O'Callaghan307d1692020-12-12 00:18:22 +11001957 int ret = 0, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001958 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001959 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001960
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001961 /*
1962 * curcontents and newcontents are opaque to walk_eraseregions, and
1963 * need to be adjusted here to keep the impression of proper
1964 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001965 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001966
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001967 info->curcontents += info->erase_start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001968
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001969 info->newcontents += info->erase_start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001970
Edward O'Callaghan307d1692020-12-12 00:18:22 +11001971 bool skipped = true;
hailfingerb437e282010-11-04 01:04:27 +00001972 msg_cdbg(":");
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001973 if (need_erase(info->curcontents, info->newcontents, info->erase_len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001974 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001975 msg_cdbg(" E");
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001976 ret = erasefn(flash, info->erase_start, info->erase_len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001977 if (ret) {
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +11001978 if (ret == SPI_ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001979 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001980 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001981 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001982 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001983 }
1984
David Hendricks0954ffc2015-11-13 15:15:44 -08001985 if (programmer_table[programmer].paranoid) {
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001986 if (check_erased_range(flash, info->erase_start, info->erase_len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001987 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001988 return -1;
1989 }
hailfingerac8e3182011-06-26 17:04:16 +00001990 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001991
hailfinger90fcf9b2010-11-05 14:51:59 +00001992 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001993 memset(info->curcontents, ERASED_VALUE(flash), info->erase_len);
Edward O'Callaghan307d1692020-12-12 00:18:22 +11001994 skipped = false;
David Hendricks048b38c2016-03-28 18:47:06 -07001995 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001996 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001997 /* get_next_write() sets starthere to a new value after the call. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001998 while ((lenhere = get_next_write(info->curcontents + starthere,
1999 info->newcontents + starthere,
2000 info->erase_len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002001 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00002002 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07002003 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00002004 /* Needs the partial write function signature. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11002005 ret = write_flash(flash, (uint8_t *)info->newcontents + starthere,
2006 info->erase_start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08002007 if (ret) {
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +11002008 if (ret == SPI_ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07002009 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00002010 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08002011 }
David Hendricks048b38c2016-03-28 18:47:06 -07002012
2013 /*
2014 * If the block needed to be erased and was erased successfully
2015 * then we can assume that we didn't run into any write-
2016 * protected areas. Otherwise, we need to verify each page to
2017 * ensure it was successfully written and abort if we encounter
2018 * any errors.
2019 */
2020 if (programmer_table[programmer].paranoid && !block_was_erased) {
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11002021 if (verify_range(flash, info->newcontents + starthere,
2022 info->erase_start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07002023 return -1;
2024 }
2025
hailfingerb437e282010-11-04 01:04:27 +00002026 starthere += lenhere;
Edward O'Callaghan307d1692020-12-12 00:18:22 +11002027 skipped = false;
hailfingerb437e282010-11-04 01:04:27 +00002028 }
Edward O'Callaghan307d1692020-12-12 00:18:22 +11002029 if (skipped)
2030 msg_cdbg("S");
hailfingerb437e282010-11-04 01:04:27 +00002031 return ret;
2032}
2033
Edward O'Callaghanaccf9ff2021-01-22 01:33:03 +11002034static int erase_and_write_flash(struct flashctx *flash,
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002035 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002036{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002037 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002038
hailfingercf848f12010-12-05 15:14:44 +00002039 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002040
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002041 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002042
hailfinger7df21362009-09-05 02:30:58 +00002043 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002044 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002045 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002046 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002047 }
2048 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002049}
2050
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11002051static int verify_flash(struct flashctx *flash,
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002052 struct action_descriptor *descriptor)
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11002053{
2054 int ret;
2055 unsigned int total_size = flash->chip->total_size * 1024;
2056 uint8_t *buf = descriptor->newcontents;
2057
2058 msg_cinfo("Verifying flash... ");
2059
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002060 const bool verify_all = flash->flags.verify_whole_chip;
2061 if (!verify_all) {
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11002062 struct processing_unit *pu = descriptor->processing_units;
2063
2064 /* Verify only areas which were written. */
2065 while (pu->num_blocks) {
2066 ret = verify_range(flash, buf + pu->offset, pu->offset,
2067 pu->block_size * pu->num_blocks);
2068 if (ret)
2069 break;
2070 pu++;
2071 }
2072 } else {
2073 ret = verify_range(flash, buf, 0, total_size);
2074 }
2075
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +11002076 if (ret == SPI_ACCESS_DENIED) {
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11002077 msg_gdbg("Could not fully verify due to access error, ");
2078 if (access_denied_action == error_ignore) {
2079 msg_gdbg("ignoring\n");
2080 ret = 0;
2081 } else {
2082 msg_gdbg("aborting\n");
2083 }
2084 }
2085
2086 if (!ret)
2087 msg_cinfo("VERIFIED. \n");
2088
2089 return ret;
2090}
2091
Daniel Campelloef545b12021-04-10 10:39:26 -06002092/**
2093 * @brief Compares the included layout regions with content from a buffer.
2094 *
2095 * If there is no layout set in the given flash context, the whole chip's
2096 * contents will be compared.
2097 *
2098 * @param flashctx Flash context to be used.
2099 * @param curcontents A buffer of full chip size to read current chip contents into.
2100 * @param newcontents The new image to compare to.
2101 * @return 0 on success,
2102 * 1 if reading failed,
2103 * 3 if the contents don't match.
2104 */
2105static int verify_by_layout(struct flashctx *const flashctx,
2106 void *const curcontents, const uint8_t *const newcontents)
2107{
2108 const struct flashrom_layout *const layout = get_layout(flashctx);
2109 const struct romentry *entry = NULL;
2110 int required_erase_size = get_required_erase_size(flashctx);
2111
2112 while ((entry = layout_next_included(layout, entry))) {
2113 const chipoff_t region_start = entry->start;
2114 const chipsize_t region_len = entry->end - entry->start + 1;
2115 unsigned int rounded_start, rounded_len;
2116
2117 if (round_to_erasable_block_boundary(required_erase_size, entry,
2118 &rounded_start, &rounded_len))
2119 return 1;
2120 if (read_flash(flashctx, curcontents + rounded_start, rounded_start, rounded_len))
2121 return 1;
2122 if (compare_range(newcontents + region_start, curcontents + region_start,
2123 region_start, region_len))
2124 return 3;
2125 }
2126 return 0;
2127}
2128
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002129static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002130{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002131 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2132#if CONFIG_INTERNAL == 1
2133 if (programmer == PROGRAMMER_INTERNAL)
2134 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2135 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2136 "mail flashrom@flashrom.org, thanks!\n"
2137 "-------------------------------------------------------------------------------\n"
2138 "You may now reboot or simply leave the machine running.\n");
2139 else
2140#endif
2141 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2142 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2143 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2144 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002145}
2146
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002147static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002148{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002149 msg_gerr("Your flash chip is in an unknown state.\n");
2150#if CONFIG_INTERNAL == 1
2151 if (programmer == PROGRAMMER_INTERNAL)
2152 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2153 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2154 "-------------------------------------------------------------------------------\n"
2155 "DO NOT REBOOT OR POWEROFF!\n");
2156 else
2157#endif
2158 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2159 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002160}
2161
hailfingerf79d1712010-10-06 23:48:34 +00002162void list_programmers_linebreak(int startcol, int cols, int paren)
2163{
2164 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002165 int pnamelen;
2166 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002167 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002168 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002169
2170 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2171 pname = programmer_table[p].name;
2172 pnamelen = strlen(pname);
2173 if (remaining - pnamelen - 2 < 0) {
2174 if (firstline)
2175 firstline = 0;
2176 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002177 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002178 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002179 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002180 remaining = cols - startcol;
2181 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002182 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002183 remaining--;
2184 }
2185 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002186 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002187 remaining--;
2188 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002189 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002190 remaining -= pnamelen;
2191 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002192 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002193 remaining--;
2194 } else {
2195 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002196 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002197 }
2198 }
2199}
2200
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002201static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002202{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002203#if IS_WINDOWS
2204 SYSTEM_INFO si;
2205 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002206
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002207 memset(&si, 0, sizeof(SYSTEM_INFO));
2208 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2209 msg_ginfo(" on Windows");
2210 /* Tell Windows which version of the structure we want. */
2211 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2212 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2213 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2214 else
2215 msg_ginfo(" unknown version");
2216 GetSystemInfo(&si);
2217 switch (si.wProcessorArchitecture) {
2218 case PROCESSOR_ARCHITECTURE_AMD64:
2219 msg_ginfo(" (x86_64)");
2220 break;
2221 case PROCESSOR_ARCHITECTURE_INTEL:
2222 msg_ginfo(" (x86)");
2223 break;
2224 default:
2225 msg_ginfo(" (unknown arch)");
2226 break;
2227 }
2228#elif HAVE_UTSNAME == 1
2229 struct utsname osinfo;
2230
2231 uname(&osinfo);
2232 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002233 osinfo.machine);
2234#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002235 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002236#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002237}
2238
2239void print_buildinfo(void)
2240{
2241 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002242#if NEED_PCI == 1
2243#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002244 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002245#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002246 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002247#endif
2248#endif
2249#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002250 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002251#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002252 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002253#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002254 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002255#endif
hailfinger3b471632010-03-27 16:36:40 +00002256#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002257 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002258#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002259 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002260#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002261 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002262#endif
2263#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002264 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002265#endif
2266#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002267 msg_gdbg(" little endian");
Edward O'Callaghan3c005942020-10-01 16:33:47 +10002268#elif defined (__FLASHROM_BIG_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002269 msg_gdbg(" big endian");
Edward O'Callaghan3c005942020-10-01 16:33:47 +10002270#else
2271#error Endianness could not be determined
hailfinger3b471632010-03-27 16:36:40 +00002272#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002273 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002274}
2275
uwefdeca092008-01-21 15:24:22 +00002276void print_version(void)
2277{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002278 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002279 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002280 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002281}
2282
hailfinger74819ad2010-05-15 15:04:37 +00002283void print_banner(void)
2284{
2285 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002286 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002287 msg_ginfo("\n");
2288}
2289
hailfingerc77acb52009-12-24 02:15:55 +00002290int selfcheck(void)
2291{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002292 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002293 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002294
2295 /* Safety check. Instead of aborting after the first error, check
2296 * if more errors exist.
2297 */
hailfingerc77acb52009-12-24 02:15:55 +00002298 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002299 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002300 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002301 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002302 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2303 const struct programmer_entry p = programmer_table[i];
2304 if (p.name == NULL) {
2305 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2306 ret = 1;
2307 /* This might hide other problems with this programmer, but allows for better error
2308 * messages below without jumping through hoops. */
2309 continue;
2310 }
2311 switch (p.type) {
2312 case USB:
2313 case PCI:
2314 case OTHER:
2315 if (p.devs.note == NULL) {
2316 if (strcmp("internal", p.name) == 0)
2317 break; /* This one has its device list stored separately. */
2318 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2319 p.name);
2320 ret = 1;
2321 }
2322 break;
2323 default:
2324 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2325 ret = 1;
2326 break;
2327 }
2328 if (p.init == NULL) {
2329 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2330 ret = 1;
2331 }
2332 if (p.delay == NULL) {
2333 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2334 ret = 1;
2335 }
2336 if (p.map_flash_region == NULL) {
2337 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2338 ret = 1;
2339 }
2340 if (p.unmap_flash_region == NULL) {
2341 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2342 ret = 1;
2343 }
2344 }
2345
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002346 /* It would be favorable if we could check for the correct layout (especially termination) of various
2347 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2348 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2349 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2350 * For 'flashchips' we export the size explicitly to work around this and to be able to implement the
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002351 * checks below. */
2352 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002353 msg_gerr("Flashchips table miscompilation!\n");
2354 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002355 } else {
2356 for (i = 0; i < flashchips_size - 1; i++) {
2357 const struct flashchip *chip = &flashchips[i];
2358 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2359 ret = 1;
2360 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2361 "Please report a bug at flashrom@flashrom.org\n", i,
2362 chip->name == NULL ? "unnamed" : chip->name);
2363 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002364 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002365 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002366 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002367 }
stefanct6d836ba2011-05-26 01:35:19 +00002368 }
stefanct6d836ba2011-05-26 01:35:19 +00002369
Edward O'Callaghane6b85692020-12-18 11:01:55 +11002370#if CONFIG_INTERNAL == 1
2371 ret |= selfcheck_board_enables();
2372#endif
2373
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002374 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002375 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002376}
2377
hailfinger771fc182010-10-15 00:01:14 +00002378/* FIXME: This function signature needs to be improved once doit() has a better
2379 * function signature.
2380 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002381static int chip_safety_check(const struct flashctx *flash, int force,
2382 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002383{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002384 const struct flashchip *chip = flash->chip;
2385
hailfinger771fc182010-10-15 00:01:14 +00002386 if (!programmer_may_write && (write_it || erase_it)) {
2387 msg_perr("Write/erase is not working yet on your programmer in "
2388 "its current configuration.\n");
2389 /* --force is the wrong approach, but it's the best we can do
2390 * until the generic programmer parameter parser is merged.
2391 */
2392 if (!force)
2393 return 1;
2394 msg_cerr("Continuing anyway.\n");
2395 }
2396
2397 if (read_it || erase_it || write_it || verify_it) {
2398 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002399 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002400 msg_cerr("Read is not working on this chip. ");
2401 if (!force)
2402 return 1;
2403 msg_cerr("Continuing anyway.\n");
2404 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002405 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002406 msg_cerr("flashrom has no read function for this "
2407 "flash chip.\n");
2408 return 1;
2409 }
2410 }
2411 if (erase_it || write_it) {
2412 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002413 if (chip->tested.erase == NA) {
2414 msg_cerr("Erase is not possible on this chip.\n");
2415 return 1;
2416 }
2417 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002418 msg_cerr("Erase is not working on this chip. ");
2419 if (!force)
2420 return 1;
2421 msg_cerr("Continuing anyway.\n");
2422 }
stefancte1c5acf2011-07-04 07:27:17 +00002423 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002424 msg_cerr("flashrom has no erase function for this "
2425 "flash chip.\n");
2426 return 1;
2427 }
hailfinger771fc182010-10-15 00:01:14 +00002428 }
2429 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002430 if (chip->tested.write == NA) {
2431 msg_cerr("Write is not possible on this chip.\n");
2432 return 1;
2433 }
2434 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002435 msg_cerr("Write is not working on this chip. ");
2436 if (!force)
2437 return 1;
2438 msg_cerr("Continuing anyway.\n");
2439 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002440 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002441 msg_cerr("flashrom has no write function for this "
2442 "flash chip.\n");
2443 return 1;
2444 }
2445 }
2446 return 0;
2447}
2448
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002449int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002450 const bool read_it, const bool write_it,
2451 const bool erase_it, const bool verify_it)
2452{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002453 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002454 msg_cerr("Aborting.\n");
2455 return 1;
2456 }
2457
Daniel Campellodf477722021-04-05 16:53:33 -06002458 if (flash->layout == get_global_layout() && normalize_romentries(flash)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002459 msg_cerr("Requested regions can not be handled. Aborting.\n");
2460 return 1;
2461 }
2462
Edward O'Callaghan40092972020-10-20 11:50:48 +11002463 /*
2464 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2465 * can be repro'ed with upstream on Volteer.
2466 *
2467 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2468 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2469 * hooked and this can fail on some board topologies. Checking the return value can
2470 * cause board rw failures by bailing early. Avoid the early bail for now until a
2471 * full investigation can reveal the proper fix. This restores previous behaviour of
2472 * assuming a map went fine.
2473 */
2474#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002475 if (map_flash(flash) != 0)
2476 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002477#endif
2478 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002479
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002480 /* Given the existence of read locks, we want to unlock for read,
2481 erase and write. */
2482 if (flash->chip->unlock)
2483 flash->chip->unlock(flash);
2484
2485 flash->address_high_byte = -1;
2486 flash->in_4ba_mode = false;
Nikolai Artemiev55f7a332020-11-05 13:54:27 +11002487 flash->chip_restore_fn_count = 0;
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002488
Edward O'Callaghan99974452020-10-13 13:28:33 +11002489 /* Be careful about 4BA chips and broken masters */
2490 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2491 /* If we can't use native instructions, bail out */
2492 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2493 || !spi_master_4ba(flash)) {
2494 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2495 return 1;
2496 }
2497 }
2498
Edward O'Callaghanecb10662020-11-11 20:23:44 +11002499 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2500 if ((flash->chip->bustype == BUS_SPI) &&
2501 (flash->chip->feature_bits & (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_ENTER_EAR7))) {
2502 int ret;
2503 if (spi_master_4ba(flash))
2504 ret = spi_enter_4ba(flash);
2505 else
2506 ret = spi_exit_4ba(flash);
2507 if (ret) {
2508 msg_cerr("Failed to set correct 4BA mode! Aborting.\n");
2509 return 1;
2510 }
2511 }
2512
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002513 return 0;
2514}
2515
Edward O'Callaghana820b212020-09-17 22:53:26 +10002516void finalize_flash_access(struct flashctx *const flash)
2517{
Nikolai Artemiev55f7a332020-11-05 13:54:27 +11002518 deregister_chip_restore(flash);
Edward O'Callaghana820b212020-09-17 22:53:26 +10002519 unmap_flash(flash);
2520}
2521
Daniel Campelloee45dc12021-04-10 10:13:51 -06002522static int setup_oldcontents(struct flashctx *flashctx, void *oldcontents,
2523 int erase_it, const void *const refcontents)
Daniel Campello98eed1a2021-03-22 07:28:34 -06002524{
Daniel Campelloee45dc12021-04-10 10:13:51 -06002525 const size_t flash_size = flashctx->chip->total_size * 1024;
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06002526 const bool verify_all = flashctx->flags.verify_whole_chip;
2527 const bool verify = flashctx->flags.verify_after_write;
Daniel Campello98eed1a2021-03-22 07:28:34 -06002528
Daniel Campelloee45dc12021-04-10 10:13:51 -06002529 memset(oldcontents, UNERASED_VALUE(flashctx), flash_size);
2530 if (!flashctx->flags.do_not_diff) {
Daniel Campello98eed1a2021-03-22 07:28:34 -06002531 /*
2532 * Obtain a reference image so that we can check whether
2533 * regions need to be erased and to give better diagnostics in
2534 * case write fails. If --fast-verify is used then only the
2535 * regions which are included using -i will be read.
2536 */
Daniel Campelloee45dc12021-04-10 10:13:51 -06002537 if (refcontents) {
2538 msg_cinfo("Assuming old flash chip contents as ref-file...\n");
2539 memcpy(oldcontents, refcontents, flash_size);
Daniel Campello98eed1a2021-03-22 07:28:34 -06002540 } else {
Daniel Campelloee45dc12021-04-10 10:13:51 -06002541 msg_cinfo("Reading old flash chip contents... ");
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06002542 if (verify && verify_all) {
2543 if (read_flash(flashctx, oldcontents, 0, flash_size)) {
2544 msg_cinfo("FAILED.\n");
2545 return 1;
2546 }
2547 } else {
2548 if (read_by_layout(flashctx, oldcontents)) {
2549 msg_cinfo("FAILED.\n");
2550 return 1;
2551 }
Daniel Campello98eed1a2021-03-22 07:28:34 -06002552 }
Daniel Campelloee45dc12021-04-10 10:13:51 -06002553 msg_cinfo("done.\n");
Daniel Campello98eed1a2021-03-22 07:28:34 -06002554 }
Daniel Campello98eed1a2021-03-22 07:28:34 -06002555 } else if (!erase_it) {
2556 msg_pinfo("No diff performed, considering the chip erased.\n");
Daniel Campelloee45dc12021-04-10 10:13:51 -06002557 memset(oldcontents, ERASED_VALUE(flashctx), flash_size);
Daniel Campello98eed1a2021-03-22 07:28:34 -06002558 }
2559
Daniel Campelloee45dc12021-04-10 10:13:51 -06002560 return 0;
Daniel Campello98eed1a2021-03-22 07:28:34 -06002561}
2562
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002563/**
2564 * @addtogroup flashrom-flash
2565 * @{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002566 */
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002567
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002568static void combine_image_by_layout(const struct flashctx *const flashctx,
2569 uint8_t *const newcontents, const uint8_t *const oldcontents);
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002570/**
2571 * @brief Erase the specified ROM chip.
2572 *
2573 * If a layout is set in the given flash context, only included regions
2574 * will be erased.
2575 *
2576 * @param flashctx The context of the flash chip to erase.
2577 * @return 0 on success.
2578 */
Daniel Campello26765322021-03-22 14:53:27 -06002579int flashrom_flash_erase(struct flashctx *const flashctx)
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002580{
Daniel Campello26765322021-03-22 14:53:27 -06002581 const size_t flash_size = flashctx->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002582
Daniel Campello26765322021-03-22 14:53:27 -06002583 int ret = 1;
2584
2585 struct action_descriptor *descriptor = NULL;
2586 uint8_t *oldcontents = malloc(flash_size);
2587 uint8_t *newcontents = malloc(flash_size);
2588 if (!oldcontents || !newcontents) {
2589 msg_gerr("Out of memory!\n");
2590 goto _free_ret;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002591 }
2592
Daniel Campello26765322021-03-22 14:53:27 -06002593 if (prepare_flash_access(flashctx, false, false, true, false))
2594 goto _free_ret;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002595
Daniel Campelloee45dc12021-04-10 10:13:51 -06002596 if (setup_oldcontents(flashctx, oldcontents, true, NULL))
2597 goto _finalize_ret;
2598
2599 memset(newcontents, ERASED_VALUE(flashctx), flash_size);
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002600 combine_image_by_layout(flashctx, newcontents, oldcontents);
Daniel Campello26765322021-03-22 14:53:27 -06002601
2602 descriptor = prepare_action_descriptor(flashctx, oldcontents, newcontents, true);
2603
2604 if (!erase_and_write_flash(flashctx, descriptor)) {
2605 ret = 0;
2606 }
2607
2608_finalize_ret:
2609 finalize_flash_access(flashctx);
2610_free_ret:
2611 if (descriptor)
2612 free(descriptor);
2613 free(oldcontents);
2614 free(newcontents);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002615 return ret;
2616}
2617
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002618/** @} */ /* end flashrom-flash */
2619
Edward O'Callaghan8c2a3402020-12-09 12:23:01 +11002620/**
2621 * @defgroup flashrom-ops Operations
2622 * @{
2623 */
2624
Edward O'Callaghan84c89182020-12-09 12:33:37 +11002625/**
2626 * @brief Read the current image from the specified ROM chip.
2627 *
2628 * If a layout is set in the specified flash context, only included regions
2629 * will be read.
2630 *
2631 * @param flashctx The context of the flash chip.
2632 * @param buffer Target buffer to write image to.
2633 * @param buffer_len Size of target buffer in bytes.
2634 * @return 0 on success,
2635 * 2 if buffer_len is too short for the flash chip's contents,
2636 * or 1 on any other failure.
2637 */
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06002638int flashrom_image_read(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len)
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002639{
Daniel Campello039cd2b2021-03-24 20:12:15 -06002640 const size_t flash_size = flashctx->chip->total_size * 1024;
2641
2642 if (flash_size > buffer_len)
2643 return 2;
2644
2645 if (prepare_flash_access(flashctx, true, false, false, false))
2646 return 1;
2647
2648 msg_cinfo("Reading flash... ");
2649
2650 int ret = 1;
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06002651 if (read_by_layout(flashctx, buffer)) {
Daniel Campello039cd2b2021-03-24 20:12:15 -06002652 msg_cerr("Read operation failed!\n");
2653 msg_cinfo("FAILED.\n");
2654 goto _finalize_ret;
2655 }
2656 msg_cinfo("done.\n");
2657 ret = 0;
2658
2659_finalize_ret:
2660 finalize_flash_access(flashctx);
2661 return ret;
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002662}
2663
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002664static void combine_image_by_layout(const struct flashctx *const flashctx,
2665 uint8_t *const newcontents, const uint8_t *const oldcontents)
2666{
2667 const struct flashrom_layout *const layout = get_layout(flashctx);
2668 const struct romentry *included;
2669 chipoff_t start = 0;
2670
2671 while ((included = layout_next_included_region(layout, start))) {
2672 if (included->start > start) {
2673 /* copy everything up to the start of this included region */
2674 memcpy(newcontents + start, oldcontents + start, included->start - start);
2675 }
2676 /* skip this included region */
2677 start = included->end + 1;
2678 if (start == 0)
2679 return;
2680 }
2681
2682 /* copy the rest of the chip */
2683 const chipsize_t copy_len = flashctx->chip->total_size * 1024 - start;
2684 memcpy(newcontents + start, oldcontents + start, copy_len);
2685}
2686
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002687/**
2688 * @brief Write the specified image to the ROM chip.
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002689 *
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002690 * If a layout is set in the specified flash context, only erase blocks
2691 * containing included regions will be touched.
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002692 *
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002693 * @param flashctx The context of the flash chip.
2694 * @param buffer Source buffer to read image from (may be altered for full verification).
2695 * @param buffer_len Size of source buffer in bytes.
2696 * @param refbuffer If given, assume flash chip contains same data as `refbuffer`.
2697 * @return 0 on success,
2698 * 4 if buffer_len doesn't match the size of the flash chip,
2699 * or 1 on any other failure.
hailfingerc77acb52009-12-24 02:15:55 +00002700 */
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002701int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len,
2702 const void *const refbuffer)
hailfingerc77acb52009-12-24 02:15:55 +00002703{
Daniel Campello57eb4882021-03-25 08:45:10 -06002704 const size_t flash_size = flashctx->chip->total_size * 1024;
Daniel Campello57eb4882021-03-25 08:45:10 -06002705 const bool verify_all = flashctx->flags.verify_whole_chip;
2706 const bool verify = flashctx->flags.verify_after_write;
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002707
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002708 if (buffer_len != flash_size)
2709 return 4;
2710
2711 int ret = 1;
2712
2713 struct action_descriptor *descriptor = NULL;
2714 uint8_t *oldcontents = malloc(flash_size);
2715 uint8_t *newcontents = malloc(flash_size);
2716 if (!oldcontents || !newcontents) {
stefanctd611e8f2011-07-12 22:35:21 +00002717 msg_gerr("Out of memory!\n");
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002718 goto _free_ret;
stefanctd611e8f2011-07-12 22:35:21 +00002719 }
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002720
2721 if (prepare_flash_access(flashctx, false, true, false, verify))
2722 goto _free_ret;
hailfingerb437e282010-11-04 01:04:27 +00002723
Daniel Campelloee45dc12021-04-10 10:13:51 -06002724 if (setup_oldcontents(flashctx, oldcontents, false, refbuffer))
2725 goto _finalize_ret;
2726
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002727 memcpy(newcontents, buffer, flash_size);
2728 combine_image_by_layout(flashctx, newcontents, oldcontents);
uwef6641642007-05-09 10:17:44 +00002729
Daniel Campello57eb4882021-03-25 08:45:10 -06002730 descriptor = prepare_action_descriptor(flashctx, oldcontents, newcontents,
Daniel Campello57dd0722021-04-08 13:28:38 -06002731 !flashctx->flags.do_not_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002732
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002733 // parse the new fmap and disable soft WP if necessary
2734 if ((ret = cros_ec_prepare(newcontents, flash_size))) {
2735 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
2736 goto _finalize_ret;
2737 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002738
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002739 if (erase_and_write_flash(flashctx, descriptor)) {
2740 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2741 msg_cinfo("Reading current flash chip contents... ");
2742 if (!read_flash(flashctx, newcontents, 0, flash_size)) {
2743 msg_cinfo("done.\n");
2744 if (!memcmp(oldcontents, newcontents, flash_size)) {
2745 nonfatal_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002746 ret = 1;
Daniel Campello57eb4882021-03-25 08:45:10 -06002747 goto _finalize_ret;
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002748 }
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002749 msg_cerr("Apparently at least some data has changed.\n");
2750 } else
2751 msg_cerr("Can't even read anymore!\n");
2752 emergency_help_message();
2753 ret = 1;
2754 goto _finalize_ret;
2755 }
2756
2757 ret = cros_ec_need_2nd_pass();
2758 if (ret < 0) {
2759 // Jump failed
2760 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
2761 emergency_help_message();
2762 ret = 1;
2763 goto _finalize_ret;
2764 } else if (ret > 0) {
2765 // Need 2nd pass. Get the just written content.
2766 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06002767 ret = setup_oldcontents(flashctx, oldcontents, false, NULL);
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002768 if (ret) {
2769 emergency_help_message();
2770 goto _finalize_ret;
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002771 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002772
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002773 /* Get a new descriptor. */
2774 free(descriptor);
2775 descriptor = prepare_action_descriptor(flashctx,
2776 oldcontents,
2777 newcontents,
Daniel Campello57dd0722021-04-08 13:28:38 -06002778 !flashctx->flags.do_not_diff);
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002779 // write 2nd pass
2780 if (erase_and_write_flash(flashctx, descriptor)) {
2781 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002782 emergency_help_message();
2783 ret = 1;
Daniel Campello57eb4882021-03-25 08:45:10 -06002784 goto _finalize_ret;
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002785 }
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002786 ret = 0;
2787 }
2788
2789 if (cros_ec_finish() < 0) {
2790 msg_cerr("cros_ec_finish() failed. Stop.\n");
2791 emergency_help_message();
2792 ret = 1;
2793 goto _finalize_ret;
stuge8ce3a3c2008-04-28 14:47:30 +00002794 }
ollie6a600992005-11-26 21:55:36 +00002795
Daniel Campello26765322021-03-22 14:53:27 -06002796 if (verify) {
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002797 if (!content_has_changed) {
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002798 msg_gdbg("Nothing was written, skipping verification\n");
David Hendricks9ba79fb2015-04-03 12:06:16 -07002799 } else {
2800 /* Work around chips which need some time to calm down. */
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002801 if (verify_all)
David Hendricks9ba79fb2015-04-03 12:06:16 -07002802 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002803
Daniel Campello57eb4882021-03-25 08:45:10 -06002804 ret = verify_flash(flashctx, descriptor);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002805
David Hendricks9ba79fb2015-04-03 12:06:16 -07002806 /* If we tried to write, and verification now fails, we
2807 * might have an emergency situation.
2808 */
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002809 if (ret)
David Hendricks9ba79fb2015-04-03 12:06:16 -07002810 emergency_help_message();
2811 }
hailfinger0459e1c2009-08-19 13:55:34 +00002812 }
ollie6a600992005-11-26 21:55:36 +00002813
Daniel Campello57eb4882021-03-25 08:45:10 -06002814_finalize_ret:
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002815 finalize_flash_access(flashctx);
2816_free_ret:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002817 if (descriptor)
2818 free(descriptor);
hailfinger90fcf9b2010-11-05 14:51:59 +00002819 free(oldcontents);
2820 free(newcontents);
stepan83eca252006-01-04 16:42:57 +00002821 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002822}
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002823
Daniel Campellof758a8b2021-03-22 14:47:13 -06002824/**
2825 * @brief Verify the ROM chip's contents with the specified image.
2826 *
2827 * If a layout is set in the specified flash context, only included regions
2828 * will be verified.
2829 *
2830 * @param flashctx The context of the flash chip.
2831 * @param buffer Source buffer to verify with.
2832 * @param buffer_len Size of source buffer in bytes.
2833 * @return 0 on success,
Daniel Campelloef545b12021-04-10 10:39:26 -06002834 * 3 if the chip's contents don't match,
Daniel Campellof758a8b2021-03-22 14:47:13 -06002835 * 2 if buffer_len doesn't match the size of the flash chip,
2836 * or 1 on any other failure.
2837 */
2838int flashrom_image_verify(struct flashctx *const flashctx, const void *const buffer, const size_t buffer_len)
2839{
2840 const size_t flash_size = flashctx->chip->total_size * 1024;
2841
2842 if (buffer_len != flash_size)
2843 return 2;
2844
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002845 const uint8_t *const newcontents = buffer;
Daniel Campelloef545b12021-04-10 10:39:26 -06002846 uint8_t *const curcontents = malloc(flash_size);
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002847 if (!curcontents) {
Daniel Campellof758a8b2021-03-22 14:47:13 -06002848 msg_gerr("Out of memory!\n");
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002849 return 1;
Daniel Campellof758a8b2021-03-22 14:47:13 -06002850 }
2851
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002852 int ret = 1;
2853
Daniel Campellof758a8b2021-03-22 14:47:13 -06002854 if (prepare_flash_access(flashctx, false, false, false, true))
2855 goto _free_ret;
2856
Daniel Campellof758a8b2021-03-22 14:47:13 -06002857 msg_cinfo("Verifying flash... ");
Daniel Campelloef545b12021-04-10 10:39:26 -06002858 ret = verify_by_layout(flashctx, curcontents, newcontents);
Daniel Campellof758a8b2021-03-22 14:47:13 -06002859 if (!ret)
2860 msg_cinfo("VERIFIED.\n");
2861
Daniel Campellof758a8b2021-03-22 14:47:13 -06002862 finalize_flash_access(flashctx);
2863_free_ret:
Daniel Campelloef545b12021-04-10 10:39:26 -06002864 free(curcontents);
Daniel Campellof758a8b2021-03-22 14:47:13 -06002865 return ret;
2866}
2867
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002868/** @} */ /* end flashrom-ops */
2869
2870int do_read(struct flashctx *const flash, const char *const filename)
2871{
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002872 if (prepare_flash_access(flash, true, false, false, false))
2873 return 1;
2874
Edward O'Callaghan471958e2020-12-09 12:40:12 +11002875 const int ret = read_flash_to_file(flash, filename);
2876
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002877 finalize_flash_access(flash);
2878
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002879 return ret;
2880}
2881
Daniel Campello83752f82021-04-16 14:54:27 -06002882int do_extract(struct flashctx *const flash)
2883{
2884 prepare_layout_for_extraction(flash);
2885 return do_read(flash, NULL);
2886}
2887
Edward O'Callaghan6e573be2020-12-18 10:38:06 +11002888int do_erase(struct flashctx *const flash)
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002889{
Daniel Campello26765322021-03-22 14:53:27 -06002890 const int ret = flashrom_flash_erase(flash);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002891
2892 /*
2893 * FIXME: Do we really want the scary warning if erase failed?
2894 * After all, after erase the chip is either blank or partially
2895 * blank or it has the old contents. A blank chip won't boot,
2896 * so if the user wanted erase and reboots afterwards, the user
2897 * knows very well that booting won't work.
2898 */
2899 if (ret)
2900 emergency_help_message();
2901
2902 return ret;
2903}
2904
Edward O'Callaghan6e573be2020-12-18 10:38:06 +11002905int do_write(struct flashctx *const flash, const char *const filename, const char *const referencefile)
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002906{
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002907 const size_t flash_size = flash->chip->total_size * 1024;
2908 int ret = 1;
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002909
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002910 uint8_t *const newcontents = malloc(flash_size);
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002911 uint8_t *const refcontents = referencefile ? malloc(flash_size) : NULL;
2912
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002913 if (!newcontents || (referencefile && !refcontents)) {
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002914 msg_gerr("Out of memory!\n");
2915 goto _free_ret;
2916 }
2917
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002918 /* Read '-w' argument first... */
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002919 if (filename) {
2920 if (read_buf_from_file(newcontents, flash_size, filename))
2921 goto _free_ret;
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002922 }
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002923 /*
2924 * ... then update newcontents with contents from files provided to '-i'
2925 * args if needed.
2926 */
2927 if (read_buf_from_include_args(flash, newcontents))
2928 goto _free_ret;
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002929
2930 if (referencefile) {
2931 if (read_buf_from_file(refcontents, flash_size, referencefile))
2932 goto _free_ret;
2933 }
2934
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002935 ret = flashrom_image_write(flash, newcontents, flash_size, refcontents);
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002936
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002937_free_ret:
2938 free(refcontents);
2939 free(newcontents);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002940 return ret;
2941}
2942
Edward O'Callaghan6e573be2020-12-18 10:38:06 +11002943int do_verify(struct flashctx *const flash, const char *const filename)
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002944{
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002945 const size_t flash_size = flash->chip->total_size * 1024;
2946 int ret = 1;
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002947
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002948 uint8_t *const newcontents = malloc(flash_size);
2949 if (!newcontents) {
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002950 msg_gerr("Out of memory!\n");
2951 goto _free_ret;
2952 }
2953
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002954 /* Read '-v' argument first... */
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002955 if (filename) {
2956 if (read_buf_from_file(newcontents, flash_size, filename))
2957 goto _free_ret;
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002958 }
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002959 /*
2960 * ... then update newcontents with contents from files provided to '-i'
2961 * args if needed.
2962 */
2963 if (read_buf_from_include_args(flash, newcontents))
2964 goto _free_ret;
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002965
Daniel Campellof758a8b2021-03-22 14:47:13 -06002966 ret = flashrom_image_verify(flash, newcontents, flash_size);
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002967
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002968_free_ret:
2969 free(newcontents);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002970 return ret;
2971}