blob: 06a368b219528bfc3a2947f6eed6086bfd9c90fb [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 }
dhendrix0ffc2eb2011-06-14 01:35:36 +0000727 return ret;
uweabe92a52009-05-16 22:36:00 +0000728}
729
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000730void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000731{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000732 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
733 return ret;
uweabe92a52009-05-16 22:36:00 +0000734}
735
736void programmer_unmap_flash_region(void *virt_addr, size_t len)
737{
738 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000739 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000740}
741
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700742void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000743{
Craig Hesling65eb8812019-08-01 09:33:56 -0700744 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000745}
746
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700747void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000748{
Craig Hesling65eb8812019-08-01 09:33:56 -0700749 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000750}
751
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700752void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000753{
Craig Hesling65eb8812019-08-01 09:33:56 -0700754 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000755}
756
Stuart langleyc98e43f2020-03-26 20:27:36 +1100757void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000758{
Craig Hesling65eb8812019-08-01 09:33:56 -0700759 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000760}
761
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700762uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000763{
Craig Hesling65eb8812019-08-01 09:33:56 -0700764 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000765}
766
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700767uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000768{
Craig Hesling65eb8812019-08-01 09:33:56 -0700769 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000770}
771
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700772uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000773{
Craig Hesling65eb8812019-08-01 09:33:56 -0700774 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000775}
776
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000777void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
778 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000779{
Craig Hesling65eb8812019-08-01 09:33:56 -0700780 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000781}
782
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000783void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000784{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000785 if (usecs > 0)
786 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000787}
788
Edward O'Callaghana820b212020-09-17 22:53:26 +1000789int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
790 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000791{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700792 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000793
hailfinger23060112009-05-08 12:49:03 +0000794 return 0;
795}
796
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000797/* This is a somewhat hacked function similar in some ways to strtok().
798 * It will look for needle with a subsequent '=' in haystack, return a copy of
799 * needle and remove everything from the first occurrence of needle to the next
800 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000801 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000802char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000803{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000804 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000805 char *opt = NULL;
806 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000807 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000808
hailfingerf4aaccc2010-04-28 15:22:14 +0000809 needlelen = strlen(needle);
810 if (!needlelen) {
811 msg_gerr("%s: empty needle! Please report a bug at "
812 "flashrom@flashrom.org\n", __func__);
813 return NULL;
814 }
815 /* No programmer parameters given. */
816 if (*haystack == NULL)
817 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000818 param_pos = strstr(*haystack, needle);
819 do {
820 if (!param_pos)
821 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000822 /* Needle followed by '='? */
823 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000824 /* Beginning of the string? */
825 if (param_pos == *haystack)
826 break;
827 /* After a delimiter? */
828 if (strchr(delim, *(param_pos - 1)))
829 break;
830 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000831 /* Continue searching. */
832 param_pos++;
833 param_pos = strstr(param_pos, needle);
834 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000835
hailfinger6e5a52a2009-11-24 18:27:10 +0000836 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000837 /* Get the string after needle and '='. */
838 opt_pos = param_pos + needlelen + 1;
839 optlen = strcspn(opt_pos, delim);
840 /* Return an empty string if the parameter was empty. */
841 opt = malloc(optlen + 1);
842 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000843 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000844 exit(1);
845 }
hailfinger1ef766d2010-07-06 09:55:48 +0000846 strncpy(opt, opt_pos, optlen);
847 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000848 rest = opt_pos + optlen;
849 /* Skip all delimiters after the current parameter. */
850 rest += strspn(rest, delim);
851 memmove(param_pos, rest, strlen(rest) + 1);
852 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000853 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000854
hailfinger1ef766d2010-07-06 09:55:48 +0000855 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000856}
857
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000858char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000859{
860 return extract_param(&programmer_param, param_name, ",");
861}
862
stefancte1c5acf2011-07-04 07:27:17 +0000863/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700864static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000865{
866 unsigned int usable_erasefunctions = 0;
867 int k;
868 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
869 if (!check_block_eraser(flash, k, 0))
870 usable_erasefunctions++;
871 }
872 return usable_erasefunctions;
873}
874
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000875static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700876{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000877 int ret = 0, failcount = 0;
878 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700879 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000880 if (wantbuf[i] != havebuf[i]) {
881 /* Only print the first failure. */
882 if (!failcount++)
883 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
884 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700885 }
886 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000887 if (failcount) {
888 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
889 start, start + len - 1, failcount);
890 ret = -1;
891 }
892 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700893}
894
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000895/* start is an offset to the base address of the flash chip */
896static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
897{
898 int ret;
899 uint8_t *cmpbuf = malloc(len);
900 const uint8_t erased_value = ERASED_VALUE(flash);
901
902 if (!cmpbuf) {
903 msg_gerr("Could not allocate memory!\n");
904 exit(1);
905 }
906 memset(cmpbuf, erased_value, len);
907 ret = verify_range(flash, cmpbuf, start, len);
908 free(cmpbuf);
909 return ret;
910}
911
uwee15beb92010-08-08 17:01:18 +0000912/*
hailfinger7af3d192009-11-25 17:05:52 +0000913 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000914 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000915 * @start offset to the base address of the flash chip
916 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000917 * @return 0 for success, -1 for failure
918 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000919int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000920{
hailfinger7af83692009-06-15 17:23:36 +0000921 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000922 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000923
Patrick Georgif3fa2992017-02-02 16:24:44 +0100924 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000925 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000926 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000927 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000928
929 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000930 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000931 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000932 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000933 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000934 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000935
Patrick Georgif3fa2992017-02-02 16:24:44 +0100936 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000937 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000938 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100939 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000940 ret = -1;
941 goto out_free;
942 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700943 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700944 if (programmer_table[programmer].paranoid) {
945 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800946
Simon Glass4e305f42015-01-08 06:29:04 -0700947 /* limit chunksize in order to catch errors early */
948 for (i = 0, chunksize = 0; i < len; i += chunksize) {
949 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800950
Patrick Georgif3fa2992017-02-02 16:24:44 +0100951 chunksize = min(flash->chip->page_size, len - i);
952 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700953 if (tmp) {
954 ret = tmp;
955 if (ignore_error(tmp))
956 continue;
957 else
958 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800959 }
Simon Glass4e305f42015-01-08 06:29:04 -0700960
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700961 /*
962 * Check write access permission and do not compare chunks
963 * where flashrom does not have write access to the region.
964 */
965 if (flash->chip->check_access) {
966 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
967 if (tmp && ignore_error(tmp))
968 continue;
969 }
970
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000971 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700972 if (failcount)
973 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800974 }
Simon Glass4e305f42015-01-08 06:29:04 -0700975 } else {
976 int tmp;
977
978 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +0100979 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -0700980 if (tmp && !ignore_error(tmp)) {
981 ret = tmp;
982 goto out_free;
983 }
984
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000985 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +0000986 }
987
hailfinger5be6c0f2009-07-23 01:42:56 +0000988 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +0000989 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +0000990 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +0000991 ret = -1;
992 }
hailfinger7af83692009-06-15 17:23:36 +0000993
994out_free:
995 free(readbuf);
996 return ret;
997}
998
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100999/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1000static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001001 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001002{
1003 unsigned int i, j, limit;
1004 for (j = 0; j < len / gran; j++) {
1005 limit = min (gran, len - j * gran);
1006 /* Are 'have' and 'want' identical? */
1007 if (!memcmp(have + j * gran, want + j * gran, limit))
1008 continue;
1009 /* have needs to be in erased state. */
1010 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001011 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001012 return 1;
1013 }
1014 return 0;
1015}
1016
uwee15beb92010-08-08 17:01:18 +00001017/*
hailfingerb247c7a2010-03-08 00:42:32 +00001018 * Check if the buffer @have can be programmed to the content of @want without
1019 * erasing. This is only possible if all chunks of size @gran are either kept
1020 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001021 *
hailfingerb437e282010-11-04 01:04:27 +00001022 * Warning: This function assumes that @have and @want point to naturally
1023 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001024 *
1025 * @have buffer with current content
1026 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001027 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001028 * @gran write granularity (enum, not count)
1029 * @return 0 if no erase is needed, 1 otherwise
1030 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001031int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1032 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001033{
hailfingerb91c08c2011-08-15 19:54:20 +00001034 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001035 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001036
hailfingerb247c7a2010-03-08 00:42:32 +00001037 switch (gran) {
1038 case write_gran_1bit:
1039 for (i = 0; i < len; i++)
1040 if ((have[i] & want[i]) != want[i]) {
1041 result = 1;
1042 break;
1043 }
1044 break;
1045 case write_gran_1byte:
1046 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001047 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001048 result = 1;
1049 break;
1050 }
1051 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001052 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001053 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001054 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001055 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001056 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001057 break;
1058 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001059 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001060 break;
1061 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001062 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001063 break;
1064 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001065 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001066 break;
1067 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001068 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001069 break;
1070 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001071 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001072 break;
1073 case write_gran_1byte_implicit_erase:
1074 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1075 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001076 break;
hailfingerb437e282010-11-04 01:04:27 +00001077 default:
1078 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1079 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001080 }
1081 return result;
1082}
1083
hailfingerb437e282010-11-04 01:04:27 +00001084/**
1085 * Check if the buffer @have needs to be programmed to get the content of @want.
1086 * If yes, return 1 and fill in first_start with the start address of the
1087 * write operation and first_len with the length of the first to-be-written
1088 * chunk. If not, return 0 and leave first_start and first_len undefined.
1089 *
1090 * Warning: This function assumes that @have and @want point to naturally
1091 * aligned regions.
1092 *
1093 * @have buffer with current content
1094 * @want buffer with desired content
1095 * @len length of the checked area
1096 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001097 * @first_start offset of the first byte which needs to be written (passed in
1098 * value is increased by the offset of the first needed write
1099 * relative to have/want or unchanged if no write is needed)
1100 * @return length of the first contiguous area which needs to be written
1101 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001102 *
1103 * FIXME: This function needs a parameter which tells it about coalescing
1104 * in relation to the max write length of the programmer and the max write
1105 * length of the chip.
1106 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001107static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001108 unsigned int *first_start,
1109 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001110{
stefanctc5eb8a92011-11-23 09:13:48 +00001111 int need_write = 0;
1112 unsigned int rel_start = 0, first_len = 0;
1113 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001114
hailfingerb437e282010-11-04 01:04:27 +00001115 switch (gran) {
1116 case write_gran_1bit:
1117 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001118 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001119 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001120 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001121 case write_gran_128bytes:
1122 stride = 128;
1123 break;
hailfingerb437e282010-11-04 01:04:27 +00001124 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001125 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001126 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001127 case write_gran_264bytes:
1128 stride = 264;
1129 break;
1130 case write_gran_512bytes:
1131 stride = 512;
1132 break;
1133 case write_gran_528bytes:
1134 stride = 528;
1135 break;
1136 case write_gran_1024bytes:
1137 stride = 1024;
1138 break;
1139 case write_gran_1056bytes:
1140 stride = 1056;
1141 break;
hailfingerb437e282010-11-04 01:04:27 +00001142 default:
1143 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1144 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001145 /* Claim that no write was needed. A write with unknown
1146 * granularity is too dangerous to try.
1147 */
1148 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001149 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001150 for (i = 0; i < len / stride; i++) {
1151 limit = min(stride, len - i * stride);
1152 /* Are 'have' and 'want' identical? */
1153 if (memcmp(have + i * stride, want + i * stride, limit)) {
1154 if (!need_write) {
1155 /* First location where have and want differ. */
1156 need_write = 1;
1157 rel_start = i * stride;
1158 }
1159 } else {
1160 if (need_write) {
1161 /* First location where have and want
1162 * do not differ anymore.
1163 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001164 break;
1165 }
1166 }
1167 }
hailfingerffb7f382010-12-06 13:05:44 +00001168 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001169 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001170 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001171 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001172}
1173
hailfinger0c515352009-11-23 12:55:31 +00001174/* This function generates various test patterns useful for testing controller
1175 * and chip communication as well as chip behaviour.
1176 *
1177 * If a byte can be written multiple times, each time keeping 0-bits at 0
1178 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1179 * is essentially an AND operation. That's also the reason why this function
1180 * provides the result of AND between various patterns.
1181 *
1182 * Below is a list of patterns (and their block length).
1183 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1184 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1185 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1186 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1187 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1188 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1189 * Pattern 6 is 00 (1 Byte)
1190 * Pattern 7 is ff (1 Byte)
1191 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1192 * byte block.
1193 *
1194 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1195 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1196 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1197 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1198 * Pattern 12 is 00 (1 Byte)
1199 * Pattern 13 is ff (1 Byte)
1200 * Patterns 8-13 have no block number.
1201 *
1202 * Patterns 0-3 are created to detect and efficiently diagnose communication
1203 * slips like missed bits or bytes and their repetitive nature gives good visual
1204 * cues to the person inspecting the results. In addition, the following holds:
1205 * AND Pattern 0/1 == Pattern 4
1206 * AND Pattern 2/3 == Pattern 5
1207 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1208 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1209 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1210 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1211 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1212 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1213 * Besides that, they provide for bit testing of the last two bytes of every
1214 * 256 byte block which contains the block number for patterns 0-6.
1215 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1216 * block sizes >256 bytes (some Dataflash chips etc.)
1217 * AND Pattern 8/9 == Pattern 12
1218 * AND Pattern 10/11 == Pattern 12
1219 * Pattern 13 is the completely erased state.
1220 * None of the patterns can detect aliasing at boundaries which are a multiple
1221 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1222 */
1223int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1224{
1225 int i;
1226
1227 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001228 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001229 return 1;
1230 }
1231
1232 switch (variant) {
1233 case 0:
1234 for (i = 0; i < size; i++)
1235 buf[i] = (i & 0xf) << 4 | 0x5;
1236 break;
1237 case 1:
1238 for (i = 0; i < size; i++)
1239 buf[i] = (i & 0xf) << 4 | 0xa;
1240 break;
1241 case 2:
1242 for (i = 0; i < size; i++)
1243 buf[i] = 0x50 | (i & 0xf);
1244 break;
1245 case 3:
1246 for (i = 0; i < size; i++)
1247 buf[i] = 0xa0 | (i & 0xf);
1248 break;
1249 case 4:
1250 for (i = 0; i < size; i++)
1251 buf[i] = (i & 0xf) << 4;
1252 break;
1253 case 5:
1254 for (i = 0; i < size; i++)
1255 buf[i] = i & 0xf;
1256 break;
1257 case 6:
1258 memset(buf, 0x00, size);
1259 break;
1260 case 7:
1261 memset(buf, 0xff, size);
1262 break;
1263 case 8:
1264 for (i = 0; i < size; i++)
1265 buf[i] = i & 0xff;
1266 break;
1267 case 9:
1268 for (i = 0; i < size; i++)
1269 buf[i] = ~(i & 0xff);
1270 break;
1271 case 10:
1272 for (i = 0; i < size % 2; i++) {
1273 buf[i * 2] = (i >> 8) & 0xff;
1274 buf[i * 2 + 1] = i & 0xff;
1275 }
1276 if (size & 0x1)
1277 buf[i * 2] = (i >> 8) & 0xff;
1278 break;
1279 case 11:
1280 for (i = 0; i < size % 2; i++) {
1281 buf[i * 2] = ~((i >> 8) & 0xff);
1282 buf[i * 2 + 1] = ~(i & 0xff);
1283 }
1284 if (size & 0x1)
1285 buf[i * 2] = ~((i >> 8) & 0xff);
1286 break;
1287 case 12:
1288 memset(buf, 0x00, size);
1289 break;
1290 case 13:
1291 memset(buf, 0xff, size);
1292 break;
1293 }
1294
1295 if ((variant >= 0) && (variant <= 7)) {
1296 /* Write block number in the last two bytes of each 256-byte
1297 * block, big endian for easier reading of the hexdump.
1298 * Note that this wraps around for chips larger than 2^24 bytes
1299 * (16 MB).
1300 */
1301 for (i = 0; i < size / 256; i++) {
1302 buf[i * 256 + 254] = (i >> 8) & 0xff;
1303 buf[i * 256 + 255] = i & 0xff;
1304 }
1305 }
1306
1307 return 0;
1308}
1309
hailfingeraec9c962009-10-31 01:53:09 +00001310int check_max_decode(enum chipbustype buses, uint32_t size)
1311{
1312 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001313
1314 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001315 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001316 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001317 "size %u kB of chipset/board/programmer "
1318 "for %s interface, "
1319 "probe/read/erase/write may fail. ", size / 1024,
1320 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001321 }
hailfingere1e41ea2011-07-27 07:13:06 +00001322 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001323 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001324 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001325 "size %u kB of chipset/board/programmer "
1326 "for %s interface, "
1327 "probe/read/erase/write may fail. ", size / 1024,
1328 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001329 }
hailfingere1e41ea2011-07-27 07:13:06 +00001330 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001331 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001332 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001333 "size %u kB of chipset/board/programmer "
1334 "for %s interface, "
1335 "probe/read/erase/write may fail. ", size / 1024,
1336 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001337 }
hailfingere1e41ea2011-07-27 07:13:06 +00001338 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001339 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001340 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001341 "size %u kB of chipset/board/programmer "
1342 "for %s interface, "
1343 "probe/read/erase/write may fail. ", size / 1024,
1344 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001345 }
1346 if (!limitexceeded)
1347 return 0;
1348 /* Sometimes chip and programmer have more than one bus in common,
1349 * and the limit is not exceeded on all buses. Tell the user.
1350 */
1351 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001352 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001353 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001354 "interface which can support a chip of this size. "
1355 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001356 return 1;
1357}
1358
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001359void unmap_flash(struct flashctx *flash)
1360{
1361 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1362 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1363 flash->physical_registers = 0;
1364 flash->virtual_registers = (chipaddr)ERROR_PTR;
1365 }
1366
1367 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1368 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1369 flash->physical_memory = 0;
1370 flash->virtual_memory = (chipaddr)ERROR_PTR;
1371 }
1372}
1373
1374int map_flash(struct flashctx *flash)
1375{
1376 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1377 flash->virtual_memory = (chipaddr)ERROR_PTR;
1378 flash->virtual_registers = (chipaddr)ERROR_PTR;
1379
1380 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1381 * These are used for various probing-related hacks that would not map successfully anyway and should be
1382 * removed ASAP. */
1383 if (flash->chip->total_size == 0)
1384 return 0;
1385
1386 const chipsize_t size = flash->chip->total_size * 1024;
1387 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1388 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1389 if (addr == ERROR_PTR) {
1390 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1391 flash->chip->name, PRIxPTR_WIDTH, base);
1392 return 1;
1393 }
1394 flash->physical_memory = base;
1395 flash->virtual_memory = (chipaddr)addr;
1396
1397 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1398 * completely different on some chips and programmers, or not mappable at all.
1399 * Ignore these problems for now and always report success. */
1400 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1401 base = 0xffffffff - size - 0x400000 + 1;
1402 addr = programmer_map_flash_region("flash chip registers", base, size);
1403 if (addr == ERROR_PTR) {
1404 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1405 flash->chip->name, PRIxPTR_WIDTH, base);
1406 return 0;
1407 }
1408 flash->physical_registers = base;
1409 flash->virtual_registers = (chipaddr)addr;
1410 }
1411 return 0;
1412}
1413
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001414/*
1415 * Return a string corresponding to the bustype parameter.
1416 * Memory is obtained with malloc() and must be freed with free() by the caller.
1417 */
1418char *flashbuses_to_text(enum chipbustype bustype)
1419{
1420 char *ret = calloc(1, 1);
1421 /*
1422 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1423 * will cease to exist and should be eliminated here as well.
1424 */
1425 if (bustype == BUS_NONSPI) {
1426 ret = strcat_realloc(ret, "Non-SPI, ");
1427 } else {
1428 if (bustype & BUS_PARALLEL)
1429 ret = strcat_realloc(ret, "Parallel, ");
1430 if (bustype & BUS_LPC)
1431 ret = strcat_realloc(ret, "LPC, ");
1432 if (bustype & BUS_FWH)
1433 ret = strcat_realloc(ret, "FWH, ");
1434 if (bustype & BUS_SPI)
1435 ret = strcat_realloc(ret, "SPI, ");
1436 if (bustype & BUS_PROG)
1437 ret = strcat_realloc(ret, "Programmer-specific, ");
1438 if (bustype == BUS_NONE)
1439 ret = strcat_realloc(ret, "None, ");
1440 }
1441 /* Kill last comma. */
1442 ret[strlen(ret) - 2] = '\0';
1443 ret = realloc(ret, strlen(ret) + 1);
1444 return ret;
1445}
1446
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001447int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001448{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001449 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001450 uint32_t size;
1451 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001452 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001453
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301454 /* Based on the host controller interface that a platform
1455 * needs to use (hwseq or swseq),
1456 * set the flashchips list here.
1457 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001458 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301459 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001460 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301461 flash_list = flashchips_hwseq;
1462 break;
1463 default:
1464 flash_list = flashchips;
1465 break;
1466 }
1467
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001468 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1469 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001470 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001471 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001472 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001473 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001474 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001475 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001476 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001477 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001478 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001479 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001480 continue;
1481 }
stepan782fb172007-04-06 11:58:03 +00001482
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001483 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001484 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001485
hailfinger48ed3e22011-05-04 00:39:50 +00001486 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001487 flash->chip = calloc(1, sizeof(struct flashchip));
1488 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001489 msg_gerr("Out of memory!\n");
1490 exit(1);
1491 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001492 memcpy(flash->chip, chip, sizeof(struct flashchip));
1493 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001494
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001495 if (map_flash(flash) != 0)
1496 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001497
Edward O'Callaghana820b212020-09-17 22:53:26 +10001498 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1499 * is only called with force=1 after normal probing failed.
1500 */
stugec1e55fe2008-07-02 17:15:47 +00001501 if (force)
1502 break;
stepanc98b80b2006-03-16 16:57:41 +00001503
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001504 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001505 goto notfound;
1506
hailfinger48ed3e22011-05-04 00:39:50 +00001507 /* If this is the first chip found, accept it.
1508 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001509 * a non-generic match. SFDP and CFI are generic matches.
1510 * startchip==0 means this call to probe_flash() is the first
1511 * one for this programmer interface (master) and thus no other chip has
1512 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001513 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001514 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1515 msg_cinfo("===\n"
1516 "SFDP has autodetected a flash chip which is "
1517 "not natively supported by flashrom yet.\n");
1518 if (count_usable_erasers(flash) == 0)
1519 msg_cinfo("The standard operations read and "
1520 "verify should work, but to support "
1521 "erase, write and all other "
1522 "possible features");
1523 else
1524 msg_cinfo("All standard operations (read, "
1525 "verify, erase and write) should "
1526 "work, but to support all possible "
1527 "features");
1528
1529 msg_cinfo(" we need to add them manually.\n"
1530 "You can help us by mailing us the output of the following command to "
1531 "flashrom@flashrom.org:\n"
1532 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1533 "Thanks for your help!\n"
1534 "===\n");
1535 }
stugec1e55fe2008-07-02 17:15:47 +00001536
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001537 /* First flash chip detected on this bus. */
1538 if (startchip == 0)
1539 break;
1540 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001541 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001542 break;
1543 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001544notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001545 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001546 free(flash->chip);
1547 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001548 }
uwebe4477b2007-08-23 16:08:21 +00001549
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001550 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001551 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001552
stepan3e7aeae2011-01-19 06:21:54 +00001553
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001554 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001555 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1556 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001557 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001558#if CONFIG_INTERNAL == 1
1559 if (programmer_table[programmer].map_flash_region == physmap)
1560 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1561 PRIxPTR_WIDTH, flash->physical_memory);
1562 else
1563#endif
1564 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001565
Edward O'Callaghana820b212020-09-17 22:53:26 +10001566 /* Flash registers may more likely not be mapped if the chip was forced.
1567 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001568 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001569 if (flash->chip->printlock)
1570 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001571
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001572 /* Get out of the way for later runs. */
1573 unmap_flash(flash);
1574
hailfinger48ed3e22011-05-04 00:39:50 +00001575 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001576 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001577}
1578
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001579static int verify_flash(struct flashctx *flash,
1580 struct action_descriptor *descriptor,
1581 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001582{
hailfingerb0f4d122009-06-24 08:20:45 +00001583 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001584 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001585 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001586
snelsone42c3802010-05-07 20:09:04 +00001587 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001588
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001589 if (verify_it == VERIFY_PARTIAL) {
1590 struct processing_unit *pu = descriptor->processing_units;
1591
1592 /* Verify only areas which were written. */
1593 while (pu->num_blocks) {
1594 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001595 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001596 if (ret)
1597 break;
1598 pu++;
1599 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001600 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001601 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001602 }
uwef6641642007-05-09 10:17:44 +00001603
David Hendricks1ed1d352011-11-23 17:54:37 -08001604 if (ret == ACCESS_DENIED) {
1605 msg_gdbg("Could not fully verify due to access error, ");
1606 if (access_denied_action == error_ignore) {
1607 msg_gdbg("ignoring\n");
1608 ret = 0;
1609 } else {
1610 msg_gdbg("aborting\n");
1611 }
1612 }
1613
hailfingerb0f4d122009-06-24 08:20:45 +00001614 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001615 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001616
hailfingerb0f4d122009-06-24 08:20:45 +00001617 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001618}
1619
uwe8d342eb2011-07-28 08:13:25 +00001620int read_buf_from_file(unsigned char *buf, unsigned long size,
1621 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001622{
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001623#ifdef __LIBPAYLOAD__
1624 msg_gerr("Error: No file I/O support in libpayload\n");
1625 return 1;
1626#else
1627 int ret = 0;
hailfinger771fc182010-10-15 00:01:14 +00001628
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001629 FILE *image;
1630 if ((image = fopen(filename, "rb")) == NULL) {
1631 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger771fc182010-10-15 00:01:14 +00001632 return 1;
1633 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001634
1635 struct stat image_stat;
hailfinger771fc182010-10-15 00:01:14 +00001636 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001637 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1638 ret = 1;
1639 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001640 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001641 if (image_stat.st_size != (intmax_t)size) {
1642 msg_gerr("Error: Image size (%jd B) doesn't match the flash chip's size (%lu B)!\n",
1643 (intmax_t)image_stat.st_size, size);
1644 ret = 1;
1645 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001646 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001647
1648 unsigned long numbytes = fread(buf, 1, size, image);
hailfinger771fc182010-10-15 00:01:14 +00001649 if (numbytes != size) {
1650 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1651 "wanted %ld!\n", numbytes, size);
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001652 ret = 1;
hailfinger771fc182010-10-15 00:01:14 +00001653 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001654out:
1655 (void)fclose(image);
1656 return ret;
1657#endif
hailfinger771fc182010-10-15 00:01:14 +00001658}
1659
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001660int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001661{
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001662#ifdef __LIBPAYLOAD__
1663 msg_gerr("Error: No file I/O support in libpayload\n");
1664 return 1;
1665#else
hailfingerd219a232009-01-28 00:27:54 +00001666 FILE *image;
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001667 int ret = 0;
hailfingerde345862009-06-01 22:07:52 +00001668
1669 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001670 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001671 return 1;
1672 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001673 if ((image = fopen(filename, "wb")) == NULL) {
1674 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger23060112009-05-08 12:49:03 +00001675 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001676 }
hailfingerd219a232009-01-28 00:27:54 +00001677
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001678 unsigned long numbytes = fwrite(buf, 1, size, image);
hailfinger42a850a2010-07-13 23:56:13 +00001679 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001680 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001681 ret = 1;
1682 goto out;
hailfinger42a850a2010-07-13 23:56:13 +00001683 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001684 if (fflush(image)) {
1685 msg_gerr("Error: flushing file \"%s\" failed: %s\n", filename, strerror(errno));
1686 ret = 1;
1687 }
1688 // Try to fsync() only regular files and if that function is available at all (e.g. not on MinGW).
1689#if defined(_POSIX_FSYNC) && (_POSIX_FSYNC != -1)
1690 struct stat image_stat;
1691 if (fstat(fileno(image), &image_stat) != 0) {
1692 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1693 ret = 1;
1694 goto out;
1695 }
1696 if (S_ISREG(image_stat.st_mode)) {
1697 if (fsync(fileno(image))) {
1698 msg_gerr("Error: fsyncing file \"%s\" failed: %s\n", filename, strerror(errno));
1699 ret = 1;
1700 }
1701 }
1702#endif
1703out:
1704 if (fclose(image)) {
1705 msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
1706 ret = 1;
1707 }
1708 return ret;
1709#endif
hailfingerd219a232009-01-28 00:27:54 +00001710}
1711
David Hendrickse3451942013-03-21 17:23:29 -07001712/*
1713 * read_flash - wrapper for flash->read() with additional high-level policy
1714 *
1715 * @flash flash chip
1716 * @buf buffer to store data in
1717 * @start start address
1718 * @len number of bytes to read
1719 *
1720 * This wrapper simplifies most cases when the flash chip needs to be read
1721 * since policy decisions such as non-fatal error handling is centralized.
1722 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001723int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001724 unsigned int start, unsigned int len)
1725{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001726 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001727
Patrick Georgif3fa2992017-02-02 16:24:44 +01001728 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001729 return -1;
1730
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001731 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1732
Patrick Georgif3fa2992017-02-02 16:24:44 +01001733 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001734 if (ret) {
1735 if (ignore_error(ret)) {
1736 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1737 start, start + len - 1);
1738 ret = 0;
1739 } else {
1740 msg_gdbg("failed to read 0x%x-0x%x\n",
1741 start, start + len - 1);
1742 }
1743 }
1744
1745 return ret;
1746}
1747
David Hendricks7c8a1612013-04-26 19:14:44 -07001748/*
1749 * write_flash - wrapper for flash->write() with additional high-level policy
1750 *
1751 * @flash flash chip
1752 * @buf buffer to write to flash
1753 * @start start address in flash
1754 * @len number of bytes to write
1755 *
1756 * TODO: Look up regions that are write-protected and avoid attempt to write
1757 * to them at all.
1758 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001759int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001760 unsigned int start, unsigned int len)
1761{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001762 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001763 return -1;
1764
Patrick Georgif3fa2992017-02-02 16:24:44 +01001765 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001766}
1767
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001768int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001769{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001770 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001771 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001772 int ret = 0;
1773
1774 msg_cinfo("Reading flash... ");
1775 if (!buf) {
1776 msg_gerr("Memory allocation failed!\n");
1777 msg_cinfo("FAILED.\n");
1778 return 1;
1779 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001780
1781 /* To support partial read, fill buffer to all 0xFF at beginning to make
1782 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001783 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001784
Patrick Georgif3fa2992017-02-02 16:24:44 +01001785 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001786 msg_cerr("No read function available for this flash chip.\n");
1787 ret = 1;
1788 goto out_free;
1789 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001790
1791 /* First try to handle partial read case, rather than read the whole
1792 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001793 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001794 if (ret < 0) {
1795 msg_cerr("Partial read operation failed!\n");
1796 ret = 1;
1797 goto out_free;
1798 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001799 int num_regions = get_num_include_args();
1800
1801 if (ret != num_regions) {
1802 msg_cerr("Requested %d regions, but only read %d\n",
1803 num_regions, ret);
1804 ret = 1;
1805 goto out_free;
1806 }
1807
1808 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001809 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001810 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001811 msg_cerr("Read operation failed!\n");
1812 ret = 1;
1813 goto out_free;
1814 }
hailfinger42a850a2010-07-13 23:56:13 +00001815 }
1816
David Hendricksdf29a832013-06-28 14:33:51 -07001817 if (filename)
1818 ret = write_buf_to_file(buf, size, filename);
1819
hailfinger42a850a2010-07-13 23:56:13 +00001820out_free:
1821 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001822 if (ret)
1823 msg_cerr("FAILED.");
1824 else
1825 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001826 return ret;
1827}
1828
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001829/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001830static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001831{
hailfingerb91c08c2011-08-15 19:54:20 +00001832 int i, j, k;
1833 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001834
1835 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1836 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001837 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001838
1839 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1840 /* Blocks with zero size are bugs in flashchips.c. */
1841 if (eraser.eraseblocks[i].count &&
1842 !eraser.eraseblocks[i].size) {
1843 msg_gerr("ERROR: Flash chip %s erase function "
1844 "%i region %i has size 0. Please report"
1845 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001846 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001847 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001848 }
1849 /* Blocks with zero count are bugs in flashchips.c. */
1850 if (!eraser.eraseblocks[i].count &&
1851 eraser.eraseblocks[i].size) {
1852 msg_gerr("ERROR: Flash chip %s erase function "
1853 "%i region %i has count 0. Please report"
1854 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001855 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001856 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001857 }
1858 done += eraser.eraseblocks[i].count *
1859 eraser.eraseblocks[i].size;
1860 }
hailfinger9fed35d2010-01-19 06:42:46 +00001861 /* Empty eraseblock definition with erase function. */
1862 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001863 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001864 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001865 if (!done)
1866 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001867 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001868 msg_gerr("ERROR: Flash chip %s erase function %i "
1869 "region walking resulted in 0x%06x bytes total,"
1870 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001871 " flashrom@flashrom.org\n", chip->name, k,
1872 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001873 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001874 }
hailfinger9fed35d2010-01-19 06:42:46 +00001875 if (!eraser.block_erase)
1876 continue;
1877 /* Check if there are identical erase functions for different
1878 * layouts. That would imply "magic" erase functions. The
1879 * easiest way to check this is with function pointers.
1880 */
uwef6f94d42010-03-13 17:28:29 +00001881 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001882 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001883 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001884 msg_gerr("ERROR: Flash chip %s erase function "
1885 "%i and %i are identical. Please report"
1886 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001887 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001888 ret = 1;
1889 }
uwef6f94d42010-03-13 17:28:29 +00001890 }
hailfinger45177872010-01-18 08:14:43 +00001891 }
hailfinger9fed35d2010-01-19 06:42:46 +00001892 return ret;
hailfinger45177872010-01-18 08:14:43 +00001893}
1894
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001895static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001896 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001897 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001898 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001899 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001900 unsigned int addr,
1901 unsigned int len))
1902{
stefanctc5eb8a92011-11-23 09:13:48 +00001903 unsigned int starthere = 0, lenhere = 0;
1904 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001905 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001906 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001907
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001908 /*
1909 * curcontents and newcontents are opaque to walk_eraseregions, and
1910 * need to be adjusted here to keep the impression of proper
1911 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001912 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001913
hailfinger90fcf9b2010-11-05 14:51:59 +00001914 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001915
hailfingerb437e282010-11-04 01:04:27 +00001916 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001917
hailfingerb437e282010-11-04 01:04:27 +00001918 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001919 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001920 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001921 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001922 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001923 if (ret) {
1924 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001925 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001926 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001927 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001928 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001929 }
1930
David Hendricks0954ffc2015-11-13 15:15:44 -08001931 if (programmer_table[programmer].paranoid) {
1932 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001933 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001934 return -1;
1935 }
hailfingerac8e3182011-06-26 17:04:16 +00001936 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001937
hailfinger90fcf9b2010-11-05 14:51:59 +00001938 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001939 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001940 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001941 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001942 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001943 /* get_next_write() sets starthere to a new value after the call. */
1944 while ((lenhere = get_next_write(curcontents + starthere,
1945 newcontents + starthere,
1946 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001947 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001948 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001949 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001950 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001951 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001952 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001953 if (ret) {
1954 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001955 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001956 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001957 }
David Hendricks048b38c2016-03-28 18:47:06 -07001958
1959 /*
1960 * If the block needed to be erased and was erased successfully
1961 * then we can assume that we didn't run into any write-
1962 * protected areas. Otherwise, we need to verify each page to
1963 * ensure it was successfully written and abort if we encounter
1964 * any errors.
1965 */
1966 if (programmer_table[programmer].paranoid && !block_was_erased) {
1967 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001968 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001969 return -1;
1970 }
1971
hailfingerb437e282010-11-04 01:04:27 +00001972 starthere += lenhere;
1973 skip = 0;
1974 }
1975 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001976 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001977 return ret;
1978}
1979
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001980/*
1981 * Function to process processing units accumulated in the action descriptor.
1982 *
1983 * @flash pointer to the flash context to operate on
1984 * @do_something helper function which can erase and program a section of the
1985 * flash chip. It receives the flash context, offset and length
1986 * of the area to erase/program, before and after contents (to
1987 * decide what exactly needs to be erased and or programmed)
1988 * and a pointer to the erase function which can operate on the
1989 * proper granularity.
1990 * @descriptor action descriptor including pointers to before and after
1991 * contents and an array of processing actions to take.
1992 *
1993 * Returns zero on success or an error code.
1994 */
1995static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001996 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001997 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001998 unsigned int len,
1999 uint8_t *param1,
2000 uint8_t *param2,
2001 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002002 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00002003 unsigned int addr,
2004 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002005 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00002006{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002007 struct processing_unit *pu;
2008 int rc = 0;
2009 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00002010
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002011 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
2012 unsigned base = pu->offset;
2013 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07002014
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002015 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07002016
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002017 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00002018 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002019 else
2020 print_comma = 1;
2021
2022 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
2023
2024 rc = do_something(flash, base,
2025 pu->block_size,
2026 descriptor->oldcontents,
2027 descriptor->newcontents,
2028 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
2029
David Hendricks1ed1d352011-11-23 17:54:37 -08002030 if (rc) {
2031 if (ignore_error(rc))
2032 rc = 0;
2033 else
2034 return rc;
hailfingerb437e282010-11-04 01:04:27 +00002035 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002036 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00002037 }
2038 }
hailfingerb437e282010-11-04 01:04:27 +00002039 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08002040 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00002041}
2042
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002043static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00002044{
Patrick Georgif3fa2992017-02-02 16:24:44 +01002045 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00002046
2047 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
2048 if (log)
2049 msg_cdbg("not defined. ");
2050 return 1;
2051 }
2052 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
2053 if (log)
2054 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00002055 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00002056 return 1;
2057 }
2058 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
2059 if (log)
2060 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00002061 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00002062 return 1;
2063 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002064 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002065 return 0;
2066}
2067
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002068int erase_and_write_flash(struct flashctx *flash,
2069 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002070{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002071 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002072
hailfingercf848f12010-12-05 15:14:44 +00002073 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002074
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002075 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002076
hailfinger7df21362009-09-05 02:30:58 +00002077 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002078 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002079 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002080 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002081 }
2082 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002083}
2084
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002085static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002086{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002087 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2088#if CONFIG_INTERNAL == 1
2089 if (programmer == PROGRAMMER_INTERNAL)
2090 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2091 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2092 "mail flashrom@flashrom.org, thanks!\n"
2093 "-------------------------------------------------------------------------------\n"
2094 "You may now reboot or simply leave the machine running.\n");
2095 else
2096#endif
2097 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2098 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2099 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2100 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002101}
2102
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002103static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002104{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002105 msg_gerr("Your flash chip is in an unknown state.\n");
2106#if CONFIG_INTERNAL == 1
2107 if (programmer == PROGRAMMER_INTERNAL)
2108 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2109 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2110 "-------------------------------------------------------------------------------\n"
2111 "DO NOT REBOOT OR POWEROFF!\n");
2112 else
2113#endif
2114 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2115 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002116}
2117
hailfingerf79d1712010-10-06 23:48:34 +00002118void list_programmers_linebreak(int startcol, int cols, int paren)
2119{
2120 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002121 int pnamelen;
2122 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002123 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002124 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002125
2126 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2127 pname = programmer_table[p].name;
2128 pnamelen = strlen(pname);
2129 if (remaining - pnamelen - 2 < 0) {
2130 if (firstline)
2131 firstline = 0;
2132 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002133 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002134 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002135 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002136 remaining = cols - startcol;
2137 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002138 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002139 remaining--;
2140 }
2141 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002142 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002143 remaining--;
2144 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002145 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002146 remaining -= pnamelen;
2147 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002148 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002149 remaining--;
2150 } else {
2151 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002152 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002153 }
2154 }
2155}
2156
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002157static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002158{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002159#if IS_WINDOWS
2160 SYSTEM_INFO si;
2161 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002162
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002163 memset(&si, 0, sizeof(SYSTEM_INFO));
2164 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2165 msg_ginfo(" on Windows");
2166 /* Tell Windows which version of the structure we want. */
2167 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2168 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2169 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2170 else
2171 msg_ginfo(" unknown version");
2172 GetSystemInfo(&si);
2173 switch (si.wProcessorArchitecture) {
2174 case PROCESSOR_ARCHITECTURE_AMD64:
2175 msg_ginfo(" (x86_64)");
2176 break;
2177 case PROCESSOR_ARCHITECTURE_INTEL:
2178 msg_ginfo(" (x86)");
2179 break;
2180 default:
2181 msg_ginfo(" (unknown arch)");
2182 break;
2183 }
2184#elif HAVE_UTSNAME == 1
2185 struct utsname osinfo;
2186
2187 uname(&osinfo);
2188 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002189 osinfo.machine);
2190#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002191 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002192#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002193}
2194
2195void print_buildinfo(void)
2196{
2197 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002198#if NEED_PCI == 1
2199#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002200 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002201#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002202 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002203#endif
2204#endif
2205#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002206 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002207#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002208 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002209#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002210 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002211#endif
hailfinger3b471632010-03-27 16:36:40 +00002212#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002213 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002214#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002215 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002216#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002217 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002218#endif
2219#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002220 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002221#endif
2222#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002223 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00002224#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002225 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00002226#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002227 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002228}
2229
uwefdeca092008-01-21 15:24:22 +00002230void print_version(void)
2231{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002232 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002233 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002234 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002235}
2236
hailfinger74819ad2010-05-15 15:04:37 +00002237void print_banner(void)
2238{
2239 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002240 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002241 msg_ginfo("\n");
2242}
2243
hailfingerc77acb52009-12-24 02:15:55 +00002244int selfcheck(void)
2245{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002246 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002247 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002248
2249 /* Safety check. Instead of aborting after the first error, check
2250 * if more errors exist.
2251 */
hailfingerc77acb52009-12-24 02:15:55 +00002252 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002253 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002254 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002255 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002256 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2257 const struct programmer_entry p = programmer_table[i];
2258 if (p.name == NULL) {
2259 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2260 ret = 1;
2261 /* This might hide other problems with this programmer, but allows for better error
2262 * messages below without jumping through hoops. */
2263 continue;
2264 }
2265 switch (p.type) {
2266 case USB:
2267 case PCI:
2268 case OTHER:
2269 if (p.devs.note == NULL) {
2270 if (strcmp("internal", p.name) == 0)
2271 break; /* This one has its device list stored separately. */
2272 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2273 p.name);
2274 ret = 1;
2275 }
2276 break;
2277 default:
2278 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2279 ret = 1;
2280 break;
2281 }
2282 if (p.init == NULL) {
2283 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2284 ret = 1;
2285 }
2286 if (p.delay == NULL) {
2287 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2288 ret = 1;
2289 }
2290 if (p.map_flash_region == NULL) {
2291 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2292 ret = 1;
2293 }
2294 if (p.unmap_flash_region == NULL) {
2295 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2296 ret = 1;
2297 }
2298 }
2299
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002300 /* It would be favorable if we could check for the correct layout (especially termination) of various
2301 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2302 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2303 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2304 * 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 +10002305 * checks below. */
2306 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002307 msg_gerr("Flashchips table miscompilation!\n");
2308 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002309 } else {
2310 for (i = 0; i < flashchips_size - 1; i++) {
2311 const struct flashchip *chip = &flashchips[i];
2312 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2313 ret = 1;
2314 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2315 "Please report a bug at flashrom@flashrom.org\n", i,
2316 chip->name == NULL ? "unnamed" : chip->name);
2317 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002318 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002319 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002320 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002321 }
stefanct6d836ba2011-05-26 01:35:19 +00002322 }
stefanct6d836ba2011-05-26 01:35:19 +00002323
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002324 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002325 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002326}
2327
hailfinger771fc182010-10-15 00:01:14 +00002328/* FIXME: This function signature needs to be improved once doit() has a better
2329 * function signature.
2330 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002331static int chip_safety_check(const struct flashctx *flash, int force,
2332 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002333{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002334 const struct flashchip *chip = flash->chip;
2335
hailfinger771fc182010-10-15 00:01:14 +00002336 if (!programmer_may_write && (write_it || erase_it)) {
2337 msg_perr("Write/erase is not working yet on your programmer in "
2338 "its current configuration.\n");
2339 /* --force is the wrong approach, but it's the best we can do
2340 * until the generic programmer parameter parser is merged.
2341 */
2342 if (!force)
2343 return 1;
2344 msg_cerr("Continuing anyway.\n");
2345 }
2346
2347 if (read_it || erase_it || write_it || verify_it) {
2348 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002349 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002350 msg_cerr("Read is not working on this chip. ");
2351 if (!force)
2352 return 1;
2353 msg_cerr("Continuing anyway.\n");
2354 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002355 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002356 msg_cerr("flashrom has no read function for this "
2357 "flash chip.\n");
2358 return 1;
2359 }
2360 }
2361 if (erase_it || write_it) {
2362 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002363 if (chip->tested.erase == NA) {
2364 msg_cerr("Erase is not possible on this chip.\n");
2365 return 1;
2366 }
2367 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002368 msg_cerr("Erase is not working on this chip. ");
2369 if (!force)
2370 return 1;
2371 msg_cerr("Continuing anyway.\n");
2372 }
stefancte1c5acf2011-07-04 07:27:17 +00002373 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002374 msg_cerr("flashrom has no erase function for this "
2375 "flash chip.\n");
2376 return 1;
2377 }
hailfinger771fc182010-10-15 00:01:14 +00002378 }
2379 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002380 if (chip->tested.write == NA) {
2381 msg_cerr("Write is not possible on this chip.\n");
2382 return 1;
2383 }
2384 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002385 msg_cerr("Write is not working on this chip. ");
2386 if (!force)
2387 return 1;
2388 msg_cerr("Continuing anyway.\n");
2389 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002390 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002391 msg_cerr("flashrom has no write function for this "
2392 "flash chip.\n");
2393 return 1;
2394 }
2395 }
2396 return 0;
2397}
2398
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002399int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002400 const bool read_it, const bool write_it,
2401 const bool erase_it, const bool verify_it)
2402{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002403 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002404 msg_cerr("Aborting.\n");
2405 return 1;
2406 }
2407
2408 if (normalize_romentries(flash)) {
2409 msg_cerr("Requested regions can not be handled. Aborting.\n");
2410 return 1;
2411 }
2412
Edward O'Callaghan40092972020-10-20 11:50:48 +11002413 /*
2414 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2415 * can be repro'ed with upstream on Volteer.
2416 *
2417 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2418 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2419 * hooked and this can fail on some board topologies. Checking the return value can
2420 * cause board rw failures by bailing early. Avoid the early bail for now until a
2421 * full investigation can reveal the proper fix. This restores previous behaviour of
2422 * assuming a map went fine.
2423 */
2424#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002425 if (map_flash(flash) != 0)
2426 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002427#endif
2428 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002429
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002430 /* Given the existence of read locks, we want to unlock for read,
2431 erase and write. */
2432 if (flash->chip->unlock)
2433 flash->chip->unlock(flash);
2434
2435 flash->address_high_byte = -1;
2436 flash->in_4ba_mode = false;
2437
2438 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2439 if ((flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN) && flash->chip->set_4ba) {
2440 if (flash->chip->set_4ba(flash)) {
2441 msg_cerr("Enabling/disabling 4-byte addressing mode failed!\n");
2442 return 1;
2443 }
2444 }
2445
2446 return 0;
2447}
2448
Edward O'Callaghana820b212020-09-17 22:53:26 +10002449void finalize_flash_access(struct flashctx *const flash)
2450{
2451 unmap_flash(flash);
2452}
2453
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002454/*
2455 * Function to erase entire flash chip.
2456 *
2457 * @flashctx pointer to the flash context to use
2458 * @oldcontents pointer to the buffer including current chip contents, to
2459 * decide which areas do in fact need to be erased
2460 * @size the size of the flash chip, in bytes.
2461 *
2462 * Returns zero on success or an error code.
2463 */
2464static int erase_chip(struct flashctx *flash, void *oldcontents,
2465 void *newcontents, size_t size)
2466{
2467 /*
2468 * To make sure that the chip is fully erased, let's cheat and create
2469 * a descriptor where the new contents are all erased.
2470 */
2471 struct action_descriptor *fake_descriptor;
2472 int ret = 0;
2473
2474 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2475 newcontents, 1);
2476 /* FIXME: Do we really want the scary warning if erase failed? After
2477 * all, after erase the chip is either blank or partially blank or it
2478 * has the old contents. A blank chip won't boot, so if the user
2479 * wanted erase and reboots afterwards, the user knows very well that
2480 * booting won't work.
2481 */
2482 if (erase_and_write_flash(flash, fake_descriptor)) {
2483 emergency_help_message();
2484 ret = 1;
2485 }
2486
2487 free(fake_descriptor);
2488
2489 return ret;
2490}
2491
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002492static int read_dest_content(struct flashctx *flash, int verify_it,
2493 uint8_t *dest, unsigned long size)
2494{
2495 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2496 && get_num_include_args()) {
2497 /*
2498 * If no full verification is required and not
2499 * the entire chip is about to be programmed,
2500 * read only the areas which might change.
2501 */
2502 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2503 return 1;
2504 } else {
2505 if (read_flash(flash, dest, 0, size))
2506 return 1;
2507 }
2508 return 0;
2509}
2510
hailfingerc77acb52009-12-24 02:15:55 +00002511/* This function signature is horrible. We need to design a better interface,
2512 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002513 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002514 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002515int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002516 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002517 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002518{
hailfinger4c47e9d2010-10-19 22:06:20 +00002519 uint8_t *oldcontents;
2520 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002521 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002522 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002523 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002524
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002525 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002526 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002527 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002528
Simon Glass9ad06c12013-07-03 22:08:17 +09002529 if (extract_it) {
2530 ret = extract_regions(flash);
2531 goto out_nofree;
2532 }
2533
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002534 /* mark entries included using -i argument as "included" if they are
2535 found in the master rom_entries list */
2536 if (process_include_args() < 0) {
2537 ret = 1;
2538 goto out_nofree;
2539 }
2540
hailfinger771fc182010-10-15 00:01:14 +00002541 if (read_it) {
2542 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002543 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002544 }
hailfingerb437e282010-11-04 01:04:27 +00002545
stefanctd611e8f2011-07-12 22:35:21 +00002546 oldcontents = malloc(size);
2547 if (!oldcontents) {
2548 msg_gerr("Out of memory!\n");
2549 exit(1);
2550 }
Simon Glass4c214132013-07-16 10:09:28 -06002551 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002552 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002553 newcontents = malloc(size);
2554 if (!newcontents) {
2555 msg_gerr("Out of memory!\n");
2556 exit(1);
2557 }
Simon Glass4c214132013-07-16 10:09:28 -06002558 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002559 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002560 /* Side effect of the assumptions above: Default write action is erase
2561 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002562 * oldcontents being completely unerased means we have to erase
2563 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002564 */
2565
hailfingerd217d122010-10-08 18:52:29 +00002566 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002567 /*
2568 * Note: This must be done before any files specified by -i
2569 * arguments are processed merged into the newcontents since
2570 * -i files take priority. See http://crbug.com/263495.
2571 */
2572 if (filename) {
2573 if (read_buf_from_file(newcontents, size, filename)) {
2574 ret = 1;
2575 goto out;
2576 }
2577 } else {
2578 /* Content will be read from -i args, so they must
2579 * not overlap. */
2580 if (included_regions_overlap()) {
2581 msg_gerr("Error: Included regions must "
2582 "not overlap.\n");
2583 ret = 1;
2584 goto out;
2585 }
stepan1da96c02006-11-21 23:48:51 +00002586 }
ollie5672ac62004-03-17 22:22:08 +00002587 }
2588
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002589 if (do_diff) {
2590 /*
2591 * Obtain a reference image so that we can check whether
2592 * regions need to be erased and to give better diagnostics in
2593 * case write fails. If --fast-verify is used then only the
2594 * regions which are included using -i will be read.
2595 */
2596 if (diff_file) {
2597 msg_cdbg("Reading old contents from file... ");
2598 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002599 ret = 1;
2600 msg_cdbg("FAILED.\n");
2601 goto out;
2602 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002603 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002604 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002605 ret = read_dest_content(flash, verify_it,
2606 oldcontents, size);
2607 if (ret) {
2608 msg_cdbg("FAILED.\n");
2609 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002610 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002611 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002612 msg_cdbg("done.\n");
2613 } else if (!erase_it) {
2614 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002615 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002616 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002617
David Hendricksdf29a832013-06-28 14:33:51 -07002618 /*
2619 * Note: This must be done after reading the file specified for the
2620 * -w/-v argument, if any, so that files specified using -i end up
2621 * in the "newcontents" buffer before being written.
2622 * See http://crbug.com/263495.
2623 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002624 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002625 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002626 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002627 goto out;
2628 }
uwef6641642007-05-09 10:17:44 +00002629
David Hendricksa7e114b2016-02-26 18:49:15 -08002630 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002631 erase_chip(flash, oldcontents, newcontents, size);
2632 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002633 }
2634
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002635 descriptor = prepare_action_descriptor(flash, oldcontents,
2636 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002637 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002638 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002639 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002640 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002641 goto out;
2642 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002643
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002644 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002645 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2646 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002647 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002648 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002649 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002650 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002651 ret = 1;
2652 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002653 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002654 msg_cerr("Apparently at least some data has changed.\n");
2655 } else
2656 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002657 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002658 ret = 1;
2659 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002660 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002661
David Hendricksac1d25c2016-08-09 17:00:58 -07002662 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002663 if (ret < 0) {
2664 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002665 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002666 emergency_help_message();
2667 ret = 1;
2668 goto out;
2669 } else if (ret > 0) {
2670 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002671 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002672 ret = read_dest_content(flash, verify_it,
2673 oldcontents, size);
2674 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002675 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002676 goto out;
2677 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002678
2679 /* Get a new descriptor. */
2680 free(descriptor);
2681 descriptor = prepare_action_descriptor(flash,
2682 oldcontents,
2683 newcontents,
2684 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002685 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002686 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002687 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002688 emergency_help_message();
2689 ret = 1;
2690 goto out;
2691 }
2692 ret = 0;
2693 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002694
David Hendricksac1d25c2016-08-09 17:00:58 -07002695 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002696 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002697 emergency_help_message();
2698 ret = 1;
2699 goto out;
2700 }
stuge8ce3a3c2008-04-28 14:47:30 +00002701 }
ollie6a600992005-11-26 21:55:36 +00002702
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002703 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002704 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002705 if ((write_it || erase_it) && !content_has_changed) {
2706 msg_gdbg("Nothing was erased or written, skipping "
2707 "verification\n");
2708 } else {
2709 /* Work around chips which need some time to calm down. */
2710 if (write_it && verify_it != VERIFY_PARTIAL)
2711 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002712
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002713 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002714
David Hendricks9ba79fb2015-04-03 12:06:16 -07002715 /* If we tried to write, and verification now fails, we
2716 * might have an emergency situation.
2717 */
2718 if (ret && write_it)
2719 emergency_help_message();
2720 }
hailfinger0459e1c2009-08-19 13:55:34 +00002721 }
ollie6a600992005-11-26 21:55:36 +00002722
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002723 finalize_flash_access(flash);
2724
hailfinger90fcf9b2010-11-05 14:51:59 +00002725out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002726 if (descriptor)
2727 free(descriptor);
2728
hailfinger90fcf9b2010-11-05 14:51:59 +00002729 free(oldcontents);
2730 free(newcontents);
2731out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002732 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002733 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002734 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002735 * tree. This is because some operations, such as write protection,
2736 * requires programmer_shutdown() but does not call doit().
2737 */
2738// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002739 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002740}