blob: 8a8d951ea082b148951fd9ac0d226be58858cbc2 [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"
Simon Glass9ad06c12013-07-03 22:08:17 +090041#include "layout.h"
hailfinger428f6852010-07-27 22:41:39 +000042#include "programmer.h"
Duncan Laurie25a4ca22019-04-25 12:08:52 -070043#include "spi.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 */
53enum error_action access_denied_action = error_ignore;
54
55int ignore_error(int err) {
56 int rc = 0;
57
58 switch(err) {
59 case ACCESS_DENIED:
60 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
David Hendricksac1d25c2016-08-09 17:00:58 -070073/* Supported buses for the current programmer. */
74enum chipbustype buses_supported;
75
uwee15beb92010-08-08 17:01:18 +000076/*
hailfinger80422e22009-12-13 22:28:00 +000077 * Programmers supporting multiple buses can have differing size limits on
78 * each bus. Store the limits for each bus in a common struct.
79 */
hailfinger1ff33dc2010-07-03 11:02:10 +000080struct decode_sizes max_rom_decode;
81
82/* If nonzero, used as the start address of bottom-aligned flash. */
83unsigned long flashbase;
hailfinger80422e22009-12-13 22:28:00 +000084
hailfinger5828baf2010-07-03 12:14:25 +000085/* Is writing allowed with this programmer? */
86int programmer_may_write;
87
hailfingerabe249e2009-05-08 17:43:22 +000088const struct programmer_entry programmer_table[] = {
hailfinger90c7d542010-05-31 15:27:27 +000089#if CONFIG_INTERNAL == 1
hailfingerabe249e2009-05-08 17:43:22 +000090 {
hailfinger3548a9a2009-08-12 14:34:35 +000091 .name = "internal",
Edward O'Callaghan0949b782019-11-10 23:23:20 +110092 .type = OTHER,
93 .devs.note = NULL,
hailfinger6c69ab02009-05-11 15:46:43 +000094 .init = internal_init,
hailfinger11ae3c42009-05-11 14:13:25 +000095 .map_flash_region = physmap,
96 .unmap_flash_region = physunmap,
hailfingere5829f62009-06-05 17:48:08 +000097 .delay = internal_delay,
David Hendricks55cdd9c2015-11-25 14:37:26 -080098
99 /*
100 * "Internal" implies in-system programming on a live system, so
101 * handle with paranoia to catch errors early. If something goes
102 * wrong then hopefully the system will still be recoverable.
103 */
104 .paranoid = 1,
hailfingerabe249e2009-05-08 17:43:22 +0000105 },
hailfinger80422e22009-12-13 22:28:00 +0000106#endif
stepan927d4e22007-04-04 22:45:58 +0000107
hailfinger90c7d542010-05-31 15:27:27 +0000108#if CONFIG_DUMMY == 1
hailfingera9df33c2009-05-09 00:54:55 +0000109 {
hailfinger3548a9a2009-08-12 14:34:35 +0000110 .name = "dummy",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100111 .type = OTHER,
112 /* FIXME */
113 .devs.note = "Dummy device, does nothing and logs all accesses\n",
hailfinger6c69ab02009-05-11 15:46:43 +0000114 .init = dummy_init,
hailfinger11ae3c42009-05-11 14:13:25 +0000115 .map_flash_region = dummy_map,
116 .unmap_flash_region = dummy_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000117 .delay = internal_delay,
hailfingera9df33c2009-05-09 00:54:55 +0000118 },
hailfinger571a6b32009-09-16 10:09:21 +0000119#endif
hailfingera9df33c2009-05-09 00:54:55 +0000120
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000121#if CONFIG_MEC1308 == 1
122 {
123 .name = "mec1308",
124 .type = OTHER,
125 .devs.note = "Microchip MEC1308 Embedded Controller.\n",
126 .init = mec1308_init,
127 .map_flash_region = fallback_map,
128 .unmap_flash_region = fallback_unmap,
129 .delay = internal_delay,
130 },
131#endif
132
hailfinger90c7d542010-05-31 15:27:27 +0000133#if CONFIG_NIC3COM == 1
uwe0f5a3a22009-05-13 11:36:06 +0000134 {
hailfinger3548a9a2009-08-12 14:34:35 +0000135 .name = "nic3com",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100136 .type = PCI,
137 .devs.dev = nics_3com,
uwe0f5a3a22009-05-13 11:36:06 +0000138 .init = nic3com_init,
uwe3e656bd2009-05-17 23:12:17 +0000139 .map_flash_region = fallback_map,
140 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000141 .delay = internal_delay,
uwe0f5a3a22009-05-13 11:36:06 +0000142 },
hailfinger571a6b32009-09-16 10:09:21 +0000143#endif
uwe0f5a3a22009-05-13 11:36:06 +0000144
hailfinger90c7d542010-05-31 15:27:27 +0000145#if CONFIG_NICREALTEK == 1
hailfinger5aa36982010-05-21 21:54:07 +0000146 {
hailfinger0d703d42011-03-07 01:08:09 +0000147 /* This programmer works for Realtek RTL8139 and SMC 1211. */
uwe8d342eb2011-07-28 08:13:25 +0000148 .name = "nicrealtek",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100149 .type = PCI,
150 .devs.dev = nics_realtek,
uwe8d342eb2011-07-28 08:13:25 +0000151 .init = nicrealtek_init,
152 .map_flash_region = fallback_map,
153 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000154 .delay = internal_delay,
hailfinger5aa36982010-05-21 21:54:07 +0000155 },
hailfinger5aa36982010-05-21 21:54:07 +0000156#endif
157
hailfingerf0a368f2010-06-07 22:37:54 +0000158#if CONFIG_NICNATSEMI == 1
159 {
uwe8d342eb2011-07-28 08:13:25 +0000160 .name = "nicnatsemi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100161 .type = PCI,
162 .devs.dev = nics_natsemi,
uwe8d342eb2011-07-28 08:13:25 +0000163 .init = nicnatsemi_init,
164 .map_flash_region = fallback_map,
165 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000166 .delay = internal_delay,
hailfingerf0a368f2010-06-07 22:37:54 +0000167 },
168#endif
hailfinger5aa36982010-05-21 21:54:07 +0000169
hailfinger90c7d542010-05-31 15:27:27 +0000170#if CONFIG_GFXNVIDIA == 1
uweff4576d2009-09-30 18:29:55 +0000171 {
172 .name = "gfxnvidia",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100173 .type = PCI,
174 .devs.dev = gfx_nvidia,
uweff4576d2009-09-30 18:29:55 +0000175 .init = gfxnvidia_init,
uweff4576d2009-09-30 18:29:55 +0000176 .map_flash_region = fallback_map,
177 .unmap_flash_region = fallback_unmap,
uweff4576d2009-09-30 18:29:55 +0000178 .delay = internal_delay,
179 },
180#endif
181
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000182#if CONFIG_RAIDEN_DEBUG_SPI == 1
183 {
184 .name = "raiden_debug_spi",
185 .type = USB,
186 .devs.dev = devs_raiden,
187 .init = raiden_debug_spi_init,
188 .map_flash_region = fallback_map,
189 .unmap_flash_region = fallback_unmap,
190 .delay = internal_delay,
191 },
192#endif
193
hailfinger90c7d542010-05-31 15:27:27 +0000194#if CONFIG_DRKAISER == 1
ruikda922a12009-05-17 19:39:27 +0000195 {
uwee2f95ef2009-09-02 23:00:46 +0000196 .name = "drkaiser",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100197 .type = PCI,
198 .devs.dev = drkaiser_pcidev,
uwee2f95ef2009-09-02 23:00:46 +0000199 .init = drkaiser_init,
uwee2f95ef2009-09-02 23:00:46 +0000200 .map_flash_region = fallback_map,
201 .unmap_flash_region = fallback_unmap,
uwee2f95ef2009-09-02 23:00:46 +0000202 .delay = internal_delay,
203 },
hailfinger571a6b32009-09-16 10:09:21 +0000204#endif
uwee2f95ef2009-09-02 23:00:46 +0000205
hailfinger90c7d542010-05-31 15:27:27 +0000206#if CONFIG_SATASII == 1
uwee2f95ef2009-09-02 23:00:46 +0000207 {
hailfinger3548a9a2009-08-12 14:34:35 +0000208 .name = "satasii",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100209 .type = PCI,
210 .devs.dev = satas_sii,
ruikda922a12009-05-17 19:39:27 +0000211 .init = satasii_init,
uwe3e656bd2009-05-17 23:12:17 +0000212 .map_flash_region = fallback_map,
213 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000214 .delay = internal_delay,
ruikda922a12009-05-17 19:39:27 +0000215 },
hailfinger571a6b32009-09-16 10:09:21 +0000216#endif
ruikda922a12009-05-17 19:39:27 +0000217
hailfinger90c7d542010-05-31 15:27:27 +0000218#if CONFIG_ATAHPT == 1
uwe7e627c82010-02-21 21:17:00 +0000219 {
220 .name = "atahpt",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100221 .type = PCI,
222 .devs.dev = ata_hpt,
uwe7e627c82010-02-21 21:17:00 +0000223 .init = atahpt_init,
uwe7e627c82010-02-21 21:17:00 +0000224 .map_flash_region = fallback_map,
225 .unmap_flash_region = fallback_unmap,
uwe7e627c82010-02-21 21:17:00 +0000226 .delay = internal_delay,
227 },
228#endif
229
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000230#if CONFIG_ATAVIA == 1
231 {
232 .name = "atavia",
233 .type = PCI,
234 .devs.dev = ata_via,
235 .init = atavia_init,
236 .map_flash_region = atavia_map,
237 .unmap_flash_region = fallback_unmap,
238 .delay = internal_delay,
239 },
240#endif
241
242#if CONFIG_ATAPROMISE == 1
243 {
244 .name = "atapromise",
245 .type = PCI,
246 .devs.dev = ata_promise,
247 .init = atapromise_init,
248 .map_flash_region = atapromise_map,
249 .unmap_flash_region = fallback_unmap,
250 .delay = internal_delay,
251 },
252#endif
253
254#if CONFIG_IT8212 == 1
255 {
256 .name = "it8212",
257 .type = PCI,
258 .devs.dev = devs_it8212,
259 .init = it8212_init,
260 .map_flash_region = fallback_map,
261 .unmap_flash_region = fallback_unmap,
262 .delay = internal_delay,
263 },
264#endif
265
hailfinger90c7d542010-05-31 15:27:27 +0000266#if CONFIG_FT2232_SPI == 1
hailfingerf31da3d2009-06-16 21:08:06 +0000267 {
hailfinger90c7d542010-05-31 15:27:27 +0000268 .name = "ft2232_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100269 .type = USB,
Nikolai Artemievc347a852020-04-29 12:17:08 +1000270 .devs.dev = devs_ft2232spi,
hailfingerf31da3d2009-06-16 21:08:06 +0000271 .init = ft2232_spi_init,
hailfinger6fe23d62009-08-12 11:39:29 +0000272 .map_flash_region = fallback_map,
273 .unmap_flash_region = fallback_unmap,
hailfingerf31da3d2009-06-16 21:08:06 +0000274 .delay = internal_delay,
275 },
hailfingerd9dcfbd2009-08-19 13:27:58 +0000276#endif
hailfinger6fe23d62009-08-12 11:39:29 +0000277
hailfinger90c7d542010-05-31 15:27:27 +0000278#if CONFIG_SERPROG == 1
hailfinger37b4fbf2009-06-23 11:33:43 +0000279 {
hailfinger3548a9a2009-08-12 14:34:35 +0000280 .name = "serprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100281 .type = OTHER,
282 /* FIXME */
283 .devs.note = "All programmer devices speaking the serprog protocol\n",
hailfinger37b4fbf2009-06-23 11:33:43 +0000284 .init = serprog_init,
hailfinger37b4fbf2009-06-23 11:33:43 +0000285 .map_flash_region = fallback_map,
286 .unmap_flash_region = fallback_unmap,
hailfinger37b4fbf2009-06-23 11:33:43 +0000287 .delay = serprog_delay,
288 },
hailfinger74d88a72009-08-12 16:17:41 +0000289#endif
hailfingerf31da3d2009-06-16 21:08:06 +0000290
hailfinger90c7d542010-05-31 15:27:27 +0000291#if CONFIG_BUSPIRATE_SPI == 1
hailfinger9c5add72009-11-24 00:20:03 +0000292 {
hailfinger90c7d542010-05-31 15:27:27 +0000293 .name = "buspirate_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100294 .type = OTHER,
295 /* FIXME */
296 .devs.note = "Dangerous Prototypes Bus Pirate\n",
hailfinger9c5add72009-11-24 00:20:03 +0000297 .init = buspirate_spi_init,
hailfinger9c5add72009-11-24 00:20:03 +0000298 .map_flash_region = fallback_map,
299 .unmap_flash_region = fallback_unmap,
hailfinger9c5add72009-11-24 00:20:03 +0000300 .delay = internal_delay,
301 },
302#endif
303
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000304#if CONFIG_DEDIPROG == 1
Anton Staafb2647882014-09-17 15:13:43 -0700305 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000306 .name = "dediprog",
Brian J. Nemecb42d6c12020-07-23 03:07:38 -0700307 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000308 .init = dediprog_init,
Anton Staafb2647882014-09-17 15:13:43 -0700309 .map_flash_region = fallback_map,
310 .unmap_flash_region = fallback_unmap,
311 .delay = internal_delay,
312 },
313#endif
314
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000315#if CONFIG_DEVELOPERBOX_SPI == 1
hailfingerdfb32a02010-01-19 11:15:48 +0000316 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000317 .name = "developerbox",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100318 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000319 .devs.dev = devs_developerbox_spi,
320 .init = developerbox_spi_init,
321 .map_flash_region = fallback_map,
322 .unmap_flash_region = fallback_unmap,
323 .delay = internal_delay,
324 },
325#endif
326
327#if CONFIG_ENE_LPC == 1
328 {
329 .name = "ene_lpc",
330 .type = OTHER,
331 .devs.note = "ENE LPC interface keyboard controller\n",
332 .init = ene_lpc_init,
hailfingerdfb32a02010-01-19 11:15:48 +0000333 .map_flash_region = fallback_map,
334 .unmap_flash_region = fallback_unmap,
hailfingerdfb32a02010-01-19 11:15:48 +0000335 .delay = internal_delay,
336 },
337#endif
338
hailfinger52c4fa02010-07-21 10:26:01 +0000339#if CONFIG_RAYER_SPI == 1
340 {
341 .name = "rayer_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100342 .type = OTHER,
343 /* FIXME */
344 .devs.note = "RayeR parallel port programmer\n",
hailfinger52c4fa02010-07-21 10:26:01 +0000345 .init = rayer_spi_init,
hailfinger52c4fa02010-07-21 10:26:01 +0000346 .map_flash_region = fallback_map,
347 .unmap_flash_region = fallback_unmap,
hailfinger52c4fa02010-07-21 10:26:01 +0000348 .delay = internal_delay,
349 },
350#endif
351
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000352#if CONFIG_PONY_SPI == 1
353 {
354 .name = "pony_spi",
355 .type = OTHER,
356 /* FIXME */
357 .devs.note = "Programmers compatible with SI-Prog, serbang or AJAWe\n",
358 .init = pony_spi_init,
359 .map_flash_region = fallback_map,
360 .unmap_flash_region = fallback_unmap,
361 .delay = internal_delay,
362 },
363#endif
364
hailfinger7949b652011-05-08 00:24:18 +0000365#if CONFIG_NICINTEL == 1
366 {
367 .name = "nicintel",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100368 .type = PCI,
369 .devs.dev = nics_intel,
hailfinger7949b652011-05-08 00:24:18 +0000370 .init = nicintel_init,
hailfinger7949b652011-05-08 00:24:18 +0000371 .map_flash_region = fallback_map,
372 .unmap_flash_region = fallback_unmap,
hailfinger7949b652011-05-08 00:24:18 +0000373 .delay = internal_delay,
374 },
375#endif
376
uwe6764e922010-09-03 18:21:21 +0000377#if CONFIG_NICINTEL_SPI == 1
378 {
uwe8d342eb2011-07-28 08:13:25 +0000379 .name = "nicintel_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100380 .type = PCI,
381 .devs.dev = nics_intel_spi,
uwe8d342eb2011-07-28 08:13:25 +0000382 .init = nicintel_spi_init,
383 .map_flash_region = fallback_map,
384 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000385 .delay = internal_delay,
uwe6764e922010-09-03 18:21:21 +0000386 },
387#endif
388
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000389#if CONFIG_NICINTEL_EEPROM == 1
390 {
391 .name = "nicintel_eeprom",
392 .type = PCI,
393 .devs.dev = nics_intel_ee,
394 .init = nicintel_ee_init,
395 .map_flash_region = fallback_map,
396 .unmap_flash_region = fallback_unmap,
397 .delay = internal_delay,
398 },
399#endif
400
hailfingerfb1f31f2010-12-03 14:48:11 +0000401#if CONFIG_OGP_SPI == 1
402 {
uwe8d342eb2011-07-28 08:13:25 +0000403 .name = "ogp_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100404 .type = PCI,
405 .devs.dev = ogp_spi,
uwe8d342eb2011-07-28 08:13:25 +0000406 .init = ogp_spi_init,
407 .map_flash_region = fallback_map,
408 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000409 .delay = internal_delay,
hailfingerfb1f31f2010-12-03 14:48:11 +0000410 },
411#endif
412
hailfinger935365d2011-02-04 21:37:59 +0000413#if CONFIG_SATAMV == 1
414 {
415 .name = "satamv",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100416 .type = PCI,
417 .devs.dev = satas_mv,
hailfinger935365d2011-02-04 21:37:59 +0000418 .init = satamv_init,
hailfinger935365d2011-02-04 21:37:59 +0000419 .map_flash_region = fallback_map,
420 .unmap_flash_region = fallback_unmap,
hailfinger935365d2011-02-04 21:37:59 +0000421 .delay = internal_delay,
422 },
423#endif
424
David Hendrickscebee892015-05-23 20:30:30 -0700425#if CONFIG_LINUX_MTD == 1
426 {
427 .name = "linux_mtd",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100428 .type = OTHER,
429 .devs.note = "Device files /dev/mtd*\n",
David Hendrickscebee892015-05-23 20:30:30 -0700430 .init = linux_mtd_init,
431 .map_flash_region = fallback_map,
432 .unmap_flash_region = fallback_unmap,
433 .delay = internal_delay,
434 },
435#endif
436
uwe7df6dda2011-09-03 18:37:52 +0000437#if CONFIG_LINUX_SPI == 1
438 {
439 .name = "linux_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100440 .type = OTHER,
441 .devs.note = "Device files /dev/spidev*.*\n",
uwe7df6dda2011-09-03 18:37:52 +0000442 .init = linux_spi_init,
443 .map_flash_region = fallback_map,
444 .unmap_flash_region = fallback_unmap,
uwe7df6dda2011-09-03 18:37:52 +0000445 .delay = internal_delay,
446 },
447#endif
448
Shiyu Sun9dde7162020-04-16 17:32:55 +1000449#if CONFIG_LSPCON_I2C_SPI == 1
450 {
451 .name = "lspcon_i2c_spi",
452 .type = OTHER,
453 .devs.note = "Device files /dev/i2c-*.\n",
454 .init = lspcon_i2c_spi_init,
455 .map_flash_region = fallback_map,
456 .unmap_flash_region = fallback_unmap,
457 .delay = internal_delay,
458 },
459#endif
460
Edward O'Callaghan97dd9262020-03-26 00:00:41 +1100461#if CONFIG_REALTEK_MST_I2C_SPI == 1
462 {
463 .name = "realtek_mst_i2c_spi",
464 .type = OTHER,
465 .devs.note = "Device files /dev/i2c-*.\n",
466 .init = realtek_mst_i2c_spi_init,
467 .map_flash_region = fallback_map,
468 .unmap_flash_region = fallback_unmap,
469 .delay = internal_delay,
470 },
471#endif
472
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000473#if CONFIG_USBBLASTER_SPI == 1
474 {
475 .name = "usbblaster_spi",
476 .type = USB,
477 .devs.dev = devs_usbblasterspi,
478 .init = usbblaster_spi_init,
479 .map_flash_region = fallback_map,
480 .unmap_flash_region = fallback_unmap,
481 .delay = internal_delay,
482 },
483#endif
484
485#if CONFIG_MSTARDDC_SPI == 1
486 {
487 .name = "mstarddc_spi",
488 .type = OTHER,
489 .devs.note = "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
490 .init = mstarddc_spi_init,
491 .map_flash_region = fallback_map,
492 .unmap_flash_region = fallback_unmap,
493 .delay = internal_delay,
494 },
495#endif
496
497#if CONFIG_PICKIT2_SPI == 1
498 {
499 .name = "pickit2_spi",
500 .type = USB,
501 .devs.dev = devs_pickit2_spi,
502 .init = pickit2_spi_init,
503 .map_flash_region = fallback_map,
504 .unmap_flash_region = fallback_unmap,
505 .delay = internal_delay,
506 },
507#endif
508
509#if CONFIG_CH341A_SPI == 1
510 {
511 .name = "ch341a_spi",
512 .type = USB,
513 .devs.dev = devs_ch341a_spi,
514 .init = ch341a_spi_init,
515 .map_flash_region = fallback_map,
516 .unmap_flash_region = fallback_unmap,
517 .delay = ch341a_spi_delay,
518 },
519#endif
520
521#if CONFIG_DIGILENT_SPI == 1
522 {
523 .name = "digilent_spi",
524 .type = USB,
525 .devs.dev = devs_digilent_spi,
526 .init = digilent_spi_init,
527 .map_flash_region = fallback_map,
528 .unmap_flash_region = fallback_unmap,
529 .delay = internal_delay,
530 },
531#endif
532
533#if CONFIG_JLINK_SPI == 1
534 {
535 .name = "jlink_spi",
536 .type = OTHER,
537 .init = jlink_spi_init,
538 .devs.note = "SEGGER J-Link and compatible devices\n",
539 .map_flash_region = fallback_map,
540 .unmap_flash_region = fallback_unmap,
541 .delay = internal_delay,
542 },
543#endif
544
545#if CONFIG_NI845X_SPI == 1
546 {
547 .name = "ni845x_spi",
548 .type = OTHER, // choose other because NI-845x uses own USB implementation
549 .devs.note = "National Instruments USB-845x\n",
550 .init = ni845x_spi_init,
551 .map_flash_region = fallback_map,
552 .unmap_flash_region = fallback_unmap,
553 .delay = internal_delay,
554 },
555#endif
556
557#if CONFIG_STLINKV3_SPI == 1
558 {
559 .name = "stlinkv3_spi",
560 .type = USB,
561 .devs.dev = devs_stlinkv3_spi,
562 .init = stlinkv3_spi_init,
563 .map_flash_region = fallback_map,
564 .unmap_flash_region = fallback_unmap,
565 .delay = internal_delay,
566 },
567#endif
568
Edward O'Callaghand8f72232020-09-30 14:21:42 +1000569#if CONFIG_GOOGLE_EC == 1
570 {
571 .name = "google_ec",
572 .type = OTHER,
573 .devs.note = "Google EC.\n",
574 .init = cros_ec_probe_dev,
575 .map_flash_region = fallback_map,
576 .unmap_flash_region = fallback_unmap,
577 .delay = internal_delay,
578 },
579#endif
580
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100581 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000582};
stepan927d4e22007-04-04 22:45:58 +0000583
David Hendricksbf36f092010-11-02 23:39:29 -0700584#define CHIP_RESTORE_MAXFN 4
585static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000586static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700587 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700588 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700589 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000590} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700591
David Hendricks668f29d2011-01-27 18:51:45 -0800592
hailfingerf31cbdc2010-11-10 15:25:18 +0000593#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000594static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000595/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000596static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700597 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000598 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000599} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000600/* Initialize to 0 to make sure nobody registers a shutdown function before
601 * programmer init.
602 */
603static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000604
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700605static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000606
hailfingerdc6f7972010-02-14 01:20:28 +0000607/* Register a function to be executed on programmer shutdown.
608 * The advantage over atexit() is that you can supply a void pointer which will
609 * be used as parameter to the registered function upon programmer shutdown.
610 * This pointer can point to arbitrary data used by said function, e.g. undo
611 * information for GPIO settings etc. If unneeded, set data=NULL.
612 * Please note that the first (void *data) belongs to the function signature of
613 * the function passed as first parameter.
614 */
David Hendricks93784b42016-08-09 17:00:38 -0700615int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000616{
617 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000618 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000619 SHUTDOWN_MAXFN);
620 return 1;
621 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000622 if (!may_register_shutdown) {
623 msg_perr("Tried to register a shutdown function before "
624 "programmer init.\n");
625 return 1;
626 }
hailfingerdc6f7972010-02-14 01:20:28 +0000627 shutdown_fn[shutdown_fn_count].func = function;
628 shutdown_fn[shutdown_fn_count].data = data;
629 shutdown_fn_count++;
630
631 return 0;
632}
633
David Hendricksbf36f092010-11-02 23:39:29 -0700634//int register_chip_restore(int (*function) (void *data), void *data)
635int register_chip_restore(CHIP_RESTORE_CALLBACK,
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700636 struct flashctx *flash, uint8_t status)
David Hendricksbf36f092010-11-02 23:39:29 -0700637{
638 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
639 msg_perr("Tried to register more than %i chip restore"
640 " functions.\n", CHIP_RESTORE_MAXFN);
641 return 1;
642 }
643 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
644 chip_restore_fn[chip_restore_fn_count].flash = flash;
645 chip_restore_fn[chip_restore_fn_count].status = status;
646 chip_restore_fn_count++;
647
648 return 0;
649}
650
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000651int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000652{
hailfinger1ef766d2010-07-06 09:55:48 +0000653 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000654
655 if (prog >= PROGRAMMER_INVALID) {
656 msg_perr("Invalid programmer specified!\n");
657 return -1;
658 }
659 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000660 /* Initialize all programmer specific data. */
661 /* Default to unlimited decode sizes. */
662 max_rom_decode = (const struct decode_sizes) {
663 .parallel = 0xffffffff,
664 .lpc = 0xffffffff,
665 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000666 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000667 };
David Hendricksac1d25c2016-08-09 17:00:58 -0700668 buses_supported = BUS_NONE;
hailfinger1ff33dc2010-07-03 11:02:10 +0000669 /* Default to top aligned flash at 4 GB. */
670 flashbase = 0;
671 /* Registering shutdown functions is now allowed. */
672 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000673 /* Default to allowing writes. Broken programmers set this to 0. */
674 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000675
676 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000677 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700678 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000679 if (programmer_param && strlen(programmer_param)) {
680 if (ret != 0) {
681 /* It is quite possible that any unhandled programmer parameter would have been valid,
682 * but an error in actual programmer init happened before the parameter was evaluated.
683 */
684 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
685 programmer_param);
686 } else {
687 /* Actual programmer init was successful, but the user specified an invalid or unusable
688 * (for the current programmer configuration) parameter.
689 */
690 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
691 msg_perr("Aborting.\n");
692 ret = ERROR_FATAL;
693 }
694 }
hailfinger1ef766d2010-07-06 09:55:48 +0000695 return ret;
uweabe92a52009-05-16 22:36:00 +0000696}
697
David Hendricksbf36f092010-11-02 23:39:29 -0700698int chip_restore()
699{
700 int rc = 0;
701
702 while (chip_restore_fn_count > 0) {
703 int i = --chip_restore_fn_count;
704 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
705 chip_restore_fn[i].status);
706 }
707
708 return rc;
709}
710
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000711/** Calls registered shutdown functions and resets internal programmer-related variables.
712 * Calling it is safe even without previous initialization, but further interactions with programmer support
713 * require a call to programmer_init() (afterwards).
714 *
715 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700716int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000717{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000718 int ret = 0;
719
hailfinger1ff33dc2010-07-03 11:02:10 +0000720 /* Registering shutdown functions is no longer allowed. */
721 may_register_shutdown = 0;
722 while (shutdown_fn_count > 0) {
723 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700724 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000725 }
dhendrix0ffc2eb2011-06-14 01:35:36 +0000726 return ret;
uweabe92a52009-05-16 22:36:00 +0000727}
728
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000729void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000730{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000731 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
732 return ret;
uweabe92a52009-05-16 22:36:00 +0000733}
734
735void programmer_unmap_flash_region(void *virt_addr, size_t len)
736{
737 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000738 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000739}
740
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700741void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000742{
Craig Hesling65eb8812019-08-01 09:33:56 -0700743 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000744}
745
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700746void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000747{
Craig Hesling65eb8812019-08-01 09:33:56 -0700748 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000749}
750
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700751void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000752{
Craig Hesling65eb8812019-08-01 09:33:56 -0700753 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000754}
755
Stuart langleyc98e43f2020-03-26 20:27:36 +1100756void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000757{
Craig Hesling65eb8812019-08-01 09:33:56 -0700758 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000759}
760
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700761uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000762{
Craig Hesling65eb8812019-08-01 09:33:56 -0700763 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000764}
765
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700766uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000767{
Craig Hesling65eb8812019-08-01 09:33:56 -0700768 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000769}
770
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700771uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000772{
Craig Hesling65eb8812019-08-01 09:33:56 -0700773 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000774}
775
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000776void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
777 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000778{
Craig Hesling65eb8812019-08-01 09:33:56 -0700779 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000780}
781
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000782void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000783{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000784 if (usecs > 0)
785 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000786}
787
Edward O'Callaghana820b212020-09-17 22:53:26 +1000788int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
789 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000790{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700791 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000792
hailfinger23060112009-05-08 12:49:03 +0000793 return 0;
794}
795
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000796/* This is a somewhat hacked function similar in some ways to strtok().
797 * It will look for needle with a subsequent '=' in haystack, return a copy of
798 * needle and remove everything from the first occurrence of needle to the next
799 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000800 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000801char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000802{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000803 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000804 char *opt = NULL;
805 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000806 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000807
hailfingerf4aaccc2010-04-28 15:22:14 +0000808 needlelen = strlen(needle);
809 if (!needlelen) {
810 msg_gerr("%s: empty needle! Please report a bug at "
811 "flashrom@flashrom.org\n", __func__);
812 return NULL;
813 }
814 /* No programmer parameters given. */
815 if (*haystack == NULL)
816 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000817 param_pos = strstr(*haystack, needle);
818 do {
819 if (!param_pos)
820 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000821 /* Needle followed by '='? */
822 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000823 /* Beginning of the string? */
824 if (param_pos == *haystack)
825 break;
826 /* After a delimiter? */
827 if (strchr(delim, *(param_pos - 1)))
828 break;
829 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000830 /* Continue searching. */
831 param_pos++;
832 param_pos = strstr(param_pos, needle);
833 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000834
hailfinger6e5a52a2009-11-24 18:27:10 +0000835 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000836 /* Get the string after needle and '='. */
837 opt_pos = param_pos + needlelen + 1;
838 optlen = strcspn(opt_pos, delim);
839 /* Return an empty string if the parameter was empty. */
840 opt = malloc(optlen + 1);
841 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000842 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000843 exit(1);
844 }
hailfinger1ef766d2010-07-06 09:55:48 +0000845 strncpy(opt, opt_pos, optlen);
846 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000847 rest = opt_pos + optlen;
848 /* Skip all delimiters after the current parameter. */
849 rest += strspn(rest, delim);
850 memmove(param_pos, rest, strlen(rest) + 1);
851 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000852 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000853
hailfinger1ef766d2010-07-06 09:55:48 +0000854 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000855}
856
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000857char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000858{
859 return extract_param(&programmer_param, param_name, ",");
860}
861
stefancte1c5acf2011-07-04 07:27:17 +0000862/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700863static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000864{
865 unsigned int usable_erasefunctions = 0;
866 int k;
867 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
868 if (!check_block_eraser(flash, k, 0))
869 usable_erasefunctions++;
870 }
871 return usable_erasefunctions;
872}
873
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000874static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700875{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000876 int ret = 0, failcount = 0;
877 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700878 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000879 if (wantbuf[i] != havebuf[i]) {
880 /* Only print the first failure. */
881 if (!failcount++)
882 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
883 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700884 }
885 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000886 if (failcount) {
887 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
888 start, start + len - 1, failcount);
889 ret = -1;
890 }
891 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700892}
893
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000894/* start is an offset to the base address of the flash chip */
895static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
896{
897 int ret;
898 uint8_t *cmpbuf = malloc(len);
899 const uint8_t erased_value = ERASED_VALUE(flash);
900
901 if (!cmpbuf) {
902 msg_gerr("Could not allocate memory!\n");
903 exit(1);
904 }
905 memset(cmpbuf, erased_value, len);
906 ret = verify_range(flash, cmpbuf, start, len);
907 free(cmpbuf);
908 return ret;
909}
910
uwee15beb92010-08-08 17:01:18 +0000911/*
hailfinger7af3d192009-11-25 17:05:52 +0000912 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000913 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000914 * @start offset to the base address of the flash chip
915 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000916 * @return 0 for success, -1 for failure
917 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000918int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000919{
hailfinger7af83692009-06-15 17:23:36 +0000920 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000921 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000922
Patrick Georgif3fa2992017-02-02 16:24:44 +0100923 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000924 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000925 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000926 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000927
928 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000929 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000930 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000931 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000932 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000933 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000934
Patrick Georgif3fa2992017-02-02 16:24:44 +0100935 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000936 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000937 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100938 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000939 ret = -1;
940 goto out_free;
941 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700942 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700943 if (programmer_table[programmer].paranoid) {
944 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800945
Simon Glass4e305f42015-01-08 06:29:04 -0700946 /* limit chunksize in order to catch errors early */
947 for (i = 0, chunksize = 0; i < len; i += chunksize) {
948 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800949
Patrick Georgif3fa2992017-02-02 16:24:44 +0100950 chunksize = min(flash->chip->page_size, len - i);
951 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700952 if (tmp) {
953 ret = tmp;
954 if (ignore_error(tmp))
955 continue;
956 else
957 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800958 }
Simon Glass4e305f42015-01-08 06:29:04 -0700959
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700960 /*
961 * Check write access permission and do not compare chunks
962 * where flashrom does not have write access to the region.
963 */
964 if (flash->chip->check_access) {
965 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
966 if (tmp && ignore_error(tmp))
967 continue;
968 }
969
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000970 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700971 if (failcount)
972 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800973 }
Simon Glass4e305f42015-01-08 06:29:04 -0700974 } else {
975 int tmp;
976
977 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +0100978 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -0700979 if (tmp && !ignore_error(tmp)) {
980 ret = tmp;
981 goto out_free;
982 }
983
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000984 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +0000985 }
986
hailfinger5be6c0f2009-07-23 01:42:56 +0000987 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +0000988 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +0000989 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +0000990 ret = -1;
991 }
hailfinger7af83692009-06-15 17:23:36 +0000992
993out_free:
994 free(readbuf);
995 return ret;
996}
997
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100998/* Helper function for need_erase() that focuses on granularities of gran bytes. */
999static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001000 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001001{
1002 unsigned int i, j, limit;
1003 for (j = 0; j < len / gran; j++) {
1004 limit = min (gran, len - j * gran);
1005 /* Are 'have' and 'want' identical? */
1006 if (!memcmp(have + j * gran, want + j * gran, limit))
1007 continue;
1008 /* have needs to be in erased state. */
1009 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001010 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001011 return 1;
1012 }
1013 return 0;
1014}
1015
uwee15beb92010-08-08 17:01:18 +00001016/*
hailfingerb247c7a2010-03-08 00:42:32 +00001017 * Check if the buffer @have can be programmed to the content of @want without
1018 * erasing. This is only possible if all chunks of size @gran are either kept
1019 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001020 *
hailfingerb437e282010-11-04 01:04:27 +00001021 * Warning: This function assumes that @have and @want point to naturally
1022 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001023 *
1024 * @have buffer with current content
1025 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001026 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001027 * @gran write granularity (enum, not count)
1028 * @return 0 if no erase is needed, 1 otherwise
1029 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001030int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1031 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001032{
hailfingerb91c08c2011-08-15 19:54:20 +00001033 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001034 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001035
hailfingerb247c7a2010-03-08 00:42:32 +00001036 switch (gran) {
1037 case write_gran_1bit:
1038 for (i = 0; i < len; i++)
1039 if ((have[i] & want[i]) != want[i]) {
1040 result = 1;
1041 break;
1042 }
1043 break;
1044 case write_gran_1byte:
1045 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001046 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001047 result = 1;
1048 break;
1049 }
1050 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001051 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001052 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001053 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001054 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001055 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001056 break;
1057 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001058 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001059 break;
1060 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001061 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001062 break;
1063 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001064 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001065 break;
1066 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001067 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001068 break;
1069 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001070 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001071 break;
1072 case write_gran_1byte_implicit_erase:
1073 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1074 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001075 break;
hailfingerb437e282010-11-04 01:04:27 +00001076 default:
1077 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1078 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001079 }
1080 return result;
1081}
1082
hailfingerb437e282010-11-04 01:04:27 +00001083/**
1084 * Check if the buffer @have needs to be programmed to get the content of @want.
1085 * If yes, return 1 and fill in first_start with the start address of the
1086 * write operation and first_len with the length of the first to-be-written
1087 * chunk. If not, return 0 and leave first_start and first_len undefined.
1088 *
1089 * Warning: This function assumes that @have and @want point to naturally
1090 * aligned regions.
1091 *
1092 * @have buffer with current content
1093 * @want buffer with desired content
1094 * @len length of the checked area
1095 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001096 * @first_start offset of the first byte which needs to be written (passed in
1097 * value is increased by the offset of the first needed write
1098 * relative to have/want or unchanged if no write is needed)
1099 * @return length of the first contiguous area which needs to be written
1100 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001101 *
1102 * FIXME: This function needs a parameter which tells it about coalescing
1103 * in relation to the max write length of the programmer and the max write
1104 * length of the chip.
1105 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001106static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001107 unsigned int *first_start,
1108 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001109{
stefanctc5eb8a92011-11-23 09:13:48 +00001110 int need_write = 0;
1111 unsigned int rel_start = 0, first_len = 0;
1112 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001113
hailfingerb437e282010-11-04 01:04:27 +00001114 switch (gran) {
1115 case write_gran_1bit:
1116 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001117 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001118 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001119 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001120 case write_gran_128bytes:
1121 stride = 128;
1122 break;
hailfingerb437e282010-11-04 01:04:27 +00001123 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001124 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001125 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001126 case write_gran_264bytes:
1127 stride = 264;
1128 break;
1129 case write_gran_512bytes:
1130 stride = 512;
1131 break;
1132 case write_gran_528bytes:
1133 stride = 528;
1134 break;
1135 case write_gran_1024bytes:
1136 stride = 1024;
1137 break;
1138 case write_gran_1056bytes:
1139 stride = 1056;
1140 break;
hailfingerb437e282010-11-04 01:04:27 +00001141 default:
1142 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1143 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001144 /* Claim that no write was needed. A write with unknown
1145 * granularity is too dangerous to try.
1146 */
1147 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001148 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001149 for (i = 0; i < len / stride; i++) {
1150 limit = min(stride, len - i * stride);
1151 /* Are 'have' and 'want' identical? */
1152 if (memcmp(have + i * stride, want + i * stride, limit)) {
1153 if (!need_write) {
1154 /* First location where have and want differ. */
1155 need_write = 1;
1156 rel_start = i * stride;
1157 }
1158 } else {
1159 if (need_write) {
1160 /* First location where have and want
1161 * do not differ anymore.
1162 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001163 break;
1164 }
1165 }
1166 }
hailfingerffb7f382010-12-06 13:05:44 +00001167 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001168 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001169 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001170 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001171}
1172
hailfinger0c515352009-11-23 12:55:31 +00001173/* This function generates various test patterns useful for testing controller
1174 * and chip communication as well as chip behaviour.
1175 *
1176 * If a byte can be written multiple times, each time keeping 0-bits at 0
1177 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1178 * is essentially an AND operation. That's also the reason why this function
1179 * provides the result of AND between various patterns.
1180 *
1181 * Below is a list of patterns (and their block length).
1182 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1183 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1184 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1185 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1186 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1187 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1188 * Pattern 6 is 00 (1 Byte)
1189 * Pattern 7 is ff (1 Byte)
1190 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1191 * byte block.
1192 *
1193 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1194 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1195 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1196 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1197 * Pattern 12 is 00 (1 Byte)
1198 * Pattern 13 is ff (1 Byte)
1199 * Patterns 8-13 have no block number.
1200 *
1201 * Patterns 0-3 are created to detect and efficiently diagnose communication
1202 * slips like missed bits or bytes and their repetitive nature gives good visual
1203 * cues to the person inspecting the results. In addition, the following holds:
1204 * AND Pattern 0/1 == Pattern 4
1205 * AND Pattern 2/3 == Pattern 5
1206 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1207 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1208 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1209 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1210 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1211 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1212 * Besides that, they provide for bit testing of the last two bytes of every
1213 * 256 byte block which contains the block number for patterns 0-6.
1214 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1215 * block sizes >256 bytes (some Dataflash chips etc.)
1216 * AND Pattern 8/9 == Pattern 12
1217 * AND Pattern 10/11 == Pattern 12
1218 * Pattern 13 is the completely erased state.
1219 * None of the patterns can detect aliasing at boundaries which are a multiple
1220 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1221 */
1222int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1223{
1224 int i;
1225
1226 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001227 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001228 return 1;
1229 }
1230
1231 switch (variant) {
1232 case 0:
1233 for (i = 0; i < size; i++)
1234 buf[i] = (i & 0xf) << 4 | 0x5;
1235 break;
1236 case 1:
1237 for (i = 0; i < size; i++)
1238 buf[i] = (i & 0xf) << 4 | 0xa;
1239 break;
1240 case 2:
1241 for (i = 0; i < size; i++)
1242 buf[i] = 0x50 | (i & 0xf);
1243 break;
1244 case 3:
1245 for (i = 0; i < size; i++)
1246 buf[i] = 0xa0 | (i & 0xf);
1247 break;
1248 case 4:
1249 for (i = 0; i < size; i++)
1250 buf[i] = (i & 0xf) << 4;
1251 break;
1252 case 5:
1253 for (i = 0; i < size; i++)
1254 buf[i] = i & 0xf;
1255 break;
1256 case 6:
1257 memset(buf, 0x00, size);
1258 break;
1259 case 7:
1260 memset(buf, 0xff, size);
1261 break;
1262 case 8:
1263 for (i = 0; i < size; i++)
1264 buf[i] = i & 0xff;
1265 break;
1266 case 9:
1267 for (i = 0; i < size; i++)
1268 buf[i] = ~(i & 0xff);
1269 break;
1270 case 10:
1271 for (i = 0; i < size % 2; i++) {
1272 buf[i * 2] = (i >> 8) & 0xff;
1273 buf[i * 2 + 1] = i & 0xff;
1274 }
1275 if (size & 0x1)
1276 buf[i * 2] = (i >> 8) & 0xff;
1277 break;
1278 case 11:
1279 for (i = 0; i < size % 2; i++) {
1280 buf[i * 2] = ~((i >> 8) & 0xff);
1281 buf[i * 2 + 1] = ~(i & 0xff);
1282 }
1283 if (size & 0x1)
1284 buf[i * 2] = ~((i >> 8) & 0xff);
1285 break;
1286 case 12:
1287 memset(buf, 0x00, size);
1288 break;
1289 case 13:
1290 memset(buf, 0xff, size);
1291 break;
1292 }
1293
1294 if ((variant >= 0) && (variant <= 7)) {
1295 /* Write block number in the last two bytes of each 256-byte
1296 * block, big endian for easier reading of the hexdump.
1297 * Note that this wraps around for chips larger than 2^24 bytes
1298 * (16 MB).
1299 */
1300 for (i = 0; i < size / 256; i++) {
1301 buf[i * 256 + 254] = (i >> 8) & 0xff;
1302 buf[i * 256 + 255] = i & 0xff;
1303 }
1304 }
1305
1306 return 0;
1307}
1308
hailfingeraec9c962009-10-31 01:53:09 +00001309int check_max_decode(enum chipbustype buses, uint32_t size)
1310{
1311 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001312
1313 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001314 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001315 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001316 "size %u kB of chipset/board/programmer "
1317 "for %s interface, "
1318 "probe/read/erase/write may fail. ", size / 1024,
1319 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001320 }
hailfingere1e41ea2011-07-27 07:13:06 +00001321 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001322 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001323 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001324 "size %u kB of chipset/board/programmer "
1325 "for %s interface, "
1326 "probe/read/erase/write may fail. ", size / 1024,
1327 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001328 }
hailfingere1e41ea2011-07-27 07:13:06 +00001329 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001330 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001331 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001332 "size %u kB of chipset/board/programmer "
1333 "for %s interface, "
1334 "probe/read/erase/write may fail. ", size / 1024,
1335 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001336 }
hailfingere1e41ea2011-07-27 07:13:06 +00001337 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001338 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001339 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001340 "size %u kB of chipset/board/programmer "
1341 "for %s interface, "
1342 "probe/read/erase/write may fail. ", size / 1024,
1343 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001344 }
1345 if (!limitexceeded)
1346 return 0;
1347 /* Sometimes chip and programmer have more than one bus in common,
1348 * and the limit is not exceeded on all buses. Tell the user.
1349 */
1350 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001351 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001352 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001353 "interface which can support a chip of this size. "
1354 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001355 return 1;
1356}
1357
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001358void unmap_flash(struct flashctx *flash)
1359{
1360 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1361 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1362 flash->physical_registers = 0;
1363 flash->virtual_registers = (chipaddr)ERROR_PTR;
1364 }
1365
1366 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1367 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1368 flash->physical_memory = 0;
1369 flash->virtual_memory = (chipaddr)ERROR_PTR;
1370 }
1371}
1372
1373int map_flash(struct flashctx *flash)
1374{
1375 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1376 flash->virtual_memory = (chipaddr)ERROR_PTR;
1377 flash->virtual_registers = (chipaddr)ERROR_PTR;
1378
1379 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1380 * These are used for various probing-related hacks that would not map successfully anyway and should be
1381 * removed ASAP. */
1382 if (flash->chip->total_size == 0)
1383 return 0;
1384
1385 const chipsize_t size = flash->chip->total_size * 1024;
1386 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1387 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1388 if (addr == ERROR_PTR) {
1389 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1390 flash->chip->name, PRIxPTR_WIDTH, base);
1391 return 1;
1392 }
1393 flash->physical_memory = base;
1394 flash->virtual_memory = (chipaddr)addr;
1395
1396 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1397 * completely different on some chips and programmers, or not mappable at all.
1398 * Ignore these problems for now and always report success. */
1399 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1400 base = 0xffffffff - size - 0x400000 + 1;
1401 addr = programmer_map_flash_region("flash chip registers", base, size);
1402 if (addr == ERROR_PTR) {
1403 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1404 flash->chip->name, PRIxPTR_WIDTH, base);
1405 return 0;
1406 }
1407 flash->physical_registers = base;
1408 flash->virtual_registers = (chipaddr)addr;
1409 }
1410 return 0;
1411}
1412
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001413/*
1414 * Return a string corresponding to the bustype parameter.
1415 * Memory is obtained with malloc() and must be freed with free() by the caller.
1416 */
1417char *flashbuses_to_text(enum chipbustype bustype)
1418{
1419 char *ret = calloc(1, 1);
1420 /*
1421 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1422 * will cease to exist and should be eliminated here as well.
1423 */
1424 if (bustype == BUS_NONSPI) {
1425 ret = strcat_realloc(ret, "Non-SPI, ");
1426 } else {
1427 if (bustype & BUS_PARALLEL)
1428 ret = strcat_realloc(ret, "Parallel, ");
1429 if (bustype & BUS_LPC)
1430 ret = strcat_realloc(ret, "LPC, ");
1431 if (bustype & BUS_FWH)
1432 ret = strcat_realloc(ret, "FWH, ");
1433 if (bustype & BUS_SPI)
1434 ret = strcat_realloc(ret, "SPI, ");
1435 if (bustype & BUS_PROG)
1436 ret = strcat_realloc(ret, "Programmer-specific, ");
1437 if (bustype == BUS_NONE)
1438 ret = strcat_realloc(ret, "None, ");
1439 }
1440 /* Kill last comma. */
1441 ret[strlen(ret) - 2] = '\0';
1442 ret = realloc(ret, strlen(ret) + 1);
1443 return ret;
1444}
1445
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001446int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001447{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001448 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001449 uint32_t size;
1450 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001451 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001452
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301453 /* Based on the host controller interface that a platform
1454 * needs to use (hwseq or swseq),
1455 * set the flashchips list here.
1456 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001457 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301458 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001459 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301460 flash_list = flashchips_hwseq;
1461 break;
1462 default:
1463 flash_list = flashchips;
1464 break;
1465 }
1466
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001467 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1468 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001469 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001470 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001471 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001472 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001473 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001474 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001475 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001476 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001477 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001478 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001479 continue;
1480 }
stepan782fb172007-04-06 11:58:03 +00001481
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001482 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001483 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001484
hailfinger48ed3e22011-05-04 00:39:50 +00001485 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001486 flash->chip = calloc(1, sizeof(struct flashchip));
1487 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001488 msg_gerr("Out of memory!\n");
1489 exit(1);
1490 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001491 memcpy(flash->chip, chip, sizeof(struct flashchip));
1492 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001493
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001494 if (map_flash(flash) != 0)
1495 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001496
Edward O'Callaghana820b212020-09-17 22:53:26 +10001497 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1498 * is only called with force=1 after normal probing failed.
1499 */
stugec1e55fe2008-07-02 17:15:47 +00001500 if (force)
1501 break;
stepanc98b80b2006-03-16 16:57:41 +00001502
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001503 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001504 goto notfound;
1505
hailfinger48ed3e22011-05-04 00:39:50 +00001506 /* If this is the first chip found, accept it.
1507 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001508 * a non-generic match. SFDP and CFI are generic matches.
1509 * startchip==0 means this call to probe_flash() is the first
1510 * one for this programmer interface (master) and thus no other chip has
1511 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001512 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001513 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1514 msg_cinfo("===\n"
1515 "SFDP has autodetected a flash chip which is "
1516 "not natively supported by flashrom yet.\n");
1517 if (count_usable_erasers(flash) == 0)
1518 msg_cinfo("The standard operations read and "
1519 "verify should work, but to support "
1520 "erase, write and all other "
1521 "possible features");
1522 else
1523 msg_cinfo("All standard operations (read, "
1524 "verify, erase and write) should "
1525 "work, but to support all possible "
1526 "features");
1527
1528 msg_cinfo(" we need to add them manually.\n"
1529 "You can help us by mailing us the output of the following command to "
1530 "flashrom@flashrom.org:\n"
1531 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1532 "Thanks for your help!\n"
1533 "===\n");
1534 }
stugec1e55fe2008-07-02 17:15:47 +00001535
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001536 /* First flash chip detected on this bus. */
1537 if (startchip == 0)
1538 break;
1539 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001540 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001541 break;
1542 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001543notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001544 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001545 free(flash->chip);
1546 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001547 }
uwebe4477b2007-08-23 16:08:21 +00001548
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001549 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001550 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001551
stepan3e7aeae2011-01-19 06:21:54 +00001552
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001553 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001554 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1555 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001556 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001557#if CONFIG_INTERNAL == 1
1558 if (programmer_table[programmer].map_flash_region == physmap)
1559 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1560 PRIxPTR_WIDTH, flash->physical_memory);
1561 else
1562#endif
1563 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001564
Edward O'Callaghana820b212020-09-17 22:53:26 +10001565 /* Flash registers may more likely not be mapped if the chip was forced.
1566 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001567 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001568 if (flash->chip->printlock)
1569 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001570
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001571 /* Get out of the way for later runs. */
1572 unmap_flash(flash);
1573
hailfinger48ed3e22011-05-04 00:39:50 +00001574 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001575 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001576}
1577
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001578static int verify_flash(struct flashctx *flash,
1579 struct action_descriptor *descriptor,
1580 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001581{
hailfingerb0f4d122009-06-24 08:20:45 +00001582 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001583 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001584 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001585
snelsone42c3802010-05-07 20:09:04 +00001586 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001587
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001588 if (verify_it == VERIFY_PARTIAL) {
1589 struct processing_unit *pu = descriptor->processing_units;
1590
1591 /* Verify only areas which were written. */
1592 while (pu->num_blocks) {
1593 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001594 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001595 if (ret)
1596 break;
1597 pu++;
1598 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001599 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001600 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001601 }
uwef6641642007-05-09 10:17:44 +00001602
David Hendricks1ed1d352011-11-23 17:54:37 -08001603 if (ret == ACCESS_DENIED) {
1604 msg_gdbg("Could not fully verify due to access error, ");
1605 if (access_denied_action == error_ignore) {
1606 msg_gdbg("ignoring\n");
1607 ret = 0;
1608 } else {
1609 msg_gdbg("aborting\n");
1610 }
1611 }
1612
hailfingerb0f4d122009-06-24 08:20:45 +00001613 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001614 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001615
hailfingerb0f4d122009-06-24 08:20:45 +00001616 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001617}
1618
uwe8d342eb2011-07-28 08:13:25 +00001619int read_buf_from_file(unsigned char *buf, unsigned long size,
1620 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001621{
1622 unsigned long numbytes;
1623 FILE *image;
1624 struct stat image_stat;
1625
Vincent Palatin7ab23932014-10-01 12:09:16 -07001626 if (!strncmp(filename, "-", sizeof("-")))
1627 image = fdopen(STDIN_FILENO, "rb");
1628 else
1629 image = fopen(filename, "rb");
1630 if (image == NULL) {
hailfinger771fc182010-10-15 00:01:14 +00001631 perror(filename);
1632 return 1;
1633 }
1634 if (fstat(fileno(image), &image_stat) != 0) {
1635 perror(filename);
1636 fclose(image);
1637 return 1;
1638 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001639 if ((image_stat.st_size != size) &&
1640 (strncmp(filename, "-", sizeof("-")))) {
Mike Frysinger62c794d2017-05-29 12:02:45 -04001641 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1642 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
hailfinger771fc182010-10-15 00:01:14 +00001643 fclose(image);
1644 return 1;
1645 }
1646 numbytes = fread(buf, 1, size, image);
1647 if (fclose(image)) {
1648 perror(filename);
1649 return 1;
1650 }
1651 if (numbytes != size) {
1652 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1653 "wanted %ld!\n", numbytes, size);
1654 return 1;
1655 }
1656 return 0;
1657}
1658
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001659int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001660{
1661 unsigned long numbytes;
1662 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001663
1664 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001665 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001666 return 1;
1667 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001668 if (!strncmp(filename, "-", sizeof("-")))
1669 image = fdopen(STDOUT_FILENO, "wb");
1670 else
1671 image = fopen(filename, "wb");
1672 if (image == NULL) {
hailfingerd219a232009-01-28 00:27:54 +00001673 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001674 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001675 }
hailfingerd219a232009-01-28 00:27:54 +00001676
hailfingerd219a232009-01-28 00:27:54 +00001677 numbytes = fwrite(buf, 1, size, image);
1678 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001679 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001680 msg_gerr("Error: file %s could not be written completely.\n", filename);
hailfingerd219a232009-01-28 00:27:54 +00001681 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001682 }
hailfingerd219a232009-01-28 00:27:54 +00001683 return 0;
1684}
1685
David Hendrickse3451942013-03-21 17:23:29 -07001686/*
1687 * read_flash - wrapper for flash->read() with additional high-level policy
1688 *
1689 * @flash flash chip
1690 * @buf buffer to store data in
1691 * @start start address
1692 * @len number of bytes to read
1693 *
1694 * This wrapper simplifies most cases when the flash chip needs to be read
1695 * since policy decisions such as non-fatal error handling is centralized.
1696 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001697int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001698 unsigned int start, unsigned int len)
1699{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001700 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001701
Patrick Georgif3fa2992017-02-02 16:24:44 +01001702 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001703 return -1;
1704
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001705 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1706
Patrick Georgif3fa2992017-02-02 16:24:44 +01001707 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001708 if (ret) {
1709 if (ignore_error(ret)) {
1710 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1711 start, start + len - 1);
1712 ret = 0;
1713 } else {
1714 msg_gdbg("failed to read 0x%x-0x%x\n",
1715 start, start + len - 1);
1716 }
1717 }
1718
1719 return ret;
1720}
1721
David Hendricks7c8a1612013-04-26 19:14:44 -07001722/*
1723 * write_flash - wrapper for flash->write() with additional high-level policy
1724 *
1725 * @flash flash chip
1726 * @buf buffer to write to flash
1727 * @start start address in flash
1728 * @len number of bytes to write
1729 *
1730 * TODO: Look up regions that are write-protected and avoid attempt to write
1731 * to them at all.
1732 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001733int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001734 unsigned int start, unsigned int len)
1735{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001736 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001737 return -1;
1738
Patrick Georgif3fa2992017-02-02 16:24:44 +01001739 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001740}
1741
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001742int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001743{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001744 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001745 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001746 int ret = 0;
1747
1748 msg_cinfo("Reading flash... ");
1749 if (!buf) {
1750 msg_gerr("Memory allocation failed!\n");
1751 msg_cinfo("FAILED.\n");
1752 return 1;
1753 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001754
1755 /* To support partial read, fill buffer to all 0xFF at beginning to make
1756 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001757 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001758
Patrick Georgif3fa2992017-02-02 16:24:44 +01001759 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001760 msg_cerr("No read function available for this flash chip.\n");
1761 ret = 1;
1762 goto out_free;
1763 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001764
1765 /* First try to handle partial read case, rather than read the whole
1766 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001767 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001768 if (ret < 0) {
1769 msg_cerr("Partial read operation failed!\n");
1770 ret = 1;
1771 goto out_free;
1772 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001773 int num_regions = get_num_include_args();
1774
1775 if (ret != num_regions) {
1776 msg_cerr("Requested %d regions, but only read %d\n",
1777 num_regions, ret);
1778 ret = 1;
1779 goto out_free;
1780 }
1781
1782 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001783 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001784 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001785 msg_cerr("Read operation failed!\n");
1786 ret = 1;
1787 goto out_free;
1788 }
hailfinger42a850a2010-07-13 23:56:13 +00001789 }
1790
David Hendricksdf29a832013-06-28 14:33:51 -07001791 if (filename)
1792 ret = write_buf_to_file(buf, size, filename);
1793
hailfinger42a850a2010-07-13 23:56:13 +00001794out_free:
1795 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001796 if (ret)
1797 msg_cerr("FAILED.");
1798 else
1799 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001800 return ret;
1801}
1802
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001803/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001804static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001805{
hailfingerb91c08c2011-08-15 19:54:20 +00001806 int i, j, k;
1807 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001808
1809 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1810 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001811 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001812
1813 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1814 /* Blocks with zero size are bugs in flashchips.c. */
1815 if (eraser.eraseblocks[i].count &&
1816 !eraser.eraseblocks[i].size) {
1817 msg_gerr("ERROR: Flash chip %s erase function "
1818 "%i region %i has size 0. Please report"
1819 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001820 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001821 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001822 }
1823 /* Blocks with zero count are bugs in flashchips.c. */
1824 if (!eraser.eraseblocks[i].count &&
1825 eraser.eraseblocks[i].size) {
1826 msg_gerr("ERROR: Flash chip %s erase function "
1827 "%i region %i has count 0. Please report"
1828 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001829 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001830 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001831 }
1832 done += eraser.eraseblocks[i].count *
1833 eraser.eraseblocks[i].size;
1834 }
hailfinger9fed35d2010-01-19 06:42:46 +00001835 /* Empty eraseblock definition with erase function. */
1836 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001837 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001838 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001839 if (!done)
1840 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001841 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001842 msg_gerr("ERROR: Flash chip %s erase function %i "
1843 "region walking resulted in 0x%06x bytes total,"
1844 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001845 " flashrom@flashrom.org\n", chip->name, k,
1846 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001847 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001848 }
hailfinger9fed35d2010-01-19 06:42:46 +00001849 if (!eraser.block_erase)
1850 continue;
1851 /* Check if there are identical erase functions for different
1852 * layouts. That would imply "magic" erase functions. The
1853 * easiest way to check this is with function pointers.
1854 */
uwef6f94d42010-03-13 17:28:29 +00001855 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001856 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001857 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001858 msg_gerr("ERROR: Flash chip %s erase function "
1859 "%i and %i are identical. Please report"
1860 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001861 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001862 ret = 1;
1863 }
uwef6f94d42010-03-13 17:28:29 +00001864 }
hailfinger45177872010-01-18 08:14:43 +00001865 }
hailfinger9fed35d2010-01-19 06:42:46 +00001866 return ret;
hailfinger45177872010-01-18 08:14:43 +00001867}
1868
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001869static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001870 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001871 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001872 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001873 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001874 unsigned int addr,
1875 unsigned int len))
1876{
stefanctc5eb8a92011-11-23 09:13:48 +00001877 unsigned int starthere = 0, lenhere = 0;
1878 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001879 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001880 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001881
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001882 /*
1883 * curcontents and newcontents are opaque to walk_eraseregions, and
1884 * need to be adjusted here to keep the impression of proper
1885 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001886 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001887
hailfinger90fcf9b2010-11-05 14:51:59 +00001888 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001889
hailfingerb437e282010-11-04 01:04:27 +00001890 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001891
hailfingerb437e282010-11-04 01:04:27 +00001892 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001893 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001894 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001895 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001896 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001897 if (ret) {
1898 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001899 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001900 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001901 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001902 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001903 }
1904
David Hendricks0954ffc2015-11-13 15:15:44 -08001905 if (programmer_table[programmer].paranoid) {
1906 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001907 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001908 return -1;
1909 }
hailfingerac8e3182011-06-26 17:04:16 +00001910 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001911
hailfinger90fcf9b2010-11-05 14:51:59 +00001912 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001913 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001914 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001915 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001916 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001917 /* get_next_write() sets starthere to a new value after the call. */
1918 while ((lenhere = get_next_write(curcontents + starthere,
1919 newcontents + starthere,
1920 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001921 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001922 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001923 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001924 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001925 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001926 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001927 if (ret) {
1928 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001929 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001930 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001931 }
David Hendricks048b38c2016-03-28 18:47:06 -07001932
1933 /*
1934 * If the block needed to be erased and was erased successfully
1935 * then we can assume that we didn't run into any write-
1936 * protected areas. Otherwise, we need to verify each page to
1937 * ensure it was successfully written and abort if we encounter
1938 * any errors.
1939 */
1940 if (programmer_table[programmer].paranoid && !block_was_erased) {
1941 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001942 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001943 return -1;
1944 }
1945
hailfingerb437e282010-11-04 01:04:27 +00001946 starthere += lenhere;
1947 skip = 0;
1948 }
1949 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001950 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001951 return ret;
1952}
1953
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001954/*
1955 * Function to process processing units accumulated in the action descriptor.
1956 *
1957 * @flash pointer to the flash context to operate on
1958 * @do_something helper function which can erase and program a section of the
1959 * flash chip. It receives the flash context, offset and length
1960 * of the area to erase/program, before and after contents (to
1961 * decide what exactly needs to be erased and or programmed)
1962 * and a pointer to the erase function which can operate on the
1963 * proper granularity.
1964 * @descriptor action descriptor including pointers to before and after
1965 * contents and an array of processing actions to take.
1966 *
1967 * Returns zero on success or an error code.
1968 */
1969static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001970 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001971 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001972 unsigned int len,
1973 uint8_t *param1,
1974 uint8_t *param2,
1975 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001976 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001977 unsigned int addr,
1978 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001979 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00001980{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001981 struct processing_unit *pu;
1982 int rc = 0;
1983 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00001984
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001985 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1986 unsigned base = pu->offset;
1987 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07001988
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001989 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07001990
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001991 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00001992 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001993 else
1994 print_comma = 1;
1995
1996 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1997
1998 rc = do_something(flash, base,
1999 pu->block_size,
2000 descriptor->oldcontents,
2001 descriptor->newcontents,
2002 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
2003
David Hendricks1ed1d352011-11-23 17:54:37 -08002004 if (rc) {
2005 if (ignore_error(rc))
2006 rc = 0;
2007 else
2008 return rc;
hailfingerb437e282010-11-04 01:04:27 +00002009 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002010 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00002011 }
2012 }
hailfingerb437e282010-11-04 01:04:27 +00002013 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08002014 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00002015}
2016
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002017static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00002018{
Patrick Georgif3fa2992017-02-02 16:24:44 +01002019 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00002020
2021 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
2022 if (log)
2023 msg_cdbg("not defined. ");
2024 return 1;
2025 }
2026 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
2027 if (log)
2028 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00002029 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00002030 return 1;
2031 }
2032 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
2033 if (log)
2034 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00002035 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00002036 return 1;
2037 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002038 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002039 return 0;
2040}
2041
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002042int erase_and_write_flash(struct flashctx *flash,
2043 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002044{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002045 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002046
hailfingercf848f12010-12-05 15:14:44 +00002047 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002048
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002049 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002050
hailfinger7df21362009-09-05 02:30:58 +00002051 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002052 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002053 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002054 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002055 }
2056 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002057}
2058
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002059static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002060{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002061 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2062#if CONFIG_INTERNAL == 1
2063 if (programmer == PROGRAMMER_INTERNAL)
2064 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2065 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2066 "mail flashrom@flashrom.org, thanks!\n"
2067 "-------------------------------------------------------------------------------\n"
2068 "You may now reboot or simply leave the machine running.\n");
2069 else
2070#endif
2071 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2072 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2073 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2074 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002075}
2076
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002077static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002078{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002079 msg_gerr("Your flash chip is in an unknown state.\n");
2080#if CONFIG_INTERNAL == 1
2081 if (programmer == PROGRAMMER_INTERNAL)
2082 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2083 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2084 "-------------------------------------------------------------------------------\n"
2085 "DO NOT REBOOT OR POWEROFF!\n");
2086 else
2087#endif
2088 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2089 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002090}
2091
hailfingerf79d1712010-10-06 23:48:34 +00002092void list_programmers_linebreak(int startcol, int cols, int paren)
2093{
2094 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002095 int pnamelen;
2096 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002097 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002098 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002099
2100 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2101 pname = programmer_table[p].name;
2102 pnamelen = strlen(pname);
2103 if (remaining - pnamelen - 2 < 0) {
2104 if (firstline)
2105 firstline = 0;
2106 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002107 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002108 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002109 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002110 remaining = cols - startcol;
2111 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002112 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002113 remaining--;
2114 }
2115 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002116 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002117 remaining--;
2118 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002119 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002120 remaining -= pnamelen;
2121 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002122 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002123 remaining--;
2124 } else {
2125 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002126 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002127 }
2128 }
2129}
2130
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002131static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002132{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002133#if IS_WINDOWS
2134 SYSTEM_INFO si;
2135 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002136
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002137 memset(&si, 0, sizeof(SYSTEM_INFO));
2138 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2139 msg_ginfo(" on Windows");
2140 /* Tell Windows which version of the structure we want. */
2141 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2142 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2143 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2144 else
2145 msg_ginfo(" unknown version");
2146 GetSystemInfo(&si);
2147 switch (si.wProcessorArchitecture) {
2148 case PROCESSOR_ARCHITECTURE_AMD64:
2149 msg_ginfo(" (x86_64)");
2150 break;
2151 case PROCESSOR_ARCHITECTURE_INTEL:
2152 msg_ginfo(" (x86)");
2153 break;
2154 default:
2155 msg_ginfo(" (unknown arch)");
2156 break;
2157 }
2158#elif HAVE_UTSNAME == 1
2159 struct utsname osinfo;
2160
2161 uname(&osinfo);
2162 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002163 osinfo.machine);
2164#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002165 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002166#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002167}
2168
2169void print_buildinfo(void)
2170{
2171 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002172#if NEED_PCI == 1
2173#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002174 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002175#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002176 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002177#endif
2178#endif
2179#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002180 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002181#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002182 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002183#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002184 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002185#endif
hailfinger3b471632010-03-27 16:36:40 +00002186#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002187 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002188#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002189 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002190#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002191 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002192#endif
2193#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002194 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002195#endif
2196#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002197 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00002198#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002199 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00002200#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002201 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002202}
2203
uwefdeca092008-01-21 15:24:22 +00002204void print_version(void)
2205{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002206 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002207 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002208 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002209}
2210
hailfinger74819ad2010-05-15 15:04:37 +00002211void print_banner(void)
2212{
2213 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002214 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002215 msg_ginfo("\n");
2216}
2217
hailfingerc77acb52009-12-24 02:15:55 +00002218int selfcheck(void)
2219{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002220 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002221 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002222
2223 /* Safety check. Instead of aborting after the first error, check
2224 * if more errors exist.
2225 */
hailfingerc77acb52009-12-24 02:15:55 +00002226 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002227 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002228 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002229 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002230 /* It would be favorable if we could check for the correct layout (especially termination) of various
2231 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2232 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2233 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2234 * 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 +10002235 * checks below. */
2236 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002237 msg_gerr("Flashchips table miscompilation!\n");
2238 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002239 } else {
2240 for (i = 0; i < flashchips_size - 1; i++) {
2241 const struct flashchip *chip = &flashchips[i];
2242 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2243 ret = 1;
2244 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2245 "Please report a bug at flashrom@flashrom.org\n", i,
2246 chip->name == NULL ? "unnamed" : chip->name);
2247 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002248 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002249 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002250 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002251 }
stefanct6d836ba2011-05-26 01:35:19 +00002252 }
stefanct6d836ba2011-05-26 01:35:19 +00002253
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002254 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002255 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002256}
2257
hailfinger771fc182010-10-15 00:01:14 +00002258/* FIXME: This function signature needs to be improved once doit() has a better
2259 * function signature.
2260 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002261static int chip_safety_check(const struct flashctx *flash, int force,
2262 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002263{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002264 const struct flashchip *chip = flash->chip;
2265
hailfinger771fc182010-10-15 00:01:14 +00002266 if (!programmer_may_write && (write_it || erase_it)) {
2267 msg_perr("Write/erase is not working yet on your programmer in "
2268 "its current configuration.\n");
2269 /* --force is the wrong approach, but it's the best we can do
2270 * until the generic programmer parameter parser is merged.
2271 */
2272 if (!force)
2273 return 1;
2274 msg_cerr("Continuing anyway.\n");
2275 }
2276
2277 if (read_it || erase_it || write_it || verify_it) {
2278 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002279 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002280 msg_cerr("Read is not working on this chip. ");
2281 if (!force)
2282 return 1;
2283 msg_cerr("Continuing anyway.\n");
2284 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002285 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002286 msg_cerr("flashrom has no read function for this "
2287 "flash chip.\n");
2288 return 1;
2289 }
2290 }
2291 if (erase_it || write_it) {
2292 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002293 if (chip->tested.erase == NA) {
2294 msg_cerr("Erase is not possible on this chip.\n");
2295 return 1;
2296 }
2297 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002298 msg_cerr("Erase is not working on this chip. ");
2299 if (!force)
2300 return 1;
2301 msg_cerr("Continuing anyway.\n");
2302 }
stefancte1c5acf2011-07-04 07:27:17 +00002303 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002304 msg_cerr("flashrom has no erase function for this "
2305 "flash chip.\n");
2306 return 1;
2307 }
hailfinger771fc182010-10-15 00:01:14 +00002308 }
2309 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002310 if (chip->tested.write == NA) {
2311 msg_cerr("Write is not possible on this chip.\n");
2312 return 1;
2313 }
2314 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002315 msg_cerr("Write is not working on this chip. ");
2316 if (!force)
2317 return 1;
2318 msg_cerr("Continuing anyway.\n");
2319 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002320 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002321 msg_cerr("flashrom has no write function for this "
2322 "flash chip.\n");
2323 return 1;
2324 }
2325 }
2326 return 0;
2327}
2328
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002329int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002330 const bool read_it, const bool write_it,
2331 const bool erase_it, const bool verify_it)
2332{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002333 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002334 msg_cerr("Aborting.\n");
2335 return 1;
2336 }
2337
2338 if (normalize_romentries(flash)) {
2339 msg_cerr("Requested regions can not be handled. Aborting.\n");
2340 return 1;
2341 }
2342
2343 /* Given the existence of read locks, we want to unlock for read,
2344 erase and write. */
2345 if (flash->chip->unlock)
2346 flash->chip->unlock(flash);
2347
2348 flash->address_high_byte = -1;
2349 flash->in_4ba_mode = false;
2350
2351 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2352 if ((flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN) && flash->chip->set_4ba) {
2353 if (flash->chip->set_4ba(flash)) {
2354 msg_cerr("Enabling/disabling 4-byte addressing mode failed!\n");
2355 return 1;
2356 }
2357 }
2358
2359 return 0;
2360}
2361
Edward O'Callaghana820b212020-09-17 22:53:26 +10002362void finalize_flash_access(struct flashctx *const flash)
2363{
2364 unmap_flash(flash);
2365}
2366
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002367/*
2368 * Function to erase entire flash chip.
2369 *
2370 * @flashctx pointer to the flash context to use
2371 * @oldcontents pointer to the buffer including current chip contents, to
2372 * decide which areas do in fact need to be erased
2373 * @size the size of the flash chip, in bytes.
2374 *
2375 * Returns zero on success or an error code.
2376 */
2377static int erase_chip(struct flashctx *flash, void *oldcontents,
2378 void *newcontents, size_t size)
2379{
2380 /*
2381 * To make sure that the chip is fully erased, let's cheat and create
2382 * a descriptor where the new contents are all erased.
2383 */
2384 struct action_descriptor *fake_descriptor;
2385 int ret = 0;
2386
2387 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2388 newcontents, 1);
2389 /* FIXME: Do we really want the scary warning if erase failed? After
2390 * all, after erase the chip is either blank or partially blank or it
2391 * has the old contents. A blank chip won't boot, so if the user
2392 * wanted erase and reboots afterwards, the user knows very well that
2393 * booting won't work.
2394 */
2395 if (erase_and_write_flash(flash, fake_descriptor)) {
2396 emergency_help_message();
2397 ret = 1;
2398 }
2399
2400 free(fake_descriptor);
2401
2402 return ret;
2403}
2404
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002405static int read_dest_content(struct flashctx *flash, int verify_it,
2406 uint8_t *dest, unsigned long size)
2407{
2408 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2409 && get_num_include_args()) {
2410 /*
2411 * If no full verification is required and not
2412 * the entire chip is about to be programmed,
2413 * read only the areas which might change.
2414 */
2415 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2416 return 1;
2417 } else {
2418 if (read_flash(flash, dest, 0, size))
2419 return 1;
2420 }
2421 return 0;
2422}
2423
hailfingerc77acb52009-12-24 02:15:55 +00002424/* This function signature is horrible. We need to design a better interface,
2425 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002426 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002427 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002428int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002429 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002430 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002431{
hailfinger4c47e9d2010-10-19 22:06:20 +00002432 uint8_t *oldcontents;
2433 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002434 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002435 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002436 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002437
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002438 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002439 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002440 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002441
Simon Glass9ad06c12013-07-03 22:08:17 +09002442 if (extract_it) {
2443 ret = extract_regions(flash);
2444 goto out_nofree;
2445 }
2446
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002447 /* mark entries included using -i argument as "included" if they are
2448 found in the master rom_entries list */
2449 if (process_include_args() < 0) {
2450 ret = 1;
2451 goto out_nofree;
2452 }
2453
hailfinger771fc182010-10-15 00:01:14 +00002454 if (read_it) {
2455 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002456 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002457 }
hailfingerb437e282010-11-04 01:04:27 +00002458
stefanctd611e8f2011-07-12 22:35:21 +00002459 oldcontents = malloc(size);
2460 if (!oldcontents) {
2461 msg_gerr("Out of memory!\n");
2462 exit(1);
2463 }
Simon Glass4c214132013-07-16 10:09:28 -06002464 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002465 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002466 newcontents = malloc(size);
2467 if (!newcontents) {
2468 msg_gerr("Out of memory!\n");
2469 exit(1);
2470 }
Simon Glass4c214132013-07-16 10:09:28 -06002471 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002472 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002473 /* Side effect of the assumptions above: Default write action is erase
2474 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002475 * oldcontents being completely unerased means we have to erase
2476 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002477 */
2478
hailfingerd217d122010-10-08 18:52:29 +00002479 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002480 /*
2481 * Note: This must be done before any files specified by -i
2482 * arguments are processed merged into the newcontents since
2483 * -i files take priority. See http://crbug.com/263495.
2484 */
2485 if (filename) {
2486 if (read_buf_from_file(newcontents, size, filename)) {
2487 ret = 1;
2488 goto out;
2489 }
2490 } else {
2491 /* Content will be read from -i args, so they must
2492 * not overlap. */
2493 if (included_regions_overlap()) {
2494 msg_gerr("Error: Included regions must "
2495 "not overlap.\n");
2496 ret = 1;
2497 goto out;
2498 }
stepan1da96c02006-11-21 23:48:51 +00002499 }
ollie5672ac62004-03-17 22:22:08 +00002500 }
2501
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002502 if (do_diff) {
2503 /*
2504 * Obtain a reference image so that we can check whether
2505 * regions need to be erased and to give better diagnostics in
2506 * case write fails. If --fast-verify is used then only the
2507 * regions which are included using -i will be read.
2508 */
2509 if (diff_file) {
2510 msg_cdbg("Reading old contents from file... ");
2511 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002512 ret = 1;
2513 msg_cdbg("FAILED.\n");
2514 goto out;
2515 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002516 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002517 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002518 ret = read_dest_content(flash, verify_it,
2519 oldcontents, size);
2520 if (ret) {
2521 msg_cdbg("FAILED.\n");
2522 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002523 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002524 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002525 msg_cdbg("done.\n");
2526 } else if (!erase_it) {
2527 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002528 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002529 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002530
David Hendricksdf29a832013-06-28 14:33:51 -07002531 /*
2532 * Note: This must be done after reading the file specified for the
2533 * -w/-v argument, if any, so that files specified using -i end up
2534 * in the "newcontents" buffer before being written.
2535 * See http://crbug.com/263495.
2536 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002537 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002538 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002539 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002540 goto out;
2541 }
uwef6641642007-05-09 10:17:44 +00002542
David Hendricksa7e114b2016-02-26 18:49:15 -08002543 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002544 erase_chip(flash, oldcontents, newcontents, size);
2545 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002546 }
2547
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002548 descriptor = prepare_action_descriptor(flash, oldcontents,
2549 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002550 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002551 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002552 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002553 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002554 goto out;
2555 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002556
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002557 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002558 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2559 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002560 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002561 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002562 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002563 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002564 ret = 1;
2565 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002566 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002567 msg_cerr("Apparently at least some data has changed.\n");
2568 } else
2569 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002570 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002571 ret = 1;
2572 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002573 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002574
David Hendricksac1d25c2016-08-09 17:00:58 -07002575 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002576 if (ret < 0) {
2577 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002578 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002579 emergency_help_message();
2580 ret = 1;
2581 goto out;
2582 } else if (ret > 0) {
2583 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002584 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002585 ret = read_dest_content(flash, verify_it,
2586 oldcontents, size);
2587 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002588 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002589 goto out;
2590 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002591
2592 /* Get a new descriptor. */
2593 free(descriptor);
2594 descriptor = prepare_action_descriptor(flash,
2595 oldcontents,
2596 newcontents,
2597 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002598 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002599 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002600 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002601 emergency_help_message();
2602 ret = 1;
2603 goto out;
2604 }
2605 ret = 0;
2606 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002607
David Hendricksac1d25c2016-08-09 17:00:58 -07002608 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002609 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002610 emergency_help_message();
2611 ret = 1;
2612 goto out;
2613 }
stuge8ce3a3c2008-04-28 14:47:30 +00002614 }
ollie6a600992005-11-26 21:55:36 +00002615
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002616 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002617 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002618 if ((write_it || erase_it) && !content_has_changed) {
2619 msg_gdbg("Nothing was erased or written, skipping "
2620 "verification\n");
2621 } else {
2622 /* Work around chips which need some time to calm down. */
2623 if (write_it && verify_it != VERIFY_PARTIAL)
2624 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002625
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002626 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002627
David Hendricks9ba79fb2015-04-03 12:06:16 -07002628 /* If we tried to write, and verification now fails, we
2629 * might have an emergency situation.
2630 */
2631 if (ret && write_it)
2632 emergency_help_message();
2633 }
hailfinger0459e1c2009-08-19 13:55:34 +00002634 }
ollie6a600992005-11-26 21:55:36 +00002635
hailfinger90fcf9b2010-11-05 14:51:59 +00002636out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002637 if (descriptor)
2638 free(descriptor);
2639
hailfinger90fcf9b2010-11-05 14:51:59 +00002640 free(oldcontents);
2641 free(newcontents);
2642out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002643 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002644 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002645 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002646 * tree. This is because some operations, such as write protection,
2647 * requires programmer_shutdown() but does not call doit().
2648 */
2649// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002650 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002651}