blob: a7a5d3e0ff5d26625d867fa64e9fdb40c6cfa517 [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
Edward O'Callaghana0176ff2020-08-18 15:49:23 +100052static int g_force = 0; // HACK to keep prepare_flash_access() signature the same.
53
David Hendricks1ed1d352011-11-23 17:54:37 -080054/* error handling stuff */
55enum error_action access_denied_action = error_ignore;
56
57int ignore_error(int err) {
58 int rc = 0;
59
60 switch(err) {
61 case ACCESS_DENIED:
62 if (access_denied_action == error_ignore)
63 rc = 1;
64 break;
65 default:
66 break;
67 }
68
69 return rc;
70}
71
hailfinger969e2f32011-09-08 00:00:29 +000072static enum programmer programmer = PROGRAMMER_INVALID;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100073static const char *programmer_param = NULL;
stepan782fb172007-04-06 11:58:03 +000074
David Hendricksac1d25c2016-08-09 17:00:58 -070075/* Supported buses for the current programmer. */
76enum chipbustype buses_supported;
77
uwee15beb92010-08-08 17:01:18 +000078/*
hailfinger80422e22009-12-13 22:28:00 +000079 * Programmers supporting multiple buses can have differing size limits on
80 * each bus. Store the limits for each bus in a common struct.
81 */
hailfinger1ff33dc2010-07-03 11:02:10 +000082struct decode_sizes max_rom_decode;
83
84/* If nonzero, used as the start address of bottom-aligned flash. */
85unsigned long flashbase;
hailfinger80422e22009-12-13 22:28:00 +000086
hailfinger5828baf2010-07-03 12:14:25 +000087/* Is writing allowed with this programmer? */
88int programmer_may_write;
89
hailfingerabe249e2009-05-08 17:43:22 +000090const struct programmer_entry programmer_table[] = {
hailfinger90c7d542010-05-31 15:27:27 +000091#if CONFIG_INTERNAL == 1
hailfingerabe249e2009-05-08 17:43:22 +000092 {
hailfinger3548a9a2009-08-12 14:34:35 +000093 .name = "internal",
Edward O'Callaghan0949b782019-11-10 23:23:20 +110094 .type = OTHER,
95 .devs.note = NULL,
hailfinger6c69ab02009-05-11 15:46:43 +000096 .init = internal_init,
hailfinger11ae3c42009-05-11 14:13:25 +000097 .map_flash_region = physmap,
98 .unmap_flash_region = physunmap,
hailfingere5829f62009-06-05 17:48:08 +000099 .delay = internal_delay,
David Hendricks55cdd9c2015-11-25 14:37:26 -0800100
101 /*
102 * "Internal" implies in-system programming on a live system, so
103 * handle with paranoia to catch errors early. If something goes
104 * wrong then hopefully the system will still be recoverable.
105 */
106 .paranoid = 1,
hailfingerabe249e2009-05-08 17:43:22 +0000107 },
hailfinger80422e22009-12-13 22:28:00 +0000108#endif
stepan927d4e22007-04-04 22:45:58 +0000109
hailfinger90c7d542010-05-31 15:27:27 +0000110#if CONFIG_DUMMY == 1
hailfingera9df33c2009-05-09 00:54:55 +0000111 {
hailfinger3548a9a2009-08-12 14:34:35 +0000112 .name = "dummy",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100113 .type = OTHER,
114 /* FIXME */
115 .devs.note = "Dummy device, does nothing and logs all accesses\n",
hailfinger6c69ab02009-05-11 15:46:43 +0000116 .init = dummy_init,
hailfinger11ae3c42009-05-11 14:13:25 +0000117 .map_flash_region = dummy_map,
118 .unmap_flash_region = dummy_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000119 .delay = internal_delay,
hailfingera9df33c2009-05-09 00:54:55 +0000120 },
hailfinger571a6b32009-09-16 10:09:21 +0000121#endif
hailfingera9df33c2009-05-09 00:54:55 +0000122
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000123#if CONFIG_MEC1308 == 1
124 {
125 .name = "mec1308",
126 .type = OTHER,
127 .devs.note = "Microchip MEC1308 Embedded Controller.\n",
128 .init = mec1308_init,
129 .map_flash_region = fallback_map,
130 .unmap_flash_region = fallback_unmap,
131 .delay = internal_delay,
132 },
133#endif
134
hailfinger90c7d542010-05-31 15:27:27 +0000135#if CONFIG_NIC3COM == 1
uwe0f5a3a22009-05-13 11:36:06 +0000136 {
hailfinger3548a9a2009-08-12 14:34:35 +0000137 .name = "nic3com",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100138 .type = PCI,
139 .devs.dev = nics_3com,
uwe0f5a3a22009-05-13 11:36:06 +0000140 .init = nic3com_init,
uwe3e656bd2009-05-17 23:12:17 +0000141 .map_flash_region = fallback_map,
142 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000143 .delay = internal_delay,
uwe0f5a3a22009-05-13 11:36:06 +0000144 },
hailfinger571a6b32009-09-16 10:09:21 +0000145#endif
uwe0f5a3a22009-05-13 11:36:06 +0000146
hailfinger90c7d542010-05-31 15:27:27 +0000147#if CONFIG_NICREALTEK == 1
hailfinger5aa36982010-05-21 21:54:07 +0000148 {
hailfinger0d703d42011-03-07 01:08:09 +0000149 /* This programmer works for Realtek RTL8139 and SMC 1211. */
uwe8d342eb2011-07-28 08:13:25 +0000150 .name = "nicrealtek",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100151 .type = PCI,
152 .devs.dev = nics_realtek,
uwe8d342eb2011-07-28 08:13:25 +0000153 .init = nicrealtek_init,
154 .map_flash_region = fallback_map,
155 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000156 .delay = internal_delay,
hailfinger5aa36982010-05-21 21:54:07 +0000157 },
hailfinger5aa36982010-05-21 21:54:07 +0000158#endif
159
hailfingerf0a368f2010-06-07 22:37:54 +0000160#if CONFIG_NICNATSEMI == 1
161 {
uwe8d342eb2011-07-28 08:13:25 +0000162 .name = "nicnatsemi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100163 .type = PCI,
164 .devs.dev = nics_natsemi,
uwe8d342eb2011-07-28 08:13:25 +0000165 .init = nicnatsemi_init,
166 .map_flash_region = fallback_map,
167 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000168 .delay = internal_delay,
hailfingerf0a368f2010-06-07 22:37:54 +0000169 },
170#endif
hailfinger5aa36982010-05-21 21:54:07 +0000171
hailfinger90c7d542010-05-31 15:27:27 +0000172#if CONFIG_GFXNVIDIA == 1
uweff4576d2009-09-30 18:29:55 +0000173 {
174 .name = "gfxnvidia",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100175 .type = PCI,
176 .devs.dev = gfx_nvidia,
uweff4576d2009-09-30 18:29:55 +0000177 .init = gfxnvidia_init,
uweff4576d2009-09-30 18:29:55 +0000178 .map_flash_region = fallback_map,
179 .unmap_flash_region = fallback_unmap,
uweff4576d2009-09-30 18:29:55 +0000180 .delay = internal_delay,
181 },
182#endif
183
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000184#if CONFIG_RAIDEN_DEBUG_SPI == 1
185 {
186 .name = "raiden_debug_spi",
187 .type = USB,
188 .devs.dev = devs_raiden,
189 .init = raiden_debug_spi_init,
190 .map_flash_region = fallback_map,
191 .unmap_flash_region = fallback_unmap,
192 .delay = internal_delay,
193 },
194#endif
195
hailfinger90c7d542010-05-31 15:27:27 +0000196#if CONFIG_DRKAISER == 1
ruikda922a12009-05-17 19:39:27 +0000197 {
uwee2f95ef2009-09-02 23:00:46 +0000198 .name = "drkaiser",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100199 .type = PCI,
200 .devs.dev = drkaiser_pcidev,
uwee2f95ef2009-09-02 23:00:46 +0000201 .init = drkaiser_init,
uwee2f95ef2009-09-02 23:00:46 +0000202 .map_flash_region = fallback_map,
203 .unmap_flash_region = fallback_unmap,
uwee2f95ef2009-09-02 23:00:46 +0000204 .delay = internal_delay,
205 },
hailfinger571a6b32009-09-16 10:09:21 +0000206#endif
uwee2f95ef2009-09-02 23:00:46 +0000207
hailfinger90c7d542010-05-31 15:27:27 +0000208#if CONFIG_SATASII == 1
uwee2f95ef2009-09-02 23:00:46 +0000209 {
hailfinger3548a9a2009-08-12 14:34:35 +0000210 .name = "satasii",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100211 .type = PCI,
212 .devs.dev = satas_sii,
ruikda922a12009-05-17 19:39:27 +0000213 .init = satasii_init,
uwe3e656bd2009-05-17 23:12:17 +0000214 .map_flash_region = fallback_map,
215 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000216 .delay = internal_delay,
ruikda922a12009-05-17 19:39:27 +0000217 },
hailfinger571a6b32009-09-16 10:09:21 +0000218#endif
ruikda922a12009-05-17 19:39:27 +0000219
hailfinger90c7d542010-05-31 15:27:27 +0000220#if CONFIG_ATAHPT == 1
uwe7e627c82010-02-21 21:17:00 +0000221 {
222 .name = "atahpt",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100223 .type = PCI,
224 .devs.dev = ata_hpt,
uwe7e627c82010-02-21 21:17:00 +0000225 .init = atahpt_init,
uwe7e627c82010-02-21 21:17:00 +0000226 .map_flash_region = fallback_map,
227 .unmap_flash_region = fallback_unmap,
uwe7e627c82010-02-21 21:17:00 +0000228 .delay = internal_delay,
229 },
230#endif
231
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000232#if CONFIG_ATAVIA == 1
233 {
234 .name = "atavia",
235 .type = PCI,
236 .devs.dev = ata_via,
237 .init = atavia_init,
238 .map_flash_region = atavia_map,
239 .unmap_flash_region = fallback_unmap,
240 .delay = internal_delay,
241 },
242#endif
243
244#if CONFIG_ATAPROMISE == 1
245 {
246 .name = "atapromise",
247 .type = PCI,
248 .devs.dev = ata_promise,
249 .init = atapromise_init,
250 .map_flash_region = atapromise_map,
251 .unmap_flash_region = fallback_unmap,
252 .delay = internal_delay,
253 },
254#endif
255
256#if CONFIG_IT8212 == 1
257 {
258 .name = "it8212",
259 .type = PCI,
260 .devs.dev = devs_it8212,
261 .init = it8212_init,
262 .map_flash_region = fallback_map,
263 .unmap_flash_region = fallback_unmap,
264 .delay = internal_delay,
265 },
266#endif
267
hailfinger90c7d542010-05-31 15:27:27 +0000268#if CONFIG_FT2232_SPI == 1
hailfingerf31da3d2009-06-16 21:08:06 +0000269 {
hailfinger90c7d542010-05-31 15:27:27 +0000270 .name = "ft2232_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100271 .type = USB,
Nikolai Artemievc347a852020-04-29 12:17:08 +1000272 .devs.dev = devs_ft2232spi,
hailfingerf31da3d2009-06-16 21:08:06 +0000273 .init = ft2232_spi_init,
hailfinger6fe23d62009-08-12 11:39:29 +0000274 .map_flash_region = fallback_map,
275 .unmap_flash_region = fallback_unmap,
hailfingerf31da3d2009-06-16 21:08:06 +0000276 .delay = internal_delay,
277 },
hailfingerd9dcfbd2009-08-19 13:27:58 +0000278#endif
hailfinger6fe23d62009-08-12 11:39:29 +0000279
hailfinger90c7d542010-05-31 15:27:27 +0000280#if CONFIG_SERPROG == 1
hailfinger37b4fbf2009-06-23 11:33:43 +0000281 {
hailfinger3548a9a2009-08-12 14:34:35 +0000282 .name = "serprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100283 .type = OTHER,
284 /* FIXME */
285 .devs.note = "All programmer devices speaking the serprog protocol\n",
hailfinger37b4fbf2009-06-23 11:33:43 +0000286 .init = serprog_init,
hailfinger37b4fbf2009-06-23 11:33:43 +0000287 .map_flash_region = fallback_map,
288 .unmap_flash_region = fallback_unmap,
hailfinger37b4fbf2009-06-23 11:33:43 +0000289 .delay = serprog_delay,
290 },
hailfinger74d88a72009-08-12 16:17:41 +0000291#endif
hailfingerf31da3d2009-06-16 21:08:06 +0000292
hailfinger90c7d542010-05-31 15:27:27 +0000293#if CONFIG_BUSPIRATE_SPI == 1
hailfinger9c5add72009-11-24 00:20:03 +0000294 {
hailfinger90c7d542010-05-31 15:27:27 +0000295 .name = "buspirate_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100296 .type = OTHER,
297 /* FIXME */
298 .devs.note = "Dangerous Prototypes Bus Pirate\n",
hailfinger9c5add72009-11-24 00:20:03 +0000299 .init = buspirate_spi_init,
hailfinger9c5add72009-11-24 00:20:03 +0000300 .map_flash_region = fallback_map,
301 .unmap_flash_region = fallback_unmap,
hailfinger9c5add72009-11-24 00:20:03 +0000302 .delay = internal_delay,
303 },
304#endif
305
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000306#if CONFIG_DEDIPROG == 1
Anton Staafb2647882014-09-17 15:13:43 -0700307 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000308 .name = "dediprog",
Brian J. Nemecb42d6c12020-07-23 03:07:38 -0700309 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000310 .init = dediprog_init,
Anton Staafb2647882014-09-17 15:13:43 -0700311 .map_flash_region = fallback_map,
312 .unmap_flash_region = fallback_unmap,
313 .delay = internal_delay,
314 },
315#endif
316
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000317#if CONFIG_DEVELOPERBOX_SPI == 1
hailfingerdfb32a02010-01-19 11:15:48 +0000318 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000319 .name = "developerbox",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100320 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000321 .devs.dev = devs_developerbox_spi,
322 .init = developerbox_spi_init,
323 .map_flash_region = fallback_map,
324 .unmap_flash_region = fallback_unmap,
325 .delay = internal_delay,
326 },
327#endif
328
329#if CONFIG_ENE_LPC == 1
330 {
331 .name = "ene_lpc",
332 .type = OTHER,
333 .devs.note = "ENE LPC interface keyboard controller\n",
334 .init = ene_lpc_init,
hailfingerdfb32a02010-01-19 11:15:48 +0000335 .map_flash_region = fallback_map,
336 .unmap_flash_region = fallback_unmap,
hailfingerdfb32a02010-01-19 11:15:48 +0000337 .delay = internal_delay,
338 },
339#endif
340
hailfinger52c4fa02010-07-21 10:26:01 +0000341#if CONFIG_RAYER_SPI == 1
342 {
343 .name = "rayer_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100344 .type = OTHER,
345 /* FIXME */
346 .devs.note = "RayeR parallel port programmer\n",
hailfinger52c4fa02010-07-21 10:26:01 +0000347 .init = rayer_spi_init,
hailfinger52c4fa02010-07-21 10:26:01 +0000348 .map_flash_region = fallback_map,
349 .unmap_flash_region = fallback_unmap,
hailfinger52c4fa02010-07-21 10:26:01 +0000350 .delay = internal_delay,
351 },
352#endif
353
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000354#if CONFIG_PONY_SPI == 1
355 {
356 .name = "pony_spi",
357 .type = OTHER,
358 /* FIXME */
359 .devs.note = "Programmers compatible with SI-Prog, serbang or AJAWe\n",
360 .init = pony_spi_init,
361 .map_flash_region = fallback_map,
362 .unmap_flash_region = fallback_unmap,
363 .delay = internal_delay,
364 },
365#endif
366
hailfinger7949b652011-05-08 00:24:18 +0000367#if CONFIG_NICINTEL == 1
368 {
369 .name = "nicintel",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100370 .type = PCI,
371 .devs.dev = nics_intel,
hailfinger7949b652011-05-08 00:24:18 +0000372 .init = nicintel_init,
hailfinger7949b652011-05-08 00:24:18 +0000373 .map_flash_region = fallback_map,
374 .unmap_flash_region = fallback_unmap,
hailfinger7949b652011-05-08 00:24:18 +0000375 .delay = internal_delay,
376 },
377#endif
378
uwe6764e922010-09-03 18:21:21 +0000379#if CONFIG_NICINTEL_SPI == 1
380 {
uwe8d342eb2011-07-28 08:13:25 +0000381 .name = "nicintel_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100382 .type = PCI,
383 .devs.dev = nics_intel_spi,
uwe8d342eb2011-07-28 08:13:25 +0000384 .init = nicintel_spi_init,
385 .map_flash_region = fallback_map,
386 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000387 .delay = internal_delay,
uwe6764e922010-09-03 18:21:21 +0000388 },
389#endif
390
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000391#if CONFIG_NICINTEL_EEPROM == 1
392 {
393 .name = "nicintel_eeprom",
394 .type = PCI,
395 .devs.dev = nics_intel_ee,
396 .init = nicintel_ee_init,
397 .map_flash_region = fallback_map,
398 .unmap_flash_region = fallback_unmap,
399 .delay = internal_delay,
400 },
401#endif
402
hailfingerfb1f31f2010-12-03 14:48:11 +0000403#if CONFIG_OGP_SPI == 1
404 {
uwe8d342eb2011-07-28 08:13:25 +0000405 .name = "ogp_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100406 .type = PCI,
407 .devs.dev = ogp_spi,
uwe8d342eb2011-07-28 08:13:25 +0000408 .init = ogp_spi_init,
409 .map_flash_region = fallback_map,
410 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000411 .delay = internal_delay,
hailfingerfb1f31f2010-12-03 14:48:11 +0000412 },
413#endif
414
hailfinger935365d2011-02-04 21:37:59 +0000415#if CONFIG_SATAMV == 1
416 {
417 .name = "satamv",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100418 .type = PCI,
419 .devs.dev = satas_mv,
hailfinger935365d2011-02-04 21:37:59 +0000420 .init = satamv_init,
hailfinger935365d2011-02-04 21:37:59 +0000421 .map_flash_region = fallback_map,
422 .unmap_flash_region = fallback_unmap,
hailfinger935365d2011-02-04 21:37:59 +0000423 .delay = internal_delay,
424 },
425#endif
426
David Hendrickscebee892015-05-23 20:30:30 -0700427#if CONFIG_LINUX_MTD == 1
428 {
429 .name = "linux_mtd",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100430 .type = OTHER,
431 .devs.note = "Device files /dev/mtd*\n",
David Hendrickscebee892015-05-23 20:30:30 -0700432 .init = linux_mtd_init,
433 .map_flash_region = fallback_map,
434 .unmap_flash_region = fallback_unmap,
435 .delay = internal_delay,
436 },
437#endif
438
uwe7df6dda2011-09-03 18:37:52 +0000439#if CONFIG_LINUX_SPI == 1
440 {
441 .name = "linux_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100442 .type = OTHER,
443 .devs.note = "Device files /dev/spidev*.*\n",
uwe7df6dda2011-09-03 18:37:52 +0000444 .init = linux_spi_init,
445 .map_flash_region = fallback_map,
446 .unmap_flash_region = fallback_unmap,
uwe7df6dda2011-09-03 18:37:52 +0000447 .delay = internal_delay,
448 },
449#endif
450
Shiyu Sun9dde7162020-04-16 17:32:55 +1000451#if CONFIG_LSPCON_I2C_SPI == 1
452 {
453 .name = "lspcon_i2c_spi",
454 .type = OTHER,
455 .devs.note = "Device files /dev/i2c-*.\n",
456 .init = lspcon_i2c_spi_init,
457 .map_flash_region = fallback_map,
458 .unmap_flash_region = fallback_unmap,
459 .delay = internal_delay,
460 },
461#endif
462
Edward O'Callaghan97dd9262020-03-26 00:00:41 +1100463#if CONFIG_REALTEK_MST_I2C_SPI == 1
464 {
465 .name = "realtek_mst_i2c_spi",
466 .type = OTHER,
467 .devs.note = "Device files /dev/i2c-*.\n",
468 .init = realtek_mst_i2c_spi_init,
469 .map_flash_region = fallback_map,
470 .unmap_flash_region = fallback_unmap,
471 .delay = internal_delay,
472 },
473#endif
474
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000475#if CONFIG_USBBLASTER_SPI == 1
476 {
477 .name = "usbblaster_spi",
478 .type = USB,
479 .devs.dev = devs_usbblasterspi,
480 .init = usbblaster_spi_init,
481 .map_flash_region = fallback_map,
482 .unmap_flash_region = fallback_unmap,
483 .delay = internal_delay,
484 },
485#endif
486
487#if CONFIG_MSTARDDC_SPI == 1
488 {
489 .name = "mstarddc_spi",
490 .type = OTHER,
491 .devs.note = "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
492 .init = mstarddc_spi_init,
493 .map_flash_region = fallback_map,
494 .unmap_flash_region = fallback_unmap,
495 .delay = internal_delay,
496 },
497#endif
498
499#if CONFIG_PICKIT2_SPI == 1
500 {
501 .name = "pickit2_spi",
502 .type = USB,
503 .devs.dev = devs_pickit2_spi,
504 .init = pickit2_spi_init,
505 .map_flash_region = fallback_map,
506 .unmap_flash_region = fallback_unmap,
507 .delay = internal_delay,
508 },
509#endif
510
511#if CONFIG_CH341A_SPI == 1
512 {
513 .name = "ch341a_spi",
514 .type = USB,
515 .devs.dev = devs_ch341a_spi,
516 .init = ch341a_spi_init,
517 .map_flash_region = fallback_map,
518 .unmap_flash_region = fallback_unmap,
519 .delay = ch341a_spi_delay,
520 },
521#endif
522
523#if CONFIG_DIGILENT_SPI == 1
524 {
525 .name = "digilent_spi",
526 .type = USB,
527 .devs.dev = devs_digilent_spi,
528 .init = digilent_spi_init,
529 .map_flash_region = fallback_map,
530 .unmap_flash_region = fallback_unmap,
531 .delay = internal_delay,
532 },
533#endif
534
535#if CONFIG_JLINK_SPI == 1
536 {
537 .name = "jlink_spi",
538 .type = OTHER,
539 .init = jlink_spi_init,
540 .devs.note = "SEGGER J-Link and compatible devices\n",
541 .map_flash_region = fallback_map,
542 .unmap_flash_region = fallback_unmap,
543 .delay = internal_delay,
544 },
545#endif
546
547#if CONFIG_NI845X_SPI == 1
548 {
549 .name = "ni845x_spi",
550 .type = OTHER, // choose other because NI-845x uses own USB implementation
551 .devs.note = "National Instruments USB-845x\n",
552 .init = ni845x_spi_init,
553 .map_flash_region = fallback_map,
554 .unmap_flash_region = fallback_unmap,
555 .delay = internal_delay,
556 },
557#endif
558
559#if CONFIG_STLINKV3_SPI == 1
560 {
561 .name = "stlinkv3_spi",
562 .type = USB,
563 .devs.dev = devs_stlinkv3_spi,
564 .init = stlinkv3_spi_init,
565 .map_flash_region = fallback_map,
566 .unmap_flash_region = fallback_unmap,
567 .delay = internal_delay,
568 },
569#endif
570
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100571 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000572};
stepan927d4e22007-04-04 22:45:58 +0000573
David Hendricksbf36f092010-11-02 23:39:29 -0700574#define CHIP_RESTORE_MAXFN 4
575static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000576static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700577 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700578 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700579 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000580} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700581
David Hendricks668f29d2011-01-27 18:51:45 -0800582
hailfingerf31cbdc2010-11-10 15:25:18 +0000583#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000584static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000585/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000586static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700587 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000588 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000589} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000590/* Initialize to 0 to make sure nobody registers a shutdown function before
591 * programmer init.
592 */
593static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000594
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700595static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000596
hailfingerdc6f7972010-02-14 01:20:28 +0000597/* Register a function to be executed on programmer shutdown.
598 * The advantage over atexit() is that you can supply a void pointer which will
599 * be used as parameter to the registered function upon programmer shutdown.
600 * This pointer can point to arbitrary data used by said function, e.g. undo
601 * information for GPIO settings etc. If unneeded, set data=NULL.
602 * Please note that the first (void *data) belongs to the function signature of
603 * the function passed as first parameter.
604 */
David Hendricks93784b42016-08-09 17:00:38 -0700605int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000606{
607 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000608 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000609 SHUTDOWN_MAXFN);
610 return 1;
611 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000612 if (!may_register_shutdown) {
613 msg_perr("Tried to register a shutdown function before "
614 "programmer init.\n");
615 return 1;
616 }
hailfingerdc6f7972010-02-14 01:20:28 +0000617 shutdown_fn[shutdown_fn_count].func = function;
618 shutdown_fn[shutdown_fn_count].data = data;
619 shutdown_fn_count++;
620
621 return 0;
622}
623
David Hendricksbf36f092010-11-02 23:39:29 -0700624//int register_chip_restore(int (*function) (void *data), void *data)
625int register_chip_restore(CHIP_RESTORE_CALLBACK,
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700626 struct flashctx *flash, uint8_t status)
David Hendricksbf36f092010-11-02 23:39:29 -0700627{
628 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
629 msg_perr("Tried to register more than %i chip restore"
630 " functions.\n", CHIP_RESTORE_MAXFN);
631 return 1;
632 }
633 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
634 chip_restore_fn[chip_restore_fn_count].flash = flash;
635 chip_restore_fn[chip_restore_fn_count].status = status;
636 chip_restore_fn_count++;
637
638 return 0;
639}
640
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000641int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000642{
hailfinger1ef766d2010-07-06 09:55:48 +0000643 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000644
645 if (prog >= PROGRAMMER_INVALID) {
646 msg_perr("Invalid programmer specified!\n");
647 return -1;
648 }
649 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000650 /* Initialize all programmer specific data. */
651 /* Default to unlimited decode sizes. */
652 max_rom_decode = (const struct decode_sizes) {
653 .parallel = 0xffffffff,
654 .lpc = 0xffffffff,
655 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000656 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000657 };
David Hendricksac1d25c2016-08-09 17:00:58 -0700658 buses_supported = BUS_NONE;
hailfinger1ff33dc2010-07-03 11:02:10 +0000659 /* Default to top aligned flash at 4 GB. */
660 flashbase = 0;
661 /* Registering shutdown functions is now allowed. */
662 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000663 /* Default to allowing writes. Broken programmers set this to 0. */
664 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000665
666 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000667 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700668 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000669 if (programmer_param && strlen(programmer_param)) {
670 if (ret != 0) {
671 /* It is quite possible that any unhandled programmer parameter would have been valid,
672 * but an error in actual programmer init happened before the parameter was evaluated.
673 */
674 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
675 programmer_param);
676 } else {
677 /* Actual programmer init was successful, but the user specified an invalid or unusable
678 * (for the current programmer configuration) parameter.
679 */
680 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
681 msg_perr("Aborting.\n");
682 ret = ERROR_FATAL;
683 }
684 }
hailfinger1ef766d2010-07-06 09:55:48 +0000685 return ret;
uweabe92a52009-05-16 22:36:00 +0000686}
687
David Hendricksbf36f092010-11-02 23:39:29 -0700688int chip_restore()
689{
690 int rc = 0;
691
692 while (chip_restore_fn_count > 0) {
693 int i = --chip_restore_fn_count;
694 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
695 chip_restore_fn[i].status);
696 }
697
698 return rc;
699}
700
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000701/** Calls registered shutdown functions and resets internal programmer-related variables.
702 * Calling it is safe even without previous initialization, but further interactions with programmer support
703 * require a call to programmer_init() (afterwards).
704 *
705 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700706int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000707{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000708 int ret = 0;
709
hailfinger1ff33dc2010-07-03 11:02:10 +0000710 /* Registering shutdown functions is no longer allowed. */
711 may_register_shutdown = 0;
712 while (shutdown_fn_count > 0) {
713 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700714 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000715 }
dhendrix0ffc2eb2011-06-14 01:35:36 +0000716 return ret;
uweabe92a52009-05-16 22:36:00 +0000717}
718
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000719void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000720{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000721 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
722 return ret;
uweabe92a52009-05-16 22:36:00 +0000723}
724
725void programmer_unmap_flash_region(void *virt_addr, size_t len)
726{
727 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000728 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000729}
730
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700731void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000732{
Craig Hesling65eb8812019-08-01 09:33:56 -0700733 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000734}
735
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700736void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000737{
Craig Hesling65eb8812019-08-01 09:33:56 -0700738 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000739}
740
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700741void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000742{
Craig Hesling65eb8812019-08-01 09:33:56 -0700743 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000744}
745
Stuart langleyc98e43f2020-03-26 20:27:36 +1100746void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000747{
Craig Hesling65eb8812019-08-01 09:33:56 -0700748 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000749}
750
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700751uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000752{
Craig Hesling65eb8812019-08-01 09:33:56 -0700753 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000754}
755
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700756uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000757{
Craig Hesling65eb8812019-08-01 09:33:56 -0700758 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000759}
760
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700761uint32_t chip_readl(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_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000764}
765
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000766void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
767 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000768{
Craig Hesling65eb8812019-08-01 09:33:56 -0700769 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000770}
771
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000772void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000773{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000774 if (usecs > 0)
775 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000776}
777
Edward O'Callaghana820b212020-09-17 22:53:26 +1000778int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
779 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000780{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700781 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000782
hailfinger23060112009-05-08 12:49:03 +0000783 return 0;
784}
785
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000786/* This is a somewhat hacked function similar in some ways to strtok().
787 * It will look for needle with a subsequent '=' in haystack, return a copy of
788 * needle and remove everything from the first occurrence of needle to the next
789 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000790 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000791char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000792{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000793 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000794 char *opt = NULL;
795 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000796 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000797
hailfingerf4aaccc2010-04-28 15:22:14 +0000798 needlelen = strlen(needle);
799 if (!needlelen) {
800 msg_gerr("%s: empty needle! Please report a bug at "
801 "flashrom@flashrom.org\n", __func__);
802 return NULL;
803 }
804 /* No programmer parameters given. */
805 if (*haystack == NULL)
806 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000807 param_pos = strstr(*haystack, needle);
808 do {
809 if (!param_pos)
810 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000811 /* Needle followed by '='? */
812 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000813 /* Beginning of the string? */
814 if (param_pos == *haystack)
815 break;
816 /* After a delimiter? */
817 if (strchr(delim, *(param_pos - 1)))
818 break;
819 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000820 /* Continue searching. */
821 param_pos++;
822 param_pos = strstr(param_pos, needle);
823 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000824
hailfinger6e5a52a2009-11-24 18:27:10 +0000825 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000826 /* Get the string after needle and '='. */
827 opt_pos = param_pos + needlelen + 1;
828 optlen = strcspn(opt_pos, delim);
829 /* Return an empty string if the parameter was empty. */
830 opt = malloc(optlen + 1);
831 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000832 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000833 exit(1);
834 }
hailfinger1ef766d2010-07-06 09:55:48 +0000835 strncpy(opt, opt_pos, optlen);
836 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000837 rest = opt_pos + optlen;
838 /* Skip all delimiters after the current parameter. */
839 rest += strspn(rest, delim);
840 memmove(param_pos, rest, strlen(rest) + 1);
841 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000842 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000843
hailfinger1ef766d2010-07-06 09:55:48 +0000844 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000845}
846
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000847char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000848{
849 return extract_param(&programmer_param, param_name, ",");
850}
851
stefancte1c5acf2011-07-04 07:27:17 +0000852/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700853static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000854{
855 unsigned int usable_erasefunctions = 0;
856 int k;
857 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
858 if (!check_block_eraser(flash, k, 0))
859 usable_erasefunctions++;
860 }
861 return usable_erasefunctions;
862}
863
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000864static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700865{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000866 int ret = 0, failcount = 0;
867 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700868 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000869 if (wantbuf[i] != havebuf[i]) {
870 /* Only print the first failure. */
871 if (!failcount++)
872 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
873 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700874 }
875 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000876 if (failcount) {
877 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
878 start, start + len - 1, failcount);
879 ret = -1;
880 }
881 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700882}
883
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000884/* start is an offset to the base address of the flash chip */
885static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
886{
887 int ret;
888 uint8_t *cmpbuf = malloc(len);
889 const uint8_t erased_value = ERASED_VALUE(flash);
890
891 if (!cmpbuf) {
892 msg_gerr("Could not allocate memory!\n");
893 exit(1);
894 }
895 memset(cmpbuf, erased_value, len);
896 ret = verify_range(flash, cmpbuf, start, len);
897 free(cmpbuf);
898 return ret;
899}
900
uwee15beb92010-08-08 17:01:18 +0000901/*
hailfinger7af3d192009-11-25 17:05:52 +0000902 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000903 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000904 * @start offset to the base address of the flash chip
905 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000906 * @return 0 for success, -1 for failure
907 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000908int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000909{
hailfinger7af83692009-06-15 17:23:36 +0000910 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000911 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000912
Patrick Georgif3fa2992017-02-02 16:24:44 +0100913 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000914 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000915 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000916 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000917
918 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000919 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000920 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000921 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000922 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000923 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000924
Patrick Georgif3fa2992017-02-02 16:24:44 +0100925 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000926 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000927 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100928 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000929 ret = -1;
930 goto out_free;
931 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700932 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700933 if (programmer_table[programmer].paranoid) {
934 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800935
Simon Glass4e305f42015-01-08 06:29:04 -0700936 /* limit chunksize in order to catch errors early */
937 for (i = 0, chunksize = 0; i < len; i += chunksize) {
938 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800939
Patrick Georgif3fa2992017-02-02 16:24:44 +0100940 chunksize = min(flash->chip->page_size, len - i);
941 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700942 if (tmp) {
943 ret = tmp;
944 if (ignore_error(tmp))
945 continue;
946 else
947 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800948 }
Simon Glass4e305f42015-01-08 06:29:04 -0700949
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700950 /*
951 * Check write access permission and do not compare chunks
952 * where flashrom does not have write access to the region.
953 */
954 if (flash->chip->check_access) {
955 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
956 if (tmp && ignore_error(tmp))
957 continue;
958 }
959
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000960 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700961 if (failcount)
962 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800963 }
Simon Glass4e305f42015-01-08 06:29:04 -0700964 } else {
965 int tmp;
966
967 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +0100968 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -0700969 if (tmp && !ignore_error(tmp)) {
970 ret = tmp;
971 goto out_free;
972 }
973
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000974 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +0000975 }
976
hailfinger5be6c0f2009-07-23 01:42:56 +0000977 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +0000978 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +0000979 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +0000980 ret = -1;
981 }
hailfinger7af83692009-06-15 17:23:36 +0000982
983out_free:
984 free(readbuf);
985 return ret;
986}
987
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100988/* Helper function for need_erase() that focuses on granularities of gran bytes. */
989static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000990 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100991{
992 unsigned int i, j, limit;
993 for (j = 0; j < len / gran; j++) {
994 limit = min (gran, len - j * gran);
995 /* Are 'have' and 'want' identical? */
996 if (!memcmp(have + j * gran, want + j * gran, limit))
997 continue;
998 /* have needs to be in erased state. */
999 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001000 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001001 return 1;
1002 }
1003 return 0;
1004}
1005
uwee15beb92010-08-08 17:01:18 +00001006/*
hailfingerb247c7a2010-03-08 00:42:32 +00001007 * Check if the buffer @have can be programmed to the content of @want without
1008 * erasing. This is only possible if all chunks of size @gran are either kept
1009 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001010 *
hailfingerb437e282010-11-04 01:04:27 +00001011 * Warning: This function assumes that @have and @want point to naturally
1012 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001013 *
1014 * @have buffer with current content
1015 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001016 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001017 * @gran write granularity (enum, not count)
1018 * @return 0 if no erase is needed, 1 otherwise
1019 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001020int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1021 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001022{
hailfingerb91c08c2011-08-15 19:54:20 +00001023 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001024 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001025
hailfingerb247c7a2010-03-08 00:42:32 +00001026 switch (gran) {
1027 case write_gran_1bit:
1028 for (i = 0; i < len; i++)
1029 if ((have[i] & want[i]) != want[i]) {
1030 result = 1;
1031 break;
1032 }
1033 break;
1034 case write_gran_1byte:
1035 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001036 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001037 result = 1;
1038 break;
1039 }
1040 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001041 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001042 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001043 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001044 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001045 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001046 break;
1047 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001048 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001049 break;
1050 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001051 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001052 break;
1053 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001054 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001055 break;
1056 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001057 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001058 break;
1059 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001060 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001061 break;
1062 case write_gran_1byte_implicit_erase:
1063 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1064 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001065 break;
hailfingerb437e282010-11-04 01:04:27 +00001066 default:
1067 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1068 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001069 }
1070 return result;
1071}
1072
hailfingerb437e282010-11-04 01:04:27 +00001073/**
1074 * Check if the buffer @have needs to be programmed to get the content of @want.
1075 * If yes, return 1 and fill in first_start with the start address of the
1076 * write operation and first_len with the length of the first to-be-written
1077 * chunk. If not, return 0 and leave first_start and first_len undefined.
1078 *
1079 * Warning: This function assumes that @have and @want point to naturally
1080 * aligned regions.
1081 *
1082 * @have buffer with current content
1083 * @want buffer with desired content
1084 * @len length of the checked area
1085 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001086 * @first_start offset of the first byte which needs to be written (passed in
1087 * value is increased by the offset of the first needed write
1088 * relative to have/want or unchanged if no write is needed)
1089 * @return length of the first contiguous area which needs to be written
1090 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001091 *
1092 * FIXME: This function needs a parameter which tells it about coalescing
1093 * in relation to the max write length of the programmer and the max write
1094 * length of the chip.
1095 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001096static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001097 unsigned int *first_start,
1098 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001099{
stefanctc5eb8a92011-11-23 09:13:48 +00001100 int need_write = 0;
1101 unsigned int rel_start = 0, first_len = 0;
1102 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001103
hailfingerb437e282010-11-04 01:04:27 +00001104 switch (gran) {
1105 case write_gran_1bit:
1106 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001107 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001108 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001109 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001110 case write_gran_128bytes:
1111 stride = 128;
1112 break;
hailfingerb437e282010-11-04 01:04:27 +00001113 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001114 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001115 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001116 case write_gran_264bytes:
1117 stride = 264;
1118 break;
1119 case write_gran_512bytes:
1120 stride = 512;
1121 break;
1122 case write_gran_528bytes:
1123 stride = 528;
1124 break;
1125 case write_gran_1024bytes:
1126 stride = 1024;
1127 break;
1128 case write_gran_1056bytes:
1129 stride = 1056;
1130 break;
hailfingerb437e282010-11-04 01:04:27 +00001131 default:
1132 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1133 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001134 /* Claim that no write was needed. A write with unknown
1135 * granularity is too dangerous to try.
1136 */
1137 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001138 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001139 for (i = 0; i < len / stride; i++) {
1140 limit = min(stride, len - i * stride);
1141 /* Are 'have' and 'want' identical? */
1142 if (memcmp(have + i * stride, want + i * stride, limit)) {
1143 if (!need_write) {
1144 /* First location where have and want differ. */
1145 need_write = 1;
1146 rel_start = i * stride;
1147 }
1148 } else {
1149 if (need_write) {
1150 /* First location where have and want
1151 * do not differ anymore.
1152 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001153 break;
1154 }
1155 }
1156 }
hailfingerffb7f382010-12-06 13:05:44 +00001157 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001158 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001159 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001160 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001161}
1162
hailfinger0c515352009-11-23 12:55:31 +00001163/* This function generates various test patterns useful for testing controller
1164 * and chip communication as well as chip behaviour.
1165 *
1166 * If a byte can be written multiple times, each time keeping 0-bits at 0
1167 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1168 * is essentially an AND operation. That's also the reason why this function
1169 * provides the result of AND between various patterns.
1170 *
1171 * Below is a list of patterns (and their block length).
1172 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1173 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1174 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1175 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1176 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1177 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1178 * Pattern 6 is 00 (1 Byte)
1179 * Pattern 7 is ff (1 Byte)
1180 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1181 * byte block.
1182 *
1183 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1184 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1185 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1186 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1187 * Pattern 12 is 00 (1 Byte)
1188 * Pattern 13 is ff (1 Byte)
1189 * Patterns 8-13 have no block number.
1190 *
1191 * Patterns 0-3 are created to detect and efficiently diagnose communication
1192 * slips like missed bits or bytes and their repetitive nature gives good visual
1193 * cues to the person inspecting the results. In addition, the following holds:
1194 * AND Pattern 0/1 == Pattern 4
1195 * AND Pattern 2/3 == Pattern 5
1196 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1197 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1198 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1199 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1200 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1201 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1202 * Besides that, they provide for bit testing of the last two bytes of every
1203 * 256 byte block which contains the block number for patterns 0-6.
1204 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1205 * block sizes >256 bytes (some Dataflash chips etc.)
1206 * AND Pattern 8/9 == Pattern 12
1207 * AND Pattern 10/11 == Pattern 12
1208 * Pattern 13 is the completely erased state.
1209 * None of the patterns can detect aliasing at boundaries which are a multiple
1210 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1211 */
1212int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1213{
1214 int i;
1215
1216 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001217 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001218 return 1;
1219 }
1220
1221 switch (variant) {
1222 case 0:
1223 for (i = 0; i < size; i++)
1224 buf[i] = (i & 0xf) << 4 | 0x5;
1225 break;
1226 case 1:
1227 for (i = 0; i < size; i++)
1228 buf[i] = (i & 0xf) << 4 | 0xa;
1229 break;
1230 case 2:
1231 for (i = 0; i < size; i++)
1232 buf[i] = 0x50 | (i & 0xf);
1233 break;
1234 case 3:
1235 for (i = 0; i < size; i++)
1236 buf[i] = 0xa0 | (i & 0xf);
1237 break;
1238 case 4:
1239 for (i = 0; i < size; i++)
1240 buf[i] = (i & 0xf) << 4;
1241 break;
1242 case 5:
1243 for (i = 0; i < size; i++)
1244 buf[i] = i & 0xf;
1245 break;
1246 case 6:
1247 memset(buf, 0x00, size);
1248 break;
1249 case 7:
1250 memset(buf, 0xff, size);
1251 break;
1252 case 8:
1253 for (i = 0; i < size; i++)
1254 buf[i] = i & 0xff;
1255 break;
1256 case 9:
1257 for (i = 0; i < size; i++)
1258 buf[i] = ~(i & 0xff);
1259 break;
1260 case 10:
1261 for (i = 0; i < size % 2; i++) {
1262 buf[i * 2] = (i >> 8) & 0xff;
1263 buf[i * 2 + 1] = i & 0xff;
1264 }
1265 if (size & 0x1)
1266 buf[i * 2] = (i >> 8) & 0xff;
1267 break;
1268 case 11:
1269 for (i = 0; i < size % 2; i++) {
1270 buf[i * 2] = ~((i >> 8) & 0xff);
1271 buf[i * 2 + 1] = ~(i & 0xff);
1272 }
1273 if (size & 0x1)
1274 buf[i * 2] = ~((i >> 8) & 0xff);
1275 break;
1276 case 12:
1277 memset(buf, 0x00, size);
1278 break;
1279 case 13:
1280 memset(buf, 0xff, size);
1281 break;
1282 }
1283
1284 if ((variant >= 0) && (variant <= 7)) {
1285 /* Write block number in the last two bytes of each 256-byte
1286 * block, big endian for easier reading of the hexdump.
1287 * Note that this wraps around for chips larger than 2^24 bytes
1288 * (16 MB).
1289 */
1290 for (i = 0; i < size / 256; i++) {
1291 buf[i * 256 + 254] = (i >> 8) & 0xff;
1292 buf[i * 256 + 255] = i & 0xff;
1293 }
1294 }
1295
1296 return 0;
1297}
1298
hailfingeraec9c962009-10-31 01:53:09 +00001299int check_max_decode(enum chipbustype buses, uint32_t size)
1300{
1301 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001302
1303 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001304 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001305 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001306 "size %u kB of chipset/board/programmer "
1307 "for %s interface, "
1308 "probe/read/erase/write may fail. ", size / 1024,
1309 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001310 }
hailfingere1e41ea2011-07-27 07:13:06 +00001311 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001312 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001313 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001314 "size %u kB of chipset/board/programmer "
1315 "for %s interface, "
1316 "probe/read/erase/write may fail. ", size / 1024,
1317 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001318 }
hailfingere1e41ea2011-07-27 07:13:06 +00001319 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001320 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001321 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001322 "size %u kB of chipset/board/programmer "
1323 "for %s interface, "
1324 "probe/read/erase/write may fail. ", size / 1024,
1325 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001326 }
hailfingere1e41ea2011-07-27 07:13:06 +00001327 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001328 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001329 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001330 "size %u kB of chipset/board/programmer "
1331 "for %s interface, "
1332 "probe/read/erase/write may fail. ", size / 1024,
1333 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001334 }
1335 if (!limitexceeded)
1336 return 0;
1337 /* Sometimes chip and programmer have more than one bus in common,
1338 * and the limit is not exceeded on all buses. Tell the user.
1339 */
1340 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001341 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001342 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001343 "interface which can support a chip of this size. "
1344 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001345 return 1;
1346}
1347
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001348void unmap_flash(struct flashctx *flash)
1349{
1350 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1351 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1352 flash->physical_registers = 0;
1353 flash->virtual_registers = (chipaddr)ERROR_PTR;
1354 }
1355
1356 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1357 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1358 flash->physical_memory = 0;
1359 flash->virtual_memory = (chipaddr)ERROR_PTR;
1360 }
1361}
1362
1363int map_flash(struct flashctx *flash)
1364{
1365 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1366 flash->virtual_memory = (chipaddr)ERROR_PTR;
1367 flash->virtual_registers = (chipaddr)ERROR_PTR;
1368
1369 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1370 * These are used for various probing-related hacks that would not map successfully anyway and should be
1371 * removed ASAP. */
1372 if (flash->chip->total_size == 0)
1373 return 0;
1374
1375 const chipsize_t size = flash->chip->total_size * 1024;
1376 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1377 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1378 if (addr == ERROR_PTR) {
1379 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1380 flash->chip->name, PRIxPTR_WIDTH, base);
1381 return 1;
1382 }
1383 flash->physical_memory = base;
1384 flash->virtual_memory = (chipaddr)addr;
1385
1386 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1387 * completely different on some chips and programmers, or not mappable at all.
1388 * Ignore these problems for now and always report success. */
1389 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1390 base = 0xffffffff - size - 0x400000 + 1;
1391 addr = programmer_map_flash_region("flash chip registers", base, size);
1392 if (addr == ERROR_PTR) {
1393 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1394 flash->chip->name, PRIxPTR_WIDTH, base);
1395 return 0;
1396 }
1397 flash->physical_registers = base;
1398 flash->virtual_registers = (chipaddr)addr;
1399 }
1400 return 0;
1401}
1402
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001403/*
1404 * Return a string corresponding to the bustype parameter.
1405 * Memory is obtained with malloc() and must be freed with free() by the caller.
1406 */
1407char *flashbuses_to_text(enum chipbustype bustype)
1408{
1409 char *ret = calloc(1, 1);
1410 /*
1411 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1412 * will cease to exist and should be eliminated here as well.
1413 */
1414 if (bustype == BUS_NONSPI) {
1415 ret = strcat_realloc(ret, "Non-SPI, ");
1416 } else {
1417 if (bustype & BUS_PARALLEL)
1418 ret = strcat_realloc(ret, "Parallel, ");
1419 if (bustype & BUS_LPC)
1420 ret = strcat_realloc(ret, "LPC, ");
1421 if (bustype & BUS_FWH)
1422 ret = strcat_realloc(ret, "FWH, ");
1423 if (bustype & BUS_SPI)
1424 ret = strcat_realloc(ret, "SPI, ");
1425 if (bustype & BUS_PROG)
1426 ret = strcat_realloc(ret, "Programmer-specific, ");
1427 if (bustype == BUS_NONE)
1428 ret = strcat_realloc(ret, "None, ");
1429 }
1430 /* Kill last comma. */
1431 ret[strlen(ret) - 2] = '\0';
1432 ret = realloc(ret, strlen(ret) + 1);
1433 return ret;
1434}
1435
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001436int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001437{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001438 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001439 uint32_t size;
1440 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001441 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001442
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301443 /* Based on the host controller interface that a platform
1444 * needs to use (hwseq or swseq),
1445 * set the flashchips list here.
1446 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001447 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301448 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001449 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301450 flash_list = flashchips_hwseq;
1451 break;
1452 default:
1453 flash_list = flashchips;
1454 break;
1455 }
1456
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001457 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1458 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001459 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001460 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001461 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001462 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001463 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001464 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001465 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001466 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001467 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001468 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001469 continue;
1470 }
stepan782fb172007-04-06 11:58:03 +00001471
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001472 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001473 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001474
hailfinger48ed3e22011-05-04 00:39:50 +00001475 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001476 flash->chip = calloc(1, sizeof(struct flashchip));
1477 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001478 msg_gerr("Out of memory!\n");
1479 exit(1);
1480 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001481 memcpy(flash->chip, chip, sizeof(struct flashchip));
1482 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001483
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001484 if (map_flash(flash) != 0)
1485 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001486
Edward O'Callaghana820b212020-09-17 22:53:26 +10001487 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1488 * is only called with force=1 after normal probing failed.
1489 */
stugec1e55fe2008-07-02 17:15:47 +00001490 if (force)
1491 break;
stepanc98b80b2006-03-16 16:57:41 +00001492
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001493 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001494 goto notfound;
1495
hailfinger48ed3e22011-05-04 00:39:50 +00001496 /* If this is the first chip found, accept it.
1497 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001498 * a non-generic match. SFDP and CFI are generic matches.
1499 * startchip==0 means this call to probe_flash() is the first
1500 * one for this programmer interface (master) and thus no other chip has
1501 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001502 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001503 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1504 msg_cinfo("===\n"
1505 "SFDP has autodetected a flash chip which is "
1506 "not natively supported by flashrom yet.\n");
1507 if (count_usable_erasers(flash) == 0)
1508 msg_cinfo("The standard operations read and "
1509 "verify should work, but to support "
1510 "erase, write and all other "
1511 "possible features");
1512 else
1513 msg_cinfo("All standard operations (read, "
1514 "verify, erase and write) should "
1515 "work, but to support all possible "
1516 "features");
1517
1518 msg_cinfo(" we need to add them manually.\n"
1519 "You can help us by mailing us the output of the following command to "
1520 "flashrom@flashrom.org:\n"
1521 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1522 "Thanks for your help!\n"
1523 "===\n");
1524 }
stugec1e55fe2008-07-02 17:15:47 +00001525
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001526 /* First flash chip detected on this bus. */
1527 if (startchip == 0)
1528 break;
1529 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001530 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001531 break;
1532 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001533notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001534 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001535 free(flash->chip);
1536 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001537 }
uwebe4477b2007-08-23 16:08:21 +00001538
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001539 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001540 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001541
stepan3e7aeae2011-01-19 06:21:54 +00001542
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001543 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001544 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1545 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001546 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001547#if CONFIG_INTERNAL == 1
1548 if (programmer_table[programmer].map_flash_region == physmap)
1549 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1550 PRIxPTR_WIDTH, flash->physical_memory);
1551 else
1552#endif
1553 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001554
Edward O'Callaghana820b212020-09-17 22:53:26 +10001555 /* Flash registers may more likely not be mapped if the chip was forced.
1556 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001557 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001558 if (flash->chip->printlock)
1559 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001560
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001561 /* Get out of the way for later runs. */
1562 unmap_flash(flash);
1563
hailfinger48ed3e22011-05-04 00:39:50 +00001564 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001565 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001566}
1567
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001568static int verify_flash(struct flashctx *flash,
1569 struct action_descriptor *descriptor,
1570 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001571{
hailfingerb0f4d122009-06-24 08:20:45 +00001572 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001573 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001574 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001575
snelsone42c3802010-05-07 20:09:04 +00001576 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001577
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001578 if (verify_it == VERIFY_PARTIAL) {
1579 struct processing_unit *pu = descriptor->processing_units;
1580
1581 /* Verify only areas which were written. */
1582 while (pu->num_blocks) {
1583 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001584 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001585 if (ret)
1586 break;
1587 pu++;
1588 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001589 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001590 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001591 }
uwef6641642007-05-09 10:17:44 +00001592
David Hendricks1ed1d352011-11-23 17:54:37 -08001593 if (ret == ACCESS_DENIED) {
1594 msg_gdbg("Could not fully verify due to access error, ");
1595 if (access_denied_action == error_ignore) {
1596 msg_gdbg("ignoring\n");
1597 ret = 0;
1598 } else {
1599 msg_gdbg("aborting\n");
1600 }
1601 }
1602
hailfingerb0f4d122009-06-24 08:20:45 +00001603 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001604 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001605
hailfingerb0f4d122009-06-24 08:20:45 +00001606 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001607}
1608
uwe8d342eb2011-07-28 08:13:25 +00001609int read_buf_from_file(unsigned char *buf, unsigned long size,
1610 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001611{
1612 unsigned long numbytes;
1613 FILE *image;
1614 struct stat image_stat;
1615
Vincent Palatin7ab23932014-10-01 12:09:16 -07001616 if (!strncmp(filename, "-", sizeof("-")))
1617 image = fdopen(STDIN_FILENO, "rb");
1618 else
1619 image = fopen(filename, "rb");
1620 if (image == NULL) {
hailfinger771fc182010-10-15 00:01:14 +00001621 perror(filename);
1622 return 1;
1623 }
1624 if (fstat(fileno(image), &image_stat) != 0) {
1625 perror(filename);
1626 fclose(image);
1627 return 1;
1628 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001629 if ((image_stat.st_size != size) &&
1630 (strncmp(filename, "-", sizeof("-")))) {
Mike Frysinger62c794d2017-05-29 12:02:45 -04001631 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1632 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
hailfinger771fc182010-10-15 00:01:14 +00001633 fclose(image);
1634 return 1;
1635 }
1636 numbytes = fread(buf, 1, size, image);
1637 if (fclose(image)) {
1638 perror(filename);
1639 return 1;
1640 }
1641 if (numbytes != size) {
1642 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1643 "wanted %ld!\n", numbytes, size);
1644 return 1;
1645 }
1646 return 0;
1647}
1648
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001649int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001650{
1651 unsigned long numbytes;
1652 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001653
1654 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001655 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001656 return 1;
1657 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001658 if (!strncmp(filename, "-", sizeof("-")))
1659 image = fdopen(STDOUT_FILENO, "wb");
1660 else
1661 image = fopen(filename, "wb");
1662 if (image == NULL) {
hailfingerd219a232009-01-28 00:27:54 +00001663 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001664 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001665 }
hailfingerd219a232009-01-28 00:27:54 +00001666
hailfingerd219a232009-01-28 00:27:54 +00001667 numbytes = fwrite(buf, 1, size, image);
1668 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001669 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001670 msg_gerr("Error: file %s could not be written completely.\n", filename);
hailfingerd219a232009-01-28 00:27:54 +00001671 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001672 }
hailfingerd219a232009-01-28 00:27:54 +00001673 return 0;
1674}
1675
David Hendrickse3451942013-03-21 17:23:29 -07001676/*
1677 * read_flash - wrapper for flash->read() with additional high-level policy
1678 *
1679 * @flash flash chip
1680 * @buf buffer to store data in
1681 * @start start address
1682 * @len number of bytes to read
1683 *
1684 * This wrapper simplifies most cases when the flash chip needs to be read
1685 * since policy decisions such as non-fatal error handling is centralized.
1686 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001687int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001688 unsigned int start, unsigned int len)
1689{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001690 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001691
Patrick Georgif3fa2992017-02-02 16:24:44 +01001692 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001693 return -1;
1694
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001695 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1696
Patrick Georgif3fa2992017-02-02 16:24:44 +01001697 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001698 if (ret) {
1699 if (ignore_error(ret)) {
1700 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1701 start, start + len - 1);
1702 ret = 0;
1703 } else {
1704 msg_gdbg("failed to read 0x%x-0x%x\n",
1705 start, start + len - 1);
1706 }
1707 }
1708
1709 return ret;
1710}
1711
David Hendricks7c8a1612013-04-26 19:14:44 -07001712/*
1713 * write_flash - wrapper for flash->write() with additional high-level policy
1714 *
1715 * @flash flash chip
1716 * @buf buffer to write to flash
1717 * @start start address in flash
1718 * @len number of bytes to write
1719 *
1720 * TODO: Look up regions that are write-protected and avoid attempt to write
1721 * to them at all.
1722 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001723int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001724 unsigned int start, unsigned int len)
1725{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001726 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001727 return -1;
1728
Patrick Georgif3fa2992017-02-02 16:24:44 +01001729 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001730}
1731
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001732int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001733{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001734 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001735 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001736 int ret = 0;
1737
1738 msg_cinfo("Reading flash... ");
1739 if (!buf) {
1740 msg_gerr("Memory allocation failed!\n");
1741 msg_cinfo("FAILED.\n");
1742 return 1;
1743 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001744
1745 /* To support partial read, fill buffer to all 0xFF at beginning to make
1746 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001747 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001748
Patrick Georgif3fa2992017-02-02 16:24:44 +01001749 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001750 msg_cerr("No read function available for this flash chip.\n");
1751 ret = 1;
1752 goto out_free;
1753 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001754
1755 /* First try to handle partial read case, rather than read the whole
1756 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001757 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001758 if (ret < 0) {
1759 msg_cerr("Partial read operation failed!\n");
1760 ret = 1;
1761 goto out_free;
1762 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001763 int num_regions = get_num_include_args();
1764
1765 if (ret != num_regions) {
1766 msg_cerr("Requested %d regions, but only read %d\n",
1767 num_regions, ret);
1768 ret = 1;
1769 goto out_free;
1770 }
1771
1772 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001773 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001774 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001775 msg_cerr("Read operation failed!\n");
1776 ret = 1;
1777 goto out_free;
1778 }
hailfinger42a850a2010-07-13 23:56:13 +00001779 }
1780
David Hendricksdf29a832013-06-28 14:33:51 -07001781 if (filename)
1782 ret = write_buf_to_file(buf, size, filename);
1783
hailfinger42a850a2010-07-13 23:56:13 +00001784out_free:
1785 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001786 if (ret)
1787 msg_cerr("FAILED.");
1788 else
1789 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001790 return ret;
1791}
1792
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001793/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001794static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001795{
hailfingerb91c08c2011-08-15 19:54:20 +00001796 int i, j, k;
1797 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001798
1799 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1800 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001801 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001802
1803 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1804 /* Blocks with zero size are bugs in flashchips.c. */
1805 if (eraser.eraseblocks[i].count &&
1806 !eraser.eraseblocks[i].size) {
1807 msg_gerr("ERROR: Flash chip %s erase function "
1808 "%i region %i has size 0. Please report"
1809 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001810 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001811 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001812 }
1813 /* Blocks with zero count are bugs in flashchips.c. */
1814 if (!eraser.eraseblocks[i].count &&
1815 eraser.eraseblocks[i].size) {
1816 msg_gerr("ERROR: Flash chip %s erase function "
1817 "%i region %i has count 0. Please report"
1818 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001819 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001820 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001821 }
1822 done += eraser.eraseblocks[i].count *
1823 eraser.eraseblocks[i].size;
1824 }
hailfinger9fed35d2010-01-19 06:42:46 +00001825 /* Empty eraseblock definition with erase function. */
1826 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001827 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001828 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001829 if (!done)
1830 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001831 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001832 msg_gerr("ERROR: Flash chip %s erase function %i "
1833 "region walking resulted in 0x%06x bytes total,"
1834 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001835 " flashrom@flashrom.org\n", chip->name, k,
1836 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001837 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001838 }
hailfinger9fed35d2010-01-19 06:42:46 +00001839 if (!eraser.block_erase)
1840 continue;
1841 /* Check if there are identical erase functions for different
1842 * layouts. That would imply "magic" erase functions. The
1843 * easiest way to check this is with function pointers.
1844 */
uwef6f94d42010-03-13 17:28:29 +00001845 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001846 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001847 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001848 msg_gerr("ERROR: Flash chip %s erase function "
1849 "%i and %i are identical. Please report"
1850 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001851 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001852 ret = 1;
1853 }
uwef6f94d42010-03-13 17:28:29 +00001854 }
hailfinger45177872010-01-18 08:14:43 +00001855 }
hailfinger9fed35d2010-01-19 06:42:46 +00001856 return ret;
hailfinger45177872010-01-18 08:14:43 +00001857}
1858
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001859static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001860 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001861 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001862 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001863 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001864 unsigned int addr,
1865 unsigned int len))
1866{
stefanctc5eb8a92011-11-23 09:13:48 +00001867 unsigned int starthere = 0, lenhere = 0;
1868 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001869 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001870 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001871
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001872 /*
1873 * curcontents and newcontents are opaque to walk_eraseregions, and
1874 * need to be adjusted here to keep the impression of proper
1875 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001876 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001877
hailfinger90fcf9b2010-11-05 14:51:59 +00001878 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001879
hailfingerb437e282010-11-04 01:04:27 +00001880 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001881
hailfingerb437e282010-11-04 01:04:27 +00001882 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001883 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001884 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001885 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001886 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001887 if (ret) {
1888 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001889 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001890 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001891 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001892 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001893 }
1894
David Hendricks0954ffc2015-11-13 15:15:44 -08001895 if (programmer_table[programmer].paranoid) {
1896 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001897 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001898 return -1;
1899 }
hailfingerac8e3182011-06-26 17:04:16 +00001900 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001901
hailfinger90fcf9b2010-11-05 14:51:59 +00001902 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001903 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001904 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001905 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001906 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001907 /* get_next_write() sets starthere to a new value after the call. */
1908 while ((lenhere = get_next_write(curcontents + starthere,
1909 newcontents + starthere,
1910 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001911 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001912 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001913 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001914 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001915 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001916 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001917 if (ret) {
1918 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001919 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001920 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001921 }
David Hendricks048b38c2016-03-28 18:47:06 -07001922
1923 /*
1924 * If the block needed to be erased and was erased successfully
1925 * then we can assume that we didn't run into any write-
1926 * protected areas. Otherwise, we need to verify each page to
1927 * ensure it was successfully written and abort if we encounter
1928 * any errors.
1929 */
1930 if (programmer_table[programmer].paranoid && !block_was_erased) {
1931 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001932 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001933 return -1;
1934 }
1935
hailfingerb437e282010-11-04 01:04:27 +00001936 starthere += lenhere;
1937 skip = 0;
1938 }
1939 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001940 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001941 return ret;
1942}
1943
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001944/*
1945 * Function to process processing units accumulated in the action descriptor.
1946 *
1947 * @flash pointer to the flash context to operate on
1948 * @do_something helper function which can erase and program a section of the
1949 * flash chip. It receives the flash context, offset and length
1950 * of the area to erase/program, before and after contents (to
1951 * decide what exactly needs to be erased and or programmed)
1952 * and a pointer to the erase function which can operate on the
1953 * proper granularity.
1954 * @descriptor action descriptor including pointers to before and after
1955 * contents and an array of processing actions to take.
1956 *
1957 * Returns zero on success or an error code.
1958 */
1959static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001960 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001961 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001962 unsigned int len,
1963 uint8_t *param1,
1964 uint8_t *param2,
1965 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001966 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001967 unsigned int addr,
1968 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001969 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00001970{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001971 struct processing_unit *pu;
1972 int rc = 0;
1973 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00001974
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001975 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1976 unsigned base = pu->offset;
1977 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07001978
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001979 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07001980
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001981 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00001982 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001983 else
1984 print_comma = 1;
1985
1986 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1987
1988 rc = do_something(flash, base,
1989 pu->block_size,
1990 descriptor->oldcontents,
1991 descriptor->newcontents,
1992 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
1993
David Hendricks1ed1d352011-11-23 17:54:37 -08001994 if (rc) {
1995 if (ignore_error(rc))
1996 rc = 0;
1997 else
1998 return rc;
hailfingerb437e282010-11-04 01:04:27 +00001999 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002000 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00002001 }
2002 }
hailfingerb437e282010-11-04 01:04:27 +00002003 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08002004 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00002005}
2006
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002007static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00002008{
Patrick Georgif3fa2992017-02-02 16:24:44 +01002009 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00002010
2011 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
2012 if (log)
2013 msg_cdbg("not defined. ");
2014 return 1;
2015 }
2016 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
2017 if (log)
2018 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00002019 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00002020 return 1;
2021 }
2022 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
2023 if (log)
2024 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00002025 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00002026 return 1;
2027 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002028 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002029 return 0;
2030}
2031
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002032int erase_and_write_flash(struct flashctx *flash,
2033 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002034{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002035 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002036
hailfingercf848f12010-12-05 15:14:44 +00002037 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002038
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002039 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002040
hailfinger7df21362009-09-05 02:30:58 +00002041 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002042 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002043 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002044 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002045 }
2046 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002047}
2048
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002049static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002050{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002051 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2052#if CONFIG_INTERNAL == 1
2053 if (programmer == PROGRAMMER_INTERNAL)
2054 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2055 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2056 "mail flashrom@flashrom.org, thanks!\n"
2057 "-------------------------------------------------------------------------------\n"
2058 "You may now reboot or simply leave the machine running.\n");
2059 else
2060#endif
2061 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2062 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2063 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2064 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002065}
2066
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002067static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002068{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002069 msg_gerr("Your flash chip is in an unknown state.\n");
2070#if CONFIG_INTERNAL == 1
2071 if (programmer == PROGRAMMER_INTERNAL)
2072 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2073 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2074 "-------------------------------------------------------------------------------\n"
2075 "DO NOT REBOOT OR POWEROFF!\n");
2076 else
2077#endif
2078 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2079 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002080}
2081
hailfingerf79d1712010-10-06 23:48:34 +00002082void list_programmers_linebreak(int startcol, int cols, int paren)
2083{
2084 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002085 int pnamelen;
2086 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002087 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002088 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002089
2090 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2091 pname = programmer_table[p].name;
2092 pnamelen = strlen(pname);
2093 if (remaining - pnamelen - 2 < 0) {
2094 if (firstline)
2095 firstline = 0;
2096 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002097 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002098 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002099 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002100 remaining = cols - startcol;
2101 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002102 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002103 remaining--;
2104 }
2105 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002106 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002107 remaining--;
2108 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002109 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002110 remaining -= pnamelen;
2111 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002112 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002113 remaining--;
2114 } else {
2115 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002116 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002117 }
2118 }
2119}
2120
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002121static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002122{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002123#if IS_WINDOWS
2124 SYSTEM_INFO si;
2125 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002126
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002127 memset(&si, 0, sizeof(SYSTEM_INFO));
2128 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2129 msg_ginfo(" on Windows");
2130 /* Tell Windows which version of the structure we want. */
2131 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2132 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2133 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2134 else
2135 msg_ginfo(" unknown version");
2136 GetSystemInfo(&si);
2137 switch (si.wProcessorArchitecture) {
2138 case PROCESSOR_ARCHITECTURE_AMD64:
2139 msg_ginfo(" (x86_64)");
2140 break;
2141 case PROCESSOR_ARCHITECTURE_INTEL:
2142 msg_ginfo(" (x86)");
2143 break;
2144 default:
2145 msg_ginfo(" (unknown arch)");
2146 break;
2147 }
2148#elif HAVE_UTSNAME == 1
2149 struct utsname osinfo;
2150
2151 uname(&osinfo);
2152 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002153 osinfo.machine);
2154#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002155 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002156#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002157}
2158
2159void print_buildinfo(void)
2160{
2161 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002162#if NEED_PCI == 1
2163#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002164 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002165#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002166 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002167#endif
2168#endif
2169#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002170 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002171#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002172 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002173#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002174 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002175#endif
hailfinger3b471632010-03-27 16:36:40 +00002176#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002177 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002178#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002179 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002180#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002181 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002182#endif
2183#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002184 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002185#endif
2186#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002187 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00002188#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002189 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00002190#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002191 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002192}
2193
uwefdeca092008-01-21 15:24:22 +00002194void print_version(void)
2195{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002196 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002197 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002198 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002199}
2200
hailfinger74819ad2010-05-15 15:04:37 +00002201void print_banner(void)
2202{
2203 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002204 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002205 msg_ginfo("\n");
2206}
2207
hailfingerc77acb52009-12-24 02:15:55 +00002208int selfcheck(void)
2209{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002210 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002211 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002212
2213 /* Safety check. Instead of aborting after the first error, check
2214 * if more errors exist.
2215 */
hailfingerc77acb52009-12-24 02:15:55 +00002216 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002217 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002218 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002219 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002220 /* It would be favorable if we could check for the correct layout (especially termination) of various
2221 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2222 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2223 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2224 * 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 +10002225 * checks below. */
2226 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002227 msg_gerr("Flashchips table miscompilation!\n");
2228 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002229 } else {
2230 for (i = 0; i < flashchips_size - 1; i++) {
2231 const struct flashchip *chip = &flashchips[i];
2232 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2233 ret = 1;
2234 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2235 "Please report a bug at flashrom@flashrom.org\n", i,
2236 chip->name == NULL ? "unnamed" : chip->name);
2237 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002238 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002239 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002240 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002241 }
stefanct6d836ba2011-05-26 01:35:19 +00002242 }
stefanct6d836ba2011-05-26 01:35:19 +00002243
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002244 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002245 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002246}
2247
hailfinger771fc182010-10-15 00:01:14 +00002248/* FIXME: This function signature needs to be improved once doit() has a better
2249 * function signature.
2250 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002251static int chip_safety_check(const struct flashctx *flash, int force,
2252 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002253{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002254 const struct flashchip *chip = flash->chip;
2255
hailfinger771fc182010-10-15 00:01:14 +00002256 if (!programmer_may_write && (write_it || erase_it)) {
2257 msg_perr("Write/erase is not working yet on your programmer in "
2258 "its current configuration.\n");
2259 /* --force is the wrong approach, but it's the best we can do
2260 * until the generic programmer parameter parser is merged.
2261 */
2262 if (!force)
2263 return 1;
2264 msg_cerr("Continuing anyway.\n");
2265 }
2266
2267 if (read_it || erase_it || write_it || verify_it) {
2268 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002269 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002270 msg_cerr("Read is not working on this chip. ");
2271 if (!force)
2272 return 1;
2273 msg_cerr("Continuing anyway.\n");
2274 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002275 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002276 msg_cerr("flashrom has no read function for this "
2277 "flash chip.\n");
2278 return 1;
2279 }
2280 }
2281 if (erase_it || write_it) {
2282 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002283 if (chip->tested.erase == NA) {
2284 msg_cerr("Erase is not possible on this chip.\n");
2285 return 1;
2286 }
2287 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002288 msg_cerr("Erase is not working on this chip. ");
2289 if (!force)
2290 return 1;
2291 msg_cerr("Continuing anyway.\n");
2292 }
stefancte1c5acf2011-07-04 07:27:17 +00002293 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002294 msg_cerr("flashrom has no erase function for this "
2295 "flash chip.\n");
2296 return 1;
2297 }
hailfinger771fc182010-10-15 00:01:14 +00002298 }
2299 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002300 if (chip->tested.write == NA) {
2301 msg_cerr("Write is not possible on this chip.\n");
2302 return 1;
2303 }
2304 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002305 msg_cerr("Write is not working on this chip. ");
2306 if (!force)
2307 return 1;
2308 msg_cerr("Continuing anyway.\n");
2309 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002310 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002311 msg_cerr("flashrom has no write function for this "
2312 "flash chip.\n");
2313 return 1;
2314 }
2315 }
2316 return 0;
2317}
2318
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002319int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002320 const bool read_it, const bool write_it,
2321 const bool erase_it, const bool verify_it)
2322{
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002323 if (chip_safety_check(flash, g_force /*flash->flags.force*/, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002324 msg_cerr("Aborting.\n");
2325 return 1;
2326 }
2327
2328 if (normalize_romentries(flash)) {
2329 msg_cerr("Requested regions can not be handled. Aborting.\n");
2330 return 1;
2331 }
2332
2333 /* Given the existence of read locks, we want to unlock for read,
2334 erase and write. */
2335 if (flash->chip->unlock)
2336 flash->chip->unlock(flash);
2337
2338 flash->address_high_byte = -1;
2339 flash->in_4ba_mode = false;
2340
2341 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2342 if ((flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN) && flash->chip->set_4ba) {
2343 if (flash->chip->set_4ba(flash)) {
2344 msg_cerr("Enabling/disabling 4-byte addressing mode failed!\n");
2345 return 1;
2346 }
2347 }
2348
2349 return 0;
2350}
2351
Edward O'Callaghana820b212020-09-17 22:53:26 +10002352void finalize_flash_access(struct flashctx *const flash)
2353{
2354 unmap_flash(flash);
2355}
2356
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002357/*
2358 * Function to erase entire flash chip.
2359 *
2360 * @flashctx pointer to the flash context to use
2361 * @oldcontents pointer to the buffer including current chip contents, to
2362 * decide which areas do in fact need to be erased
2363 * @size the size of the flash chip, in bytes.
2364 *
2365 * Returns zero on success or an error code.
2366 */
2367static int erase_chip(struct flashctx *flash, void *oldcontents,
2368 void *newcontents, size_t size)
2369{
2370 /*
2371 * To make sure that the chip is fully erased, let's cheat and create
2372 * a descriptor where the new contents are all erased.
2373 */
2374 struct action_descriptor *fake_descriptor;
2375 int ret = 0;
2376
2377 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2378 newcontents, 1);
2379 /* FIXME: Do we really want the scary warning if erase failed? After
2380 * all, after erase the chip is either blank or partially blank or it
2381 * has the old contents. A blank chip won't boot, so if the user
2382 * wanted erase and reboots afterwards, the user knows very well that
2383 * booting won't work.
2384 */
2385 if (erase_and_write_flash(flash, fake_descriptor)) {
2386 emergency_help_message();
2387 ret = 1;
2388 }
2389
2390 free(fake_descriptor);
2391
2392 return ret;
2393}
2394
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002395static int read_dest_content(struct flashctx *flash, int verify_it,
2396 uint8_t *dest, unsigned long size)
2397{
2398 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2399 && get_num_include_args()) {
2400 /*
2401 * If no full verification is required and not
2402 * the entire chip is about to be programmed,
2403 * read only the areas which might change.
2404 */
2405 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2406 return 1;
2407 } else {
2408 if (read_flash(flash, dest, 0, size))
2409 return 1;
2410 }
2411 return 0;
2412}
2413
hailfingerc77acb52009-12-24 02:15:55 +00002414/* This function signature is horrible. We need to design a better interface,
2415 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002416 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002417 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002418int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002419 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002420 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002421{
hailfinger4c47e9d2010-10-19 22:06:20 +00002422 uint8_t *oldcontents;
2423 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002424 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002425 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002426 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002427
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002428 g_force = force; // HACK
2429 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002430 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002431 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002432
Simon Glass9ad06c12013-07-03 22:08:17 +09002433 if (extract_it) {
2434 ret = extract_regions(flash);
2435 goto out_nofree;
2436 }
2437
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002438 /* mark entries included using -i argument as "included" if they are
2439 found in the master rom_entries list */
2440 if (process_include_args() < 0) {
2441 ret = 1;
2442 goto out_nofree;
2443 }
2444
hailfinger771fc182010-10-15 00:01:14 +00002445 if (read_it) {
2446 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002447 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002448 }
hailfingerb437e282010-11-04 01:04:27 +00002449
stefanctd611e8f2011-07-12 22:35:21 +00002450 oldcontents = malloc(size);
2451 if (!oldcontents) {
2452 msg_gerr("Out of memory!\n");
2453 exit(1);
2454 }
Simon Glass4c214132013-07-16 10:09:28 -06002455 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002456 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002457 newcontents = malloc(size);
2458 if (!newcontents) {
2459 msg_gerr("Out of memory!\n");
2460 exit(1);
2461 }
Simon Glass4c214132013-07-16 10:09:28 -06002462 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002463 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002464 /* Side effect of the assumptions above: Default write action is erase
2465 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002466 * oldcontents being completely unerased means we have to erase
2467 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002468 */
2469
hailfingerd217d122010-10-08 18:52:29 +00002470 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002471 /*
2472 * Note: This must be done before any files specified by -i
2473 * arguments are processed merged into the newcontents since
2474 * -i files take priority. See http://crbug.com/263495.
2475 */
2476 if (filename) {
2477 if (read_buf_from_file(newcontents, size, filename)) {
2478 ret = 1;
2479 goto out;
2480 }
2481 } else {
2482 /* Content will be read from -i args, so they must
2483 * not overlap. */
2484 if (included_regions_overlap()) {
2485 msg_gerr("Error: Included regions must "
2486 "not overlap.\n");
2487 ret = 1;
2488 goto out;
2489 }
stepan1da96c02006-11-21 23:48:51 +00002490 }
ollie5672ac62004-03-17 22:22:08 +00002491 }
2492
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002493 if (do_diff) {
2494 /*
2495 * Obtain a reference image so that we can check whether
2496 * regions need to be erased and to give better diagnostics in
2497 * case write fails. If --fast-verify is used then only the
2498 * regions which are included using -i will be read.
2499 */
2500 if (diff_file) {
2501 msg_cdbg("Reading old contents from file... ");
2502 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002503 ret = 1;
2504 msg_cdbg("FAILED.\n");
2505 goto out;
2506 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002507 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002508 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002509 ret = read_dest_content(flash, verify_it,
2510 oldcontents, size);
2511 if (ret) {
2512 msg_cdbg("FAILED.\n");
2513 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002514 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002515 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002516 msg_cdbg("done.\n");
2517 } else if (!erase_it) {
2518 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002519 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002520 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002521
David Hendricksdf29a832013-06-28 14:33:51 -07002522 /*
2523 * Note: This must be done after reading the file specified for the
2524 * -w/-v argument, if any, so that files specified using -i end up
2525 * in the "newcontents" buffer before being written.
2526 * See http://crbug.com/263495.
2527 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002528 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002529 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002530 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002531 goto out;
2532 }
uwef6641642007-05-09 10:17:44 +00002533
David Hendricksa7e114b2016-02-26 18:49:15 -08002534 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002535 erase_chip(flash, oldcontents, newcontents, size);
2536 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002537 }
2538
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002539 descriptor = prepare_action_descriptor(flash, oldcontents,
2540 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002541 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002542 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002543 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002544 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002545 goto out;
2546 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002547
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002548 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002549 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2550 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002551 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002552 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002553 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002554 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002555 ret = 1;
2556 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002557 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002558 msg_cerr("Apparently at least some data has changed.\n");
2559 } else
2560 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002561 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002562 ret = 1;
2563 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002564 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002565
David Hendricksac1d25c2016-08-09 17:00:58 -07002566 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002567 if (ret < 0) {
2568 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002569 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002570 emergency_help_message();
2571 ret = 1;
2572 goto out;
2573 } else if (ret > 0) {
2574 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002575 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002576 ret = read_dest_content(flash, verify_it,
2577 oldcontents, size);
2578 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002579 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002580 goto out;
2581 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002582
2583 /* Get a new descriptor. */
2584 free(descriptor);
2585 descriptor = prepare_action_descriptor(flash,
2586 oldcontents,
2587 newcontents,
2588 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002589 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002590 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002591 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002592 emergency_help_message();
2593 ret = 1;
2594 goto out;
2595 }
2596 ret = 0;
2597 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002598
David Hendricksac1d25c2016-08-09 17:00:58 -07002599 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002600 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002601 emergency_help_message();
2602 ret = 1;
2603 goto out;
2604 }
stuge8ce3a3c2008-04-28 14:47:30 +00002605 }
ollie6a600992005-11-26 21:55:36 +00002606
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002607 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002608 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002609 if ((write_it || erase_it) && !content_has_changed) {
2610 msg_gdbg("Nothing was erased or written, skipping "
2611 "verification\n");
2612 } else {
2613 /* Work around chips which need some time to calm down. */
2614 if (write_it && verify_it != VERIFY_PARTIAL)
2615 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002616
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002617 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002618
David Hendricks9ba79fb2015-04-03 12:06:16 -07002619 /* If we tried to write, and verification now fails, we
2620 * might have an emergency situation.
2621 */
2622 if (ret && write_it)
2623 emergency_help_message();
2624 }
hailfinger0459e1c2009-08-19 13:55:34 +00002625 }
ollie6a600992005-11-26 21:55:36 +00002626
hailfinger90fcf9b2010-11-05 14:51:59 +00002627out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002628 if (descriptor)
2629 free(descriptor);
2630
hailfinger90fcf9b2010-11-05 14:51:59 +00002631 free(oldcontents);
2632 free(newcontents);
2633out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002634 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002635 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002636 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002637 * tree. This is because some operations, such as write protection,
2638 * requires programmer_shutdown() but does not call doit().
2639 */
2640// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002641 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002642}