blob: 8d6f8d6017fcfa8bcdf0b662b81bddc3a7d403c1 [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);
Edward O'Callaghanea9e2452020-12-18 11:01:38 +1100758 msg_gspew("%s: mapping %s from 0x%0*" PRIxPTR " to 0x%0*" PRIxPTR "\n",
759 __func__, descr, PRIxPTR_WIDTH, phys_addr, PRIxPTR_WIDTH, (uintptr_t) ret);
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000760 return ret;
uweabe92a52009-05-16 22:36:00 +0000761}
762
763void programmer_unmap_flash_region(void *virt_addr, size_t len)
764{
765 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000766 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000767}
768
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700769void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000770{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100771 flash->mst->par.chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000772}
773
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700774void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000775{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100776 flash->mst->par.chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000777}
778
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700779void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000780{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100781 flash->mst->par.chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000782}
783
Stuart langleyc98e43f2020-03-26 20:27:36 +1100784void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000785{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100786 flash->mst->par.chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000787}
788
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700789uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000790{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100791 return flash->mst->par.chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000792}
793
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700794uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000795{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100796 return flash->mst->par.chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000797}
798
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700799uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000800{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100801 return flash->mst->par.chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000802}
803
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000804void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
805 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000806{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100807 flash->mst->par.chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000808}
809
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000810void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000811{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000812 if (usecs > 0)
813 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000814}
815
Edward O'Callaghana820b212020-09-17 22:53:26 +1000816int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
817 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000818{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700819 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000820
hailfinger23060112009-05-08 12:49:03 +0000821 return 0;
822}
823
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000824/* This is a somewhat hacked function similar in some ways to strtok().
825 * It will look for needle with a subsequent '=' in haystack, return a copy of
826 * needle and remove everything from the first occurrence of needle to the next
827 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000828 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000829char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000830{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000831 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000832 char *opt = NULL;
833 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000834 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000835
hailfingerf4aaccc2010-04-28 15:22:14 +0000836 needlelen = strlen(needle);
837 if (!needlelen) {
838 msg_gerr("%s: empty needle! Please report a bug at "
839 "flashrom@flashrom.org\n", __func__);
840 return NULL;
841 }
842 /* No programmer parameters given. */
843 if (*haystack == NULL)
844 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000845 param_pos = strstr(*haystack, needle);
846 do {
847 if (!param_pos)
848 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000849 /* Needle followed by '='? */
850 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000851 /* Beginning of the string? */
852 if (param_pos == *haystack)
853 break;
854 /* After a delimiter? */
855 if (strchr(delim, *(param_pos - 1)))
856 break;
857 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000858 /* Continue searching. */
859 param_pos++;
860 param_pos = strstr(param_pos, needle);
861 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000862
hailfinger6e5a52a2009-11-24 18:27:10 +0000863 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000864 /* Get the string after needle and '='. */
865 opt_pos = param_pos + needlelen + 1;
866 optlen = strcspn(opt_pos, delim);
867 /* Return an empty string if the parameter was empty. */
868 opt = malloc(optlen + 1);
869 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000870 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000871 exit(1);
872 }
hailfinger1ef766d2010-07-06 09:55:48 +0000873 strncpy(opt, opt_pos, optlen);
874 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000875 rest = opt_pos + optlen;
876 /* Skip all delimiters after the current parameter. */
877 rest += strspn(rest, delim);
878 memmove(param_pos, rest, strlen(rest) + 1);
879 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000880 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000881
hailfinger1ef766d2010-07-06 09:55:48 +0000882 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000883}
884
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000885char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000886{
887 return extract_param(&programmer_param, param_name, ",");
888}
889
stefancte1c5acf2011-07-04 07:27:17 +0000890/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700891static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000892{
893 unsigned int usable_erasefunctions = 0;
894 int k;
895 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
896 if (!check_block_eraser(flash, k, 0))
897 usable_erasefunctions++;
898 }
899 return usable_erasefunctions;
900}
901
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000902static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700903{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000904 int ret = 0, failcount = 0;
905 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700906 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000907 if (wantbuf[i] != havebuf[i]) {
908 /* Only print the first failure. */
909 if (!failcount++)
910 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
911 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700912 }
913 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000914 if (failcount) {
915 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
916 start, start + len - 1, failcount);
917 ret = -1;
918 }
919 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700920}
921
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000922/* start is an offset to the base address of the flash chip */
923static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
924{
925 int ret;
926 uint8_t *cmpbuf = malloc(len);
927 const uint8_t erased_value = ERASED_VALUE(flash);
928
929 if (!cmpbuf) {
930 msg_gerr("Could not allocate memory!\n");
931 exit(1);
932 }
933 memset(cmpbuf, erased_value, len);
934 ret = verify_range(flash, cmpbuf, start, len);
935 free(cmpbuf);
936 return ret;
937}
938
uwee15beb92010-08-08 17:01:18 +0000939/*
hailfinger7af3d192009-11-25 17:05:52 +0000940 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000941 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000942 * @start offset to the base address of the flash chip
943 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000944 * @return 0 for success, -1 for failure
945 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000946int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000947{
hailfinger7af83692009-06-15 17:23:36 +0000948 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000949 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000950
Patrick Georgif3fa2992017-02-02 16:24:44 +0100951 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000952 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000953 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000954 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000955
956 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000957 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000958 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000959 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000960 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000961 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000962
Patrick Georgif3fa2992017-02-02 16:24:44 +0100963 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000964 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000965 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100966 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000967 ret = -1;
968 goto out_free;
969 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700970 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700971 if (programmer_table[programmer].paranoid) {
972 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800973
Simon Glass4e305f42015-01-08 06:29:04 -0700974 /* limit chunksize in order to catch errors early */
975 for (i = 0, chunksize = 0; i < len; i += chunksize) {
976 int tmp;
Douglas Anderson81e58f12021-02-01 13:16:08 -0800977 int chk_acc = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -0800978
Douglas Anderson81e58f12021-02-01 13:16:08 -0800979 /*
980 * Let's work in chunks of at least 4096 bytes at a
981 * time to balance reacting fast but still avoiding the
982 * overhead of working at a smaller size if page_size is
983 * something like 256 bytes.
984 */
985 chunksize = max(flash->chip->page_size, 4096);
986 chunksize = min(chunksize, len - i);
987
988 /*
989 * If we don't have access to some part of this chunk
990 * then bring the size back down to page_size.
991 */
992 if (flash->chip->check_access) {
993 chk_acc = flash->chip->check_access(flash, start + i, chunksize, 0);
994 if (chk_acc) {
995 chunksize = min(chunksize, flash->chip->page_size);
996 chk_acc = flash->chip->check_access(flash, start + i, chunksize, 0);
997 }
998 }
999
Patrick Georgif3fa2992017-02-02 16:24:44 +01001000 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -07001001 if (tmp) {
1002 ret = tmp;
1003 if (ignore_error(tmp))
1004 continue;
1005 else
1006 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -08001007 }
Simon Glass4e305f42015-01-08 06:29:04 -07001008
Duncan Laurie25a4ca22019-04-25 12:08:52 -07001009 /*
1010 * Check write access permission and do not compare chunks
1011 * where flashrom does not have write access to the region.
1012 */
Douglas Anderson81e58f12021-02-01 13:16:08 -08001013 if (chk_acc && ignore_error(chk_acc))
1014 continue;
Duncan Laurie25a4ca22019-04-25 12:08:52 -07001015
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001016 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -07001017 if (failcount)
1018 break;
David Hendricks1ed1d352011-11-23 17:54:37 -08001019 }
Simon Glass4e305f42015-01-08 06:29:04 -07001020 } else {
1021 int tmp;
1022
1023 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +01001024 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -07001025 if (tmp && !ignore_error(tmp)) {
1026 ret = tmp;
1027 goto out_free;
1028 }
1029
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001030 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +00001031 }
1032
hailfinger5be6c0f2009-07-23 01:42:56 +00001033 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +00001034 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +00001035 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +00001036 ret = -1;
1037 }
hailfinger7af83692009-06-15 17:23:36 +00001038
1039out_free:
1040 free(readbuf);
1041 return ret;
1042}
1043
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001044/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1045static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001046 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001047{
1048 unsigned int i, j, limit;
1049 for (j = 0; j < len / gran; j++) {
1050 limit = min (gran, len - j * gran);
1051 /* Are 'have' and 'want' identical? */
1052 if (!memcmp(have + j * gran, want + j * gran, limit))
1053 continue;
1054 /* have needs to be in erased state. */
1055 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001056 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001057 return 1;
1058 }
1059 return 0;
1060}
1061
uwee15beb92010-08-08 17:01:18 +00001062/*
hailfingerb247c7a2010-03-08 00:42:32 +00001063 * Check if the buffer @have can be programmed to the content of @want without
1064 * erasing. This is only possible if all chunks of size @gran are either kept
1065 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001066 *
hailfingerb437e282010-11-04 01:04:27 +00001067 * Warning: This function assumes that @have and @want point to naturally
1068 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001069 *
1070 * @have buffer with current content
1071 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001072 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001073 * @gran write granularity (enum, not count)
1074 * @return 0 if no erase is needed, 1 otherwise
1075 */
Edward O'Callaghanaccf9ff2021-01-22 01:33:03 +11001076static int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001077 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001078{
hailfingerb91c08c2011-08-15 19:54:20 +00001079 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001080 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001081
hailfingerb247c7a2010-03-08 00:42:32 +00001082 switch (gran) {
1083 case write_gran_1bit:
1084 for (i = 0; i < len; i++)
1085 if ((have[i] & want[i]) != want[i]) {
1086 result = 1;
1087 break;
1088 }
1089 break;
1090 case write_gran_1byte:
1091 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001092 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001093 result = 1;
1094 break;
1095 }
1096 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001097 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001098 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001099 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001100 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001101 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001102 break;
1103 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001104 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001105 break;
1106 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001107 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001108 break;
1109 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001110 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001111 break;
1112 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001113 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001114 break;
1115 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001116 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001117 break;
1118 case write_gran_1byte_implicit_erase:
1119 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1120 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001121 break;
hailfingerb437e282010-11-04 01:04:27 +00001122 default:
1123 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1124 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001125 }
1126 return result;
1127}
1128
hailfingerb437e282010-11-04 01:04:27 +00001129/**
1130 * Check if the buffer @have needs to be programmed to get the content of @want.
1131 * If yes, return 1 and fill in first_start with the start address of the
1132 * write operation and first_len with the length of the first to-be-written
1133 * chunk. If not, return 0 and leave first_start and first_len undefined.
1134 *
1135 * Warning: This function assumes that @have and @want point to naturally
1136 * aligned regions.
1137 *
1138 * @have buffer with current content
1139 * @want buffer with desired content
1140 * @len length of the checked area
1141 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001142 * @first_start offset of the first byte which needs to be written (passed in
1143 * value is increased by the offset of the first needed write
1144 * relative to have/want or unchanged if no write is needed)
1145 * @return length of the first contiguous area which needs to be written
1146 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001147 *
1148 * FIXME: This function needs a parameter which tells it about coalescing
1149 * in relation to the max write length of the programmer and the max write
1150 * length of the chip.
1151 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001152static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001153 unsigned int *first_start,
1154 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001155{
stefanctc5eb8a92011-11-23 09:13:48 +00001156 int need_write = 0;
1157 unsigned int rel_start = 0, first_len = 0;
1158 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001159
hailfingerb437e282010-11-04 01:04:27 +00001160 switch (gran) {
1161 case write_gran_1bit:
1162 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001163 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001164 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001165 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001166 case write_gran_128bytes:
1167 stride = 128;
1168 break;
hailfingerb437e282010-11-04 01:04:27 +00001169 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001170 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001171 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001172 case write_gran_264bytes:
1173 stride = 264;
1174 break;
1175 case write_gran_512bytes:
1176 stride = 512;
1177 break;
1178 case write_gran_528bytes:
1179 stride = 528;
1180 break;
1181 case write_gran_1024bytes:
1182 stride = 1024;
1183 break;
1184 case write_gran_1056bytes:
1185 stride = 1056;
1186 break;
hailfingerb437e282010-11-04 01:04:27 +00001187 default:
1188 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1189 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001190 /* Claim that no write was needed. A write with unknown
1191 * granularity is too dangerous to try.
1192 */
1193 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001194 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001195 for (i = 0; i < len / stride; i++) {
1196 limit = min(stride, len - i * stride);
1197 /* Are 'have' and 'want' identical? */
1198 if (memcmp(have + i * stride, want + i * stride, limit)) {
1199 if (!need_write) {
1200 /* First location where have and want differ. */
1201 need_write = 1;
1202 rel_start = i * stride;
1203 }
1204 } else {
1205 if (need_write) {
1206 /* First location where have and want
1207 * do not differ anymore.
1208 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001209 break;
1210 }
1211 }
1212 }
hailfingerffb7f382010-12-06 13:05:44 +00001213 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001214 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001215 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001216 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001217}
1218
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001219/* Returns the number of busses commonly supported by the current programmer and flash chip where the latter
1220 * can not be completely accessed due to size/address limits of the programmer. */
1221unsigned int count_max_decode_exceedings(const struct flashctx *flash)
hailfingeraec9c962009-10-31 01:53:09 +00001222{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001223 unsigned int limitexceeded = 0;
1224 uint32_t size = flash->chip->total_size * 1024;
1225 enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
uwe8d342eb2011-07-28 08:13:25 +00001226
1227 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001228 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001229 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001230 "size %u kB of chipset/board/programmer "
1231 "for %s interface, "
1232 "probe/read/erase/write may fail. ", size / 1024,
1233 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001234 }
hailfingere1e41ea2011-07-27 07:13:06 +00001235 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001236 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001237 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001238 "size %u kB of chipset/board/programmer "
1239 "for %s interface, "
1240 "probe/read/erase/write may fail. ", size / 1024,
1241 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001242 }
hailfingere1e41ea2011-07-27 07:13:06 +00001243 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001244 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001245 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001246 "size %u kB of chipset/board/programmer "
1247 "for %s interface, "
1248 "probe/read/erase/write may fail. ", size / 1024,
1249 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001250 }
hailfingere1e41ea2011-07-27 07:13:06 +00001251 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001252 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001253 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001254 "size %u kB of chipset/board/programmer "
1255 "for %s interface, "
1256 "probe/read/erase/write may fail. ", size / 1024,
1257 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001258 }
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001259 return limitexceeded;
hailfingeraec9c962009-10-31 01:53:09 +00001260}
1261
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001262void unmap_flash(struct flashctx *flash)
1263{
1264 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1265 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1266 flash->physical_registers = 0;
1267 flash->virtual_registers = (chipaddr)ERROR_PTR;
1268 }
1269
1270 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1271 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1272 flash->physical_memory = 0;
1273 flash->virtual_memory = (chipaddr)ERROR_PTR;
1274 }
1275}
1276
1277int map_flash(struct flashctx *flash)
1278{
1279 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1280 flash->virtual_memory = (chipaddr)ERROR_PTR;
1281 flash->virtual_registers = (chipaddr)ERROR_PTR;
1282
1283 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1284 * These are used for various probing-related hacks that would not map successfully anyway and should be
1285 * removed ASAP. */
1286 if (flash->chip->total_size == 0)
1287 return 0;
1288
1289 const chipsize_t size = flash->chip->total_size * 1024;
1290 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1291 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1292 if (addr == ERROR_PTR) {
1293 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1294 flash->chip->name, PRIxPTR_WIDTH, base);
1295 return 1;
1296 }
1297 flash->physical_memory = base;
1298 flash->virtual_memory = (chipaddr)addr;
1299
1300 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1301 * completely different on some chips and programmers, or not mappable at all.
1302 * Ignore these problems for now and always report success. */
1303 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1304 base = 0xffffffff - size - 0x400000 + 1;
1305 addr = programmer_map_flash_region("flash chip registers", base, size);
1306 if (addr == ERROR_PTR) {
1307 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1308 flash->chip->name, PRIxPTR_WIDTH, base);
1309 return 0;
1310 }
1311 flash->physical_registers = base;
1312 flash->virtual_registers = (chipaddr)addr;
1313 }
1314 return 0;
1315}
1316
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001317/*
1318 * Return a string corresponding to the bustype parameter.
1319 * Memory is obtained with malloc() and must be freed with free() by the caller.
1320 */
1321char *flashbuses_to_text(enum chipbustype bustype)
1322{
1323 char *ret = calloc(1, 1);
1324 /*
1325 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1326 * will cease to exist and should be eliminated here as well.
1327 */
1328 if (bustype == BUS_NONSPI) {
1329 ret = strcat_realloc(ret, "Non-SPI, ");
1330 } else {
1331 if (bustype & BUS_PARALLEL)
1332 ret = strcat_realloc(ret, "Parallel, ");
1333 if (bustype & BUS_LPC)
1334 ret = strcat_realloc(ret, "LPC, ");
1335 if (bustype & BUS_FWH)
1336 ret = strcat_realloc(ret, "FWH, ");
1337 if (bustype & BUS_SPI)
1338 ret = strcat_realloc(ret, "SPI, ");
1339 if (bustype & BUS_PROG)
1340 ret = strcat_realloc(ret, "Programmer-specific, ");
1341 if (bustype == BUS_NONE)
1342 ret = strcat_realloc(ret, "None, ");
1343 }
1344 /* Kill last comma. */
1345 ret[strlen(ret) - 2] = '\0';
1346 ret = realloc(ret, strlen(ret) + 1);
1347 return ret;
1348}
1349
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001350int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001351{
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001352 const struct flashchip *chip;
hailfingeraec9c962009-10-31 01:53:09 +00001353 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001354 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001355
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001356 for (chip = flashchips + startchip; chip && chip->name; chip++) {
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001357 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001358 continue;
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001359 buses_common = mst->buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001360 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001361 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001362 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001363 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001364 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001365 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001366 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001367 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001368 continue;
1369 }
stepan782fb172007-04-06 11:58:03 +00001370
hailfinger48ed3e22011-05-04 00:39:50 +00001371 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001372 flash->chip = calloc(1, sizeof(struct flashchip));
1373 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001374 msg_gerr("Out of memory!\n");
1375 exit(1);
1376 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001377 memcpy(flash->chip, chip, sizeof(struct flashchip));
1378 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001379
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001380 if (map_flash(flash) != 0)
1381 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001382
Edward O'Callaghana820b212020-09-17 22:53:26 +10001383 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1384 * is only called with force=1 after normal probing failed.
1385 */
stugec1e55fe2008-07-02 17:15:47 +00001386 if (force)
1387 break;
stepanc98b80b2006-03-16 16:57:41 +00001388
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001389 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001390 goto notfound;
1391
hailfinger48ed3e22011-05-04 00:39:50 +00001392 /* If this is the first chip found, accept it.
1393 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001394 * a non-generic match. SFDP and CFI are generic matches.
1395 * startchip==0 means this call to probe_flash() is the first
1396 * one for this programmer interface (master) and thus no other chip has
1397 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001398 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001399 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1400 msg_cinfo("===\n"
1401 "SFDP has autodetected a flash chip which is "
1402 "not natively supported by flashrom yet.\n");
1403 if (count_usable_erasers(flash) == 0)
1404 msg_cinfo("The standard operations read and "
1405 "verify should work, but to support "
1406 "erase, write and all other "
1407 "possible features");
1408 else
1409 msg_cinfo("All standard operations (read, "
1410 "verify, erase and write) should "
1411 "work, but to support all possible "
1412 "features");
1413
1414 msg_cinfo(" we need to add them manually.\n"
1415 "You can help us by mailing us the output of the following command to "
1416 "flashrom@flashrom.org:\n"
1417 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1418 "Thanks for your help!\n"
1419 "===\n");
1420 }
stugec1e55fe2008-07-02 17:15:47 +00001421
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001422 /* First flash chip detected on this bus. */
1423 if (startchip == 0)
1424 break;
1425 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001426 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001427 break;
1428 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001429notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001430 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001431 free(flash->chip);
1432 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001433 }
uwebe4477b2007-08-23 16:08:21 +00001434
Edward O'Callaghanea9e2452020-12-18 11:01:38 +11001435 if (!flash->chip)
hailfinger48ed3e22011-05-04 00:39:50 +00001436 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001437
Edward O'Callaghan53ff4ad2020-12-16 20:36:28 +11001438 /* Fill fallback layout covering the whole chip. */
1439 struct single_layout *const fallback = &flash->fallback_layout;
1440 fallback->base.entries = &fallback->entry;
1441 fallback->base.num_entries = 1;
1442 fallback->entry.start = 0;
1443 fallback->entry.end = flash->chip->total_size * 1024 - 1;
1444 fallback->entry.included = true;
1445 fallback->entry.name = strdup("complete flash");
1446 if (!fallback->entry.name) {
1447 msg_cerr("Failed to probe chip: %s\n", strerror(errno));
1448 return -1;
1449 }
stepan3e7aeae2011-01-19 06:21:54 +00001450
Edward O'Callaghanea9e2452020-12-18 11:01:38 +11001451 tmp = flashbuses_to_text(flash->chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001452 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1453 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001454 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001455#if CONFIG_INTERNAL == 1
1456 if (programmer_table[programmer].map_flash_region == physmap)
1457 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1458 PRIxPTR_WIDTH, flash->physical_memory);
1459 else
1460#endif
1461 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001462
Edward O'Callaghana820b212020-09-17 22:53:26 +10001463 /* Flash registers may more likely not be mapped if the chip was forced.
1464 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001465 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001466 if (flash->chip->printlock)
1467 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001468
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001469 /* Get out of the way for later runs. */
1470 unmap_flash(flash);
1471
hailfinger48ed3e22011-05-04 00:39:50 +00001472 /* Return position of matching chip. */
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001473 return chip - flashchips;
rminnich8d3ff912003-10-25 17:01:29 +00001474}
1475
uwe8d342eb2011-07-28 08:13:25 +00001476int read_buf_from_file(unsigned char *buf, unsigned long size,
1477 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001478{
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001479#ifdef __LIBPAYLOAD__
1480 msg_gerr("Error: No file I/O support in libpayload\n");
1481 return 1;
1482#else
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001483 int ret = 0;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001484
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001485 FILE *image;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001486 if (!strncmp(filename, "-", sizeof("-")))
1487 image = fdopen(STDIN_FILENO, "rb");
1488 else
1489 image = fopen(filename, "rb");
1490 if (image == NULL) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001491 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger771fc182010-10-15 00:01:14 +00001492 return 1;
1493 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001494
1495 struct stat image_stat;
hailfinger771fc182010-10-15 00:01:14 +00001496 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001497 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001498 ret = 1;
1499 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001500 }
Nikolai Artemieve1f8f602021-02-12 11:44:32 +11001501 if ((image_stat.st_size != (__off_t)size) &&
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001502 (strncmp(filename, "-", sizeof("-")))) {
Daniel Campellocb88c9a2021-04-13 19:23:47 -06001503 msg_gerr("Error: Image size (%jd B) doesn't match the expected size (%lu B)!\n",
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001504 (intmax_t)image_stat.st_size, size);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001505 ret = 1;
1506 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001507 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001508
1509 unsigned long numbytes = fread(buf, 1, size, image);
hailfinger771fc182010-10-15 00:01:14 +00001510 if (numbytes != size) {
1511 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1512 "wanted %ld!\n", numbytes, size);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001513 ret = 1;
hailfinger771fc182010-10-15 00:01:14 +00001514 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001515out:
1516 (void)fclose(image);
1517 return ret;
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001518#endif
hailfinger771fc182010-10-15 00:01:14 +00001519}
1520
Daniel Campellocb88c9a2021-04-13 19:23:47 -06001521/**
1522 * @brief Reads content to buffer from one or more files.
1523 *
1524 * Reads content to supplied buffer from files. If a filename is specified for
1525 * individual regions using the partial read syntax ('-i <region>[:<filename>]')
1526 * then this will read file data into the corresponding region in the
1527 * supplied buffer.
1528 *
1529 * @param flashctx Flash context to be used.
1530 * @param buf Chip-sized buffer to write data to
1531 * @return 0 on success
1532 */
1533static int read_buf_from_include_args(const struct flashctx *const flash,
1534 unsigned char *buf)
1535{
1536 const struct flashrom_layout *const layout = get_layout(flash);
1537 const struct romentry *entry = NULL;
1538
1539 /*
1540 * Content will be read from -i args, so they must not overlap since
1541 * we need to know exactly what content to write to the ROM.
1542 */
1543 if (included_regions_overlap(layout)) {
Daniel Campello2fdc8372021-04-16 17:52:51 -06001544 msg_gerr("Error: Included regions must not overlap when writing.\n");
Daniel Campellocb88c9a2021-04-13 19:23:47 -06001545 return 1;
1546 }
1547
1548 while ((entry = layout_next_included(layout, entry))) {
1549 if (!entry->file)
1550 continue;
1551 if (read_buf_from_file(buf + entry->start,
1552 entry->end - entry->start + 1, entry->file))
1553 return 1;
1554 }
1555 return 0;
1556}
1557
1558/**
1559 * @brief Writes passed data buffer into a file
1560 *
1561 * @param buf Buffer with data to write
1562 * @param size Size of buffer
1563 * @param filename File path to write to
1564 * @return 0 on success
1565 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001566int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001567{
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001568#ifdef __LIBPAYLOAD__
1569 msg_gerr("Error: No file I/O support in libpayload\n");
1570 return 1;
1571#else
hailfingerd219a232009-01-28 00:27:54 +00001572 FILE *image;
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001573 int ret = 0;
hailfingerde345862009-06-01 22:07:52 +00001574
1575 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001576 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001577 return 1;
1578 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001579 if (!strncmp(filename, "-", sizeof("-")))
1580 image = fdopen(STDOUT_FILENO, "wb");
1581 else
1582 image = fopen(filename, "wb");
1583 if (image == NULL) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001584 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger23060112009-05-08 12:49:03 +00001585 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001586 }
hailfingerd219a232009-01-28 00:27:54 +00001587
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001588 unsigned long numbytes = fwrite(buf, 1, size, image);
hailfinger42a850a2010-07-13 23:56:13 +00001589 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001590 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001591 ret = 1;
1592 goto out;
hailfinger42a850a2010-07-13 23:56:13 +00001593 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001594 if (fflush(image)) {
1595 msg_gerr("Error: flushing file \"%s\" failed: %s\n", filename, strerror(errno));
1596 ret = 1;
1597 }
1598 // Try to fsync() only regular files and if that function is available at all (e.g. not on MinGW).
1599#if defined(_POSIX_FSYNC) && (_POSIX_FSYNC != -1)
1600 struct stat image_stat;
1601 if (fstat(fileno(image), &image_stat) != 0) {
1602 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1603 ret = 1;
1604 goto out;
1605 }
1606 if (S_ISREG(image_stat.st_mode)) {
1607 if (fsync(fileno(image))) {
1608 msg_gerr("Error: fsyncing file \"%s\" failed: %s\n", filename, strerror(errno));
1609 ret = 1;
1610 }
1611 }
1612#endif
1613out:
1614 if (fclose(image)) {
1615 msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
1616 ret = 1;
1617 }
1618 return ret;
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001619#endif
hailfingerd219a232009-01-28 00:27:54 +00001620}
1621
Daniel Campellocb88c9a2021-04-13 19:23:47 -06001622/**
1623 * @brief Writes content from buffer to one or more files.
1624 *
1625 * Writes content from supplied buffer to files. If a filename is specified for
1626 * individual regions using the partial read syntax ('-i <region>[:<filename>]')
1627 * then this will write files using data from the corresponding region in the
1628 * supplied buffer.
1629 *
1630 * @param flashctx Flash context to be used.
1631 * @param buf Chip-sized buffer to read data from
1632 * @return 0 on success
1633 */
1634static int write_buf_to_include_args(const struct flashctx *const flash,
1635 unsigned char *buf)
1636{
1637#ifdef __LIBPAYLOAD__
1638 msg_gerr("Error: No file I/O support in libpayload\n");
1639 return 1;
1640#else
1641 const struct flashrom_layout *const layout = get_layout(flash);
1642 const struct romentry *entry = NULL;
1643
1644 while ((entry = layout_next_included(layout, entry))) {
1645 if (!entry->file)
1646 continue;
1647 if (write_buf_to_file(buf + entry->start,
1648 entry->end - entry->start + 1, entry->file))
1649 return 1;
1650 }
1651
1652 return 0;
1653#endif
1654}
1655
David Hendrickse3451942013-03-21 17:23:29 -07001656/*
1657 * read_flash - wrapper for flash->read() with additional high-level policy
1658 *
1659 * @flash flash chip
1660 * @buf buffer to store data in
1661 * @start start address
1662 * @len number of bytes to read
1663 *
1664 * This wrapper simplifies most cases when the flash chip needs to be read
1665 * since policy decisions such as non-fatal error handling is centralized.
1666 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001667int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001668 unsigned int start, unsigned int len)
1669{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001670 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001671
Patrick Georgif3fa2992017-02-02 16:24:44 +01001672 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001673 return -1;
1674
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001675 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1676
Patrick Georgif3fa2992017-02-02 16:24:44 +01001677 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001678 if (ret) {
1679 if (ignore_error(ret)) {
1680 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1681 start, start + len - 1);
1682 ret = 0;
1683 } else {
1684 msg_gdbg("failed to read 0x%x-0x%x\n",
1685 start, start + len - 1);
1686 }
1687 }
1688
1689 return ret;
1690}
1691
David Hendricks7c8a1612013-04-26 19:14:44 -07001692/*
1693 * write_flash - wrapper for flash->write() with additional high-level policy
1694 *
1695 * @flash flash chip
1696 * @buf buffer to write to flash
1697 * @start start address in flash
1698 * @len number of bytes to write
1699 *
1700 * TODO: Look up regions that are write-protected and avoid attempt to write
1701 * to them at all.
1702 */
Edward O'Callaghanaccf9ff2021-01-22 01:33:03 +11001703static int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001704 unsigned int start, unsigned int len)
1705{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001706 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001707 return -1;
1708
Patrick Georgif3fa2992017-02-02 16:24:44 +01001709 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001710}
1711
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06001712static int read_by_layout(struct flashctx *, uint8_t *);
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001713int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001714{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001715 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001716 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001717 int ret = 0;
1718
1719 msg_cinfo("Reading flash... ");
1720 if (!buf) {
1721 msg_gerr("Memory allocation failed!\n");
1722 msg_cinfo("FAILED.\n");
1723 return 1;
1724 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001725
1726 /* To support partial read, fill buffer to all 0xFF at beginning to make
1727 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001728 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001729
Patrick Georgif3fa2992017-02-02 16:24:44 +01001730 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001731 msg_cerr("No read function available for this flash chip.\n");
1732 ret = 1;
1733 goto out_free;
1734 }
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06001735 if (read_by_layout(flash, buf)) {
1736 msg_cerr("Read operation failed!\n");
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001737 ret = 1;
1738 goto out_free;
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06001739 }
Daniel Campellocb88c9a2021-04-13 19:23:47 -06001740 if (write_buf_to_include_args(flash, buf)) {
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06001741 ret = 1;
1742 goto out_free;
hailfinger42a850a2010-07-13 23:56:13 +00001743 }
1744
David Hendricksdf29a832013-06-28 14:33:51 -07001745 if (filename)
1746 ret = write_buf_to_file(buf, size, filename);
hailfinger42a850a2010-07-13 23:56:13 +00001747out_free:
1748 free(buf);
Edward O'Callaghan6b2ff8a2020-12-11 14:33:23 +11001749 msg_cinfo("%s.\n", ret ? "FAILED" : "done");
hailfinger42a850a2010-07-13 23:56:13 +00001750 return ret;
1751}
1752
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001753/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001754static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001755{
hailfingerb91c08c2011-08-15 19:54:20 +00001756 int i, j, k;
1757 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001758
1759 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1760 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001761 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001762
1763 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1764 /* Blocks with zero size are bugs in flashchips.c. */
1765 if (eraser.eraseblocks[i].count &&
1766 !eraser.eraseblocks[i].size) {
1767 msg_gerr("ERROR: Flash chip %s erase function "
1768 "%i region %i has size 0. Please report"
1769 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001770 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001771 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001772 }
1773 /* Blocks with zero count are bugs in flashchips.c. */
1774 if (!eraser.eraseblocks[i].count &&
1775 eraser.eraseblocks[i].size) {
1776 msg_gerr("ERROR: Flash chip %s erase function "
1777 "%i region %i has count 0. Please report"
1778 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001779 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001780 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001781 }
1782 done += eraser.eraseblocks[i].count *
1783 eraser.eraseblocks[i].size;
1784 }
hailfinger9fed35d2010-01-19 06:42:46 +00001785 /* Empty eraseblock definition with erase function. */
1786 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001787 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001788 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001789 if (!done)
1790 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001791 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001792 msg_gerr("ERROR: Flash chip %s erase function %i "
1793 "region walking resulted in 0x%06x bytes total,"
1794 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001795 " flashrom@flashrom.org\n", chip->name, k,
1796 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001797 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001798 }
hailfinger9fed35d2010-01-19 06:42:46 +00001799 if (!eraser.block_erase)
1800 continue;
1801 /* Check if there are identical erase functions for different
1802 * layouts. That would imply "magic" erase functions. The
1803 * easiest way to check this is with function pointers.
1804 */
uwef6f94d42010-03-13 17:28:29 +00001805 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001806 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001807 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001808 msg_gerr("ERROR: Flash chip %s erase function "
1809 "%i and %i are identical. Please report"
1810 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001811 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001812 ret = 1;
1813 }
uwef6f94d42010-03-13 17:28:29 +00001814 }
hailfinger45177872010-01-18 08:14:43 +00001815 }
hailfinger9fed35d2010-01-19 06:42:46 +00001816 return ret;
hailfinger45177872010-01-18 08:14:43 +00001817}
1818
Edward O'Callaghanbef74c22020-12-04 16:23:54 +11001819static int check_block_eraser(const struct flashctx *flash, int k, int log)
1820{
1821 struct block_eraser eraser = flash->chip->block_erasers[k];
1822
1823 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1824 if (log)
1825 msg_cdbg("not defined. ");
1826 return 1;
1827 }
1828 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1829 if (log)
1830 msg_cdbg("eraseblock layout is known, but matching "
1831 "block erase function is not implemented. ");
1832 return 1;
1833 }
1834 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1835 if (log)
1836 msg_cdbg("block erase function found, but "
1837 "eraseblock layout is not defined. ");
1838 return 1;
1839 }
1840 // TODO: Once erase functions are annotated with allowed buses, check that as well.
1841 return 0;
1842}
1843
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06001844/**
1845 * @brief Reads the included layout regions into a buffer.
1846 *
1847 * If there is no layout set in the given flash context, the whole chip will
1848 * be read.
1849 *
1850 * @param flashctx Flash context to be used.
1851 * @param buffer Buffer of full chip size to read into.
1852 * @return 0 on success,
1853 * 1 if any read fails.
1854 */
1855static int read_by_layout(struct flashctx *const flashctx, uint8_t *const buffer)
1856{
1857 const struct flashrom_layout *const layout = get_layout(flashctx);
1858 const struct romentry *entry = NULL;
1859 int required_erase_size = get_required_erase_size(flashctx);
1860
1861 while ((entry = layout_next_included(layout, entry))) {
1862 unsigned int rounded_start, rounded_len;
1863
1864 if (round_to_erasable_block_boundary(required_erase_size, entry,
1865 &rounded_start, &rounded_len))
1866 return 1;
1867 if (read_flash(flashctx, buffer + rounded_start, rounded_start,
1868 rounded_len))
1869 return 1;
1870 }
1871 return 0;
1872}
1873
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001874typedef int (*erasefn_t)(struct flashctx *, unsigned int addr, unsigned int len);
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001875/**
1876 * @private
1877 *
1878 * For read-erase-write, `curcontents` and `newcontents` shall point
1879 * to buffers of the chip's size. Both are supposed to be prefilled
1880 * with at least the included layout regions of the current flash
1881 * contents (`curcontents`) and the data to be written to the flash
1882 * (`newcontents`).
1883 *
1884 * For erase, `curcontents` and `newcontents` shall be NULL-pointers.
1885 *
1886 * The `chipoff_t` values are used internally by `walk_by_layout()`.
1887 */
1888struct walk_info {
1889 uint8_t *curcontents;
1890 const uint8_t *newcontents;
1891 chipoff_t erase_start;
1892 chipoff_t erase_len;
1893};
Edward O'Callaghan5e9e5712020-12-10 11:11:56 +11001894typedef int (*per_blockfn_t)(struct flashctx *, struct walk_info *const, erasefn_t);
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001895
Edward O'Callaghanecc0b202020-12-10 11:35:11 +11001896/*
1897 * Function to process processing units accumulated in the action descriptor.
1898 *
1899 * @flash pointer to the flash context to operate on
1900 * @per_blockfn helper function which can erase and program a section of the
1901 * flash chip. It receives the flash context, offset and length
1902 * of the area to erase/program, before and after contents (to
1903 * decide what exactly needs to be erased and or programmed)
1904 * and a pointer to the erase function which can operate on the
1905 * proper granularity.
1906 * @descriptor action descriptor including pointers to before and after
1907 * contents and an array of processing actions to take.
1908 *
1909 * Returns zero on success or an error code.
1910 */
1911static int walk_eraseregions(struct flashctx *flash,
1912 const per_blockfn_t per_blockfn,
1913 struct action_descriptor *descriptor)
1914{
1915 struct processing_unit *pu;
1916 int rc = 0;
1917 static int print_comma;
1918
1919 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1920 unsigned base = pu->offset;
1921 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
Edward O'Callaghan17361062020-12-12 17:31:59 +11001922 struct block_eraser *const eraser = &flash->chip->block_erasers[pu->block_eraser_index];
Edward O'Callaghanecc0b202020-12-10 11:35:11 +11001923
1924 while (base < top) {
1925
1926 if (print_comma)
1927 msg_cdbg(", ");
1928 else
1929 print_comma = 1;
1930
1931 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1932
1933 struct walk_info info = {
1934 .curcontents = descriptor->oldcontents,
1935 .newcontents = descriptor->newcontents,
1936 .erase_start = base,
1937 .erase_len = pu->block_size,
1938 };
Edward O'Callaghan17361062020-12-12 17:31:59 +11001939 rc = per_blockfn(flash, &info, eraser->block_erase);
Edward O'Callaghanecc0b202020-12-10 11:35:11 +11001940
1941 if (rc) {
1942 if (ignore_error(rc))
1943 rc = 0;
1944 else
1945 return rc;
1946 }
1947 base += pu->block_size;
1948 }
1949 }
1950 msg_cdbg("\n");
1951 return rc;
1952}
1953
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001954static int erase_and_write_block_helper(struct flashctx *flash,
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001955 struct walk_info *const info,
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001956 erasefn_t erasefn)
hailfingerb437e282010-11-04 01:04:27 +00001957{
stefanctc5eb8a92011-11-23 09:13:48 +00001958 unsigned int starthere = 0, lenhere = 0;
Edward O'Callaghan307d1692020-12-12 00:18:22 +11001959 int ret = 0, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001960 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001961 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001962
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001963 /*
1964 * curcontents and newcontents are opaque to walk_eraseregions, and
1965 * need to be adjusted here to keep the impression of proper
1966 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001967 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001968
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001969 info->curcontents += info->erase_start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001970
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001971 info->newcontents += info->erase_start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001972
Edward O'Callaghan307d1692020-12-12 00:18:22 +11001973 bool skipped = true;
hailfingerb437e282010-11-04 01:04:27 +00001974 msg_cdbg(":");
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001975 if (need_erase(info->curcontents, info->newcontents, info->erase_len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001976 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001977 msg_cdbg(" E");
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001978 ret = erasefn(flash, info->erase_start, info->erase_len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001979 if (ret) {
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +11001980 if (ret == SPI_ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001981 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001982 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001983 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001984 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001985 }
1986
David Hendricks0954ffc2015-11-13 15:15:44 -08001987 if (programmer_table[programmer].paranoid) {
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001988 if (check_erased_range(flash, info->erase_start, info->erase_len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001989 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001990 return -1;
1991 }
hailfingerac8e3182011-06-26 17:04:16 +00001992 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001993
hailfinger90fcf9b2010-11-05 14:51:59 +00001994 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001995 memset(info->curcontents, ERASED_VALUE(flash), info->erase_len);
Edward O'Callaghan307d1692020-12-12 00:18:22 +11001996 skipped = false;
David Hendricks048b38c2016-03-28 18:47:06 -07001997 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001998 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001999 /* get_next_write() sets starthere to a new value after the call. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11002000 while ((lenhere = get_next_write(info->curcontents + starthere,
2001 info->newcontents + starthere,
2002 info->erase_len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002003 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00002004 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07002005 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00002006 /* Needs the partial write function signature. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11002007 ret = write_flash(flash, (uint8_t *)info->newcontents + starthere,
2008 info->erase_start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08002009 if (ret) {
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +11002010 if (ret == SPI_ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07002011 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00002012 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08002013 }
David Hendricks048b38c2016-03-28 18:47:06 -07002014
2015 /*
2016 * If the block needed to be erased and was erased successfully
2017 * then we can assume that we didn't run into any write-
2018 * protected areas. Otherwise, we need to verify each page to
2019 * ensure it was successfully written and abort if we encounter
2020 * any errors.
2021 */
2022 if (programmer_table[programmer].paranoid && !block_was_erased) {
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11002023 if (verify_range(flash, info->newcontents + starthere,
2024 info->erase_start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07002025 return -1;
2026 }
2027
hailfingerb437e282010-11-04 01:04:27 +00002028 starthere += lenhere;
Edward O'Callaghan307d1692020-12-12 00:18:22 +11002029 skipped = false;
hailfingerb437e282010-11-04 01:04:27 +00002030 }
Edward O'Callaghan307d1692020-12-12 00:18:22 +11002031 if (skipped)
2032 msg_cdbg("S");
hailfingerb437e282010-11-04 01:04:27 +00002033 return ret;
2034}
2035
Edward O'Callaghanaccf9ff2021-01-22 01:33:03 +11002036static int erase_and_write_flash(struct flashctx *flash,
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002037 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002038{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002039 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002040
hailfingercf848f12010-12-05 15:14:44 +00002041 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002042
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002043 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002044
hailfinger7df21362009-09-05 02:30:58 +00002045 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002046 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002047 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002048 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002049 }
2050 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002051}
2052
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11002053static int verify_flash(struct flashctx *flash,
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002054 struct action_descriptor *descriptor)
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11002055{
2056 int ret;
2057 unsigned int total_size = flash->chip->total_size * 1024;
2058 uint8_t *buf = descriptor->newcontents;
2059
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002060 const bool verify_all = flash->flags.verify_whole_chip;
2061 if (!verify_all) {
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11002062 struct processing_unit *pu = descriptor->processing_units;
2063
2064 /* Verify only areas which were written. */
2065 while (pu->num_blocks) {
2066 ret = verify_range(flash, buf + pu->offset, pu->offset,
2067 pu->block_size * pu->num_blocks);
2068 if (ret)
2069 break;
2070 pu++;
2071 }
2072 } else {
2073 ret = verify_range(flash, buf, 0, total_size);
2074 }
2075
Daniel Campellocd387fd2021-04-20 17:54:35 -06002076 if (ret) {
2077 msg_gdbg("Could not fully verify due to error, ");
2078 if (ignore_error(ret)) {
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11002079 msg_gdbg("ignoring\n");
2080 ret = 0;
2081 } else {
2082 msg_gdbg("aborting\n");
2083 }
2084 }
2085
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11002086 return ret;
2087}
2088
Daniel Campelloef545b12021-04-10 10:39:26 -06002089/**
2090 * @brief Compares the included layout regions with content from a buffer.
2091 *
2092 * If there is no layout set in the given flash context, the whole chip's
2093 * contents will be compared.
2094 *
2095 * @param flashctx Flash context to be used.
2096 * @param curcontents A buffer of full chip size to read current chip contents into.
2097 * @param newcontents The new image to compare to.
2098 * @return 0 on success,
2099 * 1 if reading failed,
2100 * 3 if the contents don't match.
2101 */
2102static int verify_by_layout(struct flashctx *const flashctx,
2103 void *const curcontents, const uint8_t *const newcontents)
2104{
2105 const struct flashrom_layout *const layout = get_layout(flashctx);
2106 const struct romentry *entry = NULL;
2107 int required_erase_size = get_required_erase_size(flashctx);
2108
2109 while ((entry = layout_next_included(layout, entry))) {
2110 const chipoff_t region_start = entry->start;
2111 const chipsize_t region_len = entry->end - entry->start + 1;
2112 unsigned int rounded_start, rounded_len;
2113
2114 if (round_to_erasable_block_boundary(required_erase_size, entry,
2115 &rounded_start, &rounded_len))
2116 return 1;
2117 if (read_flash(flashctx, curcontents + rounded_start, rounded_start, rounded_len))
2118 return 1;
2119 if (compare_range(newcontents + region_start, curcontents + region_start,
2120 region_start, region_len))
2121 return 3;
2122 }
2123 return 0;
2124}
2125
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002126static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002127{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002128 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2129#if CONFIG_INTERNAL == 1
2130 if (programmer == PROGRAMMER_INTERNAL)
2131 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2132 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2133 "mail flashrom@flashrom.org, thanks!\n"
2134 "-------------------------------------------------------------------------------\n"
2135 "You may now reboot or simply leave the machine running.\n");
2136 else
2137#endif
2138 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2139 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2140 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2141 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002142}
2143
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002144static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002145{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002146 msg_gerr("Your flash chip is in an unknown state.\n");
2147#if CONFIG_INTERNAL == 1
2148 if (programmer == PROGRAMMER_INTERNAL)
2149 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2150 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2151 "-------------------------------------------------------------------------------\n"
2152 "DO NOT REBOOT OR POWEROFF!\n");
2153 else
2154#endif
2155 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2156 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002157}
2158
hailfingerf79d1712010-10-06 23:48:34 +00002159void list_programmers_linebreak(int startcol, int cols, int paren)
2160{
2161 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002162 int pnamelen;
2163 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002164 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002165 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002166
2167 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2168 pname = programmer_table[p].name;
2169 pnamelen = strlen(pname);
2170 if (remaining - pnamelen - 2 < 0) {
2171 if (firstline)
2172 firstline = 0;
2173 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002174 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002175 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002176 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002177 remaining = cols - startcol;
2178 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002179 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002180 remaining--;
2181 }
2182 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002183 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002184 remaining--;
2185 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002186 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002187 remaining -= pnamelen;
2188 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002189 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002190 remaining--;
2191 } else {
2192 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002193 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002194 }
2195 }
2196}
2197
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002198static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002199{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002200#if IS_WINDOWS
2201 SYSTEM_INFO si;
2202 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002203
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002204 memset(&si, 0, sizeof(SYSTEM_INFO));
2205 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2206 msg_ginfo(" on Windows");
2207 /* Tell Windows which version of the structure we want. */
2208 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2209 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2210 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2211 else
2212 msg_ginfo(" unknown version");
2213 GetSystemInfo(&si);
2214 switch (si.wProcessorArchitecture) {
2215 case PROCESSOR_ARCHITECTURE_AMD64:
2216 msg_ginfo(" (x86_64)");
2217 break;
2218 case PROCESSOR_ARCHITECTURE_INTEL:
2219 msg_ginfo(" (x86)");
2220 break;
2221 default:
2222 msg_ginfo(" (unknown arch)");
2223 break;
2224 }
2225#elif HAVE_UTSNAME == 1
2226 struct utsname osinfo;
2227
2228 uname(&osinfo);
2229 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002230 osinfo.machine);
2231#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002232 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002233#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002234}
2235
2236void print_buildinfo(void)
2237{
2238 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002239#if NEED_PCI == 1
2240#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002241 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002242#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002243 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002244#endif
2245#endif
2246#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002247 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002248#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002249 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002250#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002251 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002252#endif
hailfinger3b471632010-03-27 16:36:40 +00002253#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002254 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002255#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002256 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002257#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002258 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002259#endif
2260#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002261 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002262#endif
2263#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002264 msg_gdbg(" little endian");
Edward O'Callaghan3c005942020-10-01 16:33:47 +10002265#elif defined (__FLASHROM_BIG_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002266 msg_gdbg(" big endian");
Edward O'Callaghan3c005942020-10-01 16:33:47 +10002267#else
2268#error Endianness could not be determined
hailfinger3b471632010-03-27 16:36:40 +00002269#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002270 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002271}
2272
uwefdeca092008-01-21 15:24:22 +00002273void print_version(void)
2274{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002275 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002276 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002277 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002278}
2279
hailfinger74819ad2010-05-15 15:04:37 +00002280void print_banner(void)
2281{
2282 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002283 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002284 msg_ginfo("\n");
2285}
2286
hailfingerc77acb52009-12-24 02:15:55 +00002287int selfcheck(void)
2288{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002289 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002290 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002291
2292 /* Safety check. Instead of aborting after the first error, check
2293 * if more errors exist.
2294 */
hailfingerc77acb52009-12-24 02:15:55 +00002295 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002296 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002297 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002298 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002299 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2300 const struct programmer_entry p = programmer_table[i];
2301 if (p.name == NULL) {
2302 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2303 ret = 1;
2304 /* This might hide other problems with this programmer, but allows for better error
2305 * messages below without jumping through hoops. */
2306 continue;
2307 }
2308 switch (p.type) {
2309 case USB:
2310 case PCI:
2311 case OTHER:
2312 if (p.devs.note == NULL) {
2313 if (strcmp("internal", p.name) == 0)
2314 break; /* This one has its device list stored separately. */
2315 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2316 p.name);
2317 ret = 1;
2318 }
2319 break;
2320 default:
2321 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2322 ret = 1;
2323 break;
2324 }
2325 if (p.init == NULL) {
2326 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2327 ret = 1;
2328 }
2329 if (p.delay == NULL) {
2330 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2331 ret = 1;
2332 }
2333 if (p.map_flash_region == NULL) {
2334 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2335 ret = 1;
2336 }
2337 if (p.unmap_flash_region == NULL) {
2338 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2339 ret = 1;
2340 }
2341 }
2342
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002343 /* It would be favorable if we could check for the correct layout (especially termination) of various
2344 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2345 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2346 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2347 * 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 +10002348 * checks below. */
2349 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002350 msg_gerr("Flashchips table miscompilation!\n");
2351 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002352 } else {
2353 for (i = 0; i < flashchips_size - 1; i++) {
2354 const struct flashchip *chip = &flashchips[i];
2355 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2356 ret = 1;
2357 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2358 "Please report a bug at flashrom@flashrom.org\n", i,
2359 chip->name == NULL ? "unnamed" : chip->name);
2360 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002361 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002362 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002363 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002364 }
stefanct6d836ba2011-05-26 01:35:19 +00002365 }
stefanct6d836ba2011-05-26 01:35:19 +00002366
Edward O'Callaghane6b85692020-12-18 11:01:55 +11002367#if CONFIG_INTERNAL == 1
2368 ret |= selfcheck_board_enables();
2369#endif
2370
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002371 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002372 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002373}
2374
hailfinger771fc182010-10-15 00:01:14 +00002375/* FIXME: This function signature needs to be improved once doit() has a better
2376 * function signature.
2377 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002378static int chip_safety_check(const struct flashctx *flash, int force,
2379 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002380{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002381 const struct flashchip *chip = flash->chip;
2382
hailfinger771fc182010-10-15 00:01:14 +00002383 if (!programmer_may_write && (write_it || erase_it)) {
2384 msg_perr("Write/erase is not working yet on your programmer in "
2385 "its current configuration.\n");
2386 /* --force is the wrong approach, but it's the best we can do
2387 * until the generic programmer parameter parser is merged.
2388 */
2389 if (!force)
2390 return 1;
2391 msg_cerr("Continuing anyway.\n");
2392 }
2393
2394 if (read_it || erase_it || write_it || verify_it) {
2395 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002396 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002397 msg_cerr("Read is not working on this chip. ");
2398 if (!force)
2399 return 1;
2400 msg_cerr("Continuing anyway.\n");
2401 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002402 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002403 msg_cerr("flashrom has no read function for this "
2404 "flash chip.\n");
2405 return 1;
2406 }
2407 }
2408 if (erase_it || write_it) {
2409 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002410 if (chip->tested.erase == NA) {
2411 msg_cerr("Erase is not possible on this chip.\n");
2412 return 1;
2413 }
2414 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002415 msg_cerr("Erase is not working on this chip. ");
2416 if (!force)
2417 return 1;
2418 msg_cerr("Continuing anyway.\n");
2419 }
stefancte1c5acf2011-07-04 07:27:17 +00002420 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002421 msg_cerr("flashrom has no erase function for this "
2422 "flash chip.\n");
2423 return 1;
2424 }
hailfinger771fc182010-10-15 00:01:14 +00002425 }
2426 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002427 if (chip->tested.write == NA) {
2428 msg_cerr("Write is not possible on this chip.\n");
2429 return 1;
2430 }
2431 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002432 msg_cerr("Write is not working on this chip. ");
2433 if (!force)
2434 return 1;
2435 msg_cerr("Continuing anyway.\n");
2436 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002437 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002438 msg_cerr("flashrom has no write function for this "
2439 "flash chip.\n");
2440 return 1;
2441 }
2442 }
2443 return 0;
2444}
2445
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002446int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002447 const bool read_it, const bool write_it,
2448 const bool erase_it, const bool verify_it)
2449{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002450 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002451 msg_cerr("Aborting.\n");
2452 return 1;
2453 }
2454
Daniel Campellodf477722021-04-05 16:53:33 -06002455 if (flash->layout == get_global_layout() && normalize_romentries(flash)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002456 msg_cerr("Requested regions can not be handled. Aborting.\n");
2457 return 1;
2458 }
2459
Edward O'Callaghan40092972020-10-20 11:50:48 +11002460 /*
2461 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2462 * can be repro'ed with upstream on Volteer.
2463 *
2464 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2465 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2466 * hooked and this can fail on some board topologies. Checking the return value can
2467 * cause board rw failures by bailing early. Avoid the early bail for now until a
2468 * full investigation can reveal the proper fix. This restores previous behaviour of
2469 * assuming a map went fine.
2470 */
2471#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002472 if (map_flash(flash) != 0)
2473 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002474#endif
2475 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002476
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002477 /* Given the existence of read locks, we want to unlock for read,
2478 erase and write. */
2479 if (flash->chip->unlock)
2480 flash->chip->unlock(flash);
2481
2482 flash->address_high_byte = -1;
2483 flash->in_4ba_mode = false;
Nikolai Artemiev55f7a332020-11-05 13:54:27 +11002484 flash->chip_restore_fn_count = 0;
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002485
Edward O'Callaghan99974452020-10-13 13:28:33 +11002486 /* Be careful about 4BA chips and broken masters */
2487 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2488 /* If we can't use native instructions, bail out */
2489 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2490 || !spi_master_4ba(flash)) {
2491 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2492 return 1;
2493 }
2494 }
2495
Edward O'Callaghanecb10662020-11-11 20:23:44 +11002496 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2497 if ((flash->chip->bustype == BUS_SPI) &&
2498 (flash->chip->feature_bits & (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_ENTER_EAR7))) {
2499 int ret;
2500 if (spi_master_4ba(flash))
2501 ret = spi_enter_4ba(flash);
2502 else
2503 ret = spi_exit_4ba(flash);
2504 if (ret) {
2505 msg_cerr("Failed to set correct 4BA mode! Aborting.\n");
2506 return 1;
2507 }
2508 }
2509
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002510 return 0;
2511}
2512
Edward O'Callaghana820b212020-09-17 22:53:26 +10002513void finalize_flash_access(struct flashctx *const flash)
2514{
Nikolai Artemiev55f7a332020-11-05 13:54:27 +11002515 deregister_chip_restore(flash);
Edward O'Callaghana820b212020-09-17 22:53:26 +10002516 unmap_flash(flash);
2517}
2518
Daniel Campelloee45dc12021-04-10 10:13:51 -06002519static int setup_oldcontents(struct flashctx *flashctx, void *oldcontents,
2520 int erase_it, const void *const refcontents)
Daniel Campello98eed1a2021-03-22 07:28:34 -06002521{
Daniel Campelloee45dc12021-04-10 10:13:51 -06002522 const size_t flash_size = flashctx->chip->total_size * 1024;
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06002523 const bool verify_all = flashctx->flags.verify_whole_chip;
2524 const bool verify = flashctx->flags.verify_after_write;
Daniel Campello98eed1a2021-03-22 07:28:34 -06002525
Daniel Campelloee45dc12021-04-10 10:13:51 -06002526 memset(oldcontents, UNERASED_VALUE(flashctx), flash_size);
2527 if (!flashctx->flags.do_not_diff) {
Daniel Campello98eed1a2021-03-22 07:28:34 -06002528 /*
2529 * Obtain a reference image so that we can check whether
2530 * regions need to be erased and to give better diagnostics in
2531 * case write fails. If --fast-verify is used then only the
2532 * regions which are included using -i will be read.
2533 */
Daniel Campelloee45dc12021-04-10 10:13:51 -06002534 if (refcontents) {
2535 msg_cinfo("Assuming old flash chip contents as ref-file...\n");
2536 memcpy(oldcontents, refcontents, flash_size);
Daniel Campello98eed1a2021-03-22 07:28:34 -06002537 } else {
Daniel Campelloee45dc12021-04-10 10:13:51 -06002538 msg_cinfo("Reading old flash chip contents... ");
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06002539 if (verify && verify_all) {
2540 if (read_flash(flashctx, oldcontents, 0, flash_size)) {
2541 msg_cinfo("FAILED.\n");
2542 return 1;
2543 }
2544 } else {
2545 if (read_by_layout(flashctx, oldcontents)) {
2546 msg_cinfo("FAILED.\n");
2547 return 1;
2548 }
Daniel Campello98eed1a2021-03-22 07:28:34 -06002549 }
Daniel Campelloee45dc12021-04-10 10:13:51 -06002550 msg_cinfo("done.\n");
Daniel Campello98eed1a2021-03-22 07:28:34 -06002551 }
Daniel Campello98eed1a2021-03-22 07:28:34 -06002552 } else if (!erase_it) {
2553 msg_pinfo("No diff performed, considering the chip erased.\n");
Daniel Campelloee45dc12021-04-10 10:13:51 -06002554 memset(oldcontents, ERASED_VALUE(flashctx), flash_size);
Daniel Campello98eed1a2021-03-22 07:28:34 -06002555 }
2556
Daniel Campelloee45dc12021-04-10 10:13:51 -06002557 return 0;
Daniel Campello98eed1a2021-03-22 07:28:34 -06002558}
2559
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002560/**
2561 * @addtogroup flashrom-flash
2562 * @{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002563 */
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002564
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002565static void combine_image_by_layout(const struct flashctx *const flashctx,
2566 uint8_t *const newcontents, const uint8_t *const oldcontents);
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002567/**
2568 * @brief Erase the specified ROM chip.
2569 *
2570 * If a layout is set in the given flash context, only included regions
2571 * will be erased.
2572 *
2573 * @param flashctx The context of the flash chip to erase.
2574 * @return 0 on success.
2575 */
Daniel Campello26765322021-03-22 14:53:27 -06002576int flashrom_flash_erase(struct flashctx *const flashctx)
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002577{
Daniel Campello26765322021-03-22 14:53:27 -06002578 const size_t flash_size = flashctx->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002579
Daniel Campello26765322021-03-22 14:53:27 -06002580 int ret = 1;
2581
2582 struct action_descriptor *descriptor = NULL;
2583 uint8_t *oldcontents = malloc(flash_size);
2584 uint8_t *newcontents = malloc(flash_size);
2585 if (!oldcontents || !newcontents) {
2586 msg_gerr("Out of memory!\n");
2587 goto _free_ret;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002588 }
2589
Daniel Campello26765322021-03-22 14:53:27 -06002590 if (prepare_flash_access(flashctx, false, false, true, false))
2591 goto _free_ret;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002592
Daniel Campelloee45dc12021-04-10 10:13:51 -06002593 if (setup_oldcontents(flashctx, oldcontents, true, NULL))
2594 goto _finalize_ret;
2595
2596 memset(newcontents, ERASED_VALUE(flashctx), flash_size);
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002597 combine_image_by_layout(flashctx, newcontents, oldcontents);
Daniel Campello26765322021-03-22 14:53:27 -06002598
2599 descriptor = prepare_action_descriptor(flashctx, oldcontents, newcontents, true);
2600
2601 if (!erase_and_write_flash(flashctx, descriptor)) {
2602 ret = 0;
2603 }
2604
2605_finalize_ret:
2606 finalize_flash_access(flashctx);
2607_free_ret:
2608 if (descriptor)
2609 free(descriptor);
2610 free(oldcontents);
2611 free(newcontents);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002612 return ret;
2613}
2614
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002615/** @} */ /* end flashrom-flash */
2616
Edward O'Callaghan8c2a3402020-12-09 12:23:01 +11002617/**
2618 * @defgroup flashrom-ops Operations
2619 * @{
2620 */
2621
Edward O'Callaghan84c89182020-12-09 12:33:37 +11002622/**
2623 * @brief Read the current image from the specified ROM chip.
2624 *
2625 * If a layout is set in the specified flash context, only included regions
2626 * will be read.
2627 *
2628 * @param flashctx The context of the flash chip.
2629 * @param buffer Target buffer to write image to.
2630 * @param buffer_len Size of target buffer in bytes.
2631 * @return 0 on success,
2632 * 2 if buffer_len is too short for the flash chip's contents,
2633 * or 1 on any other failure.
2634 */
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06002635int flashrom_image_read(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len)
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002636{
Daniel Campello039cd2b2021-03-24 20:12:15 -06002637 const size_t flash_size = flashctx->chip->total_size * 1024;
2638
2639 if (flash_size > buffer_len)
2640 return 2;
2641
2642 if (prepare_flash_access(flashctx, true, false, false, false))
2643 return 1;
2644
2645 msg_cinfo("Reading flash... ");
2646
2647 int ret = 1;
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06002648 if (read_by_layout(flashctx, buffer)) {
Daniel Campello039cd2b2021-03-24 20:12:15 -06002649 msg_cerr("Read operation failed!\n");
2650 msg_cinfo("FAILED.\n");
2651 goto _finalize_ret;
2652 }
2653 msg_cinfo("done.\n");
2654 ret = 0;
2655
2656_finalize_ret:
2657 finalize_flash_access(flashctx);
2658 return ret;
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002659}
2660
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002661static void combine_image_by_layout(const struct flashctx *const flashctx,
2662 uint8_t *const newcontents, const uint8_t *const oldcontents)
2663{
2664 const struct flashrom_layout *const layout = get_layout(flashctx);
2665 const struct romentry *included;
2666 chipoff_t start = 0;
2667
2668 while ((included = layout_next_included_region(layout, start))) {
2669 if (included->start > start) {
2670 /* copy everything up to the start of this included region */
2671 memcpy(newcontents + start, oldcontents + start, included->start - start);
2672 }
2673 /* skip this included region */
2674 start = included->end + 1;
2675 if (start == 0)
2676 return;
2677 }
2678
2679 /* copy the rest of the chip */
2680 const chipsize_t copy_len = flashctx->chip->total_size * 1024 - start;
2681 memcpy(newcontents + start, oldcontents + start, copy_len);
2682}
2683
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002684/**
2685 * @brief Write the specified image to the ROM chip.
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002686 *
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002687 * If a layout is set in the specified flash context, only erase blocks
2688 * containing included regions will be touched.
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002689 *
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002690 * @param flashctx The context of the flash chip.
2691 * @param buffer Source buffer to read image from (may be altered for full verification).
2692 * @param buffer_len Size of source buffer in bytes.
2693 * @param refbuffer If given, assume flash chip contains same data as `refbuffer`.
2694 * @return 0 on success,
2695 * 4 if buffer_len doesn't match the size of the flash chip,
2696 * or 1 on any other failure.
hailfingerc77acb52009-12-24 02:15:55 +00002697 */
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002698int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len,
2699 const void *const refbuffer)
hailfingerc77acb52009-12-24 02:15:55 +00002700{
Daniel Campello57eb4882021-03-25 08:45:10 -06002701 const size_t flash_size = flashctx->chip->total_size * 1024;
Daniel Campello57eb4882021-03-25 08:45:10 -06002702 const bool verify_all = flashctx->flags.verify_whole_chip;
2703 const bool verify = flashctx->flags.verify_after_write;
Edward O'Callaghan4eb85102020-12-18 13:17:08 +11002704
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002705 if (buffer_len != flash_size)
2706 return 4;
2707
2708 int ret = 1;
2709
2710 struct action_descriptor *descriptor = NULL;
2711 uint8_t *oldcontents = malloc(flash_size);
2712 uint8_t *newcontents = malloc(flash_size);
2713 if (!oldcontents || !newcontents) {
stefanctd611e8f2011-07-12 22:35:21 +00002714 msg_gerr("Out of memory!\n");
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002715 goto _free_ret;
stefanctd611e8f2011-07-12 22:35:21 +00002716 }
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002717
2718 if (prepare_flash_access(flashctx, false, true, false, verify))
2719 goto _free_ret;
hailfingerb437e282010-11-04 01:04:27 +00002720
Daniel Campelloee45dc12021-04-10 10:13:51 -06002721 if (setup_oldcontents(flashctx, oldcontents, false, refbuffer))
2722 goto _finalize_ret;
2723
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002724 memcpy(newcontents, buffer, flash_size);
2725 combine_image_by_layout(flashctx, newcontents, oldcontents);
uwef6641642007-05-09 10:17:44 +00002726
Daniel Campello57eb4882021-03-25 08:45:10 -06002727 descriptor = prepare_action_descriptor(flashctx, oldcontents, newcontents,
Daniel Campello57dd0722021-04-08 13:28:38 -06002728 !flashctx->flags.do_not_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002729
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002730 // parse the new fmap and disable soft WP if necessary
2731 if ((ret = cros_ec_prepare(newcontents, flash_size))) {
2732 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
2733 goto _finalize_ret;
2734 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002735
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002736 if (erase_and_write_flash(flashctx, descriptor)) {
2737 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2738 msg_cinfo("Reading current flash chip contents... ");
2739 if (!read_flash(flashctx, newcontents, 0, flash_size)) {
2740 msg_cinfo("done.\n");
2741 if (!memcmp(oldcontents, newcontents, flash_size)) {
2742 nonfatal_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002743 ret = 1;
Daniel Campello57eb4882021-03-25 08:45:10 -06002744 goto _finalize_ret;
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002745 }
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002746 msg_cerr("Apparently at least some data has changed.\n");
2747 } else
2748 msg_cerr("Can't even read anymore!\n");
2749 emergency_help_message();
2750 ret = 1;
2751 goto _finalize_ret;
2752 }
2753
2754 ret = cros_ec_need_2nd_pass();
2755 if (ret < 0) {
2756 // Jump failed
2757 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
2758 emergency_help_message();
2759 ret = 1;
2760 goto _finalize_ret;
2761 } else if (ret > 0) {
2762 // Need 2nd pass. Get the just written content.
2763 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daniel Campello6b0f1fc2021-04-09 21:28:12 -06002764 ret = setup_oldcontents(flashctx, oldcontents, false, NULL);
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002765 if (ret) {
2766 emergency_help_message();
2767 goto _finalize_ret;
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002768 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002769
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002770 /* Get a new descriptor. */
2771 free(descriptor);
2772 descriptor = prepare_action_descriptor(flashctx,
2773 oldcontents,
2774 newcontents,
Daniel Campello57dd0722021-04-08 13:28:38 -06002775 !flashctx->flags.do_not_diff);
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002776 // write 2nd pass
2777 if (erase_and_write_flash(flashctx, descriptor)) {
2778 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002779 emergency_help_message();
2780 ret = 1;
Daniel Campello57eb4882021-03-25 08:45:10 -06002781 goto _finalize_ret;
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002782 }
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002783 ret = 0;
2784 }
2785
2786 if (cros_ec_finish() < 0) {
2787 msg_cerr("cros_ec_finish() failed. Stop.\n");
2788 emergency_help_message();
2789 ret = 1;
2790 goto _finalize_ret;
stuge8ce3a3c2008-04-28 14:47:30 +00002791 }
ollie6a600992005-11-26 21:55:36 +00002792
Daniel Campellocd387fd2021-04-20 17:54:35 -06002793 /* Verify only if we actually changed something. */
2794 if (verify && content_has_changed) {
2795 msg_cinfo("Verifying flash... ");
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002796
Daniel Campellocd387fd2021-04-20 17:54:35 -06002797 /* Work around chips which need some time to calm down. */
2798 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002799
Daniel Campellocd387fd2021-04-20 17:54:35 -06002800 ret = verify_flash(flashctx, descriptor);
2801
2802 /* If we tried to write, and verification now fails, we
2803 might have an emergency situation. */
2804 if (ret)
2805 emergency_help_message();
2806 else
2807 msg_cinfo("VERIFIED.\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002808 }
ollie6a600992005-11-26 21:55:36 +00002809
Daniel Campello57eb4882021-03-25 08:45:10 -06002810_finalize_ret:
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002811 finalize_flash_access(flashctx);
2812_free_ret:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002813 if (descriptor)
2814 free(descriptor);
hailfinger90fcf9b2010-11-05 14:51:59 +00002815 free(oldcontents);
2816 free(newcontents);
stepan83eca252006-01-04 16:42:57 +00002817 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002818}
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002819
Daniel Campellof758a8b2021-03-22 14:47:13 -06002820/**
2821 * @brief Verify the ROM chip's contents with the specified image.
2822 *
2823 * If a layout is set in the specified flash context, only included regions
2824 * will be verified.
2825 *
2826 * @param flashctx The context of the flash chip.
2827 * @param buffer Source buffer to verify with.
2828 * @param buffer_len Size of source buffer in bytes.
2829 * @return 0 on success,
Daniel Campelloef545b12021-04-10 10:39:26 -06002830 * 3 if the chip's contents don't match,
Daniel Campellof758a8b2021-03-22 14:47:13 -06002831 * 2 if buffer_len doesn't match the size of the flash chip,
2832 * or 1 on any other failure.
2833 */
2834int flashrom_image_verify(struct flashctx *const flashctx, const void *const buffer, const size_t buffer_len)
2835{
2836 const size_t flash_size = flashctx->chip->total_size * 1024;
2837
2838 if (buffer_len != flash_size)
2839 return 2;
2840
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002841 const uint8_t *const newcontents = buffer;
Daniel Campelloef545b12021-04-10 10:39:26 -06002842 uint8_t *const curcontents = malloc(flash_size);
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002843 if (!curcontents) {
Daniel Campellof758a8b2021-03-22 14:47:13 -06002844 msg_gerr("Out of memory!\n");
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002845 return 1;
Daniel Campellof758a8b2021-03-22 14:47:13 -06002846 }
2847
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002848 int ret = 1;
2849
Daniel Campellof758a8b2021-03-22 14:47:13 -06002850 if (prepare_flash_access(flashctx, false, false, false, true))
2851 goto _free_ret;
2852
Daniel Campellof758a8b2021-03-22 14:47:13 -06002853 msg_cinfo("Verifying flash... ");
Daniel Campelloef545b12021-04-10 10:39:26 -06002854 ret = verify_by_layout(flashctx, curcontents, newcontents);
Daniel Campellof758a8b2021-03-22 14:47:13 -06002855 if (!ret)
2856 msg_cinfo("VERIFIED.\n");
2857
Daniel Campellof758a8b2021-03-22 14:47:13 -06002858 finalize_flash_access(flashctx);
2859_free_ret:
Daniel Campelloef545b12021-04-10 10:39:26 -06002860 free(curcontents);
Daniel Campellof758a8b2021-03-22 14:47:13 -06002861 return ret;
2862}
2863
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002864/** @} */ /* end flashrom-ops */
2865
2866int do_read(struct flashctx *const flash, const char *const filename)
2867{
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002868 if (prepare_flash_access(flash, true, false, false, false))
2869 return 1;
2870
Edward O'Callaghan471958e2020-12-09 12:40:12 +11002871 const int ret = read_flash_to_file(flash, filename);
2872
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002873 finalize_flash_access(flash);
2874
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002875 return ret;
2876}
2877
Daniel Campello83752f82021-04-16 14:54:27 -06002878int do_extract(struct flashctx *const flash)
2879{
2880 prepare_layout_for_extraction(flash);
2881 return do_read(flash, NULL);
2882}
2883
Edward O'Callaghan6e573be2020-12-18 10:38:06 +11002884int do_erase(struct flashctx *const flash)
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002885{
Daniel Campello26765322021-03-22 14:53:27 -06002886 const int ret = flashrom_flash_erase(flash);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002887
2888 /*
2889 * FIXME: Do we really want the scary warning if erase failed?
2890 * After all, after erase the chip is either blank or partially
2891 * blank or it has the old contents. A blank chip won't boot,
2892 * so if the user wanted erase and reboots afterwards, the user
2893 * knows very well that booting won't work.
2894 */
2895 if (ret)
2896 emergency_help_message();
2897
2898 return ret;
2899}
2900
Edward O'Callaghan6e573be2020-12-18 10:38:06 +11002901int do_write(struct flashctx *const flash, const char *const filename, const char *const referencefile)
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002902{
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002903 const size_t flash_size = flash->chip->total_size * 1024;
2904 int ret = 1;
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002905
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002906 uint8_t *const newcontents = malloc(flash_size);
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002907 uint8_t *const refcontents = referencefile ? malloc(flash_size) : NULL;
2908
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002909 if (!newcontents || (referencefile && !refcontents)) {
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002910 msg_gerr("Out of memory!\n");
2911 goto _free_ret;
2912 }
2913
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002914 /* Read '-w' argument first... */
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002915 if (filename) {
2916 if (read_buf_from_file(newcontents, flash_size, filename))
2917 goto _free_ret;
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002918 }
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002919 /*
2920 * ... then update newcontents with contents from files provided to '-i'
2921 * args if needed.
2922 */
2923 if (read_buf_from_include_args(flash, newcontents))
2924 goto _free_ret;
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002925
2926 if (referencefile) {
2927 if (read_buf_from_file(refcontents, flash_size, referencefile))
2928 goto _free_ret;
2929 }
2930
Daniel Campelloc1c1f7b2021-03-19 13:09:27 -06002931 ret = flashrom_image_write(flash, newcontents, flash_size, refcontents);
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002932
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002933_free_ret:
2934 free(refcontents);
2935 free(newcontents);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002936 return ret;
2937}
2938
Edward O'Callaghan6e573be2020-12-18 10:38:06 +11002939int do_verify(struct flashctx *const flash, const char *const filename)
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002940{
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002941 const size_t flash_size = flash->chip->total_size * 1024;
2942 int ret = 1;
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002943
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002944 uint8_t *const newcontents = malloc(flash_size);
2945 if (!newcontents) {
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002946 msg_gerr("Out of memory!\n");
2947 goto _free_ret;
2948 }
2949
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002950 /* Read '-v' argument first... */
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002951 if (filename) {
2952 if (read_buf_from_file(newcontents, flash_size, filename))
2953 goto _free_ret;
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002954 }
Daniel Campellocb88c9a2021-04-13 19:23:47 -06002955 /*
2956 * ... then update newcontents with contents from files provided to '-i'
2957 * args if needed.
2958 */
2959 if (read_buf_from_include_args(flash, newcontents))
2960 goto _free_ret;
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002961
Daniel Campellof758a8b2021-03-22 14:47:13 -06002962 ret = flashrom_image_verify(flash, newcontents, flash_size);
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002963
Daniel Campellofb0ee9c2021-03-19 12:51:25 -06002964_free_ret:
2965 free(newcontents);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002966 return ret;
2967}