blob: cb1dca6d92180ee918cb455b32d402f682c9054e [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
Carl-Daniel Hailfinger1c6d2ff2012-08-27 00:44:42 +0000452 {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000453};
Luc Verhaegen8e3a6002007-04-04 22:45:58 +0000454
Carl-Daniel Hailfinger2bee8cf2010-11-10 15:25:18 +0000455#define SHUTDOWN_MAXFN 32
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000456static int shutdown_fn_count = 0;
Nico Huber454f6132012-12-10 13:34:10 +0000457/** @private */
Richard Hughes93e16252018-12-19 11:54:47 +0000458static struct shutdown_func_data {
David Hendricks8bb20212011-06-14 01:35:36 +0000459 int (*func) (void *data);
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000460 void *data;
Richard Hughes93e16252018-12-19 11:54:47 +0000461} shutdown_fn[SHUTDOWN_MAXFN];
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000462/* Initialize to 0 to make sure nobody registers a shutdown function before
463 * programmer init.
464 */
465static int may_register_shutdown = 0;
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000466
Stefan Taunerc4f44df2013-08-12 22:58:43 +0000467/* Did we change something or was every erase/write skipped (if any)? */
468static bool all_skipped = true;
469
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000470static int check_block_eraser(const struct flashctx *flash, int k, int log);
Stefan Tauner5368dca2011-07-01 00:19:12 +0000471
Stefan Tauner2a1ed772014-08-31 00:09:21 +0000472int shutdown_free(void *data)
473{
474 free(data);
475 return 0;
476}
477
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000478/* Register a function to be executed on programmer shutdown.
479 * The advantage over atexit() is that you can supply a void pointer which will
480 * be used as parameter to the registered function upon programmer shutdown.
481 * This pointer can point to arbitrary data used by said function, e.g. undo
482 * information for GPIO settings etc. If unneeded, set data=NULL.
483 * Please note that the first (void *data) belongs to the function signature of
484 * the function passed as first parameter.
485 */
David Hendricks8bb20212011-06-14 01:35:36 +0000486int register_shutdown(int (*function) (void *data), void *data)
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000487{
488 if (shutdown_fn_count >= SHUTDOWN_MAXFN) {
Carl-Daniel Hailfinger9f5f2152010-06-04 23:20:21 +0000489 msg_perr("Tried to register more than %i shutdown functions.\n",
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000490 SHUTDOWN_MAXFN);
491 return 1;
492 }
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000493 if (!may_register_shutdown) {
494 msg_perr("Tried to register a shutdown function before "
495 "programmer init.\n");
496 return 1;
497 }
Carl-Daniel Hailfingercc389fc2010-02-14 01:20:28 +0000498 shutdown_fn[shutdown_fn_count].func = function;
499 shutdown_fn[shutdown_fn_count].data = data;
500 shutdown_fn_count++;
501
502 return 0;
503}
504
Nico Huberbcb2e5a2012-12-30 01:23:17 +0000505int programmer_init(enum programmer prog, const char *param)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000506{
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000507 int ret;
Carl-Daniel Hailfinger2e681602011-09-08 00:00:29 +0000508
509 if (prog >= PROGRAMMER_INVALID) {
510 msg_perr("Invalid programmer specified!\n");
511 return -1;
512 }
513 programmer = prog;
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000514 /* Initialize all programmer specific data. */
515 /* Default to unlimited decode sizes. */
516 max_rom_decode = (const struct decode_sizes) {
517 .parallel = 0xffffffff,
518 .lpc = 0xffffffff,
519 .fwh = 0xffffffff,
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000520 .spi = 0xffffffff,
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000521 };
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000522 /* Default to top aligned flash at 4 GB. */
523 flashbase = 0;
524 /* Registering shutdown functions is now allowed. */
525 may_register_shutdown = 1;
Carl-Daniel Hailfingerd1be52d2010-07-03 12:14:25 +0000526 /* Default to allowing writes. Broken programmers set this to 0. */
527 programmer_may_write = 1;
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000528
529 programmer_param = param;
Carl-Daniel Hailfinger20a36ba2013-08-13 07:09:57 +0000530 msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000531 ret = programmer_table[programmer].init();
532 if (programmer_param && strlen(programmer_param)) {
Carl-Daniel Hailfinger20a36ba2013-08-13 07:09:57 +0000533 if (ret != 0) {
534 /* It is quite possible that any unhandled programmer parameter would have been valid,
535 * but an error in actual programmer init happened before the parameter was evaluated.
536 */
537 msg_pwarn("Unhandled programmer parameters (possibly due to another failure): %s\n",
538 programmer_param);
539 } else {
540 /* Actual programmer init was successful, but the user specified an invalid or unusable
541 * (for the current programmer configuration) parameter.
542 */
543 msg_perr("Unhandled programmer parameters: %s\n", programmer_param);
544 msg_perr("Aborting.\n");
545 ret = ERROR_FATAL;
546 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000547 }
548 return ret;
Uwe Hermann09e04f72009-05-16 22:36:00 +0000549}
550
Stefan Tauner20da4aa2014-05-07 22:07:23 +0000551/** Calls registered shutdown functions and resets internal programmer-related variables.
552 * Calling it is safe even without previous initialization, but further interactions with programmer support
553 * require a call to programmer_init() (afterwards).
554 *
555 * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
Uwe Hermann09e04f72009-05-16 22:36:00 +0000556int programmer_shutdown(void)
557{
David Hendricks8bb20212011-06-14 01:35:36 +0000558 int ret = 0;
559
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000560 /* Registering shutdown functions is no longer allowed. */
561 may_register_shutdown = 0;
562 while (shutdown_fn_count > 0) {
563 int i = --shutdown_fn_count;
David Hendricks8bb20212011-06-14 01:35:36 +0000564 ret |= shutdown_fn[i].func(shutdown_fn[i].data);
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000565 }
Stefan Taunere34e3e82013-01-01 00:06:51 +0000566
Stefan Taunerb8911d62012-12-26 07:55:00 +0000567 programmer_param = NULL;
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000568 registered_master_count = 0;
Stefan Taunere34e3e82013-01-01 00:06:51 +0000569
David Hendricks8bb20212011-06-14 01:35:36 +0000570 return ret;
Uwe Hermann09e04f72009-05-16 22:36:00 +0000571}
572
Stefan Tauner305e0b92013-07-17 23:46:44 +0000573void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000574{
Stefan Tauner26e7a152013-09-13 17:21:05 +0000575 void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
576 msg_gspew("%s: mapping %s from 0x%0*" PRIxPTR " to 0x%0*" PRIxPTR "\n",
577 __func__, descr, PRIxPTR_WIDTH, phys_addr, PRIxPTR_WIDTH, (uintptr_t) ret);
578 return ret;
Uwe Hermann09e04f72009-05-16 22:36:00 +0000579}
580
581void programmer_unmap_flash_region(void *virt_addr, size_t len)
582{
583 programmer_table[programmer].unmap_flash_region(virt_addr, len);
Stefan Tauner4e32ec12014-08-30 23:39:51 +0000584 msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000585}
586
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000587void chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000588{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000589 flash->mst->par.chip_writeb(flash, val, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000590}
591
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000592void chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000593{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000594 flash->mst->par.chip_writew(flash, val, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000595}
596
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000597void chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000598{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000599 flash->mst->par.chip_writel(flash, val, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000600}
601
Mark Marshallf20b7be2014-05-09 21:16:21 +0000602void chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000603{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000604 flash->mst->par.chip_writen(flash, buf, addr, len);
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000605}
606
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000607uint8_t chip_readb(const struct flashctx *flash, const chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000608{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000609 return flash->mst->par.chip_readb(flash, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000610}
611
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000612uint16_t chip_readw(const struct flashctx *flash, const chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000613{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000614 return flash->mst->par.chip_readw(flash, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000615}
616
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000617uint32_t chip_readl(const struct flashctx *flash, const chipaddr addr)
Uwe Hermann09e04f72009-05-16 22:36:00 +0000618{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000619 return flash->mst->par.chip_readl(flash, addr);
Uwe Hermann09e04f72009-05-16 22:36:00 +0000620}
621
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000622void chip_readn(const struct flashctx *flash, uint8_t *buf, chipaddr addr,
623 size_t len)
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000624{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000625 flash->mst->par.chip_readn(flash, buf, addr, len);
Carl-Daniel Hailfinger0bd2a2b2009-06-05 18:32:07 +0000626}
627
Stefan Taunerf80419c2014-05-02 15:41:42 +0000628void programmer_delay(unsigned int usecs)
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000629{
Urja Rannikko8d7ec2a2013-10-21 21:49:08 +0000630 if (usecs > 0)
631 programmer_table[programmer].delay(usecs);
Carl-Daniel Hailfingerca8bfc62009-06-05 17:48:08 +0000632}
633
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000634int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
635 int unsigned len)
Carl-Daniel Hailfinger03b4e712009-05-08 12:49:03 +0000636{
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000637 chip_readn(flash, buf, flash->virtual_memory + start, len);
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000638
Carl-Daniel Hailfinger03b4e712009-05-08 12:49:03 +0000639 return 0;
640}
641
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000642/* This is a somewhat hacked function similar in some ways to strtok().
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000643 * It will look for needle with a subsequent '=' in haystack, return a copy of
644 * needle and remove everything from the first occurrence of needle to the next
645 * delimiter from haystack.
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000646 */
Nico Huberbcb2e5a2012-12-30 01:23:17 +0000647char *extract_param(const char *const *haystack, const char *needle, const char *delim)
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000648{
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000649 char *param_pos, *opt_pos, *rest;
650 char *opt = NULL;
651 int optlen;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000652 int needlelen;
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000653
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000654 needlelen = strlen(needle);
655 if (!needlelen) {
656 msg_gerr("%s: empty needle! Please report a bug at "
657 "flashrom@flashrom.org\n", __func__);
658 return NULL;
659 }
660 /* No programmer parameters given. */
661 if (*haystack == NULL)
662 return NULL;
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000663 param_pos = strstr(*haystack, needle);
664 do {
665 if (!param_pos)
666 return NULL;
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000667 /* Needle followed by '='? */
668 if (param_pos[needlelen] == '=') {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000669 /* Beginning of the string? */
670 if (param_pos == *haystack)
671 break;
672 /* After a delimiter? */
673 if (strchr(delim, *(param_pos - 1)))
674 break;
675 }
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000676 /* Continue searching. */
677 param_pos++;
678 param_pos = strstr(param_pos, needle);
679 } while (1);
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000680
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000681 if (param_pos) {
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000682 /* Get the string after needle and '='. */
683 opt_pos = param_pos + needlelen + 1;
684 optlen = strcspn(opt_pos, delim);
685 /* Return an empty string if the parameter was empty. */
686 opt = malloc(optlen + 1);
687 if (!opt) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000688 msg_gerr("Out of memory!\n");
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000689 exit(1);
690 }
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000691 strncpy(opt, opt_pos, optlen);
692 opt[optlen] = '\0';
693 rest = opt_pos + optlen;
694 /* Skip all delimiters after the current parameter. */
695 rest += strspn(rest, delim);
696 memmove(param_pos, rest, strlen(rest) + 1);
697 /* We could shrink haystack, but the effort is not worth it. */
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000698 }
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000699
Carl-Daniel Hailfinger744132a2010-07-06 09:55:48 +0000700 return opt;
Carl-Daniel Hailfingerd5b28fa2009-11-24 18:27:10 +0000701}
702
Stefan Tauner66652442011-06-26 17:38:17 +0000703char *extract_programmer_param(const char *param_name)
Carl-Daniel Hailfinger2b6dcb32010-07-08 10:13:37 +0000704{
705 return extract_param(&programmer_param, param_name, ",");
706}
707
Sylvain "ythier" Hitier9db45512011-07-04 07:27:17 +0000708/* Returns the number of well-defined erasers for a chip. */
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000709static unsigned int count_usable_erasers(const struct flashctx *flash)
Stefan Tauner5368dca2011-07-01 00:19:12 +0000710{
711 unsigned int usable_erasefunctions = 0;
712 int k;
713 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
714 if (!check_block_eraser(flash, k, 0))
715 usable_erasefunctions++;
716 }
717 return usable_erasefunctions;
718}
719
Mark Marshallf20b7be2014-05-09 21:16:21 +0000720static int compare_range(const uint8_t *wantbuf, const uint8_t *havebuf, unsigned int start, unsigned int len)
Stefan Tauner78ffbea2012-10-27 15:36:56 +0000721{
722 int ret = 0, failcount = 0;
723 unsigned int i;
724 for (i = 0; i < len; i++) {
725 if (wantbuf[i] != havebuf[i]) {
726 /* Only print the first failure. */
727 if (!failcount++)
728 msg_cerr("FAILED at 0x%08x! Expected=0x%02x, Found=0x%02x,",
729 start + i, wantbuf[i], havebuf[i]);
730 }
731 }
732 if (failcount) {
733 msg_cerr(" failed byte count from 0x%08x-0x%08x: 0x%x\n",
734 start, start + len - 1, failcount);
735 ret = -1;
736 }
737 return ret;
738}
739
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000740/* start is an offset to the base address of the flash chip */
Jacob Garberbeeb8bc2019-06-21 15:24:17 -0600741static int check_erased_range(struct flashctx *flash, unsigned int start, unsigned int len)
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000742{
743 int ret;
744 uint8_t *cmpbuf = malloc(len);
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300745 const uint8_t erased_value = ERASED_VALUE(flash);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000746
747 if (!cmpbuf) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000748 msg_gerr("Could not allocate memory!\n");
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000749 exit(1);
750 }
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300751 memset(cmpbuf, erased_value, len);
Stefan Tauner78ffbea2012-10-27 15:36:56 +0000752 ret = verify_range(flash, cmpbuf, start, len);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000753 free(cmpbuf);
754 return ret;
755}
756
Uwe Hermann48ec1b12010-08-08 17:01:18 +0000757/*
Carl-Daniel Hailfingerd0250a32009-11-25 17:05:52 +0000758 * @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000759 * flash content at location start
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000760 * @start offset to the base address of the flash chip
761 * @len length of the verified area
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000762 * @return 0 for success, -1 for failure
763 */
Mark Marshallf20b7be2014-05-09 21:16:21 +0000764int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int start, unsigned int len)
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000765{
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000766 if (!len)
Stefan Taunerdf64a422014-05-27 00:06:14 +0000767 return -1;
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000768
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000769 if (!flash->chip->read) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000770 msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
Stefan Taunerdf64a422014-05-27 00:06:14 +0000771 return -1;
Carl-Daniel Hailfinger23290662009-06-24 08:20:45 +0000772 }
Stefan Taunerdf64a422014-05-27 00:06:14 +0000773
774 uint8_t *readbuf = malloc(len);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000775 if (!readbuf) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000776 msg_gerr("Could not allocate memory!\n");
Stefan Taunerdf64a422014-05-27 00:06:14 +0000777 return -1;
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000778 }
Stefan Taunerdf64a422014-05-27 00:06:14 +0000779 int ret = 0;
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000780
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000781 if (start + len > flash->chip->total_size * 1024) {
Sean Nelson316a29f2010-05-07 20:09:04 +0000782 msg_gerr("Error: %s called with start 0x%x + len 0x%x >"
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000783 " total_size 0x%x\n", __func__, start, len,
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000784 flash->chip->total_size * 1024);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000785 ret = -1;
786 goto out_free;
787 }
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000788
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +0000789 ret = flash->chip->read(flash, readbuf, start, len);
Carl-Daniel Hailfingerd8369412010-11-16 17:21:58 +0000790 if (ret) {
791 msg_gerr("Verification impossible because read failed "
792 "at 0x%x (len 0x%x)\n", start, len);
Stefan Taunerdf64a422014-05-27 00:06:14 +0000793 ret = -1;
794 goto out_free;
Carl-Daniel Hailfingerd8369412010-11-16 17:21:58 +0000795 }
796
Stefan Tauner78ffbea2012-10-27 15:36:56 +0000797 ret = compare_range(cmpbuf, readbuf, start, len);
Carl-Daniel Hailfinger30f7cb22009-06-15 17:23:36 +0000798out_free:
799 free(readbuf);
800 return ret;
801}
802
Stefan Tauner02437452013-04-01 19:34:53 +0000803/* Helper function for need_erase() that focuses on granularities of gran bytes. */
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300804static int need_erase_gran_bytes(const uint8_t *have, const uint8_t *want, unsigned int len,
805 unsigned int gran, const uint8_t erased_value)
Stefan Tauner02437452013-04-01 19:34:53 +0000806{
807 unsigned int i, j, limit;
808 for (j = 0; j < len / gran; j++) {
809 limit = min (gran, len - j * gran);
810 /* Are 'have' and 'want' identical? */
811 if (!memcmp(have + j * gran, want + j * gran, limit))
812 continue;
813 /* have needs to be in erased state. */
814 for (i = 0; i < limit; i++)
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300815 if (have[j * gran + i] != erased_value)
Stefan Tauner02437452013-04-01 19:34:53 +0000816 return 1;
817 }
818 return 0;
819}
820
Uwe Hermann48ec1b12010-08-08 17:01:18 +0000821/*
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000822 * Check if the buffer @have can be programmed to the content of @want without
823 * erasing. This is only possible if all chunks of size @gran are either kept
824 * as-is or changed from an all-ones state to any other state.
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000825 *
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000826 * Warning: This function assumes that @have and @want point to naturally
827 * aligned regions.
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000828 *
829 * @have buffer with current content
830 * @want buffer with desired content
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000831 * @len length of the checked area
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000832 * @gran write granularity (enum, not count)
833 * @return 0 if no erase is needed, 1 otherwise
834 */
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300835int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len,
836 enum write_granularity gran, const uint8_t erased_value)
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000837{
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +0000838 int result = 0;
Stefan Tauner02437452013-04-01 19:34:53 +0000839 unsigned int i;
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000840
841 switch (gran) {
842 case write_gran_1bit:
843 for (i = 0; i < len; i++)
844 if ((have[i] & want[i]) != want[i]) {
845 result = 1;
846 break;
847 }
848 break;
849 case write_gran_1byte:
850 for (i = 0; i < len; i++)
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300851 if ((have[i] != want[i]) && (have[i] != erased_value)) {
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000852 result = 1;
853 break;
854 }
855 break;
Paul Kocialkowskic8305e12015-10-16 02:16:20 +0000856 case write_gran_128bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300857 result = need_erase_gran_bytes(have, want, len, 128, erased_value);
Paul Kocialkowskic8305e12015-10-16 02:16:20 +0000858 break;
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000859 case write_gran_256bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300860 result = need_erase_gran_bytes(have, want, len, 256, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000861 break;
862 case write_gran_264bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300863 result = need_erase_gran_bytes(have, want, len, 264, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000864 break;
865 case write_gran_512bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300866 result = need_erase_gran_bytes(have, want, len, 512, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000867 break;
868 case write_gran_528bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300869 result = need_erase_gran_bytes(have, want, len, 528, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000870 break;
871 case write_gran_1024bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300872 result = need_erase_gran_bytes(have, want, len, 1024, erased_value);
Stefan Tauner02437452013-04-01 19:34:53 +0000873 break;
874 case write_gran_1056bytes:
Paul Kocialkowski995f7552018-01-15 01:06:09 +0300875 result = need_erase_gran_bytes(have, want, len, 1056, erased_value);
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000876 break;
Carl-Daniel Hailfinger1b0e9fc2014-06-16 22:36:17 +0000877 case write_gran_1byte_implicit_erase:
878 /* Do not erase, handle content changes from anything->0xff by writing 0xff. */
879 result = 0;
880 break;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000881 default:
882 msg_cerr("%s: Unsupported granularity! Please report a bug at "
883 "flashrom@flashrom.org\n", __func__);
Carl-Daniel Hailfingere8e369f2010-03-08 00:42:32 +0000884 }
885 return result;
886}
887
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000888/**
889 * Check if the buffer @have needs to be programmed to get the content of @want.
890 * If yes, return 1 and fill in first_start with the start address of the
891 * write operation and first_len with the length of the first to-be-written
892 * chunk. If not, return 0 and leave first_start and first_len undefined.
893 *
894 * Warning: This function assumes that @have and @want point to naturally
895 * aligned regions.
896 *
897 * @have buffer with current content
898 * @want buffer with desired content
899 * @len length of the checked area
900 * @gran write granularity (enum, not count)
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000901 * @first_start offset of the first byte which needs to be written (passed in
902 * value is increased by the offset of the first needed write
903 * relative to have/want or unchanged if no write is needed)
904 * @return length of the first contiguous area which needs to be written
905 * 0 if no write is needed
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000906 *
907 * FIXME: This function needs a parameter which tells it about coalescing
908 * in relation to the max write length of the programmer and the max write
909 * length of the chip.
910 */
Mark Marshallf20b7be2014-05-09 21:16:21 +0000911static unsigned int get_next_write(const uint8_t *have, const uint8_t *want, unsigned int len,
Stefan Taunerc69c9c82011-11-23 09:13:48 +0000912 unsigned int *first_start,
913 enum write_granularity gran)
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000914{
Stefan Taunerc69c9c82011-11-23 09:13:48 +0000915 int need_write = 0;
916 unsigned int rel_start = 0, first_len = 0;
917 unsigned int i, limit, stride;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000918
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000919 switch (gran) {
920 case write_gran_1bit:
921 case write_gran_1byte:
Carl-Daniel Hailfinger1b0e9fc2014-06-16 22:36:17 +0000922 case write_gran_1byte_implicit_erase:
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000923 stride = 1;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000924 break;
Paul Kocialkowskic8305e12015-10-16 02:16:20 +0000925 case write_gran_128bytes:
926 stride = 128;
927 break;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000928 case write_gran_256bytes:
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000929 stride = 256;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000930 break;
Stefan Tauner02437452013-04-01 19:34:53 +0000931 case write_gran_264bytes:
932 stride = 264;
933 break;
934 case write_gran_512bytes:
935 stride = 512;
936 break;
937 case write_gran_528bytes:
938 stride = 528;
939 break;
940 case write_gran_1024bytes:
941 stride = 1024;
942 break;
943 case write_gran_1056bytes:
944 stride = 1056;
945 break;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000946 default:
947 msg_cerr("%s: Unsupported granularity! Please report a bug at "
948 "flashrom@flashrom.org\n", __func__);
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000949 /* Claim that no write was needed. A write with unknown
950 * granularity is too dangerous to try.
951 */
952 return 0;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000953 }
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000954 for (i = 0; i < len / stride; i++) {
955 limit = min(stride, len - i * stride);
956 /* Are 'have' and 'want' identical? */
957 if (memcmp(have + i * stride, want + i * stride, limit)) {
958 if (!need_write) {
959 /* First location where have and want differ. */
960 need_write = 1;
961 rel_start = i * stride;
962 }
963 } else {
964 if (need_write) {
965 /* First location where have and want
966 * do not differ anymore.
967 */
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000968 break;
969 }
970 }
971 }
Carl-Daniel Hailfinger202bf532010-12-06 13:05:44 +0000972 if (need_write)
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000973 first_len = min(i * stride - rel_start, len);
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000974 *first_start += rel_start;
Carl-Daniel Hailfinger12d6d822010-11-05 14:51:59 +0000975 return first_len;
Carl-Daniel Hailfinger6e2ea322010-11-04 01:04:27 +0000976}
977
Stefan Tauner9e3a6982014-08-15 17:17:59 +0000978/* Returns the number of busses commonly supported by the current programmer and flash chip where the latter
979 * can not be completely accessed due to size/address limits of the programmer. */
980unsigned int count_max_decode_exceedings(const struct flashctx *flash)
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +0000981{
Stefan Tauner9e3a6982014-08-15 17:17:59 +0000982 unsigned int limitexceeded = 0;
983 uint32_t size = flash->chip->total_size * 1024;
984 enum chipbustype buses = flash->mst->buses_supported & flash->chip->bustype;
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000985
986 if ((buses & BUS_PARALLEL) && (max_rom_decode.parallel < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +0000987 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +0000988 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000989 "size %u kB of chipset/board/programmer "
990 "for %s interface, "
991 "probe/read/erase/write may fail. ", size / 1024,
992 max_rom_decode.parallel / 1024, "Parallel");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +0000993 }
Carl-Daniel Hailfinger1a227952011-07-27 07:13:06 +0000994 if ((buses & BUS_LPC) && (max_rom_decode.lpc < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +0000995 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +0000996 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000997 "size %u kB of chipset/board/programmer "
998 "for %s interface, "
999 "probe/read/erase/write may fail. ", size / 1024,
1000 max_rom_decode.lpc / 1024, "LPC");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001001 }
Carl-Daniel Hailfinger1a227952011-07-27 07:13:06 +00001002 if ((buses & BUS_FWH) && (max_rom_decode.fwh < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001003 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +00001004 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001005 "size %u kB of chipset/board/programmer "
1006 "for %s interface, "
1007 "probe/read/erase/write may fail. ", size / 1024,
1008 max_rom_decode.fwh / 1024, "FWH");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001009 }
Carl-Daniel Hailfinger1a227952011-07-27 07:13:06 +00001010 if ((buses & BUS_SPI) && (max_rom_decode.spi < size)) {
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001011 limitexceeded++;
Sean Nelson316a29f2010-05-07 20:09:04 +00001012 msg_pdbg("Chip size %u kB is bigger than supported "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001013 "size %u kB of chipset/board/programmer "
1014 "for %s interface, "
1015 "probe/read/erase/write may fail. ", size / 1024,
1016 max_rom_decode.spi / 1024, "SPI");
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001017 }
Stefan Tauner9e3a6982014-08-15 17:17:59 +00001018 return limitexceeded;
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001019}
1020
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001021void unmap_flash(struct flashctx *flash)
1022{
1023 if (flash->virtual_registers != (chipaddr)ERROR_PTR) {
1024 programmer_unmap_flash_region((void *)flash->virtual_registers, flash->chip->total_size * 1024);
1025 flash->physical_registers = 0;
1026 flash->virtual_registers = (chipaddr)ERROR_PTR;
1027 }
1028
1029 if (flash->virtual_memory != (chipaddr)ERROR_PTR) {
1030 programmer_unmap_flash_region((void *)flash->virtual_memory, flash->chip->total_size * 1024);
1031 flash->physical_memory = 0;
1032 flash->virtual_memory = (chipaddr)ERROR_PTR;
1033 }
1034}
1035
1036int map_flash(struct flashctx *flash)
1037{
1038 /* Init pointers to the fail-safe state to distinguish them later from legit values. */
1039 flash->virtual_memory = (chipaddr)ERROR_PTR;
1040 flash->virtual_registers = (chipaddr)ERROR_PTR;
1041
1042 /* FIXME: This avoids mapping (and unmapping) of flash chip definitions with size 0.
1043 * These are used for various probing-related hacks that would not map successfully anyway and should be
1044 * removed ASAP. */
1045 if (flash->chip->total_size == 0)
1046 return 0;
1047
1048 const chipsize_t size = flash->chip->total_size * 1024;
1049 uintptr_t base = flashbase ? flashbase : (0xffffffff - size + 1);
1050 void *addr = programmer_map_flash_region(flash->chip->name, base, size);
1051 if (addr == ERROR_PTR) {
1052 msg_perr("Could not map flash chip %s at 0x%0*" PRIxPTR ".\n",
1053 flash->chip->name, PRIxPTR_WIDTH, base);
1054 return 1;
1055 }
1056 flash->physical_memory = base;
1057 flash->virtual_memory = (chipaddr)addr;
1058
1059 /* FIXME: Special function registers normally live 4 MByte below flash space, but it might be somewhere
1060 * completely different on some chips and programmers, or not mappable at all.
1061 * Ignore these problems for now and always report success. */
1062 if (flash->chip->feature_bits & FEATURE_REGISTERMAP) {
1063 base = 0xffffffff - size - 0x400000 + 1;
1064 addr = programmer_map_flash_region("flash chip registers", base, size);
1065 if (addr == ERROR_PTR) {
1066 msg_pdbg2("Could not map flash chip registers %s at 0x%0*" PRIxPTR ".\n",
1067 flash->chip->name, PRIxPTR_WIDTH, base);
1068 return 0;
1069 }
1070 flash->physical_registers = base;
1071 flash->virtual_registers = (chipaddr)addr;
1072 }
1073 return 0;
1074}
1075
Nico Huber2d625722016-05-03 10:48:02 +02001076/*
1077 * Return a string corresponding to the bustype parameter.
1078 * Memory is obtained with malloc() and must be freed with free() by the caller.
1079 */
1080char *flashbuses_to_text(enum chipbustype bustype)
1081{
1082 char *ret = calloc(1, 1);
1083 /*
1084 * FIXME: Once all chipsets and flash chips have been updated, NONSPI
1085 * will cease to exist and should be eliminated here as well.
1086 */
1087 if (bustype == BUS_NONSPI) {
1088 ret = strcat_realloc(ret, "Non-SPI, ");
1089 } else {
1090 if (bustype & BUS_PARALLEL)
1091 ret = strcat_realloc(ret, "Parallel, ");
1092 if (bustype & BUS_LPC)
1093 ret = strcat_realloc(ret, "LPC, ");
1094 if (bustype & BUS_FWH)
1095 ret = strcat_realloc(ret, "FWH, ");
1096 if (bustype & BUS_SPI)
1097 ret = strcat_realloc(ret, "SPI, ");
1098 if (bustype & BUS_PROG)
1099 ret = strcat_realloc(ret, "Programmer-specific, ");
1100 if (bustype == BUS_NONE)
1101 ret = strcat_realloc(ret, "None, ");
1102 }
1103 /* Kill last comma. */
1104 ret[strlen(ret) - 2] = '\0';
1105 ret = realloc(ret, strlen(ret) + 1);
1106 return ret;
1107}
1108
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001109int probe_flash(struct registered_master *mst, int startchip, struct flashctx *flash, int force)
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001110{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001111 const struct flashchip *chip;
Carl-Daniel Hailfinger115d3902009-10-31 01:53:09 +00001112 enum chipbustype buses_common;
Carl-Daniel Hailfingerb22918c2009-06-01 02:08:58 +00001113 char *tmp;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001114
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001115 for (chip = flashchips + startchip; chip && chip->name; chip++) {
1116 if (chip_to_probe && strcmp(chip->name, chip_to_probe) != 0)
Ollie Lhocbbf1252004-03-17 22:22:08 +00001117 continue;
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001118 buses_common = mst->buses_supported & chip->bustype;
Carl-Daniel Hailfingerc40cff72011-12-20 00:19:29 +00001119 if (!buses_common)
Carl-Daniel Hailfinger6573b742011-06-17 22:38:53 +00001120 continue;
Mike Banon31b5e3b2018-01-15 01:10:00 +03001121 /* Only probe for SPI25 chips by default. */
1122 if (chip->bustype == BUS_SPI && !chip_to_probe && chip->spi_cmd_set != SPI25)
1123 continue;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001124 msg_gdbg("Probing for %s %s, %d kB: ", chip->vendor, chip->name, chip->total_size);
1125 if (!chip->probe && !force) {
1126 msg_gdbg("failed! flashrom has no probe function for this flash chip.\n");
Carl-Daniel Hailfingerb22918c2009-06-01 02:08:58 +00001127 continue;
1128 }
Stefan Reinauer70385642007-04-06 11:58:03 +00001129
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001130 /* Start filling in the dynamic data. */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001131 flash->chip = calloc(1, sizeof(struct flashchip));
1132 if (!flash->chip) {
1133 msg_gerr("Out of memory!\n");
1134 exit(1);
1135 }
1136 memcpy(flash->chip, chip, sizeof(struct flashchip));
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001137 flash->mst = mst;
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001138
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001139 if (map_flash(flash) != 0)
Martin Schiller57a3b732017-11-23 06:24:57 +01001140 goto notfound;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001141
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001142 /* We handle a forced match like a real match, we just avoid probing. Note that probe_flash()
1143 * is only called with force=1 after normal probing failed.
1144 */
Peter Stuge27c3e2d2008-07-02 17:15:47 +00001145 if (force)
1146 break;
Stefan Reinauerfcb63682006-03-16 16:57:41 +00001147
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001148 if (flash->chip->probe(flash) != 1)
Peter Stuge483b8f02008-09-03 23:10:05 +00001149 goto notfound;
1150
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001151 /* If this is the first chip found, accept it.
1152 * If this is not the first chip found, accept it only if it is
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001153 * a non-generic match. SFDP and CFI are generic matches.
1154 * startchip==0 means this call to probe_flash() is the first
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +00001155 * one for this programmer interface (master) and thus no other chip has
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001156 * been found on this interface.
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001157 */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001158 if (startchip == 0 && flash->chip->model_id == SFDP_DEVICE_ID) {
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001159 msg_cinfo("===\n"
1160 "SFDP has autodetected a flash chip which is "
1161 "not natively supported by flashrom yet.\n");
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001162 if (count_usable_erasers(flash) == 0)
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001163 msg_cinfo("The standard operations read and "
1164 "verify should work, but to support "
1165 "erase, write and all other "
1166 "possible features");
1167 else
1168 msg_cinfo("All standard operations (read, "
1169 "verify, erase and write) should "
1170 "work, but to support all possible "
1171 "features");
1172
Stefan Taunerb4e06bd2012-08-20 00:24:22 +00001173 msg_cinfo(" we need to add them manually.\n"
1174 "You can help us by mailing us the output of the following command to "
1175 "flashrom@flashrom.org:\n"
1176 "'flashrom -VV [plus the -p/--programmer parameter]'\n"
1177 "Thanks for your help!\n"
Stefan Taunerac1b4c82012-02-17 14:51:04 +00001178 "===\n");
1179 }
1180
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001181 /* First flash chip detected on this bus. */
1182 if (startchip == 0)
Peter Stuge27c3e2d2008-07-02 17:15:47 +00001183 break;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001184 /* Not the first flash chip detected on this bus, but not a generic match either. */
1185 if ((flash->chip->model_id != GENERIC_DEVICE_ID) && (flash->chip->model_id != SFDP_DEVICE_ID))
1186 break;
1187 /* 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 +00001188notfound:
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001189 unmap_flash(flash);
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001190 free(flash->chip);
1191 flash->chip = NULL;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001192 }
Uwe Hermannffec5f32007-08-23 16:08:21 +00001193
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001194 if (!flash->chip)
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001195 return -1;
Peter Stuge27c3e2d2008-07-02 17:15:47 +00001196
Nico Huber7af0e792016-04-29 16:40:15 +02001197 /* Fill fallback layout covering the whole chip. */
1198 struct single_layout *const fallback = &flash->fallback_layout;
1199 fallback->base.entries = &fallback->entry;
1200 fallback->base.num_entries = 1;
1201 fallback->entry.start = 0;
1202 fallback->entry.end = flash->chip->total_size * 1024 - 1;
1203 fallback->entry.included = true;
Nico Huber70461a92019-06-15 14:56:19 +02001204 fallback->entry.name = strdup("complete flash");
1205 if (!fallback->entry.name) {
1206 msg_cerr("Failed to probe chip: %s\n", strerror(errno));
1207 return -1;
1208 }
Stefan Reinauer051e2362011-01-19 06:21:54 +00001209
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001210 tmp = flashbuses_to_text(flash->chip->bustype);
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001211 msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
1212 flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
Stefan Tauner00155492011-06-26 20:45:35 +00001213 free(tmp);
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001214#if CONFIG_INTERNAL == 1
1215 if (programmer_table[programmer].map_flash_region == physmap)
1216 msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
1217 PRIxPTR_WIDTH, flash->physical_memory);
1218 else
1219#endif
1220 msg_cinfo("on %s.\n", programmer_table[programmer].name);
Uwe Hermann9899cad2009-06-28 21:47:57 +00001221
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001222 /* Flash registers may more likely not be mapped if the chip was forced.
1223 * Lock info may be stored in registers, so avoid lock info printing. */
Carl-Daniel Hailfinger859f3f02010-12-02 21:59:42 +00001224 if (!force)
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001225 if (flash->chip->printlock)
1226 flash->chip->printlock(flash);
Sean Nelson6e0b9122010-02-19 00:52:10 +00001227
Stefan Tauner4e32ec12014-08-30 23:39:51 +00001228 /* Get out of the way for later runs. */
1229 unmap_flash(flash);
1230
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +00001231 /* Return position of matching chip. */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001232 return chip - flashchips;
Ronald G. Minnichf4cf2ba2002-01-29 18:26:26 +00001233}
1234
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001235int read_buf_from_file(unsigned char *buf, unsigned long size,
1236 const char *filename)
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001237{
Nico Huber7562f7d2013-08-30 21:29:45 +00001238#ifdef __LIBPAYLOAD__
1239 msg_gerr("Error: No file I/O support in libpayload\n");
1240 return 1;
1241#else
Stefan Tauner16687702015-12-25 21:59:45 +00001242 int ret = 0;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001243
Stefan Tauner16687702015-12-25 21:59:45 +00001244 FILE *image;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001245 if ((image = fopen(filename, "rb")) == NULL) {
Stefan Tauner363fd7e2013-04-07 13:08:30 +00001246 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001247 return 1;
1248 }
Stefan Tauner16687702015-12-25 21:59:45 +00001249
1250 struct stat image_stat;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001251 if (fstat(fileno(image), &image_stat) != 0) {
Stefan Tauner363fd7e2013-04-07 13:08:30 +00001252 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
Stefan Tauner16687702015-12-25 21:59:45 +00001253 ret = 1;
1254 goto out;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001255 }
1256 if (image_stat.st_size != size) {
Carl-Daniel Hailfinger11990da2013-07-13 23:21:05 +00001257 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 +00001258 (intmax_t)image_stat.st_size, size);
Stefan Tauner16687702015-12-25 21:59:45 +00001259 ret = 1;
1260 goto out;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001261 }
Stefan Tauner16687702015-12-25 21:59:45 +00001262
1263 unsigned long numbytes = fread(buf, 1, size, image);
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001264 if (numbytes != size) {
1265 msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
1266 "wanted %ld!\n", numbytes, size);
Stefan Tauner16687702015-12-25 21:59:45 +00001267 ret = 1;
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001268 }
Stefan Tauner16687702015-12-25 21:59:45 +00001269out:
1270 (void)fclose(image);
1271 return ret;
Nico Huber7562f7d2013-08-30 21:29:45 +00001272#endif
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00001273}
1274
Mark Marshallf20b7be2014-05-09 21:16:21 +00001275int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename)
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001276{
Nico Huber7562f7d2013-08-30 21:29:45 +00001277#ifdef __LIBPAYLOAD__
1278 msg_gerr("Error: No file I/O support in libpayload\n");
1279 return 1;
1280#else
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001281 FILE *image;
Stefan Tauner16687702015-12-25 21:59:45 +00001282 int ret = 0;
Stephan Guilloux21dd55b2009-06-01 22:07:52 +00001283
1284 if (!filename) {
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001285 msg_gerr("No filename specified.\n");
Stephan Guilloux21dd55b2009-06-01 22:07:52 +00001286 return 1;
1287 }
Patrick Georgi0bf842d2010-01-25 22:55:33 +00001288 if ((image = fopen(filename, "wb")) == NULL) {
Stefan Tauner363fd7e2013-04-07 13:08:30 +00001289 msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
Carl-Daniel Hailfinger03b4e712009-05-08 12:49:03 +00001290 return 1;
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001291 }
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001292
Stefan Tauner16687702015-12-25 21:59:45 +00001293 unsigned long numbytes = fwrite(buf, 1, size, image);
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001294 if (numbytes != size) {
Stefan Tauner16687702015-12-25 21:59:45 +00001295 msg_gerr("Error: file %s could not be written completely.\n", filename);
1296 ret = 1;
1297 goto out;
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001298 }
Stefan Tauner16687702015-12-25 21:59:45 +00001299 if (fflush(image)) {
1300 msg_gerr("Error: flushing file \"%s\" failed: %s\n", filename, strerror(errno));
1301 ret = 1;
1302 }
1303 // Try to fsync() only regular files and if that function is available at all (e.g. not on MinGW).
1304#if defined(_POSIX_FSYNC) && (_POSIX_FSYNC != -1)
1305 struct stat image_stat;
1306 if (fstat(fileno(image), &image_stat) != 0) {
1307 msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
1308 ret = 1;
1309 goto out;
1310 }
1311 if (S_ISREG(image_stat.st_mode)) {
1312 if (fsync(fileno(image))) {
1313 msg_gerr("Error: fsyncing file \"%s\" failed: %s\n", filename, strerror(errno));
1314 ret = 1;
1315 }
1316 }
1317#endif
1318out:
1319 if (fclose(image)) {
1320 msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
1321 ret = 1;
1322 }
1323 return ret;
Nico Huber7562f7d2013-08-30 21:29:45 +00001324#endif
Carl-Daniel Hailfinger7314cc32009-01-28 00:27:54 +00001325}
1326
Nico Huber899e4ec2016-04-29 18:39:01 +02001327static int read_by_layout(struct flashctx *, uint8_t *);
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +00001328int read_flash_to_file(struct flashctx *flash, const char *filename)
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001329{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001330 unsigned long size = flash->chip->total_size * 1024;
Richard Hughes84b453e2018-12-19 15:30:39 +00001331 unsigned char *buf = calloc(size, sizeof(unsigned char));
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001332 int ret = 0;
1333
1334 msg_cinfo("Reading flash... ");
1335 if (!buf) {
1336 msg_gerr("Memory allocation failed!\n");
1337 msg_cinfo("FAILED.\n");
1338 return 1;
1339 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001340 if (!flash->chip->read) {
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001341 msg_cerr("No read function available for this flash chip.\n");
1342 ret = 1;
1343 goto out_free;
1344 }
Nico Huber899e4ec2016-04-29 18:39:01 +02001345 if (read_by_layout(flash, buf)) {
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001346 msg_cerr("Read operation failed!\n");
1347 ret = 1;
1348 goto out_free;
1349 }
1350
Stefan Tauner355cbfd2011-05-28 02:37:14 +00001351 ret = write_buf_to_file(buf, size, filename);
Carl-Daniel Hailfinger1748c572010-07-13 23:56:13 +00001352out_free:
1353 free(buf);
1354 msg_cinfo("%s.\n", ret ? "FAILED" : "done");
1355 return ret;
1356}
1357
Stefan Tauner96658be2014-05-26 22:05:31 +00001358/* Even if an error is found, the function will keep going and check the rest. */
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001359static int selfcheck_eraseblocks(const struct flashchip *chip)
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001360{
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +00001361 int i, j, k;
1362 int ret = 0;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001363
1364 for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
1365 unsigned int done = 0;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001366 struct block_eraser eraser = chip->block_erasers[k];
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001367
1368 for (i = 0; i < NUM_ERASEREGIONS; i++) {
1369 /* Blocks with zero size are bugs in flashchips.c. */
1370 if (eraser.eraseblocks[i].count &&
1371 !eraser.eraseblocks[i].size) {
1372 msg_gerr("ERROR: Flash chip %s erase function "
1373 "%i region %i has size 0. Please report"
1374 " a bug at flashrom@flashrom.org\n",
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001375 chip->name, k, i);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001376 ret = 1;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001377 }
1378 /* Blocks with zero count are bugs in flashchips.c. */
1379 if (!eraser.eraseblocks[i].count &&
1380 eraser.eraseblocks[i].size) {
1381 msg_gerr("ERROR: Flash chip %s erase function "
1382 "%i region %i has count 0. Please report"
1383 " a bug at flashrom@flashrom.org\n",
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001384 chip->name, k, i);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001385 ret = 1;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001386 }
1387 done += eraser.eraseblocks[i].count *
1388 eraser.eraseblocks[i].size;
1389 }
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001390 /* Empty eraseblock definition with erase function. */
1391 if (!done && eraser.block_erase)
Sean Nelson316a29f2010-05-07 20:09:04 +00001392 msg_gspew("Strange: Empty eraseblock definition with "
Uwe Hermann91f4afa2011-07-28 08:13:25 +00001393 "non-empty erase function. Not an error.\n");
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001394 if (!done)
1395 continue;
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001396 if (done != chip->total_size * 1024) {
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001397 msg_gerr("ERROR: Flash chip %s erase function %i "
1398 "region walking resulted in 0x%06x bytes total,"
1399 " expected 0x%06x bytes. Please report a bug at"
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001400 " flashrom@flashrom.org\n", chip->name, k,
1401 done, chip->total_size * 1024);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001402 ret = 1;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001403 }
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001404 if (!eraser.block_erase)
1405 continue;
1406 /* Check if there are identical erase functions for different
1407 * layouts. That would imply "magic" erase functions. The
1408 * easiest way to check this is with function pointers.
1409 */
Uwe Hermann43959702010-03-13 17:28:29 +00001410 for (j = k + 1; j < NUM_ERASEFUNCTIONS; j++) {
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001411 if (eraser.block_erase ==
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001412 chip->block_erasers[j].block_erase) {
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001413 msg_gerr("ERROR: Flash chip %s erase function "
1414 "%i and %i are identical. Please report"
1415 " a bug at flashrom@flashrom.org\n",
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001416 chip->name, k, j);
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001417 ret = 1;
1418 }
Uwe Hermann43959702010-03-13 17:28:29 +00001419 }
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001420 }
Carl-Daniel Hailfinger415afcf2010-01-19 06:42:46 +00001421 return ret;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00001422}
1423
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +00001424static int check_block_eraser(const struct flashctx *flash, int k, int log)
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001425{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001426 struct block_eraser eraser = flash->chip->block_erasers[k];
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001427
1428 if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
1429 if (log)
1430 msg_cdbg("not defined. ");
1431 return 1;
1432 }
1433 if (!eraser.block_erase && eraser.eraseblocks[0].count) {
1434 if (log)
1435 msg_cdbg("eraseblock layout is known, but matching "
Stefan Tauner355cbfd2011-05-28 02:37:14 +00001436 "block erase function is not implemented. ");
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001437 return 1;
1438 }
1439 if (eraser.block_erase && !eraser.eraseblocks[0].count) {
1440 if (log)
1441 msg_cdbg("block erase function found, but "
Stefan Tauner355cbfd2011-05-28 02:37:14 +00001442 "eraseblock layout is not defined. ");
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001443 return 1;
1444 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00001445 // TODO: Once erase functions are annotated with allowed buses, check that as well.
Carl-Daniel Hailfingerdce73ae2010-12-05 15:14:44 +00001446 return 0;
1447}
1448
Nico Huber7af0e792016-04-29 16:40:15 +02001449/**
1450 * @brief Reads the included layout regions into a buffer.
1451 *
1452 * If there is no layout set in the given flash context, the whole chip will
1453 * be read.
1454 *
1455 * @param flashctx Flash context to be used.
1456 * @param buffer Buffer of full chip size to read into.
1457 * @return 0 on success,
1458 * 1 if any read fails.
1459 */
1460static int read_by_layout(struct flashctx *const flashctx, uint8_t *const buffer)
1461{
1462 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber5ca55232019-06-15 22:29:08 +02001463 const struct romentry *entry = NULL;
Nico Huber7af0e792016-04-29 16:40:15 +02001464
Nico Huber5ca55232019-06-15 22:29:08 +02001465 while ((entry = layout_next_included(layout, entry))) {
1466 const chipoff_t region_start = entry->start;
1467 const chipsize_t region_len = entry->end - entry->start + 1;
Nico Huber7af0e792016-04-29 16:40:15 +02001468
1469 if (flashctx->chip->read(flashctx, buffer + region_start, region_start, region_len))
1470 return 1;
1471 }
1472 return 0;
1473}
1474
1475typedef int (*erasefn_t)(struct flashctx *, unsigned int addr, unsigned int len);
1476/**
1477 * @private
1478 *
1479 * For read-erase-write, `curcontents` and `newcontents` shall point
1480 * to buffers of the chip's size. Both are supposed to be prefilled
1481 * with at least the included layout regions of the current flash
1482 * contents (`curcontents`) and the data to be written to the flash
1483 * (`newcontents`).
1484 *
1485 * For erase, `curcontents` and `newcontents` shall be NULL-pointers.
1486 *
1487 * The `chipoff_t` values are used internally by `walk_by_layout()`.
1488 */
1489struct walk_info {
1490 uint8_t *curcontents;
1491 const uint8_t *newcontents;
1492 chipoff_t region_start;
1493 chipoff_t region_end;
1494 chipoff_t erase_start;
1495 chipoff_t erase_end;
1496};
1497/* returns 0 on success, 1 to retry with another erase function, 2 for immediate abort */
1498typedef int (*per_blockfn_t)(struct flashctx *, const struct walk_info *, erasefn_t);
1499
1500static int walk_eraseblocks(struct flashctx *const flashctx,
1501 struct walk_info *const info,
1502 const size_t erasefunction, const per_blockfn_t per_blockfn)
1503{
1504 int ret;
1505 size_t i, j;
1506 bool first = true;
1507 struct block_eraser *const eraser = &flashctx->chip->block_erasers[erasefunction];
1508
1509 info->erase_start = 0;
1510 for (i = 0; i < NUM_ERASEREGIONS; ++i) {
1511 /* count==0 for all automatically initialized array
1512 members so the loop below won't be executed for them. */
1513 for (j = 0; j < eraser->eraseblocks[i].count; ++j, info->erase_start = info->erase_end + 1) {
1514 info->erase_end = info->erase_start + eraser->eraseblocks[i].size - 1;
1515
1516 /* Skip any eraseblock that is completely outside the current region. */
1517 if (info->erase_end < info->region_start)
1518 continue;
1519 if (info->region_end < info->erase_start)
1520 break;
1521
1522 /* Print this for every block except the first one. */
1523 if (first)
1524 first = false;
1525 else
1526 msg_cdbg(", ");
1527 msg_cdbg("0x%06x-0x%06x:", info->erase_start, info->erase_end);
1528
1529 ret = per_blockfn(flashctx, info, eraser->block_erase);
1530 if (ret)
1531 return ret;
1532 }
1533 if (info->region_end < info->erase_start)
1534 break;
1535 }
1536 msg_cdbg("\n");
1537 return 0;
1538}
1539
1540static int walk_by_layout(struct flashctx *const flashctx, struct walk_info *const info,
1541 const per_blockfn_t per_blockfn)
1542{
1543 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber5ca55232019-06-15 22:29:08 +02001544 const struct romentry *entry = NULL;
Nico Huber7af0e792016-04-29 16:40:15 +02001545
1546 all_skipped = true;
1547 msg_cinfo("Erasing and writing flash chip... ");
1548
Nico Huber5ca55232019-06-15 22:29:08 +02001549 while ((entry = layout_next_included(layout, entry))) {
1550 info->region_start = entry->start;
1551 info->region_end = entry->end;
Nico Huber7af0e792016-04-29 16:40:15 +02001552
1553 size_t j;
1554 int error = 1; /* retry as long as it's 1 */
1555 for (j = 0; j < NUM_ERASEFUNCTIONS; ++j) {
1556 if (j != 0)
1557 msg_cinfo("Looking for another erase function.\n");
1558 msg_cdbg("Trying erase function %zi... ", j);
1559 if (check_block_eraser(flashctx, j, 1))
1560 continue;
1561
1562 error = walk_eraseblocks(flashctx, info, j, per_blockfn);
1563 if (error != 1)
1564 break;
1565
1566 if (info->curcontents) {
1567 msg_cinfo("Reading current flash chip contents... ");
1568 if (read_by_layout(flashctx, info->curcontents)) {
1569 /* Now we are truly screwed. Read failed as well. */
1570 msg_cerr("Can't read anymore! Aborting.\n");
1571 /* We have no idea about the flash chip contents, so
1572 retrying with another erase function is pointless. */
1573 error = 2;
1574 break;
1575 }
1576 msg_cinfo("done. ");
1577 }
1578 }
1579 if (error == 1)
1580 msg_cinfo("No usable erase functions left.\n");
1581 if (error) {
1582 msg_cerr("FAILED!\n");
1583 return 1;
1584 }
1585 }
1586 if (all_skipped)
1587 msg_cinfo("\nWarning: Chip content is identical to the requested image.\n");
1588 msg_cinfo("Erase/write done.\n");
1589 return 0;
1590}
1591
1592static int erase_block(struct flashctx *const flashctx,
1593 const struct walk_info *const info, const erasefn_t erasefn)
1594{
1595 const unsigned int erase_len = info->erase_end + 1 - info->erase_start;
Nico Huber6e61e0c2019-01-23 17:07:49 +01001596 const bool region_unaligned = info->region_start > info->erase_start ||
1597 info->erase_end > info->region_end;
1598 uint8_t *backup_contents = NULL, *erased_contents = NULL;
1599 int ret = 2;
Nico Huber7af0e792016-04-29 16:40:15 +02001600
Nico Huber6e61e0c2019-01-23 17:07:49 +01001601 /*
1602 * If the region is not erase-block aligned, merge current flash con-
1603 * tents into a new buffer `backup_contents`.
1604 */
1605 if (region_unaligned) {
1606 backup_contents = malloc(erase_len);
1607 erased_contents = malloc(erase_len);
1608 if (!backup_contents || !erased_contents) {
1609 msg_cerr("Out of memory!\n");
1610 ret = 1;
1611 goto _free_ret;
1612 }
1613 memset(backup_contents, ERASED_VALUE(flashctx), erase_len);
1614 memset(erased_contents, ERASED_VALUE(flashctx), erase_len);
1615
1616 msg_cdbg("R");
1617 /* Merge data preceding the current region. */
1618 if (info->region_start > info->erase_start) {
1619 const chipoff_t start = info->erase_start;
1620 const chipsize_t len = info->region_start - info->erase_start;
1621 if (flashctx->chip->read(flashctx, backup_contents, start, len)) {
1622 msg_cerr("Can't read! Aborting.\n");
1623 goto _free_ret;
1624 }
1625 }
1626 /* Merge data following the current region. */
1627 if (info->erase_end > info->region_end) {
1628 const chipoff_t start = info->region_end + 1;
1629 const chipoff_t rel_start = start - info->erase_start; /* within this erase block */
1630 const chipsize_t len = info->erase_end - info->region_end;
1631 if (flashctx->chip->read(flashctx, backup_contents + rel_start, start, len)) {
1632 msg_cerr("Can't read! Aborting.\n");
1633 goto _free_ret;
1634 }
1635 }
1636 }
1637
1638 ret = 1;
Nico Huber7af0e792016-04-29 16:40:15 +02001639 all_skipped = false;
1640
1641 msg_cdbg("E");
1642 if (erasefn(flashctx, info->erase_start, erase_len))
Nico Huber6e61e0c2019-01-23 17:07:49 +01001643 goto _free_ret;
Nico Huber7af0e792016-04-29 16:40:15 +02001644 if (check_erased_range(flashctx, info->erase_start, erase_len)) {
1645 msg_cerr("ERASE FAILED!\n");
Nico Huber6e61e0c2019-01-23 17:07:49 +01001646 goto _free_ret;
Nico Huber7af0e792016-04-29 16:40:15 +02001647 }
Nico Huber6e61e0c2019-01-23 17:07:49 +01001648
1649 if (region_unaligned) {
1650 unsigned int starthere = 0, lenhere = 0, writecount = 0;
1651 /* get_next_write() sets starthere to a new value after the call. */
1652 while ((lenhere = get_next_write(erased_contents + starthere, backup_contents + starthere,
1653 erase_len - starthere, &starthere, flashctx->chip->gran))) {
1654 if (!writecount++)
1655 msg_cdbg("W");
1656 /* Needs the partial write function signature. */
1657 if (flashctx->chip->write(flashctx, backup_contents + starthere,
1658 info->erase_start + starthere, lenhere))
1659 goto _free_ret;
1660 starthere += lenhere;
1661 }
1662 }
1663
1664 ret = 0;
1665
1666_free_ret:
1667 free(erased_contents);
1668 free(backup_contents);
1669 return ret;
Nico Huber7af0e792016-04-29 16:40:15 +02001670}
1671
1672/**
1673 * @brief Erases the included layout regions.
1674 *
1675 * If there is no layout set in the given flash context, the whole chip will
1676 * be erased.
1677 *
1678 * @param flashctx Flash context to be used.
1679 * @param buffer Buffer of full chip size to read into.
1680 * @return 0 on success,
1681 * 1 if all available erase functions failed.
1682 */
Nico Huber454f6132012-12-10 13:34:10 +00001683static int erase_by_layout(struct flashctx *const flashctx)
Nico Huber7af0e792016-04-29 16:40:15 +02001684{
1685 struct walk_info info = { 0 };
1686 return walk_by_layout(flashctx, &info, &erase_block);
1687}
1688
1689static int read_erase_write_block(struct flashctx *const flashctx,
1690 const struct walk_info *const info, const erasefn_t erasefn)
1691{
1692 const chipsize_t erase_len = info->erase_end + 1 - info->erase_start;
1693 const bool region_unaligned = info->region_start > info->erase_start ||
1694 info->erase_end > info->region_end;
1695 const uint8_t *newcontents = NULL;
1696 int ret = 2;
1697
1698 /*
1699 * If the region is not erase-block aligned, merge current flash con-
1700 * tents into `info->curcontents` and a new buffer `newc`. The former
1701 * is necessary since we have no guarantee that the full erase block
1702 * was already read into `info->curcontents`. For the latter a new
1703 * buffer is used since `info->newcontents` might contain data for
1704 * other unaligned regions that touch this erase block too.
1705 */
1706 if (region_unaligned) {
1707 msg_cdbg("R");
1708 uint8_t *const newc = malloc(erase_len);
1709 if (!newc) {
1710 msg_cerr("Out of memory!\n");
1711 return 1;
1712 }
1713 memcpy(newc, info->newcontents + info->erase_start, erase_len);
1714
1715 /* Merge data preceding the current region. */
1716 if (info->region_start > info->erase_start) {
1717 const chipoff_t start = info->erase_start;
1718 const chipsize_t len = info->region_start - info->erase_start;
1719 if (flashctx->chip->read(flashctx, newc, start, len)) {
1720 msg_cerr("Can't read! Aborting.\n");
1721 goto _free_ret;
1722 }
1723 memcpy(info->curcontents + start, newc, len);
1724 }
1725 /* Merge data following the current region. */
1726 if (info->erase_end > info->region_end) {
1727 const chipoff_t start = info->region_end + 1;
1728 const chipoff_t rel_start = start - info->erase_start; /* within this erase block */
1729 const chipsize_t len = info->erase_end - info->region_end;
1730 if (flashctx->chip->read(flashctx, newc + rel_start, start, len)) {
1731 msg_cerr("Can't read! Aborting.\n");
1732 goto _free_ret;
1733 }
1734 memcpy(info->curcontents + start, newc + rel_start, len);
1735 }
1736
1737 newcontents = newc;
1738 } else {
1739 newcontents = info->newcontents + info->erase_start;
1740 }
1741
1742 ret = 1;
1743 bool skipped = true;
1744 uint8_t *const curcontents = info->curcontents + info->erase_start;
Paul Kocialkowski995f7552018-01-15 01:06:09 +03001745 const uint8_t erased_value = ERASED_VALUE(flashctx);
David Hendricksf9a30552015-05-23 20:30:30 -07001746 if (!(flashctx->chip->feature_bits & FEATURE_NO_ERASE) &&
1747 need_erase(curcontents, newcontents, erase_len, flashctx->chip->gran, erased_value)) {
Nico Huber7af0e792016-04-29 16:40:15 +02001748 if (erase_block(flashctx, info, erasefn))
1749 goto _free_ret;
1750 /* Erase was successful. Adjust curcontents. */
Paul Kocialkowski995f7552018-01-15 01:06:09 +03001751 memset(curcontents, erased_value, erase_len);
Nico Huber7af0e792016-04-29 16:40:15 +02001752 skipped = false;
1753 }
1754
1755 unsigned int starthere = 0, lenhere = 0, writecount = 0;
1756 /* get_next_write() sets starthere to a new value after the call. */
1757 while ((lenhere = get_next_write(curcontents + starthere, newcontents + starthere,
1758 erase_len - starthere, &starthere, flashctx->chip->gran))) {
1759 if (!writecount++)
1760 msg_cdbg("W");
1761 /* Needs the partial write function signature. */
1762 if (flashctx->chip->write(flashctx, newcontents + starthere,
1763 info->erase_start + starthere, lenhere))
1764 goto _free_ret;
1765 starthere += lenhere;
1766 skipped = false;
1767 }
1768 if (skipped)
1769 msg_cdbg("S");
1770 else
1771 all_skipped = false;
1772
1773 /* Update curcontents, other regions with overlapping erase blocks
1774 might rely on this. */
1775 memcpy(curcontents, newcontents, erase_len);
1776 ret = 0;
1777
1778_free_ret:
1779 if (region_unaligned)
1780 free((void *)newcontents);
1781 return ret;
1782}
1783
1784/**
1785 * @brief Writes the included layout regions from a given image.
1786 *
1787 * If there is no layout set in the given flash context, the whole image
1788 * will be written.
1789 *
1790 * @param flashctx Flash context to be used.
1791 * @param curcontents A buffer of full chip size with current chip contents of included regions.
1792 * @param newcontents The new image to be written.
1793 * @return 0 on success,
1794 * 1 if anything has gone wrong.
1795 */
Nico Huber454f6132012-12-10 13:34:10 +00001796static int write_by_layout(struct flashctx *const flashctx,
1797 void *const curcontents, const void *const newcontents)
Nico Huber7af0e792016-04-29 16:40:15 +02001798{
1799 struct walk_info info;
1800 info.curcontents = curcontents;
1801 info.newcontents = newcontents;
1802 return walk_by_layout(flashctx, &info, read_erase_write_block);
1803}
1804
1805/**
1806 * @brief Compares the included layout regions with content from a buffer.
1807 *
1808 * If there is no layout set in the given flash context, the whole chip's
1809 * contents will be compared.
1810 *
1811 * @param flashctx Flash context to be used.
1812 * @param curcontents A buffer of full chip size to read current chip contents into.
1813 * @param newcontents The new image to compare to.
1814 * @return 0 on success,
1815 * 1 if reading failed,
1816 * 3 if the contents don't match.
1817 */
Nico Huber454f6132012-12-10 13:34:10 +00001818static int verify_by_layout(struct flashctx *const flashctx,
1819 void *const curcontents, const uint8_t *const newcontents)
Nico Huber7af0e792016-04-29 16:40:15 +02001820{
1821 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber5ca55232019-06-15 22:29:08 +02001822 const struct romentry *entry = NULL;
Nico Huber7af0e792016-04-29 16:40:15 +02001823
Nico Huber5ca55232019-06-15 22:29:08 +02001824 while ((entry = layout_next_included(layout, entry))) {
1825 const chipoff_t region_start = entry->start;
1826 const chipsize_t region_len = entry->end - entry->start + 1;
Nico Huber7af0e792016-04-29 16:40:15 +02001827
1828 if (flashctx->chip->read(flashctx, curcontents + region_start, region_start, region_len))
1829 return 1;
1830 if (compare_range(newcontents + region_start, curcontents + region_start,
1831 region_start, region_len))
1832 return 3;
1833 }
1834 return 0;
1835}
1836
Stefan Tauner136388f2013-07-15 10:47:53 +00001837static void nonfatal_help_message(void)
Carl-Daniel Hailfinger42d38a92010-10-19 22:06:20 +00001838{
Stefan Taunera58f6e92014-05-10 09:25:44 +00001839 msg_gerr("Good, writing to the flash chip apparently didn't do anything.\n");
Stefan Tauner136388f2013-07-15 10:47:53 +00001840#if CONFIG_INTERNAL == 1
1841 if (programmer == PROGRAMMER_INTERNAL)
1842 msg_gerr("This means we have to add special support for your board, programmer or flash\n"
1843 "chip. Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1844 "mail flashrom@flashrom.org, thanks!\n"
1845 "-------------------------------------------------------------------------------\n"
1846 "You may now reboot or simply leave the machine running.\n");
1847 else
1848#endif
1849 msg_gerr("Please check the connections (especially those to write protection pins) between\n"
1850 "the programmer and the flash chip. If you think the error is caused by flashrom\n"
1851 "please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1852 "mail flashrom@flashrom.org, thanks!\n");
Carl-Daniel Hailfinger42d38a92010-10-19 22:06:20 +00001853}
1854
Stefan Tauner136388f2013-07-15 10:47:53 +00001855static void emergency_help_message(void)
Carl-Daniel Hailfinger8ab49e72009-08-19 13:55:34 +00001856{
Stefan Tauner136388f2013-07-15 10:47:53 +00001857 msg_gerr("Your flash chip is in an unknown state.\n");
1858#if CONFIG_INTERNAL == 1
1859 if (programmer == PROGRAMMER_INTERNAL)
1860 msg_gerr("Get help on IRC at chat.freenode.net (channel #flashrom) or\n"
1861 "mail flashrom@flashrom.org with the subject \"FAILED: <your board name>\"!\n"
1862 "-------------------------------------------------------------------------------\n"
1863 "DO NOT REBOOT OR POWEROFF!\n");
1864 else
1865#endif
1866 msg_gerr("Please report this on IRC at chat.freenode.net (channel #flashrom) or\n"
1867 "mail flashrom@flashrom.org, thanks!\n");
Carl-Daniel Hailfinger8ab49e72009-08-19 13:55:34 +00001868}
1869
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001870void list_programmers_linebreak(int startcol, int cols, int paren)
1871{
1872 const char *pname;
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +00001873 int pnamelen;
1874 int remaining = 0, firstline = 1;
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001875 enum programmer p;
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +00001876 int i;
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001877
1878 for (p = 0; p < PROGRAMMER_INVALID; p++) {
1879 pname = programmer_table[p].name;
1880 pnamelen = strlen(pname);
1881 if (remaining - pnamelen - 2 < 0) {
1882 if (firstline)
1883 firstline = 0;
1884 else
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001885 msg_ginfo("\n");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001886 for (i = 0; i < startcol; i++)
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001887 msg_ginfo(" ");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001888 remaining = cols - startcol;
1889 } else {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001890 msg_ginfo(" ");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001891 remaining--;
1892 }
1893 if (paren && (p == 0)) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001894 msg_ginfo("(");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001895 remaining--;
1896 }
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001897 msg_ginfo("%s", pname);
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001898 remaining -= pnamelen;
1899 if (p < PROGRAMMER_INVALID - 1) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001900 msg_ginfo(",");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001901 remaining--;
1902 } else {
1903 if (paren)
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +00001904 msg_ginfo(")");
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +00001905 }
1906 }
1907}
1908
Jacob Garberbeeb8bc2019-06-21 15:24:17 -06001909static void print_sysinfo(void)
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001910{
Stefan Taunerb0eee9b2015-01-10 09:32:50 +00001911#if IS_WINDOWS
Carl-Daniel Hailfinger60d9bd22012-08-09 23:34:41 +00001912 SYSTEM_INFO si;
1913 OSVERSIONINFOEX osvi;
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001914
Carl-Daniel Hailfinger60d9bd22012-08-09 23:34:41 +00001915 memset(&si, 0, sizeof(SYSTEM_INFO));
1916 memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
1917 msg_ginfo(" on Windows");
1918 /* Tell Windows which version of the structure we want. */
1919 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
1920 if (GetVersionEx((OSVERSIONINFO*) &osvi))
1921 msg_ginfo(" %lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion);
1922 else
1923 msg_ginfo(" unknown version");
1924 GetSystemInfo(&si);
1925 switch (si.wProcessorArchitecture) {
1926 case PROCESSOR_ARCHITECTURE_AMD64:
1927 msg_ginfo(" (x86_64)");
1928 break;
1929 case PROCESSOR_ARCHITECTURE_INTEL:
1930 msg_ginfo(" (x86)");
1931 break;
1932 default:
1933 msg_ginfo(" (unknown arch)");
1934 break;
1935 }
1936#elif HAVE_UTSNAME == 1
1937 struct utsname osinfo;
1938
1939 uname(&osinfo);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001940 msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
1941 osinfo.machine);
1942#else
1943 msg_ginfo(" on unknown machine");
1944#endif
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001945}
1946
1947void print_buildinfo(void)
1948{
1949 msg_gdbg("flashrom was built with");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001950#if NEED_PCI == 1
1951#ifdef PCILIB_VERSION
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001952 msg_gdbg(" libpci %s,", PCILIB_VERSION);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001953#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001954 msg_gdbg(" unknown PCI library,");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001955#endif
1956#endif
1957#ifdef __clang__
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001958 msg_gdbg(" LLVM Clang");
Carl-Daniel Hailfingerb51e58e2010-07-17 14:49:30 +00001959#ifdef __clang_version__
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001960 msg_gdbg(" %s,", __clang_version__);
Carl-Daniel Hailfingerb51e58e2010-07-17 14:49:30 +00001961#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001962 msg_gdbg(" unknown version (before r102686),");
Carl-Daniel Hailfingerb51e58e2010-07-17 14:49:30 +00001963#endif
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001964#elif defined(__GNUC__)
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001965 msg_gdbg(" GCC");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001966#ifdef __VERSION__
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001967 msg_gdbg(" %s,", __VERSION__);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001968#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001969 msg_gdbg(" unknown version,");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001970#endif
1971#else
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001972 msg_gdbg(" unknown compiler,");
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +00001973#endif
1974#if defined (__FLASHROM_LITTLE_ENDIAN__)
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001975 msg_gdbg(" little endian");
Carl-Daniel Hailfinger06b9efa2012-08-07 11:59:59 +00001976#elif defined (__FLASHROM_BIG_ENDIAN__)
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001977 msg_gdbg(" big endian");
Carl-Daniel Hailfinger06b9efa2012-08-07 11:59:59 +00001978#else
1979#error Endianness could not be determined
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001980#endif
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001981 msg_gdbg("\n");
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001982}
1983
Bernhard Walle201bde32008-01-21 15:24:22 +00001984void print_version(void)
1985{
Stefan Tauner76347082016-11-27 17:45:49 +01001986 msg_ginfo("flashrom %s", flashrom_version);
Carl-Daniel Hailfinger132e2ec2010-03-27 16:36:40 +00001987 print_sysinfo();
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +00001988 msg_ginfo("\n");
Bernhard Walle201bde32008-01-21 15:24:22 +00001989}
1990
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +00001991void print_banner(void)
1992{
1993 msg_ginfo("flashrom is free software, get the source code at "
Stefan Tauner4c723152016-01-14 22:47:55 +00001994 "https://flashrom.org\n");
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +00001995 msg_ginfo("\n");
1996}
1997
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00001998int selfcheck(void)
1999{
Stefan Tauner96658be2014-05-26 22:05:31 +00002000 unsigned int i;
Stefan Taunera6d96482012-12-26 19:51:23 +00002001 int ret = 0;
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00002002
2003 /* Safety check. Instead of aborting after the first error, check
2004 * if more errors exist.
2005 */
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00002006 if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
Sean Nelson316a29f2010-05-07 20:09:04 +00002007 msg_gerr("Programmer table miscompilation!\n");
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00002008 ret = 1;
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00002009 }
Stefan Taunera6d96482012-12-26 19:51:23 +00002010 for (i = 0; i < PROGRAMMER_INVALID; i++) {
2011 const struct programmer_entry p = programmer_table[i];
2012 if (p.name == NULL) {
2013 msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
2014 ret = 1;
2015 /* This might hide other problems with this programmer, but allows for better error
2016 * messages below without jumping through hoops. */
2017 continue;
2018 }
Stefan Tauneraf358d62012-12-27 18:40:26 +00002019 switch (p.type) {
2020 case USB:
2021 case PCI:
2022 case OTHER:
2023 if (p.devs.note == NULL) {
2024 if (strcmp("internal", p.name) == 0)
2025 break; /* This one has its device list stored separately. */
2026 msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
2027 p.name);
2028 ret = 1;
2029 }
2030 break;
2031 default:
2032 msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
2033 ret = 1;
2034 break;
2035 }
Stefan Taunera6d96482012-12-26 19:51:23 +00002036 if (p.init == NULL) {
2037 msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
2038 ret = 1;
2039 }
2040 if (p.delay == NULL) {
2041 msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
2042 ret = 1;
2043 }
2044 if (p.map_flash_region == NULL) {
2045 msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
2046 ret = 1;
2047 }
2048 if (p.unmap_flash_region == NULL) {
2049 msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
2050 ret = 1;
2051 }
2052 }
Stefan Tauner96658be2014-05-26 22:05:31 +00002053
2054 /* It would be favorable if we could check for the correct layout (especially termination) of various
2055 * constant arrays: flashchips, chipset_enables, board_matches, boards_known, laptops_known.
2056 * They are all defined as externs in this compilation unit so we don't know their sizes which vary
2057 * depending on compiler flags, e.g. the target architecture, and can sometimes be 0.
2058 * For 'flashchips' we export the size explicitly to work around this and to be able to implement the
2059 * checks below. */
Stefan Tauner6697f712014-08-06 15:09:15 +00002060 if (flashchips_size <= 1 || flashchips[flashchips_size - 1].name != NULL) {
Stefan Tauner7bcacb12011-05-26 01:35:19 +00002061 msg_gerr("Flashchips table miscompilation!\n");
2062 ret = 1;
Stefan Tauner96658be2014-05-26 22:05:31 +00002063 } else {
2064 for (i = 0; i < flashchips_size - 1; i++) {
2065 const struct flashchip *chip = &flashchips[i];
2066 if (chip->vendor == NULL || chip->name == NULL || chip->bustype == BUS_NONE) {
2067 ret = 1;
2068 msg_gerr("ERROR: Some field of flash chip #%d (%s) is misconfigured.\n"
2069 "Please report a bug at flashrom@flashrom.org\n", i,
2070 chip->name == NULL ? "unnamed" : chip->name);
2071 }
2072 if (selfcheck_eraseblocks(chip)) {
2073 ret = 1;
2074 }
2075 }
Stefan Tauner7bcacb12011-05-26 01:35:19 +00002076 }
Stefan Tauner7bcacb12011-05-26 01:35:19 +00002077
Stefan Tauner600576b2014-06-12 22:57:36 +00002078#if CONFIG_INTERNAL == 1
2079 ret |= selfcheck_board_enables();
2080#endif
2081
Stefan Tauner96658be2014-05-26 22:05:31 +00002082 /* TODO: implement similar sanity checks for other arrays where deemed necessary. */
Carl-Daniel Hailfinger293adf02010-01-18 08:14:43 +00002083 return ret;
Carl-Daniel Hailfinger552420b2009-12-24 02:15:55 +00002084}
2085
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002086/* FIXME: This function signature needs to be improved once doit() has a better
2087 * function signature.
2088 */
Jacob Garberbeeb8bc2019-06-21 15:24:17 -06002089static int chip_safety_check(const struct flashctx *flash, int force,
2090 int read_it, int write_it, int erase_it, int verify_it)
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002091{
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00002092 const struct flashchip *chip = flash->chip;
2093
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002094 if (!programmer_may_write && (write_it || erase_it)) {
2095 msg_perr("Write/erase is not working yet on your programmer in "
2096 "its current configuration.\n");
2097 /* --force is the wrong approach, but it's the best we can do
2098 * until the generic programmer parameter parser is merged.
2099 */
2100 if (!force)
2101 return 1;
2102 msg_cerr("Continuing anyway.\n");
2103 }
2104
2105 if (read_it || erase_it || write_it || verify_it) {
2106 /* Everything needs read. */
Stefan Tauner6455dff2014-05-26 00:36:24 +00002107 if (chip->tested.read == BAD) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002108 msg_cerr("Read is not working on this chip. ");
2109 if (!force)
2110 return 1;
2111 msg_cerr("Continuing anyway.\n");
2112 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00002113 if (!chip->read) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002114 msg_cerr("flashrom has no read function for this "
2115 "flash chip.\n");
2116 return 1;
2117 }
2118 }
2119 if (erase_it || write_it) {
2120 /* Write needs erase. */
Stefan Tauner6455dff2014-05-26 00:36:24 +00002121 if (chip->tested.erase == NA) {
2122 msg_cerr("Erase is not possible on this chip.\n");
2123 return 1;
2124 }
2125 if (chip->tested.erase == BAD) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002126 msg_cerr("Erase is not working on this chip. ");
2127 if (!force)
2128 return 1;
2129 msg_cerr("Continuing anyway.\n");
2130 }
Sylvain "ythier" Hitier9db45512011-07-04 07:27:17 +00002131 if(count_usable_erasers(flash) == 0) {
Stefan Tauner5368dca2011-07-01 00:19:12 +00002132 msg_cerr("flashrom has no erase function for this "
2133 "flash chip.\n");
2134 return 1;
2135 }
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002136 }
2137 if (write_it) {
Stefan Tauner6455dff2014-05-26 00:36:24 +00002138 if (chip->tested.write == NA) {
2139 msg_cerr("Write is not possible on this chip.\n");
2140 return 1;
2141 }
2142 if (chip->tested.write == BAD) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002143 msg_cerr("Write is not working on this chip. ");
2144 if (!force)
2145 return 1;
2146 msg_cerr("Continuing anyway.\n");
2147 }
Carl-Daniel Hailfinger5a7cb842012-08-25 01:17:58 +00002148 if (!chip->write) {
Carl-Daniel Hailfinger43069442010-10-15 00:01:14 +00002149 msg_cerr("flashrom has no write function for this "
2150 "flash chip.\n");
2151 return 1;
2152 }
2153 }
2154 return 0;
2155}
2156
Nico Huber305f4172013-06-14 11:55:26 +02002157int prepare_flash_access(struct flashctx *const flash,
2158 const bool read_it, const bool write_it,
2159 const bool erase_it, const bool verify_it)
Nico Huber454f6132012-12-10 13:34:10 +00002160{
2161 if (chip_safety_check(flash, flash->flags.force, read_it, write_it, erase_it, verify_it)) {
2162 msg_cerr("Aborting.\n");
2163 return 1;
2164 }
2165
2166 if (flash->layout == get_global_layout() && normalize_romentries(flash)) {
2167 msg_cerr("Requested regions can not be handled. Aborting.\n");
2168 return 1;
2169 }
2170
2171 if (map_flash(flash) != 0)
2172 return 1;
2173
2174 /* Given the existence of read locks, we want to unlock for read,
2175 erase and write. */
2176 if (flash->chip->unlock)
2177 flash->chip->unlock(flash);
2178
Nico Huberf43c6542017-10-14 17:47:28 +02002179 flash->address_high_byte = -1;
2180 flash->in_4ba_mode = false;
2181
Nico Huberdc5af542018-12-22 16:54:59 +01002182 /* Be careful about 4BA chips and broken masters */
2183 if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
2184 /* If we can't use native instructions, bail out */
2185 if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
2186 || !spi_master_4ba(flash)) {
2187 msg_cerr("Programmer doesn't support this chip. Aborting.\n");
2188 return 1;
2189 }
2190 }
2191
Ed Swierkcc20a9b2017-07-03 13:17:18 -07002192 /* Enable/disable 4-byte addressing mode if flash chip supports it */
Nico Huber86bddb52018-03-13 18:14:52 +01002193 if (flash->chip->feature_bits & (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_ENTER_EAR7)) {
Nico Huberfe34d2a2017-11-10 21:10:20 +01002194 int ret;
2195 if (spi_master_4ba(flash))
2196 ret = spi_enter_4ba(flash);
2197 else
2198 ret = spi_exit_4ba(flash);
2199 if (ret) {
2200 msg_cerr("Failed to set correct 4BA mode! Aborting.\n");
Ed Swierkcc20a9b2017-07-03 13:17:18 -07002201 return 1;
Boris Baykov7fe85692016-06-11 18:29:03 +02002202 }
Boris Baykov99127182016-06-11 18:29:00 +02002203 }
2204
Nico Huber454f6132012-12-10 13:34:10 +00002205 return 0;
2206}
2207
Nico Huber305f4172013-06-14 11:55:26 +02002208void finalize_flash_access(struct flashctx *const flash)
Nico Huber454f6132012-12-10 13:34:10 +00002209{
2210 unmap_flash(flash);
2211}
2212
2213/**
2214 * @addtogroup flashrom-flash
2215 * @{
2216 */
2217
2218/**
2219 * @brief Erase the specified ROM chip.
2220 *
2221 * If a layout is set in the given flash context, only included regions
2222 * will be erased.
2223 *
2224 * @param flashctx The context of the flash chip to erase.
2225 * @return 0 on success.
2226 */
2227int flashrom_flash_erase(struct flashctx *const flashctx)
2228{
2229 if (prepare_flash_access(flashctx, false, false, true, false))
2230 return 1;
2231
2232 const int ret = erase_by_layout(flashctx);
2233
2234 finalize_flash_access(flashctx);
2235
2236 return ret;
2237}
2238
2239/** @} */ /* end flashrom-flash */
2240
2241/**
2242 * @defgroup flashrom-ops Operations
2243 * @{
2244 */
2245
2246/**
2247 * @brief Read the current image from the specified ROM chip.
2248 *
2249 * If a layout is set in the specified flash context, only included regions
2250 * will be read.
2251 *
2252 * @param flashctx The context of the flash chip.
2253 * @param buffer Target buffer to write image to.
2254 * @param buffer_len Size of target buffer in bytes.
2255 * @return 0 on success,
2256 * 2 if buffer_len is too short for the flash chip's contents,
2257 * or 1 on any other failure.
2258 */
2259int flashrom_image_read(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len)
2260{
2261 const size_t flash_size = flashctx->chip->total_size * 1024;
2262
2263 if (flash_size > buffer_len)
2264 return 2;
2265
2266 if (prepare_flash_access(flashctx, true, false, false, false))
2267 return 1;
2268
2269 msg_cinfo("Reading flash... ");
2270
2271 int ret = 1;
2272 if (read_by_layout(flashctx, buffer)) {
2273 msg_cerr("Read operation failed!\n");
2274 msg_cinfo("FAILED.\n");
2275 goto _finalize_ret;
2276 }
2277 msg_cinfo("done.\n");
2278 ret = 0;
2279
2280_finalize_ret:
2281 finalize_flash_access(flashctx);
2282 return ret;
2283}
2284
2285static void combine_image_by_layout(const struct flashctx *const flashctx,
2286 uint8_t *const newcontents, const uint8_t *const oldcontents)
2287{
2288 const struct flashrom_layout *const layout = get_layout(flashctx);
Nico Huber3d7b1e32018-12-22 00:53:14 +01002289 const struct romentry *included;
2290 chipoff_t start = 0;
Nico Huber454f6132012-12-10 13:34:10 +00002291
Nico Huber3d7b1e32018-12-22 00:53:14 +01002292 while ((included = layout_next_included_region(layout, start))) {
2293 if (included->start > start) {
2294 /* copy everything up to the start of this included region */
2295 memcpy(newcontents + start, oldcontents + start, included->start - start);
2296 }
2297 /* skip this included region */
2298 start = included->end + 1;
2299 if (start == 0)
2300 return;
Nico Huber454f6132012-12-10 13:34:10 +00002301 }
Nico Huber3d7b1e32018-12-22 00:53:14 +01002302
2303 /* copy the rest of the chip */
2304 const chipsize_t copy_len = flashctx->chip->total_size * 1024 - start;
2305 memcpy(newcontents + start, oldcontents + start, copy_len);
Nico Huber454f6132012-12-10 13:34:10 +00002306}
2307
2308/**
2309 * @brief Write the specified image to the ROM chip.
2310 *
2311 * If a layout is set in the specified flash context, only erase blocks
2312 * containing included regions will be touched.
2313 *
2314 * @param flashctx The context of the flash chip.
Nico Huber1b172f22017-06-19 12:35:24 +02002315 * @param buffer Source buffer to read image from (may be altered for full verification).
Nico Huber454f6132012-12-10 13:34:10 +00002316 * @param buffer_len Size of source buffer in bytes.
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002317 * @param refbuffer If given, assume flash chip contains same data as `refbuffer`.
Nico Huber454f6132012-12-10 13:34:10 +00002318 * @return 0 on success,
2319 * 4 if buffer_len doesn't match the size of the flash chip,
2320 * 3 if write was tried but nothing has changed,
2321 * 2 if write failed and flash contents changed,
2322 * or 1 on any other failure.
2323 */
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002324int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len,
2325 const void *const refbuffer)
Nico Huber454f6132012-12-10 13:34:10 +00002326{
2327 const size_t flash_size = flashctx->chip->total_size * 1024;
2328 const bool verify_all = flashctx->flags.verify_whole_chip;
2329 const bool verify = flashctx->flags.verify_after_write;
2330
2331 if (buffer_len != flash_size)
2332 return 4;
2333
2334 int ret = 1;
2335
2336 uint8_t *const newcontents = buffer;
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002337 const uint8_t *const refcontents = refbuffer;
Nico Huber454f6132012-12-10 13:34:10 +00002338 uint8_t *const curcontents = malloc(flash_size);
2339 uint8_t *oldcontents = NULL;
2340 if (verify_all)
2341 oldcontents = malloc(flash_size);
2342 if (!curcontents || (verify_all && !oldcontents)) {
2343 msg_gerr("Out of memory!\n");
2344 goto _free_ret;
2345 }
2346
2347#if CONFIG_INTERNAL == 1
2348 if (programmer == PROGRAMMER_INTERNAL && cb_check_image(newcontents, flash_size) < 0) {
2349 if (flashctx->flags.force_boardmismatch) {
2350 msg_pinfo("Proceeding anyway because user forced us to.\n");
2351 } else {
2352 msg_perr("Aborting. You can override this with "
2353 "-p internal:boardmismatch=force.\n");
2354 goto _free_ret;
2355 }
2356 }
2357#endif
2358
2359 if (prepare_flash_access(flashctx, false, true, false, verify))
2360 goto _free_ret;
2361
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002362 /* If given, assume flash chip contains same data as `refcontents`. */
2363 if (refcontents) {
2364 msg_cinfo("Assuming old flash chip contents as ref-file...\n");
2365 memcpy(curcontents, refcontents, flash_size);
2366 if (oldcontents)
2367 memcpy(oldcontents, refcontents, flash_size);
Nico Huber454f6132012-12-10 13:34:10 +00002368 } else {
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002369 /*
2370 * Read the whole chip to be able to check whether regions need to be
2371 * erased and to give better diagnostics in case write fails.
2372 * The alternative is to read only the regions which are to be
2373 * preserved, but in that case we might perform unneeded erase which
2374 * takes time as well.
2375 */
2376 msg_cinfo("Reading old flash chip contents... ");
2377 if (verify_all) {
2378 if (flashctx->chip->read(flashctx, oldcontents, 0, flash_size)) {
2379 msg_cinfo("FAILED.\n");
2380 goto _finalize_ret;
2381 }
2382 memcpy(curcontents, oldcontents, flash_size);
2383 } else {
2384 if (read_by_layout(flashctx, curcontents)) {
2385 msg_cinfo("FAILED.\n");
2386 goto _finalize_ret;
2387 }
Nico Huber454f6132012-12-10 13:34:10 +00002388 }
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002389 msg_cinfo("done.\n");
Nico Huber454f6132012-12-10 13:34:10 +00002390 }
Nico Huber454f6132012-12-10 13:34:10 +00002391
2392 if (write_by_layout(flashctx, curcontents, newcontents)) {
2393 msg_cerr("Uh oh. Erase/write failed. ");
2394 ret = 2;
2395 if (verify_all) {
2396 msg_cerr("Checking if anything has changed.\n");
2397 msg_cinfo("Reading current flash chip contents... ");
2398 if (!flashctx->chip->read(flashctx, curcontents, 0, flash_size)) {
2399 msg_cinfo("done.\n");
2400 if (!memcmp(oldcontents, curcontents, flash_size)) {
2401 nonfatal_help_message();
2402 goto _finalize_ret;
2403 }
2404 msg_cerr("Apparently at least some data has changed.\n");
2405 } else
2406 msg_cerr("Can't even read anymore!\n");
2407 emergency_help_message();
2408 goto _finalize_ret;
2409 } else {
2410 msg_cerr("\n");
2411 }
2412 emergency_help_message();
2413 goto _finalize_ret;
2414 }
2415
2416 /* Verify only if we actually changed something. */
2417 if (verify && !all_skipped) {
2418 const struct flashrom_layout *const layout_bak = flashctx->layout;
2419
2420 msg_cinfo("Verifying flash... ");
2421
2422 /* Work around chips which need some time to calm down. */
2423 programmer_delay(1000*1000);
2424
2425 if (verify_all) {
2426 combine_image_by_layout(flashctx, newcontents, oldcontents);
2427 flashctx->layout = NULL;
2428 }
2429 ret = verify_by_layout(flashctx, curcontents, newcontents);
2430 flashctx->layout = layout_bak;
2431 /* If we tried to write, and verification now fails, we
2432 might have an emergency situation. */
2433 if (ret)
2434 emergency_help_message();
2435 else
2436 msg_cinfo("VERIFIED.\n");
2437 } else {
2438 /* We didn't change anything. */
2439 ret = 0;
2440 }
2441
2442_finalize_ret:
2443 finalize_flash_access(flashctx);
2444_free_ret:
2445 free(oldcontents);
2446 free(curcontents);
2447 return ret;
2448}
2449
2450/**
2451 * @brief Verify the ROM chip's contents with the specified image.
2452 *
2453 * If a layout is set in the specified flash context, only included regions
2454 * will be verified.
2455 *
2456 * @param flashctx The context of the flash chip.
2457 * @param buffer Source buffer to verify with.
2458 * @param buffer_len Size of source buffer in bytes.
2459 * @return 0 on success,
2460 * 3 if the chip's contents don't match,
2461 * 2 if buffer_len doesn't match the size of the flash chip,
2462 * or 1 on any other failure.
2463 */
2464int flashrom_image_verify(struct flashctx *const flashctx, const void *const buffer, const size_t buffer_len)
2465{
2466 const size_t flash_size = flashctx->chip->total_size * 1024;
2467
2468 if (buffer_len != flash_size)
2469 return 2;
2470
2471 const uint8_t *const newcontents = buffer;
2472 uint8_t *const curcontents = malloc(flash_size);
2473 if (!curcontents) {
2474 msg_gerr("Out of memory!\n");
2475 return 1;
2476 }
2477
2478 int ret = 1;
2479
2480 if (prepare_flash_access(flashctx, false, false, false, true))
2481 goto _free_ret;
2482
2483 msg_cinfo("Verifying flash... ");
2484 ret = verify_by_layout(flashctx, curcontents, newcontents);
2485 if (!ret)
2486 msg_cinfo("VERIFIED.\n");
2487
2488 finalize_flash_access(flashctx);
2489_free_ret:
2490 free(curcontents);
2491 return ret;
2492}
2493
2494/** @} */ /* end flashrom-ops */
Nico Huber899e4ec2016-04-29 18:39:01 +02002495
2496int do_read(struct flashctx *const flash, const char *const filename)
2497{
2498 if (prepare_flash_access(flash, true, false, false, false))
2499 return 1;
2500
2501 const int ret = read_flash_to_file(flash, filename);
2502
2503 finalize_flash_access(flash);
2504
2505 return ret;
2506}
2507
2508int do_erase(struct flashctx *const flash)
2509{
2510 const int ret = flashrom_flash_erase(flash);
2511
2512 /*
2513 * FIXME: Do we really want the scary warning if erase failed?
2514 * After all, after erase the chip is either blank or partially
2515 * blank or it has the old contents. A blank chip won't boot,
2516 * so if the user wanted erase and reboots afterwards, the user
2517 * knows very well that booting won't work.
2518 */
2519 if (ret)
2520 emergency_help_message();
2521
2522 return ret;
2523}
2524
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002525int do_write(struct flashctx *const flash, const char *const filename, const char *const referencefile)
Nico Huber899e4ec2016-04-29 18:39:01 +02002526{
2527 const size_t flash_size = flash->chip->total_size * 1024;
2528 int ret = 1;
2529
2530 uint8_t *const newcontents = malloc(flash_size);
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002531 uint8_t *const refcontents = referencefile ? malloc(flash_size) : NULL;
2532
2533 if (!newcontents || (referencefile && !refcontents)) {
Nico Huber899e4ec2016-04-29 18:39:01 +02002534 msg_gerr("Out of memory!\n");
2535 goto _free_ret;
2536 }
2537
2538 if (read_buf_from_file(newcontents, flash_size, filename))
2539 goto _free_ret;
2540
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002541 if (referencefile) {
2542 if (read_buf_from_file(refcontents, flash_size, referencefile))
2543 goto _free_ret;
2544 }
2545
2546 ret = flashrom_image_write(flash, newcontents, flash_size, refcontents);
Nico Huber899e4ec2016-04-29 18:39:01 +02002547
2548_free_ret:
Paul Kocialkowskif701f342018-01-15 01:10:36 +03002549 free(refcontents);
Nico Huber899e4ec2016-04-29 18:39:01 +02002550 free(newcontents);
2551 return ret;
2552}
2553
2554int do_verify(struct flashctx *const flash, const char *const filename)
2555{
2556 const size_t flash_size = flash->chip->total_size * 1024;
2557 int ret = 1;
2558
2559 uint8_t *const newcontents = malloc(flash_size);
2560 if (!newcontents) {
2561 msg_gerr("Out of memory!\n");
2562 goto _free_ret;
2563 }
2564
2565 if (read_buf_from_file(newcontents, flash_size, filename))
2566 goto _free_ret;
2567
2568 ret = flashrom_image_verify(flash, newcontents, flash_size);
2569
2570_free_ret:
2571 free(newcontents);
2572 return ret;
2573}