blob: 1755857940742631e44645cd5d42b311c3bcf921 [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;
David Hendricks1ed1d352011-11-23 17:54:37 -0800975
Patrick Georgif3fa2992017-02-02 16:24:44 +0100976 chunksize = min(flash->chip->page_size, len - i);
977 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700978 if (tmp) {
979 ret = tmp;
980 if (ignore_error(tmp))
981 continue;
982 else
983 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800984 }
Simon Glass4e305f42015-01-08 06:29:04 -0700985
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700986 /*
987 * Check write access permission and do not compare chunks
988 * where flashrom does not have write access to the region.
989 */
990 if (flash->chip->check_access) {
991 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
992 if (tmp && ignore_error(tmp))
993 continue;
994 }
995
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000996 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700997 if (failcount)
998 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800999 }
Simon Glass4e305f42015-01-08 06:29:04 -07001000 } else {
1001 int tmp;
1002
1003 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +01001004 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -07001005 if (tmp && !ignore_error(tmp)) {
1006 ret = tmp;
1007 goto out_free;
1008 }
1009
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001010 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +00001011 }
1012
hailfinger5be6c0f2009-07-23 01:42:56 +00001013 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +00001014 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +00001015 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +00001016 ret = -1;
1017 }
hailfinger7af83692009-06-15 17:23:36 +00001018
1019out_free:
1020 free(readbuf);
1021 return ret;
1022}
1023
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001024/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1025static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001026 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001027{
1028 unsigned int i, j, limit;
1029 for (j = 0; j < len / gran; j++) {
1030 limit = min (gran, len - j * gran);
1031 /* Are 'have' and 'want' identical? */
1032 if (!memcmp(have + j * gran, want + j * gran, limit))
1033 continue;
1034 /* have needs to be in erased state. */
1035 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001036 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001037 return 1;
1038 }
1039 return 0;
1040}
1041
uwee15beb92010-08-08 17:01:18 +00001042/*
hailfingerb247c7a2010-03-08 00:42:32 +00001043 * Check if the buffer @have can be programmed to the content of @want without
1044 * erasing. This is only possible if all chunks of size @gran are either kept
1045 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001046 *
hailfingerb437e282010-11-04 01:04:27 +00001047 * Warning: This function assumes that @have and @want point to naturally
1048 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001049 *
1050 * @have buffer with current content
1051 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001052 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001053 * @gran write granularity (enum, not count)
1054 * @return 0 if no erase is needed, 1 otherwise
1055 */
Edward O'Callaghanaccf9ff2021-01-22 01:33:03 +11001056static int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001057 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001058{
hailfingerb91c08c2011-08-15 19:54:20 +00001059 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001060 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001061
hailfingerb247c7a2010-03-08 00:42:32 +00001062 switch (gran) {
1063 case write_gran_1bit:
1064 for (i = 0; i < len; i++)
1065 if ((have[i] & want[i]) != want[i]) {
1066 result = 1;
1067 break;
1068 }
1069 break;
1070 case write_gran_1byte:
1071 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001072 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001073 result = 1;
1074 break;
1075 }
1076 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001077 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001078 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001079 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001080 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001081 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001082 break;
1083 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001084 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001085 break;
1086 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001087 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001088 break;
1089 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001090 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001091 break;
1092 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001093 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001094 break;
1095 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001096 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001097 break;
1098 case write_gran_1byte_implicit_erase:
1099 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1100 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001101 break;
hailfingerb437e282010-11-04 01:04:27 +00001102 default:
1103 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1104 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001105 }
1106 return result;
1107}
1108
hailfingerb437e282010-11-04 01:04:27 +00001109/**
1110 * Check if the buffer @have needs to be programmed to get the content of @want.
1111 * If yes, return 1 and fill in first_start with the start address of the
1112 * write operation and first_len with the length of the first to-be-written
1113 * chunk. If not, return 0 and leave first_start and first_len undefined.
1114 *
1115 * Warning: This function assumes that @have and @want point to naturally
1116 * aligned regions.
1117 *
1118 * @have buffer with current content
1119 * @want buffer with desired content
1120 * @len length of the checked area
1121 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001122 * @first_start offset of the first byte which needs to be written (passed in
1123 * value is increased by the offset of the first needed write
1124 * relative to have/want or unchanged if no write is needed)
1125 * @return length of the first contiguous area which needs to be written
1126 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001127 *
1128 * FIXME: This function needs a parameter which tells it about coalescing
1129 * in relation to the max write length of the programmer and the max write
1130 * length of the chip.
1131 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001132static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001133 unsigned int *first_start,
1134 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001135{
stefanctc5eb8a92011-11-23 09:13:48 +00001136 int need_write = 0;
1137 unsigned int rel_start = 0, first_len = 0;
1138 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001139
hailfingerb437e282010-11-04 01:04:27 +00001140 switch (gran) {
1141 case write_gran_1bit:
1142 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001143 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001144 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001145 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001146 case write_gran_128bytes:
1147 stride = 128;
1148 break;
hailfingerb437e282010-11-04 01:04:27 +00001149 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001150 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001151 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001152 case write_gran_264bytes:
1153 stride = 264;
1154 break;
1155 case write_gran_512bytes:
1156 stride = 512;
1157 break;
1158 case write_gran_528bytes:
1159 stride = 528;
1160 break;
1161 case write_gran_1024bytes:
1162 stride = 1024;
1163 break;
1164 case write_gran_1056bytes:
1165 stride = 1056;
1166 break;
hailfingerb437e282010-11-04 01:04:27 +00001167 default:
1168 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1169 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001170 /* Claim that no write was needed. A write with unknown
1171 * granularity is too dangerous to try.
1172 */
1173 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001174 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001175 for (i = 0; i < len / stride; i++) {
1176 limit = min(stride, len - i * stride);
1177 /* Are 'have' and 'want' identical? */
1178 if (memcmp(have + i * stride, want + i * stride, limit)) {
1179 if (!need_write) {
1180 /* First location where have and want differ. */
1181 need_write = 1;
1182 rel_start = i * stride;
1183 }
1184 } else {
1185 if (need_write) {
1186 /* First location where have and want
1187 * do not differ anymore.
1188 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001189 break;
1190 }
1191 }
1192 }
hailfingerffb7f382010-12-06 13:05:44 +00001193 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001194 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001195 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001196 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001197}
1198
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001199/* Returns the number of busses commonly supported by the current programmer and flash chip where the latter
1200 * can not be completely accessed due to size/address limits of the programmer. */
1201unsigned int count_max_decode_exceedings(const struct flashctx *flash)
hailfingeraec9c962009-10-31 01:53:09 +00001202{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001203 unsigned int limitexceeded = 0;
1204 uint32_t size = flash->chip->total_size * 1024;
1205 enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
uwe8d342eb2011-07-28 08:13:25 +00001206
1207 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001208 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001209 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001210 "size %u kB of chipset/board/programmer "
1211 "for %s interface, "
1212 "probe/read/erase/write may fail. ", size / 1024,
1213 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001214 }
hailfingere1e41ea2011-07-27 07:13:06 +00001215 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001216 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001217 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001218 "size %u kB of chipset/board/programmer "
1219 "for %s interface, "
1220 "probe/read/erase/write may fail. ", size / 1024,
1221 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001222 }
hailfingere1e41ea2011-07-27 07:13:06 +00001223 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001224 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001225 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001226 "size %u kB of chipset/board/programmer "
1227 "for %s interface, "
1228 "probe/read/erase/write may fail. ", size / 1024,
1229 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001230 }
hailfingere1e41ea2011-07-27 07:13:06 +00001231 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001232 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001233 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001234 "size %u kB of chipset/board/programmer "
1235 "for %s interface, "
1236 "probe/read/erase/write may fail. ", size / 1024,
1237 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001238 }
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001239 return limitexceeded;
hailfingeraec9c962009-10-31 01:53:09 +00001240}
1241
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001242void unmap_flash(struct flashctx *flash)
1243{
1244 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1245 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1246 flash->physical_registers = 0;
1247 flash->virtual_registers = (chipaddr)ERROR_PTR;
1248 }
1249
1250 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1251 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1252 flash->physical_memory = 0;
1253 flash->virtual_memory = (chipaddr)ERROR_PTR;
1254 }
1255}
1256
1257int map_flash(struct flashctx *flash)
1258{
1259 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1260 flash->virtual_memory = (chipaddr)ERROR_PTR;
1261 flash->virtual_registers = (chipaddr)ERROR_PTR;
1262
1263 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1264 * These are used for various probing-related hacks that would not map successfully anyway and should be
1265 * removed ASAP. */
1266 if (flash->chip->total_size == 0)
1267 return 0;
1268
1269 const chipsize_t size = flash->chip->total_size * 1024;
1270 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1271 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1272 if (addr == ERROR_PTR) {
1273 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1274 flash->chip->name, PRIxPTR_WIDTH, base);
1275 return 1;
1276 }
1277 flash->physical_memory = base;
1278 flash->virtual_memory = (chipaddr)addr;
1279
1280 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1281 * completely different on some chips and programmers, or not mappable at all.
1282 * Ignore these problems for now and always report success. */
1283 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1284 base = 0xffffffff - size - 0x400000 + 1;
1285 addr = programmer_map_flash_region("flash chip registers", base, size);
1286 if (addr == ERROR_PTR) {
1287 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1288 flash->chip->name, PRIxPTR_WIDTH, base);
1289 return 0;
1290 }
1291 flash->physical_registers = base;
1292 flash->virtual_registers = (chipaddr)addr;
1293 }
1294 return 0;
1295}
1296
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001297/*
1298 * Return a string corresponding to the bustype parameter.
1299 * Memory is obtained with malloc() and must be freed with free() by the caller.
1300 */
1301char *flashbuses_to_text(enum chipbustype bustype)
1302{
1303 char *ret = calloc(1, 1);
1304 /*
1305 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1306 * will cease to exist and should be eliminated here as well.
1307 */
1308 if (bustype == BUS_NONSPI) {
1309 ret = strcat_realloc(ret, "Non-SPI, ");
1310 } else {
1311 if (bustype & BUS_PARALLEL)
1312 ret = strcat_realloc(ret, "Parallel, ");
1313 if (bustype & BUS_LPC)
1314 ret = strcat_realloc(ret, "LPC, ");
1315 if (bustype & BUS_FWH)
1316 ret = strcat_realloc(ret, "FWH, ");
1317 if (bustype & BUS_SPI)
1318 ret = strcat_realloc(ret, "SPI, ");
1319 if (bustype & BUS_PROG)
1320 ret = strcat_realloc(ret, "Programmer-specific, ");
1321 if (bustype == BUS_NONE)
1322 ret = strcat_realloc(ret, "None, ");
1323 }
1324 /* Kill last comma. */
1325 ret[strlen(ret) - 2] = '\0';
1326 ret = realloc(ret, strlen(ret) + 1);
1327 return ret;
1328}
1329
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001330int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001331{
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001332 const struct flashchip *chip;
hailfingeraec9c962009-10-31 01:53:09 +00001333 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001334 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001335
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001336 for (chip = flashchips + startchip; chip && chip->name; chip++) {
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001337 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001338 continue;
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001339 buses_common = mst->buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001340 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001341 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001342 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001343 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001344 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001345 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001346 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001347 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001348 continue;
1349 }
stepan782fb172007-04-06 11:58:03 +00001350
hailfinger48ed3e22011-05-04 00:39:50 +00001351 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001352 flash->chip = calloc(1, sizeof(struct flashchip));
1353 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001354 msg_gerr("Out of memory!\n");
1355 exit(1);
1356 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001357 memcpy(flash->chip, chip, sizeof(struct flashchip));
1358 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001359
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001360 if (map_flash(flash) != 0)
1361 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001362
Edward O'Callaghana820b212020-09-17 22:53:26 +10001363 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1364 * is only called with force=1 after normal probing failed.
1365 */
stugec1e55fe2008-07-02 17:15:47 +00001366 if (force)
1367 break;
stepanc98b80b2006-03-16 16:57:41 +00001368
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001369 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001370 goto notfound;
1371
hailfinger48ed3e22011-05-04 00:39:50 +00001372 /* If this is the first chip found, accept it.
1373 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001374 * a non-generic match. SFDP and CFI are generic matches.
1375 * startchip==0 means this call to probe_flash() is the first
1376 * one for this programmer interface (master) and thus no other chip has
1377 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001378 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001379 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1380 msg_cinfo("===\n"
1381 "SFDP has autodetected a flash chip which is "
1382 "not natively supported by flashrom yet.\n");
1383 if (count_usable_erasers(flash) == 0)
1384 msg_cinfo("The standard operations read and "
1385 "verify should work, but to support "
1386 "erase, write and all other "
1387 "possible features");
1388 else
1389 msg_cinfo("All standard operations (read, "
1390 "verify, erase and write) should "
1391 "work, but to support all possible "
1392 "features");
1393
1394 msg_cinfo(" we need to add them manually.\n"
1395 "You can help us by mailing us the output of the following command to "
1396 "flashrom@flashrom.org:\n"
1397 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1398 "Thanks for your help!\n"
1399 "===\n");
1400 }
stugec1e55fe2008-07-02 17:15:47 +00001401
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001402 /* First flash chip detected on this bus. */
1403 if (startchip == 0)
1404 break;
1405 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001406 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001407 break;
1408 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001409notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001410 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001411 free(flash->chip);
1412 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001413 }
uwebe4477b2007-08-23 16:08:21 +00001414
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001415 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001416 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001417
Edward O'Callaghan53ff4ad2020-12-16 20:36:28 +11001418 /* Fill fallback layout covering the whole chip. */
1419 struct single_layout *const fallback = &flash->fallback_layout;
1420 fallback->base.entries = &fallback->entry;
1421 fallback->base.num_entries = 1;
1422 fallback->entry.start = 0;
1423 fallback->entry.end = flash->chip->total_size * 1024 - 1;
1424 fallback->entry.included = true;
1425 fallback->entry.name = strdup("complete flash");
1426 if (!fallback->entry.name) {
1427 msg_cerr("Failed to probe chip: %s\n", strerror(errno));
1428 return -1;
1429 }
stepan3e7aeae2011-01-19 06:21:54 +00001430
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001431 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001432 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1433 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001434 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001435#if CONFIG_INTERNAL == 1
1436 if (programmer_table[programmer].map_flash_region == physmap)
1437 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1438 PRIxPTR_WIDTH, flash->physical_memory);
1439 else
1440#endif
1441 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001442
Edward O'Callaghana820b212020-09-17 22:53:26 +10001443 /* Flash registers may more likely not be mapped if the chip was forced.
1444 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001445 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001446 if (flash->chip->printlock)
1447 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001448
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001449 /* Get out of the way for later runs. */
1450 unmap_flash(flash);
1451
hailfinger48ed3e22011-05-04 00:39:50 +00001452 /* Return position of matching chip. */
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001453 return chip - flashchips;
rminnich8d3ff912003-10-25 17:01:29 +00001454}
1455
uwe8d342eb2011-07-28 08:13:25 +00001456int read_buf_from_file(unsigned char *buf, unsigned long size,
1457 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001458{
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001459#ifdef __LIBPAYLOAD__
1460 msg_gerr("Error: No file I/O support in libpayload\n");
1461 return 1;
1462#else
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001463 int ret = 0;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001464
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001465 FILE *image;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001466 if (!strncmp(filename, "-", sizeof("-")))
1467 image = fdopen(STDIN_FILENO, "rb");
1468 else
1469 image = fopen(filename, "rb");
1470 if (image == NULL) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001471 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger771fc182010-10-15 00:01:14 +00001472 return 1;
1473 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001474
1475 struct stat image_stat;
hailfinger771fc182010-10-15 00:01:14 +00001476 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001477 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001478 ret = 1;
1479 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001480 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001481 if ((image_stat.st_size != size) &&
1482 (strncmp(filename, "-", sizeof("-")))) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001483 msg_gerr("Error: Image size (%jd B) doesn't match the flash chip's size (%lu B)!\n",
1484 (intmax_t)image_stat.st_size, size);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001485 ret = 1;
1486 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001487 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001488
1489 unsigned long numbytes = fread(buf, 1, size, image);
hailfinger771fc182010-10-15 00:01:14 +00001490 if (numbytes != size) {
1491 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1492 "wanted %ld!\n", numbytes, size);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001493 ret = 1;
hailfinger771fc182010-10-15 00:01:14 +00001494 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001495out:
1496 (void)fclose(image);
1497 return ret;
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001498#endif
hailfinger771fc182010-10-15 00:01:14 +00001499}
1500
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001501int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001502{
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001503#ifdef __LIBPAYLOAD__
1504 msg_gerr("Error: No file I/O support in libpayload\n");
1505 return 1;
1506#else
hailfingerd219a232009-01-28 00:27:54 +00001507 FILE *image;
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001508 int ret = 0;
hailfingerde345862009-06-01 22:07:52 +00001509
1510 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001511 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001512 return 1;
1513 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001514 if (!strncmp(filename, "-", sizeof("-")))
1515 image = fdopen(STDOUT_FILENO, "wb");
1516 else
1517 image = fopen(filename, "wb");
1518 if (image == NULL) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001519 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger23060112009-05-08 12:49:03 +00001520 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001521 }
hailfingerd219a232009-01-28 00:27:54 +00001522
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001523 unsigned long numbytes = fwrite(buf, 1, size, image);
hailfinger42a850a2010-07-13 23:56:13 +00001524 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001525 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001526 ret = 1;
1527 goto out;
hailfinger42a850a2010-07-13 23:56:13 +00001528 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001529 if (fflush(image)) {
1530 msg_gerr("Error: flushing file \"%s\" failed: %s\n", filename, strerror(errno));
1531 ret = 1;
1532 }
1533 // Try to fsync() only regular files and if that function is available at all (e.g. not on MinGW).
1534#if defined(_POSIX_FSYNC) && (_POSIX_FSYNC != -1)
1535 struct stat image_stat;
1536 if (fstat(fileno(image), &image_stat) != 0) {
1537 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1538 ret = 1;
1539 goto out;
1540 }
1541 if (S_ISREG(image_stat.st_mode)) {
1542 if (fsync(fileno(image))) {
1543 msg_gerr("Error: fsyncing file \"%s\" failed: %s\n", filename, strerror(errno));
1544 ret = 1;
1545 }
1546 }
1547#endif
1548out:
1549 if (fclose(image)) {
1550 msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
1551 ret = 1;
1552 }
1553 return ret;
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001554#endif
hailfingerd219a232009-01-28 00:27:54 +00001555}
1556
David Hendrickse3451942013-03-21 17:23:29 -07001557/*
1558 * read_flash - wrapper for flash->read() with additional high-level policy
1559 *
1560 * @flash flash chip
1561 * @buf buffer to store data in
1562 * @start start address
1563 * @len number of bytes to read
1564 *
1565 * This wrapper simplifies most cases when the flash chip needs to be read
1566 * since policy decisions such as non-fatal error handling is centralized.
1567 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001568int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001569 unsigned int start, unsigned int len)
1570{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001571 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001572
Patrick Georgif3fa2992017-02-02 16:24:44 +01001573 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001574 return -1;
1575
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001576 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1577
Patrick Georgif3fa2992017-02-02 16:24:44 +01001578 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001579 if (ret) {
1580 if (ignore_error(ret)) {
1581 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1582 start, start + len - 1);
1583 ret = 0;
1584 } else {
1585 msg_gdbg("failed to read 0x%x-0x%x\n",
1586 start, start + len - 1);
1587 }
1588 }
1589
1590 return ret;
1591}
1592
David Hendricks7c8a1612013-04-26 19:14:44 -07001593/*
1594 * write_flash - wrapper for flash->write() with additional high-level policy
1595 *
1596 * @flash flash chip
1597 * @buf buffer to write to flash
1598 * @start start address in flash
1599 * @len number of bytes to write
1600 *
1601 * TODO: Look up regions that are write-protected and avoid attempt to write
1602 * to them at all.
1603 */
Edward O'Callaghanaccf9ff2021-01-22 01:33:03 +11001604static int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001605 unsigned int start, unsigned int len)
1606{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001607 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001608 return -1;
1609
Patrick Georgif3fa2992017-02-02 16:24:44 +01001610 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001611}
1612
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001613int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001614{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001615 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001616 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001617 int ret = 0;
1618
1619 msg_cinfo("Reading flash... ");
1620 if (!buf) {
1621 msg_gerr("Memory allocation failed!\n");
1622 msg_cinfo("FAILED.\n");
1623 return 1;
1624 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001625
1626 /* To support partial read, fill buffer to all 0xFF at beginning to make
1627 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001628 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001629
Patrick Georgif3fa2992017-02-02 16:24:44 +01001630 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001631 msg_cerr("No read function available for this flash chip.\n");
1632 ret = 1;
1633 goto out_free;
1634 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001635
1636 /* First try to handle partial read case, rather than read the whole
1637 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001638 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001639 if (ret < 0) {
1640 msg_cerr("Partial read operation failed!\n");
1641 ret = 1;
1642 goto out_free;
1643 } else if (ret > 0) {
Edward O'Callaghan10bb9ae2020-12-17 13:06:10 +11001644 int num_regions = get_num_include_args(get_global_layout());
David Hendricksdf29a832013-06-28 14:33:51 -07001645
1646 if (ret != num_regions) {
1647 msg_cerr("Requested %d regions, but only read %d\n",
1648 num_regions, ret);
1649 ret = 1;
1650 goto out_free;
1651 }
1652
1653 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001654 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001655 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001656 msg_cerr("Read operation failed!\n");
1657 ret = 1;
1658 goto out_free;
1659 }
hailfinger42a850a2010-07-13 23:56:13 +00001660 }
1661
David Hendricksdf29a832013-06-28 14:33:51 -07001662 if (filename)
1663 ret = write_buf_to_file(buf, size, filename);
1664
hailfinger42a850a2010-07-13 23:56:13 +00001665out_free:
1666 free(buf);
Edward O'Callaghan6b2ff8a2020-12-11 14:33:23 +11001667 msg_cinfo("%s.\n", ret ? "FAILED" : "done");
hailfinger42a850a2010-07-13 23:56:13 +00001668 return ret;
1669}
1670
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001671/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001672static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001673{
hailfingerb91c08c2011-08-15 19:54:20 +00001674 int i, j, k;
1675 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001676
1677 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1678 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001679 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001680
1681 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1682 /* Blocks with zero size are bugs in flashchips.c. */
1683 if (eraser.eraseblocks[i].count &&
1684 !eraser.eraseblocks[i].size) {
1685 msg_gerr("ERROR: Flash chip %s erase function "
1686 "%i region %i has size 0. Please report"
1687 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001688 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001689 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001690 }
1691 /* Blocks with zero count are bugs in flashchips.c. */
1692 if (!eraser.eraseblocks[i].count &&
1693 eraser.eraseblocks[i].size) {
1694 msg_gerr("ERROR: Flash chip %s erase function "
1695 "%i region %i has count 0. Please report"
1696 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001697 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001698 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001699 }
1700 done += eraser.eraseblocks[i].count *
1701 eraser.eraseblocks[i].size;
1702 }
hailfinger9fed35d2010-01-19 06:42:46 +00001703 /* Empty eraseblock definition with erase function. */
1704 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001705 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001706 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001707 if (!done)
1708 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001709 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001710 msg_gerr("ERROR: Flash chip %s erase function %i "
1711 "region walking resulted in 0x%06x bytes total,"
1712 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001713 " flashrom@flashrom.org\n", chip->name, k,
1714 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001715 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001716 }
hailfinger9fed35d2010-01-19 06:42:46 +00001717 if (!eraser.block_erase)
1718 continue;
1719 /* Check if there are identical erase functions for different
1720 * layouts. That would imply "magic" erase functions. The
1721 * easiest way to check this is with function pointers.
1722 */
uwef6f94d42010-03-13 17:28:29 +00001723 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001724 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001725 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001726 msg_gerr("ERROR: Flash chip %s erase function "
1727 "%i and %i are identical. Please report"
1728 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001729 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001730 ret = 1;
1731 }
uwef6f94d42010-03-13 17:28:29 +00001732 }
hailfinger45177872010-01-18 08:14:43 +00001733 }
hailfinger9fed35d2010-01-19 06:42:46 +00001734 return ret;
hailfinger45177872010-01-18 08:14:43 +00001735}
1736
Edward O'Callaghanbef74c22020-12-04 16:23:54 +11001737static int check_block_eraser(const struct flashctx *flash, int k, int log)
1738{
1739 struct block_eraser eraser = flash->chip->block_erasers[k];
1740
1741 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1742 if (log)
1743 msg_cdbg("not defined. ");
1744 return 1;
1745 }
1746 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1747 if (log)
1748 msg_cdbg("eraseblock layout is known, but matching "
1749 "block erase function is not implemented. ");
1750 return 1;
1751 }
1752 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1753 if (log)
1754 msg_cdbg("block erase function found, but "
1755 "eraseblock layout is not defined. ");
1756 return 1;
1757 }
1758 // TODO: Once erase functions are annotated with allowed buses, check that as well.
1759 return 0;
1760}
1761
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001762typedef int (*erasefn_t)(struct flashctx *, unsigned int addr, unsigned int len);
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001763/**
1764 * @private
1765 *
1766 * For read-erase-write, `curcontents` and `newcontents` shall point
1767 * to buffers of the chip's size. Both are supposed to be prefilled
1768 * with at least the included layout regions of the current flash
1769 * contents (`curcontents`) and the data to be written to the flash
1770 * (`newcontents`).
1771 *
1772 * For erase, `curcontents` and `newcontents` shall be NULL-pointers.
1773 *
1774 * The `chipoff_t` values are used internally by `walk_by_layout()`.
1775 */
1776struct walk_info {
1777 uint8_t *curcontents;
1778 const uint8_t *newcontents;
1779 chipoff_t erase_start;
1780 chipoff_t erase_len;
1781};
Edward O'Callaghan5e9e5712020-12-10 11:11:56 +11001782typedef int (*per_blockfn_t)(struct flashctx *, struct walk_info *const, erasefn_t);
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001783
Edward O'Callaghanecc0b202020-12-10 11:35:11 +11001784/*
1785 * Function to process processing units accumulated in the action descriptor.
1786 *
1787 * @flash pointer to the flash context to operate on
1788 * @per_blockfn helper function which can erase and program a section of the
1789 * flash chip. It receives the flash context, offset and length
1790 * of the area to erase/program, before and after contents (to
1791 * decide what exactly needs to be erased and or programmed)
1792 * and a pointer to the erase function which can operate on the
1793 * proper granularity.
1794 * @descriptor action descriptor including pointers to before and after
1795 * contents and an array of processing actions to take.
1796 *
1797 * Returns zero on success or an error code.
1798 */
1799static int walk_eraseregions(struct flashctx *flash,
1800 const per_blockfn_t per_blockfn,
1801 struct action_descriptor *descriptor)
1802{
1803 struct processing_unit *pu;
1804 int rc = 0;
1805 static int print_comma;
1806
1807 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1808 unsigned base = pu->offset;
1809 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
Edward O'Callaghan17361062020-12-12 17:31:59 +11001810 struct block_eraser *const eraser = &flash->chip->block_erasers[pu->block_eraser_index];
Edward O'Callaghanecc0b202020-12-10 11:35:11 +11001811
1812 while (base < top) {
1813
1814 if (print_comma)
1815 msg_cdbg(", ");
1816 else
1817 print_comma = 1;
1818
1819 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1820
1821 struct walk_info info = {
1822 .curcontents = descriptor->oldcontents,
1823 .newcontents = descriptor->newcontents,
1824 .erase_start = base,
1825 .erase_len = pu->block_size,
1826 };
Edward O'Callaghan17361062020-12-12 17:31:59 +11001827 rc = per_blockfn(flash, &info, eraser->block_erase);
Edward O'Callaghanecc0b202020-12-10 11:35:11 +11001828
1829 if (rc) {
1830 if (ignore_error(rc))
1831 rc = 0;
1832 else
1833 return rc;
1834 }
1835 base += pu->block_size;
1836 }
1837 }
1838 msg_cdbg("\n");
1839 return rc;
1840}
1841
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001842static int erase_and_write_block_helper(struct flashctx *flash,
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001843 struct walk_info *const info,
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001844 erasefn_t erasefn)
hailfingerb437e282010-11-04 01:04:27 +00001845{
stefanctc5eb8a92011-11-23 09:13:48 +00001846 unsigned int starthere = 0, lenhere = 0;
Edward O'Callaghan307d1692020-12-12 00:18:22 +11001847 int ret = 0, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001848 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001849 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001850
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001851 /*
1852 * curcontents and newcontents are opaque to walk_eraseregions, and
1853 * need to be adjusted here to keep the impression of proper
1854 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001855 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001856
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001857 info->curcontents += info->erase_start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001858
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001859 info->newcontents += info->erase_start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001860
Edward O'Callaghan307d1692020-12-12 00:18:22 +11001861 bool skipped = true;
hailfingerb437e282010-11-04 01:04:27 +00001862 msg_cdbg(":");
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001863 if (need_erase(info->curcontents, info->newcontents, info->erase_len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001864 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001865 msg_cdbg(" E");
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001866 ret = erasefn(flash, info->erase_start, info->erase_len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001867 if (ret) {
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +11001868 if (ret == SPI_ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001869 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001870 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001871 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001872 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001873 }
1874
David Hendricks0954ffc2015-11-13 15:15:44 -08001875 if (programmer_table[programmer].paranoid) {
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001876 if (check_erased_range(flash, info->erase_start, info->erase_len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001877 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001878 return -1;
1879 }
hailfingerac8e3182011-06-26 17:04:16 +00001880 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001881
hailfinger90fcf9b2010-11-05 14:51:59 +00001882 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001883 memset(info->curcontents, ERASED_VALUE(flash), info->erase_len);
Edward O'Callaghan307d1692020-12-12 00:18:22 +11001884 skipped = false;
David Hendricks048b38c2016-03-28 18:47:06 -07001885 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001886 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001887 /* get_next_write() sets starthere to a new value after the call. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001888 while ((lenhere = get_next_write(info->curcontents + starthere,
1889 info->newcontents + starthere,
1890 info->erase_len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001891 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001892 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001893 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001894 /* Needs the partial write function signature. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001895 ret = write_flash(flash, (uint8_t *)info->newcontents + starthere,
1896 info->erase_start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001897 if (ret) {
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +11001898 if (ret == SPI_ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001899 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001900 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001901 }
David Hendricks048b38c2016-03-28 18:47:06 -07001902
1903 /*
1904 * If the block needed to be erased and was erased successfully
1905 * then we can assume that we didn't run into any write-
1906 * protected areas. Otherwise, we need to verify each page to
1907 * ensure it was successfully written and abort if we encounter
1908 * any errors.
1909 */
1910 if (programmer_table[programmer].paranoid && !block_was_erased) {
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001911 if (verify_range(flash, info->newcontents + starthere,
1912 info->erase_start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001913 return -1;
1914 }
1915
hailfingerb437e282010-11-04 01:04:27 +00001916 starthere += lenhere;
Edward O'Callaghan307d1692020-12-12 00:18:22 +11001917 skipped = false;
hailfingerb437e282010-11-04 01:04:27 +00001918 }
Edward O'Callaghan307d1692020-12-12 00:18:22 +11001919 if (skipped)
1920 msg_cdbg("S");
hailfingerb437e282010-11-04 01:04:27 +00001921 return ret;
1922}
1923
Edward O'Callaghanaccf9ff2021-01-22 01:33:03 +11001924static int erase_and_write_flash(struct flashctx *flash,
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001925 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00001926{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001927 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00001928
hailfingercf848f12010-12-05 15:14:44 +00001929 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00001930
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001931 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00001932
hailfinger7df21362009-09-05 02:30:58 +00001933 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00001934 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00001935 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07001936 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00001937 }
1938 return ret;
hailfingerd219a232009-01-28 00:27:54 +00001939}
1940
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11001941static int verify_flash(struct flashctx *flash,
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11001942 struct action_descriptor *descriptor)
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11001943{
1944 int ret;
1945 unsigned int total_size = flash->chip->total_size * 1024;
1946 uint8_t *buf = descriptor->newcontents;
1947
1948 msg_cinfo("Verifying flash... ");
1949
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11001950 const bool verify_all = flash->flags.verify_whole_chip;
1951 if (!verify_all) {
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11001952 struct processing_unit *pu = descriptor->processing_units;
1953
1954 /* Verify only areas which were written. */
1955 while (pu->num_blocks) {
1956 ret = verify_range(flash, buf + pu->offset, pu->offset,
1957 pu->block_size * pu->num_blocks);
1958 if (ret)
1959 break;
1960 pu++;
1961 }
1962 } else {
1963 ret = verify_range(flash, buf, 0, total_size);
1964 }
1965
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +11001966 if (ret == SPI_ACCESS_DENIED) {
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11001967 msg_gdbg("Could not fully verify due to access error, ");
1968 if (access_denied_action == error_ignore) {
1969 msg_gdbg("ignoring\n");
1970 ret = 0;
1971 } else {
1972 msg_gdbg("aborting\n");
1973 }
1974 }
1975
1976 if (!ret)
1977 msg_cinfo("VERIFIED. \n");
1978
1979 return ret;
1980}
1981
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001982static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00001983{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001984 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
1985#if CONFIG_INTERNAL == 1
1986 if (programmer == PROGRAMMER_INTERNAL)
1987 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
1988 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1989 "mail flashrom@flashrom.org, thanks!\n"
1990 "-------------------------------------------------------------------------------\n"
1991 "You may now reboot or simply leave the machine running.\n");
1992 else
1993#endif
1994 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
1995 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
1996 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1997 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00001998}
1999
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002000static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002001{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002002 msg_gerr("Your flash chip is in an unknown state.\n");
2003#if CONFIG_INTERNAL == 1
2004 if (programmer == PROGRAMMER_INTERNAL)
2005 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2006 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2007 "-------------------------------------------------------------------------------\n"
2008 "DO NOT REBOOT OR POWEROFF!\n");
2009 else
2010#endif
2011 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2012 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002013}
2014
hailfingerf79d1712010-10-06 23:48:34 +00002015void list_programmers_linebreak(int startcol, int cols, int paren)
2016{
2017 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002018 int pnamelen;
2019 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002020 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002021 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002022
2023 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2024 pname = programmer_table[p].name;
2025 pnamelen = strlen(pname);
2026 if (remaining - pnamelen - 2 < 0) {
2027 if (firstline)
2028 firstline = 0;
2029 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002030 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002031 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002032 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002033 remaining = cols - startcol;
2034 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002035 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002036 remaining--;
2037 }
2038 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002039 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002040 remaining--;
2041 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002042 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002043 remaining -= pnamelen;
2044 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002045 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002046 remaining--;
2047 } else {
2048 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002049 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002050 }
2051 }
2052}
2053
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002054static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002055{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002056#if IS_WINDOWS
2057 SYSTEM_INFO si;
2058 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002059
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002060 memset(&si, 0, sizeof(SYSTEM_INFO));
2061 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2062 msg_ginfo(" on Windows");
2063 /* Tell Windows which version of the structure we want. */
2064 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2065 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2066 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2067 else
2068 msg_ginfo(" unknown version");
2069 GetSystemInfo(&si);
2070 switch (si.wProcessorArchitecture) {
2071 case PROCESSOR_ARCHITECTURE_AMD64:
2072 msg_ginfo(" (x86_64)");
2073 break;
2074 case PROCESSOR_ARCHITECTURE_INTEL:
2075 msg_ginfo(" (x86)");
2076 break;
2077 default:
2078 msg_ginfo(" (unknown arch)");
2079 break;
2080 }
2081#elif HAVE_UTSNAME == 1
2082 struct utsname osinfo;
2083
2084 uname(&osinfo);
2085 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002086 osinfo.machine);
2087#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002088 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002089#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002090}
2091
2092void print_buildinfo(void)
2093{
2094 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002095#if NEED_PCI == 1
2096#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002097 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002098#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002099 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002100#endif
2101#endif
2102#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002103 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002104#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002105 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002106#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002107 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002108#endif
hailfinger3b471632010-03-27 16:36:40 +00002109#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002110 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002111#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002112 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002113#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002114 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002115#endif
2116#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002117 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002118#endif
2119#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002120 msg_gdbg(" little endian");
Edward O'Callaghan3c005942020-10-01 16:33:47 +10002121#elif defined (__FLASHROM_BIG_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002122 msg_gdbg(" big endian");
Edward O'Callaghan3c005942020-10-01 16:33:47 +10002123#else
2124#error Endianness could not be determined
hailfinger3b471632010-03-27 16:36:40 +00002125#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002126 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002127}
2128
uwefdeca092008-01-21 15:24:22 +00002129void print_version(void)
2130{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002131 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002132 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002133 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002134}
2135
hailfinger74819ad2010-05-15 15:04:37 +00002136void print_banner(void)
2137{
2138 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002139 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002140 msg_ginfo("\n");
2141}
2142
hailfingerc77acb52009-12-24 02:15:55 +00002143int selfcheck(void)
2144{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002145 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002146 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002147
2148 /* Safety check. Instead of aborting after the first error, check
2149 * if more errors exist.
2150 */
hailfingerc77acb52009-12-24 02:15:55 +00002151 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002152 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002153 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002154 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002155 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2156 const struct programmer_entry p = programmer_table[i];
2157 if (p.name == NULL) {
2158 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2159 ret = 1;
2160 /* This might hide other problems with this programmer, but allows for better error
2161 * messages below without jumping through hoops. */
2162 continue;
2163 }
2164 switch (p.type) {
2165 case USB:
2166 case PCI:
2167 case OTHER:
2168 if (p.devs.note == NULL) {
2169 if (strcmp("internal", p.name) == 0)
2170 break; /* This one has its device list stored separately. */
2171 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2172 p.name);
2173 ret = 1;
2174 }
2175 break;
2176 default:
2177 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2178 ret = 1;
2179 break;
2180 }
2181 if (p.init == NULL) {
2182 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2183 ret = 1;
2184 }
2185 if (p.delay == NULL) {
2186 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2187 ret = 1;
2188 }
2189 if (p.map_flash_region == NULL) {
2190 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2191 ret = 1;
2192 }
2193 if (p.unmap_flash_region == NULL) {
2194 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2195 ret = 1;
2196 }
2197 }
2198
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002199 /* It would be favorable if we could check for the correct layout (especially termination) of various
2200 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2201 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2202 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2203 * 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 +10002204 * checks below. */
2205 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002206 msg_gerr("Flashchips table miscompilation!\n");
2207 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002208 } else {
2209 for (i = 0; i < flashchips_size - 1; i++) {
2210 const struct flashchip *chip = &flashchips[i];
2211 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2212 ret = 1;
2213 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2214 "Please report a bug at flashrom@flashrom.org\n", i,
2215 chip->name == NULL ? "unnamed" : chip->name);
2216 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002217 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002218 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002219 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002220 }
stefanct6d836ba2011-05-26 01:35:19 +00002221 }
stefanct6d836ba2011-05-26 01:35:19 +00002222
Edward O'Callaghane6b85692020-12-18 11:01:55 +11002223#if CONFIG_INTERNAL == 1
2224 ret |= selfcheck_board_enables();
2225#endif
2226
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002227 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002228 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002229}
2230
hailfinger771fc182010-10-15 00:01:14 +00002231/* FIXME: This function signature needs to be improved once doit() has a better
2232 * function signature.
2233 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002234static int chip_safety_check(const struct flashctx *flash, int force,
2235 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002236{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002237 const struct flashchip *chip = flash->chip;
2238
hailfinger771fc182010-10-15 00:01:14 +00002239 if (!programmer_may_write && (write_it || erase_it)) {
2240 msg_perr("Write/erase is not working yet on your programmer in "
2241 "its current configuration.\n");
2242 /* --force is the wrong approach, but it's the best we can do
2243 * until the generic programmer parameter parser is merged.
2244 */
2245 if (!force)
2246 return 1;
2247 msg_cerr("Continuing anyway.\n");
2248 }
2249
2250 if (read_it || erase_it || write_it || verify_it) {
2251 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002252 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002253 msg_cerr("Read is not working on this chip. ");
2254 if (!force)
2255 return 1;
2256 msg_cerr("Continuing anyway.\n");
2257 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002258 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002259 msg_cerr("flashrom has no read function for this "
2260 "flash chip.\n");
2261 return 1;
2262 }
2263 }
2264 if (erase_it || write_it) {
2265 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002266 if (chip->tested.erase == NA) {
2267 msg_cerr("Erase is not possible on this chip.\n");
2268 return 1;
2269 }
2270 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002271 msg_cerr("Erase is not working on this chip. ");
2272 if (!force)
2273 return 1;
2274 msg_cerr("Continuing anyway.\n");
2275 }
stefancte1c5acf2011-07-04 07:27:17 +00002276 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002277 msg_cerr("flashrom has no erase function for this "
2278 "flash chip.\n");
2279 return 1;
2280 }
hailfinger771fc182010-10-15 00:01:14 +00002281 }
2282 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002283 if (chip->tested.write == NA) {
2284 msg_cerr("Write is not possible on this chip.\n");
2285 return 1;
2286 }
2287 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002288 msg_cerr("Write is not working on this chip. ");
2289 if (!force)
2290 return 1;
2291 msg_cerr("Continuing anyway.\n");
2292 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002293 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002294 msg_cerr("flashrom has no write function for this "
2295 "flash chip.\n");
2296 return 1;
2297 }
2298 }
2299 return 0;
2300}
2301
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002302int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002303 const bool read_it, const bool write_it,
2304 const bool erase_it, const bool verify_it)
2305{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002306 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002307 msg_cerr("Aborting.\n");
2308 return 1;
2309 }
2310
2311 if (normalize_romentries(flash)) {
2312 msg_cerr("Requested regions can not be handled. Aborting.\n");
2313 return 1;
2314 }
2315
Edward O'Callaghan40092972020-10-20 11:50:48 +11002316 /*
2317 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2318 * can be repro'ed with upstream on Volteer.
2319 *
2320 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2321 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2322 * hooked and this can fail on some board topologies. Checking the return value can
2323 * cause board rw failures by bailing early. Avoid the early bail for now until a
2324 * full investigation can reveal the proper fix. This restores previous behaviour of
2325 * assuming a map went fine.
2326 */
2327#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002328 if (map_flash(flash) != 0)
2329 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002330#endif
2331 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002332
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002333 /* Given the existence of read locks, we want to unlock for read,
2334 erase and write. */
2335 if (flash->chip->unlock)
2336 flash->chip->unlock(flash);
2337
2338 flash->address_high_byte = -1;
2339 flash->in_4ba_mode = false;
Nikolai Artemiev55f7a332020-11-05 13:54:27 +11002340 flash->chip_restore_fn_count = 0;
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002341
Edward O'Callaghan99974452020-10-13 13:28:33 +11002342 /* Be careful about 4BA chips and broken masters */
2343 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2344 /* If we can't use native instructions, bail out */
2345 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2346 || !spi_master_4ba(flash)) {
2347 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2348 return 1;
2349 }
2350 }
2351
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002352 return 0;
2353}
2354
Edward O'Callaghana820b212020-09-17 22:53:26 +10002355void finalize_flash_access(struct flashctx *const flash)
2356{
Nikolai Artemiev55f7a332020-11-05 13:54:27 +11002357 deregister_chip_restore(flash);
Edward O'Callaghana820b212020-09-17 22:53:26 +10002358 unmap_flash(flash);
2359}
2360
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002361/**
2362 * @addtogroup flashrom-flash
2363 * @{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002364 */
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002365
2366/**
2367 * @brief Erase the specified ROM chip.
2368 *
2369 * If a layout is set in the given flash context, only included regions
2370 * will be erased.
2371 *
2372 * @param flashctx The context of the flash chip to erase.
2373 * @return 0 on success.
2374 */
2375static int flashrom_flash_erase(struct flashctx *const flashctx,
2376 void *oldcontents, void *newcontents, size_t size)
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002377{
2378 /*
2379 * To make sure that the chip is fully erased, let's cheat and create
2380 * a descriptor where the new contents are all erased.
2381 */
2382 struct action_descriptor *fake_descriptor;
2383 int ret = 0;
2384
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002385 fake_descriptor = prepare_action_descriptor(flashctx, oldcontents,
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002386 newcontents, 1);
2387 /* FIXME: Do we really want the scary warning if erase failed? After
2388 * all, after erase the chip is either blank or partially blank or it
2389 * has the old contents. A blank chip won't boot, so if the user
2390 * wanted erase and reboots afterwards, the user knows very well that
2391 * booting won't work.
2392 */
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002393 if (erase_and_write_flash(flashctx, fake_descriptor)) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002394 emergency_help_message();
2395 ret = 1;
2396 }
2397
2398 free(fake_descriptor);
2399
2400 return ret;
2401}
2402
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002403/** @} */ /* end flashrom-flash */
2404
Edward O'Callaghan8c2a3402020-12-09 12:23:01 +11002405/**
2406 * @defgroup flashrom-ops Operations
2407 * @{
2408 */
2409
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002410
Edward O'Callaghan84c89182020-12-09 12:33:37 +11002411/**
2412 * @brief Read the current image from the specified ROM chip.
2413 *
2414 * If a layout is set in the specified flash context, only included regions
2415 * will be read.
2416 *
2417 * @param flashctx The context of the flash chip.
2418 * @param buffer Target buffer to write image to.
2419 * @param buffer_len Size of target buffer in bytes.
2420 * @return 0 on success,
2421 * 2 if buffer_len is too short for the flash chip's contents,
2422 * or 1 on any other failure.
2423 */
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002424int flashrom_image_read(struct flashctx *const flashctx,
Edward O'Callaghan84c89182020-12-09 12:33:37 +11002425 void *const buffer, const size_t buffer_len)
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002426{
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002427 const bool verify_all = flashctx->flags.verify_whole_chip;
2428 const bool verify = flashctx->flags.verify_after_write;
2429
2430 if ((!verify || !verify_all) && get_num_include_args(get_global_layout())) {
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002431 /*
2432 * If no full verification is required and not
2433 * the entire chip is about to be programmed,
2434 * read only the areas which might change.
2435 */
Edward O'Callaghan84c89182020-12-09 12:33:37 +11002436 if (handle_partial_read(flashctx, buffer, read_flash, 0) < 0)
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002437 return 1;
2438 } else {
Edward O'Callaghan84c89182020-12-09 12:33:37 +11002439 if (read_flash(flashctx, buffer, 0, buffer_len))
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002440 return 1;
2441 }
2442 return 0;
2443}
2444
hailfingerc77acb52009-12-24 02:15:55 +00002445/* This function signature is horrible. We need to design a better interface,
2446 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002447 * Besides that, the function itself is a textbook example of abysmal code flow.
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002448 *
2449 *
2450 * The main processing function of flashrom utility; it is invoked once
2451 * command line parameters are processed and verified, and the type of the
2452 * flash chip the programmer operates on has been determined.
2453 *
2454 * @flash pointer to the flash context matching the chip detected
2455 * during initialization.
2456 * @force when set proceed even if the chip is not known to work
2457 * @filename pointer to the name of the file to read from or write to
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002458 * @write_it when true, flash is programmed with 'filename' contents
2459 * @erase_it when true, flash chip is erased
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002460 * @extract_it extract all known flash chip regions into separate files
2461 * @diff_file when deciding what areas to program, use this file's
2462 * contents instead of reading the current chip contents
2463 * @do_diff when true - compare result of the operation with either the
2464 * original chip contents for 'diff_file' contents, is present.
2465 * When false - do not diff, consider the chip erased before
2466 * operation starts.
2467 *
2468 * Only one of 'read_it', 'write_it', and 'erase_it' is expected to be set,
2469 * but this is not enforced.
2470 *
2471 * 'do_diff' must be set if 'diff_file' is set. If 'do_diff' is set, but
2472 * 'diff_file' is not - comparison is done against the pre-operation chip
2473 * contents.
hailfingerc77acb52009-12-24 02:15:55 +00002474 */
Edward O'Callaghan11e1c552021-01-27 15:59:57 +11002475static int doit(struct flashctx *flash, const char *filename,
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002476 int write_it, int erase_it, const char *diff_file)
hailfingerc77acb52009-12-24 02:15:55 +00002477{
hailfinger4c47e9d2010-10-19 22:06:20 +00002478 uint8_t *oldcontents;
2479 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002480 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002481 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002482 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002483
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002484 const bool verify_all = flash->flags.verify_whole_chip;
2485 const bool verify = flash->flags.verify_after_write;
2486
stefanctd611e8f2011-07-12 22:35:21 +00002487 oldcontents = malloc(size);
2488 if (!oldcontents) {
2489 msg_gerr("Out of memory!\n");
2490 exit(1);
2491 }
Simon Glass4c214132013-07-16 10:09:28 -06002492 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002493 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002494 newcontents = malloc(size);
2495 if (!newcontents) {
2496 msg_gerr("Out of memory!\n");
2497 exit(1);
2498 }
Simon Glass4c214132013-07-16 10:09:28 -06002499 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002500 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002501 /* Side effect of the assumptions above: Default write action is erase
2502 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002503 * oldcontents being completely unerased means we have to erase
2504 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002505 */
2506
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002507 if ((write_it || verify) && !erase_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002508 /*
2509 * Note: This must be done before any files specified by -i
2510 * arguments are processed merged into the newcontents since
2511 * -i files take priority. See http://crbug.com/263495.
2512 */
2513 if (filename) {
2514 if (read_buf_from_file(newcontents, size, filename)) {
2515 ret = 1;
2516 goto out;
2517 }
2518 } else {
2519 /* Content will be read from -i args, so they must
2520 * not overlap. */
2521 if (included_regions_overlap()) {
2522 msg_gerr("Error: Included regions must "
2523 "not overlap.\n");
2524 ret = 1;
2525 goto out;
2526 }
stepan1da96c02006-11-21 23:48:51 +00002527 }
ollie5672ac62004-03-17 22:22:08 +00002528 }
2529
Edward O'Callaghane8118582020-12-03 12:45:59 +11002530 if (flash->flags.do_diff) {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002531 /*
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 */
2537 if (diff_file) {
2538 msg_cdbg("Reading old contents from file... ");
2539 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002540 ret = 1;
2541 msg_cdbg("FAILED.\n");
2542 goto out;
2543 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002544 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002545 msg_cdbg("Reading old contents from flash chip... ");
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002546 ret = flashrom_image_read(flash, oldcontents, size);
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002547 if (ret) {
2548 msg_cdbg("FAILED.\n");
2549 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002550 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002551 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002552 msg_cdbg("done.\n");
2553 } else if (!erase_it) {
2554 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002555 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002556 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002557
David Hendricksdf29a832013-06-28 14:33:51 -07002558 /*
2559 * Note: This must be done after reading the file specified for the
2560 * -w/-v argument, if any, so that files specified using -i end up
2561 * in the "newcontents" buffer before being written.
2562 * See http://crbug.com/263495.
2563 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002564 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002565 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002566 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002567 goto out;
2568 }
uwef6641642007-05-09 10:17:44 +00002569
David Hendricksa7e114b2016-02-26 18:49:15 -08002570 if (erase_it) {
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002571 flashrom_flash_erase(flash, oldcontents, newcontents, size);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002572 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002573 }
2574
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002575 descriptor = prepare_action_descriptor(flash, oldcontents,
Edward O'Callaghane8118582020-12-03 12:45:59 +11002576 newcontents, flash->flags.do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002577 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002578 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002579 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002580 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002581 goto out;
2582 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002583
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002584 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002585 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2586 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002587 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002588 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002589 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002590 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002591 ret = 1;
2592 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002593 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002594 msg_cerr("Apparently at least some data has changed.\n");
2595 } else
2596 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002597 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002598 ret = 1;
2599 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002600 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002601
David Hendricksac1d25c2016-08-09 17:00:58 -07002602 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002603 if (ret < 0) {
2604 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002605 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002606 emergency_help_message();
2607 ret = 1;
2608 goto out;
2609 } else if (ret > 0) {
2610 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002611 msg_pdbg("CROS_EC needs 2nd pass.\n");
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002612 ret = flashrom_image_read(flash, oldcontents, size);
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002613 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002614 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002615 goto out;
2616 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002617
2618 /* Get a new descriptor. */
2619 free(descriptor);
2620 descriptor = prepare_action_descriptor(flash,
2621 oldcontents,
2622 newcontents,
Edward O'Callaghane8118582020-12-03 12:45:59 +11002623 flash->flags.do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002624 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002625 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002626 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002627 emergency_help_message();
2628 ret = 1;
2629 goto out;
2630 }
2631 ret = 0;
2632 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002633
David Hendricksac1d25c2016-08-09 17:00:58 -07002634 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002635 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002636 emergency_help_message();
2637 ret = 1;
2638 goto out;
2639 }
stuge8ce3a3c2008-04-28 14:47:30 +00002640 }
ollie6a600992005-11-26 21:55:36 +00002641
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002642 verify:
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002643 if (verify && !erase_it) {
2644 if (write_it && !content_has_changed) {
2645 msg_gdbg("Nothing was written, skipping verification\n");
David Hendricks9ba79fb2015-04-03 12:06:16 -07002646 } else {
2647 /* Work around chips which need some time to calm down. */
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002648 if (write_it && verify_all)
David Hendricks9ba79fb2015-04-03 12:06:16 -07002649 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002650
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002651 ret = verify_flash(flash, descriptor);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002652
David Hendricks9ba79fb2015-04-03 12:06:16 -07002653 /* If we tried to write, and verification now fails, we
2654 * might have an emergency situation.
2655 */
2656 if (ret && write_it)
2657 emergency_help_message();
2658 }
hailfinger0459e1c2009-08-19 13:55:34 +00002659 }
ollie6a600992005-11-26 21:55:36 +00002660
hailfinger90fcf9b2010-11-05 14:51:59 +00002661out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002662 if (descriptor)
2663 free(descriptor);
2664
hailfinger90fcf9b2010-11-05 14:51:59 +00002665 free(oldcontents);
2666 free(newcontents);
David Hendricks668f29d2011-01-27 18:51:45 -08002667 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002668 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002669 * tree. This is because some operations, such as write protection,
2670 * requires programmer_shutdown() but does not call doit().
2671 */
2672// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002673 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002674}
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002675
2676/** @} */ /* end flashrom-ops */
2677
2678int do_read(struct flashctx *const flash, const char *const filename)
2679{
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002680 if (prepare_flash_access(flash, true, false, false, false))
2681 return 1;
2682
Edward O'Callaghan471958e2020-12-09 12:40:12 +11002683 const int ret = read_flash_to_file(flash, filename);
2684
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002685 finalize_flash_access(flash);
2686
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002687 return ret;
2688}
2689
Edward O'Callaghan6e573be2020-12-18 10:38:06 +11002690int do_erase(struct flashctx *const flash)
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002691{
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002692 if (prepare_flash_access(flash, false, false, true, false))
2693 return 1;
2694
Edward O'Callaghan11e1c552021-01-27 15:59:57 +11002695 int ret = doit(flash, NULL, false, true, flash->diff_file);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002696
2697 /*
2698 * FIXME: Do we really want the scary warning if erase failed?
2699 * After all, after erase the chip is either blank or partially
2700 * blank or it has the old contents. A blank chip won't boot,
2701 * so if the user wanted erase and reboots afterwards, the user
2702 * knows very well that booting won't work.
2703 */
2704 if (ret)
2705 emergency_help_message();
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002706 finalize_flash_access(flash);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002707
2708 return ret;
2709}
2710
Edward O'Callaghan6e573be2020-12-18 10:38:06 +11002711int do_write(struct flashctx *const flash, const char *const filename, const char *const referencefile)
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002712{
Sam McNally99c62982020-12-08 12:34:27 +11002713 if (prepare_flash_access(flash, false, true, false, flash->flags.verify_after_write))
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002714 return 1;
2715
Edward O'Callaghan11e1c552021-01-27 15:59:57 +11002716 int ret = doit(flash, filename, true, false, flash->diff_file);
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002717 finalize_flash_access(flash);
2718
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002719 return ret;
2720}
2721
Edward O'Callaghan6e573be2020-12-18 10:38:06 +11002722int do_verify(struct flashctx *const flash, const char *const filename)
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002723{
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002724 if (prepare_flash_access(flash, false, false, false, true))
2725 return 1;
2726
Edward O'Callaghan11e1c552021-01-27 15:59:57 +11002727 int ret = doit(flash, filename, false, false, flash->diff_file);
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002728 finalize_flash_access(flash);
2729
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002730 return ret;
2731}
2732
2733int do_extract_it(struct flashctx *const flash)
2734{
2735 if (prepare_flash_access(flash, false, false, false, false))
2736 return 1;
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002737 int ret = extract_regions(flash);
2738 finalize_flash_access(flash);
2739
2740 return ret;
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002741}