blob: 58b8e930c111b0270a3114edfc07eeb81526a0b1 [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 },
600#endif
601
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100602 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000603};
stepan927d4e22007-04-04 22:45:58 +0000604
David Hendricksbf36f092010-11-02 23:39:29 -0700605#define CHIP_RESTORE_MAXFN 4
606static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000607static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700608 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700609 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700610 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000611} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700612
David Hendricks668f29d2011-01-27 18:51:45 -0800613
hailfingerf31cbdc2010-11-10 15:25:18 +0000614#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000615static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000616/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000617static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700618 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000619 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000620} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000621/* Initialize to 0 to make sure nobody registers a shutdown function before
622 * programmer init.
623 */
624static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000625
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700626static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000627
hailfingerdc6f7972010-02-14 01:20:28 +0000628/* Register a function to be executed on programmer shutdown.
629 * The advantage over atexit() is that you can supply a void pointer which will
630 * be used as parameter to the registered function upon programmer shutdown.
631 * This pointer can point to arbitrary data used by said function, e.g. undo
632 * information for GPIO settings etc. If unneeded, set data=NULL.
633 * Please note that the first (void *data) belongs to the function signature of
634 * the function passed as first parameter.
635 */
David Hendricks93784b42016-08-09 17:00:38 -0700636int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000637{
638 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000639 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000640 SHUTDOWN_MAXFN);
641 return 1;
642 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000643 if (!may_register_shutdown) {
644 msg_perr("Tried to register a shutdown function before "
645 "programmer init.\n");
646 return 1;
647 }
hailfingerdc6f7972010-02-14 01:20:28 +0000648 shutdown_fn[shutdown_fn_count].func = function;
649 shutdown_fn[shutdown_fn_count].data = data;
650 shutdown_fn_count++;
651
652 return 0;
653}
654
David Hendricksbf36f092010-11-02 23:39:29 -0700655//int register_chip_restore(int (*function) (void *data), void *data)
656int register_chip_restore(CHIP_RESTORE_CALLBACK,
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700657 struct flashctx *flash, uint8_t status)
David Hendricksbf36f092010-11-02 23:39:29 -0700658{
659 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
660 msg_perr("Tried to register more than %i chip restore"
661 " functions.\n", CHIP_RESTORE_MAXFN);
662 return 1;
663 }
664 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
665 chip_restore_fn[chip_restore_fn_count].flash = flash;
666 chip_restore_fn[chip_restore_fn_count].status = status;
667 chip_restore_fn_count++;
668
669 return 0;
670}
671
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000672int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000673{
hailfinger1ef766d2010-07-06 09:55:48 +0000674 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000675
676 if (prog >= PROGRAMMER_INVALID) {
677 msg_perr("Invalid programmer specified!\n");
678 return -1;
679 }
680 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000681 /* Initialize all programmer specific data. */
682 /* Default to unlimited decode sizes. */
683 max_rom_decode = (const struct decode_sizes) {
684 .parallel = 0xffffffff,
685 .lpc = 0xffffffff,
686 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000687 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000688 };
David Hendricksac1d25c2016-08-09 17:00:58 -0700689 buses_supported = BUS_NONE;
hailfinger1ff33dc2010-07-03 11:02:10 +0000690 /* Default to top aligned flash at 4 GB. */
691 flashbase = 0;
692 /* Registering shutdown functions is now allowed. */
693 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000694 /* Default to allowing writes. Broken programmers set this to 0. */
695 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000696
697 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000698 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700699 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000700 if (programmer_param && strlen(programmer_param)) {
701 if (ret != 0) {
702 /* It is quite possible that any unhandled programmer parameter would have been valid,
703 * but an error in actual programmer init happened before the parameter was evaluated.
704 */
705 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
706 programmer_param);
707 } else {
708 /* Actual programmer init was successful, but the user specified an invalid or unusable
709 * (for the current programmer configuration) parameter.
710 */
711 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
712 msg_perr("Aborting.\n");
713 ret = ERROR_FATAL;
714 }
715 }
hailfinger1ef766d2010-07-06 09:55:48 +0000716 return ret;
uweabe92a52009-05-16 22:36:00 +0000717}
718
David Hendricksbf36f092010-11-02 23:39:29 -0700719int chip_restore()
720{
721 int rc = 0;
722
723 while (chip_restore_fn_count > 0) {
724 int i = --chip_restore_fn_count;
725 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
726 chip_restore_fn[i].status);
727 }
728
729 return rc;
730}
731
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000732/** Calls registered shutdown functions and resets internal programmer-related variables.
733 * Calling it is safe even without previous initialization, but further interactions with programmer support
734 * require a call to programmer_init() (afterwards).
735 *
736 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700737int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000738{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000739 int ret = 0;
740
hailfinger1ff33dc2010-07-03 11:02:10 +0000741 /* Registering shutdown functions is no longer allowed. */
742 may_register_shutdown = 0;
743 while (shutdown_fn_count > 0) {
744 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700745 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000746 }
Edward O'Callaghancf9c40f2020-10-19 20:02:39 +1100747
748 programmer_param = NULL;
749 registered_master_count = 0;
750
dhendrix0ffc2eb2011-06-14 01:35:36 +0000751 return ret;
uweabe92a52009-05-16 22:36:00 +0000752}
753
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000754void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000755{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000756 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
757 return ret;
uweabe92a52009-05-16 22:36:00 +0000758}
759
760void programmer_unmap_flash_region(void *virt_addr, size_t len)
761{
762 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000763 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000764}
765
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700766void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000767{
Craig Hesling65eb8812019-08-01 09:33:56 -0700768 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000769}
770
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700771void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000772{
Craig Hesling65eb8812019-08-01 09:33:56 -0700773 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000774}
775
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700776void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000777{
Craig Hesling65eb8812019-08-01 09:33:56 -0700778 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000779}
780
Stuart langleyc98e43f2020-03-26 20:27:36 +1100781void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000782{
Craig Hesling65eb8812019-08-01 09:33:56 -0700783 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000784}
785
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700786uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000787{
Craig Hesling65eb8812019-08-01 09:33:56 -0700788 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000789}
790
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700791uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000792{
Craig Hesling65eb8812019-08-01 09:33:56 -0700793 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000794}
795
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700796uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000797{
Craig Hesling65eb8812019-08-01 09:33:56 -0700798 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000799}
800
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000801void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
802 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000803{
Craig Hesling65eb8812019-08-01 09:33:56 -0700804 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000805}
806
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000807void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000808{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000809 if (usecs > 0)
810 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000811}
812
Edward O'Callaghana820b212020-09-17 22:53:26 +1000813int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
814 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000815{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700816 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000817
hailfinger23060112009-05-08 12:49:03 +0000818 return 0;
819}
820
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000821/* This is a somewhat hacked function similar in some ways to strtok().
822 * It will look for needle with a subsequent '=' in haystack, return a copy of
823 * needle and remove everything from the first occurrence of needle to the next
824 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000825 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000826char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000827{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000828 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000829 char *opt = NULL;
830 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000831 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000832
hailfingerf4aaccc2010-04-28 15:22:14 +0000833 needlelen = strlen(needle);
834 if (!needlelen) {
835 msg_gerr("%s: empty needle! Please report a bug at "
836 "flashrom@flashrom.org\n", __func__);
837 return NULL;
838 }
839 /* No programmer parameters given. */
840 if (*haystack == NULL)
841 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000842 param_pos = strstr(*haystack, needle);
843 do {
844 if (!param_pos)
845 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000846 /* Needle followed by '='? */
847 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000848 /* Beginning of the string? */
849 if (param_pos == *haystack)
850 break;
851 /* After a delimiter? */
852 if (strchr(delim, *(param_pos - 1)))
853 break;
854 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000855 /* Continue searching. */
856 param_pos++;
857 param_pos = strstr(param_pos, needle);
858 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000859
hailfinger6e5a52a2009-11-24 18:27:10 +0000860 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000861 /* Get the string after needle and '='. */
862 opt_pos = param_pos + needlelen + 1;
863 optlen = strcspn(opt_pos, delim);
864 /* Return an empty string if the parameter was empty. */
865 opt = malloc(optlen + 1);
866 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000867 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000868 exit(1);
869 }
hailfinger1ef766d2010-07-06 09:55:48 +0000870 strncpy(opt, opt_pos, optlen);
871 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000872 rest = opt_pos + optlen;
873 /* Skip all delimiters after the current parameter. */
874 rest += strspn(rest, delim);
875 memmove(param_pos, rest, strlen(rest) + 1);
876 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000877 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000878
hailfinger1ef766d2010-07-06 09:55:48 +0000879 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000880}
881
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000882char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000883{
884 return extract_param(&programmer_param, param_name, ",");
885}
886
stefancte1c5acf2011-07-04 07:27:17 +0000887/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700888static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000889{
890 unsigned int usable_erasefunctions = 0;
891 int k;
892 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
893 if (!check_block_eraser(flash, k, 0))
894 usable_erasefunctions++;
895 }
896 return usable_erasefunctions;
897}
898
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000899static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700900{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000901 int ret = 0, failcount = 0;
902 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700903 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000904 if (wantbuf[i] != havebuf[i]) {
905 /* Only print the first failure. */
906 if (!failcount++)
907 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
908 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700909 }
910 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000911 if (failcount) {
912 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
913 start, start + len - 1, failcount);
914 ret = -1;
915 }
916 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700917}
918
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000919/* start is an offset to the base address of the flash chip */
920static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
921{
922 int ret;
923 uint8_t *cmpbuf = malloc(len);
924 const uint8_t erased_value = ERASED_VALUE(flash);
925
926 if (!cmpbuf) {
927 msg_gerr("Could not allocate memory!\n");
928 exit(1);
929 }
930 memset(cmpbuf, erased_value, len);
931 ret = verify_range(flash, cmpbuf, start, len);
932 free(cmpbuf);
933 return ret;
934}
935
uwee15beb92010-08-08 17:01:18 +0000936/*
hailfinger7af3d192009-11-25 17:05:52 +0000937 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000938 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000939 * @start offset to the base address of the flash chip
940 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000941 * @return 0 for success, -1 for failure
942 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000943int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000944{
hailfinger7af83692009-06-15 17:23:36 +0000945 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000946 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000947
Patrick Georgif3fa2992017-02-02 16:24:44 +0100948 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000949 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000950 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000951 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000952
953 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000954 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000955 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000956 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000957 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000958 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000959
Patrick Georgif3fa2992017-02-02 16:24:44 +0100960 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000961 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000962 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100963 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000964 ret = -1;
965 goto out_free;
966 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700967 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700968 if (programmer_table[programmer].paranoid) {
969 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800970
Simon Glass4e305f42015-01-08 06:29:04 -0700971 /* limit chunksize in order to catch errors early */
972 for (i = 0, chunksize = 0; i < len; i += chunksize) {
973 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800974
Patrick Georgif3fa2992017-02-02 16:24:44 +0100975 chunksize = min(flash->chip->page_size, len - i);
976 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700977 if (tmp) {
978 ret = tmp;
979 if (ignore_error(tmp))
980 continue;
981 else
982 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800983 }
Simon Glass4e305f42015-01-08 06:29:04 -0700984
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700985 /*
986 * Check write access permission and do not compare chunks
987 * where flashrom does not have write access to the region.
988 */
989 if (flash->chip->check_access) {
990 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
991 if (tmp && ignore_error(tmp))
992 continue;
993 }
994
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000995 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700996 if (failcount)
997 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800998 }
Simon Glass4e305f42015-01-08 06:29:04 -0700999 } else {
1000 int tmp;
1001
1002 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +01001003 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -07001004 if (tmp && !ignore_error(tmp)) {
1005 ret = tmp;
1006 goto out_free;
1007 }
1008
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001009 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +00001010 }
1011
hailfinger5be6c0f2009-07-23 01:42:56 +00001012 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +00001013 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +00001014 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +00001015 ret = -1;
1016 }
hailfinger7af83692009-06-15 17:23:36 +00001017
1018out_free:
1019 free(readbuf);
1020 return ret;
1021}
1022
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001023/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1024static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001025 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001026{
1027 unsigned int i, j, limit;
1028 for (j = 0; j < len / gran; j++) {
1029 limit = min (gran, len - j * gran);
1030 /* Are 'have' and 'want' identical? */
1031 if (!memcmp(have + j * gran, want + j * gran, limit))
1032 continue;
1033 /* have needs to be in erased state. */
1034 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001035 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001036 return 1;
1037 }
1038 return 0;
1039}
1040
uwee15beb92010-08-08 17:01:18 +00001041/*
hailfingerb247c7a2010-03-08 00:42:32 +00001042 * Check if the buffer @have can be programmed to the content of @want without
1043 * erasing. This is only possible if all chunks of size @gran are either kept
1044 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001045 *
hailfingerb437e282010-11-04 01:04:27 +00001046 * Warning: This function assumes that @have and @want point to naturally
1047 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001048 *
1049 * @have buffer with current content
1050 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001051 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001052 * @gran write granularity (enum, not count)
1053 * @return 0 if no erase is needed, 1 otherwise
1054 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001055int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1056 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001057{
hailfingerb91c08c2011-08-15 19:54:20 +00001058 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001059 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001060
hailfingerb247c7a2010-03-08 00:42:32 +00001061 switch (gran) {
1062 case write_gran_1bit:
1063 for (i = 0; i < len; i++)
1064 if ((have[i] & want[i]) != want[i]) {
1065 result = 1;
1066 break;
1067 }
1068 break;
1069 case write_gran_1byte:
1070 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001071 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001072 result = 1;
1073 break;
1074 }
1075 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001076 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001077 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001078 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001079 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001080 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001081 break;
1082 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001083 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001084 break;
1085 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001086 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001087 break;
1088 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001089 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001090 break;
1091 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001092 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001093 break;
1094 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001095 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001096 break;
1097 case write_gran_1byte_implicit_erase:
1098 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1099 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001100 break;
hailfingerb437e282010-11-04 01:04:27 +00001101 default:
1102 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1103 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001104 }
1105 return result;
1106}
1107
hailfingerb437e282010-11-04 01:04:27 +00001108/**
1109 * Check if the buffer @have needs to be programmed to get the content of @want.
1110 * If yes, return 1 and fill in first_start with the start address of the
1111 * write operation and first_len with the length of the first to-be-written
1112 * chunk. If not, return 0 and leave first_start and first_len undefined.
1113 *
1114 * Warning: This function assumes that @have and @want point to naturally
1115 * aligned regions.
1116 *
1117 * @have buffer with current content
1118 * @want buffer with desired content
1119 * @len length of the checked area
1120 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001121 * @first_start offset of the first byte which needs to be written (passed in
1122 * value is increased by the offset of the first needed write
1123 * relative to have/want or unchanged if no write is needed)
1124 * @return length of the first contiguous area which needs to be written
1125 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001126 *
1127 * FIXME: This function needs a parameter which tells it about coalescing
1128 * in relation to the max write length of the programmer and the max write
1129 * length of the chip.
1130 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001131static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001132 unsigned int *first_start,
1133 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001134{
stefanctc5eb8a92011-11-23 09:13:48 +00001135 int need_write = 0;
1136 unsigned int rel_start = 0, first_len = 0;
1137 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001138
hailfingerb437e282010-11-04 01:04:27 +00001139 switch (gran) {
1140 case write_gran_1bit:
1141 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001142 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001143 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001144 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001145 case write_gran_128bytes:
1146 stride = 128;
1147 break;
hailfingerb437e282010-11-04 01:04:27 +00001148 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001149 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001150 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001151 case write_gran_264bytes:
1152 stride = 264;
1153 break;
1154 case write_gran_512bytes:
1155 stride = 512;
1156 break;
1157 case write_gran_528bytes:
1158 stride = 528;
1159 break;
1160 case write_gran_1024bytes:
1161 stride = 1024;
1162 break;
1163 case write_gran_1056bytes:
1164 stride = 1056;
1165 break;
hailfingerb437e282010-11-04 01:04:27 +00001166 default:
1167 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1168 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001169 /* Claim that no write was needed. A write with unknown
1170 * granularity is too dangerous to try.
1171 */
1172 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001173 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001174 for (i = 0; i < len / stride; i++) {
1175 limit = min(stride, len - i * stride);
1176 /* Are 'have' and 'want' identical? */
1177 if (memcmp(have + i * stride, want + i * stride, limit)) {
1178 if (!need_write) {
1179 /* First location where have and want differ. */
1180 need_write = 1;
1181 rel_start = i * stride;
1182 }
1183 } else {
1184 if (need_write) {
1185 /* First location where have and want
1186 * do not differ anymore.
1187 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001188 break;
1189 }
1190 }
1191 }
hailfingerffb7f382010-12-06 13:05:44 +00001192 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001193 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001194 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001195 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001196}
1197
hailfinger0c515352009-11-23 12:55:31 +00001198/* This function generates various test patterns useful for testing controller
1199 * and chip communication as well as chip behaviour.
1200 *
1201 * If a byte can be written multiple times, each time keeping 0-bits at 0
1202 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1203 * is essentially an AND operation. That's also the reason why this function
1204 * provides the result of AND between various patterns.
1205 *
1206 * Below is a list of patterns (and their block length).
1207 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1208 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1209 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1210 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1211 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1212 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1213 * Pattern 6 is 00 (1 Byte)
1214 * Pattern 7 is ff (1 Byte)
1215 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1216 * byte block.
1217 *
1218 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1219 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1220 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1221 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1222 * Pattern 12 is 00 (1 Byte)
1223 * Pattern 13 is ff (1 Byte)
1224 * Patterns 8-13 have no block number.
1225 *
1226 * Patterns 0-3 are created to detect and efficiently diagnose communication
1227 * slips like missed bits or bytes and their repetitive nature gives good visual
1228 * cues to the person inspecting the results. In addition, the following holds:
1229 * AND Pattern 0/1 == Pattern 4
1230 * AND Pattern 2/3 == Pattern 5
1231 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1232 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1233 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1234 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1235 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1236 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1237 * Besides that, they provide for bit testing of the last two bytes of every
1238 * 256 byte block which contains the block number for patterns 0-6.
1239 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1240 * block sizes >256 bytes (some Dataflash chips etc.)
1241 * AND Pattern 8/9 == Pattern 12
1242 * AND Pattern 10/11 == Pattern 12
1243 * Pattern 13 is the completely erased state.
1244 * None of the patterns can detect aliasing at boundaries which are a multiple
1245 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1246 */
1247int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1248{
1249 int i;
1250
1251 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001252 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001253 return 1;
1254 }
1255
1256 switch (variant) {
1257 case 0:
1258 for (i = 0; i < size; i++)
1259 buf[i] = (i & 0xf) << 4 | 0x5;
1260 break;
1261 case 1:
1262 for (i = 0; i < size; i++)
1263 buf[i] = (i & 0xf) << 4 | 0xa;
1264 break;
1265 case 2:
1266 for (i = 0; i < size; i++)
1267 buf[i] = 0x50 | (i & 0xf);
1268 break;
1269 case 3:
1270 for (i = 0; i < size; i++)
1271 buf[i] = 0xa0 | (i & 0xf);
1272 break;
1273 case 4:
1274 for (i = 0; i < size; i++)
1275 buf[i] = (i & 0xf) << 4;
1276 break;
1277 case 5:
1278 for (i = 0; i < size; i++)
1279 buf[i] = i & 0xf;
1280 break;
1281 case 6:
1282 memset(buf, 0x00, size);
1283 break;
1284 case 7:
1285 memset(buf, 0xff, size);
1286 break;
1287 case 8:
1288 for (i = 0; i < size; i++)
1289 buf[i] = i & 0xff;
1290 break;
1291 case 9:
1292 for (i = 0; i < size; i++)
1293 buf[i] = ~(i & 0xff);
1294 break;
1295 case 10:
1296 for (i = 0; i < size % 2; i++) {
1297 buf[i * 2] = (i >> 8) & 0xff;
1298 buf[i * 2 + 1] = i & 0xff;
1299 }
1300 if (size & 0x1)
1301 buf[i * 2] = (i >> 8) & 0xff;
1302 break;
1303 case 11:
1304 for (i = 0; i < size % 2; i++) {
1305 buf[i * 2] = ~((i >> 8) & 0xff);
1306 buf[i * 2 + 1] = ~(i & 0xff);
1307 }
1308 if (size & 0x1)
1309 buf[i * 2] = ~((i >> 8) & 0xff);
1310 break;
1311 case 12:
1312 memset(buf, 0x00, size);
1313 break;
1314 case 13:
1315 memset(buf, 0xff, size);
1316 break;
1317 }
1318
1319 if ((variant >= 0) && (variant <= 7)) {
1320 /* Write block number in the last two bytes of each 256-byte
1321 * block, big endian for easier reading of the hexdump.
1322 * Note that this wraps around for chips larger than 2^24 bytes
1323 * (16 MB).
1324 */
1325 for (i = 0; i < size / 256; i++) {
1326 buf[i * 256 + 254] = (i >> 8) & 0xff;
1327 buf[i * 256 + 255] = i & 0xff;
1328 }
1329 }
1330
1331 return 0;
1332}
1333
hailfingeraec9c962009-10-31 01:53:09 +00001334int check_max_decode(enum chipbustype buses, uint32_t size)
1335{
1336 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001337
1338 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001339 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001340 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001341 "size %u kB of chipset/board/programmer "
1342 "for %s interface, "
1343 "probe/read/erase/write may fail. ", size / 1024,
1344 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001345 }
hailfingere1e41ea2011-07-27 07:13:06 +00001346 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001347 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001348 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001349 "size %u kB of chipset/board/programmer "
1350 "for %s interface, "
1351 "probe/read/erase/write may fail. ", size / 1024,
1352 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001353 }
hailfingere1e41ea2011-07-27 07:13:06 +00001354 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001355 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001356 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001357 "size %u kB of chipset/board/programmer "
1358 "for %s interface, "
1359 "probe/read/erase/write may fail. ", size / 1024,
1360 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001361 }
hailfingere1e41ea2011-07-27 07:13:06 +00001362 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001363 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001364 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001365 "size %u kB of chipset/board/programmer "
1366 "for %s interface, "
1367 "probe/read/erase/write may fail. ", size / 1024,
1368 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001369 }
1370 if (!limitexceeded)
1371 return 0;
1372 /* Sometimes chip and programmer have more than one bus in common,
1373 * and the limit is not exceeded on all buses. Tell the user.
1374 */
1375 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001376 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001377 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001378 "interface which can support a chip of this size. "
1379 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001380 return 1;
1381}
1382
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001383void unmap_flash(struct flashctx *flash)
1384{
1385 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1386 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1387 flash->physical_registers = 0;
1388 flash->virtual_registers = (chipaddr)ERROR_PTR;
1389 }
1390
1391 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1392 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1393 flash->physical_memory = 0;
1394 flash->virtual_memory = (chipaddr)ERROR_PTR;
1395 }
1396}
1397
1398int map_flash(struct flashctx *flash)
1399{
1400 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1401 flash->virtual_memory = (chipaddr)ERROR_PTR;
1402 flash->virtual_registers = (chipaddr)ERROR_PTR;
1403
1404 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1405 * These are used for various probing-related hacks that would not map successfully anyway and should be
1406 * removed ASAP. */
1407 if (flash->chip->total_size == 0)
1408 return 0;
1409
1410 const chipsize_t size = flash->chip->total_size * 1024;
1411 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1412 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1413 if (addr == ERROR_PTR) {
1414 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1415 flash->chip->name, PRIxPTR_WIDTH, base);
1416 return 1;
1417 }
1418 flash->physical_memory = base;
1419 flash->virtual_memory = (chipaddr)addr;
1420
1421 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1422 * completely different on some chips and programmers, or not mappable at all.
1423 * Ignore these problems for now and always report success. */
1424 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1425 base = 0xffffffff - size - 0x400000 + 1;
1426 addr = programmer_map_flash_region("flash chip registers", base, size);
1427 if (addr == ERROR_PTR) {
1428 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1429 flash->chip->name, PRIxPTR_WIDTH, base);
1430 return 0;
1431 }
1432 flash->physical_registers = base;
1433 flash->virtual_registers = (chipaddr)addr;
1434 }
1435 return 0;
1436}
1437
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001438/*
1439 * Return a string corresponding to the bustype parameter.
1440 * Memory is obtained with malloc() and must be freed with free() by the caller.
1441 */
1442char *flashbuses_to_text(enum chipbustype bustype)
1443{
1444 char *ret = calloc(1, 1);
1445 /*
1446 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1447 * will cease to exist and should be eliminated here as well.
1448 */
1449 if (bustype == BUS_NONSPI) {
1450 ret = strcat_realloc(ret, "Non-SPI, ");
1451 } else {
1452 if (bustype & BUS_PARALLEL)
1453 ret = strcat_realloc(ret, "Parallel, ");
1454 if (bustype & BUS_LPC)
1455 ret = strcat_realloc(ret, "LPC, ");
1456 if (bustype & BUS_FWH)
1457 ret = strcat_realloc(ret, "FWH, ");
1458 if (bustype & BUS_SPI)
1459 ret = strcat_realloc(ret, "SPI, ");
1460 if (bustype & BUS_PROG)
1461 ret = strcat_realloc(ret, "Programmer-specific, ");
1462 if (bustype == BUS_NONE)
1463 ret = strcat_realloc(ret, "None, ");
1464 }
1465 /* Kill last comma. */
1466 ret[strlen(ret) - 2] = '\0';
1467 ret = realloc(ret, strlen(ret) + 1);
1468 return ret;
1469}
1470
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001471int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001472{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001473 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001474 uint32_t size;
1475 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001476 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001477
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301478 /* Based on the host controller interface that a platform
1479 * needs to use (hwseq or swseq),
1480 * set the flashchips list here.
1481 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001482 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301483 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001484 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301485 flash_list = flashchips_hwseq;
1486 break;
1487 default:
1488 flash_list = flashchips;
1489 break;
1490 }
1491
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001492 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1493 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001494 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001495 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001496 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001497 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001498 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001499 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001500 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001501 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001502 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001503 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001504 continue;
1505 }
stepan782fb172007-04-06 11:58:03 +00001506
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001507 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001508 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001509
hailfinger48ed3e22011-05-04 00:39:50 +00001510 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001511 flash->chip = calloc(1, sizeof(struct flashchip));
1512 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001513 msg_gerr("Out of memory!\n");
1514 exit(1);
1515 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001516 memcpy(flash->chip, chip, sizeof(struct flashchip));
1517 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001518
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001519 if (map_flash(flash) != 0)
1520 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001521
Edward O'Callaghana820b212020-09-17 22:53:26 +10001522 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1523 * is only called with force=1 after normal probing failed.
1524 */
stugec1e55fe2008-07-02 17:15:47 +00001525 if (force)
1526 break;
stepanc98b80b2006-03-16 16:57:41 +00001527
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001528 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001529 goto notfound;
1530
hailfinger48ed3e22011-05-04 00:39:50 +00001531 /* If this is the first chip found, accept it.
1532 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001533 * a non-generic match. SFDP and CFI are generic matches.
1534 * startchip==0 means this call to probe_flash() is the first
1535 * one for this programmer interface (master) and thus no other chip has
1536 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001537 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001538 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1539 msg_cinfo("===\n"
1540 "SFDP has autodetected a flash chip which is "
1541 "not natively supported by flashrom yet.\n");
1542 if (count_usable_erasers(flash) == 0)
1543 msg_cinfo("The standard operations read and "
1544 "verify should work, but to support "
1545 "erase, write and all other "
1546 "possible features");
1547 else
1548 msg_cinfo("All standard operations (read, "
1549 "verify, erase and write) should "
1550 "work, but to support all possible "
1551 "features");
1552
1553 msg_cinfo(" we need to add them manually.\n"
1554 "You can help us by mailing us the output of the following command to "
1555 "flashrom@flashrom.org:\n"
1556 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1557 "Thanks for your help!\n"
1558 "===\n");
1559 }
stugec1e55fe2008-07-02 17:15:47 +00001560
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001561 /* First flash chip detected on this bus. */
1562 if (startchip == 0)
1563 break;
1564 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001565 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001566 break;
1567 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001568notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001569 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001570 free(flash->chip);
1571 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001572 }
uwebe4477b2007-08-23 16:08:21 +00001573
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001574 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001575 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001576
stepan3e7aeae2011-01-19 06:21:54 +00001577
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001578 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001579 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1580 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001581 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001582#if CONFIG_INTERNAL == 1
1583 if (programmer_table[programmer].map_flash_region == physmap)
1584 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1585 PRIxPTR_WIDTH, flash->physical_memory);
1586 else
1587#endif
1588 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001589
Edward O'Callaghana820b212020-09-17 22:53:26 +10001590 /* Flash registers may more likely not be mapped if the chip was forced.
1591 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001592 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001593 if (flash->chip->printlock)
1594 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001595
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001596 /* Get out of the way for later runs. */
1597 unmap_flash(flash);
1598
hailfinger48ed3e22011-05-04 00:39:50 +00001599 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001600 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001601}
1602
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001603static int verify_flash(struct flashctx *flash,
1604 struct action_descriptor *descriptor,
1605 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001606{
hailfingerb0f4d122009-06-24 08:20:45 +00001607 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001608 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001609 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001610
snelsone42c3802010-05-07 20:09:04 +00001611 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001612
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001613 if (verify_it == VERIFY_PARTIAL) {
1614 struct processing_unit *pu = descriptor->processing_units;
1615
1616 /* Verify only areas which were written. */
1617 while (pu->num_blocks) {
1618 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001619 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001620 if (ret)
1621 break;
1622 pu++;
1623 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001624 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001625 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001626 }
uwef6641642007-05-09 10:17:44 +00001627
David Hendricks1ed1d352011-11-23 17:54:37 -08001628 if (ret == ACCESS_DENIED) {
1629 msg_gdbg("Could not fully verify due to access error, ");
1630 if (access_denied_action == error_ignore) {
1631 msg_gdbg("ignoring\n");
1632 ret = 0;
1633 } else {
1634 msg_gdbg("aborting\n");
1635 }
1636 }
1637
hailfingerb0f4d122009-06-24 08:20:45 +00001638 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001639 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001640
hailfingerb0f4d122009-06-24 08:20:45 +00001641 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001642}
1643
uwe8d342eb2011-07-28 08:13:25 +00001644int read_buf_from_file(unsigned char *buf, unsigned long size,
1645 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001646{
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001647 unsigned long numbytes;
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001648 FILE *image;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001649 struct stat image_stat;
1650
1651 if (!strncmp(filename, "-", sizeof("-")))
1652 image = fdopen(STDIN_FILENO, "rb");
1653 else
1654 image = fopen(filename, "rb");
1655 if (image == NULL) {
1656 perror(filename);
hailfinger771fc182010-10-15 00:01:14 +00001657 return 1;
1658 }
1659 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001660 perror(filename);
1661 fclose(image);
1662 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001663 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001664 if ((image_stat.st_size != size) &&
1665 (strncmp(filename, "-", sizeof("-")))) {
1666 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1667 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
1668 fclose(image);
1669 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001670 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001671 numbytes = fread(buf, 1, size, image);
1672 if (fclose(image)) {
1673 perror(filename);
1674 return 1;
1675 }
hailfinger771fc182010-10-15 00:01:14 +00001676 if (numbytes != size) {
1677 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1678 "wanted %ld!\n", numbytes, size);
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001679 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001680 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001681 return 0;
hailfinger771fc182010-10-15 00:01:14 +00001682}
1683
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001684int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001685{
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001686 unsigned long numbytes;
hailfingerd219a232009-01-28 00:27:54 +00001687 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001688
1689 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001690 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001691 return 1;
1692 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001693 if (!strncmp(filename, "-", sizeof("-")))
1694 image = fdopen(STDOUT_FILENO, "wb");
1695 else
1696 image = fopen(filename, "wb");
1697 if (image == NULL) {
1698 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001699 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001700 }
hailfingerd219a232009-01-28 00:27:54 +00001701
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001702 numbytes = fwrite(buf, 1, size, image);
1703 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001704 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001705 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001706 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001707 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001708 return 0;
hailfingerd219a232009-01-28 00:27:54 +00001709}
1710
David Hendrickse3451942013-03-21 17:23:29 -07001711/*
1712 * read_flash - wrapper for flash->read() with additional high-level policy
1713 *
1714 * @flash flash chip
1715 * @buf buffer to store data in
1716 * @start start address
1717 * @len number of bytes to read
1718 *
1719 * This wrapper simplifies most cases when the flash chip needs to be read
1720 * since policy decisions such as non-fatal error handling is centralized.
1721 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001722int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001723 unsigned int start, unsigned int len)
1724{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001725 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001726
Patrick Georgif3fa2992017-02-02 16:24:44 +01001727 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001728 return -1;
1729
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001730 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1731
Patrick Georgif3fa2992017-02-02 16:24:44 +01001732 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001733 if (ret) {
1734 if (ignore_error(ret)) {
1735 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1736 start, start + len - 1);
1737 ret = 0;
1738 } else {
1739 msg_gdbg("failed to read 0x%x-0x%x\n",
1740 start, start + len - 1);
1741 }
1742 }
1743
1744 return ret;
1745}
1746
David Hendricks7c8a1612013-04-26 19:14:44 -07001747/*
1748 * write_flash - wrapper for flash->write() with additional high-level policy
1749 *
1750 * @flash flash chip
1751 * @buf buffer to write to flash
1752 * @start start address in flash
1753 * @len number of bytes to write
1754 *
1755 * TODO: Look up regions that are write-protected and avoid attempt to write
1756 * to them at all.
1757 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001758int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001759 unsigned int start, unsigned int len)
1760{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001761 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001762 return -1;
1763
Patrick Georgif3fa2992017-02-02 16:24:44 +01001764 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001765}
1766
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001767int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001768{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001769 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001770 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001771 int ret = 0;
1772
1773 msg_cinfo("Reading flash... ");
1774 if (!buf) {
1775 msg_gerr("Memory allocation failed!\n");
1776 msg_cinfo("FAILED.\n");
1777 return 1;
1778 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001779
1780 /* To support partial read, fill buffer to all 0xFF at beginning to make
1781 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001782 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001783
Patrick Georgif3fa2992017-02-02 16:24:44 +01001784 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001785 msg_cerr("No read function available for this flash chip.\n");
1786 ret = 1;
1787 goto out_free;
1788 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001789
1790 /* First try to handle partial read case, rather than read the whole
1791 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001792 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001793 if (ret < 0) {
1794 msg_cerr("Partial read operation failed!\n");
1795 ret = 1;
1796 goto out_free;
1797 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001798 int num_regions = get_num_include_args();
1799
1800 if (ret != num_regions) {
1801 msg_cerr("Requested %d regions, but only read %d\n",
1802 num_regions, ret);
1803 ret = 1;
1804 goto out_free;
1805 }
1806
1807 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001808 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001809 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001810 msg_cerr("Read operation failed!\n");
1811 ret = 1;
1812 goto out_free;
1813 }
hailfinger42a850a2010-07-13 23:56:13 +00001814 }
1815
David Hendricksdf29a832013-06-28 14:33:51 -07001816 if (filename)
1817 ret = write_buf_to_file(buf, size, filename);
1818
hailfinger42a850a2010-07-13 23:56:13 +00001819out_free:
1820 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001821 if (ret)
1822 msg_cerr("FAILED.");
1823 else
1824 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001825 return ret;
1826}
1827
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001828/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001829static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001830{
hailfingerb91c08c2011-08-15 19:54:20 +00001831 int i, j, k;
1832 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001833
1834 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1835 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001836 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001837
1838 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1839 /* Blocks with zero size are bugs in flashchips.c. */
1840 if (eraser.eraseblocks[i].count &&
1841 !eraser.eraseblocks[i].size) {
1842 msg_gerr("ERROR: Flash chip %s erase function "
1843 "%i region %i has size 0. Please report"
1844 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001845 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001846 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001847 }
1848 /* Blocks with zero count are bugs in flashchips.c. */
1849 if (!eraser.eraseblocks[i].count &&
1850 eraser.eraseblocks[i].size) {
1851 msg_gerr("ERROR: Flash chip %s erase function "
1852 "%i region %i has count 0. Please report"
1853 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001854 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001855 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001856 }
1857 done += eraser.eraseblocks[i].count *
1858 eraser.eraseblocks[i].size;
1859 }
hailfinger9fed35d2010-01-19 06:42:46 +00001860 /* Empty eraseblock definition with erase function. */
1861 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001862 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001863 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001864 if (!done)
1865 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001866 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001867 msg_gerr("ERROR: Flash chip %s erase function %i "
1868 "region walking resulted in 0x%06x bytes total,"
1869 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001870 " flashrom@flashrom.org\n", chip->name, k,
1871 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001872 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001873 }
hailfinger9fed35d2010-01-19 06:42:46 +00001874 if (!eraser.block_erase)
1875 continue;
1876 /* Check if there are identical erase functions for different
1877 * layouts. That would imply "magic" erase functions. The
1878 * easiest way to check this is with function pointers.
1879 */
uwef6f94d42010-03-13 17:28:29 +00001880 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001881 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001882 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001883 msg_gerr("ERROR: Flash chip %s erase function "
1884 "%i and %i are identical. Please report"
1885 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001886 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001887 ret = 1;
1888 }
uwef6f94d42010-03-13 17:28:29 +00001889 }
hailfinger45177872010-01-18 08:14:43 +00001890 }
hailfinger9fed35d2010-01-19 06:42:46 +00001891 return ret;
hailfinger45177872010-01-18 08:14:43 +00001892}
1893
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001894static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001895 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001896 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001897 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001898 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001899 unsigned int addr,
1900 unsigned int len))
1901{
stefanctc5eb8a92011-11-23 09:13:48 +00001902 unsigned int starthere = 0, lenhere = 0;
1903 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001904 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001905 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001906
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001907 /*
1908 * curcontents and newcontents are opaque to walk_eraseregions, and
1909 * need to be adjusted here to keep the impression of proper
1910 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001911 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001912
hailfinger90fcf9b2010-11-05 14:51:59 +00001913 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001914
hailfingerb437e282010-11-04 01:04:27 +00001915 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001916
hailfingerb437e282010-11-04 01:04:27 +00001917 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001918 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001919 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001920 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001921 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001922 if (ret) {
1923 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001924 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001925 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001926 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001927 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001928 }
1929
David Hendricks0954ffc2015-11-13 15:15:44 -08001930 if (programmer_table[programmer].paranoid) {
1931 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001932 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001933 return -1;
1934 }
hailfingerac8e3182011-06-26 17:04:16 +00001935 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001936
hailfinger90fcf9b2010-11-05 14:51:59 +00001937 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001938 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001939 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001940 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001941 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001942 /* get_next_write() sets starthere to a new value after the call. */
1943 while ((lenhere = get_next_write(curcontents + starthere,
1944 newcontents + starthere,
1945 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001946 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001947 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001948 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001949 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001950 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001951 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001952 if (ret) {
1953 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001954 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001955 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001956 }
David Hendricks048b38c2016-03-28 18:47:06 -07001957
1958 /*
1959 * If the block needed to be erased and was erased successfully
1960 * then we can assume that we didn't run into any write-
1961 * protected areas. Otherwise, we need to verify each page to
1962 * ensure it was successfully written and abort if we encounter
1963 * any errors.
1964 */
1965 if (programmer_table[programmer].paranoid && !block_was_erased) {
1966 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001967 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001968 return -1;
1969 }
1970
hailfingerb437e282010-11-04 01:04:27 +00001971 starthere += lenhere;
1972 skip = 0;
1973 }
1974 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001975 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001976 return ret;
1977}
1978
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001979/*
1980 * Function to process processing units accumulated in the action descriptor.
1981 *
1982 * @flash pointer to the flash context to operate on
1983 * @do_something helper function which can erase and program a section of the
1984 * flash chip. It receives the flash context, offset and length
1985 * of the area to erase/program, before and after contents (to
1986 * decide what exactly needs to be erased and or programmed)
1987 * and a pointer to the erase function which can operate on the
1988 * proper granularity.
1989 * @descriptor action descriptor including pointers to before and after
1990 * contents and an array of processing actions to take.
1991 *
1992 * Returns zero on success or an error code.
1993 */
1994static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001995 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001996 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001997 unsigned int len,
1998 uint8_t *param1,
1999 uint8_t *param2,
2000 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002001 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00002002 unsigned int addr,
2003 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002004 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00002005{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002006 struct processing_unit *pu;
2007 int rc = 0;
2008 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00002009
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002010 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
2011 unsigned base = pu->offset;
2012 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07002013
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002014 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07002015
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002016 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00002017 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002018 else
2019 print_comma = 1;
2020
2021 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
2022
2023 rc = do_something(flash, base,
2024 pu->block_size,
2025 descriptor->oldcontents,
2026 descriptor->newcontents,
2027 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
2028
David Hendricks1ed1d352011-11-23 17:54:37 -08002029 if (rc) {
2030 if (ignore_error(rc))
2031 rc = 0;
2032 else
2033 return rc;
hailfingerb437e282010-11-04 01:04:27 +00002034 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002035 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00002036 }
2037 }
hailfingerb437e282010-11-04 01:04:27 +00002038 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08002039 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00002040}
2041
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002042static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00002043{
Patrick Georgif3fa2992017-02-02 16:24:44 +01002044 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00002045
2046 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
2047 if (log)
2048 msg_cdbg("not defined. ");
2049 return 1;
2050 }
2051 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
2052 if (log)
2053 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00002054 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00002055 return 1;
2056 }
2057 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
2058 if (log)
2059 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00002060 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00002061 return 1;
2062 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002063 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002064 return 0;
2065}
2066
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002067int erase_and_write_flash(struct flashctx *flash,
2068 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002069{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002070 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002071
hailfingercf848f12010-12-05 15:14:44 +00002072 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002073
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002074 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002075
hailfinger7df21362009-09-05 02:30:58 +00002076 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002077 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002078 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002079 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002080 }
2081 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002082}
2083
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002084static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002085{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002086 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2087#if CONFIG_INTERNAL == 1
2088 if (programmer == PROGRAMMER_INTERNAL)
2089 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2090 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2091 "mail flashrom@flashrom.org, thanks!\n"
2092 "-------------------------------------------------------------------------------\n"
2093 "You may now reboot or simply leave the machine running.\n");
2094 else
2095#endif
2096 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2097 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2098 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2099 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002100}
2101
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002102static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002103{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002104 msg_gerr("Your flash chip is in an unknown state.\n");
2105#if CONFIG_INTERNAL == 1
2106 if (programmer == PROGRAMMER_INTERNAL)
2107 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2108 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2109 "-------------------------------------------------------------------------------\n"
2110 "DO NOT REBOOT OR POWEROFF!\n");
2111 else
2112#endif
2113 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2114 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002115}
2116
hailfingerf79d1712010-10-06 23:48:34 +00002117void list_programmers_linebreak(int startcol, int cols, int paren)
2118{
2119 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002120 int pnamelen;
2121 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002122 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002123 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002124
2125 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2126 pname = programmer_table[p].name;
2127 pnamelen = strlen(pname);
2128 if (remaining - pnamelen - 2 < 0) {
2129 if (firstline)
2130 firstline = 0;
2131 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002132 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002133 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002134 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002135 remaining = cols - startcol;
2136 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002137 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002138 remaining--;
2139 }
2140 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002141 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002142 remaining--;
2143 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002144 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002145 remaining -= pnamelen;
2146 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002147 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002148 remaining--;
2149 } else {
2150 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002151 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002152 }
2153 }
2154}
2155
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002156static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002157{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002158#if IS_WINDOWS
2159 SYSTEM_INFO si;
2160 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002161
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002162 memset(&si, 0, sizeof(SYSTEM_INFO));
2163 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2164 msg_ginfo(" on Windows");
2165 /* Tell Windows which version of the structure we want. */
2166 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2167 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2168 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2169 else
2170 msg_ginfo(" unknown version");
2171 GetSystemInfo(&si);
2172 switch (si.wProcessorArchitecture) {
2173 case PROCESSOR_ARCHITECTURE_AMD64:
2174 msg_ginfo(" (x86_64)");
2175 break;
2176 case PROCESSOR_ARCHITECTURE_INTEL:
2177 msg_ginfo(" (x86)");
2178 break;
2179 default:
2180 msg_ginfo(" (unknown arch)");
2181 break;
2182 }
2183#elif HAVE_UTSNAME == 1
2184 struct utsname osinfo;
2185
2186 uname(&osinfo);
2187 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002188 osinfo.machine);
2189#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002190 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002191#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002192}
2193
2194void print_buildinfo(void)
2195{
2196 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002197#if NEED_PCI == 1
2198#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002199 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002200#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002201 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002202#endif
2203#endif
2204#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002205 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002206#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002207 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002208#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002209 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002210#endif
hailfinger3b471632010-03-27 16:36:40 +00002211#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002212 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002213#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002214 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002215#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002216 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002217#endif
2218#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002219 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002220#endif
2221#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002222 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00002223#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002224 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00002225#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002226 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002227}
2228
uwefdeca092008-01-21 15:24:22 +00002229void print_version(void)
2230{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002231 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002232 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002233 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002234}
2235
hailfinger74819ad2010-05-15 15:04:37 +00002236void print_banner(void)
2237{
2238 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002239 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002240 msg_ginfo("\n");
2241}
2242
hailfingerc77acb52009-12-24 02:15:55 +00002243int selfcheck(void)
2244{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002245 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002246 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002247
2248 /* Safety check. Instead of aborting after the first error, check
2249 * if more errors exist.
2250 */
hailfingerc77acb52009-12-24 02:15:55 +00002251 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002252 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002253 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002254 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002255 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2256 const struct programmer_entry p = programmer_table[i];
2257 if (p.name == NULL) {
2258 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2259 ret = 1;
2260 /* This might hide other problems with this programmer, but allows for better error
2261 * messages below without jumping through hoops. */
2262 continue;
2263 }
2264 switch (p.type) {
2265 case USB:
2266 case PCI:
2267 case OTHER:
2268 if (p.devs.note == NULL) {
2269 if (strcmp("internal", p.name) == 0)
2270 break; /* This one has its device list stored separately. */
2271 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2272 p.name);
2273 ret = 1;
2274 }
2275 break;
2276 default:
2277 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2278 ret = 1;
2279 break;
2280 }
2281 if (p.init == NULL) {
2282 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2283 ret = 1;
2284 }
2285 if (p.delay == NULL) {
2286 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2287 ret = 1;
2288 }
2289 if (p.map_flash_region == NULL) {
2290 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2291 ret = 1;
2292 }
2293 if (p.unmap_flash_region == NULL) {
2294 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2295 ret = 1;
2296 }
2297 }
2298
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002299 /* It would be favorable if we could check for the correct layout (especially termination) of various
2300 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2301 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2302 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2303 * 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 +10002304 * checks below. */
2305 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002306 msg_gerr("Flashchips table miscompilation!\n");
2307 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002308 } else {
2309 for (i = 0; i < flashchips_size - 1; i++) {
2310 const struct flashchip *chip = &flashchips[i];
2311 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2312 ret = 1;
2313 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2314 "Please report a bug at flashrom@flashrom.org\n", i,
2315 chip->name == NULL ? "unnamed" : chip->name);
2316 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002317 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002318 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002319 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002320 }
stefanct6d836ba2011-05-26 01:35:19 +00002321 }
stefanct6d836ba2011-05-26 01:35:19 +00002322
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002323 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002324 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002325}
2326
hailfinger771fc182010-10-15 00:01:14 +00002327/* FIXME: This function signature needs to be improved once doit() has a better
2328 * function signature.
2329 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002330static int chip_safety_check(const struct flashctx *flash, int force,
2331 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002332{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002333 const struct flashchip *chip = flash->chip;
2334
hailfinger771fc182010-10-15 00:01:14 +00002335 if (!programmer_may_write && (write_it || erase_it)) {
2336 msg_perr("Write/erase is not working yet on your programmer in "
2337 "its current configuration.\n");
2338 /* --force is the wrong approach, but it's the best we can do
2339 * until the generic programmer parameter parser is merged.
2340 */
2341 if (!force)
2342 return 1;
2343 msg_cerr("Continuing anyway.\n");
2344 }
2345
2346 if (read_it || erase_it || write_it || verify_it) {
2347 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002348 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002349 msg_cerr("Read is not working on this chip. ");
2350 if (!force)
2351 return 1;
2352 msg_cerr("Continuing anyway.\n");
2353 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002354 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002355 msg_cerr("flashrom has no read function for this "
2356 "flash chip.\n");
2357 return 1;
2358 }
2359 }
2360 if (erase_it || write_it) {
2361 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002362 if (chip->tested.erase == NA) {
2363 msg_cerr("Erase is not possible on this chip.\n");
2364 return 1;
2365 }
2366 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002367 msg_cerr("Erase is not working on this chip. ");
2368 if (!force)
2369 return 1;
2370 msg_cerr("Continuing anyway.\n");
2371 }
stefancte1c5acf2011-07-04 07:27:17 +00002372 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002373 msg_cerr("flashrom has no erase function for this "
2374 "flash chip.\n");
2375 return 1;
2376 }
hailfinger771fc182010-10-15 00:01:14 +00002377 }
2378 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002379 if (chip->tested.write == NA) {
2380 msg_cerr("Write is not possible on this chip.\n");
2381 return 1;
2382 }
2383 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002384 msg_cerr("Write is not working on this chip. ");
2385 if (!force)
2386 return 1;
2387 msg_cerr("Continuing anyway.\n");
2388 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002389 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002390 msg_cerr("flashrom has no write function for this "
2391 "flash chip.\n");
2392 return 1;
2393 }
2394 }
2395 return 0;
2396}
2397
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002398int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002399 const bool read_it, const bool write_it,
2400 const bool erase_it, const bool verify_it)
2401{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002402 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002403 msg_cerr("Aborting.\n");
2404 return 1;
2405 }
2406
2407 if (normalize_romentries(flash)) {
2408 msg_cerr("Requested regions can not be handled. Aborting.\n");
2409 return 1;
2410 }
2411
Edward O'Callaghan40092972020-10-20 11:50:48 +11002412 /*
2413 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2414 * can be repro'ed with upstream on Volteer.
2415 *
2416 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2417 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2418 * hooked and this can fail on some board topologies. Checking the return value can
2419 * cause board rw failures by bailing early. Avoid the early bail for now until a
2420 * full investigation can reveal the proper fix. This restores previous behaviour of
2421 * assuming a map went fine.
2422 */
2423#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002424 if (map_flash(flash) != 0)
2425 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002426#endif
2427 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002428
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002429 /* Given the existence of read locks, we want to unlock for read,
2430 erase and write. */
2431 if (flash->chip->unlock)
2432 flash->chip->unlock(flash);
2433
2434 flash->address_high_byte = -1;
2435 flash->in_4ba_mode = false;
2436
Edward O'Callaghan99974452020-10-13 13:28:33 +11002437 /* Be careful about 4BA chips and broken masters */
2438 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2439 /* If we can't use native instructions, bail out */
2440 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2441 || !spi_master_4ba(flash)) {
2442 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2443 return 1;
2444 }
2445 }
2446
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002447 /* Enable/disable 4-byte addressing mode if flash chip supports it */
Edward O'Callaghan99974452020-10-13 13:28:33 +11002448 if (flash->chip->feature_bits & (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_ENTER_EAR7)) {
2449 int ret;
2450 if (spi_master_4ba(flash))
2451 ret = spi_enter_4ba(flash);
2452 else
2453 ret = spi_exit_4ba(flash);
2454 if (ret) {
2455 msg_cerr("Failed to set correct 4BA mode! Aborting.\n");
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002456 return 1;
2457 }
2458 }
2459
2460 return 0;
2461}
2462
Edward O'Callaghana820b212020-09-17 22:53:26 +10002463void finalize_flash_access(struct flashctx *const flash)
2464{
2465 unmap_flash(flash);
2466}
2467
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002468/*
2469 * Function to erase entire flash chip.
2470 *
2471 * @flashctx pointer to the flash context to use
2472 * @oldcontents pointer to the buffer including current chip contents, to
2473 * decide which areas do in fact need to be erased
2474 * @size the size of the flash chip, in bytes.
2475 *
2476 * Returns zero on success or an error code.
2477 */
2478static int erase_chip(struct flashctx *flash, void *oldcontents,
2479 void *newcontents, size_t size)
2480{
2481 /*
2482 * To make sure that the chip is fully erased, let's cheat and create
2483 * a descriptor where the new contents are all erased.
2484 */
2485 struct action_descriptor *fake_descriptor;
2486 int ret = 0;
2487
2488 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2489 newcontents, 1);
2490 /* FIXME: Do we really want the scary warning if erase failed? After
2491 * all, after erase the chip is either blank or partially blank or it
2492 * has the old contents. A blank chip won't boot, so if the user
2493 * wanted erase and reboots afterwards, the user knows very well that
2494 * booting won't work.
2495 */
2496 if (erase_and_write_flash(flash, fake_descriptor)) {
2497 emergency_help_message();
2498 ret = 1;
2499 }
2500
2501 free(fake_descriptor);
2502
2503 return ret;
2504}
2505
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002506static int read_dest_content(struct flashctx *flash, int verify_it,
2507 uint8_t *dest, unsigned long size)
2508{
2509 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2510 && get_num_include_args()) {
2511 /*
2512 * If no full verification is required and not
2513 * the entire chip is about to be programmed,
2514 * read only the areas which might change.
2515 */
2516 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2517 return 1;
2518 } else {
2519 if (read_flash(flash, dest, 0, size))
2520 return 1;
2521 }
2522 return 0;
2523}
2524
hailfingerc77acb52009-12-24 02:15:55 +00002525/* This function signature is horrible. We need to design a better interface,
2526 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002527 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002528 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002529int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002530 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002531 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002532{
hailfinger4c47e9d2010-10-19 22:06:20 +00002533 uint8_t *oldcontents;
2534 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002535 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002536 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002537 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002538
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002539 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002540 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002541 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002542
Simon Glass9ad06c12013-07-03 22:08:17 +09002543 if (extract_it) {
2544 ret = extract_regions(flash);
2545 goto out_nofree;
2546 }
2547
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002548 /* mark entries included using -i argument as "included" if they are
2549 found in the master rom_entries list */
2550 if (process_include_args() < 0) {
2551 ret = 1;
2552 goto out_nofree;
2553 }
2554
hailfinger771fc182010-10-15 00:01:14 +00002555 if (read_it) {
2556 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002557 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002558 }
hailfingerb437e282010-11-04 01:04:27 +00002559
stefanctd611e8f2011-07-12 22:35:21 +00002560 oldcontents = malloc(size);
2561 if (!oldcontents) {
2562 msg_gerr("Out of memory!\n");
2563 exit(1);
2564 }
Simon Glass4c214132013-07-16 10:09:28 -06002565 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002566 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002567 newcontents = malloc(size);
2568 if (!newcontents) {
2569 msg_gerr("Out of memory!\n");
2570 exit(1);
2571 }
Simon Glass4c214132013-07-16 10:09:28 -06002572 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002573 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002574 /* Side effect of the assumptions above: Default write action is erase
2575 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002576 * oldcontents being completely unerased means we have to erase
2577 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002578 */
2579
hailfingerd217d122010-10-08 18:52:29 +00002580 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002581 /*
2582 * Note: This must be done before any files specified by -i
2583 * arguments are processed merged into the newcontents since
2584 * -i files take priority. See http://crbug.com/263495.
2585 */
2586 if (filename) {
2587 if (read_buf_from_file(newcontents, size, filename)) {
2588 ret = 1;
2589 goto out;
2590 }
2591 } else {
2592 /* Content will be read from -i args, so they must
2593 * not overlap. */
2594 if (included_regions_overlap()) {
2595 msg_gerr("Error: Included regions must "
2596 "not overlap.\n");
2597 ret = 1;
2598 goto out;
2599 }
stepan1da96c02006-11-21 23:48:51 +00002600 }
ollie5672ac62004-03-17 22:22:08 +00002601 }
2602
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002603 if (do_diff) {
2604 /*
2605 * Obtain a reference image so that we can check whether
2606 * regions need to be erased and to give better diagnostics in
2607 * case write fails. If --fast-verify is used then only the
2608 * regions which are included using -i will be read.
2609 */
2610 if (diff_file) {
2611 msg_cdbg("Reading old contents from file... ");
2612 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002613 ret = 1;
2614 msg_cdbg("FAILED.\n");
2615 goto out;
2616 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002617 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002618 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002619 ret = read_dest_content(flash, verify_it,
2620 oldcontents, size);
2621 if (ret) {
2622 msg_cdbg("FAILED.\n");
2623 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002624 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002625 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002626 msg_cdbg("done.\n");
2627 } else if (!erase_it) {
2628 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002629 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002630 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002631
David Hendricksdf29a832013-06-28 14:33:51 -07002632 /*
2633 * Note: This must be done after reading the file specified for the
2634 * -w/-v argument, if any, so that files specified using -i end up
2635 * in the "newcontents" buffer before being written.
2636 * See http://crbug.com/263495.
2637 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002638 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002639 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002640 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002641 goto out;
2642 }
uwef6641642007-05-09 10:17:44 +00002643
David Hendricksa7e114b2016-02-26 18:49:15 -08002644 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002645 erase_chip(flash, oldcontents, newcontents, size);
2646 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002647 }
2648
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002649 descriptor = prepare_action_descriptor(flash, oldcontents,
2650 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002651 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002652 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002653 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002654 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002655 goto out;
2656 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002657
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002658 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002659 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2660 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002661 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002662 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002663 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002664 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002665 ret = 1;
2666 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002667 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002668 msg_cerr("Apparently at least some data has changed.\n");
2669 } else
2670 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002671 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002672 ret = 1;
2673 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002674 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002675
David Hendricksac1d25c2016-08-09 17:00:58 -07002676 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002677 if (ret < 0) {
2678 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002679 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002680 emergency_help_message();
2681 ret = 1;
2682 goto out;
2683 } else if (ret > 0) {
2684 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002685 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002686 ret = read_dest_content(flash, verify_it,
2687 oldcontents, size);
2688 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002689 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002690 goto out;
2691 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002692
2693 /* Get a new descriptor. */
2694 free(descriptor);
2695 descriptor = prepare_action_descriptor(flash,
2696 oldcontents,
2697 newcontents,
2698 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002699 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002700 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002701 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002702 emergency_help_message();
2703 ret = 1;
2704 goto out;
2705 }
2706 ret = 0;
2707 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002708
David Hendricksac1d25c2016-08-09 17:00:58 -07002709 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002710 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002711 emergency_help_message();
2712 ret = 1;
2713 goto out;
2714 }
stuge8ce3a3c2008-04-28 14:47:30 +00002715 }
ollie6a600992005-11-26 21:55:36 +00002716
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002717 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002718 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002719 if ((write_it || erase_it) && !content_has_changed) {
2720 msg_gdbg("Nothing was erased or written, skipping "
2721 "verification\n");
2722 } else {
2723 /* Work around chips which need some time to calm down. */
2724 if (write_it && verify_it != VERIFY_PARTIAL)
2725 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002726
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002727 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002728
David Hendricks9ba79fb2015-04-03 12:06:16 -07002729 /* If we tried to write, and verification now fails, we
2730 * might have an emergency situation.
2731 */
2732 if (ret && write_it)
2733 emergency_help_message();
2734 }
hailfinger0459e1c2009-08-19 13:55:34 +00002735 }
ollie6a600992005-11-26 21:55:36 +00002736
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002737 finalize_flash_access(flash);
2738
hailfinger90fcf9b2010-11-05 14:51:59 +00002739out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002740 if (descriptor)
2741 free(descriptor);
2742
hailfinger90fcf9b2010-11-05 14:51:59 +00002743 free(oldcontents);
2744 free(newcontents);
2745out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002746 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002747 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002748 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002749 * tree. This is because some operations, such as write protection,
2750 * requires programmer_shutdown() but does not call doit().
2751 */
2752// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002753 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002754}