blob: 4d03b17d4bef3405d8d290df5a6561b12657d78e [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
Edward O'Callaghand8f72232020-09-30 14:21:42 +1000571#if CONFIG_GOOGLE_EC == 1
572 {
573 .name = "google_ec",
574 .type = OTHER,
575 .devs.note = "Google EC.\n",
576 .init = cros_ec_probe_dev,
577 .map_flash_region = fallback_map,
578 .unmap_flash_region = fallback_unmap,
579 .delay = internal_delay,
580 },
581#endif
582
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100583 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000584};
stepan927d4e22007-04-04 22:45:58 +0000585
David Hendricksbf36f092010-11-02 23:39:29 -0700586#define CHIP_RESTORE_MAXFN 4
587static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000588static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700589 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700590 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700591 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000592} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700593
David Hendricks668f29d2011-01-27 18:51:45 -0800594
hailfingerf31cbdc2010-11-10 15:25:18 +0000595#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000596static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000597/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000598static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700599 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000600 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000601} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000602/* Initialize to 0 to make sure nobody registers a shutdown function before
603 * programmer init.
604 */
605static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000606
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700607static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000608
hailfingerdc6f7972010-02-14 01:20:28 +0000609/* Register a function to be executed on programmer shutdown.
610 * The advantage over atexit() is that you can supply a void pointer which will
611 * be used as parameter to the registered function upon programmer shutdown.
612 * This pointer can point to arbitrary data used by said function, e.g. undo
613 * information for GPIO settings etc. If unneeded, set data=NULL.
614 * Please note that the first (void *data) belongs to the function signature of
615 * the function passed as first parameter.
616 */
David Hendricks93784b42016-08-09 17:00:38 -0700617int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000618{
619 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000620 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000621 SHUTDOWN_MAXFN);
622 return 1;
623 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000624 if (!may_register_shutdown) {
625 msg_perr("Tried to register a shutdown function before "
626 "programmer init.\n");
627 return 1;
628 }
hailfingerdc6f7972010-02-14 01:20:28 +0000629 shutdown_fn[shutdown_fn_count].func = function;
630 shutdown_fn[shutdown_fn_count].data = data;
631 shutdown_fn_count++;
632
633 return 0;
634}
635
David Hendricksbf36f092010-11-02 23:39:29 -0700636//int register_chip_restore(int (*function) (void *data), void *data)
637int register_chip_restore(CHIP_RESTORE_CALLBACK,
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700638 struct flashctx *flash, uint8_t status)
David Hendricksbf36f092010-11-02 23:39:29 -0700639{
640 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
641 msg_perr("Tried to register more than %i chip restore"
642 " functions.\n", CHIP_RESTORE_MAXFN);
643 return 1;
644 }
645 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
646 chip_restore_fn[chip_restore_fn_count].flash = flash;
647 chip_restore_fn[chip_restore_fn_count].status = status;
648 chip_restore_fn_count++;
649
650 return 0;
651}
652
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000653int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000654{
hailfinger1ef766d2010-07-06 09:55:48 +0000655 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000656
657 if (prog >= PROGRAMMER_INVALID) {
658 msg_perr("Invalid programmer specified!\n");
659 return -1;
660 }
661 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000662 /* Initialize all programmer specific data. */
663 /* Default to unlimited decode sizes. */
664 max_rom_decode = (const struct decode_sizes) {
665 .parallel = 0xffffffff,
666 .lpc = 0xffffffff,
667 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000668 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000669 };
David Hendricksac1d25c2016-08-09 17:00:58 -0700670 buses_supported = BUS_NONE;
hailfinger1ff33dc2010-07-03 11:02:10 +0000671 /* Default to top aligned flash at 4 GB. */
672 flashbase = 0;
673 /* Registering shutdown functions is now allowed. */
674 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000675 /* Default to allowing writes. Broken programmers set this to 0. */
676 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000677
678 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000679 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700680 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000681 if (programmer_param && strlen(programmer_param)) {
682 if (ret != 0) {
683 /* It is quite possible that any unhandled programmer parameter would have been valid,
684 * but an error in actual programmer init happened before the parameter was evaluated.
685 */
686 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
687 programmer_param);
688 } else {
689 /* Actual programmer init was successful, but the user specified an invalid or unusable
690 * (for the current programmer configuration) parameter.
691 */
692 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
693 msg_perr("Aborting.\n");
694 ret = ERROR_FATAL;
695 }
696 }
hailfinger1ef766d2010-07-06 09:55:48 +0000697 return ret;
uweabe92a52009-05-16 22:36:00 +0000698}
699
David Hendricksbf36f092010-11-02 23:39:29 -0700700int chip_restore()
701{
702 int rc = 0;
703
704 while (chip_restore_fn_count > 0) {
705 int i = --chip_restore_fn_count;
706 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
707 chip_restore_fn[i].status);
708 }
709
710 return rc;
711}
712
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000713/** Calls registered shutdown functions and resets internal programmer-related variables.
714 * Calling it is safe even without previous initialization, but further interactions with programmer support
715 * require a call to programmer_init() (afterwards).
716 *
717 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700718int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000719{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000720 int ret = 0;
721
hailfinger1ff33dc2010-07-03 11:02:10 +0000722 /* Registering shutdown functions is no longer allowed. */
723 may_register_shutdown = 0;
724 while (shutdown_fn_count > 0) {
725 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700726 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000727 }
dhendrix0ffc2eb2011-06-14 01:35:36 +0000728 return ret;
uweabe92a52009-05-16 22:36:00 +0000729}
730
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000731void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000732{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000733 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
734 return ret;
uweabe92a52009-05-16 22:36:00 +0000735}
736
737void programmer_unmap_flash_region(void *virt_addr, size_t len)
738{
739 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000740 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000741}
742
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700743void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000744{
Craig Hesling65eb8812019-08-01 09:33:56 -0700745 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000746}
747
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700748void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000749{
Craig Hesling65eb8812019-08-01 09:33:56 -0700750 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000751}
752
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700753void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000754{
Craig Hesling65eb8812019-08-01 09:33:56 -0700755 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000756}
757
Stuart langleyc98e43f2020-03-26 20:27:36 +1100758void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000759{
Craig Hesling65eb8812019-08-01 09:33:56 -0700760 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000761}
762
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700763uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000764{
Craig Hesling65eb8812019-08-01 09:33:56 -0700765 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000766}
767
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700768uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000769{
Craig Hesling65eb8812019-08-01 09:33:56 -0700770 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000771}
772
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700773uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000774{
Craig Hesling65eb8812019-08-01 09:33:56 -0700775 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000776}
777
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000778void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
779 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000780{
Craig Hesling65eb8812019-08-01 09:33:56 -0700781 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000782}
783
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000784void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000785{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000786 if (usecs > 0)
787 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000788}
789
Edward O'Callaghana820b212020-09-17 22:53:26 +1000790int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
791 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000792{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700793 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000794
hailfinger23060112009-05-08 12:49:03 +0000795 return 0;
796}
797
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000798/* This is a somewhat hacked function similar in some ways to strtok().
799 * It will look for needle with a subsequent '=' in haystack, return a copy of
800 * needle and remove everything from the first occurrence of needle to the next
801 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000802 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000803char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000804{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000805 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000806 char *opt = NULL;
807 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000808 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000809
hailfingerf4aaccc2010-04-28 15:22:14 +0000810 needlelen = strlen(needle);
811 if (!needlelen) {
812 msg_gerr("%s: empty needle! Please report a bug at "
813 "flashrom@flashrom.org\n", __func__);
814 return NULL;
815 }
816 /* No programmer parameters given. */
817 if (*haystack == NULL)
818 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000819 param_pos = strstr(*haystack, needle);
820 do {
821 if (!param_pos)
822 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000823 /* Needle followed by '='? */
824 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000825 /* Beginning of the string? */
826 if (param_pos == *haystack)
827 break;
828 /* After a delimiter? */
829 if (strchr(delim, *(param_pos - 1)))
830 break;
831 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000832 /* Continue searching. */
833 param_pos++;
834 param_pos = strstr(param_pos, needle);
835 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000836
hailfinger6e5a52a2009-11-24 18:27:10 +0000837 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000838 /* Get the string after needle and '='. */
839 opt_pos = param_pos + needlelen + 1;
840 optlen = strcspn(opt_pos, delim);
841 /* Return an empty string if the parameter was empty. */
842 opt = malloc(optlen + 1);
843 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000844 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000845 exit(1);
846 }
hailfinger1ef766d2010-07-06 09:55:48 +0000847 strncpy(opt, opt_pos, optlen);
848 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000849 rest = opt_pos + optlen;
850 /* Skip all delimiters after the current parameter. */
851 rest += strspn(rest, delim);
852 memmove(param_pos, rest, strlen(rest) + 1);
853 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000854 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000855
hailfinger1ef766d2010-07-06 09:55:48 +0000856 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000857}
858
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000859char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000860{
861 return extract_param(&programmer_param, param_name, ",");
862}
863
stefancte1c5acf2011-07-04 07:27:17 +0000864/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700865static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000866{
867 unsigned int usable_erasefunctions = 0;
868 int k;
869 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
870 if (!check_block_eraser(flash, k, 0))
871 usable_erasefunctions++;
872 }
873 return usable_erasefunctions;
874}
875
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000876static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700877{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000878 int ret = 0, failcount = 0;
879 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700880 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000881 if (wantbuf[i] != havebuf[i]) {
882 /* Only print the first failure. */
883 if (!failcount++)
884 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
885 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700886 }
887 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000888 if (failcount) {
889 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
890 start, start + len - 1, failcount);
891 ret = -1;
892 }
893 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700894}
895
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000896/* start is an offset to the base address of the flash chip */
897static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
898{
899 int ret;
900 uint8_t *cmpbuf = malloc(len);
901 const uint8_t erased_value = ERASED_VALUE(flash);
902
903 if (!cmpbuf) {
904 msg_gerr("Could not allocate memory!\n");
905 exit(1);
906 }
907 memset(cmpbuf, erased_value, len);
908 ret = verify_range(flash, cmpbuf, start, len);
909 free(cmpbuf);
910 return ret;
911}
912
uwee15beb92010-08-08 17:01:18 +0000913/*
hailfinger7af3d192009-11-25 17:05:52 +0000914 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000915 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000916 * @start offset to the base address of the flash chip
917 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000918 * @return 0 for success, -1 for failure
919 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000920int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000921{
hailfinger7af83692009-06-15 17:23:36 +0000922 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000923 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000924
Patrick Georgif3fa2992017-02-02 16:24:44 +0100925 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000926 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000927 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000928 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000929
930 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000931 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000932 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000933 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000934 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000935 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000936
Patrick Georgif3fa2992017-02-02 16:24:44 +0100937 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000938 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000939 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100940 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000941 ret = -1;
942 goto out_free;
943 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700944 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700945 if (programmer_table[programmer].paranoid) {
946 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800947
Simon Glass4e305f42015-01-08 06:29:04 -0700948 /* limit chunksize in order to catch errors early */
949 for (i = 0, chunksize = 0; i < len; i += chunksize) {
950 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800951
Patrick Georgif3fa2992017-02-02 16:24:44 +0100952 chunksize = min(flash->chip->page_size, len - i);
953 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700954 if (tmp) {
955 ret = tmp;
956 if (ignore_error(tmp))
957 continue;
958 else
959 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800960 }
Simon Glass4e305f42015-01-08 06:29:04 -0700961
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700962 /*
963 * Check write access permission and do not compare chunks
964 * where flashrom does not have write access to the region.
965 */
966 if (flash->chip->check_access) {
967 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
968 if (tmp && ignore_error(tmp))
969 continue;
970 }
971
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000972 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700973 if (failcount)
974 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800975 }
Simon Glass4e305f42015-01-08 06:29:04 -0700976 } else {
977 int tmp;
978
979 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +0100980 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -0700981 if (tmp && !ignore_error(tmp)) {
982 ret = tmp;
983 goto out_free;
984 }
985
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000986 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +0000987 }
988
hailfinger5be6c0f2009-07-23 01:42:56 +0000989 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +0000990 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +0000991 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +0000992 ret = -1;
993 }
hailfinger7af83692009-06-15 17:23:36 +0000994
995out_free:
996 free(readbuf);
997 return ret;
998}
999
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001000/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1001static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001002 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001003{
1004 unsigned int i, j, limit;
1005 for (j = 0; j < len / gran; j++) {
1006 limit = min (gran, len - j * gran);
1007 /* Are 'have' and 'want' identical? */
1008 if (!memcmp(have + j * gran, want + j * gran, limit))
1009 continue;
1010 /* have needs to be in erased state. */
1011 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001012 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001013 return 1;
1014 }
1015 return 0;
1016}
1017
uwee15beb92010-08-08 17:01:18 +00001018/*
hailfingerb247c7a2010-03-08 00:42:32 +00001019 * Check if the buffer @have can be programmed to the content of @want without
1020 * erasing. This is only possible if all chunks of size @gran are either kept
1021 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001022 *
hailfingerb437e282010-11-04 01:04:27 +00001023 * Warning: This function assumes that @have and @want point to naturally
1024 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001025 *
1026 * @have buffer with current content
1027 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001028 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001029 * @gran write granularity (enum, not count)
1030 * @return 0 if no erase is needed, 1 otherwise
1031 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001032int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1033 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001034{
hailfingerb91c08c2011-08-15 19:54:20 +00001035 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001036 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001037
hailfingerb247c7a2010-03-08 00:42:32 +00001038 switch (gran) {
1039 case write_gran_1bit:
1040 for (i = 0; i < len; i++)
1041 if ((have[i] & want[i]) != want[i]) {
1042 result = 1;
1043 break;
1044 }
1045 break;
1046 case write_gran_1byte:
1047 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001048 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001049 result = 1;
1050 break;
1051 }
1052 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001053 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001054 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001055 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001056 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001057 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001058 break;
1059 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001060 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001061 break;
1062 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001063 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001064 break;
1065 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001066 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001067 break;
1068 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001069 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001070 break;
1071 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001072 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001073 break;
1074 case write_gran_1byte_implicit_erase:
1075 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1076 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001077 break;
hailfingerb437e282010-11-04 01:04:27 +00001078 default:
1079 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1080 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001081 }
1082 return result;
1083}
1084
hailfingerb437e282010-11-04 01:04:27 +00001085/**
1086 * Check if the buffer @have needs to be programmed to get the content of @want.
1087 * If yes, return 1 and fill in first_start with the start address of the
1088 * write operation and first_len with the length of the first to-be-written
1089 * chunk. If not, return 0 and leave first_start and first_len undefined.
1090 *
1091 * Warning: This function assumes that @have and @want point to naturally
1092 * aligned regions.
1093 *
1094 * @have buffer with current content
1095 * @want buffer with desired content
1096 * @len length of the checked area
1097 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001098 * @first_start offset of the first byte which needs to be written (passed in
1099 * value is increased by the offset of the first needed write
1100 * relative to have/want or unchanged if no write is needed)
1101 * @return length of the first contiguous area which needs to be written
1102 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001103 *
1104 * FIXME: This function needs a parameter which tells it about coalescing
1105 * in relation to the max write length of the programmer and the max write
1106 * length of the chip.
1107 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001108static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001109 unsigned int *first_start,
1110 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001111{
stefanctc5eb8a92011-11-23 09:13:48 +00001112 int need_write = 0;
1113 unsigned int rel_start = 0, first_len = 0;
1114 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001115
hailfingerb437e282010-11-04 01:04:27 +00001116 switch (gran) {
1117 case write_gran_1bit:
1118 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001119 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001120 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001121 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001122 case write_gran_128bytes:
1123 stride = 128;
1124 break;
hailfingerb437e282010-11-04 01:04:27 +00001125 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001126 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001127 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001128 case write_gran_264bytes:
1129 stride = 264;
1130 break;
1131 case write_gran_512bytes:
1132 stride = 512;
1133 break;
1134 case write_gran_528bytes:
1135 stride = 528;
1136 break;
1137 case write_gran_1024bytes:
1138 stride = 1024;
1139 break;
1140 case write_gran_1056bytes:
1141 stride = 1056;
1142 break;
hailfingerb437e282010-11-04 01:04:27 +00001143 default:
1144 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1145 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001146 /* Claim that no write was needed. A write with unknown
1147 * granularity is too dangerous to try.
1148 */
1149 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001150 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001151 for (i = 0; i < len / stride; i++) {
1152 limit = min(stride, len - i * stride);
1153 /* Are 'have' and 'want' identical? */
1154 if (memcmp(have + i * stride, want + i * stride, limit)) {
1155 if (!need_write) {
1156 /* First location where have and want differ. */
1157 need_write = 1;
1158 rel_start = i * stride;
1159 }
1160 } else {
1161 if (need_write) {
1162 /* First location where have and want
1163 * do not differ anymore.
1164 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001165 break;
1166 }
1167 }
1168 }
hailfingerffb7f382010-12-06 13:05:44 +00001169 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001170 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001171 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001172 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001173}
1174
hailfinger0c515352009-11-23 12:55:31 +00001175/* This function generates various test patterns useful for testing controller
1176 * and chip communication as well as chip behaviour.
1177 *
1178 * If a byte can be written multiple times, each time keeping 0-bits at 0
1179 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1180 * is essentially an AND operation. That's also the reason why this function
1181 * provides the result of AND between various patterns.
1182 *
1183 * Below is a list of patterns (and their block length).
1184 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1185 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1186 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1187 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1188 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1189 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1190 * Pattern 6 is 00 (1 Byte)
1191 * Pattern 7 is ff (1 Byte)
1192 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1193 * byte block.
1194 *
1195 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1196 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1197 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1198 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1199 * Pattern 12 is 00 (1 Byte)
1200 * Pattern 13 is ff (1 Byte)
1201 * Patterns 8-13 have no block number.
1202 *
1203 * Patterns 0-3 are created to detect and efficiently diagnose communication
1204 * slips like missed bits or bytes and their repetitive nature gives good visual
1205 * cues to the person inspecting the results. In addition, the following holds:
1206 * AND Pattern 0/1 == Pattern 4
1207 * AND Pattern 2/3 == Pattern 5
1208 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1209 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1210 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1211 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1212 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1213 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1214 * Besides that, they provide for bit testing of the last two bytes of every
1215 * 256 byte block which contains the block number for patterns 0-6.
1216 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1217 * block sizes >256 bytes (some Dataflash chips etc.)
1218 * AND Pattern 8/9 == Pattern 12
1219 * AND Pattern 10/11 == Pattern 12
1220 * Pattern 13 is the completely erased state.
1221 * None of the patterns can detect aliasing at boundaries which are a multiple
1222 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1223 */
1224int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1225{
1226 int i;
1227
1228 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001229 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001230 return 1;
1231 }
1232
1233 switch (variant) {
1234 case 0:
1235 for (i = 0; i < size; i++)
1236 buf[i] = (i & 0xf) << 4 | 0x5;
1237 break;
1238 case 1:
1239 for (i = 0; i < size; i++)
1240 buf[i] = (i & 0xf) << 4 | 0xa;
1241 break;
1242 case 2:
1243 for (i = 0; i < size; i++)
1244 buf[i] = 0x50 | (i & 0xf);
1245 break;
1246 case 3:
1247 for (i = 0; i < size; i++)
1248 buf[i] = 0xa0 | (i & 0xf);
1249 break;
1250 case 4:
1251 for (i = 0; i < size; i++)
1252 buf[i] = (i & 0xf) << 4;
1253 break;
1254 case 5:
1255 for (i = 0; i < size; i++)
1256 buf[i] = i & 0xf;
1257 break;
1258 case 6:
1259 memset(buf, 0x00, size);
1260 break;
1261 case 7:
1262 memset(buf, 0xff, size);
1263 break;
1264 case 8:
1265 for (i = 0; i < size; i++)
1266 buf[i] = i & 0xff;
1267 break;
1268 case 9:
1269 for (i = 0; i < size; i++)
1270 buf[i] = ~(i & 0xff);
1271 break;
1272 case 10:
1273 for (i = 0; i < size % 2; i++) {
1274 buf[i * 2] = (i >> 8) & 0xff;
1275 buf[i * 2 + 1] = i & 0xff;
1276 }
1277 if (size & 0x1)
1278 buf[i * 2] = (i >> 8) & 0xff;
1279 break;
1280 case 11:
1281 for (i = 0; i < size % 2; i++) {
1282 buf[i * 2] = ~((i >> 8) & 0xff);
1283 buf[i * 2 + 1] = ~(i & 0xff);
1284 }
1285 if (size & 0x1)
1286 buf[i * 2] = ~((i >> 8) & 0xff);
1287 break;
1288 case 12:
1289 memset(buf, 0x00, size);
1290 break;
1291 case 13:
1292 memset(buf, 0xff, size);
1293 break;
1294 }
1295
1296 if ((variant >= 0) && (variant <= 7)) {
1297 /* Write block number in the last two bytes of each 256-byte
1298 * block, big endian for easier reading of the hexdump.
1299 * Note that this wraps around for chips larger than 2^24 bytes
1300 * (16 MB).
1301 */
1302 for (i = 0; i < size / 256; i++) {
1303 buf[i * 256 + 254] = (i >> 8) & 0xff;
1304 buf[i * 256 + 255] = i & 0xff;
1305 }
1306 }
1307
1308 return 0;
1309}
1310
hailfingeraec9c962009-10-31 01:53:09 +00001311int check_max_decode(enum chipbustype buses, uint32_t size)
1312{
1313 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001314
1315 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001316 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001317 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001318 "size %u kB of chipset/board/programmer "
1319 "for %s interface, "
1320 "probe/read/erase/write may fail. ", size / 1024,
1321 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001322 }
hailfingere1e41ea2011-07-27 07:13:06 +00001323 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001324 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001325 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001326 "size %u kB of chipset/board/programmer "
1327 "for %s interface, "
1328 "probe/read/erase/write may fail. ", size / 1024,
1329 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001330 }
hailfingere1e41ea2011-07-27 07:13:06 +00001331 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001332 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001333 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001334 "size %u kB of chipset/board/programmer "
1335 "for %s interface, "
1336 "probe/read/erase/write may fail. ", size / 1024,
1337 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001338 }
hailfingere1e41ea2011-07-27 07:13:06 +00001339 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001340 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001341 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001342 "size %u kB of chipset/board/programmer "
1343 "for %s interface, "
1344 "probe/read/erase/write may fail. ", size / 1024,
1345 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001346 }
1347 if (!limitexceeded)
1348 return 0;
1349 /* Sometimes chip and programmer have more than one bus in common,
1350 * and the limit is not exceeded on all buses. Tell the user.
1351 */
1352 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001353 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001354 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001355 "interface which can support a chip of this size. "
1356 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001357 return 1;
1358}
1359
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001360void unmap_flash(struct flashctx *flash)
1361{
1362 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1363 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1364 flash->physical_registers = 0;
1365 flash->virtual_registers = (chipaddr)ERROR_PTR;
1366 }
1367
1368 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1369 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1370 flash->physical_memory = 0;
1371 flash->virtual_memory = (chipaddr)ERROR_PTR;
1372 }
1373}
1374
1375int map_flash(struct flashctx *flash)
1376{
1377 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1378 flash->virtual_memory = (chipaddr)ERROR_PTR;
1379 flash->virtual_registers = (chipaddr)ERROR_PTR;
1380
1381 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1382 * These are used for various probing-related hacks that would not map successfully anyway and should be
1383 * removed ASAP. */
1384 if (flash->chip->total_size == 0)
1385 return 0;
1386
1387 const chipsize_t size = flash->chip->total_size * 1024;
1388 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1389 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1390 if (addr == ERROR_PTR) {
1391 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1392 flash->chip->name, PRIxPTR_WIDTH, base);
1393 return 1;
1394 }
1395 flash->physical_memory = base;
1396 flash->virtual_memory = (chipaddr)addr;
1397
1398 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1399 * completely different on some chips and programmers, or not mappable at all.
1400 * Ignore these problems for now and always report success. */
1401 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1402 base = 0xffffffff - size - 0x400000 + 1;
1403 addr = programmer_map_flash_region("flash chip registers", base, size);
1404 if (addr == ERROR_PTR) {
1405 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1406 flash->chip->name, PRIxPTR_WIDTH, base);
1407 return 0;
1408 }
1409 flash->physical_registers = base;
1410 flash->virtual_registers = (chipaddr)addr;
1411 }
1412 return 0;
1413}
1414
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001415/*
1416 * Return a string corresponding to the bustype parameter.
1417 * Memory is obtained with malloc() and must be freed with free() by the caller.
1418 */
1419char *flashbuses_to_text(enum chipbustype bustype)
1420{
1421 char *ret = calloc(1, 1);
1422 /*
1423 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1424 * will cease to exist and should be eliminated here as well.
1425 */
1426 if (bustype == BUS_NONSPI) {
1427 ret = strcat_realloc(ret, "Non-SPI, ");
1428 } else {
1429 if (bustype & BUS_PARALLEL)
1430 ret = strcat_realloc(ret, "Parallel, ");
1431 if (bustype & BUS_LPC)
1432 ret = strcat_realloc(ret, "LPC, ");
1433 if (bustype & BUS_FWH)
1434 ret = strcat_realloc(ret, "FWH, ");
1435 if (bustype & BUS_SPI)
1436 ret = strcat_realloc(ret, "SPI, ");
1437 if (bustype & BUS_PROG)
1438 ret = strcat_realloc(ret, "Programmer-specific, ");
1439 if (bustype == BUS_NONE)
1440 ret = strcat_realloc(ret, "None, ");
1441 }
1442 /* Kill last comma. */
1443 ret[strlen(ret) - 2] = '\0';
1444 ret = realloc(ret, strlen(ret) + 1);
1445 return ret;
1446}
1447
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001448int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001449{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001450 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001451 uint32_t size;
1452 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001453 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001454
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301455 /* Based on the host controller interface that a platform
1456 * needs to use (hwseq or swseq),
1457 * set the flashchips list here.
1458 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001459 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301460 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001461 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301462 flash_list = flashchips_hwseq;
1463 break;
1464 default:
1465 flash_list = flashchips;
1466 break;
1467 }
1468
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001469 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1470 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001471 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001472 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001473 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001474 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001475 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001476 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001477 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001478 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001479 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001480 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001481 continue;
1482 }
stepan782fb172007-04-06 11:58:03 +00001483
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001484 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001485 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001486
hailfinger48ed3e22011-05-04 00:39:50 +00001487 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001488 flash->chip = calloc(1, sizeof(struct flashchip));
1489 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001490 msg_gerr("Out of memory!\n");
1491 exit(1);
1492 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001493 memcpy(flash->chip, chip, sizeof(struct flashchip));
1494 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001495
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001496 if (map_flash(flash) != 0)
1497 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001498
Edward O'Callaghana820b212020-09-17 22:53:26 +10001499 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1500 * is only called with force=1 after normal probing failed.
1501 */
stugec1e55fe2008-07-02 17:15:47 +00001502 if (force)
1503 break;
stepanc98b80b2006-03-16 16:57:41 +00001504
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001505 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001506 goto notfound;
1507
hailfinger48ed3e22011-05-04 00:39:50 +00001508 /* If this is the first chip found, accept it.
1509 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001510 * a non-generic match. SFDP and CFI are generic matches.
1511 * startchip==0 means this call to probe_flash() is the first
1512 * one for this programmer interface (master) and thus no other chip has
1513 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001514 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001515 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1516 msg_cinfo("===\n"
1517 "SFDP has autodetected a flash chip which is "
1518 "not natively supported by flashrom yet.\n");
1519 if (count_usable_erasers(flash) == 0)
1520 msg_cinfo("The standard operations read and "
1521 "verify should work, but to support "
1522 "erase, write and all other "
1523 "possible features");
1524 else
1525 msg_cinfo("All standard operations (read, "
1526 "verify, erase and write) should "
1527 "work, but to support all possible "
1528 "features");
1529
1530 msg_cinfo(" we need to add them manually.\n"
1531 "You can help us by mailing us the output of the following command to "
1532 "flashrom@flashrom.org:\n"
1533 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1534 "Thanks for your help!\n"
1535 "===\n");
1536 }
stugec1e55fe2008-07-02 17:15:47 +00001537
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001538 /* First flash chip detected on this bus. */
1539 if (startchip == 0)
1540 break;
1541 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001542 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001543 break;
1544 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001545notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001546 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001547 free(flash->chip);
1548 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001549 }
uwebe4477b2007-08-23 16:08:21 +00001550
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001551 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001552 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001553
stepan3e7aeae2011-01-19 06:21:54 +00001554
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001555 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001556 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1557 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001558 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001559#if CONFIG_INTERNAL == 1
1560 if (programmer_table[programmer].map_flash_region == physmap)
1561 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1562 PRIxPTR_WIDTH, flash->physical_memory);
1563 else
1564#endif
1565 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001566
Edward O'Callaghana820b212020-09-17 22:53:26 +10001567 /* Flash registers may more likely not be mapped if the chip was forced.
1568 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001569 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001570 if (flash->chip->printlock)
1571 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001572
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001573 /* Get out of the way for later runs. */
1574 unmap_flash(flash);
1575
hailfinger48ed3e22011-05-04 00:39:50 +00001576 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001577 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001578}
1579
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001580static int verify_flash(struct flashctx *flash,
1581 struct action_descriptor *descriptor,
1582 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001583{
hailfingerb0f4d122009-06-24 08:20:45 +00001584 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001585 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001586 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001587
snelsone42c3802010-05-07 20:09:04 +00001588 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001589
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001590 if (verify_it == VERIFY_PARTIAL) {
1591 struct processing_unit *pu = descriptor->processing_units;
1592
1593 /* Verify only areas which were written. */
1594 while (pu->num_blocks) {
1595 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001596 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001597 if (ret)
1598 break;
1599 pu++;
1600 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001601 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001602 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001603 }
uwef6641642007-05-09 10:17:44 +00001604
David Hendricks1ed1d352011-11-23 17:54:37 -08001605 if (ret == ACCESS_DENIED) {
1606 msg_gdbg("Could not fully verify due to access error, ");
1607 if (access_denied_action == error_ignore) {
1608 msg_gdbg("ignoring\n");
1609 ret = 0;
1610 } else {
1611 msg_gdbg("aborting\n");
1612 }
1613 }
1614
hailfingerb0f4d122009-06-24 08:20:45 +00001615 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001616 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001617
hailfingerb0f4d122009-06-24 08:20:45 +00001618 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001619}
1620
uwe8d342eb2011-07-28 08:13:25 +00001621int read_buf_from_file(unsigned char *buf, unsigned long size,
1622 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001623{
1624 unsigned long numbytes;
1625 FILE *image;
1626 struct stat image_stat;
1627
Vincent Palatin7ab23932014-10-01 12:09:16 -07001628 if (!strncmp(filename, "-", sizeof("-")))
1629 image = fdopen(STDIN_FILENO, "rb");
1630 else
1631 image = fopen(filename, "rb");
1632 if (image == NULL) {
hailfinger771fc182010-10-15 00:01:14 +00001633 perror(filename);
1634 return 1;
1635 }
1636 if (fstat(fileno(image), &image_stat) != 0) {
1637 perror(filename);
1638 fclose(image);
1639 return 1;
1640 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001641 if ((image_stat.st_size != size) &&
1642 (strncmp(filename, "-", sizeof("-")))) {
Mike Frysinger62c794d2017-05-29 12:02:45 -04001643 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1644 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
hailfinger771fc182010-10-15 00:01:14 +00001645 fclose(image);
1646 return 1;
1647 }
1648 numbytes = fread(buf, 1, size, image);
1649 if (fclose(image)) {
1650 perror(filename);
1651 return 1;
1652 }
1653 if (numbytes != size) {
1654 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1655 "wanted %ld!\n", numbytes, size);
1656 return 1;
1657 }
1658 return 0;
1659}
1660
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001661int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001662{
1663 unsigned long numbytes;
1664 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001665
1666 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001667 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001668 return 1;
1669 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001670 if (!strncmp(filename, "-", sizeof("-")))
1671 image = fdopen(STDOUT_FILENO, "wb");
1672 else
1673 image = fopen(filename, "wb");
1674 if (image == NULL) {
hailfingerd219a232009-01-28 00:27:54 +00001675 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001676 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001677 }
hailfingerd219a232009-01-28 00:27:54 +00001678
hailfingerd219a232009-01-28 00:27:54 +00001679 numbytes = fwrite(buf, 1, size, image);
1680 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001681 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001682 msg_gerr("Error: file %s could not be written completely.\n", filename);
hailfingerd219a232009-01-28 00:27:54 +00001683 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001684 }
hailfingerd219a232009-01-28 00:27:54 +00001685 return 0;
1686}
1687
David Hendrickse3451942013-03-21 17:23:29 -07001688/*
1689 * read_flash - wrapper for flash->read() with additional high-level policy
1690 *
1691 * @flash flash chip
1692 * @buf buffer to store data in
1693 * @start start address
1694 * @len number of bytes to read
1695 *
1696 * This wrapper simplifies most cases when the flash chip needs to be read
1697 * since policy decisions such as non-fatal error handling is centralized.
1698 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001699int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001700 unsigned int start, unsigned int len)
1701{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001702 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001703
Patrick Georgif3fa2992017-02-02 16:24:44 +01001704 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001705 return -1;
1706
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001707 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1708
Patrick Georgif3fa2992017-02-02 16:24:44 +01001709 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001710 if (ret) {
1711 if (ignore_error(ret)) {
1712 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1713 start, start + len - 1);
1714 ret = 0;
1715 } else {
1716 msg_gdbg("failed to read 0x%x-0x%x\n",
1717 start, start + len - 1);
1718 }
1719 }
1720
1721 return ret;
1722}
1723
David Hendricks7c8a1612013-04-26 19:14:44 -07001724/*
1725 * write_flash - wrapper for flash->write() with additional high-level policy
1726 *
1727 * @flash flash chip
1728 * @buf buffer to write to flash
1729 * @start start address in flash
1730 * @len number of bytes to write
1731 *
1732 * TODO: Look up regions that are write-protected and avoid attempt to write
1733 * to them at all.
1734 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001735int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001736 unsigned int start, unsigned int len)
1737{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001738 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001739 return -1;
1740
Patrick Georgif3fa2992017-02-02 16:24:44 +01001741 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001742}
1743
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001744int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001745{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001746 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001747 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001748 int ret = 0;
1749
1750 msg_cinfo("Reading flash... ");
1751 if (!buf) {
1752 msg_gerr("Memory allocation failed!\n");
1753 msg_cinfo("FAILED.\n");
1754 return 1;
1755 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001756
1757 /* To support partial read, fill buffer to all 0xFF at beginning to make
1758 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001759 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001760
Patrick Georgif3fa2992017-02-02 16:24:44 +01001761 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001762 msg_cerr("No read function available for this flash chip.\n");
1763 ret = 1;
1764 goto out_free;
1765 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001766
1767 /* First try to handle partial read case, rather than read the whole
1768 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001769 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001770 if (ret < 0) {
1771 msg_cerr("Partial read operation failed!\n");
1772 ret = 1;
1773 goto out_free;
1774 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001775 int num_regions = get_num_include_args();
1776
1777 if (ret != num_regions) {
1778 msg_cerr("Requested %d regions, but only read %d\n",
1779 num_regions, ret);
1780 ret = 1;
1781 goto out_free;
1782 }
1783
1784 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001785 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001786 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001787 msg_cerr("Read operation failed!\n");
1788 ret = 1;
1789 goto out_free;
1790 }
hailfinger42a850a2010-07-13 23:56:13 +00001791 }
1792
David Hendricksdf29a832013-06-28 14:33:51 -07001793 if (filename)
1794 ret = write_buf_to_file(buf, size, filename);
1795
hailfinger42a850a2010-07-13 23:56:13 +00001796out_free:
1797 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001798 if (ret)
1799 msg_cerr("FAILED.");
1800 else
1801 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001802 return ret;
1803}
1804
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001805/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001806static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001807{
hailfingerb91c08c2011-08-15 19:54:20 +00001808 int i, j, k;
1809 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001810
1811 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1812 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001813 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001814
1815 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1816 /* Blocks with zero size are bugs in flashchips.c. */
1817 if (eraser.eraseblocks[i].count &&
1818 !eraser.eraseblocks[i].size) {
1819 msg_gerr("ERROR: Flash chip %s erase function "
1820 "%i region %i has size 0. Please report"
1821 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001822 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001823 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001824 }
1825 /* Blocks with zero count are bugs in flashchips.c. */
1826 if (!eraser.eraseblocks[i].count &&
1827 eraser.eraseblocks[i].size) {
1828 msg_gerr("ERROR: Flash chip %s erase function "
1829 "%i region %i has count 0. Please report"
1830 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001831 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001832 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001833 }
1834 done += eraser.eraseblocks[i].count *
1835 eraser.eraseblocks[i].size;
1836 }
hailfinger9fed35d2010-01-19 06:42:46 +00001837 /* Empty eraseblock definition with erase function. */
1838 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001839 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001840 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001841 if (!done)
1842 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001843 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001844 msg_gerr("ERROR: Flash chip %s erase function %i "
1845 "region walking resulted in 0x%06x bytes total,"
1846 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001847 " flashrom@flashrom.org\n", chip->name, k,
1848 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001849 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001850 }
hailfinger9fed35d2010-01-19 06:42:46 +00001851 if (!eraser.block_erase)
1852 continue;
1853 /* Check if there are identical erase functions for different
1854 * layouts. That would imply "magic" erase functions. The
1855 * easiest way to check this is with function pointers.
1856 */
uwef6f94d42010-03-13 17:28:29 +00001857 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001858 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001859 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001860 msg_gerr("ERROR: Flash chip %s erase function "
1861 "%i and %i are identical. Please report"
1862 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001863 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001864 ret = 1;
1865 }
uwef6f94d42010-03-13 17:28:29 +00001866 }
hailfinger45177872010-01-18 08:14:43 +00001867 }
hailfinger9fed35d2010-01-19 06:42:46 +00001868 return ret;
hailfinger45177872010-01-18 08:14:43 +00001869}
1870
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001871static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001872 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001873 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001874 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001875 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001876 unsigned int addr,
1877 unsigned int len))
1878{
stefanctc5eb8a92011-11-23 09:13:48 +00001879 unsigned int starthere = 0, lenhere = 0;
1880 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001881 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001882 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001883
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001884 /*
1885 * curcontents and newcontents are opaque to walk_eraseregions, and
1886 * need to be adjusted here to keep the impression of proper
1887 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001888 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001889
hailfinger90fcf9b2010-11-05 14:51:59 +00001890 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001891
hailfingerb437e282010-11-04 01:04:27 +00001892 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001893
hailfingerb437e282010-11-04 01:04:27 +00001894 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001895 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001896 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001897 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001898 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001899 if (ret) {
1900 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001901 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001902 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001903 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001904 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001905 }
1906
David Hendricks0954ffc2015-11-13 15:15:44 -08001907 if (programmer_table[programmer].paranoid) {
1908 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001909 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001910 return -1;
1911 }
hailfingerac8e3182011-06-26 17:04:16 +00001912 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001913
hailfinger90fcf9b2010-11-05 14:51:59 +00001914 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001915 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001916 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001917 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001918 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001919 /* get_next_write() sets starthere to a new value after the call. */
1920 while ((lenhere = get_next_write(curcontents + starthere,
1921 newcontents + starthere,
1922 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001923 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001924 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001925 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001926 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001927 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001928 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001929 if (ret) {
1930 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001931 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001932 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001933 }
David Hendricks048b38c2016-03-28 18:47:06 -07001934
1935 /*
1936 * If the block needed to be erased and was erased successfully
1937 * then we can assume that we didn't run into any write-
1938 * protected areas. Otherwise, we need to verify each page to
1939 * ensure it was successfully written and abort if we encounter
1940 * any errors.
1941 */
1942 if (programmer_table[programmer].paranoid && !block_was_erased) {
1943 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001944 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001945 return -1;
1946 }
1947
hailfingerb437e282010-11-04 01:04:27 +00001948 starthere += lenhere;
1949 skip = 0;
1950 }
1951 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001952 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001953 return ret;
1954}
1955
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001956/*
1957 * Function to process processing units accumulated in the action descriptor.
1958 *
1959 * @flash pointer to the flash context to operate on
1960 * @do_something helper function which can erase and program a section of the
1961 * flash chip. It receives the flash context, offset and length
1962 * of the area to erase/program, before and after contents (to
1963 * decide what exactly needs to be erased and or programmed)
1964 * and a pointer to the erase function which can operate on the
1965 * proper granularity.
1966 * @descriptor action descriptor including pointers to before and after
1967 * contents and an array of processing actions to take.
1968 *
1969 * Returns zero on success or an error code.
1970 */
1971static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001972 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001973 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001974 unsigned int len,
1975 uint8_t *param1,
1976 uint8_t *param2,
1977 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001978 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001979 unsigned int addr,
1980 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001981 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00001982{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001983 struct processing_unit *pu;
1984 int rc = 0;
1985 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00001986
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001987 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1988 unsigned base = pu->offset;
1989 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07001990
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001991 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07001992
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001993 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00001994 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001995 else
1996 print_comma = 1;
1997
1998 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1999
2000 rc = do_something(flash, base,
2001 pu->block_size,
2002 descriptor->oldcontents,
2003 descriptor->newcontents,
2004 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
2005
David Hendricks1ed1d352011-11-23 17:54:37 -08002006 if (rc) {
2007 if (ignore_error(rc))
2008 rc = 0;
2009 else
2010 return rc;
hailfingerb437e282010-11-04 01:04:27 +00002011 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002012 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00002013 }
2014 }
hailfingerb437e282010-11-04 01:04:27 +00002015 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08002016 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00002017}
2018
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002019static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00002020{
Patrick Georgif3fa2992017-02-02 16:24:44 +01002021 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00002022
2023 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
2024 if (log)
2025 msg_cdbg("not defined. ");
2026 return 1;
2027 }
2028 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
2029 if (log)
2030 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00002031 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00002032 return 1;
2033 }
2034 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
2035 if (log)
2036 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00002037 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00002038 return 1;
2039 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002040 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002041 return 0;
2042}
2043
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002044int erase_and_write_flash(struct flashctx *flash,
2045 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002046{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002047 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002048
hailfingercf848f12010-12-05 15:14:44 +00002049 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002050
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002051 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002052
hailfinger7df21362009-09-05 02:30:58 +00002053 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002054 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002055 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002056 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002057 }
2058 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002059}
2060
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002061static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002062{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002063 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2064#if CONFIG_INTERNAL == 1
2065 if (programmer == PROGRAMMER_INTERNAL)
2066 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2067 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2068 "mail flashrom@flashrom.org, thanks!\n"
2069 "-------------------------------------------------------------------------------\n"
2070 "You may now reboot or simply leave the machine running.\n");
2071 else
2072#endif
2073 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2074 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2075 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2076 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002077}
2078
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002079static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002080{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002081 msg_gerr("Your flash chip is in an unknown state.\n");
2082#if CONFIG_INTERNAL == 1
2083 if (programmer == PROGRAMMER_INTERNAL)
2084 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2085 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2086 "-------------------------------------------------------------------------------\n"
2087 "DO NOT REBOOT OR POWEROFF!\n");
2088 else
2089#endif
2090 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2091 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002092}
2093
hailfingerf79d1712010-10-06 23:48:34 +00002094void list_programmers_linebreak(int startcol, int cols, int paren)
2095{
2096 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002097 int pnamelen;
2098 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002099 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002100 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002101
2102 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2103 pname = programmer_table[p].name;
2104 pnamelen = strlen(pname);
2105 if (remaining - pnamelen - 2 < 0) {
2106 if (firstline)
2107 firstline = 0;
2108 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002109 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002110 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002111 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002112 remaining = cols - startcol;
2113 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002114 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002115 remaining--;
2116 }
2117 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002118 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002119 remaining--;
2120 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002121 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002122 remaining -= pnamelen;
2123 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002124 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002125 remaining--;
2126 } else {
2127 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002128 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002129 }
2130 }
2131}
2132
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002133static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002134{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002135#if IS_WINDOWS
2136 SYSTEM_INFO si;
2137 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002138
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002139 memset(&si, 0, sizeof(SYSTEM_INFO));
2140 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2141 msg_ginfo(" on Windows");
2142 /* Tell Windows which version of the structure we want. */
2143 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2144 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2145 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2146 else
2147 msg_ginfo(" unknown version");
2148 GetSystemInfo(&si);
2149 switch (si.wProcessorArchitecture) {
2150 case PROCESSOR_ARCHITECTURE_AMD64:
2151 msg_ginfo(" (x86_64)");
2152 break;
2153 case PROCESSOR_ARCHITECTURE_INTEL:
2154 msg_ginfo(" (x86)");
2155 break;
2156 default:
2157 msg_ginfo(" (unknown arch)");
2158 break;
2159 }
2160#elif HAVE_UTSNAME == 1
2161 struct utsname osinfo;
2162
2163 uname(&osinfo);
2164 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002165 osinfo.machine);
2166#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002167 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002168#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002169}
2170
2171void print_buildinfo(void)
2172{
2173 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002174#if NEED_PCI == 1
2175#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002176 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002177#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002178 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002179#endif
2180#endif
2181#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002182 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002183#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002184 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002185#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002186 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002187#endif
hailfinger3b471632010-03-27 16:36:40 +00002188#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002189 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002190#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002191 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002192#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002193 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002194#endif
2195#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002196 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002197#endif
2198#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002199 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00002200#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002201 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00002202#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002203 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002204}
2205
uwefdeca092008-01-21 15:24:22 +00002206void print_version(void)
2207{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002208 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002209 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002210 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002211}
2212
hailfinger74819ad2010-05-15 15:04:37 +00002213void print_banner(void)
2214{
2215 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002216 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002217 msg_ginfo("\n");
2218}
2219
hailfingerc77acb52009-12-24 02:15:55 +00002220int selfcheck(void)
2221{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002222 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002223 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002224
2225 /* Safety check. Instead of aborting after the first error, check
2226 * if more errors exist.
2227 */
hailfingerc77acb52009-12-24 02:15:55 +00002228 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002229 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002230 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002231 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002232 /* It would be favorable if we could check for the correct layout (especially termination) of various
2233 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2234 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2235 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2236 * 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 +10002237 * checks below. */
2238 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002239 msg_gerr("Flashchips table miscompilation!\n");
2240 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002241 } else {
2242 for (i = 0; i < flashchips_size - 1; i++) {
2243 const struct flashchip *chip = &flashchips[i];
2244 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2245 ret = 1;
2246 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2247 "Please report a bug at flashrom@flashrom.org\n", i,
2248 chip->name == NULL ? "unnamed" : chip->name);
2249 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002250 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002251 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002252 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002253 }
stefanct6d836ba2011-05-26 01:35:19 +00002254 }
stefanct6d836ba2011-05-26 01:35:19 +00002255
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002256 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002257 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002258}
2259
hailfinger771fc182010-10-15 00:01:14 +00002260/* FIXME: This function signature needs to be improved once doit() has a better
2261 * function signature.
2262 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002263static int chip_safety_check(const struct flashctx *flash, int force,
2264 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002265{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002266 const struct flashchip *chip = flash->chip;
2267
hailfinger771fc182010-10-15 00:01:14 +00002268 if (!programmer_may_write && (write_it || erase_it)) {
2269 msg_perr("Write/erase is not working yet on your programmer in "
2270 "its current configuration.\n");
2271 /* --force is the wrong approach, but it's the best we can do
2272 * until the generic programmer parameter parser is merged.
2273 */
2274 if (!force)
2275 return 1;
2276 msg_cerr("Continuing anyway.\n");
2277 }
2278
2279 if (read_it || erase_it || write_it || verify_it) {
2280 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002281 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002282 msg_cerr("Read is not working on this chip. ");
2283 if (!force)
2284 return 1;
2285 msg_cerr("Continuing anyway.\n");
2286 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002287 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002288 msg_cerr("flashrom has no read function for this "
2289 "flash chip.\n");
2290 return 1;
2291 }
2292 }
2293 if (erase_it || write_it) {
2294 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002295 if (chip->tested.erase == NA) {
2296 msg_cerr("Erase is not possible on this chip.\n");
2297 return 1;
2298 }
2299 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002300 msg_cerr("Erase is not working on this chip. ");
2301 if (!force)
2302 return 1;
2303 msg_cerr("Continuing anyway.\n");
2304 }
stefancte1c5acf2011-07-04 07:27:17 +00002305 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002306 msg_cerr("flashrom has no erase function for this "
2307 "flash chip.\n");
2308 return 1;
2309 }
hailfinger771fc182010-10-15 00:01:14 +00002310 }
2311 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002312 if (chip->tested.write == NA) {
2313 msg_cerr("Write is not possible on this chip.\n");
2314 return 1;
2315 }
2316 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002317 msg_cerr("Write is not working on this chip. ");
2318 if (!force)
2319 return 1;
2320 msg_cerr("Continuing anyway.\n");
2321 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002322 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002323 msg_cerr("flashrom has no write function for this "
2324 "flash chip.\n");
2325 return 1;
2326 }
2327 }
2328 return 0;
2329}
2330
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002331int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002332 const bool read_it, const bool write_it,
2333 const bool erase_it, const bool verify_it)
2334{
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002335 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 +10002336 msg_cerr("Aborting.\n");
2337 return 1;
2338 }
2339
2340 if (normalize_romentries(flash)) {
2341 msg_cerr("Requested regions can not be handled. Aborting.\n");
2342 return 1;
2343 }
2344
2345 /* Given the existence of read locks, we want to unlock for read,
2346 erase and write. */
2347 if (flash->chip->unlock)
2348 flash->chip->unlock(flash);
2349
2350 flash->address_high_byte = -1;
2351 flash->in_4ba_mode = false;
2352
2353 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2354 if ((flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN) && flash->chip->set_4ba) {
2355 if (flash->chip->set_4ba(flash)) {
2356 msg_cerr("Enabling/disabling 4-byte addressing mode failed!\n");
2357 return 1;
2358 }
2359 }
2360
2361 return 0;
2362}
2363
Edward O'Callaghana820b212020-09-17 22:53:26 +10002364void finalize_flash_access(struct flashctx *const flash)
2365{
2366 unmap_flash(flash);
2367}
2368
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002369/*
2370 * Function to erase entire flash chip.
2371 *
2372 * @flashctx pointer to the flash context to use
2373 * @oldcontents pointer to the buffer including current chip contents, to
2374 * decide which areas do in fact need to be erased
2375 * @size the size of the flash chip, in bytes.
2376 *
2377 * Returns zero on success or an error code.
2378 */
2379static int erase_chip(struct flashctx *flash, void *oldcontents,
2380 void *newcontents, size_t size)
2381{
2382 /*
2383 * To make sure that the chip is fully erased, let's cheat and create
2384 * a descriptor where the new contents are all erased.
2385 */
2386 struct action_descriptor *fake_descriptor;
2387 int ret = 0;
2388
2389 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2390 newcontents, 1);
2391 /* FIXME: Do we really want the scary warning if erase failed? After
2392 * all, after erase the chip is either blank or partially blank or it
2393 * has the old contents. A blank chip won't boot, so if the user
2394 * wanted erase and reboots afterwards, the user knows very well that
2395 * booting won't work.
2396 */
2397 if (erase_and_write_flash(flash, fake_descriptor)) {
2398 emergency_help_message();
2399 ret = 1;
2400 }
2401
2402 free(fake_descriptor);
2403
2404 return ret;
2405}
2406
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002407static int read_dest_content(struct flashctx *flash, int verify_it,
2408 uint8_t *dest, unsigned long size)
2409{
2410 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2411 && get_num_include_args()) {
2412 /*
2413 * If no full verification is required and not
2414 * the entire chip is about to be programmed,
2415 * read only the areas which might change.
2416 */
2417 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2418 return 1;
2419 } else {
2420 if (read_flash(flash, dest, 0, size))
2421 return 1;
2422 }
2423 return 0;
2424}
2425
hailfingerc77acb52009-12-24 02:15:55 +00002426/* This function signature is horrible. We need to design a better interface,
2427 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002428 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002429 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002430int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002431 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002432 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002433{
hailfinger4c47e9d2010-10-19 22:06:20 +00002434 uint8_t *oldcontents;
2435 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002436 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002437 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002438 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002439
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002440 g_force = force; // HACK
2441 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002442 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002443 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002444
Simon Glass9ad06c12013-07-03 22:08:17 +09002445 if (extract_it) {
2446 ret = extract_regions(flash);
2447 goto out_nofree;
2448 }
2449
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002450 /* mark entries included using -i argument as "included" if they are
2451 found in the master rom_entries list */
2452 if (process_include_args() < 0) {
2453 ret = 1;
2454 goto out_nofree;
2455 }
2456
hailfinger771fc182010-10-15 00:01:14 +00002457 if (read_it) {
2458 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002459 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002460 }
hailfingerb437e282010-11-04 01:04:27 +00002461
stefanctd611e8f2011-07-12 22:35:21 +00002462 oldcontents = malloc(size);
2463 if (!oldcontents) {
2464 msg_gerr("Out of memory!\n");
2465 exit(1);
2466 }
Simon Glass4c214132013-07-16 10:09:28 -06002467 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002468 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002469 newcontents = malloc(size);
2470 if (!newcontents) {
2471 msg_gerr("Out of memory!\n");
2472 exit(1);
2473 }
Simon Glass4c214132013-07-16 10:09:28 -06002474 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002475 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002476 /* Side effect of the assumptions above: Default write action is erase
2477 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002478 * oldcontents being completely unerased means we have to erase
2479 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002480 */
2481
hailfingerd217d122010-10-08 18:52:29 +00002482 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002483 /*
2484 * Note: This must be done before any files specified by -i
2485 * arguments are processed merged into the newcontents since
2486 * -i files take priority. See http://crbug.com/263495.
2487 */
2488 if (filename) {
2489 if (read_buf_from_file(newcontents, size, filename)) {
2490 ret = 1;
2491 goto out;
2492 }
2493 } else {
2494 /* Content will be read from -i args, so they must
2495 * not overlap. */
2496 if (included_regions_overlap()) {
2497 msg_gerr("Error: Included regions must "
2498 "not overlap.\n");
2499 ret = 1;
2500 goto out;
2501 }
stepan1da96c02006-11-21 23:48:51 +00002502 }
ollie5672ac62004-03-17 22:22:08 +00002503 }
2504
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002505 if (do_diff) {
2506 /*
2507 * Obtain a reference image so that we can check whether
2508 * regions need to be erased and to give better diagnostics in
2509 * case write fails. If --fast-verify is used then only the
2510 * regions which are included using -i will be read.
2511 */
2512 if (diff_file) {
2513 msg_cdbg("Reading old contents from file... ");
2514 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002515 ret = 1;
2516 msg_cdbg("FAILED.\n");
2517 goto out;
2518 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002519 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002520 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002521 ret = read_dest_content(flash, verify_it,
2522 oldcontents, size);
2523 if (ret) {
2524 msg_cdbg("FAILED.\n");
2525 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002526 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002527 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002528 msg_cdbg("done.\n");
2529 } else if (!erase_it) {
2530 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002531 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002532 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002533
David Hendricksdf29a832013-06-28 14:33:51 -07002534 /*
2535 * Note: This must be done after reading the file specified for the
2536 * -w/-v argument, if any, so that files specified using -i end up
2537 * in the "newcontents" buffer before being written.
2538 * See http://crbug.com/263495.
2539 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002540 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002541 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002542 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002543 goto out;
2544 }
uwef6641642007-05-09 10:17:44 +00002545
David Hendricksa7e114b2016-02-26 18:49:15 -08002546 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002547 erase_chip(flash, oldcontents, newcontents, size);
2548 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002549 }
2550
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002551 descriptor = prepare_action_descriptor(flash, oldcontents,
2552 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002553 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002554 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002555 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002556 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002557 goto out;
2558 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002559
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002560 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002561 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2562 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002563 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002564 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002565 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002566 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002567 ret = 1;
2568 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002569 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002570 msg_cerr("Apparently at least some data has changed.\n");
2571 } else
2572 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002573 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002574 ret = 1;
2575 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002576 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002577
David Hendricksac1d25c2016-08-09 17:00:58 -07002578 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002579 if (ret < 0) {
2580 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002581 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002582 emergency_help_message();
2583 ret = 1;
2584 goto out;
2585 } else if (ret > 0) {
2586 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002587 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002588 ret = read_dest_content(flash, verify_it,
2589 oldcontents, size);
2590 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002591 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002592 goto out;
2593 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002594
2595 /* Get a new descriptor. */
2596 free(descriptor);
2597 descriptor = prepare_action_descriptor(flash,
2598 oldcontents,
2599 newcontents,
2600 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002601 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002602 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002603 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002604 emergency_help_message();
2605 ret = 1;
2606 goto out;
2607 }
2608 ret = 0;
2609 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002610
David Hendricksac1d25c2016-08-09 17:00:58 -07002611 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002612 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002613 emergency_help_message();
2614 ret = 1;
2615 goto out;
2616 }
stuge8ce3a3c2008-04-28 14:47:30 +00002617 }
ollie6a600992005-11-26 21:55:36 +00002618
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002619 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002620 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002621 if ((write_it || erase_it) && !content_has_changed) {
2622 msg_gdbg("Nothing was erased or written, skipping "
2623 "verification\n");
2624 } else {
2625 /* Work around chips which need some time to calm down. */
2626 if (write_it && verify_it != VERIFY_PARTIAL)
2627 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002628
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002629 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002630
David Hendricks9ba79fb2015-04-03 12:06:16 -07002631 /* If we tried to write, and verification now fails, we
2632 * might have an emergency situation.
2633 */
2634 if (ret && write_it)
2635 emergency_help_message();
2636 }
hailfinger0459e1c2009-08-19 13:55:34 +00002637 }
ollie6a600992005-11-26 21:55:36 +00002638
hailfinger90fcf9b2010-11-05 14:51:59 +00002639out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002640 if (descriptor)
2641 free(descriptor);
2642
hailfinger90fcf9b2010-11-05 14:51:59 +00002643 free(oldcontents);
2644 free(newcontents);
2645out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002646 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002647 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002648 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002649 * tree. This is because some operations, such as write protection,
2650 * requires programmer_shutdown() but does not call doit().
2651 */
2652// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002653 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002654}