blob: 91765f79a95726193bfa3e4f928eb2880aa8e5f2 [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"
Edward O'Callaghan99974452020-10-13 13:28:33 +110044#include "chipdrivers.h"
rminnich8d3ff912003-10-25 17:01:29 +000045
krause2eb76212011-01-17 07:50:42 +000046const char flashrom_version[] = FLASHROM_VERSION;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100047const char *chip_to_probe = NULL;
hailfinger80422e22009-12-13 22:28:00 +000048
David Hendricks9ba79fb2015-04-03 12:06:16 -070049/* Set if any erase/write operation is to be done. This will be used to
50 * decide if final verification is needed. */
51static int content_has_changed = 0;
52
David Hendricks1ed1d352011-11-23 17:54:37 -080053/* error handling stuff */
54enum error_action access_denied_action = error_ignore;
55
56int ignore_error(int err) {
57 int rc = 0;
58
59 switch(err) {
60 case ACCESS_DENIED:
61 if (access_denied_action == error_ignore)
62 rc = 1;
63 break;
64 default:
65 break;
66 }
67
68 return rc;
69}
70
hailfinger969e2f32011-09-08 00:00:29 +000071static enum programmer programmer = PROGRAMMER_INVALID;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100072static const char *programmer_param = NULL;
stepan782fb172007-04-06 11:58:03 +000073
David Hendricksac1d25c2016-08-09 17:00:58 -070074/* Supported buses for the current programmer. */
75enum chipbustype buses_supported;
76
uwee15beb92010-08-08 17:01:18 +000077/*
hailfinger80422e22009-12-13 22:28:00 +000078 * Programmers supporting multiple buses can have differing size limits on
79 * each bus. Store the limits for each bus in a common struct.
80 */
hailfinger1ff33dc2010-07-03 11:02:10 +000081struct decode_sizes max_rom_decode;
82
83/* If nonzero, used as the start address of bottom-aligned flash. */
84unsigned long flashbase;
hailfinger80422e22009-12-13 22:28:00 +000085
hailfinger5828baf2010-07-03 12:14:25 +000086/* Is writing allowed with this programmer? */
87int programmer_may_write;
88
hailfingerabe249e2009-05-08 17:43:22 +000089const struct programmer_entry programmer_table[] = {
hailfinger90c7d542010-05-31 15:27:27 +000090#if CONFIG_INTERNAL == 1
hailfingerabe249e2009-05-08 17:43:22 +000091 {
hailfinger3548a9a2009-08-12 14:34:35 +000092 .name = "internal",
Edward O'Callaghan0949b782019-11-10 23:23:20 +110093 .type = OTHER,
94 .devs.note = NULL,
hailfinger6c69ab02009-05-11 15:46:43 +000095 .init = internal_init,
hailfinger11ae3c42009-05-11 14:13:25 +000096 .map_flash_region = physmap,
97 .unmap_flash_region = physunmap,
hailfingere5829f62009-06-05 17:48:08 +000098 .delay = internal_delay,
David Hendricks55cdd9c2015-11-25 14:37:26 -080099
100 /*
101 * "Internal" implies in-system programming on a live system, so
102 * handle with paranoia to catch errors early. If something goes
103 * wrong then hopefully the system will still be recoverable.
104 */
105 .paranoid = 1,
hailfingerabe249e2009-05-08 17:43:22 +0000106 },
hailfinger80422e22009-12-13 22:28:00 +0000107#endif
stepan927d4e22007-04-04 22:45:58 +0000108
hailfinger90c7d542010-05-31 15:27:27 +0000109#if CONFIG_DUMMY == 1
hailfingera9df33c2009-05-09 00:54:55 +0000110 {
hailfinger3548a9a2009-08-12 14:34:35 +0000111 .name = "dummy",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100112 .type = OTHER,
113 /* FIXME */
114 .devs.note = "Dummy device, does nothing and logs all accesses\n",
hailfinger6c69ab02009-05-11 15:46:43 +0000115 .init = dummy_init,
hailfinger11ae3c42009-05-11 14:13:25 +0000116 .map_flash_region = dummy_map,
117 .unmap_flash_region = dummy_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000118 .delay = internal_delay,
hailfingera9df33c2009-05-09 00:54:55 +0000119 },
hailfinger571a6b32009-09-16 10:09:21 +0000120#endif
hailfingera9df33c2009-05-09 00:54:55 +0000121
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000122#if CONFIG_MEC1308 == 1
123 {
124 .name = "mec1308",
125 .type = OTHER,
126 .devs.note = "Microchip MEC1308 Embedded Controller.\n",
127 .init = mec1308_init,
128 .map_flash_region = fallback_map,
129 .unmap_flash_region = fallback_unmap,
130 .delay = internal_delay,
131 },
132#endif
133
hailfinger90c7d542010-05-31 15:27:27 +0000134#if CONFIG_NIC3COM == 1
uwe0f5a3a22009-05-13 11:36:06 +0000135 {
hailfinger3548a9a2009-08-12 14:34:35 +0000136 .name = "nic3com",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100137 .type = PCI,
138 .devs.dev = nics_3com,
uwe0f5a3a22009-05-13 11:36:06 +0000139 .init = nic3com_init,
uwe3e656bd2009-05-17 23:12:17 +0000140 .map_flash_region = fallback_map,
141 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000142 .delay = internal_delay,
uwe0f5a3a22009-05-13 11:36:06 +0000143 },
hailfinger571a6b32009-09-16 10:09:21 +0000144#endif
uwe0f5a3a22009-05-13 11:36:06 +0000145
hailfinger90c7d542010-05-31 15:27:27 +0000146#if CONFIG_NICREALTEK == 1
hailfinger5aa36982010-05-21 21:54:07 +0000147 {
hailfinger0d703d42011-03-07 01:08:09 +0000148 /* This programmer works for Realtek RTL8139 and SMC 1211. */
uwe8d342eb2011-07-28 08:13:25 +0000149 .name = "nicrealtek",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100150 .type = PCI,
151 .devs.dev = nics_realtek,
uwe8d342eb2011-07-28 08:13:25 +0000152 .init = nicrealtek_init,
153 .map_flash_region = fallback_map,
154 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000155 .delay = internal_delay,
hailfinger5aa36982010-05-21 21:54:07 +0000156 },
hailfinger5aa36982010-05-21 21:54:07 +0000157#endif
158
hailfingerf0a368f2010-06-07 22:37:54 +0000159#if CONFIG_NICNATSEMI == 1
160 {
uwe8d342eb2011-07-28 08:13:25 +0000161 .name = "nicnatsemi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100162 .type = PCI,
163 .devs.dev = nics_natsemi,
uwe8d342eb2011-07-28 08:13:25 +0000164 .init = nicnatsemi_init,
165 .map_flash_region = fallback_map,
166 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000167 .delay = internal_delay,
hailfingerf0a368f2010-06-07 22:37:54 +0000168 },
169#endif
hailfinger5aa36982010-05-21 21:54:07 +0000170
hailfinger90c7d542010-05-31 15:27:27 +0000171#if CONFIG_GFXNVIDIA == 1
uweff4576d2009-09-30 18:29:55 +0000172 {
173 .name = "gfxnvidia",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100174 .type = PCI,
175 .devs.dev = gfx_nvidia,
uweff4576d2009-09-30 18:29:55 +0000176 .init = gfxnvidia_init,
uweff4576d2009-09-30 18:29:55 +0000177 .map_flash_region = fallback_map,
178 .unmap_flash_region = fallback_unmap,
uweff4576d2009-09-30 18:29:55 +0000179 .delay = internal_delay,
180 },
181#endif
182
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000183#if CONFIG_RAIDEN_DEBUG_SPI == 1
184 {
185 .name = "raiden_debug_spi",
186 .type = USB,
187 .devs.dev = devs_raiden,
188 .init = raiden_debug_spi_init,
189 .map_flash_region = fallback_map,
190 .unmap_flash_region = fallback_unmap,
191 .delay = internal_delay,
192 },
193#endif
194
hailfinger90c7d542010-05-31 15:27:27 +0000195#if CONFIG_DRKAISER == 1
ruikda922a12009-05-17 19:39:27 +0000196 {
uwee2f95ef2009-09-02 23:00:46 +0000197 .name = "drkaiser",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100198 .type = PCI,
199 .devs.dev = drkaiser_pcidev,
uwee2f95ef2009-09-02 23:00:46 +0000200 .init = drkaiser_init,
uwee2f95ef2009-09-02 23:00:46 +0000201 .map_flash_region = fallback_map,
202 .unmap_flash_region = fallback_unmap,
uwee2f95ef2009-09-02 23:00:46 +0000203 .delay = internal_delay,
204 },
hailfinger571a6b32009-09-16 10:09:21 +0000205#endif
uwee2f95ef2009-09-02 23:00:46 +0000206
hailfinger90c7d542010-05-31 15:27:27 +0000207#if CONFIG_SATASII == 1
uwee2f95ef2009-09-02 23:00:46 +0000208 {
hailfinger3548a9a2009-08-12 14:34:35 +0000209 .name = "satasii",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100210 .type = PCI,
211 .devs.dev = satas_sii,
ruikda922a12009-05-17 19:39:27 +0000212 .init = satasii_init,
uwe3e656bd2009-05-17 23:12:17 +0000213 .map_flash_region = fallback_map,
214 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000215 .delay = internal_delay,
ruikda922a12009-05-17 19:39:27 +0000216 },
hailfinger571a6b32009-09-16 10:09:21 +0000217#endif
ruikda922a12009-05-17 19:39:27 +0000218
hailfinger90c7d542010-05-31 15:27:27 +0000219#if CONFIG_ATAHPT == 1
uwe7e627c82010-02-21 21:17:00 +0000220 {
221 .name = "atahpt",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100222 .type = PCI,
223 .devs.dev = ata_hpt,
uwe7e627c82010-02-21 21:17:00 +0000224 .init = atahpt_init,
uwe7e627c82010-02-21 21:17:00 +0000225 .map_flash_region = fallback_map,
226 .unmap_flash_region = fallback_unmap,
uwe7e627c82010-02-21 21:17:00 +0000227 .delay = internal_delay,
228 },
229#endif
230
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000231#if CONFIG_ATAVIA == 1
232 {
233 .name = "atavia",
234 .type = PCI,
235 .devs.dev = ata_via,
236 .init = atavia_init,
237 .map_flash_region = atavia_map,
238 .unmap_flash_region = fallback_unmap,
239 .delay = internal_delay,
240 },
241#endif
242
243#if CONFIG_ATAPROMISE == 1
244 {
245 .name = "atapromise",
246 .type = PCI,
247 .devs.dev = ata_promise,
248 .init = atapromise_init,
249 .map_flash_region = atapromise_map,
250 .unmap_flash_region = fallback_unmap,
251 .delay = internal_delay,
252 },
253#endif
254
255#if CONFIG_IT8212 == 1
256 {
257 .name = "it8212",
258 .type = PCI,
259 .devs.dev = devs_it8212,
260 .init = it8212_init,
261 .map_flash_region = fallback_map,
262 .unmap_flash_region = fallback_unmap,
263 .delay = internal_delay,
264 },
265#endif
266
hailfinger90c7d542010-05-31 15:27:27 +0000267#if CONFIG_FT2232_SPI == 1
hailfingerf31da3d2009-06-16 21:08:06 +0000268 {
hailfinger90c7d542010-05-31 15:27:27 +0000269 .name = "ft2232_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100270 .type = USB,
Nikolai Artemievc347a852020-04-29 12:17:08 +1000271 .devs.dev = devs_ft2232spi,
hailfingerf31da3d2009-06-16 21:08:06 +0000272 .init = ft2232_spi_init,
hailfinger6fe23d62009-08-12 11:39:29 +0000273 .map_flash_region = fallback_map,
274 .unmap_flash_region = fallback_unmap,
hailfingerf31da3d2009-06-16 21:08:06 +0000275 .delay = internal_delay,
276 },
hailfingerd9dcfbd2009-08-19 13:27:58 +0000277#endif
hailfinger6fe23d62009-08-12 11:39:29 +0000278
hailfinger90c7d542010-05-31 15:27:27 +0000279#if CONFIG_SERPROG == 1
hailfinger37b4fbf2009-06-23 11:33:43 +0000280 {
hailfinger3548a9a2009-08-12 14:34:35 +0000281 .name = "serprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100282 .type = OTHER,
283 /* FIXME */
284 .devs.note = "All programmer devices speaking the serprog protocol\n",
hailfinger37b4fbf2009-06-23 11:33:43 +0000285 .init = serprog_init,
Edward O'Callaghan62018182020-10-03 00:16:48 +1000286 .map_flash_region = serprog_map,
hailfinger37b4fbf2009-06-23 11:33:43 +0000287 .unmap_flash_region = fallback_unmap,
hailfinger37b4fbf2009-06-23 11:33:43 +0000288 .delay = serprog_delay,
289 },
hailfinger74d88a72009-08-12 16:17:41 +0000290#endif
hailfingerf31da3d2009-06-16 21:08:06 +0000291
hailfinger90c7d542010-05-31 15:27:27 +0000292#if CONFIG_BUSPIRATE_SPI == 1
hailfinger9c5add72009-11-24 00:20:03 +0000293 {
hailfinger90c7d542010-05-31 15:27:27 +0000294 .name = "buspirate_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100295 .type = OTHER,
296 /* FIXME */
297 .devs.note = "Dangerous Prototypes Bus Pirate\n",
hailfinger9c5add72009-11-24 00:20:03 +0000298 .init = buspirate_spi_init,
hailfinger9c5add72009-11-24 00:20:03 +0000299 .map_flash_region = fallback_map,
300 .unmap_flash_region = fallback_unmap,
hailfinger9c5add72009-11-24 00:20:03 +0000301 .delay = internal_delay,
302 },
303#endif
304
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000305#if CONFIG_DEDIPROG == 1
Anton Staafb2647882014-09-17 15:13:43 -0700306 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000307 .name = "dediprog",
Brian J. Nemecb42d6c12020-07-23 03:07:38 -0700308 .type = USB,
Edward O'Callaghanac1678b2020-07-27 15:55:45 +1000309 .devs.dev = devs_dediprog,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000310 .init = dediprog_init,
Anton Staafb2647882014-09-17 15:13:43 -0700311 .map_flash_region = fallback_map,
312 .unmap_flash_region = fallback_unmap,
313 .delay = internal_delay,
314 },
315#endif
316
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000317#if CONFIG_DEVELOPERBOX_SPI == 1
hailfingerdfb32a02010-01-19 11:15:48 +0000318 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000319 .name = "developerbox",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100320 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000321 .devs.dev = devs_developerbox_spi,
322 .init = developerbox_spi_init,
323 .map_flash_region = fallback_map,
324 .unmap_flash_region = fallback_unmap,
325 .delay = internal_delay,
326 },
327#endif
328
329#if CONFIG_ENE_LPC == 1
330 {
331 .name = "ene_lpc",
332 .type = OTHER,
333 .devs.note = "ENE LPC interface keyboard controller\n",
334 .init = ene_lpc_init,
hailfingerdfb32a02010-01-19 11:15:48 +0000335 .map_flash_region = fallback_map,
336 .unmap_flash_region = fallback_unmap,
hailfingerdfb32a02010-01-19 11:15:48 +0000337 .delay = internal_delay,
338 },
339#endif
340
hailfinger52c4fa02010-07-21 10:26:01 +0000341#if CONFIG_RAYER_SPI == 1
342 {
343 .name = "rayer_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100344 .type = OTHER,
345 /* FIXME */
346 .devs.note = "RayeR parallel port programmer\n",
hailfinger52c4fa02010-07-21 10:26:01 +0000347 .init = rayer_spi_init,
hailfinger52c4fa02010-07-21 10:26:01 +0000348 .map_flash_region = fallback_map,
349 .unmap_flash_region = fallback_unmap,
hailfinger52c4fa02010-07-21 10:26:01 +0000350 .delay = internal_delay,
351 },
352#endif
353
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000354#if CONFIG_PONY_SPI == 1
355 {
356 .name = "pony_spi",
357 .type = OTHER,
358 /* FIXME */
359 .devs.note = "Programmers compatible with SI-Prog, serbang or AJAWe\n",
360 .init = pony_spi_init,
361 .map_flash_region = fallback_map,
362 .unmap_flash_region = fallback_unmap,
363 .delay = internal_delay,
364 },
365#endif
366
hailfinger7949b652011-05-08 00:24:18 +0000367#if CONFIG_NICINTEL == 1
368 {
369 .name = "nicintel",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100370 .type = PCI,
371 .devs.dev = nics_intel,
hailfinger7949b652011-05-08 00:24:18 +0000372 .init = nicintel_init,
hailfinger7949b652011-05-08 00:24:18 +0000373 .map_flash_region = fallback_map,
374 .unmap_flash_region = fallback_unmap,
hailfinger7949b652011-05-08 00:24:18 +0000375 .delay = internal_delay,
376 },
377#endif
378
uwe6764e922010-09-03 18:21:21 +0000379#if CONFIG_NICINTEL_SPI == 1
380 {
uwe8d342eb2011-07-28 08:13:25 +0000381 .name = "nicintel_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100382 .type = PCI,
383 .devs.dev = nics_intel_spi,
uwe8d342eb2011-07-28 08:13:25 +0000384 .init = nicintel_spi_init,
385 .map_flash_region = fallback_map,
386 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000387 .delay = internal_delay,
uwe6764e922010-09-03 18:21:21 +0000388 },
389#endif
390
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000391#if CONFIG_NICINTEL_EEPROM == 1
392 {
393 .name = "nicintel_eeprom",
394 .type = PCI,
395 .devs.dev = nics_intel_ee,
396 .init = nicintel_ee_init,
397 .map_flash_region = fallback_map,
398 .unmap_flash_region = fallback_unmap,
399 .delay = internal_delay,
400 },
401#endif
402
hailfingerfb1f31f2010-12-03 14:48:11 +0000403#if CONFIG_OGP_SPI == 1
404 {
uwe8d342eb2011-07-28 08:13:25 +0000405 .name = "ogp_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100406 .type = PCI,
407 .devs.dev = ogp_spi,
uwe8d342eb2011-07-28 08:13:25 +0000408 .init = ogp_spi_init,
409 .map_flash_region = fallback_map,
410 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000411 .delay = internal_delay,
hailfingerfb1f31f2010-12-03 14:48:11 +0000412 },
413#endif
414
hailfinger935365d2011-02-04 21:37:59 +0000415#if CONFIG_SATAMV == 1
416 {
417 .name = "satamv",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100418 .type = PCI,
419 .devs.dev = satas_mv,
hailfinger935365d2011-02-04 21:37:59 +0000420 .init = satamv_init,
hailfinger935365d2011-02-04 21:37:59 +0000421 .map_flash_region = fallback_map,
422 .unmap_flash_region = fallback_unmap,
hailfinger935365d2011-02-04 21:37:59 +0000423 .delay = internal_delay,
424 },
425#endif
426
David Hendrickscebee892015-05-23 20:30:30 -0700427#if CONFIG_LINUX_MTD == 1
428 {
429 .name = "linux_mtd",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100430 .type = OTHER,
431 .devs.note = "Device files /dev/mtd*\n",
David Hendrickscebee892015-05-23 20:30:30 -0700432 .init = linux_mtd_init,
433 .map_flash_region = fallback_map,
434 .unmap_flash_region = fallback_unmap,
435 .delay = internal_delay,
436 },
437#endif
438
uwe7df6dda2011-09-03 18:37:52 +0000439#if CONFIG_LINUX_SPI == 1
440 {
441 .name = "linux_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100442 .type = OTHER,
443 .devs.note = "Device files /dev/spidev*.*\n",
uwe7df6dda2011-09-03 18:37:52 +0000444 .init = linux_spi_init,
445 .map_flash_region = fallback_map,
446 .unmap_flash_region = fallback_unmap,
uwe7df6dda2011-09-03 18:37:52 +0000447 .delay = internal_delay,
448 },
449#endif
450
Shiyu Sun9dde7162020-04-16 17:32:55 +1000451#if CONFIG_LSPCON_I2C_SPI == 1
452 {
453 .name = "lspcon_i2c_spi",
454 .type = OTHER,
455 .devs.note = "Device files /dev/i2c-*.\n",
456 .init = lspcon_i2c_spi_init,
457 .map_flash_region = fallback_map,
458 .unmap_flash_region = fallback_unmap,
459 .delay = internal_delay,
460 },
461#endif
462
Edward O'Callaghan97dd9262020-03-26 00:00:41 +1100463#if CONFIG_REALTEK_MST_I2C_SPI == 1
464 {
465 .name = "realtek_mst_i2c_spi",
466 .type = OTHER,
467 .devs.note = "Device files /dev/i2c-*.\n",
468 .init = realtek_mst_i2c_spi_init,
469 .map_flash_region = fallback_map,
470 .unmap_flash_region = fallback_unmap,
471 .delay = internal_delay,
472 },
473#endif
474
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000475#if CONFIG_USBBLASTER_SPI == 1
476 {
477 .name = "usbblaster_spi",
478 .type = USB,
479 .devs.dev = devs_usbblasterspi,
480 .init = usbblaster_spi_init,
481 .map_flash_region = fallback_map,
482 .unmap_flash_region = fallback_unmap,
483 .delay = internal_delay,
484 },
485#endif
486
487#if CONFIG_MSTARDDC_SPI == 1
488 {
489 .name = "mstarddc_spi",
490 .type = OTHER,
491 .devs.note = "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
492 .init = mstarddc_spi_init,
493 .map_flash_region = fallback_map,
494 .unmap_flash_region = fallback_unmap,
495 .delay = internal_delay,
496 },
497#endif
498
499#if CONFIG_PICKIT2_SPI == 1
500 {
501 .name = "pickit2_spi",
502 .type = USB,
503 .devs.dev = devs_pickit2_spi,
504 .init = pickit2_spi_init,
505 .map_flash_region = fallback_map,
506 .unmap_flash_region = fallback_unmap,
507 .delay = internal_delay,
508 },
509#endif
510
511#if CONFIG_CH341A_SPI == 1
512 {
513 .name = "ch341a_spi",
514 .type = USB,
515 .devs.dev = devs_ch341a_spi,
516 .init = ch341a_spi_init,
517 .map_flash_region = fallback_map,
518 .unmap_flash_region = fallback_unmap,
519 .delay = ch341a_spi_delay,
520 },
521#endif
522
523#if CONFIG_DIGILENT_SPI == 1
524 {
525 .name = "digilent_spi",
526 .type = USB,
527 .devs.dev = devs_digilent_spi,
528 .init = digilent_spi_init,
529 .map_flash_region = fallback_map,
530 .unmap_flash_region = fallback_unmap,
531 .delay = internal_delay,
532 },
533#endif
534
535#if CONFIG_JLINK_SPI == 1
536 {
537 .name = "jlink_spi",
538 .type = OTHER,
539 .init = jlink_spi_init,
540 .devs.note = "SEGGER J-Link and compatible devices\n",
541 .map_flash_region = fallback_map,
542 .unmap_flash_region = fallback_unmap,
543 .delay = internal_delay,
544 },
545#endif
546
547#if CONFIG_NI845X_SPI == 1
548 {
549 .name = "ni845x_spi",
550 .type = OTHER, // choose other because NI-845x uses own USB implementation
551 .devs.note = "National Instruments USB-845x\n",
552 .init = ni845x_spi_init,
553 .map_flash_region = fallback_map,
554 .unmap_flash_region = fallback_unmap,
555 .delay = internal_delay,
556 },
557#endif
558
559#if CONFIG_STLINKV3_SPI == 1
560 {
561 .name = "stlinkv3_spi",
562 .type = USB,
563 .devs.dev = devs_stlinkv3_spi,
564 .init = stlinkv3_spi_init,
565 .map_flash_region = fallback_map,
566 .unmap_flash_region = fallback_unmap,
567 .delay = internal_delay,
568 },
569#endif
570
Edward O'Callaghand8f72232020-09-30 14:21:42 +1000571#if CONFIG_GOOGLE_EC == 1
572 {
573 .name = "google_ec",
574 .type = OTHER,
575 .devs.note = "Google EC.\n",
576 .init = cros_ec_probe_dev,
577 .map_flash_region = fallback_map,
578 .unmap_flash_region = fallback_unmap,
579 .delay = internal_delay,
580 },
581#endif
582
Edward O'Callaghanda29ca82020-10-20 00:49:47 +1100583#if CONFIG_CROS_ALIAS == 1
584 {
585 .name = "ec",
586 .type = OTHER,
587 .devs.note = "Google EC alias mechanism.\n",
588 .init = cros_ec_alias_init,
589 .map_flash_region = physmap, /* TODO(b/171934191) */
590 .unmap_flash_region = physunmap, /* TODO(b/171934191) */
591 .delay = internal_delay,
592
593 /*
594 * "ec" implies in-system programming on a live system, so
595 * handle with paranoia to catch errors early. If something goes
596 * wrong then hopefully the system will still be recoverable.
597 */
598 .paranoid = 1,
599 },
Edward O'Callaghan5b16a082020-10-20 16:30:16 +1100600
601 {
602 .name = "host",
603 .type = OTHER,
604 .devs.note = "Google host alias mechanism.\n",
605 .init = cros_host_alias_init,
606 .map_flash_region = physmap,
607 .unmap_flash_region = physunmap,
608 .delay = internal_delay,
609
610 /*
611 * "Internal" implies in-system programming on a live system, so
612 * handle with paranoia to catch errors early. If something goes
613 * wrong then hopefully the system will still be recoverable.
614 */
615 .paranoid = 1,
616 },
Edward O'Callaghanda29ca82020-10-20 00:49:47 +1100617#endif
618
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100619 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000620};
stepan927d4e22007-04-04 22:45:58 +0000621
David Hendricksbf36f092010-11-02 23:39:29 -0700622#define CHIP_RESTORE_MAXFN 4
623static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000624static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700625 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700626 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700627 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000628} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700629
David Hendricks668f29d2011-01-27 18:51:45 -0800630
hailfingerf31cbdc2010-11-10 15:25:18 +0000631#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000632static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000633/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000634static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700635 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000636 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000637} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000638/* Initialize to 0 to make sure nobody registers a shutdown function before
639 * programmer init.
640 */
641static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000642
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700643static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000644
hailfingerdc6f7972010-02-14 01:20:28 +0000645/* Register a function to be executed on programmer shutdown.
646 * The advantage over atexit() is that you can supply a void pointer which will
647 * be used as parameter to the registered function upon programmer shutdown.
648 * This pointer can point to arbitrary data used by said function, e.g. undo
649 * information for GPIO settings etc. If unneeded, set data=NULL.
650 * Please note that the first (void *data) belongs to the function signature of
651 * the function passed as first parameter.
652 */
David Hendricks93784b42016-08-09 17:00:38 -0700653int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000654{
655 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000656 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000657 SHUTDOWN_MAXFN);
658 return 1;
659 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000660 if (!may_register_shutdown) {
661 msg_perr("Tried to register a shutdown function before "
662 "programmer init.\n");
663 return 1;
664 }
hailfingerdc6f7972010-02-14 01:20:28 +0000665 shutdown_fn[shutdown_fn_count].func = function;
666 shutdown_fn[shutdown_fn_count].data = data;
667 shutdown_fn_count++;
668
669 return 0;
670}
671
David Hendricksbf36f092010-11-02 23:39:29 -0700672//int register_chip_restore(int (*function) (void *data), void *data)
673int register_chip_restore(CHIP_RESTORE_CALLBACK,
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700674 struct flashctx *flash, uint8_t status)
David Hendricksbf36f092010-11-02 23:39:29 -0700675{
676 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
677 msg_perr("Tried to register more than %i chip restore"
678 " functions.\n", CHIP_RESTORE_MAXFN);
679 return 1;
680 }
681 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
682 chip_restore_fn[chip_restore_fn_count].flash = flash;
683 chip_restore_fn[chip_restore_fn_count].status = status;
684 chip_restore_fn_count++;
685
686 return 0;
687}
688
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000689int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000690{
hailfinger1ef766d2010-07-06 09:55:48 +0000691 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000692
693 if (prog >= PROGRAMMER_INVALID) {
694 msg_perr("Invalid programmer specified!\n");
695 return -1;
696 }
697 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000698 /* Initialize all programmer specific data. */
699 /* Default to unlimited decode sizes. */
700 max_rom_decode = (const struct decode_sizes) {
701 .parallel = 0xffffffff,
702 .lpc = 0xffffffff,
703 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000704 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000705 };
David Hendricksac1d25c2016-08-09 17:00:58 -0700706 buses_supported = BUS_NONE;
hailfinger1ff33dc2010-07-03 11:02:10 +0000707 /* Default to top aligned flash at 4 GB. */
708 flashbase = 0;
709 /* Registering shutdown functions is now allowed. */
710 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000711 /* Default to allowing writes. Broken programmers set this to 0. */
712 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000713
714 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000715 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700716 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000717 if (programmer_param && strlen(programmer_param)) {
718 if (ret != 0) {
719 /* It is quite possible that any unhandled programmer parameter would have been valid,
720 * but an error in actual programmer init happened before the parameter was evaluated.
721 */
722 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
723 programmer_param);
724 } else {
725 /* Actual programmer init was successful, but the user specified an invalid or unusable
726 * (for the current programmer configuration) parameter.
727 */
728 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
729 msg_perr("Aborting.\n");
730 ret = ERROR_FATAL;
731 }
732 }
hailfinger1ef766d2010-07-06 09:55:48 +0000733 return ret;
uweabe92a52009-05-16 22:36:00 +0000734}
735
David Hendricksbf36f092010-11-02 23:39:29 -0700736int chip_restore()
737{
738 int rc = 0;
739
740 while (chip_restore_fn_count > 0) {
741 int i = --chip_restore_fn_count;
742 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
743 chip_restore_fn[i].status);
744 }
745
746 return rc;
747}
748
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000749/** Calls registered shutdown functions and resets internal programmer-related variables.
750 * Calling it is safe even without previous initialization, but further interactions with programmer support
751 * require a call to programmer_init() (afterwards).
752 *
753 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700754int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000755{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000756 int ret = 0;
757
hailfinger1ff33dc2010-07-03 11:02:10 +0000758 /* Registering shutdown functions is no longer allowed. */
759 may_register_shutdown = 0;
760 while (shutdown_fn_count > 0) {
761 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700762 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000763 }
Edward O'Callaghancf9c40f2020-10-19 20:02:39 +1100764
765 programmer_param = NULL;
766 registered_master_count = 0;
767
dhendrix0ffc2eb2011-06-14 01:35:36 +0000768 return ret;
uweabe92a52009-05-16 22:36:00 +0000769}
770
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000771void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000772{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000773 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
774 return ret;
uweabe92a52009-05-16 22:36:00 +0000775}
776
777void programmer_unmap_flash_region(void *virt_addr, size_t len)
778{
779 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000780 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000781}
782
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700783void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000784{
Craig Hesling65eb8812019-08-01 09:33:56 -0700785 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000786}
787
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700788void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000789{
Craig Hesling65eb8812019-08-01 09:33:56 -0700790 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000791}
792
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700793void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000794{
Craig Hesling65eb8812019-08-01 09:33:56 -0700795 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000796}
797
Stuart langleyc98e43f2020-03-26 20:27:36 +1100798void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000799{
Craig Hesling65eb8812019-08-01 09:33:56 -0700800 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000801}
802
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700803uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000804{
Craig Hesling65eb8812019-08-01 09:33:56 -0700805 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000806}
807
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700808uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000809{
Craig Hesling65eb8812019-08-01 09:33:56 -0700810 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000811}
812
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700813uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000814{
Craig Hesling65eb8812019-08-01 09:33:56 -0700815 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000816}
817
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000818void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
819 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000820{
Craig Hesling65eb8812019-08-01 09:33:56 -0700821 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000822}
823
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000824void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000825{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000826 if (usecs > 0)
827 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000828}
829
Edward O'Callaghana820b212020-09-17 22:53:26 +1000830int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
831 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000832{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700833 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000834
hailfinger23060112009-05-08 12:49:03 +0000835 return 0;
836}
837
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000838/* This is a somewhat hacked function similar in some ways to strtok().
839 * It will look for needle with a subsequent '=' in haystack, return a copy of
840 * needle and remove everything from the first occurrence of needle to the next
841 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000842 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000843char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000844{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000845 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000846 char *opt = NULL;
847 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000848 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000849
hailfingerf4aaccc2010-04-28 15:22:14 +0000850 needlelen = strlen(needle);
851 if (!needlelen) {
852 msg_gerr("%s: empty needle! Please report a bug at "
853 "flashrom@flashrom.org\n", __func__);
854 return NULL;
855 }
856 /* No programmer parameters given. */
857 if (*haystack == NULL)
858 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000859 param_pos = strstr(*haystack, needle);
860 do {
861 if (!param_pos)
862 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000863 /* Needle followed by '='? */
864 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000865 /* Beginning of the string? */
866 if (param_pos == *haystack)
867 break;
868 /* After a delimiter? */
869 if (strchr(delim, *(param_pos - 1)))
870 break;
871 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000872 /* Continue searching. */
873 param_pos++;
874 param_pos = strstr(param_pos, needle);
875 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000876
hailfinger6e5a52a2009-11-24 18:27:10 +0000877 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000878 /* Get the string after needle and '='. */
879 opt_pos = param_pos + needlelen + 1;
880 optlen = strcspn(opt_pos, delim);
881 /* Return an empty string if the parameter was empty. */
882 opt = malloc(optlen + 1);
883 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000884 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000885 exit(1);
886 }
hailfinger1ef766d2010-07-06 09:55:48 +0000887 strncpy(opt, opt_pos, optlen);
888 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000889 rest = opt_pos + optlen;
890 /* Skip all delimiters after the current parameter. */
891 rest += strspn(rest, delim);
892 memmove(param_pos, rest, strlen(rest) + 1);
893 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000894 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000895
hailfinger1ef766d2010-07-06 09:55:48 +0000896 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000897}
898
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000899char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000900{
901 return extract_param(&programmer_param, param_name, ",");
902}
903
stefancte1c5acf2011-07-04 07:27:17 +0000904/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700905static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000906{
907 unsigned int usable_erasefunctions = 0;
908 int k;
909 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
910 if (!check_block_eraser(flash, k, 0))
911 usable_erasefunctions++;
912 }
913 return usable_erasefunctions;
914}
915
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000916static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700917{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000918 int ret = 0, failcount = 0;
919 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700920 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000921 if (wantbuf[i] != havebuf[i]) {
922 /* Only print the first failure. */
923 if (!failcount++)
924 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
925 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700926 }
927 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000928 if (failcount) {
929 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
930 start, start + len - 1, failcount);
931 ret = -1;
932 }
933 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700934}
935
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000936/* start is an offset to the base address of the flash chip */
937static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
938{
939 int ret;
940 uint8_t *cmpbuf = malloc(len);
941 const uint8_t erased_value = ERASED_VALUE(flash);
942
943 if (!cmpbuf) {
944 msg_gerr("Could not allocate memory!\n");
945 exit(1);
946 }
947 memset(cmpbuf, erased_value, len);
948 ret = verify_range(flash, cmpbuf, start, len);
949 free(cmpbuf);
950 return ret;
951}
952
uwee15beb92010-08-08 17:01:18 +0000953/*
hailfinger7af3d192009-11-25 17:05:52 +0000954 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000955 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000956 * @start offset to the base address of the flash chip
957 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000958 * @return 0 for success, -1 for failure
959 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000960int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000961{
hailfinger7af83692009-06-15 17:23:36 +0000962 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000963 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000964
Patrick Georgif3fa2992017-02-02 16:24:44 +0100965 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000966 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000967 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000968 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000969
970 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000971 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000972 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000973 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000974 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000975 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000976
Patrick Georgif3fa2992017-02-02 16:24:44 +0100977 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000978 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000979 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100980 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000981 ret = -1;
982 goto out_free;
983 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700984 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700985 if (programmer_table[programmer].paranoid) {
986 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800987
Simon Glass4e305f42015-01-08 06:29:04 -0700988 /* limit chunksize in order to catch errors early */
989 for (i = 0, chunksize = 0; i < len; i += chunksize) {
990 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800991
Patrick Georgif3fa2992017-02-02 16:24:44 +0100992 chunksize = min(flash->chip->page_size, len - i);
993 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700994 if (tmp) {
995 ret = tmp;
996 if (ignore_error(tmp))
997 continue;
998 else
999 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -08001000 }
Simon Glass4e305f42015-01-08 06:29:04 -07001001
Duncan Laurie25a4ca22019-04-25 12:08:52 -07001002 /*
1003 * Check write access permission and do not compare chunks
1004 * where flashrom does not have write access to the region.
1005 */
1006 if (flash->chip->check_access) {
1007 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
1008 if (tmp && ignore_error(tmp))
1009 continue;
1010 }
1011
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001012 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -07001013 if (failcount)
1014 break;
David Hendricks1ed1d352011-11-23 17:54:37 -08001015 }
Simon Glass4e305f42015-01-08 06:29:04 -07001016 } else {
1017 int tmp;
1018
1019 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +01001020 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -07001021 if (tmp && !ignore_error(tmp)) {
1022 ret = tmp;
1023 goto out_free;
1024 }
1025
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001026 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +00001027 }
1028
hailfinger5be6c0f2009-07-23 01:42:56 +00001029 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +00001030 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +00001031 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +00001032 ret = -1;
1033 }
hailfinger7af83692009-06-15 17:23:36 +00001034
1035out_free:
1036 free(readbuf);
1037 return ret;
1038}
1039
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001040/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1041static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001042 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001043{
1044 unsigned int i, j, limit;
1045 for (j = 0; j < len / gran; j++) {
1046 limit = min (gran, len - j * gran);
1047 /* Are 'have' and 'want' identical? */
1048 if (!memcmp(have + j * gran, want + j * gran, limit))
1049 continue;
1050 /* have needs to be in erased state. */
1051 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001052 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001053 return 1;
1054 }
1055 return 0;
1056}
1057
uwee15beb92010-08-08 17:01:18 +00001058/*
hailfingerb247c7a2010-03-08 00:42:32 +00001059 * Check if the buffer @have can be programmed to the content of @want without
1060 * erasing. This is only possible if all chunks of size @gran are either kept
1061 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001062 *
hailfingerb437e282010-11-04 01:04:27 +00001063 * Warning: This function assumes that @have and @want point to naturally
1064 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001065 *
1066 * @have buffer with current content
1067 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001068 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001069 * @gran write granularity (enum, not count)
1070 * @return 0 if no erase is needed, 1 otherwise
1071 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001072int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1073 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001074{
hailfingerb91c08c2011-08-15 19:54:20 +00001075 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001076 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001077
hailfingerb247c7a2010-03-08 00:42:32 +00001078 switch (gran) {
1079 case write_gran_1bit:
1080 for (i = 0; i < len; i++)
1081 if ((have[i] & want[i]) != want[i]) {
1082 result = 1;
1083 break;
1084 }
1085 break;
1086 case write_gran_1byte:
1087 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001088 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001089 result = 1;
1090 break;
1091 }
1092 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001093 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001094 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001095 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001096 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001097 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001098 break;
1099 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001100 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001101 break;
1102 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001103 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001104 break;
1105 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001106 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001107 break;
1108 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001109 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001110 break;
1111 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001112 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001113 break;
1114 case write_gran_1byte_implicit_erase:
1115 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1116 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001117 break;
hailfingerb437e282010-11-04 01:04:27 +00001118 default:
1119 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1120 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001121 }
1122 return result;
1123}
1124
hailfingerb437e282010-11-04 01:04:27 +00001125/**
1126 * Check if the buffer @have needs to be programmed to get the content of @want.
1127 * If yes, return 1 and fill in first_start with the start address of the
1128 * write operation and first_len with the length of the first to-be-written
1129 * chunk. If not, return 0 and leave first_start and first_len undefined.
1130 *
1131 * Warning: This function assumes that @have and @want point to naturally
1132 * aligned regions.
1133 *
1134 * @have buffer with current content
1135 * @want buffer with desired content
1136 * @len length of the checked area
1137 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001138 * @first_start offset of the first byte which needs to be written (passed in
1139 * value is increased by the offset of the first needed write
1140 * relative to have/want or unchanged if no write is needed)
1141 * @return length of the first contiguous area which needs to be written
1142 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001143 *
1144 * FIXME: This function needs a parameter which tells it about coalescing
1145 * in relation to the max write length of the programmer and the max write
1146 * length of the chip.
1147 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001148static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001149 unsigned int *first_start,
1150 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001151{
stefanctc5eb8a92011-11-23 09:13:48 +00001152 int need_write = 0;
1153 unsigned int rel_start = 0, first_len = 0;
1154 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001155
hailfingerb437e282010-11-04 01:04:27 +00001156 switch (gran) {
1157 case write_gran_1bit:
1158 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001159 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001160 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001161 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001162 case write_gran_128bytes:
1163 stride = 128;
1164 break;
hailfingerb437e282010-11-04 01:04:27 +00001165 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001166 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001167 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001168 case write_gran_264bytes:
1169 stride = 264;
1170 break;
1171 case write_gran_512bytes:
1172 stride = 512;
1173 break;
1174 case write_gran_528bytes:
1175 stride = 528;
1176 break;
1177 case write_gran_1024bytes:
1178 stride = 1024;
1179 break;
1180 case write_gran_1056bytes:
1181 stride = 1056;
1182 break;
hailfingerb437e282010-11-04 01:04:27 +00001183 default:
1184 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1185 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001186 /* Claim that no write was needed. A write with unknown
1187 * granularity is too dangerous to try.
1188 */
1189 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001190 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001191 for (i = 0; i < len / stride; i++) {
1192 limit = min(stride, len - i * stride);
1193 /* Are 'have' and 'want' identical? */
1194 if (memcmp(have + i * stride, want + i * stride, limit)) {
1195 if (!need_write) {
1196 /* First location where have and want differ. */
1197 need_write = 1;
1198 rel_start = i * stride;
1199 }
1200 } else {
1201 if (need_write) {
1202 /* First location where have and want
1203 * do not differ anymore.
1204 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001205 break;
1206 }
1207 }
1208 }
hailfingerffb7f382010-12-06 13:05:44 +00001209 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001210 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001211 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001212 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001213}
1214
hailfinger0c515352009-11-23 12:55:31 +00001215/* This function generates various test patterns useful for testing controller
1216 * and chip communication as well as chip behaviour.
1217 *
1218 * If a byte can be written multiple times, each time keeping 0-bits at 0
1219 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1220 * is essentially an AND operation. That's also the reason why this function
1221 * provides the result of AND between various patterns.
1222 *
1223 * Below is a list of patterns (and their block length).
1224 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1225 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1226 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1227 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1228 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1229 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1230 * Pattern 6 is 00 (1 Byte)
1231 * Pattern 7 is ff (1 Byte)
1232 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1233 * byte block.
1234 *
1235 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1236 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1237 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1238 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1239 * Pattern 12 is 00 (1 Byte)
1240 * Pattern 13 is ff (1 Byte)
1241 * Patterns 8-13 have no block number.
1242 *
1243 * Patterns 0-3 are created to detect and efficiently diagnose communication
1244 * slips like missed bits or bytes and their repetitive nature gives good visual
1245 * cues to the person inspecting the results. In addition, the following holds:
1246 * AND Pattern 0/1 == Pattern 4
1247 * AND Pattern 2/3 == Pattern 5
1248 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1249 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1250 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1251 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1252 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1253 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1254 * Besides that, they provide for bit testing of the last two bytes of every
1255 * 256 byte block which contains the block number for patterns 0-6.
1256 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1257 * block sizes >256 bytes (some Dataflash chips etc.)
1258 * AND Pattern 8/9 == Pattern 12
1259 * AND Pattern 10/11 == Pattern 12
1260 * Pattern 13 is the completely erased state.
1261 * None of the patterns can detect aliasing at boundaries which are a multiple
1262 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1263 */
1264int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1265{
1266 int i;
1267
1268 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001269 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001270 return 1;
1271 }
1272
1273 switch (variant) {
1274 case 0:
1275 for (i = 0; i < size; i++)
1276 buf[i] = (i & 0xf) << 4 | 0x5;
1277 break;
1278 case 1:
1279 for (i = 0; i < size; i++)
1280 buf[i] = (i & 0xf) << 4 | 0xa;
1281 break;
1282 case 2:
1283 for (i = 0; i < size; i++)
1284 buf[i] = 0x50 | (i & 0xf);
1285 break;
1286 case 3:
1287 for (i = 0; i < size; i++)
1288 buf[i] = 0xa0 | (i & 0xf);
1289 break;
1290 case 4:
1291 for (i = 0; i < size; i++)
1292 buf[i] = (i & 0xf) << 4;
1293 break;
1294 case 5:
1295 for (i = 0; i < size; i++)
1296 buf[i] = i & 0xf;
1297 break;
1298 case 6:
1299 memset(buf, 0x00, size);
1300 break;
1301 case 7:
1302 memset(buf, 0xff, size);
1303 break;
1304 case 8:
1305 for (i = 0; i < size; i++)
1306 buf[i] = i & 0xff;
1307 break;
1308 case 9:
1309 for (i = 0; i < size; i++)
1310 buf[i] = ~(i & 0xff);
1311 break;
1312 case 10:
1313 for (i = 0; i < size % 2; i++) {
1314 buf[i * 2] = (i >> 8) & 0xff;
1315 buf[i * 2 + 1] = i & 0xff;
1316 }
1317 if (size & 0x1)
1318 buf[i * 2] = (i >> 8) & 0xff;
1319 break;
1320 case 11:
1321 for (i = 0; i < size % 2; i++) {
1322 buf[i * 2] = ~((i >> 8) & 0xff);
1323 buf[i * 2 + 1] = ~(i & 0xff);
1324 }
1325 if (size & 0x1)
1326 buf[i * 2] = ~((i >> 8) & 0xff);
1327 break;
1328 case 12:
1329 memset(buf, 0x00, size);
1330 break;
1331 case 13:
1332 memset(buf, 0xff, size);
1333 break;
1334 }
1335
1336 if ((variant >= 0) && (variant <= 7)) {
1337 /* Write block number in the last two bytes of each 256-byte
1338 * block, big endian for easier reading of the hexdump.
1339 * Note that this wraps around for chips larger than 2^24 bytes
1340 * (16 MB).
1341 */
1342 for (i = 0; i < size / 256; i++) {
1343 buf[i * 256 + 254] = (i >> 8) & 0xff;
1344 buf[i * 256 + 255] = i & 0xff;
1345 }
1346 }
1347
1348 return 0;
1349}
1350
hailfingeraec9c962009-10-31 01:53:09 +00001351int check_max_decode(enum chipbustype buses, uint32_t size)
1352{
1353 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001354
1355 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001356 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001357 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001358 "size %u kB of chipset/board/programmer "
1359 "for %s interface, "
1360 "probe/read/erase/write may fail. ", size / 1024,
1361 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001362 }
hailfingere1e41ea2011-07-27 07:13:06 +00001363 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001364 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001365 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001366 "size %u kB of chipset/board/programmer "
1367 "for %s interface, "
1368 "probe/read/erase/write may fail. ", size / 1024,
1369 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001370 }
hailfingere1e41ea2011-07-27 07:13:06 +00001371 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001372 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001373 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001374 "size %u kB of chipset/board/programmer "
1375 "for %s interface, "
1376 "probe/read/erase/write may fail. ", size / 1024,
1377 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001378 }
hailfingere1e41ea2011-07-27 07:13:06 +00001379 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001380 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001381 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001382 "size %u kB of chipset/board/programmer "
1383 "for %s interface, "
1384 "probe/read/erase/write may fail. ", size / 1024,
1385 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001386 }
1387 if (!limitexceeded)
1388 return 0;
1389 /* Sometimes chip and programmer have more than one bus in common,
1390 * and the limit is not exceeded on all buses. Tell the user.
1391 */
1392 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001393 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001394 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001395 "interface which can support a chip of this size. "
1396 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001397 return 1;
1398}
1399
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001400void unmap_flash(struct flashctx *flash)
1401{
1402 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1403 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1404 flash->physical_registers = 0;
1405 flash->virtual_registers = (chipaddr)ERROR_PTR;
1406 }
1407
1408 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1409 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1410 flash->physical_memory = 0;
1411 flash->virtual_memory = (chipaddr)ERROR_PTR;
1412 }
1413}
1414
1415int map_flash(struct flashctx *flash)
1416{
1417 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1418 flash->virtual_memory = (chipaddr)ERROR_PTR;
1419 flash->virtual_registers = (chipaddr)ERROR_PTR;
1420
1421 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1422 * These are used for various probing-related hacks that would not map successfully anyway and should be
1423 * removed ASAP. */
1424 if (flash->chip->total_size == 0)
1425 return 0;
1426
1427 const chipsize_t size = flash->chip->total_size * 1024;
1428 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1429 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1430 if (addr == ERROR_PTR) {
1431 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1432 flash->chip->name, PRIxPTR_WIDTH, base);
1433 return 1;
1434 }
1435 flash->physical_memory = base;
1436 flash->virtual_memory = (chipaddr)addr;
1437
1438 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1439 * completely different on some chips and programmers, or not mappable at all.
1440 * Ignore these problems for now and always report success. */
1441 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1442 base = 0xffffffff - size - 0x400000 + 1;
1443 addr = programmer_map_flash_region("flash chip registers", base, size);
1444 if (addr == ERROR_PTR) {
1445 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1446 flash->chip->name, PRIxPTR_WIDTH, base);
1447 return 0;
1448 }
1449 flash->physical_registers = base;
1450 flash->virtual_registers = (chipaddr)addr;
1451 }
1452 return 0;
1453}
1454
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001455/*
1456 * Return a string corresponding to the bustype parameter.
1457 * Memory is obtained with malloc() and must be freed with free() by the caller.
1458 */
1459char *flashbuses_to_text(enum chipbustype bustype)
1460{
1461 char *ret = calloc(1, 1);
1462 /*
1463 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1464 * will cease to exist and should be eliminated here as well.
1465 */
1466 if (bustype == BUS_NONSPI) {
1467 ret = strcat_realloc(ret, "Non-SPI, ");
1468 } else {
1469 if (bustype & BUS_PARALLEL)
1470 ret = strcat_realloc(ret, "Parallel, ");
1471 if (bustype & BUS_LPC)
1472 ret = strcat_realloc(ret, "LPC, ");
1473 if (bustype & BUS_FWH)
1474 ret = strcat_realloc(ret, "FWH, ");
1475 if (bustype & BUS_SPI)
1476 ret = strcat_realloc(ret, "SPI, ");
1477 if (bustype & BUS_PROG)
1478 ret = strcat_realloc(ret, "Programmer-specific, ");
1479 if (bustype == BUS_NONE)
1480 ret = strcat_realloc(ret, "None, ");
1481 }
1482 /* Kill last comma. */
1483 ret[strlen(ret) - 2] = '\0';
1484 ret = realloc(ret, strlen(ret) + 1);
1485 return ret;
1486}
1487
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001488int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001489{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001490 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001491 uint32_t size;
1492 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001493 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001494
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301495 /* Based on the host controller interface that a platform
1496 * needs to use (hwseq or swseq),
1497 * set the flashchips list here.
1498 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001499 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301500 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001501 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301502 flash_list = flashchips_hwseq;
1503 break;
1504 default:
1505 flash_list = flashchips;
1506 break;
1507 }
1508
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001509 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1510 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001511 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001512 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001513 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001514 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001515 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001516 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001517 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001518 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001519 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001520 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001521 continue;
1522 }
stepan782fb172007-04-06 11:58:03 +00001523
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001524 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001525 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001526
hailfinger48ed3e22011-05-04 00:39:50 +00001527 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001528 flash->chip = calloc(1, sizeof(struct flashchip));
1529 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001530 msg_gerr("Out of memory!\n");
1531 exit(1);
1532 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001533 memcpy(flash->chip, chip, sizeof(struct flashchip));
1534 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001535
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001536 if (map_flash(flash) != 0)
1537 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001538
Edward O'Callaghana820b212020-09-17 22:53:26 +10001539 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1540 * is only called with force=1 after normal probing failed.
1541 */
stugec1e55fe2008-07-02 17:15:47 +00001542 if (force)
1543 break;
stepanc98b80b2006-03-16 16:57:41 +00001544
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001545 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001546 goto notfound;
1547
hailfinger48ed3e22011-05-04 00:39:50 +00001548 /* If this is the first chip found, accept it.
1549 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001550 * a non-generic match. SFDP and CFI are generic matches.
1551 * startchip==0 means this call to probe_flash() is the first
1552 * one for this programmer interface (master) and thus no other chip has
1553 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001554 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001555 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1556 msg_cinfo("===\n"
1557 "SFDP has autodetected a flash chip which is "
1558 "not natively supported by flashrom yet.\n");
1559 if (count_usable_erasers(flash) == 0)
1560 msg_cinfo("The standard operations read and "
1561 "verify should work, but to support "
1562 "erase, write and all other "
1563 "possible features");
1564 else
1565 msg_cinfo("All standard operations (read, "
1566 "verify, erase and write) should "
1567 "work, but to support all possible "
1568 "features");
1569
1570 msg_cinfo(" we need to add them manually.\n"
1571 "You can help us by mailing us the output of the following command to "
1572 "flashrom@flashrom.org:\n"
1573 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1574 "Thanks for your help!\n"
1575 "===\n");
1576 }
stugec1e55fe2008-07-02 17:15:47 +00001577
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001578 /* First flash chip detected on this bus. */
1579 if (startchip == 0)
1580 break;
1581 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001582 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001583 break;
1584 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001585notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001586 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001587 free(flash->chip);
1588 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001589 }
uwebe4477b2007-08-23 16:08:21 +00001590
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001591 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001592 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001593
stepan3e7aeae2011-01-19 06:21:54 +00001594
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001595 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001596 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1597 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001598 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001599#if CONFIG_INTERNAL == 1
1600 if (programmer_table[programmer].map_flash_region == physmap)
1601 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1602 PRIxPTR_WIDTH, flash->physical_memory);
1603 else
1604#endif
1605 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001606
Edward O'Callaghana820b212020-09-17 22:53:26 +10001607 /* Flash registers may more likely not be mapped if the chip was forced.
1608 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001609 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001610 if (flash->chip->printlock)
1611 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001612
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001613 /* Get out of the way for later runs. */
1614 unmap_flash(flash);
1615
hailfinger48ed3e22011-05-04 00:39:50 +00001616 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001617 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001618}
1619
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001620static int verify_flash(struct flashctx *flash,
1621 struct action_descriptor *descriptor,
1622 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001623{
hailfingerb0f4d122009-06-24 08:20:45 +00001624 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001625 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001626 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001627
snelsone42c3802010-05-07 20:09:04 +00001628 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001629
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001630 if (verify_it == VERIFY_PARTIAL) {
1631 struct processing_unit *pu = descriptor->processing_units;
1632
1633 /* Verify only areas which were written. */
1634 while (pu->num_blocks) {
1635 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001636 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001637 if (ret)
1638 break;
1639 pu++;
1640 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001641 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001642 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001643 }
uwef6641642007-05-09 10:17:44 +00001644
David Hendricks1ed1d352011-11-23 17:54:37 -08001645 if (ret == ACCESS_DENIED) {
1646 msg_gdbg("Could not fully verify due to access error, ");
1647 if (access_denied_action == error_ignore) {
1648 msg_gdbg("ignoring\n");
1649 ret = 0;
1650 } else {
1651 msg_gdbg("aborting\n");
1652 }
1653 }
1654
hailfingerb0f4d122009-06-24 08:20:45 +00001655 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001656 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001657
hailfingerb0f4d122009-06-24 08:20:45 +00001658 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001659}
1660
uwe8d342eb2011-07-28 08:13:25 +00001661int read_buf_from_file(unsigned char *buf, unsigned long size,
1662 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001663{
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001664 unsigned long numbytes;
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001665 FILE *image;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001666 struct stat image_stat;
1667
1668 if (!strncmp(filename, "-", sizeof("-")))
1669 image = fdopen(STDIN_FILENO, "rb");
1670 else
1671 image = fopen(filename, "rb");
1672 if (image == NULL) {
1673 perror(filename);
hailfinger771fc182010-10-15 00:01:14 +00001674 return 1;
1675 }
1676 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001677 perror(filename);
1678 fclose(image);
1679 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001680 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001681 if ((image_stat.st_size != size) &&
1682 (strncmp(filename, "-", sizeof("-")))) {
1683 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1684 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
1685 fclose(image);
1686 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001687 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001688 numbytes = fread(buf, 1, size, image);
1689 if (fclose(image)) {
1690 perror(filename);
1691 return 1;
1692 }
hailfinger771fc182010-10-15 00:01:14 +00001693 if (numbytes != size) {
1694 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1695 "wanted %ld!\n", numbytes, size);
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001696 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001697 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001698 return 0;
hailfinger771fc182010-10-15 00:01:14 +00001699}
1700
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001701int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001702{
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001703 unsigned long numbytes;
hailfingerd219a232009-01-28 00:27:54 +00001704 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001705
1706 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001707 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001708 return 1;
1709 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001710 if (!strncmp(filename, "-", sizeof("-")))
1711 image = fdopen(STDOUT_FILENO, "wb");
1712 else
1713 image = fopen(filename, "wb");
1714 if (image == NULL) {
1715 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001716 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001717 }
hailfingerd219a232009-01-28 00:27:54 +00001718
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001719 numbytes = fwrite(buf, 1, size, image);
1720 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001721 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001722 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001723 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001724 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001725 return 0;
hailfingerd219a232009-01-28 00:27:54 +00001726}
1727
David Hendrickse3451942013-03-21 17:23:29 -07001728/*
1729 * read_flash - wrapper for flash->read() with additional high-level policy
1730 *
1731 * @flash flash chip
1732 * @buf buffer to store data in
1733 * @start start address
1734 * @len number of bytes to read
1735 *
1736 * This wrapper simplifies most cases when the flash chip needs to be read
1737 * since policy decisions such as non-fatal error handling is centralized.
1738 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001739int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001740 unsigned int start, unsigned int len)
1741{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001742 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001743
Patrick Georgif3fa2992017-02-02 16:24:44 +01001744 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001745 return -1;
1746
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001747 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1748
Patrick Georgif3fa2992017-02-02 16:24:44 +01001749 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001750 if (ret) {
1751 if (ignore_error(ret)) {
1752 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1753 start, start + len - 1);
1754 ret = 0;
1755 } else {
1756 msg_gdbg("failed to read 0x%x-0x%x\n",
1757 start, start + len - 1);
1758 }
1759 }
1760
1761 return ret;
1762}
1763
David Hendricks7c8a1612013-04-26 19:14:44 -07001764/*
1765 * write_flash - wrapper for flash->write() with additional high-level policy
1766 *
1767 * @flash flash chip
1768 * @buf buffer to write to flash
1769 * @start start address in flash
1770 * @len number of bytes to write
1771 *
1772 * TODO: Look up regions that are write-protected and avoid attempt to write
1773 * to them at all.
1774 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001775int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001776 unsigned int start, unsigned int len)
1777{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001778 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001779 return -1;
1780
Patrick Georgif3fa2992017-02-02 16:24:44 +01001781 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001782}
1783
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001784int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001785{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001786 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001787 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001788 int ret = 0;
1789
1790 msg_cinfo("Reading flash... ");
1791 if (!buf) {
1792 msg_gerr("Memory allocation failed!\n");
1793 msg_cinfo("FAILED.\n");
1794 return 1;
1795 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001796
1797 /* To support partial read, fill buffer to all 0xFF at beginning to make
1798 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001799 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001800
Patrick Georgif3fa2992017-02-02 16:24:44 +01001801 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001802 msg_cerr("No read function available for this flash chip.\n");
1803 ret = 1;
1804 goto out_free;
1805 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001806
1807 /* First try to handle partial read case, rather than read the whole
1808 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001809 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001810 if (ret < 0) {
1811 msg_cerr("Partial read operation failed!\n");
1812 ret = 1;
1813 goto out_free;
1814 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001815 int num_regions = get_num_include_args();
1816
1817 if (ret != num_regions) {
1818 msg_cerr("Requested %d regions, but only read %d\n",
1819 num_regions, ret);
1820 ret = 1;
1821 goto out_free;
1822 }
1823
1824 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001825 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001826 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001827 msg_cerr("Read operation failed!\n");
1828 ret = 1;
1829 goto out_free;
1830 }
hailfinger42a850a2010-07-13 23:56:13 +00001831 }
1832
David Hendricksdf29a832013-06-28 14:33:51 -07001833 if (filename)
1834 ret = write_buf_to_file(buf, size, filename);
1835
hailfinger42a850a2010-07-13 23:56:13 +00001836out_free:
1837 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001838 if (ret)
1839 msg_cerr("FAILED.");
1840 else
1841 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001842 return ret;
1843}
1844
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001845/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001846static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001847{
hailfingerb91c08c2011-08-15 19:54:20 +00001848 int i, j, k;
1849 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001850
1851 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1852 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001853 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001854
1855 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1856 /* Blocks with zero size are bugs in flashchips.c. */
1857 if (eraser.eraseblocks[i].count &&
1858 !eraser.eraseblocks[i].size) {
1859 msg_gerr("ERROR: Flash chip %s erase function "
1860 "%i region %i has size 0. Please report"
1861 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001862 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001863 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001864 }
1865 /* Blocks with zero count are bugs in flashchips.c. */
1866 if (!eraser.eraseblocks[i].count &&
1867 eraser.eraseblocks[i].size) {
1868 msg_gerr("ERROR: Flash chip %s erase function "
1869 "%i region %i has count 0. Please report"
1870 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001871 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001872 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001873 }
1874 done += eraser.eraseblocks[i].count *
1875 eraser.eraseblocks[i].size;
1876 }
hailfinger9fed35d2010-01-19 06:42:46 +00001877 /* Empty eraseblock definition with erase function. */
1878 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001879 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001880 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001881 if (!done)
1882 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001883 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001884 msg_gerr("ERROR: Flash chip %s erase function %i "
1885 "region walking resulted in 0x%06x bytes total,"
1886 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001887 " flashrom@flashrom.org\n", chip->name, k,
1888 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001889 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001890 }
hailfinger9fed35d2010-01-19 06:42:46 +00001891 if (!eraser.block_erase)
1892 continue;
1893 /* Check if there are identical erase functions for different
1894 * layouts. That would imply "magic" erase functions. The
1895 * easiest way to check this is with function pointers.
1896 */
uwef6f94d42010-03-13 17:28:29 +00001897 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001898 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001899 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001900 msg_gerr("ERROR: Flash chip %s erase function "
1901 "%i and %i are identical. Please report"
1902 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001903 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001904 ret = 1;
1905 }
uwef6f94d42010-03-13 17:28:29 +00001906 }
hailfinger45177872010-01-18 08:14:43 +00001907 }
hailfinger9fed35d2010-01-19 06:42:46 +00001908 return ret;
hailfinger45177872010-01-18 08:14:43 +00001909}
1910
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001911static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001912 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001913 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001914 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001915 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001916 unsigned int addr,
1917 unsigned int len))
1918{
stefanctc5eb8a92011-11-23 09:13:48 +00001919 unsigned int starthere = 0, lenhere = 0;
1920 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001921 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001922 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001923
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001924 /*
1925 * curcontents and newcontents are opaque to walk_eraseregions, and
1926 * need to be adjusted here to keep the impression of proper
1927 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001928 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001929
hailfinger90fcf9b2010-11-05 14:51:59 +00001930 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001931
hailfingerb437e282010-11-04 01:04:27 +00001932 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001933
hailfingerb437e282010-11-04 01:04:27 +00001934 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001935 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001936 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001937 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001938 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001939 if (ret) {
1940 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001941 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001942 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001943 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001944 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001945 }
1946
David Hendricks0954ffc2015-11-13 15:15:44 -08001947 if (programmer_table[programmer].paranoid) {
1948 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001949 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001950 return -1;
1951 }
hailfingerac8e3182011-06-26 17:04:16 +00001952 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001953
hailfinger90fcf9b2010-11-05 14:51:59 +00001954 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001955 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001956 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001957 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001958 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001959 /* get_next_write() sets starthere to a new value after the call. */
1960 while ((lenhere = get_next_write(curcontents + starthere,
1961 newcontents + starthere,
1962 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001963 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001964 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001965 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001966 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001967 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001968 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001969 if (ret) {
1970 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001971 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001972 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001973 }
David Hendricks048b38c2016-03-28 18:47:06 -07001974
1975 /*
1976 * If the block needed to be erased and was erased successfully
1977 * then we can assume that we didn't run into any write-
1978 * protected areas. Otherwise, we need to verify each page to
1979 * ensure it was successfully written and abort if we encounter
1980 * any errors.
1981 */
1982 if (programmer_table[programmer].paranoid && !block_was_erased) {
1983 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001984 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001985 return -1;
1986 }
1987
hailfingerb437e282010-11-04 01:04:27 +00001988 starthere += lenhere;
1989 skip = 0;
1990 }
1991 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001992 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001993 return ret;
1994}
1995
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001996/*
1997 * Function to process processing units accumulated in the action descriptor.
1998 *
1999 * @flash pointer to the flash context to operate on
2000 * @do_something helper function which can erase and program a section of the
2001 * flash chip. It receives the flash context, offset and length
2002 * of the area to erase/program, before and after contents (to
2003 * decide what exactly needs to be erased and or programmed)
2004 * and a pointer to the erase function which can operate on the
2005 * proper granularity.
2006 * @descriptor action descriptor including pointers to before and after
2007 * contents and an array of processing actions to take.
2008 *
2009 * Returns zero on success or an error code.
2010 */
2011static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002012 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00002013 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00002014 unsigned int len,
2015 uint8_t *param1,
2016 uint8_t *param2,
2017 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002018 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00002019 unsigned int addr,
2020 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002021 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00002022{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002023 struct processing_unit *pu;
2024 int rc = 0;
2025 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00002026
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002027 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
2028 unsigned base = pu->offset;
2029 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07002030
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002031 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07002032
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002033 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00002034 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002035 else
2036 print_comma = 1;
2037
2038 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
2039
2040 rc = do_something(flash, base,
2041 pu->block_size,
2042 descriptor->oldcontents,
2043 descriptor->newcontents,
2044 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
2045
David Hendricks1ed1d352011-11-23 17:54:37 -08002046 if (rc) {
2047 if (ignore_error(rc))
2048 rc = 0;
2049 else
2050 return rc;
hailfingerb437e282010-11-04 01:04:27 +00002051 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002052 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00002053 }
2054 }
hailfingerb437e282010-11-04 01:04:27 +00002055 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08002056 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00002057}
2058
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002059static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00002060{
Patrick Georgif3fa2992017-02-02 16:24:44 +01002061 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00002062
2063 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
2064 if (log)
2065 msg_cdbg("not defined. ");
2066 return 1;
2067 }
2068 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
2069 if (log)
2070 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00002071 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00002072 return 1;
2073 }
2074 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
2075 if (log)
2076 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00002077 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00002078 return 1;
2079 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002080 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002081 return 0;
2082}
2083
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002084int erase_and_write_flash(struct flashctx *flash,
2085 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002086{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002087 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002088
hailfingercf848f12010-12-05 15:14:44 +00002089 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002090
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002091 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002092
hailfinger7df21362009-09-05 02:30:58 +00002093 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002094 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002095 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002096 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002097 }
2098 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002099}
2100
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002101static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002102{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002103 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2104#if CONFIG_INTERNAL == 1
2105 if (programmer == PROGRAMMER_INTERNAL)
2106 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2107 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2108 "mail flashrom@flashrom.org, thanks!\n"
2109 "-------------------------------------------------------------------------------\n"
2110 "You may now reboot or simply leave the machine running.\n");
2111 else
2112#endif
2113 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2114 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2115 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2116 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002117}
2118
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002119static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002120{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002121 msg_gerr("Your flash chip is in an unknown state.\n");
2122#if CONFIG_INTERNAL == 1
2123 if (programmer == PROGRAMMER_INTERNAL)
2124 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2125 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2126 "-------------------------------------------------------------------------------\n"
2127 "DO NOT REBOOT OR POWEROFF!\n");
2128 else
2129#endif
2130 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2131 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002132}
2133
hailfingerf79d1712010-10-06 23:48:34 +00002134void list_programmers_linebreak(int startcol, int cols, int paren)
2135{
2136 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002137 int pnamelen;
2138 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002139 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002140 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002141
2142 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2143 pname = programmer_table[p].name;
2144 pnamelen = strlen(pname);
2145 if (remaining - pnamelen - 2 < 0) {
2146 if (firstline)
2147 firstline = 0;
2148 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002149 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002150 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002151 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002152 remaining = cols - startcol;
2153 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002154 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002155 remaining--;
2156 }
2157 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002158 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002159 remaining--;
2160 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002161 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002162 remaining -= pnamelen;
2163 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002164 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002165 remaining--;
2166 } else {
2167 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002168 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002169 }
2170 }
2171}
2172
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002173static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002174{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002175#if IS_WINDOWS
2176 SYSTEM_INFO si;
2177 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002178
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002179 memset(&si, 0, sizeof(SYSTEM_INFO));
2180 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2181 msg_ginfo(" on Windows");
2182 /* Tell Windows which version of the structure we want. */
2183 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2184 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2185 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2186 else
2187 msg_ginfo(" unknown version");
2188 GetSystemInfo(&si);
2189 switch (si.wProcessorArchitecture) {
2190 case PROCESSOR_ARCHITECTURE_AMD64:
2191 msg_ginfo(" (x86_64)");
2192 break;
2193 case PROCESSOR_ARCHITECTURE_INTEL:
2194 msg_ginfo(" (x86)");
2195 break;
2196 default:
2197 msg_ginfo(" (unknown arch)");
2198 break;
2199 }
2200#elif HAVE_UTSNAME == 1
2201 struct utsname osinfo;
2202
2203 uname(&osinfo);
2204 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002205 osinfo.machine);
2206#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002207 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002208#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002209}
2210
2211void print_buildinfo(void)
2212{
2213 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002214#if NEED_PCI == 1
2215#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002216 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002217#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002218 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002219#endif
2220#endif
2221#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002222 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002223#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002224 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002225#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002226 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002227#endif
hailfinger3b471632010-03-27 16:36:40 +00002228#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002229 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002230#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002231 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002232#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002233 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002234#endif
2235#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002236 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002237#endif
2238#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002239 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00002240#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002241 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00002242#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002243 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002244}
2245
uwefdeca092008-01-21 15:24:22 +00002246void print_version(void)
2247{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002248 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002249 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002250 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002251}
2252
hailfinger74819ad2010-05-15 15:04:37 +00002253void print_banner(void)
2254{
2255 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002256 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002257 msg_ginfo("\n");
2258}
2259
hailfingerc77acb52009-12-24 02:15:55 +00002260int selfcheck(void)
2261{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002262 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002263 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002264
2265 /* Safety check. Instead of aborting after the first error, check
2266 * if more errors exist.
2267 */
hailfingerc77acb52009-12-24 02:15:55 +00002268 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002269 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002270 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002271 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002272 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2273 const struct programmer_entry p = programmer_table[i];
2274 if (p.name == NULL) {
2275 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2276 ret = 1;
2277 /* This might hide other problems with this programmer, but allows for better error
2278 * messages below without jumping through hoops. */
2279 continue;
2280 }
2281 switch (p.type) {
2282 case USB:
2283 case PCI:
2284 case OTHER:
2285 if (p.devs.note == NULL) {
2286 if (strcmp("internal", p.name) == 0)
2287 break; /* This one has its device list stored separately. */
2288 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2289 p.name);
2290 ret = 1;
2291 }
2292 break;
2293 default:
2294 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2295 ret = 1;
2296 break;
2297 }
2298 if (p.init == NULL) {
2299 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2300 ret = 1;
2301 }
2302 if (p.delay == NULL) {
2303 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2304 ret = 1;
2305 }
2306 if (p.map_flash_region == NULL) {
2307 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2308 ret = 1;
2309 }
2310 if (p.unmap_flash_region == NULL) {
2311 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2312 ret = 1;
2313 }
2314 }
2315
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002316 /* It would be favorable if we could check for the correct layout (especially termination) of various
2317 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2318 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2319 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2320 * 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 +10002321 * checks below. */
2322 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002323 msg_gerr("Flashchips table miscompilation!\n");
2324 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002325 } else {
2326 for (i = 0; i < flashchips_size - 1; i++) {
2327 const struct flashchip *chip = &flashchips[i];
2328 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2329 ret = 1;
2330 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2331 "Please report a bug at flashrom@flashrom.org\n", i,
2332 chip->name == NULL ? "unnamed" : chip->name);
2333 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002334 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002335 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002336 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002337 }
stefanct6d836ba2011-05-26 01:35:19 +00002338 }
stefanct6d836ba2011-05-26 01:35:19 +00002339
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002340 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002341 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002342}
2343
hailfinger771fc182010-10-15 00:01:14 +00002344/* FIXME: This function signature needs to be improved once doit() has a better
2345 * function signature.
2346 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002347static int chip_safety_check(const struct flashctx *flash, int force,
2348 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002349{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002350 const struct flashchip *chip = flash->chip;
2351
hailfinger771fc182010-10-15 00:01:14 +00002352 if (!programmer_may_write && (write_it || erase_it)) {
2353 msg_perr("Write/erase is not working yet on your programmer in "
2354 "its current configuration.\n");
2355 /* --force is the wrong approach, but it's the best we can do
2356 * until the generic programmer parameter parser is merged.
2357 */
2358 if (!force)
2359 return 1;
2360 msg_cerr("Continuing anyway.\n");
2361 }
2362
2363 if (read_it || erase_it || write_it || verify_it) {
2364 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002365 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002366 msg_cerr("Read is not working on this chip. ");
2367 if (!force)
2368 return 1;
2369 msg_cerr("Continuing anyway.\n");
2370 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002371 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002372 msg_cerr("flashrom has no read function for this "
2373 "flash chip.\n");
2374 return 1;
2375 }
2376 }
2377 if (erase_it || write_it) {
2378 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002379 if (chip->tested.erase == NA) {
2380 msg_cerr("Erase is not possible on this chip.\n");
2381 return 1;
2382 }
2383 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002384 msg_cerr("Erase is not working on this chip. ");
2385 if (!force)
2386 return 1;
2387 msg_cerr("Continuing anyway.\n");
2388 }
stefancte1c5acf2011-07-04 07:27:17 +00002389 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002390 msg_cerr("flashrom has no erase function for this "
2391 "flash chip.\n");
2392 return 1;
2393 }
hailfinger771fc182010-10-15 00:01:14 +00002394 }
2395 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002396 if (chip->tested.write == NA) {
2397 msg_cerr("Write is not possible on this chip.\n");
2398 return 1;
2399 }
2400 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002401 msg_cerr("Write is not working on this chip. ");
2402 if (!force)
2403 return 1;
2404 msg_cerr("Continuing anyway.\n");
2405 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002406 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002407 msg_cerr("flashrom has no write function for this "
2408 "flash chip.\n");
2409 return 1;
2410 }
2411 }
2412 return 0;
2413}
2414
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002415int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002416 const bool read_it, const bool write_it,
2417 const bool erase_it, const bool verify_it)
2418{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002419 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002420 msg_cerr("Aborting.\n");
2421 return 1;
2422 }
2423
2424 if (normalize_romentries(flash)) {
2425 msg_cerr("Requested regions can not be handled. Aborting.\n");
2426 return 1;
2427 }
2428
Edward O'Callaghan40092972020-10-20 11:50:48 +11002429 /*
2430 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2431 * can be repro'ed with upstream on Volteer.
2432 *
2433 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2434 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2435 * hooked and this can fail on some board topologies. Checking the return value can
2436 * cause board rw failures by bailing early. Avoid the early bail for now until a
2437 * full investigation can reveal the proper fix. This restores previous behaviour of
2438 * assuming a map went fine.
2439 */
2440#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002441 if (map_flash(flash) != 0)
2442 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002443#endif
2444 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002445
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002446 /* Given the existence of read locks, we want to unlock for read,
2447 erase and write. */
2448 if (flash->chip->unlock)
2449 flash->chip->unlock(flash);
2450
2451 flash->address_high_byte = -1;
2452 flash->in_4ba_mode = false;
2453
Edward O'Callaghan99974452020-10-13 13:28:33 +11002454 /* Be careful about 4BA chips and broken masters */
2455 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2456 /* If we can't use native instructions, bail out */
2457 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2458 || !spi_master_4ba(flash)) {
2459 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2460 return 1;
2461 }
2462 }
2463
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002464 /* Enable/disable 4-byte addressing mode if flash chip supports it */
Edward O'Callaghanf5cd3c12020-10-30 13:19:27 +11002465 if ((flash->chip->feature_bits & (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_ENTER_EAR7)) && flash->chip->set_4ba) {
2466 if (flash->chip->set_4ba(flash)) {
Edward O'Callaghan99974452020-10-13 13:28:33 +11002467 msg_cerr("Failed to set correct 4BA mode! Aborting.\n");
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002468 return 1;
2469 }
2470 }
2471
2472 return 0;
2473}
2474
Edward O'Callaghana820b212020-09-17 22:53:26 +10002475void finalize_flash_access(struct flashctx *const flash)
2476{
2477 unmap_flash(flash);
2478}
2479
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002480/*
2481 * Function to erase entire flash chip.
2482 *
2483 * @flashctx pointer to the flash context to use
2484 * @oldcontents pointer to the buffer including current chip contents, to
2485 * decide which areas do in fact need to be erased
2486 * @size the size of the flash chip, in bytes.
2487 *
2488 * Returns zero on success or an error code.
2489 */
2490static int erase_chip(struct flashctx *flash, void *oldcontents,
2491 void *newcontents, size_t size)
2492{
2493 /*
2494 * To make sure that the chip is fully erased, let's cheat and create
2495 * a descriptor where the new contents are all erased.
2496 */
2497 struct action_descriptor *fake_descriptor;
2498 int ret = 0;
2499
2500 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2501 newcontents, 1);
2502 /* FIXME: Do we really want the scary warning if erase failed? After
2503 * all, after erase the chip is either blank or partially blank or it
2504 * has the old contents. A blank chip won't boot, so if the user
2505 * wanted erase and reboots afterwards, the user knows very well that
2506 * booting won't work.
2507 */
2508 if (erase_and_write_flash(flash, fake_descriptor)) {
2509 emergency_help_message();
2510 ret = 1;
2511 }
2512
2513 free(fake_descriptor);
2514
2515 return ret;
2516}
2517
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002518static int read_dest_content(struct flashctx *flash, int verify_it,
2519 uint8_t *dest, unsigned long size)
2520{
2521 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2522 && get_num_include_args()) {
2523 /*
2524 * If no full verification is required and not
2525 * the entire chip is about to be programmed,
2526 * read only the areas which might change.
2527 */
2528 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2529 return 1;
2530 } else {
2531 if (read_flash(flash, dest, 0, size))
2532 return 1;
2533 }
2534 return 0;
2535}
2536
hailfingerc77acb52009-12-24 02:15:55 +00002537/* This function signature is horrible. We need to design a better interface,
2538 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002539 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002540 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002541int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002542 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002543 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002544{
hailfinger4c47e9d2010-10-19 22:06:20 +00002545 uint8_t *oldcontents;
2546 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002547 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002548 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002549 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002550
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002551 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002552 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002553 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002554
Simon Glass9ad06c12013-07-03 22:08:17 +09002555 if (extract_it) {
2556 ret = extract_regions(flash);
2557 goto out_nofree;
2558 }
2559
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002560 /* mark entries included using -i argument as "included" if they are
2561 found in the master rom_entries list */
2562 if (process_include_args() < 0) {
2563 ret = 1;
2564 goto out_nofree;
2565 }
2566
hailfinger771fc182010-10-15 00:01:14 +00002567 if (read_it) {
2568 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002569 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002570 }
hailfingerb437e282010-11-04 01:04:27 +00002571
stefanctd611e8f2011-07-12 22:35:21 +00002572 oldcontents = malloc(size);
2573 if (!oldcontents) {
2574 msg_gerr("Out of memory!\n");
2575 exit(1);
2576 }
Simon Glass4c214132013-07-16 10:09:28 -06002577 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002578 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002579 newcontents = malloc(size);
2580 if (!newcontents) {
2581 msg_gerr("Out of memory!\n");
2582 exit(1);
2583 }
Simon Glass4c214132013-07-16 10:09:28 -06002584 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002585 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002586 /* Side effect of the assumptions above: Default write action is erase
2587 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002588 * oldcontents being completely unerased means we have to erase
2589 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002590 */
2591
hailfingerd217d122010-10-08 18:52:29 +00002592 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002593 /*
2594 * Note: This must be done before any files specified by -i
2595 * arguments are processed merged into the newcontents since
2596 * -i files take priority. See http://crbug.com/263495.
2597 */
2598 if (filename) {
2599 if (read_buf_from_file(newcontents, size, filename)) {
2600 ret = 1;
2601 goto out;
2602 }
2603 } else {
2604 /* Content will be read from -i args, so they must
2605 * not overlap. */
2606 if (included_regions_overlap()) {
2607 msg_gerr("Error: Included regions must "
2608 "not overlap.\n");
2609 ret = 1;
2610 goto out;
2611 }
stepan1da96c02006-11-21 23:48:51 +00002612 }
ollie5672ac62004-03-17 22:22:08 +00002613 }
2614
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002615 if (do_diff) {
2616 /*
2617 * Obtain a reference image so that we can check whether
2618 * regions need to be erased and to give better diagnostics in
2619 * case write fails. If --fast-verify is used then only the
2620 * regions which are included using -i will be read.
2621 */
2622 if (diff_file) {
2623 msg_cdbg("Reading old contents from file... ");
2624 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002625 ret = 1;
2626 msg_cdbg("FAILED.\n");
2627 goto out;
2628 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002629 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002630 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002631 ret = read_dest_content(flash, verify_it,
2632 oldcontents, size);
2633 if (ret) {
2634 msg_cdbg("FAILED.\n");
2635 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002636 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002637 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002638 msg_cdbg("done.\n");
2639 } else if (!erase_it) {
2640 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002641 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002642 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002643
David Hendricksdf29a832013-06-28 14:33:51 -07002644 /*
2645 * Note: This must be done after reading the file specified for the
2646 * -w/-v argument, if any, so that files specified using -i end up
2647 * in the "newcontents" buffer before being written.
2648 * See http://crbug.com/263495.
2649 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002650 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002651 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002652 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002653 goto out;
2654 }
uwef6641642007-05-09 10:17:44 +00002655
David Hendricksa7e114b2016-02-26 18:49:15 -08002656 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002657 erase_chip(flash, oldcontents, newcontents, size);
2658 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002659 }
2660
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002661 descriptor = prepare_action_descriptor(flash, oldcontents,
2662 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002663 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002664 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002665 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002666 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002667 goto out;
2668 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002669
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002670 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002671 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2672 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002673 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002674 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002675 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002676 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002677 ret = 1;
2678 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002679 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002680 msg_cerr("Apparently at least some data has changed.\n");
2681 } else
2682 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002683 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002684 ret = 1;
2685 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002686 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002687
David Hendricksac1d25c2016-08-09 17:00:58 -07002688 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002689 if (ret < 0) {
2690 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002691 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002692 emergency_help_message();
2693 ret = 1;
2694 goto out;
2695 } else if (ret > 0) {
2696 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002697 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002698 ret = read_dest_content(flash, verify_it,
2699 oldcontents, size);
2700 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002701 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002702 goto out;
2703 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002704
2705 /* Get a new descriptor. */
2706 free(descriptor);
2707 descriptor = prepare_action_descriptor(flash,
2708 oldcontents,
2709 newcontents,
2710 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002711 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002712 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002713 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002714 emergency_help_message();
2715 ret = 1;
2716 goto out;
2717 }
2718 ret = 0;
2719 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002720
David Hendricksac1d25c2016-08-09 17:00:58 -07002721 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002722 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002723 emergency_help_message();
2724 ret = 1;
2725 goto out;
2726 }
stuge8ce3a3c2008-04-28 14:47:30 +00002727 }
ollie6a600992005-11-26 21:55:36 +00002728
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002729 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002730 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002731 if ((write_it || erase_it) && !content_has_changed) {
2732 msg_gdbg("Nothing was erased or written, skipping "
2733 "verification\n");
2734 } else {
2735 /* Work around chips which need some time to calm down. */
2736 if (write_it && verify_it != VERIFY_PARTIAL)
2737 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002738
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002739 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002740
David Hendricks9ba79fb2015-04-03 12:06:16 -07002741 /* If we tried to write, and verification now fails, we
2742 * might have an emergency situation.
2743 */
2744 if (ret && write_it)
2745 emergency_help_message();
2746 }
hailfinger0459e1c2009-08-19 13:55:34 +00002747 }
ollie6a600992005-11-26 21:55:36 +00002748
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002749 finalize_flash_access(flash);
2750
hailfinger90fcf9b2010-11-05 14:51:59 +00002751out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002752 if (descriptor)
2753 free(descriptor);
2754
hailfinger90fcf9b2010-11-05 14:51:59 +00002755 free(oldcontents);
2756 free(newcontents);
2757out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002758 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002759 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002760 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002761 * tree. This is because some operations, such as write protection,
2762 * requires programmer_shutdown() but does not call doit().
2763 */
2764// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002765 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002766}