blob: 44d6145bc71261e2bb639bd180d21009282f5f50 [file] [log] [blame]
rminnich8d3ff912003-10-25 17:01:29 +00001/*
uweb25f1ea2007-08-29 17:52:32 +00002 * This file is part of the flashrom project.
rminnich8d3ff912003-10-25 17:01:29 +00003 *
uwe555dd972007-09-09 20:21:05 +00004 * Copyright (C) 2000 Silicon Integrated System Corporation
5 * Copyright (C) 2004 Tyan Corp <yhlu@tyan.com>
uwe4475e902009-05-19 14:14:21 +00006 * Copyright (C) 2005-2008 coresystems GmbH
hailfinger23060112009-05-08 12:49:03 +00007 * Copyright (C) 2008,2009 Carl-Daniel Hailfinger
Edward O'Callaghan0949b782019-11-10 23:23:20 +11008 * Copyright (C) 2016 secunet Security Networks AG
9 * (Written by Nico Huber <nico.huber@secunet.com> for secunet)
rminnich8d3ff912003-10-25 17:01:29 +000010 *
uweb25f1ea2007-08-29 17:52:32 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
rminnich8d3ff912003-10-25 17:01:29 +000015 *
uweb25f1ea2007-08-29 17:52:32 +000016 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
rminnich8d3ff912003-10-25 17:01:29 +000020 */
21
hailfingera83a5fe2010-05-30 22:24:40 +000022#include <stdio.h>
stepan1da96c02006-11-21 23:48:51 +000023#include <sys/types.h>
oxygene50275892010-09-30 17:03:32 +000024#ifndef __LIBPAYLOAD__
25#include <fcntl.h>
stepan1da96c02006-11-21 23:48:51 +000026#include <sys/stat.h>
oxygene50275892010-09-30 17:03:32 +000027#endif
rminnich8d3ff912003-10-25 17:01:29 +000028#include <string.h>
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +100029#include <unistd.h>
rminnich8d3ff912003-10-25 17:01:29 +000030#include <stdlib.h>
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +100031#include <errno.h>
hailfingerf76cc322010-11-09 22:00:31 +000032#include <ctype.h>
ollie6a600992005-11-26 21:55:36 +000033#include <getopt.h>
hailfinger3b471632010-03-27 16:36:40 +000034#if HAVE_UTSNAME == 1
35#include <sys/utsname.h>
36#endif
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -070037
38#include "action_descriptor.h"
rminnich8d3ff912003-10-25 17:01:29 +000039#include "flash.h"
hailfinger66966da2009-06-15 14:14:48 +000040#include "flashchips.h"
Simon Glass9ad06c12013-07-03 22:08:17 +090041#include "layout.h"
hailfinger428f6852010-07-27 22:41:39 +000042#include "programmer.h"
Duncan Laurie25a4ca22019-04-25 12:08:52 -070043#include "spi.h"
rminnich8d3ff912003-10-25 17:01:29 +000044
krause2eb76212011-01-17 07:50:42 +000045const char flashrom_version[] = FLASHROM_VERSION;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100046const char *chip_to_probe = NULL;
hailfinger80422e22009-12-13 22:28:00 +000047
David Hendricks9ba79fb2015-04-03 12:06:16 -070048/* Set if any erase/write operation is to be done. This will be used to
49 * decide if final verification is needed. */
50static int content_has_changed = 0;
51
Edward O'Callaghana0176ff2020-08-18 15:49:23 +100052static int g_force = 0; // HACK to keep prepare_flash_access() signature the same.
53
David Hendricks1ed1d352011-11-23 17:54:37 -080054/* error handling stuff */
55enum error_action access_denied_action = error_ignore;
56
57int ignore_error(int err) {
58 int rc = 0;
59
60 switch(err) {
61 case ACCESS_DENIED:
62 if (access_denied_action == error_ignore)
63 rc = 1;
64 break;
65 default:
66 break;
67 }
68
69 return rc;
70}
71
hailfinger969e2f32011-09-08 00:00:29 +000072static enum programmer programmer = PROGRAMMER_INVALID;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100073static const char *programmer_param = NULL;
stepan782fb172007-04-06 11:58:03 +000074
David Hendricksac1d25c2016-08-09 17:00:58 -070075/* Supported buses for the current programmer. */
76enum chipbustype buses_supported;
77
uwee15beb92010-08-08 17:01:18 +000078/*
hailfinger80422e22009-12-13 22:28:00 +000079 * Programmers supporting multiple buses can have differing size limits on
80 * each bus. Store the limits for each bus in a common struct.
81 */
hailfinger1ff33dc2010-07-03 11:02:10 +000082struct decode_sizes max_rom_decode;
83
84/* If nonzero, used as the start address of bottom-aligned flash. */
85unsigned long flashbase;
hailfinger80422e22009-12-13 22:28:00 +000086
hailfinger5828baf2010-07-03 12:14:25 +000087/* Is writing allowed with this programmer? */
88int programmer_may_write;
89
hailfingerabe249e2009-05-08 17:43:22 +000090const struct programmer_entry programmer_table[] = {
hailfinger90c7d542010-05-31 15:27:27 +000091#if CONFIG_INTERNAL == 1
hailfingerabe249e2009-05-08 17:43:22 +000092 {
hailfinger3548a9a2009-08-12 14:34:35 +000093 .name = "internal",
Edward O'Callaghan0949b782019-11-10 23:23:20 +110094 .type = OTHER,
95 .devs.note = NULL,
hailfinger6c69ab02009-05-11 15:46:43 +000096 .init = internal_init,
hailfinger11ae3c42009-05-11 14:13:25 +000097 .map_flash_region = physmap,
98 .unmap_flash_region = physunmap,
hailfingere5829f62009-06-05 17:48:08 +000099 .delay = internal_delay,
David Hendricks55cdd9c2015-11-25 14:37:26 -0800100
101 /*
102 * "Internal" implies in-system programming on a live system, so
103 * handle with paranoia to catch errors early. If something goes
104 * wrong then hopefully the system will still be recoverable.
105 */
106 .paranoid = 1,
hailfingerabe249e2009-05-08 17:43:22 +0000107 },
hailfinger80422e22009-12-13 22:28:00 +0000108#endif
stepan927d4e22007-04-04 22:45:58 +0000109
hailfinger90c7d542010-05-31 15:27:27 +0000110#if CONFIG_DUMMY == 1
hailfingera9df33c2009-05-09 00:54:55 +0000111 {
hailfinger3548a9a2009-08-12 14:34:35 +0000112 .name = "dummy",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100113 .type = OTHER,
114 /* FIXME */
115 .devs.note = "Dummy device, does nothing and logs all accesses\n",
hailfinger6c69ab02009-05-11 15:46:43 +0000116 .init = dummy_init,
hailfinger11ae3c42009-05-11 14:13:25 +0000117 .map_flash_region = dummy_map,
118 .unmap_flash_region = dummy_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000119 .delay = internal_delay,
hailfingera9df33c2009-05-09 00:54:55 +0000120 },
hailfinger571a6b32009-09-16 10:09:21 +0000121#endif
hailfingera9df33c2009-05-09 00:54:55 +0000122
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000123#if CONFIG_MEC1308 == 1
124 {
125 .name = "mec1308",
126 .type = OTHER,
127 .devs.note = "Microchip MEC1308 Embedded Controller.\n",
128 .init = mec1308_init,
129 .map_flash_region = fallback_map,
130 .unmap_flash_region = fallback_unmap,
131 .delay = internal_delay,
132 },
133#endif
134
hailfinger90c7d542010-05-31 15:27:27 +0000135#if CONFIG_NIC3COM == 1
uwe0f5a3a22009-05-13 11:36:06 +0000136 {
hailfinger3548a9a2009-08-12 14:34:35 +0000137 .name = "nic3com",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100138 .type = PCI,
139 .devs.dev = nics_3com,
uwe0f5a3a22009-05-13 11:36:06 +0000140 .init = nic3com_init,
uwe3e656bd2009-05-17 23:12:17 +0000141 .map_flash_region = fallback_map,
142 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000143 .delay = internal_delay,
uwe0f5a3a22009-05-13 11:36:06 +0000144 },
hailfinger571a6b32009-09-16 10:09:21 +0000145#endif
uwe0f5a3a22009-05-13 11:36:06 +0000146
hailfinger90c7d542010-05-31 15:27:27 +0000147#if CONFIG_NICREALTEK == 1
hailfinger5aa36982010-05-21 21:54:07 +0000148 {
hailfinger0d703d42011-03-07 01:08:09 +0000149 /* This programmer works for Realtek RTL8139 and SMC 1211. */
uwe8d342eb2011-07-28 08:13:25 +0000150 .name = "nicrealtek",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100151 .type = PCI,
152 .devs.dev = nics_realtek,
uwe8d342eb2011-07-28 08:13:25 +0000153 .init = nicrealtek_init,
154 .map_flash_region = fallback_map,
155 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000156 .delay = internal_delay,
hailfinger5aa36982010-05-21 21:54:07 +0000157 },
hailfinger5aa36982010-05-21 21:54:07 +0000158#endif
159
hailfingerf0a368f2010-06-07 22:37:54 +0000160#if CONFIG_NICNATSEMI == 1
161 {
uwe8d342eb2011-07-28 08:13:25 +0000162 .name = "nicnatsemi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100163 .type = PCI,
164 .devs.dev = nics_natsemi,
uwe8d342eb2011-07-28 08:13:25 +0000165 .init = nicnatsemi_init,
166 .map_flash_region = fallback_map,
167 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000168 .delay = internal_delay,
hailfingerf0a368f2010-06-07 22:37:54 +0000169 },
170#endif
hailfinger5aa36982010-05-21 21:54:07 +0000171
hailfinger90c7d542010-05-31 15:27:27 +0000172#if CONFIG_GFXNVIDIA == 1
uweff4576d2009-09-30 18:29:55 +0000173 {
174 .name = "gfxnvidia",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100175 .type = PCI,
176 .devs.dev = gfx_nvidia,
uweff4576d2009-09-30 18:29:55 +0000177 .init = gfxnvidia_init,
uweff4576d2009-09-30 18:29:55 +0000178 .map_flash_region = fallback_map,
179 .unmap_flash_region = fallback_unmap,
uweff4576d2009-09-30 18:29:55 +0000180 .delay = internal_delay,
181 },
182#endif
183
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000184#if CONFIG_RAIDEN_DEBUG_SPI == 1
185 {
186 .name = "raiden_debug_spi",
187 .type = USB,
188 .devs.dev = devs_raiden,
189 .init = raiden_debug_spi_init,
190 .map_flash_region = fallback_map,
191 .unmap_flash_region = fallback_unmap,
192 .delay = internal_delay,
193 },
194#endif
195
hailfinger90c7d542010-05-31 15:27:27 +0000196#if CONFIG_DRKAISER == 1
ruikda922a12009-05-17 19:39:27 +0000197 {
uwee2f95ef2009-09-02 23:00:46 +0000198 .name = "drkaiser",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100199 .type = PCI,
200 .devs.dev = drkaiser_pcidev,
uwee2f95ef2009-09-02 23:00:46 +0000201 .init = drkaiser_init,
uwee2f95ef2009-09-02 23:00:46 +0000202 .map_flash_region = fallback_map,
203 .unmap_flash_region = fallback_unmap,
uwee2f95ef2009-09-02 23:00:46 +0000204 .delay = internal_delay,
205 },
hailfinger571a6b32009-09-16 10:09:21 +0000206#endif
uwee2f95ef2009-09-02 23:00:46 +0000207
hailfinger90c7d542010-05-31 15:27:27 +0000208#if CONFIG_SATASII == 1
uwee2f95ef2009-09-02 23:00:46 +0000209 {
hailfinger3548a9a2009-08-12 14:34:35 +0000210 .name = "satasii",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100211 .type = PCI,
212 .devs.dev = satas_sii,
ruikda922a12009-05-17 19:39:27 +0000213 .init = satasii_init,
uwe3e656bd2009-05-17 23:12:17 +0000214 .map_flash_region = fallback_map,
215 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000216 .delay = internal_delay,
ruikda922a12009-05-17 19:39:27 +0000217 },
hailfinger571a6b32009-09-16 10:09:21 +0000218#endif
ruikda922a12009-05-17 19:39:27 +0000219
hailfinger90c7d542010-05-31 15:27:27 +0000220#if CONFIG_ATAHPT == 1
uwe7e627c82010-02-21 21:17:00 +0000221 {
222 .name = "atahpt",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100223 .type = PCI,
224 .devs.dev = ata_hpt,
uwe7e627c82010-02-21 21:17:00 +0000225 .init = atahpt_init,
uwe7e627c82010-02-21 21:17:00 +0000226 .map_flash_region = fallback_map,
227 .unmap_flash_region = fallback_unmap,
uwe7e627c82010-02-21 21:17:00 +0000228 .delay = internal_delay,
229 },
230#endif
231
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000232#if CONFIG_ATAVIA == 1
233 {
234 .name = "atavia",
235 .type = PCI,
236 .devs.dev = ata_via,
237 .init = atavia_init,
238 .map_flash_region = atavia_map,
239 .unmap_flash_region = fallback_unmap,
240 .delay = internal_delay,
241 },
242#endif
243
244#if CONFIG_ATAPROMISE == 1
245 {
246 .name = "atapromise",
247 .type = PCI,
248 .devs.dev = ata_promise,
249 .init = atapromise_init,
250 .map_flash_region = atapromise_map,
251 .unmap_flash_region = fallback_unmap,
252 .delay = internal_delay,
253 },
254#endif
255
256#if CONFIG_IT8212 == 1
257 {
258 .name = "it8212",
259 .type = PCI,
260 .devs.dev = devs_it8212,
261 .init = it8212_init,
262 .map_flash_region = fallback_map,
263 .unmap_flash_region = fallback_unmap,
264 .delay = internal_delay,
265 },
266#endif
267
hailfinger90c7d542010-05-31 15:27:27 +0000268#if CONFIG_FT2232_SPI == 1
hailfingerf31da3d2009-06-16 21:08:06 +0000269 {
hailfinger90c7d542010-05-31 15:27:27 +0000270 .name = "ft2232_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100271 .type = USB,
Nikolai Artemievc347a852020-04-29 12:17:08 +1000272 .devs.dev = devs_ft2232spi,
hailfingerf31da3d2009-06-16 21:08:06 +0000273 .init = ft2232_spi_init,
hailfinger6fe23d62009-08-12 11:39:29 +0000274 .map_flash_region = fallback_map,
275 .unmap_flash_region = fallback_unmap,
hailfingerf31da3d2009-06-16 21:08:06 +0000276 .delay = internal_delay,
277 },
hailfingerd9dcfbd2009-08-19 13:27:58 +0000278#endif
hailfinger6fe23d62009-08-12 11:39:29 +0000279
hailfinger90c7d542010-05-31 15:27:27 +0000280#if CONFIG_SERPROG == 1
hailfinger37b4fbf2009-06-23 11:33:43 +0000281 {
hailfinger3548a9a2009-08-12 14:34:35 +0000282 .name = "serprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100283 .type = OTHER,
284 /* FIXME */
285 .devs.note = "All programmer devices speaking the serprog protocol\n",
hailfinger37b4fbf2009-06-23 11:33:43 +0000286 .init = serprog_init,
hailfinger37b4fbf2009-06-23 11:33:43 +0000287 .map_flash_region = fallback_map,
288 .unmap_flash_region = fallback_unmap,
hailfinger37b4fbf2009-06-23 11:33:43 +0000289 .delay = serprog_delay,
290 },
hailfinger74d88a72009-08-12 16:17:41 +0000291#endif
hailfingerf31da3d2009-06-16 21:08:06 +0000292
hailfinger90c7d542010-05-31 15:27:27 +0000293#if CONFIG_BUSPIRATE_SPI == 1
hailfinger9c5add72009-11-24 00:20:03 +0000294 {
hailfinger90c7d542010-05-31 15:27:27 +0000295 .name = "buspirate_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100296 .type = OTHER,
297 /* FIXME */
298 .devs.note = "Dangerous Prototypes Bus Pirate\n",
hailfinger9c5add72009-11-24 00:20:03 +0000299 .init = buspirate_spi_init,
hailfinger9c5add72009-11-24 00:20:03 +0000300 .map_flash_region = fallback_map,
301 .unmap_flash_region = fallback_unmap,
hailfinger9c5add72009-11-24 00:20:03 +0000302 .delay = internal_delay,
303 },
304#endif
305
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000306#if CONFIG_DEDIPROG == 1
Anton Staafb2647882014-09-17 15:13:43 -0700307 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000308 .name = "dediprog",
Brian J. Nemecb42d6c12020-07-23 03:07:38 -0700309 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000310 .init = dediprog_init,
Anton Staafb2647882014-09-17 15:13:43 -0700311 .map_flash_region = fallback_map,
312 .unmap_flash_region = fallback_unmap,
313 .delay = internal_delay,
314 },
315#endif
316
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000317#if CONFIG_DEVELOPERBOX_SPI == 1
hailfingerdfb32a02010-01-19 11:15:48 +0000318 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000319 .name = "developerbox",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100320 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000321 .devs.dev = devs_developerbox_spi,
322 .init = developerbox_spi_init,
323 .map_flash_region = fallback_map,
324 .unmap_flash_region = fallback_unmap,
325 .delay = internal_delay,
326 },
327#endif
328
329#if CONFIG_ENE_LPC == 1
330 {
331 .name = "ene_lpc",
332 .type = OTHER,
333 .devs.note = "ENE LPC interface keyboard controller\n",
334 .init = ene_lpc_init,
hailfingerdfb32a02010-01-19 11:15:48 +0000335 .map_flash_region = fallback_map,
336 .unmap_flash_region = fallback_unmap,
hailfingerdfb32a02010-01-19 11:15:48 +0000337 .delay = internal_delay,
338 },
339#endif
340
hailfinger52c4fa02010-07-21 10:26:01 +0000341#if CONFIG_RAYER_SPI == 1
342 {
343 .name = "rayer_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100344 .type = OTHER,
345 /* FIXME */
346 .devs.note = "RayeR parallel port programmer\n",
hailfinger52c4fa02010-07-21 10:26:01 +0000347 .init = rayer_spi_init,
hailfinger52c4fa02010-07-21 10:26:01 +0000348 .map_flash_region = fallback_map,
349 .unmap_flash_region = fallback_unmap,
hailfinger52c4fa02010-07-21 10:26:01 +0000350 .delay = internal_delay,
351 },
352#endif
353
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000354#if CONFIG_PONY_SPI == 1
355 {
356 .name = "pony_spi",
357 .type = OTHER,
358 /* FIXME */
359 .devs.note = "Programmers compatible with SI-Prog, serbang or AJAWe\n",
360 .init = pony_spi_init,
361 .map_flash_region = fallback_map,
362 .unmap_flash_region = fallback_unmap,
363 .delay = internal_delay,
364 },
365#endif
366
hailfinger7949b652011-05-08 00:24:18 +0000367#if CONFIG_NICINTEL == 1
368 {
369 .name = "nicintel",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100370 .type = PCI,
371 .devs.dev = nics_intel,
hailfinger7949b652011-05-08 00:24:18 +0000372 .init = nicintel_init,
hailfinger7949b652011-05-08 00:24:18 +0000373 .map_flash_region = fallback_map,
374 .unmap_flash_region = fallback_unmap,
hailfinger7949b652011-05-08 00:24:18 +0000375 .delay = internal_delay,
376 },
377#endif
378
uwe6764e922010-09-03 18:21:21 +0000379#if CONFIG_NICINTEL_SPI == 1
380 {
uwe8d342eb2011-07-28 08:13:25 +0000381 .name = "nicintel_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100382 .type = PCI,
383 .devs.dev = nics_intel_spi,
uwe8d342eb2011-07-28 08:13:25 +0000384 .init = nicintel_spi_init,
385 .map_flash_region = fallback_map,
386 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000387 .delay = internal_delay,
uwe6764e922010-09-03 18:21:21 +0000388 },
389#endif
390
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000391#if CONFIG_NICINTEL_EEPROM == 1
392 {
393 .name = "nicintel_eeprom",
394 .type = PCI,
395 .devs.dev = nics_intel_ee,
396 .init = nicintel_ee_init,
397 .map_flash_region = fallback_map,
398 .unmap_flash_region = fallback_unmap,
399 .delay = internal_delay,
400 },
401#endif
402
hailfingerfb1f31f2010-12-03 14:48:11 +0000403#if CONFIG_OGP_SPI == 1
404 {
uwe8d342eb2011-07-28 08:13:25 +0000405 .name = "ogp_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100406 .type = PCI,
407 .devs.dev = ogp_spi,
uwe8d342eb2011-07-28 08:13:25 +0000408 .init = ogp_spi_init,
409 .map_flash_region = fallback_map,
410 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000411 .delay = internal_delay,
hailfingerfb1f31f2010-12-03 14:48:11 +0000412 },
413#endif
414
hailfinger935365d2011-02-04 21:37:59 +0000415#if CONFIG_SATAMV == 1
416 {
417 .name = "satamv",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100418 .type = PCI,
419 .devs.dev = satas_mv,
hailfinger935365d2011-02-04 21:37:59 +0000420 .init = satamv_init,
hailfinger935365d2011-02-04 21:37:59 +0000421 .map_flash_region = fallback_map,
422 .unmap_flash_region = fallback_unmap,
hailfinger935365d2011-02-04 21:37:59 +0000423 .delay = internal_delay,
424 },
425#endif
426
David Hendrickscebee892015-05-23 20:30:30 -0700427#if CONFIG_LINUX_MTD == 1
428 {
429 .name = "linux_mtd",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100430 .type = OTHER,
431 .devs.note = "Device files /dev/mtd*\n",
David Hendrickscebee892015-05-23 20:30:30 -0700432 .init = linux_mtd_init,
433 .map_flash_region = fallback_map,
434 .unmap_flash_region = fallback_unmap,
435 .delay = internal_delay,
436 },
437#endif
438
uwe7df6dda2011-09-03 18:37:52 +0000439#if CONFIG_LINUX_SPI == 1
440 {
441 .name = "linux_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100442 .type = OTHER,
443 .devs.note = "Device files /dev/spidev*.*\n",
uwe7df6dda2011-09-03 18:37:52 +0000444 .init = linux_spi_init,
445 .map_flash_region = fallback_map,
446 .unmap_flash_region = fallback_unmap,
uwe7df6dda2011-09-03 18:37:52 +0000447 .delay = internal_delay,
448 },
449#endif
450
Shiyu Sun9dde7162020-04-16 17:32:55 +1000451#if CONFIG_LSPCON_I2C_SPI == 1
452 {
453 .name = "lspcon_i2c_spi",
454 .type = OTHER,
455 .devs.note = "Device files /dev/i2c-*.\n",
456 .init = lspcon_i2c_spi_init,
457 .map_flash_region = fallback_map,
458 .unmap_flash_region = fallback_unmap,
459 .delay = internal_delay,
460 },
461#endif
462
Edward O'Callaghan97dd9262020-03-26 00:00:41 +1100463#if CONFIG_REALTEK_MST_I2C_SPI == 1
464 {
465 .name = "realtek_mst_i2c_spi",
466 .type = OTHER,
467 .devs.note = "Device files /dev/i2c-*.\n",
468 .init = realtek_mst_i2c_spi_init,
469 .map_flash_region = fallback_map,
470 .unmap_flash_region = fallback_unmap,
471 .delay = internal_delay,
472 },
473#endif
474
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000475#if CONFIG_USBBLASTER_SPI == 1
476 {
477 .name = "usbblaster_spi",
478 .type = USB,
479 .devs.dev = devs_usbblasterspi,
480 .init = usbblaster_spi_init,
481 .map_flash_region = fallback_map,
482 .unmap_flash_region = fallback_unmap,
483 .delay = internal_delay,
484 },
485#endif
486
487#if CONFIG_MSTARDDC_SPI == 1
488 {
489 .name = "mstarddc_spi",
490 .type = OTHER,
491 .devs.note = "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
492 .init = mstarddc_spi_init,
493 .map_flash_region = fallback_map,
494 .unmap_flash_region = fallback_unmap,
495 .delay = internal_delay,
496 },
497#endif
498
499#if CONFIG_PICKIT2_SPI == 1
500 {
501 .name = "pickit2_spi",
502 .type = USB,
503 .devs.dev = devs_pickit2_spi,
504 .init = pickit2_spi_init,
505 .map_flash_region = fallback_map,
506 .unmap_flash_region = fallback_unmap,
507 .delay = internal_delay,
508 },
509#endif
510
511#if CONFIG_CH341A_SPI == 1
512 {
513 .name = "ch341a_spi",
514 .type = USB,
515 .devs.dev = devs_ch341a_spi,
516 .init = ch341a_spi_init,
517 .map_flash_region = fallback_map,
518 .unmap_flash_region = fallback_unmap,
519 .delay = ch341a_spi_delay,
520 },
521#endif
522
523#if CONFIG_DIGILENT_SPI == 1
524 {
525 .name = "digilent_spi",
526 .type = USB,
527 .devs.dev = devs_digilent_spi,
528 .init = digilent_spi_init,
529 .map_flash_region = fallback_map,
530 .unmap_flash_region = fallback_unmap,
531 .delay = internal_delay,
532 },
533#endif
534
535#if CONFIG_JLINK_SPI == 1
536 {
537 .name = "jlink_spi",
538 .type = OTHER,
539 .init = jlink_spi_init,
540 .devs.note = "SEGGER J-Link and compatible devices\n",
541 .map_flash_region = fallback_map,
542 .unmap_flash_region = fallback_unmap,
543 .delay = internal_delay,
544 },
545#endif
546
547#if CONFIG_NI845X_SPI == 1
548 {
549 .name = "ni845x_spi",
550 .type = OTHER, // choose other because NI-845x uses own USB implementation
551 .devs.note = "National Instruments USB-845x\n",
552 .init = ni845x_spi_init,
553 .map_flash_region = fallback_map,
554 .unmap_flash_region = fallback_unmap,
555 .delay = internal_delay,
556 },
557#endif
558
559#if CONFIG_STLINKV3_SPI == 1
560 {
561 .name = "stlinkv3_spi",
562 .type = USB,
563 .devs.dev = devs_stlinkv3_spi,
564 .init = stlinkv3_spi_init,
565 .map_flash_region = fallback_map,
566 .unmap_flash_region = fallback_unmap,
567 .delay = internal_delay,
568 },
569#endif
570
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100571 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000572};
stepan927d4e22007-04-04 22:45:58 +0000573
David Hendricksbf36f092010-11-02 23:39:29 -0700574#define CHIP_RESTORE_MAXFN 4
575static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000576static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700577 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700578 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700579 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000580} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700581
David Hendricks668f29d2011-01-27 18:51:45 -0800582
hailfingerf31cbdc2010-11-10 15:25:18 +0000583#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000584static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000585/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000586static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700587 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000588 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000589} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000590/* Initialize to 0 to make sure nobody registers a shutdown function before
591 * programmer init.
592 */
593static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000594
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700595static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000596
hailfingerdc6f7972010-02-14 01:20:28 +0000597/* Register a function to be executed on programmer shutdown.
598 * The advantage over atexit() is that you can supply a void pointer which will
599 * be used as parameter to the registered function upon programmer shutdown.
600 * This pointer can point to arbitrary data used by said function, e.g. undo
601 * information for GPIO settings etc. If unneeded, set data=NULL.
602 * Please note that the first (void *data) belongs to the function signature of
603 * the function passed as first parameter.
604 */
David Hendricks93784b42016-08-09 17:00:38 -0700605int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000606{
607 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000608 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000609 SHUTDOWN_MAXFN);
610 return 1;
611 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000612 if (!may_register_shutdown) {
613 msg_perr("Tried to register a shutdown function before "
614 "programmer init.\n");
615 return 1;
616 }
hailfingerdc6f7972010-02-14 01:20:28 +0000617 shutdown_fn[shutdown_fn_count].func = function;
618 shutdown_fn[shutdown_fn_count].data = data;
619 shutdown_fn_count++;
620
621 return 0;
622}
623
David Hendricksbf36f092010-11-02 23:39:29 -0700624//int register_chip_restore(int (*function) (void *data), void *data)
625int register_chip_restore(CHIP_RESTORE_CALLBACK,
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700626 struct flashctx *flash, uint8_t status)
David Hendricksbf36f092010-11-02 23:39:29 -0700627{
628 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
629 msg_perr("Tried to register more than %i chip restore"
630 " functions.\n", CHIP_RESTORE_MAXFN);
631 return 1;
632 }
633 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
634 chip_restore_fn[chip_restore_fn_count].flash = flash;
635 chip_restore_fn[chip_restore_fn_count].status = status;
636 chip_restore_fn_count++;
637
638 return 0;
639}
640
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000641int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000642{
hailfinger1ef766d2010-07-06 09:55:48 +0000643 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000644
645 if (prog >= PROGRAMMER_INVALID) {
646 msg_perr("Invalid programmer specified!\n");
647 return -1;
648 }
649 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000650 /* Initialize all programmer specific data. */
651 /* Default to unlimited decode sizes. */
652 max_rom_decode = (const struct decode_sizes) {
653 .parallel = 0xffffffff,
654 .lpc = 0xffffffff,
655 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000656 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000657 };
David Hendricksac1d25c2016-08-09 17:00:58 -0700658 buses_supported = BUS_NONE;
hailfinger1ff33dc2010-07-03 11:02:10 +0000659 /* Default to top aligned flash at 4 GB. */
660 flashbase = 0;
661 /* Registering shutdown functions is now allowed. */
662 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000663 /* Default to allowing writes. Broken programmers set this to 0. */
664 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000665
666 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000667 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700668 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000669 if (programmer_param && strlen(programmer_param)) {
670 if (ret != 0) {
671 /* It is quite possible that any unhandled programmer parameter would have been valid,
672 * but an error in actual programmer init happened before the parameter was evaluated.
673 */
674 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
675 programmer_param);
676 } else {
677 /* Actual programmer init was successful, but the user specified an invalid or unusable
678 * (for the current programmer configuration) parameter.
679 */
680 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
681 msg_perr("Aborting.\n");
682 ret = ERROR_FATAL;
683 }
684 }
hailfinger1ef766d2010-07-06 09:55:48 +0000685 return ret;
uweabe92a52009-05-16 22:36:00 +0000686}
687
David Hendricksbf36f092010-11-02 23:39:29 -0700688int chip_restore()
689{
690 int rc = 0;
691
692 while (chip_restore_fn_count > 0) {
693 int i = --chip_restore_fn_count;
694 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
695 chip_restore_fn[i].status);
696 }
697
698 return rc;
699}
700
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000701/** Calls registered shutdown functions and resets internal programmer-related variables.
702 * Calling it is safe even without previous initialization, but further interactions with programmer support
703 * require a call to programmer_init() (afterwards).
704 *
705 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700706int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000707{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000708 int ret = 0;
709
hailfinger1ff33dc2010-07-03 11:02:10 +0000710 /* Registering shutdown functions is no longer allowed. */
711 may_register_shutdown = 0;
712 while (shutdown_fn_count > 0) {
713 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700714 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000715 }
dhendrix0ffc2eb2011-06-14 01:35:36 +0000716 return ret;
uweabe92a52009-05-16 22:36:00 +0000717}
718
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000719void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000720{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000721 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
722 return ret;
uweabe92a52009-05-16 22:36:00 +0000723}
724
725void programmer_unmap_flash_region(void *virt_addr, size_t len)
726{
727 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000728 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000729}
730
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700731void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000732{
Craig Hesling65eb8812019-08-01 09:33:56 -0700733 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000734}
735
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700736void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000737{
Craig Hesling65eb8812019-08-01 09:33:56 -0700738 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000739}
740
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700741void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000742{
Craig Hesling65eb8812019-08-01 09:33:56 -0700743 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000744}
745
Stuart langleyc98e43f2020-03-26 20:27:36 +1100746void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000747{
Craig Hesling65eb8812019-08-01 09:33:56 -0700748 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000749}
750
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700751uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000752{
Craig Hesling65eb8812019-08-01 09:33:56 -0700753 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000754}
755
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700756uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000757{
Craig Hesling65eb8812019-08-01 09:33:56 -0700758 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000759}
760
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700761uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000762{
Craig Hesling65eb8812019-08-01 09:33:56 -0700763 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000764}
765
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000766void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
767 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000768{
Craig Hesling65eb8812019-08-01 09:33:56 -0700769 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000770}
771
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000772void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000773{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000774 if (usecs > 0)
775 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000776}
777
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700778int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000779{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700780 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000781
hailfinger23060112009-05-08 12:49:03 +0000782 return 0;
783}
784
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000785/* This is a somewhat hacked function similar in some ways to strtok().
786 * It will look for needle with a subsequent '=' in haystack, return a copy of
787 * needle and remove everything from the first occurrence of needle to the next
788 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000789 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000790char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000791{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000792 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000793 char *opt = NULL;
794 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000795 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000796
hailfingerf4aaccc2010-04-28 15:22:14 +0000797 needlelen = strlen(needle);
798 if (!needlelen) {
799 msg_gerr("%s: empty needle! Please report a bug at "
800 "flashrom@flashrom.org\n", __func__);
801 return NULL;
802 }
803 /* No programmer parameters given. */
804 if (*haystack == NULL)
805 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000806 param_pos = strstr(*haystack, needle);
807 do {
808 if (!param_pos)
809 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000810 /* Needle followed by '='? */
811 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000812 /* Beginning of the string? */
813 if (param_pos == *haystack)
814 break;
815 /* After a delimiter? */
816 if (strchr(delim, *(param_pos - 1)))
817 break;
818 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000819 /* Continue searching. */
820 param_pos++;
821 param_pos = strstr(param_pos, needle);
822 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000823
hailfinger6e5a52a2009-11-24 18:27:10 +0000824 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000825 /* Get the string after needle and '='. */
826 opt_pos = param_pos + needlelen + 1;
827 optlen = strcspn(opt_pos, delim);
828 /* Return an empty string if the parameter was empty. */
829 opt = malloc(optlen + 1);
830 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000831 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000832 exit(1);
833 }
hailfinger1ef766d2010-07-06 09:55:48 +0000834 strncpy(opt, opt_pos, optlen);
835 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000836 rest = opt_pos + optlen;
837 /* Skip all delimiters after the current parameter. */
838 rest += strspn(rest, delim);
839 memmove(param_pos, rest, strlen(rest) + 1);
840 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000841 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000842
hailfinger1ef766d2010-07-06 09:55:48 +0000843 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000844}
845
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000846char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000847{
848 return extract_param(&programmer_param, param_name, ",");
849}
850
stefancte1c5acf2011-07-04 07:27:17 +0000851/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700852static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000853{
854 unsigned int usable_erasefunctions = 0;
855 int k;
856 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
857 if (!check_block_eraser(flash, k, 0))
858 usable_erasefunctions++;
859 }
860 return usable_erasefunctions;
861}
862
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000863static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700864{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000865 int ret = 0, failcount = 0;
866 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700867 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000868 if (wantbuf[i] != havebuf[i]) {
869 /* Only print the first failure. */
870 if (!failcount++)
871 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
872 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700873 }
874 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000875 if (failcount) {
876 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
877 start, start + len - 1, failcount);
878 ret = -1;
879 }
880 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700881}
882
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000883/* start is an offset to the base address of the flash chip */
884static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
885{
886 int ret;
887 uint8_t *cmpbuf = malloc(len);
888 const uint8_t erased_value = ERASED_VALUE(flash);
889
890 if (!cmpbuf) {
891 msg_gerr("Could not allocate memory!\n");
892 exit(1);
893 }
894 memset(cmpbuf, erased_value, len);
895 ret = verify_range(flash, cmpbuf, start, len);
896 free(cmpbuf);
897 return ret;
898}
899
uwee15beb92010-08-08 17:01:18 +0000900/*
hailfinger7af3d192009-11-25 17:05:52 +0000901 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000902 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000903 * @start offset to the base address of the flash chip
904 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000905 * @return 0 for success, -1 for failure
906 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000907int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000908{
hailfinger7af83692009-06-15 17:23:36 +0000909 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000910 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000911
Patrick Georgif3fa2992017-02-02 16:24:44 +0100912 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000913 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000914 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000915 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000916
917 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000918 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000919 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000920 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000921 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000922 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000923
Patrick Georgif3fa2992017-02-02 16:24:44 +0100924 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000925 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000926 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100927 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000928 ret = -1;
929 goto out_free;
930 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700931 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700932 if (programmer_table[programmer].paranoid) {
933 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800934
Simon Glass4e305f42015-01-08 06:29:04 -0700935 /* limit chunksize in order to catch errors early */
936 for (i = 0, chunksize = 0; i < len; i += chunksize) {
937 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800938
Patrick Georgif3fa2992017-02-02 16:24:44 +0100939 chunksize = min(flash->chip->page_size, len - i);
940 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700941 if (tmp) {
942 ret = tmp;
943 if (ignore_error(tmp))
944 continue;
945 else
946 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800947 }
Simon Glass4e305f42015-01-08 06:29:04 -0700948
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700949 /*
950 * Check write access permission and do not compare chunks
951 * where flashrom does not have write access to the region.
952 */
953 if (flash->chip->check_access) {
954 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
955 if (tmp && ignore_error(tmp))
956 continue;
957 }
958
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000959 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700960 if (failcount)
961 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800962 }
Simon Glass4e305f42015-01-08 06:29:04 -0700963 } else {
964 int tmp;
965
966 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +0100967 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -0700968 if (tmp && !ignore_error(tmp)) {
969 ret = tmp;
970 goto out_free;
971 }
972
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000973 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +0000974 }
975
hailfinger5be6c0f2009-07-23 01:42:56 +0000976 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +0000977 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +0000978 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +0000979 ret = -1;
980 }
hailfinger7af83692009-06-15 17:23:36 +0000981
982out_free:
983 free(readbuf);
984 return ret;
985}
986
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100987/* Helper function for need_erase() that focuses on granularities of gran bytes. */
988static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000989 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100990{
991 unsigned int i, j, limit;
992 for (j = 0; j < len / gran; j++) {
993 limit = min (gran, len - j * gran);
994 /* Are 'have' and 'want' identical? */
995 if (!memcmp(have + j * gran, want + j * gran, limit))
996 continue;
997 /* have needs to be in erased state. */
998 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000999 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001000 return 1;
1001 }
1002 return 0;
1003}
1004
uwee15beb92010-08-08 17:01:18 +00001005/*
hailfingerb247c7a2010-03-08 00:42:32 +00001006 * Check if the buffer @have can be programmed to the content of @want without
1007 * erasing. This is only possible if all chunks of size @gran are either kept
1008 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001009 *
hailfingerb437e282010-11-04 01:04:27 +00001010 * Warning: This function assumes that @have and @want point to naturally
1011 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001012 *
1013 * @have buffer with current content
1014 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001015 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001016 * @gran write granularity (enum, not count)
1017 * @return 0 if no erase is needed, 1 otherwise
1018 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001019int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1020 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001021{
hailfingerb91c08c2011-08-15 19:54:20 +00001022 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001023 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001024
hailfingerb247c7a2010-03-08 00:42:32 +00001025 switch (gran) {
1026 case write_gran_1bit:
1027 for (i = 0; i < len; i++)
1028 if ((have[i] & want[i]) != want[i]) {
1029 result = 1;
1030 break;
1031 }
1032 break;
1033 case write_gran_1byte:
1034 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001035 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001036 result = 1;
1037 break;
1038 }
1039 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001040 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001041 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001042 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001043 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001044 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001045 break;
1046 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001047 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001048 break;
1049 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001050 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001051 break;
1052 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001053 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001054 break;
1055 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001056 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001057 break;
1058 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001059 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001060 break;
1061 case write_gran_1byte_implicit_erase:
1062 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1063 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001064 break;
hailfingerb437e282010-11-04 01:04:27 +00001065 default:
1066 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1067 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001068 }
1069 return result;
1070}
1071
hailfingerb437e282010-11-04 01:04:27 +00001072/**
1073 * Check if the buffer @have needs to be programmed to get the content of @want.
1074 * If yes, return 1 and fill in first_start with the start address of the
1075 * write operation and first_len with the length of the first to-be-written
1076 * chunk. If not, return 0 and leave first_start and first_len undefined.
1077 *
1078 * Warning: This function assumes that @have and @want point to naturally
1079 * aligned regions.
1080 *
1081 * @have buffer with current content
1082 * @want buffer with desired content
1083 * @len length of the checked area
1084 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001085 * @first_start offset of the first byte which needs to be written (passed in
1086 * value is increased by the offset of the first needed write
1087 * relative to have/want or unchanged if no write is needed)
1088 * @return length of the first contiguous area which needs to be written
1089 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001090 *
1091 * FIXME: This function needs a parameter which tells it about coalescing
1092 * in relation to the max write length of the programmer and the max write
1093 * length of the chip.
1094 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001095static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001096 unsigned int *first_start,
1097 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001098{
stefanctc5eb8a92011-11-23 09:13:48 +00001099 int need_write = 0;
1100 unsigned int rel_start = 0, first_len = 0;
1101 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001102
hailfingerb437e282010-11-04 01:04:27 +00001103 switch (gran) {
1104 case write_gran_1bit:
1105 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001106 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001107 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001108 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001109 case write_gran_128bytes:
1110 stride = 128;
1111 break;
hailfingerb437e282010-11-04 01:04:27 +00001112 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001113 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001114 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001115 case write_gran_264bytes:
1116 stride = 264;
1117 break;
1118 case write_gran_512bytes:
1119 stride = 512;
1120 break;
1121 case write_gran_528bytes:
1122 stride = 528;
1123 break;
1124 case write_gran_1024bytes:
1125 stride = 1024;
1126 break;
1127 case write_gran_1056bytes:
1128 stride = 1056;
1129 break;
hailfingerb437e282010-11-04 01:04:27 +00001130 default:
1131 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1132 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001133 /* Claim that no write was needed. A write with unknown
1134 * granularity is too dangerous to try.
1135 */
1136 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001137 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001138 for (i = 0; i < len / stride; i++) {
1139 limit = min(stride, len - i * stride);
1140 /* Are 'have' and 'want' identical? */
1141 if (memcmp(have + i * stride, want + i * stride, limit)) {
1142 if (!need_write) {
1143 /* First location where have and want differ. */
1144 need_write = 1;
1145 rel_start = i * stride;
1146 }
1147 } else {
1148 if (need_write) {
1149 /* First location where have and want
1150 * do not differ anymore.
1151 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001152 break;
1153 }
1154 }
1155 }
hailfingerffb7f382010-12-06 13:05:44 +00001156 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001157 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001158 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001159 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001160}
1161
hailfinger0c515352009-11-23 12:55:31 +00001162/* This function generates various test patterns useful for testing controller
1163 * and chip communication as well as chip behaviour.
1164 *
1165 * If a byte can be written multiple times, each time keeping 0-bits at 0
1166 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1167 * is essentially an AND operation. That's also the reason why this function
1168 * provides the result of AND between various patterns.
1169 *
1170 * Below is a list of patterns (and their block length).
1171 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1172 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1173 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1174 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1175 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1176 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1177 * Pattern 6 is 00 (1 Byte)
1178 * Pattern 7 is ff (1 Byte)
1179 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1180 * byte block.
1181 *
1182 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1183 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1184 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1185 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1186 * Pattern 12 is 00 (1 Byte)
1187 * Pattern 13 is ff (1 Byte)
1188 * Patterns 8-13 have no block number.
1189 *
1190 * Patterns 0-3 are created to detect and efficiently diagnose communication
1191 * slips like missed bits or bytes and their repetitive nature gives good visual
1192 * cues to the person inspecting the results. In addition, the following holds:
1193 * AND Pattern 0/1 == Pattern 4
1194 * AND Pattern 2/3 == Pattern 5
1195 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1196 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1197 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1198 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1199 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1200 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1201 * Besides that, they provide for bit testing of the last two bytes of every
1202 * 256 byte block which contains the block number for patterns 0-6.
1203 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1204 * block sizes >256 bytes (some Dataflash chips etc.)
1205 * AND Pattern 8/9 == Pattern 12
1206 * AND Pattern 10/11 == Pattern 12
1207 * Pattern 13 is the completely erased state.
1208 * None of the patterns can detect aliasing at boundaries which are a multiple
1209 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1210 */
1211int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1212{
1213 int i;
1214
1215 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001216 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001217 return 1;
1218 }
1219
1220 switch (variant) {
1221 case 0:
1222 for (i = 0; i < size; i++)
1223 buf[i] = (i & 0xf) << 4 | 0x5;
1224 break;
1225 case 1:
1226 for (i = 0; i < size; i++)
1227 buf[i] = (i & 0xf) << 4 | 0xa;
1228 break;
1229 case 2:
1230 for (i = 0; i < size; i++)
1231 buf[i] = 0x50 | (i & 0xf);
1232 break;
1233 case 3:
1234 for (i = 0; i < size; i++)
1235 buf[i] = 0xa0 | (i & 0xf);
1236 break;
1237 case 4:
1238 for (i = 0; i < size; i++)
1239 buf[i] = (i & 0xf) << 4;
1240 break;
1241 case 5:
1242 for (i = 0; i < size; i++)
1243 buf[i] = i & 0xf;
1244 break;
1245 case 6:
1246 memset(buf, 0x00, size);
1247 break;
1248 case 7:
1249 memset(buf, 0xff, size);
1250 break;
1251 case 8:
1252 for (i = 0; i < size; i++)
1253 buf[i] = i & 0xff;
1254 break;
1255 case 9:
1256 for (i = 0; i < size; i++)
1257 buf[i] = ~(i & 0xff);
1258 break;
1259 case 10:
1260 for (i = 0; i < size % 2; i++) {
1261 buf[i * 2] = (i >> 8) & 0xff;
1262 buf[i * 2 + 1] = i & 0xff;
1263 }
1264 if (size & 0x1)
1265 buf[i * 2] = (i >> 8) & 0xff;
1266 break;
1267 case 11:
1268 for (i = 0; i < size % 2; i++) {
1269 buf[i * 2] = ~((i >> 8) & 0xff);
1270 buf[i * 2 + 1] = ~(i & 0xff);
1271 }
1272 if (size & 0x1)
1273 buf[i * 2] = ~((i >> 8) & 0xff);
1274 break;
1275 case 12:
1276 memset(buf, 0x00, size);
1277 break;
1278 case 13:
1279 memset(buf, 0xff, size);
1280 break;
1281 }
1282
1283 if ((variant >= 0) && (variant <= 7)) {
1284 /* Write block number in the last two bytes of each 256-byte
1285 * block, big endian for easier reading of the hexdump.
1286 * Note that this wraps around for chips larger than 2^24 bytes
1287 * (16 MB).
1288 */
1289 for (i = 0; i < size / 256; i++) {
1290 buf[i * 256 + 254] = (i >> 8) & 0xff;
1291 buf[i * 256 + 255] = i & 0xff;
1292 }
1293 }
1294
1295 return 0;
1296}
1297
hailfingeraec9c962009-10-31 01:53:09 +00001298int check_max_decode(enum chipbustype buses, uint32_t size)
1299{
1300 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001301
1302 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001303 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001304 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001305 "size %u kB of chipset/board/programmer "
1306 "for %s interface, "
1307 "probe/read/erase/write may fail. ", size / 1024,
1308 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001309 }
hailfingere1e41ea2011-07-27 07:13:06 +00001310 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001311 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001312 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001313 "size %u kB of chipset/board/programmer "
1314 "for %s interface, "
1315 "probe/read/erase/write may fail. ", size / 1024,
1316 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001317 }
hailfingere1e41ea2011-07-27 07:13:06 +00001318 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001319 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001320 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001321 "size %u kB of chipset/board/programmer "
1322 "for %s interface, "
1323 "probe/read/erase/write may fail. ", size / 1024,
1324 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001325 }
hailfingere1e41ea2011-07-27 07:13:06 +00001326 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001327 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001328 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001329 "size %u kB of chipset/board/programmer "
1330 "for %s interface, "
1331 "probe/read/erase/write may fail. ", size / 1024,
1332 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001333 }
1334 if (!limitexceeded)
1335 return 0;
1336 /* Sometimes chip and programmer have more than one bus in common,
1337 * and the limit is not exceeded on all buses. Tell the user.
1338 */
1339 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001340 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001341 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001342 "interface which can support a chip of this size. "
1343 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001344 return 1;
1345}
1346
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001347void unmap_flash(struct flashctx *flash)
1348{
1349 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1350 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1351 flash->physical_registers = 0;
1352 flash->virtual_registers = (chipaddr)ERROR_PTR;
1353 }
1354
1355 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1356 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1357 flash->physical_memory = 0;
1358 flash->virtual_memory = (chipaddr)ERROR_PTR;
1359 }
1360}
1361
1362int map_flash(struct flashctx *flash)
1363{
1364 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1365 flash->virtual_memory = (chipaddr)ERROR_PTR;
1366 flash->virtual_registers = (chipaddr)ERROR_PTR;
1367
1368 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1369 * These are used for various probing-related hacks that would not map successfully anyway and should be
1370 * removed ASAP. */
1371 if (flash->chip->total_size == 0)
1372 return 0;
1373
1374 const chipsize_t size = flash->chip->total_size * 1024;
1375 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1376 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1377 if (addr == ERROR_PTR) {
1378 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1379 flash->chip->name, PRIxPTR_WIDTH, base);
1380 return 1;
1381 }
1382 flash->physical_memory = base;
1383 flash->virtual_memory = (chipaddr)addr;
1384
1385 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1386 * completely different on some chips and programmers, or not mappable at all.
1387 * Ignore these problems for now and always report success. */
1388 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1389 base = 0xffffffff - size - 0x400000 + 1;
1390 addr = programmer_map_flash_region("flash chip registers", base, size);
1391 if (addr == ERROR_PTR) {
1392 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1393 flash->chip->name, PRIxPTR_WIDTH, base);
1394 return 0;
1395 }
1396 flash->physical_registers = base;
1397 flash->virtual_registers = (chipaddr)addr;
1398 }
1399 return 0;
1400}
1401
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001402/*
1403 * Return a string corresponding to the bustype parameter.
1404 * Memory is obtained with malloc() and must be freed with free() by the caller.
1405 */
1406char *flashbuses_to_text(enum chipbustype bustype)
1407{
1408 char *ret = calloc(1, 1);
1409 /*
1410 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1411 * will cease to exist and should be eliminated here as well.
1412 */
1413 if (bustype == BUS_NONSPI) {
1414 ret = strcat_realloc(ret, "Non-SPI, ");
1415 } else {
1416 if (bustype & BUS_PARALLEL)
1417 ret = strcat_realloc(ret, "Parallel, ");
1418 if (bustype & BUS_LPC)
1419 ret = strcat_realloc(ret, "LPC, ");
1420 if (bustype & BUS_FWH)
1421 ret = strcat_realloc(ret, "FWH, ");
1422 if (bustype & BUS_SPI)
1423 ret = strcat_realloc(ret, "SPI, ");
1424 if (bustype & BUS_PROG)
1425 ret = strcat_realloc(ret, "Programmer-specific, ");
1426 if (bustype == BUS_NONE)
1427 ret = strcat_realloc(ret, "None, ");
1428 }
1429 /* Kill last comma. */
1430 ret[strlen(ret) - 2] = '\0';
1431 ret = realloc(ret, strlen(ret) + 1);
1432 return ret;
1433}
1434
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001435int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001436{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001437 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001438 uint32_t size;
1439 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001440 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001441
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301442 /* Based on the host controller interface that a platform
1443 * needs to use (hwseq or swseq),
1444 * set the flashchips list here.
1445 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001446 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301447 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001448 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301449 flash_list = flashchips_hwseq;
1450 break;
1451 default:
1452 flash_list = flashchips;
1453 break;
1454 }
1455
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001456 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1457 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001458 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001459 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001460 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001461 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001462 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001463 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001464 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001465 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001466 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001467 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001468 continue;
1469 }
stepan782fb172007-04-06 11:58:03 +00001470
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001471 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001472 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001473
hailfinger48ed3e22011-05-04 00:39:50 +00001474 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001475 flash->chip = calloc(1, sizeof(struct flashchip));
1476 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001477 msg_gerr("Out of memory!\n");
1478 exit(1);
1479 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001480 memcpy(flash->chip, chip, sizeof(struct flashchip));
1481 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001482
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001483 if (map_flash(flash) != 0)
1484 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001485
stugec1e55fe2008-07-02 17:15:47 +00001486 if (force)
1487 break;
stepanc98b80b2006-03-16 16:57:41 +00001488
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001489 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001490 goto notfound;
1491
hailfinger48ed3e22011-05-04 00:39:50 +00001492 /* If this is the first chip found, accept it.
1493 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001494 * a non-generic match. SFDP and CFI are generic matches.
1495 * startchip==0 means this call to probe_flash() is the first
1496 * one for this programmer interface (master) and thus no other chip has
1497 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001498 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001499 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1500 msg_cinfo("===\n"
1501 "SFDP has autodetected a flash chip which is "
1502 "not natively supported by flashrom yet.\n");
1503 if (count_usable_erasers(flash) == 0)
1504 msg_cinfo("The standard operations read and "
1505 "verify should work, but to support "
1506 "erase, write and all other "
1507 "possible features");
1508 else
1509 msg_cinfo("All standard operations (read, "
1510 "verify, erase and write) should "
1511 "work, but to support all possible "
1512 "features");
1513
1514 msg_cinfo(" we need to add them manually.\n"
1515 "You can help us by mailing us the output of the following command to "
1516 "flashrom@flashrom.org:\n"
1517 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1518 "Thanks for your help!\n"
1519 "===\n");
1520 }
stugec1e55fe2008-07-02 17:15:47 +00001521
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001522 /* First flash chip detected on this bus. */
1523 if (startchip == 0)
1524 break;
1525 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001526 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001527 break;
1528 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001529notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001530 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001531 free(flash->chip);
1532 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001533 }
uwebe4477b2007-08-23 16:08:21 +00001534
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001535 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001536 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001537
stepan3e7aeae2011-01-19 06:21:54 +00001538
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001539 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001540 msg_cdbg("%s %s flash chip \"%s\" (%d kB, %s) \n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001541 force ? "Assuming" : "Found", flash->chip->vendor,
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001542 flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001543 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001544#if CONFIG_INTERNAL == 1
1545 if (programmer_table[programmer].map_flash_region == physmap)
1546 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1547 PRIxPTR_WIDTH, flash->physical_memory);
1548 else
1549#endif
1550 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001551
hailfinger0f4c3952010-12-02 21:59:42 +00001552 /* Flash registers will not be mapped if the chip was forced. Lock info
1553 * may be stored in registers, so avoid lock info printing.
1554 */
1555 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001556 if (flash->chip->printlock)
1557 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001558
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001559 /* Get out of the way for later runs. */
1560 unmap_flash(flash);
1561
hailfinger48ed3e22011-05-04 00:39:50 +00001562 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001563 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001564}
1565
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001566static int verify_flash(struct flashctx *flash,
1567 struct action_descriptor *descriptor,
1568 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001569{
hailfingerb0f4d122009-06-24 08:20:45 +00001570 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001571 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001572 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001573
snelsone42c3802010-05-07 20:09:04 +00001574 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001575
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001576 if (verify_it == VERIFY_PARTIAL) {
1577 struct processing_unit *pu = descriptor->processing_units;
1578
1579 /* Verify only areas which were written. */
1580 while (pu->num_blocks) {
1581 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001582 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001583 if (ret)
1584 break;
1585 pu++;
1586 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001587 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001588 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001589 }
uwef6641642007-05-09 10:17:44 +00001590
David Hendricks1ed1d352011-11-23 17:54:37 -08001591 if (ret == ACCESS_DENIED) {
1592 msg_gdbg("Could not fully verify due to access error, ");
1593 if (access_denied_action == error_ignore) {
1594 msg_gdbg("ignoring\n");
1595 ret = 0;
1596 } else {
1597 msg_gdbg("aborting\n");
1598 }
1599 }
1600
hailfingerb0f4d122009-06-24 08:20:45 +00001601 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001602 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001603
hailfingerb0f4d122009-06-24 08:20:45 +00001604 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001605}
1606
uwe8d342eb2011-07-28 08:13:25 +00001607int read_buf_from_file(unsigned char *buf, unsigned long size,
1608 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001609{
1610 unsigned long numbytes;
1611 FILE *image;
1612 struct stat image_stat;
1613
Vincent Palatin7ab23932014-10-01 12:09:16 -07001614 if (!strncmp(filename, "-", sizeof("-")))
1615 image = fdopen(STDIN_FILENO, "rb");
1616 else
1617 image = fopen(filename, "rb");
1618 if (image == NULL) {
hailfinger771fc182010-10-15 00:01:14 +00001619 perror(filename);
1620 return 1;
1621 }
1622 if (fstat(fileno(image), &image_stat) != 0) {
1623 perror(filename);
1624 fclose(image);
1625 return 1;
1626 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001627 if ((image_stat.st_size != size) &&
1628 (strncmp(filename, "-", sizeof("-")))) {
Mike Frysinger62c794d2017-05-29 12:02:45 -04001629 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1630 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
hailfinger771fc182010-10-15 00:01:14 +00001631 fclose(image);
1632 return 1;
1633 }
1634 numbytes = fread(buf, 1, size, image);
1635 if (fclose(image)) {
1636 perror(filename);
1637 return 1;
1638 }
1639 if (numbytes != size) {
1640 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1641 "wanted %ld!\n", numbytes, size);
1642 return 1;
1643 }
1644 return 0;
1645}
1646
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001647int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001648{
1649 unsigned long numbytes;
1650 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001651
1652 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001653 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001654 return 1;
1655 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001656 if (!strncmp(filename, "-", sizeof("-")))
1657 image = fdopen(STDOUT_FILENO, "wb");
1658 else
1659 image = fopen(filename, "wb");
1660 if (image == NULL) {
hailfingerd219a232009-01-28 00:27:54 +00001661 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001662 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001663 }
hailfingerd219a232009-01-28 00:27:54 +00001664
hailfingerd219a232009-01-28 00:27:54 +00001665 numbytes = fwrite(buf, 1, size, image);
1666 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001667 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001668 msg_gerr("Error: file %s could not be written completely.\n", filename);
hailfingerd219a232009-01-28 00:27:54 +00001669 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001670 }
hailfingerd219a232009-01-28 00:27:54 +00001671 return 0;
1672}
1673
David Hendrickse3451942013-03-21 17:23:29 -07001674/*
1675 * read_flash - wrapper for flash->read() with additional high-level policy
1676 *
1677 * @flash flash chip
1678 * @buf buffer to store data in
1679 * @start start address
1680 * @len number of bytes to read
1681 *
1682 * This wrapper simplifies most cases when the flash chip needs to be read
1683 * since policy decisions such as non-fatal error handling is centralized.
1684 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001685int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001686 unsigned int start, unsigned int len)
1687{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001688 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001689
Patrick Georgif3fa2992017-02-02 16:24:44 +01001690 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001691 return -1;
1692
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001693 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1694
Patrick Georgif3fa2992017-02-02 16:24:44 +01001695 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001696 if (ret) {
1697 if (ignore_error(ret)) {
1698 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1699 start, start + len - 1);
1700 ret = 0;
1701 } else {
1702 msg_gdbg("failed to read 0x%x-0x%x\n",
1703 start, start + len - 1);
1704 }
1705 }
1706
1707 return ret;
1708}
1709
David Hendricks7c8a1612013-04-26 19:14:44 -07001710/*
1711 * write_flash - wrapper for flash->write() with additional high-level policy
1712 *
1713 * @flash flash chip
1714 * @buf buffer to write to flash
1715 * @start start address in flash
1716 * @len number of bytes to write
1717 *
1718 * TODO: Look up regions that are write-protected and avoid attempt to write
1719 * to them at all.
1720 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001721int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001722 unsigned int start, unsigned int len)
1723{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001724 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001725 return -1;
1726
Patrick Georgif3fa2992017-02-02 16:24:44 +01001727 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001728}
1729
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001730int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001731{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001732 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001733 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001734 int ret = 0;
1735
1736 msg_cinfo("Reading flash... ");
1737 if (!buf) {
1738 msg_gerr("Memory allocation failed!\n");
1739 msg_cinfo("FAILED.\n");
1740 return 1;
1741 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001742
1743 /* To support partial read, fill buffer to all 0xFF at beginning to make
1744 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001745 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001746
Patrick Georgif3fa2992017-02-02 16:24:44 +01001747 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001748 msg_cerr("No read function available for this flash chip.\n");
1749 ret = 1;
1750 goto out_free;
1751 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001752
1753 /* First try to handle partial read case, rather than read the whole
1754 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001755 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001756 if (ret < 0) {
1757 msg_cerr("Partial read operation failed!\n");
1758 ret = 1;
1759 goto out_free;
1760 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001761 int num_regions = get_num_include_args();
1762
1763 if (ret != num_regions) {
1764 msg_cerr("Requested %d regions, but only read %d\n",
1765 num_regions, ret);
1766 ret = 1;
1767 goto out_free;
1768 }
1769
1770 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001771 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001772 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001773 msg_cerr("Read operation failed!\n");
1774 ret = 1;
1775 goto out_free;
1776 }
hailfinger42a850a2010-07-13 23:56:13 +00001777 }
1778
David Hendricksdf29a832013-06-28 14:33:51 -07001779 if (filename)
1780 ret = write_buf_to_file(buf, size, filename);
1781
hailfinger42a850a2010-07-13 23:56:13 +00001782out_free:
1783 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001784 if (ret)
1785 msg_cerr("FAILED.");
1786 else
1787 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001788 return ret;
1789}
1790
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001791/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001792static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001793{
hailfingerb91c08c2011-08-15 19:54:20 +00001794 int i, j, k;
1795 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001796
1797 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1798 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001799 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001800
1801 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1802 /* Blocks with zero size are bugs in flashchips.c. */
1803 if (eraser.eraseblocks[i].count &&
1804 !eraser.eraseblocks[i].size) {
1805 msg_gerr("ERROR: Flash chip %s erase function "
1806 "%i region %i has size 0. Please report"
1807 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001808 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001809 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001810 }
1811 /* Blocks with zero count are bugs in flashchips.c. */
1812 if (!eraser.eraseblocks[i].count &&
1813 eraser.eraseblocks[i].size) {
1814 msg_gerr("ERROR: Flash chip %s erase function "
1815 "%i region %i has count 0. Please report"
1816 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001817 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001818 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001819 }
1820 done += eraser.eraseblocks[i].count *
1821 eraser.eraseblocks[i].size;
1822 }
hailfinger9fed35d2010-01-19 06:42:46 +00001823 /* Empty eraseblock definition with erase function. */
1824 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001825 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001826 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001827 if (!done)
1828 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001829 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001830 msg_gerr("ERROR: Flash chip %s erase function %i "
1831 "region walking resulted in 0x%06x bytes total,"
1832 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001833 " flashrom@flashrom.org\n", chip->name, k,
1834 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001835 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001836 }
hailfinger9fed35d2010-01-19 06:42:46 +00001837 if (!eraser.block_erase)
1838 continue;
1839 /* Check if there are identical erase functions for different
1840 * layouts. That would imply "magic" erase functions. The
1841 * easiest way to check this is with function pointers.
1842 */
uwef6f94d42010-03-13 17:28:29 +00001843 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001844 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001845 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001846 msg_gerr("ERROR: Flash chip %s erase function "
1847 "%i and %i are identical. Please report"
1848 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001849 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001850 ret = 1;
1851 }
uwef6f94d42010-03-13 17:28:29 +00001852 }
hailfinger45177872010-01-18 08:14:43 +00001853 }
hailfinger9fed35d2010-01-19 06:42:46 +00001854 return ret;
hailfinger45177872010-01-18 08:14:43 +00001855}
1856
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001857static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001858 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001859 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001860 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001861 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001862 unsigned int addr,
1863 unsigned int len))
1864{
stefanctc5eb8a92011-11-23 09:13:48 +00001865 unsigned int starthere = 0, lenhere = 0;
1866 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001867 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001868 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001869
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001870 /*
1871 * curcontents and newcontents are opaque to walk_eraseregions, and
1872 * need to be adjusted here to keep the impression of proper
1873 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001874 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001875
hailfinger90fcf9b2010-11-05 14:51:59 +00001876 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001877
hailfingerb437e282010-11-04 01:04:27 +00001878 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001879
hailfingerb437e282010-11-04 01:04:27 +00001880 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001881 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001882 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001883 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001884 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001885 if (ret) {
1886 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001887 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001888 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001889 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001890 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001891 }
1892
David Hendricks0954ffc2015-11-13 15:15:44 -08001893 if (programmer_table[programmer].paranoid) {
1894 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001895 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001896 return -1;
1897 }
hailfingerac8e3182011-06-26 17:04:16 +00001898 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001899
hailfinger90fcf9b2010-11-05 14:51:59 +00001900 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001901 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001902 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001903 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001904 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001905 /* get_next_write() sets starthere to a new value after the call. */
1906 while ((lenhere = get_next_write(curcontents + starthere,
1907 newcontents + starthere,
1908 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001909 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001910 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001911 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001912 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001913 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001914 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001915 if (ret) {
1916 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001917 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001918 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001919 }
David Hendricks048b38c2016-03-28 18:47:06 -07001920
1921 /*
1922 * If the block needed to be erased and was erased successfully
1923 * then we can assume that we didn't run into any write-
1924 * protected areas. Otherwise, we need to verify each page to
1925 * ensure it was successfully written and abort if we encounter
1926 * any errors.
1927 */
1928 if (programmer_table[programmer].paranoid && !block_was_erased) {
1929 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001930 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001931 return -1;
1932 }
1933
hailfingerb437e282010-11-04 01:04:27 +00001934 starthere += lenhere;
1935 skip = 0;
1936 }
1937 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001938 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001939 return ret;
1940}
1941
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001942/*
1943 * Function to process processing units accumulated in the action descriptor.
1944 *
1945 * @flash pointer to the flash context to operate on
1946 * @do_something helper function which can erase and program a section of the
1947 * flash chip. It receives the flash context, offset and length
1948 * of the area to erase/program, before and after contents (to
1949 * decide what exactly needs to be erased and or programmed)
1950 * and a pointer to the erase function which can operate on the
1951 * proper granularity.
1952 * @descriptor action descriptor including pointers to before and after
1953 * contents and an array of processing actions to take.
1954 *
1955 * Returns zero on success or an error code.
1956 */
1957static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001958 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001959 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001960 unsigned int len,
1961 uint8_t *param1,
1962 uint8_t *param2,
1963 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001964 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001965 unsigned int addr,
1966 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001967 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00001968{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001969 struct processing_unit *pu;
1970 int rc = 0;
1971 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00001972
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001973 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1974 unsigned base = pu->offset;
1975 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07001976
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001977 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07001978
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001979 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00001980 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001981 else
1982 print_comma = 1;
1983
1984 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1985
1986 rc = do_something(flash, base,
1987 pu->block_size,
1988 descriptor->oldcontents,
1989 descriptor->newcontents,
1990 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
1991
David Hendricks1ed1d352011-11-23 17:54:37 -08001992 if (rc) {
1993 if (ignore_error(rc))
1994 rc = 0;
1995 else
1996 return rc;
hailfingerb437e282010-11-04 01:04:27 +00001997 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001998 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00001999 }
2000 }
hailfingerb437e282010-11-04 01:04:27 +00002001 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08002002 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00002003}
2004
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002005static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00002006{
Patrick Georgif3fa2992017-02-02 16:24:44 +01002007 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00002008
2009 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
2010 if (log)
2011 msg_cdbg("not defined. ");
2012 return 1;
2013 }
2014 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
2015 if (log)
2016 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00002017 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00002018 return 1;
2019 }
2020 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
2021 if (log)
2022 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00002023 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00002024 return 1;
2025 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002026 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002027 return 0;
2028}
2029
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002030int erase_and_write_flash(struct flashctx *flash,
2031 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002032{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002033 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002034
hailfingercf848f12010-12-05 15:14:44 +00002035 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002036
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002037 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002038
hailfinger7df21362009-09-05 02:30:58 +00002039 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002040 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002041 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002042 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002043 }
2044 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002045}
2046
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002047static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002048{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002049 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2050#if CONFIG_INTERNAL == 1
2051 if (programmer == PROGRAMMER_INTERNAL)
2052 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2053 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2054 "mail flashrom@flashrom.org, thanks!\n"
2055 "-------------------------------------------------------------------------------\n"
2056 "You may now reboot or simply leave the machine running.\n");
2057 else
2058#endif
2059 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2060 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2061 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2062 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002063}
2064
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002065static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002066{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002067 msg_gerr("Your flash chip is in an unknown state.\n");
2068#if CONFIG_INTERNAL == 1
2069 if (programmer == PROGRAMMER_INTERNAL)
2070 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2071 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2072 "-------------------------------------------------------------------------------\n"
2073 "DO NOT REBOOT OR POWEROFF!\n");
2074 else
2075#endif
2076 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2077 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002078}
2079
hailfingerf79d1712010-10-06 23:48:34 +00002080void list_programmers_linebreak(int startcol, int cols, int paren)
2081{
2082 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002083 int pnamelen;
2084 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002085 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002086 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002087
2088 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2089 pname = programmer_table[p].name;
2090 pnamelen = strlen(pname);
2091 if (remaining - pnamelen - 2 < 0) {
2092 if (firstline)
2093 firstline = 0;
2094 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002095 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002096 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002097 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002098 remaining = cols - startcol;
2099 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002100 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002101 remaining--;
2102 }
2103 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002104 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002105 remaining--;
2106 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002107 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002108 remaining -= pnamelen;
2109 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002110 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002111 remaining--;
2112 } else {
2113 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002114 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002115 }
2116 }
2117}
2118
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002119static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002120{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002121#if IS_WINDOWS
2122 SYSTEM_INFO si;
2123 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002124
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002125 memset(&si, 0, sizeof(SYSTEM_INFO));
2126 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2127 msg_ginfo(" on Windows");
2128 /* Tell Windows which version of the structure we want. */
2129 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2130 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2131 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2132 else
2133 msg_ginfo(" unknown version");
2134 GetSystemInfo(&si);
2135 switch (si.wProcessorArchitecture) {
2136 case PROCESSOR_ARCHITECTURE_AMD64:
2137 msg_ginfo(" (x86_64)");
2138 break;
2139 case PROCESSOR_ARCHITECTURE_INTEL:
2140 msg_ginfo(" (x86)");
2141 break;
2142 default:
2143 msg_ginfo(" (unknown arch)");
2144 break;
2145 }
2146#elif HAVE_UTSNAME == 1
2147 struct utsname osinfo;
2148
2149 uname(&osinfo);
2150 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002151 osinfo.machine);
2152#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002153 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002154#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002155}
2156
2157void print_buildinfo(void)
2158{
2159 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002160#if NEED_PCI == 1
2161#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002162 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002163#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002164 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002165#endif
2166#endif
2167#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002168 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002169#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002170 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002171#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002172 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002173#endif
hailfinger3b471632010-03-27 16:36:40 +00002174#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002175 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002176#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002177 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002178#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002179 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002180#endif
2181#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002182 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002183#endif
2184#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002185 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00002186#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002187 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00002188#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002189 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002190}
2191
uwefdeca092008-01-21 15:24:22 +00002192void print_version(void)
2193{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002194 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002195 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002196 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002197}
2198
hailfinger74819ad2010-05-15 15:04:37 +00002199void print_banner(void)
2200{
2201 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002202 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002203 msg_ginfo("\n");
2204}
2205
hailfingerc77acb52009-12-24 02:15:55 +00002206int selfcheck(void)
2207{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002208 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002209 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002210
2211 /* Safety check. Instead of aborting after the first error, check
2212 * if more errors exist.
2213 */
hailfingerc77acb52009-12-24 02:15:55 +00002214 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002215 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002216 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002217 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002218 /* It would be favorable if we could check for the correct layout (especially termination) of various
2219 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2220 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2221 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2222 * 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 +10002223 * checks below. */
2224 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002225 msg_gerr("Flashchips table miscompilation!\n");
2226 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002227 } else {
2228 for (i = 0; i < flashchips_size - 1; i++) {
2229 const struct flashchip *chip = &flashchips[i];
2230 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2231 ret = 1;
2232 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2233 "Please report a bug at flashrom@flashrom.org\n", i,
2234 chip->name == NULL ? "unnamed" : chip->name);
2235 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002236 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002237 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002238 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002239 }
stefanct6d836ba2011-05-26 01:35:19 +00002240 }
stefanct6d836ba2011-05-26 01:35:19 +00002241
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002242 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002243 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002244}
2245
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002246
hailfinger771fc182010-10-15 00:01:14 +00002247/* FIXME: This function signature needs to be improved once doit() has a better
2248 * function signature.
2249 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002250static int chip_safety_check(const struct flashctx *flash, int force,
2251 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002252{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002253 const struct flashchip *chip = flash->chip;
2254
hailfinger771fc182010-10-15 00:01:14 +00002255 if (!programmer_may_write && (write_it || erase_it)) {
2256 msg_perr("Write/erase is not working yet on your programmer in "
2257 "its current configuration.\n");
2258 /* --force is the wrong approach, but it's the best we can do
2259 * until the generic programmer parameter parser is merged.
2260 */
2261 if (!force)
2262 return 1;
2263 msg_cerr("Continuing anyway.\n");
2264 }
2265
2266 if (read_it || erase_it || write_it || verify_it) {
2267 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002268 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002269 msg_cerr("Read is not working on this chip. ");
2270 if (!force)
2271 return 1;
2272 msg_cerr("Continuing anyway.\n");
2273 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002274 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002275 msg_cerr("flashrom has no read function for this "
2276 "flash chip.\n");
2277 return 1;
2278 }
2279 }
2280 if (erase_it || write_it) {
2281 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002282 if (chip->tested.erase == NA) {
2283 msg_cerr("Erase is not possible on this chip.\n");
2284 return 1;
2285 }
2286 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002287 msg_cerr("Erase is not working on this chip. ");
2288 if (!force)
2289 return 1;
2290 msg_cerr("Continuing anyway.\n");
2291 }
stefancte1c5acf2011-07-04 07:27:17 +00002292 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002293 msg_cerr("flashrom has no erase function for this "
2294 "flash chip.\n");
2295 return 1;
2296 }
hailfinger771fc182010-10-15 00:01:14 +00002297 }
2298 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002299 if (chip->tested.write == NA) {
2300 msg_cerr("Write is not possible on this chip.\n");
2301 return 1;
2302 }
2303 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002304 msg_cerr("Write is not working on this chip. ");
2305 if (!force)
2306 return 1;
2307 msg_cerr("Continuing anyway.\n");
2308 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002309 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002310 msg_cerr("flashrom has no write function for this "
2311 "flash chip.\n");
2312 return 1;
2313 }
2314 }
2315 return 0;
2316}
2317
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002318int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002319 const bool read_it, const bool write_it,
2320 const bool erase_it, const bool verify_it)
2321{
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002322 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 +10002323 msg_cerr("Aborting.\n");
2324 return 1;
2325 }
2326
2327 if (normalize_romentries(flash)) {
2328 msg_cerr("Requested regions can not be handled. Aborting.\n");
2329 return 1;
2330 }
2331
2332 /* Given the existence of read locks, we want to unlock for read,
2333 erase and write. */
2334 if (flash->chip->unlock)
2335 flash->chip->unlock(flash);
2336
2337 flash->address_high_byte = -1;
2338 flash->in_4ba_mode = false;
2339
2340 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2341 if ((flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN) && flash->chip->set_4ba) {
2342 if (flash->chip->set_4ba(flash)) {
2343 msg_cerr("Enabling/disabling 4-byte addressing mode failed!\n");
2344 return 1;
2345 }
2346 }
2347
2348 return 0;
2349}
2350
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002351/*
2352 * Function to erase entire flash chip.
2353 *
2354 * @flashctx pointer to the flash context to use
2355 * @oldcontents pointer to the buffer including current chip contents, to
2356 * decide which areas do in fact need to be erased
2357 * @size the size of the flash chip, in bytes.
2358 *
2359 * Returns zero on success or an error code.
2360 */
2361static int erase_chip(struct flashctx *flash, void *oldcontents,
2362 void *newcontents, size_t size)
2363{
2364 /*
2365 * To make sure that the chip is fully erased, let's cheat and create
2366 * a descriptor where the new contents are all erased.
2367 */
2368 struct action_descriptor *fake_descriptor;
2369 int ret = 0;
2370
2371 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2372 newcontents, 1);
2373 /* FIXME: Do we really want the scary warning if erase failed? After
2374 * all, after erase the chip is either blank or partially blank or it
2375 * has the old contents. A blank chip won't boot, so if the user
2376 * wanted erase and reboots afterwards, the user knows very well that
2377 * booting won't work.
2378 */
2379 if (erase_and_write_flash(flash, fake_descriptor)) {
2380 emergency_help_message();
2381 ret = 1;
2382 }
2383
2384 free(fake_descriptor);
2385
2386 return ret;
2387}
2388
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002389static int read_dest_content(struct flashctx *flash, int verify_it,
2390 uint8_t *dest, unsigned long size)
2391{
2392 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2393 && get_num_include_args()) {
2394 /*
2395 * If no full verification is required and not
2396 * the entire chip is about to be programmed,
2397 * read only the areas which might change.
2398 */
2399 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2400 return 1;
2401 } else {
2402 if (read_flash(flash, dest, 0, size))
2403 return 1;
2404 }
2405 return 0;
2406}
2407
hailfingerc77acb52009-12-24 02:15:55 +00002408/* This function signature is horrible. We need to design a better interface,
2409 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002410 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002411 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002412int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002413 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002414 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002415{
hailfinger4c47e9d2010-10-19 22:06:20 +00002416 uint8_t *oldcontents;
2417 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002418 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002419 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002420 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002421
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002422 g_force = force; // HACK
2423 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002424 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002425 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002426
Simon Glass9ad06c12013-07-03 22:08:17 +09002427 if (extract_it) {
2428 ret = extract_regions(flash);
2429 goto out_nofree;
2430 }
2431
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002432 /* mark entries included using -i argument as "included" if they are
2433 found in the master rom_entries list */
2434 if (process_include_args() < 0) {
2435 ret = 1;
2436 goto out_nofree;
2437 }
2438
hailfinger771fc182010-10-15 00:01:14 +00002439 if (read_it) {
2440 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002441 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002442 }
hailfingerb437e282010-11-04 01:04:27 +00002443
stefanctd611e8f2011-07-12 22:35:21 +00002444 oldcontents = malloc(size);
2445 if (!oldcontents) {
2446 msg_gerr("Out of memory!\n");
2447 exit(1);
2448 }
Simon Glass4c214132013-07-16 10:09:28 -06002449 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002450 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002451 newcontents = malloc(size);
2452 if (!newcontents) {
2453 msg_gerr("Out of memory!\n");
2454 exit(1);
2455 }
Simon Glass4c214132013-07-16 10:09:28 -06002456 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002457 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002458 /* Side effect of the assumptions above: Default write action is erase
2459 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002460 * oldcontents being completely unerased means we have to erase
2461 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002462 */
2463
hailfingerd217d122010-10-08 18:52:29 +00002464 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002465 /*
2466 * Note: This must be done before any files specified by -i
2467 * arguments are processed merged into the newcontents since
2468 * -i files take priority. See http://crbug.com/263495.
2469 */
2470 if (filename) {
2471 if (read_buf_from_file(newcontents, size, filename)) {
2472 ret = 1;
2473 goto out;
2474 }
2475 } else {
2476 /* Content will be read from -i args, so they must
2477 * not overlap. */
2478 if (included_regions_overlap()) {
2479 msg_gerr("Error: Included regions must "
2480 "not overlap.\n");
2481 ret = 1;
2482 goto out;
2483 }
stepan1da96c02006-11-21 23:48:51 +00002484 }
ollie5672ac62004-03-17 22:22:08 +00002485 }
2486
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002487 if (do_diff) {
2488 /*
2489 * Obtain a reference image so that we can check whether
2490 * regions need to be erased and to give better diagnostics in
2491 * case write fails. If --fast-verify is used then only the
2492 * regions which are included using -i will be read.
2493 */
2494 if (diff_file) {
2495 msg_cdbg("Reading old contents from file... ");
2496 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002497 ret = 1;
2498 msg_cdbg("FAILED.\n");
2499 goto out;
2500 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002501 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002502 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002503 ret = read_dest_content(flash, verify_it,
2504 oldcontents, size);
2505 if (ret) {
2506 msg_cdbg("FAILED.\n");
2507 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002508 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002509 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002510 msg_cdbg("done.\n");
2511 } else if (!erase_it) {
2512 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002513 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002514 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002515
David Hendricksdf29a832013-06-28 14:33:51 -07002516 /*
2517 * Note: This must be done after reading the file specified for the
2518 * -w/-v argument, if any, so that files specified using -i end up
2519 * in the "newcontents" buffer before being written.
2520 * See http://crbug.com/263495.
2521 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002522 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002523 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002524 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002525 goto out;
2526 }
uwef6641642007-05-09 10:17:44 +00002527
David Hendricksa7e114b2016-02-26 18:49:15 -08002528 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002529 erase_chip(flash, oldcontents, newcontents, size);
2530 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002531 }
2532
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002533 descriptor = prepare_action_descriptor(flash, oldcontents,
2534 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002535 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002536 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002537 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002538 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002539 goto out;
2540 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002541
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002542 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002543 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2544 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002545 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002546 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002547 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002548 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002549 ret = 1;
2550 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002551 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002552 msg_cerr("Apparently at least some data has changed.\n");
2553 } else
2554 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002555 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002556 ret = 1;
2557 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002558 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002559
David Hendricksac1d25c2016-08-09 17:00:58 -07002560 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002561 if (ret < 0) {
2562 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002563 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002564 emergency_help_message();
2565 ret = 1;
2566 goto out;
2567 } else if (ret > 0) {
2568 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002569 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002570 ret = read_dest_content(flash, verify_it,
2571 oldcontents, size);
2572 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002573 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002574 goto out;
2575 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002576
2577 /* Get a new descriptor. */
2578 free(descriptor);
2579 descriptor = prepare_action_descriptor(flash,
2580 oldcontents,
2581 newcontents,
2582 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002583 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002584 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002585 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002586 emergency_help_message();
2587 ret = 1;
2588 goto out;
2589 }
2590 ret = 0;
2591 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002592
David Hendricksac1d25c2016-08-09 17:00:58 -07002593 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002594 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002595 emergency_help_message();
2596 ret = 1;
2597 goto out;
2598 }
stuge8ce3a3c2008-04-28 14:47:30 +00002599 }
ollie6a600992005-11-26 21:55:36 +00002600
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002601 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002602 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002603 if ((write_it || erase_it) && !content_has_changed) {
2604 msg_gdbg("Nothing was erased or written, skipping "
2605 "verification\n");
2606 } else {
2607 /* Work around chips which need some time to calm down. */
2608 if (write_it && verify_it != VERIFY_PARTIAL)
2609 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002610
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002611 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002612
David Hendricks9ba79fb2015-04-03 12:06:16 -07002613 /* If we tried to write, and verification now fails, we
2614 * might have an emergency situation.
2615 */
2616 if (ret && write_it)
2617 emergency_help_message();
2618 }
hailfinger0459e1c2009-08-19 13:55:34 +00002619 }
ollie6a600992005-11-26 21:55:36 +00002620
hailfinger90fcf9b2010-11-05 14:51:59 +00002621out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002622 if (descriptor)
2623 free(descriptor);
2624
hailfinger90fcf9b2010-11-05 14:51:59 +00002625 free(oldcontents);
2626 free(newcontents);
2627out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002628 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002629 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002630 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002631 * tree. This is because some operations, such as write protection,
2632 * requires programmer_shutdown() but does not call doit().
2633 */
2634// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002635 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002636}
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002637
2638void finalize_flash_access(struct flashctx *const flash)
2639{
2640 unmap_flash(flash);
2641}