blob: 2534e4a7a6d029d2ecc64a8a84a0266d780cbaa4 [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
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +0000463 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000464};
Luc Verhaegen8e3a6002007-04-04 22:45:58 +0000465
Carl-Daniel Hailfinger2bee8cf2010-11-10 15:25:18 +0000466#define SHUTDOWN_MAXFN 32
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000467static int shutdown_fn_count = 0;
Nico Huber454f6132012-12-10 13:34:10 +0000468/** @private */
Richard Hughes93e16252018-12-19 11:54:47 +0000469static struct shutdown_func_data {
David Hendricks8bb20212011-06-14 01:35:36 +0000470 int (*func) (void *data);
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000471 void *data;
Richard Hughes93e16252018-12-19 11:54:47 +0000472} shutdown_fn[SHUTDOWN_MAXFN];
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000473/* Initialize to 0 to make sure nobody registers a shutdown function before
474 * programmer init.
475 */
476static int may_register_shutdown = 0;
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000477
Stefan Taunerc4f44df2013-08-12 22:58:43 +0000478/* Did we change something or was every erase/write skipped (if any)? */
479static bool all_skipped = true;
480
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000481static int check_block_eraser(const struct flashctx *flash, int k, int log);
Stefan Tauner5368dca2011-07-01 00:19:12 +0000482
Stefan Tauner2a1ed772014-08-31 00:09:21 +0000483int shutdown_free(void *data)
484{
485 free(data);
486 return 0;
487}
488
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000489/* Register a function to be executed on programmer shutdown.
490 * The advantage over atexit() is that you can supply a void pointer which will
491 * be used as parameter to the registered function upon programmer shutdown.
492 * This pointer can point to arbitrary data used by said function, e.g. undo
493 * information for GPIO settings etc. If unneeded, set data=NULL.
494 * Please note that the first (void *data) belongs to the function signature of
495 * the function passed as first parameter.
496 */
David Hendricks8bb20212011-06-14 01:35:36 +0000497int register_shutdown(int (*function) (void *data), void *data)
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000498{
499 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
Carl-Daniel Hailfinger9f5f2152010-06-04 23:20:21 +0000500 msg_perr("Tried to register more than %i shutdown functions.\n",
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000501 SHUTDOWN_MAXFN);
502 return 1;
503 }
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000504 if (!may_register_shutdown) {
505 msg_perr("Tried to register a shutdown function before "
506 "programmer init.\n");
507 return 1;
508 }
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000509 shutdown_fn[shutdown_fn_count].func = function;
510 shutdown_fn[shutdown_fn_count].data = data;
511 shutdown_fn_count++;
512
513 return 0;
514}
515
Nico Huberbcb2e5a2012-12-30 01:23:17 +0000516int programmer_init(enum programmer prog, const char *param)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000517{
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000518 int ret;
Carl-Daniel Hailfinger2e681602011-09-08 00:00:29 +0000519
520 if (prog >= PROGRAMMER_INVALID) {
521 msg_perr("Invalid programmer specified!\n");
522 return -1;
523 }
524 programmer = prog;
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000525 /* Initialize all programmer specific data. */
526 /* Default to unlimited decode sizes. */
527 max_rom_decode = (const struct decode_sizes) {
528 .parallel = 0xffffffff,
529 .lpc = 0xffffffff,
530 .fwh = 0xffffffff,
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000531 .spi = 0xffffffff,
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000532 };
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000533 /* Default to top aligned flash at 4 GB. */
534 flashbase = 0;
535 /* Registering shutdown functions is now allowed. */
536 may_register_shutdown = 1;
Carl-Daniel Hailfingerd1be52d2010-07-03 12:14:25 +0000537 /* Default to allowing writes. Broken programmers set this to 0. */
538 programmer_may_write = 1;
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000539
540 programmer_param = param;
Carl-Daniel Hailfinger20a36ba2013-08-13 07:09:57 +0000541 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000542 ret = programmer_table[programmer].init();
543 if (programmer_param && strlen(programmer_param)) {
Carl-Daniel Hailfinger20a36ba2013-08-13 07:09:57 +0000544 if (ret != 0) {
545 /* It is quite possible that any unhandled programmer parameter would have been valid,
546 * but an error in actual programmer init happened before the parameter was evaluated.
547 */
548 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
549 programmer_param);
550 } else {
551 /* Actual programmer init was successful, but the user specified an invalid or unusable
552 * (for the current programmer configuration) parameter.
553 */
554 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
555 msg_perr("Aborting.\n");
556 ret = ERROR_FATAL;
557 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000558 }
559 return ret;
Uwe Hermann09e04f72009-05-16 22:36:00 +0000560}
561
Stefan Tauner20da4aa2014-05-07 22:07:23 +0000562/** Calls registered shutdown functions and resets internal programmer-related variables.
563 * Calling it is safe even without previous initialization, but further interactions with programmer support
564 * require a call to programmer_init() (afterwards).
565 *
566 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
Uwe Hermann09e04f72009-05-16 22:36:00 +0000567int programmer_shutdown(void)
568{
David Hendricks8bb20212011-06-14 01:35:36 +0000569 int ret = 0;
570
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000571 /* Registering shutdown functions is no longer allowed. */
572 may_register_shutdown = 0;
573 while (shutdown_fn_count > 0) {
574 int i = --shutdown_fn_count;
David Hendricks8bb20212011-06-14 01:35:36 +0000575 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000576 }
Stefan Taunere34e3e82013-01-01 00:06:51 +0000577
Stefan Taunerb8911d62012-12-26 07:55:00 +0000578 programmer_param = NULL;
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000579 registered_master_count = 0;
Stefan Taunere34e3e82013-01-01 00:06:51 +0000580
David Hendricks8bb20212011-06-14 01:35:36 +0000581 return ret;
Uwe Hermann09e04f72009-05-16 22:36:00 +0000582}
583
Stefan Tauner305e0b92013-07-17 23:46:44 +0000584void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000585{
Stefan Tauner26e7a152013-09-13 17:21:05 +0000586 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
587 msg_gspew("%s: mapping %s from 0x%0*" PRIxPTR " to 0x%0*" PRIxPTR "\n",
588 __func__, descr, PRIxPTR_WIDTH, phys_addr, PRIxPTR_WIDTH, (uintptr_t) ret);
589 return ret;
Uwe Hermann09e04f72009-05-16 22:36:00 +0000590}
591
592void programmer_unmap_flash_region(void *virt_addr, size_t len)
593{
594 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Stefan Tauner4e32ec12014-08-30 23:39:51 +0000595 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000596}
597
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000598void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000599{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000600 flash->mst->par.chip_writeb(flash, val, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000601}
602
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000603void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000604{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000605 flash->mst->par.chip_writew(flash, val, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000606}
607
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000608void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000609{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000610 flash->mst->par.chip_writel(flash, val, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000611}
612
Mark Marshallf20b7be2014-05-09 21:16:21 +0000613void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000614{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000615 flash->mst->par.chip_writen(flash, buf, addr, len);
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000616}
617
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000618uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000619{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000620 return flash->mst->par.chip_readb(flash, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000621}
622
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000623uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000624{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000625 return flash->mst->par.chip_readw(flash, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000626}
627
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000628uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000629{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000630 return flash->mst->par.chip_readl(flash, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000631}
632
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000633void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
634 size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000635{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000636 flash->mst->par.chip_readn(flash, buf, addr, len);
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000637}
638
Stefan Taunerf80419c2014-05-02 15:41:42 +0000639void programmer_delay(unsigned int usecs)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000640{
Urja Rannikko8d7ec2a2013-10-21 21:49:08 +0000641 if (usecs > 0)
642 programmer_table[programmer].delay(usecs);
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000643}
644
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000645int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
646 int unsigned len)
Carl-Daniel Hailfinger03b4e712009-05-08 12:49:03 +0000647{
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000648 chip_readn(flash, buf, flash->virtual_memory + start, len);
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000649
Carl-Daniel Hailfinger03b4e712009-05-08 12:49:03 +0000650 return 0;
651}
652
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000653/* This is a somewhat hacked function similar in some ways to strtok().
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000654 * It will look for needle with a subsequent '=' in haystack, return a copy of
655 * needle and remove everything from the first occurrence of needle to the next
656 * delimiter from haystack.
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000657 */
Nico Huberbcb2e5a2012-12-30 01:23:17 +0000658char *extract_param(const char *const *haystack, const char *needle, const char *delim)
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000659{
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000660 char *param_pos, *opt_pos, *rest;
661 char *opt = NULL;
662 int optlen;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000663 int needlelen;
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000664
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000665 needlelen = strlen(needle);
666 if (!needlelen) {
667 msg_gerr("%s: empty needle! Please report a bug at "
668 "flashrom@flashrom.org\n", __func__);
669 return NULL;
670 }
671 /* No programmer parameters given. */
672 if (*haystack == NULL)
673 return NULL;
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000674 param_pos = strstr(*haystack, needle);
675 do {
676 if (!param_pos)
677 return NULL;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000678 /* Needle followed by '='? */
679 if (param_pos[needlelen] == '=') {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000680 /* Beginning of the string? */
681 if (param_pos == *haystack)
682 break;
683 /* After a delimiter? */
684 if (strchr(delim, *(param_pos - 1)))
685 break;
686 }
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000687 /* Continue searching. */
688 param_pos++;
689 param_pos = strstr(param_pos, needle);
690 } while (1);
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000691
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000692 if (param_pos) {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000693 /* Get the string after needle and '='. */
694 opt_pos = param_pos + needlelen + 1;
695 optlen = strcspn(opt_pos, delim);
696 /* Return an empty string if the parameter was empty. */
697 opt = malloc(optlen + 1);
698 if (!opt) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000699 msg_gerr("Out of memory!\n");
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000700 exit(1);
701 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000702 strncpy(opt, opt_pos, optlen);
703 opt[optlen] = '\0';
704 rest = opt_pos + optlen;
705 /* Skip all delimiters after the current parameter. */
706 rest += strspn(rest, delim);
707 memmove(param_pos, rest, strlen(rest) + 1);
708 /* We could shrink haystack, but the effort is not worth it. */
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000709 }
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000710
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000711 return opt;
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000712}
713
Stefan Tauner66652442011-06-26 17:38:17 +0000714char *extract_programmer_param(const char *param_name)
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000715{
716 return extract_param(&programmer_param, param_name, ",");
717}
718
Sylvain "ythier" Hitier9db45512011-07-04 07:27:17 +0000719/* Returns the number of well-defined erasers for a chip. */
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000720static unsigned int count_usable_erasers(const struct flashctx *flash)
Stefan Tauner5368dca2011-07-01 00:19:12 +0000721{
722 unsigned int usable_erasefunctions = 0;
723 int k;
724 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
725 if (!check_block_eraser(flash, k, 0))
726 usable_erasefunctions++;
727 }
728 return usable_erasefunctions;
729}
730
Mark Marshallf20b7be2014-05-09 21:16:21 +0000731static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Stefan Tauner78ffbea2012-10-27 15:36:56 +0000732{
733 int ret = 0, failcount = 0;
734 unsigned int i;
735 for (i = 0; i < len; i++) {
736 if (wantbuf[i] != havebuf[i]) {
737 /* Only print the first failure. */
738 if (!failcount++)
739 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
740 start + i, wantbuf[i], havebuf[i]);
741 }
742 }
743 if (failcount) {
744 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
745 start, start + len - 1, failcount);
746 ret = -1;
747 }
748 return ret;
749}
750
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000751/* start is an offset to the base address of the flash chip */
Jacob Garberbeeb8bc2019-06-21 15:24:17 -0600752static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000753{
754 int ret;
755 uint8_t *cmpbuf = malloc(len);
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300756 const uint8_t erased_value = ERASED_VALUE(flash);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000757
758 if (!cmpbuf) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000759 msg_gerr("Could not allocate memory!\n");
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000760 exit(1);
761 }
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300762 memset(cmpbuf, erased_value, len);
Stefan Tauner78ffbea2012-10-27 15:36:56 +0000763 ret = verify_range(flash, cmpbuf, start, len);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000764 free(cmpbuf);
765 return ret;
766}
767
Uwe Hermann48ec1b12010-08-08 17:01:18 +0000768/*
Carl-Daniel Hailfingerd0250a32009-11-25 17:05:52 +0000769 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000770 * flash content at location start
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000771 * @start offset to the base address of the flash chip
772 * @len length of the verified area
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000773 * @return 0 for success, -1 for failure
774 */
Mark Marshallf20b7be2014-05-09 21:16:21 +0000775int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000776{
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000777 if (!len)
Stefan Taunerdf64a422014-05-27 00:06:14 +0000778 return -1;
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000779
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000780 if (!flash->chip->read) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000781 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Stefan Taunerdf64a422014-05-27 00:06:14 +0000782 return -1;
Carl-Daniel Hailfinger23290662009-06-24 08:20:45 +0000783 }
Stefan Taunerdf64a422014-05-27 00:06:14 +0000784
785 uint8_t *readbuf = malloc(len);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000786 if (!readbuf) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000787 msg_gerr("Could not allocate memory!\n");
Stefan Taunerdf64a422014-05-27 00:06:14 +0000788 return -1;
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000789 }
Stefan Taunerdf64a422014-05-27 00:06:14 +0000790 int ret = 0;
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000791
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000792 if (start + len > flash->chip->total_size * 1024) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000793 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000794 " total_size 0x%x\n", __func__, start, len,
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000795 flash->chip->total_size * 1024);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000796 ret = -1;
797 goto out_free;
798 }
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000799
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000800 ret = flash->chip->read(flash, readbuf, start, len);
Carl-Daniel Hailfingerd8369412010-11-16 17:21:58 +0000801 if (ret) {
802 msg_gerr("Verification impossible because read failed "
803 "at 0x%x (len 0x%x)\n", start, len);
Stefan Taunerdf64a422014-05-27 00:06:14 +0000804 ret = -1;
805 goto out_free;
Carl-Daniel Hailfingerd8369412010-11-16 17:21:58 +0000806 }
807
Stefan Tauner78ffbea2012-10-27 15:36:56 +0000808 ret = compare_range(cmpbuf, readbuf, start, len);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000809out_free:
810 free(readbuf);
811 return ret;
812}
813
Stefan Tauner02437452013-04-01 19:34:53 +0000814/* Helper function for need_erase() that focuses on granularities of gran bytes. */
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300815static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
816 unsigned int gran, const uint8_t erased_value)
Stefan Tauner02437452013-04-01 19:34:53 +0000817{
818 unsigned int i, j, limit;
819 for (j = 0; j < len / gran; j++) {
820 limit = min (gran, len - j * gran);
821 /* Are 'have' and 'want' identical? */
822 if (!memcmp(have + j * gran, want + j * gran, limit))
823 continue;
824 /* have needs to be in erased state. */
825 for (i = 0; i < limit; i++)
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300826 if (have[j * gran + i] != erased_value)
Stefan Tauner02437452013-04-01 19:34:53 +0000827 return 1;
828 }
829 return 0;
830}
831
Uwe Hermann48ec1b12010-08-08 17:01:18 +0000832/*
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000833 * Check if the buffer @have can be programmed to the content of @want without
834 * erasing. This is only possible if all chunks of size @gran are either kept
835 * as-is or changed from an all-ones state to any other state.
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000836 *
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000837 * Warning: This function assumes that @have and @want point to naturally
838 * aligned regions.
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000839 *
840 * @have buffer with current content
841 * @want buffer with desired content
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000842 * @len length of the checked area
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000843 * @gran write granularity (enum, not count)
844 * @return 0 if no erase is needed, 1 otherwise
845 */
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300846int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
847 enum write_granularity gran, const uint8_t erased_value)
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000848{
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +0000849 int result = 0;
Stefan Tauner02437452013-04-01 19:34:53 +0000850 unsigned int i;
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000851
852 switch (gran) {
853 case write_gran_1bit:
854 for (i = 0; i < len; i++)
855 if ((have[i] & want[i]) != want[i]) {
856 result = 1;
857 break;
858 }
859 break;
860 case write_gran_1byte:
861 for (i = 0; i < len; i++)
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300862 if ((have[i] != want[i]) && (have[i] != erased_value)) {
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000863 result = 1;
864 break;
865 }
866 break;
Paul Kocialkowskic8305e12015-10-16 02:16:20 +0000867 case write_gran_128bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300868 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Paul Kocialkowskic8305e12015-10-16 02:16:20 +0000869 break;
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000870 case write_gran_256bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300871 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000872 break;
873 case write_gran_264bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300874 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000875 break;
876 case write_gran_512bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300877 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000878 break;
879 case write_gran_528bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300880 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000881 break;
882 case write_gran_1024bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300883 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000884 break;
885 case write_gran_1056bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300886 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000887 break;
Carl-Daniel Hailfinger1b0e9fc2014-06-16 22:36:17 +0000888 case write_gran_1byte_implicit_erase:
889 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
890 result = 0;
891 break;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000892 default:
893 msg_cerr("%s: Unsupported granularity! Please report a bug at "
894 "flashrom@flashrom.org\n", __func__);
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000895 }
896 return result;
897}
898
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000899/**
900 * Check if the buffer @have needs to be programmed to get the content of @want.
901 * If yes, return 1 and fill in first_start with the start address of the
902 * write operation and first_len with the length of the first to-be-written
903 * chunk. If not, return 0 and leave first_start and first_len undefined.
904 *
905 * Warning: This function assumes that @have and @want point to naturally
906 * aligned regions.
907 *
908 * @have buffer with current content
909 * @want buffer with desired content
910 * @len length of the checked area
911 * @gran write granularity (enum, not count)
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000912 * @first_start offset of the first byte which needs to be written (passed in
913 * value is increased by the offset of the first needed write
914 * relative to have/want or unchanged if no write is needed)
915 * @return length of the first contiguous area which needs to be written
916 * 0 if no write is needed
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000917 *
918 * FIXME: This function needs a parameter which tells it about coalescing
919 * in relation to the max write length of the programmer and the max write
920 * length of the chip.
921 */
Mark Marshallf20b7be2014-05-09 21:16:21 +0000922static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
Stefan Taunerc69c9c82011-11-23 09:13:48 +0000923 unsigned int *first_start,
924 enum write_granularity gran)
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000925{
Stefan Taunerc69c9c82011-11-23 09:13:48 +0000926 int need_write = 0;
927 unsigned int rel_start = 0, first_len = 0;
928 unsigned int i, limit, stride;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000929
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000930 switch (gran) {
931 case write_gran_1bit:
932 case write_gran_1byte:
Carl-Daniel Hailfinger1b0e9fc2014-06-16 22:36:17 +0000933 case write_gran_1byte_implicit_erase:
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000934 stride = 1;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000935 break;
Paul Kocialkowskic8305e12015-10-16 02:16:20 +0000936 case write_gran_128bytes:
937 stride = 128;
938 break;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000939 case write_gran_256bytes:
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000940 stride = 256;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000941 break;
Stefan Tauner02437452013-04-01 19:34:53 +0000942 case write_gran_264bytes:
943 stride = 264;
944 break;
945 case write_gran_512bytes:
946 stride = 512;
947 break;
948 case write_gran_528bytes:
949 stride = 528;
950 break;
951 case write_gran_1024bytes:
952 stride = 1024;
953 break;
954 case write_gran_1056bytes:
955 stride = 1056;
956 break;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000957 default:
958 msg_cerr("%s: Unsupported granularity! Please report a bug at "
959 "flashrom@flashrom.org\n", __func__);
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000960 /* Claim that no write was needed. A write with unknown
961 * granularity is too dangerous to try.
962 */
963 return 0;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000964 }
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000965 for (i = 0; i < len / stride; i++) {
966 limit = min(stride, len - i * stride);
967 /* Are 'have' and 'want' identical? */
968 if (memcmp(have + i * stride, want + i * stride, limit)) {
969 if (!need_write) {
970 /* First location where have and want differ. */
971 need_write = 1;
972 rel_start = i * stride;
973 }
974 } else {
975 if (need_write) {
976 /* First location where have and want
977 * do not differ anymore.
978 */
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000979 break;
980 }
981 }
982 }
Carl-Daniel Hailfinger202bf532010-12-06 13:05:44 +0000983 if (need_write)
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000984 first_len = min(i * stride - rel_start, len);
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000985 *first_start += rel_start;
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000986 return first_len;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000987}
988
Stefan Tauner9e3a6982014-08-15 17:17:59 +0000989/* Returns the number of busses commonly supported by the current programmer and flash chip where the latter
990 * can not be completely accessed due to size/address limits of the programmer. */
991unsigned int count_max_decode_exceedings(const struct flashctx *flash)
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +0000992{
Stefan Tauner9e3a6982014-08-15 17:17:59 +0000993 unsigned int limitexceeded = 0;
994 uint32_t size = flash->chip->total_size * 1024;
995 enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000996
997 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +0000998 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +0000999 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001000 "size %u kB of chipset/board/programmer "
1001 "for %s interface, "
1002 "probe/read/erase/write may fail. ", size / 1024,
1003 max_rom_decode.parallel / 1024, "Parallel");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001004 }
Carl-Daniel Hailfinger1a227952011-07-27 07:13:06 +00001005 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001006 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +00001007 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001008 "size %u kB of chipset/board/programmer "
1009 "for %s interface, "
1010 "probe/read/erase/write may fail. ", size / 1024,
1011 max_rom_decode.lpc / 1024, "LPC");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001012 }
Carl-Daniel Hailfinger1a227952011-07-27 07:13:06 +00001013 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001014 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +00001015 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001016 "size %u kB of chipset/board/programmer "
1017 "for %s interface, "
1018 "probe/read/erase/write may fail. ", size / 1024,
1019 max_rom_decode.fwh / 1024, "FWH");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001020 }
Carl-Daniel Hailfinger1a227952011-07-27 07:13:06 +00001021 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001022 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +00001023 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001024 "size %u kB of chipset/board/programmer "
1025 "for %s interface, "
1026 "probe/read/erase/write may fail. ", size / 1024,
1027 max_rom_decode.spi / 1024, "SPI");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001028 }
Stefan Tauner9e3a6982014-08-15 17:17:59 +00001029 return limitexceeded;
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001030}
1031
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001032void unmap_flash(struct flashctx *flash)
1033{
1034 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1035 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1036 flash->physical_registers = 0;
1037 flash->virtual_registers = (chipaddr)ERROR_PTR;
1038 }
1039
1040 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1041 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1042 flash->physical_memory = 0;
1043 flash->virtual_memory = (chipaddr)ERROR_PTR;
1044 }
1045}
1046
1047int map_flash(struct flashctx *flash)
1048{
1049 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1050 flash->virtual_memory = (chipaddr)ERROR_PTR;
1051 flash->virtual_registers = (chipaddr)ERROR_PTR;
1052
1053 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1054 * These are used for various probing-related hacks that would not map successfully anyway and should be
1055 * removed ASAP. */
1056 if (flash->chip->total_size == 0)
1057 return 0;
1058
1059 const chipsize_t size = flash->chip->total_size * 1024;
1060 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1061 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1062 if (addr == ERROR_PTR) {
1063 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1064 flash->chip->name, PRIxPTR_WIDTH, base);
1065 return 1;
1066 }
1067 flash->physical_memory = base;
1068 flash->virtual_memory = (chipaddr)addr;
1069
1070 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1071 * completely different on some chips and programmers, or not mappable at all.
1072 * Ignore these problems for now and always report success. */
1073 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1074 base = 0xffffffff - size - 0x400000 + 1;
1075 addr = programmer_map_flash_region("flash chip registers", base, size);
1076 if (addr == ERROR_PTR) {
1077 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1078 flash->chip->name, PRIxPTR_WIDTH, base);
1079 return 0;
1080 }
1081 flash->physical_registers = base;
1082 flash->virtual_registers = (chipaddr)addr;
1083 }
1084 return 0;
1085}
1086
Nico Huber2d625722016-05-03 10:48:02 +02001087/*
1088 * Return a string corresponding to the bustype parameter.
1089 * Memory is obtained with malloc() and must be freed with free() by the caller.
1090 */
1091char *flashbuses_to_text(enum chipbustype bustype)
1092{
1093 char *ret = calloc(1, 1);
1094 /*
1095 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1096 * will cease to exist and should be eliminated here as well.
1097 */
1098 if (bustype == BUS_NONSPI) {
1099 ret = strcat_realloc(ret, "Non-SPI, ");
1100 } else {
1101 if (bustype & BUS_PARALLEL)
1102 ret = strcat_realloc(ret, "Parallel, ");
1103 if (bustype & BUS_LPC)
1104 ret = strcat_realloc(ret, "LPC, ");
1105 if (bustype & BUS_FWH)
1106 ret = strcat_realloc(ret, "FWH, ");
1107 if (bustype & BUS_SPI)
1108 ret = strcat_realloc(ret, "SPI, ");
1109 if (bustype & BUS_PROG)
1110 ret = strcat_realloc(ret, "Programmer-specific, ");
1111 if (bustype == BUS_NONE)
1112 ret = strcat_realloc(ret, "None, ");
1113 }
1114 /* Kill last comma. */
1115 ret[strlen(ret) - 2] = '\0';
1116 ret = realloc(ret, strlen(ret) + 1);
1117 return ret;
1118}
1119
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001120int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001121{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001122 const struct flashchip *chip;
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001123 enum chipbustype buses_common;
Carl-Daniel Hailfingerb22918c2009-06-01 02:08:58 +00001124 char *tmp;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001125
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001126 for (chip = flashchips + startchip; chip && chip->name; chip++) {
1127 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
Ollie Lhocbbf1252004-03-17 22:22:08 +00001128 continue;
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001129 buses_common = mst->buses_supported & chip->bustype;
Carl-Daniel Hailfingerc40cff72011-12-20 00:19:29 +00001130 if (!buses_common)
Carl-Daniel Hailfinger6573b742011-06-17 22:38:53 +00001131 continue;
Mike Banon31b5e3b2018-01-15 01:10:00 +03001132 /* Only probe for SPI25 chips by default. */
1133 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
1134 continue;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001135 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
1136 if (!chip->probe && !force) {
1137 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
Carl-Daniel Hailfingerb22918c2009-06-01 02:08:58 +00001138 continue;
1139 }
Stefan Reinauer70385642007-04-06 11:58:03 +00001140
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001141 /* Start filling in the dynamic data. */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001142 flash->chip = calloc(1, sizeof(struct flashchip));
1143 if (!flash->chip) {
1144 msg_gerr("Out of memory!\n");
1145 exit(1);
1146 }
1147 memcpy(flash->chip, chip, sizeof(struct flashchip));
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001148 flash->mst = mst;
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001149
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001150 if (map_flash(flash) != 0)
Martin Schiller57a3b732017-11-23 06:24:57 +01001151 goto notfound;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001152
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001153 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1154 * is only called with force=1 after normal probing failed.
1155 */
Peter Stuge27c3e2d2008-07-02 17:15:47 +00001156 if (force)
1157 break;
Stefan Reinauerfcb63682006-03-16 16:57:41 +00001158
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001159 if (flash->chip->probe(flash) != 1)
Peter Stuge483b8f02008-09-03 23:10:05 +00001160 goto notfound;
1161
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001162 /* If this is the first chip found, accept it.
1163 * If this is not the first chip found, accept it only if it is
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001164 * a non-generic match. SFDP and CFI are generic matches.
1165 * startchip==0 means this call to probe_flash() is the first
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001166 * one for this programmer interface (master) and thus no other chip has
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001167 * been found on this interface.
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001168 */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001169 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001170 msg_cinfo("===\n"
1171 "SFDP has autodetected a flash chip which is "
1172 "not natively supported by flashrom yet.\n");
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001173 if (count_usable_erasers(flash) == 0)
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001174 msg_cinfo("The standard operations read and "
1175 "verify should work, but to support "
1176 "erase, write and all other "
1177 "possible features");
1178 else
1179 msg_cinfo("All standard operations (read, "
1180 "verify, erase and write) should "
1181 "work, but to support all possible "
1182 "features");
1183
Stefan Taunerb4e06bd2012-08-20 00:24:22 +00001184 msg_cinfo(" we need to add them manually.\n"
1185 "You can help us by mailing us the output of the following command to "
1186 "flashrom@flashrom.org:\n"
1187 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1188 "Thanks for your help!\n"
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001189 "===\n");
1190 }
1191
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001192 /* First flash chip detected on this bus. */
1193 if (startchip == 0)
Peter Stuge27c3e2d2008-07-02 17:15:47 +00001194 break;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001195 /* Not the first flash chip detected on this bus, but not a generic match either. */
1196 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
1197 break;
1198 /* 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 +00001199notfound:
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001200 unmap_flash(flash);
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001201 free(flash->chip);
1202 flash->chip = NULL;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001203 }
Uwe Hermannffec5f32007-08-23 16:08:21 +00001204
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001205 if (!flash->chip)
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001206 return -1;
Peter Stuge27c3e2d2008-07-02 17:15:47 +00001207
Nico Huber7af0e792016-04-29 16:40:15 +02001208 /* Fill fallback layout covering the whole chip. */
1209 struct single_layout *const fallback = &flash->fallback_layout;
1210 fallback->base.entries = &fallback->entry;
1211 fallback->base.num_entries = 1;
1212 fallback->entry.start = 0;
1213 fallback->entry.end = flash->chip->total_size * 1024 - 1;
1214 fallback->entry.included = true;
Nico Huber70461a92019-06-15 14:56:19 +02001215 fallback->entry.name = strdup("complete flash");
1216 if (!fallback->entry.name) {
1217 msg_cerr("Failed to probe chip: %s\n", strerror(errno));
1218 return -1;
1219 }
Stefan Reinauer051e2362011-01-19 06:21:54 +00001220
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001221 tmp = flashbuses_to_text(flash->chip->bustype);
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001222 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1223 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
Stefan Tauner00155492011-06-26 20:45:35 +00001224 free(tmp);
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001225#if CONFIG_INTERNAL == 1
1226 if (programmer_table[programmer].map_flash_region == physmap)
1227 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1228 PRIxPTR_WIDTH, flash->physical_memory);
1229 else
1230#endif
1231 msg_cinfo("on %s.\n", programmer_table[programmer].name);
Uwe Hermann9899cad2009-06-28 21:47:57 +00001232
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001233 /* Flash registers may more likely not be mapped if the chip was forced.
1234 * Lock info may be stored in registers, so avoid lock info printing. */
Carl-Daniel Hailfinger859f3f02010-12-02 21:59:42 +00001235 if (!force)
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001236 if (flash->chip->printlock)
1237 flash->chip->printlock(flash);
Sean Nelson6e0b9122010-02-19 00:52:10 +00001238
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001239 /* Get out of the way for later runs. */
1240 unmap_flash(flash);
1241
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001242 /* Return position of matching chip. */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001243 return chip - flashchips;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001244}
1245
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001246int read_buf_from_file(unsigned char *buf, unsigned long size,
1247 const char *filename)
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001248{
Nico Huber7562f7d2013-08-30 21:29:45 +00001249#ifdef __LIBPAYLOAD__
1250 msg_gerr("Error: No file I/O support in libpayload\n");
1251 return 1;
1252#else
Stefan Tauner16687702015-12-25 21:59:45 +00001253 int ret = 0;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001254
Stefan Tauner16687702015-12-25 21:59:45 +00001255 FILE *image;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001256 if ((image = fopen(filename, "rb")) == NULL) {
Stefan Tauner363fd7e2013-04-07 13:08:30 +00001257 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001258 return 1;
1259 }
Stefan Tauner16687702015-12-25 21:59:45 +00001260
1261 struct stat image_stat;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001262 if (fstat(fileno(image), &image_stat) != 0) {
Stefan Tauner363fd7e2013-04-07 13:08:30 +00001263 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
Stefan Tauner16687702015-12-25 21:59:45 +00001264 ret = 1;
1265 goto out;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001266 }
Nico Huber519be662018-12-23 20:03:35 +01001267 if (image_stat.st_size != (intmax_t)size) {
Carl-Daniel Hailfinger11990da2013-07-13 23:21:05 +00001268 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 +00001269 (intmax_t)image_stat.st_size, size);
Stefan Tauner16687702015-12-25 21:59:45 +00001270 ret = 1;
1271 goto out;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001272 }
Stefan Tauner16687702015-12-25 21:59:45 +00001273
1274 unsigned long numbytes = fread(buf, 1, size, image);
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001275 if (numbytes != size) {
1276 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1277 "wanted %ld!\n", numbytes, size);
Stefan Tauner16687702015-12-25 21:59:45 +00001278 ret = 1;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001279 }
Stefan Tauner16687702015-12-25 21:59:45 +00001280out:
1281 (void)fclose(image);
1282 return ret;
Nico Huber7562f7d2013-08-30 21:29:45 +00001283#endif
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001284}
1285
Mark Marshallf20b7be2014-05-09 21:16:21 +00001286int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001287{
Nico Huber7562f7d2013-08-30 21:29:45 +00001288#ifdef __LIBPAYLOAD__
1289 msg_gerr("Error: No file I/O support in libpayload\n");
1290 return 1;
1291#else
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001292 FILE *image;
Stefan Tauner16687702015-12-25 21:59:45 +00001293 int ret = 0;
Stephan Guilloux21dd55b2009-06-01 22:07:52 +00001294
1295 if (!filename) {
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001296 msg_gerr("No filename specified.\n");
Stephan Guilloux21dd55b2009-06-01 22:07:52 +00001297 return 1;
1298 }
Patrick Georgi0bf842d2010-01-25 22:55:33 +00001299 if ((image = fopen(filename, "wb")) == NULL) {
Stefan Tauner363fd7e2013-04-07 13:08:30 +00001300 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
Carl-Daniel Hailfinger03b4e712009-05-08 12:49:03 +00001301 return 1;
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001302 }
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001303
Stefan Tauner16687702015-12-25 21:59:45 +00001304 unsigned long numbytes = fwrite(buf, 1, size, image);
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001305 if (numbytes != size) {
Stefan Tauner16687702015-12-25 21:59:45 +00001306 msg_gerr("Error: file %s could not be written completely.\n", filename);
1307 ret = 1;
1308 goto out;
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001309 }
Stefan Tauner16687702015-12-25 21:59:45 +00001310 if (fflush(image)) {
1311 msg_gerr("Error: flushing file \"%s\" failed: %s\n", filename, strerror(errno));
1312 ret = 1;
1313 }
1314 // Try to fsync() only regular files and if that function is available at all (e.g. not on MinGW).
1315#if defined(_POSIX_FSYNC) && (_POSIX_FSYNC != -1)
1316 struct stat image_stat;
1317 if (fstat(fileno(image), &image_stat) != 0) {
1318 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1319 ret = 1;
1320 goto out;
1321 }
1322 if (S_ISREG(image_stat.st_mode)) {
1323 if (fsync(fileno(image))) {
1324 msg_gerr("Error: fsyncing file \"%s\" failed: %s\n", filename, strerror(errno));
1325 ret = 1;
1326 }
1327 }
1328#endif
1329out:
1330 if (fclose(image)) {
1331 msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
1332 ret = 1;
1333 }
1334 return ret;
Nico Huber7562f7d2013-08-30 21:29:45 +00001335#endif
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001336}
1337
Nico Huber899e4ec2016-04-29 18:39:01 +02001338static int read_by_layout(struct flashctx *, uint8_t *);
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +00001339int read_flash_to_file(struct flashctx *flash, const char *filename)
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001340{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001341 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes84b453e2018-12-19 15:30:39 +00001342 unsigned char *buf = calloc(size, sizeof(unsigned char));
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001343 int ret = 0;
1344
1345 msg_cinfo("Reading flash... ");
1346 if (!buf) {
1347 msg_gerr("Memory allocation failed!\n");
1348 msg_cinfo("FAILED.\n");
1349 return 1;
1350 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001351 if (!flash->chip->read) {
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001352 msg_cerr("No read function available for this flash chip.\n");
1353 ret = 1;
1354 goto out_free;
1355 }
Nico Huber899e4ec2016-04-29 18:39:01 +02001356 if (read_by_layout(flash, buf)) {
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001357 msg_cerr("Read operation failed!\n");
1358 ret = 1;
1359 goto out_free;
1360 }
1361
Stefan Tauner355cbfd2011-05-28 02:37:14 +00001362 ret = write_buf_to_file(buf, size, filename);
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001363out_free:
1364 free(buf);
1365 msg_cinfo("%s.\n", ret ? "FAILED" : "done");
1366 return ret;
1367}
1368
Stefan Tauner96658be2014-05-26 22:05:31 +00001369/* Even if an error is found, the function will keep going and check the rest. */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001370static int selfcheck_eraseblocks(const struct flashchip *chip)
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001371{
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +00001372 int i, j, k;
1373 int ret = 0;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001374
1375 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1376 unsigned int done = 0;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001377 struct block_eraser eraser = chip->block_erasers[k];
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001378
1379 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1380 /* Blocks with zero size are bugs in flashchips.c. */
1381 if (eraser.eraseblocks[i].count &&
1382 !eraser.eraseblocks[i].size) {
1383 msg_gerr("ERROR: Flash chip %s erase function "
1384 "%i region %i has size 0. Please report"
1385 " a bug at flashrom@flashrom.org\n",
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001386 chip->name, k, i);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001387 ret = 1;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001388 }
1389 /* Blocks with zero count are bugs in flashchips.c. */
1390 if (!eraser.eraseblocks[i].count &&
1391 eraser.eraseblocks[i].size) {
1392 msg_gerr("ERROR: Flash chip %s erase function "
1393 "%i region %i has count 0. Please report"
1394 " a bug at flashrom@flashrom.org\n",
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001395 chip->name, k, i);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001396 ret = 1;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001397 }
1398 done += eraser.eraseblocks[i].count *
1399 eraser.eraseblocks[i].size;
1400 }
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001401 /* Empty eraseblock definition with erase function. */
1402 if (!done && eraser.block_erase)
Sean Nelson316a29f2010-05-07 20:09:04 +00001403 msg_gspew("Strange: Empty eraseblock definition with "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001404 "non-empty erase function. Not an error.\n");
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001405 if (!done)
1406 continue;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001407 if (done != chip->total_size * 1024) {
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001408 msg_gerr("ERROR: Flash chip %s erase function %i "
1409 "region walking resulted in 0x%06x bytes total,"
1410 " expected 0x%06x bytes. Please report a bug at"
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001411 " flashrom@flashrom.org\n", chip->name, k,
1412 done, chip->total_size * 1024);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001413 ret = 1;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001414 }
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001415 if (!eraser.block_erase)
1416 continue;
1417 /* Check if there are identical erase functions for different
1418 * layouts. That would imply "magic" erase functions. The
1419 * easiest way to check this is with function pointers.
1420 */
Uwe Hermann43959702010-03-13 17:28:29 +00001421 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001422 if (eraser.block_erase ==
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001423 chip->block_erasers[j].block_erase) {
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001424 msg_gerr("ERROR: Flash chip %s erase function "
1425 "%i and %i are identical. Please report"
1426 " a bug at flashrom@flashrom.org\n",
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001427 chip->name, k, j);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001428 ret = 1;
1429 }
Uwe Hermann43959702010-03-13 17:28:29 +00001430 }
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001431 }
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001432 return ret;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001433}
1434
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +00001435static int check_block_eraser(const struct flashctx *flash, int k, int log)
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001436{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001437 struct block_eraser eraser = flash->chip->block_erasers[k];
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001438
1439 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1440 if (log)
1441 msg_cdbg("not defined. ");
1442 return 1;
1443 }
1444 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1445 if (log)
1446 msg_cdbg("eraseblock layout is known, but matching "
Stefan Tauner355cbfd2011-05-28 02:37:14 +00001447 "block erase function is not implemented. ");
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001448 return 1;
1449 }
1450 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1451 if (log)
1452 msg_cdbg("block erase function found, but "
Stefan Tauner355cbfd2011-05-28 02:37:14 +00001453 "eraseblock layout is not defined. ");
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001454 return 1;
1455 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001456 // TODO: Once erase functions are annotated with allowed buses, check that as well.
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001457 return 0;
1458}
1459
Nico Huber7af0e792016-04-29 16:40:15 +02001460/**
1461 * @brief Reads the included layout regions into a buffer.
1462 *
1463 * If there is no layout set in the given flash context, the whole chip will
1464 * be read.
1465 *
1466 * @param flashctx Flash context to be used.
1467 * @param buffer Buffer of full chip size to read into.
1468 * @return 0 on success,
1469 * 1 if any read fails.
1470 */
1471static int read_by_layout(struct flashctx *const flashctx, uint8_t *const buffer)
1472{
1473 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber5ca55232019-06-15 22:29:08 +02001474 const struct romentry *entry = NULL;
Nico Huber7af0e792016-04-29 16:40:15 +02001475
Nico Huber5ca55232019-06-15 22:29:08 +02001476 while ((entry = layout_next_included(layout, entry))) {
1477 const chipoff_t region_start = entry->start;
1478 const chipsize_t region_len = entry->end - entry->start + 1;
Nico Huber7af0e792016-04-29 16:40:15 +02001479
1480 if (flashctx->chip->read(flashctx, buffer + region_start, region_start, region_len))
1481 return 1;
1482 }
1483 return 0;
1484}
1485
1486typedef int (*erasefn_t)(struct flashctx *, unsigned int addr, unsigned int len);
1487/**
1488 * @private
1489 *
1490 * For read-erase-write, `curcontents` and `newcontents` shall point
1491 * to buffers of the chip's size. Both are supposed to be prefilled
1492 * with at least the included layout regions of the current flash
1493 * contents (`curcontents`) and the data to be written to the flash
1494 * (`newcontents`).
1495 *
1496 * For erase, `curcontents` and `newcontents` shall be NULL-pointers.
1497 *
1498 * The `chipoff_t` values are used internally by `walk_by_layout()`.
1499 */
1500struct walk_info {
1501 uint8_t *curcontents;
1502 const uint8_t *newcontents;
1503 chipoff_t region_start;
1504 chipoff_t region_end;
1505 chipoff_t erase_start;
1506 chipoff_t erase_end;
1507};
1508/* returns 0 on success, 1 to retry with another erase function, 2 for immediate abort */
1509typedef int (*per_blockfn_t)(struct flashctx *, const struct walk_info *, erasefn_t);
1510
1511static int walk_eraseblocks(struct flashctx *const flashctx,
1512 struct walk_info *const info,
1513 const size_t erasefunction, const per_blockfn_t per_blockfn)
1514{
1515 int ret;
1516 size_t i, j;
1517 bool first = true;
1518 struct block_eraser *const eraser = &flashctx->chip->block_erasers[erasefunction];
1519
1520 info->erase_start = 0;
1521 for (i = 0; i < NUM_ERASEREGIONS; ++i) {
1522 /* count==0 for all automatically initialized array
1523 members so the loop below won't be executed for them. */
1524 for (j = 0; j < eraser->eraseblocks[i].count; ++j, info->erase_start = info->erase_end + 1) {
1525 info->erase_end = info->erase_start + eraser->eraseblocks[i].size - 1;
1526
1527 /* Skip any eraseblock that is completely outside the current region. */
1528 if (info->erase_end < info->region_start)
1529 continue;
1530 if (info->region_end < info->erase_start)
1531 break;
1532
1533 /* Print this for every block except the first one. */
1534 if (first)
1535 first = false;
1536 else
1537 msg_cdbg(", ");
1538 msg_cdbg("0x%06x-0x%06x:", info->erase_start, info->erase_end);
1539
1540 ret = per_blockfn(flashctx, info, eraser->block_erase);
1541 if (ret)
1542 return ret;
1543 }
1544 if (info->region_end < info->erase_start)
1545 break;
1546 }
1547 msg_cdbg("\n");
1548 return 0;
1549}
1550
1551static int walk_by_layout(struct flashctx *const flashctx, struct walk_info *const info,
1552 const per_blockfn_t per_blockfn)
1553{
1554 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber5ca55232019-06-15 22:29:08 +02001555 const struct romentry *entry = NULL;
Nico Huber7af0e792016-04-29 16:40:15 +02001556
1557 all_skipped = true;
1558 msg_cinfo("Erasing and writing flash chip... ");
1559
Nico Huber5ca55232019-06-15 22:29:08 +02001560 while ((entry = layout_next_included(layout, entry))) {
1561 info->region_start = entry->start;
1562 info->region_end = entry->end;
Nico Huber7af0e792016-04-29 16:40:15 +02001563
1564 size_t j;
1565 int error = 1; /* retry as long as it's 1 */
1566 for (j = 0; j < NUM_ERASEFUNCTIONS; ++j) {
1567 if (j != 0)
1568 msg_cinfo("Looking for another erase function.\n");
1569 msg_cdbg("Trying erase function %zi... ", j);
1570 if (check_block_eraser(flashctx, j, 1))
1571 continue;
1572
1573 error = walk_eraseblocks(flashctx, info, j, per_blockfn);
1574 if (error != 1)
1575 break;
1576
1577 if (info->curcontents) {
1578 msg_cinfo("Reading current flash chip contents... ");
1579 if (read_by_layout(flashctx, info->curcontents)) {
1580 /* Now we are truly screwed. Read failed as well. */
1581 msg_cerr("Can't read anymore! Aborting.\n");
1582 /* We have no idea about the flash chip contents, so
1583 retrying with another erase function is pointless. */
1584 error = 2;
1585 break;
1586 }
1587 msg_cinfo("done. ");
1588 }
1589 }
1590 if (error == 1)
1591 msg_cinfo("No usable erase functions left.\n");
1592 if (error) {
1593 msg_cerr("FAILED!\n");
1594 return 1;
1595 }
1596 }
1597 if (all_skipped)
1598 msg_cinfo("\nWarning: Chip content is identical to the requested image.\n");
1599 msg_cinfo("Erase/write done.\n");
1600 return 0;
1601}
1602
1603static int erase_block(struct flashctx *const flashctx,
1604 const struct walk_info *const info, const erasefn_t erasefn)
1605{
1606 const unsigned int erase_len = info->erase_end + 1 - info->erase_start;
Nico Huber6e61e0c2019-01-23 17:07:49 +01001607 const bool region_unaligned = info->region_start > info->erase_start ||
1608 info->erase_end > info->region_end;
1609 uint8_t *backup_contents = NULL, *erased_contents = NULL;
1610 int ret = 2;
Nico Huber7af0e792016-04-29 16:40:15 +02001611
Nico Huber6e61e0c2019-01-23 17:07:49 +01001612 /*
1613 * If the region is not erase-block aligned, merge current flash con-
1614 * tents into a new buffer `backup_contents`.
1615 */
1616 if (region_unaligned) {
1617 backup_contents = malloc(erase_len);
1618 erased_contents = malloc(erase_len);
1619 if (!backup_contents || !erased_contents) {
1620 msg_cerr("Out of memory!\n");
1621 ret = 1;
1622 goto _free_ret;
1623 }
1624 memset(backup_contents, ERASED_VALUE(flashctx), erase_len);
1625 memset(erased_contents, ERASED_VALUE(flashctx), erase_len);
1626
1627 msg_cdbg("R");
1628 /* Merge data preceding the current region. */
1629 if (info->region_start > info->erase_start) {
1630 const chipoff_t start = info->erase_start;
1631 const chipsize_t len = info->region_start - info->erase_start;
1632 if (flashctx->chip->read(flashctx, backup_contents, start, len)) {
1633 msg_cerr("Can't read! Aborting.\n");
1634 goto _free_ret;
1635 }
1636 }
1637 /* Merge data following the current region. */
1638 if (info->erase_end > info->region_end) {
1639 const chipoff_t start = info->region_end + 1;
1640 const chipoff_t rel_start = start - info->erase_start; /* within this erase block */
1641 const chipsize_t len = info->erase_end - info->region_end;
1642 if (flashctx->chip->read(flashctx, backup_contents + rel_start, start, len)) {
1643 msg_cerr("Can't read! Aborting.\n");
1644 goto _free_ret;
1645 }
1646 }
1647 }
1648
1649 ret = 1;
Nico Huber7af0e792016-04-29 16:40:15 +02001650 all_skipped = false;
1651
1652 msg_cdbg("E");
1653 if (erasefn(flashctx, info->erase_start, erase_len))
Nico Huber6e61e0c2019-01-23 17:07:49 +01001654 goto _free_ret;
Nico Huber7af0e792016-04-29 16:40:15 +02001655 if (check_erased_range(flashctx, info->erase_start, erase_len)) {
1656 msg_cerr("ERASE FAILED!\n");
Nico Huber6e61e0c2019-01-23 17:07:49 +01001657 goto _free_ret;
Nico Huber7af0e792016-04-29 16:40:15 +02001658 }
Nico Huber6e61e0c2019-01-23 17:07:49 +01001659
1660 if (region_unaligned) {
1661 unsigned int starthere = 0, lenhere = 0, writecount = 0;
1662 /* get_next_write() sets starthere to a new value after the call. */
1663 while ((lenhere = get_next_write(erased_contents + starthere, backup_contents + starthere,
1664 erase_len - starthere, &starthere, flashctx->chip->gran))) {
1665 if (!writecount++)
1666 msg_cdbg("W");
1667 /* Needs the partial write function signature. */
1668 if (flashctx->chip->write(flashctx, backup_contents + starthere,
1669 info->erase_start + starthere, lenhere))
1670 goto _free_ret;
1671 starthere += lenhere;
1672 }
1673 }
1674
1675 ret = 0;
1676
1677_free_ret:
1678 free(erased_contents);
1679 free(backup_contents);
1680 return ret;
Nico Huber7af0e792016-04-29 16:40:15 +02001681}
1682
1683/**
1684 * @brief Erases the included layout regions.
1685 *
1686 * If there is no layout set in the given flash context, the whole chip will
1687 * be erased.
1688 *
1689 * @param flashctx Flash context to be used.
1690 * @param buffer Buffer of full chip size to read into.
1691 * @return 0 on success,
1692 * 1 if all available erase functions failed.
1693 */
Nico Huber454f6132012-12-10 13:34:10 +00001694static int erase_by_layout(struct flashctx *const flashctx)
Nico Huber7af0e792016-04-29 16:40:15 +02001695{
1696 struct walk_info info = { 0 };
1697 return walk_by_layout(flashctx, &info, &erase_block);
1698}
1699
1700static int read_erase_write_block(struct flashctx *const flashctx,
1701 const struct walk_info *const info, const erasefn_t erasefn)
1702{
1703 const chipsize_t erase_len = info->erase_end + 1 - info->erase_start;
1704 const bool region_unaligned = info->region_start > info->erase_start ||
1705 info->erase_end > info->region_end;
1706 const uint8_t *newcontents = NULL;
1707 int ret = 2;
1708
1709 /*
1710 * If the region is not erase-block aligned, merge current flash con-
1711 * tents into `info->curcontents` and a new buffer `newc`. The former
1712 * is necessary since we have no guarantee that the full erase block
1713 * was already read into `info->curcontents`. For the latter a new
1714 * buffer is used since `info->newcontents` might contain data for
1715 * other unaligned regions that touch this erase block too.
1716 */
1717 if (region_unaligned) {
1718 msg_cdbg("R");
1719 uint8_t *const newc = malloc(erase_len);
1720 if (!newc) {
1721 msg_cerr("Out of memory!\n");
1722 return 1;
1723 }
1724 memcpy(newc, info->newcontents + info->erase_start, erase_len);
1725
1726 /* Merge data preceding the current region. */
1727 if (info->region_start > info->erase_start) {
1728 const chipoff_t start = info->erase_start;
1729 const chipsize_t len = info->region_start - info->erase_start;
1730 if (flashctx->chip->read(flashctx, newc, start, len)) {
1731 msg_cerr("Can't read! Aborting.\n");
1732 goto _free_ret;
1733 }
1734 memcpy(info->curcontents + start, newc, len);
1735 }
1736 /* Merge data following the current region. */
1737 if (info->erase_end > info->region_end) {
1738 const chipoff_t start = info->region_end + 1;
1739 const chipoff_t rel_start = start - info->erase_start; /* within this erase block */
1740 const chipsize_t len = info->erase_end - info->region_end;
1741 if (flashctx->chip->read(flashctx, newc + rel_start, start, len)) {
1742 msg_cerr("Can't read! Aborting.\n");
1743 goto _free_ret;
1744 }
1745 memcpy(info->curcontents + start, newc + rel_start, len);
1746 }
1747
1748 newcontents = newc;
1749 } else {
1750 newcontents = info->newcontents + info->erase_start;
1751 }
1752
1753 ret = 1;
1754 bool skipped = true;
1755 uint8_t *const curcontents = info->curcontents + info->erase_start;
Paul Kocialkowski995f7552018-01-15 01:06:09 +03001756 const uint8_t erased_value = ERASED_VALUE(flashctx);
David Hendricksf9a30552015-05-23 20:30:30 -07001757 if (!(flashctx->chip->feature_bits & FEATURE_NO_ERASE) &&
1758 need_erase(curcontents, newcontents, erase_len, flashctx->chip->gran, erased_value)) {
Nico Huber7af0e792016-04-29 16:40:15 +02001759 if (erase_block(flashctx, info, erasefn))
1760 goto _free_ret;
1761 /* Erase was successful. Adjust curcontents. */
Paul Kocialkowski995f7552018-01-15 01:06:09 +03001762 memset(curcontents, erased_value, erase_len);
Nico Huber7af0e792016-04-29 16:40:15 +02001763 skipped = false;
1764 }
1765
1766 unsigned int starthere = 0, lenhere = 0, writecount = 0;
1767 /* get_next_write() sets starthere to a new value after the call. */
1768 while ((lenhere = get_next_write(curcontents + starthere, newcontents + starthere,
1769 erase_len - starthere, &starthere, flashctx->chip->gran))) {
1770 if (!writecount++)
1771 msg_cdbg("W");
1772 /* Needs the partial write function signature. */
1773 if (flashctx->chip->write(flashctx, newcontents + starthere,
1774 info->erase_start + starthere, lenhere))
1775 goto _free_ret;
1776 starthere += lenhere;
1777 skipped = false;
1778 }
1779 if (skipped)
1780 msg_cdbg("S");
1781 else
1782 all_skipped = false;
1783
1784 /* Update curcontents, other regions with overlapping erase blocks
1785 might rely on this. */
1786 memcpy(curcontents, newcontents, erase_len);
1787 ret = 0;
1788
1789_free_ret:
1790 if (region_unaligned)
1791 free((void *)newcontents);
1792 return ret;
1793}
1794
1795/**
1796 * @brief Writes the included layout regions from a given image.
1797 *
1798 * If there is no layout set in the given flash context, the whole image
1799 * will be written.
1800 *
1801 * @param flashctx Flash context to be used.
1802 * @param curcontents A buffer of full chip size with current chip contents of included regions.
1803 * @param newcontents The new image to be written.
1804 * @return 0 on success,
1805 * 1 if anything has gone wrong.
1806 */
Nico Huber454f6132012-12-10 13:34:10 +00001807static int write_by_layout(struct flashctx *const flashctx,
1808 void *const curcontents, const void *const newcontents)
Nico Huber7af0e792016-04-29 16:40:15 +02001809{
1810 struct walk_info info;
1811 info.curcontents = curcontents;
1812 info.newcontents = newcontents;
1813 return walk_by_layout(flashctx, &info, read_erase_write_block);
1814}
1815
1816/**
1817 * @brief Compares the included layout regions with content from a buffer.
1818 *
1819 * If there is no layout set in the given flash context, the whole chip's
1820 * contents will be compared.
1821 *
1822 * @param flashctx Flash context to be used.
1823 * @param curcontents A buffer of full chip size to read current chip contents into.
1824 * @param newcontents The new image to compare to.
1825 * @return 0 on success,
1826 * 1 if reading failed,
1827 * 3 if the contents don't match.
1828 */
Nico Huber454f6132012-12-10 13:34:10 +00001829static int verify_by_layout(struct flashctx *const flashctx,
1830 void *const curcontents, const uint8_t *const newcontents)
Nico Huber7af0e792016-04-29 16:40:15 +02001831{
1832 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber5ca55232019-06-15 22:29:08 +02001833 const struct romentry *entry = NULL;
Nico Huber7af0e792016-04-29 16:40:15 +02001834
Nico Huber5ca55232019-06-15 22:29:08 +02001835 while ((entry = layout_next_included(layout, entry))) {
1836 const chipoff_t region_start = entry->start;
1837 const chipsize_t region_len = entry->end - entry->start + 1;
Nico Huber7af0e792016-04-29 16:40:15 +02001838
1839 if (flashctx->chip->read(flashctx, curcontents + region_start, region_start, region_len))
1840 return 1;
1841 if (compare_range(newcontents + region_start, curcontents + region_start,
1842 region_start, region_len))
1843 return 3;
1844 }
1845 return 0;
1846}
1847
Stefan Tauner136388f2013-07-15 10:47:53 +00001848static void nonfatal_help_message(void)
Carl-Daniel Hailfinger42d38a92010-10-19 22:06:20 +00001849{
Stefan Taunera58f6e92014-05-10 09:25:44 +00001850 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
Stefan Tauner136388f2013-07-15 10:47:53 +00001851#if CONFIG_INTERNAL == 1
1852 if (programmer == PROGRAMMER_INTERNAL)
1853 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
1854 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1855 "mail flashrom@flashrom.org, thanks!\n"
1856 "-------------------------------------------------------------------------------\n"
1857 "You may now reboot or simply leave the machine running.\n");
1858 else
1859#endif
1860 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
1861 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
1862 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1863 "mail flashrom@flashrom.org, thanks!\n");
Carl-Daniel Hailfinger42d38a92010-10-19 22:06:20 +00001864}
1865
Stefan Tauner136388f2013-07-15 10:47:53 +00001866static void emergency_help_message(void)
Carl-Daniel Hailfinger8ab49e72009-08-19 13:55:34 +00001867{
Stefan Tauner136388f2013-07-15 10:47:53 +00001868 msg_gerr("Your flash chip is in an unknown state.\n");
1869#if CONFIG_INTERNAL == 1
1870 if (programmer == PROGRAMMER_INTERNAL)
1871 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
1872 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
1873 "-------------------------------------------------------------------------------\n"
1874 "DO NOT REBOOT OR POWEROFF!\n");
1875 else
1876#endif
1877 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1878 "mail flashrom@flashrom.org, thanks!\n");
Carl-Daniel Hailfinger8ab49e72009-08-19 13:55:34 +00001879}
1880
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001881void list_programmers_linebreak(int startcol, int cols, int paren)
1882{
1883 const char *pname;
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +00001884 int pnamelen;
1885 int remaining = 0, firstline = 1;
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001886 enum programmer p;
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +00001887 int i;
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001888
1889 for (p = 0; p < PROGRAMMER_INVALID; p++) {
1890 pname = programmer_table[p].name;
1891 pnamelen = strlen(pname);
1892 if (remaining - pnamelen - 2 < 0) {
1893 if (firstline)
1894 firstline = 0;
1895 else
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001896 msg_ginfo("\n");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001897 for (i = 0; i < startcol; i++)
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001898 msg_ginfo(" ");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001899 remaining = cols - startcol;
1900 } else {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001901 msg_ginfo(" ");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001902 remaining--;
1903 }
1904 if (paren && (p == 0)) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001905 msg_ginfo("(");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001906 remaining--;
1907 }
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001908 msg_ginfo("%s", pname);
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001909 remaining -= pnamelen;
1910 if (p < PROGRAMMER_INVALID - 1) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001911 msg_ginfo(",");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001912 remaining--;
1913 } else {
1914 if (paren)
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001915 msg_ginfo(")");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001916 }
1917 }
1918}
1919
Jacob Garberbeeb8bc2019-06-21 15:24:17 -06001920static void print_sysinfo(void)
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001921{
Stefan Taunerb0eee9b2015-01-10 09:32:50 +00001922#if IS_WINDOWS
Carl-Daniel Hailfinger60d9bd22012-08-09 23:34:41 +00001923 SYSTEM_INFO si;
1924 OSVERSIONINFOEX osvi;
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001925
Carl-Daniel Hailfinger60d9bd22012-08-09 23:34:41 +00001926 memset(&si, 0, sizeof(SYSTEM_INFO));
1927 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
1928 msg_ginfo(" on Windows");
1929 /* Tell Windows which version of the structure we want. */
1930 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
1931 if (GetVersionEx((OSVERSIONINFO*) &osvi))
1932 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
1933 else
1934 msg_ginfo(" unknown version");
1935 GetSystemInfo(&si);
1936 switch (si.wProcessorArchitecture) {
1937 case PROCESSOR_ARCHITECTURE_AMD64:
1938 msg_ginfo(" (x86_64)");
1939 break;
1940 case PROCESSOR_ARCHITECTURE_INTEL:
1941 msg_ginfo(" (x86)");
1942 break;
1943 default:
1944 msg_ginfo(" (unknown arch)");
1945 break;
1946 }
1947#elif HAVE_UTSNAME == 1
1948 struct utsname osinfo;
1949
1950 uname(&osinfo);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001951 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
1952 osinfo.machine);
1953#else
1954 msg_ginfo(" on unknown machine");
1955#endif
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001956}
1957
1958void print_buildinfo(void)
1959{
1960 msg_gdbg("flashrom was built with");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001961#if NEED_PCI == 1
1962#ifdef PCILIB_VERSION
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001963 msg_gdbg(" libpci %s,", PCILIB_VERSION);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001964#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001965 msg_gdbg(" unknown PCI library,");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001966#endif
1967#endif
1968#ifdef __clang__
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001969 msg_gdbg(" LLVM Clang");
Carl-Daniel Hailfingerb51e58e2010-07-17 14:49:30 +00001970#ifdef __clang_version__
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001971 msg_gdbg(" %s,", __clang_version__);
Carl-Daniel Hailfingerb51e58e2010-07-17 14:49:30 +00001972#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001973 msg_gdbg(" unknown version (before r102686),");
Carl-Daniel Hailfingerb51e58e2010-07-17 14:49:30 +00001974#endif
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001975#elif defined(__GNUC__)
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001976 msg_gdbg(" GCC");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001977#ifdef __VERSION__
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001978 msg_gdbg(" %s,", __VERSION__);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001979#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001980 msg_gdbg(" unknown version,");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001981#endif
1982#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001983 msg_gdbg(" unknown compiler,");
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +00001984#endif
1985#if defined (__FLASHROM_LITTLE_ENDIAN__)
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001986 msg_gdbg(" little endian");
Carl-Daniel Hailfinger06b9efa2012-08-07 11:59:59 +00001987#elif defined (__FLASHROM_BIG_ENDIAN__)
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001988 msg_gdbg(" big endian");
Carl-Daniel Hailfinger06b9efa2012-08-07 11:59:59 +00001989#else
1990#error Endianness could not be determined
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001991#endif
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001992 msg_gdbg("\n");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001993}
1994
Bernhard Walle201bde32008-01-21 15:24:22 +00001995void print_version(void)
1996{
Stefan Tauner76347082016-11-27 17:45:49 +01001997 msg_ginfo("flashrom %s", flashrom_version);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001998 print_sysinfo();
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001999 msg_ginfo("\n");
Bernhard Walle201bde32008-01-21 15:24:22 +00002000}
2001
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +00002002void print_banner(void)
2003{
2004 msg_ginfo("flashrom is free software, get the source code at "
Stefan Tauner4c723152016-01-14 22:47:55 +00002005 "https://flashrom.org\n");
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +00002006 msg_ginfo("\n");
2007}
2008
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00002009int selfcheck(void)
2010{
Stefan Tauner96658be2014-05-26 22:05:31 +00002011 unsigned int i;
Stefan Taunera6d96482012-12-26 19:51:23 +00002012 int ret = 0;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00002013
2014 /* Safety check. Instead of aborting after the first error, check
2015 * if more errors exist.
2016 */
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00002017 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
Sean Nelson316a29f2010-05-07 20:09:04 +00002018 msg_gerr("Programmer table miscompilation!\n");
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00002019 ret = 1;
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00002020 }
Stefan Taunera6d96482012-12-26 19:51:23 +00002021 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2022 const struct programmer_entry p = programmer_table[i];
2023 if (p.name == NULL) {
2024 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2025 ret = 1;
2026 /* This might hide other problems with this programmer, but allows for better error
2027 * messages below without jumping through hoops. */
2028 continue;
2029 }
Stefan Tauneraf358d62012-12-27 18:40:26 +00002030 switch (p.type) {
2031 case USB:
2032 case PCI:
2033 case OTHER:
2034 if (p.devs.note == NULL) {
2035 if (strcmp("internal", p.name) == 0)
2036 break; /* This one has its device list stored separately. */
2037 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2038 p.name);
2039 ret = 1;
2040 }
2041 break;
2042 default:
2043 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2044 ret = 1;
2045 break;
2046 }
Stefan Taunera6d96482012-12-26 19:51:23 +00002047 if (p.init == NULL) {
2048 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2049 ret = 1;
2050 }
2051 if (p.delay == NULL) {
2052 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2053 ret = 1;
2054 }
2055 if (p.map_flash_region == NULL) {
2056 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2057 ret = 1;
2058 }
2059 if (p.unmap_flash_region == NULL) {
2060 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2061 ret = 1;
2062 }
2063 }
Stefan Tauner96658be2014-05-26 22:05:31 +00002064
2065 /* It would be favorable if we could check for the correct layout (especially termination) of various
2066 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2067 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2068 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2069 * For 'flashchips' we export the size explicitly to work around this and to be able to implement the
2070 * checks below. */
Stefan Tauner6697f712014-08-06 15:09:15 +00002071 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
Stefan Tauner7bcacb12011-05-26 01:35:19 +00002072 msg_gerr("Flashchips table miscompilation!\n");
2073 ret = 1;
Stefan Tauner96658be2014-05-26 22:05:31 +00002074 } else {
2075 for (i = 0; i < flashchips_size - 1; i++) {
2076 const struct flashchip *chip = &flashchips[i];
2077 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2078 ret = 1;
2079 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2080 "Please report a bug at flashrom@flashrom.org\n", i,
2081 chip->name == NULL ? "unnamed" : chip->name);
2082 }
2083 if (selfcheck_eraseblocks(chip)) {
2084 ret = 1;
2085 }
2086 }
Stefan Tauner7bcacb12011-05-26 01:35:19 +00002087 }
Stefan Tauner7bcacb12011-05-26 01:35:19 +00002088
Stefan Tauner600576b2014-06-12 22:57:36 +00002089#if CONFIG_INTERNAL == 1
2090 ret |= selfcheck_board_enables();
2091#endif
2092
Stefan Tauner96658be2014-05-26 22:05:31 +00002093 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00002094 return ret;
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00002095}
2096
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002097/* FIXME: This function signature needs to be improved once doit() has a better
2098 * function signature.
2099 */
Jacob Garberbeeb8bc2019-06-21 15:24:17 -06002100static int chip_safety_check(const struct flashctx *flash, int force,
2101 int read_it, int write_it, int erase_it, int verify_it)
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002102{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00002103 const struct flashchip *chip = flash->chip;
2104
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002105 if (!programmer_may_write && (write_it || erase_it)) {
2106 msg_perr("Write/erase is not working yet on your programmer in "
2107 "its current configuration.\n");
2108 /* --force is the wrong approach, but it's the best we can do
2109 * until the generic programmer parameter parser is merged.
2110 */
2111 if (!force)
2112 return 1;
2113 msg_cerr("Continuing anyway.\n");
2114 }
2115
2116 if (read_it || erase_it || write_it || verify_it) {
2117 /* Everything needs read. */
Stefan Tauner6455dff2014-05-26 00:36:24 +00002118 if (chip->tested.read == BAD) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002119 msg_cerr("Read is not working on this chip. ");
2120 if (!force)
2121 return 1;
2122 msg_cerr("Continuing anyway.\n");
2123 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00002124 if (!chip->read) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002125 msg_cerr("flashrom has no read function for this "
2126 "flash chip.\n");
2127 return 1;
2128 }
2129 }
2130 if (erase_it || write_it) {
2131 /* Write needs erase. */
Stefan Tauner6455dff2014-05-26 00:36:24 +00002132 if (chip->tested.erase == NA) {
2133 msg_cerr("Erase is not possible on this chip.\n");
2134 return 1;
2135 }
2136 if (chip->tested.erase == BAD) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002137 msg_cerr("Erase is not working on this chip. ");
2138 if (!force)
2139 return 1;
2140 msg_cerr("Continuing anyway.\n");
2141 }
Sylvain "ythier" Hitier9db45512011-07-04 07:27:17 +00002142 if(count_usable_erasers(flash) == 0) {
Stefan Tauner5368dca2011-07-01 00:19:12 +00002143 msg_cerr("flashrom has no erase function for this "
2144 "flash chip.\n");
2145 return 1;
2146 }
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002147 }
2148 if (write_it) {
Stefan Tauner6455dff2014-05-26 00:36:24 +00002149 if (chip->tested.write == NA) {
2150 msg_cerr("Write is not possible on this chip.\n");
2151 return 1;
2152 }
2153 if (chip->tested.write == BAD) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002154 msg_cerr("Write is not working on this chip. ");
2155 if (!force)
2156 return 1;
2157 msg_cerr("Continuing anyway.\n");
2158 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00002159 if (!chip->write) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002160 msg_cerr("flashrom has no write function for this "
2161 "flash chip.\n");
2162 return 1;
2163 }
2164 }
2165 return 0;
2166}
2167
Nico Huber305f4172013-06-14 11:55:26 +02002168int prepare_flash_access(struct flashctx *const flash,
2169 const bool read_it, const bool write_it,
2170 const bool erase_it, const bool verify_it)
Nico Huber454f6132012-12-10 13:34:10 +00002171{
2172 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
2173 msg_cerr("Aborting.\n");
2174 return 1;
2175 }
2176
2177 if (flash->layout == get_global_layout() && normalize_romentries(flash)) {
2178 msg_cerr("Requested regions can not be handled. Aborting.\n");
2179 return 1;
2180 }
2181
2182 if (map_flash(flash) != 0)
2183 return 1;
2184
2185 /* Given the existence of read locks, we want to unlock for read,
2186 erase and write. */
2187 if (flash->chip->unlock)
2188 flash->chip->unlock(flash);
2189
Nico Huberf43c6542017-10-14 17:47:28 +02002190 flash->address_high_byte = -1;
2191 flash->in_4ba_mode = false;
2192
Nico Huberdc5af542018-12-22 16:54:59 +01002193 /* Be careful about 4BA chips and broken masters */
2194 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2195 /* If we can't use native instructions, bail out */
2196 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2197 || !spi_master_4ba(flash)) {
2198 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2199 return 1;
2200 }
2201 }
2202
Ed Swierkcc20a9b2017-07-03 13:17:18 -07002203 /* Enable/disable 4-byte addressing mode if flash chip supports it */
Nico Huber86bddb52018-03-13 18:14:52 +01002204 if (flash->chip->feature_bits & (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_ENTER_EAR7)) {
Nico Huberfe34d2a2017-11-10 21:10:20 +01002205 int ret;
2206 if (spi_master_4ba(flash))
2207 ret = spi_enter_4ba(flash);
2208 else
2209 ret = spi_exit_4ba(flash);
2210 if (ret) {
2211 msg_cerr("Failed to set correct 4BA mode! Aborting.\n");
Ed Swierkcc20a9b2017-07-03 13:17:18 -07002212 return 1;
Boris Baykov7fe85692016-06-11 18:29:03 +02002213 }
Boris Baykov99127182016-06-11 18:29:00 +02002214 }
2215
Nico Huber454f6132012-12-10 13:34:10 +00002216 return 0;
2217}
2218
Nico Huber305f4172013-06-14 11:55:26 +02002219void finalize_flash_access(struct flashctx *const flash)
Nico Huber454f6132012-12-10 13:34:10 +00002220{
2221 unmap_flash(flash);
2222}
2223
2224/**
2225 * @addtogroup flashrom-flash
2226 * @{
2227 */
2228
2229/**
2230 * @brief Erase the specified ROM chip.
2231 *
2232 * If a layout is set in the given flash context, only included regions
2233 * will be erased.
2234 *
2235 * @param flashctx The context of the flash chip to erase.
2236 * @return 0 on success.
2237 */
2238int flashrom_flash_erase(struct flashctx *const flashctx)
2239{
2240 if (prepare_flash_access(flashctx, false, false, true, false))
2241 return 1;
2242
2243 const int ret = erase_by_layout(flashctx);
2244
2245 finalize_flash_access(flashctx);
2246
2247 return ret;
2248}
2249
2250/** @} */ /* end flashrom-flash */
2251
2252/**
2253 * @defgroup flashrom-ops Operations
2254 * @{
2255 */
2256
2257/**
2258 * @brief Read the current image from the specified ROM chip.
2259 *
2260 * If a layout is set in the specified flash context, only included regions
2261 * will be read.
2262 *
2263 * @param flashctx The context of the flash chip.
2264 * @param buffer Target buffer to write image to.
2265 * @param buffer_len Size of target buffer in bytes.
2266 * @return 0 on success,
2267 * 2 if buffer_len is too short for the flash chip's contents,
2268 * or 1 on any other failure.
2269 */
2270int flashrom_image_read(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len)
2271{
2272 const size_t flash_size = flashctx->chip->total_size * 1024;
2273
2274 if (flash_size > buffer_len)
2275 return 2;
2276
2277 if (prepare_flash_access(flashctx, true, false, false, false))
2278 return 1;
2279
2280 msg_cinfo("Reading flash... ");
2281
2282 int ret = 1;
2283 if (read_by_layout(flashctx, buffer)) {
2284 msg_cerr("Read operation failed!\n");
2285 msg_cinfo("FAILED.\n");
2286 goto _finalize_ret;
2287 }
2288 msg_cinfo("done.\n");
2289 ret = 0;
2290
2291_finalize_ret:
2292 finalize_flash_access(flashctx);
2293 return ret;
2294}
2295
2296static void combine_image_by_layout(const struct flashctx *const flashctx,
2297 uint8_t *const newcontents, const uint8_t *const oldcontents)
2298{
2299 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber3d7b1e32018-12-22 00:53:14 +01002300 const struct romentry *included;
2301 chipoff_t start = 0;
Nico Huber454f6132012-12-10 13:34:10 +00002302
Nico Huber3d7b1e32018-12-22 00:53:14 +01002303 while ((included = layout_next_included_region(layout, start))) {
2304 if (included->start > start) {
2305 /* copy everything up to the start of this included region */
2306 memcpy(newcontents + start, oldcontents + start, included->start - start);
2307 }
2308 /* skip this included region */
2309 start = included->end + 1;
2310 if (start == 0)
2311 return;
Nico Huber454f6132012-12-10 13:34:10 +00002312 }
Nico Huber3d7b1e32018-12-22 00:53:14 +01002313
2314 /* copy the rest of the chip */
2315 const chipsize_t copy_len = flashctx->chip->total_size * 1024 - start;
2316 memcpy(newcontents + start, oldcontents + start, copy_len);
Nico Huber454f6132012-12-10 13:34:10 +00002317}
2318
2319/**
2320 * @brief Write the specified image to the ROM chip.
2321 *
2322 * If a layout is set in the specified flash context, only erase blocks
2323 * containing included regions will be touched.
2324 *
2325 * @param flashctx The context of the flash chip.
Nico Huber1b172f22017-06-19 12:35:24 +02002326 * @param buffer Source buffer to read image from (may be altered for full verification).
Nico Huber454f6132012-12-10 13:34:10 +00002327 * @param buffer_len Size of source buffer in bytes.
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002328 * @param refbuffer If given, assume flash chip contains same data as `refbuffer`.
Nico Huber454f6132012-12-10 13:34:10 +00002329 * @return 0 on success,
2330 * 4 if buffer_len doesn't match the size of the flash chip,
2331 * 3 if write was tried but nothing has changed,
2332 * 2 if write failed and flash contents changed,
2333 * or 1 on any other failure.
2334 */
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002335int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len,
2336 const void *const refbuffer)
Nico Huber454f6132012-12-10 13:34:10 +00002337{
2338 const size_t flash_size = flashctx->chip->total_size * 1024;
2339 const bool verify_all = flashctx->flags.verify_whole_chip;
2340 const bool verify = flashctx->flags.verify_after_write;
2341
2342 if (buffer_len != flash_size)
2343 return 4;
2344
2345 int ret = 1;
2346
2347 uint8_t *const newcontents = buffer;
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002348 const uint8_t *const refcontents = refbuffer;
Nico Huber454f6132012-12-10 13:34:10 +00002349 uint8_t *const curcontents = malloc(flash_size);
2350 uint8_t *oldcontents = NULL;
2351 if (verify_all)
2352 oldcontents = malloc(flash_size);
2353 if (!curcontents || (verify_all && !oldcontents)) {
2354 msg_gerr("Out of memory!\n");
2355 goto _free_ret;
2356 }
2357
2358#if CONFIG_INTERNAL == 1
2359 if (programmer == PROGRAMMER_INTERNAL && cb_check_image(newcontents, flash_size) < 0) {
2360 if (flashctx->flags.force_boardmismatch) {
2361 msg_pinfo("Proceeding anyway because user forced us to.\n");
2362 } else {
2363 msg_perr("Aborting. You can override this with "
2364 "-p internal:boardmismatch=force.\n");
2365 goto _free_ret;
2366 }
2367 }
2368#endif
2369
2370 if (prepare_flash_access(flashctx, false, true, false, verify))
2371 goto _free_ret;
2372
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002373 /* If given, assume flash chip contains same data as `refcontents`. */
2374 if (refcontents) {
2375 msg_cinfo("Assuming old flash chip contents as ref-file...\n");
2376 memcpy(curcontents, refcontents, flash_size);
2377 if (oldcontents)
2378 memcpy(oldcontents, refcontents, flash_size);
Nico Huber454f6132012-12-10 13:34:10 +00002379 } else {
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002380 /*
2381 * Read the whole chip to be able to check whether regions need to be
2382 * erased and to give better diagnostics in case write fails.
2383 * The alternative is to read only the regions which are to be
2384 * preserved, but in that case we might perform unneeded erase which
2385 * takes time as well.
2386 */
2387 msg_cinfo("Reading old flash chip contents... ");
2388 if (verify_all) {
2389 if (flashctx->chip->read(flashctx, oldcontents, 0, flash_size)) {
2390 msg_cinfo("FAILED.\n");
2391 goto _finalize_ret;
2392 }
2393 memcpy(curcontents, oldcontents, flash_size);
2394 } else {
2395 if (read_by_layout(flashctx, curcontents)) {
2396 msg_cinfo("FAILED.\n");
2397 goto _finalize_ret;
2398 }
Nico Huber454f6132012-12-10 13:34:10 +00002399 }
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002400 msg_cinfo("done.\n");
Nico Huber454f6132012-12-10 13:34:10 +00002401 }
Nico Huber454f6132012-12-10 13:34:10 +00002402
2403 if (write_by_layout(flashctx, curcontents, newcontents)) {
2404 msg_cerr("Uh oh. Erase/write failed. ");
2405 ret = 2;
2406 if (verify_all) {
2407 msg_cerr("Checking if anything has changed.\n");
2408 msg_cinfo("Reading current flash chip contents... ");
2409 if (!flashctx->chip->read(flashctx, curcontents, 0, flash_size)) {
2410 msg_cinfo("done.\n");
2411 if (!memcmp(oldcontents, curcontents, flash_size)) {
2412 nonfatal_help_message();
2413 goto _finalize_ret;
2414 }
2415 msg_cerr("Apparently at least some data has changed.\n");
2416 } else
2417 msg_cerr("Can't even read anymore!\n");
2418 emergency_help_message();
2419 goto _finalize_ret;
2420 } else {
2421 msg_cerr("\n");
2422 }
2423 emergency_help_message();
2424 goto _finalize_ret;
2425 }
2426
2427 /* Verify only if we actually changed something. */
2428 if (verify && !all_skipped) {
2429 const struct flashrom_layout *const layout_bak = flashctx->layout;
2430
2431 msg_cinfo("Verifying flash... ");
2432
2433 /* Work around chips which need some time to calm down. */
2434 programmer_delay(1000*1000);
2435
2436 if (verify_all) {
2437 combine_image_by_layout(flashctx, newcontents, oldcontents);
2438 flashctx->layout = NULL;
2439 }
2440 ret = verify_by_layout(flashctx, curcontents, newcontents);
2441 flashctx->layout = layout_bak;
2442 /* If we tried to write, and verification now fails, we
2443 might have an emergency situation. */
2444 if (ret)
2445 emergency_help_message();
2446 else
2447 msg_cinfo("VERIFIED.\n");
2448 } else {
2449 /* We didn't change anything. */
2450 ret = 0;
2451 }
2452
2453_finalize_ret:
2454 finalize_flash_access(flashctx);
2455_free_ret:
2456 free(oldcontents);
2457 free(curcontents);
2458 return ret;
2459}
2460
2461/**
2462 * @brief Verify the ROM chip's contents with the specified image.
2463 *
2464 * If a layout is set in the specified flash context, only included regions
2465 * will be verified.
2466 *
2467 * @param flashctx The context of the flash chip.
2468 * @param buffer Source buffer to verify with.
2469 * @param buffer_len Size of source buffer in bytes.
2470 * @return 0 on success,
2471 * 3 if the chip's contents don't match,
2472 * 2 if buffer_len doesn't match the size of the flash chip,
2473 * or 1 on any other failure.
2474 */
2475int flashrom_image_verify(struct flashctx *const flashctx, const void *const buffer, const size_t buffer_len)
2476{
2477 const size_t flash_size = flashctx->chip->total_size * 1024;
2478
2479 if (buffer_len != flash_size)
2480 return 2;
2481
2482 const uint8_t *const newcontents = buffer;
2483 uint8_t *const curcontents = malloc(flash_size);
2484 if (!curcontents) {
2485 msg_gerr("Out of memory!\n");
2486 return 1;
2487 }
2488
2489 int ret = 1;
2490
2491 if (prepare_flash_access(flashctx, false, false, false, true))
2492 goto _free_ret;
2493
2494 msg_cinfo("Verifying flash... ");
2495 ret = verify_by_layout(flashctx, curcontents, newcontents);
2496 if (!ret)
2497 msg_cinfo("VERIFIED.\n");
2498
2499 finalize_flash_access(flashctx);
2500_free_ret:
2501 free(curcontents);
2502 return ret;
2503}
2504
2505/** @} */ /* end flashrom-ops */
Nico Huber899e4ec2016-04-29 18:39:01 +02002506
2507int do_read(struct flashctx *const flash, const char *const filename)
2508{
2509 if (prepare_flash_access(flash, true, false, false, false))
2510 return 1;
2511
2512 const int ret = read_flash_to_file(flash, filename);
2513
2514 finalize_flash_access(flash);
2515
2516 return ret;
2517}
2518
2519int do_erase(struct flashctx *const flash)
2520{
2521 const int ret = flashrom_flash_erase(flash);
2522
2523 /*
2524 * FIXME: Do we really want the scary warning if erase failed?
2525 * After all, after erase the chip is either blank or partially
2526 * blank or it has the old contents. A blank chip won't boot,
2527 * so if the user wanted erase and reboots afterwards, the user
2528 * knows very well that booting won't work.
2529 */
2530 if (ret)
2531 emergency_help_message();
2532
2533 return ret;
2534}
2535
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002536int do_write(struct flashctx *const flash, const char *const filename, const char *const referencefile)
Nico Huber899e4ec2016-04-29 18:39:01 +02002537{
2538 const size_t flash_size = flash->chip->total_size * 1024;
2539 int ret = 1;
2540
2541 uint8_t *const newcontents = malloc(flash_size);
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002542 uint8_t *const refcontents = referencefile ? malloc(flash_size) : NULL;
2543
2544 if (!newcontents || (referencefile && !refcontents)) {
Nico Huber899e4ec2016-04-29 18:39:01 +02002545 msg_gerr("Out of memory!\n");
2546 goto _free_ret;
2547 }
2548
2549 if (read_buf_from_file(newcontents, flash_size, filename))
2550 goto _free_ret;
2551
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002552 if (referencefile) {
2553 if (read_buf_from_file(refcontents, flash_size, referencefile))
2554 goto _free_ret;
2555 }
2556
2557 ret = flashrom_image_write(flash, newcontents, flash_size, refcontents);
Nico Huber899e4ec2016-04-29 18:39:01 +02002558
2559_free_ret:
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002560 free(refcontents);
Nico Huber899e4ec2016-04-29 18:39:01 +02002561 free(newcontents);
2562 return ret;
2563}
2564
2565int do_verify(struct flashctx *const flash, const char *const filename)
2566{
2567 const size_t flash_size = flash->chip->total_size * 1024;
2568 int ret = 1;
2569
2570 uint8_t *const newcontents = malloc(flash_size);
2571 if (!newcontents) {
2572 msg_gerr("Out of memory!\n");
2573 goto _free_ret;
2574 }
2575
2576 if (read_buf_from_file(newcontents, flash_size, filename))
2577 goto _free_ret;
2578
2579 ret = flashrom_image_verify(flash, newcontents, flash_size);
2580
2581_free_ret:
2582 free(newcontents);
2583 return ret;
2584}