blob: 6c89ea0f4aaf6fb154907849ecaca769c944684f [file] [log] [blame]
rminnich8d3ff912003-10-25 17:01:29 +00001/*
uweb25f1ea2007-08-29 17:52:32 +00002 * This file is part of the flashrom project.
rminnich8d3ff912003-10-25 17:01:29 +00003 *
uwe555dd972007-09-09 20:21:05 +00004 * Copyright (C) 2000 Silicon Integrated System Corporation
5 * Copyright (C) 2004 Tyan Corp <yhlu@tyan.com>
uwe4475e902009-05-19 14:14:21 +00006 * Copyright (C) 2005-2008 coresystems GmbH
hailfinger23060112009-05-08 12:49:03 +00007 * Copyright (C) 2008,2009 Carl-Daniel Hailfinger
Edward O'Callaghan0949b782019-11-10 23:23:20 +11008 * Copyright (C) 2016 secunet Security Networks AG
9 * (Written by Nico Huber <nico.huber@secunet.com> for secunet)
rminnich8d3ff912003-10-25 17:01:29 +000010 *
uweb25f1ea2007-08-29 17:52:32 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
rminnich8d3ff912003-10-25 17:01:29 +000015 *
uweb25f1ea2007-08-29 17:52:32 +000016 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
rminnich8d3ff912003-10-25 17:01:29 +000020 */
21
hailfingera83a5fe2010-05-30 22:24:40 +000022#include <stdio.h>
stepan1da96c02006-11-21 23:48:51 +000023#include <sys/types.h>
oxygene50275892010-09-30 17:03:32 +000024#ifndef __LIBPAYLOAD__
25#include <fcntl.h>
stepan1da96c02006-11-21 23:48:51 +000026#include <sys/stat.h>
oxygene50275892010-09-30 17:03:32 +000027#endif
rminnich8d3ff912003-10-25 17:01:29 +000028#include <string.h>
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +100029#include <unistd.h>
rminnich8d3ff912003-10-25 17:01:29 +000030#include <stdlib.h>
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +100031#include <errno.h>
hailfingerf76cc322010-11-09 22:00:31 +000032#include <ctype.h>
ollie6a600992005-11-26 21:55:36 +000033#include <getopt.h>
hailfinger3b471632010-03-27 16:36:40 +000034#if HAVE_UTSNAME == 1
35#include <sys/utsname.h>
36#endif
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -070037
38#include "action_descriptor.h"
rminnich8d3ff912003-10-25 17:01:29 +000039#include "flash.h"
hailfinger66966da2009-06-15 14:14:48 +000040#include "flashchips.h"
Simon Glass9ad06c12013-07-03 22:08:17 +090041#include "layout.h"
hailfinger428f6852010-07-27 22:41:39 +000042#include "programmer.h"
Duncan Laurie25a4ca22019-04-25 12:08:52 -070043#include "spi.h"
rminnich8d3ff912003-10-25 17:01:29 +000044
krause2eb76212011-01-17 07:50:42 +000045const char flashrom_version[] = FLASHROM_VERSION;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100046const char *chip_to_probe = NULL;
hailfinger80422e22009-12-13 22:28:00 +000047
David Hendricks9ba79fb2015-04-03 12:06:16 -070048/* Set if any erase/write operation is to be done. This will be used to
49 * decide if final verification is needed. */
50static int content_has_changed = 0;
51
David Hendricks1ed1d352011-11-23 17:54:37 -080052/* error handling stuff */
53enum error_action access_denied_action = error_ignore;
54
55int ignore_error(int err) {
56 int rc = 0;
57
58 switch(err) {
59 case ACCESS_DENIED:
60 if (access_denied_action == error_ignore)
61 rc = 1;
62 break;
63 default:
64 break;
65 }
66
67 return rc;
68}
69
hailfinger969e2f32011-09-08 00:00:29 +000070static enum programmer programmer = PROGRAMMER_INVALID;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100071static const char *programmer_param = NULL;
stepan782fb172007-04-06 11:58:03 +000072
David Hendricksac1d25c2016-08-09 17:00:58 -070073/* Supported buses for the current programmer. */
74enum chipbustype buses_supported;
75
uwee15beb92010-08-08 17:01:18 +000076/*
hailfinger80422e22009-12-13 22:28:00 +000077 * Programmers supporting multiple buses can have differing size limits on
78 * each bus. Store the limits for each bus in a common struct.
79 */
hailfinger1ff33dc2010-07-03 11:02:10 +000080struct decode_sizes max_rom_decode;
81
82/* If nonzero, used as the start address of bottom-aligned flash. */
83unsigned long flashbase;
hailfinger80422e22009-12-13 22:28:00 +000084
hailfinger5828baf2010-07-03 12:14:25 +000085/* Is writing allowed with this programmer? */
86int programmer_may_write;
87
hailfingerabe249e2009-05-08 17:43:22 +000088const struct programmer_entry programmer_table[] = {
hailfinger90c7d542010-05-31 15:27:27 +000089#if CONFIG_INTERNAL == 1
hailfingerabe249e2009-05-08 17:43:22 +000090 {
hailfinger3548a9a2009-08-12 14:34:35 +000091 .name = "internal",
Edward O'Callaghan0949b782019-11-10 23:23:20 +110092 .type = OTHER,
93 .devs.note = NULL,
hailfinger6c69ab02009-05-11 15:46:43 +000094 .init = internal_init,
hailfinger11ae3c42009-05-11 14:13:25 +000095 .map_flash_region = physmap,
96 .unmap_flash_region = physunmap,
hailfingere5829f62009-06-05 17:48:08 +000097 .delay = internal_delay,
David Hendricks55cdd9c2015-11-25 14:37:26 -080098
99 /*
100 * "Internal" implies in-system programming on a live system, so
101 * handle with paranoia to catch errors early. If something goes
102 * wrong then hopefully the system will still be recoverable.
103 */
104 .paranoid = 1,
hailfingerabe249e2009-05-08 17:43:22 +0000105 },
hailfinger80422e22009-12-13 22:28:00 +0000106#endif
stepan927d4e22007-04-04 22:45:58 +0000107
hailfinger90c7d542010-05-31 15:27:27 +0000108#if CONFIG_DUMMY == 1
hailfingera9df33c2009-05-09 00:54:55 +0000109 {
hailfinger3548a9a2009-08-12 14:34:35 +0000110 .name = "dummy",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100111 .type = OTHER,
112 /* FIXME */
113 .devs.note = "Dummy device, does nothing and logs all accesses\n",
hailfinger6c69ab02009-05-11 15:46:43 +0000114 .init = dummy_init,
hailfinger11ae3c42009-05-11 14:13:25 +0000115 .map_flash_region = dummy_map,
116 .unmap_flash_region = dummy_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000117 .delay = internal_delay,
hailfingera9df33c2009-05-09 00:54:55 +0000118 },
hailfinger571a6b32009-09-16 10:09:21 +0000119#endif
hailfingera9df33c2009-05-09 00:54:55 +0000120
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000121#if CONFIG_MEC1308 == 1
122 {
123 .name = "mec1308",
124 .type = OTHER,
125 .devs.note = "Microchip MEC1308 Embedded Controller.\n",
126 .init = mec1308_init,
127 .map_flash_region = fallback_map,
128 .unmap_flash_region = fallback_unmap,
129 .delay = internal_delay,
130 },
131#endif
132
hailfinger90c7d542010-05-31 15:27:27 +0000133#if CONFIG_NIC3COM == 1
uwe0f5a3a22009-05-13 11:36:06 +0000134 {
hailfinger3548a9a2009-08-12 14:34:35 +0000135 .name = "nic3com",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100136 .type = PCI,
137 .devs.dev = nics_3com,
uwe0f5a3a22009-05-13 11:36:06 +0000138 .init = nic3com_init,
uwe3e656bd2009-05-17 23:12:17 +0000139 .map_flash_region = fallback_map,
140 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000141 .delay = internal_delay,
uwe0f5a3a22009-05-13 11:36:06 +0000142 },
hailfinger571a6b32009-09-16 10:09:21 +0000143#endif
uwe0f5a3a22009-05-13 11:36:06 +0000144
hailfinger90c7d542010-05-31 15:27:27 +0000145#if CONFIG_NICREALTEK == 1
hailfinger5aa36982010-05-21 21:54:07 +0000146 {
hailfinger0d703d42011-03-07 01:08:09 +0000147 /* This programmer works for Realtek RTL8139 and SMC 1211. */
uwe8d342eb2011-07-28 08:13:25 +0000148 .name = "nicrealtek",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100149 .type = PCI,
150 .devs.dev = nics_realtek,
uwe8d342eb2011-07-28 08:13:25 +0000151 .init = nicrealtek_init,
152 .map_flash_region = fallback_map,
153 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000154 .delay = internal_delay,
hailfinger5aa36982010-05-21 21:54:07 +0000155 },
hailfinger5aa36982010-05-21 21:54:07 +0000156#endif
157
hailfingerf0a368f2010-06-07 22:37:54 +0000158#if CONFIG_NICNATSEMI == 1
159 {
uwe8d342eb2011-07-28 08:13:25 +0000160 .name = "nicnatsemi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100161 .type = PCI,
162 .devs.dev = nics_natsemi,
uwe8d342eb2011-07-28 08:13:25 +0000163 .init = nicnatsemi_init,
164 .map_flash_region = fallback_map,
165 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000166 .delay = internal_delay,
hailfingerf0a368f2010-06-07 22:37:54 +0000167 },
168#endif
hailfinger5aa36982010-05-21 21:54:07 +0000169
hailfinger90c7d542010-05-31 15:27:27 +0000170#if CONFIG_GFXNVIDIA == 1
uweff4576d2009-09-30 18:29:55 +0000171 {
172 .name = "gfxnvidia",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100173 .type = PCI,
174 .devs.dev = gfx_nvidia,
uweff4576d2009-09-30 18:29:55 +0000175 .init = gfxnvidia_init,
uweff4576d2009-09-30 18:29:55 +0000176 .map_flash_region = fallback_map,
177 .unmap_flash_region = fallback_unmap,
uweff4576d2009-09-30 18:29:55 +0000178 .delay = internal_delay,
179 },
180#endif
181
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000182#if CONFIG_RAIDEN_DEBUG_SPI == 1
183 {
184 .name = "raiden_debug_spi",
185 .type = USB,
186 .devs.dev = devs_raiden,
187 .init = raiden_debug_spi_init,
188 .map_flash_region = fallback_map,
189 .unmap_flash_region = fallback_unmap,
190 .delay = internal_delay,
191 },
192#endif
193
hailfinger90c7d542010-05-31 15:27:27 +0000194#if CONFIG_DRKAISER == 1
ruikda922a12009-05-17 19:39:27 +0000195 {
uwee2f95ef2009-09-02 23:00:46 +0000196 .name = "drkaiser",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100197 .type = PCI,
198 .devs.dev = drkaiser_pcidev,
uwee2f95ef2009-09-02 23:00:46 +0000199 .init = drkaiser_init,
uwee2f95ef2009-09-02 23:00:46 +0000200 .map_flash_region = fallback_map,
201 .unmap_flash_region = fallback_unmap,
uwee2f95ef2009-09-02 23:00:46 +0000202 .delay = internal_delay,
203 },
hailfinger571a6b32009-09-16 10:09:21 +0000204#endif
uwee2f95ef2009-09-02 23:00:46 +0000205
hailfinger90c7d542010-05-31 15:27:27 +0000206#if CONFIG_SATASII == 1
uwee2f95ef2009-09-02 23:00:46 +0000207 {
hailfinger3548a9a2009-08-12 14:34:35 +0000208 .name = "satasii",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100209 .type = PCI,
210 .devs.dev = satas_sii,
ruikda922a12009-05-17 19:39:27 +0000211 .init = satasii_init,
uwe3e656bd2009-05-17 23:12:17 +0000212 .map_flash_region = fallback_map,
213 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000214 .delay = internal_delay,
ruikda922a12009-05-17 19:39:27 +0000215 },
hailfinger571a6b32009-09-16 10:09:21 +0000216#endif
ruikda922a12009-05-17 19:39:27 +0000217
hailfinger90c7d542010-05-31 15:27:27 +0000218#if CONFIG_ATAHPT == 1
uwe7e627c82010-02-21 21:17:00 +0000219 {
220 .name = "atahpt",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100221 .type = PCI,
222 .devs.dev = ata_hpt,
uwe7e627c82010-02-21 21:17:00 +0000223 .init = atahpt_init,
uwe7e627c82010-02-21 21:17:00 +0000224 .map_flash_region = fallback_map,
225 .unmap_flash_region = fallback_unmap,
uwe7e627c82010-02-21 21:17:00 +0000226 .delay = internal_delay,
227 },
228#endif
229
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000230#if CONFIG_ATAVIA == 1
231 {
232 .name = "atavia",
233 .type = PCI,
234 .devs.dev = ata_via,
235 .init = atavia_init,
236 .map_flash_region = atavia_map,
237 .unmap_flash_region = fallback_unmap,
238 .delay = internal_delay,
239 },
240#endif
241
242#if CONFIG_ATAPROMISE == 1
243 {
244 .name = "atapromise",
245 .type = PCI,
246 .devs.dev = ata_promise,
247 .init = atapromise_init,
248 .map_flash_region = atapromise_map,
249 .unmap_flash_region = fallback_unmap,
250 .delay = internal_delay,
251 },
252#endif
253
254#if CONFIG_IT8212 == 1
255 {
256 .name = "it8212",
257 .type = PCI,
258 .devs.dev = devs_it8212,
259 .init = it8212_init,
260 .map_flash_region = fallback_map,
261 .unmap_flash_region = fallback_unmap,
262 .delay = internal_delay,
263 },
264#endif
265
hailfinger90c7d542010-05-31 15:27:27 +0000266#if CONFIG_FT2232_SPI == 1
hailfingerf31da3d2009-06-16 21:08:06 +0000267 {
hailfinger90c7d542010-05-31 15:27:27 +0000268 .name = "ft2232_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100269 .type = USB,
Nikolai Artemievc347a852020-04-29 12:17:08 +1000270 .devs.dev = devs_ft2232spi,
hailfingerf31da3d2009-06-16 21:08:06 +0000271 .init = ft2232_spi_init,
hailfinger6fe23d62009-08-12 11:39:29 +0000272 .map_flash_region = fallback_map,
273 .unmap_flash_region = fallback_unmap,
hailfingerf31da3d2009-06-16 21:08:06 +0000274 .delay = internal_delay,
275 },
hailfingerd9dcfbd2009-08-19 13:27:58 +0000276#endif
hailfinger6fe23d62009-08-12 11:39:29 +0000277
hailfinger90c7d542010-05-31 15:27:27 +0000278#if CONFIG_SERPROG == 1
hailfinger37b4fbf2009-06-23 11:33:43 +0000279 {
hailfinger3548a9a2009-08-12 14:34:35 +0000280 .name = "serprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100281 .type = OTHER,
282 /* FIXME */
283 .devs.note = "All programmer devices speaking the serprog protocol\n",
hailfinger37b4fbf2009-06-23 11:33:43 +0000284 .init = serprog_init,
Edward O'Callaghan62018182020-10-03 00:16:48 +1000285 .map_flash_region = serprog_map,
hailfinger37b4fbf2009-06-23 11:33:43 +0000286 .unmap_flash_region = fallback_unmap,
hailfinger37b4fbf2009-06-23 11:33:43 +0000287 .delay = serprog_delay,
288 },
hailfinger74d88a72009-08-12 16:17:41 +0000289#endif
hailfingerf31da3d2009-06-16 21:08:06 +0000290
hailfinger90c7d542010-05-31 15:27:27 +0000291#if CONFIG_BUSPIRATE_SPI == 1
hailfinger9c5add72009-11-24 00:20:03 +0000292 {
hailfinger90c7d542010-05-31 15:27:27 +0000293 .name = "buspirate_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100294 .type = OTHER,
295 /* FIXME */
296 .devs.note = "Dangerous Prototypes Bus Pirate\n",
hailfinger9c5add72009-11-24 00:20:03 +0000297 .init = buspirate_spi_init,
hailfinger9c5add72009-11-24 00:20:03 +0000298 .map_flash_region = fallback_map,
299 .unmap_flash_region = fallback_unmap,
hailfinger9c5add72009-11-24 00:20:03 +0000300 .delay = internal_delay,
301 },
302#endif
303
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000304#if CONFIG_DEDIPROG == 1
Anton Staafb2647882014-09-17 15:13:43 -0700305 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000306 .name = "dediprog",
Brian J. Nemecb42d6c12020-07-23 03:07:38 -0700307 .type = USB,
Edward O'Callaghanac1678b2020-07-27 15:55:45 +1000308 .devs.dev = devs_dediprog,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000309 .init = dediprog_init,
Anton Staafb2647882014-09-17 15:13:43 -0700310 .map_flash_region = fallback_map,
311 .unmap_flash_region = fallback_unmap,
312 .delay = internal_delay,
313 },
314#endif
315
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000316#if CONFIG_DEVELOPERBOX_SPI == 1
hailfingerdfb32a02010-01-19 11:15:48 +0000317 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000318 .name = "developerbox",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100319 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000320 .devs.dev = devs_developerbox_spi,
321 .init = developerbox_spi_init,
322 .map_flash_region = fallback_map,
323 .unmap_flash_region = fallback_unmap,
324 .delay = internal_delay,
325 },
326#endif
327
328#if CONFIG_ENE_LPC == 1
329 {
330 .name = "ene_lpc",
331 .type = OTHER,
332 .devs.note = "ENE LPC interface keyboard controller\n",
333 .init = ene_lpc_init,
hailfingerdfb32a02010-01-19 11:15:48 +0000334 .map_flash_region = fallback_map,
335 .unmap_flash_region = fallback_unmap,
hailfingerdfb32a02010-01-19 11:15:48 +0000336 .delay = internal_delay,
337 },
338#endif
339
hailfinger52c4fa02010-07-21 10:26:01 +0000340#if CONFIG_RAYER_SPI == 1
341 {
342 .name = "rayer_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100343 .type = OTHER,
344 /* FIXME */
345 .devs.note = "RayeR parallel port programmer\n",
hailfinger52c4fa02010-07-21 10:26:01 +0000346 .init = rayer_spi_init,
hailfinger52c4fa02010-07-21 10:26:01 +0000347 .map_flash_region = fallback_map,
348 .unmap_flash_region = fallback_unmap,
hailfinger52c4fa02010-07-21 10:26:01 +0000349 .delay = internal_delay,
350 },
351#endif
352
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000353#if CONFIG_PONY_SPI == 1
354 {
355 .name = "pony_spi",
356 .type = OTHER,
357 /* FIXME */
358 .devs.note = "Programmers compatible with SI-Prog, serbang or AJAWe\n",
359 .init = pony_spi_init,
360 .map_flash_region = fallback_map,
361 .unmap_flash_region = fallback_unmap,
362 .delay = internal_delay,
363 },
364#endif
365
hailfinger7949b652011-05-08 00:24:18 +0000366#if CONFIG_NICINTEL == 1
367 {
368 .name = "nicintel",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100369 .type = PCI,
370 .devs.dev = nics_intel,
hailfinger7949b652011-05-08 00:24:18 +0000371 .init = nicintel_init,
hailfinger7949b652011-05-08 00:24:18 +0000372 .map_flash_region = fallback_map,
373 .unmap_flash_region = fallback_unmap,
hailfinger7949b652011-05-08 00:24:18 +0000374 .delay = internal_delay,
375 },
376#endif
377
uwe6764e922010-09-03 18:21:21 +0000378#if CONFIG_NICINTEL_SPI == 1
379 {
uwe8d342eb2011-07-28 08:13:25 +0000380 .name = "nicintel_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100381 .type = PCI,
382 .devs.dev = nics_intel_spi,
uwe8d342eb2011-07-28 08:13:25 +0000383 .init = nicintel_spi_init,
384 .map_flash_region = fallback_map,
385 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000386 .delay = internal_delay,
uwe6764e922010-09-03 18:21:21 +0000387 },
388#endif
389
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000390#if CONFIG_NICINTEL_EEPROM == 1
391 {
392 .name = "nicintel_eeprom",
393 .type = PCI,
394 .devs.dev = nics_intel_ee,
395 .init = nicintel_ee_init,
396 .map_flash_region = fallback_map,
397 .unmap_flash_region = fallback_unmap,
398 .delay = internal_delay,
399 },
400#endif
401
hailfingerfb1f31f2010-12-03 14:48:11 +0000402#if CONFIG_OGP_SPI == 1
403 {
uwe8d342eb2011-07-28 08:13:25 +0000404 .name = "ogp_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100405 .type = PCI,
406 .devs.dev = ogp_spi,
uwe8d342eb2011-07-28 08:13:25 +0000407 .init = ogp_spi_init,
408 .map_flash_region = fallback_map,
409 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000410 .delay = internal_delay,
hailfingerfb1f31f2010-12-03 14:48:11 +0000411 },
412#endif
413
hailfinger935365d2011-02-04 21:37:59 +0000414#if CONFIG_SATAMV == 1
415 {
416 .name = "satamv",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100417 .type = PCI,
418 .devs.dev = satas_mv,
hailfinger935365d2011-02-04 21:37:59 +0000419 .init = satamv_init,
hailfinger935365d2011-02-04 21:37:59 +0000420 .map_flash_region = fallback_map,
421 .unmap_flash_region = fallback_unmap,
hailfinger935365d2011-02-04 21:37:59 +0000422 .delay = internal_delay,
423 },
424#endif
425
David Hendrickscebee892015-05-23 20:30:30 -0700426#if CONFIG_LINUX_MTD == 1
427 {
428 .name = "linux_mtd",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100429 .type = OTHER,
430 .devs.note = "Device files /dev/mtd*\n",
David Hendrickscebee892015-05-23 20:30:30 -0700431 .init = linux_mtd_init,
432 .map_flash_region = fallback_map,
433 .unmap_flash_region = fallback_unmap,
434 .delay = internal_delay,
435 },
436#endif
437
uwe7df6dda2011-09-03 18:37:52 +0000438#if CONFIG_LINUX_SPI == 1
439 {
440 .name = "linux_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100441 .type = OTHER,
442 .devs.note = "Device files /dev/spidev*.*\n",
uwe7df6dda2011-09-03 18:37:52 +0000443 .init = linux_spi_init,
444 .map_flash_region = fallback_map,
445 .unmap_flash_region = fallback_unmap,
uwe7df6dda2011-09-03 18:37:52 +0000446 .delay = internal_delay,
447 },
448#endif
449
Shiyu Sun9dde7162020-04-16 17:32:55 +1000450#if CONFIG_LSPCON_I2C_SPI == 1
451 {
452 .name = "lspcon_i2c_spi",
453 .type = OTHER,
454 .devs.note = "Device files /dev/i2c-*.\n",
455 .init = lspcon_i2c_spi_init,
456 .map_flash_region = fallback_map,
457 .unmap_flash_region = fallback_unmap,
458 .delay = internal_delay,
459 },
460#endif
461
Edward O'Callaghan97dd9262020-03-26 00:00:41 +1100462#if CONFIG_REALTEK_MST_I2C_SPI == 1
463 {
464 .name = "realtek_mst_i2c_spi",
465 .type = OTHER,
466 .devs.note = "Device files /dev/i2c-*.\n",
467 .init = realtek_mst_i2c_spi_init,
468 .map_flash_region = fallback_map,
469 .unmap_flash_region = fallback_unmap,
470 .delay = internal_delay,
471 },
472#endif
473
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000474#if CONFIG_USBBLASTER_SPI == 1
475 {
476 .name = "usbblaster_spi",
477 .type = USB,
478 .devs.dev = devs_usbblasterspi,
479 .init = usbblaster_spi_init,
480 .map_flash_region = fallback_map,
481 .unmap_flash_region = fallback_unmap,
482 .delay = internal_delay,
483 },
484#endif
485
486#if CONFIG_MSTARDDC_SPI == 1
487 {
488 .name = "mstarddc_spi",
489 .type = OTHER,
490 .devs.note = "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
491 .init = mstarddc_spi_init,
492 .map_flash_region = fallback_map,
493 .unmap_flash_region = fallback_unmap,
494 .delay = internal_delay,
495 },
496#endif
497
498#if CONFIG_PICKIT2_SPI == 1
499 {
500 .name = "pickit2_spi",
501 .type = USB,
502 .devs.dev = devs_pickit2_spi,
503 .init = pickit2_spi_init,
504 .map_flash_region = fallback_map,
505 .unmap_flash_region = fallback_unmap,
506 .delay = internal_delay,
507 },
508#endif
509
510#if CONFIG_CH341A_SPI == 1
511 {
512 .name = "ch341a_spi",
513 .type = USB,
514 .devs.dev = devs_ch341a_spi,
515 .init = ch341a_spi_init,
516 .map_flash_region = fallback_map,
517 .unmap_flash_region = fallback_unmap,
518 .delay = ch341a_spi_delay,
519 },
520#endif
521
522#if CONFIG_DIGILENT_SPI == 1
523 {
524 .name = "digilent_spi",
525 .type = USB,
526 .devs.dev = devs_digilent_spi,
527 .init = digilent_spi_init,
528 .map_flash_region = fallback_map,
529 .unmap_flash_region = fallback_unmap,
530 .delay = internal_delay,
531 },
532#endif
533
534#if CONFIG_JLINK_SPI == 1
535 {
536 .name = "jlink_spi",
537 .type = OTHER,
538 .init = jlink_spi_init,
539 .devs.note = "SEGGER J-Link and compatible devices\n",
540 .map_flash_region = fallback_map,
541 .unmap_flash_region = fallback_unmap,
542 .delay = internal_delay,
543 },
544#endif
545
546#if CONFIG_NI845X_SPI == 1
547 {
548 .name = "ni845x_spi",
549 .type = OTHER, // choose other because NI-845x uses own USB implementation
550 .devs.note = "National Instruments USB-845x\n",
551 .init = ni845x_spi_init,
552 .map_flash_region = fallback_map,
553 .unmap_flash_region = fallback_unmap,
554 .delay = internal_delay,
555 },
556#endif
557
558#if CONFIG_STLINKV3_SPI == 1
559 {
560 .name = "stlinkv3_spi",
561 .type = USB,
562 .devs.dev = devs_stlinkv3_spi,
563 .init = stlinkv3_spi_init,
564 .map_flash_region = fallback_map,
565 .unmap_flash_region = fallback_unmap,
566 .delay = internal_delay,
567 },
568#endif
569
Edward O'Callaghand8f72232020-09-30 14:21:42 +1000570#if CONFIG_GOOGLE_EC == 1
571 {
572 .name = "google_ec",
573 .type = OTHER,
574 .devs.note = "Google EC.\n",
575 .init = cros_ec_probe_dev,
576 .map_flash_region = fallback_map,
577 .unmap_flash_region = fallback_unmap,
578 .delay = internal_delay,
579 },
580#endif
581
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100582 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000583};
stepan927d4e22007-04-04 22:45:58 +0000584
David Hendricksbf36f092010-11-02 23:39:29 -0700585#define CHIP_RESTORE_MAXFN 4
586static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000587static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700588 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700589 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700590 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000591} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700592
David Hendricks668f29d2011-01-27 18:51:45 -0800593
hailfingerf31cbdc2010-11-10 15:25:18 +0000594#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000595static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000596/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000597static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700598 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000599 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000600} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000601/* Initialize to 0 to make sure nobody registers a shutdown function before
602 * programmer init.
603 */
604static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000605
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700606static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000607
hailfingerdc6f7972010-02-14 01:20:28 +0000608/* Register a function to be executed on programmer shutdown.
609 * The advantage over atexit() is that you can supply a void pointer which will
610 * be used as parameter to the registered function upon programmer shutdown.
611 * This pointer can point to arbitrary data used by said function, e.g. undo
612 * information for GPIO settings etc. If unneeded, set data=NULL.
613 * Please note that the first (void *data) belongs to the function signature of
614 * the function passed as first parameter.
615 */
David Hendricks93784b42016-08-09 17:00:38 -0700616int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000617{
618 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000619 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000620 SHUTDOWN_MAXFN);
621 return 1;
622 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000623 if (!may_register_shutdown) {
624 msg_perr("Tried to register a shutdown function before "
625 "programmer init.\n");
626 return 1;
627 }
hailfingerdc6f7972010-02-14 01:20:28 +0000628 shutdown_fn[shutdown_fn_count].func = function;
629 shutdown_fn[shutdown_fn_count].data = data;
630 shutdown_fn_count++;
631
632 return 0;
633}
634
David Hendricksbf36f092010-11-02 23:39:29 -0700635//int register_chip_restore(int (*function) (void *data), void *data)
636int register_chip_restore(CHIP_RESTORE_CALLBACK,
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700637 struct flashctx *flash, uint8_t status)
David Hendricksbf36f092010-11-02 23:39:29 -0700638{
639 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
640 msg_perr("Tried to register more than %i chip restore"
641 " functions.\n", CHIP_RESTORE_MAXFN);
642 return 1;
643 }
644 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
645 chip_restore_fn[chip_restore_fn_count].flash = flash;
646 chip_restore_fn[chip_restore_fn_count].status = status;
647 chip_restore_fn_count++;
648
649 return 0;
650}
651
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000652int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000653{
hailfinger1ef766d2010-07-06 09:55:48 +0000654 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000655
656 if (prog >= PROGRAMMER_INVALID) {
657 msg_perr("Invalid programmer specified!\n");
658 return -1;
659 }
660 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000661 /* Initialize all programmer specific data. */
662 /* Default to unlimited decode sizes. */
663 max_rom_decode = (const struct decode_sizes) {
664 .parallel = 0xffffffff,
665 .lpc = 0xffffffff,
666 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000667 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000668 };
David Hendricksac1d25c2016-08-09 17:00:58 -0700669 buses_supported = BUS_NONE;
hailfinger1ff33dc2010-07-03 11:02:10 +0000670 /* Default to top aligned flash at 4 GB. */
671 flashbase = 0;
672 /* Registering shutdown functions is now allowed. */
673 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000674 /* Default to allowing writes. Broken programmers set this to 0. */
675 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000676
677 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000678 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700679 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000680 if (programmer_param && strlen(programmer_param)) {
681 if (ret != 0) {
682 /* It is quite possible that any unhandled programmer parameter would have been valid,
683 * but an error in actual programmer init happened before the parameter was evaluated.
684 */
685 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
686 programmer_param);
687 } else {
688 /* Actual programmer init was successful, but the user specified an invalid or unusable
689 * (for the current programmer configuration) parameter.
690 */
691 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
692 msg_perr("Aborting.\n");
693 ret = ERROR_FATAL;
694 }
695 }
hailfinger1ef766d2010-07-06 09:55:48 +0000696 return ret;
uweabe92a52009-05-16 22:36:00 +0000697}
698
David Hendricksbf36f092010-11-02 23:39:29 -0700699int chip_restore()
700{
701 int rc = 0;
702
703 while (chip_restore_fn_count > 0) {
704 int i = --chip_restore_fn_count;
705 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
706 chip_restore_fn[i].status);
707 }
708
709 return rc;
710}
711
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000712/** Calls registered shutdown functions and resets internal programmer-related variables.
713 * Calling it is safe even without previous initialization, but further interactions with programmer support
714 * require a call to programmer_init() (afterwards).
715 *
716 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700717int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000718{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000719 int ret = 0;
720
hailfinger1ff33dc2010-07-03 11:02:10 +0000721 /* Registering shutdown functions is no longer allowed. */
722 may_register_shutdown = 0;
723 while (shutdown_fn_count > 0) {
724 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700725 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000726 }
Edward O'Callaghancf9c40f2020-10-19 20:02:39 +1100727
728 programmer_param = NULL;
729 registered_master_count = 0;
730
dhendrix0ffc2eb2011-06-14 01:35:36 +0000731 return ret;
uweabe92a52009-05-16 22:36:00 +0000732}
733
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000734void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000735{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000736 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
737 return ret;
uweabe92a52009-05-16 22:36:00 +0000738}
739
740void programmer_unmap_flash_region(void *virt_addr, size_t len)
741{
742 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000743 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000744}
745
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700746void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000747{
Craig Hesling65eb8812019-08-01 09:33:56 -0700748 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000749}
750
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700751void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000752{
Craig Hesling65eb8812019-08-01 09:33:56 -0700753 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000754}
755
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700756void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000757{
Craig Hesling65eb8812019-08-01 09:33:56 -0700758 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000759}
760
Stuart langleyc98e43f2020-03-26 20:27:36 +1100761void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000762{
Craig Hesling65eb8812019-08-01 09:33:56 -0700763 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000764}
765
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700766uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000767{
Craig Hesling65eb8812019-08-01 09:33:56 -0700768 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000769}
770
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700771uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000772{
Craig Hesling65eb8812019-08-01 09:33:56 -0700773 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000774}
775
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700776uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000777{
Craig Hesling65eb8812019-08-01 09:33:56 -0700778 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000779}
780
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000781void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
782 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000783{
Craig Hesling65eb8812019-08-01 09:33:56 -0700784 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000785}
786
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000787void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000788{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000789 if (usecs > 0)
790 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000791}
792
Edward O'Callaghana820b212020-09-17 22:53:26 +1000793int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
794 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000795{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700796 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000797
hailfinger23060112009-05-08 12:49:03 +0000798 return 0;
799}
800
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000801/* This is a somewhat hacked function similar in some ways to strtok().
802 * It will look for needle with a subsequent '=' in haystack, return a copy of
803 * needle and remove everything from the first occurrence of needle to the next
804 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000805 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000806char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000807{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000808 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000809 char *opt = NULL;
810 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000811 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000812
hailfingerf4aaccc2010-04-28 15:22:14 +0000813 needlelen = strlen(needle);
814 if (!needlelen) {
815 msg_gerr("%s: empty needle! Please report a bug at "
816 "flashrom@flashrom.org\n", __func__);
817 return NULL;
818 }
819 /* No programmer parameters given. */
820 if (*haystack == NULL)
821 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000822 param_pos = strstr(*haystack, needle);
823 do {
824 if (!param_pos)
825 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000826 /* Needle followed by '='? */
827 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000828 /* Beginning of the string? */
829 if (param_pos == *haystack)
830 break;
831 /* After a delimiter? */
832 if (strchr(delim, *(param_pos - 1)))
833 break;
834 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000835 /* Continue searching. */
836 param_pos++;
837 param_pos = strstr(param_pos, needle);
838 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000839
hailfinger6e5a52a2009-11-24 18:27:10 +0000840 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000841 /* Get the string after needle and '='. */
842 opt_pos = param_pos + needlelen + 1;
843 optlen = strcspn(opt_pos, delim);
844 /* Return an empty string if the parameter was empty. */
845 opt = malloc(optlen + 1);
846 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000847 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000848 exit(1);
849 }
hailfinger1ef766d2010-07-06 09:55:48 +0000850 strncpy(opt, opt_pos, optlen);
851 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000852 rest = opt_pos + optlen;
853 /* Skip all delimiters after the current parameter. */
854 rest += strspn(rest, delim);
855 memmove(param_pos, rest, strlen(rest) + 1);
856 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000857 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000858
hailfinger1ef766d2010-07-06 09:55:48 +0000859 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000860}
861
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000862char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000863{
864 return extract_param(&programmer_param, param_name, ",");
865}
866
stefancte1c5acf2011-07-04 07:27:17 +0000867/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700868static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000869{
870 unsigned int usable_erasefunctions = 0;
871 int k;
872 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
873 if (!check_block_eraser(flash, k, 0))
874 usable_erasefunctions++;
875 }
876 return usable_erasefunctions;
877}
878
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000879static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700880{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000881 int ret = 0, failcount = 0;
882 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700883 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000884 if (wantbuf[i] != havebuf[i]) {
885 /* Only print the first failure. */
886 if (!failcount++)
887 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
888 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700889 }
890 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000891 if (failcount) {
892 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
893 start, start + len - 1, failcount);
894 ret = -1;
895 }
896 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700897}
898
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000899/* start is an offset to the base address of the flash chip */
900static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
901{
902 int ret;
903 uint8_t *cmpbuf = malloc(len);
904 const uint8_t erased_value = ERASED_VALUE(flash);
905
906 if (!cmpbuf) {
907 msg_gerr("Could not allocate memory!\n");
908 exit(1);
909 }
910 memset(cmpbuf, erased_value, len);
911 ret = verify_range(flash, cmpbuf, start, len);
912 free(cmpbuf);
913 return ret;
914}
915
uwee15beb92010-08-08 17:01:18 +0000916/*
hailfinger7af3d192009-11-25 17:05:52 +0000917 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000918 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000919 * @start offset to the base address of the flash chip
920 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000921 * @return 0 for success, -1 for failure
922 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000923int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000924{
hailfinger7af83692009-06-15 17:23:36 +0000925 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000926 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000927
Patrick Georgif3fa2992017-02-02 16:24:44 +0100928 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000929 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000930 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000931 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000932
933 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000934 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000935 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000936 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000937 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000938 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000939
Patrick Georgif3fa2992017-02-02 16:24:44 +0100940 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000941 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000942 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100943 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000944 ret = -1;
945 goto out_free;
946 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700947 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700948 if (programmer_table[programmer].paranoid) {
949 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800950
Simon Glass4e305f42015-01-08 06:29:04 -0700951 /* limit chunksize in order to catch errors early */
952 for (i = 0, chunksize = 0; i < len; i += chunksize) {
953 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800954
Patrick Georgif3fa2992017-02-02 16:24:44 +0100955 chunksize = min(flash->chip->page_size, len - i);
956 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700957 if (tmp) {
958 ret = tmp;
959 if (ignore_error(tmp))
960 continue;
961 else
962 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800963 }
Simon Glass4e305f42015-01-08 06:29:04 -0700964
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700965 /*
966 * Check write access permission and do not compare chunks
967 * where flashrom does not have write access to the region.
968 */
969 if (flash->chip->check_access) {
970 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
971 if (tmp && ignore_error(tmp))
972 continue;
973 }
974
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000975 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700976 if (failcount)
977 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800978 }
Simon Glass4e305f42015-01-08 06:29:04 -0700979 } else {
980 int tmp;
981
982 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +0100983 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -0700984 if (tmp && !ignore_error(tmp)) {
985 ret = tmp;
986 goto out_free;
987 }
988
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000989 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +0000990 }
991
hailfinger5be6c0f2009-07-23 01:42:56 +0000992 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +0000993 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +0000994 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +0000995 ret = -1;
996 }
hailfinger7af83692009-06-15 17:23:36 +0000997
998out_free:
999 free(readbuf);
1000 return ret;
1001}
1002
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001003/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1004static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001005 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001006{
1007 unsigned int i, j, limit;
1008 for (j = 0; j < len / gran; j++) {
1009 limit = min (gran, len - j * gran);
1010 /* Are 'have' and 'want' identical? */
1011 if (!memcmp(have + j * gran, want + j * gran, limit))
1012 continue;
1013 /* have needs to be in erased state. */
1014 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001015 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001016 return 1;
1017 }
1018 return 0;
1019}
1020
uwee15beb92010-08-08 17:01:18 +00001021/*
hailfingerb247c7a2010-03-08 00:42:32 +00001022 * Check if the buffer @have can be programmed to the content of @want without
1023 * erasing. This is only possible if all chunks of size @gran are either kept
1024 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001025 *
hailfingerb437e282010-11-04 01:04:27 +00001026 * Warning: This function assumes that @have and @want point to naturally
1027 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001028 *
1029 * @have buffer with current content
1030 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001031 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001032 * @gran write granularity (enum, not count)
1033 * @return 0 if no erase is needed, 1 otherwise
1034 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001035int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1036 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001037{
hailfingerb91c08c2011-08-15 19:54:20 +00001038 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001039 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001040
hailfingerb247c7a2010-03-08 00:42:32 +00001041 switch (gran) {
1042 case write_gran_1bit:
1043 for (i = 0; i < len; i++)
1044 if ((have[i] & want[i]) != want[i]) {
1045 result = 1;
1046 break;
1047 }
1048 break;
1049 case write_gran_1byte:
1050 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001051 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001052 result = 1;
1053 break;
1054 }
1055 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001056 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001057 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001058 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001059 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001060 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001061 break;
1062 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001063 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001064 break;
1065 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001066 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001067 break;
1068 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001069 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001070 break;
1071 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001072 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001073 break;
1074 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001075 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001076 break;
1077 case write_gran_1byte_implicit_erase:
1078 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1079 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001080 break;
hailfingerb437e282010-11-04 01:04:27 +00001081 default:
1082 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1083 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001084 }
1085 return result;
1086}
1087
hailfingerb437e282010-11-04 01:04:27 +00001088/**
1089 * Check if the buffer @have needs to be programmed to get the content of @want.
1090 * If yes, return 1 and fill in first_start with the start address of the
1091 * write operation and first_len with the length of the first to-be-written
1092 * chunk. If not, return 0 and leave first_start and first_len undefined.
1093 *
1094 * Warning: This function assumes that @have and @want point to naturally
1095 * aligned regions.
1096 *
1097 * @have buffer with current content
1098 * @want buffer with desired content
1099 * @len length of the checked area
1100 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001101 * @first_start offset of the first byte which needs to be written (passed in
1102 * value is increased by the offset of the first needed write
1103 * relative to have/want or unchanged if no write is needed)
1104 * @return length of the first contiguous area which needs to be written
1105 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001106 *
1107 * FIXME: This function needs a parameter which tells it about coalescing
1108 * in relation to the max write length of the programmer and the max write
1109 * length of the chip.
1110 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001111static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001112 unsigned int *first_start,
1113 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001114{
stefanctc5eb8a92011-11-23 09:13:48 +00001115 int need_write = 0;
1116 unsigned int rel_start = 0, first_len = 0;
1117 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001118
hailfingerb437e282010-11-04 01:04:27 +00001119 switch (gran) {
1120 case write_gran_1bit:
1121 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001122 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001123 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001124 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001125 case write_gran_128bytes:
1126 stride = 128;
1127 break;
hailfingerb437e282010-11-04 01:04:27 +00001128 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001129 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001130 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001131 case write_gran_264bytes:
1132 stride = 264;
1133 break;
1134 case write_gran_512bytes:
1135 stride = 512;
1136 break;
1137 case write_gran_528bytes:
1138 stride = 528;
1139 break;
1140 case write_gran_1024bytes:
1141 stride = 1024;
1142 break;
1143 case write_gran_1056bytes:
1144 stride = 1056;
1145 break;
hailfingerb437e282010-11-04 01:04:27 +00001146 default:
1147 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1148 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001149 /* Claim that no write was needed. A write with unknown
1150 * granularity is too dangerous to try.
1151 */
1152 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001153 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001154 for (i = 0; i < len / stride; i++) {
1155 limit = min(stride, len - i * stride);
1156 /* Are 'have' and 'want' identical? */
1157 if (memcmp(have + i * stride, want + i * stride, limit)) {
1158 if (!need_write) {
1159 /* First location where have and want differ. */
1160 need_write = 1;
1161 rel_start = i * stride;
1162 }
1163 } else {
1164 if (need_write) {
1165 /* First location where have and want
1166 * do not differ anymore.
1167 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001168 break;
1169 }
1170 }
1171 }
hailfingerffb7f382010-12-06 13:05:44 +00001172 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001173 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001174 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001175 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001176}
1177
hailfinger0c515352009-11-23 12:55:31 +00001178/* This function generates various test patterns useful for testing controller
1179 * and chip communication as well as chip behaviour.
1180 *
1181 * If a byte can be written multiple times, each time keeping 0-bits at 0
1182 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1183 * is essentially an AND operation. That's also the reason why this function
1184 * provides the result of AND between various patterns.
1185 *
1186 * Below is a list of patterns (and their block length).
1187 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1188 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1189 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1190 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1191 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1192 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1193 * Pattern 6 is 00 (1 Byte)
1194 * Pattern 7 is ff (1 Byte)
1195 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1196 * byte block.
1197 *
1198 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1199 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1200 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1201 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1202 * Pattern 12 is 00 (1 Byte)
1203 * Pattern 13 is ff (1 Byte)
1204 * Patterns 8-13 have no block number.
1205 *
1206 * Patterns 0-3 are created to detect and efficiently diagnose communication
1207 * slips like missed bits or bytes and their repetitive nature gives good visual
1208 * cues to the person inspecting the results. In addition, the following holds:
1209 * AND Pattern 0/1 == Pattern 4
1210 * AND Pattern 2/3 == Pattern 5
1211 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1212 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1213 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1214 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1215 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1216 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1217 * Besides that, they provide for bit testing of the last two bytes of every
1218 * 256 byte block which contains the block number for patterns 0-6.
1219 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1220 * block sizes >256 bytes (some Dataflash chips etc.)
1221 * AND Pattern 8/9 == Pattern 12
1222 * AND Pattern 10/11 == Pattern 12
1223 * Pattern 13 is the completely erased state.
1224 * None of the patterns can detect aliasing at boundaries which are a multiple
1225 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1226 */
1227int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1228{
1229 int i;
1230
1231 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001232 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001233 return 1;
1234 }
1235
1236 switch (variant) {
1237 case 0:
1238 for (i = 0; i < size; i++)
1239 buf[i] = (i & 0xf) << 4 | 0x5;
1240 break;
1241 case 1:
1242 for (i = 0; i < size; i++)
1243 buf[i] = (i & 0xf) << 4 | 0xa;
1244 break;
1245 case 2:
1246 for (i = 0; i < size; i++)
1247 buf[i] = 0x50 | (i & 0xf);
1248 break;
1249 case 3:
1250 for (i = 0; i < size; i++)
1251 buf[i] = 0xa0 | (i & 0xf);
1252 break;
1253 case 4:
1254 for (i = 0; i < size; i++)
1255 buf[i] = (i & 0xf) << 4;
1256 break;
1257 case 5:
1258 for (i = 0; i < size; i++)
1259 buf[i] = i & 0xf;
1260 break;
1261 case 6:
1262 memset(buf, 0x00, size);
1263 break;
1264 case 7:
1265 memset(buf, 0xff, size);
1266 break;
1267 case 8:
1268 for (i = 0; i < size; i++)
1269 buf[i] = i & 0xff;
1270 break;
1271 case 9:
1272 for (i = 0; i < size; i++)
1273 buf[i] = ~(i & 0xff);
1274 break;
1275 case 10:
1276 for (i = 0; i < size % 2; i++) {
1277 buf[i * 2] = (i >> 8) & 0xff;
1278 buf[i * 2 + 1] = i & 0xff;
1279 }
1280 if (size & 0x1)
1281 buf[i * 2] = (i >> 8) & 0xff;
1282 break;
1283 case 11:
1284 for (i = 0; i < size % 2; i++) {
1285 buf[i * 2] = ~((i >> 8) & 0xff);
1286 buf[i * 2 + 1] = ~(i & 0xff);
1287 }
1288 if (size & 0x1)
1289 buf[i * 2] = ~((i >> 8) & 0xff);
1290 break;
1291 case 12:
1292 memset(buf, 0x00, size);
1293 break;
1294 case 13:
1295 memset(buf, 0xff, size);
1296 break;
1297 }
1298
1299 if ((variant >= 0) && (variant <= 7)) {
1300 /* Write block number in the last two bytes of each 256-byte
1301 * block, big endian for easier reading of the hexdump.
1302 * Note that this wraps around for chips larger than 2^24 bytes
1303 * (16 MB).
1304 */
1305 for (i = 0; i < size / 256; i++) {
1306 buf[i * 256 + 254] = (i >> 8) & 0xff;
1307 buf[i * 256 + 255] = i & 0xff;
1308 }
1309 }
1310
1311 return 0;
1312}
1313
hailfingeraec9c962009-10-31 01:53:09 +00001314int check_max_decode(enum chipbustype buses, uint32_t size)
1315{
1316 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001317
1318 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001319 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001320 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001321 "size %u kB of chipset/board/programmer "
1322 "for %s interface, "
1323 "probe/read/erase/write may fail. ", size / 1024,
1324 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001325 }
hailfingere1e41ea2011-07-27 07:13:06 +00001326 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001327 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001328 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001329 "size %u kB of chipset/board/programmer "
1330 "for %s interface, "
1331 "probe/read/erase/write may fail. ", size / 1024,
1332 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001333 }
hailfingere1e41ea2011-07-27 07:13:06 +00001334 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001335 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001336 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001337 "size %u kB of chipset/board/programmer "
1338 "for %s interface, "
1339 "probe/read/erase/write may fail. ", size / 1024,
1340 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001341 }
hailfingere1e41ea2011-07-27 07:13:06 +00001342 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001343 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001344 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001345 "size %u kB of chipset/board/programmer "
1346 "for %s interface, "
1347 "probe/read/erase/write may fail. ", size / 1024,
1348 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001349 }
1350 if (!limitexceeded)
1351 return 0;
1352 /* Sometimes chip and programmer have more than one bus in common,
1353 * and the limit is not exceeded on all buses. Tell the user.
1354 */
1355 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001356 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001357 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001358 "interface which can support a chip of this size. "
1359 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001360 return 1;
1361}
1362
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001363void unmap_flash(struct flashctx *flash)
1364{
1365 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1366 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1367 flash->physical_registers = 0;
1368 flash->virtual_registers = (chipaddr)ERROR_PTR;
1369 }
1370
1371 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1372 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1373 flash->physical_memory = 0;
1374 flash->virtual_memory = (chipaddr)ERROR_PTR;
1375 }
1376}
1377
1378int map_flash(struct flashctx *flash)
1379{
1380 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1381 flash->virtual_memory = (chipaddr)ERROR_PTR;
1382 flash->virtual_registers = (chipaddr)ERROR_PTR;
1383
1384 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1385 * These are used for various probing-related hacks that would not map successfully anyway and should be
1386 * removed ASAP. */
1387 if (flash->chip->total_size == 0)
1388 return 0;
1389
1390 const chipsize_t size = flash->chip->total_size * 1024;
1391 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1392 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1393 if (addr == ERROR_PTR) {
1394 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1395 flash->chip->name, PRIxPTR_WIDTH, base);
1396 return 1;
1397 }
1398 flash->physical_memory = base;
1399 flash->virtual_memory = (chipaddr)addr;
1400
1401 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1402 * completely different on some chips and programmers, or not mappable at all.
1403 * Ignore these problems for now and always report success. */
1404 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1405 base = 0xffffffff - size - 0x400000 + 1;
1406 addr = programmer_map_flash_region("flash chip registers", base, size);
1407 if (addr == ERROR_PTR) {
1408 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1409 flash->chip->name, PRIxPTR_WIDTH, base);
1410 return 0;
1411 }
1412 flash->physical_registers = base;
1413 flash->virtual_registers = (chipaddr)addr;
1414 }
1415 return 0;
1416}
1417
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001418/*
1419 * Return a string corresponding to the bustype parameter.
1420 * Memory is obtained with malloc() and must be freed with free() by the caller.
1421 */
1422char *flashbuses_to_text(enum chipbustype bustype)
1423{
1424 char *ret = calloc(1, 1);
1425 /*
1426 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1427 * will cease to exist and should be eliminated here as well.
1428 */
1429 if (bustype == BUS_NONSPI) {
1430 ret = strcat_realloc(ret, "Non-SPI, ");
1431 } else {
1432 if (bustype & BUS_PARALLEL)
1433 ret = strcat_realloc(ret, "Parallel, ");
1434 if (bustype & BUS_LPC)
1435 ret = strcat_realloc(ret, "LPC, ");
1436 if (bustype & BUS_FWH)
1437 ret = strcat_realloc(ret, "FWH, ");
1438 if (bustype & BUS_SPI)
1439 ret = strcat_realloc(ret, "SPI, ");
1440 if (bustype & BUS_PROG)
1441 ret = strcat_realloc(ret, "Programmer-specific, ");
1442 if (bustype == BUS_NONE)
1443 ret = strcat_realloc(ret, "None, ");
1444 }
1445 /* Kill last comma. */
1446 ret[strlen(ret) - 2] = '\0';
1447 ret = realloc(ret, strlen(ret) + 1);
1448 return ret;
1449}
1450
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001451int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001452{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001453 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001454 uint32_t size;
1455 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001456 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001457
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301458 /* Based on the host controller interface that a platform
1459 * needs to use (hwseq or swseq),
1460 * set the flashchips list here.
1461 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001462 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301463 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001464 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301465 flash_list = flashchips_hwseq;
1466 break;
1467 default:
1468 flash_list = flashchips;
1469 break;
1470 }
1471
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001472 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1473 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001474 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001475 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001476 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001477 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001478 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001479 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001480 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001481 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001482 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001483 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001484 continue;
1485 }
stepan782fb172007-04-06 11:58:03 +00001486
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001487 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001488 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001489
hailfinger48ed3e22011-05-04 00:39:50 +00001490 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001491 flash->chip = calloc(1, sizeof(struct flashchip));
1492 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001493 msg_gerr("Out of memory!\n");
1494 exit(1);
1495 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001496 memcpy(flash->chip, chip, sizeof(struct flashchip));
1497 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001498
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001499 if (map_flash(flash) != 0)
1500 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001501
Edward O'Callaghana820b212020-09-17 22:53:26 +10001502 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1503 * is only called with force=1 after normal probing failed.
1504 */
stugec1e55fe2008-07-02 17:15:47 +00001505 if (force)
1506 break;
stepanc98b80b2006-03-16 16:57:41 +00001507
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001508 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001509 goto notfound;
1510
hailfinger48ed3e22011-05-04 00:39:50 +00001511 /* If this is the first chip found, accept it.
1512 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001513 * a non-generic match. SFDP and CFI are generic matches.
1514 * startchip==0 means this call to probe_flash() is the first
1515 * one for this programmer interface (master) and thus no other chip has
1516 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001517 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001518 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1519 msg_cinfo("===\n"
1520 "SFDP has autodetected a flash chip which is "
1521 "not natively supported by flashrom yet.\n");
1522 if (count_usable_erasers(flash) == 0)
1523 msg_cinfo("The standard operations read and "
1524 "verify should work, but to support "
1525 "erase, write and all other "
1526 "possible features");
1527 else
1528 msg_cinfo("All standard operations (read, "
1529 "verify, erase and write) should "
1530 "work, but to support all possible "
1531 "features");
1532
1533 msg_cinfo(" we need to add them manually.\n"
1534 "You can help us by mailing us the output of the following command to "
1535 "flashrom@flashrom.org:\n"
1536 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1537 "Thanks for your help!\n"
1538 "===\n");
1539 }
stugec1e55fe2008-07-02 17:15:47 +00001540
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001541 /* First flash chip detected on this bus. */
1542 if (startchip == 0)
1543 break;
1544 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001545 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001546 break;
1547 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001548notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001549 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001550 free(flash->chip);
1551 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001552 }
uwebe4477b2007-08-23 16:08:21 +00001553
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001554 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001555 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001556
stepan3e7aeae2011-01-19 06:21:54 +00001557
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001558 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001559 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1560 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001561 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001562#if CONFIG_INTERNAL == 1
1563 if (programmer_table[programmer].map_flash_region == physmap)
1564 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1565 PRIxPTR_WIDTH, flash->physical_memory);
1566 else
1567#endif
1568 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001569
Edward O'Callaghana820b212020-09-17 22:53:26 +10001570 /* Flash registers may more likely not be mapped if the chip was forced.
1571 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001572 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001573 if (flash->chip->printlock)
1574 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001575
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001576 /* Get out of the way for later runs. */
1577 unmap_flash(flash);
1578
hailfinger48ed3e22011-05-04 00:39:50 +00001579 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001580 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001581}
1582
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001583static int verify_flash(struct flashctx *flash,
1584 struct action_descriptor *descriptor,
1585 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001586{
hailfingerb0f4d122009-06-24 08:20:45 +00001587 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001588 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001589 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001590
snelsone42c3802010-05-07 20:09:04 +00001591 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001592
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001593 if (verify_it == VERIFY_PARTIAL) {
1594 struct processing_unit *pu = descriptor->processing_units;
1595
1596 /* Verify only areas which were written. */
1597 while (pu->num_blocks) {
1598 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001599 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001600 if (ret)
1601 break;
1602 pu++;
1603 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001604 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001605 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001606 }
uwef6641642007-05-09 10:17:44 +00001607
David Hendricks1ed1d352011-11-23 17:54:37 -08001608 if (ret == ACCESS_DENIED) {
1609 msg_gdbg("Could not fully verify due to access error, ");
1610 if (access_denied_action == error_ignore) {
1611 msg_gdbg("ignoring\n");
1612 ret = 0;
1613 } else {
1614 msg_gdbg("aborting\n");
1615 }
1616 }
1617
hailfingerb0f4d122009-06-24 08:20:45 +00001618 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001619 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001620
hailfingerb0f4d122009-06-24 08:20:45 +00001621 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001622}
1623
uwe8d342eb2011-07-28 08:13:25 +00001624int read_buf_from_file(unsigned char *buf, unsigned long size,
1625 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001626{
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001627#ifdef __LIBPAYLOAD__
1628 msg_gerr("Error: No file I/O support in libpayload\n");
1629 return 1;
1630#else
1631 int ret = 0;
hailfinger771fc182010-10-15 00:01:14 +00001632
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001633 FILE *image;
1634 if ((image = fopen(filename, "rb")) == NULL) {
1635 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger771fc182010-10-15 00:01:14 +00001636 return 1;
1637 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001638
1639 struct stat image_stat;
hailfinger771fc182010-10-15 00:01:14 +00001640 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001641 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1642 ret = 1;
1643 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001644 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001645 if (image_stat.st_size != (intmax_t)size) {
1646 msg_gerr("Error: Image size (%jd B) doesn't match the flash chip's size (%lu B)!\n",
1647 (intmax_t)image_stat.st_size, size);
1648 ret = 1;
1649 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001650 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001651
1652 unsigned long numbytes = fread(buf, 1, size, image);
hailfinger771fc182010-10-15 00:01:14 +00001653 if (numbytes != size) {
1654 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1655 "wanted %ld!\n", numbytes, size);
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001656 ret = 1;
hailfinger771fc182010-10-15 00:01:14 +00001657 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001658out:
1659 (void)fclose(image);
1660 return ret;
1661#endif
hailfinger771fc182010-10-15 00:01:14 +00001662}
1663
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001664int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001665{
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001666#ifdef __LIBPAYLOAD__
1667 msg_gerr("Error: No file I/O support in libpayload\n");
1668 return 1;
1669#else
hailfingerd219a232009-01-28 00:27:54 +00001670 FILE *image;
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001671 int ret = 0;
hailfingerde345862009-06-01 22:07:52 +00001672
1673 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001674 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001675 return 1;
1676 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001677 if ((image = fopen(filename, "wb")) == NULL) {
1678 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger23060112009-05-08 12:49:03 +00001679 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001680 }
hailfingerd219a232009-01-28 00:27:54 +00001681
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001682 unsigned long numbytes = fwrite(buf, 1, size, image);
hailfinger42a850a2010-07-13 23:56:13 +00001683 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001684 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001685 ret = 1;
1686 goto out;
hailfinger42a850a2010-07-13 23:56:13 +00001687 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001688 if (fflush(image)) {
1689 msg_gerr("Error: flushing file \"%s\" failed: %s\n", filename, strerror(errno));
1690 ret = 1;
1691 }
1692 // Try to fsync() only regular files and if that function is available at all (e.g. not on MinGW).
1693#if defined(_POSIX_FSYNC) && (_POSIX_FSYNC != -1)
1694 struct stat image_stat;
1695 if (fstat(fileno(image), &image_stat) != 0) {
1696 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1697 ret = 1;
1698 goto out;
1699 }
1700 if (S_ISREG(image_stat.st_mode)) {
1701 if (fsync(fileno(image))) {
1702 msg_gerr("Error: fsyncing file \"%s\" failed: %s\n", filename, strerror(errno));
1703 ret = 1;
1704 }
1705 }
1706#endif
1707out:
1708 if (fclose(image)) {
1709 msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
1710 ret = 1;
1711 }
1712 return ret;
1713#endif
hailfingerd219a232009-01-28 00:27:54 +00001714}
1715
David Hendrickse3451942013-03-21 17:23:29 -07001716/*
1717 * read_flash - wrapper for flash->read() with additional high-level policy
1718 *
1719 * @flash flash chip
1720 * @buf buffer to store data in
1721 * @start start address
1722 * @len number of bytes to read
1723 *
1724 * This wrapper simplifies most cases when the flash chip needs to be read
1725 * since policy decisions such as non-fatal error handling is centralized.
1726 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001727int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001728 unsigned int start, unsigned int len)
1729{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001730 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001731
Patrick Georgif3fa2992017-02-02 16:24:44 +01001732 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001733 return -1;
1734
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001735 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1736
Patrick Georgif3fa2992017-02-02 16:24:44 +01001737 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001738 if (ret) {
1739 if (ignore_error(ret)) {
1740 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1741 start, start + len - 1);
1742 ret = 0;
1743 } else {
1744 msg_gdbg("failed to read 0x%x-0x%x\n",
1745 start, start + len - 1);
1746 }
1747 }
1748
1749 return ret;
1750}
1751
David Hendricks7c8a1612013-04-26 19:14:44 -07001752/*
1753 * write_flash - wrapper for flash->write() with additional high-level policy
1754 *
1755 * @flash flash chip
1756 * @buf buffer to write to flash
1757 * @start start address in flash
1758 * @len number of bytes to write
1759 *
1760 * TODO: Look up regions that are write-protected and avoid attempt to write
1761 * to them at all.
1762 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001763int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001764 unsigned int start, unsigned int len)
1765{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001766 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001767 return -1;
1768
Patrick Georgif3fa2992017-02-02 16:24:44 +01001769 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001770}
1771
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001772int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001773{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001774 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001775 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001776 int ret = 0;
1777
1778 msg_cinfo("Reading flash... ");
1779 if (!buf) {
1780 msg_gerr("Memory allocation failed!\n");
1781 msg_cinfo("FAILED.\n");
1782 return 1;
1783 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001784
1785 /* To support partial read, fill buffer to all 0xFF at beginning to make
1786 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001787 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001788
Patrick Georgif3fa2992017-02-02 16:24:44 +01001789 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001790 msg_cerr("No read function available for this flash chip.\n");
1791 ret = 1;
1792 goto out_free;
1793 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001794
1795 /* First try to handle partial read case, rather than read the whole
1796 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001797 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001798 if (ret < 0) {
1799 msg_cerr("Partial read operation failed!\n");
1800 ret = 1;
1801 goto out_free;
1802 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001803 int num_regions = get_num_include_args();
1804
1805 if (ret != num_regions) {
1806 msg_cerr("Requested %d regions, but only read %d\n",
1807 num_regions, ret);
1808 ret = 1;
1809 goto out_free;
1810 }
1811
1812 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001813 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001814 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001815 msg_cerr("Read operation failed!\n");
1816 ret = 1;
1817 goto out_free;
1818 }
hailfinger42a850a2010-07-13 23:56:13 +00001819 }
1820
David Hendricksdf29a832013-06-28 14:33:51 -07001821 if (filename)
1822 ret = write_buf_to_file(buf, size, filename);
1823
hailfinger42a850a2010-07-13 23:56:13 +00001824out_free:
1825 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001826 if (ret)
1827 msg_cerr("FAILED.");
1828 else
1829 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001830 return ret;
1831}
1832
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001833/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001834static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001835{
hailfingerb91c08c2011-08-15 19:54:20 +00001836 int i, j, k;
1837 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001838
1839 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1840 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001841 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001842
1843 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1844 /* Blocks with zero size are bugs in flashchips.c. */
1845 if (eraser.eraseblocks[i].count &&
1846 !eraser.eraseblocks[i].size) {
1847 msg_gerr("ERROR: Flash chip %s erase function "
1848 "%i region %i has size 0. Please report"
1849 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001850 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001851 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001852 }
1853 /* Blocks with zero count are bugs in flashchips.c. */
1854 if (!eraser.eraseblocks[i].count &&
1855 eraser.eraseblocks[i].size) {
1856 msg_gerr("ERROR: Flash chip %s erase function "
1857 "%i region %i has count 0. Please report"
1858 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001859 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001860 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001861 }
1862 done += eraser.eraseblocks[i].count *
1863 eraser.eraseblocks[i].size;
1864 }
hailfinger9fed35d2010-01-19 06:42:46 +00001865 /* Empty eraseblock definition with erase function. */
1866 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001867 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001868 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001869 if (!done)
1870 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001871 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001872 msg_gerr("ERROR: Flash chip %s erase function %i "
1873 "region walking resulted in 0x%06x bytes total,"
1874 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001875 " flashrom@flashrom.org\n", chip->name, k,
1876 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001877 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001878 }
hailfinger9fed35d2010-01-19 06:42:46 +00001879 if (!eraser.block_erase)
1880 continue;
1881 /* Check if there are identical erase functions for different
1882 * layouts. That would imply "magic" erase functions. The
1883 * easiest way to check this is with function pointers.
1884 */
uwef6f94d42010-03-13 17:28:29 +00001885 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001886 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001887 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001888 msg_gerr("ERROR: Flash chip %s erase function "
1889 "%i and %i are identical. Please report"
1890 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001891 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001892 ret = 1;
1893 }
uwef6f94d42010-03-13 17:28:29 +00001894 }
hailfinger45177872010-01-18 08:14:43 +00001895 }
hailfinger9fed35d2010-01-19 06:42:46 +00001896 return ret;
hailfinger45177872010-01-18 08:14:43 +00001897}
1898
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001899static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001900 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001901 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001902 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001903 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001904 unsigned int addr,
1905 unsigned int len))
1906{
stefanctc5eb8a92011-11-23 09:13:48 +00001907 unsigned int starthere = 0, lenhere = 0;
1908 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001909 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001910 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001911
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001912 /*
1913 * curcontents and newcontents are opaque to walk_eraseregions, and
1914 * need to be adjusted here to keep the impression of proper
1915 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001916 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001917
hailfinger90fcf9b2010-11-05 14:51:59 +00001918 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001919
hailfingerb437e282010-11-04 01:04:27 +00001920 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001921
hailfingerb437e282010-11-04 01:04:27 +00001922 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001923 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001924 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001925 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001926 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001927 if (ret) {
1928 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001929 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001930 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001931 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001932 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001933 }
1934
David Hendricks0954ffc2015-11-13 15:15:44 -08001935 if (programmer_table[programmer].paranoid) {
1936 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001937 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001938 return -1;
1939 }
hailfingerac8e3182011-06-26 17:04:16 +00001940 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001941
hailfinger90fcf9b2010-11-05 14:51:59 +00001942 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001943 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001944 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001945 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001946 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001947 /* get_next_write() sets starthere to a new value after the call. */
1948 while ((lenhere = get_next_write(curcontents + starthere,
1949 newcontents + starthere,
1950 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001951 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001952 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001953 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001954 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001955 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001956 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001957 if (ret) {
1958 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001959 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001960 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001961 }
David Hendricks048b38c2016-03-28 18:47:06 -07001962
1963 /*
1964 * If the block needed to be erased and was erased successfully
1965 * then we can assume that we didn't run into any write-
1966 * protected areas. Otherwise, we need to verify each page to
1967 * ensure it was successfully written and abort if we encounter
1968 * any errors.
1969 */
1970 if (programmer_table[programmer].paranoid && !block_was_erased) {
1971 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001972 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001973 return -1;
1974 }
1975
hailfingerb437e282010-11-04 01:04:27 +00001976 starthere += lenhere;
1977 skip = 0;
1978 }
1979 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001980 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001981 return ret;
1982}
1983
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001984/*
1985 * Function to process processing units accumulated in the action descriptor.
1986 *
1987 * @flash pointer to the flash context to operate on
1988 * @do_something helper function which can erase and program a section of the
1989 * flash chip. It receives the flash context, offset and length
1990 * of the area to erase/program, before and after contents (to
1991 * decide what exactly needs to be erased and or programmed)
1992 * and a pointer to the erase function which can operate on the
1993 * proper granularity.
1994 * @descriptor action descriptor including pointers to before and after
1995 * contents and an array of processing actions to take.
1996 *
1997 * Returns zero on success or an error code.
1998 */
1999static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002000 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00002001 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00002002 unsigned int len,
2003 uint8_t *param1,
2004 uint8_t *param2,
2005 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002006 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00002007 unsigned int addr,
2008 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002009 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00002010{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002011 struct processing_unit *pu;
2012 int rc = 0;
2013 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00002014
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002015 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
2016 unsigned base = pu->offset;
2017 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07002018
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002019 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07002020
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002021 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00002022 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002023 else
2024 print_comma = 1;
2025
2026 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
2027
2028 rc = do_something(flash, base,
2029 pu->block_size,
2030 descriptor->oldcontents,
2031 descriptor->newcontents,
2032 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
2033
David Hendricks1ed1d352011-11-23 17:54:37 -08002034 if (rc) {
2035 if (ignore_error(rc))
2036 rc = 0;
2037 else
2038 return rc;
hailfingerb437e282010-11-04 01:04:27 +00002039 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002040 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00002041 }
2042 }
hailfingerb437e282010-11-04 01:04:27 +00002043 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08002044 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00002045}
2046
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002047static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00002048{
Patrick Georgif3fa2992017-02-02 16:24:44 +01002049 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00002050
2051 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
2052 if (log)
2053 msg_cdbg("not defined. ");
2054 return 1;
2055 }
2056 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
2057 if (log)
2058 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00002059 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00002060 return 1;
2061 }
2062 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
2063 if (log)
2064 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00002065 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00002066 return 1;
2067 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002068 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002069 return 0;
2070}
2071
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002072int erase_and_write_flash(struct flashctx *flash,
2073 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002074{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002075 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002076
hailfingercf848f12010-12-05 15:14:44 +00002077 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002078
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002079 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002080
hailfinger7df21362009-09-05 02:30:58 +00002081 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002082 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002083 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002084 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002085 }
2086 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002087}
2088
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002089static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002090{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002091 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2092#if CONFIG_INTERNAL == 1
2093 if (programmer == PROGRAMMER_INTERNAL)
2094 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2095 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2096 "mail flashrom@flashrom.org, thanks!\n"
2097 "-------------------------------------------------------------------------------\n"
2098 "You may now reboot or simply leave the machine running.\n");
2099 else
2100#endif
2101 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2102 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2103 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2104 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002105}
2106
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002107static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002108{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002109 msg_gerr("Your flash chip is in an unknown state.\n");
2110#if CONFIG_INTERNAL == 1
2111 if (programmer == PROGRAMMER_INTERNAL)
2112 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2113 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2114 "-------------------------------------------------------------------------------\n"
2115 "DO NOT REBOOT OR POWEROFF!\n");
2116 else
2117#endif
2118 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2119 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002120}
2121
hailfingerf79d1712010-10-06 23:48:34 +00002122void list_programmers_linebreak(int startcol, int cols, int paren)
2123{
2124 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002125 int pnamelen;
2126 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002127 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002128 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002129
2130 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2131 pname = programmer_table[p].name;
2132 pnamelen = strlen(pname);
2133 if (remaining - pnamelen - 2 < 0) {
2134 if (firstline)
2135 firstline = 0;
2136 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002137 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002138 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002139 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002140 remaining = cols - startcol;
2141 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002142 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002143 remaining--;
2144 }
2145 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002146 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002147 remaining--;
2148 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002149 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002150 remaining -= pnamelen;
2151 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002152 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002153 remaining--;
2154 } else {
2155 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002156 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002157 }
2158 }
2159}
2160
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002161static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002162{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002163#if IS_WINDOWS
2164 SYSTEM_INFO si;
2165 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002166
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002167 memset(&si, 0, sizeof(SYSTEM_INFO));
2168 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2169 msg_ginfo(" on Windows");
2170 /* Tell Windows which version of the structure we want. */
2171 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2172 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2173 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2174 else
2175 msg_ginfo(" unknown version");
2176 GetSystemInfo(&si);
2177 switch (si.wProcessorArchitecture) {
2178 case PROCESSOR_ARCHITECTURE_AMD64:
2179 msg_ginfo(" (x86_64)");
2180 break;
2181 case PROCESSOR_ARCHITECTURE_INTEL:
2182 msg_ginfo(" (x86)");
2183 break;
2184 default:
2185 msg_ginfo(" (unknown arch)");
2186 break;
2187 }
2188#elif HAVE_UTSNAME == 1
2189 struct utsname osinfo;
2190
2191 uname(&osinfo);
2192 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002193 osinfo.machine);
2194#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002195 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002196#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002197}
2198
2199void print_buildinfo(void)
2200{
2201 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002202#if NEED_PCI == 1
2203#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002204 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002205#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002206 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002207#endif
2208#endif
2209#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002210 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002211#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002212 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002213#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002214 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002215#endif
hailfinger3b471632010-03-27 16:36:40 +00002216#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002217 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002218#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002219 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002220#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002221 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002222#endif
2223#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002224 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002225#endif
2226#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002227 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00002228#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002229 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00002230#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002231 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002232}
2233
uwefdeca092008-01-21 15:24:22 +00002234void print_version(void)
2235{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002236 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002237 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002238 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002239}
2240
hailfinger74819ad2010-05-15 15:04:37 +00002241void print_banner(void)
2242{
2243 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002244 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002245 msg_ginfo("\n");
2246}
2247
hailfingerc77acb52009-12-24 02:15:55 +00002248int selfcheck(void)
2249{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002250 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002251 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002252
2253 /* Safety check. Instead of aborting after the first error, check
2254 * if more errors exist.
2255 */
hailfingerc77acb52009-12-24 02:15:55 +00002256 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002257 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002258 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002259 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002260 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2261 const struct programmer_entry p = programmer_table[i];
2262 if (p.name == NULL) {
2263 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2264 ret = 1;
2265 /* This might hide other problems with this programmer, but allows for better error
2266 * messages below without jumping through hoops. */
2267 continue;
2268 }
2269 switch (p.type) {
2270 case USB:
2271 case PCI:
2272 case OTHER:
2273 if (p.devs.note == NULL) {
2274 if (strcmp("internal", p.name) == 0)
2275 break; /* This one has its device list stored separately. */
2276 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2277 p.name);
2278 ret = 1;
2279 }
2280 break;
2281 default:
2282 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2283 ret = 1;
2284 break;
2285 }
2286 if (p.init == NULL) {
2287 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2288 ret = 1;
2289 }
2290 if (p.delay == NULL) {
2291 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2292 ret = 1;
2293 }
2294 if (p.map_flash_region == NULL) {
2295 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2296 ret = 1;
2297 }
2298 if (p.unmap_flash_region == NULL) {
2299 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2300 ret = 1;
2301 }
2302 }
2303
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002304 /* It would be favorable if we could check for the correct layout (especially termination) of various
2305 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2306 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2307 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2308 * 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 +10002309 * checks below. */
2310 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002311 msg_gerr("Flashchips table miscompilation!\n");
2312 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002313 } else {
2314 for (i = 0; i < flashchips_size - 1; i++) {
2315 const struct flashchip *chip = &flashchips[i];
2316 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2317 ret = 1;
2318 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2319 "Please report a bug at flashrom@flashrom.org\n", i,
2320 chip->name == NULL ? "unnamed" : chip->name);
2321 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002322 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002323 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002324 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002325 }
stefanct6d836ba2011-05-26 01:35:19 +00002326 }
stefanct6d836ba2011-05-26 01:35:19 +00002327
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002328 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002329 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002330}
2331
hailfinger771fc182010-10-15 00:01:14 +00002332/* FIXME: This function signature needs to be improved once doit() has a better
2333 * function signature.
2334 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002335static int chip_safety_check(const struct flashctx *flash, int force,
2336 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002337{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002338 const struct flashchip *chip = flash->chip;
2339
hailfinger771fc182010-10-15 00:01:14 +00002340 if (!programmer_may_write && (write_it || erase_it)) {
2341 msg_perr("Write/erase is not working yet on your programmer in "
2342 "its current configuration.\n");
2343 /* --force is the wrong approach, but it's the best we can do
2344 * until the generic programmer parameter parser is merged.
2345 */
2346 if (!force)
2347 return 1;
2348 msg_cerr("Continuing anyway.\n");
2349 }
2350
2351 if (read_it || erase_it || write_it || verify_it) {
2352 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002353 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002354 msg_cerr("Read is not working on this chip. ");
2355 if (!force)
2356 return 1;
2357 msg_cerr("Continuing anyway.\n");
2358 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002359 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002360 msg_cerr("flashrom has no read function for this "
2361 "flash chip.\n");
2362 return 1;
2363 }
2364 }
2365 if (erase_it || write_it) {
2366 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002367 if (chip->tested.erase == NA) {
2368 msg_cerr("Erase is not possible on this chip.\n");
2369 return 1;
2370 }
2371 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002372 msg_cerr("Erase is not working on this chip. ");
2373 if (!force)
2374 return 1;
2375 msg_cerr("Continuing anyway.\n");
2376 }
stefancte1c5acf2011-07-04 07:27:17 +00002377 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002378 msg_cerr("flashrom has no erase function for this "
2379 "flash chip.\n");
2380 return 1;
2381 }
hailfinger771fc182010-10-15 00:01:14 +00002382 }
2383 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002384 if (chip->tested.write == NA) {
2385 msg_cerr("Write is not possible on this chip.\n");
2386 return 1;
2387 }
2388 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002389 msg_cerr("Write is not working on this chip. ");
2390 if (!force)
2391 return 1;
2392 msg_cerr("Continuing anyway.\n");
2393 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002394 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002395 msg_cerr("flashrom has no write function for this "
2396 "flash chip.\n");
2397 return 1;
2398 }
2399 }
2400 return 0;
2401}
2402
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002403int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002404 const bool read_it, const bool write_it,
2405 const bool erase_it, const bool verify_it)
2406{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002407 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002408 msg_cerr("Aborting.\n");
2409 return 1;
2410 }
2411
2412 if (normalize_romentries(flash)) {
2413 msg_cerr("Requested regions can not be handled. Aborting.\n");
2414 return 1;
2415 }
2416
Edward O'Callaghan40092972020-10-20 11:50:48 +11002417 /*
2418 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2419 * can be repro'ed with upstream on Volteer.
2420 *
2421 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2422 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2423 * hooked and this can fail on some board topologies. Checking the return value can
2424 * cause board rw failures by bailing early. Avoid the early bail for now until a
2425 * full investigation can reveal the proper fix. This restores previous behaviour of
2426 * assuming a map went fine.
2427 */
2428#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002429 if (map_flash(flash) != 0)
2430 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002431#endif
2432 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002433
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002434 /* Given the existence of read locks, we want to unlock for read,
2435 erase and write. */
2436 if (flash->chip->unlock)
2437 flash->chip->unlock(flash);
2438
2439 flash->address_high_byte = -1;
2440 flash->in_4ba_mode = false;
2441
2442 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2443 if ((flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN) && flash->chip->set_4ba) {
2444 if (flash->chip->set_4ba(flash)) {
2445 msg_cerr("Enabling/disabling 4-byte addressing mode failed!\n");
2446 return 1;
2447 }
2448 }
2449
2450 return 0;
2451}
2452
Edward O'Callaghana820b212020-09-17 22:53:26 +10002453void finalize_flash_access(struct flashctx *const flash)
2454{
2455 unmap_flash(flash);
2456}
2457
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002458/*
2459 * Function to erase entire flash chip.
2460 *
2461 * @flashctx pointer to the flash context to use
2462 * @oldcontents pointer to the buffer including current chip contents, to
2463 * decide which areas do in fact need to be erased
2464 * @size the size of the flash chip, in bytes.
2465 *
2466 * Returns zero on success or an error code.
2467 */
2468static int erase_chip(struct flashctx *flash, void *oldcontents,
2469 void *newcontents, size_t size)
2470{
2471 /*
2472 * To make sure that the chip is fully erased, let's cheat and create
2473 * a descriptor where the new contents are all erased.
2474 */
2475 struct action_descriptor *fake_descriptor;
2476 int ret = 0;
2477
2478 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2479 newcontents, 1);
2480 /* FIXME: Do we really want the scary warning if erase failed? After
2481 * all, after erase the chip is either blank or partially blank or it
2482 * has the old contents. A blank chip won't boot, so if the user
2483 * wanted erase and reboots afterwards, the user knows very well that
2484 * booting won't work.
2485 */
2486 if (erase_and_write_flash(flash, fake_descriptor)) {
2487 emergency_help_message();
2488 ret = 1;
2489 }
2490
2491 free(fake_descriptor);
2492
2493 return ret;
2494}
2495
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002496static int read_dest_content(struct flashctx *flash, int verify_it,
2497 uint8_t *dest, unsigned long size)
2498{
2499 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2500 && get_num_include_args()) {
2501 /*
2502 * If no full verification is required and not
2503 * the entire chip is about to be programmed,
2504 * read only the areas which might change.
2505 */
2506 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2507 return 1;
2508 } else {
2509 if (read_flash(flash, dest, 0, size))
2510 return 1;
2511 }
2512 return 0;
2513}
2514
hailfingerc77acb52009-12-24 02:15:55 +00002515/* This function signature is horrible. We need to design a better interface,
2516 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002517 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002518 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002519int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002520 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002521 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002522{
hailfinger4c47e9d2010-10-19 22:06:20 +00002523 uint8_t *oldcontents;
2524 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002525 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002526 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002527 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002528
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002529 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002530 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002531 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002532
Simon Glass9ad06c12013-07-03 22:08:17 +09002533 if (extract_it) {
2534 ret = extract_regions(flash);
2535 goto out_nofree;
2536 }
2537
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002538 /* mark entries included using -i argument as "included" if they are
2539 found in the master rom_entries list */
2540 if (process_include_args() < 0) {
2541 ret = 1;
2542 goto out_nofree;
2543 }
2544
hailfinger771fc182010-10-15 00:01:14 +00002545 if (read_it) {
2546 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002547 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002548 }
hailfingerb437e282010-11-04 01:04:27 +00002549
stefanctd611e8f2011-07-12 22:35:21 +00002550 oldcontents = malloc(size);
2551 if (!oldcontents) {
2552 msg_gerr("Out of memory!\n");
2553 exit(1);
2554 }
Simon Glass4c214132013-07-16 10:09:28 -06002555 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002556 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002557 newcontents = malloc(size);
2558 if (!newcontents) {
2559 msg_gerr("Out of memory!\n");
2560 exit(1);
2561 }
Simon Glass4c214132013-07-16 10:09:28 -06002562 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002563 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002564 /* Side effect of the assumptions above: Default write action is erase
2565 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002566 * oldcontents being completely unerased means we have to erase
2567 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002568 */
2569
hailfingerd217d122010-10-08 18:52:29 +00002570 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002571 /*
2572 * Note: This must be done before any files specified by -i
2573 * arguments are processed merged into the newcontents since
2574 * -i files take priority. See http://crbug.com/263495.
2575 */
2576 if (filename) {
2577 if (read_buf_from_file(newcontents, size, filename)) {
2578 ret = 1;
2579 goto out;
2580 }
2581 } else {
2582 /* Content will be read from -i args, so they must
2583 * not overlap. */
2584 if (included_regions_overlap()) {
2585 msg_gerr("Error: Included regions must "
2586 "not overlap.\n");
2587 ret = 1;
2588 goto out;
2589 }
stepan1da96c02006-11-21 23:48:51 +00002590 }
ollie5672ac62004-03-17 22:22:08 +00002591 }
2592
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002593 if (do_diff) {
2594 /*
2595 * Obtain a reference image so that we can check whether
2596 * regions need to be erased and to give better diagnostics in
2597 * case write fails. If --fast-verify is used then only the
2598 * regions which are included using -i will be read.
2599 */
2600 if (diff_file) {
2601 msg_cdbg("Reading old contents from file... ");
2602 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002603 ret = 1;
2604 msg_cdbg("FAILED.\n");
2605 goto out;
2606 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002607 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002608 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002609 ret = read_dest_content(flash, verify_it,
2610 oldcontents, size);
2611 if (ret) {
2612 msg_cdbg("FAILED.\n");
2613 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002614 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002615 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002616 msg_cdbg("done.\n");
2617 } else if (!erase_it) {
2618 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002619 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002620 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002621
David Hendricksdf29a832013-06-28 14:33:51 -07002622 /*
2623 * Note: This must be done after reading the file specified for the
2624 * -w/-v argument, if any, so that files specified using -i end up
2625 * in the "newcontents" buffer before being written.
2626 * See http://crbug.com/263495.
2627 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002628 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002629 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002630 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002631 goto out;
2632 }
uwef6641642007-05-09 10:17:44 +00002633
David Hendricksa7e114b2016-02-26 18:49:15 -08002634 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002635 erase_chip(flash, oldcontents, newcontents, size);
2636 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002637 }
2638
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002639 descriptor = prepare_action_descriptor(flash, oldcontents,
2640 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002641 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002642 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002643 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002644 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002645 goto out;
2646 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002647
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002648 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002649 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2650 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002651 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002652 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002653 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002654 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002655 ret = 1;
2656 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002657 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002658 msg_cerr("Apparently at least some data has changed.\n");
2659 } else
2660 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002661 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002662 ret = 1;
2663 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002664 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002665
David Hendricksac1d25c2016-08-09 17:00:58 -07002666 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002667 if (ret < 0) {
2668 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002669 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002670 emergency_help_message();
2671 ret = 1;
2672 goto out;
2673 } else if (ret > 0) {
2674 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002675 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002676 ret = read_dest_content(flash, verify_it,
2677 oldcontents, size);
2678 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002679 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002680 goto out;
2681 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002682
2683 /* Get a new descriptor. */
2684 free(descriptor);
2685 descriptor = prepare_action_descriptor(flash,
2686 oldcontents,
2687 newcontents,
2688 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002689 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002690 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002691 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002692 emergency_help_message();
2693 ret = 1;
2694 goto out;
2695 }
2696 ret = 0;
2697 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002698
David Hendricksac1d25c2016-08-09 17:00:58 -07002699 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002700 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002701 emergency_help_message();
2702 ret = 1;
2703 goto out;
2704 }
stuge8ce3a3c2008-04-28 14:47:30 +00002705 }
ollie6a600992005-11-26 21:55:36 +00002706
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002707 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002708 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002709 if ((write_it || erase_it) && !content_has_changed) {
2710 msg_gdbg("Nothing was erased or written, skipping "
2711 "verification\n");
2712 } else {
2713 /* Work around chips which need some time to calm down. */
2714 if (write_it && verify_it != VERIFY_PARTIAL)
2715 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002716
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002717 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002718
David Hendricks9ba79fb2015-04-03 12:06:16 -07002719 /* If we tried to write, and verification now fails, we
2720 * might have an emergency situation.
2721 */
2722 if (ret && write_it)
2723 emergency_help_message();
2724 }
hailfinger0459e1c2009-08-19 13:55:34 +00002725 }
ollie6a600992005-11-26 21:55:36 +00002726
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002727 finalize_flash_access(flash);
2728
hailfinger90fcf9b2010-11-05 14:51:59 +00002729out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002730 if (descriptor)
2731 free(descriptor);
2732
hailfinger90fcf9b2010-11-05 14:51:59 +00002733 free(oldcontents);
2734 free(newcontents);
2735out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002736 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002737 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002738 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002739 * tree. This is because some operations, such as write protection,
2740 * requires programmer_shutdown() but does not call doit().
2741 */
2742// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002743 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002744}