xref: /aosp_15_r20/external/vboot_reference/host/lib/flashrom_drv.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2021 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker  * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker  *
5*8617a60dSAndroid Build Coastguard Worker  * The utility functions for firmware updater.
6*8617a60dSAndroid Build Coastguard Worker  */
7*8617a60dSAndroid Build Coastguard Worker 
8*8617a60dSAndroid Build Coastguard Worker #include <libflashrom.h>
9*8617a60dSAndroid Build Coastguard Worker 
10*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
11*8617a60dSAndroid Build Coastguard Worker #include "crossystem.h"
12*8617a60dSAndroid Build Coastguard Worker #include "host_misc.h"
13*8617a60dSAndroid Build Coastguard Worker #include "util_misc.h"
14*8617a60dSAndroid Build Coastguard Worker //#include "updater.h"
15*8617a60dSAndroid Build Coastguard Worker #include "../../futility/futility.h"
16*8617a60dSAndroid Build Coastguard Worker #include "flashrom.h"
17*8617a60dSAndroid Build Coastguard Worker 
18*8617a60dSAndroid Build Coastguard Worker // global to allow verbosity level to be injected into callback.
19*8617a60dSAndroid Build Coastguard Worker static enum flashrom_log_level g_verbose_screen = FLASHROM_MSG_INFO;
20*8617a60dSAndroid Build Coastguard Worker 
flashrom_print_cb(enum flashrom_log_level level,const char * fmt,va_list ap)21*8617a60dSAndroid Build Coastguard Worker static int flashrom_print_cb(enum flashrom_log_level level, const char *fmt,
22*8617a60dSAndroid Build Coastguard Worker 			     va_list ap)
23*8617a60dSAndroid Build Coastguard Worker {
24*8617a60dSAndroid Build Coastguard Worker 	int ret = 0;
25*8617a60dSAndroid Build Coastguard Worker 	FILE *output_type = (level < FLASHROM_MSG_INFO) ? stderr : stdout;
26*8617a60dSAndroid Build Coastguard Worker 
27*8617a60dSAndroid Build Coastguard Worker 	if (level > g_verbose_screen)
28*8617a60dSAndroid Build Coastguard Worker 		return ret;
29*8617a60dSAndroid Build Coastguard Worker 
30*8617a60dSAndroid Build Coastguard Worker 	ret = vfprintf(output_type, fmt, ap);
31*8617a60dSAndroid Build Coastguard Worker 	/* msg_*spew often happens inside chip accessors
32*8617a60dSAndroid Build Coastguard Worker 	 * in possibly time-critical operations.
33*8617a60dSAndroid Build Coastguard Worker 	 * Don't slow them down by flushing.
34*8617a60dSAndroid Build Coastguard Worker 	 */
35*8617a60dSAndroid Build Coastguard Worker 	if (level != FLASHROM_MSG_SPEW)
36*8617a60dSAndroid Build Coastguard Worker 		fflush(output_type);
37*8617a60dSAndroid Build Coastguard Worker 
38*8617a60dSAndroid Build Coastguard Worker 	return ret;
39*8617a60dSAndroid Build Coastguard Worker }
40*8617a60dSAndroid Build Coastguard Worker 
flashrom_extract_params(const char * str,char ** prog,char ** params)41*8617a60dSAndroid Build Coastguard Worker static char *flashrom_extract_params(const char *str, char **prog, char **params)
42*8617a60dSAndroid Build Coastguard Worker {
43*8617a60dSAndroid Build Coastguard Worker 	char *tmp = strdup(str);
44*8617a60dSAndroid Build Coastguard Worker 	*prog = strtok(tmp, ":");
45*8617a60dSAndroid Build Coastguard Worker 	*params = strtok(NULL, "");
46*8617a60dSAndroid Build Coastguard Worker 	return tmp;
47*8617a60dSAndroid Build Coastguard Worker }
48*8617a60dSAndroid Build Coastguard Worker 
49*8617a60dSAndroid Build Coastguard Worker /*
50*8617a60dSAndroid Build Coastguard Worker  * NOTE: When `regions` contains multiple regions, `region_start` and
51*8617a60dSAndroid Build Coastguard Worker  * `region_len` will be filled with the data of the first region.
52*8617a60dSAndroid Build Coastguard Worker  */
flashrom_read_image_impl(struct firmware_image * image,const char * const regions[],const size_t regions_len,unsigned int * region_start,unsigned int * region_len,int verbosity)53*8617a60dSAndroid Build Coastguard Worker static int flashrom_read_image_impl(struct firmware_image *image,
54*8617a60dSAndroid Build Coastguard Worker 				    const char * const regions[],
55*8617a60dSAndroid Build Coastguard Worker 						const size_t regions_len,
56*8617a60dSAndroid Build Coastguard Worker 				    unsigned int *region_start,
57*8617a60dSAndroid Build Coastguard Worker 				    unsigned int *region_len, int verbosity)
58*8617a60dSAndroid Build Coastguard Worker {
59*8617a60dSAndroid Build Coastguard Worker 	int r = 0;
60*8617a60dSAndroid Build Coastguard Worker 	size_t len = 0;
61*8617a60dSAndroid Build Coastguard Worker 	*region_start = 0;
62*8617a60dSAndroid Build Coastguard Worker 	*region_len = 0;
63*8617a60dSAndroid Build Coastguard Worker 
64*8617a60dSAndroid Build Coastguard Worker 	g_verbose_screen = (verbosity == -1) ? FLASHROM_MSG_INFO : verbosity;
65*8617a60dSAndroid Build Coastguard Worker 
66*8617a60dSAndroid Build Coastguard Worker 	char *programmer, *params;
67*8617a60dSAndroid Build Coastguard Worker 	char *tmp = flashrom_extract_params(image->programmer, &programmer, &params);
68*8617a60dSAndroid Build Coastguard Worker 
69*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_programmer *prog = NULL;
70*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_flashctx *flashctx = NULL;
71*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_layout *layout = NULL;
72*8617a60dSAndroid Build Coastguard Worker 
73*8617a60dSAndroid Build Coastguard Worker 	flashrom_set_log_callback((flashrom_log_callback *)&flashrom_print_cb);
74*8617a60dSAndroid Build Coastguard Worker 
75*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_init(1)
76*8617a60dSAndroid Build Coastguard Worker 		|| flashrom_programmer_init(&prog, programmer, params)) {
77*8617a60dSAndroid Build Coastguard Worker 		r = -1;
78*8617a60dSAndroid Build Coastguard Worker 		goto err_init;
79*8617a60dSAndroid Build Coastguard Worker 	}
80*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_flash_probe(&flashctx, prog, NULL)) {
81*8617a60dSAndroid Build Coastguard Worker 		r = -1;
82*8617a60dSAndroid Build Coastguard Worker 		goto err_probe;
83*8617a60dSAndroid Build Coastguard Worker 	}
84*8617a60dSAndroid Build Coastguard Worker 
85*8617a60dSAndroid Build Coastguard Worker 	len = flashrom_flash_getsize(flashctx);
86*8617a60dSAndroid Build Coastguard Worker 	if (!len) {
87*8617a60dSAndroid Build Coastguard Worker 		ERROR("Chip found had zero length, probing probably failed.\n");
88*8617a60dSAndroid Build Coastguard Worker 		r = -1;
89*8617a60dSAndroid Build Coastguard Worker 		goto err_probe;
90*8617a60dSAndroid Build Coastguard Worker 	}
91*8617a60dSAndroid Build Coastguard Worker 
92*8617a60dSAndroid Build Coastguard Worker 	flashrom_flag_set(flashctx, FLASHROM_FLAG_SKIP_UNREADABLE_REGIONS, true);
93*8617a60dSAndroid Build Coastguard Worker 
94*8617a60dSAndroid Build Coastguard Worker 	if (regions_len) {
95*8617a60dSAndroid Build Coastguard Worker 		int i;
96*8617a60dSAndroid Build Coastguard Worker 		r = flashrom_layout_read_fmap_from_rom(
97*8617a60dSAndroid Build Coastguard Worker 			&layout, flashctx, 0, len);
98*8617a60dSAndroid Build Coastguard Worker 		if (r > 0) {
99*8617a60dSAndroid Build Coastguard Worker 			ERROR("could not read fmap from rom, r=%d\n", r);
100*8617a60dSAndroid Build Coastguard Worker 			r = -1;
101*8617a60dSAndroid Build Coastguard Worker 			goto err_cleanup;
102*8617a60dSAndroid Build Coastguard Worker 		}
103*8617a60dSAndroid Build Coastguard Worker 		for (i = 0; i < regions_len; i++) {
104*8617a60dSAndroid Build Coastguard Worker 			// empty region causes seg fault in API.
105*8617a60dSAndroid Build Coastguard Worker 			r |= flashrom_layout_include_region(layout, regions[i]);
106*8617a60dSAndroid Build Coastguard Worker 			if (r > 0) {
107*8617a60dSAndroid Build Coastguard Worker 				ERROR("could not include region = '%s'\n",
108*8617a60dSAndroid Build Coastguard Worker 				      regions[i]);
109*8617a60dSAndroid Build Coastguard Worker 				r = -1;
110*8617a60dSAndroid Build Coastguard Worker 				goto err_cleanup;
111*8617a60dSAndroid Build Coastguard Worker 			}
112*8617a60dSAndroid Build Coastguard Worker 		}
113*8617a60dSAndroid Build Coastguard Worker 		flashrom_layout_set(flashctx, layout);
114*8617a60dSAndroid Build Coastguard Worker 	}
115*8617a60dSAndroid Build Coastguard Worker 
116*8617a60dSAndroid Build Coastguard Worker 	image->data = calloc(1, len);
117*8617a60dSAndroid Build Coastguard Worker 	image->size = len;
118*8617a60dSAndroid Build Coastguard Worker 	image->file_name = strdup("<sys-flash>");
119*8617a60dSAndroid Build Coastguard Worker 
120*8617a60dSAndroid Build Coastguard Worker 	r |= flashrom_image_read(flashctx, image->data, len);
121*8617a60dSAndroid Build Coastguard Worker 
122*8617a60dSAndroid Build Coastguard Worker 	if (r == 0 && regions_len)
123*8617a60dSAndroid Build Coastguard Worker 		r |= flashrom_layout_get_region_range(layout, regions[0],
124*8617a60dSAndroid Build Coastguard Worker 						      region_start, region_len);
125*8617a60dSAndroid Build Coastguard Worker 
126*8617a60dSAndroid Build Coastguard Worker err_cleanup:
127*8617a60dSAndroid Build Coastguard Worker 	flashrom_layout_release(layout);
128*8617a60dSAndroid Build Coastguard Worker 	flashrom_flash_release(flashctx);
129*8617a60dSAndroid Build Coastguard Worker 
130*8617a60dSAndroid Build Coastguard Worker err_probe:
131*8617a60dSAndroid Build Coastguard Worker 	r |= flashrom_programmer_shutdown(prog);
132*8617a60dSAndroid Build Coastguard Worker 
133*8617a60dSAndroid Build Coastguard Worker err_init:
134*8617a60dSAndroid Build Coastguard Worker 	free(tmp);
135*8617a60dSAndroid Build Coastguard Worker 	return r;
136*8617a60dSAndroid Build Coastguard Worker }
137*8617a60dSAndroid Build Coastguard Worker 
flashrom_read_image(struct firmware_image * image,const char * const regions[],const size_t regions_len,int verbosity)138*8617a60dSAndroid Build Coastguard Worker int flashrom_read_image(struct firmware_image *image,
139*8617a60dSAndroid Build Coastguard Worker 			const char * const regions[],
140*8617a60dSAndroid Build Coastguard Worker 			const size_t regions_len,
141*8617a60dSAndroid Build Coastguard Worker 			int verbosity)
142*8617a60dSAndroid Build Coastguard Worker {
143*8617a60dSAndroid Build Coastguard Worker 	unsigned int start, len;
144*8617a60dSAndroid Build Coastguard Worker 	return flashrom_read_image_impl(image, regions, regions_len, &start,
145*8617a60dSAndroid Build Coastguard Worker 					&len, verbosity);
146*8617a60dSAndroid Build Coastguard Worker }
147*8617a60dSAndroid Build Coastguard Worker 
flashrom_read_region(struct firmware_image * image,const char * region,int verbosity)148*8617a60dSAndroid Build Coastguard Worker int flashrom_read_region(struct firmware_image *image, const char *region,
149*8617a60dSAndroid Build Coastguard Worker 			 int verbosity)
150*8617a60dSAndroid Build Coastguard Worker {
151*8617a60dSAndroid Build Coastguard Worker 	const char * const regions[] = {region};
152*8617a60dSAndroid Build Coastguard Worker 	unsigned int start, len;
153*8617a60dSAndroid Build Coastguard Worker 	int r = flashrom_read_image_impl(image, regions, ARRAY_SIZE(regions),
154*8617a60dSAndroid Build Coastguard Worker 					 &start, &len, verbosity);
155*8617a60dSAndroid Build Coastguard Worker 	if (r != 0)
156*8617a60dSAndroid Build Coastguard Worker 		return r;
157*8617a60dSAndroid Build Coastguard Worker 
158*8617a60dSAndroid Build Coastguard Worker 	memmove(image->data, image->data + start, len);
159*8617a60dSAndroid Build Coastguard Worker 	image->size = len;
160*8617a60dSAndroid Build Coastguard Worker 	return 0;
161*8617a60dSAndroid Build Coastguard Worker }
162*8617a60dSAndroid Build Coastguard Worker 
flashrom_write_image(const struct firmware_image * image,const char * const regions[],const size_t regions_len,const struct firmware_image * diff_image,int do_verify,int verbosity)163*8617a60dSAndroid Build Coastguard Worker int flashrom_write_image(const struct firmware_image *image,
164*8617a60dSAndroid Build Coastguard Worker 			const char * const regions[],
165*8617a60dSAndroid Build Coastguard Worker 			const size_t regions_len,
166*8617a60dSAndroid Build Coastguard Worker 			const struct firmware_image *diff_image,
167*8617a60dSAndroid Build Coastguard Worker 			int do_verify, int verbosity)
168*8617a60dSAndroid Build Coastguard Worker {
169*8617a60dSAndroid Build Coastguard Worker 	int r = 0;
170*8617a60dSAndroid Build Coastguard Worker 	size_t len = 0;
171*8617a60dSAndroid Build Coastguard Worker 
172*8617a60dSAndroid Build Coastguard Worker 	g_verbose_screen = (verbosity == -1) ? FLASHROM_MSG_INFO : verbosity;
173*8617a60dSAndroid Build Coastguard Worker 
174*8617a60dSAndroid Build Coastguard Worker 	char *programmer, *params;
175*8617a60dSAndroid Build Coastguard Worker 	char *tmp = flashrom_extract_params(image->programmer, &programmer, &params);
176*8617a60dSAndroid Build Coastguard Worker 
177*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_programmer *prog = NULL;
178*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_flashctx *flashctx = NULL;
179*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_layout *layout = NULL;
180*8617a60dSAndroid Build Coastguard Worker 
181*8617a60dSAndroid Build Coastguard Worker 	flashrom_set_log_callback((flashrom_log_callback *)&flashrom_print_cb);
182*8617a60dSAndroid Build Coastguard Worker 
183*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_init(1)
184*8617a60dSAndroid Build Coastguard Worker 		|| flashrom_programmer_init(&prog, programmer, params)) {
185*8617a60dSAndroid Build Coastguard Worker 		r = -1;
186*8617a60dSAndroid Build Coastguard Worker 		goto err_init;
187*8617a60dSAndroid Build Coastguard Worker 	}
188*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_flash_probe(&flashctx, prog, NULL)) {
189*8617a60dSAndroid Build Coastguard Worker 		r = -1;
190*8617a60dSAndroid Build Coastguard Worker 		goto err_probe;
191*8617a60dSAndroid Build Coastguard Worker 	}
192*8617a60dSAndroid Build Coastguard Worker 
193*8617a60dSAndroid Build Coastguard Worker 	len = flashrom_flash_getsize(flashctx);
194*8617a60dSAndroid Build Coastguard Worker 	if (!len) {
195*8617a60dSAndroid Build Coastguard Worker 		ERROR("Chip found had zero length, probing probably failed.\n");
196*8617a60dSAndroid Build Coastguard Worker 		r = -1;
197*8617a60dSAndroid Build Coastguard Worker 		goto err_cleanup;
198*8617a60dSAndroid Build Coastguard Worker 	}
199*8617a60dSAndroid Build Coastguard Worker 
200*8617a60dSAndroid Build Coastguard Worker 	if (diff_image) {
201*8617a60dSAndroid Build Coastguard Worker 		if (diff_image->size != image->size) {
202*8617a60dSAndroid Build Coastguard Worker 			ERROR("diff_image->size != image->size");
203*8617a60dSAndroid Build Coastguard Worker 			r = -1;
204*8617a60dSAndroid Build Coastguard Worker 			goto err_cleanup;
205*8617a60dSAndroid Build Coastguard Worker 		}
206*8617a60dSAndroid Build Coastguard Worker 	}
207*8617a60dSAndroid Build Coastguard Worker 
208*8617a60dSAndroid Build Coastguard Worker 	/* Must occur before attempting to read FMAP from SPI flash. */
209*8617a60dSAndroid Build Coastguard Worker 	flashrom_flag_set(flashctx, FLASHROM_FLAG_SKIP_UNREADABLE_REGIONS, true);
210*8617a60dSAndroid Build Coastguard Worker 
211*8617a60dSAndroid Build Coastguard Worker 	if (regions_len) {
212*8617a60dSAndroid Build Coastguard Worker 		int i;
213*8617a60dSAndroid Build Coastguard Worker 		r = flashrom_layout_read_fmap_from_buffer(
214*8617a60dSAndroid Build Coastguard Worker 			&layout, flashctx, (const uint8_t *)image->data,
215*8617a60dSAndroid Build Coastguard Worker 			image->size);
216*8617a60dSAndroid Build Coastguard Worker 		if (r > 0) {
217*8617a60dSAndroid Build Coastguard Worker 			WARN("could not read fmap from image, r=%d, "
218*8617a60dSAndroid Build Coastguard Worker 				"falling back to read from rom\n", r);
219*8617a60dSAndroid Build Coastguard Worker 			r = flashrom_layout_read_fmap_from_rom(
220*8617a60dSAndroid Build Coastguard Worker 				&layout, flashctx, 0, len);
221*8617a60dSAndroid Build Coastguard Worker 			if (r > 0) {
222*8617a60dSAndroid Build Coastguard Worker 				ERROR("could not read fmap from rom, r=%d\n", r);
223*8617a60dSAndroid Build Coastguard Worker 				r = -1;
224*8617a60dSAndroid Build Coastguard Worker 				goto err_cleanup;
225*8617a60dSAndroid Build Coastguard Worker 			}
226*8617a60dSAndroid Build Coastguard Worker 		}
227*8617a60dSAndroid Build Coastguard Worker 		for (i = 0; i < regions_len; i++) {
228*8617a60dSAndroid Build Coastguard Worker 			INFO(" including region '%s'\n", regions[i]);
229*8617a60dSAndroid Build Coastguard Worker 			// empty region causes seg fault in API.
230*8617a60dSAndroid Build Coastguard Worker 			r |= flashrom_layout_include_region(layout, regions[i]);
231*8617a60dSAndroid Build Coastguard Worker 			if (r > 0) {
232*8617a60dSAndroid Build Coastguard Worker 				ERROR("could not include region = '%s'\n",
233*8617a60dSAndroid Build Coastguard Worker 				      regions[i]);
234*8617a60dSAndroid Build Coastguard Worker 				r = -1;
235*8617a60dSAndroid Build Coastguard Worker 				goto err_cleanup;
236*8617a60dSAndroid Build Coastguard Worker 			}
237*8617a60dSAndroid Build Coastguard Worker 		}
238*8617a60dSAndroid Build Coastguard Worker 		flashrom_layout_set(flashctx, layout);
239*8617a60dSAndroid Build Coastguard Worker 	} else if (image->size != len) {
240*8617a60dSAndroid Build Coastguard Worker 		r = -1;
241*8617a60dSAndroid Build Coastguard Worker 		goto err_cleanup;
242*8617a60dSAndroid Build Coastguard Worker 	}
243*8617a60dSAndroid Build Coastguard Worker 
244*8617a60dSAndroid Build Coastguard Worker 	flashrom_flag_set(flashctx, FLASHROM_FLAG_SKIP_UNWRITABLE_REGIONS, true);
245*8617a60dSAndroid Build Coastguard Worker 	flashrom_flag_set(flashctx, FLASHROM_FLAG_VERIFY_WHOLE_CHIP, false);
246*8617a60dSAndroid Build Coastguard Worker 	flashrom_flag_set(flashctx, FLASHROM_FLAG_VERIFY_AFTER_WRITE,
247*8617a60dSAndroid Build Coastguard Worker 			  do_verify);
248*8617a60dSAndroid Build Coastguard Worker 
249*8617a60dSAndroid Build Coastguard Worker 	r |= flashrom_image_write(flashctx, image->data, image->size,
250*8617a60dSAndroid Build Coastguard Worker 				  diff_image ? diff_image->data : NULL);
251*8617a60dSAndroid Build Coastguard Worker 
252*8617a60dSAndroid Build Coastguard Worker err_cleanup:
253*8617a60dSAndroid Build Coastguard Worker 	flashrom_layout_release(layout);
254*8617a60dSAndroid Build Coastguard Worker 	flashrom_flash_release(flashctx);
255*8617a60dSAndroid Build Coastguard Worker 
256*8617a60dSAndroid Build Coastguard Worker err_probe:
257*8617a60dSAndroid Build Coastguard Worker 	r |= flashrom_programmer_shutdown(prog);
258*8617a60dSAndroid Build Coastguard Worker 
259*8617a60dSAndroid Build Coastguard Worker err_init:
260*8617a60dSAndroid Build Coastguard Worker 	free(tmp);
261*8617a60dSAndroid Build Coastguard Worker 	return r;
262*8617a60dSAndroid Build Coastguard Worker }
263*8617a60dSAndroid Build Coastguard Worker 
flashrom_get_wp(const char * prog_with_params,bool * wp_mode,uint32_t * wp_start,uint32_t * wp_len,int verbosity)264*8617a60dSAndroid Build Coastguard Worker int flashrom_get_wp(const char *prog_with_params, bool *wp_mode,
265*8617a60dSAndroid Build Coastguard Worker 		    uint32_t *wp_start, uint32_t *wp_len, int verbosity)
266*8617a60dSAndroid Build Coastguard Worker {
267*8617a60dSAndroid Build Coastguard Worker 	int ret = -1;
268*8617a60dSAndroid Build Coastguard Worker 
269*8617a60dSAndroid Build Coastguard Worker 	g_verbose_screen = (verbosity == -1) ? FLASHROM_MSG_INFO : verbosity;
270*8617a60dSAndroid Build Coastguard Worker 
271*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_programmer *prog = NULL;
272*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_flashctx *flashctx = NULL;
273*8617a60dSAndroid Build Coastguard Worker 
274*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_wp_cfg *cfg = NULL;
275*8617a60dSAndroid Build Coastguard Worker 
276*8617a60dSAndroid Build Coastguard Worker 	char *programmer, *params;
277*8617a60dSAndroid Build Coastguard Worker 	char *tmp = flashrom_extract_params(prog_with_params, &programmer,
278*8617a60dSAndroid Build Coastguard Worker 					    &params);
279*8617a60dSAndroid Build Coastguard Worker 
280*8617a60dSAndroid Build Coastguard Worker 	flashrom_set_log_callback((flashrom_log_callback *)&flashrom_print_cb);
281*8617a60dSAndroid Build Coastguard Worker 
282*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_init(1)
283*8617a60dSAndroid Build Coastguard Worker 		|| flashrom_programmer_init(&prog, programmer, params))
284*8617a60dSAndroid Build Coastguard Worker 		goto err_init;
285*8617a60dSAndroid Build Coastguard Worker 
286*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_flash_probe(&flashctx, prog, NULL))
287*8617a60dSAndroid Build Coastguard Worker 		goto err_probe;
288*8617a60dSAndroid Build Coastguard Worker 
289*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_wp_cfg_new(&cfg) != FLASHROM_WP_OK)
290*8617a60dSAndroid Build Coastguard Worker 		goto err_cleanup;
291*8617a60dSAndroid Build Coastguard Worker 
292*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_wp_read_cfg(cfg, flashctx) != FLASHROM_WP_OK)
293*8617a60dSAndroid Build Coastguard Worker 		goto err_read_cfg;
294*8617a60dSAndroid Build Coastguard Worker 
295*8617a60dSAndroid Build Coastguard Worker 	/* size_t tmp variables for libflashrom compatibility */
296*8617a60dSAndroid Build Coastguard Worker 	size_t tmp_wp_start, tmp_wp_len;
297*8617a60dSAndroid Build Coastguard Worker 	flashrom_wp_get_range(&tmp_wp_start, &tmp_wp_len, cfg);
298*8617a60dSAndroid Build Coastguard Worker 
299*8617a60dSAndroid Build Coastguard Worker 	if (wp_start != NULL)
300*8617a60dSAndroid Build Coastguard Worker 		*wp_start = tmp_wp_start;
301*8617a60dSAndroid Build Coastguard Worker 	if (wp_start != NULL)
302*8617a60dSAndroid Build Coastguard Worker 		*wp_len = tmp_wp_len;
303*8617a60dSAndroid Build Coastguard Worker 	if (wp_mode != NULL)
304*8617a60dSAndroid Build Coastguard Worker 		*wp_mode = flashrom_wp_get_mode(cfg) != FLASHROM_WP_MODE_DISABLED;
305*8617a60dSAndroid Build Coastguard Worker 
306*8617a60dSAndroid Build Coastguard Worker 	ret = 0;
307*8617a60dSAndroid Build Coastguard Worker 
308*8617a60dSAndroid Build Coastguard Worker err_read_cfg:
309*8617a60dSAndroid Build Coastguard Worker 	flashrom_wp_cfg_release(cfg);
310*8617a60dSAndroid Build Coastguard Worker 
311*8617a60dSAndroid Build Coastguard Worker err_cleanup:
312*8617a60dSAndroid Build Coastguard Worker 	flashrom_flash_release(flashctx);
313*8617a60dSAndroid Build Coastguard Worker 
314*8617a60dSAndroid Build Coastguard Worker err_probe:
315*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_programmer_shutdown(prog))
316*8617a60dSAndroid Build Coastguard Worker 		ret = -1;
317*8617a60dSAndroid Build Coastguard Worker 
318*8617a60dSAndroid Build Coastguard Worker err_init:
319*8617a60dSAndroid Build Coastguard Worker 	free(tmp);
320*8617a60dSAndroid Build Coastguard Worker 
321*8617a60dSAndroid Build Coastguard Worker 	return ret;
322*8617a60dSAndroid Build Coastguard Worker }
323*8617a60dSAndroid Build Coastguard Worker 
flashrom_set_wp(const char * prog_with_params,bool wp_mode,uint32_t wp_start,uint32_t wp_len,int verbosity)324*8617a60dSAndroid Build Coastguard Worker int flashrom_set_wp(const char *prog_with_params, bool wp_mode,
325*8617a60dSAndroid Build Coastguard Worker 		    uint32_t wp_start, uint32_t wp_len, int verbosity)
326*8617a60dSAndroid Build Coastguard Worker {
327*8617a60dSAndroid Build Coastguard Worker 	int ret = 1;
328*8617a60dSAndroid Build Coastguard Worker 
329*8617a60dSAndroid Build Coastguard Worker 	g_verbose_screen = (verbosity == -1) ? FLASHROM_MSG_INFO : verbosity;
330*8617a60dSAndroid Build Coastguard Worker 
331*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_programmer *prog = NULL;
332*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_flashctx *flashctx = NULL;
333*8617a60dSAndroid Build Coastguard Worker 
334*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_wp_cfg *cfg = NULL;
335*8617a60dSAndroid Build Coastguard Worker 
336*8617a60dSAndroid Build Coastguard Worker 	char *programmer, *params;
337*8617a60dSAndroid Build Coastguard Worker 	char *tmp = flashrom_extract_params(prog_with_params, &programmer,
338*8617a60dSAndroid Build Coastguard Worker 					    &params);
339*8617a60dSAndroid Build Coastguard Worker 
340*8617a60dSAndroid Build Coastguard Worker 	flashrom_set_log_callback((flashrom_log_callback *)&flashrom_print_cb);
341*8617a60dSAndroid Build Coastguard Worker 
342*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_init(1)
343*8617a60dSAndroid Build Coastguard Worker 		|| flashrom_programmer_init(&prog, programmer, params))
344*8617a60dSAndroid Build Coastguard Worker 		goto err_init;
345*8617a60dSAndroid Build Coastguard Worker 
346*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_flash_probe(&flashctx, prog, NULL))
347*8617a60dSAndroid Build Coastguard Worker 		goto err_probe;
348*8617a60dSAndroid Build Coastguard Worker 
349*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_wp_cfg_new(&cfg) != FLASHROM_WP_OK)
350*8617a60dSAndroid Build Coastguard Worker 		goto err_cleanup;
351*8617a60dSAndroid Build Coastguard Worker 
352*8617a60dSAndroid Build Coastguard Worker 	enum flashrom_wp_mode mode = wp_mode ?
353*8617a60dSAndroid Build Coastguard Worker 			FLASHROM_WP_MODE_HARDWARE : FLASHROM_WP_MODE_DISABLED;
354*8617a60dSAndroid Build Coastguard Worker 	flashrom_wp_set_mode(cfg, mode);
355*8617a60dSAndroid Build Coastguard Worker 	flashrom_wp_set_range(cfg, wp_start, wp_len);
356*8617a60dSAndroid Build Coastguard Worker 
357*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_wp_write_cfg(flashctx, cfg) != FLASHROM_WP_OK)
358*8617a60dSAndroid Build Coastguard Worker 		goto err_write_cfg;
359*8617a60dSAndroid Build Coastguard Worker 
360*8617a60dSAndroid Build Coastguard Worker 	ret = 0;
361*8617a60dSAndroid Build Coastguard Worker 
362*8617a60dSAndroid Build Coastguard Worker err_write_cfg:
363*8617a60dSAndroid Build Coastguard Worker 	flashrom_wp_cfg_release(cfg);
364*8617a60dSAndroid Build Coastguard Worker 
365*8617a60dSAndroid Build Coastguard Worker err_cleanup:
366*8617a60dSAndroid Build Coastguard Worker 	flashrom_flash_release(flashctx);
367*8617a60dSAndroid Build Coastguard Worker 
368*8617a60dSAndroid Build Coastguard Worker err_probe:
369*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_programmer_shutdown(prog))
370*8617a60dSAndroid Build Coastguard Worker 		ret = 1;
371*8617a60dSAndroid Build Coastguard Worker 
372*8617a60dSAndroid Build Coastguard Worker err_init:
373*8617a60dSAndroid Build Coastguard Worker 	free(tmp);
374*8617a60dSAndroid Build Coastguard Worker 
375*8617a60dSAndroid Build Coastguard Worker 	return ret;
376*8617a60dSAndroid Build Coastguard Worker }
377*8617a60dSAndroid Build Coastguard Worker 
flashrom_get_info(const char * prog_with_params,char ** vendor,char ** name,uint32_t * vid,uint32_t * pid,uint32_t * flash_len,int verbosity)378*8617a60dSAndroid Build Coastguard Worker int flashrom_get_info(const char *prog_with_params,
379*8617a60dSAndroid Build Coastguard Worker 		      char **vendor, char **name,
380*8617a60dSAndroid Build Coastguard Worker 		      uint32_t *vid, uint32_t *pid,
381*8617a60dSAndroid Build Coastguard Worker 		      uint32_t *flash_len, int verbosity)
382*8617a60dSAndroid Build Coastguard Worker {
383*8617a60dSAndroid Build Coastguard Worker 	int r = 0;
384*8617a60dSAndroid Build Coastguard Worker 
385*8617a60dSAndroid Build Coastguard Worker 	g_verbose_screen = (verbosity == -1) ? FLASHROM_MSG_INFO : verbosity;
386*8617a60dSAndroid Build Coastguard Worker 
387*8617a60dSAndroid Build Coastguard Worker 	char *programmer, *params;
388*8617a60dSAndroid Build Coastguard Worker 	char *tmp = flashrom_extract_params(prog_with_params,
389*8617a60dSAndroid Build Coastguard Worker 					    &programmer, &params);
390*8617a60dSAndroid Build Coastguard Worker 
391*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_programmer *prog = NULL;
392*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_flashctx *flashctx = NULL;
393*8617a60dSAndroid Build Coastguard Worker 
394*8617a60dSAndroid Build Coastguard Worker 	flashrom_set_log_callback((flashrom_log_callback *)&flashrom_print_cb);
395*8617a60dSAndroid Build Coastguard Worker 
396*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_init(1) ||
397*8617a60dSAndroid Build Coastguard Worker 	    flashrom_programmer_init(&prog, programmer, params)) {
398*8617a60dSAndroid Build Coastguard Worker 		r = -1;
399*8617a60dSAndroid Build Coastguard Worker 		goto err_init;
400*8617a60dSAndroid Build Coastguard Worker 	}
401*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_flash_probe(&flashctx, prog, NULL)) {
402*8617a60dSAndroid Build Coastguard Worker 		r = -1;
403*8617a60dSAndroid Build Coastguard Worker 		goto err_probe;
404*8617a60dSAndroid Build Coastguard Worker 	}
405*8617a60dSAndroid Build Coastguard Worker 
406*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_flashchip_info info;
407*8617a60dSAndroid Build Coastguard Worker 	flashrom_flash_getinfo(flashctx, &info);
408*8617a60dSAndroid Build Coastguard Worker 
409*8617a60dSAndroid Build Coastguard Worker 	*vendor = strdup(info.vendor);
410*8617a60dSAndroid Build Coastguard Worker 	*name = strdup(info.name);
411*8617a60dSAndroid Build Coastguard Worker 	*vid = info.manufacture_id;
412*8617a60dSAndroid Build Coastguard Worker 	*pid = info.model_id;
413*8617a60dSAndroid Build Coastguard Worker 	*flash_len = info.total_size * 1024;
414*8617a60dSAndroid Build Coastguard Worker 
415*8617a60dSAndroid Build Coastguard Worker 	flashrom_flash_release(flashctx);
416*8617a60dSAndroid Build Coastguard Worker 
417*8617a60dSAndroid Build Coastguard Worker err_probe:
418*8617a60dSAndroid Build Coastguard Worker 	r |= flashrom_programmer_shutdown(prog);
419*8617a60dSAndroid Build Coastguard Worker 
420*8617a60dSAndroid Build Coastguard Worker err_init:
421*8617a60dSAndroid Build Coastguard Worker 	free(tmp);
422*8617a60dSAndroid Build Coastguard Worker 	return r;
423*8617a60dSAndroid Build Coastguard Worker }
424*8617a60dSAndroid Build Coastguard Worker 
flashrom_get_size(const char * prog_with_params,uint32_t * flash_len,int verbosity)425*8617a60dSAndroid Build Coastguard Worker int flashrom_get_size(const char *prog_with_params,
426*8617a60dSAndroid Build Coastguard Worker 		      uint32_t *flash_len, int verbosity)
427*8617a60dSAndroid Build Coastguard Worker {
428*8617a60dSAndroid Build Coastguard Worker 	int r = 0;
429*8617a60dSAndroid Build Coastguard Worker 
430*8617a60dSAndroid Build Coastguard Worker 	g_verbose_screen = (verbosity == -1) ? FLASHROM_MSG_INFO : verbosity;
431*8617a60dSAndroid Build Coastguard Worker 
432*8617a60dSAndroid Build Coastguard Worker 	char *programmer, *params;
433*8617a60dSAndroid Build Coastguard Worker 	char *tmp = flashrom_extract_params(prog_with_params,
434*8617a60dSAndroid Build Coastguard Worker 					    &programmer, &params);
435*8617a60dSAndroid Build Coastguard Worker 
436*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_programmer *prog = NULL;
437*8617a60dSAndroid Build Coastguard Worker 	struct flashrom_flashctx *flashctx = NULL;
438*8617a60dSAndroid Build Coastguard Worker 
439*8617a60dSAndroid Build Coastguard Worker 	flashrom_set_log_callback((flashrom_log_callback *)&flashrom_print_cb);
440*8617a60dSAndroid Build Coastguard Worker 
441*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_init(1) ||
442*8617a60dSAndroid Build Coastguard Worker 	    flashrom_programmer_init(&prog, programmer, params)) {
443*8617a60dSAndroid Build Coastguard Worker 		r = -1;
444*8617a60dSAndroid Build Coastguard Worker 		goto err_init;
445*8617a60dSAndroid Build Coastguard Worker 	}
446*8617a60dSAndroid Build Coastguard Worker 	if (flashrom_flash_probe(&flashctx, prog, NULL)) {
447*8617a60dSAndroid Build Coastguard Worker 		r = -1;
448*8617a60dSAndroid Build Coastguard Worker 		goto err_probe;
449*8617a60dSAndroid Build Coastguard Worker 	}
450*8617a60dSAndroid Build Coastguard Worker 
451*8617a60dSAndroid Build Coastguard Worker 	*flash_len = flashrom_flash_getsize(flashctx);
452*8617a60dSAndroid Build Coastguard Worker 
453*8617a60dSAndroid Build Coastguard Worker 	flashrom_flash_release(flashctx);
454*8617a60dSAndroid Build Coastguard Worker 
455*8617a60dSAndroid Build Coastguard Worker err_probe:
456*8617a60dSAndroid Build Coastguard Worker 	r |= flashrom_programmer_shutdown(prog);
457*8617a60dSAndroid Build Coastguard Worker 
458*8617a60dSAndroid Build Coastguard Worker err_init:
459*8617a60dSAndroid Build Coastguard Worker 	free(tmp);
460*8617a60dSAndroid Build Coastguard Worker 	return r;
461*8617a60dSAndroid Build Coastguard Worker }
462