blob: 941ee318d095ccd233a16bf3d733c255a43e72d0 [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
Edward O'Callaghana0176ff2020-08-18 15:49:23 +100052static int g_force = 0; // HACK to keep prepare_flash_access() signature the same.
53
David Hendricks1ed1d352011-11-23 17:54:37 -080054/* error handling stuff */
55enum error_action access_denied_action = error_ignore;
56
57int ignore_error(int err) {
58 int rc = 0;
59
60 switch(err) {
61 case ACCESS_DENIED:
62 if (access_denied_action == error_ignore)
63 rc = 1;
64 break;
65 default:
66 break;
67 }
68
69 return rc;
70}
71
hailfinger969e2f32011-09-08 00:00:29 +000072static enum programmer programmer = PROGRAMMER_INVALID;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100073static const char *programmer_param = NULL;
stepan782fb172007-04-06 11:58:03 +000074
David Hendricksac1d25c2016-08-09 17:00:58 -070075/* Supported buses for the current programmer. */
76enum chipbustype buses_supported;
77
uwee15beb92010-08-08 17:01:18 +000078/*
hailfinger80422e22009-12-13 22:28:00 +000079 * Programmers supporting multiple buses can have differing size limits on
80 * each bus. Store the limits for each bus in a common struct.
81 */
hailfinger1ff33dc2010-07-03 11:02:10 +000082struct decode_sizes max_rom_decode;
83
84/* If nonzero, used as the start address of bottom-aligned flash. */
85unsigned long flashbase;
hailfinger80422e22009-12-13 22:28:00 +000086
hailfinger5828baf2010-07-03 12:14:25 +000087/* Is writing allowed with this programmer? */
88int programmer_may_write;
89
hailfingerabe249e2009-05-08 17:43:22 +000090const struct programmer_entry programmer_table[] = {
hailfinger90c7d542010-05-31 15:27:27 +000091#if CONFIG_INTERNAL == 1
hailfingerabe249e2009-05-08 17:43:22 +000092 {
hailfinger3548a9a2009-08-12 14:34:35 +000093 .name = "internal",
Edward O'Callaghan0949b782019-11-10 23:23:20 +110094 .type = OTHER,
95 .devs.note = NULL,
hailfinger6c69ab02009-05-11 15:46:43 +000096 .init = internal_init,
hailfinger11ae3c42009-05-11 14:13:25 +000097 .map_flash_region = physmap,
98 .unmap_flash_region = physunmap,
hailfingere5829f62009-06-05 17:48:08 +000099 .delay = internal_delay,
David Hendricks55cdd9c2015-11-25 14:37:26 -0800100
101 /*
102 * "Internal" implies in-system programming on a live system, so
103 * handle with paranoia to catch errors early. If something goes
104 * wrong then hopefully the system will still be recoverable.
105 */
106 .paranoid = 1,
hailfingerabe249e2009-05-08 17:43:22 +0000107 },
hailfinger80422e22009-12-13 22:28:00 +0000108#endif
stepan927d4e22007-04-04 22:45:58 +0000109
hailfinger90c7d542010-05-31 15:27:27 +0000110#if CONFIG_DUMMY == 1
hailfingera9df33c2009-05-09 00:54:55 +0000111 {
hailfinger3548a9a2009-08-12 14:34:35 +0000112 .name = "dummy",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100113 .type = OTHER,
114 /* FIXME */
115 .devs.note = "Dummy device, does nothing and logs all accesses\n",
hailfinger6c69ab02009-05-11 15:46:43 +0000116 .init = dummy_init,
hailfinger11ae3c42009-05-11 14:13:25 +0000117 .map_flash_region = dummy_map,
118 .unmap_flash_region = dummy_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000119 .delay = internal_delay,
hailfingera9df33c2009-05-09 00:54:55 +0000120 },
hailfinger571a6b32009-09-16 10:09:21 +0000121#endif
hailfingera9df33c2009-05-09 00:54:55 +0000122
hailfinger90c7d542010-05-31 15:27:27 +0000123#if CONFIG_NIC3COM == 1
uwe0f5a3a22009-05-13 11:36:06 +0000124 {
hailfinger3548a9a2009-08-12 14:34:35 +0000125 .name = "nic3com",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100126 .type = PCI,
127 .devs.dev = nics_3com,
uwe0f5a3a22009-05-13 11:36:06 +0000128 .init = nic3com_init,
uwe3e656bd2009-05-17 23:12:17 +0000129 .map_flash_region = fallback_map,
130 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000131 .delay = internal_delay,
uwe0f5a3a22009-05-13 11:36:06 +0000132 },
hailfinger571a6b32009-09-16 10:09:21 +0000133#endif
uwe0f5a3a22009-05-13 11:36:06 +0000134
hailfinger90c7d542010-05-31 15:27:27 +0000135#if CONFIG_NICREALTEK == 1
hailfinger5aa36982010-05-21 21:54:07 +0000136 {
hailfinger0d703d42011-03-07 01:08:09 +0000137 /* This programmer works for Realtek RTL8139 and SMC 1211. */
uwe8d342eb2011-07-28 08:13:25 +0000138 .name = "nicrealtek",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100139 .type = PCI,
140 .devs.dev = nics_realtek,
uwe8d342eb2011-07-28 08:13:25 +0000141 .init = nicrealtek_init,
142 .map_flash_region = fallback_map,
143 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000144 .delay = internal_delay,
hailfinger5aa36982010-05-21 21:54:07 +0000145 },
hailfinger5aa36982010-05-21 21:54:07 +0000146#endif
147
hailfingerf0a368f2010-06-07 22:37:54 +0000148#if CONFIG_NICNATSEMI == 1
149 {
uwe8d342eb2011-07-28 08:13:25 +0000150 .name = "nicnatsemi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100151 .type = PCI,
152 .devs.dev = nics_natsemi,
uwe8d342eb2011-07-28 08:13:25 +0000153 .init = nicnatsemi_init,
154 .map_flash_region = fallback_map,
155 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000156 .delay = internal_delay,
hailfingerf0a368f2010-06-07 22:37:54 +0000157 },
158#endif
hailfinger5aa36982010-05-21 21:54:07 +0000159
hailfinger90c7d542010-05-31 15:27:27 +0000160#if CONFIG_GFXNVIDIA == 1
uweff4576d2009-09-30 18:29:55 +0000161 {
162 .name = "gfxnvidia",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100163 .type = PCI,
164 .devs.dev = gfx_nvidia,
uweff4576d2009-09-30 18:29:55 +0000165 .init = gfxnvidia_init,
uweff4576d2009-09-30 18:29:55 +0000166 .map_flash_region = fallback_map,
167 .unmap_flash_region = fallback_unmap,
uweff4576d2009-09-30 18:29:55 +0000168 .delay = internal_delay,
169 },
170#endif
171
hailfinger90c7d542010-05-31 15:27:27 +0000172#if CONFIG_DRKAISER == 1
ruikda922a12009-05-17 19:39:27 +0000173 {
uwee2f95ef2009-09-02 23:00:46 +0000174 .name = "drkaiser",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100175 .type = PCI,
176 .devs.dev = drkaiser_pcidev,
uwee2f95ef2009-09-02 23:00:46 +0000177 .init = drkaiser_init,
uwee2f95ef2009-09-02 23:00:46 +0000178 .map_flash_region = fallback_map,
179 .unmap_flash_region = fallback_unmap,
uwee2f95ef2009-09-02 23:00:46 +0000180 .delay = internal_delay,
181 },
hailfinger571a6b32009-09-16 10:09:21 +0000182#endif
uwee2f95ef2009-09-02 23:00:46 +0000183
hailfinger90c7d542010-05-31 15:27:27 +0000184#if CONFIG_SATASII == 1
uwee2f95ef2009-09-02 23:00:46 +0000185 {
hailfinger3548a9a2009-08-12 14:34:35 +0000186 .name = "satasii",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100187 .type = PCI,
188 .devs.dev = satas_sii,
ruikda922a12009-05-17 19:39:27 +0000189 .init = satasii_init,
uwe3e656bd2009-05-17 23:12:17 +0000190 .map_flash_region = fallback_map,
191 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000192 .delay = internal_delay,
ruikda922a12009-05-17 19:39:27 +0000193 },
hailfinger571a6b32009-09-16 10:09:21 +0000194#endif
ruikda922a12009-05-17 19:39:27 +0000195
hailfinger90c7d542010-05-31 15:27:27 +0000196#if CONFIG_ATAHPT == 1
uwe7e627c82010-02-21 21:17:00 +0000197 {
198 .name = "atahpt",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100199 .type = PCI,
200 .devs.dev = ata_hpt,
uwe7e627c82010-02-21 21:17:00 +0000201 .init = atahpt_init,
uwe7e627c82010-02-21 21:17:00 +0000202 .map_flash_region = fallback_map,
203 .unmap_flash_region = fallback_unmap,
uwe7e627c82010-02-21 21:17:00 +0000204 .delay = internal_delay,
205 },
206#endif
207
hailfinger90c7d542010-05-31 15:27:27 +0000208#if CONFIG_FT2232_SPI == 1
hailfingerf31da3d2009-06-16 21:08:06 +0000209 {
hailfinger90c7d542010-05-31 15:27:27 +0000210 .name = "ft2232_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100211 .type = USB,
Nikolai Artemievc347a852020-04-29 12:17:08 +1000212 .devs.dev = devs_ft2232spi,
hailfingerf31da3d2009-06-16 21:08:06 +0000213 .init = ft2232_spi_init,
hailfinger6fe23d62009-08-12 11:39:29 +0000214 .map_flash_region = fallback_map,
215 .unmap_flash_region = fallback_unmap,
hailfingerf31da3d2009-06-16 21:08:06 +0000216 .delay = internal_delay,
217 },
hailfingerd9dcfbd2009-08-19 13:27:58 +0000218#endif
hailfinger6fe23d62009-08-12 11:39:29 +0000219
hailfinger90c7d542010-05-31 15:27:27 +0000220#if CONFIG_SERPROG == 1
hailfinger37b4fbf2009-06-23 11:33:43 +0000221 {
hailfinger3548a9a2009-08-12 14:34:35 +0000222 .name = "serprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100223 .type = OTHER,
224 /* FIXME */
225 .devs.note = "All programmer devices speaking the serprog protocol\n",
hailfinger37b4fbf2009-06-23 11:33:43 +0000226 .init = serprog_init,
hailfinger37b4fbf2009-06-23 11:33:43 +0000227 .map_flash_region = fallback_map,
228 .unmap_flash_region = fallback_unmap,
hailfinger37b4fbf2009-06-23 11:33:43 +0000229 .delay = serprog_delay,
230 },
hailfinger74d88a72009-08-12 16:17:41 +0000231#endif
hailfingerf31da3d2009-06-16 21:08:06 +0000232
hailfinger90c7d542010-05-31 15:27:27 +0000233#if CONFIG_BUSPIRATE_SPI == 1
hailfinger9c5add72009-11-24 00:20:03 +0000234 {
hailfinger90c7d542010-05-31 15:27:27 +0000235 .name = "buspirate_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100236 .type = OTHER,
237 /* FIXME */
238 .devs.note = "Dangerous Prototypes Bus Pirate\n",
hailfinger9c5add72009-11-24 00:20:03 +0000239 .init = buspirate_spi_init,
hailfinger9c5add72009-11-24 00:20:03 +0000240 .map_flash_region = fallback_map,
241 .unmap_flash_region = fallback_unmap,
hailfinger9c5add72009-11-24 00:20:03 +0000242 .delay = internal_delay,
243 },
244#endif
245
Anton Staafb2647882014-09-17 15:13:43 -0700246#if CONFIG_RAIDEN_DEBUG_SPI == 1
247 {
248 .name = "raiden_debug_spi",
Brian J. Nemecb42d6c12020-07-23 03:07:38 -0700249 .type = USB,
250 .devs.dev = devs_raiden,
Anton Staafb2647882014-09-17 15:13:43 -0700251 .init = raiden_debug_spi_init,
252 .map_flash_region = fallback_map,
253 .unmap_flash_region = fallback_unmap,
254 .delay = internal_delay,
255 },
256#endif
257
hailfinger90c7d542010-05-31 15:27:27 +0000258#if CONFIG_DEDIPROG == 1
hailfingerdfb32a02010-01-19 11:15:48 +0000259 {
260 .name = "dediprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100261 .type = USB,
hailfingerdfb32a02010-01-19 11:15:48 +0000262 .init = dediprog_init,
hailfingerdfb32a02010-01-19 11:15:48 +0000263 .map_flash_region = fallback_map,
264 .unmap_flash_region = fallback_unmap,
hailfingerdfb32a02010-01-19 11:15:48 +0000265 .delay = internal_delay,
266 },
267#endif
268
hailfinger52c4fa02010-07-21 10:26:01 +0000269#if CONFIG_RAYER_SPI == 1
270 {
271 .name = "rayer_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100272 .type = OTHER,
273 /* FIXME */
274 .devs.note = "RayeR parallel port programmer\n",
hailfinger52c4fa02010-07-21 10:26:01 +0000275 .init = rayer_spi_init,
hailfinger52c4fa02010-07-21 10:26:01 +0000276 .map_flash_region = fallback_map,
277 .unmap_flash_region = fallback_unmap,
hailfinger52c4fa02010-07-21 10:26:01 +0000278 .delay = internal_delay,
279 },
280#endif
281
hailfinger7949b652011-05-08 00:24:18 +0000282#if CONFIG_NICINTEL == 1
283 {
284 .name = "nicintel",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100285 .type = PCI,
286 .devs.dev = nics_intel,
hailfinger7949b652011-05-08 00:24:18 +0000287 .init = nicintel_init,
hailfinger7949b652011-05-08 00:24:18 +0000288 .map_flash_region = fallback_map,
289 .unmap_flash_region = fallback_unmap,
hailfinger7949b652011-05-08 00:24:18 +0000290 .delay = internal_delay,
291 },
292#endif
293
uwe6764e922010-09-03 18:21:21 +0000294#if CONFIG_NICINTEL_SPI == 1
295 {
uwe8d342eb2011-07-28 08:13:25 +0000296 .name = "nicintel_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100297 .type = PCI,
298 .devs.dev = nics_intel_spi,
uwe8d342eb2011-07-28 08:13:25 +0000299 .init = nicintel_spi_init,
300 .map_flash_region = fallback_map,
301 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000302 .delay = internal_delay,
uwe6764e922010-09-03 18:21:21 +0000303 },
304#endif
305
hailfingerfb1f31f2010-12-03 14:48:11 +0000306#if CONFIG_OGP_SPI == 1
307 {
uwe8d342eb2011-07-28 08:13:25 +0000308 .name = "ogp_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100309 .type = PCI,
310 .devs.dev = ogp_spi,
uwe8d342eb2011-07-28 08:13:25 +0000311 .init = ogp_spi_init,
312 .map_flash_region = fallback_map,
313 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000314 .delay = internal_delay,
hailfingerfb1f31f2010-12-03 14:48:11 +0000315 },
316#endif
317
hailfinger935365d2011-02-04 21:37:59 +0000318#if CONFIG_SATAMV == 1
319 {
320 .name = "satamv",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100321 .type = PCI,
322 .devs.dev = satas_mv,
hailfinger935365d2011-02-04 21:37:59 +0000323 .init = satamv_init,
hailfinger935365d2011-02-04 21:37:59 +0000324 .map_flash_region = fallback_map,
325 .unmap_flash_region = fallback_unmap,
hailfinger935365d2011-02-04 21:37:59 +0000326 .delay = internal_delay,
327 },
328#endif
329
David Hendrickscebee892015-05-23 20:30:30 -0700330#if CONFIG_LINUX_MTD == 1
331 {
332 .name = "linux_mtd",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100333 .type = OTHER,
334 .devs.note = "Device files /dev/mtd*\n",
David Hendrickscebee892015-05-23 20:30:30 -0700335 .init = linux_mtd_init,
336 .map_flash_region = fallback_map,
337 .unmap_flash_region = fallback_unmap,
338 .delay = internal_delay,
339 },
340#endif
341
uwe7df6dda2011-09-03 18:37:52 +0000342#if CONFIG_LINUX_SPI == 1
343 {
344 .name = "linux_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100345 .type = OTHER,
346 .devs.note = "Device files /dev/spidev*.*\n",
uwe7df6dda2011-09-03 18:37:52 +0000347 .init = linux_spi_init,
348 .map_flash_region = fallback_map,
349 .unmap_flash_region = fallback_unmap,
uwe7df6dda2011-09-03 18:37:52 +0000350 .delay = internal_delay,
351 },
352#endif
353
Shiyu Sun9dde7162020-04-16 17:32:55 +1000354#if CONFIG_LSPCON_I2C_SPI == 1
355 {
356 .name = "lspcon_i2c_spi",
357 .type = OTHER,
358 .devs.note = "Device files /dev/i2c-*.\n",
359 .init = lspcon_i2c_spi_init,
360 .map_flash_region = fallback_map,
361 .unmap_flash_region = fallback_unmap,
362 .delay = internal_delay,
363 },
364#endif
365
Edward O'Callaghan97dd9262020-03-26 00:00:41 +1100366#if CONFIG_REALTEK_MST_I2C_SPI == 1
367 {
368 .name = "realtek_mst_i2c_spi",
369 .type = OTHER,
370 .devs.note = "Device files /dev/i2c-*.\n",
371 .init = realtek_mst_i2c_spi_init,
372 .map_flash_region = fallback_map,
373 .unmap_flash_region = fallback_unmap,
374 .delay = internal_delay,
375 },
376#endif
377
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100378 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000379};
stepan927d4e22007-04-04 22:45:58 +0000380
David Hendricksbf36f092010-11-02 23:39:29 -0700381#define CHIP_RESTORE_MAXFN 4
382static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000383static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700384 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700385 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700386 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000387} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700388
David Hendricks668f29d2011-01-27 18:51:45 -0800389
hailfingerf31cbdc2010-11-10 15:25:18 +0000390#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000391static int shutdown_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000392static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700393 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000394 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000395} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000396/* Initialize to 0 to make sure nobody registers a shutdown function before
397 * programmer init.
398 */
399static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000400
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700401static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000402
hailfingerdc6f7972010-02-14 01:20:28 +0000403/* Register a function to be executed on programmer shutdown.
404 * The advantage over atexit() is that you can supply a void pointer which will
405 * be used as parameter to the registered function upon programmer shutdown.
406 * This pointer can point to arbitrary data used by said function, e.g. undo
407 * information for GPIO settings etc. If unneeded, set data=NULL.
408 * Please note that the first (void *data) belongs to the function signature of
409 * the function passed as first parameter.
410 */
David Hendricks93784b42016-08-09 17:00:38 -0700411int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000412{
413 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000414 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000415 SHUTDOWN_MAXFN);
416 return 1;
417 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000418 if (!may_register_shutdown) {
419 msg_perr("Tried to register a shutdown function before "
420 "programmer init.\n");
421 return 1;
422 }
hailfingerdc6f7972010-02-14 01:20:28 +0000423 shutdown_fn[shutdown_fn_count].func = function;
424 shutdown_fn[shutdown_fn_count].data = data;
425 shutdown_fn_count++;
426
427 return 0;
428}
429
David Hendricksbf36f092010-11-02 23:39:29 -0700430//int register_chip_restore(int (*function) (void *data), void *data)
431int register_chip_restore(CHIP_RESTORE_CALLBACK,
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700432 struct flashctx *flash, uint8_t status)
David Hendricksbf36f092010-11-02 23:39:29 -0700433{
434 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
435 msg_perr("Tried to register more than %i chip restore"
436 " functions.\n", CHIP_RESTORE_MAXFN);
437 return 1;
438 }
439 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
440 chip_restore_fn[chip_restore_fn_count].flash = flash;
441 chip_restore_fn[chip_restore_fn_count].status = status;
442 chip_restore_fn_count++;
443
444 return 0;
445}
446
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000447int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000448{
hailfinger1ef766d2010-07-06 09:55:48 +0000449 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000450
451 if (prog >= PROGRAMMER_INVALID) {
452 msg_perr("Invalid programmer specified!\n");
453 return -1;
454 }
455 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000456 /* Initialize all programmer specific data. */
457 /* Default to unlimited decode sizes. */
458 max_rom_decode = (const struct decode_sizes) {
459 .parallel = 0xffffffff,
460 .lpc = 0xffffffff,
461 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000462 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000463 };
David Hendricksac1d25c2016-08-09 17:00:58 -0700464 buses_supported = BUS_NONE;
hailfinger1ff33dc2010-07-03 11:02:10 +0000465 /* Default to top aligned flash at 4 GB. */
466 flashbase = 0;
467 /* Registering shutdown functions is now allowed. */
468 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000469 /* Default to allowing writes. Broken programmers set this to 0. */
470 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000471
472 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000473 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700474 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000475 if (programmer_param && strlen(programmer_param)) {
476 if (ret != 0) {
477 /* It is quite possible that any unhandled programmer parameter would have been valid,
478 * but an error in actual programmer init happened before the parameter was evaluated.
479 */
480 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
481 programmer_param);
482 } else {
483 /* Actual programmer init was successful, but the user specified an invalid or unusable
484 * (for the current programmer configuration) parameter.
485 */
486 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
487 msg_perr("Aborting.\n");
488 ret = ERROR_FATAL;
489 }
490 }
hailfinger1ef766d2010-07-06 09:55:48 +0000491 return ret;
uweabe92a52009-05-16 22:36:00 +0000492}
493
David Hendricksbf36f092010-11-02 23:39:29 -0700494int chip_restore()
495{
496 int rc = 0;
497
498 while (chip_restore_fn_count > 0) {
499 int i = --chip_restore_fn_count;
500 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
501 chip_restore_fn[i].status);
502 }
503
504 return rc;
505}
506
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000507/** Calls registered shutdown functions and resets internal programmer-related variables.
508 * Calling it is safe even without previous initialization, but further interactions with programmer support
509 * require a call to programmer_init() (afterwards).
510 *
511 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700512int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000513{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000514 int ret = 0;
515
hailfinger1ff33dc2010-07-03 11:02:10 +0000516 /* Registering shutdown functions is no longer allowed. */
517 may_register_shutdown = 0;
518 while (shutdown_fn_count > 0) {
519 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700520 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000521 }
dhendrix0ffc2eb2011-06-14 01:35:36 +0000522 return ret;
uweabe92a52009-05-16 22:36:00 +0000523}
524
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000525void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000526{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000527 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
528 return ret;
uweabe92a52009-05-16 22:36:00 +0000529}
530
531void programmer_unmap_flash_region(void *virt_addr, size_t len)
532{
533 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000534 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000535}
536
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700537void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000538{
Craig Hesling65eb8812019-08-01 09:33:56 -0700539 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000540}
541
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700542void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000543{
Craig Hesling65eb8812019-08-01 09:33:56 -0700544 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000545}
546
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700547void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000548{
Craig Hesling65eb8812019-08-01 09:33:56 -0700549 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000550}
551
Stuart langleyc98e43f2020-03-26 20:27:36 +1100552void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000553{
Craig Hesling65eb8812019-08-01 09:33:56 -0700554 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000555}
556
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700557uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000558{
Craig Hesling65eb8812019-08-01 09:33:56 -0700559 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000560}
561
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700562uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000563{
Craig Hesling65eb8812019-08-01 09:33:56 -0700564 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000565}
566
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700567uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000568{
Craig Hesling65eb8812019-08-01 09:33:56 -0700569 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000570}
571
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000572void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
573 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000574{
Craig Hesling65eb8812019-08-01 09:33:56 -0700575 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000576}
577
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000578void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000579{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000580 if (usecs > 0)
581 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000582}
583
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700584int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000585{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700586 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000587
hailfinger23060112009-05-08 12:49:03 +0000588 return 0;
589}
590
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000591/* This is a somewhat hacked function similar in some ways to strtok().
592 * It will look for needle with a subsequent '=' in haystack, return a copy of
593 * needle and remove everything from the first occurrence of needle to the next
594 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000595 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000596char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000597{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000598 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000599 char *opt = NULL;
600 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000601 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000602
hailfingerf4aaccc2010-04-28 15:22:14 +0000603 needlelen = strlen(needle);
604 if (!needlelen) {
605 msg_gerr("%s: empty needle! Please report a bug at "
606 "flashrom@flashrom.org\n", __func__);
607 return NULL;
608 }
609 /* No programmer parameters given. */
610 if (*haystack == NULL)
611 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000612 param_pos = strstr(*haystack, needle);
613 do {
614 if (!param_pos)
615 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000616 /* Needle followed by '='? */
617 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000618 /* Beginning of the string? */
619 if (param_pos == *haystack)
620 break;
621 /* After a delimiter? */
622 if (strchr(delim, *(param_pos - 1)))
623 break;
624 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000625 /* Continue searching. */
626 param_pos++;
627 param_pos = strstr(param_pos, needle);
628 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000629
hailfinger6e5a52a2009-11-24 18:27:10 +0000630 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000631 /* Get the string after needle and '='. */
632 opt_pos = param_pos + needlelen + 1;
633 optlen = strcspn(opt_pos, delim);
634 /* Return an empty string if the parameter was empty. */
635 opt = malloc(optlen + 1);
636 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000637 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000638 exit(1);
639 }
hailfinger1ef766d2010-07-06 09:55:48 +0000640 strncpy(opt, opt_pos, optlen);
641 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000642 rest = opt_pos + optlen;
643 /* Skip all delimiters after the current parameter. */
644 rest += strspn(rest, delim);
645 memmove(param_pos, rest, strlen(rest) + 1);
646 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000647 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000648
hailfinger1ef766d2010-07-06 09:55:48 +0000649 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000650}
651
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000652char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000653{
654 return extract_param(&programmer_param, param_name, ",");
655}
656
stefancte1c5acf2011-07-04 07:27:17 +0000657/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700658static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000659{
660 unsigned int usable_erasefunctions = 0;
661 int k;
662 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
663 if (!check_block_eraser(flash, k, 0))
664 usable_erasefunctions++;
665 }
666 return usable_erasefunctions;
667}
668
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000669static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700670{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000671 int ret = 0, failcount = 0;
672 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700673 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000674 if (wantbuf[i] != havebuf[i]) {
675 /* Only print the first failure. */
676 if (!failcount++)
677 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
678 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700679 }
680 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000681 if (failcount) {
682 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
683 start, start + len - 1, failcount);
684 ret = -1;
685 }
686 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700687}
688
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000689/* start is an offset to the base address of the flash chip */
690static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
691{
692 int ret;
693 uint8_t *cmpbuf = malloc(len);
694 const uint8_t erased_value = ERASED_VALUE(flash);
695
696 if (!cmpbuf) {
697 msg_gerr("Could not allocate memory!\n");
698 exit(1);
699 }
700 memset(cmpbuf, erased_value, len);
701 ret = verify_range(flash, cmpbuf, start, len);
702 free(cmpbuf);
703 return ret;
704}
705
uwee15beb92010-08-08 17:01:18 +0000706/*
hailfinger7af3d192009-11-25 17:05:52 +0000707 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000708 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000709 * @start offset to the base address of the flash chip
710 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000711 * @return 0 for success, -1 for failure
712 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000713int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000714{
hailfinger7af83692009-06-15 17:23:36 +0000715 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000716 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000717
Patrick Georgif3fa2992017-02-02 16:24:44 +0100718 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000719 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000720 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000721 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000722
723 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000724 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000725 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000726 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000727 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000728 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000729
Patrick Georgif3fa2992017-02-02 16:24:44 +0100730 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000731 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000732 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100733 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000734 ret = -1;
735 goto out_free;
736 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700737 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700738 if (programmer_table[programmer].paranoid) {
739 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800740
Simon Glass4e305f42015-01-08 06:29:04 -0700741 /* limit chunksize in order to catch errors early */
742 for (i = 0, chunksize = 0; i < len; i += chunksize) {
743 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800744
Patrick Georgif3fa2992017-02-02 16:24:44 +0100745 chunksize = min(flash->chip->page_size, len - i);
746 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700747 if (tmp) {
748 ret = tmp;
749 if (ignore_error(tmp))
750 continue;
751 else
752 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800753 }
Simon Glass4e305f42015-01-08 06:29:04 -0700754
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700755 /*
756 * Check write access permission and do not compare chunks
757 * where flashrom does not have write access to the region.
758 */
759 if (flash->chip->check_access) {
760 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
761 if (tmp && ignore_error(tmp))
762 continue;
763 }
764
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000765 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700766 if (failcount)
767 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800768 }
Simon Glass4e305f42015-01-08 06:29:04 -0700769 } else {
770 int tmp;
771
772 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +0100773 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -0700774 if (tmp && !ignore_error(tmp)) {
775 ret = tmp;
776 goto out_free;
777 }
778
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000779 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +0000780 }
781
hailfinger5be6c0f2009-07-23 01:42:56 +0000782 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +0000783 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +0000784 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +0000785 ret = -1;
786 }
hailfinger7af83692009-06-15 17:23:36 +0000787
788out_free:
789 free(readbuf);
790 return ret;
791}
792
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100793/* Helper function for need_erase() that focuses on granularities of gran bytes. */
794static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000795 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100796{
797 unsigned int i, j, limit;
798 for (j = 0; j < len / gran; j++) {
799 limit = min (gran, len - j * gran);
800 /* Are 'have' and 'want' identical? */
801 if (!memcmp(have + j * gran, want + j * gran, limit))
802 continue;
803 /* have needs to be in erased state. */
804 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000805 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100806 return 1;
807 }
808 return 0;
809}
810
uwee15beb92010-08-08 17:01:18 +0000811/*
hailfingerb247c7a2010-03-08 00:42:32 +0000812 * Check if the buffer @have can be programmed to the content of @want without
813 * erasing. This is only possible if all chunks of size @gran are either kept
814 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +0000815 *
hailfingerb437e282010-11-04 01:04:27 +0000816 * Warning: This function assumes that @have and @want point to naturally
817 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +0000818 *
819 * @have buffer with current content
820 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +0000821 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +0000822 * @gran write granularity (enum, not count)
823 * @return 0 if no erase is needed, 1 otherwise
824 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000825int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
826 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +0000827{
hailfingerb91c08c2011-08-15 19:54:20 +0000828 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100829 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -0700830
hailfingerb247c7a2010-03-08 00:42:32 +0000831 switch (gran) {
832 case write_gran_1bit:
833 for (i = 0; i < len; i++)
834 if ((have[i] & want[i]) != want[i]) {
835 result = 1;
836 break;
837 }
838 break;
839 case write_gran_1byte:
840 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000841 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +0000842 result = 1;
843 break;
844 }
845 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100846 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000847 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100848 break;
hailfingerb247c7a2010-03-08 00:42:32 +0000849 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000850 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100851 break;
852 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000853 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100854 break;
855 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000856 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100857 break;
858 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000859 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100860 break;
861 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000862 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100863 break;
864 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000865 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100866 break;
867 case write_gran_1byte_implicit_erase:
868 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
869 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +0000870 break;
hailfingerb437e282010-11-04 01:04:27 +0000871 default:
872 msg_cerr("%s: Unsupported granularity! Please report a bug at "
873 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +0000874 }
875 return result;
876}
877
hailfingerb437e282010-11-04 01:04:27 +0000878/**
879 * Check if the buffer @have needs to be programmed to get the content of @want.
880 * If yes, return 1 and fill in first_start with the start address of the
881 * write operation and first_len with the length of the first to-be-written
882 * chunk. If not, return 0 and leave first_start and first_len undefined.
883 *
884 * Warning: This function assumes that @have and @want point to naturally
885 * aligned regions.
886 *
887 * @have buffer with current content
888 * @want buffer with desired content
889 * @len length of the checked area
890 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +0000891 * @first_start offset of the first byte which needs to be written (passed in
892 * value is increased by the offset of the first needed write
893 * relative to have/want or unchanged if no write is needed)
894 * @return length of the first contiguous area which needs to be written
895 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +0000896 *
897 * FIXME: This function needs a parameter which tells it about coalescing
898 * in relation to the max write length of the programmer and the max write
899 * length of the chip.
900 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000901static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +0000902 unsigned int *first_start,
903 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +0000904{
stefanctc5eb8a92011-11-23 09:13:48 +0000905 int need_write = 0;
906 unsigned int rel_start = 0, first_len = 0;
907 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +0000908
hailfingerb437e282010-11-04 01:04:27 +0000909 switch (gran) {
910 case write_gran_1bit:
911 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100912 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +0000913 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +0000914 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100915 case write_gran_128bytes:
916 stride = 128;
917 break;
hailfingerb437e282010-11-04 01:04:27 +0000918 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +0000919 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +0000920 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100921 case write_gran_264bytes:
922 stride = 264;
923 break;
924 case write_gran_512bytes:
925 stride = 512;
926 break;
927 case write_gran_528bytes:
928 stride = 528;
929 break;
930 case write_gran_1024bytes:
931 stride = 1024;
932 break;
933 case write_gran_1056bytes:
934 stride = 1056;
935 break;
hailfingerb437e282010-11-04 01:04:27 +0000936 default:
937 msg_cerr("%s: Unsupported granularity! Please report a bug at "
938 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +0000939 /* Claim that no write was needed. A write with unknown
940 * granularity is too dangerous to try.
941 */
942 return 0;
hailfingerb437e282010-11-04 01:04:27 +0000943 }
hailfinger90fcf9b2010-11-05 14:51:59 +0000944 for (i = 0; i < len / stride; i++) {
945 limit = min(stride, len - i * stride);
946 /* Are 'have' and 'want' identical? */
947 if (memcmp(have + i * stride, want + i * stride, limit)) {
948 if (!need_write) {
949 /* First location where have and want differ. */
950 need_write = 1;
951 rel_start = i * stride;
952 }
953 } else {
954 if (need_write) {
955 /* First location where have and want
956 * do not differ anymore.
957 */
hailfinger90fcf9b2010-11-05 14:51:59 +0000958 break;
959 }
960 }
961 }
hailfingerffb7f382010-12-06 13:05:44 +0000962 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +0000963 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +0000964 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +0000965 return first_len;
hailfingerb437e282010-11-04 01:04:27 +0000966}
967
hailfinger0c515352009-11-23 12:55:31 +0000968/* This function generates various test patterns useful for testing controller
969 * and chip communication as well as chip behaviour.
970 *
971 * If a byte can be written multiple times, each time keeping 0-bits at 0
972 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
973 * is essentially an AND operation. That's also the reason why this function
974 * provides the result of AND between various patterns.
975 *
976 * Below is a list of patterns (and their block length).
977 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
978 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
979 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
980 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
981 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
982 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
983 * Pattern 6 is 00 (1 Byte)
984 * Pattern 7 is ff (1 Byte)
985 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
986 * byte block.
987 *
988 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
989 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
990 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
991 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
992 * Pattern 12 is 00 (1 Byte)
993 * Pattern 13 is ff (1 Byte)
994 * Patterns 8-13 have no block number.
995 *
996 * Patterns 0-3 are created to detect and efficiently diagnose communication
997 * slips like missed bits or bytes and their repetitive nature gives good visual
998 * cues to the person inspecting the results. In addition, the following holds:
999 * AND Pattern 0/1 == Pattern 4
1000 * AND Pattern 2/3 == Pattern 5
1001 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1002 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1003 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1004 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1005 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1006 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1007 * Besides that, they provide for bit testing of the last two bytes of every
1008 * 256 byte block which contains the block number for patterns 0-6.
1009 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1010 * block sizes >256 bytes (some Dataflash chips etc.)
1011 * AND Pattern 8/9 == Pattern 12
1012 * AND Pattern 10/11 == Pattern 12
1013 * Pattern 13 is the completely erased state.
1014 * None of the patterns can detect aliasing at boundaries which are a multiple
1015 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1016 */
1017int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1018{
1019 int i;
1020
1021 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001022 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001023 return 1;
1024 }
1025
1026 switch (variant) {
1027 case 0:
1028 for (i = 0; i < size; i++)
1029 buf[i] = (i & 0xf) << 4 | 0x5;
1030 break;
1031 case 1:
1032 for (i = 0; i < size; i++)
1033 buf[i] = (i & 0xf) << 4 | 0xa;
1034 break;
1035 case 2:
1036 for (i = 0; i < size; i++)
1037 buf[i] = 0x50 | (i & 0xf);
1038 break;
1039 case 3:
1040 for (i = 0; i < size; i++)
1041 buf[i] = 0xa0 | (i & 0xf);
1042 break;
1043 case 4:
1044 for (i = 0; i < size; i++)
1045 buf[i] = (i & 0xf) << 4;
1046 break;
1047 case 5:
1048 for (i = 0; i < size; i++)
1049 buf[i] = i & 0xf;
1050 break;
1051 case 6:
1052 memset(buf, 0x00, size);
1053 break;
1054 case 7:
1055 memset(buf, 0xff, size);
1056 break;
1057 case 8:
1058 for (i = 0; i < size; i++)
1059 buf[i] = i & 0xff;
1060 break;
1061 case 9:
1062 for (i = 0; i < size; i++)
1063 buf[i] = ~(i & 0xff);
1064 break;
1065 case 10:
1066 for (i = 0; i < size % 2; i++) {
1067 buf[i * 2] = (i >> 8) & 0xff;
1068 buf[i * 2 + 1] = i & 0xff;
1069 }
1070 if (size & 0x1)
1071 buf[i * 2] = (i >> 8) & 0xff;
1072 break;
1073 case 11:
1074 for (i = 0; i < size % 2; i++) {
1075 buf[i * 2] = ~((i >> 8) & 0xff);
1076 buf[i * 2 + 1] = ~(i & 0xff);
1077 }
1078 if (size & 0x1)
1079 buf[i * 2] = ~((i >> 8) & 0xff);
1080 break;
1081 case 12:
1082 memset(buf, 0x00, size);
1083 break;
1084 case 13:
1085 memset(buf, 0xff, size);
1086 break;
1087 }
1088
1089 if ((variant >= 0) && (variant <= 7)) {
1090 /* Write block number in the last two bytes of each 256-byte
1091 * block, big endian for easier reading of the hexdump.
1092 * Note that this wraps around for chips larger than 2^24 bytes
1093 * (16 MB).
1094 */
1095 for (i = 0; i < size / 256; i++) {
1096 buf[i * 256 + 254] = (i >> 8) & 0xff;
1097 buf[i * 256 + 255] = i & 0xff;
1098 }
1099 }
1100
1101 return 0;
1102}
1103
hailfingeraec9c962009-10-31 01:53:09 +00001104int check_max_decode(enum chipbustype buses, uint32_t size)
1105{
1106 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001107
1108 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < 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.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001115 }
hailfingere1e41ea2011-07-27 07:13:06 +00001116 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001117 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001118 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001119 "size %u kB of chipset/board/programmer "
1120 "for %s interface, "
1121 "probe/read/erase/write may fail. ", size / 1024,
1122 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001123 }
hailfingere1e41ea2011-07-27 07:13:06 +00001124 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001125 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001126 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001127 "size %u kB of chipset/board/programmer "
1128 "for %s interface, "
1129 "probe/read/erase/write may fail. ", size / 1024,
1130 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001131 }
hailfingere1e41ea2011-07-27 07:13:06 +00001132 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001133 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001134 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001135 "size %u kB of chipset/board/programmer "
1136 "for %s interface, "
1137 "probe/read/erase/write may fail. ", size / 1024,
1138 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001139 }
1140 if (!limitexceeded)
1141 return 0;
1142 /* Sometimes chip and programmer have more than one bus in common,
1143 * and the limit is not exceeded on all buses. Tell the user.
1144 */
1145 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001146 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001147 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001148 "interface which can support a chip of this size. "
1149 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001150 return 1;
1151}
1152
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001153void unmap_flash(struct flashctx *flash)
1154{
1155 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1156 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1157 flash->physical_registers = 0;
1158 flash->virtual_registers = (chipaddr)ERROR_PTR;
1159 }
1160
1161 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1162 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1163 flash->physical_memory = 0;
1164 flash->virtual_memory = (chipaddr)ERROR_PTR;
1165 }
1166}
1167
1168int map_flash(struct flashctx *flash)
1169{
1170 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1171 flash->virtual_memory = (chipaddr)ERROR_PTR;
1172 flash->virtual_registers = (chipaddr)ERROR_PTR;
1173
1174 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1175 * These are used for various probing-related hacks that would not map successfully anyway and should be
1176 * removed ASAP. */
1177 if (flash->chip->total_size == 0)
1178 return 0;
1179
1180 const chipsize_t size = flash->chip->total_size * 1024;
1181 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1182 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1183 if (addr == ERROR_PTR) {
1184 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1185 flash->chip->name, PRIxPTR_WIDTH, base);
1186 return 1;
1187 }
1188 flash->physical_memory = base;
1189 flash->virtual_memory = (chipaddr)addr;
1190
1191 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1192 * completely different on some chips and programmers, or not mappable at all.
1193 * Ignore these problems for now and always report success. */
1194 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1195 base = 0xffffffff - size - 0x400000 + 1;
1196 addr = programmer_map_flash_region("flash chip registers", base, size);
1197 if (addr == ERROR_PTR) {
1198 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1199 flash->chip->name, PRIxPTR_WIDTH, base);
1200 return 0;
1201 }
1202 flash->physical_registers = base;
1203 flash->virtual_registers = (chipaddr)addr;
1204 }
1205 return 0;
1206}
1207
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001208/*
1209 * Return a string corresponding to the bustype parameter.
1210 * Memory is obtained with malloc() and must be freed with free() by the caller.
1211 */
1212char *flashbuses_to_text(enum chipbustype bustype)
1213{
1214 char *ret = calloc(1, 1);
1215 /*
1216 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1217 * will cease to exist and should be eliminated here as well.
1218 */
1219 if (bustype == BUS_NONSPI) {
1220 ret = strcat_realloc(ret, "Non-SPI, ");
1221 } else {
1222 if (bustype & BUS_PARALLEL)
1223 ret = strcat_realloc(ret, "Parallel, ");
1224 if (bustype & BUS_LPC)
1225 ret = strcat_realloc(ret, "LPC, ");
1226 if (bustype & BUS_FWH)
1227 ret = strcat_realloc(ret, "FWH, ");
1228 if (bustype & BUS_SPI)
1229 ret = strcat_realloc(ret, "SPI, ");
1230 if (bustype & BUS_PROG)
1231 ret = strcat_realloc(ret, "Programmer-specific, ");
1232 if (bustype == BUS_NONE)
1233 ret = strcat_realloc(ret, "None, ");
1234 }
1235 /* Kill last comma. */
1236 ret[strlen(ret) - 2] = '\0';
1237 ret = realloc(ret, strlen(ret) + 1);
1238 return ret;
1239}
1240
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001241int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001242{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001243 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001244 uint32_t size;
1245 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001246 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001247
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301248 /* Based on the host controller interface that a platform
1249 * needs to use (hwseq or swseq),
1250 * set the flashchips list here.
1251 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001252 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301253 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001254 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301255 flash_list = flashchips_hwseq;
1256 break;
1257 default:
1258 flash_list = flashchips;
1259 break;
1260 }
1261
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001262 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1263 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001264 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001265 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001266 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001267 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001268 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001269 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001270 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001271 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001272 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001273 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001274 continue;
1275 }
stepan782fb172007-04-06 11:58:03 +00001276
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001277 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001278 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001279
hailfinger48ed3e22011-05-04 00:39:50 +00001280 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001281 flash->chip = calloc(1, sizeof(struct flashchip));
1282 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001283 msg_gerr("Out of memory!\n");
1284 exit(1);
1285 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001286 memcpy(flash->chip, chip, sizeof(struct flashchip));
1287 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001288
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001289 if (map_flash(flash) != 0)
1290 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001291
stugec1e55fe2008-07-02 17:15:47 +00001292 if (force)
1293 break;
stepanc98b80b2006-03-16 16:57:41 +00001294
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001295 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001296 goto notfound;
1297
hailfinger48ed3e22011-05-04 00:39:50 +00001298 /* If this is the first chip found, accept it.
1299 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001300 * a non-generic match. SFDP and CFI are generic matches.
1301 * startchip==0 means this call to probe_flash() is the first
1302 * one for this programmer interface (master) and thus no other chip has
1303 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001304 */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001305 if (startchip == 0 || flash->chip->model_id != GENERIC_DEVICE_ID)
stugec1e55fe2008-07-02 17:15:47 +00001306 break;
1307
stuge56300c32008-09-03 23:10:05 +00001308notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001309 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001310 free(flash->chip);
1311 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001312 }
uwebe4477b2007-08-23 16:08:21 +00001313
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001314 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001315 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001316
stepan3e7aeae2011-01-19 06:21:54 +00001317
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001318 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001319 msg_cdbg("%s %s flash chip \"%s\" (%d kB, %s) \n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001320 force ? "Assuming" : "Found", flash->chip->vendor,
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001321 flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001322 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001323#if CONFIG_INTERNAL == 1
1324 if (programmer_table[programmer].map_flash_region == physmap)
1325 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1326 PRIxPTR_WIDTH, flash->physical_memory);
1327 else
1328#endif
1329 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001330
hailfinger0f4c3952010-12-02 21:59:42 +00001331 /* Flash registers will not be mapped if the chip was forced. Lock info
1332 * may be stored in registers, so avoid lock info printing.
1333 */
1334 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001335 if (flash->chip->printlock)
1336 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001337
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001338 /* Get out of the way for later runs. */
1339 unmap_flash(flash);
1340
hailfinger48ed3e22011-05-04 00:39:50 +00001341 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001342 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001343}
1344
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001345static int verify_flash(struct flashctx *flash,
1346 struct action_descriptor *descriptor,
1347 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001348{
hailfingerb0f4d122009-06-24 08:20:45 +00001349 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001350 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001351 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001352
snelsone42c3802010-05-07 20:09:04 +00001353 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001354
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001355 if (verify_it == VERIFY_PARTIAL) {
1356 struct processing_unit *pu = descriptor->processing_units;
1357
1358 /* Verify only areas which were written. */
1359 while (pu->num_blocks) {
1360 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001361 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001362 if (ret)
1363 break;
1364 pu++;
1365 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001366 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001367 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001368 }
uwef6641642007-05-09 10:17:44 +00001369
David Hendricks1ed1d352011-11-23 17:54:37 -08001370 if (ret == ACCESS_DENIED) {
1371 msg_gdbg("Could not fully verify due to access error, ");
1372 if (access_denied_action == error_ignore) {
1373 msg_gdbg("ignoring\n");
1374 ret = 0;
1375 } else {
1376 msg_gdbg("aborting\n");
1377 }
1378 }
1379
hailfingerb0f4d122009-06-24 08:20:45 +00001380 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001381 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001382
hailfingerb0f4d122009-06-24 08:20:45 +00001383 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001384}
1385
uwe8d342eb2011-07-28 08:13:25 +00001386int read_buf_from_file(unsigned char *buf, unsigned long size,
1387 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001388{
1389 unsigned long numbytes;
1390 FILE *image;
1391 struct stat image_stat;
1392
Vincent Palatin7ab23932014-10-01 12:09:16 -07001393 if (!strncmp(filename, "-", sizeof("-")))
1394 image = fdopen(STDIN_FILENO, "rb");
1395 else
1396 image = fopen(filename, "rb");
1397 if (image == NULL) {
hailfinger771fc182010-10-15 00:01:14 +00001398 perror(filename);
1399 return 1;
1400 }
1401 if (fstat(fileno(image), &image_stat) != 0) {
1402 perror(filename);
1403 fclose(image);
1404 return 1;
1405 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001406 if ((image_stat.st_size != size) &&
1407 (strncmp(filename, "-", sizeof("-")))) {
Mike Frysinger62c794d2017-05-29 12:02:45 -04001408 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1409 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
hailfinger771fc182010-10-15 00:01:14 +00001410 fclose(image);
1411 return 1;
1412 }
1413 numbytes = fread(buf, 1, size, image);
1414 if (fclose(image)) {
1415 perror(filename);
1416 return 1;
1417 }
1418 if (numbytes != size) {
1419 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1420 "wanted %ld!\n", numbytes, size);
1421 return 1;
1422 }
1423 return 0;
1424}
1425
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001426int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001427{
1428 unsigned long numbytes;
1429 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001430
1431 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001432 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001433 return 1;
1434 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001435 if (!strncmp(filename, "-", sizeof("-")))
1436 image = fdopen(STDOUT_FILENO, "wb");
1437 else
1438 image = fopen(filename, "wb");
1439 if (image == NULL) {
hailfingerd219a232009-01-28 00:27:54 +00001440 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001441 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001442 }
hailfingerd219a232009-01-28 00:27:54 +00001443
hailfingerd219a232009-01-28 00:27:54 +00001444 numbytes = fwrite(buf, 1, size, image);
1445 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001446 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001447 msg_gerr("Error: file %s could not be written completely.\n", filename);
hailfingerd219a232009-01-28 00:27:54 +00001448 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001449 }
hailfingerd219a232009-01-28 00:27:54 +00001450 return 0;
1451}
1452
David Hendrickse3451942013-03-21 17:23:29 -07001453/*
1454 * read_flash - wrapper for flash->read() with additional high-level policy
1455 *
1456 * @flash flash chip
1457 * @buf buffer to store data in
1458 * @start start address
1459 * @len number of bytes to read
1460 *
1461 * This wrapper simplifies most cases when the flash chip needs to be read
1462 * since policy decisions such as non-fatal error handling is centralized.
1463 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001464int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001465 unsigned int start, unsigned int len)
1466{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001467 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001468
Patrick Georgif3fa2992017-02-02 16:24:44 +01001469 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001470 return -1;
1471
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001472 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1473
Patrick Georgif3fa2992017-02-02 16:24:44 +01001474 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001475 if (ret) {
1476 if (ignore_error(ret)) {
1477 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1478 start, start + len - 1);
1479 ret = 0;
1480 } else {
1481 msg_gdbg("failed to read 0x%x-0x%x\n",
1482 start, start + len - 1);
1483 }
1484 }
1485
1486 return ret;
1487}
1488
David Hendricks7c8a1612013-04-26 19:14:44 -07001489/*
1490 * write_flash - wrapper for flash->write() with additional high-level policy
1491 *
1492 * @flash flash chip
1493 * @buf buffer to write to flash
1494 * @start start address in flash
1495 * @len number of bytes to write
1496 *
1497 * TODO: Look up regions that are write-protected and avoid attempt to write
1498 * to them at all.
1499 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001500int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001501 unsigned int start, unsigned int len)
1502{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001503 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001504 return -1;
1505
Patrick Georgif3fa2992017-02-02 16:24:44 +01001506 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001507}
1508
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001509int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001510{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001511 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001512 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001513 int ret = 0;
1514
1515 msg_cinfo("Reading flash... ");
1516 if (!buf) {
1517 msg_gerr("Memory allocation failed!\n");
1518 msg_cinfo("FAILED.\n");
1519 return 1;
1520 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001521
1522 /* To support partial read, fill buffer to all 0xFF at beginning to make
1523 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001524 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001525
Patrick Georgif3fa2992017-02-02 16:24:44 +01001526 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001527 msg_cerr("No read function available for this flash chip.\n");
1528 ret = 1;
1529 goto out_free;
1530 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001531
1532 /* First try to handle partial read case, rather than read the whole
1533 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001534 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001535 if (ret < 0) {
1536 msg_cerr("Partial read operation failed!\n");
1537 ret = 1;
1538 goto out_free;
1539 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001540 int num_regions = get_num_include_args();
1541
1542 if (ret != num_regions) {
1543 msg_cerr("Requested %d regions, but only read %d\n",
1544 num_regions, ret);
1545 ret = 1;
1546 goto out_free;
1547 }
1548
1549 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001550 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001551 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001552 msg_cerr("Read operation failed!\n");
1553 ret = 1;
1554 goto out_free;
1555 }
hailfinger42a850a2010-07-13 23:56:13 +00001556 }
1557
David Hendricksdf29a832013-06-28 14:33:51 -07001558 if (filename)
1559 ret = write_buf_to_file(buf, size, filename);
1560
hailfinger42a850a2010-07-13 23:56:13 +00001561out_free:
1562 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001563 if (ret)
1564 msg_cerr("FAILED.");
1565 else
1566 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001567 return ret;
1568}
1569
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001570/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001571static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001572{
hailfingerb91c08c2011-08-15 19:54:20 +00001573 int i, j, k;
1574 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001575
1576 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1577 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001578 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001579
1580 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1581 /* Blocks with zero size are bugs in flashchips.c. */
1582 if (eraser.eraseblocks[i].count &&
1583 !eraser.eraseblocks[i].size) {
1584 msg_gerr("ERROR: Flash chip %s erase function "
1585 "%i region %i has size 0. Please report"
1586 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001587 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001588 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001589 }
1590 /* Blocks with zero count are bugs in flashchips.c. */
1591 if (!eraser.eraseblocks[i].count &&
1592 eraser.eraseblocks[i].size) {
1593 msg_gerr("ERROR: Flash chip %s erase function "
1594 "%i region %i has count 0. Please report"
1595 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001596 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001597 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001598 }
1599 done += eraser.eraseblocks[i].count *
1600 eraser.eraseblocks[i].size;
1601 }
hailfinger9fed35d2010-01-19 06:42:46 +00001602 /* Empty eraseblock definition with erase function. */
1603 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001604 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001605 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001606 if (!done)
1607 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001608 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001609 msg_gerr("ERROR: Flash chip %s erase function %i "
1610 "region walking resulted in 0x%06x bytes total,"
1611 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001612 " flashrom@flashrom.org\n", chip->name, k,
1613 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001614 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001615 }
hailfinger9fed35d2010-01-19 06:42:46 +00001616 if (!eraser.block_erase)
1617 continue;
1618 /* Check if there are identical erase functions for different
1619 * layouts. That would imply "magic" erase functions. The
1620 * easiest way to check this is with function pointers.
1621 */
uwef6f94d42010-03-13 17:28:29 +00001622 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001623 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001624 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001625 msg_gerr("ERROR: Flash chip %s erase function "
1626 "%i and %i are identical. Please report"
1627 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001628 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001629 ret = 1;
1630 }
uwef6f94d42010-03-13 17:28:29 +00001631 }
hailfinger45177872010-01-18 08:14:43 +00001632 }
hailfinger9fed35d2010-01-19 06:42:46 +00001633 return ret;
hailfinger45177872010-01-18 08:14:43 +00001634}
1635
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001636static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001637 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001638 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001639 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001640 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001641 unsigned int addr,
1642 unsigned int len))
1643{
stefanctc5eb8a92011-11-23 09:13:48 +00001644 unsigned int starthere = 0, lenhere = 0;
1645 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001646 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001647 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001648
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001649 /*
1650 * curcontents and newcontents are opaque to walk_eraseregions, and
1651 * need to be adjusted here to keep the impression of proper
1652 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001653 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001654
hailfinger90fcf9b2010-11-05 14:51:59 +00001655 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001656
hailfingerb437e282010-11-04 01:04:27 +00001657 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001658
hailfingerb437e282010-11-04 01:04:27 +00001659 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001660 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001661 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001662 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001663 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001664 if (ret) {
1665 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001666 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001667 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001668 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001669 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001670 }
1671
David Hendricks0954ffc2015-11-13 15:15:44 -08001672 if (programmer_table[programmer].paranoid) {
1673 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001674 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001675 return -1;
1676 }
hailfingerac8e3182011-06-26 17:04:16 +00001677 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001678
hailfinger90fcf9b2010-11-05 14:51:59 +00001679 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001680 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001681 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001682 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001683 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001684 /* get_next_write() sets starthere to a new value after the call. */
1685 while ((lenhere = get_next_write(curcontents + starthere,
1686 newcontents + starthere,
1687 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001688 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001689 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001690 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001691 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001692 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001693 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001694 if (ret) {
1695 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001696 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001697 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001698 }
David Hendricks048b38c2016-03-28 18:47:06 -07001699
1700 /*
1701 * If the block needed to be erased and was erased successfully
1702 * then we can assume that we didn't run into any write-
1703 * protected areas. Otherwise, we need to verify each page to
1704 * ensure it was successfully written and abort if we encounter
1705 * any errors.
1706 */
1707 if (programmer_table[programmer].paranoid && !block_was_erased) {
1708 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001709 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001710 return -1;
1711 }
1712
hailfingerb437e282010-11-04 01:04:27 +00001713 starthere += lenhere;
1714 skip = 0;
1715 }
1716 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001717 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001718 return ret;
1719}
1720
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001721/*
1722 * Function to process processing units accumulated in the action descriptor.
1723 *
1724 * @flash pointer to the flash context to operate on
1725 * @do_something helper function which can erase and program a section of the
1726 * flash chip. It receives the flash context, offset and length
1727 * of the area to erase/program, before and after contents (to
1728 * decide what exactly needs to be erased and or programmed)
1729 * and a pointer to the erase function which can operate on the
1730 * proper granularity.
1731 * @descriptor action descriptor including pointers to before and after
1732 * contents and an array of processing actions to take.
1733 *
1734 * Returns zero on success or an error code.
1735 */
1736static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001737 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001738 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001739 unsigned int len,
1740 uint8_t *param1,
1741 uint8_t *param2,
1742 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001743 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001744 unsigned int addr,
1745 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001746 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00001747{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001748 struct processing_unit *pu;
1749 int rc = 0;
1750 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00001751
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001752 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1753 unsigned base = pu->offset;
1754 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07001755
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001756 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07001757
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001758 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00001759 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001760 else
1761 print_comma = 1;
1762
1763 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1764
1765 rc = do_something(flash, base,
1766 pu->block_size,
1767 descriptor->oldcontents,
1768 descriptor->newcontents,
1769 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
1770
David Hendricks1ed1d352011-11-23 17:54:37 -08001771 if (rc) {
1772 if (ignore_error(rc))
1773 rc = 0;
1774 else
1775 return rc;
hailfingerb437e282010-11-04 01:04:27 +00001776 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001777 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00001778 }
1779 }
hailfingerb437e282010-11-04 01:04:27 +00001780 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08001781 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00001782}
1783
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001784static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00001785{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001786 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00001787
1788 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1789 if (log)
1790 msg_cdbg("not defined. ");
1791 return 1;
1792 }
1793 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1794 if (log)
1795 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00001796 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00001797 return 1;
1798 }
1799 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1800 if (log)
1801 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00001802 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00001803 return 1;
1804 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10001805 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00001806 return 0;
1807}
1808
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001809int erase_and_write_flash(struct flashctx *flash,
1810 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00001811{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001812 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00001813
hailfingercf848f12010-12-05 15:14:44 +00001814 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00001815
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001816 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00001817
hailfinger7df21362009-09-05 02:30:58 +00001818 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00001819 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00001820 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07001821 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00001822 }
1823 return ret;
hailfingerd219a232009-01-28 00:27:54 +00001824}
1825
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001826static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00001827{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001828 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
1829#if CONFIG_INTERNAL == 1
1830 if (programmer == PROGRAMMER_INTERNAL)
1831 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
1832 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1833 "mail flashrom@flashrom.org, thanks!\n"
1834 "-------------------------------------------------------------------------------\n"
1835 "You may now reboot or simply leave the machine running.\n");
1836 else
1837#endif
1838 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
1839 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
1840 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1841 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00001842}
1843
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001844static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00001845{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001846 msg_gerr("Your flash chip is in an unknown state.\n");
1847#if CONFIG_INTERNAL == 1
1848 if (programmer == PROGRAMMER_INTERNAL)
1849 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
1850 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
1851 "-------------------------------------------------------------------------------\n"
1852 "DO NOT REBOOT OR POWEROFF!\n");
1853 else
1854#endif
1855 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1856 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00001857}
1858
hailfingerf79d1712010-10-06 23:48:34 +00001859void list_programmers_linebreak(int startcol, int cols, int paren)
1860{
1861 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00001862 int pnamelen;
1863 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00001864 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00001865 int i;
hailfingerf79d1712010-10-06 23:48:34 +00001866
1867 for (p = 0; p < PROGRAMMER_INVALID; p++) {
1868 pname = programmer_table[p].name;
1869 pnamelen = strlen(pname);
1870 if (remaining - pnamelen - 2 < 0) {
1871 if (firstline)
1872 firstline = 0;
1873 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001874 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00001875 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001876 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00001877 remaining = cols - startcol;
1878 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001879 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00001880 remaining--;
1881 }
1882 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001883 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00001884 remaining--;
1885 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001886 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00001887 remaining -= pnamelen;
1888 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001889 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00001890 remaining--;
1891 } else {
1892 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001893 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00001894 }
1895 }
1896}
1897
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001898static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00001899{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10001900#if IS_WINDOWS
1901 SYSTEM_INFO si;
1902 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00001903
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10001904 memset(&si, 0, sizeof(SYSTEM_INFO));
1905 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
1906 msg_ginfo(" on Windows");
1907 /* Tell Windows which version of the structure we want. */
1908 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
1909 if (GetVersionEx((OSVERSIONINFO*) &osvi))
1910 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
1911 else
1912 msg_ginfo(" unknown version");
1913 GetSystemInfo(&si);
1914 switch (si.wProcessorArchitecture) {
1915 case PROCESSOR_ARCHITECTURE_AMD64:
1916 msg_ginfo(" (x86_64)");
1917 break;
1918 case PROCESSOR_ARCHITECTURE_INTEL:
1919 msg_ginfo(" (x86)");
1920 break;
1921 default:
1922 msg_ginfo(" (unknown arch)");
1923 break;
1924 }
1925#elif HAVE_UTSNAME == 1
1926 struct utsname osinfo;
1927
1928 uname(&osinfo);
1929 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00001930 osinfo.machine);
1931#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10001932 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00001933#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001934}
1935
1936void print_buildinfo(void)
1937{
1938 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00001939#if NEED_PCI == 1
1940#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001941 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00001942#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001943 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00001944#endif
1945#endif
1946#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001947 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00001948#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001949 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00001950#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001951 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00001952#endif
hailfinger3b471632010-03-27 16:36:40 +00001953#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001954 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00001955#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001956 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00001957#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001958 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00001959#endif
1960#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001961 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00001962#endif
1963#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001964 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00001965#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001966 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00001967#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001968 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00001969}
1970
uwefdeca092008-01-21 15:24:22 +00001971void print_version(void)
1972{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001973 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00001974 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001975 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00001976}
1977
hailfinger74819ad2010-05-15 15:04:37 +00001978void print_banner(void)
1979{
1980 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001981 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00001982 msg_ginfo("\n");
1983}
1984
hailfingerc77acb52009-12-24 02:15:55 +00001985int selfcheck(void)
1986{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001987 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00001988 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001989
1990 /* Safety check. Instead of aborting after the first error, check
1991 * if more errors exist.
1992 */
hailfingerc77acb52009-12-24 02:15:55 +00001993 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00001994 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00001995 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00001996 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001997 /* It would be favorable if we could check for the correct layout (especially termination) of various
1998 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
1999 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2000 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2001 * 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 +10002002 * checks below. */
2003 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002004 msg_gerr("Flashchips table miscompilation!\n");
2005 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002006 } else {
2007 for (i = 0; i < flashchips_size - 1; i++) {
2008 const struct flashchip *chip = &flashchips[i];
2009 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2010 ret = 1;
2011 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2012 "Please report a bug at flashrom@flashrom.org\n", i,
2013 chip->name == NULL ? "unnamed" : chip->name);
2014 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002015 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002016 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002017 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002018 }
stefanct6d836ba2011-05-26 01:35:19 +00002019 }
stefanct6d836ba2011-05-26 01:35:19 +00002020
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002021 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002022 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002023}
2024
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002025
hailfinger771fc182010-10-15 00:01:14 +00002026/* FIXME: This function signature needs to be improved once doit() has a better
2027 * function signature.
2028 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002029static int chip_safety_check(const struct flashctx *flash, int force,
2030 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002031{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002032 const struct flashchip *chip = flash->chip;
2033
hailfinger771fc182010-10-15 00:01:14 +00002034 if (!programmer_may_write && (write_it || erase_it)) {
2035 msg_perr("Write/erase is not working yet on your programmer in "
2036 "its current configuration.\n");
2037 /* --force is the wrong approach, but it's the best we can do
2038 * until the generic programmer parameter parser is merged.
2039 */
2040 if (!force)
2041 return 1;
2042 msg_cerr("Continuing anyway.\n");
2043 }
2044
2045 if (read_it || erase_it || write_it || verify_it) {
2046 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002047 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002048 msg_cerr("Read is not working on this chip. ");
2049 if (!force)
2050 return 1;
2051 msg_cerr("Continuing anyway.\n");
2052 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002053 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002054 msg_cerr("flashrom has no read function for this "
2055 "flash chip.\n");
2056 return 1;
2057 }
2058 }
2059 if (erase_it || write_it) {
2060 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002061 if (chip->tested.erase == NA) {
2062 msg_cerr("Erase is not possible on this chip.\n");
2063 return 1;
2064 }
2065 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002066 msg_cerr("Erase is not working on this chip. ");
2067 if (!force)
2068 return 1;
2069 msg_cerr("Continuing anyway.\n");
2070 }
stefancte1c5acf2011-07-04 07:27:17 +00002071 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002072 msg_cerr("flashrom has no erase function for this "
2073 "flash chip.\n");
2074 return 1;
2075 }
hailfinger771fc182010-10-15 00:01:14 +00002076 }
2077 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002078 if (chip->tested.write == NA) {
2079 msg_cerr("Write is not possible on this chip.\n");
2080 return 1;
2081 }
2082 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002083 msg_cerr("Write is not working on this chip. ");
2084 if (!force)
2085 return 1;
2086 msg_cerr("Continuing anyway.\n");
2087 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002088 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002089 msg_cerr("flashrom has no write function for this "
2090 "flash chip.\n");
2091 return 1;
2092 }
2093 }
2094 return 0;
2095}
2096
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002097int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002098 const bool read_it, const bool write_it,
2099 const bool erase_it, const bool verify_it)
2100{
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002101 if (chip_safety_check(flash, g_force /*flash->flags.force*/, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002102 msg_cerr("Aborting.\n");
2103 return 1;
2104 }
2105
2106 if (normalize_romentries(flash)) {
2107 msg_cerr("Requested regions can not be handled. Aborting.\n");
2108 return 1;
2109 }
2110
2111 /* Given the existence of read locks, we want to unlock for read,
2112 erase and write. */
2113 if (flash->chip->unlock)
2114 flash->chip->unlock(flash);
2115
2116 flash->address_high_byte = -1;
2117 flash->in_4ba_mode = false;
2118
2119 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2120 if ((flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN) && flash->chip->set_4ba) {
2121 if (flash->chip->set_4ba(flash)) {
2122 msg_cerr("Enabling/disabling 4-byte addressing mode failed!\n");
2123 return 1;
2124 }
2125 }
2126
2127 return 0;
2128}
2129
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002130/*
2131 * Function to erase entire flash chip.
2132 *
2133 * @flashctx pointer to the flash context to use
2134 * @oldcontents pointer to the buffer including current chip contents, to
2135 * decide which areas do in fact need to be erased
2136 * @size the size of the flash chip, in bytes.
2137 *
2138 * Returns zero on success or an error code.
2139 */
2140static int erase_chip(struct flashctx *flash, void *oldcontents,
2141 void *newcontents, size_t size)
2142{
2143 /*
2144 * To make sure that the chip is fully erased, let's cheat and create
2145 * a descriptor where the new contents are all erased.
2146 */
2147 struct action_descriptor *fake_descriptor;
2148 int ret = 0;
2149
2150 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2151 newcontents, 1);
2152 /* FIXME: Do we really want the scary warning if erase failed? After
2153 * all, after erase the chip is either blank or partially blank or it
2154 * has the old contents. A blank chip won't boot, so if the user
2155 * wanted erase and reboots afterwards, the user knows very well that
2156 * booting won't work.
2157 */
2158 if (erase_and_write_flash(flash, fake_descriptor)) {
2159 emergency_help_message();
2160 ret = 1;
2161 }
2162
2163 free(fake_descriptor);
2164
2165 return ret;
2166}
2167
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002168static int read_dest_content(struct flashctx *flash, int verify_it,
2169 uint8_t *dest, unsigned long size)
2170{
2171 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2172 && get_num_include_args()) {
2173 /*
2174 * If no full verification is required and not
2175 * the entire chip is about to be programmed,
2176 * read only the areas which might change.
2177 */
2178 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2179 return 1;
2180 } else {
2181 if (read_flash(flash, dest, 0, size))
2182 return 1;
2183 }
2184 return 0;
2185}
2186
hailfingerc77acb52009-12-24 02:15:55 +00002187/* This function signature is horrible. We need to design a better interface,
2188 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002189 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002190 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002191int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002192 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002193 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002194{
hailfinger4c47e9d2010-10-19 22:06:20 +00002195 uint8_t *oldcontents;
2196 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002197 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002198 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002199 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002200
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002201 g_force = force; // HACK
2202 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002203 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002204 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002205
Simon Glass9ad06c12013-07-03 22:08:17 +09002206 if (extract_it) {
2207 ret = extract_regions(flash);
2208 goto out_nofree;
2209 }
2210
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002211 /* mark entries included using -i argument as "included" if they are
2212 found in the master rom_entries list */
2213 if (process_include_args() < 0) {
2214 ret = 1;
2215 goto out_nofree;
2216 }
2217
hailfinger771fc182010-10-15 00:01:14 +00002218 if (read_it) {
2219 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002220 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002221 }
hailfingerb437e282010-11-04 01:04:27 +00002222
stefanctd611e8f2011-07-12 22:35:21 +00002223 oldcontents = malloc(size);
2224 if (!oldcontents) {
2225 msg_gerr("Out of memory!\n");
2226 exit(1);
2227 }
Simon Glass4c214132013-07-16 10:09:28 -06002228 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002229 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002230 newcontents = malloc(size);
2231 if (!newcontents) {
2232 msg_gerr("Out of memory!\n");
2233 exit(1);
2234 }
Simon Glass4c214132013-07-16 10:09:28 -06002235 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002236 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002237 /* Side effect of the assumptions above: Default write action is erase
2238 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002239 * oldcontents being completely unerased means we have to erase
2240 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002241 */
2242
hailfingerd217d122010-10-08 18:52:29 +00002243 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002244 /*
2245 * Note: This must be done before any files specified by -i
2246 * arguments are processed merged into the newcontents since
2247 * -i files take priority. See http://crbug.com/263495.
2248 */
2249 if (filename) {
2250 if (read_buf_from_file(newcontents, size, filename)) {
2251 ret = 1;
2252 goto out;
2253 }
2254 } else {
2255 /* Content will be read from -i args, so they must
2256 * not overlap. */
2257 if (included_regions_overlap()) {
2258 msg_gerr("Error: Included regions must "
2259 "not overlap.\n");
2260 ret = 1;
2261 goto out;
2262 }
stepan1da96c02006-11-21 23:48:51 +00002263 }
ollie5672ac62004-03-17 22:22:08 +00002264 }
2265
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002266 if (do_diff) {
2267 /*
2268 * Obtain a reference image so that we can check whether
2269 * regions need to be erased and to give better diagnostics in
2270 * case write fails. If --fast-verify is used then only the
2271 * regions which are included using -i will be read.
2272 */
2273 if (diff_file) {
2274 msg_cdbg("Reading old contents from file... ");
2275 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002276 ret = 1;
2277 msg_cdbg("FAILED.\n");
2278 goto out;
2279 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002280 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002281 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002282 ret = read_dest_content(flash, verify_it,
2283 oldcontents, size);
2284 if (ret) {
2285 msg_cdbg("FAILED.\n");
2286 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002287 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002288 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002289 msg_cdbg("done.\n");
2290 } else if (!erase_it) {
2291 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002292 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002293 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002294
David Hendricksdf29a832013-06-28 14:33:51 -07002295 /*
2296 * Note: This must be done after reading the file specified for the
2297 * -w/-v argument, if any, so that files specified using -i end up
2298 * in the "newcontents" buffer before being written.
2299 * See http://crbug.com/263495.
2300 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002301 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002302 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002303 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002304 goto out;
2305 }
uwef6641642007-05-09 10:17:44 +00002306
David Hendricksa7e114b2016-02-26 18:49:15 -08002307 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002308 erase_chip(flash, oldcontents, newcontents, size);
2309 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002310 }
2311
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002312 descriptor = prepare_action_descriptor(flash, oldcontents,
2313 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002314 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002315 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002316 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002317 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002318 goto out;
2319 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002320
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002321 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002322 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2323 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002324 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002325 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002326 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002327 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002328 ret = 1;
2329 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002330 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002331 msg_cerr("Apparently at least some data has changed.\n");
2332 } else
2333 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002334 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002335 ret = 1;
2336 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002337 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002338
David Hendricksac1d25c2016-08-09 17:00:58 -07002339 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002340 if (ret < 0) {
2341 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002342 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002343 emergency_help_message();
2344 ret = 1;
2345 goto out;
2346 } else if (ret > 0) {
2347 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002348 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002349 ret = read_dest_content(flash, verify_it,
2350 oldcontents, size);
2351 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002352 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002353 goto out;
2354 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002355
2356 /* Get a new descriptor. */
2357 free(descriptor);
2358 descriptor = prepare_action_descriptor(flash,
2359 oldcontents,
2360 newcontents,
2361 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002362 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002363 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002364 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002365 emergency_help_message();
2366 ret = 1;
2367 goto out;
2368 }
2369 ret = 0;
2370 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002371
David Hendricksac1d25c2016-08-09 17:00:58 -07002372 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002373 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002374 emergency_help_message();
2375 ret = 1;
2376 goto out;
2377 }
stuge8ce3a3c2008-04-28 14:47:30 +00002378 }
ollie6a600992005-11-26 21:55:36 +00002379
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002380 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002381 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002382 if ((write_it || erase_it) && !content_has_changed) {
2383 msg_gdbg("Nothing was erased or written, skipping "
2384 "verification\n");
2385 } else {
2386 /* Work around chips which need some time to calm down. */
2387 if (write_it && verify_it != VERIFY_PARTIAL)
2388 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002389
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002390 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002391
David Hendricks9ba79fb2015-04-03 12:06:16 -07002392 /* If we tried to write, and verification now fails, we
2393 * might have an emergency situation.
2394 */
2395 if (ret && write_it)
2396 emergency_help_message();
2397 }
hailfinger0459e1c2009-08-19 13:55:34 +00002398 }
ollie6a600992005-11-26 21:55:36 +00002399
hailfinger90fcf9b2010-11-05 14:51:59 +00002400out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002401 if (descriptor)
2402 free(descriptor);
2403
hailfinger90fcf9b2010-11-05 14:51:59 +00002404 free(oldcontents);
2405 free(newcontents);
2406out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002407 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002408 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002409 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002410 * tree. This is because some operations, such as write protection,
2411 * requires programmer_shutdown() but does not call doit().
2412 */
2413// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002414 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002415}
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002416
2417void finalize_flash_access(struct flashctx *const flash)
2418{
2419 unmap_flash(flash);
2420}