blob: 0007bc695b3f969951389b5437fb1a1f3836cd5c [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
hailfingerf31cbdc2010-11-10 15:25:18 +0000619#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000620static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000621/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000622static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700623 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000624 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000625} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000626/* Initialize to 0 to make sure nobody registers a shutdown function before
627 * programmer init.
628 */
629static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000630
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700631static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000632
hailfingerdc6f7972010-02-14 01:20:28 +0000633/* Register a function to be executed on programmer shutdown.
634 * The advantage over atexit() is that you can supply a void pointer which will
635 * be used as parameter to the registered function upon programmer shutdown.
636 * This pointer can point to arbitrary data used by said function, e.g. undo
637 * information for GPIO settings etc. If unneeded, set data=NULL.
638 * Please note that the first (void *data) belongs to the function signature of
639 * the function passed as first parameter.
640 */
David Hendricks93784b42016-08-09 17:00:38 -0700641int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000642{
643 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000644 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000645 SHUTDOWN_MAXFN);
646 return 1;
647 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000648 if (!may_register_shutdown) {
649 msg_perr("Tried to register a shutdown function before "
650 "programmer init.\n");
651 return 1;
652 }
hailfingerdc6f7972010-02-14 01:20:28 +0000653 shutdown_fn[shutdown_fn_count].func = function;
654 shutdown_fn[shutdown_fn_count].data = data;
655 shutdown_fn_count++;
656
657 return 0;
658}
659
Nikolai Artemiev55f7a332020-11-05 13:54:27 +1100660int register_chip_restore(chip_restore_fn_cb_t func,
661 struct flashctx *flash, uint8_t status)
662{
663 if (flash->chip_restore_fn_count >= MAX_CHIP_RESTORE_FUNCTIONS) {
664 msg_perr("Tried to register more than %i chip restore"
665 " functions.\n", MAX_CHIP_RESTORE_FUNCTIONS);
666 return 1;
667 }
668 flash->chip_restore_fn[flash->chip_restore_fn_count].func = func;
669 flash->chip_restore_fn[flash->chip_restore_fn_count].status = status;
670 flash->chip_restore_fn_count++;
671
672 return 0;
673}
674
675static int deregister_chip_restore(struct flashctx *flash)
676{
677 int rc = 0;
678
679 while (flash->chip_restore_fn_count > 0) {
680 int i = --flash->chip_restore_fn_count;
681 rc |= flash->chip_restore_fn[i].func(
682 flash, flash->chip_restore_fn[i].status);
683 }
684
685 return rc;
686}
687
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000688int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000689{
hailfinger1ef766d2010-07-06 09:55:48 +0000690 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000691
692 if (prog >= PROGRAMMER_INVALID) {
693 msg_perr("Invalid programmer specified!\n");
694 return -1;
695 }
696 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000697 /* Initialize all programmer specific data. */
698 /* Default to unlimited decode sizes. */
699 max_rom_decode = (const struct decode_sizes) {
700 .parallel = 0xffffffff,
701 .lpc = 0xffffffff,
702 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000703 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000704 };
hailfinger1ff33dc2010-07-03 11:02:10 +0000705 /* Default to top aligned flash at 4 GB. */
706 flashbase = 0;
707 /* Registering shutdown functions is now allowed. */
708 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000709 /* Default to allowing writes. Broken programmers set this to 0. */
710 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000711
712 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000713 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700714 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000715 if (programmer_param && strlen(programmer_param)) {
716 if (ret != 0) {
717 /* It is quite possible that any unhandled programmer parameter would have been valid,
718 * but an error in actual programmer init happened before the parameter was evaluated.
719 */
720 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
721 programmer_param);
722 } else {
723 /* Actual programmer init was successful, but the user specified an invalid or unusable
724 * (for the current programmer configuration) parameter.
725 */
726 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
727 msg_perr("Aborting.\n");
728 ret = ERROR_FATAL;
729 }
730 }
hailfinger1ef766d2010-07-06 09:55:48 +0000731 return ret;
uweabe92a52009-05-16 22:36:00 +0000732}
733
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000734/** Calls registered shutdown functions and resets internal programmer-related variables.
735 * Calling it is safe even without previous initialization, but further interactions with programmer support
736 * require a call to programmer_init() (afterwards).
737 *
738 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700739int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000740{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000741 int ret = 0;
742
hailfinger1ff33dc2010-07-03 11:02:10 +0000743 /* Registering shutdown functions is no longer allowed. */
744 may_register_shutdown = 0;
745 while (shutdown_fn_count > 0) {
746 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700747 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000748 }
Edward O'Callaghancf9c40f2020-10-19 20:02:39 +1100749
750 programmer_param = NULL;
751 registered_master_count = 0;
752
dhendrix0ffc2eb2011-06-14 01:35:36 +0000753 return ret;
uweabe92a52009-05-16 22:36:00 +0000754}
755
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000756void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000757{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000758 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
759 return ret;
uweabe92a52009-05-16 22:36:00 +0000760}
761
762void programmer_unmap_flash_region(void *virt_addr, size_t len)
763{
764 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000765 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000766}
767
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700768void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000769{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100770 flash->mst->par.chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000771}
772
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700773void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000774{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100775 flash->mst->par.chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000776}
777
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700778void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000779{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100780 flash->mst->par.chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000781}
782
Stuart langleyc98e43f2020-03-26 20:27:36 +1100783void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000784{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100785 flash->mst->par.chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000786}
787
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700788uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000789{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100790 return flash->mst->par.chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000791}
792
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700793uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000794{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100795 return flash->mst->par.chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000796}
797
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700798uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000799{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100800 return flash->mst->par.chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000801}
802
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000803void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
804 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000805{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100806 flash->mst->par.chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000807}
808
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000809void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000810{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000811 if (usecs > 0)
812 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000813}
814
Edward O'Callaghana820b212020-09-17 22:53:26 +1000815int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
816 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000817{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700818 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000819
hailfinger23060112009-05-08 12:49:03 +0000820 return 0;
821}
822
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000823/* This is a somewhat hacked function similar in some ways to strtok().
824 * It will look for needle with a subsequent '=' in haystack, return a copy of
825 * needle and remove everything from the first occurrence of needle to the next
826 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000827 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000828char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000829{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000830 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000831 char *opt = NULL;
832 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000833 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000834
hailfingerf4aaccc2010-04-28 15:22:14 +0000835 needlelen = strlen(needle);
836 if (!needlelen) {
837 msg_gerr("%s: empty needle! Please report a bug at "
838 "flashrom@flashrom.org\n", __func__);
839 return NULL;
840 }
841 /* No programmer parameters given. */
842 if (*haystack == NULL)
843 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000844 param_pos = strstr(*haystack, needle);
845 do {
846 if (!param_pos)
847 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000848 /* Needle followed by '='? */
849 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000850 /* Beginning of the string? */
851 if (param_pos == *haystack)
852 break;
853 /* After a delimiter? */
854 if (strchr(delim, *(param_pos - 1)))
855 break;
856 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000857 /* Continue searching. */
858 param_pos++;
859 param_pos = strstr(param_pos, needle);
860 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000861
hailfinger6e5a52a2009-11-24 18:27:10 +0000862 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000863 /* Get the string after needle and '='. */
864 opt_pos = param_pos + needlelen + 1;
865 optlen = strcspn(opt_pos, delim);
866 /* Return an empty string if the parameter was empty. */
867 opt = malloc(optlen + 1);
868 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000869 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000870 exit(1);
871 }
hailfinger1ef766d2010-07-06 09:55:48 +0000872 strncpy(opt, opt_pos, optlen);
873 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000874 rest = opt_pos + optlen;
875 /* Skip all delimiters after the current parameter. */
876 rest += strspn(rest, delim);
877 memmove(param_pos, rest, strlen(rest) + 1);
878 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000879 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000880
hailfinger1ef766d2010-07-06 09:55:48 +0000881 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000882}
883
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000884char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000885{
886 return extract_param(&programmer_param, param_name, ",");
887}
888
stefancte1c5acf2011-07-04 07:27:17 +0000889/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700890static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000891{
892 unsigned int usable_erasefunctions = 0;
893 int k;
894 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
895 if (!check_block_eraser(flash, k, 0))
896 usable_erasefunctions++;
897 }
898 return usable_erasefunctions;
899}
900
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000901static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700902{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000903 int ret = 0, failcount = 0;
904 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700905 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000906 if (wantbuf[i] != havebuf[i]) {
907 /* Only print the first failure. */
908 if (!failcount++)
909 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
910 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700911 }
912 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000913 if (failcount) {
914 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
915 start, start + len - 1, failcount);
916 ret = -1;
917 }
918 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700919}
920
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000921/* start is an offset to the base address of the flash chip */
922static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
923{
924 int ret;
925 uint8_t *cmpbuf = malloc(len);
926 const uint8_t erased_value = ERASED_VALUE(flash);
927
928 if (!cmpbuf) {
929 msg_gerr("Could not allocate memory!\n");
930 exit(1);
931 }
932 memset(cmpbuf, erased_value, len);
933 ret = verify_range(flash, cmpbuf, start, len);
934 free(cmpbuf);
935 return ret;
936}
937
uwee15beb92010-08-08 17:01:18 +0000938/*
hailfinger7af3d192009-11-25 17:05:52 +0000939 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000940 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000941 * @start offset to the base address of the flash chip
942 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000943 * @return 0 for success, -1 for failure
944 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000945int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000946{
hailfinger7af83692009-06-15 17:23:36 +0000947 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000948 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000949
Patrick Georgif3fa2992017-02-02 16:24:44 +0100950 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000951 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000952 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000953 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000954
955 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000956 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000957 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000958 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000959 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000960 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000961
Patrick Georgif3fa2992017-02-02 16:24:44 +0100962 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000963 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000964 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100965 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000966 ret = -1;
967 goto out_free;
968 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700969 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700970 if (programmer_table[programmer].paranoid) {
971 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800972
Simon Glass4e305f42015-01-08 06:29:04 -0700973 /* limit chunksize in order to catch errors early */
974 for (i = 0, chunksize = 0; i < len; i += chunksize) {
975 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800976
Patrick Georgif3fa2992017-02-02 16:24:44 +0100977 chunksize = min(flash->chip->page_size, len - i);
978 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700979 if (tmp) {
980 ret = tmp;
981 if (ignore_error(tmp))
982 continue;
983 else
984 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800985 }
Simon Glass4e305f42015-01-08 06:29:04 -0700986
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700987 /*
988 * Check write access permission and do not compare chunks
989 * where flashrom does not have write access to the region.
990 */
991 if (flash->chip->check_access) {
992 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
993 if (tmp && ignore_error(tmp))
994 continue;
995 }
996
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000997 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700998 if (failcount)
999 break;
David Hendricks1ed1d352011-11-23 17:54:37 -08001000 }
Simon Glass4e305f42015-01-08 06:29:04 -07001001 } else {
1002 int tmp;
1003
1004 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +01001005 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -07001006 if (tmp && !ignore_error(tmp)) {
1007 ret = tmp;
1008 goto out_free;
1009 }
1010
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001011 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +00001012 }
1013
hailfinger5be6c0f2009-07-23 01:42:56 +00001014 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +00001015 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +00001016 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +00001017 ret = -1;
1018 }
hailfinger7af83692009-06-15 17:23:36 +00001019
1020out_free:
1021 free(readbuf);
1022 return ret;
1023}
1024
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001025/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1026static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001027 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001028{
1029 unsigned int i, j, limit;
1030 for (j = 0; j < len / gran; j++) {
1031 limit = min (gran, len - j * gran);
1032 /* Are 'have' and 'want' identical? */
1033 if (!memcmp(have + j * gran, want + j * gran, limit))
1034 continue;
1035 /* have needs to be in erased state. */
1036 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001037 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001038 return 1;
1039 }
1040 return 0;
1041}
1042
uwee15beb92010-08-08 17:01:18 +00001043/*
hailfingerb247c7a2010-03-08 00:42:32 +00001044 * Check if the buffer @have can be programmed to the content of @want without
1045 * erasing. This is only possible if all chunks of size @gran are either kept
1046 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001047 *
hailfingerb437e282010-11-04 01:04:27 +00001048 * Warning: This function assumes that @have and @want point to naturally
1049 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001050 *
1051 * @have buffer with current content
1052 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001053 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001054 * @gran write granularity (enum, not count)
1055 * @return 0 if no erase is needed, 1 otherwise
1056 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001057int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1058 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001059{
hailfingerb91c08c2011-08-15 19:54:20 +00001060 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001061 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001062
hailfingerb247c7a2010-03-08 00:42:32 +00001063 switch (gran) {
1064 case write_gran_1bit:
1065 for (i = 0; i < len; i++)
1066 if ((have[i] & want[i]) != want[i]) {
1067 result = 1;
1068 break;
1069 }
1070 break;
1071 case write_gran_1byte:
1072 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001073 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001074 result = 1;
1075 break;
1076 }
1077 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001078 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001079 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001080 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001081 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001082 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001083 break;
1084 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001085 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001086 break;
1087 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001088 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001089 break;
1090 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001091 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001092 break;
1093 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001094 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001095 break;
1096 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001097 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001098 break;
1099 case write_gran_1byte_implicit_erase:
1100 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1101 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001102 break;
hailfingerb437e282010-11-04 01:04:27 +00001103 default:
1104 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1105 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001106 }
1107 return result;
1108}
1109
hailfingerb437e282010-11-04 01:04:27 +00001110/**
1111 * Check if the buffer @have needs to be programmed to get the content of @want.
1112 * If yes, return 1 and fill in first_start with the start address of the
1113 * write operation and first_len with the length of the first to-be-written
1114 * chunk. If not, return 0 and leave first_start and first_len undefined.
1115 *
1116 * Warning: This function assumes that @have and @want point to naturally
1117 * aligned regions.
1118 *
1119 * @have buffer with current content
1120 * @want buffer with desired content
1121 * @len length of the checked area
1122 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001123 * @first_start offset of the first byte which needs to be written (passed in
1124 * value is increased by the offset of the first needed write
1125 * relative to have/want or unchanged if no write is needed)
1126 * @return length of the first contiguous area which needs to be written
1127 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001128 *
1129 * FIXME: This function needs a parameter which tells it about coalescing
1130 * in relation to the max write length of the programmer and the max write
1131 * length of the chip.
1132 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001133static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001134 unsigned int *first_start,
1135 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001136{
stefanctc5eb8a92011-11-23 09:13:48 +00001137 int need_write = 0;
1138 unsigned int rel_start = 0, first_len = 0;
1139 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001140
hailfingerb437e282010-11-04 01:04:27 +00001141 switch (gran) {
1142 case write_gran_1bit:
1143 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001144 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001145 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001146 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001147 case write_gran_128bytes:
1148 stride = 128;
1149 break;
hailfingerb437e282010-11-04 01:04:27 +00001150 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001151 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001152 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001153 case write_gran_264bytes:
1154 stride = 264;
1155 break;
1156 case write_gran_512bytes:
1157 stride = 512;
1158 break;
1159 case write_gran_528bytes:
1160 stride = 528;
1161 break;
1162 case write_gran_1024bytes:
1163 stride = 1024;
1164 break;
1165 case write_gran_1056bytes:
1166 stride = 1056;
1167 break;
hailfingerb437e282010-11-04 01:04:27 +00001168 default:
1169 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1170 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001171 /* Claim that no write was needed. A write with unknown
1172 * granularity is too dangerous to try.
1173 */
1174 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001175 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001176 for (i = 0; i < len / stride; i++) {
1177 limit = min(stride, len - i * stride);
1178 /* Are 'have' and 'want' identical? */
1179 if (memcmp(have + i * stride, want + i * stride, limit)) {
1180 if (!need_write) {
1181 /* First location where have and want differ. */
1182 need_write = 1;
1183 rel_start = i * stride;
1184 }
1185 } else {
1186 if (need_write) {
1187 /* First location where have and want
1188 * do not differ anymore.
1189 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001190 break;
1191 }
1192 }
1193 }
hailfingerffb7f382010-12-06 13:05:44 +00001194 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001195 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001196 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001197 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001198}
1199
hailfinger0c515352009-11-23 12:55:31 +00001200/* This function generates various test patterns useful for testing controller
1201 * and chip communication as well as chip behaviour.
1202 *
1203 * If a byte can be written multiple times, each time keeping 0-bits at 0
1204 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1205 * is essentially an AND operation. That's also the reason why this function
1206 * provides the result of AND between various patterns.
1207 *
1208 * Below is a list of patterns (and their block length).
1209 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1210 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1211 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1212 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1213 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1214 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1215 * Pattern 6 is 00 (1 Byte)
1216 * Pattern 7 is ff (1 Byte)
1217 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1218 * byte block.
1219 *
1220 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1221 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1222 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1223 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1224 * Pattern 12 is 00 (1 Byte)
1225 * Pattern 13 is ff (1 Byte)
1226 * Patterns 8-13 have no block number.
1227 *
1228 * Patterns 0-3 are created to detect and efficiently diagnose communication
1229 * slips like missed bits or bytes and their repetitive nature gives good visual
1230 * cues to the person inspecting the results. In addition, the following holds:
1231 * AND Pattern 0/1 == Pattern 4
1232 * AND Pattern 2/3 == Pattern 5
1233 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1234 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1235 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1236 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1237 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1238 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1239 * Besides that, they provide for bit testing of the last two bytes of every
1240 * 256 byte block which contains the block number for patterns 0-6.
1241 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1242 * block sizes >256 bytes (some Dataflash chips etc.)
1243 * AND Pattern 8/9 == Pattern 12
1244 * AND Pattern 10/11 == Pattern 12
1245 * Pattern 13 is the completely erased state.
1246 * None of the patterns can detect aliasing at boundaries which are a multiple
1247 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1248 */
1249int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1250{
1251 int i;
1252
1253 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001254 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001255 return 1;
1256 }
1257
1258 switch (variant) {
1259 case 0:
1260 for (i = 0; i < size; i++)
1261 buf[i] = (i & 0xf) << 4 | 0x5;
1262 break;
1263 case 1:
1264 for (i = 0; i < size; i++)
1265 buf[i] = (i & 0xf) << 4 | 0xa;
1266 break;
1267 case 2:
1268 for (i = 0; i < size; i++)
1269 buf[i] = 0x50 | (i & 0xf);
1270 break;
1271 case 3:
1272 for (i = 0; i < size; i++)
1273 buf[i] = 0xa0 | (i & 0xf);
1274 break;
1275 case 4:
1276 for (i = 0; i < size; i++)
1277 buf[i] = (i & 0xf) << 4;
1278 break;
1279 case 5:
1280 for (i = 0; i < size; i++)
1281 buf[i] = i & 0xf;
1282 break;
1283 case 6:
1284 memset(buf, 0x00, size);
1285 break;
1286 case 7:
1287 memset(buf, 0xff, size);
1288 break;
1289 case 8:
1290 for (i = 0; i < size; i++)
1291 buf[i] = i & 0xff;
1292 break;
1293 case 9:
1294 for (i = 0; i < size; i++)
1295 buf[i] = ~(i & 0xff);
1296 break;
1297 case 10:
1298 for (i = 0; i < size % 2; i++) {
1299 buf[i * 2] = (i >> 8) & 0xff;
1300 buf[i * 2 + 1] = i & 0xff;
1301 }
1302 if (size & 0x1)
1303 buf[i * 2] = (i >> 8) & 0xff;
1304 break;
1305 case 11:
1306 for (i = 0; i < size % 2; i++) {
1307 buf[i * 2] = ~((i >> 8) & 0xff);
1308 buf[i * 2 + 1] = ~(i & 0xff);
1309 }
1310 if (size & 0x1)
1311 buf[i * 2] = ~((i >> 8) & 0xff);
1312 break;
1313 case 12:
1314 memset(buf, 0x00, size);
1315 break;
1316 case 13:
1317 memset(buf, 0xff, size);
1318 break;
1319 }
1320
1321 if ((variant >= 0) && (variant <= 7)) {
1322 /* Write block number in the last two bytes of each 256-byte
1323 * block, big endian for easier reading of the hexdump.
1324 * Note that this wraps around for chips larger than 2^24 bytes
1325 * (16 MB).
1326 */
1327 for (i = 0; i < size / 256; i++) {
1328 buf[i * 256 + 254] = (i >> 8) & 0xff;
1329 buf[i * 256 + 255] = i & 0xff;
1330 }
1331 }
1332
1333 return 0;
1334}
1335
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001336/* Returns the number of busses commonly supported by the current programmer and flash chip where the latter
1337 * can not be completely accessed due to size/address limits of the programmer. */
1338unsigned int count_max_decode_exceedings(const struct flashctx *flash)
hailfingeraec9c962009-10-31 01:53:09 +00001339{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001340 unsigned int limitexceeded = 0;
1341 uint32_t size = flash->chip->total_size * 1024;
1342 enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
uwe8d342eb2011-07-28 08:13:25 +00001343
1344 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001345 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001346 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001347 "size %u kB of chipset/board/programmer "
1348 "for %s interface, "
1349 "probe/read/erase/write may fail. ", size / 1024,
1350 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001351 }
hailfingere1e41ea2011-07-27 07:13:06 +00001352 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001353 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001354 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001355 "size %u kB of chipset/board/programmer "
1356 "for %s interface, "
1357 "probe/read/erase/write may fail. ", size / 1024,
1358 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001359 }
hailfingere1e41ea2011-07-27 07:13:06 +00001360 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001361 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001362 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001363 "size %u kB of chipset/board/programmer "
1364 "for %s interface, "
1365 "probe/read/erase/write may fail. ", size / 1024,
1366 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001367 }
hailfingere1e41ea2011-07-27 07:13:06 +00001368 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001369 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001370 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001371 "size %u kB of chipset/board/programmer "
1372 "for %s interface, "
1373 "probe/read/erase/write may fail. ", size / 1024,
1374 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001375 }
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001376 return limitexceeded;
hailfingeraec9c962009-10-31 01:53:09 +00001377}
1378
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001379void unmap_flash(struct flashctx *flash)
1380{
1381 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1382 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1383 flash->physical_registers = 0;
1384 flash->virtual_registers = (chipaddr)ERROR_PTR;
1385 }
1386
1387 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1388 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1389 flash->physical_memory = 0;
1390 flash->virtual_memory = (chipaddr)ERROR_PTR;
1391 }
1392}
1393
1394int map_flash(struct flashctx *flash)
1395{
1396 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1397 flash->virtual_memory = (chipaddr)ERROR_PTR;
1398 flash->virtual_registers = (chipaddr)ERROR_PTR;
1399
1400 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1401 * These are used for various probing-related hacks that would not map successfully anyway and should be
1402 * removed ASAP. */
1403 if (flash->chip->total_size == 0)
1404 return 0;
1405
1406 const chipsize_t size = flash->chip->total_size * 1024;
1407 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1408 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1409 if (addr == ERROR_PTR) {
1410 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1411 flash->chip->name, PRIxPTR_WIDTH, base);
1412 return 1;
1413 }
1414 flash->physical_memory = base;
1415 flash->virtual_memory = (chipaddr)addr;
1416
1417 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1418 * completely different on some chips and programmers, or not mappable at all.
1419 * Ignore these problems for now and always report success. */
1420 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1421 base = 0xffffffff - size - 0x400000 + 1;
1422 addr = programmer_map_flash_region("flash chip registers", base, size);
1423 if (addr == ERROR_PTR) {
1424 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1425 flash->chip->name, PRIxPTR_WIDTH, base);
1426 return 0;
1427 }
1428 flash->physical_registers = base;
1429 flash->virtual_registers = (chipaddr)addr;
1430 }
1431 return 0;
1432}
1433
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001434/*
1435 * Return a string corresponding to the bustype parameter.
1436 * Memory is obtained with malloc() and must be freed with free() by the caller.
1437 */
1438char *flashbuses_to_text(enum chipbustype bustype)
1439{
1440 char *ret = calloc(1, 1);
1441 /*
1442 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1443 * will cease to exist and should be eliminated here as well.
1444 */
1445 if (bustype == BUS_NONSPI) {
1446 ret = strcat_realloc(ret, "Non-SPI, ");
1447 } else {
1448 if (bustype & BUS_PARALLEL)
1449 ret = strcat_realloc(ret, "Parallel, ");
1450 if (bustype & BUS_LPC)
1451 ret = strcat_realloc(ret, "LPC, ");
1452 if (bustype & BUS_FWH)
1453 ret = strcat_realloc(ret, "FWH, ");
1454 if (bustype & BUS_SPI)
1455 ret = strcat_realloc(ret, "SPI, ");
1456 if (bustype & BUS_PROG)
1457 ret = strcat_realloc(ret, "Programmer-specific, ");
1458 if (bustype == BUS_NONE)
1459 ret = strcat_realloc(ret, "None, ");
1460 }
1461 /* Kill last comma. */
1462 ret[strlen(ret) - 2] = '\0';
1463 ret = realloc(ret, strlen(ret) + 1);
1464 return ret;
1465}
1466
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001467int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001468{
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001469 const struct flashchip *chip;
hailfingeraec9c962009-10-31 01:53:09 +00001470 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001471 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001472
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001473 for (chip = flashchips + startchip; chip && chip->name; chip++) {
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001474 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001475 continue;
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001476 buses_common = mst->buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001477 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001478 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001479 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001480 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001481 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001482 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001483 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001484 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001485 continue;
1486 }
stepan782fb172007-04-06 11:58:03 +00001487
hailfinger48ed3e22011-05-04 00:39:50 +00001488 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001489 flash->chip = calloc(1, sizeof(struct flashchip));
1490 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001491 msg_gerr("Out of memory!\n");
1492 exit(1);
1493 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001494 memcpy(flash->chip, chip, sizeof(struct flashchip));
1495 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001496
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001497 if (map_flash(flash) != 0)
1498 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001499
Edward O'Callaghana820b212020-09-17 22:53:26 +10001500 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1501 * is only called with force=1 after normal probing failed.
1502 */
stugec1e55fe2008-07-02 17:15:47 +00001503 if (force)
1504 break;
stepanc98b80b2006-03-16 16:57:41 +00001505
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001506 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001507 goto notfound;
1508
hailfinger48ed3e22011-05-04 00:39:50 +00001509 /* If this is the first chip found, accept it.
1510 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001511 * a non-generic match. SFDP and CFI are generic matches.
1512 * startchip==0 means this call to probe_flash() is the first
1513 * one for this programmer interface (master) and thus no other chip has
1514 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001515 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001516 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1517 msg_cinfo("===\n"
1518 "SFDP has autodetected a flash chip which is "
1519 "not natively supported by flashrom yet.\n");
1520 if (count_usable_erasers(flash) == 0)
1521 msg_cinfo("The standard operations read and "
1522 "verify should work, but to support "
1523 "erase, write and all other "
1524 "possible features");
1525 else
1526 msg_cinfo("All standard operations (read, "
1527 "verify, erase and write) should "
1528 "work, but to support all possible "
1529 "features");
1530
1531 msg_cinfo(" we need to add them manually.\n"
1532 "You can help us by mailing us the output of the following command to "
1533 "flashrom@flashrom.org:\n"
1534 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1535 "Thanks for your help!\n"
1536 "===\n");
1537 }
stugec1e55fe2008-07-02 17:15:47 +00001538
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001539 /* First flash chip detected on this bus. */
1540 if (startchip == 0)
1541 break;
1542 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001543 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001544 break;
1545 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001546notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001547 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001548 free(flash->chip);
1549 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001550 }
uwebe4477b2007-08-23 16:08:21 +00001551
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001552 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001553 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001554
stepan3e7aeae2011-01-19 06:21:54 +00001555
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001556 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001557 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1558 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001559 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001560#if CONFIG_INTERNAL == 1
1561 if (programmer_table[programmer].map_flash_region == physmap)
1562 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1563 PRIxPTR_WIDTH, flash->physical_memory);
1564 else
1565#endif
1566 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001567
Edward O'Callaghana820b212020-09-17 22:53:26 +10001568 /* Flash registers may more likely not be mapped if the chip was forced.
1569 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001570 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001571 if (flash->chip->printlock)
1572 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001573
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001574 /* Get out of the way for later runs. */
1575 unmap_flash(flash);
1576
hailfinger48ed3e22011-05-04 00:39:50 +00001577 /* Return position of matching chip. */
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001578 return chip - flashchips;
rminnich8d3ff912003-10-25 17:01:29 +00001579}
1580
uwe8d342eb2011-07-28 08:13:25 +00001581int read_buf_from_file(unsigned char *buf, unsigned long size,
1582 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001583{
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001584 unsigned long numbytes;
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001585 FILE *image;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001586 struct stat image_stat;
1587
1588 if (!strncmp(filename, "-", sizeof("-")))
1589 image = fdopen(STDIN_FILENO, "rb");
1590 else
1591 image = fopen(filename, "rb");
1592 if (image == NULL) {
1593 perror(filename);
hailfinger771fc182010-10-15 00:01:14 +00001594 return 1;
1595 }
1596 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001597 perror(filename);
1598 fclose(image);
1599 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001600 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001601 if ((image_stat.st_size != size) &&
1602 (strncmp(filename, "-", sizeof("-")))) {
1603 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1604 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
1605 fclose(image);
1606 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001607 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001608 numbytes = fread(buf, 1, size, image);
1609 if (fclose(image)) {
1610 perror(filename);
1611 return 1;
1612 }
hailfinger771fc182010-10-15 00:01:14 +00001613 if (numbytes != size) {
1614 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1615 "wanted %ld!\n", numbytes, size);
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001616 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001617 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001618 return 0;
hailfinger771fc182010-10-15 00:01:14 +00001619}
1620
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001621int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001622{
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001623 unsigned long numbytes;
hailfingerd219a232009-01-28 00:27:54 +00001624 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001625
1626 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001627 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001628 return 1;
1629 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001630 if (!strncmp(filename, "-", sizeof("-")))
1631 image = fdopen(STDOUT_FILENO, "wb");
1632 else
1633 image = fopen(filename, "wb");
1634 if (image == NULL) {
1635 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001636 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001637 }
hailfingerd219a232009-01-28 00:27:54 +00001638
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001639 numbytes = fwrite(buf, 1, size, image);
1640 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001641 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001642 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001643 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001644 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001645 return 0;
hailfingerd219a232009-01-28 00:27:54 +00001646}
1647
David Hendrickse3451942013-03-21 17:23:29 -07001648/*
1649 * read_flash - wrapper for flash->read() with additional high-level policy
1650 *
1651 * @flash flash chip
1652 * @buf buffer to store data in
1653 * @start start address
1654 * @len number of bytes to read
1655 *
1656 * This wrapper simplifies most cases when the flash chip needs to be read
1657 * since policy decisions such as non-fatal error handling is centralized.
1658 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001659int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001660 unsigned int start, unsigned int len)
1661{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001662 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001663
Patrick Georgif3fa2992017-02-02 16:24:44 +01001664 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001665 return -1;
1666
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001667 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1668
Patrick Georgif3fa2992017-02-02 16:24:44 +01001669 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001670 if (ret) {
1671 if (ignore_error(ret)) {
1672 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1673 start, start + len - 1);
1674 ret = 0;
1675 } else {
1676 msg_gdbg("failed to read 0x%x-0x%x\n",
1677 start, start + len - 1);
1678 }
1679 }
1680
1681 return ret;
1682}
1683
David Hendricks7c8a1612013-04-26 19:14:44 -07001684/*
1685 * write_flash - wrapper for flash->write() with additional high-level policy
1686 *
1687 * @flash flash chip
1688 * @buf buffer to write to flash
1689 * @start start address in flash
1690 * @len number of bytes to write
1691 *
1692 * TODO: Look up regions that are write-protected and avoid attempt to write
1693 * to them at all.
1694 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001695int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001696 unsigned int start, unsigned int len)
1697{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001698 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001699 return -1;
1700
Patrick Georgif3fa2992017-02-02 16:24:44 +01001701 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001702}
1703
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001704int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001705{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001706 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001707 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001708 int ret = 0;
1709
1710 msg_cinfo("Reading flash... ");
1711 if (!buf) {
1712 msg_gerr("Memory allocation failed!\n");
1713 msg_cinfo("FAILED.\n");
1714 return 1;
1715 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001716
1717 /* To support partial read, fill buffer to all 0xFF at beginning to make
1718 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001719 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001720
Patrick Georgif3fa2992017-02-02 16:24:44 +01001721 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001722 msg_cerr("No read function available for this flash chip.\n");
1723 ret = 1;
1724 goto out_free;
1725 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001726
1727 /* First try to handle partial read case, rather than read the whole
1728 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001729 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001730 if (ret < 0) {
1731 msg_cerr("Partial read operation failed!\n");
1732 ret = 1;
1733 goto out_free;
1734 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001735 int num_regions = get_num_include_args();
1736
1737 if (ret != num_regions) {
1738 msg_cerr("Requested %d regions, but only read %d\n",
1739 num_regions, ret);
1740 ret = 1;
1741 goto out_free;
1742 }
1743
1744 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001745 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001746 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001747 msg_cerr("Read operation failed!\n");
1748 ret = 1;
1749 goto out_free;
1750 }
hailfinger42a850a2010-07-13 23:56:13 +00001751 }
1752
David Hendricksdf29a832013-06-28 14:33:51 -07001753 if (filename)
1754 ret = write_buf_to_file(buf, size, filename);
1755
hailfinger42a850a2010-07-13 23:56:13 +00001756out_free:
1757 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001758 if (ret)
1759 msg_cerr("FAILED.");
1760 else
1761 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001762 return ret;
1763}
1764
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001765/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001766static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001767{
hailfingerb91c08c2011-08-15 19:54:20 +00001768 int i, j, k;
1769 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001770
1771 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1772 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001773 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001774
1775 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1776 /* Blocks with zero size are bugs in flashchips.c. */
1777 if (eraser.eraseblocks[i].count &&
1778 !eraser.eraseblocks[i].size) {
1779 msg_gerr("ERROR: Flash chip %s erase function "
1780 "%i region %i has size 0. Please report"
1781 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001782 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001783 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001784 }
1785 /* Blocks with zero count are bugs in flashchips.c. */
1786 if (!eraser.eraseblocks[i].count &&
1787 eraser.eraseblocks[i].size) {
1788 msg_gerr("ERROR: Flash chip %s erase function "
1789 "%i region %i has count 0. Please report"
1790 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001791 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001792 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001793 }
1794 done += eraser.eraseblocks[i].count *
1795 eraser.eraseblocks[i].size;
1796 }
hailfinger9fed35d2010-01-19 06:42:46 +00001797 /* Empty eraseblock definition with erase function. */
1798 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001799 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001800 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001801 if (!done)
1802 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001803 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001804 msg_gerr("ERROR: Flash chip %s erase function %i "
1805 "region walking resulted in 0x%06x bytes total,"
1806 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001807 " flashrom@flashrom.org\n", chip->name, k,
1808 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001809 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001810 }
hailfinger9fed35d2010-01-19 06:42:46 +00001811 if (!eraser.block_erase)
1812 continue;
1813 /* Check if there are identical erase functions for different
1814 * layouts. That would imply "magic" erase functions. The
1815 * easiest way to check this is with function pointers.
1816 */
uwef6f94d42010-03-13 17:28:29 +00001817 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001818 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001819 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001820 msg_gerr("ERROR: Flash chip %s erase function "
1821 "%i and %i are identical. Please report"
1822 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001823 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001824 ret = 1;
1825 }
uwef6f94d42010-03-13 17:28:29 +00001826 }
hailfinger45177872010-01-18 08:14:43 +00001827 }
hailfinger9fed35d2010-01-19 06:42:46 +00001828 return ret;
hailfinger45177872010-01-18 08:14:43 +00001829}
1830
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001831static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001832 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001833 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001834 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001835 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001836 unsigned int addr,
1837 unsigned int len))
1838{
stefanctc5eb8a92011-11-23 09:13:48 +00001839 unsigned int starthere = 0, lenhere = 0;
1840 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001841 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001842 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001843
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001844 /*
1845 * curcontents and newcontents are opaque to walk_eraseregions, and
1846 * need to be adjusted here to keep the impression of proper
1847 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001848 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001849
hailfinger90fcf9b2010-11-05 14:51:59 +00001850 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001851
hailfingerb437e282010-11-04 01:04:27 +00001852 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001853
hailfingerb437e282010-11-04 01:04:27 +00001854 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001855 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001856 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001857 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001858 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001859 if (ret) {
1860 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001861 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001862 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001863 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001864 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001865 }
1866
David Hendricks0954ffc2015-11-13 15:15:44 -08001867 if (programmer_table[programmer].paranoid) {
1868 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001869 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001870 return -1;
1871 }
hailfingerac8e3182011-06-26 17:04:16 +00001872 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001873
hailfinger90fcf9b2010-11-05 14:51:59 +00001874 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001875 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001876 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001877 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001878 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001879 /* get_next_write() sets starthere to a new value after the call. */
1880 while ((lenhere = get_next_write(curcontents + starthere,
1881 newcontents + starthere,
1882 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001883 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001884 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001885 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001886 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001887 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001888 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001889 if (ret) {
1890 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001891 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001892 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001893 }
David Hendricks048b38c2016-03-28 18:47:06 -07001894
1895 /*
1896 * If the block needed to be erased and was erased successfully
1897 * then we can assume that we didn't run into any write-
1898 * protected areas. Otherwise, we need to verify each page to
1899 * ensure it was successfully written and abort if we encounter
1900 * any errors.
1901 */
1902 if (programmer_table[programmer].paranoid && !block_was_erased) {
1903 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001904 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001905 return -1;
1906 }
1907
hailfingerb437e282010-11-04 01:04:27 +00001908 starthere += lenhere;
1909 skip = 0;
1910 }
1911 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001912 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001913 return ret;
1914}
1915
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001916/*
1917 * Function to process processing units accumulated in the action descriptor.
1918 *
1919 * @flash pointer to the flash context to operate on
1920 * @do_something helper function which can erase and program a section of the
1921 * flash chip. It receives the flash context, offset and length
1922 * of the area to erase/program, before and after contents (to
1923 * decide what exactly needs to be erased and or programmed)
1924 * and a pointer to the erase function which can operate on the
1925 * proper granularity.
1926 * @descriptor action descriptor including pointers to before and after
1927 * contents and an array of processing actions to take.
1928 *
1929 * Returns zero on success or an error code.
1930 */
1931static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001932 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001933 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00001934 unsigned int len,
1935 uint8_t *param1,
1936 uint8_t *param2,
1937 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001938 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001939 unsigned int addr,
1940 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001941 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00001942{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001943 struct processing_unit *pu;
1944 int rc = 0;
1945 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00001946
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001947 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1948 unsigned base = pu->offset;
1949 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07001950
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001951 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07001952
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001953 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00001954 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001955 else
1956 print_comma = 1;
1957
1958 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1959
1960 rc = do_something(flash, base,
1961 pu->block_size,
1962 descriptor->oldcontents,
1963 descriptor->newcontents,
1964 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
1965
David Hendricks1ed1d352011-11-23 17:54:37 -08001966 if (rc) {
1967 if (ignore_error(rc))
1968 rc = 0;
1969 else
1970 return rc;
hailfingerb437e282010-11-04 01:04:27 +00001971 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001972 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00001973 }
1974 }
hailfingerb437e282010-11-04 01:04:27 +00001975 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08001976 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00001977}
1978
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001979static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00001980{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001981 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00001982
1983 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1984 if (log)
1985 msg_cdbg("not defined. ");
1986 return 1;
1987 }
1988 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1989 if (log)
1990 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00001991 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00001992 return 1;
1993 }
1994 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1995 if (log)
1996 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00001997 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00001998 return 1;
1999 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002000 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002001 return 0;
2002}
2003
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002004int erase_and_write_flash(struct flashctx *flash,
2005 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002006{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002007 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002008
hailfingercf848f12010-12-05 15:14:44 +00002009 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002010
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002011 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002012
hailfinger7df21362009-09-05 02:30:58 +00002013 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002014 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002015 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002016 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002017 }
2018 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002019}
2020
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11002021static int verify_flash(struct flashctx *flash,
2022 struct action_descriptor *descriptor,
2023 int verify_it)
2024{
2025 int ret;
2026 unsigned int total_size = flash->chip->total_size * 1024;
2027 uint8_t *buf = descriptor->newcontents;
2028
2029 msg_cinfo("Verifying flash... ");
2030
2031 if (verify_it == VERIFY_PARTIAL) {
2032 struct processing_unit *pu = descriptor->processing_units;
2033
2034 /* Verify only areas which were written. */
2035 while (pu->num_blocks) {
2036 ret = verify_range(flash, buf + pu->offset, pu->offset,
2037 pu->block_size * pu->num_blocks);
2038 if (ret)
2039 break;
2040 pu++;
2041 }
2042 } else {
2043 ret = verify_range(flash, buf, 0, total_size);
2044 }
2045
2046 if (ret == ACCESS_DENIED) {
2047 msg_gdbg("Could not fully verify due to access error, ");
2048 if (access_denied_action == error_ignore) {
2049 msg_gdbg("ignoring\n");
2050 ret = 0;
2051 } else {
2052 msg_gdbg("aborting\n");
2053 }
2054 }
2055
2056 if (!ret)
2057 msg_cinfo("VERIFIED. \n");
2058
2059 return ret;
2060}
2061
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002062static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002063{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002064 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2065#if CONFIG_INTERNAL == 1
2066 if (programmer == PROGRAMMER_INTERNAL)
2067 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2068 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2069 "mail flashrom@flashrom.org, thanks!\n"
2070 "-------------------------------------------------------------------------------\n"
2071 "You may now reboot or simply leave the machine running.\n");
2072 else
2073#endif
2074 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2075 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2076 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2077 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002078}
2079
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002080static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002081{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002082 msg_gerr("Your flash chip is in an unknown state.\n");
2083#if CONFIG_INTERNAL == 1
2084 if (programmer == PROGRAMMER_INTERNAL)
2085 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2086 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2087 "-------------------------------------------------------------------------------\n"
2088 "DO NOT REBOOT OR POWEROFF!\n");
2089 else
2090#endif
2091 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2092 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002093}
2094
hailfingerf79d1712010-10-06 23:48:34 +00002095void list_programmers_linebreak(int startcol, int cols, int paren)
2096{
2097 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002098 int pnamelen;
2099 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002100 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002101 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002102
2103 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2104 pname = programmer_table[p].name;
2105 pnamelen = strlen(pname);
2106 if (remaining - pnamelen - 2 < 0) {
2107 if (firstline)
2108 firstline = 0;
2109 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002110 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002111 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002112 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002113 remaining = cols - startcol;
2114 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002115 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002116 remaining--;
2117 }
2118 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002119 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002120 remaining--;
2121 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002122 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002123 remaining -= pnamelen;
2124 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002125 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002126 remaining--;
2127 } else {
2128 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002129 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002130 }
2131 }
2132}
2133
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002134static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002135{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002136#if IS_WINDOWS
2137 SYSTEM_INFO si;
2138 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002139
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002140 memset(&si, 0, sizeof(SYSTEM_INFO));
2141 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2142 msg_ginfo(" on Windows");
2143 /* Tell Windows which version of the structure we want. */
2144 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2145 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2146 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2147 else
2148 msg_ginfo(" unknown version");
2149 GetSystemInfo(&si);
2150 switch (si.wProcessorArchitecture) {
2151 case PROCESSOR_ARCHITECTURE_AMD64:
2152 msg_ginfo(" (x86_64)");
2153 break;
2154 case PROCESSOR_ARCHITECTURE_INTEL:
2155 msg_ginfo(" (x86)");
2156 break;
2157 default:
2158 msg_ginfo(" (unknown arch)");
2159 break;
2160 }
2161#elif HAVE_UTSNAME == 1
2162 struct utsname osinfo;
2163
2164 uname(&osinfo);
2165 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002166 osinfo.machine);
2167#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002168 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002169#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002170}
2171
2172void print_buildinfo(void)
2173{
2174 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002175#if NEED_PCI == 1
2176#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002177 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002178#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002179 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002180#endif
2181#endif
2182#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002183 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002184#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002185 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002186#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002187 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002188#endif
hailfinger3b471632010-03-27 16:36:40 +00002189#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002190 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002191#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002192 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002193#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002194 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002195#endif
2196#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002197 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002198#endif
2199#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002200 msg_gdbg(" little endian");
Edward O'Callaghan3c005942020-10-01 16:33:47 +10002201#elif defined (__FLASHROM_BIG_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002202 msg_gdbg(" big endian");
Edward O'Callaghan3c005942020-10-01 16:33:47 +10002203#else
2204#error Endianness could not be determined
hailfinger3b471632010-03-27 16:36:40 +00002205#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002206 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002207}
2208
uwefdeca092008-01-21 15:24:22 +00002209void print_version(void)
2210{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002211 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002212 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002213 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002214}
2215
hailfinger74819ad2010-05-15 15:04:37 +00002216void print_banner(void)
2217{
2218 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002219 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002220 msg_ginfo("\n");
2221}
2222
hailfingerc77acb52009-12-24 02:15:55 +00002223int selfcheck(void)
2224{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002225 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002226 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002227
2228 /* Safety check. Instead of aborting after the first error, check
2229 * if more errors exist.
2230 */
hailfingerc77acb52009-12-24 02:15:55 +00002231 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002232 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002233 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002234 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002235 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2236 const struct programmer_entry p = programmer_table[i];
2237 if (p.name == NULL) {
2238 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2239 ret = 1;
2240 /* This might hide other problems with this programmer, but allows for better error
2241 * messages below without jumping through hoops. */
2242 continue;
2243 }
2244 switch (p.type) {
2245 case USB:
2246 case PCI:
2247 case OTHER:
2248 if (p.devs.note == NULL) {
2249 if (strcmp("internal", p.name) == 0)
2250 break; /* This one has its device list stored separately. */
2251 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2252 p.name);
2253 ret = 1;
2254 }
2255 break;
2256 default:
2257 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2258 ret = 1;
2259 break;
2260 }
2261 if (p.init == NULL) {
2262 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2263 ret = 1;
2264 }
2265 if (p.delay == NULL) {
2266 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2267 ret = 1;
2268 }
2269 if (p.map_flash_region == NULL) {
2270 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2271 ret = 1;
2272 }
2273 if (p.unmap_flash_region == NULL) {
2274 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2275 ret = 1;
2276 }
2277 }
2278
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002279 /* It would be favorable if we could check for the correct layout (especially termination) of various
2280 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2281 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2282 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2283 * 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 +10002284 * checks below. */
2285 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002286 msg_gerr("Flashchips table miscompilation!\n");
2287 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002288 } else {
2289 for (i = 0; i < flashchips_size - 1; i++) {
2290 const struct flashchip *chip = &flashchips[i];
2291 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2292 ret = 1;
2293 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2294 "Please report a bug at flashrom@flashrom.org\n", i,
2295 chip->name == NULL ? "unnamed" : chip->name);
2296 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002297 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002298 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002299 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002300 }
stefanct6d836ba2011-05-26 01:35:19 +00002301 }
stefanct6d836ba2011-05-26 01:35:19 +00002302
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002303 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002304 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002305}
2306
hailfinger771fc182010-10-15 00:01:14 +00002307/* FIXME: This function signature needs to be improved once doit() has a better
2308 * function signature.
2309 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002310static int chip_safety_check(const struct flashctx *flash, int force,
2311 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002312{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002313 const struct flashchip *chip = flash->chip;
2314
hailfinger771fc182010-10-15 00:01:14 +00002315 if (!programmer_may_write && (write_it || erase_it)) {
2316 msg_perr("Write/erase is not working yet on your programmer in "
2317 "its current configuration.\n");
2318 /* --force is the wrong approach, but it's the best we can do
2319 * until the generic programmer parameter parser is merged.
2320 */
2321 if (!force)
2322 return 1;
2323 msg_cerr("Continuing anyway.\n");
2324 }
2325
2326 if (read_it || erase_it || write_it || verify_it) {
2327 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002328 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002329 msg_cerr("Read is not working on this chip. ");
2330 if (!force)
2331 return 1;
2332 msg_cerr("Continuing anyway.\n");
2333 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002334 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002335 msg_cerr("flashrom has no read function for this "
2336 "flash chip.\n");
2337 return 1;
2338 }
2339 }
2340 if (erase_it || write_it) {
2341 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002342 if (chip->tested.erase == NA) {
2343 msg_cerr("Erase is not possible on this chip.\n");
2344 return 1;
2345 }
2346 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002347 msg_cerr("Erase is not working on this chip. ");
2348 if (!force)
2349 return 1;
2350 msg_cerr("Continuing anyway.\n");
2351 }
stefancte1c5acf2011-07-04 07:27:17 +00002352 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002353 msg_cerr("flashrom has no erase function for this "
2354 "flash chip.\n");
2355 return 1;
2356 }
hailfinger771fc182010-10-15 00:01:14 +00002357 }
2358 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002359 if (chip->tested.write == NA) {
2360 msg_cerr("Write is not possible on this chip.\n");
2361 return 1;
2362 }
2363 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002364 msg_cerr("Write is not working on this chip. ");
2365 if (!force)
2366 return 1;
2367 msg_cerr("Continuing anyway.\n");
2368 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002369 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002370 msg_cerr("flashrom has no write function for this "
2371 "flash chip.\n");
2372 return 1;
2373 }
2374 }
2375 return 0;
2376}
2377
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002378int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002379 const bool read_it, const bool write_it,
2380 const bool erase_it, const bool verify_it)
2381{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002382 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002383 msg_cerr("Aborting.\n");
2384 return 1;
2385 }
2386
2387 if (normalize_romentries(flash)) {
2388 msg_cerr("Requested regions can not be handled. Aborting.\n");
2389 return 1;
2390 }
2391
Edward O'Callaghan40092972020-10-20 11:50:48 +11002392 /*
2393 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2394 * can be repro'ed with upstream on Volteer.
2395 *
2396 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2397 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2398 * hooked and this can fail on some board topologies. Checking the return value can
2399 * cause board rw failures by bailing early. Avoid the early bail for now until a
2400 * full investigation can reveal the proper fix. This restores previous behaviour of
2401 * assuming a map went fine.
2402 */
2403#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002404 if (map_flash(flash) != 0)
2405 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002406#endif
2407 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002408
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002409 /* Given the existence of read locks, we want to unlock for read,
2410 erase and write. */
2411 if (flash->chip->unlock)
2412 flash->chip->unlock(flash);
2413
2414 flash->address_high_byte = -1;
2415 flash->in_4ba_mode = false;
Nikolai Artemiev55f7a332020-11-05 13:54:27 +11002416 flash->chip_restore_fn_count = 0;
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002417
Edward O'Callaghan99974452020-10-13 13:28:33 +11002418 /* Be careful about 4BA chips and broken masters */
2419 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2420 /* If we can't use native instructions, bail out */
2421 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2422 || !spi_master_4ba(flash)) {
2423 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2424 return 1;
2425 }
2426 }
2427
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002428 return 0;
2429}
2430
Edward O'Callaghana820b212020-09-17 22:53:26 +10002431void finalize_flash_access(struct flashctx *const flash)
2432{
Nikolai Artemiev55f7a332020-11-05 13:54:27 +11002433 deregister_chip_restore(flash);
Edward O'Callaghana820b212020-09-17 22:53:26 +10002434 unmap_flash(flash);
2435}
2436
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002437/**
2438 * @addtogroup flashrom-flash
2439 * @{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002440 */
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002441
2442/**
2443 * @brief Erase the specified ROM chip.
2444 *
2445 * If a layout is set in the given flash context, only included regions
2446 * will be erased.
2447 *
2448 * @param flashctx The context of the flash chip to erase.
2449 * @return 0 on success.
2450 */
2451static int flashrom_flash_erase(struct flashctx *const flashctx,
2452 void *oldcontents, void *newcontents, size_t size)
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002453{
2454 /*
2455 * To make sure that the chip is fully erased, let's cheat and create
2456 * a descriptor where the new contents are all erased.
2457 */
2458 struct action_descriptor *fake_descriptor;
2459 int ret = 0;
2460
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002461 fake_descriptor = prepare_action_descriptor(flashctx, oldcontents,
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002462 newcontents, 1);
2463 /* FIXME: Do we really want the scary warning if erase failed? After
2464 * all, after erase the chip is either blank or partially blank or it
2465 * has the old contents. A blank chip won't boot, so if the user
2466 * wanted erase and reboots afterwards, the user knows very well that
2467 * booting won't work.
2468 */
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002469 if (erase_and_write_flash(flashctx, fake_descriptor)) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002470 emergency_help_message();
2471 ret = 1;
2472 }
2473
2474 free(fake_descriptor);
2475
2476 return ret;
2477}
2478
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002479/** @} */ /* end flashrom-flash */
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.
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002504 *
2505 *
2506 * The main processing function of flashrom utility; it is invoked once
2507 * command line parameters are processed and verified, and the type of the
2508 * flash chip the programmer operates on has been determined.
2509 *
2510 * @flash pointer to the flash context matching the chip detected
2511 * during initialization.
2512 * @force when set proceed even if the chip is not known to work
2513 * @filename pointer to the name of the file to read from or write to
2514 * @read_it when true, flash contents are read into 'filename'
2515 * @write_it when true, flash is programmed with 'filename' contents
2516 * @erase_it when true, flash chip is erased
2517 * @verify_it depending on the value verify the full chip, only changed
2518 * areas, or none
2519 * @extract_it extract all known flash chip regions into separate files
2520 * @diff_file when deciding what areas to program, use this file's
2521 * contents instead of reading the current chip contents
2522 * @do_diff when true - compare result of the operation with either the
2523 * original chip contents for 'diff_file' contents, is present.
2524 * When false - do not diff, consider the chip erased before
2525 * operation starts.
2526 *
2527 * Only one of 'read_it', 'write_it', and 'erase_it' is expected to be set,
2528 * but this is not enforced.
2529 *
2530 * 'do_diff' must be set if 'diff_file' is set. If 'do_diff' is set, but
2531 * 'diff_file' is not - comparison is done against the pre-operation chip
2532 * contents.
hailfingerc77acb52009-12-24 02:15:55 +00002533 */
Edward O'Callaghan888e50e2020-12-03 12:39:22 +11002534int doit(struct flashctx *flash, const char *filename, int read_it,
Edward O'Callaghan486aaf02020-12-03 13:36:42 +11002535 int write_it, int erase_it, int verify_it,
Edward O'Callaghane8118582020-12-03 12:45:59 +11002536 const char *diff_file)
hailfingerc77acb52009-12-24 02:15:55 +00002537{
hailfinger4c47e9d2010-10-19 22:06:20 +00002538 uint8_t *oldcontents;
2539 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002540 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002541 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002542 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002543
hailfinger771fc182010-10-15 00:01:14 +00002544 if (read_it) {
2545 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002546 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002547 }
hailfingerb437e282010-11-04 01:04:27 +00002548
stefanctd611e8f2011-07-12 22:35:21 +00002549 oldcontents = malloc(size);
2550 if (!oldcontents) {
2551 msg_gerr("Out of memory!\n");
2552 exit(1);
2553 }
Simon Glass4c214132013-07-16 10:09:28 -06002554 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002555 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002556 newcontents = malloc(size);
2557 if (!newcontents) {
2558 msg_gerr("Out of memory!\n");
2559 exit(1);
2560 }
Simon Glass4c214132013-07-16 10:09:28 -06002561 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002562 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002563 /* Side effect of the assumptions above: Default write action is erase
2564 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002565 * oldcontents being completely unerased means we have to erase
2566 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002567 */
2568
hailfingerd217d122010-10-08 18:52:29 +00002569 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002570 /*
2571 * Note: This must be done before any files specified by -i
2572 * arguments are processed merged into the newcontents since
2573 * -i files take priority. See http://crbug.com/263495.
2574 */
2575 if (filename) {
2576 if (read_buf_from_file(newcontents, size, filename)) {
2577 ret = 1;
2578 goto out;
2579 }
2580 } else {
2581 /* Content will be read from -i args, so they must
2582 * not overlap. */
2583 if (included_regions_overlap()) {
2584 msg_gerr("Error: Included regions must "
2585 "not overlap.\n");
2586 ret = 1;
2587 goto out;
2588 }
stepan1da96c02006-11-21 23:48:51 +00002589 }
ollie5672ac62004-03-17 22:22:08 +00002590 }
2591
Edward O'Callaghane8118582020-12-03 12:45:59 +11002592 if (flash->flags.do_diff) {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002593 /*
2594 * Obtain a reference image so that we can check whether
2595 * regions need to be erased and to give better diagnostics in
2596 * case write fails. If --fast-verify is used then only the
2597 * regions which are included using -i will be read.
2598 */
2599 if (diff_file) {
2600 msg_cdbg("Reading old contents from file... ");
2601 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002602 ret = 1;
2603 msg_cdbg("FAILED.\n");
2604 goto out;
2605 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002606 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002607 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002608 ret = read_dest_content(flash, verify_it,
2609 oldcontents, size);
2610 if (ret) {
2611 msg_cdbg("FAILED.\n");
2612 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002613 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002614 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002615 msg_cdbg("done.\n");
2616 } else if (!erase_it) {
2617 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002618 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002619 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002620
David Hendricksdf29a832013-06-28 14:33:51 -07002621 /*
2622 * Note: This must be done after reading the file specified for the
2623 * -w/-v argument, if any, so that files specified using -i end up
2624 * in the "newcontents" buffer before being written.
2625 * See http://crbug.com/263495.
2626 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002627 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002628 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002629 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002630 goto out;
2631 }
uwef6641642007-05-09 10:17:44 +00002632
David Hendricksa7e114b2016-02-26 18:49:15 -08002633 if (erase_it) {
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002634 flashrom_flash_erase(flash, oldcontents, newcontents, size);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002635 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002636 }
2637
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002638 descriptor = prepare_action_descriptor(flash, oldcontents,
Edward O'Callaghane8118582020-12-03 12:45:59 +11002639 newcontents, flash->flags.do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002640 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002641 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002642 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002643 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002644 goto out;
2645 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002646
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002647 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002648 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2649 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002650 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002651 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002652 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002653 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002654 ret = 1;
2655 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002656 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002657 msg_cerr("Apparently at least some data has changed.\n");
2658 } else
2659 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002660 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002661 ret = 1;
2662 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002663 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002664
David Hendricksac1d25c2016-08-09 17:00:58 -07002665 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002666 if (ret < 0) {
2667 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002668 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002669 emergency_help_message();
2670 ret = 1;
2671 goto out;
2672 } else if (ret > 0) {
2673 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002674 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002675 ret = read_dest_content(flash, verify_it,
2676 oldcontents, size);
2677 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002678 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002679 goto out;
2680 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002681
2682 /* Get a new descriptor. */
2683 free(descriptor);
2684 descriptor = prepare_action_descriptor(flash,
2685 oldcontents,
2686 newcontents,
Edward O'Callaghane8118582020-12-03 12:45:59 +11002687 flash->flags.do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002688 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002689 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002690 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002691 emergency_help_message();
2692 ret = 1;
2693 goto out;
2694 }
2695 ret = 0;
2696 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002697
David Hendricksac1d25c2016-08-09 17:00:58 -07002698 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002699 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002700 emergency_help_message();
2701 ret = 1;
2702 goto out;
2703 }
stuge8ce3a3c2008-04-28 14:47:30 +00002704 }
ollie6a600992005-11-26 21:55:36 +00002705
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002706 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002707 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002708 if ((write_it || erase_it) && !content_has_changed) {
2709 msg_gdbg("Nothing was erased or written, skipping "
2710 "verification\n");
2711 } else {
2712 /* Work around chips which need some time to calm down. */
2713 if (write_it && verify_it != VERIFY_PARTIAL)
2714 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002715
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002716 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002717
David Hendricks9ba79fb2015-04-03 12:06:16 -07002718 /* If we tried to write, and verification now fails, we
2719 * might have an emergency situation.
2720 */
2721 if (ret && write_it)
2722 emergency_help_message();
2723 }
hailfinger0459e1c2009-08-19 13:55:34 +00002724 }
ollie6a600992005-11-26 21:55:36 +00002725
hailfinger90fcf9b2010-11-05 14:51:59 +00002726out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002727 if (descriptor)
2728 free(descriptor);
2729
hailfinger90fcf9b2010-11-05 14:51:59 +00002730 free(oldcontents);
2731 free(newcontents);
2732out_nofree:
David Hendricks668f29d2011-01-27 18:51:45 -08002733 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002734 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002735 * tree. This is because some operations, such as write protection,
2736 * requires programmer_shutdown() but does not call doit().
2737 */
2738// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002739 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002740}
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002741
2742/** @} */ /* end flashrom-ops */
2743
2744int do_read(struct flashctx *const flash, const char *const filename)
2745{
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002746 if (prepare_flash_access(flash, true, false, false, false))
2747 return 1;
2748
Edward O'Callaghan486aaf02020-12-03 13:36:42 +11002749 int ret = doit(flash, filename, true, false, false, false, NULL);
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002750 finalize_flash_access(flash);
2751
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002752 return ret;
2753}
2754
2755int do_erase(struct flashctx *const flash, const char *diff_file)
2756{
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002757 if (prepare_flash_access(flash, false, false, true, false))
2758 return 1;
2759
Edward O'Callaghan486aaf02020-12-03 13:36:42 +11002760 int ret = doit(flash, NULL, false, false, true, false, diff_file);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002761
2762 /*
2763 * FIXME: Do we really want the scary warning if erase failed?
2764 * After all, after erase the chip is either blank or partially
2765 * blank or it has the old contents. A blank chip won't boot,
2766 * so if the user wanted erase and reboots afterwards, the user
2767 * knows very well that booting won't work.
2768 */
2769 if (ret)
2770 emergency_help_message();
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002771 finalize_flash_access(flash);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002772
2773 return ret;
2774}
2775
2776int do_write(struct flashctx *const flash, const char *const filename, const char *const referencefile, const char *diff_file)
2777{
Sam McNally99c62982020-12-08 12:34:27 +11002778 if (prepare_flash_access(flash, false, true, false, flash->flags.verify_after_write))
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002779 return 1;
2780
Sam McNally99c62982020-12-08 12:34:27 +11002781 int ret = doit(flash, filename, false, true, false,
2782 flash->flags.verify_after_write
2783 ? flash->flags.verify_whole_chip ? VERIFY_FULL : VERIFY_PARTIAL
2784 : 0,
2785 diff_file);
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002786 finalize_flash_access(flash);
2787
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002788 return ret;
2789}
2790
2791int do_verify(struct flashctx *const flash, const char *const filename, const char *diff_file)
2792{
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002793 if (prepare_flash_access(flash, false, false, false, true))
2794 return 1;
2795
Sam McNally99c62982020-12-08 12:34:27 +11002796 int ret = doit(flash, filename, false, false, false, flash->flags.verify_whole_chip ? VERIFY_FULL : VERIFY_PARTIAL, diff_file);
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002797 finalize_flash_access(flash);
2798
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002799 return ret;
2800}
2801
2802int do_extract_it(struct flashctx *const flash)
2803{
2804 if (prepare_flash_access(flash, false, false, false, false))
2805 return 1;
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002806 int ret = extract_regions(flash);
2807 finalize_flash_access(flash);
2808
2809 return ret;
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002810}