blob: 8b3b56d1998d1e61bf3b1c4caed0387ecd5b30f9 [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"
Edward O'Callaghan99974452020-10-13 13:28:33 +110044#include "chipdrivers.h"
rminnich8d3ff912003-10-25 17:01:29 +000045
krause2eb76212011-01-17 07:50:42 +000046const char flashrom_version[] = FLASHROM_VERSION;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100047const char *chip_to_probe = NULL;
hailfinger80422e22009-12-13 22:28:00 +000048
David Hendricks9ba79fb2015-04-03 12:06:16 -070049/* Set if any erase/write operation is to be done. This will be used to
50 * decide if final verification is needed. */
51static int content_has_changed = 0;
52
David Hendricks1ed1d352011-11-23 17:54:37 -080053/* error handling stuff */
54enum error_action access_denied_action = error_ignore;
55
56int ignore_error(int err) {
57 int rc = 0;
58
59 switch(err) {
60 case ACCESS_DENIED:
61 if (access_denied_action == error_ignore)
62 rc = 1;
63 break;
64 default:
65 break;
66 }
67
68 return rc;
69}
70
hailfinger969e2f32011-09-08 00:00:29 +000071static enum programmer programmer = PROGRAMMER_INVALID;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100072static const char *programmer_param = NULL;
stepan782fb172007-04-06 11:58:03 +000073
uwee15beb92010-08-08 17:01:18 +000074/*
hailfinger80422e22009-12-13 22:28:00 +000075 * Programmers supporting multiple buses can have differing size limits on
76 * each bus. Store the limits for each bus in a common struct.
77 */
hailfinger1ff33dc2010-07-03 11:02:10 +000078struct decode_sizes max_rom_decode;
79
80/* If nonzero, used as the start address of bottom-aligned flash. */
81unsigned long flashbase;
hailfinger80422e22009-12-13 22:28:00 +000082
hailfinger5828baf2010-07-03 12:14:25 +000083/* Is writing allowed with this programmer? */
84int programmer_may_write;
85
hailfingerabe249e2009-05-08 17:43:22 +000086const struct programmer_entry programmer_table[] = {
hailfinger90c7d542010-05-31 15:27:27 +000087#if CONFIG_INTERNAL == 1
hailfingerabe249e2009-05-08 17:43:22 +000088 {
hailfinger3548a9a2009-08-12 14:34:35 +000089 .name = "internal",
Edward O'Callaghan0949b782019-11-10 23:23:20 +110090 .type = OTHER,
91 .devs.note = NULL,
hailfinger6c69ab02009-05-11 15:46:43 +000092 .init = internal_init,
hailfinger11ae3c42009-05-11 14:13:25 +000093 .map_flash_region = physmap,
94 .unmap_flash_region = physunmap,
hailfingere5829f62009-06-05 17:48:08 +000095 .delay = internal_delay,
David Hendricks55cdd9c2015-11-25 14:37:26 -080096
97 /*
98 * "Internal" implies in-system programming on a live system, so
99 * handle with paranoia to catch errors early. If something goes
100 * wrong then hopefully the system will still be recoverable.
101 */
102 .paranoid = 1,
hailfingerabe249e2009-05-08 17:43:22 +0000103 },
hailfinger80422e22009-12-13 22:28:00 +0000104#endif
stepan927d4e22007-04-04 22:45:58 +0000105
hailfinger90c7d542010-05-31 15:27:27 +0000106#if CONFIG_DUMMY == 1
hailfingera9df33c2009-05-09 00:54:55 +0000107 {
hailfinger3548a9a2009-08-12 14:34:35 +0000108 .name = "dummy",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100109 .type = OTHER,
110 /* FIXME */
111 .devs.note = "Dummy device, does nothing and logs all accesses\n",
hailfinger6c69ab02009-05-11 15:46:43 +0000112 .init = dummy_init,
hailfinger11ae3c42009-05-11 14:13:25 +0000113 .map_flash_region = dummy_map,
114 .unmap_flash_region = dummy_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000115 .delay = internal_delay,
hailfingera9df33c2009-05-09 00:54:55 +0000116 },
hailfinger571a6b32009-09-16 10:09:21 +0000117#endif
hailfingera9df33c2009-05-09 00:54:55 +0000118
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000119#if CONFIG_MEC1308 == 1
120 {
121 .name = "mec1308",
122 .type = OTHER,
123 .devs.note = "Microchip MEC1308 Embedded Controller.\n",
124 .init = mec1308_init,
125 .map_flash_region = fallback_map,
126 .unmap_flash_region = fallback_unmap,
127 .delay = internal_delay,
128 },
129#endif
130
hailfinger90c7d542010-05-31 15:27:27 +0000131#if CONFIG_NIC3COM == 1
uwe0f5a3a22009-05-13 11:36:06 +0000132 {
hailfinger3548a9a2009-08-12 14:34:35 +0000133 .name = "nic3com",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100134 .type = PCI,
135 .devs.dev = nics_3com,
uwe0f5a3a22009-05-13 11:36:06 +0000136 .init = nic3com_init,
uwe3e656bd2009-05-17 23:12:17 +0000137 .map_flash_region = fallback_map,
138 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000139 .delay = internal_delay,
uwe0f5a3a22009-05-13 11:36:06 +0000140 },
hailfinger571a6b32009-09-16 10:09:21 +0000141#endif
uwe0f5a3a22009-05-13 11:36:06 +0000142
hailfinger90c7d542010-05-31 15:27:27 +0000143#if CONFIG_NICREALTEK == 1
hailfinger5aa36982010-05-21 21:54:07 +0000144 {
hailfinger0d703d42011-03-07 01:08:09 +0000145 /* This programmer works for Realtek RTL8139 and SMC 1211. */
uwe8d342eb2011-07-28 08:13:25 +0000146 .name = "nicrealtek",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100147 .type = PCI,
148 .devs.dev = nics_realtek,
uwe8d342eb2011-07-28 08:13:25 +0000149 .init = nicrealtek_init,
150 .map_flash_region = fallback_map,
151 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000152 .delay = internal_delay,
hailfinger5aa36982010-05-21 21:54:07 +0000153 },
hailfinger5aa36982010-05-21 21:54:07 +0000154#endif
155
hailfingerf0a368f2010-06-07 22:37:54 +0000156#if CONFIG_NICNATSEMI == 1
157 {
uwe8d342eb2011-07-28 08:13:25 +0000158 .name = "nicnatsemi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100159 .type = PCI,
160 .devs.dev = nics_natsemi,
uwe8d342eb2011-07-28 08:13:25 +0000161 .init = nicnatsemi_init,
162 .map_flash_region = fallback_map,
163 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000164 .delay = internal_delay,
hailfingerf0a368f2010-06-07 22:37:54 +0000165 },
166#endif
hailfinger5aa36982010-05-21 21:54:07 +0000167
hailfinger90c7d542010-05-31 15:27:27 +0000168#if CONFIG_GFXNVIDIA == 1
uweff4576d2009-09-30 18:29:55 +0000169 {
170 .name = "gfxnvidia",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100171 .type = PCI,
172 .devs.dev = gfx_nvidia,
uweff4576d2009-09-30 18:29:55 +0000173 .init = gfxnvidia_init,
uweff4576d2009-09-30 18:29:55 +0000174 .map_flash_region = fallback_map,
175 .unmap_flash_region = fallback_unmap,
uweff4576d2009-09-30 18:29:55 +0000176 .delay = internal_delay,
177 },
178#endif
179
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000180#if CONFIG_RAIDEN_DEBUG_SPI == 1
181 {
182 .name = "raiden_debug_spi",
183 .type = USB,
184 .devs.dev = devs_raiden,
185 .init = raiden_debug_spi_init,
186 .map_flash_region = fallback_map,
187 .unmap_flash_region = fallback_unmap,
188 .delay = internal_delay,
189 },
190#endif
191
hailfinger90c7d542010-05-31 15:27:27 +0000192#if CONFIG_DRKAISER == 1
ruikda922a12009-05-17 19:39:27 +0000193 {
uwee2f95ef2009-09-02 23:00:46 +0000194 .name = "drkaiser",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100195 .type = PCI,
196 .devs.dev = drkaiser_pcidev,
uwee2f95ef2009-09-02 23:00:46 +0000197 .init = drkaiser_init,
uwee2f95ef2009-09-02 23:00:46 +0000198 .map_flash_region = fallback_map,
199 .unmap_flash_region = fallback_unmap,
uwee2f95ef2009-09-02 23:00:46 +0000200 .delay = internal_delay,
201 },
hailfinger571a6b32009-09-16 10:09:21 +0000202#endif
uwee2f95ef2009-09-02 23:00:46 +0000203
hailfinger90c7d542010-05-31 15:27:27 +0000204#if CONFIG_SATASII == 1
uwee2f95ef2009-09-02 23:00:46 +0000205 {
hailfinger3548a9a2009-08-12 14:34:35 +0000206 .name = "satasii",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100207 .type = PCI,
208 .devs.dev = satas_sii,
ruikda922a12009-05-17 19:39:27 +0000209 .init = satasii_init,
uwe3e656bd2009-05-17 23:12:17 +0000210 .map_flash_region = fallback_map,
211 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000212 .delay = internal_delay,
ruikda922a12009-05-17 19:39:27 +0000213 },
hailfinger571a6b32009-09-16 10:09:21 +0000214#endif
ruikda922a12009-05-17 19:39:27 +0000215
hailfinger90c7d542010-05-31 15:27:27 +0000216#if CONFIG_ATAHPT == 1
uwe7e627c82010-02-21 21:17:00 +0000217 {
218 .name = "atahpt",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100219 .type = PCI,
220 .devs.dev = ata_hpt,
uwe7e627c82010-02-21 21:17:00 +0000221 .init = atahpt_init,
uwe7e627c82010-02-21 21:17:00 +0000222 .map_flash_region = fallback_map,
223 .unmap_flash_region = fallback_unmap,
uwe7e627c82010-02-21 21:17:00 +0000224 .delay = internal_delay,
225 },
226#endif
227
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000228#if CONFIG_ATAVIA == 1
229 {
230 .name = "atavia",
231 .type = PCI,
232 .devs.dev = ata_via,
233 .init = atavia_init,
234 .map_flash_region = atavia_map,
235 .unmap_flash_region = fallback_unmap,
236 .delay = internal_delay,
237 },
238#endif
239
240#if CONFIG_ATAPROMISE == 1
241 {
242 .name = "atapromise",
243 .type = PCI,
244 .devs.dev = ata_promise,
245 .init = atapromise_init,
246 .map_flash_region = atapromise_map,
247 .unmap_flash_region = fallback_unmap,
248 .delay = internal_delay,
249 },
250#endif
251
252#if CONFIG_IT8212 == 1
253 {
254 .name = "it8212",
255 .type = PCI,
256 .devs.dev = devs_it8212,
257 .init = it8212_init,
258 .map_flash_region = fallback_map,
259 .unmap_flash_region = fallback_unmap,
260 .delay = internal_delay,
261 },
262#endif
263
hailfinger90c7d542010-05-31 15:27:27 +0000264#if CONFIG_FT2232_SPI == 1
hailfingerf31da3d2009-06-16 21:08:06 +0000265 {
hailfinger90c7d542010-05-31 15:27:27 +0000266 .name = "ft2232_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100267 .type = USB,
Nikolai Artemievc347a852020-04-29 12:17:08 +1000268 .devs.dev = devs_ft2232spi,
hailfingerf31da3d2009-06-16 21:08:06 +0000269 .init = ft2232_spi_init,
hailfinger6fe23d62009-08-12 11:39:29 +0000270 .map_flash_region = fallback_map,
271 .unmap_flash_region = fallback_unmap,
hailfingerf31da3d2009-06-16 21:08:06 +0000272 .delay = internal_delay,
273 },
hailfingerd9dcfbd2009-08-19 13:27:58 +0000274#endif
hailfinger6fe23d62009-08-12 11:39:29 +0000275
hailfinger90c7d542010-05-31 15:27:27 +0000276#if CONFIG_SERPROG == 1
hailfinger37b4fbf2009-06-23 11:33:43 +0000277 {
hailfinger3548a9a2009-08-12 14:34:35 +0000278 .name = "serprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100279 .type = OTHER,
280 /* FIXME */
281 .devs.note = "All programmer devices speaking the serprog protocol\n",
hailfinger37b4fbf2009-06-23 11:33:43 +0000282 .init = serprog_init,
Edward O'Callaghan62018182020-10-03 00:16:48 +1000283 .map_flash_region = serprog_map,
hailfinger37b4fbf2009-06-23 11:33:43 +0000284 .unmap_flash_region = fallback_unmap,
hailfinger37b4fbf2009-06-23 11:33:43 +0000285 .delay = serprog_delay,
286 },
hailfinger74d88a72009-08-12 16:17:41 +0000287#endif
hailfingerf31da3d2009-06-16 21:08:06 +0000288
hailfinger90c7d542010-05-31 15:27:27 +0000289#if CONFIG_BUSPIRATE_SPI == 1
hailfinger9c5add72009-11-24 00:20:03 +0000290 {
hailfinger90c7d542010-05-31 15:27:27 +0000291 .name = "buspirate_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100292 .type = OTHER,
293 /* FIXME */
294 .devs.note = "Dangerous Prototypes Bus Pirate\n",
hailfinger9c5add72009-11-24 00:20:03 +0000295 .init = buspirate_spi_init,
hailfinger9c5add72009-11-24 00:20:03 +0000296 .map_flash_region = fallback_map,
297 .unmap_flash_region = fallback_unmap,
hailfinger9c5add72009-11-24 00:20:03 +0000298 .delay = internal_delay,
299 },
300#endif
301
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000302#if CONFIG_DEDIPROG == 1
Anton Staafb2647882014-09-17 15:13:43 -0700303 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000304 .name = "dediprog",
Brian J. Nemecb42d6c12020-07-23 03:07:38 -0700305 .type = USB,
Edward O'Callaghanac1678b2020-07-27 15:55:45 +1000306 .devs.dev = devs_dediprog,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000307 .init = dediprog_init,
Anton Staafb2647882014-09-17 15:13:43 -0700308 .map_flash_region = fallback_map,
309 .unmap_flash_region = fallback_unmap,
310 .delay = internal_delay,
311 },
312#endif
313
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000314#if CONFIG_DEVELOPERBOX_SPI == 1
hailfingerdfb32a02010-01-19 11:15:48 +0000315 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000316 .name = "developerbox",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100317 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000318 .devs.dev = devs_developerbox_spi,
319 .init = developerbox_spi_init,
320 .map_flash_region = fallback_map,
321 .unmap_flash_region = fallback_unmap,
322 .delay = internal_delay,
323 },
324#endif
325
326#if CONFIG_ENE_LPC == 1
327 {
328 .name = "ene_lpc",
329 .type = OTHER,
330 .devs.note = "ENE LPC interface keyboard controller\n",
331 .init = ene_lpc_init,
hailfingerdfb32a02010-01-19 11:15:48 +0000332 .map_flash_region = fallback_map,
333 .unmap_flash_region = fallback_unmap,
hailfingerdfb32a02010-01-19 11:15:48 +0000334 .delay = internal_delay,
335 },
336#endif
337
hailfinger52c4fa02010-07-21 10:26:01 +0000338#if CONFIG_RAYER_SPI == 1
339 {
340 .name = "rayer_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100341 .type = OTHER,
342 /* FIXME */
343 .devs.note = "RayeR parallel port programmer\n",
hailfinger52c4fa02010-07-21 10:26:01 +0000344 .init = rayer_spi_init,
hailfinger52c4fa02010-07-21 10:26:01 +0000345 .map_flash_region = fallback_map,
346 .unmap_flash_region = fallback_unmap,
hailfinger52c4fa02010-07-21 10:26:01 +0000347 .delay = internal_delay,
348 },
349#endif
350
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000351#if CONFIG_PONY_SPI == 1
352 {
353 .name = "pony_spi",
354 .type = OTHER,
355 /* FIXME */
356 .devs.note = "Programmers compatible with SI-Prog, serbang or AJAWe\n",
357 .init = pony_spi_init,
358 .map_flash_region = fallback_map,
359 .unmap_flash_region = fallback_unmap,
360 .delay = internal_delay,
361 },
362#endif
363
hailfinger7949b652011-05-08 00:24:18 +0000364#if CONFIG_NICINTEL == 1
365 {
366 .name = "nicintel",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100367 .type = PCI,
368 .devs.dev = nics_intel,
hailfinger7949b652011-05-08 00:24:18 +0000369 .init = nicintel_init,
hailfinger7949b652011-05-08 00:24:18 +0000370 .map_flash_region = fallback_map,
371 .unmap_flash_region = fallback_unmap,
hailfinger7949b652011-05-08 00:24:18 +0000372 .delay = internal_delay,
373 },
374#endif
375
uwe6764e922010-09-03 18:21:21 +0000376#if CONFIG_NICINTEL_SPI == 1
377 {
uwe8d342eb2011-07-28 08:13:25 +0000378 .name = "nicintel_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100379 .type = PCI,
380 .devs.dev = nics_intel_spi,
uwe8d342eb2011-07-28 08:13:25 +0000381 .init = nicintel_spi_init,
382 .map_flash_region = fallback_map,
383 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000384 .delay = internal_delay,
uwe6764e922010-09-03 18:21:21 +0000385 },
386#endif
387
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000388#if CONFIG_NICINTEL_EEPROM == 1
389 {
390 .name = "nicintel_eeprom",
391 .type = PCI,
392 .devs.dev = nics_intel_ee,
393 .init = nicintel_ee_init,
394 .map_flash_region = fallback_map,
395 .unmap_flash_region = fallback_unmap,
396 .delay = internal_delay,
397 },
398#endif
399
hailfingerfb1f31f2010-12-03 14:48:11 +0000400#if CONFIG_OGP_SPI == 1
401 {
uwe8d342eb2011-07-28 08:13:25 +0000402 .name = "ogp_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100403 .type = PCI,
404 .devs.dev = ogp_spi,
uwe8d342eb2011-07-28 08:13:25 +0000405 .init = ogp_spi_init,
406 .map_flash_region = fallback_map,
407 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000408 .delay = internal_delay,
hailfingerfb1f31f2010-12-03 14:48:11 +0000409 },
410#endif
411
hailfinger935365d2011-02-04 21:37:59 +0000412#if CONFIG_SATAMV == 1
413 {
414 .name = "satamv",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100415 .type = PCI,
416 .devs.dev = satas_mv,
hailfinger935365d2011-02-04 21:37:59 +0000417 .init = satamv_init,
hailfinger935365d2011-02-04 21:37:59 +0000418 .map_flash_region = fallback_map,
419 .unmap_flash_region = fallback_unmap,
hailfinger935365d2011-02-04 21:37:59 +0000420 .delay = internal_delay,
421 },
422#endif
423
David Hendrickscebee892015-05-23 20:30:30 -0700424#if CONFIG_LINUX_MTD == 1
425 {
426 .name = "linux_mtd",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100427 .type = OTHER,
428 .devs.note = "Device files /dev/mtd*\n",
David Hendrickscebee892015-05-23 20:30:30 -0700429 .init = linux_mtd_init,
430 .map_flash_region = fallback_map,
431 .unmap_flash_region = fallback_unmap,
432 .delay = internal_delay,
433 },
434#endif
435
uwe7df6dda2011-09-03 18:37:52 +0000436#if CONFIG_LINUX_SPI == 1
437 {
438 .name = "linux_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100439 .type = OTHER,
440 .devs.note = "Device files /dev/spidev*.*\n",
uwe7df6dda2011-09-03 18:37:52 +0000441 .init = linux_spi_init,
442 .map_flash_region = fallback_map,
443 .unmap_flash_region = fallback_unmap,
uwe7df6dda2011-09-03 18:37:52 +0000444 .delay = internal_delay,
445 },
446#endif
447
Shiyu Sun9dde7162020-04-16 17:32:55 +1000448#if CONFIG_LSPCON_I2C_SPI == 1
449 {
450 .name = "lspcon_i2c_spi",
451 .type = OTHER,
452 .devs.note = "Device files /dev/i2c-*.\n",
453 .init = lspcon_i2c_spi_init,
454 .map_flash_region = fallback_map,
455 .unmap_flash_region = fallback_unmap,
456 .delay = internal_delay,
457 },
458#endif
459
Edward O'Callaghan97dd9262020-03-26 00:00:41 +1100460#if CONFIG_REALTEK_MST_I2C_SPI == 1
461 {
462 .name = "realtek_mst_i2c_spi",
463 .type = OTHER,
464 .devs.note = "Device files /dev/i2c-*.\n",
465 .init = realtek_mst_i2c_spi_init,
466 .map_flash_region = fallback_map,
467 .unmap_flash_region = fallback_unmap,
468 .delay = internal_delay,
469 },
470#endif
471
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000472#if CONFIG_USBBLASTER_SPI == 1
473 {
474 .name = "usbblaster_spi",
475 .type = USB,
476 .devs.dev = devs_usbblasterspi,
477 .init = usbblaster_spi_init,
478 .map_flash_region = fallback_map,
479 .unmap_flash_region = fallback_unmap,
480 .delay = internal_delay,
481 },
482#endif
483
484#if CONFIG_MSTARDDC_SPI == 1
485 {
486 .name = "mstarddc_spi",
487 .type = OTHER,
488 .devs.note = "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
489 .init = mstarddc_spi_init,
490 .map_flash_region = fallback_map,
491 .unmap_flash_region = fallback_unmap,
492 .delay = internal_delay,
493 },
494#endif
495
496#if CONFIG_PICKIT2_SPI == 1
497 {
498 .name = "pickit2_spi",
499 .type = USB,
500 .devs.dev = devs_pickit2_spi,
501 .init = pickit2_spi_init,
502 .map_flash_region = fallback_map,
503 .unmap_flash_region = fallback_unmap,
504 .delay = internal_delay,
505 },
506#endif
507
508#if CONFIG_CH341A_SPI == 1
509 {
510 .name = "ch341a_spi",
511 .type = USB,
512 .devs.dev = devs_ch341a_spi,
513 .init = ch341a_spi_init,
514 .map_flash_region = fallback_map,
515 .unmap_flash_region = fallback_unmap,
516 .delay = ch341a_spi_delay,
517 },
518#endif
519
520#if CONFIG_DIGILENT_SPI == 1
521 {
522 .name = "digilent_spi",
523 .type = USB,
524 .devs.dev = devs_digilent_spi,
525 .init = digilent_spi_init,
526 .map_flash_region = fallback_map,
527 .unmap_flash_region = fallback_unmap,
528 .delay = internal_delay,
529 },
530#endif
531
532#if CONFIG_JLINK_SPI == 1
533 {
534 .name = "jlink_spi",
535 .type = OTHER,
536 .init = jlink_spi_init,
537 .devs.note = "SEGGER J-Link and compatible devices\n",
538 .map_flash_region = fallback_map,
539 .unmap_flash_region = fallback_unmap,
540 .delay = internal_delay,
541 },
542#endif
543
544#if CONFIG_NI845X_SPI == 1
545 {
546 .name = "ni845x_spi",
547 .type = OTHER, // choose other because NI-845x uses own USB implementation
548 .devs.note = "National Instruments USB-845x\n",
549 .init = ni845x_spi_init,
550 .map_flash_region = fallback_map,
551 .unmap_flash_region = fallback_unmap,
552 .delay = internal_delay,
553 },
554#endif
555
556#if CONFIG_STLINKV3_SPI == 1
557 {
558 .name = "stlinkv3_spi",
559 .type = USB,
560 .devs.dev = devs_stlinkv3_spi,
561 .init = stlinkv3_spi_init,
562 .map_flash_region = fallback_map,
563 .unmap_flash_region = fallback_unmap,
564 .delay = internal_delay,
565 },
566#endif
567
Edward O'Callaghand8f72232020-09-30 14:21:42 +1000568#if CONFIG_GOOGLE_EC == 1
569 {
570 .name = "google_ec",
571 .type = OTHER,
572 .devs.note = "Google EC.\n",
573 .init = cros_ec_probe_dev,
574 .map_flash_region = fallback_map,
575 .unmap_flash_region = fallback_unmap,
576 .delay = internal_delay,
577 },
578#endif
579
Edward O'Callaghanda29ca82020-10-20 00:49:47 +1100580#if CONFIG_CROS_ALIAS == 1
581 {
582 .name = "ec",
583 .type = OTHER,
584 .devs.note = "Google EC alias mechanism.\n",
585 .init = cros_ec_alias_init,
586 .map_flash_region = physmap, /* TODO(b/171934191) */
587 .unmap_flash_region = physunmap, /* TODO(b/171934191) */
588 .delay = internal_delay,
589
590 /*
591 * "ec" implies in-system programming on a live system, so
592 * handle with paranoia to catch errors early. If something goes
593 * wrong then hopefully the system will still be recoverable.
594 */
595 .paranoid = 1,
596 },
Edward O'Callaghan5b16a082020-10-20 16:30:16 +1100597
598 {
599 .name = "host",
600 .type = OTHER,
601 .devs.note = "Google host alias mechanism.\n",
602 .init = cros_host_alias_init,
603 .map_flash_region = physmap,
604 .unmap_flash_region = physunmap,
605 .delay = internal_delay,
606
607 /*
608 * "Internal" implies in-system programming on a live system, so
609 * handle with paranoia to catch errors early. If something goes
610 * wrong then hopefully the system will still be recoverable.
611 */
612 .paranoid = 1,
613 },
Edward O'Callaghanda29ca82020-10-20 00:49:47 +1100614#endif
615
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100616 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000617};
stepan927d4e22007-04-04 22:45:58 +0000618
David Hendricksbf36f092010-11-02 23:39:29 -0700619#define CHIP_RESTORE_MAXFN 4
620static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000621static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700622 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700623 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700624 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000625} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700626
David Hendricks668f29d2011-01-27 18:51:45 -0800627
hailfingerf31cbdc2010-11-10 15:25:18 +0000628#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000629static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000630/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000631static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700632 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000633 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000634} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000635/* Initialize to 0 to make sure nobody registers a shutdown function before
636 * programmer init.
637 */
638static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000639
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700640static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000641
Edward O'Callaghanf0d253a2020-10-19 20:01:37 +1100642//int register_chip_restore(int (*function) (void *data), void *data)
643int register_chip_restore(CHIP_RESTORE_CALLBACK,
644 struct flashctx *flash, uint8_t status)
645{
646 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
647 msg_perr("Tried to register more than %i chip restore"
648 " functions.\n", CHIP_RESTORE_MAXFN);
649 return 1;
650 }
651 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
652 chip_restore_fn[chip_restore_fn_count].flash = flash;
653 chip_restore_fn[chip_restore_fn_count].status = status;
654 chip_restore_fn_count++;
655
656 return 0;
657}
658
659int chip_restore()
660{
661 int rc = 0;
662
663 while (chip_restore_fn_count > 0) {
664 int i = --chip_restore_fn_count;
665 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
666 chip_restore_fn[i].status);
667 }
668
669 return rc;
670}
671
hailfingerdc6f7972010-02-14 01:20:28 +0000672/* Register a function to be executed on programmer shutdown.
673 * The advantage over atexit() is that you can supply a void pointer which will
674 * be used as parameter to the registered function upon programmer shutdown.
675 * This pointer can point to arbitrary data used by said function, e.g. undo
676 * information for GPIO settings etc. If unneeded, set data=NULL.
677 * Please note that the first (void *data) belongs to the function signature of
678 * the function passed as first parameter.
679 */
David Hendricks93784b42016-08-09 17:00:38 -0700680int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000681{
682 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000683 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000684 SHUTDOWN_MAXFN);
685 return 1;
686 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000687 if (!may_register_shutdown) {
688 msg_perr("Tried to register a shutdown function before "
689 "programmer init.\n");
690 return 1;
691 }
hailfingerdc6f7972010-02-14 01:20:28 +0000692 shutdown_fn[shutdown_fn_count].func = function;
693 shutdown_fn[shutdown_fn_count].data = data;
694 shutdown_fn_count++;
695
696 return 0;
697}
698
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000699int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000700{
hailfinger1ef766d2010-07-06 09:55:48 +0000701 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000702
703 if (prog >= PROGRAMMER_INVALID) {
704 msg_perr("Invalid programmer specified!\n");
705 return -1;
706 }
707 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000708 /* Initialize all programmer specific data. */
709 /* Default to unlimited decode sizes. */
710 max_rom_decode = (const struct decode_sizes) {
711 .parallel = 0xffffffff,
712 .lpc = 0xffffffff,
713 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000714 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000715 };
hailfinger1ff33dc2010-07-03 11:02:10 +0000716 /* Default to top aligned flash at 4 GB. */
717 flashbase = 0;
718 /* Registering shutdown functions is now allowed. */
719 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000720 /* Default to allowing writes. Broken programmers set this to 0. */
721 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000722
723 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000724 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700725 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000726 if (programmer_param && strlen(programmer_param)) {
727 if (ret != 0) {
728 /* It is quite possible that any unhandled programmer parameter would have been valid,
729 * but an error in actual programmer init happened before the parameter was evaluated.
730 */
731 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
732 programmer_param);
733 } else {
734 /* Actual programmer init was successful, but the user specified an invalid or unusable
735 * (for the current programmer configuration) parameter.
736 */
737 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
738 msg_perr("Aborting.\n");
739 ret = ERROR_FATAL;
740 }
741 }
hailfinger1ef766d2010-07-06 09:55:48 +0000742 return ret;
uweabe92a52009-05-16 22:36:00 +0000743}
744
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000745/** Calls registered shutdown functions and resets internal programmer-related variables.
746 * Calling it is safe even without previous initialization, but further interactions with programmer support
747 * require a call to programmer_init() (afterwards).
748 *
749 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700750int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000751{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000752 int ret = 0;
753
hailfinger1ff33dc2010-07-03 11:02:10 +0000754 /* Registering shutdown functions is no longer allowed. */
755 may_register_shutdown = 0;
756 while (shutdown_fn_count > 0) {
757 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700758 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000759 }
Edward O'Callaghancf9c40f2020-10-19 20:02:39 +1100760
761 programmer_param = NULL;
762 registered_master_count = 0;
763
dhendrix0ffc2eb2011-06-14 01:35:36 +0000764 return ret;
uweabe92a52009-05-16 22:36:00 +0000765}
766
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000767void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000768{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000769 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
770 return ret;
uweabe92a52009-05-16 22:36:00 +0000771}
772
773void programmer_unmap_flash_region(void *virt_addr, size_t len)
774{
775 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000776 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000777}
778
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700779void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000780{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100781 flash->mst->par.chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000782}
783
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700784void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000785{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100786 flash->mst->par.chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000787}
788
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700789void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000790{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100791 flash->mst->par.chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000792}
793
Stuart langleyc98e43f2020-03-26 20:27:36 +1100794void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000795{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100796 flash->mst->par.chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000797}
798
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700799uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000800{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100801 return flash->mst->par.chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000802}
803
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700804uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000805{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100806 return flash->mst->par.chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000807}
808
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700809uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000810{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100811 return flash->mst->par.chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000812}
813
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000814void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
815 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000816{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100817 flash->mst->par.chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000818}
819
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000820void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000821{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000822 if (usecs > 0)
823 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000824}
825
Edward O'Callaghana820b212020-09-17 22:53:26 +1000826int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
827 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000828{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700829 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000830
hailfinger23060112009-05-08 12:49:03 +0000831 return 0;
832}
833
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000834/* This is a somewhat hacked function similar in some ways to strtok().
835 * It will look for needle with a subsequent '=' in haystack, return a copy of
836 * needle and remove everything from the first occurrence of needle to the next
837 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000838 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000839char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000840{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000841 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000842 char *opt = NULL;
843 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000844 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000845
hailfingerf4aaccc2010-04-28 15:22:14 +0000846 needlelen = strlen(needle);
847 if (!needlelen) {
848 msg_gerr("%s: empty needle! Please report a bug at "
849 "flashrom@flashrom.org\n", __func__);
850 return NULL;
851 }
852 /* No programmer parameters given. */
853 if (*haystack == NULL)
854 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000855 param_pos = strstr(*haystack, needle);
856 do {
857 if (!param_pos)
858 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000859 /* Needle followed by '='? */
860 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000861 /* Beginning of the string? */
862 if (param_pos == *haystack)
863 break;
864 /* After a delimiter? */
865 if (strchr(delim, *(param_pos - 1)))
866 break;
867 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000868 /* Continue searching. */
869 param_pos++;
870 param_pos = strstr(param_pos, needle);
871 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000872
hailfinger6e5a52a2009-11-24 18:27:10 +0000873 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000874 /* Get the string after needle and '='. */
875 opt_pos = param_pos + needlelen + 1;
876 optlen = strcspn(opt_pos, delim);
877 /* Return an empty string if the parameter was empty. */
878 opt = malloc(optlen + 1);
879 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000880 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000881 exit(1);
882 }
hailfinger1ef766d2010-07-06 09:55:48 +0000883 strncpy(opt, opt_pos, optlen);
884 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000885 rest = opt_pos + optlen;
886 /* Skip all delimiters after the current parameter. */
887 rest += strspn(rest, delim);
888 memmove(param_pos, rest, strlen(rest) + 1);
889 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000890 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000891
hailfinger1ef766d2010-07-06 09:55:48 +0000892 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000893}
894
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000895char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000896{
897 return extract_param(&programmer_param, param_name, ",");
898}
899
stefancte1c5acf2011-07-04 07:27:17 +0000900/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700901static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000902{
903 unsigned int usable_erasefunctions = 0;
904 int k;
905 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
906 if (!check_block_eraser(flash, k, 0))
907 usable_erasefunctions++;
908 }
909 return usable_erasefunctions;
910}
911
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000912static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700913{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000914 int ret = 0, failcount = 0;
915 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700916 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000917 if (wantbuf[i] != havebuf[i]) {
918 /* Only print the first failure. */
919 if (!failcount++)
920 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
921 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700922 }
923 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000924 if (failcount) {
925 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
926 start, start + len - 1, failcount);
927 ret = -1;
928 }
929 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700930}
931
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000932/* start is an offset to the base address of the flash chip */
933static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
934{
935 int ret;
936 uint8_t *cmpbuf = malloc(len);
937 const uint8_t erased_value = ERASED_VALUE(flash);
938
939 if (!cmpbuf) {
940 msg_gerr("Could not allocate memory!\n");
941 exit(1);
942 }
943 memset(cmpbuf, erased_value, len);
944 ret = verify_range(flash, cmpbuf, start, len);
945 free(cmpbuf);
946 return ret;
947}
948
uwee15beb92010-08-08 17:01:18 +0000949/*
hailfinger7af3d192009-11-25 17:05:52 +0000950 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000951 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000952 * @start offset to the base address of the flash chip
953 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000954 * @return 0 for success, -1 for failure
955 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000956int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000957{
hailfinger7af83692009-06-15 17:23:36 +0000958 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000959 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000960
Patrick Georgif3fa2992017-02-02 16:24:44 +0100961 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000962 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000963 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000964 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000965
966 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000967 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000968 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000969 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000970 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000971 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000972
Patrick Georgif3fa2992017-02-02 16:24:44 +0100973 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000974 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000975 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100976 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000977 ret = -1;
978 goto out_free;
979 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700980 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700981 if (programmer_table[programmer].paranoid) {
982 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800983
Simon Glass4e305f42015-01-08 06:29:04 -0700984 /* limit chunksize in order to catch errors early */
985 for (i = 0, chunksize = 0; i < len; i += chunksize) {
986 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800987
Patrick Georgif3fa2992017-02-02 16:24:44 +0100988 chunksize = min(flash->chip->page_size, len - i);
989 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700990 if (tmp) {
991 ret = tmp;
992 if (ignore_error(tmp))
993 continue;
994 else
995 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800996 }
Simon Glass4e305f42015-01-08 06:29:04 -0700997
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700998 /*
999 * Check write access permission and do not compare chunks
1000 * where flashrom does not have write access to the region.
1001 */
1002 if (flash->chip->check_access) {
1003 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
1004 if (tmp && ignore_error(tmp))
1005 continue;
1006 }
1007
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001008 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -07001009 if (failcount)
1010 break;
David Hendricks1ed1d352011-11-23 17:54:37 -08001011 }
Simon Glass4e305f42015-01-08 06:29:04 -07001012 } else {
1013 int tmp;
1014
1015 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +01001016 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -07001017 if (tmp && !ignore_error(tmp)) {
1018 ret = tmp;
1019 goto out_free;
1020 }
1021
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001022 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +00001023 }
1024
hailfinger5be6c0f2009-07-23 01:42:56 +00001025 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +00001026 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +00001027 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +00001028 ret = -1;
1029 }
hailfinger7af83692009-06-15 17:23:36 +00001030
1031out_free:
1032 free(readbuf);
1033 return ret;
1034}
1035
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001036/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1037static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001038 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001039{
1040 unsigned int i, j, limit;
1041 for (j = 0; j < len / gran; j++) {
1042 limit = min (gran, len - j * gran);
1043 /* Are 'have' and 'want' identical? */
1044 if (!memcmp(have + j * gran, want + j * gran, limit))
1045 continue;
1046 /* have needs to be in erased state. */
1047 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001048 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001049 return 1;
1050 }
1051 return 0;
1052}
1053
uwee15beb92010-08-08 17:01:18 +00001054/*
hailfingerb247c7a2010-03-08 00:42:32 +00001055 * Check if the buffer @have can be programmed to the content of @want without
1056 * erasing. This is only possible if all chunks of size @gran are either kept
1057 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001058 *
hailfingerb437e282010-11-04 01:04:27 +00001059 * Warning: This function assumes that @have and @want point to naturally
1060 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001061 *
1062 * @have buffer with current content
1063 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001064 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001065 * @gran write granularity (enum, not count)
1066 * @return 0 if no erase is needed, 1 otherwise
1067 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001068int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1069 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001070{
hailfingerb91c08c2011-08-15 19:54:20 +00001071 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001072 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001073
hailfingerb247c7a2010-03-08 00:42:32 +00001074 switch (gran) {
1075 case write_gran_1bit:
1076 for (i = 0; i < len; i++)
1077 if ((have[i] & want[i]) != want[i]) {
1078 result = 1;
1079 break;
1080 }
1081 break;
1082 case write_gran_1byte:
1083 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001084 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001085 result = 1;
1086 break;
1087 }
1088 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001089 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001090 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001091 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001092 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001093 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001094 break;
1095 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001096 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001097 break;
1098 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001099 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001100 break;
1101 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001102 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001103 break;
1104 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001105 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001106 break;
1107 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001108 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001109 break;
1110 case write_gran_1byte_implicit_erase:
1111 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1112 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001113 break;
hailfingerb437e282010-11-04 01:04:27 +00001114 default:
1115 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1116 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001117 }
1118 return result;
1119}
1120
hailfingerb437e282010-11-04 01:04:27 +00001121/**
1122 * Check if the buffer @have needs to be programmed to get the content of @want.
1123 * If yes, return 1 and fill in first_start with the start address of the
1124 * write operation and first_len with the length of the first to-be-written
1125 * chunk. If not, return 0 and leave first_start and first_len undefined.
1126 *
1127 * Warning: This function assumes that @have and @want point to naturally
1128 * aligned regions.
1129 *
1130 * @have buffer with current content
1131 * @want buffer with desired content
1132 * @len length of the checked area
1133 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001134 * @first_start offset of the first byte which needs to be written (passed in
1135 * value is increased by the offset of the first needed write
1136 * relative to have/want or unchanged if no write is needed)
1137 * @return length of the first contiguous area which needs to be written
1138 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001139 *
1140 * FIXME: This function needs a parameter which tells it about coalescing
1141 * in relation to the max write length of the programmer and the max write
1142 * length of the chip.
1143 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001144static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001145 unsigned int *first_start,
1146 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001147{
stefanctc5eb8a92011-11-23 09:13:48 +00001148 int need_write = 0;
1149 unsigned int rel_start = 0, first_len = 0;
1150 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001151
hailfingerb437e282010-11-04 01:04:27 +00001152 switch (gran) {
1153 case write_gran_1bit:
1154 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001155 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001156 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001157 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001158 case write_gran_128bytes:
1159 stride = 128;
1160 break;
hailfingerb437e282010-11-04 01:04:27 +00001161 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001162 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001163 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001164 case write_gran_264bytes:
1165 stride = 264;
1166 break;
1167 case write_gran_512bytes:
1168 stride = 512;
1169 break;
1170 case write_gran_528bytes:
1171 stride = 528;
1172 break;
1173 case write_gran_1024bytes:
1174 stride = 1024;
1175 break;
1176 case write_gran_1056bytes:
1177 stride = 1056;
1178 break;
hailfingerb437e282010-11-04 01:04:27 +00001179 default:
1180 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1181 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001182 /* Claim that no write was needed. A write with unknown
1183 * granularity is too dangerous to try.
1184 */
1185 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001186 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001187 for (i = 0; i < len / stride; i++) {
1188 limit = min(stride, len - i * stride);
1189 /* Are 'have' and 'want' identical? */
1190 if (memcmp(have + i * stride, want + i * stride, limit)) {
1191 if (!need_write) {
1192 /* First location where have and want differ. */
1193 need_write = 1;
1194 rel_start = i * stride;
1195 }
1196 } else {
1197 if (need_write) {
1198 /* First location where have and want
1199 * do not differ anymore.
1200 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001201 break;
1202 }
1203 }
1204 }
hailfingerffb7f382010-12-06 13:05:44 +00001205 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001206 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001207 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001208 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001209}
1210
hailfinger0c515352009-11-23 12:55:31 +00001211/* This function generates various test patterns useful for testing controller
1212 * and chip communication as well as chip behaviour.
1213 *
1214 * If a byte can be written multiple times, each time keeping 0-bits at 0
1215 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1216 * is essentially an AND operation. That's also the reason why this function
1217 * provides the result of AND between various patterns.
1218 *
1219 * Below is a list of patterns (and their block length).
1220 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1221 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1222 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1223 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1224 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1225 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1226 * Pattern 6 is 00 (1 Byte)
1227 * Pattern 7 is ff (1 Byte)
1228 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1229 * byte block.
1230 *
1231 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1232 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1233 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1234 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1235 * Pattern 12 is 00 (1 Byte)
1236 * Pattern 13 is ff (1 Byte)
1237 * Patterns 8-13 have no block number.
1238 *
1239 * Patterns 0-3 are created to detect and efficiently diagnose communication
1240 * slips like missed bits or bytes and their repetitive nature gives good visual
1241 * cues to the person inspecting the results. In addition, the following holds:
1242 * AND Pattern 0/1 == Pattern 4
1243 * AND Pattern 2/3 == Pattern 5
1244 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1245 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1246 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1247 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1248 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1249 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1250 * Besides that, they provide for bit testing of the last two bytes of every
1251 * 256 byte block which contains the block number for patterns 0-6.
1252 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1253 * block sizes >256 bytes (some Dataflash chips etc.)
1254 * AND Pattern 8/9 == Pattern 12
1255 * AND Pattern 10/11 == Pattern 12
1256 * Pattern 13 is the completely erased state.
1257 * None of the patterns can detect aliasing at boundaries which are a multiple
1258 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1259 */
1260int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1261{
1262 int i;
1263
1264 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001265 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001266 return 1;
1267 }
1268
1269 switch (variant) {
1270 case 0:
1271 for (i = 0; i < size; i++)
1272 buf[i] = (i & 0xf) << 4 | 0x5;
1273 break;
1274 case 1:
1275 for (i = 0; i < size; i++)
1276 buf[i] = (i & 0xf) << 4 | 0xa;
1277 break;
1278 case 2:
1279 for (i = 0; i < size; i++)
1280 buf[i] = 0x50 | (i & 0xf);
1281 break;
1282 case 3:
1283 for (i = 0; i < size; i++)
1284 buf[i] = 0xa0 | (i & 0xf);
1285 break;
1286 case 4:
1287 for (i = 0; i < size; i++)
1288 buf[i] = (i & 0xf) << 4;
1289 break;
1290 case 5:
1291 for (i = 0; i < size; i++)
1292 buf[i] = i & 0xf;
1293 break;
1294 case 6:
1295 memset(buf, 0x00, size);
1296 break;
1297 case 7:
1298 memset(buf, 0xff, size);
1299 break;
1300 case 8:
1301 for (i = 0; i < size; i++)
1302 buf[i] = i & 0xff;
1303 break;
1304 case 9:
1305 for (i = 0; i < size; i++)
1306 buf[i] = ~(i & 0xff);
1307 break;
1308 case 10:
1309 for (i = 0; i < size % 2; i++) {
1310 buf[i * 2] = (i >> 8) & 0xff;
1311 buf[i * 2 + 1] = i & 0xff;
1312 }
1313 if (size & 0x1)
1314 buf[i * 2] = (i >> 8) & 0xff;
1315 break;
1316 case 11:
1317 for (i = 0; i < size % 2; i++) {
1318 buf[i * 2] = ~((i >> 8) & 0xff);
1319 buf[i * 2 + 1] = ~(i & 0xff);
1320 }
1321 if (size & 0x1)
1322 buf[i * 2] = ~((i >> 8) & 0xff);
1323 break;
1324 case 12:
1325 memset(buf, 0x00, size);
1326 break;
1327 case 13:
1328 memset(buf, 0xff, size);
1329 break;
1330 }
1331
1332 if ((variant >= 0) && (variant <= 7)) {
1333 /* Write block number in the last two bytes of each 256-byte
1334 * block, big endian for easier reading of the hexdump.
1335 * Note that this wraps around for chips larger than 2^24 bytes
1336 * (16 MB).
1337 */
1338 for (i = 0; i < size / 256; i++) {
1339 buf[i * 256 + 254] = (i >> 8) & 0xff;
1340 buf[i * 256 + 255] = i & 0xff;
1341 }
1342 }
1343
1344 return 0;
1345}
1346
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001347/* Returns the number of busses commonly supported by the current programmer and flash chip where the latter
1348 * can not be completely accessed due to size/address limits of the programmer. */
1349unsigned int count_max_decode_exceedings(const struct flashctx *flash)
hailfingeraec9c962009-10-31 01:53:09 +00001350{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001351 unsigned int limitexceeded = 0;
1352 uint32_t size = flash->chip->total_size * 1024;
1353 enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
uwe8d342eb2011-07-28 08:13:25 +00001354
1355 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001356 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001357 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001358 "size %u kB of chipset/board/programmer "
1359 "for %s interface, "
1360 "probe/read/erase/write may fail. ", size / 1024,
1361 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001362 }
hailfingere1e41ea2011-07-27 07:13:06 +00001363 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001364 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001365 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001366 "size %u kB of chipset/board/programmer "
1367 "for %s interface, "
1368 "probe/read/erase/write may fail. ", size / 1024,
1369 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001370 }
hailfingere1e41ea2011-07-27 07:13:06 +00001371 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001372 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001373 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001374 "size %u kB of chipset/board/programmer "
1375 "for %s interface, "
1376 "probe/read/erase/write may fail. ", size / 1024,
1377 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001378 }
hailfingere1e41ea2011-07-27 07:13:06 +00001379 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001380 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001381 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001382 "size %u kB of chipset/board/programmer "
1383 "for %s interface, "
1384 "probe/read/erase/write may fail. ", size / 1024,
1385 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001386 }
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001387 return limitexceeded;
hailfingeraec9c962009-10-31 01:53:09 +00001388}
1389
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001390void unmap_flash(struct flashctx *flash)
1391{
1392 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1393 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1394 flash->physical_registers = 0;
1395 flash->virtual_registers = (chipaddr)ERROR_PTR;
1396 }
1397
1398 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1399 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1400 flash->physical_memory = 0;
1401 flash->virtual_memory = (chipaddr)ERROR_PTR;
1402 }
1403}
1404
1405int map_flash(struct flashctx *flash)
1406{
1407 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1408 flash->virtual_memory = (chipaddr)ERROR_PTR;
1409 flash->virtual_registers = (chipaddr)ERROR_PTR;
1410
1411 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1412 * These are used for various probing-related hacks that would not map successfully anyway and should be
1413 * removed ASAP. */
1414 if (flash->chip->total_size == 0)
1415 return 0;
1416
1417 const chipsize_t size = flash->chip->total_size * 1024;
1418 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1419 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1420 if (addr == ERROR_PTR) {
1421 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1422 flash->chip->name, PRIxPTR_WIDTH, base);
1423 return 1;
1424 }
1425 flash->physical_memory = base;
1426 flash->virtual_memory = (chipaddr)addr;
1427
1428 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1429 * completely different on some chips and programmers, or not mappable at all.
1430 * Ignore these problems for now and always report success. */
1431 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1432 base = 0xffffffff - size - 0x400000 + 1;
1433 addr = programmer_map_flash_region("flash chip registers", base, size);
1434 if (addr == ERROR_PTR) {
1435 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1436 flash->chip->name, PRIxPTR_WIDTH, base);
1437 return 0;
1438 }
1439 flash->physical_registers = base;
1440 flash->virtual_registers = (chipaddr)addr;
1441 }
1442 return 0;
1443}
1444
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001445/*
1446 * Return a string corresponding to the bustype parameter.
1447 * Memory is obtained with malloc() and must be freed with free() by the caller.
1448 */
1449char *flashbuses_to_text(enum chipbustype bustype)
1450{
1451 char *ret = calloc(1, 1);
1452 /*
1453 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1454 * will cease to exist and should be eliminated here as well.
1455 */
1456 if (bustype == BUS_NONSPI) {
1457 ret = strcat_realloc(ret, "Non-SPI, ");
1458 } else {
1459 if (bustype & BUS_PARALLEL)
1460 ret = strcat_realloc(ret, "Parallel, ");
1461 if (bustype & BUS_LPC)
1462 ret = strcat_realloc(ret, "LPC, ");
1463 if (bustype & BUS_FWH)
1464 ret = strcat_realloc(ret, "FWH, ");
1465 if (bustype & BUS_SPI)
1466 ret = strcat_realloc(ret, "SPI, ");
1467 if (bustype & BUS_PROG)
1468 ret = strcat_realloc(ret, "Programmer-specific, ");
1469 if (bustype == BUS_NONE)
1470 ret = strcat_realloc(ret, "None, ");
1471 }
1472 /* Kill last comma. */
1473 ret[strlen(ret) - 2] = '\0';
1474 ret = realloc(ret, strlen(ret) + 1);
1475 return ret;
1476}
1477
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001478int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001479{
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001480 const struct flashchip *chip;
hailfingeraec9c962009-10-31 01:53:09 +00001481 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001482 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001483
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001484 for (chip = flashchips + startchip; chip && chip->name; chip++) {
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001485 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001486 continue;
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001487 buses_common = mst->buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001488 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001489 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001490 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001491 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001492 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001493 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001494 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001495 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001496 continue;
1497 }
stepan782fb172007-04-06 11:58:03 +00001498
hailfinger48ed3e22011-05-04 00:39:50 +00001499 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001500 flash->chip = calloc(1, sizeof(struct flashchip));
1501 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001502 msg_gerr("Out of memory!\n");
1503 exit(1);
1504 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001505 memcpy(flash->chip, chip, sizeof(struct flashchip));
1506 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001507
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001508 if (map_flash(flash) != 0)
1509 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001510
Edward O'Callaghana820b212020-09-17 22:53:26 +10001511 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1512 * is only called with force=1 after normal probing failed.
1513 */
stugec1e55fe2008-07-02 17:15:47 +00001514 if (force)
1515 break;
stepanc98b80b2006-03-16 16:57:41 +00001516
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001517 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001518 goto notfound;
1519
hailfinger48ed3e22011-05-04 00:39:50 +00001520 /* If this is the first chip found, accept it.
1521 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001522 * a non-generic match. SFDP and CFI are generic matches.
1523 * startchip==0 means this call to probe_flash() is the first
1524 * one for this programmer interface (master) and thus no other chip has
1525 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001526 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001527 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1528 msg_cinfo("===\n"
1529 "SFDP has autodetected a flash chip which is "
1530 "not natively supported by flashrom yet.\n");
1531 if (count_usable_erasers(flash) == 0)
1532 msg_cinfo("The standard operations read and "
1533 "verify should work, but to support "
1534 "erase, write and all other "
1535 "possible features");
1536 else
1537 msg_cinfo("All standard operations (read, "
1538 "verify, erase and write) should "
1539 "work, but to support all possible "
1540 "features");
1541
1542 msg_cinfo(" we need to add them manually.\n"
1543 "You can help us by mailing us the output of the following command to "
1544 "flashrom@flashrom.org:\n"
1545 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1546 "Thanks for your help!\n"
1547 "===\n");
1548 }
stugec1e55fe2008-07-02 17:15:47 +00001549
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001550 /* First flash chip detected on this bus. */
1551 if (startchip == 0)
1552 break;
1553 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001554 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001555 break;
1556 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001557notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001558 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001559 free(flash->chip);
1560 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001561 }
uwebe4477b2007-08-23 16:08:21 +00001562
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001563 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001564 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001565
stepan3e7aeae2011-01-19 06:21:54 +00001566
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001567 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001568 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1569 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001570 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001571#if CONFIG_INTERNAL == 1
1572 if (programmer_table[programmer].map_flash_region == physmap)
1573 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1574 PRIxPTR_WIDTH, flash->physical_memory);
1575 else
1576#endif
1577 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001578
Edward O'Callaghana820b212020-09-17 22:53:26 +10001579 /* Flash registers may more likely not be mapped if the chip was forced.
1580 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001581 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001582 if (flash->chip->printlock)
1583 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001584
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001585 /* Get out of the way for later runs. */
1586 unmap_flash(flash);
1587
hailfinger48ed3e22011-05-04 00:39:50 +00001588 /* Return position of matching chip. */
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001589 return chip - flashchips;
rminnich8d3ff912003-10-25 17:01:29 +00001590}
1591
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001592static int verify_flash(struct flashctx *flash,
1593 struct action_descriptor *descriptor,
1594 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001595{
hailfingerb0f4d122009-06-24 08:20:45 +00001596 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001597 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001598 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001599
snelsone42c3802010-05-07 20:09:04 +00001600 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001601
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001602 if (verify_it == VERIFY_PARTIAL) {
1603 struct processing_unit *pu = descriptor->processing_units;
1604
1605 /* Verify only areas which were written. */
1606 while (pu->num_blocks) {
1607 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001608 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001609 if (ret)
1610 break;
1611 pu++;
1612 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001613 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001614 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001615 }
uwef6641642007-05-09 10:17:44 +00001616
David Hendricks1ed1d352011-11-23 17:54:37 -08001617 if (ret == ACCESS_DENIED) {
1618 msg_gdbg("Could not fully verify due to access error, ");
1619 if (access_denied_action == error_ignore) {
1620 msg_gdbg("ignoring\n");
1621 ret = 0;
1622 } else {
1623 msg_gdbg("aborting\n");
1624 }
1625 }
1626
hailfingerb0f4d122009-06-24 08:20:45 +00001627 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001628 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001629
hailfingerb0f4d122009-06-24 08:20:45 +00001630 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001631}
1632
uwe8d342eb2011-07-28 08:13:25 +00001633int read_buf_from_file(unsigned char *buf, unsigned long size,
1634 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001635{
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001636 unsigned long numbytes;
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001637 FILE *image;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001638 struct stat image_stat;
1639
1640 if (!strncmp(filename, "-", sizeof("-")))
1641 image = fdopen(STDIN_FILENO, "rb");
1642 else
1643 image = fopen(filename, "rb");
1644 if (image == NULL) {
1645 perror(filename);
hailfinger771fc182010-10-15 00:01:14 +00001646 return 1;
1647 }
1648 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001649 perror(filename);
1650 fclose(image);
1651 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001652 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001653 if ((image_stat.st_size != size) &&
1654 (strncmp(filename, "-", sizeof("-")))) {
1655 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1656 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
1657 fclose(image);
1658 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001659 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001660 numbytes = fread(buf, 1, size, image);
1661 if (fclose(image)) {
1662 perror(filename);
1663 return 1;
1664 }
hailfinger771fc182010-10-15 00:01:14 +00001665 if (numbytes != size) {
1666 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1667 "wanted %ld!\n", numbytes, size);
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001668 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001669 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001670 return 0;
hailfinger771fc182010-10-15 00:01:14 +00001671}
1672
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001673int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001674{
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001675 unsigned long numbytes;
hailfingerd219a232009-01-28 00:27:54 +00001676 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001677
1678 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001679 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001680 return 1;
1681 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001682 if (!strncmp(filename, "-", sizeof("-")))
1683 image = fdopen(STDOUT_FILENO, "wb");
1684 else
1685 image = fopen(filename, "wb");
1686 if (image == NULL) {
1687 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001688 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001689 }
hailfingerd219a232009-01-28 00:27:54 +00001690
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001691 numbytes = fwrite(buf, 1, size, image);
1692 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001693 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001694 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001695 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001696 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001697 return 0;
hailfingerd219a232009-01-28 00:27:54 +00001698}
1699
David Hendrickse3451942013-03-21 17:23:29 -07001700/*
1701 * read_flash - wrapper for flash->read() with additional high-level policy
1702 *
1703 * @flash flash chip
1704 * @buf buffer to store data in
1705 * @start start address
1706 * @len number of bytes to read
1707 *
1708 * This wrapper simplifies most cases when the flash chip needs to be read
1709 * since policy decisions such as non-fatal error handling is centralized.
1710 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001711int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001712 unsigned int start, unsigned int len)
1713{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001714 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001715
Patrick Georgif3fa2992017-02-02 16:24:44 +01001716 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001717 return -1;
1718
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001719 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1720
Patrick Georgif3fa2992017-02-02 16:24:44 +01001721 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001722 if (ret) {
1723 if (ignore_error(ret)) {
1724 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1725 start, start + len - 1);
1726 ret = 0;
1727 } else {
1728 msg_gdbg("failed to read 0x%x-0x%x\n",
1729 start, start + len - 1);
1730 }
1731 }
1732
1733 return ret;
1734}
1735
David Hendricks7c8a1612013-04-26 19:14:44 -07001736/*
1737 * write_flash - wrapper for flash->write() with additional high-level policy
1738 *
1739 * @flash flash chip
1740 * @buf buffer to write to flash
1741 * @start start address in flash
1742 * @len number of bytes to write
1743 *
1744 * TODO: Look up regions that are write-protected and avoid attempt to write
1745 * to them at all.
1746 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001747int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001748 unsigned int start, unsigned int len)
1749{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001750 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001751 return -1;
1752
Patrick Georgif3fa2992017-02-02 16:24:44 +01001753 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001754}
1755
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001756int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001757{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001758 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001759 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001760 int ret = 0;
1761
1762 msg_cinfo("Reading flash... ");
1763 if (!buf) {
1764 msg_gerr("Memory allocation failed!\n");
1765 msg_cinfo("FAILED.\n");
1766 return 1;
1767 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001768
1769 /* To support partial read, fill buffer to all 0xFF at beginning to make
1770 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001771 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001772
Patrick Georgif3fa2992017-02-02 16:24:44 +01001773 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001774 msg_cerr("No read function available for this flash chip.\n");
1775 ret = 1;
1776 goto out_free;
1777 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001778
1779 /* First try to handle partial read case, rather than read the whole
1780 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001781 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001782 if (ret < 0) {
1783 msg_cerr("Partial read operation failed!\n");
1784 ret = 1;
1785 goto out_free;
1786 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001787 int num_regions = get_num_include_args();
1788
1789 if (ret != num_regions) {
1790 msg_cerr("Requested %d regions, but only read %d\n",
1791 num_regions, ret);
1792 ret = 1;
1793 goto out_free;
1794 }
1795
1796 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001797 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001798 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001799 msg_cerr("Read operation failed!\n");
1800 ret = 1;
1801 goto out_free;
1802 }
hailfinger42a850a2010-07-13 23:56:13 +00001803 }
1804
David Hendricksdf29a832013-06-28 14:33:51 -07001805 if (filename)
1806 ret = write_buf_to_file(buf, size, filename);
1807
hailfinger42a850a2010-07-13 23:56:13 +00001808out_free:
1809 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001810 if (ret)
1811 msg_cerr("FAILED.");
1812 else
1813 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001814 return ret;
1815}
1816
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001817/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001818static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001819{
hailfingerb91c08c2011-08-15 19:54:20 +00001820 int i, j, k;
1821 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001822
1823 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1824 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001825 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001826
1827 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1828 /* Blocks with zero size are bugs in flashchips.c. */
1829 if (eraser.eraseblocks[i].count &&
1830 !eraser.eraseblocks[i].size) {
1831 msg_gerr("ERROR: Flash chip %s erase function "
1832 "%i region %i has size 0. Please report"
1833 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001834 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001835 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001836 }
1837 /* Blocks with zero count are bugs in flashchips.c. */
1838 if (!eraser.eraseblocks[i].count &&
1839 eraser.eraseblocks[i].size) {
1840 msg_gerr("ERROR: Flash chip %s erase function "
1841 "%i region %i has count 0. Please report"
1842 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001843 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001844 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001845 }
1846 done += eraser.eraseblocks[i].count *
1847 eraser.eraseblocks[i].size;
1848 }
hailfinger9fed35d2010-01-19 06:42:46 +00001849 /* Empty eraseblock definition with erase function. */
1850 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001851 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001852 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001853 if (!done)
1854 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001855 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001856 msg_gerr("ERROR: Flash chip %s erase function %i "
1857 "region walking resulted in 0x%06x bytes total,"
1858 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001859 " flashrom@flashrom.org\n", chip->name, k,
1860 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001861 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001862 }
hailfinger9fed35d2010-01-19 06:42:46 +00001863 if (!eraser.block_erase)
1864 continue;
1865 /* Check if there are identical erase functions for different
1866 * layouts. That would imply "magic" erase functions. The
1867 * easiest way to check this is with function pointers.
1868 */
uwef6f94d42010-03-13 17:28:29 +00001869 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001870 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001871 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001872 msg_gerr("ERROR: Flash chip %s erase function "
1873 "%i and %i are identical. Please report"
1874 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001875 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001876 ret = 1;
1877 }
uwef6f94d42010-03-13 17:28:29 +00001878 }
hailfinger45177872010-01-18 08:14:43 +00001879 }
hailfinger9fed35d2010-01-19 06:42:46 +00001880 return ret;
hailfinger45177872010-01-18 08:14:43 +00001881}
1882
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001883static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001884 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001885 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001886 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001887 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001888 unsigned int addr,
1889 unsigned int len))
1890{
stefanctc5eb8a92011-11-23 09:13:48 +00001891 unsigned int starthere = 0, lenhere = 0;
1892 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001893 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001894 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001895
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001896 /*
1897 * curcontents and newcontents are opaque to walk_eraseregions, and
1898 * need to be adjusted here to keep the impression of proper
1899 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001900 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001901
hailfinger90fcf9b2010-11-05 14:51:59 +00001902 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001903
hailfingerb437e282010-11-04 01:04:27 +00001904 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001905
hailfingerb437e282010-11-04 01:04:27 +00001906 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001907 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001908 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001909 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001910 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001911 if (ret) {
1912 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001913 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001914 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001915 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001916 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001917 }
1918
David Hendricks0954ffc2015-11-13 15:15:44 -08001919 if (programmer_table[programmer].paranoid) {
1920 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001921 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001922 return -1;
1923 }
hailfingerac8e3182011-06-26 17:04:16 +00001924 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001925
hailfinger90fcf9b2010-11-05 14:51:59 +00001926 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001927 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001928 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001929 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001930 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001931 /* get_next_write() sets starthere to a new value after the call. */
1932 while ((lenhere = get_next_write(curcontents + starthere,
1933 newcontents + starthere,
1934 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001935 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001936 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001937 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001938 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001939 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001940 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001941 if (ret) {
1942 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001943 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001944 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001945 }
David Hendricks048b38c2016-03-28 18:47:06 -07001946
1947 /*
1948 * If the block needed to be erased and was erased successfully
1949 * then we can assume that we didn't run into any write-
1950 * protected areas. Otherwise, we need to verify each page to
1951 * ensure it was successfully written and abort if we encounter
1952 * any errors.
1953 */
1954 if (programmer_table[programmer].paranoid && !block_was_erased) {
1955 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001956 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001957 return -1;
1958 }
1959
hailfingerb437e282010-11-04 01:04:27 +00001960 starthere += lenhere;
1961 skip = 0;
1962 }
1963 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001964 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001965 return ret;
1966}
1967
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001968/*
1969 * Function to process processing units accumulated in the action descriptor.
1970 *
1971 * @flash pointer to the flash context to operate on
1972 * @do_something helper function which can erase and program a section of the
1973 * flash chip. It receives the flash context, offset and length
1974 * of the area to erase/program, before and after contents (to
1975 * decide what exactly needs to be erased and or programmed)
1976 * and a pointer to the erase function which can operate on the
1977 * proper granularity.
1978 * @descriptor action descriptor including pointers to before and after
1979 * contents and an array of processing actions to take.
1980 *
1981 * Returns zero on success or an error code.
1982 */
1983static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001984 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001985 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001986 unsigned int len,
1987 uint8_t *param1,
1988 uint8_t *param2,
1989 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001990 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001991 unsigned int addr,
1992 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001993 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00001994{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001995 struct processing_unit *pu;
1996 int rc = 0;
1997 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00001998
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001999 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
2000 unsigned base = pu->offset;
2001 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07002002
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002003 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07002004
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002005 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00002006 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002007 else
2008 print_comma = 1;
2009
2010 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
2011
2012 rc = do_something(flash, base,
2013 pu->block_size,
2014 descriptor->oldcontents,
2015 descriptor->newcontents,
2016 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
2017
David Hendricks1ed1d352011-11-23 17:54:37 -08002018 if (rc) {
2019 if (ignore_error(rc))
2020 rc = 0;
2021 else
2022 return rc;
hailfingerb437e282010-11-04 01:04:27 +00002023 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002024 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00002025 }
2026 }
hailfingerb437e282010-11-04 01:04:27 +00002027 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08002028 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00002029}
2030
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002031static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00002032{
Patrick Georgif3fa2992017-02-02 16:24:44 +01002033 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00002034
2035 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
2036 if (log)
2037 msg_cdbg("not defined. ");
2038 return 1;
2039 }
2040 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
2041 if (log)
2042 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00002043 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00002044 return 1;
2045 }
2046 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
2047 if (log)
2048 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00002049 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00002050 return 1;
2051 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002052 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002053 return 0;
2054}
2055
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002056int erase_and_write_flash(struct flashctx *flash,
2057 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002058{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002059 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002060
hailfingercf848f12010-12-05 15:14:44 +00002061 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002062
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002063 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002064
hailfinger7df21362009-09-05 02:30:58 +00002065 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002066 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002067 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002068 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002069 }
2070 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002071}
2072
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002073static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002074{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002075 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2076#if CONFIG_INTERNAL == 1
2077 if (programmer == PROGRAMMER_INTERNAL)
2078 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2079 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2080 "mail flashrom@flashrom.org, thanks!\n"
2081 "-------------------------------------------------------------------------------\n"
2082 "You may now reboot or simply leave the machine running.\n");
2083 else
2084#endif
2085 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2086 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2087 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2088 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002089}
2090
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002091static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002092{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002093 msg_gerr("Your flash chip is in an unknown state.\n");
2094#if CONFIG_INTERNAL == 1
2095 if (programmer == PROGRAMMER_INTERNAL)
2096 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2097 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2098 "-------------------------------------------------------------------------------\n"
2099 "DO NOT REBOOT OR POWEROFF!\n");
2100 else
2101#endif
2102 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2103 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002104}
2105
hailfingerf79d1712010-10-06 23:48:34 +00002106void list_programmers_linebreak(int startcol, int cols, int paren)
2107{
2108 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002109 int pnamelen;
2110 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002111 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002112 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002113
2114 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2115 pname = programmer_table[p].name;
2116 pnamelen = strlen(pname);
2117 if (remaining - pnamelen - 2 < 0) {
2118 if (firstline)
2119 firstline = 0;
2120 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002121 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002122 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002123 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002124 remaining = cols - startcol;
2125 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002126 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002127 remaining--;
2128 }
2129 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002130 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002131 remaining--;
2132 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002133 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002134 remaining -= pnamelen;
2135 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002136 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002137 remaining--;
2138 } else {
2139 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002140 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002141 }
2142 }
2143}
2144
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002145static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002146{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002147#if IS_WINDOWS
2148 SYSTEM_INFO si;
2149 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002150
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002151 memset(&si, 0, sizeof(SYSTEM_INFO));
2152 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2153 msg_ginfo(" on Windows");
2154 /* Tell Windows which version of the structure we want. */
2155 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2156 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2157 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2158 else
2159 msg_ginfo(" unknown version");
2160 GetSystemInfo(&si);
2161 switch (si.wProcessorArchitecture) {
2162 case PROCESSOR_ARCHITECTURE_AMD64:
2163 msg_ginfo(" (x86_64)");
2164 break;
2165 case PROCESSOR_ARCHITECTURE_INTEL:
2166 msg_ginfo(" (x86)");
2167 break;
2168 default:
2169 msg_ginfo(" (unknown arch)");
2170 break;
2171 }
2172#elif HAVE_UTSNAME == 1
2173 struct utsname osinfo;
2174
2175 uname(&osinfo);
2176 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002177 osinfo.machine);
2178#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002179 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002180#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002181}
2182
2183void print_buildinfo(void)
2184{
2185 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002186#if NEED_PCI == 1
2187#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002188 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002189#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002190 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002191#endif
2192#endif
2193#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002194 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002195#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002196 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002197#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002198 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002199#endif
hailfinger3b471632010-03-27 16:36:40 +00002200#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002201 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002202#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002203 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002204#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002205 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002206#endif
2207#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002208 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002209#endif
2210#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002211 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00002212#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002213 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00002214#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002215 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002216}
2217
uwefdeca092008-01-21 15:24:22 +00002218void print_version(void)
2219{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002220 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002221 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002222 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002223}
2224
hailfinger74819ad2010-05-15 15:04:37 +00002225void print_banner(void)
2226{
2227 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002228 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002229 msg_ginfo("\n");
2230}
2231
hailfingerc77acb52009-12-24 02:15:55 +00002232int selfcheck(void)
2233{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002234 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002235 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002236
2237 /* Safety check. Instead of aborting after the first error, check
2238 * if more errors exist.
2239 */
hailfingerc77acb52009-12-24 02:15:55 +00002240 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002241 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002242 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002243 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002244 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2245 const struct programmer_entry p = programmer_table[i];
2246 if (p.name == NULL) {
2247 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2248 ret = 1;
2249 /* This might hide other problems with this programmer, but allows for better error
2250 * messages below without jumping through hoops. */
2251 continue;
2252 }
2253 switch (p.type) {
2254 case USB:
2255 case PCI:
2256 case OTHER:
2257 if (p.devs.note == NULL) {
2258 if (strcmp("internal", p.name) == 0)
2259 break; /* This one has its device list stored separately. */
2260 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2261 p.name);
2262 ret = 1;
2263 }
2264 break;
2265 default:
2266 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2267 ret = 1;
2268 break;
2269 }
2270 if (p.init == NULL) {
2271 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2272 ret = 1;
2273 }
2274 if (p.delay == NULL) {
2275 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2276 ret = 1;
2277 }
2278 if (p.map_flash_region == NULL) {
2279 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2280 ret = 1;
2281 }
2282 if (p.unmap_flash_region == NULL) {
2283 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2284 ret = 1;
2285 }
2286 }
2287
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002288 /* It would be favorable if we could check for the correct layout (especially termination) of various
2289 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2290 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2291 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2292 * 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 +10002293 * checks below. */
2294 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002295 msg_gerr("Flashchips table miscompilation!\n");
2296 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002297 } else {
2298 for (i = 0; i < flashchips_size - 1; i++) {
2299 const struct flashchip *chip = &flashchips[i];
2300 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2301 ret = 1;
2302 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2303 "Please report a bug at flashrom@flashrom.org\n", i,
2304 chip->name == NULL ? "unnamed" : chip->name);
2305 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002306 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002307 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002308 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002309 }
stefanct6d836ba2011-05-26 01:35:19 +00002310 }
stefanct6d836ba2011-05-26 01:35:19 +00002311
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002312 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002313 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002314}
2315
hailfinger771fc182010-10-15 00:01:14 +00002316/* FIXME: This function signature needs to be improved once doit() has a better
2317 * function signature.
2318 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002319static int chip_safety_check(const struct flashctx *flash, int force,
2320 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002321{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002322 const struct flashchip *chip = flash->chip;
2323
hailfinger771fc182010-10-15 00:01:14 +00002324 if (!programmer_may_write && (write_it || erase_it)) {
2325 msg_perr("Write/erase is not working yet on your programmer in "
2326 "its current configuration.\n");
2327 /* --force is the wrong approach, but it's the best we can do
2328 * until the generic programmer parameter parser is merged.
2329 */
2330 if (!force)
2331 return 1;
2332 msg_cerr("Continuing anyway.\n");
2333 }
2334
2335 if (read_it || erase_it || write_it || verify_it) {
2336 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002337 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002338 msg_cerr("Read is not working on this chip. ");
2339 if (!force)
2340 return 1;
2341 msg_cerr("Continuing anyway.\n");
2342 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002343 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002344 msg_cerr("flashrom has no read function for this "
2345 "flash chip.\n");
2346 return 1;
2347 }
2348 }
2349 if (erase_it || write_it) {
2350 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002351 if (chip->tested.erase == NA) {
2352 msg_cerr("Erase is not possible on this chip.\n");
2353 return 1;
2354 }
2355 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002356 msg_cerr("Erase is not working on this chip. ");
2357 if (!force)
2358 return 1;
2359 msg_cerr("Continuing anyway.\n");
2360 }
stefancte1c5acf2011-07-04 07:27:17 +00002361 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002362 msg_cerr("flashrom has no erase function for this "
2363 "flash chip.\n");
2364 return 1;
2365 }
hailfinger771fc182010-10-15 00:01:14 +00002366 }
2367 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002368 if (chip->tested.write == NA) {
2369 msg_cerr("Write is not possible on this chip.\n");
2370 return 1;
2371 }
2372 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002373 msg_cerr("Write is not working on this chip. ");
2374 if (!force)
2375 return 1;
2376 msg_cerr("Continuing anyway.\n");
2377 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002378 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002379 msg_cerr("flashrom has no write function for this "
2380 "flash chip.\n");
2381 return 1;
2382 }
2383 }
2384 return 0;
2385}
2386
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002387int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002388 const bool read_it, const bool write_it,
2389 const bool erase_it, const bool verify_it)
2390{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002391 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002392 msg_cerr("Aborting.\n");
2393 return 1;
2394 }
2395
2396 if (normalize_romentries(flash)) {
2397 msg_cerr("Requested regions can not be handled. Aborting.\n");
2398 return 1;
2399 }
2400
Edward O'Callaghan40092972020-10-20 11:50:48 +11002401 /*
2402 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2403 * can be repro'ed with upstream on Volteer.
2404 *
2405 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2406 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2407 * hooked and this can fail on some board topologies. Checking the return value can
2408 * cause board rw failures by bailing early. Avoid the early bail for now until a
2409 * full investigation can reveal the proper fix. This restores previous behaviour of
2410 * assuming a map went fine.
2411 */
2412#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002413 if (map_flash(flash) != 0)
2414 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002415#endif
2416 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002417
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002418 /* Given the existence of read locks, we want to unlock for read,
2419 erase and write. */
2420 if (flash->chip->unlock)
2421 flash->chip->unlock(flash);
2422
2423 flash->address_high_byte = -1;
2424 flash->in_4ba_mode = false;
2425
Edward O'Callaghan99974452020-10-13 13:28:33 +11002426 /* Be careful about 4BA chips and broken masters */
2427 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2428 /* If we can't use native instructions, bail out */
2429 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2430 || !spi_master_4ba(flash)) {
2431 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2432 return 1;
2433 }
2434 }
2435
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002436 return 0;
2437}
2438
Edward O'Callaghana820b212020-09-17 22:53:26 +10002439void finalize_flash_access(struct flashctx *const flash)
2440{
2441 unmap_flash(flash);
2442}
2443
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002444/*
2445 * Function to erase entire flash chip.
2446 *
2447 * @flashctx pointer to the flash context to use
2448 * @oldcontents pointer to the buffer including current chip contents, to
2449 * decide which areas do in fact need to be erased
2450 * @size the size of the flash chip, in bytes.
2451 *
2452 * Returns zero on success or an error code.
2453 */
2454static int erase_chip(struct flashctx *flash, void *oldcontents,
2455 void *newcontents, size_t size)
2456{
2457 /*
2458 * To make sure that the chip is fully erased, let's cheat and create
2459 * a descriptor where the new contents are all erased.
2460 */
2461 struct action_descriptor *fake_descriptor;
2462 int ret = 0;
2463
2464 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2465 newcontents, 1);
2466 /* FIXME: Do we really want the scary warning if erase failed? After
2467 * all, after erase the chip is either blank or partially blank or it
2468 * has the old contents. A blank chip won't boot, so if the user
2469 * wanted erase and reboots afterwards, the user knows very well that
2470 * booting won't work.
2471 */
2472 if (erase_and_write_flash(flash, fake_descriptor)) {
2473 emergency_help_message();
2474 ret = 1;
2475 }
2476
2477 free(fake_descriptor);
2478
2479 return ret;
2480}
2481
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002482static int read_dest_content(struct flashctx *flash, int verify_it,
2483 uint8_t *dest, unsigned long size)
2484{
2485 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2486 && get_num_include_args()) {
2487 /*
2488 * If no full verification is required and not
2489 * the entire chip is about to be programmed,
2490 * read only the areas which might change.
2491 */
2492 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2493 return 1;
2494 } else {
2495 if (read_flash(flash, dest, 0, size))
2496 return 1;
2497 }
2498 return 0;
2499}
2500
hailfingerc77acb52009-12-24 02:15:55 +00002501/* This function signature is horrible. We need to design a better interface,
2502 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002503 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002504 */
Edward O'Callaghan888e50e2020-12-03 12:39:22 +11002505int doit(struct flashctx *flash, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002506 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002507 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002508{
hailfinger4c47e9d2010-10-19 22:06:20 +00002509 uint8_t *oldcontents;
2510 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002511 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002512 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002513 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002514
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002515 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002516 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002517 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002518
Simon Glass9ad06c12013-07-03 22:08:17 +09002519 if (extract_it) {
2520 ret = extract_regions(flash);
2521 goto out_nofree;
2522 }
2523
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002524 /* mark entries included using -i argument as "included" if they are
2525 found in the master rom_entries list */
2526 if (process_include_args() < 0) {
2527 ret = 1;
2528 goto out_nofree;
2529 }
2530
hailfinger771fc182010-10-15 00:01:14 +00002531 if (read_it) {
2532 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002533 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002534 }
hailfingerb437e282010-11-04 01:04:27 +00002535
stefanctd611e8f2011-07-12 22:35:21 +00002536 oldcontents = malloc(size);
2537 if (!oldcontents) {
2538 msg_gerr("Out of memory!\n");
2539 exit(1);
2540 }
Simon Glass4c214132013-07-16 10:09:28 -06002541 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002542 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002543 newcontents = malloc(size);
2544 if (!newcontents) {
2545 msg_gerr("Out of memory!\n");
2546 exit(1);
2547 }
Simon Glass4c214132013-07-16 10:09:28 -06002548 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002549 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002550 /* Side effect of the assumptions above: Default write action is erase
2551 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002552 * oldcontents being completely unerased means we have to erase
2553 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002554 */
2555
hailfingerd217d122010-10-08 18:52:29 +00002556 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002557 /*
2558 * Note: This must be done before any files specified by -i
2559 * arguments are processed merged into the newcontents since
2560 * -i files take priority. See http://crbug.com/263495.
2561 */
2562 if (filename) {
2563 if (read_buf_from_file(newcontents, size, filename)) {
2564 ret = 1;
2565 goto out;
2566 }
2567 } else {
2568 /* Content will be read from -i args, so they must
2569 * not overlap. */
2570 if (included_regions_overlap()) {
2571 msg_gerr("Error: Included regions must "
2572 "not overlap.\n");
2573 ret = 1;
2574 goto out;
2575 }
stepan1da96c02006-11-21 23:48:51 +00002576 }
ollie5672ac62004-03-17 22:22:08 +00002577 }
2578
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002579 if (do_diff) {
2580 /*
2581 * Obtain a reference image so that we can check whether
2582 * regions need to be erased and to give better diagnostics in
2583 * case write fails. If --fast-verify is used then only the
2584 * regions which are included using -i will be read.
2585 */
2586 if (diff_file) {
2587 msg_cdbg("Reading old contents from file... ");
2588 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002589 ret = 1;
2590 msg_cdbg("FAILED.\n");
2591 goto out;
2592 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002593 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002594 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002595 ret = read_dest_content(flash, verify_it,
2596 oldcontents, size);
2597 if (ret) {
2598 msg_cdbg("FAILED.\n");
2599 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002600 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002601 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002602 msg_cdbg("done.\n");
2603 } else if (!erase_it) {
2604 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002605 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002606 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002607
David Hendricksdf29a832013-06-28 14:33:51 -07002608 /*
2609 * Note: This must be done after reading the file specified for the
2610 * -w/-v argument, if any, so that files specified using -i end up
2611 * in the "newcontents" buffer before being written.
2612 * See http://crbug.com/263495.
2613 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002614 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002615 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002616 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002617 goto out;
2618 }
uwef6641642007-05-09 10:17:44 +00002619
David Hendricksa7e114b2016-02-26 18:49:15 -08002620 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002621 erase_chip(flash, oldcontents, newcontents, size);
2622 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002623 }
2624
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002625 descriptor = prepare_action_descriptor(flash, oldcontents,
2626 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002627 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002628 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002629 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002630 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002631 goto out;
2632 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002633
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002634 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002635 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2636 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002637 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002638 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002639 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002640 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002641 ret = 1;
2642 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002643 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002644 msg_cerr("Apparently at least some data has changed.\n");
2645 } else
2646 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002647 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002648 ret = 1;
2649 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002650 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002651
David Hendricksac1d25c2016-08-09 17:00:58 -07002652 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002653 if (ret < 0) {
2654 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002655 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002656 emergency_help_message();
2657 ret = 1;
2658 goto out;
2659 } else if (ret > 0) {
2660 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002661 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002662 ret = read_dest_content(flash, verify_it,
2663 oldcontents, size);
2664 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002665 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002666 goto out;
2667 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002668
2669 /* Get a new descriptor. */
2670 free(descriptor);
2671 descriptor = prepare_action_descriptor(flash,
2672 oldcontents,
2673 newcontents,
2674 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002675 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002676 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002677 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002678 emergency_help_message();
2679 ret = 1;
2680 goto out;
2681 }
2682 ret = 0;
2683 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002684
David Hendricksac1d25c2016-08-09 17:00:58 -07002685 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002686 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002687 emergency_help_message();
2688 ret = 1;
2689 goto out;
2690 }
stuge8ce3a3c2008-04-28 14:47:30 +00002691 }
ollie6a600992005-11-26 21:55:36 +00002692
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002693 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002694 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002695 if ((write_it || erase_it) && !content_has_changed) {
2696 msg_gdbg("Nothing was erased or written, skipping "
2697 "verification\n");
2698 } else {
2699 /* Work around chips which need some time to calm down. */
2700 if (write_it && verify_it != VERIFY_PARTIAL)
2701 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002702
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002703 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002704
David Hendricks9ba79fb2015-04-03 12:06:16 -07002705 /* If we tried to write, and verification now fails, we
2706 * might have an emergency situation.
2707 */
2708 if (ret && write_it)
2709 emergency_help_message();
2710 }
hailfinger0459e1c2009-08-19 13:55:34 +00002711 }
ollie6a600992005-11-26 21:55:36 +00002712
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002713 finalize_flash_access(flash);
2714
hailfinger90fcf9b2010-11-05 14:51:59 +00002715out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002716 if (descriptor)
2717 free(descriptor);
2718
hailfinger90fcf9b2010-11-05 14:51:59 +00002719 free(oldcontents);
2720 free(newcontents);
2721out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002722 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002723 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002724 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002725 * tree. This is because some operations, such as write protection,
2726 * requires programmer_shutdown() but does not call doit().
2727 */
2728// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002729 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002730}