blob: 3ca973d613ed2bead95fe425fdf353a713c36285 [file] [log] [blame]
rminnich8d3ff912003-10-25 17:01:29 +00001/*
uweb25f1ea2007-08-29 17:52:32 +00002 * This file is part of the flashrom project.
rminnich8d3ff912003-10-25 17:01:29 +00003 *
uwe555dd972007-09-09 20:21:05 +00004 * Copyright (C) 2000 Silicon Integrated System Corporation
5 * Copyright (C) 2004 Tyan Corp <yhlu@tyan.com>
uwe4475e902009-05-19 14:14:21 +00006 * Copyright (C) 2005-2008 coresystems GmbH
hailfinger23060112009-05-08 12:49:03 +00007 * Copyright (C) 2008,2009 Carl-Daniel Hailfinger
Edward O'Callaghan0949b782019-11-10 23:23:20 +11008 * Copyright (C) 2016 secunet Security Networks AG
9 * (Written by Nico Huber <nico.huber@secunet.com> for secunet)
rminnich8d3ff912003-10-25 17:01:29 +000010 *
uweb25f1ea2007-08-29 17:52:32 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
rminnich8d3ff912003-10-25 17:01:29 +000015 *
uweb25f1ea2007-08-29 17:52:32 +000016 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
rminnich8d3ff912003-10-25 17:01:29 +000020 */
21
hailfingera83a5fe2010-05-30 22:24:40 +000022#include <stdio.h>
stepan1da96c02006-11-21 23:48:51 +000023#include <sys/types.h>
oxygene50275892010-09-30 17:03:32 +000024#ifndef __LIBPAYLOAD__
25#include <fcntl.h>
stepan1da96c02006-11-21 23:48:51 +000026#include <sys/stat.h>
oxygene50275892010-09-30 17:03:32 +000027#endif
rminnich8d3ff912003-10-25 17:01:29 +000028#include <string.h>
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +100029#include <unistd.h>
rminnich8d3ff912003-10-25 17:01:29 +000030#include <stdlib.h>
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +100031#include <errno.h>
hailfingerf76cc322010-11-09 22:00:31 +000032#include <ctype.h>
ollie6a600992005-11-26 21:55:36 +000033#include <getopt.h>
hailfinger3b471632010-03-27 16:36:40 +000034#if HAVE_UTSNAME == 1
35#include <sys/utsname.h>
36#endif
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -070037
38#include "action_descriptor.h"
rminnich8d3ff912003-10-25 17:01:29 +000039#include "flash.h"
hailfinger66966da2009-06-15 14:14:48 +000040#include "flashchips.h"
Simon Glass9ad06c12013-07-03 22:08:17 +090041#include "layout.h"
hailfinger428f6852010-07-27 22:41:39 +000042#include "programmer.h"
Duncan Laurie25a4ca22019-04-25 12:08:52 -070043#include "spi.h"
Edward O'Callaghan99974452020-10-13 13:28:33 +110044#include "chipdrivers.h"
rminnich8d3ff912003-10-25 17:01:29 +000045
krause2eb76212011-01-17 07:50:42 +000046const char flashrom_version[] = FLASHROM_VERSION;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100047const char *chip_to_probe = NULL;
hailfinger80422e22009-12-13 22:28:00 +000048
David Hendricks9ba79fb2015-04-03 12:06:16 -070049/* Set if any erase/write operation is to be done. This will be used to
50 * decide if final verification is needed. */
51static int content_has_changed = 0;
52
David Hendricks1ed1d352011-11-23 17:54:37 -080053/* error handling stuff */
54enum error_action access_denied_action = error_ignore;
55
56int ignore_error(int err) {
57 int rc = 0;
58
59 switch(err) {
60 case ACCESS_DENIED:
61 if (access_denied_action == error_ignore)
62 rc = 1;
63 break;
64 default:
65 break;
66 }
67
68 return rc;
69}
70
hailfinger969e2f32011-09-08 00:00:29 +000071static enum programmer programmer = PROGRAMMER_INVALID;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100072static const char *programmer_param = NULL;
stepan782fb172007-04-06 11:58:03 +000073
David Hendricksac1d25c2016-08-09 17:00:58 -070074/* Supported buses for the current programmer. */
75enum chipbustype buses_supported;
76
uwee15beb92010-08-08 17:01:18 +000077/*
hailfinger80422e22009-12-13 22:28:00 +000078 * Programmers supporting multiple buses can have differing size limits on
79 * each bus. Store the limits for each bus in a common struct.
80 */
hailfinger1ff33dc2010-07-03 11:02:10 +000081struct decode_sizes max_rom_decode;
82
83/* If nonzero, used as the start address of bottom-aligned flash. */
84unsigned long flashbase;
hailfinger80422e22009-12-13 22:28:00 +000085
hailfinger5828baf2010-07-03 12:14:25 +000086/* Is writing allowed with this programmer? */
87int programmer_may_write;
88
hailfingerabe249e2009-05-08 17:43:22 +000089const struct programmer_entry programmer_table[] = {
hailfinger90c7d542010-05-31 15:27:27 +000090#if CONFIG_INTERNAL == 1
hailfingerabe249e2009-05-08 17:43:22 +000091 {
hailfinger3548a9a2009-08-12 14:34:35 +000092 .name = "internal",
Edward O'Callaghan0949b782019-11-10 23:23:20 +110093 .type = OTHER,
94 .devs.note = NULL,
hailfinger6c69ab02009-05-11 15:46:43 +000095 .init = internal_init,
hailfinger11ae3c42009-05-11 14:13:25 +000096 .map_flash_region = physmap,
97 .unmap_flash_region = physunmap,
hailfingere5829f62009-06-05 17:48:08 +000098 .delay = internal_delay,
David Hendricks55cdd9c2015-11-25 14:37:26 -080099
100 /*
101 * "Internal" implies in-system programming on a live system, so
102 * handle with paranoia to catch errors early. If something goes
103 * wrong then hopefully the system will still be recoverable.
104 */
105 .paranoid = 1,
hailfingerabe249e2009-05-08 17:43:22 +0000106 },
hailfinger80422e22009-12-13 22:28:00 +0000107#endif
stepan927d4e22007-04-04 22:45:58 +0000108
hailfinger90c7d542010-05-31 15:27:27 +0000109#if CONFIG_DUMMY == 1
hailfingera9df33c2009-05-09 00:54:55 +0000110 {
hailfinger3548a9a2009-08-12 14:34:35 +0000111 .name = "dummy",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100112 .type = OTHER,
113 /* FIXME */
114 .devs.note = "Dummy device, does nothing and logs all accesses\n",
hailfinger6c69ab02009-05-11 15:46:43 +0000115 .init = dummy_init,
hailfinger11ae3c42009-05-11 14:13:25 +0000116 .map_flash_region = dummy_map,
117 .unmap_flash_region = dummy_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000118 .delay = internal_delay,
hailfingera9df33c2009-05-09 00:54:55 +0000119 },
hailfinger571a6b32009-09-16 10:09:21 +0000120#endif
hailfingera9df33c2009-05-09 00:54:55 +0000121
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000122#if CONFIG_MEC1308 == 1
123 {
124 .name = "mec1308",
125 .type = OTHER,
126 .devs.note = "Microchip MEC1308 Embedded Controller.\n",
127 .init = mec1308_init,
128 .map_flash_region = fallback_map,
129 .unmap_flash_region = fallback_unmap,
130 .delay = internal_delay,
131 },
132#endif
133
hailfinger90c7d542010-05-31 15:27:27 +0000134#if CONFIG_NIC3COM == 1
uwe0f5a3a22009-05-13 11:36:06 +0000135 {
hailfinger3548a9a2009-08-12 14:34:35 +0000136 .name = "nic3com",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100137 .type = PCI,
138 .devs.dev = nics_3com,
uwe0f5a3a22009-05-13 11:36:06 +0000139 .init = nic3com_init,
uwe3e656bd2009-05-17 23:12:17 +0000140 .map_flash_region = fallback_map,
141 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000142 .delay = internal_delay,
uwe0f5a3a22009-05-13 11:36:06 +0000143 },
hailfinger571a6b32009-09-16 10:09:21 +0000144#endif
uwe0f5a3a22009-05-13 11:36:06 +0000145
hailfinger90c7d542010-05-31 15:27:27 +0000146#if CONFIG_NICREALTEK == 1
hailfinger5aa36982010-05-21 21:54:07 +0000147 {
hailfinger0d703d42011-03-07 01:08:09 +0000148 /* This programmer works for Realtek RTL8139 and SMC 1211. */
uwe8d342eb2011-07-28 08:13:25 +0000149 .name = "nicrealtek",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100150 .type = PCI,
151 .devs.dev = nics_realtek,
uwe8d342eb2011-07-28 08:13:25 +0000152 .init = nicrealtek_init,
153 .map_flash_region = fallback_map,
154 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000155 .delay = internal_delay,
hailfinger5aa36982010-05-21 21:54:07 +0000156 },
hailfinger5aa36982010-05-21 21:54:07 +0000157#endif
158
hailfingerf0a368f2010-06-07 22:37:54 +0000159#if CONFIG_NICNATSEMI == 1
160 {
uwe8d342eb2011-07-28 08:13:25 +0000161 .name = "nicnatsemi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100162 .type = PCI,
163 .devs.dev = nics_natsemi,
uwe8d342eb2011-07-28 08:13:25 +0000164 .init = nicnatsemi_init,
165 .map_flash_region = fallback_map,
166 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000167 .delay = internal_delay,
hailfingerf0a368f2010-06-07 22:37:54 +0000168 },
169#endif
hailfinger5aa36982010-05-21 21:54:07 +0000170
hailfinger90c7d542010-05-31 15:27:27 +0000171#if CONFIG_GFXNVIDIA == 1
uweff4576d2009-09-30 18:29:55 +0000172 {
173 .name = "gfxnvidia",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100174 .type = PCI,
175 .devs.dev = gfx_nvidia,
uweff4576d2009-09-30 18:29:55 +0000176 .init = gfxnvidia_init,
uweff4576d2009-09-30 18:29:55 +0000177 .map_flash_region = fallback_map,
178 .unmap_flash_region = fallback_unmap,
uweff4576d2009-09-30 18:29:55 +0000179 .delay = internal_delay,
180 },
181#endif
182
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000183#if CONFIG_RAIDEN_DEBUG_SPI == 1
184 {
185 .name = "raiden_debug_spi",
186 .type = USB,
187 .devs.dev = devs_raiden,
188 .init = raiden_debug_spi_init,
189 .map_flash_region = fallback_map,
190 .unmap_flash_region = fallback_unmap,
191 .delay = internal_delay,
192 },
193#endif
194
hailfinger90c7d542010-05-31 15:27:27 +0000195#if CONFIG_DRKAISER == 1
ruikda922a12009-05-17 19:39:27 +0000196 {
uwee2f95ef2009-09-02 23:00:46 +0000197 .name = "drkaiser",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100198 .type = PCI,
199 .devs.dev = drkaiser_pcidev,
uwee2f95ef2009-09-02 23:00:46 +0000200 .init = drkaiser_init,
uwee2f95ef2009-09-02 23:00:46 +0000201 .map_flash_region = fallback_map,
202 .unmap_flash_region = fallback_unmap,
uwee2f95ef2009-09-02 23:00:46 +0000203 .delay = internal_delay,
204 },
hailfinger571a6b32009-09-16 10:09:21 +0000205#endif
uwee2f95ef2009-09-02 23:00:46 +0000206
hailfinger90c7d542010-05-31 15:27:27 +0000207#if CONFIG_SATASII == 1
uwee2f95ef2009-09-02 23:00:46 +0000208 {
hailfinger3548a9a2009-08-12 14:34:35 +0000209 .name = "satasii",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100210 .type = PCI,
211 .devs.dev = satas_sii,
ruikda922a12009-05-17 19:39:27 +0000212 .init = satasii_init,
uwe3e656bd2009-05-17 23:12:17 +0000213 .map_flash_region = fallback_map,
214 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000215 .delay = internal_delay,
ruikda922a12009-05-17 19:39:27 +0000216 },
hailfinger571a6b32009-09-16 10:09:21 +0000217#endif
ruikda922a12009-05-17 19:39:27 +0000218
hailfinger90c7d542010-05-31 15:27:27 +0000219#if CONFIG_ATAHPT == 1
uwe7e627c82010-02-21 21:17:00 +0000220 {
221 .name = "atahpt",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100222 .type = PCI,
223 .devs.dev = ata_hpt,
uwe7e627c82010-02-21 21:17:00 +0000224 .init = atahpt_init,
uwe7e627c82010-02-21 21:17:00 +0000225 .map_flash_region = fallback_map,
226 .unmap_flash_region = fallback_unmap,
uwe7e627c82010-02-21 21:17:00 +0000227 .delay = internal_delay,
228 },
229#endif
230
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000231#if CONFIG_ATAVIA == 1
232 {
233 .name = "atavia",
234 .type = PCI,
235 .devs.dev = ata_via,
236 .init = atavia_init,
237 .map_flash_region = atavia_map,
238 .unmap_flash_region = fallback_unmap,
239 .delay = internal_delay,
240 },
241#endif
242
243#if CONFIG_ATAPROMISE == 1
244 {
245 .name = "atapromise",
246 .type = PCI,
247 .devs.dev = ata_promise,
248 .init = atapromise_init,
249 .map_flash_region = atapromise_map,
250 .unmap_flash_region = fallback_unmap,
251 .delay = internal_delay,
252 },
253#endif
254
255#if CONFIG_IT8212 == 1
256 {
257 .name = "it8212",
258 .type = PCI,
259 .devs.dev = devs_it8212,
260 .init = it8212_init,
261 .map_flash_region = fallback_map,
262 .unmap_flash_region = fallback_unmap,
263 .delay = internal_delay,
264 },
265#endif
266
hailfinger90c7d542010-05-31 15:27:27 +0000267#if CONFIG_FT2232_SPI == 1
hailfingerf31da3d2009-06-16 21:08:06 +0000268 {
hailfinger90c7d542010-05-31 15:27:27 +0000269 .name = "ft2232_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100270 .type = USB,
Nikolai Artemievc347a852020-04-29 12:17:08 +1000271 .devs.dev = devs_ft2232spi,
hailfingerf31da3d2009-06-16 21:08:06 +0000272 .init = ft2232_spi_init,
hailfinger6fe23d62009-08-12 11:39:29 +0000273 .map_flash_region = fallback_map,
274 .unmap_flash_region = fallback_unmap,
hailfingerf31da3d2009-06-16 21:08:06 +0000275 .delay = internal_delay,
276 },
hailfingerd9dcfbd2009-08-19 13:27:58 +0000277#endif
hailfinger6fe23d62009-08-12 11:39:29 +0000278
hailfinger90c7d542010-05-31 15:27:27 +0000279#if CONFIG_SERPROG == 1
hailfinger37b4fbf2009-06-23 11:33:43 +0000280 {
hailfinger3548a9a2009-08-12 14:34:35 +0000281 .name = "serprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100282 .type = OTHER,
283 /* FIXME */
284 .devs.note = "All programmer devices speaking the serprog protocol\n",
hailfinger37b4fbf2009-06-23 11:33:43 +0000285 .init = serprog_init,
Edward O'Callaghan62018182020-10-03 00:16:48 +1000286 .map_flash_region = serprog_map,
hailfinger37b4fbf2009-06-23 11:33:43 +0000287 .unmap_flash_region = fallback_unmap,
hailfinger37b4fbf2009-06-23 11:33:43 +0000288 .delay = serprog_delay,
289 },
hailfinger74d88a72009-08-12 16:17:41 +0000290#endif
hailfingerf31da3d2009-06-16 21:08:06 +0000291
hailfinger90c7d542010-05-31 15:27:27 +0000292#if CONFIG_BUSPIRATE_SPI == 1
hailfinger9c5add72009-11-24 00:20:03 +0000293 {
hailfinger90c7d542010-05-31 15:27:27 +0000294 .name = "buspirate_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100295 .type = OTHER,
296 /* FIXME */
297 .devs.note = "Dangerous Prototypes Bus Pirate\n",
hailfinger9c5add72009-11-24 00:20:03 +0000298 .init = buspirate_spi_init,
hailfinger9c5add72009-11-24 00:20:03 +0000299 .map_flash_region = fallback_map,
300 .unmap_flash_region = fallback_unmap,
hailfinger9c5add72009-11-24 00:20:03 +0000301 .delay = internal_delay,
302 },
303#endif
304
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000305#if CONFIG_DEDIPROG == 1
Anton Staafb2647882014-09-17 15:13:43 -0700306 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000307 .name = "dediprog",
Brian J. Nemecb42d6c12020-07-23 03:07:38 -0700308 .type = USB,
Edward O'Callaghanac1678b2020-07-27 15:55:45 +1000309 .devs.dev = devs_dediprog,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000310 .init = dediprog_init,
Anton Staafb2647882014-09-17 15:13:43 -0700311 .map_flash_region = fallback_map,
312 .unmap_flash_region = fallback_unmap,
313 .delay = internal_delay,
314 },
315#endif
316
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000317#if CONFIG_DEVELOPERBOX_SPI == 1
hailfingerdfb32a02010-01-19 11:15:48 +0000318 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000319 .name = "developerbox",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100320 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000321 .devs.dev = devs_developerbox_spi,
322 .init = developerbox_spi_init,
323 .map_flash_region = fallback_map,
324 .unmap_flash_region = fallback_unmap,
325 .delay = internal_delay,
326 },
327#endif
328
329#if CONFIG_ENE_LPC == 1
330 {
331 .name = "ene_lpc",
332 .type = OTHER,
333 .devs.note = "ENE LPC interface keyboard controller\n",
334 .init = ene_lpc_init,
hailfingerdfb32a02010-01-19 11:15:48 +0000335 .map_flash_region = fallback_map,
336 .unmap_flash_region = fallback_unmap,
hailfingerdfb32a02010-01-19 11:15:48 +0000337 .delay = internal_delay,
338 },
339#endif
340
hailfinger52c4fa02010-07-21 10:26:01 +0000341#if CONFIG_RAYER_SPI == 1
342 {
343 .name = "rayer_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100344 .type = OTHER,
345 /* FIXME */
346 .devs.note = "RayeR parallel port programmer\n",
hailfinger52c4fa02010-07-21 10:26:01 +0000347 .init = rayer_spi_init,
hailfinger52c4fa02010-07-21 10:26:01 +0000348 .map_flash_region = fallback_map,
349 .unmap_flash_region = fallback_unmap,
hailfinger52c4fa02010-07-21 10:26:01 +0000350 .delay = internal_delay,
351 },
352#endif
353
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000354#if CONFIG_PONY_SPI == 1
355 {
356 .name = "pony_spi",
357 .type = OTHER,
358 /* FIXME */
359 .devs.note = "Programmers compatible with SI-Prog, serbang or AJAWe\n",
360 .init = pony_spi_init,
361 .map_flash_region = fallback_map,
362 .unmap_flash_region = fallback_unmap,
363 .delay = internal_delay,
364 },
365#endif
366
hailfinger7949b652011-05-08 00:24:18 +0000367#if CONFIG_NICINTEL == 1
368 {
369 .name = "nicintel",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100370 .type = PCI,
371 .devs.dev = nics_intel,
hailfinger7949b652011-05-08 00:24:18 +0000372 .init = nicintel_init,
hailfinger7949b652011-05-08 00:24:18 +0000373 .map_flash_region = fallback_map,
374 .unmap_flash_region = fallback_unmap,
hailfinger7949b652011-05-08 00:24:18 +0000375 .delay = internal_delay,
376 },
377#endif
378
uwe6764e922010-09-03 18:21:21 +0000379#if CONFIG_NICINTEL_SPI == 1
380 {
uwe8d342eb2011-07-28 08:13:25 +0000381 .name = "nicintel_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100382 .type = PCI,
383 .devs.dev = nics_intel_spi,
uwe8d342eb2011-07-28 08:13:25 +0000384 .init = nicintel_spi_init,
385 .map_flash_region = fallback_map,
386 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000387 .delay = internal_delay,
uwe6764e922010-09-03 18:21:21 +0000388 },
389#endif
390
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000391#if CONFIG_NICINTEL_EEPROM == 1
392 {
393 .name = "nicintel_eeprom",
394 .type = PCI,
395 .devs.dev = nics_intel_ee,
396 .init = nicintel_ee_init,
397 .map_flash_region = fallback_map,
398 .unmap_flash_region = fallback_unmap,
399 .delay = internal_delay,
400 },
401#endif
402
hailfingerfb1f31f2010-12-03 14:48:11 +0000403#if CONFIG_OGP_SPI == 1
404 {
uwe8d342eb2011-07-28 08:13:25 +0000405 .name = "ogp_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100406 .type = PCI,
407 .devs.dev = ogp_spi,
uwe8d342eb2011-07-28 08:13:25 +0000408 .init = ogp_spi_init,
409 .map_flash_region = fallback_map,
410 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000411 .delay = internal_delay,
hailfingerfb1f31f2010-12-03 14:48:11 +0000412 },
413#endif
414
hailfinger935365d2011-02-04 21:37:59 +0000415#if CONFIG_SATAMV == 1
416 {
417 .name = "satamv",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100418 .type = PCI,
419 .devs.dev = satas_mv,
hailfinger935365d2011-02-04 21:37:59 +0000420 .init = satamv_init,
hailfinger935365d2011-02-04 21:37:59 +0000421 .map_flash_region = fallback_map,
422 .unmap_flash_region = fallback_unmap,
hailfinger935365d2011-02-04 21:37:59 +0000423 .delay = internal_delay,
424 },
425#endif
426
David Hendrickscebee892015-05-23 20:30:30 -0700427#if CONFIG_LINUX_MTD == 1
428 {
429 .name = "linux_mtd",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100430 .type = OTHER,
431 .devs.note = "Device files /dev/mtd*\n",
David Hendrickscebee892015-05-23 20:30:30 -0700432 .init = linux_mtd_init,
433 .map_flash_region = fallback_map,
434 .unmap_flash_region = fallback_unmap,
435 .delay = internal_delay,
436 },
437#endif
438
uwe7df6dda2011-09-03 18:37:52 +0000439#if CONFIG_LINUX_SPI == 1
440 {
441 .name = "linux_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100442 .type = OTHER,
443 .devs.note = "Device files /dev/spidev*.*\n",
uwe7df6dda2011-09-03 18:37:52 +0000444 .init = linux_spi_init,
445 .map_flash_region = fallback_map,
446 .unmap_flash_region = fallback_unmap,
uwe7df6dda2011-09-03 18:37:52 +0000447 .delay = internal_delay,
448 },
449#endif
450
Shiyu Sun9dde7162020-04-16 17:32:55 +1000451#if CONFIG_LSPCON_I2C_SPI == 1
452 {
453 .name = "lspcon_i2c_spi",
454 .type = OTHER,
455 .devs.note = "Device files /dev/i2c-*.\n",
456 .init = lspcon_i2c_spi_init,
457 .map_flash_region = fallback_map,
458 .unmap_flash_region = fallback_unmap,
459 .delay = internal_delay,
460 },
461#endif
462
Edward O'Callaghan97dd9262020-03-26 00:00:41 +1100463#if CONFIG_REALTEK_MST_I2C_SPI == 1
464 {
465 .name = "realtek_mst_i2c_spi",
466 .type = OTHER,
467 .devs.note = "Device files /dev/i2c-*.\n",
468 .init = realtek_mst_i2c_spi_init,
469 .map_flash_region = fallback_map,
470 .unmap_flash_region = fallback_unmap,
471 .delay = internal_delay,
472 },
473#endif
474
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000475#if CONFIG_USBBLASTER_SPI == 1
476 {
477 .name = "usbblaster_spi",
478 .type = USB,
479 .devs.dev = devs_usbblasterspi,
480 .init = usbblaster_spi_init,
481 .map_flash_region = fallback_map,
482 .unmap_flash_region = fallback_unmap,
483 .delay = internal_delay,
484 },
485#endif
486
487#if CONFIG_MSTARDDC_SPI == 1
488 {
489 .name = "mstarddc_spi",
490 .type = OTHER,
491 .devs.note = "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
492 .init = mstarddc_spi_init,
493 .map_flash_region = fallback_map,
494 .unmap_flash_region = fallback_unmap,
495 .delay = internal_delay,
496 },
497#endif
498
499#if CONFIG_PICKIT2_SPI == 1
500 {
501 .name = "pickit2_spi",
502 .type = USB,
503 .devs.dev = devs_pickit2_spi,
504 .init = pickit2_spi_init,
505 .map_flash_region = fallback_map,
506 .unmap_flash_region = fallback_unmap,
507 .delay = internal_delay,
508 },
509#endif
510
511#if CONFIG_CH341A_SPI == 1
512 {
513 .name = "ch341a_spi",
514 .type = USB,
515 .devs.dev = devs_ch341a_spi,
516 .init = ch341a_spi_init,
517 .map_flash_region = fallback_map,
518 .unmap_flash_region = fallback_unmap,
519 .delay = ch341a_spi_delay,
520 },
521#endif
522
523#if CONFIG_DIGILENT_SPI == 1
524 {
525 .name = "digilent_spi",
526 .type = USB,
527 .devs.dev = devs_digilent_spi,
528 .init = digilent_spi_init,
529 .map_flash_region = fallback_map,
530 .unmap_flash_region = fallback_unmap,
531 .delay = internal_delay,
532 },
533#endif
534
535#if CONFIG_JLINK_SPI == 1
536 {
537 .name = "jlink_spi",
538 .type = OTHER,
539 .init = jlink_spi_init,
540 .devs.note = "SEGGER J-Link and compatible devices\n",
541 .map_flash_region = fallback_map,
542 .unmap_flash_region = fallback_unmap,
543 .delay = internal_delay,
544 },
545#endif
546
547#if CONFIG_NI845X_SPI == 1
548 {
549 .name = "ni845x_spi",
550 .type = OTHER, // choose other because NI-845x uses own USB implementation
551 .devs.note = "National Instruments USB-845x\n",
552 .init = ni845x_spi_init,
553 .map_flash_region = fallback_map,
554 .unmap_flash_region = fallback_unmap,
555 .delay = internal_delay,
556 },
557#endif
558
559#if CONFIG_STLINKV3_SPI == 1
560 {
561 .name = "stlinkv3_spi",
562 .type = USB,
563 .devs.dev = devs_stlinkv3_spi,
564 .init = stlinkv3_spi_init,
565 .map_flash_region = fallback_map,
566 .unmap_flash_region = fallback_unmap,
567 .delay = internal_delay,
568 },
569#endif
570
Edward O'Callaghand8f72232020-09-30 14:21:42 +1000571#if CONFIG_GOOGLE_EC == 1
572 {
573 .name = "google_ec",
574 .type = OTHER,
575 .devs.note = "Google EC.\n",
576 .init = cros_ec_probe_dev,
577 .map_flash_region = fallback_map,
578 .unmap_flash_region = fallback_unmap,
579 .delay = internal_delay,
580 },
581#endif
582
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100583 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000584};
stepan927d4e22007-04-04 22:45:58 +0000585
David Hendricksbf36f092010-11-02 23:39:29 -0700586#define CHIP_RESTORE_MAXFN 4
587static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000588static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700589 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700590 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700591 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000592} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700593
David Hendricks668f29d2011-01-27 18:51:45 -0800594
hailfingerf31cbdc2010-11-10 15:25:18 +0000595#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000596static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000597/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000598static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700599 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000600 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000601} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000602/* Initialize to 0 to make sure nobody registers a shutdown function before
603 * programmer init.
604 */
605static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000606
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700607static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000608
hailfingerdc6f7972010-02-14 01:20:28 +0000609/* Register a function to be executed on programmer shutdown.
610 * The advantage over atexit() is that you can supply a void pointer which will
611 * be used as parameter to the registered function upon programmer shutdown.
612 * This pointer can point to arbitrary data used by said function, e.g. undo
613 * information for GPIO settings etc. If unneeded, set data=NULL.
614 * Please note that the first (void *data) belongs to the function signature of
615 * the function passed as first parameter.
616 */
David Hendricks93784b42016-08-09 17:00:38 -0700617int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000618{
619 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000620 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000621 SHUTDOWN_MAXFN);
622 return 1;
623 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000624 if (!may_register_shutdown) {
625 msg_perr("Tried to register a shutdown function before "
626 "programmer init.\n");
627 return 1;
628 }
hailfingerdc6f7972010-02-14 01:20:28 +0000629 shutdown_fn[shutdown_fn_count].func = function;
630 shutdown_fn[shutdown_fn_count].data = data;
631 shutdown_fn_count++;
632
633 return 0;
634}
635
David Hendricksbf36f092010-11-02 23:39:29 -0700636//int register_chip_restore(int (*function) (void *data), void *data)
637int register_chip_restore(CHIP_RESTORE_CALLBACK,
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700638 struct flashctx *flash, uint8_t status)
David Hendricksbf36f092010-11-02 23:39:29 -0700639{
640 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
641 msg_perr("Tried to register more than %i chip restore"
642 " functions.\n", CHIP_RESTORE_MAXFN);
643 return 1;
644 }
645 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
646 chip_restore_fn[chip_restore_fn_count].flash = flash;
647 chip_restore_fn[chip_restore_fn_count].status = status;
648 chip_restore_fn_count++;
649
650 return 0;
651}
652
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000653int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000654{
hailfinger1ef766d2010-07-06 09:55:48 +0000655 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000656
657 if (prog >= PROGRAMMER_INVALID) {
658 msg_perr("Invalid programmer specified!\n");
659 return -1;
660 }
661 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000662 /* Initialize all programmer specific data. */
663 /* Default to unlimited decode sizes. */
664 max_rom_decode = (const struct decode_sizes) {
665 .parallel = 0xffffffff,
666 .lpc = 0xffffffff,
667 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000668 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000669 };
David Hendricksac1d25c2016-08-09 17:00:58 -0700670 buses_supported = BUS_NONE;
hailfinger1ff33dc2010-07-03 11:02:10 +0000671 /* Default to top aligned flash at 4 GB. */
672 flashbase = 0;
673 /* Registering shutdown functions is now allowed. */
674 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000675 /* Default to allowing writes. Broken programmers set this to 0. */
676 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000677
678 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000679 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700680 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000681 if (programmer_param && strlen(programmer_param)) {
682 if (ret != 0) {
683 /* It is quite possible that any unhandled programmer parameter would have been valid,
684 * but an error in actual programmer init happened before the parameter was evaluated.
685 */
686 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
687 programmer_param);
688 } else {
689 /* Actual programmer init was successful, but the user specified an invalid or unusable
690 * (for the current programmer configuration) parameter.
691 */
692 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
693 msg_perr("Aborting.\n");
694 ret = ERROR_FATAL;
695 }
696 }
hailfinger1ef766d2010-07-06 09:55:48 +0000697 return ret;
uweabe92a52009-05-16 22:36:00 +0000698}
699
David Hendricksbf36f092010-11-02 23:39:29 -0700700int chip_restore()
701{
702 int rc = 0;
703
704 while (chip_restore_fn_count > 0) {
705 int i = --chip_restore_fn_count;
706 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
707 chip_restore_fn[i].status);
708 }
709
710 return rc;
711}
712
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000713/** Calls registered shutdown functions and resets internal programmer-related variables.
714 * Calling it is safe even without previous initialization, but further interactions with programmer support
715 * require a call to programmer_init() (afterwards).
716 *
717 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700718int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000719{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000720 int ret = 0;
721
hailfinger1ff33dc2010-07-03 11:02:10 +0000722 /* Registering shutdown functions is no longer allowed. */
723 may_register_shutdown = 0;
724 while (shutdown_fn_count > 0) {
725 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700726 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000727 }
Edward O'Callaghancf9c40f2020-10-19 20:02:39 +1100728
729 programmer_param = NULL;
730 registered_master_count = 0;
731
dhendrix0ffc2eb2011-06-14 01:35:36 +0000732 return ret;
uweabe92a52009-05-16 22:36:00 +0000733}
734
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000735void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000736{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000737 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
738 return ret;
uweabe92a52009-05-16 22:36:00 +0000739}
740
741void programmer_unmap_flash_region(void *virt_addr, size_t len)
742{
743 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000744 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000745}
746
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700747void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000748{
Craig Hesling65eb8812019-08-01 09:33:56 -0700749 par_master->chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000750}
751
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700752void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000753{
Craig Hesling65eb8812019-08-01 09:33:56 -0700754 par_master->chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000755}
756
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700757void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000758{
Craig Hesling65eb8812019-08-01 09:33:56 -0700759 par_master->chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000760}
761
Stuart langleyc98e43f2020-03-26 20:27:36 +1100762void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000763{
Craig Hesling65eb8812019-08-01 09:33:56 -0700764 par_master->chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000765}
766
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700767uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000768{
Craig Hesling65eb8812019-08-01 09:33:56 -0700769 return par_master->chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000770}
771
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700772uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000773{
Craig Hesling65eb8812019-08-01 09:33:56 -0700774 return par_master->chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000775}
776
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700777uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000778{
Craig Hesling65eb8812019-08-01 09:33:56 -0700779 return par_master->chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000780}
781
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000782void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
783 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000784{
Craig Hesling65eb8812019-08-01 09:33:56 -0700785 par_master->chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000786}
787
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000788void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000789{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000790 if (usecs > 0)
791 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000792}
793
Edward O'Callaghana820b212020-09-17 22:53:26 +1000794int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
795 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000796{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700797 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000798
hailfinger23060112009-05-08 12:49:03 +0000799 return 0;
800}
801
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000802/* This is a somewhat hacked function similar in some ways to strtok().
803 * It will look for needle with a subsequent '=' in haystack, return a copy of
804 * needle and remove everything from the first occurrence of needle to the next
805 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000806 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000807char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000808{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000809 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000810 char *opt = NULL;
811 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000812 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000813
hailfingerf4aaccc2010-04-28 15:22:14 +0000814 needlelen = strlen(needle);
815 if (!needlelen) {
816 msg_gerr("%s: empty needle! Please report a bug at "
817 "flashrom@flashrom.org\n", __func__);
818 return NULL;
819 }
820 /* No programmer parameters given. */
821 if (*haystack == NULL)
822 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000823 param_pos = strstr(*haystack, needle);
824 do {
825 if (!param_pos)
826 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000827 /* Needle followed by '='? */
828 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000829 /* Beginning of the string? */
830 if (param_pos == *haystack)
831 break;
832 /* After a delimiter? */
833 if (strchr(delim, *(param_pos - 1)))
834 break;
835 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000836 /* Continue searching. */
837 param_pos++;
838 param_pos = strstr(param_pos, needle);
839 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000840
hailfinger6e5a52a2009-11-24 18:27:10 +0000841 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000842 /* Get the string after needle and '='. */
843 opt_pos = param_pos + needlelen + 1;
844 optlen = strcspn(opt_pos, delim);
845 /* Return an empty string if the parameter was empty. */
846 opt = malloc(optlen + 1);
847 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000848 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000849 exit(1);
850 }
hailfinger1ef766d2010-07-06 09:55:48 +0000851 strncpy(opt, opt_pos, optlen);
852 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000853 rest = opt_pos + optlen;
854 /* Skip all delimiters after the current parameter. */
855 rest += strspn(rest, delim);
856 memmove(param_pos, rest, strlen(rest) + 1);
857 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000858 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000859
hailfinger1ef766d2010-07-06 09:55:48 +0000860 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000861}
862
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000863char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000864{
865 return extract_param(&programmer_param, param_name, ",");
866}
867
stefancte1c5acf2011-07-04 07:27:17 +0000868/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700869static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000870{
871 unsigned int usable_erasefunctions = 0;
872 int k;
873 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
874 if (!check_block_eraser(flash, k, 0))
875 usable_erasefunctions++;
876 }
877 return usable_erasefunctions;
878}
879
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000880static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700881{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000882 int ret = 0, failcount = 0;
883 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700884 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000885 if (wantbuf[i] != havebuf[i]) {
886 /* Only print the first failure. */
887 if (!failcount++)
888 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
889 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700890 }
891 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000892 if (failcount) {
893 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
894 start, start + len - 1, failcount);
895 ret = -1;
896 }
897 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700898}
899
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000900/* start is an offset to the base address of the flash chip */
901static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
902{
903 int ret;
904 uint8_t *cmpbuf = malloc(len);
905 const uint8_t erased_value = ERASED_VALUE(flash);
906
907 if (!cmpbuf) {
908 msg_gerr("Could not allocate memory!\n");
909 exit(1);
910 }
911 memset(cmpbuf, erased_value, len);
912 ret = verify_range(flash, cmpbuf, start, len);
913 free(cmpbuf);
914 return ret;
915}
916
uwee15beb92010-08-08 17:01:18 +0000917/*
hailfinger7af3d192009-11-25 17:05:52 +0000918 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000919 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000920 * @start offset to the base address of the flash chip
921 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000922 * @return 0 for success, -1 for failure
923 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000924int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000925{
hailfinger7af83692009-06-15 17:23:36 +0000926 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000927 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000928
Patrick Georgif3fa2992017-02-02 16:24:44 +0100929 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000930 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000931 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000932 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000933
934 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000935 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000936 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000937 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000938 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000939 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000940
Patrick Georgif3fa2992017-02-02 16:24:44 +0100941 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000942 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000943 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100944 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000945 ret = -1;
946 goto out_free;
947 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700948 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700949 if (programmer_table[programmer].paranoid) {
950 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800951
Simon Glass4e305f42015-01-08 06:29:04 -0700952 /* limit chunksize in order to catch errors early */
953 for (i = 0, chunksize = 0; i < len; i += chunksize) {
954 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800955
Patrick Georgif3fa2992017-02-02 16:24:44 +0100956 chunksize = min(flash->chip->page_size, len - i);
957 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700958 if (tmp) {
959 ret = tmp;
960 if (ignore_error(tmp))
961 continue;
962 else
963 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800964 }
Simon Glass4e305f42015-01-08 06:29:04 -0700965
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700966 /*
967 * Check write access permission and do not compare chunks
968 * where flashrom does not have write access to the region.
969 */
970 if (flash->chip->check_access) {
971 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
972 if (tmp && ignore_error(tmp))
973 continue;
974 }
975
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000976 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700977 if (failcount)
978 break;
David Hendricks1ed1d352011-11-23 17:54:37 -0800979 }
Simon Glass4e305f42015-01-08 06:29:04 -0700980 } else {
981 int tmp;
982
983 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +0100984 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -0700985 if (tmp && !ignore_error(tmp)) {
986 ret = tmp;
987 goto out_free;
988 }
989
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000990 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +0000991 }
992
hailfinger5be6c0f2009-07-23 01:42:56 +0000993 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +0000994 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +0000995 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +0000996 ret = -1;
997 }
hailfinger7af83692009-06-15 17:23:36 +0000998
999out_free:
1000 free(readbuf);
1001 return ret;
1002}
1003
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001004/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1005static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001006 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001007{
1008 unsigned int i, j, limit;
1009 for (j = 0; j < len / gran; j++) {
1010 limit = min (gran, len - j * gran);
1011 /* Are 'have' and 'want' identical? */
1012 if (!memcmp(have + j * gran, want + j * gran, limit))
1013 continue;
1014 /* have needs to be in erased state. */
1015 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001016 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001017 return 1;
1018 }
1019 return 0;
1020}
1021
uwee15beb92010-08-08 17:01:18 +00001022/*
hailfingerb247c7a2010-03-08 00:42:32 +00001023 * Check if the buffer @have can be programmed to the content of @want without
1024 * erasing. This is only possible if all chunks of size @gran are either kept
1025 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001026 *
hailfingerb437e282010-11-04 01:04:27 +00001027 * Warning: This function assumes that @have and @want point to naturally
1028 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001029 *
1030 * @have buffer with current content
1031 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001032 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001033 * @gran write granularity (enum, not count)
1034 * @return 0 if no erase is needed, 1 otherwise
1035 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001036int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1037 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001038{
hailfingerb91c08c2011-08-15 19:54:20 +00001039 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001040 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001041
hailfingerb247c7a2010-03-08 00:42:32 +00001042 switch (gran) {
1043 case write_gran_1bit:
1044 for (i = 0; i < len; i++)
1045 if ((have[i] & want[i]) != want[i]) {
1046 result = 1;
1047 break;
1048 }
1049 break;
1050 case write_gran_1byte:
1051 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001052 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001053 result = 1;
1054 break;
1055 }
1056 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001057 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001058 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001059 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001060 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001061 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001062 break;
1063 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001064 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001065 break;
1066 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001067 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001068 break;
1069 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001070 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001071 break;
1072 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001073 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001074 break;
1075 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001076 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001077 break;
1078 case write_gran_1byte_implicit_erase:
1079 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1080 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001081 break;
hailfingerb437e282010-11-04 01:04:27 +00001082 default:
1083 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1084 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001085 }
1086 return result;
1087}
1088
hailfingerb437e282010-11-04 01:04:27 +00001089/**
1090 * Check if the buffer @have needs to be programmed to get the content of @want.
1091 * If yes, return 1 and fill in first_start with the start address of the
1092 * write operation and first_len with the length of the first to-be-written
1093 * chunk. If not, return 0 and leave first_start and first_len undefined.
1094 *
1095 * Warning: This function assumes that @have and @want point to naturally
1096 * aligned regions.
1097 *
1098 * @have buffer with current content
1099 * @want buffer with desired content
1100 * @len length of the checked area
1101 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001102 * @first_start offset of the first byte which needs to be written (passed in
1103 * value is increased by the offset of the first needed write
1104 * relative to have/want or unchanged if no write is needed)
1105 * @return length of the first contiguous area which needs to be written
1106 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001107 *
1108 * FIXME: This function needs a parameter which tells it about coalescing
1109 * in relation to the max write length of the programmer and the max write
1110 * length of the chip.
1111 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001112static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001113 unsigned int *first_start,
1114 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001115{
stefanctc5eb8a92011-11-23 09:13:48 +00001116 int need_write = 0;
1117 unsigned int rel_start = 0, first_len = 0;
1118 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001119
hailfingerb437e282010-11-04 01:04:27 +00001120 switch (gran) {
1121 case write_gran_1bit:
1122 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001123 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001124 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001125 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001126 case write_gran_128bytes:
1127 stride = 128;
1128 break;
hailfingerb437e282010-11-04 01:04:27 +00001129 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001130 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001131 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001132 case write_gran_264bytes:
1133 stride = 264;
1134 break;
1135 case write_gran_512bytes:
1136 stride = 512;
1137 break;
1138 case write_gran_528bytes:
1139 stride = 528;
1140 break;
1141 case write_gran_1024bytes:
1142 stride = 1024;
1143 break;
1144 case write_gran_1056bytes:
1145 stride = 1056;
1146 break;
hailfingerb437e282010-11-04 01:04:27 +00001147 default:
1148 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1149 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001150 /* Claim that no write was needed. A write with unknown
1151 * granularity is too dangerous to try.
1152 */
1153 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001154 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001155 for (i = 0; i < len / stride; i++) {
1156 limit = min(stride, len - i * stride);
1157 /* Are 'have' and 'want' identical? */
1158 if (memcmp(have + i * stride, want + i * stride, limit)) {
1159 if (!need_write) {
1160 /* First location where have and want differ. */
1161 need_write = 1;
1162 rel_start = i * stride;
1163 }
1164 } else {
1165 if (need_write) {
1166 /* First location where have and want
1167 * do not differ anymore.
1168 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001169 break;
1170 }
1171 }
1172 }
hailfingerffb7f382010-12-06 13:05:44 +00001173 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001174 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001175 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001176 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001177}
1178
hailfinger0c515352009-11-23 12:55:31 +00001179/* This function generates various test patterns useful for testing controller
1180 * and chip communication as well as chip behaviour.
1181 *
1182 * If a byte can be written multiple times, each time keeping 0-bits at 0
1183 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1184 * is essentially an AND operation. That's also the reason why this function
1185 * provides the result of AND between various patterns.
1186 *
1187 * Below is a list of patterns (and their block length).
1188 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1189 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1190 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1191 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1192 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1193 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1194 * Pattern 6 is 00 (1 Byte)
1195 * Pattern 7 is ff (1 Byte)
1196 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1197 * byte block.
1198 *
1199 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1200 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1201 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1202 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1203 * Pattern 12 is 00 (1 Byte)
1204 * Pattern 13 is ff (1 Byte)
1205 * Patterns 8-13 have no block number.
1206 *
1207 * Patterns 0-3 are created to detect and efficiently diagnose communication
1208 * slips like missed bits or bytes and their repetitive nature gives good visual
1209 * cues to the person inspecting the results. In addition, the following holds:
1210 * AND Pattern 0/1 == Pattern 4
1211 * AND Pattern 2/3 == Pattern 5
1212 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1213 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1214 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1215 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1216 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1217 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1218 * Besides that, they provide for bit testing of the last two bytes of every
1219 * 256 byte block which contains the block number for patterns 0-6.
1220 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1221 * block sizes >256 bytes (some Dataflash chips etc.)
1222 * AND Pattern 8/9 == Pattern 12
1223 * AND Pattern 10/11 == Pattern 12
1224 * Pattern 13 is the completely erased state.
1225 * None of the patterns can detect aliasing at boundaries which are a multiple
1226 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1227 */
1228int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1229{
1230 int i;
1231
1232 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001233 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001234 return 1;
1235 }
1236
1237 switch (variant) {
1238 case 0:
1239 for (i = 0; i < size; i++)
1240 buf[i] = (i & 0xf) << 4 | 0x5;
1241 break;
1242 case 1:
1243 for (i = 0; i < size; i++)
1244 buf[i] = (i & 0xf) << 4 | 0xa;
1245 break;
1246 case 2:
1247 for (i = 0; i < size; i++)
1248 buf[i] = 0x50 | (i & 0xf);
1249 break;
1250 case 3:
1251 for (i = 0; i < size; i++)
1252 buf[i] = 0xa0 | (i & 0xf);
1253 break;
1254 case 4:
1255 for (i = 0; i < size; i++)
1256 buf[i] = (i & 0xf) << 4;
1257 break;
1258 case 5:
1259 for (i = 0; i < size; i++)
1260 buf[i] = i & 0xf;
1261 break;
1262 case 6:
1263 memset(buf, 0x00, size);
1264 break;
1265 case 7:
1266 memset(buf, 0xff, size);
1267 break;
1268 case 8:
1269 for (i = 0; i < size; i++)
1270 buf[i] = i & 0xff;
1271 break;
1272 case 9:
1273 for (i = 0; i < size; i++)
1274 buf[i] = ~(i & 0xff);
1275 break;
1276 case 10:
1277 for (i = 0; i < size % 2; i++) {
1278 buf[i * 2] = (i >> 8) & 0xff;
1279 buf[i * 2 + 1] = i & 0xff;
1280 }
1281 if (size & 0x1)
1282 buf[i * 2] = (i >> 8) & 0xff;
1283 break;
1284 case 11:
1285 for (i = 0; i < size % 2; i++) {
1286 buf[i * 2] = ~((i >> 8) & 0xff);
1287 buf[i * 2 + 1] = ~(i & 0xff);
1288 }
1289 if (size & 0x1)
1290 buf[i * 2] = ~((i >> 8) & 0xff);
1291 break;
1292 case 12:
1293 memset(buf, 0x00, size);
1294 break;
1295 case 13:
1296 memset(buf, 0xff, size);
1297 break;
1298 }
1299
1300 if ((variant >= 0) && (variant <= 7)) {
1301 /* Write block number in the last two bytes of each 256-byte
1302 * block, big endian for easier reading of the hexdump.
1303 * Note that this wraps around for chips larger than 2^24 bytes
1304 * (16 MB).
1305 */
1306 for (i = 0; i < size / 256; i++) {
1307 buf[i * 256 + 254] = (i >> 8) & 0xff;
1308 buf[i * 256 + 255] = i & 0xff;
1309 }
1310 }
1311
1312 return 0;
1313}
1314
hailfingeraec9c962009-10-31 01:53:09 +00001315int check_max_decode(enum chipbustype buses, uint32_t size)
1316{
1317 int limitexceeded = 0;
uwe8d342eb2011-07-28 08:13:25 +00001318
1319 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001320 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001321 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001322 "size %u kB of chipset/board/programmer "
1323 "for %s interface, "
1324 "probe/read/erase/write may fail. ", size / 1024,
1325 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001326 }
hailfingere1e41ea2011-07-27 07:13:06 +00001327 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001328 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001329 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001330 "size %u kB of chipset/board/programmer "
1331 "for %s interface, "
1332 "probe/read/erase/write may fail. ", size / 1024,
1333 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001334 }
hailfingere1e41ea2011-07-27 07:13:06 +00001335 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001336 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001337 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001338 "size %u kB of chipset/board/programmer "
1339 "for %s interface, "
1340 "probe/read/erase/write may fail. ", size / 1024,
1341 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001342 }
hailfingere1e41ea2011-07-27 07:13:06 +00001343 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001344 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001345 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001346 "size %u kB of chipset/board/programmer "
1347 "for %s interface, "
1348 "probe/read/erase/write may fail. ", size / 1024,
1349 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001350 }
1351 if (!limitexceeded)
1352 return 0;
1353 /* Sometimes chip and programmer have more than one bus in common,
1354 * and the limit is not exceeded on all buses. Tell the user.
1355 */
1356 if (bitcount(buses) > limitexceeded)
hailfinger92cd8e32010-01-07 03:24:05 +00001357 /* FIXME: This message is designed towards CLI users. */
snelsone42c3802010-05-07 20:09:04 +00001358 msg_pdbg("There is at least one common chip/programmer "
uwe8d342eb2011-07-28 08:13:25 +00001359 "interface which can support a chip of this size. "
1360 "You can try --force at your own risk.\n");
hailfingeraec9c962009-10-31 01:53:09 +00001361 return 1;
1362}
1363
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001364void unmap_flash(struct flashctx *flash)
1365{
1366 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1367 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1368 flash->physical_registers = 0;
1369 flash->virtual_registers = (chipaddr)ERROR_PTR;
1370 }
1371
1372 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1373 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1374 flash->physical_memory = 0;
1375 flash->virtual_memory = (chipaddr)ERROR_PTR;
1376 }
1377}
1378
1379int map_flash(struct flashctx *flash)
1380{
1381 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1382 flash->virtual_memory = (chipaddr)ERROR_PTR;
1383 flash->virtual_registers = (chipaddr)ERROR_PTR;
1384
1385 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1386 * These are used for various probing-related hacks that would not map successfully anyway and should be
1387 * removed ASAP. */
1388 if (flash->chip->total_size == 0)
1389 return 0;
1390
1391 const chipsize_t size = flash->chip->total_size * 1024;
1392 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1393 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1394 if (addr == ERROR_PTR) {
1395 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1396 flash->chip->name, PRIxPTR_WIDTH, base);
1397 return 1;
1398 }
1399 flash->physical_memory = base;
1400 flash->virtual_memory = (chipaddr)addr;
1401
1402 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1403 * completely different on some chips and programmers, or not mappable at all.
1404 * Ignore these problems for now and always report success. */
1405 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1406 base = 0xffffffff - size - 0x400000 + 1;
1407 addr = programmer_map_flash_region("flash chip registers", base, size);
1408 if (addr == ERROR_PTR) {
1409 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1410 flash->chip->name, PRIxPTR_WIDTH, base);
1411 return 0;
1412 }
1413 flash->physical_registers = base;
1414 flash->virtual_registers = (chipaddr)addr;
1415 }
1416 return 0;
1417}
1418
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001419/*
1420 * Return a string corresponding to the bustype parameter.
1421 * Memory is obtained with malloc() and must be freed with free() by the caller.
1422 */
1423char *flashbuses_to_text(enum chipbustype bustype)
1424{
1425 char *ret = calloc(1, 1);
1426 /*
1427 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1428 * will cease to exist and should be eliminated here as well.
1429 */
1430 if (bustype == BUS_NONSPI) {
1431 ret = strcat_realloc(ret, "Non-SPI, ");
1432 } else {
1433 if (bustype & BUS_PARALLEL)
1434 ret = strcat_realloc(ret, "Parallel, ");
1435 if (bustype & BUS_LPC)
1436 ret = strcat_realloc(ret, "LPC, ");
1437 if (bustype & BUS_FWH)
1438 ret = strcat_realloc(ret, "FWH, ");
1439 if (bustype & BUS_SPI)
1440 ret = strcat_realloc(ret, "SPI, ");
1441 if (bustype & BUS_PROG)
1442 ret = strcat_realloc(ret, "Programmer-specific, ");
1443 if (bustype == BUS_NONE)
1444 ret = strcat_realloc(ret, "None, ");
1445 }
1446 /* Kill last comma. */
1447 ret[strlen(ret) - 2] = '\0';
1448 ret = realloc(ret, strlen(ret) + 1);
1449 return ret;
1450}
1451
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001452int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001453{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001454 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001455 uint32_t size;
1456 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001457 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001458
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301459 /* Based on the host controller interface that a platform
1460 * needs to use (hwseq or swseq),
1461 * set the flashchips list here.
1462 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001463 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301464 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001465 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301466 flash_list = flashchips_hwseq;
1467 break;
1468 default:
1469 flash_list = flashchips;
1470 break;
1471 }
1472
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001473 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1474 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001475 continue;
Craig Hesling65eb8812019-08-01 09:33:56 -07001476 buses_common = buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001477 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001478 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001479 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001480 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001481 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001482 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001483 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001484 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001485 continue;
1486 }
stepan782fb172007-04-06 11:58:03 +00001487
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001488 size = chip->total_size * 1024;
hailfingeraec9c962009-10-31 01:53:09 +00001489 check_max_decode(buses_common, size);
stepan782fb172007-04-06 11:58:03 +00001490
hailfinger48ed3e22011-05-04 00:39:50 +00001491 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001492 flash->chip = calloc(1, sizeof(struct flashchip));
1493 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001494 msg_gerr("Out of memory!\n");
1495 exit(1);
1496 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001497 memcpy(flash->chip, chip, sizeof(struct flashchip));
1498 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001499
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001500 if (map_flash(flash) != 0)
1501 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001502
Edward O'Callaghana820b212020-09-17 22:53:26 +10001503 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1504 * is only called with force=1 after normal probing failed.
1505 */
stugec1e55fe2008-07-02 17:15:47 +00001506 if (force)
1507 break;
stepanc98b80b2006-03-16 16:57:41 +00001508
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001509 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001510 goto notfound;
1511
hailfinger48ed3e22011-05-04 00:39:50 +00001512 /* If this is the first chip found, accept it.
1513 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001514 * a non-generic match. SFDP and CFI are generic matches.
1515 * startchip==0 means this call to probe_flash() is the first
1516 * one for this programmer interface (master) and thus no other chip has
1517 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001518 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001519 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1520 msg_cinfo("===\n"
1521 "SFDP has autodetected a flash chip which is "
1522 "not natively supported by flashrom yet.\n");
1523 if (count_usable_erasers(flash) == 0)
1524 msg_cinfo("The standard operations read and "
1525 "verify should work, but to support "
1526 "erase, write and all other "
1527 "possible features");
1528 else
1529 msg_cinfo("All standard operations (read, "
1530 "verify, erase and write) should "
1531 "work, but to support all possible "
1532 "features");
1533
1534 msg_cinfo(" we need to add them manually.\n"
1535 "You can help us by mailing us the output of the following command to "
1536 "flashrom@flashrom.org:\n"
1537 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1538 "Thanks for your help!\n"
1539 "===\n");
1540 }
stugec1e55fe2008-07-02 17:15:47 +00001541
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001542 /* First flash chip detected on this bus. */
1543 if (startchip == 0)
1544 break;
1545 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001546 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001547 break;
1548 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001549notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001550 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001551 free(flash->chip);
1552 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001553 }
uwebe4477b2007-08-23 16:08:21 +00001554
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001555 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001556 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001557
stepan3e7aeae2011-01-19 06:21:54 +00001558
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001559 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001560 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1561 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001562 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001563#if CONFIG_INTERNAL == 1
1564 if (programmer_table[programmer].map_flash_region == physmap)
1565 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1566 PRIxPTR_WIDTH, flash->physical_memory);
1567 else
1568#endif
1569 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001570
Edward O'Callaghana820b212020-09-17 22:53:26 +10001571 /* Flash registers may more likely not be mapped if the chip was forced.
1572 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001573 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001574 if (flash->chip->printlock)
1575 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001576
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001577 /* Get out of the way for later runs. */
1578 unmap_flash(flash);
1579
hailfinger48ed3e22011-05-04 00:39:50 +00001580 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001581 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001582}
1583
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001584static int verify_flash(struct flashctx *flash,
1585 struct action_descriptor *descriptor,
1586 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001587{
hailfingerb0f4d122009-06-24 08:20:45 +00001588 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001589 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001590 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001591
snelsone42c3802010-05-07 20:09:04 +00001592 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001593
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001594 if (verify_it == VERIFY_PARTIAL) {
1595 struct processing_unit *pu = descriptor->processing_units;
1596
1597 /* Verify only areas which were written. */
1598 while (pu->num_blocks) {
1599 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001600 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001601 if (ret)
1602 break;
1603 pu++;
1604 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001605 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001606 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001607 }
uwef6641642007-05-09 10:17:44 +00001608
David Hendricks1ed1d352011-11-23 17:54:37 -08001609 if (ret == ACCESS_DENIED) {
1610 msg_gdbg("Could not fully verify due to access error, ");
1611 if (access_denied_action == error_ignore) {
1612 msg_gdbg("ignoring\n");
1613 ret = 0;
1614 } else {
1615 msg_gdbg("aborting\n");
1616 }
1617 }
1618
hailfingerb0f4d122009-06-24 08:20:45 +00001619 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001620 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001621
hailfingerb0f4d122009-06-24 08:20:45 +00001622 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001623}
1624
uwe8d342eb2011-07-28 08:13:25 +00001625int read_buf_from_file(unsigned char *buf, unsigned long size,
1626 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001627{
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001628#ifdef __LIBPAYLOAD__
1629 msg_gerr("Error: No file I/O support in libpayload\n");
1630 return 1;
1631#else
1632 int ret = 0;
hailfinger771fc182010-10-15 00:01:14 +00001633
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001634 FILE *image;
1635 if ((image = fopen(filename, "rb")) == NULL) {
1636 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger771fc182010-10-15 00:01:14 +00001637 return 1;
1638 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001639
1640 struct stat image_stat;
hailfinger771fc182010-10-15 00:01:14 +00001641 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001642 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1643 ret = 1;
1644 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001645 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001646 if (image_stat.st_size != (intmax_t)size) {
1647 msg_gerr("Error: Image size (%jd B) doesn't match the flash chip's size (%lu B)!\n",
1648 (intmax_t)image_stat.st_size, size);
1649 ret = 1;
1650 goto out;
hailfinger771fc182010-10-15 00:01:14 +00001651 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001652
1653 unsigned long numbytes = fread(buf, 1, size, image);
hailfinger771fc182010-10-15 00:01:14 +00001654 if (numbytes != size) {
1655 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1656 "wanted %ld!\n", numbytes, size);
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001657 ret = 1;
hailfinger771fc182010-10-15 00:01:14 +00001658 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001659out:
1660 (void)fclose(image);
1661 return ret;
1662#endif
hailfinger771fc182010-10-15 00:01:14 +00001663}
1664
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001665int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001666{
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001667#ifdef __LIBPAYLOAD__
1668 msg_gerr("Error: No file I/O support in libpayload\n");
1669 return 1;
1670#else
hailfingerd219a232009-01-28 00:27:54 +00001671 FILE *image;
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001672 int ret = 0;
hailfingerde345862009-06-01 22:07:52 +00001673
1674 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001675 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001676 return 1;
1677 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001678 if ((image = fopen(filename, "wb")) == NULL) {
1679 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
hailfinger23060112009-05-08 12:49:03 +00001680 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001681 }
hailfingerd219a232009-01-28 00:27:54 +00001682
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001683 unsigned long numbytes = fwrite(buf, 1, size, image);
hailfinger42a850a2010-07-13 23:56:13 +00001684 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001685 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001686 ret = 1;
1687 goto out;
hailfinger42a850a2010-07-13 23:56:13 +00001688 }
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001689 if (fflush(image)) {
1690 msg_gerr("Error: flushing file \"%s\" failed: %s\n", filename, strerror(errno));
1691 ret = 1;
1692 }
1693 // Try to fsync() only regular files and if that function is available at all (e.g. not on MinGW).
1694#if defined(_POSIX_FSYNC) && (_POSIX_FSYNC != -1)
1695 struct stat image_stat;
1696 if (fstat(fileno(image), &image_stat) != 0) {
1697 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1698 ret = 1;
1699 goto out;
1700 }
1701 if (S_ISREG(image_stat.st_mode)) {
1702 if (fsync(fileno(image))) {
1703 msg_gerr("Error: fsyncing file \"%s\" failed: %s\n", filename, strerror(errno));
1704 ret = 1;
1705 }
1706 }
1707#endif
1708out:
1709 if (fclose(image)) {
1710 msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
1711 ret = 1;
1712 }
1713 return ret;
1714#endif
hailfingerd219a232009-01-28 00:27:54 +00001715}
1716
David Hendrickse3451942013-03-21 17:23:29 -07001717/*
1718 * read_flash - wrapper for flash->read() with additional high-level policy
1719 *
1720 * @flash flash chip
1721 * @buf buffer to store data in
1722 * @start start address
1723 * @len number of bytes to read
1724 *
1725 * This wrapper simplifies most cases when the flash chip needs to be read
1726 * since policy decisions such as non-fatal error handling is centralized.
1727 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001728int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001729 unsigned int start, unsigned int len)
1730{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001731 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001732
Patrick Georgif3fa2992017-02-02 16:24:44 +01001733 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001734 return -1;
1735
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001736 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1737
Patrick Georgif3fa2992017-02-02 16:24:44 +01001738 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001739 if (ret) {
1740 if (ignore_error(ret)) {
1741 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1742 start, start + len - 1);
1743 ret = 0;
1744 } else {
1745 msg_gdbg("failed to read 0x%x-0x%x\n",
1746 start, start + len - 1);
1747 }
1748 }
1749
1750 return ret;
1751}
1752
David Hendricks7c8a1612013-04-26 19:14:44 -07001753/*
1754 * write_flash - wrapper for flash->write() with additional high-level policy
1755 *
1756 * @flash flash chip
1757 * @buf buffer to write to flash
1758 * @start start address in flash
1759 * @len number of bytes to write
1760 *
1761 * TODO: Look up regions that are write-protected and avoid attempt to write
1762 * to them at all.
1763 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001764int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001765 unsigned int start, unsigned int len)
1766{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001767 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001768 return -1;
1769
Patrick Georgif3fa2992017-02-02 16:24:44 +01001770 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001771}
1772
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001773int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001774{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001775 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001776 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001777 int ret = 0;
1778
1779 msg_cinfo("Reading flash... ");
1780 if (!buf) {
1781 msg_gerr("Memory allocation failed!\n");
1782 msg_cinfo("FAILED.\n");
1783 return 1;
1784 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001785
1786 /* To support partial read, fill buffer to all 0xFF at beginning to make
1787 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001788 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001789
Patrick Georgif3fa2992017-02-02 16:24:44 +01001790 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001791 msg_cerr("No read function available for this flash chip.\n");
1792 ret = 1;
1793 goto out_free;
1794 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001795
1796 /* First try to handle partial read case, rather than read the whole
1797 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001798 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001799 if (ret < 0) {
1800 msg_cerr("Partial read operation failed!\n");
1801 ret = 1;
1802 goto out_free;
1803 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001804 int num_regions = get_num_include_args();
1805
1806 if (ret != num_regions) {
1807 msg_cerr("Requested %d regions, but only read %d\n",
1808 num_regions, ret);
1809 ret = 1;
1810 goto out_free;
1811 }
1812
1813 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001814 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001815 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001816 msg_cerr("Read operation failed!\n");
1817 ret = 1;
1818 goto out_free;
1819 }
hailfinger42a850a2010-07-13 23:56:13 +00001820 }
1821
David Hendricksdf29a832013-06-28 14:33:51 -07001822 if (filename)
1823 ret = write_buf_to_file(buf, size, filename);
1824
hailfinger42a850a2010-07-13 23:56:13 +00001825out_free:
1826 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001827 if (ret)
1828 msg_cerr("FAILED.");
1829 else
1830 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001831 return ret;
1832}
1833
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001834/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001835static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001836{
hailfingerb91c08c2011-08-15 19:54:20 +00001837 int i, j, k;
1838 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001839
1840 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1841 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001842 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001843
1844 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1845 /* Blocks with zero size are bugs in flashchips.c. */
1846 if (eraser.eraseblocks[i].count &&
1847 !eraser.eraseblocks[i].size) {
1848 msg_gerr("ERROR: Flash chip %s erase function "
1849 "%i region %i has size 0. Please report"
1850 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001851 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001852 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001853 }
1854 /* Blocks with zero count are bugs in flashchips.c. */
1855 if (!eraser.eraseblocks[i].count &&
1856 eraser.eraseblocks[i].size) {
1857 msg_gerr("ERROR: Flash chip %s erase function "
1858 "%i region %i has count 0. Please report"
1859 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001860 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001861 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001862 }
1863 done += eraser.eraseblocks[i].count *
1864 eraser.eraseblocks[i].size;
1865 }
hailfinger9fed35d2010-01-19 06:42:46 +00001866 /* Empty eraseblock definition with erase function. */
1867 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001868 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001869 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001870 if (!done)
1871 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001872 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001873 msg_gerr("ERROR: Flash chip %s erase function %i "
1874 "region walking resulted in 0x%06x bytes total,"
1875 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001876 " flashrom@flashrom.org\n", chip->name, k,
1877 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001878 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001879 }
hailfinger9fed35d2010-01-19 06:42:46 +00001880 if (!eraser.block_erase)
1881 continue;
1882 /* Check if there are identical erase functions for different
1883 * layouts. That would imply "magic" erase functions. The
1884 * easiest way to check this is with function pointers.
1885 */
uwef6f94d42010-03-13 17:28:29 +00001886 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001887 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001888 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001889 msg_gerr("ERROR: Flash chip %s erase function "
1890 "%i and %i are identical. Please report"
1891 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001892 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001893 ret = 1;
1894 }
uwef6f94d42010-03-13 17:28:29 +00001895 }
hailfinger45177872010-01-18 08:14:43 +00001896 }
hailfinger9fed35d2010-01-19 06:42:46 +00001897 return ret;
hailfinger45177872010-01-18 08:14:43 +00001898}
1899
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001900static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001901 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001902 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001903 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001904 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001905 unsigned int addr,
1906 unsigned int len))
1907{
stefanctc5eb8a92011-11-23 09:13:48 +00001908 unsigned int starthere = 0, lenhere = 0;
1909 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001910 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001911 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001912
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001913 /*
1914 * curcontents and newcontents are opaque to walk_eraseregions, and
1915 * need to be adjusted here to keep the impression of proper
1916 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001917 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001918
hailfinger90fcf9b2010-11-05 14:51:59 +00001919 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001920
hailfingerb437e282010-11-04 01:04:27 +00001921 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001922
hailfingerb437e282010-11-04 01:04:27 +00001923 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001924 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001925 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001926 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001927 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001928 if (ret) {
1929 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001930 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001931 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001932 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001933 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001934 }
1935
David Hendricks0954ffc2015-11-13 15:15:44 -08001936 if (programmer_table[programmer].paranoid) {
1937 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001938 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001939 return -1;
1940 }
hailfingerac8e3182011-06-26 17:04:16 +00001941 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001942
hailfinger90fcf9b2010-11-05 14:51:59 +00001943 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001944 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001945 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001946 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001947 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001948 /* get_next_write() sets starthere to a new value after the call. */
1949 while ((lenhere = get_next_write(curcontents + starthere,
1950 newcontents + starthere,
1951 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001952 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001953 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001954 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001955 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001956 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001957 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001958 if (ret) {
1959 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001960 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001961 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001962 }
David Hendricks048b38c2016-03-28 18:47:06 -07001963
1964 /*
1965 * If the block needed to be erased and was erased successfully
1966 * then we can assume that we didn't run into any write-
1967 * protected areas. Otherwise, we need to verify each page to
1968 * ensure it was successfully written and abort if we encounter
1969 * any errors.
1970 */
1971 if (programmer_table[programmer].paranoid && !block_was_erased) {
1972 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001973 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001974 return -1;
1975 }
1976
hailfingerb437e282010-11-04 01:04:27 +00001977 starthere += lenhere;
1978 skip = 0;
1979 }
1980 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001981 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001982 return ret;
1983}
1984
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001985/*
1986 * Function to process processing units accumulated in the action descriptor.
1987 *
1988 * @flash pointer to the flash context to operate on
1989 * @do_something helper function which can erase and program a section of the
1990 * flash chip. It receives the flash context, offset and length
1991 * of the area to erase/program, before and after contents (to
1992 * decide what exactly needs to be erased and or programmed)
1993 * and a pointer to the erase function which can operate on the
1994 * proper granularity.
1995 * @descriptor action descriptor including pointers to before and after
1996 * contents and an array of processing actions to take.
1997 *
1998 * Returns zero on success or an error code.
1999 */
2000static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002001 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00002002 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00002003 unsigned int len,
2004 uint8_t *param1,
2005 uint8_t *param2,
2006 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002007 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00002008 unsigned int addr,
2009 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002010 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00002011{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002012 struct processing_unit *pu;
2013 int rc = 0;
2014 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00002015
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002016 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
2017 unsigned base = pu->offset;
2018 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07002019
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002020 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07002021
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002022 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00002023 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002024 else
2025 print_comma = 1;
2026
2027 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
2028
2029 rc = do_something(flash, base,
2030 pu->block_size,
2031 descriptor->oldcontents,
2032 descriptor->newcontents,
2033 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
2034
David Hendricks1ed1d352011-11-23 17:54:37 -08002035 if (rc) {
2036 if (ignore_error(rc))
2037 rc = 0;
2038 else
2039 return rc;
hailfingerb437e282010-11-04 01:04:27 +00002040 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002041 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00002042 }
2043 }
hailfingerb437e282010-11-04 01:04:27 +00002044 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08002045 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00002046}
2047
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002048static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00002049{
Patrick Georgif3fa2992017-02-02 16:24:44 +01002050 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00002051
2052 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
2053 if (log)
2054 msg_cdbg("not defined. ");
2055 return 1;
2056 }
2057 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
2058 if (log)
2059 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00002060 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00002061 return 1;
2062 }
2063 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
2064 if (log)
2065 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00002066 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00002067 return 1;
2068 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002069 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002070 return 0;
2071}
2072
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002073int erase_and_write_flash(struct flashctx *flash,
2074 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002075{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002076 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002077
hailfingercf848f12010-12-05 15:14:44 +00002078 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002079
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002080 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002081
hailfinger7df21362009-09-05 02:30:58 +00002082 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002083 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002084 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002085 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002086 }
2087 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002088}
2089
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002090static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002091{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002092 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2093#if CONFIG_INTERNAL == 1
2094 if (programmer == PROGRAMMER_INTERNAL)
2095 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2096 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2097 "mail flashrom@flashrom.org, thanks!\n"
2098 "-------------------------------------------------------------------------------\n"
2099 "You may now reboot or simply leave the machine running.\n");
2100 else
2101#endif
2102 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2103 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2104 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2105 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002106}
2107
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002108static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002109{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002110 msg_gerr("Your flash chip is in an unknown state.\n");
2111#if CONFIG_INTERNAL == 1
2112 if (programmer == PROGRAMMER_INTERNAL)
2113 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2114 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2115 "-------------------------------------------------------------------------------\n"
2116 "DO NOT REBOOT OR POWEROFF!\n");
2117 else
2118#endif
2119 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2120 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002121}
2122
hailfingerf79d1712010-10-06 23:48:34 +00002123void list_programmers_linebreak(int startcol, int cols, int paren)
2124{
2125 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002126 int pnamelen;
2127 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002128 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002129 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002130
2131 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2132 pname = programmer_table[p].name;
2133 pnamelen = strlen(pname);
2134 if (remaining - pnamelen - 2 < 0) {
2135 if (firstline)
2136 firstline = 0;
2137 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002138 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002139 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002140 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002141 remaining = cols - startcol;
2142 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002143 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002144 remaining--;
2145 }
2146 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002147 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002148 remaining--;
2149 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002150 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002151 remaining -= pnamelen;
2152 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002153 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002154 remaining--;
2155 } else {
2156 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002157 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002158 }
2159 }
2160}
2161
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002162static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002163{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002164#if IS_WINDOWS
2165 SYSTEM_INFO si;
2166 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002167
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002168 memset(&si, 0, sizeof(SYSTEM_INFO));
2169 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2170 msg_ginfo(" on Windows");
2171 /* Tell Windows which version of the structure we want. */
2172 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2173 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2174 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2175 else
2176 msg_ginfo(" unknown version");
2177 GetSystemInfo(&si);
2178 switch (si.wProcessorArchitecture) {
2179 case PROCESSOR_ARCHITECTURE_AMD64:
2180 msg_ginfo(" (x86_64)");
2181 break;
2182 case PROCESSOR_ARCHITECTURE_INTEL:
2183 msg_ginfo(" (x86)");
2184 break;
2185 default:
2186 msg_ginfo(" (unknown arch)");
2187 break;
2188 }
2189#elif HAVE_UTSNAME == 1
2190 struct utsname osinfo;
2191
2192 uname(&osinfo);
2193 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002194 osinfo.machine);
2195#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002196 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002197#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002198}
2199
2200void print_buildinfo(void)
2201{
2202 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002203#if NEED_PCI == 1
2204#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002205 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002206#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002207 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002208#endif
2209#endif
2210#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002211 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002212#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002213 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002214#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002215 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002216#endif
hailfinger3b471632010-03-27 16:36:40 +00002217#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002218 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002219#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002220 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002221#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002222 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002223#endif
2224#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002225 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002226#endif
2227#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002228 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00002229#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002230 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00002231#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002232 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002233}
2234
uwefdeca092008-01-21 15:24:22 +00002235void print_version(void)
2236{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002237 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002238 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002239 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002240}
2241
hailfinger74819ad2010-05-15 15:04:37 +00002242void print_banner(void)
2243{
2244 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002245 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002246 msg_ginfo("\n");
2247}
2248
hailfingerc77acb52009-12-24 02:15:55 +00002249int selfcheck(void)
2250{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002251 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002252 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002253
2254 /* Safety check. Instead of aborting after the first error, check
2255 * if more errors exist.
2256 */
hailfingerc77acb52009-12-24 02:15:55 +00002257 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002258 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002259 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002260 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002261 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2262 const struct programmer_entry p = programmer_table[i];
2263 if (p.name == NULL) {
2264 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2265 ret = 1;
2266 /* This might hide other problems with this programmer, but allows for better error
2267 * messages below without jumping through hoops. */
2268 continue;
2269 }
2270 switch (p.type) {
2271 case USB:
2272 case PCI:
2273 case OTHER:
2274 if (p.devs.note == NULL) {
2275 if (strcmp("internal", p.name) == 0)
2276 break; /* This one has its device list stored separately. */
2277 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2278 p.name);
2279 ret = 1;
2280 }
2281 break;
2282 default:
2283 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2284 ret = 1;
2285 break;
2286 }
2287 if (p.init == NULL) {
2288 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2289 ret = 1;
2290 }
2291 if (p.delay == NULL) {
2292 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2293 ret = 1;
2294 }
2295 if (p.map_flash_region == NULL) {
2296 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2297 ret = 1;
2298 }
2299 if (p.unmap_flash_region == NULL) {
2300 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2301 ret = 1;
2302 }
2303 }
2304
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002305 /* It would be favorable if we could check for the correct layout (especially termination) of various
2306 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2307 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2308 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2309 * 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 +10002310 * checks below. */
2311 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002312 msg_gerr("Flashchips table miscompilation!\n");
2313 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002314 } else {
2315 for (i = 0; i < flashchips_size - 1; i++) {
2316 const struct flashchip *chip = &flashchips[i];
2317 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2318 ret = 1;
2319 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2320 "Please report a bug at flashrom@flashrom.org\n", i,
2321 chip->name == NULL ? "unnamed" : chip->name);
2322 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002323 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002324 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002325 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002326 }
stefanct6d836ba2011-05-26 01:35:19 +00002327 }
stefanct6d836ba2011-05-26 01:35:19 +00002328
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002329 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002330 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002331}
2332
hailfinger771fc182010-10-15 00:01:14 +00002333/* FIXME: This function signature needs to be improved once doit() has a better
2334 * function signature.
2335 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002336static int chip_safety_check(const struct flashctx *flash, int force,
2337 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002338{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002339 const struct flashchip *chip = flash->chip;
2340
hailfinger771fc182010-10-15 00:01:14 +00002341 if (!programmer_may_write && (write_it || erase_it)) {
2342 msg_perr("Write/erase is not working yet on your programmer in "
2343 "its current configuration.\n");
2344 /* --force is the wrong approach, but it's the best we can do
2345 * until the generic programmer parameter parser is merged.
2346 */
2347 if (!force)
2348 return 1;
2349 msg_cerr("Continuing anyway.\n");
2350 }
2351
2352 if (read_it || erase_it || write_it || verify_it) {
2353 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002354 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002355 msg_cerr("Read is not working on this chip. ");
2356 if (!force)
2357 return 1;
2358 msg_cerr("Continuing anyway.\n");
2359 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002360 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002361 msg_cerr("flashrom has no read function for this "
2362 "flash chip.\n");
2363 return 1;
2364 }
2365 }
2366 if (erase_it || write_it) {
2367 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002368 if (chip->tested.erase == NA) {
2369 msg_cerr("Erase is not possible on this chip.\n");
2370 return 1;
2371 }
2372 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002373 msg_cerr("Erase is not working on this chip. ");
2374 if (!force)
2375 return 1;
2376 msg_cerr("Continuing anyway.\n");
2377 }
stefancte1c5acf2011-07-04 07:27:17 +00002378 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002379 msg_cerr("flashrom has no erase function for this "
2380 "flash chip.\n");
2381 return 1;
2382 }
hailfinger771fc182010-10-15 00:01:14 +00002383 }
2384 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002385 if (chip->tested.write == NA) {
2386 msg_cerr("Write is not possible on this chip.\n");
2387 return 1;
2388 }
2389 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002390 msg_cerr("Write is not working on this chip. ");
2391 if (!force)
2392 return 1;
2393 msg_cerr("Continuing anyway.\n");
2394 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002395 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002396 msg_cerr("flashrom has no write function for this "
2397 "flash chip.\n");
2398 return 1;
2399 }
2400 }
2401 return 0;
2402}
2403
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002404int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002405 const bool read_it, const bool write_it,
2406 const bool erase_it, const bool verify_it)
2407{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002408 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002409 msg_cerr("Aborting.\n");
2410 return 1;
2411 }
2412
2413 if (normalize_romentries(flash)) {
2414 msg_cerr("Requested regions can not be handled. Aborting.\n");
2415 return 1;
2416 }
2417
Edward O'Callaghan40092972020-10-20 11:50:48 +11002418 /*
2419 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2420 * can be repro'ed with upstream on Volteer.
2421 *
2422 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2423 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2424 * hooked and this can fail on some board topologies. Checking the return value can
2425 * cause board rw failures by bailing early. Avoid the early bail for now until a
2426 * full investigation can reveal the proper fix. This restores previous behaviour of
2427 * assuming a map went fine.
2428 */
2429#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002430 if (map_flash(flash) != 0)
2431 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002432#endif
2433 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002434
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002435 /* Given the existence of read locks, we want to unlock for read,
2436 erase and write. */
2437 if (flash->chip->unlock)
2438 flash->chip->unlock(flash);
2439
2440 flash->address_high_byte = -1;
2441 flash->in_4ba_mode = false;
2442
Edward O'Callaghan99974452020-10-13 13:28:33 +11002443 /* Be careful about 4BA chips and broken masters */
2444 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2445 /* If we can't use native instructions, bail out */
2446 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2447 || !spi_master_4ba(flash)) {
2448 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2449 return 1;
2450 }
2451 }
2452
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002453 /* Enable/disable 4-byte addressing mode if flash chip supports it */
Edward O'Callaghan99974452020-10-13 13:28:33 +11002454 if (flash->chip->feature_bits & (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_ENTER_EAR7)) {
2455 int ret;
2456 if (spi_master_4ba(flash))
2457 ret = spi_enter_4ba(flash);
2458 else
2459 ret = spi_exit_4ba(flash);
2460 if (ret) {
2461 msg_cerr("Failed to set correct 4BA mode! Aborting.\n");
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002462 return 1;
2463 }
2464 }
2465
2466 return 0;
2467}
2468
Edward O'Callaghana820b212020-09-17 22:53:26 +10002469void finalize_flash_access(struct flashctx *const flash)
2470{
2471 unmap_flash(flash);
2472}
2473
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002474/*
2475 * Function to erase entire flash chip.
2476 *
2477 * @flashctx pointer to the flash context to use
2478 * @oldcontents pointer to the buffer including current chip contents, to
2479 * decide which areas do in fact need to be erased
2480 * @size the size of the flash chip, in bytes.
2481 *
2482 * Returns zero on success or an error code.
2483 */
2484static int erase_chip(struct flashctx *flash, void *oldcontents,
2485 void *newcontents, size_t size)
2486{
2487 /*
2488 * To make sure that the chip is fully erased, let's cheat and create
2489 * a descriptor where the new contents are all erased.
2490 */
2491 struct action_descriptor *fake_descriptor;
2492 int ret = 0;
2493
2494 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2495 newcontents, 1);
2496 /* FIXME: Do we really want the scary warning if erase failed? After
2497 * all, after erase the chip is either blank or partially blank or it
2498 * has the old contents. A blank chip won't boot, so if the user
2499 * wanted erase and reboots afterwards, the user knows very well that
2500 * booting won't work.
2501 */
2502 if (erase_and_write_flash(flash, fake_descriptor)) {
2503 emergency_help_message();
2504 ret = 1;
2505 }
2506
2507 free(fake_descriptor);
2508
2509 return ret;
2510}
2511
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002512static int read_dest_content(struct flashctx *flash, int verify_it,
2513 uint8_t *dest, unsigned long size)
2514{
2515 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2516 && get_num_include_args()) {
2517 /*
2518 * If no full verification is required and not
2519 * the entire chip is about to be programmed,
2520 * read only the areas which might change.
2521 */
2522 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2523 return 1;
2524 } else {
2525 if (read_flash(flash, dest, 0, size))
2526 return 1;
2527 }
2528 return 0;
2529}
2530
hailfingerc77acb52009-12-24 02:15:55 +00002531/* This function signature is horrible. We need to design a better interface,
2532 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002533 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002534 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002535int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002536 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002537 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002538{
hailfinger4c47e9d2010-10-19 22:06:20 +00002539 uint8_t *oldcontents;
2540 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002541 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002542 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002543 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002544
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002545 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002546 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002547 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002548
Simon Glass9ad06c12013-07-03 22:08:17 +09002549 if (extract_it) {
2550 ret = extract_regions(flash);
2551 goto out_nofree;
2552 }
2553
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002554 /* mark entries included using -i argument as "included" if they are
2555 found in the master rom_entries list */
2556 if (process_include_args() < 0) {
2557 ret = 1;
2558 goto out_nofree;
2559 }
2560
hailfinger771fc182010-10-15 00:01:14 +00002561 if (read_it) {
2562 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002563 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002564 }
hailfingerb437e282010-11-04 01:04:27 +00002565
stefanctd611e8f2011-07-12 22:35:21 +00002566 oldcontents = malloc(size);
2567 if (!oldcontents) {
2568 msg_gerr("Out of memory!\n");
2569 exit(1);
2570 }
Simon Glass4c214132013-07-16 10:09:28 -06002571 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002572 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002573 newcontents = malloc(size);
2574 if (!newcontents) {
2575 msg_gerr("Out of memory!\n");
2576 exit(1);
2577 }
Simon Glass4c214132013-07-16 10:09:28 -06002578 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002579 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002580 /* Side effect of the assumptions above: Default write action is erase
2581 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002582 * oldcontents being completely unerased means we have to erase
2583 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002584 */
2585
hailfingerd217d122010-10-08 18:52:29 +00002586 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002587 /*
2588 * Note: This must be done before any files specified by -i
2589 * arguments are processed merged into the newcontents since
2590 * -i files take priority. See http://crbug.com/263495.
2591 */
2592 if (filename) {
2593 if (read_buf_from_file(newcontents, size, filename)) {
2594 ret = 1;
2595 goto out;
2596 }
2597 } else {
2598 /* Content will be read from -i args, so they must
2599 * not overlap. */
2600 if (included_regions_overlap()) {
2601 msg_gerr("Error: Included regions must "
2602 "not overlap.\n");
2603 ret = 1;
2604 goto out;
2605 }
stepan1da96c02006-11-21 23:48:51 +00002606 }
ollie5672ac62004-03-17 22:22:08 +00002607 }
2608
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002609 if (do_diff) {
2610 /*
2611 * Obtain a reference image so that we can check whether
2612 * regions need to be erased and to give better diagnostics in
2613 * case write fails. If --fast-verify is used then only the
2614 * regions which are included using -i will be read.
2615 */
2616 if (diff_file) {
2617 msg_cdbg("Reading old contents from file... ");
2618 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002619 ret = 1;
2620 msg_cdbg("FAILED.\n");
2621 goto out;
2622 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002623 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002624 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002625 ret = read_dest_content(flash, verify_it,
2626 oldcontents, size);
2627 if (ret) {
2628 msg_cdbg("FAILED.\n");
2629 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002630 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002631 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002632 msg_cdbg("done.\n");
2633 } else if (!erase_it) {
2634 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002635 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002636 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002637
David Hendricksdf29a832013-06-28 14:33:51 -07002638 /*
2639 * Note: This must be done after reading the file specified for the
2640 * -w/-v argument, if any, so that files specified using -i end up
2641 * in the "newcontents" buffer before being written.
2642 * See http://crbug.com/263495.
2643 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002644 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002645 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002646 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002647 goto out;
2648 }
uwef6641642007-05-09 10:17:44 +00002649
David Hendricksa7e114b2016-02-26 18:49:15 -08002650 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002651 erase_chip(flash, oldcontents, newcontents, size);
2652 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002653 }
2654
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002655 descriptor = prepare_action_descriptor(flash, oldcontents,
2656 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002657 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002658 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002659 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002660 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002661 goto out;
2662 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002663
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002664 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002665 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2666 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002667 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002668 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002669 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002670 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002671 ret = 1;
2672 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002673 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002674 msg_cerr("Apparently at least some data has changed.\n");
2675 } else
2676 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002677 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002678 ret = 1;
2679 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002680 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002681
David Hendricksac1d25c2016-08-09 17:00:58 -07002682 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002683 if (ret < 0) {
2684 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002685 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002686 emergency_help_message();
2687 ret = 1;
2688 goto out;
2689 } else if (ret > 0) {
2690 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002691 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002692 ret = read_dest_content(flash, verify_it,
2693 oldcontents, size);
2694 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002695 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002696 goto out;
2697 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002698
2699 /* Get a new descriptor. */
2700 free(descriptor);
2701 descriptor = prepare_action_descriptor(flash,
2702 oldcontents,
2703 newcontents,
2704 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002705 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002706 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002707 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002708 emergency_help_message();
2709 ret = 1;
2710 goto out;
2711 }
2712 ret = 0;
2713 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002714
David Hendricksac1d25c2016-08-09 17:00:58 -07002715 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002716 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002717 emergency_help_message();
2718 ret = 1;
2719 goto out;
2720 }
stuge8ce3a3c2008-04-28 14:47:30 +00002721 }
ollie6a600992005-11-26 21:55:36 +00002722
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002723 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002724 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002725 if ((write_it || erase_it) && !content_has_changed) {
2726 msg_gdbg("Nothing was erased or written, skipping "
2727 "verification\n");
2728 } else {
2729 /* Work around chips which need some time to calm down. */
2730 if (write_it && verify_it != VERIFY_PARTIAL)
2731 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002732
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002733 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002734
David Hendricks9ba79fb2015-04-03 12:06:16 -07002735 /* If we tried to write, and verification now fails, we
2736 * might have an emergency situation.
2737 */
2738 if (ret && write_it)
2739 emergency_help_message();
2740 }
hailfinger0459e1c2009-08-19 13:55:34 +00002741 }
ollie6a600992005-11-26 21:55:36 +00002742
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002743 finalize_flash_access(flash);
2744
hailfinger90fcf9b2010-11-05 14:51:59 +00002745out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002746 if (descriptor)
2747 free(descriptor);
2748
hailfinger90fcf9b2010-11-05 14:51:59 +00002749 free(oldcontents);
2750 free(newcontents);
2751out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002752 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002753 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002754 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002755 * tree. This is because some operations, such as write protection,
2756 * requires programmer_shutdown() but does not call doit().
2757 */
2758// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002759 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002760}