blob: e540027ca49ecb2c1d59c986d411ac1d8873aa07 [file] [log] [blame]
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001/*
Uwe Hermannd1107642007-08-29 17:52:32 +00002 * This file is part of the flashrom project.
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00003 *
Uwe Hermannd22a1d42007-09-09 20:21:05 +00004 * Copyright (C) 2000 Silicon Integrated System Corporation
5 * Copyright (C) 2004 Tyan Corp <yhlu@tyan.com>
Uwe Hermannc7e8a0c2009-05-19 14:14:21 +00006 * Copyright (C) 2005-2008 coresystems GmbH
Carl-Daniel Hailfinger03b4e712009-05-08 12:49:03 +00007 * Copyright (C) 2008,2009 Carl-Daniel Hailfinger
Nico Huber7af0e792016-04-29 16:40:15 +02008 * Copyright (C) 2016 secunet Security Networks AG
9 * (Written by Nico Huber <nico.huber@secunet.com> for secunet)
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +000010 *
Uwe Hermannd1107642007-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.
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +000015 *
Uwe Hermannd1107642007-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.
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +000020 */
21
Carl-Daniel Hailfinger831e8f42010-05-30 22:24:40 +000022#include <stdio.h>
Stefan Reinauer018aca82006-11-21 23:48:51 +000023#include <sys/types.h>
Patrick Georgia9095a92010-09-30 17:03:32 +000024#ifndef __LIBPAYLOAD__
25#include <fcntl.h>
Stefan Reinauer018aca82006-11-21 23:48:51 +000026#include <sys/stat.h>
Patrick Georgia9095a92010-09-30 17:03:32 +000027#endif
Ronald G. Minnichceec4202003-07-25 04:37:41 +000028#include <string.h>
Stefan Tauner16687702015-12-25 21:59:45 +000029#include <unistd.h>
Ronald G. Minnicheaab50b2003-09-12 22:41:53 +000030#include <stdlib.h>
Stefan Tauner363fd7e2013-04-07 13:08:30 +000031#include <errno.h>
Carl-Daniel Hailfingerc2441382010-11-09 22:00:31 +000032#include <ctype.h>
Ollie Lho184a4042005-11-26 21:55:36 +000033#include <getopt.h>
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +000034#if HAVE_UTSNAME == 1
35#include <sys/utsname.h>
36#endif
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +000037#include "flash.h"
Carl-Daniel Hailfinger08454642009-06-15 14:14:48 +000038#include "flashchips.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000039#include "programmer.h"
Carl-Daniel Hailfinger06b9efa2012-08-07 11:59:59 +000040#include "hwaccess.h"
Nico Huberfe34d2a2017-11-10 21:10:20 +010041#include "chipdrivers.h"
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +000042
Mathias Krausea60faab2011-01-17 07:50:42 +000043const char flashrom_version[] = FLASHROM_VERSION;
Nico Huberbcb2e5a2012-12-30 01:23:17 +000044const char *chip_to_probe = NULL;
Carl-Daniel Hailfinger66ef4e52009-12-13 22:28:00 +000045
Carl-Daniel Hailfinger2e681602011-09-08 00:00:29 +000046static enum programmer programmer = PROGRAMMER_INVALID;
Nico Huberbcb2e5a2012-12-30 01:23:17 +000047static const char *programmer_param = NULL;
Stefan Reinauer70385642007-04-06 11:58:03 +000048
Uwe Hermann48ec1b12010-08-08 17:01:18 +000049/*
Carl-Daniel Hailfinger66ef4e52009-12-13 22:28:00 +000050 * Programmers supporting multiple buses can have differing size limits on
51 * each bus. Store the limits for each bus in a common struct.
52 */
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +000053struct decode_sizes max_rom_decode;
54
55/* If nonzero, used as the start address of bottom-aligned flash. */
56unsigned long flashbase;
Carl-Daniel Hailfinger66ef4e52009-12-13 22:28:00 +000057
Carl-Daniel Hailfingerd1be52d2010-07-03 12:14:25 +000058/* Is writing allowed with this programmer? */
59int programmer_may_write;
60
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000061const struct programmer_entry programmer_table[] = {
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +000062#if CONFIG_INTERNAL == 1
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000063 {
Carl-Daniel Hailfinger37fc4692009-08-12 14:34:35 +000064 .name = "internal",
Stefan Tauneraf358d62012-12-27 18:40:26 +000065 .type = OTHER,
66 .devs.note = NULL,
Carl-Daniel Hailfinger1e334e62009-05-11 15:46:43 +000067 .init = internal_init,
Carl-Daniel Hailfinger1455b2b2009-05-11 14:13:25 +000068 .map_flash_region = physmap,
69 .unmap_flash_region = physunmap,
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +000070 .delay = internal_delay,
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000071 },
Carl-Daniel Hailfinger66ef4e52009-12-13 22:28:00 +000072#endif
Luc Verhaegen8e3a6002007-04-04 22:45:58 +000073
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +000074#if CONFIG_DUMMY == 1
Carl-Daniel Hailfingerc3129202009-05-09 00:54:55 +000075 {
Carl-Daniel Hailfinger37fc4692009-08-12 14:34:35 +000076 .name = "dummy",
Stefan Tauneraf358d62012-12-27 18:40:26 +000077 .type = OTHER,
78 /* FIXME */
79 .devs.note = "Dummy device, does nothing and logs all accesses\n",
Carl-Daniel Hailfinger1e334e62009-05-11 15:46:43 +000080 .init = dummy_init,
Carl-Daniel Hailfinger1455b2b2009-05-11 14:13:25 +000081 .map_flash_region = dummy_map,
82 .unmap_flash_region = dummy_unmap,
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +000083 .delay = internal_delay,
Carl-Daniel Hailfingerc3129202009-05-09 00:54:55 +000084 },
Carl-Daniel Hailfinger4740c6f2009-09-16 10:09:21 +000085#endif
Carl-Daniel Hailfingerc3129202009-05-09 00:54:55 +000086
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +000087#if CONFIG_NIC3COM == 1
Uwe Hermannb4dcb712009-05-13 11:36:06 +000088 {
Carl-Daniel Hailfinger37fc4692009-08-12 14:34:35 +000089 .name = "nic3com",
Stefan Tauneraf358d62012-12-27 18:40:26 +000090 .type = PCI,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +000091 .devs.dev = nics_3com,
Uwe Hermannb4dcb712009-05-13 11:36:06 +000092 .init = nic3com_init,
Uwe Hermannc6915932009-05-17 23:12:17 +000093 .map_flash_region = fallback_map,
94 .unmap_flash_region = fallback_unmap,
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +000095 .delay = internal_delay,
Uwe Hermannb4dcb712009-05-13 11:36:06 +000096 },
Carl-Daniel Hailfinger4740c6f2009-09-16 10:09:21 +000097#endif
Uwe Hermannb4dcb712009-05-13 11:36:06 +000098
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +000099#if CONFIG_NICREALTEK == 1
Joerg Fischer5665ef32010-05-21 21:54:07 +0000100 {
Carl-Daniel Hailfinger40446ee2011-03-07 01:08:09 +0000101 /* This programmer works for Realtek RTL8139 and SMC 1211. */
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000102 .name = "nicrealtek",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000103 .type = PCI,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000104 .devs.dev = nics_realtek,
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000105 .init = nicrealtek_init,
106 .map_flash_region = fallback_map,
107 .unmap_flash_region = fallback_unmap,
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000108 .delay = internal_delay,
Joerg Fischer5665ef32010-05-21 21:54:07 +0000109 },
Joerg Fischer5665ef32010-05-21 21:54:07 +0000110#endif
111
Andrew Morganc29c2e72010-06-07 22:37:54 +0000112#if CONFIG_NICNATSEMI == 1
113 {
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000114 .name = "nicnatsemi",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000115 .type = PCI,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000116 .devs.dev = nics_natsemi,
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000117 .init = nicnatsemi_init,
118 .map_flash_region = fallback_map,
119 .unmap_flash_region = fallback_unmap,
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000120 .delay = internal_delay,
Andrew Morganc29c2e72010-06-07 22:37:54 +0000121 },
122#endif
Joerg Fischer5665ef32010-05-21 21:54:07 +0000123
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000124#if CONFIG_GFXNVIDIA == 1
Uwe Hermann2bc98f62009-09-30 18:29:55 +0000125 {
126 .name = "gfxnvidia",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000127 .type = PCI,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000128 .devs.dev = gfx_nvidia,
Uwe Hermann2bc98f62009-09-30 18:29:55 +0000129 .init = gfxnvidia_init,
Uwe Hermann2bc98f62009-09-30 18:29:55 +0000130 .map_flash_region = fallback_map,
131 .unmap_flash_region = fallback_unmap,
Uwe Hermann2bc98f62009-09-30 18:29:55 +0000132 .delay = internal_delay,
133 },
134#endif
135
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000136#if CONFIG_DRKAISER == 1
Rudolf Marek68720c72009-05-17 19:39:27 +0000137 {
TURBO Jb0912c02009-09-02 23:00:46 +0000138 .name = "drkaiser",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000139 .type = PCI,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000140 .devs.dev = drkaiser_pcidev,
TURBO Jb0912c02009-09-02 23:00:46 +0000141 .init = drkaiser_init,
TURBO Jb0912c02009-09-02 23:00:46 +0000142 .map_flash_region = fallback_map,
143 .unmap_flash_region = fallback_unmap,
TURBO Jb0912c02009-09-02 23:00:46 +0000144 .delay = internal_delay,
145 },
Carl-Daniel Hailfinger4740c6f2009-09-16 10:09:21 +0000146#endif
TURBO Jb0912c02009-09-02 23:00:46 +0000147
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000148#if CONFIG_SATASII == 1
TURBO Jb0912c02009-09-02 23:00:46 +0000149 {
Carl-Daniel Hailfinger37fc4692009-08-12 14:34:35 +0000150 .name = "satasii",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000151 .type = PCI,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000152 .devs.dev = satas_sii,
Rudolf Marek68720c72009-05-17 19:39:27 +0000153 .init = satasii_init,
Uwe Hermannc6915932009-05-17 23:12:17 +0000154 .map_flash_region = fallback_map,
155 .unmap_flash_region = fallback_unmap,
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000156 .delay = internal_delay,
Rudolf Marek68720c72009-05-17 19:39:27 +0000157 },
Carl-Daniel Hailfinger4740c6f2009-09-16 10:09:21 +0000158#endif
Rudolf Marek68720c72009-05-17 19:39:27 +0000159
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000160#if CONFIG_ATAHPT == 1
Uwe Hermannddd5c9e2010-02-21 21:17:00 +0000161 {
162 .name = "atahpt",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000163 .type = PCI,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000164 .devs.dev = ata_hpt,
Uwe Hermannddd5c9e2010-02-21 21:17:00 +0000165 .init = atahpt_init,
Uwe Hermannddd5c9e2010-02-21 21:17:00 +0000166 .map_flash_region = fallback_map,
167 .unmap_flash_region = fallback_unmap,
Uwe Hermannddd5c9e2010-02-21 21:17:00 +0000168 .delay = internal_delay,
169 },
170#endif
171
Jonathan Kollasch7f0f3fa2014-06-01 10:26:23 +0000172#if CONFIG_ATAVIA == 1
173 {
174 .name = "atavia",
175 .type = PCI,
176 .devs.dev = ata_via,
177 .init = atavia_init,
178 .map_flash_region = atavia_map,
179 .unmap_flash_region = fallback_unmap,
180 .delay = internal_delay,
181 },
182#endif
183
Joseph C. Lehnerc2644a32016-01-16 23:45:25 +0000184#if CONFIG_ATAPROMISE == 1
185 {
186 .name = "atapromise",
187 .type = PCI,
188 .devs.dev = ata_promise,
189 .init = atapromise_init,
190 .map_flash_region = atapromise_map,
191 .unmap_flash_region = fallback_unmap,
192 .delay = internal_delay,
193 },
194#endif
195
Kyösti Mälkki72d42f82014-06-01 23:48:31 +0000196#if CONFIG_IT8212 == 1
197 {
198 .name = "it8212",
199 .type = PCI,
200 .devs.dev = devs_it8212,
201 .init = it8212_init,
202 .map_flash_region = fallback_map,
203 .unmap_flash_region = fallback_unmap,
204 .delay = internal_delay,
205 },
206#endif
207
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000208#if CONFIG_FT2232_SPI == 1
Paul Fox05dfbe62009-06-16 21:08:06 +0000209 {
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000210 .name = "ft2232_spi",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000211 .type = USB,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000212 .devs.dev = devs_ft2232spi,
Paul Fox05dfbe62009-06-16 21:08:06 +0000213 .init = ft2232_spi_init,
Carl-Daniel Hailfinger415e5132009-08-12 11:39:29 +0000214 .map_flash_region = fallback_map,
215 .unmap_flash_region = fallback_unmap,
Paul Fox05dfbe62009-06-16 21:08:06 +0000216 .delay = internal_delay,
217 },
Carl-Daniel Hailfinger3426ef62009-08-19 13:27:58 +0000218#endif
Carl-Daniel Hailfinger415e5132009-08-12 11:39:29 +0000219
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000220#if CONFIG_SERPROG == 1
Urja Rannikko22915352009-06-23 11:33:43 +0000221 {
Carl-Daniel Hailfinger37fc4692009-08-12 14:34:35 +0000222 .name = "serprog",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000223 .type = OTHER,
224 /* FIXME */
225 .devs.note = "All programmer devices speaking the serprog protocol\n",
Urja Rannikko22915352009-06-23 11:33:43 +0000226 .init = serprog_init,
Urja Rannikko0b4ffd52015-06-29 23:24:23 +0000227 .map_flash_region = serprog_map,
Urja Rannikko22915352009-06-23 11:33:43 +0000228 .unmap_flash_region = fallback_unmap,
Urja Rannikko22915352009-06-23 11:33:43 +0000229 .delay = serprog_delay,
230 },
Carl-Daniel Hailfinger6be74112009-08-12 16:17:41 +0000231#endif
Paul Fox05dfbe62009-06-16 21:08:06 +0000232
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000233#if CONFIG_BUSPIRATE_SPI == 1
Carl-Daniel Hailfinger5cca01f2009-11-24 00:20:03 +0000234 {
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000235 .name = "buspirate_spi",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000236 .type = OTHER,
237 /* FIXME */
238 .devs.note = "Dangerous Prototypes Bus Pirate\n",
Carl-Daniel Hailfinger5cca01f2009-11-24 00:20:03 +0000239 .init = buspirate_spi_init,
Carl-Daniel Hailfinger5cca01f2009-11-24 00:20:03 +0000240 .map_flash_region = fallback_map,
241 .unmap_flash_region = fallback_unmap,
Carl-Daniel Hailfinger5cca01f2009-11-24 00:20:03 +0000242 .delay = internal_delay,
243 },
244#endif
245
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000246#if CONFIG_DEDIPROG == 1
Carl-Daniel Hailfingerd38fac82010-01-19 11:15:48 +0000247 {
248 .name = "dediprog",
Stefan Taunerfdec7472016-02-22 08:59:27 +0000249 .type = USB,
250 .devs.dev = devs_dediprog,
Carl-Daniel Hailfingerd38fac82010-01-19 11:15:48 +0000251 .init = dediprog_init,
Carl-Daniel Hailfingerd38fac82010-01-19 11:15:48 +0000252 .map_flash_region = fallback_map,
253 .unmap_flash_region = fallback_unmap,
Carl-Daniel Hailfingerd38fac82010-01-19 11:15:48 +0000254 .delay = internal_delay,
255 },
256#endif
257
Daniel Thompson45e91a22018-06-04 13:46:29 +0100258#if CONFIG_DEVELOPERBOX_SPI == 1
259 {
260 .name = "developerbox",
261 .type = USB,
262 .devs.dev = devs_developerbox_spi,
263 .init = developerbox_spi_init,
264 .map_flash_region = fallback_map,
265 .unmap_flash_region = fallback_unmap,
266 .delay = internal_delay,
267 },
268#endif
269
Carl-Daniel Hailfingere7fdd6e2010-07-21 10:26:01 +0000270#if CONFIG_RAYER_SPI == 1
271 {
272 .name = "rayer_spi",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000273 .type = OTHER,
274 /* FIXME */
275 .devs.note = "RayeR parallel port programmer\n",
Carl-Daniel Hailfingere7fdd6e2010-07-21 10:26:01 +0000276 .init = rayer_spi_init,
Carl-Daniel Hailfingere7fdd6e2010-07-21 10:26:01 +0000277 .map_flash_region = fallback_map,
278 .unmap_flash_region = fallback_unmap,
Carl-Daniel Hailfingere7fdd6e2010-07-21 10:26:01 +0000279 .delay = internal_delay,
280 },
281#endif
282
Virgil-Adrian Teacada7c5452012-04-30 23:11:06 +0000283#if CONFIG_PONY_SPI == 1
284 {
285 .name = "pony_spi",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000286 .type = OTHER,
287 /* FIXME */
288 .devs.note = "Programmers compatible with SI-Prog, serbang or AJAWe\n",
Virgil-Adrian Teacada7c5452012-04-30 23:11:06 +0000289 .init = pony_spi_init,
290 .map_flash_region = fallback_map,
291 .unmap_flash_region = fallback_unmap,
292 .delay = internal_delay,
Stefan Tauneraf358d62012-12-27 18:40:26 +0000293 },
Virgil-Adrian Teacada7c5452012-04-30 23:11:06 +0000294#endif
295
Carl-Daniel Hailfingerb713d2e2011-05-08 00:24:18 +0000296#if CONFIG_NICINTEL == 1
297 {
298 .name = "nicintel",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000299 .type = PCI,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000300 .devs.dev = nics_intel,
Carl-Daniel Hailfingerb713d2e2011-05-08 00:24:18 +0000301 .init = nicintel_init,
Carl-Daniel Hailfingerb713d2e2011-05-08 00:24:18 +0000302 .map_flash_region = fallback_map,
303 .unmap_flash_region = fallback_unmap,
Carl-Daniel Hailfingerb713d2e2011-05-08 00:24:18 +0000304 .delay = internal_delay,
305 },
306#endif
307
Idwer Vollering004f4b72010-09-03 18:21:21 +0000308#if CONFIG_NICINTEL_SPI == 1
309 {
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000310 .name = "nicintel_spi",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000311 .type = PCI,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000312 .devs.dev = nics_intel_spi,
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000313 .init = nicintel_spi_init,
314 .map_flash_region = fallback_map,
315 .unmap_flash_region = fallback_unmap,
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000316 .delay = internal_delay,
Idwer Vollering004f4b72010-09-03 18:21:21 +0000317 },
318#endif
319
Ricardo Ribalda Delgado2a41f0a2014-07-28 20:35:21 +0000320#if CONFIG_NICINTEL_EEPROM == 1
321 {
322 .name = "nicintel_eeprom",
323 .type = PCI,
324 .devs.dev = nics_intel_ee,
325 .init = nicintel_ee_init,
326 .map_flash_region = fallback_map,
327 .unmap_flash_region = fallback_unmap,
328 .delay = internal_delay,
329 },
330#endif
331
Mark Marshall90021f22010-12-03 14:48:11 +0000332#if CONFIG_OGP_SPI == 1
333 {
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000334 .name = "ogp_spi",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000335 .type = PCI,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000336 .devs.dev = ogp_spi,
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000337 .init = ogp_spi_init,
338 .map_flash_region = fallback_map,
339 .unmap_flash_region = fallback_unmap,
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000340 .delay = internal_delay,
Mark Marshall90021f22010-12-03 14:48:11 +0000341 },
342#endif
343
Carl-Daniel Hailfinger9a1105c2011-02-04 21:37:59 +0000344#if CONFIG_SATAMV == 1
345 {
346 .name = "satamv",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000347 .type = PCI,
Stefan Tauner4b24a2d2012-12-27 18:40:36 +0000348 .devs.dev = satas_mv,
Carl-Daniel Hailfinger9a1105c2011-02-04 21:37:59 +0000349 .init = satamv_init,
Carl-Daniel Hailfinger9a1105c2011-02-04 21:37:59 +0000350 .map_flash_region = fallback_map,
351 .unmap_flash_region = fallback_unmap,
Carl-Daniel Hailfinger9a1105c2011-02-04 21:37:59 +0000352 .delay = internal_delay,
353 },
354#endif
355
David Hendricksf9a30552015-05-23 20:30:30 -0700356#if CONFIG_LINUX_MTD == 1
357 {
358 .name = "linux_mtd",
359 .type = OTHER,
360 .devs.note = "Device files /dev/mtd*\n",
361 .init = linux_mtd_init,
362 .map_flash_region = fallback_map,
363 .unmap_flash_region = fallback_unmap,
364 .delay = internal_delay,
365 },
366#endif
367
Sven Schnelle5ce5f702011-09-03 18:37:52 +0000368#if CONFIG_LINUX_SPI == 1
369 {
370 .name = "linux_spi",
Stefan Tauneraf358d62012-12-27 18:40:26 +0000371 .type = OTHER,
372 .devs.note = "Device files /dev/spidev*.*\n",
Sven Schnelle5ce5f702011-09-03 18:37:52 +0000373 .init = linux_spi_init,
374 .map_flash_region = fallback_map,
375 .unmap_flash_region = fallback_unmap,
Sven Schnelle5ce5f702011-09-03 18:37:52 +0000376 .delay = internal_delay,
377 },
378#endif
379
James Lairdc60de0e2013-03-27 13:00:23 +0000380#if CONFIG_USBBLASTER_SPI == 1
381 {
382 .name = "usbblaster_spi",
383 .type = USB,
384 .devs.dev = devs_usbblasterspi,
385 .init = usbblaster_spi_init,
386 .map_flash_region = fallback_map,
387 .unmap_flash_region = fallback_unmap,
388 .delay = internal_delay,
389 },
390#endif
391
Alexandre Boeglin80e64712014-12-20 20:25:19 +0000392#if CONFIG_MSTARDDC_SPI == 1
393 {
394 .name = "mstarddc_spi",
395 .type = OTHER,
396 .devs.note = "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
397 .init = mstarddc_spi_init,
398 .map_flash_region = fallback_map,
399 .unmap_flash_region = fallback_unmap,
400 .delay = internal_delay,
401 },
402#endif
403
Justin Chevrier66e554b2015-02-08 21:58:10 +0000404#if CONFIG_PICKIT2_SPI == 1
405 {
406 .name = "pickit2_spi",
Stefan Taunerf31fe842016-02-22 08:59:15 +0000407 .type = USB,
408 .devs.dev = devs_pickit2_spi,
Justin Chevrier66e554b2015-02-08 21:58:10 +0000409 .init = pickit2_spi_init,
410 .map_flash_region = fallback_map,
411 .unmap_flash_region = fallback_unmap,
412 .delay = internal_delay,
413 },
414#endif
415
Urja Rannikko0870b022016-01-31 22:10:29 +0000416#if CONFIG_CH341A_SPI == 1
417 {
418 .name = "ch341a_spi",
419 .type = USB,
420 .devs.dev = devs_ch341a_spi,
421 .init = ch341a_spi_init,
422 .map_flash_region = fallback_map,
423 .unmap_flash_region = fallback_unmap,
424 .delay = ch341a_spi_delay,
425 },
426#endif
427
Lubomir Rintelb2154e82018-01-14 17:35:33 +0100428#if CONFIG_DIGILENT_SPI == 1
429 {
430 .name = "digilent_spi",
431 .type = USB,
432 .devs.dev = devs_digilent_spi,
433 .init = digilent_spi_init,
434 .map_flash_region = fallback_map,
435 .unmap_flash_region = fallback_unmap,
436 .delay = internal_delay,
437 },
438#endif
439
Marc Schink3578ec62016-03-17 16:23:03 +0100440#if CONFIG_JLINK_SPI == 1
441 {
442 .name = "jlink_spi",
443 .type = OTHER,
444 .init = jlink_spi_init,
445 .devs.note = "SEGGER J-Link and compatible devices\n",
446 .map_flash_region = fallback_map,
447 .unmap_flash_region = fallback_unmap,
448 .delay = internal_delay,
449 },
450#endif
451
Miklós Márton2d20d6d2018-01-30 20:20:15 +0100452#if CONFIG_NI845X_SPI == 1
453 {
454 .name = "ni845x_spi",
455 .type = OTHER, // choose other because NI-845x uses own USB implementation
456 .devs.note = "National Instruments USB-845x\n",
457 .init = ni845x_spi_init,
458 .map_flash_region = fallback_map,
459 .unmap_flash_region = fallback_unmap,
460 .delay = internal_delay,
461 },
462#endif
Miklós Márton324929c2019-08-01 19:14:10 +0200463
464#if CONFIG_STLINKV3_SPI == 1
465 {
466 .name = "stlinkv3_spi",
467 .type = USB,
468 .devs.dev = devs_stlinkv3_spi,
469 .init = stlinkv3_spi_init,
470 .map_flash_region = fallback_map,
471 .unmap_flash_region = fallback_unmap,
472 .delay = internal_delay,
473 },
474#endif
475
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +0000476 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000477};
Luc Verhaegen8e3a6002007-04-04 22:45:58 +0000478
Carl-Daniel Hailfinger2bee8cf2010-11-10 15:25:18 +0000479#define SHUTDOWN_MAXFN 32
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000480static int shutdown_fn_count = 0;
Nico Huber454f6132012-12-10 13:34:10 +0000481/** @private */
Richard Hughes93e16252018-12-19 11:54:47 +0000482static struct shutdown_func_data {
David Hendricks8bb20212011-06-14 01:35:36 +0000483 int (*func) (void *data);
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000484 void *data;
Richard Hughes93e16252018-12-19 11:54:47 +0000485} shutdown_fn[SHUTDOWN_MAXFN];
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000486/* Initialize to 0 to make sure nobody registers a shutdown function before
487 * programmer init.
488 */
489static int may_register_shutdown = 0;
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000490
Stefan Taunerc4f44df2013-08-12 22:58:43 +0000491/* Did we change something or was every erase/write skipped (if any)? */
492static bool all_skipped = true;
493
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000494static int check_block_eraser(const struct flashctx *flash, int k, int log);
Stefan Tauner5368dca2011-07-01 00:19:12 +0000495
Stefan Tauner2a1ed772014-08-31 00:09:21 +0000496int shutdown_free(void *data)
497{
498 free(data);
499 return 0;
500}
501
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000502/* Register a function to be executed on programmer shutdown.
503 * The advantage over atexit() is that you can supply a void pointer which will
504 * be used as parameter to the registered function upon programmer shutdown.
505 * This pointer can point to arbitrary data used by said function, e.g. undo
506 * information for GPIO settings etc. If unneeded, set data=NULL.
507 * Please note that the first (void *data) belongs to the function signature of
508 * the function passed as first parameter.
509 */
David Hendricks8bb20212011-06-14 01:35:36 +0000510int register_shutdown(int (*function) (void *data), void *data)
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000511{
512 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
Carl-Daniel Hailfinger9f5f2152010-06-04 23:20:21 +0000513 msg_perr("Tried to register more than %i shutdown functions.\n",
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000514 SHUTDOWN_MAXFN);
515 return 1;
516 }
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000517 if (!may_register_shutdown) {
518 msg_perr("Tried to register a shutdown function before "
519 "programmer init.\n");
520 return 1;
521 }
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000522 shutdown_fn[shutdown_fn_count].func = function;
523 shutdown_fn[shutdown_fn_count].data = data;
524 shutdown_fn_count++;
525
526 return 0;
527}
528
Nico Huberbcb2e5a2012-12-30 01:23:17 +0000529int programmer_init(enum programmer prog, const char *param)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000530{
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000531 int ret;
Carl-Daniel Hailfinger2e681602011-09-08 00:00:29 +0000532
533 if (prog >= PROGRAMMER_INVALID) {
534 msg_perr("Invalid programmer specified!\n");
535 return -1;
536 }
537 programmer = prog;
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000538 /* Initialize all programmer specific data. */
539 /* Default to unlimited decode sizes. */
540 max_rom_decode = (const struct decode_sizes) {
541 .parallel = 0xffffffff,
542 .lpc = 0xffffffff,
543 .fwh = 0xffffffff,
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000544 .spi = 0xffffffff,
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000545 };
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000546 /* Default to top aligned flash at 4 GB. */
547 flashbase = 0;
548 /* Registering shutdown functions is now allowed. */
549 may_register_shutdown = 1;
Carl-Daniel Hailfingerd1be52d2010-07-03 12:14:25 +0000550 /* Default to allowing writes. Broken programmers set this to 0. */
551 programmer_may_write = 1;
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000552
553 programmer_param = param;
Carl-Daniel Hailfinger20a36ba2013-08-13 07:09:57 +0000554 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000555 ret = programmer_table[programmer].init();
556 if (programmer_param && strlen(programmer_param)) {
Carl-Daniel Hailfinger20a36ba2013-08-13 07:09:57 +0000557 if (ret != 0) {
558 /* It is quite possible that any unhandled programmer parameter would have been valid,
559 * but an error in actual programmer init happened before the parameter was evaluated.
560 */
561 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
562 programmer_param);
563 } else {
564 /* Actual programmer init was successful, but the user specified an invalid or unusable
565 * (for the current programmer configuration) parameter.
566 */
567 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
568 msg_perr("Aborting.\n");
569 ret = ERROR_FATAL;
570 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000571 }
572 return ret;
Uwe Hermann09e04f72009-05-16 22:36:00 +0000573}
574
Stefan Tauner20da4aa2014-05-07 22:07:23 +0000575/** Calls registered shutdown functions and resets internal programmer-related variables.
576 * Calling it is safe even without previous initialization, but further interactions with programmer support
577 * require a call to programmer_init() (afterwards).
578 *
579 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
Uwe Hermann09e04f72009-05-16 22:36:00 +0000580int programmer_shutdown(void)
581{
David Hendricks8bb20212011-06-14 01:35:36 +0000582 int ret = 0;
583
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000584 /* Registering shutdown functions is no longer allowed. */
585 may_register_shutdown = 0;
586 while (shutdown_fn_count > 0) {
587 int i = --shutdown_fn_count;
David Hendricks8bb20212011-06-14 01:35:36 +0000588 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000589 }
Stefan Taunere34e3e82013-01-01 00:06:51 +0000590
Stefan Taunerb8911d62012-12-26 07:55:00 +0000591 programmer_param = NULL;
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000592 registered_master_count = 0;
Stefan Taunere34e3e82013-01-01 00:06:51 +0000593
David Hendricks8bb20212011-06-14 01:35:36 +0000594 return ret;
Uwe Hermann09e04f72009-05-16 22:36:00 +0000595}
596
Stefan Tauner305e0b92013-07-17 23:46:44 +0000597void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000598{
Stefan Tauner26e7a152013-09-13 17:21:05 +0000599 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
600 msg_gspew("%s: mapping %s from 0x%0*" PRIxPTR " to 0x%0*" PRIxPTR "\n",
601 __func__, descr, PRIxPTR_WIDTH, phys_addr, PRIxPTR_WIDTH, (uintptr_t) ret);
602 return ret;
Uwe Hermann09e04f72009-05-16 22:36:00 +0000603}
604
605void programmer_unmap_flash_region(void *virt_addr, size_t len)
606{
607 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Stefan Tauner4e32ec12014-08-30 23:39:51 +0000608 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000609}
610
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000611void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000612{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000613 flash->mst->par.chip_writeb(flash, val, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000614}
615
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000616void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000617{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000618 flash->mst->par.chip_writew(flash, val, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000619}
620
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000621void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000622{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000623 flash->mst->par.chip_writel(flash, val, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000624}
625
Mark Marshallf20b7be2014-05-09 21:16:21 +0000626void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000627{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000628 flash->mst->par.chip_writen(flash, buf, addr, len);
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000629}
630
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000631uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000632{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000633 return flash->mst->par.chip_readb(flash, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000634}
635
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000636uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000637{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000638 return flash->mst->par.chip_readw(flash, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000639}
640
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000641uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000642{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000643 return flash->mst->par.chip_readl(flash, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000644}
645
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000646void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
647 size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000648{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000649 flash->mst->par.chip_readn(flash, buf, addr, len);
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000650}
651
Stefan Taunerf80419c2014-05-02 15:41:42 +0000652void programmer_delay(unsigned int usecs)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000653{
Urja Rannikko8d7ec2a2013-10-21 21:49:08 +0000654 if (usecs > 0)
655 programmer_table[programmer].delay(usecs);
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000656}
657
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000658int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
659 int unsigned len)
Carl-Daniel Hailfinger03b4e712009-05-08 12:49:03 +0000660{
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000661 chip_readn(flash, buf, flash->virtual_memory + start, len);
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000662
Carl-Daniel Hailfinger03b4e712009-05-08 12:49:03 +0000663 return 0;
664}
665
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000666/* This is a somewhat hacked function similar in some ways to strtok().
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000667 * It will look for needle with a subsequent '=' in haystack, return a copy of
668 * needle and remove everything from the first occurrence of needle to the next
669 * delimiter from haystack.
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000670 */
Nico Huberbcb2e5a2012-12-30 01:23:17 +0000671char *extract_param(const char *const *haystack, const char *needle, const char *delim)
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000672{
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000673 char *param_pos, *opt_pos, *rest;
674 char *opt = NULL;
675 int optlen;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000676 int needlelen;
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000677
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000678 needlelen = strlen(needle);
679 if (!needlelen) {
680 msg_gerr("%s: empty needle! Please report a bug at "
681 "flashrom@flashrom.org\n", __func__);
682 return NULL;
683 }
684 /* No programmer parameters given. */
685 if (*haystack == NULL)
686 return NULL;
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000687 param_pos = strstr(*haystack, needle);
688 do {
689 if (!param_pos)
690 return NULL;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000691 /* Needle followed by '='? */
692 if (param_pos[needlelen] == '=') {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000693 /* Beginning of the string? */
694 if (param_pos == *haystack)
695 break;
696 /* After a delimiter? */
697 if (strchr(delim, *(param_pos - 1)))
698 break;
699 }
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000700 /* Continue searching. */
701 param_pos++;
702 param_pos = strstr(param_pos, needle);
703 } while (1);
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000704
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000705 if (param_pos) {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000706 /* Get the string after needle and '='. */
707 opt_pos = param_pos + needlelen + 1;
708 optlen = strcspn(opt_pos, delim);
709 /* Return an empty string if the parameter was empty. */
710 opt = malloc(optlen + 1);
711 if (!opt) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000712 msg_gerr("Out of memory!\n");
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000713 exit(1);
714 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000715 strncpy(opt, opt_pos, optlen);
716 opt[optlen] = '\0';
717 rest = opt_pos + optlen;
718 /* Skip all delimiters after the current parameter. */
719 rest += strspn(rest, delim);
720 memmove(param_pos, rest, strlen(rest) + 1);
721 /* We could shrink haystack, but the effort is not worth it. */
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000722 }
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000723
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000724 return opt;
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000725}
726
Stefan Tauner66652442011-06-26 17:38:17 +0000727char *extract_programmer_param(const char *param_name)
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000728{
729 return extract_param(&programmer_param, param_name, ",");
730}
731
Sylvain "ythier" Hitier9db45512011-07-04 07:27:17 +0000732/* Returns the number of well-defined erasers for a chip. */
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000733static unsigned int count_usable_erasers(const struct flashctx *flash)
Stefan Tauner5368dca2011-07-01 00:19:12 +0000734{
735 unsigned int usable_erasefunctions = 0;
736 int k;
737 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
738 if (!check_block_eraser(flash, k, 0))
739 usable_erasefunctions++;
740 }
741 return usable_erasefunctions;
742}
743
Mark Marshallf20b7be2014-05-09 21:16:21 +0000744static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Stefan Tauner78ffbea2012-10-27 15:36:56 +0000745{
746 int ret = 0, failcount = 0;
747 unsigned int i;
748 for (i = 0; i < len; i++) {
749 if (wantbuf[i] != havebuf[i]) {
750 /* Only print the first failure. */
751 if (!failcount++)
752 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
753 start + i, wantbuf[i], havebuf[i]);
754 }
755 }
756 if (failcount) {
757 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
758 start, start + len - 1, failcount);
759 ret = -1;
760 }
761 return ret;
762}
763
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000764/* start is an offset to the base address of the flash chip */
Jacob Garberbeeb8bc2019-06-21 15:24:17 -0600765static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000766{
767 int ret;
768 uint8_t *cmpbuf = malloc(len);
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300769 const uint8_t erased_value = ERASED_VALUE(flash);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000770
771 if (!cmpbuf) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000772 msg_gerr("Could not allocate memory!\n");
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000773 exit(1);
774 }
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300775 memset(cmpbuf, erased_value, len);
Stefan Tauner78ffbea2012-10-27 15:36:56 +0000776 ret = verify_range(flash, cmpbuf, start, len);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000777 free(cmpbuf);
778 return ret;
779}
780
Uwe Hermann48ec1b12010-08-08 17:01:18 +0000781/*
Carl-Daniel Hailfingerd0250a32009-11-25 17:05:52 +0000782 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000783 * flash content at location start
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000784 * @start offset to the base address of the flash chip
785 * @len length of the verified area
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000786 * @return 0 for success, -1 for failure
787 */
Mark Marshallf20b7be2014-05-09 21:16:21 +0000788int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000789{
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000790 if (!len)
Stefan Taunerdf64a422014-05-27 00:06:14 +0000791 return -1;
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000792
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000793 if (!flash->chip->read) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000794 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Stefan Taunerdf64a422014-05-27 00:06:14 +0000795 return -1;
Carl-Daniel Hailfinger23290662009-06-24 08:20:45 +0000796 }
Stefan Taunerdf64a422014-05-27 00:06:14 +0000797
798 uint8_t *readbuf = malloc(len);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000799 if (!readbuf) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000800 msg_gerr("Could not allocate memory!\n");
Stefan Taunerdf64a422014-05-27 00:06:14 +0000801 return -1;
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000802 }
Stefan Taunerdf64a422014-05-27 00:06:14 +0000803 int ret = 0;
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000804
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000805 if (start + len > flash->chip->total_size * 1024) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000806 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000807 " total_size 0x%x\n", __func__, start, len,
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000808 flash->chip->total_size * 1024);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000809 ret = -1;
810 goto out_free;
811 }
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000812
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000813 ret = flash->chip->read(flash, readbuf, start, len);
Carl-Daniel Hailfingerd8369412010-11-16 17:21:58 +0000814 if (ret) {
815 msg_gerr("Verification impossible because read failed "
816 "at 0x%x (len 0x%x)\n", start, len);
Stefan Taunerdf64a422014-05-27 00:06:14 +0000817 ret = -1;
818 goto out_free;
Carl-Daniel Hailfingerd8369412010-11-16 17:21:58 +0000819 }
820
Stefan Tauner78ffbea2012-10-27 15:36:56 +0000821 ret = compare_range(cmpbuf, readbuf, start, len);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000822out_free:
823 free(readbuf);
824 return ret;
825}
826
Stefan Tauner02437452013-04-01 19:34:53 +0000827/* Helper function for need_erase() that focuses on granularities of gran bytes. */
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300828static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
829 unsigned int gran, const uint8_t erased_value)
Stefan Tauner02437452013-04-01 19:34:53 +0000830{
831 unsigned int i, j, limit;
832 for (j = 0; j < len / gran; j++) {
833 limit = min (gran, len - j * gran);
834 /* Are 'have' and 'want' identical? */
835 if (!memcmp(have + j * gran, want + j * gran, limit))
836 continue;
837 /* have needs to be in erased state. */
838 for (i = 0; i < limit; i++)
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300839 if (have[j * gran + i] != erased_value)
Stefan Tauner02437452013-04-01 19:34:53 +0000840 return 1;
841 }
842 return 0;
843}
844
Uwe Hermann48ec1b12010-08-08 17:01:18 +0000845/*
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000846 * Check if the buffer @have can be programmed to the content of @want without
847 * erasing. This is only possible if all chunks of size @gran are either kept
848 * as-is or changed from an all-ones state to any other state.
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000849 *
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000850 * Warning: This function assumes that @have and @want point to naturally
851 * aligned regions.
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000852 *
853 * @have buffer with current content
854 * @want buffer with desired content
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000855 * @len length of the checked area
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000856 * @gran write granularity (enum, not count)
857 * @return 0 if no erase is needed, 1 otherwise
858 */
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300859int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
860 enum write_granularity gran, const uint8_t erased_value)
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000861{
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +0000862 int result = 0;
Stefan Tauner02437452013-04-01 19:34:53 +0000863 unsigned int i;
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000864
865 switch (gran) {
866 case write_gran_1bit:
867 for (i = 0; i < len; i++)
868 if ((have[i] & want[i]) != want[i]) {
869 result = 1;
870 break;
871 }
872 break;
873 case write_gran_1byte:
874 for (i = 0; i < len; i++)
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300875 if ((have[i] != want[i]) && (have[i] != erased_value)) {
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000876 result = 1;
877 break;
878 }
879 break;
Paul Kocialkowskic8305e12015-10-16 02:16:20 +0000880 case write_gran_128bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300881 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Paul Kocialkowskic8305e12015-10-16 02:16:20 +0000882 break;
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000883 case write_gran_256bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300884 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000885 break;
886 case write_gran_264bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300887 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000888 break;
889 case write_gran_512bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300890 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000891 break;
892 case write_gran_528bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300893 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000894 break;
895 case write_gran_1024bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300896 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000897 break;
898 case write_gran_1056bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300899 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000900 break;
Carl-Daniel Hailfinger1b0e9fc2014-06-16 22:36:17 +0000901 case write_gran_1byte_implicit_erase:
902 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
903 result = 0;
904 break;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000905 default:
906 msg_cerr("%s: Unsupported granularity! Please report a bug at "
907 "flashrom@flashrom.org\n", __func__);
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000908 }
909 return result;
910}
911
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000912/**
913 * Check if the buffer @have needs to be programmed to get the content of @want.
914 * If yes, return 1 and fill in first_start with the start address of the
915 * write operation and first_len with the length of the first to-be-written
916 * chunk. If not, return 0 and leave first_start and first_len undefined.
917 *
918 * Warning: This function assumes that @have and @want point to naturally
919 * aligned regions.
920 *
921 * @have buffer with current content
922 * @want buffer with desired content
923 * @len length of the checked area
924 * @gran write granularity (enum, not count)
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000925 * @first_start offset of the first byte which needs to be written (passed in
926 * value is increased by the offset of the first needed write
927 * relative to have/want or unchanged if no write is needed)
928 * @return length of the first contiguous area which needs to be written
929 * 0 if no write is needed
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000930 *
931 * FIXME: This function needs a parameter which tells it about coalescing
932 * in relation to the max write length of the programmer and the max write
933 * length of the chip.
934 */
Mark Marshallf20b7be2014-05-09 21:16:21 +0000935static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
Stefan Taunerc69c9c82011-11-23 09:13:48 +0000936 unsigned int *first_start,
937 enum write_granularity gran)
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000938{
Stefan Taunerc69c9c82011-11-23 09:13:48 +0000939 int need_write = 0;
940 unsigned int rel_start = 0, first_len = 0;
941 unsigned int i, limit, stride;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000942
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000943 switch (gran) {
944 case write_gran_1bit:
945 case write_gran_1byte:
Carl-Daniel Hailfinger1b0e9fc2014-06-16 22:36:17 +0000946 case write_gran_1byte_implicit_erase:
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000947 stride = 1;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000948 break;
Paul Kocialkowskic8305e12015-10-16 02:16:20 +0000949 case write_gran_128bytes:
950 stride = 128;
951 break;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000952 case write_gran_256bytes:
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000953 stride = 256;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000954 break;
Stefan Tauner02437452013-04-01 19:34:53 +0000955 case write_gran_264bytes:
956 stride = 264;
957 break;
958 case write_gran_512bytes:
959 stride = 512;
960 break;
961 case write_gran_528bytes:
962 stride = 528;
963 break;
964 case write_gran_1024bytes:
965 stride = 1024;
966 break;
967 case write_gran_1056bytes:
968 stride = 1056;
969 break;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000970 default:
971 msg_cerr("%s: Unsupported granularity! Please report a bug at "
972 "flashrom@flashrom.org\n", __func__);
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000973 /* Claim that no write was needed. A write with unknown
974 * granularity is too dangerous to try.
975 */
976 return 0;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000977 }
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000978 for (i = 0; i < len / stride; i++) {
979 limit = min(stride, len - i * stride);
980 /* Are 'have' and 'want' identical? */
981 if (memcmp(have + i * stride, want + i * stride, limit)) {
982 if (!need_write) {
983 /* First location where have and want differ. */
984 need_write = 1;
985 rel_start = i * stride;
986 }
987 } else {
988 if (need_write) {
989 /* First location where have and want
990 * do not differ anymore.
991 */
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000992 break;
993 }
994 }
995 }
Carl-Daniel Hailfinger202bf532010-12-06 13:05:44 +0000996 if (need_write)
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000997 first_len = min(i * stride - rel_start, len);
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000998 *first_start += rel_start;
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000999 return first_len;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +00001000}
1001
Stefan Tauner9e3a6982014-08-15 17:17:59 +00001002/* Returns the number of busses commonly supported by the current programmer and flash chip where the latter
1003 * can not be completely accessed due to size/address limits of the programmer. */
1004unsigned int count_max_decode_exceedings(const struct flashctx *flash)
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001005{
Stefan Tauner9e3a6982014-08-15 17:17:59 +00001006 unsigned int limitexceeded = 0;
1007 uint32_t size = flash->chip->total_size * 1024;
1008 enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001009
1010 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001011 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +00001012 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001013 "size %u kB of chipset/board/programmer "
1014 "for %s interface, "
1015 "probe/read/erase/write may fail. ", size / 1024,
1016 max_rom_decode.parallel / 1024, "Parallel");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001017 }
Carl-Daniel Hailfinger1a227952011-07-27 07:13:06 +00001018 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001019 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +00001020 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001021 "size %u kB of chipset/board/programmer "
1022 "for %s interface, "
1023 "probe/read/erase/write may fail. ", size / 1024,
1024 max_rom_decode.lpc / 1024, "LPC");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001025 }
Carl-Daniel Hailfinger1a227952011-07-27 07:13:06 +00001026 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001027 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +00001028 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001029 "size %u kB of chipset/board/programmer "
1030 "for %s interface, "
1031 "probe/read/erase/write may fail. ", size / 1024,
1032 max_rom_decode.fwh / 1024, "FWH");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001033 }
Carl-Daniel Hailfinger1a227952011-07-27 07:13:06 +00001034 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001035 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +00001036 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001037 "size %u kB of chipset/board/programmer "
1038 "for %s interface, "
1039 "probe/read/erase/write may fail. ", size / 1024,
1040 max_rom_decode.spi / 1024, "SPI");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001041 }
Stefan Tauner9e3a6982014-08-15 17:17:59 +00001042 return limitexceeded;
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001043}
1044
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001045void unmap_flash(struct flashctx *flash)
1046{
1047 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1048 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1049 flash->physical_registers = 0;
1050 flash->virtual_registers = (chipaddr)ERROR_PTR;
1051 }
1052
1053 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1054 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1055 flash->physical_memory = 0;
1056 flash->virtual_memory = (chipaddr)ERROR_PTR;
1057 }
1058}
1059
1060int map_flash(struct flashctx *flash)
1061{
1062 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1063 flash->virtual_memory = (chipaddr)ERROR_PTR;
1064 flash->virtual_registers = (chipaddr)ERROR_PTR;
1065
1066 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1067 * These are used for various probing-related hacks that would not map successfully anyway and should be
1068 * removed ASAP. */
1069 if (flash->chip->total_size == 0)
1070 return 0;
1071
1072 const chipsize_t size = flash->chip->total_size * 1024;
1073 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1074 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1075 if (addr == ERROR_PTR) {
1076 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1077 flash->chip->name, PRIxPTR_WIDTH, base);
1078 return 1;
1079 }
1080 flash->physical_memory = base;
1081 flash->virtual_memory = (chipaddr)addr;
1082
1083 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1084 * completely different on some chips and programmers, or not mappable at all.
1085 * Ignore these problems for now and always report success. */
1086 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1087 base = 0xffffffff - size - 0x400000 + 1;
1088 addr = programmer_map_flash_region("flash chip registers", base, size);
1089 if (addr == ERROR_PTR) {
1090 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1091 flash->chip->name, PRIxPTR_WIDTH, base);
1092 return 0;
1093 }
1094 flash->physical_registers = base;
1095 flash->virtual_registers = (chipaddr)addr;
1096 }
1097 return 0;
1098}
1099
Nico Huber2d625722016-05-03 10:48:02 +02001100/*
1101 * Return a string corresponding to the bustype parameter.
1102 * Memory is obtained with malloc() and must be freed with free() by the caller.
1103 */
1104char *flashbuses_to_text(enum chipbustype bustype)
1105{
1106 char *ret = calloc(1, 1);
1107 /*
1108 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1109 * will cease to exist and should be eliminated here as well.
1110 */
1111 if (bustype == BUS_NONSPI) {
1112 ret = strcat_realloc(ret, "Non-SPI, ");
1113 } else {
1114 if (bustype & BUS_PARALLEL)
1115 ret = strcat_realloc(ret, "Parallel, ");
1116 if (bustype & BUS_LPC)
1117 ret = strcat_realloc(ret, "LPC, ");
1118 if (bustype & BUS_FWH)
1119 ret = strcat_realloc(ret, "FWH, ");
1120 if (bustype & BUS_SPI)
1121 ret = strcat_realloc(ret, "SPI, ");
1122 if (bustype & BUS_PROG)
1123 ret = strcat_realloc(ret, "Programmer-specific, ");
1124 if (bustype == BUS_NONE)
1125 ret = strcat_realloc(ret, "None, ");
1126 }
1127 /* Kill last comma. */
1128 ret[strlen(ret) - 2] = '\0';
1129 ret = realloc(ret, strlen(ret) + 1);
1130 return ret;
1131}
1132
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001133int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001134{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001135 const struct flashchip *chip;
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001136 enum chipbustype buses_common;
Carl-Daniel Hailfingerb22918c2009-06-01 02:08:58 +00001137 char *tmp;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001138
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001139 for (chip = flashchips + startchip; chip && chip->name; chip++) {
1140 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
Ollie Lhocbbf1252004-03-17 22:22:08 +00001141 continue;
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001142 buses_common = mst->buses_supported & chip->bustype;
Carl-Daniel Hailfingerc40cff72011-12-20 00:19:29 +00001143 if (!buses_common)
Carl-Daniel Hailfinger6573b742011-06-17 22:38:53 +00001144 continue;
Mike Banon31b5e3b2018-01-15 01:10:00 +03001145 /* Only probe for SPI25 chips by default. */
1146 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
1147 continue;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001148 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
1149 if (!chip->probe && !force) {
1150 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
Carl-Daniel Hailfingerb22918c2009-06-01 02:08:58 +00001151 continue;
1152 }
Stefan Reinauer70385642007-04-06 11:58:03 +00001153
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001154 /* Start filling in the dynamic data. */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001155 flash->chip = calloc(1, sizeof(struct flashchip));
1156 if (!flash->chip) {
1157 msg_gerr("Out of memory!\n");
1158 exit(1);
1159 }
1160 memcpy(flash->chip, chip, sizeof(struct flashchip));
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001161 flash->mst = mst;
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001162
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001163 if (map_flash(flash) != 0)
Martin Schiller57a3b732017-11-23 06:24:57 +01001164 goto notfound;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001165
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001166 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1167 * is only called with force=1 after normal probing failed.
1168 */
Peter Stuge27c3e2d2008-07-02 17:15:47 +00001169 if (force)
1170 break;
Stefan Reinauerfcb63682006-03-16 16:57:41 +00001171
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001172 if (flash->chip->probe(flash) != 1)
Peter Stuge483b8f02008-09-03 23:10:05 +00001173 goto notfound;
1174
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001175 /* If this is the first chip found, accept it.
1176 * If this is not the first chip found, accept it only if it is
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001177 * a non-generic match. SFDP and CFI are generic matches.
1178 * startchip==0 means this call to probe_flash() is the first
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001179 * one for this programmer interface (master) and thus no other chip has
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001180 * been found on this interface.
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001181 */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001182 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001183 msg_cinfo("===\n"
1184 "SFDP has autodetected a flash chip which is "
1185 "not natively supported by flashrom yet.\n");
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001186 if (count_usable_erasers(flash) == 0)
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001187 msg_cinfo("The standard operations read and "
1188 "verify should work, but to support "
1189 "erase, write and all other "
1190 "possible features");
1191 else
1192 msg_cinfo("All standard operations (read, "
1193 "verify, erase and write) should "
1194 "work, but to support all possible "
1195 "features");
1196
Stefan Taunerb4e06bd2012-08-20 00:24:22 +00001197 msg_cinfo(" we need to add them manually.\n"
1198 "You can help us by mailing us the output of the following command to "
1199 "flashrom@flashrom.org:\n"
1200 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1201 "Thanks for your help!\n"
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001202 "===\n");
1203 }
1204
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001205 /* First flash chip detected on this bus. */
1206 if (startchip == 0)
Peter Stuge27c3e2d2008-07-02 17:15:47 +00001207 break;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001208 /* Not the first flash chip detected on this bus, but not a generic match either. */
1209 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
1210 break;
1211 /* Not the first flash chip detected on this bus, and it's just a generic match. Ignore it. */
Peter Stuge483b8f02008-09-03 23:10:05 +00001212notfound:
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001213 unmap_flash(flash);
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001214 free(flash->chip);
1215 flash->chip = NULL;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001216 }
Uwe Hermannffec5f32007-08-23 16:08:21 +00001217
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001218 if (!flash->chip)
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001219 return -1;
Peter Stuge27c3e2d2008-07-02 17:15:47 +00001220
Nico Huber7af0e792016-04-29 16:40:15 +02001221 /* Fill fallback layout covering the whole chip. */
1222 struct single_layout *const fallback = &flash->fallback_layout;
1223 fallback->base.entries = &fallback->entry;
1224 fallback->base.num_entries = 1;
1225 fallback->entry.start = 0;
1226 fallback->entry.end = flash->chip->total_size * 1024 - 1;
1227 fallback->entry.included = true;
Nico Huber70461a92019-06-15 14:56:19 +02001228 fallback->entry.name = strdup("complete flash");
1229 if (!fallback->entry.name) {
1230 msg_cerr("Failed to probe chip: %s\n", strerror(errno));
1231 return -1;
1232 }
Stefan Reinauer051e2362011-01-19 06:21:54 +00001233
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001234 tmp = flashbuses_to_text(flash->chip->bustype);
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001235 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1236 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
Stefan Tauner00155492011-06-26 20:45:35 +00001237 free(tmp);
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001238#if CONFIG_INTERNAL == 1
1239 if (programmer_table[programmer].map_flash_region == physmap)
1240 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1241 PRIxPTR_WIDTH, flash->physical_memory);
1242 else
1243#endif
1244 msg_cinfo("on %s.\n", programmer_table[programmer].name);
Uwe Hermann9899cad2009-06-28 21:47:57 +00001245
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001246 /* Flash registers may more likely not be mapped if the chip was forced.
1247 * Lock info may be stored in registers, so avoid lock info printing. */
Carl-Daniel Hailfinger859f3f02010-12-02 21:59:42 +00001248 if (!force)
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001249 if (flash->chip->printlock)
1250 flash->chip->printlock(flash);
Sean Nelson6e0b9122010-02-19 00:52:10 +00001251
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001252 /* Get out of the way for later runs. */
1253 unmap_flash(flash);
1254
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001255 /* Return position of matching chip. */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001256 return chip - flashchips;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001257}
1258
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001259int read_buf_from_file(unsigned char *buf, unsigned long size,
1260 const char *filename)
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001261{
Nico Huber7562f7d2013-08-30 21:29:45 +00001262#ifdef __LIBPAYLOAD__
1263 msg_gerr("Error: No file I/O support in libpayload\n");
1264 return 1;
1265#else
Stefan Tauner16687702015-12-25 21:59:45 +00001266 int ret = 0;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001267
Stefan Tauner16687702015-12-25 21:59:45 +00001268 FILE *image;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001269 if ((image = fopen(filename, "rb")) == NULL) {
Stefan Tauner363fd7e2013-04-07 13:08:30 +00001270 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001271 return 1;
1272 }
Stefan Tauner16687702015-12-25 21:59:45 +00001273
1274 struct stat image_stat;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001275 if (fstat(fileno(image), &image_stat) != 0) {
Stefan Tauner363fd7e2013-04-07 13:08:30 +00001276 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
Stefan Tauner16687702015-12-25 21:59:45 +00001277 ret = 1;
1278 goto out;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001279 }
Nico Huber519be662018-12-23 20:03:35 +01001280 if (image_stat.st_size != (intmax_t)size) {
Carl-Daniel Hailfinger11990da2013-07-13 23:21:05 +00001281 msg_gerr("Error: Image size (%jd B) doesn't match the flash chip's size (%lu B)!\n",
Stefan Taunere038e902013-02-04 04:38:42 +00001282 (intmax_t)image_stat.st_size, size);
Stefan Tauner16687702015-12-25 21:59:45 +00001283 ret = 1;
1284 goto out;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001285 }
Stefan Tauner16687702015-12-25 21:59:45 +00001286
1287 unsigned long numbytes = fread(buf, 1, size, image);
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001288 if (numbytes != size) {
1289 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1290 "wanted %ld!\n", numbytes, size);
Stefan Tauner16687702015-12-25 21:59:45 +00001291 ret = 1;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001292 }
Stefan Tauner16687702015-12-25 21:59:45 +00001293out:
1294 (void)fclose(image);
1295 return ret;
Nico Huber7562f7d2013-08-30 21:29:45 +00001296#endif
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001297}
1298
Mark Marshallf20b7be2014-05-09 21:16:21 +00001299int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001300{
Nico Huber7562f7d2013-08-30 21:29:45 +00001301#ifdef __LIBPAYLOAD__
1302 msg_gerr("Error: No file I/O support in libpayload\n");
1303 return 1;
1304#else
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001305 FILE *image;
Stefan Tauner16687702015-12-25 21:59:45 +00001306 int ret = 0;
Stephan Guilloux21dd55b2009-06-01 22:07:52 +00001307
1308 if (!filename) {
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001309 msg_gerr("No filename specified.\n");
Stephan Guilloux21dd55b2009-06-01 22:07:52 +00001310 return 1;
1311 }
Patrick Georgi0bf842d2010-01-25 22:55:33 +00001312 if ((image = fopen(filename, "wb")) == NULL) {
Stefan Tauner363fd7e2013-04-07 13:08:30 +00001313 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
Carl-Daniel Hailfinger03b4e712009-05-08 12:49:03 +00001314 return 1;
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001315 }
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001316
Stefan Tauner16687702015-12-25 21:59:45 +00001317 unsigned long numbytes = fwrite(buf, 1, size, image);
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001318 if (numbytes != size) {
Stefan Tauner16687702015-12-25 21:59:45 +00001319 msg_gerr("Error: file %s could not be written completely.\n", filename);
1320 ret = 1;
1321 goto out;
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001322 }
Stefan Tauner16687702015-12-25 21:59:45 +00001323 if (fflush(image)) {
1324 msg_gerr("Error: flushing file \"%s\" failed: %s\n", filename, strerror(errno));
1325 ret = 1;
1326 }
1327 // Try to fsync() only regular files and if that function is available at all (e.g. not on MinGW).
1328#if defined(_POSIX_FSYNC) && (_POSIX_FSYNC != -1)
1329 struct stat image_stat;
1330 if (fstat(fileno(image), &image_stat) != 0) {
1331 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1332 ret = 1;
1333 goto out;
1334 }
1335 if (S_ISREG(image_stat.st_mode)) {
1336 if (fsync(fileno(image))) {
1337 msg_gerr("Error: fsyncing file \"%s\" failed: %s\n", filename, strerror(errno));
1338 ret = 1;
1339 }
1340 }
1341#endif
1342out:
1343 if (fclose(image)) {
1344 msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
1345 ret = 1;
1346 }
1347 return ret;
Nico Huber7562f7d2013-08-30 21:29:45 +00001348#endif
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001349}
1350
Nico Huber899e4ec2016-04-29 18:39:01 +02001351static int read_by_layout(struct flashctx *, uint8_t *);
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +00001352int read_flash_to_file(struct flashctx *flash, const char *filename)
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001353{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001354 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes84b453e2018-12-19 15:30:39 +00001355 unsigned char *buf = calloc(size, sizeof(unsigned char));
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001356 int ret = 0;
1357
1358 msg_cinfo("Reading flash... ");
1359 if (!buf) {
1360 msg_gerr("Memory allocation failed!\n");
1361 msg_cinfo("FAILED.\n");
1362 return 1;
1363 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001364 if (!flash->chip->read) {
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001365 msg_cerr("No read function available for this flash chip.\n");
1366 ret = 1;
1367 goto out_free;
1368 }
Nico Huber899e4ec2016-04-29 18:39:01 +02001369 if (read_by_layout(flash, buf)) {
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001370 msg_cerr("Read operation failed!\n");
1371 ret = 1;
1372 goto out_free;
1373 }
1374
Stefan Tauner355cbfd2011-05-28 02:37:14 +00001375 ret = write_buf_to_file(buf, size, filename);
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001376out_free:
1377 free(buf);
1378 msg_cinfo("%s.\n", ret ? "FAILED" : "done");
1379 return ret;
1380}
1381
Stefan Tauner96658be2014-05-26 22:05:31 +00001382/* Even if an error is found, the function will keep going and check the rest. */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001383static int selfcheck_eraseblocks(const struct flashchip *chip)
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001384{
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +00001385 int i, j, k;
1386 int ret = 0;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001387
1388 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1389 unsigned int done = 0;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001390 struct block_eraser eraser = chip->block_erasers[k];
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001391
1392 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1393 /* Blocks with zero size are bugs in flashchips.c. */
1394 if (eraser.eraseblocks[i].count &&
1395 !eraser.eraseblocks[i].size) {
1396 msg_gerr("ERROR: Flash chip %s erase function "
1397 "%i region %i has size 0. Please report"
1398 " a bug at flashrom@flashrom.org\n",
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001399 chip->name, k, i);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001400 ret = 1;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001401 }
1402 /* Blocks with zero count are bugs in flashchips.c. */
1403 if (!eraser.eraseblocks[i].count &&
1404 eraser.eraseblocks[i].size) {
1405 msg_gerr("ERROR: Flash chip %s erase function "
1406 "%i region %i has count 0. Please report"
1407 " a bug at flashrom@flashrom.org\n",
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001408 chip->name, k, i);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001409 ret = 1;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001410 }
1411 done += eraser.eraseblocks[i].count *
1412 eraser.eraseblocks[i].size;
1413 }
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001414 /* Empty eraseblock definition with erase function. */
1415 if (!done && eraser.block_erase)
Sean Nelson316a29f2010-05-07 20:09:04 +00001416 msg_gspew("Strange: Empty eraseblock definition with "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001417 "non-empty erase function. Not an error.\n");
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001418 if (!done)
1419 continue;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001420 if (done != chip->total_size * 1024) {
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001421 msg_gerr("ERROR: Flash chip %s erase function %i "
1422 "region walking resulted in 0x%06x bytes total,"
1423 " expected 0x%06x bytes. Please report a bug at"
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001424 " flashrom@flashrom.org\n", chip->name, k,
1425 done, chip->total_size * 1024);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001426 ret = 1;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001427 }
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001428 if (!eraser.block_erase)
1429 continue;
1430 /* Check if there are identical erase functions for different
1431 * layouts. That would imply "magic" erase functions. The
1432 * easiest way to check this is with function pointers.
1433 */
Uwe Hermann43959702010-03-13 17:28:29 +00001434 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001435 if (eraser.block_erase ==
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001436 chip->block_erasers[j].block_erase) {
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001437 msg_gerr("ERROR: Flash chip %s erase function "
1438 "%i and %i are identical. Please report"
1439 " a bug at flashrom@flashrom.org\n",
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001440 chip->name, k, j);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001441 ret = 1;
1442 }
Uwe Hermann43959702010-03-13 17:28:29 +00001443 }
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001444 }
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001445 return ret;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001446}
1447
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +00001448static int check_block_eraser(const struct flashctx *flash, int k, int log)
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001449{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001450 struct block_eraser eraser = flash->chip->block_erasers[k];
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001451
1452 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1453 if (log)
1454 msg_cdbg("not defined. ");
1455 return 1;
1456 }
1457 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1458 if (log)
1459 msg_cdbg("eraseblock layout is known, but matching "
Stefan Tauner355cbfd2011-05-28 02:37:14 +00001460 "block erase function is not implemented. ");
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001461 return 1;
1462 }
1463 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1464 if (log)
1465 msg_cdbg("block erase function found, but "
Stefan Tauner355cbfd2011-05-28 02:37:14 +00001466 "eraseblock layout is not defined. ");
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001467 return 1;
1468 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001469 // TODO: Once erase functions are annotated with allowed buses, check that as well.
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001470 return 0;
1471}
1472
Nico Huber7af0e792016-04-29 16:40:15 +02001473/**
1474 * @brief Reads the included layout regions into a buffer.
1475 *
1476 * If there is no layout set in the given flash context, the whole chip will
1477 * be read.
1478 *
1479 * @param flashctx Flash context to be used.
1480 * @param buffer Buffer of full chip size to read into.
1481 * @return 0 on success,
1482 * 1 if any read fails.
1483 */
1484static int read_by_layout(struct flashctx *const flashctx, uint8_t *const buffer)
1485{
1486 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber5ca55232019-06-15 22:29:08 +02001487 const struct romentry *entry = NULL;
Nico Huber7af0e792016-04-29 16:40:15 +02001488
Nico Huber5ca55232019-06-15 22:29:08 +02001489 while ((entry = layout_next_included(layout, entry))) {
1490 const chipoff_t region_start = entry->start;
1491 const chipsize_t region_len = entry->end - entry->start + 1;
Nico Huber7af0e792016-04-29 16:40:15 +02001492
1493 if (flashctx->chip->read(flashctx, buffer + region_start, region_start, region_len))
1494 return 1;
1495 }
1496 return 0;
1497}
1498
1499typedef int (*erasefn_t)(struct flashctx *, unsigned int addr, unsigned int len);
1500/**
1501 * @private
1502 *
1503 * For read-erase-write, `curcontents` and `newcontents` shall point
1504 * to buffers of the chip's size. Both are supposed to be prefilled
1505 * with at least the included layout regions of the current flash
1506 * contents (`curcontents`) and the data to be written to the flash
1507 * (`newcontents`).
1508 *
1509 * For erase, `curcontents` and `newcontents` shall be NULL-pointers.
1510 *
1511 * The `chipoff_t` values are used internally by `walk_by_layout()`.
1512 */
1513struct walk_info {
1514 uint8_t *curcontents;
1515 const uint8_t *newcontents;
1516 chipoff_t region_start;
1517 chipoff_t region_end;
1518 chipoff_t erase_start;
1519 chipoff_t erase_end;
1520};
1521/* returns 0 on success, 1 to retry with another erase function, 2 for immediate abort */
1522typedef int (*per_blockfn_t)(struct flashctx *, const struct walk_info *, erasefn_t);
1523
1524static int walk_eraseblocks(struct flashctx *const flashctx,
1525 struct walk_info *const info,
1526 const size_t erasefunction, const per_blockfn_t per_blockfn)
1527{
1528 int ret;
1529 size_t i, j;
1530 bool first = true;
1531 struct block_eraser *const eraser = &flashctx->chip->block_erasers[erasefunction];
1532
1533 info->erase_start = 0;
1534 for (i = 0; i < NUM_ERASEREGIONS; ++i) {
1535 /* count==0 for all automatically initialized array
1536 members so the loop below won't be executed for them. */
1537 for (j = 0; j < eraser->eraseblocks[i].count; ++j, info->erase_start = info->erase_end + 1) {
1538 info->erase_end = info->erase_start + eraser->eraseblocks[i].size - 1;
1539
1540 /* Skip any eraseblock that is completely outside the current region. */
1541 if (info->erase_end < info->region_start)
1542 continue;
1543 if (info->region_end < info->erase_start)
1544 break;
1545
1546 /* Print this for every block except the first one. */
1547 if (first)
1548 first = false;
1549 else
1550 msg_cdbg(", ");
1551 msg_cdbg("0x%06x-0x%06x:", info->erase_start, info->erase_end);
1552
1553 ret = per_blockfn(flashctx, info, eraser->block_erase);
1554 if (ret)
1555 return ret;
1556 }
1557 if (info->region_end < info->erase_start)
1558 break;
1559 }
1560 msg_cdbg("\n");
1561 return 0;
1562}
1563
1564static int walk_by_layout(struct flashctx *const flashctx, struct walk_info *const info,
1565 const per_blockfn_t per_blockfn)
1566{
1567 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber5ca55232019-06-15 22:29:08 +02001568 const struct romentry *entry = NULL;
Nico Huber7af0e792016-04-29 16:40:15 +02001569
1570 all_skipped = true;
1571 msg_cinfo("Erasing and writing flash chip... ");
1572
Nico Huber5ca55232019-06-15 22:29:08 +02001573 while ((entry = layout_next_included(layout, entry))) {
1574 info->region_start = entry->start;
1575 info->region_end = entry->end;
Nico Huber7af0e792016-04-29 16:40:15 +02001576
1577 size_t j;
1578 int error = 1; /* retry as long as it's 1 */
1579 for (j = 0; j < NUM_ERASEFUNCTIONS; ++j) {
1580 if (j != 0)
1581 msg_cinfo("Looking for another erase function.\n");
1582 msg_cdbg("Trying erase function %zi... ", j);
1583 if (check_block_eraser(flashctx, j, 1))
1584 continue;
1585
1586 error = walk_eraseblocks(flashctx, info, j, per_blockfn);
1587 if (error != 1)
1588 break;
1589
1590 if (info->curcontents) {
1591 msg_cinfo("Reading current flash chip contents... ");
1592 if (read_by_layout(flashctx, info->curcontents)) {
1593 /* Now we are truly screwed. Read failed as well. */
1594 msg_cerr("Can't read anymore! Aborting.\n");
1595 /* We have no idea about the flash chip contents, so
1596 retrying with another erase function is pointless. */
1597 error = 2;
1598 break;
1599 }
1600 msg_cinfo("done. ");
1601 }
1602 }
1603 if (error == 1)
1604 msg_cinfo("No usable erase functions left.\n");
1605 if (error) {
1606 msg_cerr("FAILED!\n");
1607 return 1;
1608 }
1609 }
1610 if (all_skipped)
1611 msg_cinfo("\nWarning: Chip content is identical to the requested image.\n");
1612 msg_cinfo("Erase/write done.\n");
1613 return 0;
1614}
1615
1616static int erase_block(struct flashctx *const flashctx,
1617 const struct walk_info *const info, const erasefn_t erasefn)
1618{
1619 const unsigned int erase_len = info->erase_end + 1 - info->erase_start;
Nico Huber6e61e0c2019-01-23 17:07:49 +01001620 const bool region_unaligned = info->region_start > info->erase_start ||
1621 info->erase_end > info->region_end;
1622 uint8_t *backup_contents = NULL, *erased_contents = NULL;
1623 int ret = 2;
Nico Huber7af0e792016-04-29 16:40:15 +02001624
Nico Huber6e61e0c2019-01-23 17:07:49 +01001625 /*
1626 * If the region is not erase-block aligned, merge current flash con-
1627 * tents into a new buffer `backup_contents`.
1628 */
1629 if (region_unaligned) {
1630 backup_contents = malloc(erase_len);
1631 erased_contents = malloc(erase_len);
1632 if (!backup_contents || !erased_contents) {
1633 msg_cerr("Out of memory!\n");
1634 ret = 1;
1635 goto _free_ret;
1636 }
1637 memset(backup_contents, ERASED_VALUE(flashctx), erase_len);
1638 memset(erased_contents, ERASED_VALUE(flashctx), erase_len);
1639
1640 msg_cdbg("R");
1641 /* Merge data preceding the current region. */
1642 if (info->region_start > info->erase_start) {
1643 const chipoff_t start = info->erase_start;
1644 const chipsize_t len = info->region_start - info->erase_start;
1645 if (flashctx->chip->read(flashctx, backup_contents, start, len)) {
1646 msg_cerr("Can't read! Aborting.\n");
1647 goto _free_ret;
1648 }
1649 }
1650 /* Merge data following the current region. */
1651 if (info->erase_end > info->region_end) {
1652 const chipoff_t start = info->region_end + 1;
1653 const chipoff_t rel_start = start - info->erase_start; /* within this erase block */
1654 const chipsize_t len = info->erase_end - info->region_end;
1655 if (flashctx->chip->read(flashctx, backup_contents + rel_start, start, len)) {
1656 msg_cerr("Can't read! Aborting.\n");
1657 goto _free_ret;
1658 }
1659 }
1660 }
1661
1662 ret = 1;
Nico Huber7af0e792016-04-29 16:40:15 +02001663 all_skipped = false;
1664
1665 msg_cdbg("E");
1666 if (erasefn(flashctx, info->erase_start, erase_len))
Nico Huber6e61e0c2019-01-23 17:07:49 +01001667 goto _free_ret;
Nico Huber7af0e792016-04-29 16:40:15 +02001668 if (check_erased_range(flashctx, info->erase_start, erase_len)) {
1669 msg_cerr("ERASE FAILED!\n");
Nico Huber6e61e0c2019-01-23 17:07:49 +01001670 goto _free_ret;
Nico Huber7af0e792016-04-29 16:40:15 +02001671 }
Nico Huber6e61e0c2019-01-23 17:07:49 +01001672
1673 if (region_unaligned) {
1674 unsigned int starthere = 0, lenhere = 0, writecount = 0;
1675 /* get_next_write() sets starthere to a new value after the call. */
1676 while ((lenhere = get_next_write(erased_contents + starthere, backup_contents + starthere,
1677 erase_len - starthere, &starthere, flashctx->chip->gran))) {
1678 if (!writecount++)
1679 msg_cdbg("W");
1680 /* Needs the partial write function signature. */
1681 if (flashctx->chip->write(flashctx, backup_contents + starthere,
1682 info->erase_start + starthere, lenhere))
1683 goto _free_ret;
1684 starthere += lenhere;
1685 }
1686 }
1687
1688 ret = 0;
1689
1690_free_ret:
1691 free(erased_contents);
1692 free(backup_contents);
1693 return ret;
Nico Huber7af0e792016-04-29 16:40:15 +02001694}
1695
1696/**
1697 * @brief Erases the included layout regions.
1698 *
1699 * If there is no layout set in the given flash context, the whole chip will
1700 * be erased.
1701 *
1702 * @param flashctx Flash context to be used.
1703 * @param buffer Buffer of full chip size to read into.
1704 * @return 0 on success,
1705 * 1 if all available erase functions failed.
1706 */
Nico Huber454f6132012-12-10 13:34:10 +00001707static int erase_by_layout(struct flashctx *const flashctx)
Nico Huber7af0e792016-04-29 16:40:15 +02001708{
1709 struct walk_info info = { 0 };
1710 return walk_by_layout(flashctx, &info, &erase_block);
1711}
1712
1713static int read_erase_write_block(struct flashctx *const flashctx,
1714 const struct walk_info *const info, const erasefn_t erasefn)
1715{
1716 const chipsize_t erase_len = info->erase_end + 1 - info->erase_start;
1717 const bool region_unaligned = info->region_start > info->erase_start ||
1718 info->erase_end > info->region_end;
1719 const uint8_t *newcontents = NULL;
1720 int ret = 2;
1721
1722 /*
1723 * If the region is not erase-block aligned, merge current flash con-
1724 * tents into `info->curcontents` and a new buffer `newc`. The former
1725 * is necessary since we have no guarantee that the full erase block
1726 * was already read into `info->curcontents`. For the latter a new
1727 * buffer is used since `info->newcontents` might contain data for
1728 * other unaligned regions that touch this erase block too.
1729 */
1730 if (region_unaligned) {
1731 msg_cdbg("R");
1732 uint8_t *const newc = malloc(erase_len);
1733 if (!newc) {
1734 msg_cerr("Out of memory!\n");
1735 return 1;
1736 }
1737 memcpy(newc, info->newcontents + info->erase_start, erase_len);
1738
1739 /* Merge data preceding the current region. */
1740 if (info->region_start > info->erase_start) {
1741 const chipoff_t start = info->erase_start;
1742 const chipsize_t len = info->region_start - info->erase_start;
1743 if (flashctx->chip->read(flashctx, newc, start, len)) {
1744 msg_cerr("Can't read! Aborting.\n");
1745 goto _free_ret;
1746 }
1747 memcpy(info->curcontents + start, newc, len);
1748 }
1749 /* Merge data following the current region. */
1750 if (info->erase_end > info->region_end) {
1751 const chipoff_t start = info->region_end + 1;
1752 const chipoff_t rel_start = start - info->erase_start; /* within this erase block */
1753 const chipsize_t len = info->erase_end - info->region_end;
1754 if (flashctx->chip->read(flashctx, newc + rel_start, start, len)) {
1755 msg_cerr("Can't read! Aborting.\n");
1756 goto _free_ret;
1757 }
1758 memcpy(info->curcontents + start, newc + rel_start, len);
1759 }
1760
1761 newcontents = newc;
1762 } else {
1763 newcontents = info->newcontents + info->erase_start;
1764 }
1765
1766 ret = 1;
1767 bool skipped = true;
1768 uint8_t *const curcontents = info->curcontents + info->erase_start;
Paul Kocialkowski995f7552018-01-15 01:06:09 +03001769 const uint8_t erased_value = ERASED_VALUE(flashctx);
David Hendricksf9a30552015-05-23 20:30:30 -07001770 if (!(flashctx->chip->feature_bits & FEATURE_NO_ERASE) &&
1771 need_erase(curcontents, newcontents, erase_len, flashctx->chip->gran, erased_value)) {
Nico Huber7af0e792016-04-29 16:40:15 +02001772 if (erase_block(flashctx, info, erasefn))
1773 goto _free_ret;
1774 /* Erase was successful. Adjust curcontents. */
Paul Kocialkowski995f7552018-01-15 01:06:09 +03001775 memset(curcontents, erased_value, erase_len);
Nico Huber7af0e792016-04-29 16:40:15 +02001776 skipped = false;
1777 }
1778
1779 unsigned int starthere = 0, lenhere = 0, writecount = 0;
1780 /* get_next_write() sets starthere to a new value after the call. */
1781 while ((lenhere = get_next_write(curcontents + starthere, newcontents + starthere,
1782 erase_len - starthere, &starthere, flashctx->chip->gran))) {
1783 if (!writecount++)
1784 msg_cdbg("W");
1785 /* Needs the partial write function signature. */
1786 if (flashctx->chip->write(flashctx, newcontents + starthere,
1787 info->erase_start + starthere, lenhere))
1788 goto _free_ret;
1789 starthere += lenhere;
1790 skipped = false;
1791 }
1792 if (skipped)
1793 msg_cdbg("S");
1794 else
1795 all_skipped = false;
1796
1797 /* Update curcontents, other regions with overlapping erase blocks
1798 might rely on this. */
1799 memcpy(curcontents, newcontents, erase_len);
1800 ret = 0;
1801
1802_free_ret:
1803 if (region_unaligned)
1804 free((void *)newcontents);
1805 return ret;
1806}
1807
1808/**
1809 * @brief Writes the included layout regions from a given image.
1810 *
1811 * If there is no layout set in the given flash context, the whole image
1812 * will be written.
1813 *
1814 * @param flashctx Flash context to be used.
1815 * @param curcontents A buffer of full chip size with current chip contents of included regions.
1816 * @param newcontents The new image to be written.
1817 * @return 0 on success,
1818 * 1 if anything has gone wrong.
1819 */
Nico Huber454f6132012-12-10 13:34:10 +00001820static int write_by_layout(struct flashctx *const flashctx,
1821 void *const curcontents, const void *const newcontents)
Nico Huber7af0e792016-04-29 16:40:15 +02001822{
1823 struct walk_info info;
1824 info.curcontents = curcontents;
1825 info.newcontents = newcontents;
1826 return walk_by_layout(flashctx, &info, read_erase_write_block);
1827}
1828
1829/**
1830 * @brief Compares the included layout regions with content from a buffer.
1831 *
1832 * If there is no layout set in the given flash context, the whole chip's
1833 * contents will be compared.
1834 *
1835 * @param flashctx Flash context to be used.
1836 * @param curcontents A buffer of full chip size to read current chip contents into.
1837 * @param newcontents The new image to compare to.
1838 * @return 0 on success,
1839 * 1 if reading failed,
1840 * 3 if the contents don't match.
1841 */
Nico Huber454f6132012-12-10 13:34:10 +00001842static int verify_by_layout(struct flashctx *const flashctx,
1843 void *const curcontents, const uint8_t *const newcontents)
Nico Huber7af0e792016-04-29 16:40:15 +02001844{
1845 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber5ca55232019-06-15 22:29:08 +02001846 const struct romentry *entry = NULL;
Nico Huber7af0e792016-04-29 16:40:15 +02001847
Nico Huber5ca55232019-06-15 22:29:08 +02001848 while ((entry = layout_next_included(layout, entry))) {
1849 const chipoff_t region_start = entry->start;
1850 const chipsize_t region_len = entry->end - entry->start + 1;
Nico Huber7af0e792016-04-29 16:40:15 +02001851
1852 if (flashctx->chip->read(flashctx, curcontents + region_start, region_start, region_len))
1853 return 1;
1854 if (compare_range(newcontents + region_start, curcontents + region_start,
1855 region_start, region_len))
1856 return 3;
1857 }
1858 return 0;
1859}
1860
Stefan Tauner136388f2013-07-15 10:47:53 +00001861static void nonfatal_help_message(void)
Carl-Daniel Hailfinger42d38a92010-10-19 22:06:20 +00001862{
Stefan Taunera58f6e92014-05-10 09:25:44 +00001863 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
Stefan Tauner136388f2013-07-15 10:47:53 +00001864#if CONFIG_INTERNAL == 1
1865 if (programmer == PROGRAMMER_INTERNAL)
1866 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
1867 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1868 "mail flashrom@flashrom.org, thanks!\n"
1869 "-------------------------------------------------------------------------------\n"
1870 "You may now reboot or simply leave the machine running.\n");
1871 else
1872#endif
1873 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
1874 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
1875 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1876 "mail flashrom@flashrom.org, thanks!\n");
Carl-Daniel Hailfinger42d38a92010-10-19 22:06:20 +00001877}
1878
Stefan Tauner136388f2013-07-15 10:47:53 +00001879static void emergency_help_message(void)
Carl-Daniel Hailfinger8ab49e72009-08-19 13:55:34 +00001880{
Stefan Tauner136388f2013-07-15 10:47:53 +00001881 msg_gerr("Your flash chip is in an unknown state.\n");
1882#if CONFIG_INTERNAL == 1
1883 if (programmer == PROGRAMMER_INTERNAL)
1884 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
1885 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
1886 "-------------------------------------------------------------------------------\n"
1887 "DO NOT REBOOT OR POWEROFF!\n");
1888 else
1889#endif
1890 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1891 "mail flashrom@flashrom.org, thanks!\n");
Carl-Daniel Hailfinger8ab49e72009-08-19 13:55:34 +00001892}
1893
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001894void list_programmers_linebreak(int startcol, int cols, int paren)
1895{
1896 const char *pname;
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +00001897 int pnamelen;
1898 int remaining = 0, firstline = 1;
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001899 enum programmer p;
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +00001900 int i;
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001901
1902 for (p = 0; p < PROGRAMMER_INVALID; p++) {
1903 pname = programmer_table[p].name;
1904 pnamelen = strlen(pname);
1905 if (remaining - pnamelen - 2 < 0) {
1906 if (firstline)
1907 firstline = 0;
1908 else
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001909 msg_ginfo("\n");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001910 for (i = 0; i < startcol; i++)
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001911 msg_ginfo(" ");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001912 remaining = cols - startcol;
1913 } else {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001914 msg_ginfo(" ");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001915 remaining--;
1916 }
1917 if (paren && (p == 0)) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001918 msg_ginfo("(");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001919 remaining--;
1920 }
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001921 msg_ginfo("%s", pname);
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001922 remaining -= pnamelen;
1923 if (p < PROGRAMMER_INVALID - 1) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001924 msg_ginfo(",");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001925 remaining--;
1926 } else {
1927 if (paren)
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001928 msg_ginfo(")");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001929 }
1930 }
1931}
1932
Jacob Garberbeeb8bc2019-06-21 15:24:17 -06001933static void print_sysinfo(void)
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001934{
Stefan Taunerb0eee9b2015-01-10 09:32:50 +00001935#if IS_WINDOWS
Carl-Daniel Hailfinger60d9bd22012-08-09 23:34:41 +00001936 SYSTEM_INFO si;
1937 OSVERSIONINFOEX osvi;
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001938
Carl-Daniel Hailfinger60d9bd22012-08-09 23:34:41 +00001939 memset(&si, 0, sizeof(SYSTEM_INFO));
1940 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
1941 msg_ginfo(" on Windows");
1942 /* Tell Windows which version of the structure we want. */
1943 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
1944 if (GetVersionEx((OSVERSIONINFO*) &osvi))
1945 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
1946 else
1947 msg_ginfo(" unknown version");
1948 GetSystemInfo(&si);
1949 switch (si.wProcessorArchitecture) {
1950 case PROCESSOR_ARCHITECTURE_AMD64:
1951 msg_ginfo(" (x86_64)");
1952 break;
1953 case PROCESSOR_ARCHITECTURE_INTEL:
1954 msg_ginfo(" (x86)");
1955 break;
1956 default:
1957 msg_ginfo(" (unknown arch)");
1958 break;
1959 }
1960#elif HAVE_UTSNAME == 1
1961 struct utsname osinfo;
1962
1963 uname(&osinfo);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001964 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
1965 osinfo.machine);
1966#else
1967 msg_ginfo(" on unknown machine");
1968#endif
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001969}
1970
1971void print_buildinfo(void)
1972{
1973 msg_gdbg("flashrom was built with");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001974#if NEED_PCI == 1
1975#ifdef PCILIB_VERSION
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001976 msg_gdbg(" libpci %s,", PCILIB_VERSION);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001977#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001978 msg_gdbg(" unknown PCI library,");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001979#endif
1980#endif
1981#ifdef __clang__
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001982 msg_gdbg(" LLVM Clang");
Carl-Daniel Hailfingerb51e58e2010-07-17 14:49:30 +00001983#ifdef __clang_version__
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001984 msg_gdbg(" %s,", __clang_version__);
Carl-Daniel Hailfingerb51e58e2010-07-17 14:49:30 +00001985#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001986 msg_gdbg(" unknown version (before r102686),");
Carl-Daniel Hailfingerb51e58e2010-07-17 14:49:30 +00001987#endif
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001988#elif defined(__GNUC__)
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001989 msg_gdbg(" GCC");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001990#ifdef __VERSION__
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001991 msg_gdbg(" %s,", __VERSION__);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001992#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001993 msg_gdbg(" unknown version,");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001994#endif
1995#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001996 msg_gdbg(" unknown compiler,");
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +00001997#endif
1998#if defined (__FLASHROM_LITTLE_ENDIAN__)
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001999 msg_gdbg(" little endian");
Carl-Daniel Hailfinger06b9efa2012-08-07 11:59:59 +00002000#elif defined (__FLASHROM_BIG_ENDIAN__)
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00002001 msg_gdbg(" big endian");
Carl-Daniel Hailfinger06b9efa2012-08-07 11:59:59 +00002002#else
2003#error Endianness could not be determined
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00002004#endif
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00002005 msg_gdbg("\n");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00002006}
2007
Bernhard Walle201bde32008-01-21 15:24:22 +00002008void print_version(void)
2009{
Stefan Tauner76347082016-11-27 17:45:49 +01002010 msg_ginfo("flashrom %s", flashrom_version);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00002011 print_sysinfo();
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00002012 msg_ginfo("\n");
Bernhard Walle201bde32008-01-21 15:24:22 +00002013}
2014
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +00002015void print_banner(void)
2016{
2017 msg_ginfo("flashrom is free software, get the source code at "
Stefan Tauner4c723152016-01-14 22:47:55 +00002018 "https://flashrom.org\n");
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +00002019 msg_ginfo("\n");
2020}
2021
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00002022int selfcheck(void)
2023{
Stefan Tauner96658be2014-05-26 22:05:31 +00002024 unsigned int i;
Stefan Taunera6d96482012-12-26 19:51:23 +00002025 int ret = 0;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00002026
2027 /* Safety check. Instead of aborting after the first error, check
2028 * if more errors exist.
2029 */
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00002030 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
Sean Nelson316a29f2010-05-07 20:09:04 +00002031 msg_gerr("Programmer table miscompilation!\n");
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00002032 ret = 1;
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00002033 }
Stefan Taunera6d96482012-12-26 19:51:23 +00002034 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2035 const struct programmer_entry p = programmer_table[i];
2036 if (p.name == NULL) {
2037 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2038 ret = 1;
2039 /* This might hide other problems with this programmer, but allows for better error
2040 * messages below without jumping through hoops. */
2041 continue;
2042 }
Stefan Tauneraf358d62012-12-27 18:40:26 +00002043 switch (p.type) {
2044 case USB:
2045 case PCI:
2046 case OTHER:
2047 if (p.devs.note == NULL) {
2048 if (strcmp("internal", p.name) == 0)
2049 break; /* This one has its device list stored separately. */
2050 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2051 p.name);
2052 ret = 1;
2053 }
2054 break;
2055 default:
2056 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2057 ret = 1;
2058 break;
2059 }
Stefan Taunera6d96482012-12-26 19:51:23 +00002060 if (p.init == NULL) {
2061 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2062 ret = 1;
2063 }
2064 if (p.delay == NULL) {
2065 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2066 ret = 1;
2067 }
2068 if (p.map_flash_region == NULL) {
2069 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2070 ret = 1;
2071 }
2072 if (p.unmap_flash_region == NULL) {
2073 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2074 ret = 1;
2075 }
2076 }
Stefan Tauner96658be2014-05-26 22:05:31 +00002077
2078 /* It would be favorable if we could check for the correct layout (especially termination) of various
2079 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2080 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2081 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2082 * For 'flashchips' we export the size explicitly to work around this and to be able to implement the
2083 * checks below. */
Stefan Tauner6697f712014-08-06 15:09:15 +00002084 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
Stefan Tauner7bcacb12011-05-26 01:35:19 +00002085 msg_gerr("Flashchips table miscompilation!\n");
2086 ret = 1;
Stefan Tauner96658be2014-05-26 22:05:31 +00002087 } else {
2088 for (i = 0; i < flashchips_size - 1; i++) {
2089 const struct flashchip *chip = &flashchips[i];
2090 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2091 ret = 1;
2092 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2093 "Please report a bug at flashrom@flashrom.org\n", i,
2094 chip->name == NULL ? "unnamed" : chip->name);
2095 }
2096 if (selfcheck_eraseblocks(chip)) {
2097 ret = 1;
2098 }
2099 }
Stefan Tauner7bcacb12011-05-26 01:35:19 +00002100 }
Stefan Tauner7bcacb12011-05-26 01:35:19 +00002101
Stefan Tauner600576b2014-06-12 22:57:36 +00002102#if CONFIG_INTERNAL == 1
2103 ret |= selfcheck_board_enables();
2104#endif
2105
Stefan Tauner96658be2014-05-26 22:05:31 +00002106 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00002107 return ret;
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00002108}
2109
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002110/* FIXME: This function signature needs to be improved once doit() has a better
2111 * function signature.
2112 */
Jacob Garberbeeb8bc2019-06-21 15:24:17 -06002113static int chip_safety_check(const struct flashctx *flash, int force,
2114 int read_it, int write_it, int erase_it, int verify_it)
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002115{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00002116 const struct flashchip *chip = flash->chip;
2117
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002118 if (!programmer_may_write && (write_it || erase_it)) {
2119 msg_perr("Write/erase is not working yet on your programmer in "
2120 "its current configuration.\n");
2121 /* --force is the wrong approach, but it's the best we can do
2122 * until the generic programmer parameter parser is merged.
2123 */
2124 if (!force)
2125 return 1;
2126 msg_cerr("Continuing anyway.\n");
2127 }
2128
2129 if (read_it || erase_it || write_it || verify_it) {
2130 /* Everything needs read. */
Stefan Tauner6455dff2014-05-26 00:36:24 +00002131 if (chip->tested.read == BAD) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002132 msg_cerr("Read is not working on this chip. ");
2133 if (!force)
2134 return 1;
2135 msg_cerr("Continuing anyway.\n");
2136 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00002137 if (!chip->read) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002138 msg_cerr("flashrom has no read function for this "
2139 "flash chip.\n");
2140 return 1;
2141 }
2142 }
2143 if (erase_it || write_it) {
2144 /* Write needs erase. */
Stefan Tauner6455dff2014-05-26 00:36:24 +00002145 if (chip->tested.erase == NA) {
2146 msg_cerr("Erase is not possible on this chip.\n");
2147 return 1;
2148 }
2149 if (chip->tested.erase == BAD) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002150 msg_cerr("Erase is not working on this chip. ");
2151 if (!force)
2152 return 1;
2153 msg_cerr("Continuing anyway.\n");
2154 }
Sylvain "ythier" Hitier9db45512011-07-04 07:27:17 +00002155 if(count_usable_erasers(flash) == 0) {
Stefan Tauner5368dca2011-07-01 00:19:12 +00002156 msg_cerr("flashrom has no erase function for this "
2157 "flash chip.\n");
2158 return 1;
2159 }
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002160 }
2161 if (write_it) {
Stefan Tauner6455dff2014-05-26 00:36:24 +00002162 if (chip->tested.write == NA) {
2163 msg_cerr("Write is not possible on this chip.\n");
2164 return 1;
2165 }
2166 if (chip->tested.write == BAD) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002167 msg_cerr("Write is not working on this chip. ");
2168 if (!force)
2169 return 1;
2170 msg_cerr("Continuing anyway.\n");
2171 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00002172 if (!chip->write) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002173 msg_cerr("flashrom has no write function for this "
2174 "flash chip.\n");
2175 return 1;
2176 }
2177 }
2178 return 0;
2179}
2180
Nico Huber305f4172013-06-14 11:55:26 +02002181int prepare_flash_access(struct flashctx *const flash,
2182 const bool read_it, const bool write_it,
2183 const bool erase_it, const bool verify_it)
Nico Huber454f6132012-12-10 13:34:10 +00002184{
2185 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
2186 msg_cerr("Aborting.\n");
2187 return 1;
2188 }
2189
2190 if (flash->layout == get_global_layout() && normalize_romentries(flash)) {
2191 msg_cerr("Requested regions can not be handled. Aborting.\n");
2192 return 1;
2193 }
2194
2195 if (map_flash(flash) != 0)
2196 return 1;
2197
2198 /* Given the existence of read locks, we want to unlock for read,
2199 erase and write. */
2200 if (flash->chip->unlock)
2201 flash->chip->unlock(flash);
2202
Nico Huberf43c6542017-10-14 17:47:28 +02002203 flash->address_high_byte = -1;
2204 flash->in_4ba_mode = false;
2205
Nico Huberdc5af542018-12-22 16:54:59 +01002206 /* Be careful about 4BA chips and broken masters */
2207 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2208 /* If we can't use native instructions, bail out */
2209 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2210 || !spi_master_4ba(flash)) {
2211 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2212 return 1;
2213 }
2214 }
2215
Ed Swierkcc20a9b2017-07-03 13:17:18 -07002216 /* Enable/disable 4-byte addressing mode if flash chip supports it */
Nico Huber86bddb52018-03-13 18:14:52 +01002217 if (flash->chip->feature_bits & (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_ENTER_EAR7)) {
Nico Huberfe34d2a2017-11-10 21:10:20 +01002218 int ret;
2219 if (spi_master_4ba(flash))
2220 ret = spi_enter_4ba(flash);
2221 else
2222 ret = spi_exit_4ba(flash);
2223 if (ret) {
2224 msg_cerr("Failed to set correct 4BA mode! Aborting.\n");
Ed Swierkcc20a9b2017-07-03 13:17:18 -07002225 return 1;
Boris Baykov7fe85692016-06-11 18:29:03 +02002226 }
Boris Baykov99127182016-06-11 18:29:00 +02002227 }
2228
Nico Huber454f6132012-12-10 13:34:10 +00002229 return 0;
2230}
2231
Nico Huber305f4172013-06-14 11:55:26 +02002232void finalize_flash_access(struct flashctx *const flash)
Nico Huber454f6132012-12-10 13:34:10 +00002233{
2234 unmap_flash(flash);
2235}
2236
2237/**
2238 * @addtogroup flashrom-flash
2239 * @{
2240 */
2241
2242/**
2243 * @brief Erase the specified ROM chip.
2244 *
2245 * If a layout is set in the given flash context, only included regions
2246 * will be erased.
2247 *
2248 * @param flashctx The context of the flash chip to erase.
2249 * @return 0 on success.
2250 */
2251int flashrom_flash_erase(struct flashctx *const flashctx)
2252{
2253 if (prepare_flash_access(flashctx, false, false, true, false))
2254 return 1;
2255
2256 const int ret = erase_by_layout(flashctx);
2257
2258 finalize_flash_access(flashctx);
2259
2260 return ret;
2261}
2262
2263/** @} */ /* end flashrom-flash */
2264
2265/**
2266 * @defgroup flashrom-ops Operations
2267 * @{
2268 */
2269
2270/**
2271 * @brief Read the current image from the specified ROM chip.
2272 *
2273 * If a layout is set in the specified flash context, only included regions
2274 * will be read.
2275 *
2276 * @param flashctx The context of the flash chip.
2277 * @param buffer Target buffer to write image to.
2278 * @param buffer_len Size of target buffer in bytes.
2279 * @return 0 on success,
2280 * 2 if buffer_len is too short for the flash chip's contents,
2281 * or 1 on any other failure.
2282 */
2283int flashrom_image_read(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len)
2284{
2285 const size_t flash_size = flashctx->chip->total_size * 1024;
2286
2287 if (flash_size > buffer_len)
2288 return 2;
2289
2290 if (prepare_flash_access(flashctx, true, false, false, false))
2291 return 1;
2292
2293 msg_cinfo("Reading flash... ");
2294
2295 int ret = 1;
2296 if (read_by_layout(flashctx, buffer)) {
2297 msg_cerr("Read operation failed!\n");
2298 msg_cinfo("FAILED.\n");
2299 goto _finalize_ret;
2300 }
2301 msg_cinfo("done.\n");
2302 ret = 0;
2303
2304_finalize_ret:
2305 finalize_flash_access(flashctx);
2306 return ret;
2307}
2308
2309static void combine_image_by_layout(const struct flashctx *const flashctx,
2310 uint8_t *const newcontents, const uint8_t *const oldcontents)
2311{
2312 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber3d7b1e32018-12-22 00:53:14 +01002313 const struct romentry *included;
2314 chipoff_t start = 0;
Nico Huber454f6132012-12-10 13:34:10 +00002315
Nico Huber3d7b1e32018-12-22 00:53:14 +01002316 while ((included = layout_next_included_region(layout, start))) {
2317 if (included->start > start) {
2318 /* copy everything up to the start of this included region */
2319 memcpy(newcontents + start, oldcontents + start, included->start - start);
2320 }
2321 /* skip this included region */
2322 start = included->end + 1;
2323 if (start == 0)
2324 return;
Nico Huber454f6132012-12-10 13:34:10 +00002325 }
Nico Huber3d7b1e32018-12-22 00:53:14 +01002326
2327 /* copy the rest of the chip */
2328 const chipsize_t copy_len = flashctx->chip->total_size * 1024 - start;
2329 memcpy(newcontents + start, oldcontents + start, copy_len);
Nico Huber454f6132012-12-10 13:34:10 +00002330}
2331
2332/**
2333 * @brief Write the specified image to the ROM chip.
2334 *
2335 * If a layout is set in the specified flash context, only erase blocks
2336 * containing included regions will be touched.
2337 *
2338 * @param flashctx The context of the flash chip.
Nico Huber1b172f22017-06-19 12:35:24 +02002339 * @param buffer Source buffer to read image from (may be altered for full verification).
Nico Huber454f6132012-12-10 13:34:10 +00002340 * @param buffer_len Size of source buffer in bytes.
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002341 * @param refbuffer If given, assume flash chip contains same data as `refbuffer`.
Nico Huber454f6132012-12-10 13:34:10 +00002342 * @return 0 on success,
2343 * 4 if buffer_len doesn't match the size of the flash chip,
2344 * 3 if write was tried but nothing has changed,
2345 * 2 if write failed and flash contents changed,
2346 * or 1 on any other failure.
2347 */
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002348int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len,
2349 const void *const refbuffer)
Nico Huber454f6132012-12-10 13:34:10 +00002350{
2351 const size_t flash_size = flashctx->chip->total_size * 1024;
2352 const bool verify_all = flashctx->flags.verify_whole_chip;
2353 const bool verify = flashctx->flags.verify_after_write;
2354
2355 if (buffer_len != flash_size)
2356 return 4;
2357
2358 int ret = 1;
2359
2360 uint8_t *const newcontents = buffer;
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002361 const uint8_t *const refcontents = refbuffer;
Nico Huber454f6132012-12-10 13:34:10 +00002362 uint8_t *const curcontents = malloc(flash_size);
2363 uint8_t *oldcontents = NULL;
2364 if (verify_all)
2365 oldcontents = malloc(flash_size);
2366 if (!curcontents || (verify_all && !oldcontents)) {
2367 msg_gerr("Out of memory!\n");
2368 goto _free_ret;
2369 }
2370
2371#if CONFIG_INTERNAL == 1
2372 if (programmer == PROGRAMMER_INTERNAL && cb_check_image(newcontents, flash_size) < 0) {
2373 if (flashctx->flags.force_boardmismatch) {
2374 msg_pinfo("Proceeding anyway because user forced us to.\n");
2375 } else {
2376 msg_perr("Aborting. You can override this with "
2377 "-p internal:boardmismatch=force.\n");
2378 goto _free_ret;
2379 }
2380 }
2381#endif
2382
2383 if (prepare_flash_access(flashctx, false, true, false, verify))
2384 goto _free_ret;
2385
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002386 /* If given, assume flash chip contains same data as `refcontents`. */
2387 if (refcontents) {
2388 msg_cinfo("Assuming old flash chip contents as ref-file...\n");
2389 memcpy(curcontents, refcontents, flash_size);
2390 if (oldcontents)
2391 memcpy(oldcontents, refcontents, flash_size);
Nico Huber454f6132012-12-10 13:34:10 +00002392 } else {
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002393 /*
2394 * Read the whole chip to be able to check whether regions need to be
2395 * erased and to give better diagnostics in case write fails.
2396 * The alternative is to read only the regions which are to be
2397 * preserved, but in that case we might perform unneeded erase which
2398 * takes time as well.
2399 */
2400 msg_cinfo("Reading old flash chip contents... ");
2401 if (verify_all) {
2402 if (flashctx->chip->read(flashctx, oldcontents, 0, flash_size)) {
2403 msg_cinfo("FAILED.\n");
2404 goto _finalize_ret;
2405 }
2406 memcpy(curcontents, oldcontents, flash_size);
2407 } else {
2408 if (read_by_layout(flashctx, curcontents)) {
2409 msg_cinfo("FAILED.\n");
2410 goto _finalize_ret;
2411 }
Nico Huber454f6132012-12-10 13:34:10 +00002412 }
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002413 msg_cinfo("done.\n");
Nico Huber454f6132012-12-10 13:34:10 +00002414 }
Nico Huber454f6132012-12-10 13:34:10 +00002415
2416 if (write_by_layout(flashctx, curcontents, newcontents)) {
2417 msg_cerr("Uh oh. Erase/write failed. ");
2418 ret = 2;
2419 if (verify_all) {
2420 msg_cerr("Checking if anything has changed.\n");
2421 msg_cinfo("Reading current flash chip contents... ");
2422 if (!flashctx->chip->read(flashctx, curcontents, 0, flash_size)) {
2423 msg_cinfo("done.\n");
2424 if (!memcmp(oldcontents, curcontents, flash_size)) {
2425 nonfatal_help_message();
2426 goto _finalize_ret;
2427 }
2428 msg_cerr("Apparently at least some data has changed.\n");
2429 } else
2430 msg_cerr("Can't even read anymore!\n");
2431 emergency_help_message();
2432 goto _finalize_ret;
2433 } else {
2434 msg_cerr("\n");
2435 }
2436 emergency_help_message();
2437 goto _finalize_ret;
2438 }
2439
2440 /* Verify only if we actually changed something. */
2441 if (verify && !all_skipped) {
2442 const struct flashrom_layout *const layout_bak = flashctx->layout;
2443
2444 msg_cinfo("Verifying flash... ");
2445
2446 /* Work around chips which need some time to calm down. */
2447 programmer_delay(1000*1000);
2448
2449 if (verify_all) {
2450 combine_image_by_layout(flashctx, newcontents, oldcontents);
2451 flashctx->layout = NULL;
2452 }
2453 ret = verify_by_layout(flashctx, curcontents, newcontents);
2454 flashctx->layout = layout_bak;
2455 /* If we tried to write, and verification now fails, we
2456 might have an emergency situation. */
2457 if (ret)
2458 emergency_help_message();
2459 else
2460 msg_cinfo("VERIFIED.\n");
2461 } else {
2462 /* We didn't change anything. */
2463 ret = 0;
2464 }
2465
2466_finalize_ret:
2467 finalize_flash_access(flashctx);
2468_free_ret:
2469 free(oldcontents);
2470 free(curcontents);
2471 return ret;
2472}
2473
2474/**
2475 * @brief Verify the ROM chip's contents with the specified image.
2476 *
2477 * If a layout is set in the specified flash context, only included regions
2478 * will be verified.
2479 *
2480 * @param flashctx The context of the flash chip.
2481 * @param buffer Source buffer to verify with.
2482 * @param buffer_len Size of source buffer in bytes.
2483 * @return 0 on success,
2484 * 3 if the chip's contents don't match,
2485 * 2 if buffer_len doesn't match the size of the flash chip,
2486 * or 1 on any other failure.
2487 */
2488int flashrom_image_verify(struct flashctx *const flashctx, const void *const buffer, const size_t buffer_len)
2489{
2490 const size_t flash_size = flashctx->chip->total_size * 1024;
2491
2492 if (buffer_len != flash_size)
2493 return 2;
2494
2495 const uint8_t *const newcontents = buffer;
2496 uint8_t *const curcontents = malloc(flash_size);
2497 if (!curcontents) {
2498 msg_gerr("Out of memory!\n");
2499 return 1;
2500 }
2501
2502 int ret = 1;
2503
2504 if (prepare_flash_access(flashctx, false, false, false, true))
2505 goto _free_ret;
2506
2507 msg_cinfo("Verifying flash... ");
2508 ret = verify_by_layout(flashctx, curcontents, newcontents);
2509 if (!ret)
2510 msg_cinfo("VERIFIED.\n");
2511
2512 finalize_flash_access(flashctx);
2513_free_ret:
2514 free(curcontents);
2515 return ret;
2516}
2517
2518/** @} */ /* end flashrom-ops */
Nico Huber899e4ec2016-04-29 18:39:01 +02002519
2520int do_read(struct flashctx *const flash, const char *const filename)
2521{
2522 if (prepare_flash_access(flash, true, false, false, false))
2523 return 1;
2524
2525 const int ret = read_flash_to_file(flash, filename);
2526
2527 finalize_flash_access(flash);
2528
2529 return ret;
2530}
2531
2532int do_erase(struct flashctx *const flash)
2533{
2534 const int ret = flashrom_flash_erase(flash);
2535
2536 /*
2537 * FIXME: Do we really want the scary warning if erase failed?
2538 * After all, after erase the chip is either blank or partially
2539 * blank or it has the old contents. A blank chip won't boot,
2540 * so if the user wanted erase and reboots afterwards, the user
2541 * knows very well that booting won't work.
2542 */
2543 if (ret)
2544 emergency_help_message();
2545
2546 return ret;
2547}
2548
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002549int do_write(struct flashctx *const flash, const char *const filename, const char *const referencefile)
Nico Huber899e4ec2016-04-29 18:39:01 +02002550{
2551 const size_t flash_size = flash->chip->total_size * 1024;
2552 int ret = 1;
2553
2554 uint8_t *const newcontents = malloc(flash_size);
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002555 uint8_t *const refcontents = referencefile ? malloc(flash_size) : NULL;
2556
2557 if (!newcontents || (referencefile && !refcontents)) {
Nico Huber899e4ec2016-04-29 18:39:01 +02002558 msg_gerr("Out of memory!\n");
2559 goto _free_ret;
2560 }
2561
2562 if (read_buf_from_file(newcontents, flash_size, filename))
2563 goto _free_ret;
2564
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002565 if (referencefile) {
2566 if (read_buf_from_file(refcontents, flash_size, referencefile))
2567 goto _free_ret;
2568 }
2569
2570 ret = flashrom_image_write(flash, newcontents, flash_size, refcontents);
Nico Huber899e4ec2016-04-29 18:39:01 +02002571
2572_free_ret:
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002573 free(refcontents);
Nico Huber899e4ec2016-04-29 18:39:01 +02002574 free(newcontents);
2575 return ret;
2576}
2577
2578int do_verify(struct flashctx *const flash, const char *const filename)
2579{
2580 const size_t flash_size = flash->chip->total_size * 1024;
2581 int ret = 1;
2582
2583 uint8_t *const newcontents = malloc(flash_size);
2584 if (!newcontents) {
2585 msg_gerr("Out of memory!\n");
2586 goto _free_ret;
2587 }
2588
2589 if (read_buf_from_file(newcontents, flash_size, filename))
2590 goto _free_ret;
2591
2592 ret = flashrom_image_verify(flash, newcontents, flash_size);
2593
2594_free_ret:
2595 free(newcontents);
2596 return ret;
2597}