blob: 121b51176f555e783da883471b2c16474a15e5fe [file] [log] [blame]
rminnich8d3ff912003-10-25 17:01:29 +00001/*
uweb25f1ea2007-08-29 17:52:32 +00002 * This file is part of the flashrom project.
rminnich8d3ff912003-10-25 17:01:29 +00003 *
uwe555dd972007-09-09 20:21:05 +00004 * Copyright (C) 2000 Silicon Integrated System Corporation
5 * Copyright (C) 2004 Tyan Corp <yhlu@tyan.com>
uwe4475e902009-05-19 14:14:21 +00006 * Copyright (C) 2005-2008 coresystems GmbH
hailfinger23060112009-05-08 12:49:03 +00007 * Copyright (C) 2008,2009 Carl-Daniel Hailfinger
Edward O'Callaghan0949b782019-11-10 23:23:20 +11008 * Copyright (C) 2016 secunet Security Networks AG
9 * (Written by Nico Huber <nico.huber@secunet.com> for secunet)
rminnich8d3ff912003-10-25 17:01:29 +000010 *
uweb25f1ea2007-08-29 17:52:32 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
rminnich8d3ff912003-10-25 17:01:29 +000015 *
uweb25f1ea2007-08-29 17:52:32 +000016 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
rminnich8d3ff912003-10-25 17:01:29 +000020 */
21
hailfingera83a5fe2010-05-30 22:24:40 +000022#include <stdio.h>
stepan1da96c02006-11-21 23:48:51 +000023#include <sys/types.h>
oxygene50275892010-09-30 17:03:32 +000024#ifndef __LIBPAYLOAD__
25#include <fcntl.h>
stepan1da96c02006-11-21 23:48:51 +000026#include <sys/stat.h>
oxygene50275892010-09-30 17:03:32 +000027#endif
rminnich8d3ff912003-10-25 17:01:29 +000028#include <string.h>
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +100029#include <unistd.h>
rminnich8d3ff912003-10-25 17:01:29 +000030#include <stdlib.h>
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +100031#include <errno.h>
hailfingerf76cc322010-11-09 22:00:31 +000032#include <ctype.h>
ollie6a600992005-11-26 21:55:36 +000033#include <getopt.h>
hailfinger3b471632010-03-27 16:36:40 +000034#if HAVE_UTSNAME == 1
35#include <sys/utsname.h>
36#endif
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -070037
38#include "action_descriptor.h"
rminnich8d3ff912003-10-25 17:01:29 +000039#include "flash.h"
hailfinger66966da2009-06-15 14:14:48 +000040#include "flashchips.h"
Simon Glass9ad06c12013-07-03 22:08:17 +090041#include "layout.h"
hailfinger428f6852010-07-27 22:41:39 +000042#include "programmer.h"
Duncan Laurie25a4ca22019-04-25 12:08:52 -070043#include "spi.h"
Edward O'Callaghan99974452020-10-13 13:28:33 +110044#include "chipdrivers.h"
rminnich8d3ff912003-10-25 17:01:29 +000045
krause2eb76212011-01-17 07:50:42 +000046const char flashrom_version[] = FLASHROM_VERSION;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100047const char *chip_to_probe = NULL;
hailfinger80422e22009-12-13 22:28:00 +000048
David Hendricks9ba79fb2015-04-03 12:06:16 -070049/* Set if any erase/write operation is to be done. This will be used to
50 * decide if final verification is needed. */
51static int content_has_changed = 0;
52
David Hendricks1ed1d352011-11-23 17:54:37 -080053/* error handling stuff */
54enum error_action access_denied_action = error_ignore;
55
56int ignore_error(int err) {
57 int rc = 0;
58
59 switch(err) {
60 case ACCESS_DENIED:
61 if (access_denied_action == error_ignore)
62 rc = 1;
63 break;
64 default:
65 break;
66 }
67
68 return rc;
69}
70
hailfinger969e2f32011-09-08 00:00:29 +000071static enum programmer programmer = PROGRAMMER_INVALID;
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +100072static const char *programmer_param = NULL;
stepan782fb172007-04-06 11:58:03 +000073
uwee15beb92010-08-08 17:01:18 +000074/*
hailfinger80422e22009-12-13 22:28:00 +000075 * Programmers supporting multiple buses can have differing size limits on
76 * each bus. Store the limits for each bus in a common struct.
77 */
hailfinger1ff33dc2010-07-03 11:02:10 +000078struct decode_sizes max_rom_decode;
79
80/* If nonzero, used as the start address of bottom-aligned flash. */
81unsigned long flashbase;
hailfinger80422e22009-12-13 22:28:00 +000082
hailfinger5828baf2010-07-03 12:14:25 +000083/* Is writing allowed with this programmer? */
84int programmer_may_write;
85
hailfingerabe249e2009-05-08 17:43:22 +000086const struct programmer_entry programmer_table[] = {
hailfinger90c7d542010-05-31 15:27:27 +000087#if CONFIG_INTERNAL == 1
hailfingerabe249e2009-05-08 17:43:22 +000088 {
hailfinger3548a9a2009-08-12 14:34:35 +000089 .name = "internal",
Edward O'Callaghan0949b782019-11-10 23:23:20 +110090 .type = OTHER,
91 .devs.note = NULL,
hailfinger6c69ab02009-05-11 15:46:43 +000092 .init = internal_init,
hailfinger11ae3c42009-05-11 14:13:25 +000093 .map_flash_region = physmap,
94 .unmap_flash_region = physunmap,
hailfingere5829f62009-06-05 17:48:08 +000095 .delay = internal_delay,
David Hendricks55cdd9c2015-11-25 14:37:26 -080096
97 /*
98 * "Internal" implies in-system programming on a live system, so
99 * handle with paranoia to catch errors early. If something goes
100 * wrong then hopefully the system will still be recoverable.
101 */
102 .paranoid = 1,
hailfingerabe249e2009-05-08 17:43:22 +0000103 },
hailfinger80422e22009-12-13 22:28:00 +0000104#endif
stepan927d4e22007-04-04 22:45:58 +0000105
hailfinger90c7d542010-05-31 15:27:27 +0000106#if CONFIG_DUMMY == 1
hailfingera9df33c2009-05-09 00:54:55 +0000107 {
hailfinger3548a9a2009-08-12 14:34:35 +0000108 .name = "dummy",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100109 .type = OTHER,
110 /* FIXME */
111 .devs.note = "Dummy device, does nothing and logs all accesses\n",
hailfinger6c69ab02009-05-11 15:46:43 +0000112 .init = dummy_init,
hailfinger11ae3c42009-05-11 14:13:25 +0000113 .map_flash_region = dummy_map,
114 .unmap_flash_region = dummy_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000115 .delay = internal_delay,
hailfingera9df33c2009-05-09 00:54:55 +0000116 },
hailfinger571a6b32009-09-16 10:09:21 +0000117#endif
hailfingera9df33c2009-05-09 00:54:55 +0000118
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000119#if CONFIG_MEC1308 == 1
120 {
121 .name = "mec1308",
122 .type = OTHER,
123 .devs.note = "Microchip MEC1308 Embedded Controller.\n",
124 .init = mec1308_init,
125 .map_flash_region = fallback_map,
126 .unmap_flash_region = fallback_unmap,
127 .delay = internal_delay,
128 },
129#endif
130
hailfinger90c7d542010-05-31 15:27:27 +0000131#if CONFIG_NIC3COM == 1
uwe0f5a3a22009-05-13 11:36:06 +0000132 {
hailfinger3548a9a2009-08-12 14:34:35 +0000133 .name = "nic3com",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100134 .type = PCI,
135 .devs.dev = nics_3com,
uwe0f5a3a22009-05-13 11:36:06 +0000136 .init = nic3com_init,
uwe3e656bd2009-05-17 23:12:17 +0000137 .map_flash_region = fallback_map,
138 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000139 .delay = internal_delay,
uwe0f5a3a22009-05-13 11:36:06 +0000140 },
hailfinger571a6b32009-09-16 10:09:21 +0000141#endif
uwe0f5a3a22009-05-13 11:36:06 +0000142
hailfinger90c7d542010-05-31 15:27:27 +0000143#if CONFIG_NICREALTEK == 1
hailfinger5aa36982010-05-21 21:54:07 +0000144 {
hailfinger0d703d42011-03-07 01:08:09 +0000145 /* This programmer works for Realtek RTL8139 and SMC 1211. */
uwe8d342eb2011-07-28 08:13:25 +0000146 .name = "nicrealtek",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100147 .type = PCI,
148 .devs.dev = nics_realtek,
uwe8d342eb2011-07-28 08:13:25 +0000149 .init = nicrealtek_init,
150 .map_flash_region = fallback_map,
151 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000152 .delay = internal_delay,
hailfinger5aa36982010-05-21 21:54:07 +0000153 },
hailfinger5aa36982010-05-21 21:54:07 +0000154#endif
155
hailfingerf0a368f2010-06-07 22:37:54 +0000156#if CONFIG_NICNATSEMI == 1
157 {
uwe8d342eb2011-07-28 08:13:25 +0000158 .name = "nicnatsemi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100159 .type = PCI,
160 .devs.dev = nics_natsemi,
uwe8d342eb2011-07-28 08:13:25 +0000161 .init = nicnatsemi_init,
162 .map_flash_region = fallback_map,
163 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000164 .delay = internal_delay,
hailfingerf0a368f2010-06-07 22:37:54 +0000165 },
166#endif
hailfinger5aa36982010-05-21 21:54:07 +0000167
hailfinger90c7d542010-05-31 15:27:27 +0000168#if CONFIG_GFXNVIDIA == 1
uweff4576d2009-09-30 18:29:55 +0000169 {
170 .name = "gfxnvidia",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100171 .type = PCI,
172 .devs.dev = gfx_nvidia,
uweff4576d2009-09-30 18:29:55 +0000173 .init = gfxnvidia_init,
uweff4576d2009-09-30 18:29:55 +0000174 .map_flash_region = fallback_map,
175 .unmap_flash_region = fallback_unmap,
uweff4576d2009-09-30 18:29:55 +0000176 .delay = internal_delay,
177 },
178#endif
179
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000180#if CONFIG_RAIDEN_DEBUG_SPI == 1
181 {
182 .name = "raiden_debug_spi",
183 .type = USB,
184 .devs.dev = devs_raiden,
185 .init = raiden_debug_spi_init,
186 .map_flash_region = fallback_map,
187 .unmap_flash_region = fallback_unmap,
188 .delay = internal_delay,
189 },
190#endif
191
hailfinger90c7d542010-05-31 15:27:27 +0000192#if CONFIG_DRKAISER == 1
ruikda922a12009-05-17 19:39:27 +0000193 {
uwee2f95ef2009-09-02 23:00:46 +0000194 .name = "drkaiser",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100195 .type = PCI,
196 .devs.dev = drkaiser_pcidev,
uwee2f95ef2009-09-02 23:00:46 +0000197 .init = drkaiser_init,
uwee2f95ef2009-09-02 23:00:46 +0000198 .map_flash_region = fallback_map,
199 .unmap_flash_region = fallback_unmap,
uwee2f95ef2009-09-02 23:00:46 +0000200 .delay = internal_delay,
201 },
hailfinger571a6b32009-09-16 10:09:21 +0000202#endif
uwee2f95ef2009-09-02 23:00:46 +0000203
hailfinger90c7d542010-05-31 15:27:27 +0000204#if CONFIG_SATASII == 1
uwee2f95ef2009-09-02 23:00:46 +0000205 {
hailfinger3548a9a2009-08-12 14:34:35 +0000206 .name = "satasii",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100207 .type = PCI,
208 .devs.dev = satas_sii,
ruikda922a12009-05-17 19:39:27 +0000209 .init = satasii_init,
uwe3e656bd2009-05-17 23:12:17 +0000210 .map_flash_region = fallback_map,
211 .unmap_flash_region = fallback_unmap,
hailfingere5829f62009-06-05 17:48:08 +0000212 .delay = internal_delay,
ruikda922a12009-05-17 19:39:27 +0000213 },
hailfinger571a6b32009-09-16 10:09:21 +0000214#endif
ruikda922a12009-05-17 19:39:27 +0000215
hailfinger90c7d542010-05-31 15:27:27 +0000216#if CONFIG_ATAHPT == 1
uwe7e627c82010-02-21 21:17:00 +0000217 {
218 .name = "atahpt",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100219 .type = PCI,
220 .devs.dev = ata_hpt,
uwe7e627c82010-02-21 21:17:00 +0000221 .init = atahpt_init,
uwe7e627c82010-02-21 21:17:00 +0000222 .map_flash_region = fallback_map,
223 .unmap_flash_region = fallback_unmap,
uwe7e627c82010-02-21 21:17:00 +0000224 .delay = internal_delay,
225 },
226#endif
227
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000228#if CONFIG_ATAVIA == 1
229 {
230 .name = "atavia",
231 .type = PCI,
232 .devs.dev = ata_via,
233 .init = atavia_init,
234 .map_flash_region = atavia_map,
235 .unmap_flash_region = fallback_unmap,
236 .delay = internal_delay,
237 },
238#endif
239
240#if CONFIG_ATAPROMISE == 1
241 {
242 .name = "atapromise",
243 .type = PCI,
244 .devs.dev = ata_promise,
245 .init = atapromise_init,
246 .map_flash_region = atapromise_map,
247 .unmap_flash_region = fallback_unmap,
248 .delay = internal_delay,
249 },
250#endif
251
252#if CONFIG_IT8212 == 1
253 {
254 .name = "it8212",
255 .type = PCI,
256 .devs.dev = devs_it8212,
257 .init = it8212_init,
258 .map_flash_region = fallback_map,
259 .unmap_flash_region = fallback_unmap,
260 .delay = internal_delay,
261 },
262#endif
263
hailfinger90c7d542010-05-31 15:27:27 +0000264#if CONFIG_FT2232_SPI == 1
hailfingerf31da3d2009-06-16 21:08:06 +0000265 {
hailfinger90c7d542010-05-31 15:27:27 +0000266 .name = "ft2232_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100267 .type = USB,
Nikolai Artemievc347a852020-04-29 12:17:08 +1000268 .devs.dev = devs_ft2232spi,
hailfingerf31da3d2009-06-16 21:08:06 +0000269 .init = ft2232_spi_init,
hailfinger6fe23d62009-08-12 11:39:29 +0000270 .map_flash_region = fallback_map,
271 .unmap_flash_region = fallback_unmap,
hailfingerf31da3d2009-06-16 21:08:06 +0000272 .delay = internal_delay,
273 },
hailfingerd9dcfbd2009-08-19 13:27:58 +0000274#endif
hailfinger6fe23d62009-08-12 11:39:29 +0000275
hailfinger90c7d542010-05-31 15:27:27 +0000276#if CONFIG_SERPROG == 1
hailfinger37b4fbf2009-06-23 11:33:43 +0000277 {
hailfinger3548a9a2009-08-12 14:34:35 +0000278 .name = "serprog",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100279 .type = OTHER,
280 /* FIXME */
281 .devs.note = "All programmer devices speaking the serprog protocol\n",
hailfinger37b4fbf2009-06-23 11:33:43 +0000282 .init = serprog_init,
Edward O'Callaghan62018182020-10-03 00:16:48 +1000283 .map_flash_region = serprog_map,
hailfinger37b4fbf2009-06-23 11:33:43 +0000284 .unmap_flash_region = fallback_unmap,
hailfinger37b4fbf2009-06-23 11:33:43 +0000285 .delay = serprog_delay,
286 },
hailfinger74d88a72009-08-12 16:17:41 +0000287#endif
hailfingerf31da3d2009-06-16 21:08:06 +0000288
hailfinger90c7d542010-05-31 15:27:27 +0000289#if CONFIG_BUSPIRATE_SPI == 1
hailfinger9c5add72009-11-24 00:20:03 +0000290 {
hailfinger90c7d542010-05-31 15:27:27 +0000291 .name = "buspirate_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100292 .type = OTHER,
293 /* FIXME */
294 .devs.note = "Dangerous Prototypes Bus Pirate\n",
hailfinger9c5add72009-11-24 00:20:03 +0000295 .init = buspirate_spi_init,
hailfinger9c5add72009-11-24 00:20:03 +0000296 .map_flash_region = fallback_map,
297 .unmap_flash_region = fallback_unmap,
hailfinger9c5add72009-11-24 00:20:03 +0000298 .delay = internal_delay,
299 },
300#endif
301
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000302#if CONFIG_DEDIPROG == 1
Anton Staafb2647882014-09-17 15:13:43 -0700303 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000304 .name = "dediprog",
Brian J. Nemecb42d6c12020-07-23 03:07:38 -0700305 .type = USB,
Edward O'Callaghanac1678b2020-07-27 15:55:45 +1000306 .devs.dev = devs_dediprog,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000307 .init = dediprog_init,
Anton Staafb2647882014-09-17 15:13:43 -0700308 .map_flash_region = fallback_map,
309 .unmap_flash_region = fallback_unmap,
310 .delay = internal_delay,
311 },
312#endif
313
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000314#if CONFIG_DEVELOPERBOX_SPI == 1
hailfingerdfb32a02010-01-19 11:15:48 +0000315 {
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000316 .name = "developerbox",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100317 .type = USB,
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000318 .devs.dev = devs_developerbox_spi,
319 .init = developerbox_spi_init,
320 .map_flash_region = fallback_map,
321 .unmap_flash_region = fallback_unmap,
322 .delay = internal_delay,
323 },
324#endif
325
326#if CONFIG_ENE_LPC == 1
327 {
328 .name = "ene_lpc",
329 .type = OTHER,
330 .devs.note = "ENE LPC interface keyboard controller\n",
331 .init = ene_lpc_init,
hailfingerdfb32a02010-01-19 11:15:48 +0000332 .map_flash_region = fallback_map,
333 .unmap_flash_region = fallback_unmap,
hailfingerdfb32a02010-01-19 11:15:48 +0000334 .delay = internal_delay,
335 },
336#endif
337
hailfinger52c4fa02010-07-21 10:26:01 +0000338#if CONFIG_RAYER_SPI == 1
339 {
340 .name = "rayer_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100341 .type = OTHER,
342 /* FIXME */
343 .devs.note = "RayeR parallel port programmer\n",
hailfinger52c4fa02010-07-21 10:26:01 +0000344 .init = rayer_spi_init,
hailfinger52c4fa02010-07-21 10:26:01 +0000345 .map_flash_region = fallback_map,
346 .unmap_flash_region = fallback_unmap,
hailfinger52c4fa02010-07-21 10:26:01 +0000347 .delay = internal_delay,
348 },
349#endif
350
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000351#if CONFIG_PONY_SPI == 1
352 {
353 .name = "pony_spi",
354 .type = OTHER,
355 /* FIXME */
356 .devs.note = "Programmers compatible with SI-Prog, serbang or AJAWe\n",
357 .init = pony_spi_init,
358 .map_flash_region = fallback_map,
359 .unmap_flash_region = fallback_unmap,
360 .delay = internal_delay,
361 },
362#endif
363
hailfinger7949b652011-05-08 00:24:18 +0000364#if CONFIG_NICINTEL == 1
365 {
366 .name = "nicintel",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100367 .type = PCI,
368 .devs.dev = nics_intel,
hailfinger7949b652011-05-08 00:24:18 +0000369 .init = nicintel_init,
hailfinger7949b652011-05-08 00:24:18 +0000370 .map_flash_region = fallback_map,
371 .unmap_flash_region = fallback_unmap,
hailfinger7949b652011-05-08 00:24:18 +0000372 .delay = internal_delay,
373 },
374#endif
375
uwe6764e922010-09-03 18:21:21 +0000376#if CONFIG_NICINTEL_SPI == 1
377 {
uwe8d342eb2011-07-28 08:13:25 +0000378 .name = "nicintel_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100379 .type = PCI,
380 .devs.dev = nics_intel_spi,
uwe8d342eb2011-07-28 08:13:25 +0000381 .init = nicintel_spi_init,
382 .map_flash_region = fallback_map,
383 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000384 .delay = internal_delay,
uwe6764e922010-09-03 18:21:21 +0000385 },
386#endif
387
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000388#if CONFIG_NICINTEL_EEPROM == 1
389 {
390 .name = "nicintel_eeprom",
391 .type = PCI,
392 .devs.dev = nics_intel_ee,
393 .init = nicintel_ee_init,
394 .map_flash_region = fallback_map,
395 .unmap_flash_region = fallback_unmap,
396 .delay = internal_delay,
397 },
398#endif
399
hailfingerfb1f31f2010-12-03 14:48:11 +0000400#if CONFIG_OGP_SPI == 1
401 {
uwe8d342eb2011-07-28 08:13:25 +0000402 .name = "ogp_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100403 .type = PCI,
404 .devs.dev = ogp_spi,
uwe8d342eb2011-07-28 08:13:25 +0000405 .init = ogp_spi_init,
406 .map_flash_region = fallback_map,
407 .unmap_flash_region = fallback_unmap,
uwe8d342eb2011-07-28 08:13:25 +0000408 .delay = internal_delay,
hailfingerfb1f31f2010-12-03 14:48:11 +0000409 },
410#endif
411
hailfinger935365d2011-02-04 21:37:59 +0000412#if CONFIG_SATAMV == 1
413 {
414 .name = "satamv",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100415 .type = PCI,
416 .devs.dev = satas_mv,
hailfinger935365d2011-02-04 21:37:59 +0000417 .init = satamv_init,
hailfinger935365d2011-02-04 21:37:59 +0000418 .map_flash_region = fallback_map,
419 .unmap_flash_region = fallback_unmap,
hailfinger935365d2011-02-04 21:37:59 +0000420 .delay = internal_delay,
421 },
422#endif
423
David Hendrickscebee892015-05-23 20:30:30 -0700424#if CONFIG_LINUX_MTD == 1
425 {
426 .name = "linux_mtd",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100427 .type = OTHER,
428 .devs.note = "Device files /dev/mtd*\n",
David Hendrickscebee892015-05-23 20:30:30 -0700429 .init = linux_mtd_init,
430 .map_flash_region = fallback_map,
431 .unmap_flash_region = fallback_unmap,
432 .delay = internal_delay,
433 },
434#endif
435
uwe7df6dda2011-09-03 18:37:52 +0000436#if CONFIG_LINUX_SPI == 1
437 {
438 .name = "linux_spi",
Edward O'Callaghan0949b782019-11-10 23:23:20 +1100439 .type = OTHER,
440 .devs.note = "Device files /dev/spidev*.*\n",
uwe7df6dda2011-09-03 18:37:52 +0000441 .init = linux_spi_init,
442 .map_flash_region = fallback_map,
443 .unmap_flash_region = fallback_unmap,
uwe7df6dda2011-09-03 18:37:52 +0000444 .delay = internal_delay,
445 },
446#endif
447
Shiyu Sun9dde7162020-04-16 17:32:55 +1000448#if CONFIG_LSPCON_I2C_SPI == 1
449 {
450 .name = "lspcon_i2c_spi",
451 .type = OTHER,
452 .devs.note = "Device files /dev/i2c-*.\n",
453 .init = lspcon_i2c_spi_init,
454 .map_flash_region = fallback_map,
455 .unmap_flash_region = fallback_unmap,
456 .delay = internal_delay,
457 },
458#endif
459
Edward O'Callaghan97dd9262020-03-26 00:00:41 +1100460#if CONFIG_REALTEK_MST_I2C_SPI == 1
461 {
462 .name = "realtek_mst_i2c_spi",
463 .type = OTHER,
464 .devs.note = "Device files /dev/i2c-*.\n",
465 .init = realtek_mst_i2c_spi_init,
466 .map_flash_region = fallback_map,
467 .unmap_flash_region = fallback_unmap,
468 .delay = internal_delay,
469 },
470#endif
471
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000472#if CONFIG_USBBLASTER_SPI == 1
473 {
474 .name = "usbblaster_spi",
475 .type = USB,
476 .devs.dev = devs_usbblasterspi,
477 .init = usbblaster_spi_init,
478 .map_flash_region = fallback_map,
479 .unmap_flash_region = fallback_unmap,
480 .delay = internal_delay,
481 },
482#endif
483
484#if CONFIG_MSTARDDC_SPI == 1
485 {
486 .name = "mstarddc_spi",
487 .type = OTHER,
488 .devs.note = "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
489 .init = mstarddc_spi_init,
490 .map_flash_region = fallback_map,
491 .unmap_flash_region = fallback_unmap,
492 .delay = internal_delay,
493 },
494#endif
495
496#if CONFIG_PICKIT2_SPI == 1
497 {
498 .name = "pickit2_spi",
499 .type = USB,
500 .devs.dev = devs_pickit2_spi,
501 .init = pickit2_spi_init,
502 .map_flash_region = fallback_map,
503 .unmap_flash_region = fallback_unmap,
504 .delay = internal_delay,
505 },
506#endif
507
508#if CONFIG_CH341A_SPI == 1
509 {
510 .name = "ch341a_spi",
511 .type = USB,
512 .devs.dev = devs_ch341a_spi,
513 .init = ch341a_spi_init,
514 .map_flash_region = fallback_map,
515 .unmap_flash_region = fallback_unmap,
516 .delay = ch341a_spi_delay,
517 },
518#endif
519
520#if CONFIG_DIGILENT_SPI == 1
521 {
522 .name = "digilent_spi",
523 .type = USB,
524 .devs.dev = devs_digilent_spi,
525 .init = digilent_spi_init,
526 .map_flash_region = fallback_map,
527 .unmap_flash_region = fallback_unmap,
528 .delay = internal_delay,
529 },
530#endif
531
532#if CONFIG_JLINK_SPI == 1
533 {
534 .name = "jlink_spi",
535 .type = OTHER,
536 .init = jlink_spi_init,
537 .devs.note = "SEGGER J-Link and compatible devices\n",
538 .map_flash_region = fallback_map,
539 .unmap_flash_region = fallback_unmap,
540 .delay = internal_delay,
541 },
542#endif
543
544#if CONFIG_NI845X_SPI == 1
545 {
546 .name = "ni845x_spi",
547 .type = OTHER, // choose other because NI-845x uses own USB implementation
548 .devs.note = "National Instruments USB-845x\n",
549 .init = ni845x_spi_init,
550 .map_flash_region = fallback_map,
551 .unmap_flash_region = fallback_unmap,
552 .delay = internal_delay,
553 },
554#endif
555
556#if CONFIG_STLINKV3_SPI == 1
557 {
558 .name = "stlinkv3_spi",
559 .type = USB,
560 .devs.dev = devs_stlinkv3_spi,
561 .init = stlinkv3_spi_init,
562 .map_flash_region = fallback_map,
563 .unmap_flash_region = fallback_unmap,
564 .delay = internal_delay,
565 },
566#endif
567
Edward O'Callaghand8f72232020-09-30 14:21:42 +1000568#if CONFIG_GOOGLE_EC == 1
569 {
570 .name = "google_ec",
571 .type = OTHER,
572 .devs.note = "Google EC.\n",
573 .init = cros_ec_probe_dev,
574 .map_flash_region = fallback_map,
575 .unmap_flash_region = fallback_unmap,
576 .delay = internal_delay,
577 },
578#endif
579
Edward O'Callaghanda29ca82020-10-20 00:49:47 +1100580#if CONFIG_CROS_ALIAS == 1
581 {
582 .name = "ec",
583 .type = OTHER,
584 .devs.note = "Google EC alias mechanism.\n",
585 .init = cros_ec_alias_init,
586 .map_flash_region = physmap, /* TODO(b/171934191) */
587 .unmap_flash_region = physunmap, /* TODO(b/171934191) */
588 .delay = internal_delay,
589
590 /*
591 * "ec" implies in-system programming on a live system, so
592 * handle with paranoia to catch errors early. If something goes
593 * wrong then hopefully the system will still be recoverable.
594 */
595 .paranoid = 1,
596 },
Edward O'Callaghan5b16a082020-10-20 16:30:16 +1100597
598 {
599 .name = "host",
600 .type = OTHER,
601 .devs.note = "Google host alias mechanism.\n",
602 .init = cros_host_alias_init,
603 .map_flash_region = physmap,
604 .unmap_flash_region = physunmap,
605 .delay = internal_delay,
606
607 /*
608 * "Internal" implies in-system programming on a live system, so
609 * handle with paranoia to catch errors early. If something goes
610 * wrong then hopefully the system will still be recoverable.
611 */
612 .paranoid = 1,
613 },
Edward O'Callaghanda29ca82020-10-20 00:49:47 +1100614#endif
615
Patrick Georgi8ddfee92017-03-20 14:54:28 +0100616 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
hailfingerabe249e2009-05-08 17:43:22 +0000617};
stepan927d4e22007-04-04 22:45:58 +0000618
David Hendricksbf36f092010-11-02 23:39:29 -0700619#define CHIP_RESTORE_MAXFN 4
620static int chip_restore_fn_count = 0;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000621static struct chip_restore_func_data {
David Hendricksbf36f092010-11-02 23:39:29 -0700622 CHIP_RESTORE_CALLBACK;
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700623 struct flashctx *flash;
David Hendricksbf36f092010-11-02 23:39:29 -0700624 uint8_t status;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000625} chip_restore_fn[CHIP_RESTORE_MAXFN];
David Hendricksbf36f092010-11-02 23:39:29 -0700626
David Hendricks668f29d2011-01-27 18:51:45 -0800627
hailfingerf31cbdc2010-11-10 15:25:18 +0000628#define SHUTDOWN_MAXFN 32
hailfingerdc6f7972010-02-14 01:20:28 +0000629static int shutdown_fn_count = 0;
Edward O'Callaghande8b7632020-09-11 14:33:57 +1000630/** @private */
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000631static struct shutdown_func_data {
David Hendricks93784b42016-08-09 17:00:38 -0700632 int (*func) (void *data);
hailfingerdc6f7972010-02-14 01:20:28 +0000633 void *data;
Edward O'Callaghan60df9dd2019-09-03 14:28:48 +1000634} shutdown_fn[SHUTDOWN_MAXFN];
hailfinger1ff33dc2010-07-03 11:02:10 +0000635/* Initialize to 0 to make sure nobody registers a shutdown function before
636 * programmer init.
637 */
638static int may_register_shutdown = 0;
hailfingerdc6f7972010-02-14 01:20:28 +0000639
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700640static int check_block_eraser(const struct flashctx *flash, int k, int log);
stefanct569dbb62011-07-01 00:19:12 +0000641
hailfingerdc6f7972010-02-14 01:20:28 +0000642/* Register a function to be executed on programmer shutdown.
643 * The advantage over atexit() is that you can supply a void pointer which will
644 * be used as parameter to the registered function upon programmer shutdown.
645 * This pointer can point to arbitrary data used by said function, e.g. undo
646 * information for GPIO settings etc. If unneeded, set data=NULL.
647 * Please note that the first (void *data) belongs to the function signature of
648 * the function passed as first parameter.
649 */
David Hendricks93784b42016-08-09 17:00:38 -0700650int register_shutdown(int (*function) (void *data), void *data)
hailfingerdc6f7972010-02-14 01:20:28 +0000651{
652 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
hailfinger63932d42010-06-04 23:20:21 +0000653 msg_perr("Tried to register more than %i shutdown functions.\n",
hailfingerdc6f7972010-02-14 01:20:28 +0000654 SHUTDOWN_MAXFN);
655 return 1;
656 }
hailfinger1ff33dc2010-07-03 11:02:10 +0000657 if (!may_register_shutdown) {
658 msg_perr("Tried to register a shutdown function before "
659 "programmer init.\n");
660 return 1;
661 }
hailfingerdc6f7972010-02-14 01:20:28 +0000662 shutdown_fn[shutdown_fn_count].func = function;
663 shutdown_fn[shutdown_fn_count].data = data;
664 shutdown_fn_count++;
665
666 return 0;
667}
668
David Hendricksbf36f092010-11-02 23:39:29 -0700669//int register_chip_restore(int (*function) (void *data), void *data)
670int register_chip_restore(CHIP_RESTORE_CALLBACK,
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700671 struct flashctx *flash, uint8_t status)
David Hendricksbf36f092010-11-02 23:39:29 -0700672{
673 if (chip_restore_fn_count >= CHIP_RESTORE_MAXFN) {
674 msg_perr("Tried to register more than %i chip restore"
675 " functions.\n", CHIP_RESTORE_MAXFN);
676 return 1;
677 }
678 chip_restore_fn[chip_restore_fn_count].func = func; /* from macro */
679 chip_restore_fn[chip_restore_fn_count].flash = flash;
680 chip_restore_fn[chip_restore_fn_count].status = status;
681 chip_restore_fn_count++;
682
683 return 0;
684}
685
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000686int programmer_init(enum programmer prog, const char *param)
uweabe92a52009-05-16 22:36:00 +0000687{
hailfinger1ef766d2010-07-06 09:55:48 +0000688 int ret;
hailfinger969e2f32011-09-08 00:00:29 +0000689
690 if (prog >= PROGRAMMER_INVALID) {
691 msg_perr("Invalid programmer specified!\n");
692 return -1;
693 }
694 programmer = prog;
hailfinger1ff33dc2010-07-03 11:02:10 +0000695 /* Initialize all programmer specific data. */
696 /* Default to unlimited decode sizes. */
697 max_rom_decode = (const struct decode_sizes) {
698 .parallel = 0xffffffff,
699 .lpc = 0xffffffff,
700 .fwh = 0xffffffff,
uwe8d342eb2011-07-28 08:13:25 +0000701 .spi = 0xffffffff,
hailfinger1ff33dc2010-07-03 11:02:10 +0000702 };
hailfinger1ff33dc2010-07-03 11:02:10 +0000703 /* Default to top aligned flash at 4 GB. */
704 flashbase = 0;
705 /* Registering shutdown functions is now allowed. */
706 may_register_shutdown = 1;
hailfinger5828baf2010-07-03 12:14:25 +0000707 /* Default to allowing writes. Broken programmers set this to 0. */
708 programmer_may_write = 1;
hailfinger1ff33dc2010-07-03 11:02:10 +0000709
710 programmer_param = param;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000711 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
David Hendricksac1d25c2016-08-09 17:00:58 -0700712 ret = programmer_table[programmer].init();
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000713 if (programmer_param && strlen(programmer_param)) {
714 if (ret != 0) {
715 /* It is quite possible that any unhandled programmer parameter would have been valid,
716 * but an error in actual programmer init happened before the parameter was evaluated.
717 */
718 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
719 programmer_param);
720 } else {
721 /* Actual programmer init was successful, but the user specified an invalid or unusable
722 * (for the current programmer configuration) parameter.
723 */
724 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
725 msg_perr("Aborting.\n");
726 ret = ERROR_FATAL;
727 }
728 }
hailfinger1ef766d2010-07-06 09:55:48 +0000729 return ret;
uweabe92a52009-05-16 22:36:00 +0000730}
731
David Hendricksbf36f092010-11-02 23:39:29 -0700732int chip_restore()
733{
734 int rc = 0;
735
736 while (chip_restore_fn_count > 0) {
737 int i = --chip_restore_fn_count;
738 rc |= chip_restore_fn[i].func(chip_restore_fn[i].flash,
739 chip_restore_fn[i].status);
740 }
741
742 return rc;
743}
744
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +1000745/** Calls registered shutdown functions and resets internal programmer-related variables.
746 * Calling it is safe even without previous initialization, but further interactions with programmer support
747 * require a call to programmer_init() (afterwards).
748 *
749 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
David Hendricks93784b42016-08-09 17:00:38 -0700750int programmer_shutdown(void)
uweabe92a52009-05-16 22:36:00 +0000751{
dhendrix0ffc2eb2011-06-14 01:35:36 +0000752 int ret = 0;
753
hailfinger1ff33dc2010-07-03 11:02:10 +0000754 /* Registering shutdown functions is no longer allowed. */
755 may_register_shutdown = 0;
756 while (shutdown_fn_count > 0) {
757 int i = --shutdown_fn_count;
David Hendricks93784b42016-08-09 17:00:38 -0700758 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
hailfinger1ff33dc2010-07-03 11:02:10 +0000759 }
Edward O'Callaghancf9c40f2020-10-19 20:02:39 +1100760
761 programmer_param = NULL;
762 registered_master_count = 0;
763
dhendrix0ffc2eb2011-06-14 01:35:36 +0000764 return ret;
uweabe92a52009-05-16 22:36:00 +0000765}
766
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000767void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
uweabe92a52009-05-16 22:36:00 +0000768{
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000769 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
770 return ret;
uweabe92a52009-05-16 22:36:00 +0000771}
772
773void programmer_unmap_flash_region(void *virt_addr, size_t len)
774{
775 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Edward O'Callaghan79357b32020-08-02 01:24:58 +1000776 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
uweabe92a52009-05-16 22:36:00 +0000777}
778
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700779void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000780{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100781 flash->mst->par.chip_writeb(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000782}
783
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700784void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000785{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100786 flash->mst->par.chip_writew(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000787}
788
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700789void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000790{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100791 flash->mst->par.chip_writel(flash, val, addr);
uweabe92a52009-05-16 22:36:00 +0000792}
793
Stuart langleyc98e43f2020-03-26 20:27:36 +1100794void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000795{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100796 flash->mst->par.chip_writen(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000797}
798
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700799uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000800{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100801 return flash->mst->par.chip_readb(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000802}
803
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700804uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000805{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100806 return flash->mst->par.chip_readw(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000807}
808
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700809uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
uweabe92a52009-05-16 22:36:00 +0000810{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100811 return flash->mst->par.chip_readl(flash, addr);
uweabe92a52009-05-16 22:36:00 +0000812}
813
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000814void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
815 size_t len)
hailfinger9d987ef2009-06-05 18:32:07 +0000816{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +1100817 flash->mst->par.chip_readn(flash, buf, addr, len);
hailfinger9d987ef2009-06-05 18:32:07 +0000818}
819
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000820void programmer_delay(unsigned int usecs)
hailfingere5829f62009-06-05 17:48:08 +0000821{
Urja Rannikko71cc94f2013-10-21 21:49:08 +0000822 if (usecs > 0)
823 programmer_table[programmer].delay(usecs);
hailfingere5829f62009-06-05 17:48:08 +0000824}
825
Edward O'Callaghana820b212020-09-17 22:53:26 +1000826int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
827 int unsigned len)
hailfinger23060112009-05-08 12:49:03 +0000828{
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700829 chip_readn(flash, buf, flash->virtual_memory + start, len);
uwe8d342eb2011-07-28 08:13:25 +0000830
hailfinger23060112009-05-08 12:49:03 +0000831 return 0;
832}
833
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000834/* This is a somewhat hacked function similar in some ways to strtok().
835 * It will look for needle with a subsequent '=' in haystack, return a copy of
836 * needle and remove everything from the first occurrence of needle to the next
837 * delimiter from haystack.
hailfinger6e5a52a2009-11-24 18:27:10 +0000838 */
Edward O'Callaghanc4d1f1c2020-04-17 13:27:23 +1000839char *extract_param(const char *const *haystack, const char *needle, const char *delim)
hailfinger6e5a52a2009-11-24 18:27:10 +0000840{
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000841 char *param_pos, *opt_pos, *rest;
hailfinger1ef766d2010-07-06 09:55:48 +0000842 char *opt = NULL;
843 int optlen;
hailfingerf4aaccc2010-04-28 15:22:14 +0000844 int needlelen;
hailfinger6e5a52a2009-11-24 18:27:10 +0000845
hailfingerf4aaccc2010-04-28 15:22:14 +0000846 needlelen = strlen(needle);
847 if (!needlelen) {
848 msg_gerr("%s: empty needle! Please report a bug at "
849 "flashrom@flashrom.org\n", __func__);
850 return NULL;
851 }
852 /* No programmer parameters given. */
853 if (*haystack == NULL)
854 return NULL;
hailfinger6e5a52a2009-11-24 18:27:10 +0000855 param_pos = strstr(*haystack, needle);
856 do {
857 if (!param_pos)
858 return NULL;
hailfinger1ef766d2010-07-06 09:55:48 +0000859 /* Needle followed by '='? */
860 if (param_pos[needlelen] == '=') {
hailfinger1ef766d2010-07-06 09:55:48 +0000861 /* Beginning of the string? */
862 if (param_pos == *haystack)
863 break;
864 /* After a delimiter? */
865 if (strchr(delim, *(param_pos - 1)))
866 break;
867 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000868 /* Continue searching. */
869 param_pos++;
870 param_pos = strstr(param_pos, needle);
871 } while (1);
uwe8d342eb2011-07-28 08:13:25 +0000872
hailfinger6e5a52a2009-11-24 18:27:10 +0000873 if (param_pos) {
hailfinger1ef766d2010-07-06 09:55:48 +0000874 /* Get the string after needle and '='. */
875 opt_pos = param_pos + needlelen + 1;
876 optlen = strcspn(opt_pos, delim);
877 /* Return an empty string if the parameter was empty. */
878 opt = malloc(optlen + 1);
879 if (!opt) {
snelsone42c3802010-05-07 20:09:04 +0000880 msg_gerr("Out of memory!\n");
hailfinger6e5a52a2009-11-24 18:27:10 +0000881 exit(1);
882 }
hailfinger1ef766d2010-07-06 09:55:48 +0000883 strncpy(opt, opt_pos, optlen);
884 opt[optlen] = '\0';
Nikolai Artemiev7d9c8ff2020-08-31 14:42:59 +1000885 rest = opt_pos + optlen;
886 /* Skip all delimiters after the current parameter. */
887 rest += strspn(rest, delim);
888 memmove(param_pos, rest, strlen(rest) + 1);
889 /* We could shrink haystack, but the effort is not worth it. */
hailfinger6e5a52a2009-11-24 18:27:10 +0000890 }
hailfinger6e5a52a2009-11-24 18:27:10 +0000891
hailfinger1ef766d2010-07-06 09:55:48 +0000892 return opt;
hailfinger6e5a52a2009-11-24 18:27:10 +0000893}
894
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +1000895char *extract_programmer_param(const char *param_name)
hailfingerddeb4ac2010-07-08 10:13:37 +0000896{
897 return extract_param(&programmer_param, param_name, ",");
898}
899
stefancte1c5acf2011-07-04 07:27:17 +0000900/* Returns the number of well-defined erasers for a chip. */
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700901static unsigned int count_usable_erasers(const struct flashctx *flash)
stefanct569dbb62011-07-01 00:19:12 +0000902{
903 unsigned int usable_erasefunctions = 0;
904 int k;
905 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
906 if (!check_block_eraser(flash, k, 0))
907 usable_erasefunctions++;
908 }
909 return usable_erasefunctions;
910}
911
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000912static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Simon Glass4e305f42015-01-08 06:29:04 -0700913{
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000914 int ret = 0, failcount = 0;
915 unsigned int i;
Simon Glass4e305f42015-01-08 06:29:04 -0700916 for (i = 0; i < len; i++) {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000917 if (wantbuf[i] != havebuf[i]) {
918 /* Only print the first failure. */
919 if (!failcount++)
920 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
921 start + i, wantbuf[i], havebuf[i]);
Simon Glass4e305f42015-01-08 06:29:04 -0700922 }
923 }
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000924 if (failcount) {
925 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
926 start, start + len - 1, failcount);
927 ret = -1;
928 }
929 return ret;
Simon Glass4e305f42015-01-08 06:29:04 -0700930}
931
Edward O'Callaghanfcd4b412020-08-19 14:44:44 +1000932/* start is an offset to the base address of the flash chip */
933static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
934{
935 int ret;
936 uint8_t *cmpbuf = malloc(len);
937 const uint8_t erased_value = ERASED_VALUE(flash);
938
939 if (!cmpbuf) {
940 msg_gerr("Could not allocate memory!\n");
941 exit(1);
942 }
943 memset(cmpbuf, erased_value, len);
944 ret = verify_range(flash, cmpbuf, start, len);
945 free(cmpbuf);
946 return ret;
947}
948
uwee15beb92010-08-08 17:01:18 +0000949/*
hailfinger7af3d192009-11-25 17:05:52 +0000950 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
uwe8d342eb2011-07-28 08:13:25 +0000951 * flash content at location start
hailfinger7af83692009-06-15 17:23:36 +0000952 * @start offset to the base address of the flash chip
953 * @len length of the verified area
hailfinger7af83692009-06-15 17:23:36 +0000954 * @return 0 for success, -1 for failure
955 */
Edward O'Callaghan445b48b2020-08-13 12:25:17 +1000956int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
hailfinger7af83692009-06-15 17:23:36 +0000957{
hailfinger7af83692009-06-15 17:23:36 +0000958 if (!len)
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000959 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000960
Patrick Georgif3fa2992017-02-02 16:24:44 +0100961 if (!flash->chip->read) {
snelsone42c3802010-05-07 20:09:04 +0000962 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000963 return -1;
hailfingerb0f4d122009-06-24 08:20:45 +0000964 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000965
966 uint8_t *readbuf = malloc(len);
hailfinger7af83692009-06-15 17:23:36 +0000967 if (!readbuf) {
snelsone42c3802010-05-07 20:09:04 +0000968 msg_gerr("Could not allocate memory!\n");
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000969 return -1;
hailfinger7af83692009-06-15 17:23:36 +0000970 }
Edward O'Callaghan2bd87622020-08-13 13:58:45 +1000971 int ret = 0, failcount = 0;
hailfinger7af83692009-06-15 17:23:36 +0000972
Patrick Georgif3fa2992017-02-02 16:24:44 +0100973 if (start + len > flash->chip->total_size * 1024) {
snelsone42c3802010-05-07 20:09:04 +0000974 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
hailfinger7af83692009-06-15 17:23:36 +0000975 " total_size 0x%x\n", __func__, start, len,
Patrick Georgif3fa2992017-02-02 16:24:44 +0100976 flash->chip->total_size * 1024);
hailfinger7af83692009-06-15 17:23:36 +0000977 ret = -1;
978 goto out_free;
979 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -0700980 msg_gdbg("%#06x..%#06x ", start, start + len -1);
Simon Glass4e305f42015-01-08 06:29:04 -0700981 if (programmer_table[programmer].paranoid) {
982 unsigned int i, chunksize;
David Hendricks1ed1d352011-11-23 17:54:37 -0800983
Simon Glass4e305f42015-01-08 06:29:04 -0700984 /* limit chunksize in order to catch errors early */
985 for (i = 0, chunksize = 0; i < len; i += chunksize) {
986 int tmp;
David Hendricks1ed1d352011-11-23 17:54:37 -0800987
Patrick Georgif3fa2992017-02-02 16:24:44 +0100988 chunksize = min(flash->chip->page_size, len - i);
989 tmp = flash->chip->read(flash, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -0700990 if (tmp) {
991 ret = tmp;
992 if (ignore_error(tmp))
993 continue;
994 else
995 goto out_free;
David Hendricks1ed1d352011-11-23 17:54:37 -0800996 }
Simon Glass4e305f42015-01-08 06:29:04 -0700997
Duncan Laurie25a4ca22019-04-25 12:08:52 -0700998 /*
999 * Check write access permission and do not compare chunks
1000 * where flashrom does not have write access to the region.
1001 */
1002 if (flash->chip->check_access) {
1003 tmp = flash->chip->check_access(flash, start + i, chunksize, 0);
1004 if (tmp && ignore_error(tmp))
1005 continue;
1006 }
1007
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001008 failcount = compare_range(cmpbuf + i, readbuf + i, start + i, chunksize);
Simon Glass4e305f42015-01-08 06:29:04 -07001009 if (failcount)
1010 break;
David Hendricks1ed1d352011-11-23 17:54:37 -08001011 }
Simon Glass4e305f42015-01-08 06:29:04 -07001012 } else {
1013 int tmp;
1014
1015 /* read as much as we can to reduce transaction overhead */
Patrick Georgif3fa2992017-02-02 16:24:44 +01001016 tmp = flash->chip->read(flash, readbuf, start, len);
Simon Glass4e305f42015-01-08 06:29:04 -07001017 if (tmp && !ignore_error(tmp)) {
1018 ret = tmp;
1019 goto out_free;
1020 }
1021
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001022 failcount = compare_range(cmpbuf, readbuf, start, len);
hailfinger8cb6ece2010-11-16 17:21:58 +00001023 }
1024
hailfinger5be6c0f2009-07-23 01:42:56 +00001025 if (failcount) {
snelsone42c3802010-05-07 20:09:04 +00001026 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
uwe8d342eb2011-07-28 08:13:25 +00001027 start, start + len - 1, failcount);
hailfinger5be6c0f2009-07-23 01:42:56 +00001028 ret = -1;
1029 }
hailfinger7af83692009-06-15 17:23:36 +00001030
1031out_free:
1032 free(readbuf);
1033 return ret;
1034}
1035
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001036/* Helper function for need_erase() that focuses on granularities of gran bytes. */
1037static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001038 unsigned int gran, const uint8_t erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001039{
1040 unsigned int i, j, limit;
1041 for (j = 0; j < len / gran; j++) {
1042 limit = min (gran, len - j * gran);
1043 /* Are 'have' and 'want' identical? */
1044 if (!memcmp(have + j * gran, want + j * gran, limit))
1045 continue;
1046 /* have needs to be in erased state. */
1047 for (i = 0; i < limit; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001048 if (have[j * gran + i] != erased_value)
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001049 return 1;
1050 }
1051 return 0;
1052}
1053
uwee15beb92010-08-08 17:01:18 +00001054/*
hailfingerb247c7a2010-03-08 00:42:32 +00001055 * Check if the buffer @have can be programmed to the content of @want without
1056 * erasing. This is only possible if all chunks of size @gran are either kept
1057 * as-is or changed from an all-ones state to any other state.
hailfingerb437e282010-11-04 01:04:27 +00001058 *
hailfingerb437e282010-11-04 01:04:27 +00001059 * Warning: This function assumes that @have and @want point to naturally
1060 * aligned regions.
hailfingerb247c7a2010-03-08 00:42:32 +00001061 *
1062 * @have buffer with current content
1063 * @want buffer with desired content
hailfingerb437e282010-11-04 01:04:27 +00001064 * @len length of the checked area
hailfingerb247c7a2010-03-08 00:42:32 +00001065 * @gran write granularity (enum, not count)
1066 * @return 0 if no erase is needed, 1 otherwise
1067 */
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001068int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
1069 enum write_granularity gran, const uint8_t erased_value)
hailfingerb247c7a2010-03-08 00:42:32 +00001070{
hailfingerb91c08c2011-08-15 19:54:20 +00001071 int result = 0;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001072 unsigned int i;
William A. Kennington IIIf15c2fa2017-04-07 17:38:42 -07001073
hailfingerb247c7a2010-03-08 00:42:32 +00001074 switch (gran) {
1075 case write_gran_1bit:
1076 for (i = 0; i < len; i++)
1077 if ((have[i] & want[i]) != want[i]) {
1078 result = 1;
1079 break;
1080 }
1081 break;
1082 case write_gran_1byte:
1083 for (i = 0; i < len; i++)
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001084 if ((have[i] != want[i]) && (have[i] != erased_value)) {
hailfingerb247c7a2010-03-08 00:42:32 +00001085 result = 1;
1086 break;
1087 }
1088 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001089 case write_gran_128bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001090 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001091 break;
hailfingerb247c7a2010-03-08 00:42:32 +00001092 case write_gran_256bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001093 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001094 break;
1095 case write_gran_264bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001096 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001097 break;
1098 case write_gran_512bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001099 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001100 break;
1101 case write_gran_528bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001102 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001103 break;
1104 case write_gran_1024bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001105 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001106 break;
1107 case write_gran_1056bytes:
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001108 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001109 break;
1110 case write_gran_1byte_implicit_erase:
1111 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
1112 result = 0;
hailfingerb247c7a2010-03-08 00:42:32 +00001113 break;
hailfingerb437e282010-11-04 01:04:27 +00001114 default:
1115 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1116 "flashrom@flashrom.org\n", __func__);
hailfingerb247c7a2010-03-08 00:42:32 +00001117 }
1118 return result;
1119}
1120
hailfingerb437e282010-11-04 01:04:27 +00001121/**
1122 * Check if the buffer @have needs to be programmed to get the content of @want.
1123 * If yes, return 1 and fill in first_start with the start address of the
1124 * write operation and first_len with the length of the first to-be-written
1125 * chunk. If not, return 0 and leave first_start and first_len undefined.
1126 *
1127 * Warning: This function assumes that @have and @want point to naturally
1128 * aligned regions.
1129 *
1130 * @have buffer with current content
1131 * @want buffer with desired content
1132 * @len length of the checked area
1133 * @gran write granularity (enum, not count)
hailfinger90fcf9b2010-11-05 14:51:59 +00001134 * @first_start offset of the first byte which needs to be written (passed in
1135 * value is increased by the offset of the first needed write
1136 * relative to have/want or unchanged if no write is needed)
1137 * @return length of the first contiguous area which needs to be written
1138 * 0 if no write is needed
hailfingerb437e282010-11-04 01:04:27 +00001139 *
1140 * FIXME: This function needs a parameter which tells it about coalescing
1141 * in relation to the max write length of the programmer and the max write
1142 * length of the chip.
1143 */
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001144static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
stefanctc5eb8a92011-11-23 09:13:48 +00001145 unsigned int *first_start,
1146 enum write_granularity gran)
hailfingerb437e282010-11-04 01:04:27 +00001147{
stefanctc5eb8a92011-11-23 09:13:48 +00001148 int need_write = 0;
1149 unsigned int rel_start = 0, first_len = 0;
1150 unsigned int i, limit, stride;
hailfingerb437e282010-11-04 01:04:27 +00001151
hailfingerb437e282010-11-04 01:04:27 +00001152 switch (gran) {
1153 case write_gran_1bit:
1154 case write_gran_1byte:
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001155 case write_gran_1byte_implicit_erase:
hailfinger90fcf9b2010-11-05 14:51:59 +00001156 stride = 1;
hailfingerb437e282010-11-04 01:04:27 +00001157 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001158 case write_gran_128bytes:
1159 stride = 128;
1160 break;
hailfingerb437e282010-11-04 01:04:27 +00001161 case write_gran_256bytes:
hailfinger90fcf9b2010-11-05 14:51:59 +00001162 stride = 256;
hailfingerb437e282010-11-04 01:04:27 +00001163 break;
Edward O'Callaghand8eca562019-02-24 21:10:33 +11001164 case write_gran_264bytes:
1165 stride = 264;
1166 break;
1167 case write_gran_512bytes:
1168 stride = 512;
1169 break;
1170 case write_gran_528bytes:
1171 stride = 528;
1172 break;
1173 case write_gran_1024bytes:
1174 stride = 1024;
1175 break;
1176 case write_gran_1056bytes:
1177 stride = 1056;
1178 break;
hailfingerb437e282010-11-04 01:04:27 +00001179 default:
1180 msg_cerr("%s: Unsupported granularity! Please report a bug at "
1181 "flashrom@flashrom.org\n", __func__);
hailfinger90fcf9b2010-11-05 14:51:59 +00001182 /* Claim that no write was needed. A write with unknown
1183 * granularity is too dangerous to try.
1184 */
1185 return 0;
hailfingerb437e282010-11-04 01:04:27 +00001186 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001187 for (i = 0; i < len / stride; i++) {
1188 limit = min(stride, len - i * stride);
1189 /* Are 'have' and 'want' identical? */
1190 if (memcmp(have + i * stride, want + i * stride, limit)) {
1191 if (!need_write) {
1192 /* First location where have and want differ. */
1193 need_write = 1;
1194 rel_start = i * stride;
1195 }
1196 } else {
1197 if (need_write) {
1198 /* First location where have and want
1199 * do not differ anymore.
1200 */
hailfinger90fcf9b2010-11-05 14:51:59 +00001201 break;
1202 }
1203 }
1204 }
hailfingerffb7f382010-12-06 13:05:44 +00001205 if (need_write)
hailfinger90fcf9b2010-11-05 14:51:59 +00001206 first_len = min(i * stride - rel_start, len);
hailfingerb437e282010-11-04 01:04:27 +00001207 *first_start += rel_start;
hailfinger90fcf9b2010-11-05 14:51:59 +00001208 return first_len;
hailfingerb437e282010-11-04 01:04:27 +00001209}
1210
hailfinger0c515352009-11-23 12:55:31 +00001211/* This function generates various test patterns useful for testing controller
1212 * and chip communication as well as chip behaviour.
1213 *
1214 * If a byte can be written multiple times, each time keeping 0-bits at 0
1215 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
1216 * is essentially an AND operation. That's also the reason why this function
1217 * provides the result of AND between various patterns.
1218 *
1219 * Below is a list of patterns (and their block length).
1220 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
1221 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
1222 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
1223 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
1224 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
1225 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
1226 * Pattern 6 is 00 (1 Byte)
1227 * Pattern 7 is ff (1 Byte)
1228 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
1229 * byte block.
1230 *
1231 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
1232 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
1233 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
1234 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
1235 * Pattern 12 is 00 (1 Byte)
1236 * Pattern 13 is ff (1 Byte)
1237 * Patterns 8-13 have no block number.
1238 *
1239 * Patterns 0-3 are created to detect and efficiently diagnose communication
1240 * slips like missed bits or bytes and their repetitive nature gives good visual
1241 * cues to the person inspecting the results. In addition, the following holds:
1242 * AND Pattern 0/1 == Pattern 4
1243 * AND Pattern 2/3 == Pattern 5
1244 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
1245 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
1246 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
1247 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
1248 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
1249 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
1250 * Besides that, they provide for bit testing of the last two bytes of every
1251 * 256 byte block which contains the block number for patterns 0-6.
1252 * Patterns 10-11 are special purpose for detecting subblock aliasing with
1253 * block sizes >256 bytes (some Dataflash chips etc.)
1254 * AND Pattern 8/9 == Pattern 12
1255 * AND Pattern 10/11 == Pattern 12
1256 * Pattern 13 is the completely erased state.
1257 * None of the patterns can detect aliasing at boundaries which are a multiple
1258 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
1259 */
1260int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
1261{
1262 int i;
1263
1264 if (!buf) {
snelsone42c3802010-05-07 20:09:04 +00001265 msg_gerr("Invalid buffer!\n");
hailfinger0c515352009-11-23 12:55:31 +00001266 return 1;
1267 }
1268
1269 switch (variant) {
1270 case 0:
1271 for (i = 0; i < size; i++)
1272 buf[i] = (i & 0xf) << 4 | 0x5;
1273 break;
1274 case 1:
1275 for (i = 0; i < size; i++)
1276 buf[i] = (i & 0xf) << 4 | 0xa;
1277 break;
1278 case 2:
1279 for (i = 0; i < size; i++)
1280 buf[i] = 0x50 | (i & 0xf);
1281 break;
1282 case 3:
1283 for (i = 0; i < size; i++)
1284 buf[i] = 0xa0 | (i & 0xf);
1285 break;
1286 case 4:
1287 for (i = 0; i < size; i++)
1288 buf[i] = (i & 0xf) << 4;
1289 break;
1290 case 5:
1291 for (i = 0; i < size; i++)
1292 buf[i] = i & 0xf;
1293 break;
1294 case 6:
1295 memset(buf, 0x00, size);
1296 break;
1297 case 7:
1298 memset(buf, 0xff, size);
1299 break;
1300 case 8:
1301 for (i = 0; i < size; i++)
1302 buf[i] = i & 0xff;
1303 break;
1304 case 9:
1305 for (i = 0; i < size; i++)
1306 buf[i] = ~(i & 0xff);
1307 break;
1308 case 10:
1309 for (i = 0; i < size % 2; i++) {
1310 buf[i * 2] = (i >> 8) & 0xff;
1311 buf[i * 2 + 1] = i & 0xff;
1312 }
1313 if (size & 0x1)
1314 buf[i * 2] = (i >> 8) & 0xff;
1315 break;
1316 case 11:
1317 for (i = 0; i < size % 2; i++) {
1318 buf[i * 2] = ~((i >> 8) & 0xff);
1319 buf[i * 2 + 1] = ~(i & 0xff);
1320 }
1321 if (size & 0x1)
1322 buf[i * 2] = ~((i >> 8) & 0xff);
1323 break;
1324 case 12:
1325 memset(buf, 0x00, size);
1326 break;
1327 case 13:
1328 memset(buf, 0xff, size);
1329 break;
1330 }
1331
1332 if ((variant >= 0) && (variant <= 7)) {
1333 /* Write block number in the last two bytes of each 256-byte
1334 * block, big endian for easier reading of the hexdump.
1335 * Note that this wraps around for chips larger than 2^24 bytes
1336 * (16 MB).
1337 */
1338 for (i = 0; i < size / 256; i++) {
1339 buf[i * 256 + 254] = (i >> 8) & 0xff;
1340 buf[i * 256 + 255] = i & 0xff;
1341 }
1342 }
1343
1344 return 0;
1345}
1346
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001347/* Returns the number of busses commonly supported by the current programmer and flash chip where the latter
1348 * can not be completely accessed due to size/address limits of the programmer. */
1349unsigned int count_max_decode_exceedings(const struct flashctx *flash)
hailfingeraec9c962009-10-31 01:53:09 +00001350{
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001351 unsigned int limitexceeded = 0;
1352 uint32_t size = flash->chip->total_size * 1024;
1353 enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
uwe8d342eb2011-07-28 08:13:25 +00001354
1355 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001356 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001357 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001358 "size %u kB of chipset/board/programmer "
1359 "for %s interface, "
1360 "probe/read/erase/write may fail. ", size / 1024,
1361 max_rom_decode.parallel / 1024, "Parallel");
hailfingeraec9c962009-10-31 01:53:09 +00001362 }
hailfingere1e41ea2011-07-27 07:13:06 +00001363 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001364 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001365 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001366 "size %u kB of chipset/board/programmer "
1367 "for %s interface, "
1368 "probe/read/erase/write may fail. ", size / 1024,
1369 max_rom_decode.lpc / 1024, "LPC");
hailfingeraec9c962009-10-31 01:53:09 +00001370 }
hailfingere1e41ea2011-07-27 07:13:06 +00001371 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001372 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001373 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001374 "size %u kB of chipset/board/programmer "
1375 "for %s interface, "
1376 "probe/read/erase/write may fail. ", size / 1024,
1377 max_rom_decode.fwh / 1024, "FWH");
hailfingeraec9c962009-10-31 01:53:09 +00001378 }
hailfingere1e41ea2011-07-27 07:13:06 +00001379 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
hailfingeraec9c962009-10-31 01:53:09 +00001380 limitexceeded++;
snelsone42c3802010-05-07 20:09:04 +00001381 msg_pdbg("Chip size %u kB is bigger than supported "
uwe8d342eb2011-07-28 08:13:25 +00001382 "size %u kB of chipset/board/programmer "
1383 "for %s interface, "
1384 "probe/read/erase/write may fail. ", size / 1024,
1385 max_rom_decode.spi / 1024, "SPI");
hailfingeraec9c962009-10-31 01:53:09 +00001386 }
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001387 return limitexceeded;
hailfingeraec9c962009-10-31 01:53:09 +00001388}
1389
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001390void unmap_flash(struct flashctx *flash)
1391{
1392 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1393 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1394 flash->physical_registers = 0;
1395 flash->virtual_registers = (chipaddr)ERROR_PTR;
1396 }
1397
1398 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1399 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1400 flash->physical_memory = 0;
1401 flash->virtual_memory = (chipaddr)ERROR_PTR;
1402 }
1403}
1404
1405int map_flash(struct flashctx *flash)
1406{
1407 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1408 flash->virtual_memory = (chipaddr)ERROR_PTR;
1409 flash->virtual_registers = (chipaddr)ERROR_PTR;
1410
1411 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1412 * These are used for various probing-related hacks that would not map successfully anyway and should be
1413 * removed ASAP. */
1414 if (flash->chip->total_size == 0)
1415 return 0;
1416
1417 const chipsize_t size = flash->chip->total_size * 1024;
1418 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1419 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1420 if (addr == ERROR_PTR) {
1421 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1422 flash->chip->name, PRIxPTR_WIDTH, base);
1423 return 1;
1424 }
1425 flash->physical_memory = base;
1426 flash->virtual_memory = (chipaddr)addr;
1427
1428 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1429 * completely different on some chips and programmers, or not mappable at all.
1430 * Ignore these problems for now and always report success. */
1431 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1432 base = 0xffffffff - size - 0x400000 + 1;
1433 addr = programmer_map_flash_region("flash chip registers", base, size);
1434 if (addr == ERROR_PTR) {
1435 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1436 flash->chip->name, PRIxPTR_WIDTH, base);
1437 return 0;
1438 }
1439 flash->physical_registers = base;
1440 flash->virtual_registers = (chipaddr)addr;
1441 }
1442 return 0;
1443}
1444
Edward O'Callaghan8488f122019-06-17 12:38:15 +10001445/*
1446 * Return a string corresponding to the bustype parameter.
1447 * Memory is obtained with malloc() and must be freed with free() by the caller.
1448 */
1449char *flashbuses_to_text(enum chipbustype bustype)
1450{
1451 char *ret = calloc(1, 1);
1452 /*
1453 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1454 * will cease to exist and should be eliminated here as well.
1455 */
1456 if (bustype == BUS_NONSPI) {
1457 ret = strcat_realloc(ret, "Non-SPI, ");
1458 } else {
1459 if (bustype & BUS_PARALLEL)
1460 ret = strcat_realloc(ret, "Parallel, ");
1461 if (bustype & BUS_LPC)
1462 ret = strcat_realloc(ret, "LPC, ");
1463 if (bustype & BUS_FWH)
1464 ret = strcat_realloc(ret, "FWH, ");
1465 if (bustype & BUS_SPI)
1466 ret = strcat_realloc(ret, "SPI, ");
1467 if (bustype & BUS_PROG)
1468 ret = strcat_realloc(ret, "Programmer-specific, ");
1469 if (bustype == BUS_NONE)
1470 ret = strcat_realloc(ret, "None, ");
1471 }
1472 /* Kill last comma. */
1473 ret[strlen(ret) - 2] = '\0';
1474 ret = realloc(ret, strlen(ret) + 1);
1475 return ret;
1476}
1477
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001478int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
rminnich8d3ff912003-10-25 17:01:29 +00001479{
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001480 const struct flashchip *chip, *flash_list;
hailfingeraec9c962009-10-31 01:53:09 +00001481 enum chipbustype buses_common;
hailfingera916b422009-06-01 02:08:58 +00001482 char *tmp;
rminnich8d3ff912003-10-25 17:01:29 +00001483
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301484 /* Based on the host controller interface that a platform
1485 * needs to use (hwseq or swseq),
1486 * set the flashchips list here.
1487 */
Edward O'Callaghane3e30562019-09-03 13:10:58 +10001488 switch (g_ich_generation) {
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301489 case CHIPSET_100_SERIES_SUNRISE_POINT:
Edward O'Callaghan272b27c2020-05-26 17:06:04 +10001490 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumare6a7ca82015-05-12 14:27:29 +05301491 flash_list = flashchips_hwseq;
1492 break;
1493 default:
1494 flash_list = flashchips;
1495 break;
1496 }
1497
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001498 for (chip = flash_list + startchip; chip && chip->name; chip++) {
1499 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
ollie5672ac62004-03-17 22:22:08 +00001500 continue;
Edward O'Callaghanc66827e2020-10-09 12:22:04 +11001501 buses_common = mst->buses_supported & chip->bustype;
Edward O'Callaghan4b940572019-08-02 01:44:47 +10001502 if (!buses_common)
hailfinger18bd4cc2011-06-17 22:38:53 +00001503 continue;
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001504 /* Only probe for SPI25 chips by default. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001505 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
Edward O'Callaghancc1d0c92019-02-24 15:35:07 +11001506 continue;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001507 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001508 if (!chip->probe && !force) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001509 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
hailfingera916b422009-06-01 02:08:58 +00001510 continue;
1511 }
stepan782fb172007-04-06 11:58:03 +00001512
hailfinger48ed3e22011-05-04 00:39:50 +00001513 /* Start filling in the dynamic data. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001514 flash->chip = calloc(1, sizeof(struct flashchip));
1515 if (!flash->chip) {
Patrick Georgif3fa2992017-02-02 16:24:44 +01001516 msg_gerr("Out of memory!\n");
1517 exit(1);
1518 }
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001519 memcpy(flash->chip, chip, sizeof(struct flashchip));
1520 flash->mst = mst;
hailfinger48ed3e22011-05-04 00:39:50 +00001521
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001522 if (map_flash(flash) != 0)
1523 goto notfound;
rminnich8d3ff912003-10-25 17:01:29 +00001524
Edward O'Callaghana820b212020-09-17 22:53:26 +10001525 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1526 * is only called with force=1 after normal probing failed.
1527 */
stugec1e55fe2008-07-02 17:15:47 +00001528 if (force)
1529 break;
stepanc98b80b2006-03-16 16:57:41 +00001530
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001531 if (flash->chip->probe(flash) != 1)
stuge56300c32008-09-03 23:10:05 +00001532 goto notfound;
1533
hailfinger48ed3e22011-05-04 00:39:50 +00001534 /* If this is the first chip found, accept it.
1535 * If this is not the first chip found, accept it only if it is
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001536 * a non-generic match. SFDP and CFI are generic matches.
1537 * startchip==0 means this call to probe_flash() is the first
1538 * one for this programmer interface (master) and thus no other chip has
1539 * been found on this interface.
hailfinger48ed3e22011-05-04 00:39:50 +00001540 */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001541 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
1542 msg_cinfo("===\n"
1543 "SFDP has autodetected a flash chip which is "
1544 "not natively supported by flashrom yet.\n");
1545 if (count_usable_erasers(flash) == 0)
1546 msg_cinfo("The standard operations read and "
1547 "verify should work, but to support "
1548 "erase, write and all other "
1549 "possible features");
1550 else
1551 msg_cinfo("All standard operations (read, "
1552 "verify, erase and write) should "
1553 "work, but to support all possible "
1554 "features");
1555
1556 msg_cinfo(" we need to add them manually.\n"
1557 "You can help us by mailing us the output of the following command to "
1558 "flashrom@flashrom.org:\n"
1559 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1560 "Thanks for your help!\n"
1561 "===\n");
1562 }
stugec1e55fe2008-07-02 17:15:47 +00001563
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001564 /* First flash chip detected on this bus. */
1565 if (startchip == 0)
1566 break;
1567 /* Not the first flash chip detected on this bus, but not a generic match either. */
Edward O'Callaghaneb022ec2020-09-24 22:39:00 +10001568 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
Edward O'Callaghand0fdcb62020-09-24 22:38:44 +10001569 break;
1570 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
stuge56300c32008-09-03 23:10:05 +00001571notfound:
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001572 unmap_flash(flash);
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001573 free(flash->chip);
1574 flash->chip = NULL;
rminnich8d3ff912003-10-25 17:01:29 +00001575 }
uwebe4477b2007-08-23 16:08:21 +00001576
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001577 if (!chip || !chip->name)
hailfinger48ed3e22011-05-04 00:39:50 +00001578 return -1;
stugec1e55fe2008-07-02 17:15:47 +00001579
stepan3e7aeae2011-01-19 06:21:54 +00001580
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001581 tmp = flashbuses_to_text(chip->bustype);
Edward O'Callaghana820b212020-09-17 22:53:26 +10001582 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1583 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
stefanct588b6d22011-06-26 20:45:35 +00001584 free(tmp);
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001585#if CONFIG_INTERNAL == 1
1586 if (programmer_table[programmer].map_flash_region == physmap)
1587 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1588 PRIxPTR_WIDTH, flash->physical_memory);
1589 else
1590#endif
1591 msg_cinfo("on %s.\n", programmer_table[programmer].name);
uwe9e6811e2009-06-28 21:47:57 +00001592
Edward O'Callaghana820b212020-09-17 22:53:26 +10001593 /* Flash registers may more likely not be mapped if the chip was forced.
1594 * Lock info may be stored in registers, so avoid lock info printing. */
hailfinger0f4c3952010-12-02 21:59:42 +00001595 if (!force)
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001596 if (flash->chip->printlock)
1597 flash->chip->printlock(flash);
snelson1ee293c2010-02-19 00:52:10 +00001598
Edward O'Callaghan79357b32020-08-02 01:24:58 +10001599 /* Get out of the way for later runs. */
1600 unmap_flash(flash);
1601
hailfinger48ed3e22011-05-04 00:39:50 +00001602 /* Return position of matching chip. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001603 return chip - flash_list;
rminnich8d3ff912003-10-25 17:01:29 +00001604}
1605
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001606static int verify_flash(struct flashctx *flash,
1607 struct action_descriptor *descriptor,
1608 int verify_it)
rminnich8d3ff912003-10-25 17:01:29 +00001609{
hailfingerb0f4d122009-06-24 08:20:45 +00001610 int ret;
Patrick Georgif3fa2992017-02-02 16:24:44 +01001611 unsigned int total_size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001612 uint8_t *buf = descriptor->newcontents;
rminnich8d3ff912003-10-25 17:01:29 +00001613
snelsone42c3802010-05-07 20:09:04 +00001614 msg_cinfo("Verifying flash... ");
uwef6641642007-05-09 10:17:44 +00001615
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001616 if (verify_it == VERIFY_PARTIAL) {
1617 struct processing_unit *pu = descriptor->processing_units;
1618
1619 /* Verify only areas which were written. */
1620 while (pu->num_blocks) {
1621 ret = verify_range(flash, buf + pu->offset, pu->offset,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001622 pu->block_size * pu->num_blocks);
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001623 if (ret)
1624 break;
1625 pu++;
1626 }
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001627 } else {
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001628 ret = verify_range(flash, buf, 0, total_size);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08001629 }
uwef6641642007-05-09 10:17:44 +00001630
David Hendricks1ed1d352011-11-23 17:54:37 -08001631 if (ret == ACCESS_DENIED) {
1632 msg_gdbg("Could not fully verify due to access error, ");
1633 if (access_denied_action == error_ignore) {
1634 msg_gdbg("ignoring\n");
1635 ret = 0;
1636 } else {
1637 msg_gdbg("aborting\n");
1638 }
1639 }
1640
hailfingerb0f4d122009-06-24 08:20:45 +00001641 if (!ret)
snelsone42c3802010-05-07 20:09:04 +00001642 msg_cinfo("VERIFIED. \n");
stepanc98b80b2006-03-16 16:57:41 +00001643
hailfingerb0f4d122009-06-24 08:20:45 +00001644 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00001645}
1646
uwe8d342eb2011-07-28 08:13:25 +00001647int read_buf_from_file(unsigned char *buf, unsigned long size,
1648 const char *filename)
hailfinger771fc182010-10-15 00:01:14 +00001649{
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001650 unsigned long numbytes;
Edward O'Callaghan2427d562020-10-01 16:41:01 +10001651 FILE *image;
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001652 struct stat image_stat;
1653
1654 if (!strncmp(filename, "-", sizeof("-")))
1655 image = fdopen(STDIN_FILENO, "rb");
1656 else
1657 image = fopen(filename, "rb");
1658 if (image == NULL) {
1659 perror(filename);
hailfinger771fc182010-10-15 00:01:14 +00001660 return 1;
1661 }
1662 if (fstat(fileno(image), &image_stat) != 0) {
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001663 perror(filename);
1664 fclose(image);
1665 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001666 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001667 if ((image_stat.st_size != size) &&
1668 (strncmp(filename, "-", sizeof("-")))) {
1669 msg_gerr("Error: Image size doesn't match: stat %jd bytes, "
1670 "wanted %ld!\n", (intmax_t)image_stat.st_size, size);
1671 fclose(image);
1672 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001673 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001674 numbytes = fread(buf, 1, size, image);
1675 if (fclose(image)) {
1676 perror(filename);
1677 return 1;
1678 }
hailfinger771fc182010-10-15 00:01:14 +00001679 if (numbytes != size) {
1680 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1681 "wanted %ld!\n", numbytes, size);
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001682 return 1;
hailfinger771fc182010-10-15 00:01:14 +00001683 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001684 return 0;
hailfinger771fc182010-10-15 00:01:14 +00001685}
1686
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001687int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
hailfingerd219a232009-01-28 00:27:54 +00001688{
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001689 unsigned long numbytes;
hailfingerd219a232009-01-28 00:27:54 +00001690 FILE *image;
hailfingerde345862009-06-01 22:07:52 +00001691
1692 if (!filename) {
hailfinger42a850a2010-07-13 23:56:13 +00001693 msg_gerr("No filename specified.\n");
hailfingerde345862009-06-01 22:07:52 +00001694 return 1;
1695 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001696 if (!strncmp(filename, "-", sizeof("-")))
1697 image = fdopen(STDOUT_FILENO, "wb");
1698 else
1699 image = fopen(filename, "wb");
1700 if (image == NULL) {
1701 perror(filename);
hailfinger23060112009-05-08 12:49:03 +00001702 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001703 }
hailfingerd219a232009-01-28 00:27:54 +00001704
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001705 numbytes = fwrite(buf, 1, size, image);
1706 fclose(image);
hailfinger42a850a2010-07-13 23:56:13 +00001707 if (numbytes != size) {
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10001708 msg_gerr("Error: file %s could not be written completely.\n", filename);
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001709 return 1;
hailfinger42a850a2010-07-13 23:56:13 +00001710 }
Edward O'Callaghan3f972992020-10-26 01:48:37 +00001711 return 0;
hailfingerd219a232009-01-28 00:27:54 +00001712}
1713
David Hendrickse3451942013-03-21 17:23:29 -07001714/*
1715 * read_flash - wrapper for flash->read() with additional high-level policy
1716 *
1717 * @flash flash chip
1718 * @buf buffer to store data in
1719 * @start start address
1720 * @len number of bytes to read
1721 *
1722 * This wrapper simplifies most cases when the flash chip needs to be read
1723 * since policy decisions such as non-fatal error handling is centralized.
1724 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001725int read_flash(struct flashctx *flash, uint8_t *buf,
David Hendrickse3451942013-03-21 17:23:29 -07001726 unsigned int start, unsigned int len)
1727{
David Hendricks4e76fdc2013-05-13 16:05:36 -07001728 int ret;
David Hendrickse3451942013-03-21 17:23:29 -07001729
Patrick Georgif3fa2992017-02-02 16:24:44 +01001730 if (!flash || !flash->chip->read)
David Hendrickse3451942013-03-21 17:23:29 -07001731 return -1;
1732
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001733 msg_cdbg("%#06x-%#06x:R ", start, start + len - 1);
1734
Patrick Georgif3fa2992017-02-02 16:24:44 +01001735 ret = flash->chip->read(flash, buf, start, len);
David Hendrickse3451942013-03-21 17:23:29 -07001736 if (ret) {
1737 if (ignore_error(ret)) {
1738 msg_gdbg("ignoring error when reading 0x%x-0x%x\n",
1739 start, start + len - 1);
1740 ret = 0;
1741 } else {
1742 msg_gdbg("failed to read 0x%x-0x%x\n",
1743 start, start + len - 1);
1744 }
1745 }
1746
1747 return ret;
1748}
1749
David Hendricks7c8a1612013-04-26 19:14:44 -07001750/*
1751 * write_flash - wrapper for flash->write() with additional high-level policy
1752 *
1753 * @flash flash chip
1754 * @buf buffer to write to flash
1755 * @start start address in flash
1756 * @len number of bytes to write
1757 *
1758 * TODO: Look up regions that are write-protected and avoid attempt to write
1759 * to them at all.
1760 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001761int write_flash(struct flashctx *flash, uint8_t *buf,
David Hendricks7c8a1612013-04-26 19:14:44 -07001762 unsigned int start, unsigned int len)
1763{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001764 if (!flash || !flash->chip->write)
David Hendricks7c8a1612013-04-26 19:14:44 -07001765 return -1;
1766
Patrick Georgif3fa2992017-02-02 16:24:44 +01001767 return flash->chip->write(flash, buf, start, len);
David Hendricks7c8a1612013-04-26 19:14:44 -07001768}
1769
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001770int read_flash_to_file(struct flashctx *flash, const char *filename)
hailfinger42a850a2010-07-13 23:56:13 +00001771{
Patrick Georgif3fa2992017-02-02 16:24:44 +01001772 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes74eec602018-12-19 15:30:39 +00001773 unsigned char *buf = calloc(size, sizeof(unsigned char));
hailfinger42a850a2010-07-13 23:56:13 +00001774 int ret = 0;
1775
1776 msg_cinfo("Reading flash... ");
1777 if (!buf) {
1778 msg_gerr("Memory allocation failed!\n");
1779 msg_cinfo("FAILED.\n");
1780 return 1;
1781 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001782
1783 /* To support partial read, fill buffer to all 0xFF at beginning to make
1784 * debug easier. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001785 memset(buf, ERASED_VALUE(flash), size);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001786
Patrick Georgif3fa2992017-02-02 16:24:44 +01001787 if (!flash->chip->read) {
hailfinger42a850a2010-07-13 23:56:13 +00001788 msg_cerr("No read function available for this flash chip.\n");
1789 ret = 1;
1790 goto out_free;
1791 }
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001792
1793 /* First try to handle partial read case, rather than read the whole
1794 * flash, which is slow. */
David Hendrickse3451942013-03-21 17:23:29 -07001795 ret = handle_partial_read(flash, buf, read_flash, 1);
Louis Yung-Chieh Lo9c7525f2011-03-04 12:32:02 +08001796 if (ret < 0) {
1797 msg_cerr("Partial read operation failed!\n");
1798 ret = 1;
1799 goto out_free;
1800 } else if (ret > 0) {
David Hendricksdf29a832013-06-28 14:33:51 -07001801 int num_regions = get_num_include_args();
1802
1803 if (ret != num_regions) {
1804 msg_cerr("Requested %d regions, but only read %d\n",
1805 num_regions, ret);
1806 ret = 1;
1807 goto out_free;
1808 }
1809
1810 ret = 0;
David Hendricks1ed1d352011-11-23 17:54:37 -08001811 } else {
David Hendrickse3451942013-03-21 17:23:29 -07001812 if (read_flash(flash, buf, 0, size)) {
David Hendricks1ed1d352011-11-23 17:54:37 -08001813 msg_cerr("Read operation failed!\n");
1814 ret = 1;
1815 goto out_free;
1816 }
hailfinger42a850a2010-07-13 23:56:13 +00001817 }
1818
David Hendricksdf29a832013-06-28 14:33:51 -07001819 if (filename)
1820 ret = write_buf_to_file(buf, size, filename);
1821
hailfinger42a850a2010-07-13 23:56:13 +00001822out_free:
1823 free(buf);
David Hendricksc6c9f822010-11-03 15:07:01 -07001824 if (ret)
1825 msg_cerr("FAILED.");
1826 else
1827 msg_cdbg("done.");
hailfinger42a850a2010-07-13 23:56:13 +00001828 return ret;
1829}
1830
Edward O'Callaghan6240c852019-07-02 15:49:58 +10001831/* Even if an error is found, the function will keep going and check the rest. */
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001832static int selfcheck_eraseblocks(const struct flashchip *chip)
hailfinger45177872010-01-18 08:14:43 +00001833{
hailfingerb91c08c2011-08-15 19:54:20 +00001834 int i, j, k;
1835 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00001836
1837 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1838 unsigned int done = 0;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001839 struct block_eraser eraser = chip->block_erasers[k];
hailfinger45177872010-01-18 08:14:43 +00001840
1841 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1842 /* Blocks with zero size are bugs in flashchips.c. */
1843 if (eraser.eraseblocks[i].count &&
1844 !eraser.eraseblocks[i].size) {
1845 msg_gerr("ERROR: Flash chip %s erase function "
1846 "%i region %i has size 0. Please report"
1847 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001848 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001849 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001850 }
1851 /* Blocks with zero count are bugs in flashchips.c. */
1852 if (!eraser.eraseblocks[i].count &&
1853 eraser.eraseblocks[i].size) {
1854 msg_gerr("ERROR: Flash chip %s erase function "
1855 "%i region %i has count 0. Please report"
1856 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001857 chip->name, k, i);
hailfinger9fed35d2010-01-19 06:42:46 +00001858 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001859 }
1860 done += eraser.eraseblocks[i].count *
1861 eraser.eraseblocks[i].size;
1862 }
hailfinger9fed35d2010-01-19 06:42:46 +00001863 /* Empty eraseblock definition with erase function. */
1864 if (!done && eraser.block_erase)
snelsone42c3802010-05-07 20:09:04 +00001865 msg_gspew("Strange: Empty eraseblock definition with "
uwe8d342eb2011-07-28 08:13:25 +00001866 "non-empty erase function. Not an error.\n");
hailfinger45177872010-01-18 08:14:43 +00001867 if (!done)
1868 continue;
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001869 if (done != chip->total_size * 1024) {
hailfinger45177872010-01-18 08:14:43 +00001870 msg_gerr("ERROR: Flash chip %s erase function %i "
1871 "region walking resulted in 0x%06x bytes total,"
1872 " expected 0x%06x bytes. Please report a bug at"
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001873 " flashrom@flashrom.org\n", chip->name, k,
1874 done, chip->total_size * 1024);
hailfinger9fed35d2010-01-19 06:42:46 +00001875 ret = 1;
hailfinger45177872010-01-18 08:14:43 +00001876 }
hailfinger9fed35d2010-01-19 06:42:46 +00001877 if (!eraser.block_erase)
1878 continue;
1879 /* Check if there are identical erase functions for different
1880 * layouts. That would imply "magic" erase functions. The
1881 * easiest way to check this is with function pointers.
1882 */
uwef6f94d42010-03-13 17:28:29 +00001883 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
hailfinger9fed35d2010-01-19 06:42:46 +00001884 if (eraser.block_erase ==
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001885 chip->block_erasers[j].block_erase) {
hailfinger9fed35d2010-01-19 06:42:46 +00001886 msg_gerr("ERROR: Flash chip %s erase function "
1887 "%i and %i are identical. Please report"
1888 " a bug at flashrom@flashrom.org\n",
Edward O'Callaghanf93b3742019-02-24 17:24:27 +11001889 chip->name, k, j);
hailfinger9fed35d2010-01-19 06:42:46 +00001890 ret = 1;
1891 }
uwef6f94d42010-03-13 17:28:29 +00001892 }
hailfinger45177872010-01-18 08:14:43 +00001893 }
hailfinger9fed35d2010-01-19 06:42:46 +00001894 return ret;
hailfinger45177872010-01-18 08:14:43 +00001895}
1896
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001897static int erase_and_write_block_helper(struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001898 unsigned int start, unsigned int len,
hailfinger90fcf9b2010-11-05 14:51:59 +00001899 uint8_t *curcontents,
hailfingerb437e282010-11-04 01:04:27 +00001900 uint8_t *newcontents,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001901 int (*erasefn) (struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00001902 unsigned int addr,
1903 unsigned int len))
1904{
stefanctc5eb8a92011-11-23 09:13:48 +00001905 unsigned int starthere = 0, lenhere = 0;
1906 int ret = 0, skip = 1, writecount = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001907 int block_was_erased = 0;
Edward O'Callaghan10e63d92019-06-17 14:12:52 +10001908 enum write_granularity gran = flash->chip->gran;
hailfingerb437e282010-11-04 01:04:27 +00001909
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001910 /*
1911 * curcontents and newcontents are opaque to walk_eraseregions, and
1912 * need to be adjusted here to keep the impression of proper
1913 * abstraction
hailfingerb437e282010-11-04 01:04:27 +00001914 */
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001915
hailfinger90fcf9b2010-11-05 14:51:59 +00001916 curcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001917
hailfingerb437e282010-11-04 01:04:27 +00001918 newcontents += start;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001919
hailfingerb437e282010-11-04 01:04:27 +00001920 msg_cdbg(":");
Edward O'Callaghan65891c82020-09-07 12:33:06 +10001921 if (need_erase(curcontents, newcontents, len, gran, 0xff)) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001922 content_has_changed |= 1;
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001923 msg_cdbg(" E");
hailfingerb437e282010-11-04 01:04:27 +00001924 ret = erasefn(flash, start, len);
David Hendricks1ed1d352011-11-23 17:54:37 -08001925 if (ret) {
1926 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001927 msg_cdbg(" DENIED");
David Hendricks1ed1d352011-11-23 17:54:37 -08001928 else
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001929 msg_cerr(" ERASE_FAILED\n");
hailfingerb437e282010-11-04 01:04:27 +00001930 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001931 }
1932
David Hendricks0954ffc2015-11-13 15:15:44 -08001933 if (programmer_table[programmer].paranoid) {
1934 if (check_erased_range(flash, start, len)) {
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001935 msg_cerr(" ERASE_FAILED\n");
David Hendricks0954ffc2015-11-13 15:15:44 -08001936 return -1;
1937 }
hailfingerac8e3182011-06-26 17:04:16 +00001938 }
David Hendricks0954ffc2015-11-13 15:15:44 -08001939
hailfinger90fcf9b2010-11-05 14:51:59 +00001940 /* Erase was successful. Adjust curcontents. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10001941 memset(curcontents, ERASED_VALUE(flash), len);
hailfingerb437e282010-11-04 01:04:27 +00001942 skip = 0;
David Hendricks048b38c2016-03-28 18:47:06 -07001943 block_was_erased = 1;
hailfingerb437e282010-11-04 01:04:27 +00001944 }
hailfinger90fcf9b2010-11-05 14:51:59 +00001945 /* get_next_write() sets starthere to a new value after the call. */
1946 while ((lenhere = get_next_write(curcontents + starthere,
1947 newcontents + starthere,
1948 len - starthere, &starthere, gran))) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07001949 content_has_changed |= 1;
hailfingerb437e282010-11-04 01:04:27 +00001950 if (!writecount++)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001951 msg_cdbg(" W");
hailfingerb437e282010-11-04 01:04:27 +00001952 /* Needs the partial write function signature. */
David Hendricks7c8a1612013-04-26 19:14:44 -07001953 ret = write_flash(flash, newcontents + starthere,
hailfingerb437e282010-11-04 01:04:27 +00001954 start + starthere, lenhere);
David Hendricks1ed1d352011-11-23 17:54:37 -08001955 if (ret) {
1956 if (ret == ACCESS_DENIED)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001957 msg_cdbg(" DENIED");
hailfingerb437e282010-11-04 01:04:27 +00001958 return ret;
David Hendricks1ed1d352011-11-23 17:54:37 -08001959 }
David Hendricks048b38c2016-03-28 18:47:06 -07001960
1961 /*
1962 * If the block needed to be erased and was erased successfully
1963 * then we can assume that we didn't run into any write-
1964 * protected areas. Otherwise, we need to verify each page to
1965 * ensure it was successfully written and abort if we encounter
1966 * any errors.
1967 */
1968 if (programmer_table[programmer].paranoid && !block_was_erased) {
1969 if (verify_range(flash, newcontents + starthere,
Edward O'Callaghan445b48b2020-08-13 12:25:17 +10001970 start + starthere, lenhere))
David Hendricks048b38c2016-03-28 18:47:06 -07001971 return -1;
1972 }
1973
hailfingerb437e282010-11-04 01:04:27 +00001974 starthere += lenhere;
1975 skip = 0;
1976 }
1977 if (skip)
Daisuke Nojiri446b6732018-09-07 18:32:56 -07001978 msg_cdbg(" SKIP");
hailfingerb437e282010-11-04 01:04:27 +00001979 return ret;
1980}
1981
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07001982/*
1983 * Function to process processing units accumulated in the action descriptor.
1984 *
1985 * @flash pointer to the flash context to operate on
1986 * @do_something helper function which can erase and program a section of the
1987 * flash chip. It receives the flash context, offset and length
1988 * of the area to erase/program, before and after contents (to
1989 * decide what exactly needs to be erased and or programmed)
1990 * and a pointer to the erase function which can operate on the
1991 * proper granularity.
1992 * @descriptor action descriptor including pointers to before and after
1993 * contents and an array of processing actions to take.
1994 *
1995 * Returns zero on success or an error code.
1996 */
1997static int walk_eraseregions(struct flashctx *flash,
Souvik Ghoshd75cd672016-06-17 14:21:39 -07001998 int (*do_something) (struct flashctx *flash,
hailfinger83541b32010-07-13 00:42:00 +00001999 unsigned int addr,
hailfingerb437e282010-11-04 01:04:27 +00002000 unsigned int len,
2001 uint8_t *param1,
2002 uint8_t *param2,
2003 int (*erasefn) (
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002004 struct flashctx *flash,
hailfingerb437e282010-11-04 01:04:27 +00002005 unsigned int addr,
2006 unsigned int len)),
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002007 struct action_descriptor *descriptor)
hailfinger2b8c9382010-07-13 00:37:19 +00002008{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002009 struct processing_unit *pu;
2010 int rc = 0;
2011 static int print_comma;
uwe8d342eb2011-07-28 08:13:25 +00002012
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002013 for (pu = descriptor->processing_units; pu->num_blocks; pu++) {
2014 unsigned base = pu->offset;
2015 unsigned top = pu->offset + pu->block_size * pu->num_blocks;
David Hendricks605544b2015-08-15 16:32:58 -07002016
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002017 while (base < top) {
David Hendricks605544b2015-08-15 16:32:58 -07002018
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002019 if (print_comma)
hailfingerb437e282010-11-04 01:04:27 +00002020 msg_cdbg(", ");
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002021 else
2022 print_comma = 1;
2023
2024 msg_cdbg("0x%06x-0x%06zx", base, base + pu->block_size - 1);
2025
2026 rc = do_something(flash, base,
2027 pu->block_size,
2028 descriptor->oldcontents,
2029 descriptor->newcontents,
2030 flash->chip->block_erasers[pu->block_eraser_index].block_erase);
2031
David Hendricks1ed1d352011-11-23 17:54:37 -08002032 if (rc) {
2033 if (ignore_error(rc))
2034 rc = 0;
2035 else
2036 return rc;
hailfingerb437e282010-11-04 01:04:27 +00002037 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002038 base += pu->block_size;
hailfinger2b8c9382010-07-13 00:37:19 +00002039 }
2040 }
hailfingerb437e282010-11-04 01:04:27 +00002041 msg_cdbg("\n");
David Hendricks1ed1d352011-11-23 17:54:37 -08002042 return rc;
hailfinger2b8c9382010-07-13 00:37:19 +00002043}
2044
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002045static int check_block_eraser(const struct flashctx *flash, int k, int log)
hailfingercf848f12010-12-05 15:14:44 +00002046{
Patrick Georgif3fa2992017-02-02 16:24:44 +01002047 struct block_eraser eraser = flash->chip->block_erasers[k];
hailfingercf848f12010-12-05 15:14:44 +00002048
2049 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
2050 if (log)
2051 msg_cdbg("not defined. ");
2052 return 1;
2053 }
2054 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
2055 if (log)
2056 msg_cdbg("eraseblock layout is known, but matching "
stefanct9e6b98a2011-05-28 02:37:14 +00002057 "block erase function is not implemented. ");
hailfingercf848f12010-12-05 15:14:44 +00002058 return 1;
2059 }
2060 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
2061 if (log)
2062 msg_cdbg("block erase function found, but "
stefanct9e6b98a2011-05-28 02:37:14 +00002063 "eraseblock layout is not defined. ");
hailfingercf848f12010-12-05 15:14:44 +00002064 return 1;
2065 }
Edward O'Callaghana5cfb4d2020-09-07 16:26:42 +10002066 // TODO: Once erase functions are annotated with allowed buses, check that as well.
hailfingercf848f12010-12-05 15:14:44 +00002067 return 0;
2068}
2069
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002070int erase_and_write_flash(struct flashctx *flash,
2071 struct action_descriptor *descriptor)
hailfingerd219a232009-01-28 00:27:54 +00002072{
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002073 int ret = 1;
hailfingercf848f12010-12-05 15:14:44 +00002074
hailfingercf848f12010-12-05 15:14:44 +00002075 msg_cinfo("Erasing and writing flash chip... ");
hailfingerb437e282010-11-04 01:04:27 +00002076
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002077 ret = walk_eraseregions(flash, &erase_and_write_block_helper, descriptor);
hailfinger1e9ee0f2009-05-08 17:15:15 +00002078
hailfinger7df21362009-09-05 02:30:58 +00002079 if (ret) {
snelsone42c3802010-05-07 20:09:04 +00002080 msg_cerr("FAILED!\n");
hailfinger7df21362009-09-05 02:30:58 +00002081 } else {
David Hendricksc6c9f822010-11-03 15:07:01 -07002082 msg_cdbg("SUCCESS.\n");
hailfinger7df21362009-09-05 02:30:58 +00002083 }
2084 return ret;
hailfingerd219a232009-01-28 00:27:54 +00002085}
2086
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002087static void nonfatal_help_message(void)
hailfinger4c47e9d2010-10-19 22:06:20 +00002088{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002089 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
2090#if CONFIG_INTERNAL == 1
2091 if (programmer == PROGRAMMER_INTERNAL)
2092 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
2093 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2094 "mail flashrom@flashrom.org, thanks!\n"
2095 "-------------------------------------------------------------------------------\n"
2096 "You may now reboot or simply leave the machine running.\n");
2097 else
2098#endif
2099 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
2100 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
2101 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2102 "mail flashrom@flashrom.org, thanks!\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002103}
2104
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002105static void emergency_help_message(void)
hailfinger0459e1c2009-08-19 13:55:34 +00002106{
Edward O'Callaghan09fdc022020-09-07 15:51:53 +10002107 msg_gerr("Your flash chip is in an unknown state.\n");
2108#if CONFIG_INTERNAL == 1
2109 if (programmer == PROGRAMMER_INTERNAL)
2110 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
2111 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
2112 "-------------------------------------------------------------------------------\n"
2113 "DO NOT REBOOT OR POWEROFF!\n");
2114 else
2115#endif
2116 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
2117 "mail flashrom@flashrom.org, thanks!\n");
hailfinger0459e1c2009-08-19 13:55:34 +00002118}
2119
hailfingerf79d1712010-10-06 23:48:34 +00002120void list_programmers_linebreak(int startcol, int cols, int paren)
2121{
2122 const char *pname;
hailfingerb91c08c2011-08-15 19:54:20 +00002123 int pnamelen;
2124 int remaining = 0, firstline = 1;
hailfingerf79d1712010-10-06 23:48:34 +00002125 enum programmer p;
hailfingerb91c08c2011-08-15 19:54:20 +00002126 int i;
hailfingerf79d1712010-10-06 23:48:34 +00002127
2128 for (p = 0; p < PROGRAMMER_INVALID; p++) {
2129 pname = programmer_table[p].name;
2130 pnamelen = strlen(pname);
2131 if (remaining - pnamelen - 2 < 0) {
2132 if (firstline)
2133 firstline = 0;
2134 else
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002135 msg_ginfo("\n");
hailfingerf79d1712010-10-06 23:48:34 +00002136 for (i = 0; i < startcol; i++)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002137 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002138 remaining = cols - startcol;
2139 } else {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002140 msg_ginfo(" ");
hailfingerf79d1712010-10-06 23:48:34 +00002141 remaining--;
2142 }
2143 if (paren && (p == 0)) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002144 msg_ginfo("(");
hailfingerf79d1712010-10-06 23:48:34 +00002145 remaining--;
2146 }
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002147 msg_ginfo("%s", pname);
hailfingerf79d1712010-10-06 23:48:34 +00002148 remaining -= pnamelen;
2149 if (p < PROGRAMMER_INVALID - 1) {
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002150 msg_ginfo(",");
hailfingerf79d1712010-10-06 23:48:34 +00002151 remaining--;
2152 } else {
2153 if (paren)
Edward O'Callaghan90aaa302019-05-21 14:43:38 +10002154 msg_ginfo(")");
hailfingerf79d1712010-10-06 23:48:34 +00002155 }
2156 }
2157}
2158
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002159static void print_sysinfo(void)
hailfinger3b471632010-03-27 16:36:40 +00002160{
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002161#if IS_WINDOWS
2162 SYSTEM_INFO si;
2163 OSVERSIONINFOEX osvi;
hailfinger3b471632010-03-27 16:36:40 +00002164
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002165 memset(&si, 0, sizeof(SYSTEM_INFO));
2166 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
2167 msg_ginfo(" on Windows");
2168 /* Tell Windows which version of the structure we want. */
2169 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2170 if (GetVersionEx((OSVERSIONINFO*) &osvi))
2171 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
2172 else
2173 msg_ginfo(" unknown version");
2174 GetSystemInfo(&si);
2175 switch (si.wProcessorArchitecture) {
2176 case PROCESSOR_ARCHITECTURE_AMD64:
2177 msg_ginfo(" (x86_64)");
2178 break;
2179 case PROCESSOR_ARCHITECTURE_INTEL:
2180 msg_ginfo(" (x86)");
2181 break;
2182 default:
2183 msg_ginfo(" (unknown arch)");
2184 break;
2185 }
2186#elif HAVE_UTSNAME == 1
2187 struct utsname osinfo;
2188
2189 uname(&osinfo);
2190 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
hailfinger3b471632010-03-27 16:36:40 +00002191 osinfo.machine);
2192#else
Edward O'Callaghandfb1fa32020-09-07 16:00:36 +10002193 msg_ginfo(" on unknown machine");
hailfinger3b471632010-03-27 16:36:40 +00002194#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002195}
2196
2197void print_buildinfo(void)
2198{
2199 msg_gdbg("flashrom was built with");
hailfinger3b471632010-03-27 16:36:40 +00002200#if NEED_PCI == 1
2201#ifdef PCILIB_VERSION
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002202 msg_gdbg(" libpci %s,", PCILIB_VERSION);
hailfinger3b471632010-03-27 16:36:40 +00002203#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002204 msg_gdbg(" unknown PCI library,");
hailfinger3b471632010-03-27 16:36:40 +00002205#endif
2206#endif
2207#ifdef __clang__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002208 msg_gdbg(" LLVM Clang");
hailfinger3cc85ad2010-07-17 14:49:30 +00002209#ifdef __clang_version__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002210 msg_gdbg(" %s,", __clang_version__);
hailfinger3cc85ad2010-07-17 14:49:30 +00002211#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002212 msg_gdbg(" unknown version (before r102686),");
hailfinger3cc85ad2010-07-17 14:49:30 +00002213#endif
hailfinger3b471632010-03-27 16:36:40 +00002214#elif defined(__GNUC__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002215 msg_gdbg(" GCC");
hailfinger3b471632010-03-27 16:36:40 +00002216#ifdef __VERSION__
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002217 msg_gdbg(" %s,", __VERSION__);
hailfinger3b471632010-03-27 16:36:40 +00002218#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002219 msg_gdbg(" unknown version,");
hailfinger3b471632010-03-27 16:36:40 +00002220#endif
2221#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002222 msg_gdbg(" unknown compiler,");
hailfinger324a9cc2010-05-26 01:45:41 +00002223#endif
2224#if defined (__FLASHROM_LITTLE_ENDIAN__)
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002225 msg_gdbg(" little endian");
hailfinger324a9cc2010-05-26 01:45:41 +00002226#else
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002227 msg_gdbg(" big endian");
hailfinger3b471632010-03-27 16:36:40 +00002228#endif
Souvik Ghosh3c963a42016-07-19 18:48:15 -07002229 msg_gdbg("\n");
hailfinger3b471632010-03-27 16:36:40 +00002230}
2231
uwefdeca092008-01-21 15:24:22 +00002232void print_version(void)
2233{
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002234 msg_ginfo("flashrom %s", flashrom_version);
hailfinger3b471632010-03-27 16:36:40 +00002235 print_sysinfo();
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002236 msg_ginfo("\n");
uwefdeca092008-01-21 15:24:22 +00002237}
2238
hailfinger74819ad2010-05-15 15:04:37 +00002239void print_banner(void)
2240{
2241 msg_ginfo("flashrom is free software, get the source code at "
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002242 "https://flashrom.org\n");
hailfinger74819ad2010-05-15 15:04:37 +00002243 msg_ginfo("\n");
2244}
2245
hailfingerc77acb52009-12-24 02:15:55 +00002246int selfcheck(void)
2247{
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002248 unsigned int i;
hailfinger45177872010-01-18 08:14:43 +00002249 int ret = 0;
hailfinger45177872010-01-18 08:14:43 +00002250
2251 /* Safety check. Instead of aborting after the first error, check
2252 * if more errors exist.
2253 */
hailfingerc77acb52009-12-24 02:15:55 +00002254 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
snelsone42c3802010-05-07 20:09:04 +00002255 msg_gerr("Programmer table miscompilation!\n");
hailfinger45177872010-01-18 08:14:43 +00002256 ret = 1;
hailfingerc77acb52009-12-24 02:15:55 +00002257 }
Edward O'Callaghanac1678b2020-07-27 15:55:45 +10002258 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2259 const struct programmer_entry p = programmer_table[i];
2260 if (p.name == NULL) {
2261 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2262 ret = 1;
2263 /* This might hide other problems with this programmer, but allows for better error
2264 * messages below without jumping through hoops. */
2265 continue;
2266 }
2267 switch (p.type) {
2268 case USB:
2269 case PCI:
2270 case OTHER:
2271 if (p.devs.note == NULL) {
2272 if (strcmp("internal", p.name) == 0)
2273 break; /* This one has its device list stored separately. */
2274 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2275 p.name);
2276 ret = 1;
2277 }
2278 break;
2279 default:
2280 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2281 ret = 1;
2282 break;
2283 }
2284 if (p.init == NULL) {
2285 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2286 ret = 1;
2287 }
2288 if (p.delay == NULL) {
2289 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2290 ret = 1;
2291 }
2292 if (p.map_flash_region == NULL) {
2293 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2294 ret = 1;
2295 }
2296 if (p.unmap_flash_region == NULL) {
2297 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2298 ret = 1;
2299 }
2300 }
2301
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002302 /* It would be favorable if we could check for the correct layout (especially termination) of various
2303 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2304 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2305 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2306 * 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 +10002307 * checks below. */
2308 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
stefanct6d836ba2011-05-26 01:35:19 +00002309 msg_gerr("Flashchips table miscompilation!\n");
2310 ret = 1;
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002311 } else {
2312 for (i = 0; i < flashchips_size - 1; i++) {
2313 const struct flashchip *chip = &flashchips[i];
2314 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2315 ret = 1;
2316 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2317 "Please report a bug at flashrom@flashrom.org\n", i,
2318 chip->name == NULL ? "unnamed" : chip->name);
2319 }
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002320 if (selfcheck_eraseblocks(chip)) {
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002321 ret = 1;
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002322 }
Edward O'Callaghan6240c852019-07-02 15:49:58 +10002323 }
stefanct6d836ba2011-05-26 01:35:19 +00002324 }
stefanct6d836ba2011-05-26 01:35:19 +00002325
Edward O'Callaghanb2257cc2020-07-25 22:19:47 +10002326 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
hailfinger45177872010-01-18 08:14:43 +00002327 return ret;
hailfingerc77acb52009-12-24 02:15:55 +00002328}
2329
hailfinger771fc182010-10-15 00:01:14 +00002330/* FIXME: This function signature needs to be improved once doit() has a better
2331 * function signature.
2332 */
Edward O'Callaghan0c310fe2020-08-10 17:02:23 +10002333static int chip_safety_check(const struct flashctx *flash, int force,
2334 int read_it, int write_it, int erase_it, int verify_it)
hailfinger771fc182010-10-15 00:01:14 +00002335{
Patrick Georgiac3423f2017-02-03 20:58:06 +01002336 const struct flashchip *chip = flash->chip;
2337
hailfinger771fc182010-10-15 00:01:14 +00002338 if (!programmer_may_write && (write_it || erase_it)) {
2339 msg_perr("Write/erase is not working yet on your programmer in "
2340 "its current configuration.\n");
2341 /* --force is the wrong approach, but it's the best we can do
2342 * until the generic programmer parameter parser is merged.
2343 */
2344 if (!force)
2345 return 1;
2346 msg_cerr("Continuing anyway.\n");
2347 }
2348
2349 if (read_it || erase_it || write_it || verify_it) {
2350 /* Everything needs read. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002351 if (chip->tested.read == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002352 msg_cerr("Read is not working on this chip. ");
2353 if (!force)
2354 return 1;
2355 msg_cerr("Continuing anyway.\n");
2356 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002357 if (!chip->read) {
hailfinger771fc182010-10-15 00:01:14 +00002358 msg_cerr("flashrom has no read function for this "
2359 "flash chip.\n");
2360 return 1;
2361 }
2362 }
2363 if (erase_it || write_it) {
2364 /* Write needs erase. */
Patrick Georgiac3423f2017-02-03 20:58:06 +01002365 if (chip->tested.erase == NA) {
2366 msg_cerr("Erase is not possible on this chip.\n");
2367 return 1;
2368 }
2369 if (chip->tested.erase == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002370 msg_cerr("Erase is not working on this chip. ");
2371 if (!force)
2372 return 1;
2373 msg_cerr("Continuing anyway.\n");
2374 }
stefancte1c5acf2011-07-04 07:27:17 +00002375 if(count_usable_erasers(flash) == 0) {
stefanct569dbb62011-07-01 00:19:12 +00002376 msg_cerr("flashrom has no erase function for this "
2377 "flash chip.\n");
2378 return 1;
2379 }
hailfinger771fc182010-10-15 00:01:14 +00002380 }
2381 if (write_it) {
Patrick Georgiac3423f2017-02-03 20:58:06 +01002382 if (chip->tested.write == NA) {
2383 msg_cerr("Write is not possible on this chip.\n");
2384 return 1;
2385 }
2386 if (chip->tested.write == BAD) {
hailfinger771fc182010-10-15 00:01:14 +00002387 msg_cerr("Write is not working on this chip. ");
2388 if (!force)
2389 return 1;
2390 msg_cerr("Continuing anyway.\n");
2391 }
Patrick Georgiac3423f2017-02-03 20:58:06 +01002392 if (!chip->write) {
hailfinger771fc182010-10-15 00:01:14 +00002393 msg_cerr("flashrom has no write function for this "
2394 "flash chip.\n");
2395 return 1;
2396 }
2397 }
2398 return 0;
2399}
2400
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002401int prepare_flash_access(struct flashctx *const flash,
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002402 const bool read_it, const bool write_it,
2403 const bool erase_it, const bool verify_it)
2404{
Edward O'Callaghan2c679272020-09-23 22:41:01 +10002405 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002406 msg_cerr("Aborting.\n");
2407 return 1;
2408 }
2409
2410 if (normalize_romentries(flash)) {
2411 msg_cerr("Requested regions can not be handled. Aborting.\n");
2412 return 1;
2413 }
2414
Edward O'Callaghan40092972020-10-20 11:50:48 +11002415 /*
2416 * FIXME(b/171093672): Failures to map_flash() on some DUT's due to unknown cause,
2417 * can be repro'ed with upstream on Volteer.
2418 *
2419 * map_flash() can fail on opaque spi drv such as linux_mtd and even ichspi.
2420 * The issue is that 'internal' [alias 'host'] has the cb 'map_flash_region = physmap'
2421 * hooked and this can fail on some board topologies. Checking the return value can
2422 * cause board rw failures by bailing early. Avoid the early bail for now until a
2423 * full investigation can reveal the proper fix. This restores previous behaviour of
2424 * assuming a map went fine.
2425 */
2426#if 0
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002427 if (map_flash(flash) != 0)
2428 return 1;
Edward O'Callaghan40092972020-10-20 11:50:48 +11002429#endif
2430 map_flash(flash);
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002431
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002432 /* Given the existence of read locks, we want to unlock for read,
2433 erase and write. */
2434 if (flash->chip->unlock)
2435 flash->chip->unlock(flash);
2436
2437 flash->address_high_byte = -1;
2438 flash->in_4ba_mode = false;
2439
Edward O'Callaghan99974452020-10-13 13:28:33 +11002440 /* Be careful about 4BA chips and broken masters */
2441 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2442 /* If we can't use native instructions, bail out */
2443 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2444 || !spi_master_4ba(flash)) {
2445 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2446 return 1;
2447 }
2448 }
2449
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002450 /* Enable/disable 4-byte addressing mode if flash chip supports it */
Edward O'Callaghanf5cd3c12020-10-30 13:19:27 +11002451 if ((flash->chip->feature_bits & (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_ENTER_EAR7)) && flash->chip->set_4ba) {
2452 if (flash->chip->set_4ba(flash)) {
Edward O'Callaghan99974452020-10-13 13:28:33 +11002453 msg_cerr("Failed to set correct 4BA mode! Aborting.\n");
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002454 return 1;
2455 }
2456 }
2457
2458 return 0;
2459}
2460
Edward O'Callaghana820b212020-09-17 22:53:26 +10002461void finalize_flash_access(struct flashctx *const flash)
2462{
2463 unmap_flash(flash);
2464}
2465
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002466/*
2467 * Function to erase entire flash chip.
2468 *
2469 * @flashctx pointer to the flash context to use
2470 * @oldcontents pointer to the buffer including current chip contents, to
2471 * decide which areas do in fact need to be erased
2472 * @size the size of the flash chip, in bytes.
2473 *
2474 * Returns zero on success or an error code.
2475 */
2476static int erase_chip(struct flashctx *flash, void *oldcontents,
2477 void *newcontents, size_t size)
2478{
2479 /*
2480 * To make sure that the chip is fully erased, let's cheat and create
2481 * a descriptor where the new contents are all erased.
2482 */
2483 struct action_descriptor *fake_descriptor;
2484 int ret = 0;
2485
2486 fake_descriptor = prepare_action_descriptor(flash, oldcontents,
2487 newcontents, 1);
2488 /* FIXME: Do we really want the scary warning if erase failed? After
2489 * all, after erase the chip is either blank or partially blank or it
2490 * has the old contents. A blank chip won't boot, so if the user
2491 * wanted erase and reboots afterwards, the user knows very well that
2492 * booting won't work.
2493 */
2494 if (erase_and_write_flash(flash, fake_descriptor)) {
2495 emergency_help_message();
2496 ret = 1;
2497 }
2498
2499 free(fake_descriptor);
2500
2501 return ret;
2502}
2503
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002504static int read_dest_content(struct flashctx *flash, int verify_it,
2505 uint8_t *dest, unsigned long size)
2506{
2507 if (((verify_it == VERIFY_OFF) || (verify_it == VERIFY_PARTIAL))
2508 && get_num_include_args()) {
2509 /*
2510 * If no full verification is required and not
2511 * the entire chip is about to be programmed,
2512 * read only the areas which might change.
2513 */
2514 if (handle_partial_read(flash, dest, read_flash, 0) < 0)
2515 return 1;
2516 } else {
2517 if (read_flash(flash, dest, 0, size))
2518 return 1;
2519 }
2520 return 0;
2521}
2522
hailfingerc77acb52009-12-24 02:15:55 +00002523/* This function signature is horrible. We need to design a better interface,
2524 * but right now it allows us to split off the CLI code.
hailfingerd217d122010-10-08 18:52:29 +00002525 * Besides that, the function itself is a textbook example of abysmal code flow.
hailfingerc77acb52009-12-24 02:15:55 +00002526 */
Souvik Ghoshd75cd672016-06-17 14:21:39 -07002527int doit(struct flashctx *flash, int force, const char *filename, int read_it,
Simon Glass9ad06c12013-07-03 22:08:17 +09002528 int write_it, int erase_it, int verify_it, int extract_it,
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002529 const char *diff_file, int do_diff)
hailfingerc77acb52009-12-24 02:15:55 +00002530{
hailfinger4c47e9d2010-10-19 22:06:20 +00002531 uint8_t *oldcontents;
2532 uint8_t *newcontents;
hailfingerc77acb52009-12-24 02:15:55 +00002533 int ret = 0;
Patrick Georgif3fa2992017-02-02 16:24:44 +01002534 unsigned long size = flash->chip->total_size * 1024;
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002535 struct action_descriptor *descriptor = NULL;
hailfingerc77acb52009-12-24 02:15:55 +00002536
Edward O'Callaghana0176ff2020-08-18 15:49:23 +10002537 ret = prepare_flash_access(flash, read_it, write_it, erase_it, verify_it);
Edward O'Callaghan27362b42020-08-10 17:58:03 +10002538 if (ret)
hailfinger90fcf9b2010-11-05 14:51:59 +00002539 goto out_nofree;
Boris Baykov1a2f5322016-06-11 18:29:00 +02002540
Simon Glass9ad06c12013-07-03 22:08:17 +09002541 if (extract_it) {
2542 ret = extract_regions(flash);
2543 goto out_nofree;
2544 }
2545
David Hendricksd0ea9ed2011-03-04 17:31:57 -08002546 /* mark entries included using -i argument as "included" if they are
2547 found in the master rom_entries list */
2548 if (process_include_args() < 0) {
2549 ret = 1;
2550 goto out_nofree;
2551 }
2552
hailfinger771fc182010-10-15 00:01:14 +00002553 if (read_it) {
2554 ret = read_flash_to_file(flash, filename);
hailfinger90fcf9b2010-11-05 14:51:59 +00002555 goto out_nofree;
hailfinger5828baf2010-07-03 12:14:25 +00002556 }
hailfingerb437e282010-11-04 01:04:27 +00002557
stefanctd611e8f2011-07-12 22:35:21 +00002558 oldcontents = malloc(size);
2559 if (!oldcontents) {
2560 msg_gerr("Out of memory!\n");
2561 exit(1);
2562 }
Simon Glass4c214132013-07-16 10:09:28 -06002563 /* Assume worst case: All blocks are not erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002564 memset(oldcontents, UNERASED_VALUE(flash), size);
stefanctd611e8f2011-07-12 22:35:21 +00002565 newcontents = malloc(size);
2566 if (!newcontents) {
2567 msg_gerr("Out of memory!\n");
2568 exit(1);
2569 }
Simon Glass4c214132013-07-16 10:09:28 -06002570 /* Assume best case: All blocks are erased. */
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002571 memset(newcontents, ERASED_VALUE(flash), size);
hailfingerb437e282010-11-04 01:04:27 +00002572 /* Side effect of the assumptions above: Default write action is erase
2573 * because newcontents looks like a completely erased chip, and
Simon Glass4c214132013-07-16 10:09:28 -06002574 * oldcontents being completely unerased means we have to erase
2575 * everything before we can write.
hailfingerb437e282010-11-04 01:04:27 +00002576 */
2577
hailfingerd217d122010-10-08 18:52:29 +00002578 if (write_it || verify_it) {
David Hendricksdf29a832013-06-28 14:33:51 -07002579 /*
2580 * Note: This must be done before any files specified by -i
2581 * arguments are processed merged into the newcontents since
2582 * -i files take priority. See http://crbug.com/263495.
2583 */
2584 if (filename) {
2585 if (read_buf_from_file(newcontents, size, filename)) {
2586 ret = 1;
2587 goto out;
2588 }
2589 } else {
2590 /* Content will be read from -i args, so they must
2591 * not overlap. */
2592 if (included_regions_overlap()) {
2593 msg_gerr("Error: Included regions must "
2594 "not overlap.\n");
2595 ret = 1;
2596 goto out;
2597 }
stepan1da96c02006-11-21 23:48:51 +00002598 }
ollie5672ac62004-03-17 22:22:08 +00002599 }
2600
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002601 if (do_diff) {
2602 /*
2603 * Obtain a reference image so that we can check whether
2604 * regions need to be erased and to give better diagnostics in
2605 * case write fails. If --fast-verify is used then only the
2606 * regions which are included using -i will be read.
2607 */
2608 if (diff_file) {
2609 msg_cdbg("Reading old contents from file... ");
2610 if (read_buf_from_file(oldcontents, size, diff_file)) {
David Hendricks52ddff02013-07-23 15:05:14 -07002611 ret = 1;
2612 msg_cdbg("FAILED.\n");
2613 goto out;
2614 }
David Hendricksd4e712c2013-08-02 17:06:16 -07002615 } else {
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002616 msg_cdbg("Reading old contents from flash chip... ");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002617 ret = read_dest_content(flash, verify_it,
2618 oldcontents, size);
2619 if (ret) {
2620 msg_cdbg("FAILED.\n");
2621 goto out;
David Hendricks52ddff02013-07-23 15:05:14 -07002622 }
David Hendricksc44d7a02011-10-17 11:28:43 -07002623 }
Vadim Bendebury2f346a32018-05-21 10:24:18 -07002624 msg_cdbg("done.\n");
2625 } else if (!erase_it) {
2626 msg_pinfo("No diff performed, considering the chip erased.\n");
Edward O'Callaghanef783e32020-08-10 19:54:27 +10002627 memset(oldcontents, ERASED_VALUE(flash), size);
hailfinger4c47e9d2010-10-19 22:06:20 +00002628 }
David Hendricksac1d25c2016-08-09 17:00:58 -07002629
David Hendricksdf29a832013-06-28 14:33:51 -07002630 /*
2631 * Note: This must be done after reading the file specified for the
2632 * -w/-v argument, if any, so that files specified using -i end up
2633 * in the "newcontents" buffer before being written.
2634 * See http://crbug.com/263495.
2635 */
Edward O'Callaghana2f3e2a2020-07-26 16:49:30 +10002636 if (build_new_image(flash, oldcontents, newcontents, erase_it)) {
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002637 ret = 1;
David Hendricks5d8ea572013-07-26 14:03:05 -07002638 msg_cerr("Error handling ROM entries.\n");
Louis Yung-Chieh Lo404470d2011-09-06 16:59:40 +08002639 goto out;
2640 }
uwef6641642007-05-09 10:17:44 +00002641
David Hendricksa7e114b2016-02-26 18:49:15 -08002642 if (erase_it) {
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002643 erase_chip(flash, oldcontents, newcontents, size);
2644 goto verify;
David Hendricksa7e114b2016-02-26 18:49:15 -08002645 }
2646
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002647 descriptor = prepare_action_descriptor(flash, oldcontents,
2648 newcontents, do_diff);
stuge8ce3a3c2008-04-28 14:47:30 +00002649 if (write_it) {
David Hendricksb64b39a2016-10-11 13:48:06 -07002650 // parse the new fmap and disable soft WP if necessary
David Hendricksac1d25c2016-08-09 17:00:58 -07002651 if ((ret = cros_ec_prepare(newcontents, size))) {
David Hendricksb907de32014-08-11 16:47:09 -07002652 msg_cerr("CROS_EC prepare failed, ret=%d.\n", ret);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002653 goto out;
2654 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002655
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002656 if (erase_and_write_flash(flash, descriptor)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002657 msg_cerr("Uh oh. Erase/write failed. Checking if anything changed.\n");
2658 msg_cinfo("Reading current flash chip contents... ");
David Hendrickse3451942013-03-21 17:23:29 -07002659 if (!read_flash(flash, newcontents, 0, size)) {
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002660 msg_cinfo("done.\n");
hailfinger4c47e9d2010-10-19 22:06:20 +00002661 if (!memcmp(oldcontents, newcontents, size)) {
hailfinger4c47e9d2010-10-19 22:06:20 +00002662 nonfatal_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002663 ret = 1;
2664 goto out;
hailfinger4c47e9d2010-10-19 22:06:20 +00002665 }
Edward O'Callaghan23e7c4e2020-07-26 17:16:39 +10002666 msg_cerr("Apparently at least some data has changed.\n");
2667 } else
2668 msg_cerr("Can't even read anymore!\n");
hailfingerd217d122010-10-08 18:52:29 +00002669 emergency_help_message();
hailfinger90fcf9b2010-11-05 14:51:59 +00002670 ret = 1;
2671 goto out;
stuge8ce3a3c2008-04-28 14:47:30 +00002672 }
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002673
David Hendricksac1d25c2016-08-09 17:00:58 -07002674 ret = cros_ec_need_2nd_pass();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002675 if (ret < 0) {
2676 // Jump failed
David Hendricksb907de32014-08-11 16:47:09 -07002677 msg_cerr("cros_ec_need_2nd_pass() failed. Stop.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002678 emergency_help_message();
2679 ret = 1;
2680 goto out;
2681 } else if (ret > 0) {
2682 // Need 2nd pass. Get the just written content.
David Hendricksb907de32014-08-11 16:47:09 -07002683 msg_pdbg("CROS_EC needs 2nd pass.\n");
Daisuke Nojiri6d2cb212018-09-07 19:02:02 -07002684 ret = read_dest_content(flash, verify_it,
2685 oldcontents, size);
2686 if (ret) {
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002687 emergency_help_message();
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002688 goto out;
2689 }
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002690
2691 /* Get a new descriptor. */
2692 free(descriptor);
2693 descriptor = prepare_action_descriptor(flash,
2694 oldcontents,
2695 newcontents,
2696 do_diff);
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002697 // write 2nd pass
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002698 if (erase_and_write_flash(flash, descriptor)) {
David Hendricksb907de32014-08-11 16:47:09 -07002699 msg_cerr("Uh oh. CROS_EC 2nd pass failed.\n");
Louis Yung-Chieh Lo8d0971e2012-03-23 00:07:38 +08002700 emergency_help_message();
2701 ret = 1;
2702 goto out;
2703 }
2704 ret = 0;
2705 }
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002706
David Hendricksac1d25c2016-08-09 17:00:58 -07002707 if (cros_ec_finish() < 0) {
David Hendricksb907de32014-08-11 16:47:09 -07002708 msg_cerr("cros_ec_finish() failed. Stop.\n");
Louis Yung-Chieh Lodeefd822012-07-09 17:07:43 +08002709 emergency_help_message();
2710 ret = 1;
2711 goto out;
2712 }
stuge8ce3a3c2008-04-28 14:47:30 +00002713 }
ollie6a600992005-11-26 21:55:36 +00002714
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002715 verify:
hailfinger0459e1c2009-08-19 13:55:34 +00002716 if (verify_it) {
David Hendricks9ba79fb2015-04-03 12:06:16 -07002717 if ((write_it || erase_it) && !content_has_changed) {
2718 msg_gdbg("Nothing was erased or written, skipping "
2719 "verification\n");
2720 } else {
2721 /* Work around chips which need some time to calm down. */
2722 if (write_it && verify_it != VERIFY_PARTIAL)
2723 programmer_delay(1000*1000);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002724
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002725 ret = verify_flash(flash, descriptor, verify_it);
Louis Yung-Chieh Lo5d95f042011-09-01 17:33:06 +08002726
David Hendricks9ba79fb2015-04-03 12:06:16 -07002727 /* If we tried to write, and verification now fails, we
2728 * might have an emergency situation.
2729 */
2730 if (ret && write_it)
2731 emergency_help_message();
2732 }
hailfinger0459e1c2009-08-19 13:55:34 +00002733 }
ollie6a600992005-11-26 21:55:36 +00002734
Edward O'Callaghan12d8f832020-10-13 13:45:31 +11002735 finalize_flash_access(flash);
2736
hailfinger90fcf9b2010-11-05 14:51:59 +00002737out:
Vadim Bendebury2b4dcef2018-05-21 10:47:18 -07002738 if (descriptor)
2739 free(descriptor);
2740
hailfinger90fcf9b2010-11-05 14:51:59 +00002741 free(oldcontents);
2742 free(newcontents);
2743out_nofree:
David Hendricksbf36f092010-11-02 23:39:29 -07002744 chip_restore(); /* must be done before programmer_shutdown() */
David Hendricks668f29d2011-01-27 18:51:45 -08002745 /*
Edward O'Callaghan1a3fd132019-06-04 14:18:55 +10002746 * programmer_shutdown() call is moved to cli_classic() in chromium os
David Hendricks668f29d2011-01-27 18:51:45 -08002747 * tree. This is because some operations, such as write protection,
2748 * requires programmer_shutdown() but does not call doit().
2749 */
2750// programmer_shutdown();
stepan83eca252006-01-04 16:42:57 +00002751 return ret;
rminnich8d3ff912003-10-25 17:01:29 +00002752}