blob: ad74e9848218b051b187d21e9d97b54c39f47821 [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();
hailfinger1ef766d2010-07-06 09:55:48 +0000475 return ret;
uweabe92a52009-05-16 22:36:00 +0000476}
477
David Hendricksbf36f092010-11-02 23:39:29 -0700478int chip_restore()
479{
480 int rc = 0;
481
482 while (chip_restore_fn_count > 0) {
483 int i = --chip_restore_fn_count;
484 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
485 chip_restore_fn[i].status);
486 }
487
488 return rc;
489}
490
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000491/** Calls registered shutdown functions and resets internal programmer-related variables.
492 * Calling it is safe even without previous initialization, but further interactions with programmer support
493 * require a call to programmer_init() (afterwards).
494 *
495 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700496int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000497{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000498 int ret = 0;
499
hailfinger1ff33dc2010-07-03 11:02:10 +0000500 /* Registering shutdown functions is no longer allowed. */
501 may_register_shutdown = 0;
502 while (shutdown_fn_count > 0) {
503 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700504 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000505 }
dhendrix0ffc2eb2011-06-14 01:35:36 +0000506 return ret;
uweabe92a52009-05-16 22:36:00 +0000507}
508
509void *programmer_map_flash_region(const char *descr, unsigned long phys_addr,
510 size_t len)
511{
512 return programmer_table[programmer].map_flash_region(descr,
513 phys_addr, len);
514}
515
516void programmer_unmap_flash_region(void *virt_addr, size_t len)
517{
518 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000519 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000520}
521
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700522void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000523{
Craig Hesling65eb8812019-08-01 09:33:56 -0700524 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000525}
526
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700527void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000528{
Craig Hesling65eb8812019-08-01 09:33:56 -0700529 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000530}
531
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700532void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000533{
Craig Hesling65eb8812019-08-01 09:33:56 -0700534 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000535}
536
Stuart langleyc98e43f2020-03-26 20:27:36 +1100537void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000538{
Craig Hesling65eb8812019-08-01 09:33:56 -0700539 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000540}
541
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700542uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000543{
Craig Hesling65eb8812019-08-01 09:33:56 -0700544 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000545}
546
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700547uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000548{
Craig Hesling65eb8812019-08-01 09:33:56 -0700549 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000550}
551
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700552uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000553{
Craig Hesling65eb8812019-08-01 09:33:56 -0700554 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000555}
556
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700557void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000558{
Craig Hesling65eb8812019-08-01 09:33:56 -0700559 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000560}
561
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000562void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000563{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000564 if (usecs > 0)
565 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000566}
567
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700568int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start, int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000569{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700570 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000571
hailfinger23060112009-05-08 12:49:03 +0000572 return 0;
573}
574
David Hendricksda18f692016-10-21 17:49:49 -0700575/* This is a somewhat hacked function similar in some ways to strtok(). It will
576 * look for needle with a subsequent '=' in haystack, return a copy of needle.
hailfinger6e5a52a2009-11-24 18:27:10 +0000577 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000578char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000579{
David Hendricksda18f692016-10-21 17:49:49 -0700580 char *param_pos, *opt_pos;
hailfinger1ef766d2010-07-06 09:55:48 +0000581 char *opt = NULL;
582 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000583 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000584
hailfingerf4aaccc2010-04-28 15:22:14 +0000585 needlelen = strlen(needle);
586 if (!needlelen) {
587 msg_gerr("%s: empty needle! Please report a bug at "
588 "flashrom@flashrom.org\n", __func__);
589 return NULL;
590 }
591 /* No programmer parameters given. */
592 if (*haystack == NULL)
593 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000594 param_pos = strstr(*haystack, needle);
595 do {
596 if (!param_pos)
597 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000598 /* Needle followed by '='? */
599 if (param_pos[needlelen] == '=') {
Simon Glass8dc82732013-07-16 10:13:51 -0600600
hailfinger1ef766d2010-07-06 09:55:48 +0000601 /* Beginning of the string? */
602 if (param_pos == *haystack)
603 break;
604 /* After a delimiter? */
605 if (strchr(delim, *(param_pos - 1)))
606 break;
607 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000608 /* Continue searching. */
609 param_pos++;
610 param_pos = strstr(param_pos, needle);
611 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000612
hailfinger6e5a52a2009-11-24 18:27:10 +0000613 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000614 /* Get the string after needle and '='. */
615 opt_pos = param_pos + needlelen + 1;
616 optlen = strcspn(opt_pos, delim);
617 /* Return an empty string if the parameter was empty. */
618 opt = malloc(optlen + 1);
619 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000620 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000621 exit(1);
622 }
hailfinger1ef766d2010-07-06 09:55:48 +0000623 strncpy(opt, opt_pos, optlen);
624 opt[optlen] = '\0';
hailfinger6e5a52a2009-11-24 18:27:10 +0000625 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000626
hailfinger1ef766d2010-07-06 09:55:48 +0000627 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000628}
629
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000630char *extract_programmer_param(const char *const param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000631{
632 return extract_param(&programmer_param, param_name, ",");
633}
634
stefancte1c5acf2011-07-04 07:27:17 +0000635/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700636static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000637{
638 unsigned int usable_erasefunctions = 0;
639 int k;
640 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
641 if (!check_block_eraser(flash, k, 0))
642 usable_erasefunctions++;
643 }
644 return usable_erasefunctions;
645}
646
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000647static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700648{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000649 int ret = 0, failcount = 0;
650 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700651 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000652 if (wantbuf[i] != havebuf[i]) {
653 /* Only print the first failure. */
654 if (!failcount++)
655 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
656 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700657 }
658 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000659 if (failcount) {
660 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
661 start, start + len - 1, failcount);
662 ret = -1;
663 }
664 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700665}
666
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000667/* start is an offset to the base address of the flash chip */
668static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
669{
670 int ret;
671 uint8_t *cmpbuf = malloc(len);
672 const uint8_t erased_value = ERASED_VALUE(flash);
673
674 if (!cmpbuf) {
675 msg_gerr("Could not allocate memory!\n");
676 exit(1);
677 }
678 memset(cmpbuf, erased_value, len);
679 ret = verify_range(flash, cmpbuf, start, len);
680 free(cmpbuf);
681 return ret;
682}
683
uwee15beb92010-08-08 17:01:18 +0000684/*
hailfinger7af3d192009-11-25 17:05:52 +0000685 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000686 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000687 * @start offset to the base address of the flash chip
688 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000689 * @return 0 for success, -1 for failure
690 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000691int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000692{
hailfinger7af83692009-06-15 17:23:36 +0000693 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000694 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000695
Patrick Georgif3fa2992017-02-02 16:24:44 +0100696 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000697 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000698 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000699 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000700
701 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000702 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000703 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000704 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000705 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000706 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000707
Patrick Georgif3fa2992017-02-02 16:24:44 +0100708 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000709 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000710 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100711 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000712 ret = -1;
713 goto out_free;
714 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700715 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700716 if (programmer_table[programmer].paranoid) {
717 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800718
Simon Glass4e305f42015-01-08 06:29:04 -0700719 /* limit chunksize in order to catch errors early */
720 for (i = 0, chunksize = 0; i < len; i += chunksize) {
721 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800722
Patrick Georgif3fa2992017-02-02 16:24:44 +0100723 chunksize = min(flash->chip->page_size, len - i);
724 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700725 if (tmp) {
726 ret = tmp;
727 if (ignore_error(tmp))
728 continue;
729 else
730 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800731 }
Simon Glass4e305f42015-01-08 06:29:04 -0700732
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700733 /*
734 * Check write access permission and do not compare chunks
735 * where flashrom does not have write access to the region.
736 */
737 if (flash->chip->check_access) {
738 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
739 if (tmp && ignore_error(tmp))
740 continue;
741 }
742
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000743 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700744 if (failcount)
745 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800746 }
Simon Glass4e305f42015-01-08 06:29:04 -0700747 } else {
748 int tmp;
749
750 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +0100751 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -0700752 if (tmp && !ignore_error(tmp)) {
753 ret = tmp;
754 goto out_free;
755 }
756
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000757 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +0000758 }
759
hailfinger5be6c0f2009-07-23 01:42:56 +0000760 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +0000761 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +0000762 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +0000763 ret = -1;
764 }
hailfinger7af83692009-06-15 17:23:36 +0000765
766out_free:
767 free(readbuf);
768 return ret;
769}
770
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100771/* Helper function for need_erase() that focuses on granularities of gran bytes. */
772static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000773 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100774{
775 unsigned int i, j, limit;
776 for (j = 0; j < len / gran; j++) {
777 limit = min (gran, len - j * gran);
778 /* Are 'have' and 'want' identical? */
779 if (!memcmp(have + j * gran, want + j * gran, limit))
780 continue;
781 /* have needs to be in erased state. */
782 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000783 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100784 return 1;
785 }
786 return 0;
787}
788
uwee15beb92010-08-08 17:01:18 +0000789/*
hailfingerb247c7a2010-03-08 00:42:32 +0000790 * Check if the buffer @have can be programmed to the content of @want without
791 * erasing. This is only possible if all chunks of size @gran are either kept
792 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +0000793 *
hailfingerb437e282010-11-04 01:04:27 +0000794 * Warning: This function assumes that @have and @want point to naturally
795 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +0000796 *
797 * @have buffer with current content
798 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +0000799 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +0000800 * @gran write granularity (enum, not count)
801 * @return 0 if no erase is needed, 1 otherwise
802 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000803int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
804 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +0000805{
hailfingerb91c08c2011-08-15 19:54:20 +0000806 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100807 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -0700808
hailfingerb247c7a2010-03-08 00:42:32 +0000809 switch (gran) {
810 case write_gran_1bit:
811 for (i = 0; i < len; i++)
812 if ((have[i] & want[i]) != want[i]) {
813 result = 1;
814 break;
815 }
816 break;
817 case write_gran_1byte:
818 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000819 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +0000820 result = 1;
821 break;
822 }
823 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100824 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000825 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100826 break;
hailfingerb247c7a2010-03-08 00:42:32 +0000827 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000828 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100829 break;
830 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000831 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100832 break;
833 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000834 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100835 break;
836 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000837 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100838 break;
839 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000840 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100841 break;
842 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +1000843 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100844 break;
845 case write_gran_1byte_implicit_erase:
846 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
847 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +0000848 break;
hailfingerb437e282010-11-04 01:04:27 +0000849 default:
850 msg_cerr("%s: Unsupported granularity! Please report a bug at "
851 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +0000852 }
853 return result;
854}
855
hailfingerb437e282010-11-04 01:04:27 +0000856/**
857 * Check if the buffer @have needs to be programmed to get the content of @want.
858 * If yes, return 1 and fill in first_start with the start address of the
859 * write operation and first_len with the length of the first to-be-written
860 * chunk. If not, return 0 and leave first_start and first_len undefined.
861 *
862 * Warning: This function assumes that @have and @want point to naturally
863 * aligned regions.
864 *
865 * @have buffer with current content
866 * @want buffer with desired content
867 * @len length of the checked area
868 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +0000869 * @first_start offset of the first byte which needs to be written (passed in
870 * value is increased by the offset of the first needed write
871 * relative to have/want or unchanged if no write is needed)
872 * @return length of the first contiguous area which needs to be written
873 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +0000874 *
875 * FIXME: This function needs a parameter which tells it about coalescing
876 * in relation to the max write length of the programmer and the max write
877 * length of the chip.
878 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000879static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +0000880 unsigned int *first_start,
881 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +0000882{
stefanctc5eb8a92011-11-23 09:13:48 +0000883 int need_write = 0;
884 unsigned int rel_start = 0, first_len = 0;
885 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +0000886
hailfingerb437e282010-11-04 01:04:27 +0000887 switch (gran) {
888 case write_gran_1bit:
889 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100890 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +0000891 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +0000892 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100893 case write_gran_128bytes:
894 stride = 128;
895 break;
hailfingerb437e282010-11-04 01:04:27 +0000896 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +0000897 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +0000898 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +1100899 case write_gran_264bytes:
900 stride = 264;
901 break;
902 case write_gran_512bytes:
903 stride = 512;
904 break;
905 case write_gran_528bytes:
906 stride = 528;
907 break;
908 case write_gran_1024bytes:
909 stride = 1024;
910 break;
911 case write_gran_1056bytes:
912 stride = 1056;
913 break;
hailfingerb437e282010-11-04 01:04:27 +0000914 default:
915 msg_cerr("%s: Unsupported granularity! Please report a bug at "
916 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +0000917 /* Claim that no write was needed. A write with unknown
918 * granularity is too dangerous to try.
919 */
920 return 0;
hailfingerb437e282010-11-04 01:04:27 +0000921 }
hailfinger90fcf9b2010-11-05 14:51:59 +0000922 for (i = 0; i < len / stride; i++) {
923 limit = min(stride, len - i * stride);
924 /* Are 'have' and 'want' identical? */
925 if (memcmp(have + i * stride, want + i * stride, limit)) {
926 if (!need_write) {
927 /* First location where have and want differ. */
928 need_write = 1;
929 rel_start = i * stride;
930 }
931 } else {
932 if (need_write) {
933 /* First location where have and want
934 * do not differ anymore.
935 */
hailfinger90fcf9b2010-11-05 14:51:59 +0000936 break;
937 }
938 }
939 }
hailfingerffb7f382010-12-06 13:05:44 +0000940 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +0000941 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +0000942 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +0000943 return first_len;
hailfingerb437e282010-11-04 01:04:27 +0000944}
945
hailfinger0c515352009-11-23 12:55:31 +0000946/* This function generates various test patterns useful for testing controller
947 * and chip communication as well as chip behaviour.
948 *
949 * If a byte can be written multiple times, each time keeping 0-bits at 0
950 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
951 * is essentially an AND operation. That's also the reason why this function
952 * provides the result of AND between various patterns.
953 *
954 * Below is a list of patterns (and their block length).
955 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
956 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
957 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
958 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
959 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
960 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
961 * Pattern 6 is 00 (1 Byte)
962 * Pattern 7 is ff (1 Byte)
963 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
964 * byte block.
965 *
966 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
967 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
968 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
969 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
970 * Pattern 12 is 00 (1 Byte)
971 * Pattern 13 is ff (1 Byte)
972 * Patterns 8-13 have no block number.
973 *
974 * Patterns 0-3 are created to detect and efficiently diagnose communication
975 * slips like missed bits or bytes and their repetitive nature gives good visual
976 * cues to the person inspecting the results. In addition, the following holds:
977 * AND Pattern 0/1 == Pattern 4
978 * AND Pattern 2/3 == Pattern 5
979 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
980 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
981 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
982 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
983 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
984 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
985 * Besides that, they provide for bit testing of the last two bytes of every
986 * 256 byte block which contains the block number for patterns 0-6.
987 * Patterns 10-11 are special purpose for detecting subblock aliasing with
988 * block sizes >256 bytes (some Dataflash chips etc.)
989 * AND Pattern 8/9 == Pattern 12
990 * AND Pattern 10/11 == Pattern 12
991 * Pattern 13 is the completely erased state.
992 * None of the patterns can detect aliasing at boundaries which are a multiple
993 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
994 */
995int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
996{
997 int i;
998
999 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001000 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001001 return 1;
1002 }
1003
1004 switch (variant) {
1005 case 0:
1006 for (i = 0; i < size; i++)
1007 buf[i] = (i & 0xf) << 4 | 0x5;
1008 break;
1009 case 1:
1010 for (i = 0; i < size; i++)
1011 buf[i] = (i & 0xf) << 4 | 0xa;
1012 break;
1013 case 2:
1014 for (i = 0; i < size; i++)
1015 buf[i] = 0x50 | (i & 0xf);
1016 break;
1017 case 3:
1018 for (i = 0; i < size; i++)
1019 buf[i] = 0xa0 | (i & 0xf);
1020 break;
1021 case 4:
1022 for (i = 0; i < size; i++)
1023 buf[i] = (i & 0xf) << 4;
1024 break;
1025 case 5:
1026 for (i = 0; i < size; i++)
1027 buf[i] = i & 0xf;
1028 break;
1029 case 6:
1030 memset(buf, 0x00, size);
1031 break;
1032 case 7:
1033 memset(buf, 0xff, size);
1034 break;
1035 case 8:
1036 for (i = 0; i < size; i++)
1037 buf[i] = i & 0xff;
1038 break;
1039 case 9:
1040 for (i = 0; i < size; i++)
1041 buf[i] = ~(i & 0xff);
1042 break;
1043 case 10:
1044 for (i = 0; i < size % 2; i++) {
1045 buf[i * 2] = (i >> 8) & 0xff;
1046 buf[i * 2 + 1] = i & 0xff;
1047 }
1048 if (size & 0x1)
1049 buf[i * 2] = (i >> 8) & 0xff;
1050 break;
1051 case 11:
1052 for (i = 0; i < size % 2; i++) {
1053 buf[i * 2] = ~((i >> 8) & 0xff);
1054 buf[i * 2 + 1] = ~(i & 0xff);
1055 }
1056 if (size & 0x1)
1057 buf[i * 2] = ~((i >> 8) & 0xff);
1058 break;
1059 case 12:
1060 memset(buf, 0x00, size);
1061 break;
1062 case 13:
1063 memset(buf, 0xff, size);
1064 break;
1065 }
1066
1067 if ((variant >= 0) && (variant <= 7)) {
1068 /* Write block number in the last two bytes of each 256-byte
1069 * block, big endian for easier reading of the hexdump.
1070 * Note that this wraps around for chips larger than 2^24 bytes
1071 * (16 MB).
1072 */
1073 for (i = 0; i < size / 256; i++) {
1074 buf[i * 256 + 254] = (i >> 8) & 0xff;
1075 buf[i * 256 + 255] = i & 0xff;
1076 }
1077 }
1078
1079 return 0;
1080}
1081
hailfingeraec9c962009-10-31 01:53:09 +00001082int check_max_decode(enum chipbustype buses, uint32_t size)
1083{
1084 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001085
1086 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001087 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001088 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001089 "size %u kB of chipset/board/programmer "
1090 "for %s interface, "
1091 "probe/read/erase/write may fail. ", size / 1024,
1092 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001093 }
hailfingere1e41ea2011-07-27 07:13:06 +00001094 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001095 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001096 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001097 "size %u kB of chipset/board/programmer "
1098 "for %s interface, "
1099 "probe/read/erase/write may fail. ", size / 1024,
1100 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001101 }
hailfingere1e41ea2011-07-27 07:13:06 +00001102 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001103 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001104 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001105 "size %u kB of chipset/board/programmer "
1106 "for %s interface, "
1107 "probe/read/erase/write may fail. ", size / 1024,
1108 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001109 }
hailfingere1e41ea2011-07-27 07:13:06 +00001110 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001111 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001112 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001113 "size %u kB of chipset/board/programmer "
1114 "for %s interface, "
1115 "probe/read/erase/write may fail. ", size / 1024,
1116 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001117 }
1118 if (!limitexceeded)
1119 return 0;
1120 /* Sometimes chip and programmer have more than one bus in common,
1121 * and the limit is not exceeded on all buses. Tell the user.
1122 */
1123 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001124 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001125 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001126 "interface which can support a chip of this size. "
1127 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001128 return 1;
1129}
1130
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001131void unmap_flash(struct flashctx *flash)
1132{
1133 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1134 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1135 flash->physical_registers = 0;
1136 flash->virtual_registers = (chipaddr)ERROR_PTR;
1137 }
1138
1139 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1140 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1141 flash->physical_memory = 0;
1142 flash->virtual_memory = (chipaddr)ERROR_PTR;
1143 }
1144}
1145
1146int map_flash(struct flashctx *flash)
1147{
1148 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1149 flash->virtual_memory = (chipaddr)ERROR_PTR;
1150 flash->virtual_registers = (chipaddr)ERROR_PTR;
1151
1152 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1153 * These are used for various probing-related hacks that would not map successfully anyway and should be
1154 * removed ASAP. */
1155 if (flash->chip->total_size == 0)
1156 return 0;
1157
1158 const chipsize_t size = flash->chip->total_size * 1024;
1159 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1160 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1161 if (addr == ERROR_PTR) {
1162 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1163 flash->chip->name, PRIxPTR_WIDTH, base);
1164 return 1;
1165 }
1166 flash->physical_memory = base;
1167 flash->virtual_memory = (chipaddr)addr;
1168
1169 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1170 * completely different on some chips and programmers, or not mappable at all.
1171 * Ignore these problems for now and always report success. */
1172 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1173 base = 0xffffffff - size - 0x400000 + 1;
1174 addr = programmer_map_flash_region("flash chip registers", base, size);
1175 if (addr == ERROR_PTR) {
1176 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1177 flash->chip->name, PRIxPTR_WIDTH, base);
1178 return 0;
1179 }
1180 flash->physical_registers = base;
1181 flash->virtual_registers = (chipaddr)addr;
1182 }
1183 return 0;
1184}
1185
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001186/*
1187 * Return a string corresponding to the bustype parameter.
1188 * Memory is obtained with malloc() and must be freed with free() by the caller.
1189 */
1190char *flashbuses_to_text(enum chipbustype bustype)
1191{
1192 char *ret = calloc(1, 1);
1193 /*
1194 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1195 * will cease to exist and should be eliminated here as well.
1196 */
1197 if (bustype == BUS_NONSPI) {
1198 ret = strcat_realloc(ret, "Non-SPI, ");
1199 } else {
1200 if (bustype & BUS_PARALLEL)
1201 ret = strcat_realloc(ret, "Parallel, ");
1202 if (bustype & BUS_LPC)
1203 ret = strcat_realloc(ret, "LPC, ");
1204 if (bustype & BUS_FWH)
1205 ret = strcat_realloc(ret, "FWH, ");
1206 if (bustype & BUS_SPI)
1207 ret = strcat_realloc(ret, "SPI, ");
1208 if (bustype & BUS_PROG)
1209 ret = strcat_realloc(ret, "Programmer-specific, ");
1210 if (bustype == BUS_NONE)
1211 ret = strcat_realloc(ret, "None, ");
1212 }
1213 /* Kill last comma. */
1214 ret[strlen(ret) - 2] = '\0';
1215 ret = realloc(ret, strlen(ret) + 1);
1216 return ret;
1217}
1218
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001219int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001220{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001221 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001222 uint32_t size;
1223 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001224 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001225
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301226 /* Based on the host controller interface that a platform
1227 * needs to use (hwseq or swseq),
1228 * set the flashchips list here.
1229 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001230 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301231 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001232 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301233 flash_list = flashchips_hwseq;
1234 break;
1235 default:
1236 flash_list = flashchips;
1237 break;
1238 }
1239
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001240 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1241 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001242 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001243 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001244 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001245 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001246 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001247 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001248 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001249 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001250 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001251 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001252 continue;
1253 }
stepan782fb172007-04-06 11:58:03 +00001254
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001255 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001256 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001257
hailfinger48ed3e22011-05-04 00:39:50 +00001258 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001259 flash->chip = calloc(1, sizeof(struct flashchip));
1260 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001261 msg_gerr("Out of memory!\n");
1262 exit(1);
1263 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001264 memcpy(flash->chip, chip, sizeof(struct flashchip));
1265 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001266
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001267 if (map_flash(flash) != 0)
1268 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001269
stugec1e55fe2008-07-02 17:15:47 +00001270 if (force)
1271 break;
stepanc98b80b2006-03-16 16:57:41 +00001272
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001273 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001274 goto notfound;
1275
hailfinger48ed3e22011-05-04 00:39:50 +00001276 /* If this is the first chip found, accept it.
1277 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001278 * a non-generic match. SFDP and CFI are generic matches.
1279 * startchip==0 means this call to probe_flash() is the first
1280 * one for this programmer interface (master) and thus no other chip has
1281 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001282 */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001283 if (startchip == 0 || flash->chip->model_id != GENERIC_DEVICE_ID)
stugec1e55fe2008-07-02 17:15:47 +00001284 break;
1285
stuge56300c32008-09-03 23:10:05 +00001286notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001287 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001288 free(flash->chip);
1289 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001290 }
uwebe4477b2007-08-23 16:08:21 +00001291
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001292 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001293 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001294
stepan3e7aeae2011-01-19 06:21:54 +00001295
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001296 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001297 msg_cdbg("%s %s flash chip \"%s\" (%d kB, %s) \n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001298 force ? "Assuming" : "Found", flash->chip->vendor,
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001299 flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001300 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001301#if CONFIG_INTERNAL == 1
1302 if (programmer_table[programmer].map_flash_region == physmap)
1303 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1304 PRIxPTR_WIDTH, flash->physical_memory);
1305 else
1306#endif
1307 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001308
hailfinger0f4c3952010-12-02 21:59:42 +00001309 /* Flash registers will not be mapped if the chip was forced. Lock info
1310 * may be stored in registers, so avoid lock info printing.
1311 */
1312 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001313 if (flash->chip->printlock)
1314 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001315
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001316 /* Get out of the way for later runs. */
1317 unmap_flash(flash);
1318
hailfinger48ed3e22011-05-04 00:39:50 +00001319 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001320 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001321}
1322
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001323static int verify_flash(struct flashctx *flash,
1324 struct action_descriptor *descriptor,
1325 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001326{
hailfingerb0f4d122009-06-24 08:20:45 +00001327 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001328 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001329 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001330
snelsone42c3802010-05-07 20:09:04 +00001331 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001332
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001333 if (verify_it == VERIFY_PARTIAL) {
1334 struct processing_unit *pu = descriptor->processing_units;
1335
1336 /* Verify only areas which were written. */
1337 while (pu->num_blocks) {
1338 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001339 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001340 if (ret)
1341 break;
1342 pu++;
1343 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001344 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001345 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001346 }
uwef6641642007-05-09 10:17:44 +00001347
David Hendricks1ed1d352011-11-23 17:54:37 -08001348 if (ret == ACCESS_DENIED) {
1349 msg_gdbg("Could not fully verify due to access error, ");
1350 if (access_denied_action == error_ignore) {
1351 msg_gdbg("ignoring\n");
1352 ret = 0;
1353 } else {
1354 msg_gdbg("aborting\n");
1355 }
1356 }
1357
hailfingerb0f4d122009-06-24 08:20:45 +00001358 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001359 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001360
hailfingerb0f4d122009-06-24 08:20:45 +00001361 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001362}
1363
uwe8d342eb2011-07-28 08:13:25 +00001364int read_buf_from_file(unsigned char *buf, unsigned long size,
1365 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001366{
1367 unsigned long numbytes;
1368 FILE *image;
1369 struct stat image_stat;
1370
Vincent Palatin7ab23932014-10-01 12:09:16 -07001371 if (!strncmp(filename, "-", sizeof("-")))
1372 image = fdopen(STDIN_FILENO, "rb");
1373 else
1374 image = fopen(filename, "rb");
1375 if (image == NULL) {
hailfinger771fc182010-10-15 00:01:14 +00001376 perror(filename);
1377 return 1;
1378 }
1379 if (fstat(fileno(image), &image_stat) != 0) {
1380 perror(filename);
1381 fclose(image);
1382 return 1;
1383 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001384 if ((image_stat.st_size != size) &&
1385 (strncmp(filename, "-", sizeof("-")))) {
Mike Frysinger62c794d2017-05-29 12:02:45 -04001386 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1387 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
hailfinger771fc182010-10-15 00:01:14 +00001388 fclose(image);
1389 return 1;
1390 }
1391 numbytes = fread(buf, 1, size, image);
1392 if (fclose(image)) {
1393 perror(filename);
1394 return 1;
1395 }
1396 if (numbytes != size) {
1397 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1398 "wanted %ld!\n", numbytes, size);
1399 return 1;
1400 }
1401 return 0;
1402}
1403
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001404int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001405{
1406 unsigned long numbytes;
1407 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001408
1409 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001410 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001411 return 1;
1412 }
Vincent Palatin7ab23932014-10-01 12:09:16 -07001413 if (!strncmp(filename, "-", sizeof("-")))
1414 image = fdopen(STDOUT_FILENO, "wb");
1415 else
1416 image = fopen(filename, "wb");
1417 if (image == NULL) {
hailfingerd219a232009-01-28 00:27:54 +00001418 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001419 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001420 }
hailfingerd219a232009-01-28 00:27:54 +00001421
hailfingerd219a232009-01-28 00:27:54 +00001422 numbytes = fwrite(buf, 1, size, image);
1423 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001424 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001425 msg_gerr("Error: file %s could not be written completely.\n", filename);
hailfingerd219a232009-01-28 00:27:54 +00001426 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001427 }
hailfingerd219a232009-01-28 00:27:54 +00001428 return 0;
1429}
1430
David Hendrickse3451942013-03-21 17:23:29 -07001431/*
1432 * read_flash - wrapper for flash->read() with additional high-level policy
1433 *
1434 * @flash flash chip
1435 * @buf buffer to store data in
1436 * @start start address
1437 * @len number of bytes to read
1438 *
1439 * This wrapper simplifies most cases when the flash chip needs to be read
1440 * since policy decisions such as non-fatal error handling is centralized.
1441 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001442int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001443 unsigned int start, unsigned int len)
1444{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001445 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001446
Patrick Georgif3fa2992017-02-02 16:24:44 +01001447 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001448 return -1;
1449
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001450 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1451
Patrick Georgif3fa2992017-02-02 16:24:44 +01001452 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001453 if (ret) {
1454 if (ignore_error(ret)) {
1455 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1456 start, start + len - 1);
1457 ret = 0;
1458 } else {
1459 msg_gdbg("failed to read 0x%x-0x%x\n",
1460 start, start + len - 1);
1461 }
1462 }
1463
1464 return ret;
1465}
1466
David Hendricks7c8a1612013-04-26 19:14:44 -07001467/*
1468 * write_flash - wrapper for flash->write() with additional high-level policy
1469 *
1470 * @flash flash chip
1471 * @buf buffer to write to flash
1472 * @start start address in flash
1473 * @len number of bytes to write
1474 *
1475 * TODO: Look up regions that are write-protected and avoid attempt to write
1476 * to them at all.
1477 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001478int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001479 unsigned int start, unsigned int len)
1480{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001481 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001482 return -1;
1483
Patrick Georgif3fa2992017-02-02 16:24:44 +01001484 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001485}
1486
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001487int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001488{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001489 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001490 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001491 int ret = 0;
1492
1493 msg_cinfo("Reading flash... ");
1494 if (!buf) {
1495 msg_gerr("Memory allocation failed!\n");
1496 msg_cinfo("FAILED.\n");
1497 return 1;
1498 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001499
1500 /* To support partial read, fill buffer to all 0xFF at beginning to make
1501 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001502 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001503
Patrick Georgif3fa2992017-02-02 16:24:44 +01001504 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001505 msg_cerr("No read function available for this flash chip.\n");
1506 ret = 1;
1507 goto out_free;
1508 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001509
1510 /* First try to handle partial read case, rather than read the whole
1511 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001512 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001513 if (ret < 0) {
1514 msg_cerr("Partial read operation failed!\n");
1515 ret = 1;
1516 goto out_free;
1517 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001518 int num_regions = get_num_include_args();
1519
1520 if (ret != num_regions) {
1521 msg_cerr("Requested %d regions, but only read %d\n",
1522 num_regions, ret);
1523 ret = 1;
1524 goto out_free;
1525 }
1526
1527 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001528 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001529 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001530 msg_cerr("Read operation failed!\n");
1531 ret = 1;
1532 goto out_free;
1533 }
hailfinger42a850a2010-07-13 23:56:13 +00001534 }
1535
David Hendricksdf29a832013-06-28 14:33:51 -07001536 if (filename)
1537 ret = write_buf_to_file(buf, size, filename);
1538
hailfinger42a850a2010-07-13 23:56:13 +00001539out_free:
1540 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001541 if (ret)
1542 msg_cerr("FAILED.");
1543 else
1544 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001545 return ret;
1546}
1547
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001548/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001549static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001550{
hailfingerb91c08c2011-08-15 19:54:20 +00001551 int i, j, k;
1552 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001553
1554 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1555 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001556 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001557
1558 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1559 /* Blocks with zero size are bugs in flashchips.c. */
1560 if (eraser.eraseblocks[i].count &&
1561 !eraser.eraseblocks[i].size) {
1562 msg_gerr("ERROR: Flash chip %s erase function "
1563 "%i region %i has size 0. Please report"
1564 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001565 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001566 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001567 }
1568 /* Blocks with zero count are bugs in flashchips.c. */
1569 if (!eraser.eraseblocks[i].count &&
1570 eraser.eraseblocks[i].size) {
1571 msg_gerr("ERROR: Flash chip %s erase function "
1572 "%i region %i has count 0. Please report"
1573 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001574 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001575 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001576 }
1577 done += eraser.eraseblocks[i].count *
1578 eraser.eraseblocks[i].size;
1579 }
hailfinger9fed35d2010-01-19 06:42:46 +00001580 /* Empty eraseblock definition with erase function. */
1581 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001582 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001583 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001584 if (!done)
1585 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001586 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001587 msg_gerr("ERROR: Flash chip %s erase function %i "
1588 "region walking resulted in 0x%06x bytes total,"
1589 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001590 " flashrom@flashrom.org\n", chip->name, k,
1591 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001592 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001593 }
hailfinger9fed35d2010-01-19 06:42:46 +00001594 if (!eraser.block_erase)
1595 continue;
1596 /* Check if there are identical erase functions for different
1597 * layouts. That would imply "magic" erase functions. The
1598 * easiest way to check this is with function pointers.
1599 */
uwef6f94d42010-03-13 17:28:29 +00001600 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001601 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001602 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001603 msg_gerr("ERROR: Flash chip %s erase function "
1604 "%i and %i are identical. Please report"
1605 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001606 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001607 ret = 1;
1608 }
uwef6f94d42010-03-13 17:28:29 +00001609 }
hailfinger45177872010-01-18 08:14:43 +00001610 }
hailfinger9fed35d2010-01-19 06:42:46 +00001611 return ret;
hailfinger45177872010-01-18 08:14:43 +00001612}
1613
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001614static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001615 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001616 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001617 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001618 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001619 unsigned int addr,
1620 unsigned int len))
1621{
stefanctc5eb8a92011-11-23 09:13:48 +00001622 unsigned int starthere = 0, lenhere = 0;
1623 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001624 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001625 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001626
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001627 /*
1628 * curcontents and newcontents are opaque to walk_eraseregions, and
1629 * need to be adjusted here to keep the impression of proper
1630 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001631 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001632
hailfinger90fcf9b2010-11-05 14:51:59 +00001633 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001634
hailfingerb437e282010-11-04 01:04:27 +00001635 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001636
hailfingerb437e282010-11-04 01:04:27 +00001637 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001638 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001639 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001640 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001641 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001642 if (ret) {
1643 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001644 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001645 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001646 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001647 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001648 }
1649
David Hendricks0954ffc2015-11-13 15:15:44 -08001650 if (programmer_table[programmer].paranoid) {
1651 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001652 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001653 return -1;
1654 }
hailfingerac8e3182011-06-26 17:04:16 +00001655 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001656
hailfinger90fcf9b2010-11-05 14:51:59 +00001657 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001658 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001659 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001660 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001661 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001662 /* get_next_write() sets starthere to a new value after the call. */
1663 while ((lenhere = get_next_write(curcontents + starthere,
1664 newcontents + starthere,
1665 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001666 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001667 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001668 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001669 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001670 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001671 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001672 if (ret) {
1673 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001674 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001675 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001676 }
David Hendricks048b38c2016-03-28 18:47:06 -07001677
1678 /*
1679 * If the block needed to be erased and was erased successfully
1680 * then we can assume that we didn't run into any write-
1681 * protected areas. Otherwise, we need to verify each page to
1682 * ensure it was successfully written and abort if we encounter
1683 * any errors.
1684 */
1685 if (programmer_table[programmer].paranoid && !block_was_erased) {
1686 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001687 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001688 return -1;
1689 }
1690
hailfingerb437e282010-11-04 01:04:27 +00001691 starthere += lenhere;
1692 skip = 0;
1693 }
1694 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001695 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001696 return ret;
1697}
1698
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001699/*
1700 * Function to process processing units accumulated in the action descriptor.
1701 *
1702 * @flash pointer to the flash context to operate on
1703 * @do_something helper function which can erase and program a section of the
1704 * flash chip. It receives the flash context, offset and length
1705 * of the area to erase/program, before and after contents (to
1706 * decide what exactly needs to be erased and or programmed)
1707 * and a pointer to the erase function which can operate on the
1708 * proper granularity.
1709 * @descriptor action descriptor including pointers to before and after
1710 * contents and an array of processing actions to take.
1711 *
1712 * Returns zero on success or an error code.
1713 */
1714static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001715 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001716 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001717 unsigned int len,
1718 uint8_t *param1,
1719 uint8_t *param2,
1720 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001721 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001722 unsigned int addr,
1723 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001724 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00001725{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001726 struct processing_unit *pu;
1727 int rc = 0;
1728 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00001729
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001730 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1731 unsigned base = pu->offset;
1732 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07001733
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001734 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07001735
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001736 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00001737 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001738 else
1739 print_comma = 1;
1740
1741 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1742
1743 rc = do_something(flash, base,
1744 pu->block_size,
1745 descriptor->oldcontents,
1746 descriptor->newcontents,
1747 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
1748
David Hendricks1ed1d352011-11-23 17:54:37 -08001749 if (rc) {
1750 if (ignore_error(rc))
1751 rc = 0;
1752 else
1753 return rc;
hailfingerb437e282010-11-04 01:04:27 +00001754 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001755 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00001756 }
1757 }
hailfingerb437e282010-11-04 01:04:27 +00001758 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08001759 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00001760}
1761
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001762static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00001763{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001764 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00001765
1766 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1767 if (log)
1768 msg_cdbg("not defined. ");
1769 return 1;
1770 }
1771 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1772 if (log)
1773 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00001774 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00001775 return 1;
1776 }
1777 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1778 if (log)
1779 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00001780 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00001781 return 1;
1782 }
1783 return 0;
1784}
1785
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001786int erase_and_write_flash(struct flashctx *flash,
1787 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00001788{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001789 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00001790
hailfingercf848f12010-12-05 15:14:44 +00001791 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00001792
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001793 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00001794
hailfinger7df21362009-09-05 02:30:58 +00001795 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00001796 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00001797 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07001798 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00001799 }
1800 return ret;
hailfingerd219a232009-01-28 00:27:54 +00001801}
1802
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001803static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00001804{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001805 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
1806#if CONFIG_INTERNAL == 1
1807 if (programmer == PROGRAMMER_INTERNAL)
1808 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
1809 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1810 "mail flashrom@flashrom.org, thanks!\n"
1811 "-------------------------------------------------------------------------------\n"
1812 "You may now reboot or simply leave the machine running.\n");
1813 else
1814#endif
1815 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
1816 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
1817 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1818 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00001819}
1820
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001821static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00001822{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001823 msg_gerr("Your flash chip is in an unknown state.\n");
1824#if CONFIG_INTERNAL == 1
1825 if (programmer == PROGRAMMER_INTERNAL)
1826 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
1827 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
1828 "-------------------------------------------------------------------------------\n"
1829 "DO NOT REBOOT OR POWEROFF!\n");
1830 else
1831#endif
1832 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1833 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00001834}
1835
uwe8d342eb2011-07-28 08:13:25 +00001836/* The way to go if you want a delimited list of programmers */
stefanct52700282011-06-26 17:38:17 +00001837void list_programmers(const char *delim)
hailfingerc77acb52009-12-24 02:15:55 +00001838{
1839 enum programmer p;
1840 for (p = 0; p < PROGRAMMER_INVALID; p++) {
snelsone42c3802010-05-07 20:09:04 +00001841 msg_ginfo("%s", programmer_table[p].name);
hailfingerc77acb52009-12-24 02:15:55 +00001842 if (p < PROGRAMMER_INVALID - 1)
snelsone42c3802010-05-07 20:09:04 +00001843 msg_ginfo("%s", delim);
hailfingerc77acb52009-12-24 02:15:55 +00001844 }
Simon Glass8dc82732013-07-16 10:13:51 -06001845 msg_ginfo("\n");
hailfingerc77acb52009-12-24 02:15:55 +00001846}
1847
hailfingerf79d1712010-10-06 23:48:34 +00001848void list_programmers_linebreak(int startcol, int cols, int paren)
1849{
1850 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00001851 int pnamelen;
1852 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00001853 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00001854 int i;
hailfingerf79d1712010-10-06 23:48:34 +00001855
1856 for (p = 0; p < PROGRAMMER_INVALID; p++) {
1857 pname = programmer_table[p].name;
1858 pnamelen = strlen(pname);
1859 if (remaining - pnamelen - 2 < 0) {
1860 if (firstline)
1861 firstline = 0;
1862 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001863 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00001864 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001865 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00001866 remaining = cols - startcol;
1867 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001868 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00001869 remaining--;
1870 }
1871 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001872 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00001873 remaining--;
1874 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001875 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00001876 remaining -= pnamelen;
1877 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001878 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00001879 remaining--;
1880 } else {
1881 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10001882 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00001883 }
1884 }
1885}
1886
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001887static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00001888{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10001889#if IS_WINDOWS
1890 SYSTEM_INFO si;
1891 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00001892
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10001893 memset(&si, 0, sizeof(SYSTEM_INFO));
1894 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
1895 msg_ginfo(" on Windows");
1896 /* Tell Windows which version of the structure we want. */
1897 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
1898 if (GetVersionEx((OSVERSIONINFO*) &osvi))
1899 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
1900 else
1901 msg_ginfo(" unknown version");
1902 GetSystemInfo(&si);
1903 switch (si.wProcessorArchitecture) {
1904 case PROCESSOR_ARCHITECTURE_AMD64:
1905 msg_ginfo(" (x86_64)");
1906 break;
1907 case PROCESSOR_ARCHITECTURE_INTEL:
1908 msg_ginfo(" (x86)");
1909 break;
1910 default:
1911 msg_ginfo(" (unknown arch)");
1912 break;
1913 }
1914#elif HAVE_UTSNAME == 1
1915 struct utsname osinfo;
1916
1917 uname(&osinfo);
1918 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00001919 osinfo.machine);
1920#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10001921 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00001922#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001923}
1924
1925void print_buildinfo(void)
1926{
1927 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00001928#if NEED_PCI == 1
1929#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001930 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00001931#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001932 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00001933#endif
1934#endif
1935#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001936 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00001937#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001938 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00001939#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001940 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00001941#endif
hailfinger3b471632010-03-27 16:36:40 +00001942#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001943 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00001944#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001945 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00001946#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001947 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00001948#endif
1949#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001950 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00001951#endif
1952#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001953 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00001954#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001955 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00001956#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07001957 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00001958}
1959
uwefdeca092008-01-21 15:24:22 +00001960void print_version(void)
1961{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001962 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00001963 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001964 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00001965}
1966
hailfinger74819ad2010-05-15 15:04:37 +00001967void print_banner(void)
1968{
1969 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001970 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00001971 msg_ginfo("\n");
1972}
1973
hailfingerc77acb52009-12-24 02:15:55 +00001974int selfcheck(void)
1975{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001976 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00001977 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001978
1979 /* Safety check. Instead of aborting after the first error, check
1980 * if more errors exist.
1981 */
hailfingerc77acb52009-12-24 02:15:55 +00001982 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00001983 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00001984 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00001985 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001986 /* It would be favorable if we could check for the correct layout (especially termination) of various
1987 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
1988 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
1989 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
1990 * 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 +10001991 * checks below. */
1992 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00001993 msg_gerr("Flashchips table miscompilation!\n");
1994 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001995 } else {
1996 for (i = 0; i < flashchips_size - 1; i++) {
1997 const struct flashchip *chip = &flashchips[i];
1998 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
1999 ret = 1;
2000 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2001 "Please report a bug at flashrom@flashrom.org\n", i,
2002 chip->name == NULL ? "unnamed" : chip->name);
2003 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002004 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002005 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002006 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002007 }
stefanct6d836ba2011-05-26 01:35:19 +00002008 }
stefanct6d836ba2011-05-26 01:35:19 +00002009
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002010 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002011 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002012}
2013
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002014
hailfinger771fc182010-10-15 00:01:14 +00002015/* FIXME: This function signature needs to be improved once doit() has a better
2016 * function signature.
2017 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002018static int chip_safety_check(const struct flashctx *flash, int force,
2019 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002020{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002021 const struct flashchip *chip = flash->chip;
2022
hailfinger771fc182010-10-15 00:01:14 +00002023 if (!programmer_may_write && (write_it || erase_it)) {
2024 msg_perr("Write/erase is not working yet on your programmer in "
2025 "its current configuration.\n");
2026 /* --force is the wrong approach, but it's the best we can do
2027 * until the generic programmer parameter parser is merged.
2028 */
2029 if (!force)
2030 return 1;
2031 msg_cerr("Continuing anyway.\n");
2032 }
2033
2034 if (read_it || erase_it || write_it || verify_it) {
2035 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002036 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002037 msg_cerr("Read is not working on this chip. ");
2038 if (!force)
2039 return 1;
2040 msg_cerr("Continuing anyway.\n");
2041 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002042 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002043 msg_cerr("flashrom has no read function for this "
2044 "flash chip.\n");
2045 return 1;
2046 }
2047 }
2048 if (erase_it || write_it) {
2049 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002050 if (chip->tested.erase == NA) {
2051 msg_cerr("Erase is not possible on this chip.\n");
2052 return 1;
2053 }
2054 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002055 msg_cerr("Erase is not working on this chip. ");
2056 if (!force)
2057 return 1;
2058 msg_cerr("Continuing anyway.\n");
2059 }
stefancte1c5acf2011-07-04 07:27:17 +00002060 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002061 msg_cerr("flashrom has no erase function for this "
2062 "flash chip.\n");
2063 return 1;
2064 }
hailfinger771fc182010-10-15 00:01:14 +00002065 }
2066 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002067 if (chip->tested.write == NA) {
2068 msg_cerr("Write is not possible on this chip.\n");
2069 return 1;
2070 }
2071 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002072 msg_cerr("Write is not working on this chip. ");
2073 if (!force)
2074 return 1;
2075 msg_cerr("Continuing anyway.\n");
2076 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002077 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002078 msg_cerr("flashrom has no write function for this "
2079 "flash chip.\n");
2080 return 1;
2081 }
2082 }
2083 return 0;
2084}
2085
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002086int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002087 const bool read_it, const bool write_it,
2088 const bool erase_it, const bool verify_it)
2089{
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002090 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 +10002091 msg_cerr("Aborting.\n");
2092 return 1;
2093 }
2094
2095 if (normalize_romentries(flash)) {
2096 msg_cerr("Requested regions can not be handled. Aborting.\n");
2097 return 1;
2098 }
2099
2100 /* Given the existence of read locks, we want to unlock for read,
2101 erase and write. */
2102 if (flash->chip->unlock)
2103 flash->chip->unlock(flash);
2104
2105 flash->address_high_byte = -1;
2106 flash->in_4ba_mode = false;
2107
2108 /* Enable/disable 4-byte addressing mode if flash chip supports it */
2109 if ((flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN) && flash->chip->set_4ba) {
2110 if (flash->chip->set_4ba(flash)) {
2111 msg_cerr("Enabling/disabling 4-byte addressing mode failed!\n");
2112 return 1;
2113 }
2114 }
2115
2116 return 0;
2117}
2118
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002119/*
2120 * Function to erase entire flash chip.
2121 *
2122 * @flashctx pointer to the flash context to use
2123 * @oldcontents pointer to the buffer including current chip contents, to
2124 * decide which areas do in fact need to be erased
2125 * @size the size of the flash chip, in bytes.
2126 *
2127 * Returns zero on success or an error code.
2128 */
2129static int erase_chip(struct flashctx *flash, void *oldcontents,
2130 void *newcontents, size_t size)
2131{
2132 /*
2133 * To make sure that the chip is fully erased, let's cheat and create
2134 * a descriptor where the new contents are all erased.
2135 */
2136 struct action_descriptor *fake_descriptor;
2137 int ret = 0;
2138
2139 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2140 newcontents, 1);
2141 /* FIXME: Do we really want the scary warning if erase failed? After
2142 * all, after erase the chip is either blank or partially blank or it
2143 * has the old contents. A blank chip won't boot, so if the user
2144 * wanted erase and reboots afterwards, the user knows very well that
2145 * booting won't work.
2146 */
2147 if (erase_and_write_flash(flash, fake_descriptor)) {
2148 emergency_help_message();
2149 ret = 1;
2150 }
2151
2152 free(fake_descriptor);
2153
2154 return ret;
2155}
2156
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002157static int read_dest_content(struct flashctx *flash, int verify_it,
2158 uint8_t *dest, unsigned long size)
2159{
2160 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2161 && get_num_include_args()) {
2162 /*
2163 * If no full verification is required and not
2164 * the entire chip is about to be programmed,
2165 * read only the areas which might change.
2166 */
2167 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2168 return 1;
2169 } else {
2170 if (read_flash(flash, dest, 0, size))
2171 return 1;
2172 }
2173 return 0;
2174}
2175
hailfingerc77acb52009-12-24 02:15:55 +00002176/* This function signature is horrible. We need to design a better interface,
2177 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002178 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002179 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002180int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002181 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002182 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002183{
hailfinger4c47e9d2010-10-19 22:06:20 +00002184 uint8_t *oldcontents;
2185 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002186 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002187 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002188 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002189
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002190 g_force = force; // HACK
2191 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002192 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002193 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002194
Simon Glass9ad06c12013-07-03 22:08:17 +09002195 if (extract_it) {
2196 ret = extract_regions(flash);
2197 goto out_nofree;
2198 }
2199
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002200 /* mark entries included using -i argument as "included" if they are
2201 found in the master rom_entries list */
2202 if (process_include_args() < 0) {
2203 ret = 1;
2204 goto out_nofree;
2205 }
2206
hailfinger771fc182010-10-15 00:01:14 +00002207 if (read_it) {
2208 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002209 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002210 }
hailfingerb437e282010-11-04 01:04:27 +00002211
stefanctd611e8f2011-07-12 22:35:21 +00002212 oldcontents = malloc(size);
2213 if (!oldcontents) {
2214 msg_gerr("Out of memory!\n");
2215 exit(1);
2216 }
Simon Glass4c214132013-07-16 10:09:28 -06002217 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002218 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002219 newcontents = malloc(size);
2220 if (!newcontents) {
2221 msg_gerr("Out of memory!\n");
2222 exit(1);
2223 }
Simon Glass4c214132013-07-16 10:09:28 -06002224 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002225 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002226 /* Side effect of the assumptions above: Default write action is erase
2227 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002228 * oldcontents being completely unerased means we have to erase
2229 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002230 */
2231
hailfingerd217d122010-10-08 18:52:29 +00002232 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002233 /*
2234 * Note: This must be done before any files specified by -i
2235 * arguments are processed merged into the newcontents since
2236 * -i files take priority. See http://crbug.com/263495.
2237 */
2238 if (filename) {
2239 if (read_buf_from_file(newcontents, size, filename)) {
2240 ret = 1;
2241 goto out;
2242 }
2243 } else {
2244 /* Content will be read from -i args, so they must
2245 * not overlap. */
2246 if (included_regions_overlap()) {
2247 msg_gerr("Error: Included regions must "
2248 "not overlap.\n");
2249 ret = 1;
2250 goto out;
2251 }
stepan1da96c02006-11-21 23:48:51 +00002252 }
ollie5672ac62004-03-17 22:22:08 +00002253 }
2254
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002255 if (do_diff) {
2256 /*
2257 * Obtain a reference image so that we can check whether
2258 * regions need to be erased and to give better diagnostics in
2259 * case write fails. If --fast-verify is used then only the
2260 * regions which are included using -i will be read.
2261 */
2262 if (diff_file) {
2263 msg_cdbg("Reading old contents from file... ");
2264 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002265 ret = 1;
2266 msg_cdbg("FAILED.\n");
2267 goto out;
2268 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002269 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002270 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002271 ret = read_dest_content(flash, verify_it,
2272 oldcontents, size);
2273 if (ret) {
2274 msg_cdbg("FAILED.\n");
2275 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002276 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002277 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002278 msg_cdbg("done.\n");
2279 } else if (!erase_it) {
2280 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002281 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002282 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002283
David Hendricksdf29a832013-06-28 14:33:51 -07002284 /*
2285 * Note: This must be done after reading the file specified for the
2286 * -w/-v argument, if any, so that files specified using -i end up
2287 * in the "newcontents" buffer before being written.
2288 * See http://crbug.com/263495.
2289 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002290 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002291 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002292 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002293 goto out;
2294 }
uwef6641642007-05-09 10:17:44 +00002295
David Hendricksa7e114b2016-02-26 18:49:15 -08002296 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002297 erase_chip(flash, oldcontents, newcontents, size);
2298 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002299 }
2300
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002301 descriptor = prepare_action_descriptor(flash, oldcontents,
2302 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002303 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002304 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002305 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002306 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002307 goto out;
2308 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002309
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002310 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002311 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2312 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002313 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002314 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002315 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002316 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002317 ret = 1;
2318 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002319 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002320 msg_cerr("Apparently at least some data has changed.\n");
2321 } else
2322 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002323 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002324 ret = 1;
2325 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002326 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002327
David Hendricksac1d25c2016-08-09 17:00:58 -07002328 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002329 if (ret < 0) {
2330 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002331 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002332 emergency_help_message();
2333 ret = 1;
2334 goto out;
2335 } else if (ret > 0) {
2336 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002337 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002338 ret = read_dest_content(flash, verify_it,
2339 oldcontents, size);
2340 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002341 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002342 goto out;
2343 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002344
2345 /* Get a new descriptor. */
2346 free(descriptor);
2347 descriptor = prepare_action_descriptor(flash,
2348 oldcontents,
2349 newcontents,
2350 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002351 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002352 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002353 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002354 emergency_help_message();
2355 ret = 1;
2356 goto out;
2357 }
2358 ret = 0;
2359 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002360
David Hendricksac1d25c2016-08-09 17:00:58 -07002361 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002362 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002363 emergency_help_message();
2364 ret = 1;
2365 goto out;
2366 }
stuge8ce3a3c2008-04-28 14:47:30 +00002367 }
ollie6a600992005-11-26 21:55:36 +00002368
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002369 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002370 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002371 if ((write_it || erase_it) && !content_has_changed) {
2372 msg_gdbg("Nothing was erased or written, skipping "
2373 "verification\n");
2374 } else {
2375 /* Work around chips which need some time to calm down. */
2376 if (write_it && verify_it != VERIFY_PARTIAL)
2377 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002378
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002379 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002380
David Hendricks9ba79fb2015-04-03 12:06:16 -07002381 /* If we tried to write, and verification now fails, we
2382 * might have an emergency situation.
2383 */
2384 if (ret && write_it)
2385 emergency_help_message();
2386 }
hailfinger0459e1c2009-08-19 13:55:34 +00002387 }
ollie6a600992005-11-26 21:55:36 +00002388
hailfinger90fcf9b2010-11-05 14:51:59 +00002389out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002390 if (descriptor)
2391 free(descriptor);
2392
hailfinger90fcf9b2010-11-05 14:51:59 +00002393 free(oldcontents);
2394 free(newcontents);
2395out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002396 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002397 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002398 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002399 * tree. This is because some operations, such as write protection,
2400 * requires programmer_shutdown() but does not call doit().
2401 */
2402// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002403 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002404}
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002405
2406void finalize_flash_access(struct flashctx *const flash)
2407{
2408 unmap_flash(flash);
2409}