blob: 10b2e1047415342c46f74a25e3f6f6ec1e4f8889 [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 */
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +110054static enum error_action access_denied_action = error_ignore;
David Hendricks1ed1d352011-11-23 17:54:37 -080055
56int ignore_error(int err) {
57 int rc = 0;
58
59 switch(err) {
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +110060 case SPI_ACCESS_DENIED:
David Hendricks1ed1d352011-11-23 17:54:37 -080061 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
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001200/* Returns the number of busses commonly supported by the current programmer and flash chip where the latter
1201 * can not be completely accessed due to size/address limits of the programmer. */
1202unsigned int count_max_decode_exceedings(const struct flashctx *flash)
hailfingeraec9c962009-10-31 01:53:09 +00001203{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001204 unsigned int limitexceeded = 0;
1205 uint32_t size = flash->chip->total_size * 1024;
1206 enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
uwe8d342eb2011-07-28 08:13:25 +00001207
1208 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001209 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001210 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001211 "size %u kB of chipset/board/programmer "
1212 "for %s interface, "
1213 "probe/read/erase/write may fail. ", size / 1024,
1214 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001215 }
hailfingere1e41ea2011-07-27 07:13:06 +00001216 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001217 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001218 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001219 "size %u kB of chipset/board/programmer "
1220 "for %s interface, "
1221 "probe/read/erase/write may fail. ", size / 1024,
1222 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001223 }
hailfingere1e41ea2011-07-27 07:13:06 +00001224 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001225 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001226 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001227 "size %u kB of chipset/board/programmer "
1228 "for %s interface, "
1229 "probe/read/erase/write may fail. ", size / 1024,
1230 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001231 }
hailfingere1e41ea2011-07-27 07:13:06 +00001232 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001233 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001234 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001235 "size %u kB of chipset/board/programmer "
1236 "for %s interface, "
1237 "probe/read/erase/write may fail. ", size / 1024,
1238 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001239 }
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001240 return limitexceeded;
hailfingeraec9c962009-10-31 01:53:09 +00001241}
1242
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001243void unmap_flash(struct flashctx *flash)
1244{
1245 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1246 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1247 flash->physical_registers = 0;
1248 flash->virtual_registers = (chipaddr)ERROR_PTR;
1249 }
1250
1251 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1252 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1253 flash->physical_memory = 0;
1254 flash->virtual_memory = (chipaddr)ERROR_PTR;
1255 }
1256}
1257
1258int map_flash(struct flashctx *flash)
1259{
1260 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1261 flash->virtual_memory = (chipaddr)ERROR_PTR;
1262 flash->virtual_registers = (chipaddr)ERROR_PTR;
1263
1264 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1265 * These are used for various probing-related hacks that would not map successfully anyway and should be
1266 * removed ASAP. */
1267 if (flash->chip->total_size == 0)
1268 return 0;
1269
1270 const chipsize_t size = flash->chip->total_size * 1024;
1271 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1272 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1273 if (addr == ERROR_PTR) {
1274 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1275 flash->chip->name, PRIxPTR_WIDTH, base);
1276 return 1;
1277 }
1278 flash->physical_memory = base;
1279 flash->virtual_memory = (chipaddr)addr;
1280
1281 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1282 * completely different on some chips and programmers, or not mappable at all.
1283 * Ignore these problems for now and always report success. */
1284 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1285 base = 0xffffffff - size - 0x400000 + 1;
1286 addr = programmer_map_flash_region("flash chip registers", base, size);
1287 if (addr == ERROR_PTR) {
1288 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1289 flash->chip->name, PRIxPTR_WIDTH, base);
1290 return 0;
1291 }
1292 flash->physical_registers = base;
1293 flash->virtual_registers = (chipaddr)addr;
1294 }
1295 return 0;
1296}
1297
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001298/*
1299 * Return a string corresponding to the bustype parameter.
1300 * Memory is obtained with malloc() and must be freed with free() by the caller.
1301 */
1302char *flashbuses_to_text(enum chipbustype bustype)
1303{
1304 char *ret = calloc(1, 1);
1305 /*
1306 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1307 * will cease to exist and should be eliminated here as well.
1308 */
1309 if (bustype == BUS_NONSPI) {
1310 ret = strcat_realloc(ret, "Non-SPI, ");
1311 } else {
1312 if (bustype & BUS_PARALLEL)
1313 ret = strcat_realloc(ret, "Parallel, ");
1314 if (bustype & BUS_LPC)
1315 ret = strcat_realloc(ret, "LPC, ");
1316 if (bustype & BUS_FWH)
1317 ret = strcat_realloc(ret, "FWH, ");
1318 if (bustype & BUS_SPI)
1319 ret = strcat_realloc(ret, "SPI, ");
1320 if (bustype & BUS_PROG)
1321 ret = strcat_realloc(ret, "Programmer-specific, ");
1322 if (bustype == BUS_NONE)
1323 ret = strcat_realloc(ret, "None, ");
1324 }
1325 /* Kill last comma. */
1326 ret[strlen(ret) - 2] = '\0';
1327 ret = realloc(ret, strlen(ret) + 1);
1328 return ret;
1329}
1330
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001331int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001332{
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001333 const struct flashchip *chip;
hailfingeraec9c962009-10-31 01:53:09 +00001334 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001335 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001336
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001337 for (chip = flashchips + startchip; chip && chip->name; chip++) {
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001338 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001339 continue;
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001340 buses_common = mst->buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001341 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001342 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001343 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001344 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001345 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001346 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001347 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001348 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001349 continue;
1350 }
stepan782fb172007-04-06 11:58:03 +00001351
hailfinger48ed3e22011-05-04 00:39:50 +00001352 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001353 flash->chip = calloc(1, sizeof(struct flashchip));
1354 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001355 msg_gerr("Out of memory!\n");
1356 exit(1);
1357 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001358 memcpy(flash->chip, chip, sizeof(struct flashchip));
1359 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001360
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001361 if (map_flash(flash) != 0)
1362 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001363
Edward O'Callaghana820b212020-09-17 22:53:26 +10001364 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1365 * is only called with force=1 after normal probing failed.
1366 */
stugec1e55fe2008-07-02 17:15:47 +00001367 if (force)
1368 break;
stepanc98b80b2006-03-16 16:57:41 +00001369
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001370 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001371 goto notfound;
1372
hailfinger48ed3e22011-05-04 00:39:50 +00001373 /* If this is the first chip found, accept it.
1374 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001375 * a non-generic match. SFDP and CFI are generic matches.
1376 * startchip==0 means this call to probe_flash() is the first
1377 * one for this programmer interface (master) and thus no other chip has
1378 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001379 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001380 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1381 msg_cinfo("===\n"
1382 "SFDP has autodetected a flash chip which is "
1383 "not natively supported by flashrom yet.\n");
1384 if (count_usable_erasers(flash) == 0)
1385 msg_cinfo("The standard operations read and "
1386 "verify should work, but to support "
1387 "erase, write and all other "
1388 "possible features");
1389 else
1390 msg_cinfo("All standard operations (read, "
1391 "verify, erase and write) should "
1392 "work, but to support all possible "
1393 "features");
1394
1395 msg_cinfo(" we need to add them manually.\n"
1396 "You can help us by mailing us the output of the following command to "
1397 "flashrom@flashrom.org:\n"
1398 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1399 "Thanks for your help!\n"
1400 "===\n");
1401 }
stugec1e55fe2008-07-02 17:15:47 +00001402
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001403 /* First flash chip detected on this bus. */
1404 if (startchip == 0)
1405 break;
1406 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001407 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001408 break;
1409 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001410notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001411 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001412 free(flash->chip);
1413 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001414 }
uwebe4477b2007-08-23 16:08:21 +00001415
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001416 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001417 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001418
Edward O'Callaghan53ff4ad2020-12-16 20:36:28 +11001419 /* Fill fallback layout covering the whole chip. */
1420 struct single_layout *const fallback = &flash->fallback_layout;
1421 fallback->base.entries = &fallback->entry;
1422 fallback->base.num_entries = 1;
1423 fallback->entry.start = 0;
1424 fallback->entry.end = flash->chip->total_size * 1024 - 1;
1425 fallback->entry.included = true;
1426 fallback->entry.name = strdup("complete flash");
1427 if (!fallback->entry.name) {
1428 msg_cerr("Failed to probe chip: %s\n", strerror(errno));
1429 return -1;
1430 }
stepan3e7aeae2011-01-19 06:21:54 +00001431
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001432 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001433 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1434 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001435 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001436#if CONFIG_INTERNAL == 1
1437 if (programmer_table[programmer].map_flash_region == physmap)
1438 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1439 PRIxPTR_WIDTH, flash->physical_memory);
1440 else
1441#endif
1442 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001443
Edward O'Callaghana820b212020-09-17 22:53:26 +10001444 /* Flash registers may more likely not be mapped if the chip was forced.
1445 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001446 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001447 if (flash->chip->printlock)
1448 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001449
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001450 /* Get out of the way for later runs. */
1451 unmap_flash(flash);
1452
hailfinger48ed3e22011-05-04 00:39:50 +00001453 /* Return position of matching chip. */
Edward O'Callaghan723c12c2020-08-01 22:42:00 +10001454 return chip - flashchips;
rminnich8d3ff912003-10-25 17:01:29 +00001455}
1456
uwe8d342eb2011-07-28 08:13:25 +00001457int read_buf_from_file(unsigned char *buf, unsigned long size,
1458 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001459{
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001460#ifdef __LIBPAYLOAD__
1461 msg_gerr("Error: No file I/O support in libpayload\n");
1462 return 1;
1463#else
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001464 int ret = 0;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001465
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001466 FILE *image;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001467 if (!strncmp(filename, "-", sizeof("-")))
1468 image = fdopen(STDIN_FILENO, "rb");
1469 else
1470 image = fopen(filename, "rb");
1471 if (image == NULL) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001472 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger771fc182010-10-15 00:01:14 +00001473 return 1;
1474 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001475
1476 struct stat image_stat;
hailfinger771fc182010-10-15 00:01:14 +00001477 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001478 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001479 ret = 1;
1480 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001481 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001482 if ((image_stat.st_size != size) &&
1483 (strncmp(filename, "-", sizeof("-")))) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001484 msg_gerr("Error: Image size (%jd B) doesn't match the flash chip's size (%lu B)!\n",
1485 (intmax_t)image_stat.st_size, size);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001486 ret = 1;
1487 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001488 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001489
1490 unsigned long numbytes = fread(buf, 1, size, image);
hailfinger771fc182010-10-15 00:01:14 +00001491 if (numbytes != size) {
1492 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1493 "wanted %ld!\n", numbytes, size);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001494 ret = 1;
hailfinger771fc182010-10-15 00:01:14 +00001495 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001496out:
1497 (void)fclose(image);
1498 return ret;
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001499#endif
hailfinger771fc182010-10-15 00:01:14 +00001500}
1501
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001502int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001503{
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001504#ifdef __LIBPAYLOAD__
1505 msg_gerr("Error: No file I/O support in libpayload\n");
1506 return 1;
1507#else
hailfingerd219a232009-01-28 00:27:54 +00001508 FILE *image;
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001509 int ret = 0;
hailfingerde345862009-06-01 22:07:52 +00001510
1511 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001512 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001513 return 1;
1514 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001515 if (!strncmp(filename, "-", sizeof("-")))
1516 image = fdopen(STDOUT_FILENO, "wb");
1517 else
1518 image = fopen(filename, "wb");
1519 if (image == NULL) {
Edward O'Callaghan1c7092d2020-12-13 12:28:57 +11001520 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger23060112009-05-08 12:49:03 +00001521 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001522 }
hailfingerd219a232009-01-28 00:27:54 +00001523
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001524 unsigned long numbytes = fwrite(buf, 1, size, image);
hailfinger42a850a2010-07-13 23:56:13 +00001525 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001526 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001527 ret = 1;
1528 goto out;
hailfinger42a850a2010-07-13 23:56:13 +00001529 }
Edward O'Callaghane20f1582020-12-13 11:58:37 +11001530 if (fflush(image)) {
1531 msg_gerr("Error: flushing file \"%s\" failed: %s\n", filename, strerror(errno));
1532 ret = 1;
1533 }
1534 // Try to fsync() only regular files and if that function is available at all (e.g. not on MinGW).
1535#if defined(_POSIX_FSYNC) && (_POSIX_FSYNC != -1)
1536 struct stat image_stat;
1537 if (fstat(fileno(image), &image_stat) != 0) {
1538 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1539 ret = 1;
1540 goto out;
1541 }
1542 if (S_ISREG(image_stat.st_mode)) {
1543 if (fsync(fileno(image))) {
1544 msg_gerr("Error: fsyncing file \"%s\" failed: %s\n", filename, strerror(errno));
1545 ret = 1;
1546 }
1547 }
1548#endif
1549out:
1550 if (fclose(image)) {
1551 msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
1552 ret = 1;
1553 }
1554 return ret;
Edward O'Callaghan597e2972020-12-13 12:24:49 +11001555#endif
hailfingerd219a232009-01-28 00:27:54 +00001556}
1557
David Hendrickse3451942013-03-21 17:23:29 -07001558/*
1559 * read_flash - wrapper for flash->read() with additional high-level policy
1560 *
1561 * @flash flash chip
1562 * @buf buffer to store data in
1563 * @start start address
1564 * @len number of bytes to read
1565 *
1566 * This wrapper simplifies most cases when the flash chip needs to be read
1567 * since policy decisions such as non-fatal error handling is centralized.
1568 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001569int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001570 unsigned int start, unsigned int len)
1571{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001572 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001573
Patrick Georgif3fa2992017-02-02 16:24:44 +01001574 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001575 return -1;
1576
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001577 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1578
Patrick Georgif3fa2992017-02-02 16:24:44 +01001579 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001580 if (ret) {
1581 if (ignore_error(ret)) {
1582 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1583 start, start + len - 1);
1584 ret = 0;
1585 } else {
1586 msg_gdbg("failed to read 0x%x-0x%x\n",
1587 start, start + len - 1);
1588 }
1589 }
1590
1591 return ret;
1592}
1593
David Hendricks7c8a1612013-04-26 19:14:44 -07001594/*
1595 * write_flash - wrapper for flash->write() with additional high-level policy
1596 *
1597 * @flash flash chip
1598 * @buf buffer to write to flash
1599 * @start start address in flash
1600 * @len number of bytes to write
1601 *
1602 * TODO: Look up regions that are write-protected and avoid attempt to write
1603 * to them at all.
1604 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001605int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001606 unsigned int start, unsigned int len)
1607{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001608 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001609 return -1;
1610
Patrick Georgif3fa2992017-02-02 16:24:44 +01001611 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001612}
1613
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001614int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001615{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001616 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001617 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001618 int ret = 0;
1619
1620 msg_cinfo("Reading flash... ");
1621 if (!buf) {
1622 msg_gerr("Memory allocation failed!\n");
1623 msg_cinfo("FAILED.\n");
1624 return 1;
1625 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001626
1627 /* To support partial read, fill buffer to all 0xFF at beginning to make
1628 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001629 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001630
Patrick Georgif3fa2992017-02-02 16:24:44 +01001631 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001632 msg_cerr("No read function available for this flash chip.\n");
1633 ret = 1;
1634 goto out_free;
1635 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001636
1637 /* First try to handle partial read case, rather than read the whole
1638 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001639 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001640 if (ret < 0) {
1641 msg_cerr("Partial read operation failed!\n");
1642 ret = 1;
1643 goto out_free;
1644 } else if (ret > 0) {
Edward O'Callaghan10bb9ae2020-12-17 13:06:10 +11001645 int num_regions = get_num_include_args(get_global_layout());
David Hendricksdf29a832013-06-28 14:33:51 -07001646
1647 if (ret != num_regions) {
1648 msg_cerr("Requested %d regions, but only read %d\n",
1649 num_regions, ret);
1650 ret = 1;
1651 goto out_free;
1652 }
1653
1654 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001655 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001656 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001657 msg_cerr("Read operation failed!\n");
1658 ret = 1;
1659 goto out_free;
1660 }
hailfinger42a850a2010-07-13 23:56:13 +00001661 }
1662
David Hendricksdf29a832013-06-28 14:33:51 -07001663 if (filename)
1664 ret = write_buf_to_file(buf, size, filename);
1665
hailfinger42a850a2010-07-13 23:56:13 +00001666out_free:
1667 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001668 if (ret)
1669 msg_cerr("FAILED.");
1670 else
1671 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001672 return ret;
1673}
1674
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001675/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001676static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001677{
hailfingerb91c08c2011-08-15 19:54:20 +00001678 int i, j, k;
1679 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001680
1681 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1682 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001683 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001684
1685 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1686 /* Blocks with zero size are bugs in flashchips.c. */
1687 if (eraser.eraseblocks[i].count &&
1688 !eraser.eraseblocks[i].size) {
1689 msg_gerr("ERROR: Flash chip %s erase function "
1690 "%i region %i has size 0. Please report"
1691 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001692 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001693 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001694 }
1695 /* Blocks with zero count are bugs in flashchips.c. */
1696 if (!eraser.eraseblocks[i].count &&
1697 eraser.eraseblocks[i].size) {
1698 msg_gerr("ERROR: Flash chip %s erase function "
1699 "%i region %i has count 0. Please report"
1700 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001701 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001702 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001703 }
1704 done += eraser.eraseblocks[i].count *
1705 eraser.eraseblocks[i].size;
1706 }
hailfinger9fed35d2010-01-19 06:42:46 +00001707 /* Empty eraseblock definition with erase function. */
1708 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001709 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001710 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001711 if (!done)
1712 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001713 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001714 msg_gerr("ERROR: Flash chip %s erase function %i "
1715 "region walking resulted in 0x%06x bytes total,"
1716 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001717 " flashrom@flashrom.org\n", chip->name, k,
1718 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001719 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001720 }
hailfinger9fed35d2010-01-19 06:42:46 +00001721 if (!eraser.block_erase)
1722 continue;
1723 /* Check if there are identical erase functions for different
1724 * layouts. That would imply "magic" erase functions. The
1725 * easiest way to check this is with function pointers.
1726 */
uwef6f94d42010-03-13 17:28:29 +00001727 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001728 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001729 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001730 msg_gerr("ERROR: Flash chip %s erase function "
1731 "%i and %i are identical. Please report"
1732 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001733 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001734 ret = 1;
1735 }
uwef6f94d42010-03-13 17:28:29 +00001736 }
hailfinger45177872010-01-18 08:14:43 +00001737 }
hailfinger9fed35d2010-01-19 06:42:46 +00001738 return ret;
hailfinger45177872010-01-18 08:14:43 +00001739}
1740
Edward O'Callaghanbef74c22020-12-04 16:23:54 +11001741static int check_block_eraser(const struct flashctx *flash, int k, int log)
1742{
1743 struct block_eraser eraser = flash->chip->block_erasers[k];
1744
1745 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1746 if (log)
1747 msg_cdbg("not defined. ");
1748 return 1;
1749 }
1750 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1751 if (log)
1752 msg_cdbg("eraseblock layout is known, but matching "
1753 "block erase function is not implemented. ");
1754 return 1;
1755 }
1756 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1757 if (log)
1758 msg_cdbg("block erase function found, but "
1759 "eraseblock layout is not defined. ");
1760 return 1;
1761 }
1762 // TODO: Once erase functions are annotated with allowed buses, check that as well.
1763 return 0;
1764}
1765
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001766typedef int (*erasefn_t)(struct flashctx *, unsigned int addr, unsigned int len);
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001767/**
1768 * @private
1769 *
1770 * For read-erase-write, `curcontents` and `newcontents` shall point
1771 * to buffers of the chip's size. Both are supposed to be prefilled
1772 * with at least the included layout regions of the current flash
1773 * contents (`curcontents`) and the data to be written to the flash
1774 * (`newcontents`).
1775 *
1776 * For erase, `curcontents` and `newcontents` shall be NULL-pointers.
1777 *
1778 * The `chipoff_t` values are used internally by `walk_by_layout()`.
1779 */
1780struct walk_info {
1781 uint8_t *curcontents;
1782 const uint8_t *newcontents;
1783 chipoff_t erase_start;
1784 chipoff_t erase_len;
1785};
Edward O'Callaghan5e9e5712020-12-10 11:11:56 +11001786typedef int (*per_blockfn_t)(struct flashctx *, struct walk_info *const, erasefn_t);
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001787
Edward O'Callaghanecc0b202020-12-10 11:35:11 +11001788/*
1789 * Function to process processing units accumulated in the action descriptor.
1790 *
1791 * @flash pointer to the flash context to operate on
1792 * @per_blockfn helper function which can erase and program a section of the
1793 * flash chip. It receives the flash context, offset and length
1794 * of the area to erase/program, before and after contents (to
1795 * decide what exactly needs to be erased and or programmed)
1796 * and a pointer to the erase function which can operate on the
1797 * proper granularity.
1798 * @descriptor action descriptor including pointers to before and after
1799 * contents and an array of processing actions to take.
1800 *
1801 * Returns zero on success or an error code.
1802 */
1803static int walk_eraseregions(struct flashctx *flash,
1804 const per_blockfn_t per_blockfn,
1805 struct action_descriptor *descriptor)
1806{
1807 struct processing_unit *pu;
1808 int rc = 0;
1809 static int print_comma;
1810
1811 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
1812 unsigned base = pu->offset;
1813 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
1814
1815 while (base < top) {
1816
1817 if (print_comma)
1818 msg_cdbg(", ");
1819 else
1820 print_comma = 1;
1821
1822 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
1823
1824 struct walk_info info = {
1825 .curcontents = descriptor->oldcontents,
1826 .newcontents = descriptor->newcontents,
1827 .erase_start = base,
1828 .erase_len = pu->block_size,
1829 };
1830 rc = per_blockfn(flash, &info,
1831 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
1832
1833 if (rc) {
1834 if (ignore_error(rc))
1835 rc = 0;
1836 else
1837 return rc;
1838 }
1839 base += pu->block_size;
1840 }
1841 }
1842 msg_cdbg("\n");
1843 return rc;
1844}
1845
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001846static int erase_and_write_block_helper(struct flashctx *flash,
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001847 struct walk_info *const info,
Edward O'Callaghan58c3f382020-12-04 16:26:55 +11001848 erasefn_t erasefn)
hailfingerb437e282010-11-04 01:04:27 +00001849{
stefanctc5eb8a92011-11-23 09:13:48 +00001850 unsigned int starthere = 0, lenhere = 0;
1851 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001852 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001853 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001854
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001855 /*
1856 * curcontents and newcontents are opaque to walk_eraseregions, and
1857 * need to be adjusted here to keep the impression of proper
1858 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001859 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001860
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001861 info->curcontents += info->erase_start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001862
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001863 info->newcontents += info->erase_start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001864
hailfingerb437e282010-11-04 01:04:27 +00001865 msg_cdbg(":");
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001866 if (need_erase(info->curcontents, info->newcontents, info->erase_len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001867 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001868 msg_cdbg(" E");
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001869 ret = erasefn(flash, info->erase_start, info->erase_len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001870 if (ret) {
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +11001871 if (ret == SPI_ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001872 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001873 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001874 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001875 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001876 }
1877
David Hendricks0954ffc2015-11-13 15:15:44 -08001878 if (programmer_table[programmer].paranoid) {
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001879 if (check_erased_range(flash, info->erase_start, info->erase_len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001880 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001881 return -1;
1882 }
hailfingerac8e3182011-06-26 17:04:16 +00001883 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001884
hailfinger90fcf9b2010-11-05 14:51:59 +00001885 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001886 memset(info->curcontents, ERASED_VALUE(flash), info->erase_len);
hailfingerb437e282010-11-04 01:04:27 +00001887 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001888 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001889 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001890 /* get_next_write() sets starthere to a new value after the call. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001891 while ((lenhere = get_next_write(info->curcontents + starthere,
1892 info->newcontents + starthere,
1893 info->erase_len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001894 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001895 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001896 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001897 /* Needs the partial write function signature. */
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001898 ret = write_flash(flash, (uint8_t *)info->newcontents + starthere,
1899 info->erase_start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001900 if (ret) {
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +11001901 if (ret == SPI_ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001902 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001903 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001904 }
David Hendricks048b38c2016-03-28 18:47:06 -07001905
1906 /*
1907 * If the block needed to be erased and was erased successfully
1908 * then we can assume that we didn't run into any write-
1909 * protected areas. Otherwise, we need to verify each page to
1910 * ensure it was successfully written and abort if we encounter
1911 * any errors.
1912 */
1913 if (programmer_table[programmer].paranoid && !block_was_erased) {
Edward O'Callaghan2fc12e22020-12-10 10:32:26 +11001914 if (verify_range(flash, info->newcontents + starthere,
1915 info->erase_start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001916 return -1;
1917 }
1918
hailfingerb437e282010-11-04 01:04:27 +00001919 starthere += lenhere;
1920 skip = 0;
1921 }
1922 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001923 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001924 return ret;
1925}
1926
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001927int erase_and_write_flash(struct flashctx *flash,
1928 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00001929{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001930 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00001931
hailfingercf848f12010-12-05 15:14:44 +00001932 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00001933
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001934 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00001935
hailfinger7df21362009-09-05 02:30:58 +00001936 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00001937 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00001938 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07001939 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00001940 }
1941 return ret;
hailfingerd219a232009-01-28 00:27:54 +00001942}
1943
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11001944static int verify_flash(struct flashctx *flash,
1945 struct action_descriptor *descriptor,
1946 int verify_it)
1947{
1948 int ret;
1949 unsigned int total_size = flash->chip->total_size * 1024;
1950 uint8_t *buf = descriptor->newcontents;
1951
1952 msg_cinfo("Verifying flash... ");
1953
1954 if (verify_it == VERIFY_PARTIAL) {
1955 struct processing_unit *pu = descriptor->processing_units;
1956
1957 /* Verify only areas which were written. */
1958 while (pu->num_blocks) {
1959 ret = verify_range(flash, buf + pu->offset, pu->offset,
1960 pu->block_size * pu->num_blocks);
1961 if (ret)
1962 break;
1963 pu++;
1964 }
1965 } else {
1966 ret = verify_range(flash, buf, 0, total_size);
1967 }
1968
Edward O'Callaghan0a92ce22020-12-09 17:10:37 +11001969 if (ret == SPI_ACCESS_DENIED) {
Edward O'Callaghan3e98d3d2020-12-09 12:19:44 +11001970 msg_gdbg("Could not fully verify due to access error, ");
1971 if (access_denied_action == error_ignore) {
1972 msg_gdbg("ignoring\n");
1973 ret = 0;
1974 } else {
1975 msg_gdbg("aborting\n");
1976 }
1977 }
1978
1979 if (!ret)
1980 msg_cinfo("VERIFIED. \n");
1981
1982 return ret;
1983}
1984
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001985static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00001986{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10001987 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
1988#if CONFIG_INTERNAL == 1
1989 if (programmer == PROGRAMMER_INTERNAL)
1990 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
1991 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1992 "mail flashrom@flashrom.org, thanks!\n"
1993 "-------------------------------------------------------------------------------\n"
1994 "You may now reboot or simply leave the machine running.\n");
1995 else
1996#endif
1997 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
1998 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
1999 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2000 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002001}
2002
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002003static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002004{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002005 msg_gerr("Your flash chip is in an unknown state.\n");
2006#if CONFIG_INTERNAL == 1
2007 if (programmer == PROGRAMMER_INTERNAL)
2008 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2009 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2010 "-------------------------------------------------------------------------------\n"
2011 "DO NOT REBOOT OR POWEROFF!\n");
2012 else
2013#endif
2014 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2015 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002016}
2017
hailfingerf79d1712010-10-06 23:48:34 +00002018void list_programmers_linebreak(int startcol, int cols, int paren)
2019{
2020 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002021 int pnamelen;
2022 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002023 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002024 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002025
2026 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2027 pname = programmer_table[p].name;
2028 pnamelen = strlen(pname);
2029 if (remaining - pnamelen - 2 < 0) {
2030 if (firstline)
2031 firstline = 0;
2032 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002033 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002034 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002035 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002036 remaining = cols - startcol;
2037 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002038 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002039 remaining--;
2040 }
2041 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002042 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002043 remaining--;
2044 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002045 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002046 remaining -= pnamelen;
2047 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002048 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002049 remaining--;
2050 } else {
2051 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002052 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002053 }
2054 }
2055}
2056
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002057static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002058{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002059#if IS_WINDOWS
2060 SYSTEM_INFO si;
2061 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002062
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002063 memset(&si, 0, sizeof(SYSTEM_INFO));
2064 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2065 msg_ginfo(" on Windows");
2066 /* Tell Windows which version of the structure we want. */
2067 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2068 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2069 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2070 else
2071 msg_ginfo(" unknown version");
2072 GetSystemInfo(&si);
2073 switch (si.wProcessorArchitecture) {
2074 case PROCESSOR_ARCHITECTURE_AMD64:
2075 msg_ginfo(" (x86_64)");
2076 break;
2077 case PROCESSOR_ARCHITECTURE_INTEL:
2078 msg_ginfo(" (x86)");
2079 break;
2080 default:
2081 msg_ginfo(" (unknown arch)");
2082 break;
2083 }
2084#elif HAVE_UTSNAME == 1
2085 struct utsname osinfo;
2086
2087 uname(&osinfo);
2088 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002089 osinfo.machine);
2090#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002091 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002092#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002093}
2094
2095void print_buildinfo(void)
2096{
2097 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002098#if NEED_PCI == 1
2099#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002100 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002101#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002102 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002103#endif
2104#endif
2105#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002106 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002107#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002108 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002109#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002110 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002111#endif
hailfinger3b471632010-03-27 16:36:40 +00002112#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002113 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002114#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002115 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002116#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002117 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002118#endif
2119#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002120 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002121#endif
2122#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002123 msg_gdbg(" little endian");
Edward O'Callaghan3c005942020-10-01 16:33:47 +10002124#elif defined (__FLASHROM_BIG_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002125 msg_gdbg(" big endian");
Edward O'Callaghan3c005942020-10-01 16:33:47 +10002126#else
2127#error Endianness could not be determined
hailfinger3b471632010-03-27 16:36:40 +00002128#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002129 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002130}
2131
uwefdeca092008-01-21 15:24:22 +00002132void print_version(void)
2133{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002134 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002135 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002136 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002137}
2138
hailfinger74819ad2010-05-15 15:04:37 +00002139void print_banner(void)
2140{
2141 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002142 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002143 msg_ginfo("\n");
2144}
2145
hailfingerc77acb52009-12-24 02:15:55 +00002146int selfcheck(void)
2147{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002148 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002149 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002150
2151 /* Safety check. Instead of aborting after the first error, check
2152 * if more errors exist.
2153 */
hailfingerc77acb52009-12-24 02:15:55 +00002154 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002155 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002156 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002157 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002158 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2159 const struct programmer_entry p = programmer_table[i];
2160 if (p.name == NULL) {
2161 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2162 ret = 1;
2163 /* This might hide other problems with this programmer, but allows for better error
2164 * messages below without jumping through hoops. */
2165 continue;
2166 }
2167 switch (p.type) {
2168 case USB:
2169 case PCI:
2170 case OTHER:
2171 if (p.devs.note == NULL) {
2172 if (strcmp("internal", p.name) == 0)
2173 break; /* This one has its device list stored separately. */
2174 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2175 p.name);
2176 ret = 1;
2177 }
2178 break;
2179 default:
2180 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2181 ret = 1;
2182 break;
2183 }
2184 if (p.init == NULL) {
2185 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2186 ret = 1;
2187 }
2188 if (p.delay == NULL) {
2189 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2190 ret = 1;
2191 }
2192 if (p.map_flash_region == NULL) {
2193 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2194 ret = 1;
2195 }
2196 if (p.unmap_flash_region == NULL) {
2197 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2198 ret = 1;
2199 }
2200 }
2201
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002202 /* It would be favorable if we could check for the correct layout (especially termination) of various
2203 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2204 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2205 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2206 * 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 +10002207 * checks below. */
2208 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002209 msg_gerr("Flashchips table miscompilation!\n");
2210 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002211 } else {
2212 for (i = 0; i < flashchips_size - 1; i++) {
2213 const struct flashchip *chip = &flashchips[i];
2214 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2215 ret = 1;
2216 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2217 "Please report a bug at flashrom@flashrom.org\n", i,
2218 chip->name == NULL ? "unnamed" : chip->name);
2219 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002220 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002221 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002222 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002223 }
stefanct6d836ba2011-05-26 01:35:19 +00002224 }
stefanct6d836ba2011-05-26 01:35:19 +00002225
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002226 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002227 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002228}
2229
hailfinger771fc182010-10-15 00:01:14 +00002230/* FIXME: This function signature needs to be improved once doit() has a better
2231 * function signature.
2232 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002233static int chip_safety_check(const struct flashctx *flash, int force,
2234 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002235{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002236 const struct flashchip *chip = flash->chip;
2237
hailfinger771fc182010-10-15 00:01:14 +00002238 if (!programmer_may_write && (write_it || erase_it)) {
2239 msg_perr("Write/erase is not working yet on your programmer in "
2240 "its current configuration.\n");
2241 /* --force is the wrong approach, but it's the best we can do
2242 * until the generic programmer parameter parser is merged.
2243 */
2244 if (!force)
2245 return 1;
2246 msg_cerr("Continuing anyway.\n");
2247 }
2248
2249 if (read_it || erase_it || write_it || verify_it) {
2250 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002251 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002252 msg_cerr("Read is not working on this chip. ");
2253 if (!force)
2254 return 1;
2255 msg_cerr("Continuing anyway.\n");
2256 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002257 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002258 msg_cerr("flashrom has no read function for this "
2259 "flash chip.\n");
2260 return 1;
2261 }
2262 }
2263 if (erase_it || write_it) {
2264 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002265 if (chip->tested.erase == NA) {
2266 msg_cerr("Erase is not possible on this chip.\n");
2267 return 1;
2268 }
2269 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002270 msg_cerr("Erase is not working on this chip. ");
2271 if (!force)
2272 return 1;
2273 msg_cerr("Continuing anyway.\n");
2274 }
stefancte1c5acf2011-07-04 07:27:17 +00002275 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002276 msg_cerr("flashrom has no erase function for this "
2277 "flash chip.\n");
2278 return 1;
2279 }
hailfinger771fc182010-10-15 00:01:14 +00002280 }
2281 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002282 if (chip->tested.write == NA) {
2283 msg_cerr("Write is not possible on this chip.\n");
2284 return 1;
2285 }
2286 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002287 msg_cerr("Write is not working on this chip. ");
2288 if (!force)
2289 return 1;
2290 msg_cerr("Continuing anyway.\n");
2291 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002292 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002293 msg_cerr("flashrom has no write function for this "
2294 "flash chip.\n");
2295 return 1;
2296 }
2297 }
2298 return 0;
2299}
2300
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002301int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002302 const bool read_it, const bool write_it,
2303 const bool erase_it, const bool verify_it)
2304{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002305 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002306 msg_cerr("Aborting.\n");
2307 return 1;
2308 }
2309
2310 if (normalize_romentries(flash)) {
2311 msg_cerr("Requested regions can not be handled. Aborting.\n");
2312 return 1;
2313 }
2314
Edward O'Callaghan40092972020-10-20 11:50:48 +11002315 /*
2316 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2317 * can be repro'ed with upstream on Volteer.
2318 *
2319 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2320 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2321 * hooked and this can fail on some board topologies. Checking the return value can
2322 * cause board rw failures by bailing early. Avoid the early bail for now until a
2323 * full investigation can reveal the proper fix. This restores previous behaviour of
2324 * assuming a map went fine.
2325 */
2326#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002327 if (map_flash(flash) != 0)
2328 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002329#endif
2330 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002331
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002332 /* Given the existence of read locks, we want to unlock for read,
2333 erase and write. */
2334 if (flash->chip->unlock)
2335 flash->chip->unlock(flash);
2336
2337 flash->address_high_byte = -1;
2338 flash->in_4ba_mode = false;
Nikolai Artemiev55f7a332020-11-05 13:54:27 +11002339 flash->chip_restore_fn_count = 0;
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002340
Edward O'Callaghan99974452020-10-13 13:28:33 +11002341 /* Be careful about 4BA chips and broken masters */
2342 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2343 /* If we can't use native instructions, bail out */
2344 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2345 || !spi_master_4ba(flash)) {
2346 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2347 return 1;
2348 }
2349 }
2350
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002351 return 0;
2352}
2353
Edward O'Callaghana820b212020-09-17 22:53:26 +10002354void finalize_flash_access(struct flashctx *const flash)
2355{
Nikolai Artemiev55f7a332020-11-05 13:54:27 +11002356 deregister_chip_restore(flash);
Edward O'Callaghana820b212020-09-17 22:53:26 +10002357 unmap_flash(flash);
2358}
2359
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002360/**
2361 * @addtogroup flashrom-flash
2362 * @{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002363 */
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002364
2365/**
2366 * @brief Erase the specified ROM chip.
2367 *
2368 * If a layout is set in the given flash context, only included regions
2369 * will be erased.
2370 *
2371 * @param flashctx The context of the flash chip to erase.
2372 * @return 0 on success.
2373 */
2374static int flashrom_flash_erase(struct flashctx *const flashctx,
2375 void *oldcontents, void *newcontents, size_t size)
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002376{
2377 /*
2378 * To make sure that the chip is fully erased, let's cheat and create
2379 * a descriptor where the new contents are all erased.
2380 */
2381 struct action_descriptor *fake_descriptor;
2382 int ret = 0;
2383
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002384 fake_descriptor = prepare_action_descriptor(flashctx, oldcontents,
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002385 newcontents, 1);
2386 /* FIXME: Do we really want the scary warning if erase failed? After
2387 * all, after erase the chip is either blank or partially blank or it
2388 * has the old contents. A blank chip won't boot, so if the user
2389 * wanted erase and reboots afterwards, the user knows very well that
2390 * booting won't work.
2391 */
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002392 if (erase_and_write_flash(flashctx, fake_descriptor)) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002393 emergency_help_message();
2394 ret = 1;
2395 }
2396
2397 free(fake_descriptor);
2398
2399 return ret;
2400}
2401
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002402/** @} */ /* end flashrom-flash */
2403
Edward O'Callaghan8c2a3402020-12-09 12:23:01 +11002404/**
2405 * @defgroup flashrom-ops Operations
2406 * @{
2407 */
2408
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002409
Edward O'Callaghan84c89182020-12-09 12:33:37 +11002410/**
2411 * @brief Read the current image from the specified ROM chip.
2412 *
2413 * If a layout is set in the specified flash context, only included regions
2414 * will be read.
2415 *
2416 * @param flashctx The context of the flash chip.
2417 * @param buffer Target buffer to write image to.
2418 * @param buffer_len Size of target buffer in bytes.
2419 * @return 0 on success,
2420 * 2 if buffer_len is too short for the flash chip's contents,
2421 * or 1 on any other failure.
2422 */
2423int flashrom_image_read(struct flashctx *const flashctx, int verify_it,
2424 void *const buffer, const size_t buffer_len)
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002425{
2426 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
Edward O'Callaghan10bb9ae2020-12-17 13:06:10 +11002427 && get_num_include_args(get_global_layout())) {
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002428 /*
2429 * If no full verification is required and not
2430 * the entire chip is about to be programmed,
2431 * read only the areas which might change.
2432 */
Edward O'Callaghan84c89182020-12-09 12:33:37 +11002433 if (handle_partial_read(flashctx, buffer, read_flash, 0) < 0)
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002434 return 1;
2435 } else {
Edward O'Callaghan84c89182020-12-09 12:33:37 +11002436 if (read_flash(flashctx, buffer, 0, buffer_len))
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002437 return 1;
2438 }
2439 return 0;
2440}
2441
hailfingerc77acb52009-12-24 02:15:55 +00002442/* This function signature is horrible. We need to design a better interface,
2443 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002444 * Besides that, the function itself is a textbook example of abysmal code flow.
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002445 *
2446 *
2447 * The main processing function of flashrom utility; it is invoked once
2448 * command line parameters are processed and verified, and the type of the
2449 * flash chip the programmer operates on has been determined.
2450 *
2451 * @flash pointer to the flash context matching the chip detected
2452 * during initialization.
2453 * @force when set proceed even if the chip is not known to work
2454 * @filename pointer to the name of the file to read from or write to
2455 * @read_it when true, flash contents are read into 'filename'
2456 * @write_it when true, flash is programmed with 'filename' contents
2457 * @erase_it when true, flash chip is erased
2458 * @verify_it depending on the value verify the full chip, only changed
2459 * areas, or none
2460 * @extract_it extract all known flash chip regions into separate files
2461 * @diff_file when deciding what areas to program, use this file's
2462 * contents instead of reading the current chip contents
2463 * @do_diff when true - compare result of the operation with either the
2464 * original chip contents for 'diff_file' contents, is present.
2465 * When false - do not diff, consider the chip erased before
2466 * operation starts.
2467 *
2468 * Only one of 'read_it', 'write_it', and 'erase_it' is expected to be set,
2469 * but this is not enforced.
2470 *
2471 * 'do_diff' must be set if 'diff_file' is set. If 'do_diff' is set, but
2472 * 'diff_file' is not - comparison is done against the pre-operation chip
2473 * contents.
hailfingerc77acb52009-12-24 02:15:55 +00002474 */
Edward O'Callaghan888e50e2020-12-03 12:39:22 +11002475int doit(struct flashctx *flash, const char *filename, int read_it,
Edward O'Callaghan486aaf02020-12-03 13:36:42 +11002476 int write_it, int erase_it, int verify_it,
Edward O'Callaghane8118582020-12-03 12:45:59 +11002477 const char *diff_file)
hailfingerc77acb52009-12-24 02:15:55 +00002478{
hailfinger4c47e9d2010-10-19 22:06:20 +00002479 uint8_t *oldcontents;
2480 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002481 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002482 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002483 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002484
stefanctd611e8f2011-07-12 22:35:21 +00002485 oldcontents = malloc(size);
2486 if (!oldcontents) {
2487 msg_gerr("Out of memory!\n");
2488 exit(1);
2489 }
Simon Glass4c214132013-07-16 10:09:28 -06002490 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002491 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002492 newcontents = malloc(size);
2493 if (!newcontents) {
2494 msg_gerr("Out of memory!\n");
2495 exit(1);
2496 }
Simon Glass4c214132013-07-16 10:09:28 -06002497 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002498 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002499 /* Side effect of the assumptions above: Default write action is erase
2500 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002501 * oldcontents being completely unerased means we have to erase
2502 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002503 */
2504
hailfingerd217d122010-10-08 18:52:29 +00002505 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002506 /*
2507 * Note: This must be done before any files specified by -i
2508 * arguments are processed merged into the newcontents since
2509 * -i files take priority. See http://crbug.com/263495.
2510 */
2511 if (filename) {
2512 if (read_buf_from_file(newcontents, size, filename)) {
2513 ret = 1;
2514 goto out;
2515 }
2516 } else {
2517 /* Content will be read from -i args, so they must
2518 * not overlap. */
2519 if (included_regions_overlap()) {
2520 msg_gerr("Error: Included regions must "
2521 "not overlap.\n");
2522 ret = 1;
2523 goto out;
2524 }
stepan1da96c02006-11-21 23:48:51 +00002525 }
ollie5672ac62004-03-17 22:22:08 +00002526 }
2527
Edward O'Callaghane8118582020-12-03 12:45:59 +11002528 if (flash->flags.do_diff) {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002529 /*
2530 * Obtain a reference image so that we can check whether
2531 * regions need to be erased and to give better diagnostics in
2532 * case write fails. If --fast-verify is used then only the
2533 * regions which are included using -i will be read.
2534 */
2535 if (diff_file) {
2536 msg_cdbg("Reading old contents from file... ");
2537 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002538 ret = 1;
2539 msg_cdbg("FAILED.\n");
2540 goto out;
2541 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002542 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002543 msg_cdbg("Reading old contents from flash chip... ");
Edward O'Callaghan84c89182020-12-09 12:33:37 +11002544 ret = flashrom_image_read(flash, verify_it, oldcontents, size);
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002545 if (ret) {
2546 msg_cdbg("FAILED.\n");
2547 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002548 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002549 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002550 msg_cdbg("done.\n");
2551 } else if (!erase_it) {
2552 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002553 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002554 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002555
David Hendricksdf29a832013-06-28 14:33:51 -07002556 /*
2557 * Note: This must be done after reading the file specified for the
2558 * -w/-v argument, if any, so that files specified using -i end up
2559 * in the "newcontents" buffer before being written.
2560 * See http://crbug.com/263495.
2561 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002562 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002563 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002564 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002565 goto out;
2566 }
uwef6641642007-05-09 10:17:44 +00002567
David Hendricksa7e114b2016-02-26 18:49:15 -08002568 if (erase_it) {
Edward O'Callaghanf1436012020-12-07 17:58:23 +11002569 flashrom_flash_erase(flash, oldcontents, newcontents, size);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002570 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002571 }
2572
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002573 descriptor = prepare_action_descriptor(flash, oldcontents,
Edward O'Callaghane8118582020-12-03 12:45:59 +11002574 newcontents, flash->flags.do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002575 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002576 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002577 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002578 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002579 goto out;
2580 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002581
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002582 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002583 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2584 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002585 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002586 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002587 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002588 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002589 ret = 1;
2590 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002591 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002592 msg_cerr("Apparently at least some data has changed.\n");
2593 } else
2594 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002595 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002596 ret = 1;
2597 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002598 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002599
David Hendricksac1d25c2016-08-09 17:00:58 -07002600 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002601 if (ret < 0) {
2602 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002603 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002604 emergency_help_message();
2605 ret = 1;
2606 goto out;
2607 } else if (ret > 0) {
2608 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002609 msg_pdbg("CROS_EC needs 2nd pass.\n");
Edward O'Callaghan84c89182020-12-09 12:33:37 +11002610 ret = flashrom_image_read(flash, verify_it, oldcontents, size);
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002611 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002612 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002613 goto out;
2614 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002615
2616 /* Get a new descriptor. */
2617 free(descriptor);
2618 descriptor = prepare_action_descriptor(flash,
2619 oldcontents,
2620 newcontents,
Edward O'Callaghane8118582020-12-03 12:45:59 +11002621 flash->flags.do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002622 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002623 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002624 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002625 emergency_help_message();
2626 ret = 1;
2627 goto out;
2628 }
2629 ret = 0;
2630 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002631
David Hendricksac1d25c2016-08-09 17:00:58 -07002632 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002633 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002634 emergency_help_message();
2635 ret = 1;
2636 goto out;
2637 }
stuge8ce3a3c2008-04-28 14:47:30 +00002638 }
ollie6a600992005-11-26 21:55:36 +00002639
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002640 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002641 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002642 if ((write_it || erase_it) && !content_has_changed) {
2643 msg_gdbg("Nothing was erased or written, skipping "
2644 "verification\n");
2645 } else {
2646 /* Work around chips which need some time to calm down. */
2647 if (write_it && verify_it != VERIFY_PARTIAL)
2648 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002649
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002650 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002651
David Hendricks9ba79fb2015-04-03 12:06:16 -07002652 /* If we tried to write, and verification now fails, we
2653 * might have an emergency situation.
2654 */
2655 if (ret && write_it)
2656 emergency_help_message();
2657 }
hailfinger0459e1c2009-08-19 13:55:34 +00002658 }
ollie6a600992005-11-26 21:55:36 +00002659
hailfinger90fcf9b2010-11-05 14:51:59 +00002660out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002661 if (descriptor)
2662 free(descriptor);
2663
hailfinger90fcf9b2010-11-05 14:51:59 +00002664 free(oldcontents);
2665 free(newcontents);
David Hendricks668f29d2011-01-27 18:51:45 -08002666 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002667 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002668 * tree. This is because some operations, such as write protection,
2669 * requires programmer_shutdown() but does not call doit().
2670 */
2671// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002672 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002673}
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002674
2675/** @} */ /* end flashrom-ops */
2676
2677int do_read(struct flashctx *const flash, const char *const filename)
2678{
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002679 if (prepare_flash_access(flash, true, false, false, false))
2680 return 1;
2681
Edward O'Callaghan471958e2020-12-09 12:40:12 +11002682 const int ret = read_flash_to_file(flash, filename);
2683
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002684 finalize_flash_access(flash);
2685
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002686 return ret;
2687}
2688
2689int do_erase(struct flashctx *const flash, const char *diff_file)
2690{
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002691 if (prepare_flash_access(flash, false, false, true, false))
2692 return 1;
2693
Edward O'Callaghan486aaf02020-12-03 13:36:42 +11002694 int ret = doit(flash, NULL, false, false, true, false, diff_file);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002695
2696 /*
2697 * FIXME: Do we really want the scary warning if erase failed?
2698 * After all, after erase the chip is either blank or partially
2699 * blank or it has the old contents. A blank chip won't boot,
2700 * so if the user wanted erase and reboots afterwards, the user
2701 * knows very well that booting won't work.
2702 */
2703 if (ret)
2704 emergency_help_message();
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002705 finalize_flash_access(flash);
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002706
2707 return ret;
2708}
2709
2710int do_write(struct flashctx *const flash, const char *const filename, const char *const referencefile, const char *diff_file)
2711{
Sam McNally99c62982020-12-08 12:34:27 +11002712 if (prepare_flash_access(flash, false, true, false, flash->flags.verify_after_write))
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002713 return 1;
2714
Sam McNally99c62982020-12-08 12:34:27 +11002715 int ret = doit(flash, filename, false, true, false,
2716 flash->flags.verify_after_write
2717 ? flash->flags.verify_whole_chip ? VERIFY_FULL : VERIFY_PARTIAL
2718 : 0,
2719 diff_file);
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002720 finalize_flash_access(flash);
2721
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002722 return ret;
2723}
2724
2725int do_verify(struct flashctx *const flash, const char *const filename, const char *diff_file)
2726{
Edward O'Callaghan8e3e18f2020-12-03 13:12:06 +11002727 if (prepare_flash_access(flash, false, false, false, true))
2728 return 1;
2729
Sam McNally99c62982020-12-08 12:34:27 +11002730 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 +11002731 finalize_flash_access(flash);
2732
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002733 return ret;
2734}
2735
2736int do_extract_it(struct flashctx *const flash)
2737{
2738 if (prepare_flash_access(flash, false, false, false, false))
2739 return 1;
Edward O'Callaghan919ddbd2020-12-03 13:17:30 +11002740 int ret = extract_regions(flash);
2741 finalize_flash_access(flash);
2742
2743 return ret;
Edward O'Callaghan020dfa12020-09-23 23:12:55 +10002744}