blob: 9459497f1a302f99dde71c7a96d323e1fbee21a0 [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);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000517 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000518}
519
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700520void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000521{
Craig Hesling65eb8812019-08-01 09:33:56 -0700522 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000523}
524
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700525void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000526{
Craig Hesling65eb8812019-08-01 09:33:56 -0700527 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000528}
529
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700530void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000531{
Craig Hesling65eb8812019-08-01 09:33:56 -0700532 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000533}
534
Stuart langleyc98e43f2020-03-26 20:27:36 +1100535void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000536{
Craig Hesling65eb8812019-08-01 09:33:56 -0700537 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000538}
539
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700540uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000541{
Craig Hesling65eb8812019-08-01 09:33:56 -0700542 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000543}
544
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700545uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000546{
Craig Hesling65eb8812019-08-01 09:33:56 -0700547 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000548}
549
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700550uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000551{
Craig Hesling65eb8812019-08-01 09:33:56 -0700552 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000553}
554
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700555void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000556{
Craig Hesling65eb8812019-08-01 09:33:56 -0700557 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000558}
559
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000560void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000561{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000562 if (usecs > 0)
563 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000564}
565
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700566int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000567{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700568 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000569
hailfinger23060112009-05-08 12:49:03 +0000570 return 0;
571}
572
David Hendricksda18f692016-10-21 17:49:49 -0700573/* This is a somewhat hacked function similar in some ways to strtok(). It will
574 * look for needle with a subsequent '=' in haystack, return a copy of needle.
hailfinger6e5a52a2009-11-24 18:27:10 +0000575 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000576char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000577{
David Hendricksda18f692016-10-21 17:49:49 -0700578 char *param_pos, *opt_pos;
hailfinger1ef766d2010-07-06 09:55:48 +0000579 char *opt = NULL;
580 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000581 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000582
hailfingerf4aaccc2010-04-28 15:22:14 +0000583 needlelen = strlen(needle);
584 if (!needlelen) {
585 msg_gerr("%s: empty needle! Please report a bug at "
586 "flashrom@flashrom.org\n", __func__);
587 return NULL;
588 }
589 /* No programmer parameters given. */
590 if (*haystack == NULL)
591 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000592 param_pos = strstr(*haystack, needle);
593 do {
594 if (!param_pos)
595 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000596 /* Needle followed by '='? */
597 if (param_pos[needlelen] == '=') {
Simon Glass8dc82732013-07-16 10:13:51 -0600598
hailfinger1ef766d2010-07-06 09:55:48 +0000599 /* Beginning of the string? */
600 if (param_pos == *haystack)
601 break;
602 /* After a delimiter? */
603 if (strchr(delim, *(param_pos - 1)))
604 break;
605 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000606 /* Continue searching. */
607 param_pos++;
608 param_pos = strstr(param_pos, needle);
609 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000610
hailfinger6e5a52a2009-11-24 18:27:10 +0000611 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000612 /* Get the string after needle and '='. */
613 opt_pos = param_pos + needlelen + 1;
614 optlen = strcspn(opt_pos, delim);
615 /* Return an empty string if the parameter was empty. */
616 opt = malloc(optlen + 1);
617 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000618 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000619 exit(1);
620 }
hailfinger1ef766d2010-07-06 09:55:48 +0000621 strncpy(opt, opt_pos, optlen);
622 opt[optlen] = '\0';
hailfinger6e5a52a2009-11-24 18:27:10 +0000623 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000624
hailfinger1ef766d2010-07-06 09:55:48 +0000625 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000626}
627
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000628char *extract_programmer_param(const char *const param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000629{
630 return extract_param(&programmer_param, param_name, ",");
631}
632
stefancte1c5acf2011-07-04 07:27:17 +0000633/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700634static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000635{
636 unsigned int usable_erasefunctions = 0;
637 int k;
638 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
639 if (!check_block_eraser(flash, k, 0))
640 usable_erasefunctions++;
641 }
642 return usable_erasefunctions;
643}
644
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000645static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700646{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000647 int ret = 0, failcount = 0;
648 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700649 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000650 if (wantbuf[i] != havebuf[i]) {
651 /* Only print the first failure. */
652 if (!failcount++)
653 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
654 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700655 }
656 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000657 if (failcount) {
658 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
659 start, start + len - 1, failcount);
660 ret = -1;
661 }
662 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700663}
664
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000665/* start is an offset to the base address of the flash chip */
666static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
667{
668 int ret;
669 uint8_t *cmpbuf = malloc(len);
670 const uint8_t erased_value = ERASED_VALUE(flash);
671
672 if (!cmpbuf) {
673 msg_gerr("Could not allocate memory!\n");
674 exit(1);
675 }
676 memset(cmpbuf, erased_value, len);
677 ret = verify_range(flash, cmpbuf, start, len);
678 free(cmpbuf);
679 return ret;
680}
681
uwee15beb92010-08-08 17:01:18 +0000682/*
hailfinger7af3d192009-11-25 17:05:52 +0000683 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000684 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000685 * @start offset to the base address of the flash chip
686 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000687 * @return 0 for success, -1 for failure
688 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000689int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000690{
hailfinger7af83692009-06-15 17:23:36 +0000691 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000692 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000693
Patrick Georgif3fa2992017-02-02 16:24:44 +0100694 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000695 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000696 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000697 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000698
699 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000700 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000701 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000702 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000703 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000704 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000705
Patrick Georgif3fa2992017-02-02 16:24:44 +0100706 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000707 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000708 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100709 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000710 ret = -1;
711 goto out_free;
712 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700713 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700714 if (programmer_table[programmer].paranoid) {
715 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800716
Simon Glass4e305f42015-01-08 06:29:04 -0700717 /* limit chunksize in order to catch errors early */
718 for (i = 0, chunksize = 0; i < len; i += chunksize) {
719 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800720
Patrick Georgif3fa2992017-02-02 16:24:44 +0100721 chunksize = min(flash->chip->page_size, len - i);
722 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700723 if (tmp) {
724 ret = tmp;
725 if (ignore_error(tmp))
726 continue;
727 else
728 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800729 }
Simon Glass4e305f42015-01-08 06:29:04 -0700730
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700731 /*
732 * Check write access permission and do not compare chunks
733 * where flashrom does not have write access to the region.
734 */
735 if (flash->chip->check_access) {
736 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
737 if (tmp && ignore_error(tmp))
738 continue;
739 }
740
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000741 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700742 if (failcount)
743 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800744 }
Simon Glass4e305f42015-01-08 06:29:04 -0700745 } else {
746 int tmp;
747
748 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +0100749 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -0700750 if (tmp && !ignore_error(tmp)) {
751 ret = tmp;
752 goto out_free;
753 }
754
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000755 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +0000756 }
757
hailfinger5be6c0f2009-07-23 01:42:56 +0000758 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +0000759 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +0000760 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +0000761 ret = -1;
762 }
hailfinger7af83692009-06-15 17:23:36 +0000763
764out_free:
765 free(readbuf);
766 return ret;
767}
768
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100769/* Helper function for need_erase() that focuses on granularities of gran bytes. */
770static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000771 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100772{
773 unsigned int i, j, limit;
774 for (j = 0; j < len / gran; j++) {
775 limit = min (gran, len - j * gran);
776 /* Are 'have' and 'want' identical? */
777 if (!memcmp(have + j * gran, want + j * gran, limit))
778 continue;
779 /* have needs to be in erased state. */
780 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000781 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100782 return 1;
783 }
784 return 0;
785}
786
uwee15beb92010-08-08 17:01:18 +0000787/*
hailfingerb247c7a2010-03-08 00:42:32 +0000788 * Check if the buffer @have can be programmed to the content of @want without
789 * erasing. This is only possible if all chunks of size @gran are either kept
790 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +0000791 *
hailfingerb437e282010-11-04 01:04:27 +0000792 * Warning: This function assumes that @have and @want point to naturally
793 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +0000794 *
795 * @have buffer with current content
796 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +0000797 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +0000798 * @gran write granularity (enum, not count)
799 * @return 0 if no erase is needed, 1 otherwise
800 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000801int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
802 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +0000803{
hailfingerb91c08c2011-08-15 19:54:20 +0000804 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100805 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -0700806
hailfingerb247c7a2010-03-08 00:42:32 +0000807 switch (gran) {
808 case write_gran_1bit:
809 for (i = 0; i < len; i++)
810 if ((have[i] & want[i]) != want[i]) {
811 result = 1;
812 break;
813 }
814 break;
815 case write_gran_1byte:
816 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000817 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +0000818 result = 1;
819 break;
820 }
821 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100822 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000823 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100824 break;
hailfingerb247c7a2010-03-08 00:42:32 +0000825 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000826 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100827 break;
828 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000829 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100830 break;
831 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000832 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100833 break;
834 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000835 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100836 break;
837 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000838 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100839 break;
840 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000841 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100842 break;
843 case write_gran_1byte_implicit_erase:
844 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
845 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +0000846 break;
hailfingerb437e282010-11-04 01:04:27 +0000847 default:
848 msg_cerr("%s: Unsupported granularity! Please report a bug at "
849 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +0000850 }
851 return result;
852}
853
hailfingerb437e282010-11-04 01:04:27 +0000854/**
855 * Check if the buffer @have needs to be programmed to get the content of @want.
856 * If yes, return 1 and fill in first_start with the start address of the
857 * write operation and first_len with the length of the first to-be-written
858 * chunk. If not, return 0 and leave first_start and first_len undefined.
859 *
860 * Warning: This function assumes that @have and @want point to naturally
861 * aligned regions.
862 *
863 * @have buffer with current content
864 * @want buffer with desired content
865 * @len length of the checked area
866 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +0000867 * @first_start offset of the first byte which needs to be written (passed in
868 * value is increased by the offset of the first needed write
869 * relative to have/want or unchanged if no write is needed)
870 * @return length of the first contiguous area which needs to be written
871 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +0000872 *
873 * FIXME: This function needs a parameter which tells it about coalescing
874 * in relation to the max write length of the programmer and the max write
875 * length of the chip.
876 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000877static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +0000878 unsigned int *first_start,
879 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +0000880{
stefanctc5eb8a92011-11-23 09:13:48 +0000881 int need_write = 0;
882 unsigned int rel_start = 0, first_len = 0;
883 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +0000884
hailfingerb437e282010-11-04 01:04:27 +0000885 switch (gran) {
886 case write_gran_1bit:
887 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100888 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +0000889 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +0000890 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100891 case write_gran_128bytes:
892 stride = 128;
893 break;
hailfingerb437e282010-11-04 01:04:27 +0000894 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +0000895 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +0000896 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100897 case write_gran_264bytes:
898 stride = 264;
899 break;
900 case write_gran_512bytes:
901 stride = 512;
902 break;
903 case write_gran_528bytes:
904 stride = 528;
905 break;
906 case write_gran_1024bytes:
907 stride = 1024;
908 break;
909 case write_gran_1056bytes:
910 stride = 1056;
911 break;
hailfingerb437e282010-11-04 01:04:27 +0000912 default:
913 msg_cerr("%s: Unsupported granularity! Please report a bug at "
914 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +0000915 /* Claim that no write was needed. A write with unknown
916 * granularity is too dangerous to try.
917 */
918 return 0;
hailfingerb437e282010-11-04 01:04:27 +0000919 }
hailfinger90fcf9b2010-11-05 14:51:59 +0000920 for (i = 0; i < len / stride; i++) {
921 limit = min(stride, len - i * stride);
922 /* Are 'have' and 'want' identical? */
923 if (memcmp(have + i * stride, want + i * stride, limit)) {
924 if (!need_write) {
925 /* First location where have and want differ. */
926 need_write = 1;
927 rel_start = i * stride;
928 }
929 } else {
930 if (need_write) {
931 /* First location where have and want
932 * do not differ anymore.
933 */
hailfinger90fcf9b2010-11-05 14:51:59 +0000934 break;
935 }
936 }
937 }
hailfingerffb7f382010-12-06 13:05:44 +0000938 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +0000939 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +0000940 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +0000941 return first_len;
hailfingerb437e282010-11-04 01:04:27 +0000942}
943
hailfinger0c515352009-11-23 12:55:31 +0000944/* This function generates various test patterns useful for testing controller
945 * and chip communication as well as chip behaviour.
946 *
947 * If a byte can be written multiple times, each time keeping 0-bits at 0
948 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
949 * is essentially an AND operation. That's also the reason why this function
950 * provides the result of AND between various patterns.
951 *
952 * Below is a list of patterns (and their block length).
953 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
954 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
955 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
956 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
957 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
958 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
959 * Pattern 6 is 00 (1 Byte)
960 * Pattern 7 is ff (1 Byte)
961 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
962 * byte block.
963 *
964 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
965 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
966 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
967 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
968 * Pattern 12 is 00 (1 Byte)
969 * Pattern 13 is ff (1 Byte)
970 * Patterns 8-13 have no block number.
971 *
972 * Patterns 0-3 are created to detect and efficiently diagnose communication
973 * slips like missed bits or bytes and their repetitive nature gives good visual
974 * cues to the person inspecting the results. In addition, the following holds:
975 * AND Pattern 0/1 == Pattern 4
976 * AND Pattern 2/3 == Pattern 5
977 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
978 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
979 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
980 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
981 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
982 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
983 * Besides that, they provide for bit testing of the last two bytes of every
984 * 256 byte block which contains the block number for patterns 0-6.
985 * Patterns 10-11 are special purpose for detecting subblock aliasing with
986 * block sizes >256 bytes (some Dataflash chips etc.)
987 * AND Pattern 8/9 == Pattern 12
988 * AND Pattern 10/11 == Pattern 12
989 * Pattern 13 is the completely erased state.
990 * None of the patterns can detect aliasing at boundaries which are a multiple
991 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
992 */
993int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
994{
995 int i;
996
997 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +0000998 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +0000999 return 1;
1000 }
1001
1002 switch (variant) {
1003 case 0:
1004 for (i = 0; i < size; i++)
1005 buf[i] = (i & 0xf) << 4 | 0x5;
1006 break;
1007 case 1:
1008 for (i = 0; i < size; i++)
1009 buf[i] = (i & 0xf) << 4 | 0xa;
1010 break;
1011 case 2:
1012 for (i = 0; i < size; i++)
1013 buf[i] = 0x50 | (i & 0xf);
1014 break;
1015 case 3:
1016 for (i = 0; i < size; i++)
1017 buf[i] = 0xa0 | (i & 0xf);
1018 break;
1019 case 4:
1020 for (i = 0; i < size; i++)
1021 buf[i] = (i & 0xf) << 4;
1022 break;
1023 case 5:
1024 for (i = 0; i < size; i++)
1025 buf[i] = i & 0xf;
1026 break;
1027 case 6:
1028 memset(buf, 0x00, size);
1029 break;
1030 case 7:
1031 memset(buf, 0xff, size);
1032 break;
1033 case 8:
1034 for (i = 0; i < size; i++)
1035 buf[i] = i & 0xff;
1036 break;
1037 case 9:
1038 for (i = 0; i < size; i++)
1039 buf[i] = ~(i & 0xff);
1040 break;
1041 case 10:
1042 for (i = 0; i < size % 2; i++) {
1043 buf[i * 2] = (i >> 8) & 0xff;
1044 buf[i * 2 + 1] = i & 0xff;
1045 }
1046 if (size & 0x1)
1047 buf[i * 2] = (i >> 8) & 0xff;
1048 break;
1049 case 11:
1050 for (i = 0; i < size % 2; i++) {
1051 buf[i * 2] = ~((i >> 8) & 0xff);
1052 buf[i * 2 + 1] = ~(i & 0xff);
1053 }
1054 if (size & 0x1)
1055 buf[i * 2] = ~((i >> 8) & 0xff);
1056 break;
1057 case 12:
1058 memset(buf, 0x00, size);
1059 break;
1060 case 13:
1061 memset(buf, 0xff, size);
1062 break;
1063 }
1064
1065 if ((variant >= 0) && (variant <= 7)) {
1066 /* Write block number in the last two bytes of each 256-byte
1067 * block, big endian for easier reading of the hexdump.
1068 * Note that this wraps around for chips larger than 2^24 bytes
1069 * (16 MB).
1070 */
1071 for (i = 0; i < size / 256; i++) {
1072 buf[i * 256 + 254] = (i >> 8) & 0xff;
1073 buf[i * 256 + 255] = i & 0xff;
1074 }
1075 }
1076
1077 return 0;
1078}
1079
hailfingeraec9c962009-10-31 01:53:09 +00001080int check_max_decode(enum chipbustype buses, uint32_t size)
1081{
1082 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001083
1084 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001085 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001086 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001087 "size %u kB of chipset/board/programmer "
1088 "for %s interface, "
1089 "probe/read/erase/write may fail. ", size / 1024,
1090 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001091 }
hailfingere1e41ea2011-07-27 07:13:06 +00001092 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001093 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001094 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001095 "size %u kB of chipset/board/programmer "
1096 "for %s interface, "
1097 "probe/read/erase/write may fail. ", size / 1024,
1098 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001099 }
hailfingere1e41ea2011-07-27 07:13:06 +00001100 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001101 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001102 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001103 "size %u kB of chipset/board/programmer "
1104 "for %s interface, "
1105 "probe/read/erase/write may fail. ", size / 1024,
1106 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001107 }
hailfingere1e41ea2011-07-27 07:13:06 +00001108 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001109 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001110 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001111 "size %u kB of chipset/board/programmer "
1112 "for %s interface, "
1113 "probe/read/erase/write may fail. ", size / 1024,
1114 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001115 }
1116 if (!limitexceeded)
1117 return 0;
1118 /* Sometimes chip and programmer have more than one bus in common,
1119 * and the limit is not exceeded on all buses. Tell the user.
1120 */
1121 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001122 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001123 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001124 "interface which can support a chip of this size. "
1125 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001126 return 1;
1127}
1128
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001129void unmap_flash(struct flashctx *flash)
1130{
1131 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1132 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1133 flash->physical_registers = 0;
1134 flash->virtual_registers = (chipaddr)ERROR_PTR;
1135 }
1136
1137 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1138 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1139 flash->physical_memory = 0;
1140 flash->virtual_memory = (chipaddr)ERROR_PTR;
1141 }
1142}
1143
1144int map_flash(struct flashctx *flash)
1145{
1146 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1147 flash->virtual_memory = (chipaddr)ERROR_PTR;
1148 flash->virtual_registers = (chipaddr)ERROR_PTR;
1149
1150 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1151 * These are used for various probing-related hacks that would not map successfully anyway and should be
1152 * removed ASAP. */
1153 if (flash->chip->total_size == 0)
1154 return 0;
1155
1156 const chipsize_t size = flash->chip->total_size * 1024;
1157 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1158 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1159 if (addr == ERROR_PTR) {
1160 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1161 flash->chip->name, PRIxPTR_WIDTH, base);
1162 return 1;
1163 }
1164 flash->physical_memory = base;
1165 flash->virtual_memory = (chipaddr)addr;
1166
1167 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1168 * completely different on some chips and programmers, or not mappable at all.
1169 * Ignore these problems for now and always report success. */
1170 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1171 base = 0xffffffff - size - 0x400000 + 1;
1172 addr = programmer_map_flash_region("flash chip registers", base, size);
1173 if (addr == ERROR_PTR) {
1174 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1175 flash->chip->name, PRIxPTR_WIDTH, base);
1176 return 0;
1177 }
1178 flash->physical_registers = base;
1179 flash->virtual_registers = (chipaddr)addr;
1180 }
1181 return 0;
1182}
1183
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001184/*
1185 * Return a string corresponding to the bustype parameter.
1186 * Memory is obtained with malloc() and must be freed with free() by the caller.
1187 */
1188char *flashbuses_to_text(enum chipbustype bustype)
1189{
1190 char *ret = calloc(1, 1);
1191 /*
1192 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1193 * will cease to exist and should be eliminated here as well.
1194 */
1195 if (bustype == BUS_NONSPI) {
1196 ret = strcat_realloc(ret, "Non-SPI, ");
1197 } else {
1198 if (bustype & BUS_PARALLEL)
1199 ret = strcat_realloc(ret, "Parallel, ");
1200 if (bustype & BUS_LPC)
1201 ret = strcat_realloc(ret, "LPC, ");
1202 if (bustype & BUS_FWH)
1203 ret = strcat_realloc(ret, "FWH, ");
1204 if (bustype & BUS_SPI)
1205 ret = strcat_realloc(ret, "SPI, ");
1206 if (bustype & BUS_PROG)
1207 ret = strcat_realloc(ret, "Programmer-specific, ");
1208 if (bustype == BUS_NONE)
1209 ret = strcat_realloc(ret, "None, ");
1210 }
1211 /* Kill last comma. */
1212 ret[strlen(ret) - 2] = '\0';
1213 ret = realloc(ret, strlen(ret) + 1);
1214 return ret;
1215}
1216
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001217int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001218{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001219 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001220 uint32_t size;
1221 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001222 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001223
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301224 /* Based on the host controller interface that a platform
1225 * needs to use (hwseq or swseq),
1226 * set the flashchips list here.
1227 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001228 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301229 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001230 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301231 flash_list = flashchips_hwseq;
1232 break;
1233 default:
1234 flash_list = flashchips;
1235 break;
1236 }
1237
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001238 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1239 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001240 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001241 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001242 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001243 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001244 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001245 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001246 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001247 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001248 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001249 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001250 continue;
1251 }
stepan782fb172007-04-06 11:58:03 +00001252
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001253 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001254 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001255
hailfinger48ed3e22011-05-04 00:39:50 +00001256 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001257 flash->chip = calloc(1, sizeof(struct flashchip));
1258 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001259 msg_gerr("Out of memory!\n");
1260 exit(1);
1261 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001262 memcpy(flash->chip, chip, sizeof(struct flashchip));
1263 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001264
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001265 if (map_flash(flash) != 0)
1266 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001267
stugec1e55fe2008-07-02 17:15:47 +00001268 if (force)
1269 break;
stepanc98b80b2006-03-16 16:57:41 +00001270
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001271 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001272 goto notfound;
1273
hailfinger48ed3e22011-05-04 00:39:50 +00001274 /* If this is the first chip found, accept it.
1275 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001276 * a non-generic match. SFDP and CFI are generic matches.
1277 * startchip==0 means this call to probe_flash() is the first
1278 * one for this programmer interface (master) and thus no other chip has
1279 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001280 */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001281 if (startchip == 0 || flash->chip->model_id != GENERIC_DEVICE_ID)
stugec1e55fe2008-07-02 17:15:47 +00001282 break;
1283
stuge56300c32008-09-03 23:10:05 +00001284notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001285 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001286 free(flash->chip);
1287 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001288 }
uwebe4477b2007-08-23 16:08:21 +00001289
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001290 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001291 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001292
stepan3e7aeae2011-01-19 06:21:54 +00001293
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001294 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001295 msg_cdbg("%s %s flash chip \"%s\" (%d kB, %s) \n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001296 force ? "Assuming" : "Found", flash->chip->vendor,
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001297 flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001298 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001299#if CONFIG_INTERNAL == 1
1300 if (programmer_table[programmer].map_flash_region == physmap)
1301 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1302 PRIxPTR_WIDTH, flash->physical_memory);
1303 else
1304#endif
1305 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001306
hailfinger0f4c3952010-12-02 21:59:42 +00001307 /* Flash registers will not be mapped if the chip was forced. Lock info
1308 * may be stored in registers, so avoid lock info printing.
1309 */
1310 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001311 if (flash->chip->printlock)
1312 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001313
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001314 /* Get out of the way for later runs. */
1315 unmap_flash(flash);
1316
hailfinger48ed3e22011-05-04 00:39:50 +00001317 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001318 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001319}
1320
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001321static int verify_flash(struct flashctx *flash,
1322 struct action_descriptor *descriptor,
1323 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001324{
hailfingerb0f4d122009-06-24 08:20:45 +00001325 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001326 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001327 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001328
snelsone42c3802010-05-07 20:09:04 +00001329 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001330
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001331 if (verify_it == VERIFY_PARTIAL) {
1332 struct processing_unit *pu = descriptor->processing_units;
1333
1334 /* Verify only areas which were written. */
1335 while (pu->num_blocks) {
1336 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001337 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001338 if (ret)
1339 break;
1340 pu++;
1341 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001342 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001343 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001344 }
uwef6641642007-05-09 10:17:44 +00001345
David Hendricks1ed1d352011-11-23 17:54:37 -08001346 if (ret == ACCESS_DENIED) {
1347 msg_gdbg("Could not fully verify due to access error, ");
1348 if (access_denied_action == error_ignore) {
1349 msg_gdbg("ignoring\n");
1350 ret = 0;
1351 } else {
1352 msg_gdbg("aborting\n");
1353 }
1354 }
1355
hailfingerb0f4d122009-06-24 08:20:45 +00001356 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001357 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001358
hailfingerb0f4d122009-06-24 08:20:45 +00001359 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001360}
1361
uwe8d342eb2011-07-28 08:13:25 +00001362int read_buf_from_file(unsigned char *buf, unsigned long size,
1363 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001364{
1365 unsigned long numbytes;
1366 FILE *image;
1367 struct stat image_stat;
1368
Vincent Palatin7ab23932014-10-01 12:09:16 -07001369 if (!strncmp(filename, "-", sizeof("-")))
1370 image = fdopen(STDIN_FILENO, "rb");
1371 else
1372 image = fopen(filename, "rb");
1373 if (image == NULL) {
hailfinger771fc182010-10-15 00:01:14 +00001374 perror(filename);
1375 return 1;
1376 }
1377 if (fstat(fileno(image), &image_stat) != 0) {
1378 perror(filename);
1379 fclose(image);
1380 return 1;
1381 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001382 if ((image_stat.st_size != size) &&
1383 (strncmp(filename, "-", sizeof("-")))) {
Mike Frysinger62c794d2017-05-29 12:02:45 -04001384 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1385 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
hailfinger771fc182010-10-15 00:01:14 +00001386 fclose(image);
1387 return 1;
1388 }
1389 numbytes = fread(buf, 1, size, image);
1390 if (fclose(image)) {
1391 perror(filename);
1392 return 1;
1393 }
1394 if (numbytes != size) {
1395 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1396 "wanted %ld!\n", numbytes, size);
1397 return 1;
1398 }
1399 return 0;
1400}
1401
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001402int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001403{
1404 unsigned long numbytes;
1405 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001406
1407 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001408 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001409 return 1;
1410 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001411 if (!strncmp(filename, "-", sizeof("-")))
1412 image = fdopen(STDOUT_FILENO, "wb");
1413 else
1414 image = fopen(filename, "wb");
1415 if (image == NULL) {
hailfingerd219a232009-01-28 00:27:54 +00001416 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001417 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001418 }
hailfingerd219a232009-01-28 00:27:54 +00001419
hailfingerd219a232009-01-28 00:27:54 +00001420 numbytes = fwrite(buf, 1, size, image);
1421 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001422 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001423 msg_gerr("Error: file %s could not be written completely.\n", filename);
hailfingerd219a232009-01-28 00:27:54 +00001424 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001425 }
hailfingerd219a232009-01-28 00:27:54 +00001426 return 0;
1427}
1428
David Hendrickse3451942013-03-21 17:23:29 -07001429/*
1430 * read_flash - wrapper for flash->read() with additional high-level policy
1431 *
1432 * @flash flash chip
1433 * @buf buffer to store data in
1434 * @start start address
1435 * @len number of bytes to read
1436 *
1437 * This wrapper simplifies most cases when the flash chip needs to be read
1438 * since policy decisions such as non-fatal error handling is centralized.
1439 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001440int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001441 unsigned int start, unsigned int len)
1442{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001443 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001444
Patrick Georgif3fa2992017-02-02 16:24:44 +01001445 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001446 return -1;
1447
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001448 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1449
Patrick Georgif3fa2992017-02-02 16:24:44 +01001450 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001451 if (ret) {
1452 if (ignore_error(ret)) {
1453 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1454 start, start + len - 1);
1455 ret = 0;
1456 } else {
1457 msg_gdbg("failed to read 0x%x-0x%x\n",
1458 start, start + len - 1);
1459 }
1460 }
1461
1462 return ret;
1463}
1464
David Hendricks7c8a1612013-04-26 19:14:44 -07001465/*
1466 * write_flash - wrapper for flash->write() with additional high-level policy
1467 *
1468 * @flash flash chip
1469 * @buf buffer to write to flash
1470 * @start start address in flash
1471 * @len number of bytes to write
1472 *
1473 * TODO: Look up regions that are write-protected and avoid attempt to write
1474 * to them at all.
1475 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001476int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001477 unsigned int start, unsigned int len)
1478{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001479 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001480 return -1;
1481
Patrick Georgif3fa2992017-02-02 16:24:44 +01001482 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001483}
1484
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001485int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001486{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001487 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001488 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001489 int ret = 0;
1490
1491 msg_cinfo("Reading flash... ");
1492 if (!buf) {
1493 msg_gerr("Memory allocation failed!\n");
1494 msg_cinfo("FAILED.\n");
1495 return 1;
1496 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001497
1498 /* To support partial read, fill buffer to all 0xFF at beginning to make
1499 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001500 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001501
Patrick Georgif3fa2992017-02-02 16:24:44 +01001502 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001503 msg_cerr("No read function available for this flash chip.\n");
1504 ret = 1;
1505 goto out_free;
1506 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001507
1508 /* First try to handle partial read case, rather than read the whole
1509 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001510 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001511 if (ret < 0) {
1512 msg_cerr("Partial read operation failed!\n");
1513 ret = 1;
1514 goto out_free;
1515 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001516 int num_regions = get_num_include_args();
1517
1518 if (ret != num_regions) {
1519 msg_cerr("Requested %d regions, but only read %d\n",
1520 num_regions, ret);
1521 ret = 1;
1522 goto out_free;
1523 }
1524
1525 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001526 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001527 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001528 msg_cerr("Read operation failed!\n");
1529 ret = 1;
1530 goto out_free;
1531 }
hailfinger42a850a2010-07-13 23:56:13 +00001532 }
1533
David Hendricksdf29a832013-06-28 14:33:51 -07001534 if (filename)
1535 ret = write_buf_to_file(buf, size, filename);
1536
hailfinger42a850a2010-07-13 23:56:13 +00001537out_free:
1538 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001539 if (ret)
1540 msg_cerr("FAILED.");
1541 else
1542 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001543 return ret;
1544}
1545
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001546/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001547static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001548{
hailfingerb91c08c2011-08-15 19:54:20 +00001549 int i, j, k;
1550 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001551
1552 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1553 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001554 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001555
1556 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1557 /* Blocks with zero size are bugs in flashchips.c. */
1558 if (eraser.eraseblocks[i].count &&
1559 !eraser.eraseblocks[i].size) {
1560 msg_gerr("ERROR: Flash chip %s erase function "
1561 "%i region %i has size 0. Please report"
1562 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001563 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001564 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001565 }
1566 /* Blocks with zero count are bugs in flashchips.c. */
1567 if (!eraser.eraseblocks[i].count &&
1568 eraser.eraseblocks[i].size) {
1569 msg_gerr("ERROR: Flash chip %s erase function "
1570 "%i region %i has count 0. Please report"
1571 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001572 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001573 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001574 }
1575 done += eraser.eraseblocks[i].count *
1576 eraser.eraseblocks[i].size;
1577 }
hailfinger9fed35d2010-01-19 06:42:46 +00001578 /* Empty eraseblock definition with erase function. */
1579 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001580 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001581 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001582 if (!done)
1583 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001584 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001585 msg_gerr("ERROR: Flash chip %s erase function %i "
1586 "region walking resulted in 0x%06x bytes total,"
1587 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001588 " flashrom@flashrom.org\n", chip->name, k,
1589 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001590 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001591 }
hailfinger9fed35d2010-01-19 06:42:46 +00001592 if (!eraser.block_erase)
1593 continue;
1594 /* Check if there are identical erase functions for different
1595 * layouts. That would imply "magic" erase functions. The
1596 * easiest way to check this is with function pointers.
1597 */
uwef6f94d42010-03-13 17:28:29 +00001598 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001599 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001600 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001601 msg_gerr("ERROR: Flash chip %s erase function "
1602 "%i and %i are identical. Please report"
1603 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001604 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001605 ret = 1;
1606 }
uwef6f94d42010-03-13 17:28:29 +00001607 }
hailfinger45177872010-01-18 08:14:43 +00001608 }
hailfinger9fed35d2010-01-19 06:42:46 +00001609 return ret;
hailfinger45177872010-01-18 08:14:43 +00001610}
1611
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001612static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001613 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001614 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001615 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001616 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001617 unsigned int addr,
1618 unsigned int len))
1619{
stefanctc5eb8a92011-11-23 09:13:48 +00001620 unsigned int starthere = 0, lenhere = 0;
1621 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001622 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001623 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001624
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001625 /*
1626 * curcontents and newcontents are opaque to walk_eraseregions, and
1627 * need to be adjusted here to keep the impression of proper
1628 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001629 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001630
hailfinger90fcf9b2010-11-05 14:51:59 +00001631 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001632
hailfingerb437e282010-11-04 01:04:27 +00001633 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001634
hailfingerb437e282010-11-04 01:04:27 +00001635 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001636 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001637 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001638 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001639 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001640 if (ret) {
1641 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001642 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001643 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001644 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001645 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001646 }
1647
David Hendricks0954ffc2015-11-13 15:15:44 -08001648 if (programmer_table[programmer].paranoid) {
1649 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001650 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001651 return -1;
1652 }
hailfingerac8e3182011-06-26 17:04:16 +00001653 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001654
hailfinger90fcf9b2010-11-05 14:51:59 +00001655 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001656 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001657 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001658 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001659 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001660 /* get_next_write() sets starthere to a new value after the call. */
1661 while ((lenhere = get_next_write(curcontents + starthere,
1662 newcontents + starthere,
1663 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001664 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001665 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001666 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001667 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001668 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001669 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001670 if (ret) {
1671 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001672 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001673 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001674 }
David Hendricks048b38c2016-03-28 18:47:06 -07001675
1676 /*
1677 * If the block needed to be erased and was erased successfully
1678 * then we can assume that we didn't run into any write-
1679 * protected areas. Otherwise, we need to verify each page to
1680 * ensure it was successfully written and abort if we encounter
1681 * any errors.
1682 */
1683 if (programmer_table[programmer].paranoid && !block_was_erased) {
1684 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001685 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001686 return -1;
1687 }
1688
hailfingerb437e282010-11-04 01:04:27 +00001689 starthere += lenhere;
1690 skip = 0;
1691 }
1692 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001693 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001694 return ret;
1695}
1696
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001697/*
1698 * Function to process processing units accumulated in the action descriptor.
1699 *
1700 * @flash pointer to the flash context to operate on
1701 * @do_something helper function which can erase and program a section of the
1702 * flash chip. It receives the flash context, offset and length
1703 * of the area to erase/program, before and after contents (to
1704 * decide what exactly needs to be erased and or programmed)
1705 * and a pointer to the erase function which can operate on the
1706 * proper granularity.
1707 * @descriptor action descriptor including pointers to before and after
1708 * contents and an array of processing actions to take.
1709 *
1710 * Returns zero on success or an error code.
1711 */
1712static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001713 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001714 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001715 unsigned int len,
1716 uint8_t *param1,
1717 uint8_t *param2,
1718 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001719 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001720 unsigned int addr,
1721 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001722 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00001723{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001724 struct processing_unit *pu;
1725 int rc = 0;
1726 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00001727
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001728 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1729 unsigned base = pu->offset;
1730 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07001731
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001732 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07001733
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001734 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00001735 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001736 else
1737 print_comma = 1;
1738
1739 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1740
1741 rc = do_something(flash, base,
1742 pu->block_size,
1743 descriptor->oldcontents,
1744 descriptor->newcontents,
1745 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
1746
David Hendricks1ed1d352011-11-23 17:54:37 -08001747 if (rc) {
1748 if (ignore_error(rc))
1749 rc = 0;
1750 else
1751 return rc;
hailfingerb437e282010-11-04 01:04:27 +00001752 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001753 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00001754 }
1755 }
hailfingerb437e282010-11-04 01:04:27 +00001756 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08001757 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00001758}
1759
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001760static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00001761{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001762 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00001763
1764 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1765 if (log)
1766 msg_cdbg("not defined. ");
1767 return 1;
1768 }
1769 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1770 if (log)
1771 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00001772 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00001773 return 1;
1774 }
1775 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1776 if (log)
1777 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00001778 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00001779 return 1;
1780 }
1781 return 0;
1782}
1783
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001784int erase_and_write_flash(struct flashctx *flash,
1785 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00001786{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001787 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00001788
hailfingercf848f12010-12-05 15:14:44 +00001789 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00001790
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001791 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00001792
hailfinger7df21362009-09-05 02:30:58 +00001793 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00001794 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00001795 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07001796 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00001797 }
1798 return ret;
hailfingerd219a232009-01-28 00:27:54 +00001799}
1800
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001801static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00001802{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001803 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
1804#if CONFIG_INTERNAL == 1
1805 if (programmer == PROGRAMMER_INTERNAL)
1806 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
1807 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1808 "mail flashrom@flashrom.org, thanks!\n"
1809 "-------------------------------------------------------------------------------\n"
1810 "You may now reboot or simply leave the machine running.\n");
1811 else
1812#endif
1813 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
1814 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
1815 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1816 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00001817}
1818
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001819static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00001820{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001821 msg_gerr("Your flash chip is in an unknown state.\n");
1822#if CONFIG_INTERNAL == 1
1823 if (programmer == PROGRAMMER_INTERNAL)
1824 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
1825 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
1826 "-------------------------------------------------------------------------------\n"
1827 "DO NOT REBOOT OR POWEROFF!\n");
1828 else
1829#endif
1830 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1831 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00001832}
1833
uwe8d342eb2011-07-28 08:13:25 +00001834/* The way to go if you want a delimited list of programmers */
stefanct52700282011-06-26 17:38:17 +00001835void list_programmers(const char *delim)
hailfingerc77acb52009-12-24 02:15:55 +00001836{
1837 enum programmer p;
1838 for (p = 0; p < PROGRAMMER_INVALID; p++) {
snelsone42c3802010-05-07 20:09:04 +00001839 msg_ginfo("%s", programmer_table[p].name);
hailfingerc77acb52009-12-24 02:15:55 +00001840 if (p < PROGRAMMER_INVALID - 1)
snelsone42c3802010-05-07 20:09:04 +00001841 msg_ginfo("%s", delim);
hailfingerc77acb52009-12-24 02:15:55 +00001842 }
Simon Glass8dc82732013-07-16 10:13:51 -06001843 msg_ginfo("\n");
hailfingerc77acb52009-12-24 02:15:55 +00001844}
1845
hailfingerf79d1712010-10-06 23:48:34 +00001846void list_programmers_linebreak(int startcol, int cols, int paren)
1847{
1848 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00001849 int pnamelen;
1850 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00001851 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00001852 int i;
hailfingerf79d1712010-10-06 23:48:34 +00001853
1854 for (p = 0; p < PROGRAMMER_INVALID; p++) {
1855 pname = programmer_table[p].name;
1856 pnamelen = strlen(pname);
1857 if (remaining - pnamelen - 2 < 0) {
1858 if (firstline)
1859 firstline = 0;
1860 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001861 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00001862 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001863 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00001864 remaining = cols - startcol;
1865 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001866 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00001867 remaining--;
1868 }
1869 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001870 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00001871 remaining--;
1872 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001873 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00001874 remaining -= pnamelen;
1875 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001876 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00001877 remaining--;
1878 } else {
1879 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001880 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00001881 }
1882 }
1883}
1884
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001885static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00001886{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10001887#if IS_WINDOWS
1888 SYSTEM_INFO si;
1889 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00001890
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10001891 memset(&si, 0, sizeof(SYSTEM_INFO));
1892 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
1893 msg_ginfo(" on Windows");
1894 /* Tell Windows which version of the structure we want. */
1895 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
1896 if (GetVersionEx((OSVERSIONINFO*) &osvi))
1897 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
1898 else
1899 msg_ginfo(" unknown version");
1900 GetSystemInfo(&si);
1901 switch (si.wProcessorArchitecture) {
1902 case PROCESSOR_ARCHITECTURE_AMD64:
1903 msg_ginfo(" (x86_64)");
1904 break;
1905 case PROCESSOR_ARCHITECTURE_INTEL:
1906 msg_ginfo(" (x86)");
1907 break;
1908 default:
1909 msg_ginfo(" (unknown arch)");
1910 break;
1911 }
1912#elif HAVE_UTSNAME == 1
1913 struct utsname osinfo;
1914
1915 uname(&osinfo);
1916 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00001917 osinfo.machine);
1918#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10001919 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00001920#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001921}
1922
1923void print_buildinfo(void)
1924{
1925 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00001926#if NEED_PCI == 1
1927#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001928 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00001929#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001930 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00001931#endif
1932#endif
1933#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001934 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00001935#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001936 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00001937#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001938 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00001939#endif
hailfinger3b471632010-03-27 16:36:40 +00001940#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001941 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00001942#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001943 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00001944#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001945 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00001946#endif
1947#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001948 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00001949#endif
1950#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001951 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00001952#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001953 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00001954#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001955 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00001956}
1957
uwefdeca092008-01-21 15:24:22 +00001958void print_version(void)
1959{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001960 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00001961 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001962 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00001963}
1964
hailfinger74819ad2010-05-15 15:04:37 +00001965void print_banner(void)
1966{
1967 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001968 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00001969 msg_ginfo("\n");
1970}
1971
hailfingerc77acb52009-12-24 02:15:55 +00001972int selfcheck(void)
1973{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001974 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00001975 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001976
1977 /* Safety check. Instead of aborting after the first error, check
1978 * if more errors exist.
1979 */
hailfingerc77acb52009-12-24 02:15:55 +00001980 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00001981 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00001982 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00001983 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001984 /* It would be favorable if we could check for the correct layout (especially termination) of various
1985 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
1986 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
1987 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
1988 * 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 +10001989 * checks below. */
1990 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00001991 msg_gerr("Flashchips table miscompilation!\n");
1992 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001993 } else {
1994 for (i = 0; i < flashchips_size - 1; i++) {
1995 const struct flashchip *chip = &flashchips[i];
1996 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
1997 ret = 1;
1998 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
1999 "Please report a bug at flashrom@flashrom.org\n", i,
2000 chip->name == NULL ? "unnamed" : chip->name);
2001 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002002 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002003 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002004 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002005 }
stefanct6d836ba2011-05-26 01:35:19 +00002006 }
stefanct6d836ba2011-05-26 01:35:19 +00002007
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002008 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002009 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002010}
2011
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002012
hailfinger771fc182010-10-15 00:01:14 +00002013/* FIXME: This function signature needs to be improved once doit() has a better
2014 * function signature.
2015 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002016static int chip_safety_check(const struct flashctx *flash, int force,
2017 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002018{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002019 const struct flashchip *chip = flash->chip;
2020
hailfinger771fc182010-10-15 00:01:14 +00002021 if (!programmer_may_write && (write_it || erase_it)) {
2022 msg_perr("Write/erase is not working yet on your programmer in "
2023 "its current configuration.\n");
2024 /* --force is the wrong approach, but it's the best we can do
2025 * until the generic programmer parameter parser is merged.
2026 */
2027 if (!force)
2028 return 1;
2029 msg_cerr("Continuing anyway.\n");
2030 }
2031
2032 if (read_it || erase_it || write_it || verify_it) {
2033 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002034 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002035 msg_cerr("Read is not working on this chip. ");
2036 if (!force)
2037 return 1;
2038 msg_cerr("Continuing anyway.\n");
2039 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002040 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002041 msg_cerr("flashrom has no read function for this "
2042 "flash chip.\n");
2043 return 1;
2044 }
2045 }
2046 if (erase_it || write_it) {
2047 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002048 if (chip->tested.erase == NA) {
2049 msg_cerr("Erase is not possible on this chip.\n");
2050 return 1;
2051 }
2052 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002053 msg_cerr("Erase is not working on this chip. ");
2054 if (!force)
2055 return 1;
2056 msg_cerr("Continuing anyway.\n");
2057 }
stefancte1c5acf2011-07-04 07:27:17 +00002058 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002059 msg_cerr("flashrom has no erase function for this "
2060 "flash chip.\n");
2061 return 1;
2062 }
hailfinger771fc182010-10-15 00:01:14 +00002063 }
2064 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002065 if (chip->tested.write == NA) {
2066 msg_cerr("Write is not possible on this chip.\n");
2067 return 1;
2068 }
2069 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002070 msg_cerr("Write is not working on this chip. ");
2071 if (!force)
2072 return 1;
2073 msg_cerr("Continuing anyway.\n");
2074 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002075 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002076 msg_cerr("flashrom has no write function for this "
2077 "flash chip.\n");
2078 return 1;
2079 }
2080 }
2081 return 0;
2082}
2083
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002084int prepare_flash_access(struct flashctx *const flash, int force /*flash->flags.force*/,
2085 const bool read_it, const bool write_it,
2086 const bool erase_it, const bool verify_it)
2087{
2088 if (chip_safety_check(flash, force, read_it, write_it, erase_it, verify_it)) {
2089 msg_cerr("Aborting.\n");
2090 return 1;
2091 }
2092
2093 if (normalize_romentries(flash)) {
2094 msg_cerr("Requested regions can not be handled. Aborting.\n");
2095 return 1;
2096 }
2097
2098 /* Given the existence of read locks, we want to unlock for read,
2099 erase and write. */
2100 if (flash->chip->unlock)
2101 flash->chip->unlock(flash);
2102
2103 flash->address_high_byte = -1;
2104 flash->in_4ba_mode = false;
2105
2106 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2107 if ((flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN) && flash->chip->set_4ba) {
2108 if (flash->chip->set_4ba(flash)) {
2109 msg_cerr("Enabling/disabling 4-byte addressing mode failed!\n");
2110 return 1;
2111 }
2112 }
2113
2114 return 0;
2115}
2116
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002117/*
2118 * Function to erase entire flash chip.
2119 *
2120 * @flashctx pointer to the flash context to use
2121 * @oldcontents pointer to the buffer including current chip contents, to
2122 * decide which areas do in fact need to be erased
2123 * @size the size of the flash chip, in bytes.
2124 *
2125 * Returns zero on success or an error code.
2126 */
2127static int erase_chip(struct flashctx *flash, void *oldcontents,
2128 void *newcontents, size_t size)
2129{
2130 /*
2131 * To make sure that the chip is fully erased, let's cheat and create
2132 * a descriptor where the new contents are all erased.
2133 */
2134 struct action_descriptor *fake_descriptor;
2135 int ret = 0;
2136
2137 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2138 newcontents, 1);
2139 /* FIXME: Do we really want the scary warning if erase failed? After
2140 * all, after erase the chip is either blank or partially blank or it
2141 * has the old contents. A blank chip won't boot, so if the user
2142 * wanted erase and reboots afterwards, the user knows very well that
2143 * booting won't work.
2144 */
2145 if (erase_and_write_flash(flash, fake_descriptor)) {
2146 emergency_help_message();
2147 ret = 1;
2148 }
2149
2150 free(fake_descriptor);
2151
2152 return ret;
2153}
2154
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002155static int read_dest_content(struct flashctx *flash, int verify_it,
2156 uint8_t *dest, unsigned long size)
2157{
2158 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2159 && get_num_include_args()) {
2160 /*
2161 * If no full verification is required and not
2162 * the entire chip is about to be programmed,
2163 * read only the areas which might change.
2164 */
2165 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2166 return 1;
2167 } else {
2168 if (read_flash(flash, dest, 0, size))
2169 return 1;
2170 }
2171 return 0;
2172}
2173
hailfingerc77acb52009-12-24 02:15:55 +00002174/* This function signature is horrible. We need to design a better interface,
2175 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002176 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002177 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002178int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002179 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002180 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002181{
hailfinger4c47e9d2010-10-19 22:06:20 +00002182 uint8_t *oldcontents;
2183 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002184 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002185 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002186 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002187
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002188 ret = prepare_flash_access(flash, force, read_it, write_it, erase_it, verify_it);
2189 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002190 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002191
Simon Glass9ad06c12013-07-03 22:08:17 +09002192 if (extract_it) {
2193 ret = extract_regions(flash);
2194 goto out_nofree;
2195 }
2196
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002197 /* mark entries included using -i argument as "included" if they are
2198 found in the master rom_entries list */
2199 if (process_include_args() < 0) {
2200 ret = 1;
2201 goto out_nofree;
2202 }
2203
hailfinger771fc182010-10-15 00:01:14 +00002204 if (read_it) {
2205 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002206 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002207 }
hailfingerb437e282010-11-04 01:04:27 +00002208
stefanctd611e8f2011-07-12 22:35:21 +00002209 oldcontents = malloc(size);
2210 if (!oldcontents) {
2211 msg_gerr("Out of memory!\n");
2212 exit(1);
2213 }
Simon Glass4c214132013-07-16 10:09:28 -06002214 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002215 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002216 newcontents = malloc(size);
2217 if (!newcontents) {
2218 msg_gerr("Out of memory!\n");
2219 exit(1);
2220 }
Simon Glass4c214132013-07-16 10:09:28 -06002221 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002222 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002223 /* Side effect of the assumptions above: Default write action is erase
2224 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002225 * oldcontents being completely unerased means we have to erase
2226 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002227 */
2228
hailfingerd217d122010-10-08 18:52:29 +00002229 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002230 /*
2231 * Note: This must be done before any files specified by -i
2232 * arguments are processed merged into the newcontents since
2233 * -i files take priority. See http://crbug.com/263495.
2234 */
2235 if (filename) {
2236 if (read_buf_from_file(newcontents, size, filename)) {
2237 ret = 1;
2238 goto out;
2239 }
2240 } else {
2241 /* Content will be read from -i args, so they must
2242 * not overlap. */
2243 if (included_regions_overlap()) {
2244 msg_gerr("Error: Included regions must "
2245 "not overlap.\n");
2246 ret = 1;
2247 goto out;
2248 }
stepan1da96c02006-11-21 23:48:51 +00002249 }
ollie5672ac62004-03-17 22:22:08 +00002250 }
2251
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002252 if (do_diff) {
2253 /*
2254 * Obtain a reference image so that we can check whether
2255 * regions need to be erased and to give better diagnostics in
2256 * case write fails. If --fast-verify is used then only the
2257 * regions which are included using -i will be read.
2258 */
2259 if (diff_file) {
2260 msg_cdbg("Reading old contents from file... ");
2261 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002262 ret = 1;
2263 msg_cdbg("FAILED.\n");
2264 goto out;
2265 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002266 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002267 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002268 ret = read_dest_content(flash, verify_it,
2269 oldcontents, size);
2270 if (ret) {
2271 msg_cdbg("FAILED.\n");
2272 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002273 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002274 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002275 msg_cdbg("done.\n");
2276 } else if (!erase_it) {
2277 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002278 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002279 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002280
David Hendricksdf29a832013-06-28 14:33:51 -07002281 /*
2282 * Note: This must be done after reading the file specified for the
2283 * -w/-v argument, if any, so that files specified using -i end up
2284 * in the "newcontents" buffer before being written.
2285 * See http://crbug.com/263495.
2286 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002287 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002288 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002289 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002290 goto out;
2291 }
uwef6641642007-05-09 10:17:44 +00002292
David Hendricksa7e114b2016-02-26 18:49:15 -08002293 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002294 erase_chip(flash, oldcontents, newcontents, size);
2295 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002296 }
2297
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002298 descriptor = prepare_action_descriptor(flash, oldcontents,
2299 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002300 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002301 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002302 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002303 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002304 goto out;
2305 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002306
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002307 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002308 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2309 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002310 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002311 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002312 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002313 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002314 ret = 1;
2315 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002316 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002317 msg_cerr("Apparently at least some data has changed.\n");
2318 } else
2319 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002320 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002321 ret = 1;
2322 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002323 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002324
David Hendricksac1d25c2016-08-09 17:00:58 -07002325 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002326 if (ret < 0) {
2327 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002328 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002329 emergency_help_message();
2330 ret = 1;
2331 goto out;
2332 } else if (ret > 0) {
2333 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002334 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002335 ret = read_dest_content(flash, verify_it,
2336 oldcontents, size);
2337 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002338 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002339 goto out;
2340 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002341
2342 /* Get a new descriptor. */
2343 free(descriptor);
2344 descriptor = prepare_action_descriptor(flash,
2345 oldcontents,
2346 newcontents,
2347 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002348 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002349 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002350 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002351 emergency_help_message();
2352 ret = 1;
2353 goto out;
2354 }
2355 ret = 0;
2356 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002357
David Hendricksac1d25c2016-08-09 17:00:58 -07002358 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002359 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002360 emergency_help_message();
2361 ret = 1;
2362 goto out;
2363 }
stuge8ce3a3c2008-04-28 14:47:30 +00002364 }
ollie6a600992005-11-26 21:55:36 +00002365
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002366 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002367 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002368 if ((write_it || erase_it) && !content_has_changed) {
2369 msg_gdbg("Nothing was erased or written, skipping "
2370 "verification\n");
2371 } else {
2372 /* Work around chips which need some time to calm down. */
2373 if (write_it && verify_it != VERIFY_PARTIAL)
2374 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002375
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002376 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002377
David Hendricks9ba79fb2015-04-03 12:06:16 -07002378 /* If we tried to write, and verification now fails, we
2379 * might have an emergency situation.
2380 */
2381 if (ret && write_it)
2382 emergency_help_message();
2383 }
hailfinger0459e1c2009-08-19 13:55:34 +00002384 }
ollie6a600992005-11-26 21:55:36 +00002385
hailfinger90fcf9b2010-11-05 14:51:59 +00002386out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002387 if (descriptor)
2388 free(descriptor);
2389
hailfinger90fcf9b2010-11-05 14:51:59 +00002390 free(oldcontents);
2391 free(newcontents);
2392out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002393 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002394 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002395 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002396 * tree. This is because some operations, such as write protection,
2397 * requires programmer_shutdown() but does not call doit().
2398 */
2399// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002400 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002401}