blob: 588b60204d7eb0bdbc495302d7e0370bfd6fec39 [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
hailfinger90c7d542010-05-31 15:27:27 +0000121#if CONFIG_NIC3COM == 1
uwe0f5a3a22009-05-13 11:36:06 +0000122 {
hailfinger3548a9a2009-08-12 14:34:35 +0000123 .name = "nic3com",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100124 .type = PCI,
125 .devs.dev = nics_3com,
uwe0f5a3a22009-05-13 11:36:06 +0000126 .init = nic3com_init,
uwe3e656bd2009-05-17 23:12:17 +0000127 .map_flash_region = fallback_map,
128 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000129 .delay = internal_delay,
uwe0f5a3a22009-05-13 11:36:06 +0000130 },
hailfinger571a6b32009-09-16 10:09:21 +0000131#endif
uwe0f5a3a22009-05-13 11:36:06 +0000132
hailfinger90c7d542010-05-31 15:27:27 +0000133#if CONFIG_NICREALTEK == 1
hailfinger5aa36982010-05-21 21:54:07 +0000134 {
hailfinger0d703d42011-03-07 01:08:09 +0000135 /* This programmer works for Realtek RTL8139 and SMC 1211. */
uwe8d342eb2011-07-28 08:13:25 +0000136 .name = "nicrealtek",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100137 .type = PCI,
138 .devs.dev = nics_realtek,
uwe8d342eb2011-07-28 08:13:25 +0000139 .init = nicrealtek_init,
140 .map_flash_region = fallback_map,
141 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000142 .delay = internal_delay,
hailfinger5aa36982010-05-21 21:54:07 +0000143 },
hailfinger5aa36982010-05-21 21:54:07 +0000144#endif
145
hailfingerf0a368f2010-06-07 22:37:54 +0000146#if CONFIG_NICNATSEMI == 1
147 {
uwe8d342eb2011-07-28 08:13:25 +0000148 .name = "nicnatsemi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100149 .type = PCI,
150 .devs.dev = nics_natsemi,
uwe8d342eb2011-07-28 08:13:25 +0000151 .init = nicnatsemi_init,
152 .map_flash_region = fallback_map,
153 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000154 .delay = internal_delay,
hailfingerf0a368f2010-06-07 22:37:54 +0000155 },
156#endif
hailfinger5aa36982010-05-21 21:54:07 +0000157
hailfinger90c7d542010-05-31 15:27:27 +0000158#if CONFIG_GFXNVIDIA == 1
uweff4576d2009-09-30 18:29:55 +0000159 {
160 .name = "gfxnvidia",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100161 .type = PCI,
162 .devs.dev = gfx_nvidia,
uweff4576d2009-09-30 18:29:55 +0000163 .init = gfxnvidia_init,
uweff4576d2009-09-30 18:29:55 +0000164 .map_flash_region = fallback_map,
165 .unmap_flash_region = fallback_unmap,
uweff4576d2009-09-30 18:29:55 +0000166 .delay = internal_delay,
167 },
168#endif
169
hailfinger90c7d542010-05-31 15:27:27 +0000170#if CONFIG_DRKAISER == 1
ruikda922a12009-05-17 19:39:27 +0000171 {
uwee2f95ef2009-09-02 23:00:46 +0000172 .name = "drkaiser",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100173 .type = PCI,
174 .devs.dev = drkaiser_pcidev,
uwee2f95ef2009-09-02 23:00:46 +0000175 .init = drkaiser_init,
uwee2f95ef2009-09-02 23:00:46 +0000176 .map_flash_region = fallback_map,
177 .unmap_flash_region = fallback_unmap,
uwee2f95ef2009-09-02 23:00:46 +0000178 .delay = internal_delay,
179 },
hailfinger571a6b32009-09-16 10:09:21 +0000180#endif
uwee2f95ef2009-09-02 23:00:46 +0000181
hailfinger90c7d542010-05-31 15:27:27 +0000182#if CONFIG_SATASII == 1
uwee2f95ef2009-09-02 23:00:46 +0000183 {
hailfinger3548a9a2009-08-12 14:34:35 +0000184 .name = "satasii",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100185 .type = PCI,
186 .devs.dev = satas_sii,
ruikda922a12009-05-17 19:39:27 +0000187 .init = satasii_init,
uwe3e656bd2009-05-17 23:12:17 +0000188 .map_flash_region = fallback_map,
189 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000190 .delay = internal_delay,
ruikda922a12009-05-17 19:39:27 +0000191 },
hailfinger571a6b32009-09-16 10:09:21 +0000192#endif
ruikda922a12009-05-17 19:39:27 +0000193
hailfinger90c7d542010-05-31 15:27:27 +0000194#if CONFIG_ATAHPT == 1
uwe7e627c82010-02-21 21:17:00 +0000195 {
196 .name = "atahpt",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100197 .type = PCI,
198 .devs.dev = ata_hpt,
uwe7e627c82010-02-21 21:17:00 +0000199 .init = atahpt_init,
uwe7e627c82010-02-21 21:17:00 +0000200 .map_flash_region = fallback_map,
201 .unmap_flash_region = fallback_unmap,
uwe7e627c82010-02-21 21:17:00 +0000202 .delay = internal_delay,
203 },
204#endif
205
hailfinger90c7d542010-05-31 15:27:27 +0000206#if CONFIG_FT2232_SPI == 1
hailfingerf31da3d2009-06-16 21:08:06 +0000207 {
hailfinger90c7d542010-05-31 15:27:27 +0000208 .name = "ft2232_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100209 .type = USB,
Nikolai Artemievc347a852020-04-29 12:17:08 +1000210 .devs.dev = devs_ft2232spi,
hailfingerf31da3d2009-06-16 21:08:06 +0000211 .init = ft2232_spi_init,
hailfinger6fe23d62009-08-12 11:39:29 +0000212 .map_flash_region = fallback_map,
213 .unmap_flash_region = fallback_unmap,
hailfingerf31da3d2009-06-16 21:08:06 +0000214 .delay = internal_delay,
215 },
hailfingerd9dcfbd2009-08-19 13:27:58 +0000216#endif
hailfinger6fe23d62009-08-12 11:39:29 +0000217
hailfinger90c7d542010-05-31 15:27:27 +0000218#if CONFIG_SERPROG == 1
hailfinger37b4fbf2009-06-23 11:33:43 +0000219 {
hailfinger3548a9a2009-08-12 14:34:35 +0000220 .name = "serprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100221 .type = OTHER,
222 /* FIXME */
223 .devs.note = "All programmer devices speaking the serprog protocol\n",
hailfinger37b4fbf2009-06-23 11:33:43 +0000224 .init = serprog_init,
hailfinger37b4fbf2009-06-23 11:33:43 +0000225 .map_flash_region = fallback_map,
226 .unmap_flash_region = fallback_unmap,
hailfinger37b4fbf2009-06-23 11:33:43 +0000227 .delay = serprog_delay,
228 },
hailfinger74d88a72009-08-12 16:17:41 +0000229#endif
hailfingerf31da3d2009-06-16 21:08:06 +0000230
hailfinger90c7d542010-05-31 15:27:27 +0000231#if CONFIG_BUSPIRATE_SPI == 1
hailfinger9c5add72009-11-24 00:20:03 +0000232 {
hailfinger90c7d542010-05-31 15:27:27 +0000233 .name = "buspirate_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100234 .type = OTHER,
235 /* FIXME */
236 .devs.note = "Dangerous Prototypes Bus Pirate\n",
hailfinger9c5add72009-11-24 00:20:03 +0000237 .init = buspirate_spi_init,
hailfinger9c5add72009-11-24 00:20:03 +0000238 .map_flash_region = fallback_map,
239 .unmap_flash_region = fallback_unmap,
hailfinger9c5add72009-11-24 00:20:03 +0000240 .delay = internal_delay,
241 },
242#endif
243
Anton Staafb2647882014-09-17 15:13:43 -0700244#if CONFIG_RAIDEN_DEBUG_SPI == 1
245 {
246 .name = "raiden_debug_spi",
Brian J. Nemecb42d6c12020-07-23 03:07:38 -0700247 .type = USB,
248 .devs.dev = devs_raiden,
Anton Staafb2647882014-09-17 15:13:43 -0700249 .init = raiden_debug_spi_init,
250 .map_flash_region = fallback_map,
251 .unmap_flash_region = fallback_unmap,
252 .delay = internal_delay,
253 },
254#endif
255
hailfinger90c7d542010-05-31 15:27:27 +0000256#if CONFIG_DEDIPROG == 1
hailfingerdfb32a02010-01-19 11:15:48 +0000257 {
258 .name = "dediprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100259 .type = USB,
hailfingerdfb32a02010-01-19 11:15:48 +0000260 .init = dediprog_init,
hailfingerdfb32a02010-01-19 11:15:48 +0000261 .map_flash_region = fallback_map,
262 .unmap_flash_region = fallback_unmap,
hailfingerdfb32a02010-01-19 11:15:48 +0000263 .delay = internal_delay,
264 },
265#endif
266
hailfinger52c4fa02010-07-21 10:26:01 +0000267#if CONFIG_RAYER_SPI == 1
268 {
269 .name = "rayer_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100270 .type = OTHER,
271 /* FIXME */
272 .devs.note = "RayeR parallel port programmer\n",
hailfinger52c4fa02010-07-21 10:26:01 +0000273 .init = rayer_spi_init,
hailfinger52c4fa02010-07-21 10:26:01 +0000274 .map_flash_region = fallback_map,
275 .unmap_flash_region = fallback_unmap,
hailfinger52c4fa02010-07-21 10:26:01 +0000276 .delay = internal_delay,
277 },
278#endif
279
hailfinger7949b652011-05-08 00:24:18 +0000280#if CONFIG_NICINTEL == 1
281 {
282 .name = "nicintel",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100283 .type = PCI,
284 .devs.dev = nics_intel,
hailfinger7949b652011-05-08 00:24:18 +0000285 .init = nicintel_init,
hailfinger7949b652011-05-08 00:24:18 +0000286 .map_flash_region = fallback_map,
287 .unmap_flash_region = fallback_unmap,
hailfinger7949b652011-05-08 00:24:18 +0000288 .delay = internal_delay,
289 },
290#endif
291
uwe6764e922010-09-03 18:21:21 +0000292#if CONFIG_NICINTEL_SPI == 1
293 {
uwe8d342eb2011-07-28 08:13:25 +0000294 .name = "nicintel_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100295 .type = PCI,
296 .devs.dev = nics_intel_spi,
uwe8d342eb2011-07-28 08:13:25 +0000297 .init = nicintel_spi_init,
298 .map_flash_region = fallback_map,
299 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000300 .delay = internal_delay,
uwe6764e922010-09-03 18:21:21 +0000301 },
302#endif
303
hailfingerfb1f31f2010-12-03 14:48:11 +0000304#if CONFIG_OGP_SPI == 1
305 {
uwe8d342eb2011-07-28 08:13:25 +0000306 .name = "ogp_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100307 .type = PCI,
308 .devs.dev = ogp_spi,
uwe8d342eb2011-07-28 08:13:25 +0000309 .init = ogp_spi_init,
310 .map_flash_region = fallback_map,
311 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000312 .delay = internal_delay,
hailfingerfb1f31f2010-12-03 14:48:11 +0000313 },
314#endif
315
hailfinger935365d2011-02-04 21:37:59 +0000316#if CONFIG_SATAMV == 1
317 {
318 .name = "satamv",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100319 .type = PCI,
320 .devs.dev = satas_mv,
hailfinger935365d2011-02-04 21:37:59 +0000321 .init = satamv_init,
hailfinger935365d2011-02-04 21:37:59 +0000322 .map_flash_region = fallback_map,
323 .unmap_flash_region = fallback_unmap,
hailfinger935365d2011-02-04 21:37:59 +0000324 .delay = internal_delay,
325 },
326#endif
327
David Hendrickscebee892015-05-23 20:30:30 -0700328#if CONFIG_LINUX_MTD == 1
329 {
330 .name = "linux_mtd",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100331 .type = OTHER,
332 .devs.note = "Device files /dev/mtd*\n",
David Hendrickscebee892015-05-23 20:30:30 -0700333 .init = linux_mtd_init,
334 .map_flash_region = fallback_map,
335 .unmap_flash_region = fallback_unmap,
336 .delay = internal_delay,
337 },
338#endif
339
uwe7df6dda2011-09-03 18:37:52 +0000340#if CONFIG_LINUX_SPI == 1
341 {
342 .name = "linux_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100343 .type = OTHER,
344 .devs.note = "Device files /dev/spidev*.*\n",
uwe7df6dda2011-09-03 18:37:52 +0000345 .init = linux_spi_init,
346 .map_flash_region = fallback_map,
347 .unmap_flash_region = fallback_unmap,
uwe7df6dda2011-09-03 18:37:52 +0000348 .delay = internal_delay,
349 },
350#endif
351
Shiyu Sun9dde7162020-04-16 17:32:55 +1000352#if CONFIG_LSPCON_I2C_SPI == 1
353 {
354 .name = "lspcon_i2c_spi",
355 .type = OTHER,
356 .devs.note = "Device files /dev/i2c-*.\n",
357 .init = lspcon_i2c_spi_init,
358 .map_flash_region = fallback_map,
359 .unmap_flash_region = fallback_unmap,
360 .delay = internal_delay,
361 },
362#endif
363
Edward O'Callaghan97dd9262020-03-26 00:00:41 +1100364#if CONFIG_REALTEK_MST_I2C_SPI == 1
365 {
366 .name = "realtek_mst_i2c_spi",
367 .type = OTHER,
368 .devs.note = "Device files /dev/i2c-*.\n",
369 .init = realtek_mst_i2c_spi_init,
370 .map_flash_region = fallback_map,
371 .unmap_flash_region = fallback_unmap,
372 .delay = internal_delay,
373 },
374#endif
375
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100376 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000377};
stepan927d4e22007-04-04 22:45:58 +0000378
David Hendricksbf36f092010-11-02 23:39:29 -0700379#define CHIP_RESTORE_MAXFN 4
380static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000381static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700382 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700383 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700384 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000385} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700386
David Hendricks668f29d2011-01-27 18:51:45 -0800387
hailfingerf31cbdc2010-11-10 15:25:18 +0000388#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000389static int shutdown_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000390static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700391 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000392 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000393} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000394/* Initialize to 0 to make sure nobody registers a shutdown function before
395 * programmer init.
396 */
397static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000398
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700399static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000400
hailfingerdc6f7972010-02-14 01:20:28 +0000401/* Register a function to be executed on programmer shutdown.
402 * The advantage over atexit() is that you can supply a void pointer which will
403 * be used as parameter to the registered function upon programmer shutdown.
404 * This pointer can point to arbitrary data used by said function, e.g. undo
405 * information for GPIO settings etc. If unneeded, set data=NULL.
406 * Please note that the first (void *data) belongs to the function signature of
407 * the function passed as first parameter.
408 */
David Hendricks93784b42016-08-09 17:00:38 -0700409int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000410{
411 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000412 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000413 SHUTDOWN_MAXFN);
414 return 1;
415 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000416 if (!may_register_shutdown) {
417 msg_perr("Tried to register a shutdown function before "
418 "programmer init.\n");
419 return 1;
420 }
hailfingerdc6f7972010-02-14 01:20:28 +0000421 shutdown_fn[shutdown_fn_count].func = function;
422 shutdown_fn[shutdown_fn_count].data = data;
423 shutdown_fn_count++;
424
425 return 0;
426}
427
David Hendricksbf36f092010-11-02 23:39:29 -0700428//int register_chip_restore(int (*function) (void *data), void *data)
429int register_chip_restore(CHIP_RESTORE_CALLBACK,
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700430 struct flashctx *flash, uint8_t status)
David Hendricksbf36f092010-11-02 23:39:29 -0700431{
432 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
433 msg_perr("Tried to register more than %i chip restore"
434 " functions.\n", CHIP_RESTORE_MAXFN);
435 return 1;
436 }
437 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
438 chip_restore_fn[chip_restore_fn_count].flash = flash;
439 chip_restore_fn[chip_restore_fn_count].status = status;
440 chip_restore_fn_count++;
441
442 return 0;
443}
444
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000445int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000446{
hailfinger1ef766d2010-07-06 09:55:48 +0000447 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000448
449 if (prog >= PROGRAMMER_INVALID) {
450 msg_perr("Invalid programmer specified!\n");
451 return -1;
452 }
453 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000454 /* Initialize all programmer specific data. */
455 /* Default to unlimited decode sizes. */
456 max_rom_decode = (const struct decode_sizes) {
457 .parallel = 0xffffffff,
458 .lpc = 0xffffffff,
459 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000460 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000461 };
David Hendricksac1d25c2016-08-09 17:00:58 -0700462 buses_supported = BUS_NONE;
hailfinger1ff33dc2010-07-03 11:02:10 +0000463 /* Default to top aligned flash at 4 GB. */
464 flashbase = 0;
465 /* Registering shutdown functions is now allowed. */
466 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000467 /* Default to allowing writes. Broken programmers set this to 0. */
468 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000469
470 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000471 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700472 ret = programmer_table[programmer].init();
hailfinger1ef766d2010-07-06 09:55:48 +0000473 return ret;
uweabe92a52009-05-16 22:36:00 +0000474}
475
David Hendricksbf36f092010-11-02 23:39:29 -0700476int chip_restore()
477{
478 int rc = 0;
479
480 while (chip_restore_fn_count > 0) {
481 int i = --chip_restore_fn_count;
482 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
483 chip_restore_fn[i].status);
484 }
485
486 return rc;
487}
488
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000489/** Calls registered shutdown functions and resets internal programmer-related variables.
490 * Calling it is safe even without previous initialization, but further interactions with programmer support
491 * require a call to programmer_init() (afterwards).
492 *
493 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700494int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000495{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000496 int ret = 0;
497
hailfinger1ff33dc2010-07-03 11:02:10 +0000498 /* Registering shutdown functions is no longer allowed. */
499 may_register_shutdown = 0;
500 while (shutdown_fn_count > 0) {
501 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700502 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000503 }
dhendrix0ffc2eb2011-06-14 01:35:36 +0000504 return ret;
uweabe92a52009-05-16 22:36:00 +0000505}
506
507void *programmer_map_flash_region(const char *descr, unsigned long phys_addr,
508 size_t len)
509{
510 return programmer_table[programmer].map_flash_region(descr,
511 phys_addr, len);
512}
513
514void programmer_unmap_flash_region(void *virt_addr, size_t len)
515{
516 programmer_table[programmer].unmap_flash_region(virt_addr, len);
517}
518
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700519void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000520{
Craig Hesling65eb8812019-08-01 09:33:56 -0700521 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000522}
523
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700524void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000525{
Craig Hesling65eb8812019-08-01 09:33:56 -0700526 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000527}
528
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700529void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000530{
Craig Hesling65eb8812019-08-01 09:33:56 -0700531 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000532}
533
Stuart langleyc98e43f2020-03-26 20:27:36 +1100534void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000535{
Craig Hesling65eb8812019-08-01 09:33:56 -0700536 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000537}
538
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700539uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000540{
Craig Hesling65eb8812019-08-01 09:33:56 -0700541 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000542}
543
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700544uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000545{
Craig Hesling65eb8812019-08-01 09:33:56 -0700546 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000547}
548
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700549uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000550{
Craig Hesling65eb8812019-08-01 09:33:56 -0700551 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000552}
553
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700554void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000555{
Craig Hesling65eb8812019-08-01 09:33:56 -0700556 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000557}
558
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000559void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000560{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000561 if (usecs > 0)
562 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000563}
564
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700565void map_flash_registers(struct flashctx *flash)
stepan15e64bc2007-05-24 08:48:10 +0000566{
Patrick Georgif3fa2992017-02-02 16:24:44 +0100567 size_t size = flash->chip->total_size * 1024;
hailfinger8577ad12009-05-11 14:01:17 +0000568 /* Flash registers live 4 MByte below the flash. */
hailfinger0459e1c2009-08-19 13:55:34 +0000569 /* FIXME: This is incorrect for nonstandard flashbase. */
hailfingerb91c08c2011-08-15 19:54:20 +0000570 flash->virtual_registers = (chipaddr)programmer_map_flash_region("flash chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
stepan15e64bc2007-05-24 08:48:10 +0000571}
572
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700573int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000574{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700575 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000576
hailfinger23060112009-05-08 12:49:03 +0000577 return 0;
578}
579
David Hendricksda18f692016-10-21 17:49:49 -0700580/* This is a somewhat hacked function similar in some ways to strtok(). It will
581 * look for needle with a subsequent '=' in haystack, return a copy of needle.
hailfinger6e5a52a2009-11-24 18:27:10 +0000582 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000583char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000584{
David Hendricksda18f692016-10-21 17:49:49 -0700585 char *param_pos, *opt_pos;
hailfinger1ef766d2010-07-06 09:55:48 +0000586 char *opt = NULL;
587 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000588 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000589
hailfingerf4aaccc2010-04-28 15:22:14 +0000590 needlelen = strlen(needle);
591 if (!needlelen) {
592 msg_gerr("%s: empty needle! Please report a bug at "
593 "flashrom@flashrom.org\n", __func__);
594 return NULL;
595 }
596 /* No programmer parameters given. */
597 if (*haystack == NULL)
598 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000599 param_pos = strstr(*haystack, needle);
600 do {
601 if (!param_pos)
602 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000603 /* Needle followed by '='? */
604 if (param_pos[needlelen] == '=') {
Simon Glass8dc82732013-07-16 10:13:51 -0600605
hailfinger1ef766d2010-07-06 09:55:48 +0000606 /* Beginning of the string? */
607 if (param_pos == *haystack)
608 break;
609 /* After a delimiter? */
610 if (strchr(delim, *(param_pos - 1)))
611 break;
612 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000613 /* Continue searching. */
614 param_pos++;
615 param_pos = strstr(param_pos, needle);
616 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000617
hailfinger6e5a52a2009-11-24 18:27:10 +0000618 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000619 /* Get the string after needle and '='. */
620 opt_pos = param_pos + needlelen + 1;
621 optlen = strcspn(opt_pos, delim);
622 /* Return an empty string if the parameter was empty. */
623 opt = malloc(optlen + 1);
624 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000625 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000626 exit(1);
627 }
hailfinger1ef766d2010-07-06 09:55:48 +0000628 strncpy(opt, opt_pos, optlen);
629 opt[optlen] = '\0';
hailfinger6e5a52a2009-11-24 18:27:10 +0000630 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000631
hailfinger1ef766d2010-07-06 09:55:48 +0000632 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000633}
634
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000635char *extract_programmer_param(const char *const param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000636{
637 return extract_param(&programmer_param, param_name, ",");
638}
639
stefancte1c5acf2011-07-04 07:27:17 +0000640/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700641static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000642{
643 unsigned int usable_erasefunctions = 0;
644 int k;
645 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
646 if (!check_block_eraser(flash, k, 0))
647 usable_erasefunctions++;
648 }
649 return usable_erasefunctions;
650}
651
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000652static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700653{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000654 int ret = 0, failcount = 0;
655 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700656 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000657 if (wantbuf[i] != havebuf[i]) {
658 /* Only print the first failure. */
659 if (!failcount++)
660 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
661 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700662 }
663 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000664 if (failcount) {
665 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
666 start, start + len - 1, failcount);
667 ret = -1;
668 }
669 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700670}
671
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000672/* start is an offset to the base address of the flash chip */
673static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
674{
675 int ret;
676 uint8_t *cmpbuf = malloc(len);
677 const uint8_t erased_value = ERASED_VALUE(flash);
678
679 if (!cmpbuf) {
680 msg_gerr("Could not allocate memory!\n");
681 exit(1);
682 }
683 memset(cmpbuf, erased_value, len);
684 ret = verify_range(flash, cmpbuf, start, len);
685 free(cmpbuf);
686 return ret;
687}
688
uwee15beb92010-08-08 17:01:18 +0000689/*
hailfinger7af3d192009-11-25 17:05:52 +0000690 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000691 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000692 * @start offset to the base address of the flash chip
693 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000694 * @return 0 for success, -1 for failure
695 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000696int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000697{
hailfinger7af83692009-06-15 17:23:36 +0000698 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000699 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000700
Patrick Georgif3fa2992017-02-02 16:24:44 +0100701 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000702 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000703 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000704 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000705
706 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000707 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000708 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000709 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000710 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000711 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000712
Patrick Georgif3fa2992017-02-02 16:24:44 +0100713 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000714 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000715 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100716 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000717 ret = -1;
718 goto out_free;
719 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700720 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700721 if (programmer_table[programmer].paranoid) {
722 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800723
Simon Glass4e305f42015-01-08 06:29:04 -0700724 /* limit chunksize in order to catch errors early */
725 for (i = 0, chunksize = 0; i < len; i += chunksize) {
726 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800727
Patrick Georgif3fa2992017-02-02 16:24:44 +0100728 chunksize = min(flash->chip->page_size, len - i);
729 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700730 if (tmp) {
731 ret = tmp;
732 if (ignore_error(tmp))
733 continue;
734 else
735 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800736 }
Simon Glass4e305f42015-01-08 06:29:04 -0700737
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700738 /*
739 * Check write access permission and do not compare chunks
740 * where flashrom does not have write access to the region.
741 */
742 if (flash->chip->check_access) {
743 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
744 if (tmp && ignore_error(tmp))
745 continue;
746 }
747
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000748 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700749 if (failcount)
750 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800751 }
Simon Glass4e305f42015-01-08 06:29:04 -0700752 } else {
753 int tmp;
754
755 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +0100756 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -0700757 if (tmp && !ignore_error(tmp)) {
758 ret = tmp;
759 goto out_free;
760 }
761
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000762 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +0000763 }
764
hailfinger5be6c0f2009-07-23 01:42:56 +0000765 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +0000766 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +0000767 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +0000768 ret = -1;
769 }
hailfinger7af83692009-06-15 17:23:36 +0000770
771out_free:
772 free(readbuf);
773 return ret;
774}
775
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100776/* Helper function for need_erase() that focuses on granularities of gran bytes. */
777static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000778 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100779{
780 unsigned int i, j, limit;
781 for (j = 0; j < len / gran; j++) {
782 limit = min (gran, len - j * gran);
783 /* Are 'have' and 'want' identical? */
784 if (!memcmp(have + j * gran, want + j * gran, limit))
785 continue;
786 /* have needs to be in erased state. */
787 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000788 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100789 return 1;
790 }
791 return 0;
792}
793
uwee15beb92010-08-08 17:01:18 +0000794/*
hailfingerb247c7a2010-03-08 00:42:32 +0000795 * Check if the buffer @have can be programmed to the content of @want without
796 * erasing. This is only possible if all chunks of size @gran are either kept
797 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +0000798 *
hailfingerb437e282010-11-04 01:04:27 +0000799 * Warning: This function assumes that @have and @want point to naturally
800 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +0000801 *
802 * @have buffer with current content
803 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +0000804 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +0000805 * @gran write granularity (enum, not count)
806 * @return 0 if no erase is needed, 1 otherwise
807 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000808int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
809 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +0000810{
hailfingerb91c08c2011-08-15 19:54:20 +0000811 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100812 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -0700813
hailfingerb247c7a2010-03-08 00:42:32 +0000814 switch (gran) {
815 case write_gran_1bit:
816 for (i = 0; i < len; i++)
817 if ((have[i] & want[i]) != want[i]) {
818 result = 1;
819 break;
820 }
821 break;
822 case write_gran_1byte:
823 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000824 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +0000825 result = 1;
826 break;
827 }
828 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100829 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000830 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100831 break;
hailfingerb247c7a2010-03-08 00:42:32 +0000832 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000833 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100834 break;
835 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000836 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100837 break;
838 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000839 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100840 break;
841 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000842 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100843 break;
844 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000845 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100846 break;
847 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000848 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100849 break;
850 case write_gran_1byte_implicit_erase:
851 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
852 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +0000853 break;
hailfingerb437e282010-11-04 01:04:27 +0000854 default:
855 msg_cerr("%s: Unsupported granularity! Please report a bug at "
856 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +0000857 }
858 return result;
859}
860
hailfingerb437e282010-11-04 01:04:27 +0000861/**
862 * Check if the buffer @have needs to be programmed to get the content of @want.
863 * If yes, return 1 and fill in first_start with the start address of the
864 * write operation and first_len with the length of the first to-be-written
865 * chunk. If not, return 0 and leave first_start and first_len undefined.
866 *
867 * Warning: This function assumes that @have and @want point to naturally
868 * aligned regions.
869 *
870 * @have buffer with current content
871 * @want buffer with desired content
872 * @len length of the checked area
873 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +0000874 * @first_start offset of the first byte which needs to be written (passed in
875 * value is increased by the offset of the first needed write
876 * relative to have/want or unchanged if no write is needed)
877 * @return length of the first contiguous area which needs to be written
878 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +0000879 *
880 * FIXME: This function needs a parameter which tells it about coalescing
881 * in relation to the max write length of the programmer and the max write
882 * length of the chip.
883 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000884static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +0000885 unsigned int *first_start,
886 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +0000887{
stefanctc5eb8a92011-11-23 09:13:48 +0000888 int need_write = 0;
889 unsigned int rel_start = 0, first_len = 0;
890 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +0000891
hailfingerb437e282010-11-04 01:04:27 +0000892 switch (gran) {
893 case write_gran_1bit:
894 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100895 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +0000896 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +0000897 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100898 case write_gran_128bytes:
899 stride = 128;
900 break;
hailfingerb437e282010-11-04 01:04:27 +0000901 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +0000902 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +0000903 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100904 case write_gran_264bytes:
905 stride = 264;
906 break;
907 case write_gran_512bytes:
908 stride = 512;
909 break;
910 case write_gran_528bytes:
911 stride = 528;
912 break;
913 case write_gran_1024bytes:
914 stride = 1024;
915 break;
916 case write_gran_1056bytes:
917 stride = 1056;
918 break;
hailfingerb437e282010-11-04 01:04:27 +0000919 default:
920 msg_cerr("%s: Unsupported granularity! Please report a bug at "
921 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +0000922 /* Claim that no write was needed. A write with unknown
923 * granularity is too dangerous to try.
924 */
925 return 0;
hailfingerb437e282010-11-04 01:04:27 +0000926 }
hailfinger90fcf9b2010-11-05 14:51:59 +0000927 for (i = 0; i < len / stride; i++) {
928 limit = min(stride, len - i * stride);
929 /* Are 'have' and 'want' identical? */
930 if (memcmp(have + i * stride, want + i * stride, limit)) {
931 if (!need_write) {
932 /* First location where have and want differ. */
933 need_write = 1;
934 rel_start = i * stride;
935 }
936 } else {
937 if (need_write) {
938 /* First location where have and want
939 * do not differ anymore.
940 */
hailfinger90fcf9b2010-11-05 14:51:59 +0000941 break;
942 }
943 }
944 }
hailfingerffb7f382010-12-06 13:05:44 +0000945 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +0000946 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +0000947 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +0000948 return first_len;
hailfingerb437e282010-11-04 01:04:27 +0000949}
950
hailfinger0c515352009-11-23 12:55:31 +0000951/* This function generates various test patterns useful for testing controller
952 * and chip communication as well as chip behaviour.
953 *
954 * If a byte can be written multiple times, each time keeping 0-bits at 0
955 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
956 * is essentially an AND operation. That's also the reason why this function
957 * provides the result of AND between various patterns.
958 *
959 * Below is a list of patterns (and their block length).
960 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
961 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
962 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
963 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
964 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
965 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
966 * Pattern 6 is 00 (1 Byte)
967 * Pattern 7 is ff (1 Byte)
968 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
969 * byte block.
970 *
971 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
972 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
973 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
974 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
975 * Pattern 12 is 00 (1 Byte)
976 * Pattern 13 is ff (1 Byte)
977 * Patterns 8-13 have no block number.
978 *
979 * Patterns 0-3 are created to detect and efficiently diagnose communication
980 * slips like missed bits or bytes and their repetitive nature gives good visual
981 * cues to the person inspecting the results. In addition, the following holds:
982 * AND Pattern 0/1 == Pattern 4
983 * AND Pattern 2/3 == Pattern 5
984 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
985 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
986 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
987 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
988 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
989 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
990 * Besides that, they provide for bit testing of the last two bytes of every
991 * 256 byte block which contains the block number for patterns 0-6.
992 * Patterns 10-11 are special purpose for detecting subblock aliasing with
993 * block sizes >256 bytes (some Dataflash chips etc.)
994 * AND Pattern 8/9 == Pattern 12
995 * AND Pattern 10/11 == Pattern 12
996 * Pattern 13 is the completely erased state.
997 * None of the patterns can detect aliasing at boundaries which are a multiple
998 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
999 */
1000int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1001{
1002 int i;
1003
1004 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001005 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001006 return 1;
1007 }
1008
1009 switch (variant) {
1010 case 0:
1011 for (i = 0; i < size; i++)
1012 buf[i] = (i & 0xf) << 4 | 0x5;
1013 break;
1014 case 1:
1015 for (i = 0; i < size; i++)
1016 buf[i] = (i & 0xf) << 4 | 0xa;
1017 break;
1018 case 2:
1019 for (i = 0; i < size; i++)
1020 buf[i] = 0x50 | (i & 0xf);
1021 break;
1022 case 3:
1023 for (i = 0; i < size; i++)
1024 buf[i] = 0xa0 | (i & 0xf);
1025 break;
1026 case 4:
1027 for (i = 0; i < size; i++)
1028 buf[i] = (i & 0xf) << 4;
1029 break;
1030 case 5:
1031 for (i = 0; i < size; i++)
1032 buf[i] = i & 0xf;
1033 break;
1034 case 6:
1035 memset(buf, 0x00, size);
1036 break;
1037 case 7:
1038 memset(buf, 0xff, size);
1039 break;
1040 case 8:
1041 for (i = 0; i < size; i++)
1042 buf[i] = i & 0xff;
1043 break;
1044 case 9:
1045 for (i = 0; i < size; i++)
1046 buf[i] = ~(i & 0xff);
1047 break;
1048 case 10:
1049 for (i = 0; i < size % 2; i++) {
1050 buf[i * 2] = (i >> 8) & 0xff;
1051 buf[i * 2 + 1] = i & 0xff;
1052 }
1053 if (size & 0x1)
1054 buf[i * 2] = (i >> 8) & 0xff;
1055 break;
1056 case 11:
1057 for (i = 0; i < size % 2; i++) {
1058 buf[i * 2] = ~((i >> 8) & 0xff);
1059 buf[i * 2 + 1] = ~(i & 0xff);
1060 }
1061 if (size & 0x1)
1062 buf[i * 2] = ~((i >> 8) & 0xff);
1063 break;
1064 case 12:
1065 memset(buf, 0x00, size);
1066 break;
1067 case 13:
1068 memset(buf, 0xff, size);
1069 break;
1070 }
1071
1072 if ((variant >= 0) && (variant <= 7)) {
1073 /* Write block number in the last two bytes of each 256-byte
1074 * block, big endian for easier reading of the hexdump.
1075 * Note that this wraps around for chips larger than 2^24 bytes
1076 * (16 MB).
1077 */
1078 for (i = 0; i < size / 256; i++) {
1079 buf[i * 256 + 254] = (i >> 8) & 0xff;
1080 buf[i * 256 + 255] = i & 0xff;
1081 }
1082 }
1083
1084 return 0;
1085}
1086
hailfingeraec9c962009-10-31 01:53:09 +00001087int check_max_decode(enum chipbustype buses, uint32_t size)
1088{
1089 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001090
1091 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001092 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001093 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001094 "size %u kB of chipset/board/programmer "
1095 "for %s interface, "
1096 "probe/read/erase/write may fail. ", size / 1024,
1097 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001098 }
hailfingere1e41ea2011-07-27 07:13:06 +00001099 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001100 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001101 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001102 "size %u kB of chipset/board/programmer "
1103 "for %s interface, "
1104 "probe/read/erase/write may fail. ", size / 1024,
1105 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001106 }
hailfingere1e41ea2011-07-27 07:13:06 +00001107 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001108 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001109 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001110 "size %u kB of chipset/board/programmer "
1111 "for %s interface, "
1112 "probe/read/erase/write may fail. ", size / 1024,
1113 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001114 }
hailfingere1e41ea2011-07-27 07:13:06 +00001115 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001116 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001117 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001118 "size %u kB of chipset/board/programmer "
1119 "for %s interface, "
1120 "probe/read/erase/write may fail. ", size / 1024,
1121 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001122 }
1123 if (!limitexceeded)
1124 return 0;
1125 /* Sometimes chip and programmer have more than one bus in common,
1126 * and the limit is not exceeded on all buses. Tell the user.
1127 */
1128 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001129 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001130 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001131 "interface which can support a chip of this size. "
1132 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001133 return 1;
1134}
1135
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001136/*
1137 * Return a string corresponding to the bustype parameter.
1138 * Memory is obtained with malloc() and must be freed with free() by the caller.
1139 */
1140char *flashbuses_to_text(enum chipbustype bustype)
1141{
1142 char *ret = calloc(1, 1);
1143 /*
1144 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1145 * will cease to exist and should be eliminated here as well.
1146 */
1147 if (bustype == BUS_NONSPI) {
1148 ret = strcat_realloc(ret, "Non-SPI, ");
1149 } else {
1150 if (bustype & BUS_PARALLEL)
1151 ret = strcat_realloc(ret, "Parallel, ");
1152 if (bustype & BUS_LPC)
1153 ret = strcat_realloc(ret, "LPC, ");
1154 if (bustype & BUS_FWH)
1155 ret = strcat_realloc(ret, "FWH, ");
1156 if (bustype & BUS_SPI)
1157 ret = strcat_realloc(ret, "SPI, ");
1158 if (bustype & BUS_PROG)
1159 ret = strcat_realloc(ret, "Programmer-specific, ");
1160 if (bustype == BUS_NONE)
1161 ret = strcat_realloc(ret, "None, ");
1162 }
1163 /* Kill last comma. */
1164 ret[strlen(ret) - 2] = '\0';
1165 ret = realloc(ret, strlen(ret) + 1);
1166 return ret;
1167}
1168
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001169int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001170{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001171 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001172 unsigned long base = 0;
stepan3e7aeae2011-01-19 06:21:54 +00001173 char location[64];
hailfingeraec9c962009-10-31 01:53:09 +00001174 uint32_t size;
1175 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001176 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001177
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301178 /* Based on the host controller interface that a platform
1179 * needs to use (hwseq or swseq),
1180 * set the flashchips list here.
1181 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001182 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301183 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001184 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301185 flash_list = flashchips_hwseq;
1186 break;
1187 default:
1188 flash_list = flashchips;
1189 break;
1190 }
1191
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001192 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1193 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001194 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001195 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001196 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001197 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001198 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001199 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001200 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001201 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001202 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001203 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001204 continue;
1205 }
stepan782fb172007-04-06 11:58:03 +00001206
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001207 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001208 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001209
hailfinger48ed3e22011-05-04 00:39:50 +00001210 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001211 flash->chip = calloc(1, sizeof(struct flashchip));
1212 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001213 msg_gerr("Out of memory!\n");
1214 exit(1);
1215 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001216 memcpy(flash->chip, chip, sizeof(struct flashchip));
1217 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001218
Edward O'Callaghan7bd44c62019-11-13 12:44:49 +11001219 base = flashbase ? flashbase : (0xffffffff - size + 1);
1220 flash->virtual_memory = (chipaddr)programmer_map_flash_region("flash chip", base, size);
rminnich8d3ff912003-10-25 17:01:29 +00001221
stugec1e55fe2008-07-02 17:15:47 +00001222 if (force)
1223 break;
stepanc98b80b2006-03-16 16:57:41 +00001224
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001225 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001226 goto notfound;
1227
hailfinger48ed3e22011-05-04 00:39:50 +00001228 /* If this is the first chip found, accept it.
1229 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001230 * a non-generic match. SFDP and CFI are generic matches.
1231 * startchip==0 means this call to probe_flash() is the first
1232 * one for this programmer interface (master) and thus no other chip has
1233 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001234 */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001235 if (startchip == 0 || flash->chip->model_id != GENERIC_DEVICE_ID)
stugec1e55fe2008-07-02 17:15:47 +00001236 break;
1237
stuge56300c32008-09-03 23:10:05 +00001238notfound:
Martin Roth80be5552019-12-23 15:22:11 -07001239 if (size)
1240 programmer_unmap_flash_region((void *)flash->virtual_memory, size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001241 free(flash->chip);
1242 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001243 }
uwebe4477b2007-08-23 16:08:21 +00001244
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001245 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001246 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001247
hailfingere11396b2011-03-08 00:09:11 +00001248#if CONFIG_INTERNAL == 1
1249 if (programmer_table[programmer].map_flash_region == physmap)
stepan3e7aeae2011-01-19 06:21:54 +00001250 snprintf(location, sizeof(location), "at physical address 0x%lx", base);
hailfingere11396b2011-03-08 00:09:11 +00001251 else
1252#endif
stepan3e7aeae2011-01-19 06:21:54 +00001253 snprintf(location, sizeof(location), "on %s", programmer_table[programmer].name);
stepan3e7aeae2011-01-19 06:21:54 +00001254
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001255 tmp = flashbuses_to_text(chip->bustype);
stefanctdfd58832011-07-25 20:38:52 +00001256 msg_cdbg("%s %s flash chip \"%s\" (%d kB, %s) %s.\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001257 force ? "Assuming" : "Found", flash->chip->vendor,
1258 flash->chip->name, flash->chip->total_size, tmp,
Patrick Georgif3fa2992017-02-02 16:24:44 +01001259 location);
stefanct588b6d22011-06-26 20:45:35 +00001260 free(tmp);
uwe9e6811e2009-06-28 21:47:57 +00001261
hailfinger0f4c3952010-12-02 21:59:42 +00001262 /* Flash registers will not be mapped if the chip was forced. Lock info
1263 * may be stored in registers, so avoid lock info printing.
1264 */
1265 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001266 if (flash->chip->printlock)
1267 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001268
hailfinger48ed3e22011-05-04 00:39:50 +00001269 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001270 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001271}
1272
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001273static int verify_flash(struct flashctx *flash,
1274 struct action_descriptor *descriptor,
1275 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001276{
hailfingerb0f4d122009-06-24 08:20:45 +00001277 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001278 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001279 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001280
snelsone42c3802010-05-07 20:09:04 +00001281 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001282
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001283 if (verify_it == VERIFY_PARTIAL) {
1284 struct processing_unit *pu = descriptor->processing_units;
1285
1286 /* Verify only areas which were written. */
1287 while (pu->num_blocks) {
1288 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001289 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001290 if (ret)
1291 break;
1292 pu++;
1293 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001294 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001295 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001296 }
uwef6641642007-05-09 10:17:44 +00001297
David Hendricks1ed1d352011-11-23 17:54:37 -08001298 if (ret == ACCESS_DENIED) {
1299 msg_gdbg("Could not fully verify due to access error, ");
1300 if (access_denied_action == error_ignore) {
1301 msg_gdbg("ignoring\n");
1302 ret = 0;
1303 } else {
1304 msg_gdbg("aborting\n");
1305 }
1306 }
1307
hailfingerb0f4d122009-06-24 08:20:45 +00001308 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001309 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001310
hailfingerb0f4d122009-06-24 08:20:45 +00001311 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001312}
1313
uwe8d342eb2011-07-28 08:13:25 +00001314int read_buf_from_file(unsigned char *buf, unsigned long size,
1315 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001316{
1317 unsigned long numbytes;
1318 FILE *image;
1319 struct stat image_stat;
1320
Vincent Palatin7ab23932014-10-01 12:09:16 -07001321 if (!strncmp(filename, "-", sizeof("-")))
1322 image = fdopen(STDIN_FILENO, "rb");
1323 else
1324 image = fopen(filename, "rb");
1325 if (image == NULL) {
hailfinger771fc182010-10-15 00:01:14 +00001326 perror(filename);
1327 return 1;
1328 }
1329 if (fstat(fileno(image), &image_stat) != 0) {
1330 perror(filename);
1331 fclose(image);
1332 return 1;
1333 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001334 if ((image_stat.st_size != size) &&
1335 (strncmp(filename, "-", sizeof("-")))) {
Mike Frysinger62c794d2017-05-29 12:02:45 -04001336 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1337 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
hailfinger771fc182010-10-15 00:01:14 +00001338 fclose(image);
1339 return 1;
1340 }
1341 numbytes = fread(buf, 1, size, image);
1342 if (fclose(image)) {
1343 perror(filename);
1344 return 1;
1345 }
1346 if (numbytes != size) {
1347 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1348 "wanted %ld!\n", numbytes, size);
1349 return 1;
1350 }
1351 return 0;
1352}
1353
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001354int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001355{
1356 unsigned long numbytes;
1357 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001358
1359 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001360 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001361 return 1;
1362 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001363 if (!strncmp(filename, "-", sizeof("-")))
1364 image = fdopen(STDOUT_FILENO, "wb");
1365 else
1366 image = fopen(filename, "wb");
1367 if (image == NULL) {
hailfingerd219a232009-01-28 00:27:54 +00001368 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001369 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001370 }
hailfingerd219a232009-01-28 00:27:54 +00001371
hailfingerd219a232009-01-28 00:27:54 +00001372 numbytes = fwrite(buf, 1, size, image);
1373 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001374 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001375 msg_gerr("Error: file %s could not be written completely.\n", filename);
hailfingerd219a232009-01-28 00:27:54 +00001376 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001377 }
hailfingerd219a232009-01-28 00:27:54 +00001378 return 0;
1379}
1380
David Hendrickse3451942013-03-21 17:23:29 -07001381/*
1382 * read_flash - wrapper for flash->read() with additional high-level policy
1383 *
1384 * @flash flash chip
1385 * @buf buffer to store data in
1386 * @start start address
1387 * @len number of bytes to read
1388 *
1389 * This wrapper simplifies most cases when the flash chip needs to be read
1390 * since policy decisions such as non-fatal error handling is centralized.
1391 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001392int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001393 unsigned int start, unsigned int len)
1394{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001395 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001396
Patrick Georgif3fa2992017-02-02 16:24:44 +01001397 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001398 return -1;
1399
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001400 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1401
Patrick Georgif3fa2992017-02-02 16:24:44 +01001402 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001403 if (ret) {
1404 if (ignore_error(ret)) {
1405 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1406 start, start + len - 1);
1407 ret = 0;
1408 } else {
1409 msg_gdbg("failed to read 0x%x-0x%x\n",
1410 start, start + len - 1);
1411 }
1412 }
1413
1414 return ret;
1415}
1416
David Hendricks7c8a1612013-04-26 19:14:44 -07001417/*
1418 * write_flash - wrapper for flash->write() with additional high-level policy
1419 *
1420 * @flash flash chip
1421 * @buf buffer to write to flash
1422 * @start start address in flash
1423 * @len number of bytes to write
1424 *
1425 * TODO: Look up regions that are write-protected and avoid attempt to write
1426 * to them at all.
1427 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001428int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001429 unsigned int start, unsigned int len)
1430{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001431 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001432 return -1;
1433
Patrick Georgif3fa2992017-02-02 16:24:44 +01001434 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001435}
1436
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001437int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001438{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001439 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001440 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001441 int ret = 0;
1442
1443 msg_cinfo("Reading flash... ");
1444 if (!buf) {
1445 msg_gerr("Memory allocation failed!\n");
1446 msg_cinfo("FAILED.\n");
1447 return 1;
1448 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001449
1450 /* To support partial read, fill buffer to all 0xFF at beginning to make
1451 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001452 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001453
Patrick Georgif3fa2992017-02-02 16:24:44 +01001454 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001455 msg_cerr("No read function available for this flash chip.\n");
1456 ret = 1;
1457 goto out_free;
1458 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001459
1460 /* First try to handle partial read case, rather than read the whole
1461 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001462 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001463 if (ret < 0) {
1464 msg_cerr("Partial read operation failed!\n");
1465 ret = 1;
1466 goto out_free;
1467 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001468 int num_regions = get_num_include_args();
1469
1470 if (ret != num_regions) {
1471 msg_cerr("Requested %d regions, but only read %d\n",
1472 num_regions, ret);
1473 ret = 1;
1474 goto out_free;
1475 }
1476
1477 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001478 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001479 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001480 msg_cerr("Read operation failed!\n");
1481 ret = 1;
1482 goto out_free;
1483 }
hailfinger42a850a2010-07-13 23:56:13 +00001484 }
1485
David Hendricksdf29a832013-06-28 14:33:51 -07001486 if (filename)
1487 ret = write_buf_to_file(buf, size, filename);
1488
hailfinger42a850a2010-07-13 23:56:13 +00001489out_free:
1490 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001491 if (ret)
1492 msg_cerr("FAILED.");
1493 else
1494 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001495 return ret;
1496}
1497
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001498/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001499static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001500{
hailfingerb91c08c2011-08-15 19:54:20 +00001501 int i, j, k;
1502 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001503
1504 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1505 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001506 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001507
1508 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1509 /* Blocks with zero size are bugs in flashchips.c. */
1510 if (eraser.eraseblocks[i].count &&
1511 !eraser.eraseblocks[i].size) {
1512 msg_gerr("ERROR: Flash chip %s erase function "
1513 "%i region %i has size 0. Please report"
1514 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001515 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001516 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001517 }
1518 /* Blocks with zero count are bugs in flashchips.c. */
1519 if (!eraser.eraseblocks[i].count &&
1520 eraser.eraseblocks[i].size) {
1521 msg_gerr("ERROR: Flash chip %s erase function "
1522 "%i region %i has count 0. Please report"
1523 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001524 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001525 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001526 }
1527 done += eraser.eraseblocks[i].count *
1528 eraser.eraseblocks[i].size;
1529 }
hailfinger9fed35d2010-01-19 06:42:46 +00001530 /* Empty eraseblock definition with erase function. */
1531 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001532 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001533 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001534 if (!done)
1535 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001536 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001537 msg_gerr("ERROR: Flash chip %s erase function %i "
1538 "region walking resulted in 0x%06x bytes total,"
1539 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001540 " flashrom@flashrom.org\n", chip->name, k,
1541 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001542 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001543 }
hailfinger9fed35d2010-01-19 06:42:46 +00001544 if (!eraser.block_erase)
1545 continue;
1546 /* Check if there are identical erase functions for different
1547 * layouts. That would imply "magic" erase functions. The
1548 * easiest way to check this is with function pointers.
1549 */
uwef6f94d42010-03-13 17:28:29 +00001550 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001551 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001552 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001553 msg_gerr("ERROR: Flash chip %s erase function "
1554 "%i and %i are identical. Please report"
1555 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001556 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001557 ret = 1;
1558 }
uwef6f94d42010-03-13 17:28:29 +00001559 }
hailfinger45177872010-01-18 08:14:43 +00001560 }
hailfinger9fed35d2010-01-19 06:42:46 +00001561 return ret;
hailfinger45177872010-01-18 08:14:43 +00001562}
1563
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001564static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001565 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001566 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001567 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001568 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001569 unsigned int addr,
1570 unsigned int len))
1571{
stefanctc5eb8a92011-11-23 09:13:48 +00001572 unsigned int starthere = 0, lenhere = 0;
1573 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001574 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001575 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001576
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001577 /*
1578 * curcontents and newcontents are opaque to walk_eraseregions, and
1579 * need to be adjusted here to keep the impression of proper
1580 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001581 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001582
hailfinger90fcf9b2010-11-05 14:51:59 +00001583 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001584
hailfingerb437e282010-11-04 01:04:27 +00001585 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001586
hailfingerb437e282010-11-04 01:04:27 +00001587 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001588 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001589 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001590 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001591 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001592 if (ret) {
1593 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001594 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001595 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001596 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001597 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001598 }
1599
David Hendricks0954ffc2015-11-13 15:15:44 -08001600 if (programmer_table[programmer].paranoid) {
1601 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001602 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001603 return -1;
1604 }
hailfingerac8e3182011-06-26 17:04:16 +00001605 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001606
hailfinger90fcf9b2010-11-05 14:51:59 +00001607 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001608 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001609 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001610 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001611 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001612 /* get_next_write() sets starthere to a new value after the call. */
1613 while ((lenhere = get_next_write(curcontents + starthere,
1614 newcontents + starthere,
1615 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001616 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001617 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001618 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001619 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001620 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001621 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001622 if (ret) {
1623 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001624 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001625 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001626 }
David Hendricks048b38c2016-03-28 18:47:06 -07001627
1628 /*
1629 * If the block needed to be erased and was erased successfully
1630 * then we can assume that we didn't run into any write-
1631 * protected areas. Otherwise, we need to verify each page to
1632 * ensure it was successfully written and abort if we encounter
1633 * any errors.
1634 */
1635 if (programmer_table[programmer].paranoid && !block_was_erased) {
1636 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001637 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001638 return -1;
1639 }
1640
hailfingerb437e282010-11-04 01:04:27 +00001641 starthere += lenhere;
1642 skip = 0;
1643 }
1644 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001645 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001646 return ret;
1647}
1648
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001649/*
1650 * Function to process processing units accumulated in the action descriptor.
1651 *
1652 * @flash pointer to the flash context to operate on
1653 * @do_something helper function which can erase and program a section of the
1654 * flash chip. It receives the flash context, offset and length
1655 * of the area to erase/program, before and after contents (to
1656 * decide what exactly needs to be erased and or programmed)
1657 * and a pointer to the erase function which can operate on the
1658 * proper granularity.
1659 * @descriptor action descriptor including pointers to before and after
1660 * contents and an array of processing actions to take.
1661 *
1662 * Returns zero on success or an error code.
1663 */
1664static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001665 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001666 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001667 unsigned int len,
1668 uint8_t *param1,
1669 uint8_t *param2,
1670 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001671 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001672 unsigned int addr,
1673 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001674 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00001675{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001676 struct processing_unit *pu;
1677 int rc = 0;
1678 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00001679
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001680 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1681 unsigned base = pu->offset;
1682 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07001683
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001684 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07001685
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001686 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00001687 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001688 else
1689 print_comma = 1;
1690
1691 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1692
1693 rc = do_something(flash, base,
1694 pu->block_size,
1695 descriptor->oldcontents,
1696 descriptor->newcontents,
1697 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
1698
David Hendricks1ed1d352011-11-23 17:54:37 -08001699 if (rc) {
1700 if (ignore_error(rc))
1701 rc = 0;
1702 else
1703 return rc;
hailfingerb437e282010-11-04 01:04:27 +00001704 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001705 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00001706 }
1707 }
hailfingerb437e282010-11-04 01:04:27 +00001708 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08001709 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00001710}
1711
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001712static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00001713{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001714 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00001715
1716 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1717 if (log)
1718 msg_cdbg("not defined. ");
1719 return 1;
1720 }
1721 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1722 if (log)
1723 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00001724 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00001725 return 1;
1726 }
1727 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1728 if (log)
1729 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00001730 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00001731 return 1;
1732 }
1733 return 0;
1734}
1735
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001736int erase_and_write_flash(struct flashctx *flash,
1737 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00001738{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001739 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00001740
hailfingercf848f12010-12-05 15:14:44 +00001741 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00001742
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001743 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00001744
hailfinger7df21362009-09-05 02:30:58 +00001745 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00001746 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00001747 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07001748 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00001749 }
1750 return ret;
hailfingerd219a232009-01-28 00:27:54 +00001751}
1752
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001753static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00001754{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001755 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
1756#if CONFIG_INTERNAL == 1
1757 if (programmer == PROGRAMMER_INTERNAL)
1758 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
1759 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1760 "mail flashrom@flashrom.org, thanks!\n"
1761 "-------------------------------------------------------------------------------\n"
1762 "You may now reboot or simply leave the machine running.\n");
1763 else
1764#endif
1765 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
1766 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
1767 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1768 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00001769}
1770
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001771static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00001772{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001773 msg_gerr("Your flash chip is in an unknown state.\n");
1774#if CONFIG_INTERNAL == 1
1775 if (programmer == PROGRAMMER_INTERNAL)
1776 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
1777 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
1778 "-------------------------------------------------------------------------------\n"
1779 "DO NOT REBOOT OR POWEROFF!\n");
1780 else
1781#endif
1782 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1783 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00001784}
1785
uwe8d342eb2011-07-28 08:13:25 +00001786/* The way to go if you want a delimited list of programmers */
stefanct52700282011-06-26 17:38:17 +00001787void list_programmers(const char *delim)
hailfingerc77acb52009-12-24 02:15:55 +00001788{
1789 enum programmer p;
1790 for (p = 0; p < PROGRAMMER_INVALID; p++) {
snelsone42c3802010-05-07 20:09:04 +00001791 msg_ginfo("%s", programmer_table[p].name);
hailfingerc77acb52009-12-24 02:15:55 +00001792 if (p < PROGRAMMER_INVALID - 1)
snelsone42c3802010-05-07 20:09:04 +00001793 msg_ginfo("%s", delim);
hailfingerc77acb52009-12-24 02:15:55 +00001794 }
Simon Glass8dc82732013-07-16 10:13:51 -06001795 msg_ginfo("\n");
hailfingerc77acb52009-12-24 02:15:55 +00001796}
1797
hailfingerf79d1712010-10-06 23:48:34 +00001798void list_programmers_linebreak(int startcol, int cols, int paren)
1799{
1800 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00001801 int pnamelen;
1802 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00001803 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00001804 int i;
hailfingerf79d1712010-10-06 23:48:34 +00001805
1806 for (p = 0; p < PROGRAMMER_INVALID; p++) {
1807 pname = programmer_table[p].name;
1808 pnamelen = strlen(pname);
1809 if (remaining - pnamelen - 2 < 0) {
1810 if (firstline)
1811 firstline = 0;
1812 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001813 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00001814 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001815 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00001816 remaining = cols - startcol;
1817 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001818 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00001819 remaining--;
1820 }
1821 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001822 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00001823 remaining--;
1824 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001825 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00001826 remaining -= pnamelen;
1827 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001828 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00001829 remaining--;
1830 } else {
1831 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001832 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00001833 }
1834 }
1835}
1836
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001837static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00001838{
David Hendricksc6c9f822010-11-03 15:07:01 -07001839 /* send to stderr for chromium os */
hailfinger3b471632010-03-27 16:36:40 +00001840#if HAVE_UTSNAME == 1
1841 struct utsname osinfo;
1842 uname(&osinfo);
1843
David Hendricksc6c9f822010-11-03 15:07:01 -07001844 msg_gerr(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00001845 osinfo.machine);
1846#else
David Hendricksc6c9f822010-11-03 15:07:01 -07001847 msg_gerr(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00001848#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001849}
1850
1851void print_buildinfo(void)
1852{
1853 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00001854#if NEED_PCI == 1
1855#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001856 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00001857#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001858 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00001859#endif
1860#endif
1861#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001862 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00001863#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001864 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00001865#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001866 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00001867#endif
hailfinger3b471632010-03-27 16:36:40 +00001868#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001869 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00001870#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001871 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00001872#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001873 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00001874#endif
1875#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001876 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00001877#endif
1878#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001879 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00001880#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001881 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00001882#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001883 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00001884}
1885
uwefdeca092008-01-21 15:24:22 +00001886void print_version(void)
1887{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001888 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00001889 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001890 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00001891}
1892
hailfinger74819ad2010-05-15 15:04:37 +00001893void print_banner(void)
1894{
1895 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001896 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00001897 msg_ginfo("\n");
1898}
1899
hailfingerc77acb52009-12-24 02:15:55 +00001900int selfcheck(void)
1901{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001902 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00001903 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001904
1905 /* Safety check. Instead of aborting after the first error, check
1906 * if more errors exist.
1907 */
hailfingerc77acb52009-12-24 02:15:55 +00001908 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00001909 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00001910 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00001911 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001912 /* It would be favorable if we could check for the correct layout (especially termination) of various
1913 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
1914 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
1915 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
1916 * 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 +10001917 * checks below. */
1918 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00001919 msg_gerr("Flashchips table miscompilation!\n");
1920 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001921 } else {
1922 for (i = 0; i < flashchips_size - 1; i++) {
1923 const struct flashchip *chip = &flashchips[i];
1924 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
1925 ret = 1;
1926 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
1927 "Please report a bug at flashrom@flashrom.org\n", i,
1928 chip->name == NULL ? "unnamed" : chip->name);
1929 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001930 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001931 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001932 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001933 }
stefanct6d836ba2011-05-26 01:35:19 +00001934 }
stefanct6d836ba2011-05-26 01:35:19 +00001935
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001936 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00001937 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00001938}
1939
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10001940
hailfinger771fc182010-10-15 00:01:14 +00001941/* FIXME: This function signature needs to be improved once doit() has a better
1942 * function signature.
1943 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10001944static int chip_safety_check(const struct flashctx *flash, int force,
1945 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00001946{
Patrick Georgiac3423f2017-02-03 20:58:06 +01001947 const struct flashchip *chip = flash->chip;
1948
hailfinger771fc182010-10-15 00:01:14 +00001949 if (!programmer_may_write && (write_it || erase_it)) {
1950 msg_perr("Write/erase is not working yet on your programmer in "
1951 "its current configuration.\n");
1952 /* --force is the wrong approach, but it's the best we can do
1953 * until the generic programmer parameter parser is merged.
1954 */
1955 if (!force)
1956 return 1;
1957 msg_cerr("Continuing anyway.\n");
1958 }
1959
1960 if (read_it || erase_it || write_it || verify_it) {
1961 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01001962 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00001963 msg_cerr("Read is not working on this chip. ");
1964 if (!force)
1965 return 1;
1966 msg_cerr("Continuing anyway.\n");
1967 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01001968 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00001969 msg_cerr("flashrom has no read function for this "
1970 "flash chip.\n");
1971 return 1;
1972 }
1973 }
1974 if (erase_it || write_it) {
1975 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01001976 if (chip->tested.erase == NA) {
1977 msg_cerr("Erase is not possible on this chip.\n");
1978 return 1;
1979 }
1980 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00001981 msg_cerr("Erase is not working on this chip. ");
1982 if (!force)
1983 return 1;
1984 msg_cerr("Continuing anyway.\n");
1985 }
stefancte1c5acf2011-07-04 07:27:17 +00001986 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00001987 msg_cerr("flashrom has no erase function for this "
1988 "flash chip.\n");
1989 return 1;
1990 }
hailfinger771fc182010-10-15 00:01:14 +00001991 }
1992 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01001993 if (chip->tested.write == NA) {
1994 msg_cerr("Write is not possible on this chip.\n");
1995 return 1;
1996 }
1997 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00001998 msg_cerr("Write is not working on this chip. ");
1999 if (!force)
2000 return 1;
2001 msg_cerr("Continuing anyway.\n");
2002 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002003 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002004 msg_cerr("flashrom has no write function for this "
2005 "flash chip.\n");
2006 return 1;
2007 }
2008 }
2009 return 0;
2010}
2011
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002012int prepare_flash_access(struct flashctx *const flash, int force /*flash->flags.force*/,
2013 const bool read_it, const bool write_it,
2014 const bool erase_it, const bool verify_it)
2015{
2016 if (chip_safety_check(flash, force, read_it, write_it, erase_it, verify_it)) {
2017 msg_cerr("Aborting.\n");
2018 return 1;
2019 }
2020
2021 if (normalize_romentries(flash)) {
2022 msg_cerr("Requested regions can not be handled. Aborting.\n");
2023 return 1;
2024 }
2025
2026 /* Given the existence of read locks, we want to unlock for read,
2027 erase and write. */
2028 if (flash->chip->unlock)
2029 flash->chip->unlock(flash);
2030
2031 flash->address_high_byte = -1;
2032 flash->in_4ba_mode = false;
2033
2034 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2035 if ((flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN) && flash->chip->set_4ba) {
2036 if (flash->chip->set_4ba(flash)) {
2037 msg_cerr("Enabling/disabling 4-byte addressing mode failed!\n");
2038 return 1;
2039 }
2040 }
2041
2042 return 0;
2043}
2044
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002045/*
2046 * Function to erase entire flash chip.
2047 *
2048 * @flashctx pointer to the flash context to use
2049 * @oldcontents pointer to the buffer including current chip contents, to
2050 * decide which areas do in fact need to be erased
2051 * @size the size of the flash chip, in bytes.
2052 *
2053 * Returns zero on success or an error code.
2054 */
2055static int erase_chip(struct flashctx *flash, void *oldcontents,
2056 void *newcontents, size_t size)
2057{
2058 /*
2059 * To make sure that the chip is fully erased, let's cheat and create
2060 * a descriptor where the new contents are all erased.
2061 */
2062 struct action_descriptor *fake_descriptor;
2063 int ret = 0;
2064
2065 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2066 newcontents, 1);
2067 /* FIXME: Do we really want the scary warning if erase failed? After
2068 * all, after erase the chip is either blank or partially blank or it
2069 * has the old contents. A blank chip won't boot, so if the user
2070 * wanted erase and reboots afterwards, the user knows very well that
2071 * booting won't work.
2072 */
2073 if (erase_and_write_flash(flash, fake_descriptor)) {
2074 emergency_help_message();
2075 ret = 1;
2076 }
2077
2078 free(fake_descriptor);
2079
2080 return ret;
2081}
2082
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002083static int read_dest_content(struct flashctx *flash, int verify_it,
2084 uint8_t *dest, unsigned long size)
2085{
2086 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2087 && get_num_include_args()) {
2088 /*
2089 * If no full verification is required and not
2090 * the entire chip is about to be programmed,
2091 * read only the areas which might change.
2092 */
2093 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2094 return 1;
2095 } else {
2096 if (read_flash(flash, dest, 0, size))
2097 return 1;
2098 }
2099 return 0;
2100}
2101
hailfingerc77acb52009-12-24 02:15:55 +00002102/* This function signature is horrible. We need to design a better interface,
2103 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002104 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002105 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002106int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002107 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002108 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002109{
hailfinger4c47e9d2010-10-19 22:06:20 +00002110 uint8_t *oldcontents;
2111 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002112 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002113 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002114 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002115
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002116 ret = prepare_flash_access(flash, force, read_it, write_it, erase_it, verify_it);
2117 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002118 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002119
Simon Glass9ad06c12013-07-03 22:08:17 +09002120 if (extract_it) {
2121 ret = extract_regions(flash);
2122 goto out_nofree;
2123 }
2124
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002125 /* mark entries included using -i argument as "included" if they are
2126 found in the master rom_entries list */
2127 if (process_include_args() < 0) {
2128 ret = 1;
2129 goto out_nofree;
2130 }
2131
hailfinger771fc182010-10-15 00:01:14 +00002132 if (read_it) {
2133 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002134 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002135 }
hailfingerb437e282010-11-04 01:04:27 +00002136
stefanctd611e8f2011-07-12 22:35:21 +00002137 oldcontents = malloc(size);
2138 if (!oldcontents) {
2139 msg_gerr("Out of memory!\n");
2140 exit(1);
2141 }
Simon Glass4c214132013-07-16 10:09:28 -06002142 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002143 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002144 newcontents = malloc(size);
2145 if (!newcontents) {
2146 msg_gerr("Out of memory!\n");
2147 exit(1);
2148 }
Simon Glass4c214132013-07-16 10:09:28 -06002149 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002150 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002151 /* Side effect of the assumptions above: Default write action is erase
2152 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002153 * oldcontents being completely unerased means we have to erase
2154 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002155 */
2156
hailfingerd217d122010-10-08 18:52:29 +00002157 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002158 /*
2159 * Note: This must be done before any files specified by -i
2160 * arguments are processed merged into the newcontents since
2161 * -i files take priority. See http://crbug.com/263495.
2162 */
2163 if (filename) {
2164 if (read_buf_from_file(newcontents, size, filename)) {
2165 ret = 1;
2166 goto out;
2167 }
2168 } else {
2169 /* Content will be read from -i args, so they must
2170 * not overlap. */
2171 if (included_regions_overlap()) {
2172 msg_gerr("Error: Included regions must "
2173 "not overlap.\n");
2174 ret = 1;
2175 goto out;
2176 }
stepan1da96c02006-11-21 23:48:51 +00002177 }
ollie5672ac62004-03-17 22:22:08 +00002178 }
2179
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002180 if (do_diff) {
2181 /*
2182 * Obtain a reference image so that we can check whether
2183 * regions need to be erased and to give better diagnostics in
2184 * case write fails. If --fast-verify is used then only the
2185 * regions which are included using -i will be read.
2186 */
2187 if (diff_file) {
2188 msg_cdbg("Reading old contents from file... ");
2189 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002190 ret = 1;
2191 msg_cdbg("FAILED.\n");
2192 goto out;
2193 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002194 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002195 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002196 ret = read_dest_content(flash, verify_it,
2197 oldcontents, size);
2198 if (ret) {
2199 msg_cdbg("FAILED.\n");
2200 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002201 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002202 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002203 msg_cdbg("done.\n");
2204 } else if (!erase_it) {
2205 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002206 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002207 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002208
David Hendricksdf29a832013-06-28 14:33:51 -07002209 /*
2210 * Note: This must be done after reading the file specified for the
2211 * -w/-v argument, if any, so that files specified using -i end up
2212 * in the "newcontents" buffer before being written.
2213 * See http://crbug.com/263495.
2214 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002215 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002216 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002217 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002218 goto out;
2219 }
uwef6641642007-05-09 10:17:44 +00002220
David Hendricksa7e114b2016-02-26 18:49:15 -08002221 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002222 erase_chip(flash, oldcontents, newcontents, size);
2223 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002224 }
2225
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002226 descriptor = prepare_action_descriptor(flash, oldcontents,
2227 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002228 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002229 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002230 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002231 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002232 goto out;
2233 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002234
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002235 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002236 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2237 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002238 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002239 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002240 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002241 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002242 ret = 1;
2243 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002244 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002245 msg_cerr("Apparently at least some data has changed.\n");
2246 } else
2247 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002248 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002249 ret = 1;
2250 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002251 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002252
David Hendricksac1d25c2016-08-09 17:00:58 -07002253 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002254 if (ret < 0) {
2255 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002256 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002257 emergency_help_message();
2258 ret = 1;
2259 goto out;
2260 } else if (ret > 0) {
2261 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002262 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002263 ret = read_dest_content(flash, verify_it,
2264 oldcontents, size);
2265 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002266 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002267 goto out;
2268 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002269
2270 /* Get a new descriptor. */
2271 free(descriptor);
2272 descriptor = prepare_action_descriptor(flash,
2273 oldcontents,
2274 newcontents,
2275 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002276 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002277 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002278 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002279 emergency_help_message();
2280 ret = 1;
2281 goto out;
2282 }
2283 ret = 0;
2284 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002285
David Hendricksac1d25c2016-08-09 17:00:58 -07002286 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002287 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002288 emergency_help_message();
2289 ret = 1;
2290 goto out;
2291 }
stuge8ce3a3c2008-04-28 14:47:30 +00002292 }
ollie6a600992005-11-26 21:55:36 +00002293
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002294 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002295 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002296 if ((write_it || erase_it) && !content_has_changed) {
2297 msg_gdbg("Nothing was erased or written, skipping "
2298 "verification\n");
2299 } else {
2300 /* Work around chips which need some time to calm down. */
2301 if (write_it && verify_it != VERIFY_PARTIAL)
2302 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002303
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002304 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002305
David Hendricks9ba79fb2015-04-03 12:06:16 -07002306 /* If we tried to write, and verification now fails, we
2307 * might have an emergency situation.
2308 */
2309 if (ret && write_it)
2310 emergency_help_message();
2311 }
hailfinger0459e1c2009-08-19 13:55:34 +00002312 }
ollie6a600992005-11-26 21:55:36 +00002313
hailfinger90fcf9b2010-11-05 14:51:59 +00002314out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002315 if (descriptor)
2316 free(descriptor);
2317
hailfinger90fcf9b2010-11-05 14:51:59 +00002318 free(oldcontents);
2319 free(newcontents);
2320out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002321 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002322 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002323 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002324 * tree. This is because some operations, such as write protection,
2325 * requires programmer_shutdown() but does not call doit().
2326 */
2327// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002328 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002329}