xref: /aosp_15_r20/external/flashrom/tests/chip.c (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
1*0d6140beSAndroid Build Coastguard Worker /*
2*0d6140beSAndroid Build Coastguard Worker  * This file is part of the flashrom project.
3*0d6140beSAndroid Build Coastguard Worker  *
4*0d6140beSAndroid Build Coastguard Worker  * Copyright 2021 Google LLC
5*0d6140beSAndroid Build Coastguard Worker  *
6*0d6140beSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify
7*0d6140beSAndroid Build Coastguard Worker  * it under the terms of the GNU General Public License as published by
8*0d6140beSAndroid Build Coastguard Worker  * the Free Software Foundation; version 2 of the License.
9*0d6140beSAndroid Build Coastguard Worker  *
10*0d6140beSAndroid Build Coastguard Worker  * This program is distributed in the hope that it will be useful,
11*0d6140beSAndroid Build Coastguard Worker  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*0d6140beSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*0d6140beSAndroid Build Coastguard Worker  * GNU General Public License for more details.
14*0d6140beSAndroid Build Coastguard Worker  *
15*0d6140beSAndroid Build Coastguard Worker  * This file contains tests for operations on flash chip.
16*0d6140beSAndroid Build Coastguard Worker  *
17*0d6140beSAndroid Build Coastguard Worker  * Two flash chip test variants are used:
18*0d6140beSAndroid Build Coastguard Worker  *
19*0d6140beSAndroid Build Coastguard Worker  * 1) Mock chip state backed by `g_chip_state`.
20*0d6140beSAndroid Build Coastguard Worker  * Example of test: erase_chip_test_success.
21*0d6140beSAndroid Build Coastguard Worker  *
22*0d6140beSAndroid Build Coastguard Worker  * 2) Mock chip operations backed by `dummyflasher` emulation.
23*0d6140beSAndroid Build Coastguard Worker  * Dummyflasher controls chip state and emulates read/write/erase.
24*0d6140beSAndroid Build Coastguard Worker  * `g_chip_state` is NOT used for this type of tests.
25*0d6140beSAndroid Build Coastguard Worker  * Example of test: erase_chip_with_dummyflasher_test_success.
26*0d6140beSAndroid Build Coastguard Worker  */
27*0d6140beSAndroid Build Coastguard Worker 
28*0d6140beSAndroid Build Coastguard Worker #include <include/test.h>
29*0d6140beSAndroid Build Coastguard Worker #include <stdio.h>
30*0d6140beSAndroid Build Coastguard Worker #include <stdlib.h>
31*0d6140beSAndroid Build Coastguard Worker #include <string.h>
32*0d6140beSAndroid Build Coastguard Worker 
33*0d6140beSAndroid Build Coastguard Worker #include "tests.h"
34*0d6140beSAndroid Build Coastguard Worker #include "chipdrivers.h"
35*0d6140beSAndroid Build Coastguard Worker #include "flash.h"
36*0d6140beSAndroid Build Coastguard Worker #include "io_mock.h"
37*0d6140beSAndroid Build Coastguard Worker #include "libflashrom.h"
38*0d6140beSAndroid Build Coastguard Worker #include "programmer.h"
39*0d6140beSAndroid Build Coastguard Worker 
40*0d6140beSAndroid Build Coastguard Worker #define MOCK_CHIP_SIZE (8*MiB)
41*0d6140beSAndroid Build Coastguard Worker #define MOCK_CHIP_CONTENT 0xCC /* 0x00 is a zeroed heap and 0xFF is an erased chip. */
42*0d6140beSAndroid Build Coastguard Worker 
43*0d6140beSAndroid Build Coastguard Worker static struct {
44*0d6140beSAndroid Build Coastguard Worker 	uint8_t buf[MOCK_CHIP_SIZE]; /* buffer of total size of chip, to emulate a chip */
45*0d6140beSAndroid Build Coastguard Worker } g_chip_state = {
46*0d6140beSAndroid Build Coastguard Worker 	.buf = { 0 },
47*0d6140beSAndroid Build Coastguard Worker };
48*0d6140beSAndroid Build Coastguard Worker 
read_chip(struct flashctx * flash,uint8_t * buf,unsigned int start,unsigned int len)49*0d6140beSAndroid Build Coastguard Worker static int read_chip(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
50*0d6140beSAndroid Build Coastguard Worker {
51*0d6140beSAndroid Build Coastguard Worker 	printf("Read chip called with start=0x%x, len=0x%x\n", start, len);
52*0d6140beSAndroid Build Coastguard Worker 
53*0d6140beSAndroid Build Coastguard Worker 	assert_in_range(start + len, 0, MOCK_CHIP_SIZE);
54*0d6140beSAndroid Build Coastguard Worker 
55*0d6140beSAndroid Build Coastguard Worker 	memcpy(buf, &g_chip_state.buf[start], len);
56*0d6140beSAndroid Build Coastguard Worker 	return 0;
57*0d6140beSAndroid Build Coastguard Worker }
58*0d6140beSAndroid Build Coastguard Worker 
write_chip(struct flashctx * flash,const uint8_t * buf,unsigned int start,unsigned int len)59*0d6140beSAndroid Build Coastguard Worker static int write_chip(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
60*0d6140beSAndroid Build Coastguard Worker {
61*0d6140beSAndroid Build Coastguard Worker 	printf("Write chip called with start=0x%x, len=0x%x\n", start, len);
62*0d6140beSAndroid Build Coastguard Worker 
63*0d6140beSAndroid Build Coastguard Worker 	assert_in_range(start + len, 0, MOCK_CHIP_SIZE);
64*0d6140beSAndroid Build Coastguard Worker 
65*0d6140beSAndroid Build Coastguard Worker 	memcpy(&g_chip_state.buf[start], buf, len);
66*0d6140beSAndroid Build Coastguard Worker 	return 0;
67*0d6140beSAndroid Build Coastguard Worker }
68*0d6140beSAndroid Build Coastguard Worker 
block_erase_chip(struct flashctx * flash,unsigned int blockaddr,unsigned int blocklen)69*0d6140beSAndroid Build Coastguard Worker static int block_erase_chip(struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen)
70*0d6140beSAndroid Build Coastguard Worker {
71*0d6140beSAndroid Build Coastguard Worker 	printf("Block erase called with blockaddr=0x%x, blocklen=0x%x\n", blockaddr, blocklen);
72*0d6140beSAndroid Build Coastguard Worker 
73*0d6140beSAndroid Build Coastguard Worker 	assert_in_range(blockaddr + blocklen, 0, MOCK_CHIP_SIZE);
74*0d6140beSAndroid Build Coastguard Worker 
75*0d6140beSAndroid Build Coastguard Worker 	memset(&g_chip_state.buf[blockaddr], 0xff, blocklen);
76*0d6140beSAndroid Build Coastguard Worker 	return 0;
77*0d6140beSAndroid Build Coastguard Worker }
78*0d6140beSAndroid Build Coastguard Worker 
setup_chip(struct flashrom_flashctx * flashctx,struct flashrom_layout ** layout,struct flashchip * chip,const char * programmer_param,const struct io_mock * io)79*0d6140beSAndroid Build Coastguard Worker static void setup_chip(struct flashrom_flashctx *flashctx, struct flashrom_layout **layout,
80*0d6140beSAndroid Build Coastguard Worker 		struct flashchip *chip, const char *programmer_param, const struct io_mock *io)
81*0d6140beSAndroid Build Coastguard Worker {
82*0d6140beSAndroid Build Coastguard Worker 	io_mock_register(io);
83*0d6140beSAndroid Build Coastguard Worker 
84*0d6140beSAndroid Build Coastguard Worker 	flashctx->chip = chip;
85*0d6140beSAndroid Build Coastguard Worker 
86*0d6140beSAndroid Build Coastguard Worker 	memset(g_chip_state.buf, MOCK_CHIP_CONTENT, sizeof(g_chip_state.buf));
87*0d6140beSAndroid Build Coastguard Worker 
88*0d6140beSAndroid Build Coastguard Worker 	printf("Creating layout with one included region... ");
89*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_layout_new(layout));
90*0d6140beSAndroid Build Coastguard Worker 	/* One region which covers total size of chip. */
91*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_layout_add_region(*layout, 0, chip->total_size * KiB - 1, "region"));
92*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_layout_include_region(*layout, "region"));
93*0d6140beSAndroid Build Coastguard Worker 
94*0d6140beSAndroid Build Coastguard Worker 	flashrom_layout_set(flashctx, *layout);
95*0d6140beSAndroid Build Coastguard Worker 	printf("done\n");
96*0d6140beSAndroid Build Coastguard Worker 
97*0d6140beSAndroid Build Coastguard Worker 	/*
98*0d6140beSAndroid Build Coastguard Worker 	 * We need some programmer (any), and dummy is a very good one,
99*0d6140beSAndroid Build Coastguard Worker 	 * because it doesn't need any mocking. So no extra complexity
100*0d6140beSAndroid Build Coastguard Worker 	 * from a programmer side, and test can focus on working with the chip.
101*0d6140beSAndroid Build Coastguard Worker 	 */
102*0d6140beSAndroid Build Coastguard Worker 	printf("Dummyflasher initialising with param=\"%s\"... ", programmer_param);
103*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, programmer_init(&programmer_dummy, programmer_param));
104*0d6140beSAndroid Build Coastguard Worker 	/* Assignment below normally happens while probing, but this test is not probing. */
105*0d6140beSAndroid Build Coastguard Worker 	flashctx->mst = &registered_masters[0];
106*0d6140beSAndroid Build Coastguard Worker 	printf("done\n");
107*0d6140beSAndroid Build Coastguard Worker }
108*0d6140beSAndroid Build Coastguard Worker 
teardown(struct flashrom_layout ** layout)109*0d6140beSAndroid Build Coastguard Worker static void teardown(struct flashrom_layout **layout)
110*0d6140beSAndroid Build Coastguard Worker {
111*0d6140beSAndroid Build Coastguard Worker 	printf("Dummyflasher shutdown... ");
112*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, programmer_shutdown());
113*0d6140beSAndroid Build Coastguard Worker 	printf("done\n");
114*0d6140beSAndroid Build Coastguard Worker 
115*0d6140beSAndroid Build Coastguard Worker 	printf("Releasing layout... ");
116*0d6140beSAndroid Build Coastguard Worker 	flashrom_layout_release(*layout);
117*0d6140beSAndroid Build Coastguard Worker 	printf("done\n");
118*0d6140beSAndroid Build Coastguard Worker 
119*0d6140beSAndroid Build Coastguard Worker 	io_mock_register(NULL);
120*0d6140beSAndroid Build Coastguard Worker }
121*0d6140beSAndroid Build Coastguard Worker 
122*0d6140beSAndroid Build Coastguard Worker extern write_func_t *g_test_write_injector;
123*0d6140beSAndroid Build Coastguard Worker extern read_func_t *g_test_read_injector;
124*0d6140beSAndroid Build Coastguard Worker extern erasefunc_t *g_test_erase_injector;
125*0d6140beSAndroid Build Coastguard Worker 
126*0d6140beSAndroid Build Coastguard Worker static const struct flashchip chip_8MiB = {
127*0d6140beSAndroid Build Coastguard Worker 	.vendor		= "aklm",
128*0d6140beSAndroid Build Coastguard Worker 	.total_size	= MOCK_CHIP_SIZE / KiB,
129*0d6140beSAndroid Build Coastguard Worker 	.tested		= TEST_OK_PREW,
130*0d6140beSAndroid Build Coastguard Worker 	.read		= TEST_READ_INJECTOR,
131*0d6140beSAndroid Build Coastguard Worker 	.write		= TEST_WRITE_INJECTOR,
132*0d6140beSAndroid Build Coastguard Worker 	.block_erasers	=
133*0d6140beSAndroid Build Coastguard Worker 	{{
134*0d6140beSAndroid Build Coastguard Worker 		 /* All blocks within total size of the chip. */
135*0d6140beSAndroid Build Coastguard Worker 		.eraseblocks = { {2 * MiB, 4} },
136*0d6140beSAndroid Build Coastguard Worker 		.block_erase = TEST_ERASE_INJECTOR,
137*0d6140beSAndroid Build Coastguard Worker 	 }},
138*0d6140beSAndroid Build Coastguard Worker };
139*0d6140beSAndroid Build Coastguard Worker 
140*0d6140beSAndroid Build Coastguard Worker /* Chip expected to be processed with dummyflasher, so using real op functions. */
141*0d6140beSAndroid Build Coastguard Worker static const struct flashchip chip_no_erase = {
142*0d6140beSAndroid Build Coastguard Worker 	.vendor		= "aklm&dummyflasher",
143*0d6140beSAndroid Build Coastguard Worker 	.total_size	= 16 * 1024,
144*0d6140beSAndroid Build Coastguard Worker 	.tested		= TEST_OK_PREW,
145*0d6140beSAndroid Build Coastguard Worker 	.read		= SPI_CHIP_READ,
146*0d6140beSAndroid Build Coastguard Worker 	.write		= SPI_CHIP_WRITE256,
147*0d6140beSAndroid Build Coastguard Worker 	.page_size	= 256,
148*0d6140beSAndroid Build Coastguard Worker 	.feature_bits   = FEATURE_NO_ERASE | FEATURE_ERASED_ZERO,
149*0d6140beSAndroid Build Coastguard Worker 	.block_erasers  =
150*0d6140beSAndroid Build Coastguard Worker 	{
151*0d6140beSAndroid Build Coastguard Worker 		{
152*0d6140beSAndroid Build Coastguard Worker 			.eraseblocks = { {16 * 1024 * 1024, 1} },
153*0d6140beSAndroid Build Coastguard Worker 			/* Special erase fn for chips without erase capability. */
154*0d6140beSAndroid Build Coastguard Worker 			.block_erase = SPI_BLOCK_ERASE_EMULATION,
155*0d6140beSAndroid Build Coastguard Worker 		}
156*0d6140beSAndroid Build Coastguard Worker 	},
157*0d6140beSAndroid Build Coastguard Worker };
158*0d6140beSAndroid Build Coastguard Worker 
159*0d6140beSAndroid Build Coastguard Worker /* Setup the struct for W25Q128.V, all values come from flashchips.c */
160*0d6140beSAndroid Build Coastguard Worker static const struct flashchip chip_W25Q128_V = {
161*0d6140beSAndroid Build Coastguard Worker 	.vendor		= "aklm&dummyflasher",
162*0d6140beSAndroid Build Coastguard Worker 	.total_size	= 16 * 1024,
163*0d6140beSAndroid Build Coastguard Worker 	.tested		= TEST_OK_PREW,
164*0d6140beSAndroid Build Coastguard Worker 	.read		= SPI_CHIP_READ,
165*0d6140beSAndroid Build Coastguard Worker 	.write		= SPI_CHIP_WRITE256,
166*0d6140beSAndroid Build Coastguard Worker 	.page_size	= 256,
167*0d6140beSAndroid Build Coastguard Worker 	.block_erasers  =
168*0d6140beSAndroid Build Coastguard Worker 	{
169*0d6140beSAndroid Build Coastguard Worker 		{
170*0d6140beSAndroid Build Coastguard Worker 			.eraseblocks = { {4 * 1024, 4096} },
171*0d6140beSAndroid Build Coastguard Worker 			.block_erase = SPI_BLOCK_ERASE_20,
172*0d6140beSAndroid Build Coastguard Worker 		}, {
173*0d6140beSAndroid Build Coastguard Worker 			.eraseblocks = { {32 * 1024, 512} },
174*0d6140beSAndroid Build Coastguard Worker 			.block_erase = SPI_BLOCK_ERASE_52,
175*0d6140beSAndroid Build Coastguard Worker 		}, {
176*0d6140beSAndroid Build Coastguard Worker 			.eraseblocks = { {64 * 1024, 256} },
177*0d6140beSAndroid Build Coastguard Worker 			.block_erase = SPI_BLOCK_ERASE_D8,
178*0d6140beSAndroid Build Coastguard Worker 		}, {
179*0d6140beSAndroid Build Coastguard Worker 			.eraseblocks = { {16 * 1024 * 1024, 1} },
180*0d6140beSAndroid Build Coastguard Worker 			.block_erase = SPI_BLOCK_ERASE_60,
181*0d6140beSAndroid Build Coastguard Worker 		}, {
182*0d6140beSAndroid Build Coastguard Worker 			.eraseblocks = { {16 * 1024 * 1024, 1} },
183*0d6140beSAndroid Build Coastguard Worker 			.block_erase = SPI_BLOCK_ERASE_C7,
184*0d6140beSAndroid Build Coastguard Worker 		}
185*0d6140beSAndroid Build Coastguard Worker 	},
186*0d6140beSAndroid Build Coastguard Worker };
187*0d6140beSAndroid Build Coastguard Worker 
erase_chip_test_success(void ** state)188*0d6140beSAndroid Build Coastguard Worker void erase_chip_test_success(void **state)
189*0d6140beSAndroid Build Coastguard Worker {
190*0d6140beSAndroid Build Coastguard Worker 	(void) state; /* unused */
191*0d6140beSAndroid Build Coastguard Worker 
192*0d6140beSAndroid Build Coastguard Worker 	static struct io_mock_fallback_open_state data = {
193*0d6140beSAndroid Build Coastguard Worker 		.noc	= 0,
194*0d6140beSAndroid Build Coastguard Worker 		.paths	= { SUSPEND_ANNOUNCED_FILE, NULL },
195*0d6140beSAndroid Build Coastguard Worker 	};
196*0d6140beSAndroid Build Coastguard Worker 	const struct io_mock chip_io = {
197*0d6140beSAndroid Build Coastguard Worker 		.fallback_open_state = &data,
198*0d6140beSAndroid Build Coastguard Worker 	};
199*0d6140beSAndroid Build Coastguard Worker 
200*0d6140beSAndroid Build Coastguard Worker 	g_test_write_injector = write_chip;
201*0d6140beSAndroid Build Coastguard Worker 	g_test_read_injector = read_chip;
202*0d6140beSAndroid Build Coastguard Worker 	g_test_erase_injector = block_erase_chip;
203*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_flashctx flashctx = { 0 };
204*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_layout *layout;
205*0d6140beSAndroid Build Coastguard Worker 	struct flashchip mock_chip = chip_8MiB;
206*0d6140beSAndroid Build Coastguard Worker 	const char *param = ""; /* Default values for all params. */
207*0d6140beSAndroid Build Coastguard Worker 
208*0d6140beSAndroid Build Coastguard Worker 	setup_chip(&flashctx, &layout, &mock_chip, param, &chip_io);
209*0d6140beSAndroid Build Coastguard Worker 
210*0d6140beSAndroid Build Coastguard Worker 	printf("Erase chip operation started.\n");
211*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_flash_erase(&flashctx));
212*0d6140beSAndroid Build Coastguard Worker 	printf("Erase chip operation done.\n");
213*0d6140beSAndroid Build Coastguard Worker 
214*0d6140beSAndroid Build Coastguard Worker 	teardown(&layout);
215*0d6140beSAndroid Build Coastguard Worker }
216*0d6140beSAndroid Build Coastguard Worker 
erase_chip_with_dummyflasher_test_success(void ** state)217*0d6140beSAndroid Build Coastguard Worker void erase_chip_with_dummyflasher_test_success(void **state)
218*0d6140beSAndroid Build Coastguard Worker {
219*0d6140beSAndroid Build Coastguard Worker 	(void) state; /* unused */
220*0d6140beSAndroid Build Coastguard Worker 
221*0d6140beSAndroid Build Coastguard Worker 	static struct io_mock_fallback_open_state data = {
222*0d6140beSAndroid Build Coastguard Worker 		.noc	= 0,
223*0d6140beSAndroid Build Coastguard Worker 		.paths	= { NULL },
224*0d6140beSAndroid Build Coastguard Worker 	};
225*0d6140beSAndroid Build Coastguard Worker 	const struct io_mock chip_io = {
226*0d6140beSAndroid Build Coastguard Worker 		.fallback_open_state = &data,
227*0d6140beSAndroid Build Coastguard Worker 	};
228*0d6140beSAndroid Build Coastguard Worker 
229*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_flashctx flashctx = { 0 };
230*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_layout *layout;
231*0d6140beSAndroid Build Coastguard Worker 	struct flashchip mock_chip = chip_W25Q128_V;
232*0d6140beSAndroid Build Coastguard Worker 	/*
233*0d6140beSAndroid Build Coastguard Worker 	 * Dummyflasher is capable to emulate W25Q128.V, so we ask it to do this.
234*0d6140beSAndroid Build Coastguard Worker 	 * Nothing to mock, dummy is taking care of this already.
235*0d6140beSAndroid Build Coastguard Worker 	 */
236*0d6140beSAndroid Build Coastguard Worker 	const char *param_dup = "bus=spi,emulate=W25Q128FV";
237*0d6140beSAndroid Build Coastguard Worker 
238*0d6140beSAndroid Build Coastguard Worker 	setup_chip(&flashctx, &layout, &mock_chip, param_dup, &chip_io);
239*0d6140beSAndroid Build Coastguard Worker 
240*0d6140beSAndroid Build Coastguard Worker 	printf("Erase chip operation started.\n");
241*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_flash_erase(&flashctx));
242*0d6140beSAndroid Build Coastguard Worker 	printf("Erase chip operation done.\n");
243*0d6140beSAndroid Build Coastguard Worker 
244*0d6140beSAndroid Build Coastguard Worker 	teardown(&layout);
245*0d6140beSAndroid Build Coastguard Worker }
246*0d6140beSAndroid Build Coastguard Worker 
read_chip_test_success(void ** state)247*0d6140beSAndroid Build Coastguard Worker void read_chip_test_success(void **state)
248*0d6140beSAndroid Build Coastguard Worker {
249*0d6140beSAndroid Build Coastguard Worker 	(void) state; /* unused */
250*0d6140beSAndroid Build Coastguard Worker 
251*0d6140beSAndroid Build Coastguard Worker 	static struct io_mock_fallback_open_state data = {
252*0d6140beSAndroid Build Coastguard Worker 		.noc	= 0,
253*0d6140beSAndroid Build Coastguard Worker 		.paths	= { NULL },
254*0d6140beSAndroid Build Coastguard Worker 	};
255*0d6140beSAndroid Build Coastguard Worker 	const struct io_mock chip_io = {
256*0d6140beSAndroid Build Coastguard Worker 		.fallback_open_state = &data,
257*0d6140beSAndroid Build Coastguard Worker 	};
258*0d6140beSAndroid Build Coastguard Worker 
259*0d6140beSAndroid Build Coastguard Worker 	g_test_write_injector = write_chip;
260*0d6140beSAndroid Build Coastguard Worker 	g_test_read_injector = read_chip;
261*0d6140beSAndroid Build Coastguard Worker 	g_test_erase_injector = block_erase_chip;
262*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_flashctx flashctx = { 0 };
263*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_layout *layout;
264*0d6140beSAndroid Build Coastguard Worker 	struct flashchip mock_chip = chip_8MiB;
265*0d6140beSAndroid Build Coastguard Worker 	const char *param = ""; /* Default values for all params. */
266*0d6140beSAndroid Build Coastguard Worker 
267*0d6140beSAndroid Build Coastguard Worker 	setup_chip(&flashctx, &layout, &mock_chip, param, &chip_io);
268*0d6140beSAndroid Build Coastguard Worker 
269*0d6140beSAndroid Build Coastguard Worker 	const char *const filename = "read_chip.test";
270*0d6140beSAndroid Build Coastguard Worker 	unsigned long size = mock_chip.total_size * 1024;
271*0d6140beSAndroid Build Coastguard Worker 	unsigned char *buf = calloc(size, sizeof(unsigned char));
272*0d6140beSAndroid Build Coastguard Worker 	assert_non_null(buf);
273*0d6140beSAndroid Build Coastguard Worker 
274*0d6140beSAndroid Build Coastguard Worker 	printf("Read chip operation started.\n");
275*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_read(&flashctx, buf, size));
276*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, write_buf_to_file(buf, size, filename));
277*0d6140beSAndroid Build Coastguard Worker 	printf("Read chip operation done.\n");
278*0d6140beSAndroid Build Coastguard Worker 
279*0d6140beSAndroid Build Coastguard Worker 	teardown(&layout);
280*0d6140beSAndroid Build Coastguard Worker 
281*0d6140beSAndroid Build Coastguard Worker 	free(buf);
282*0d6140beSAndroid Build Coastguard Worker }
283*0d6140beSAndroid Build Coastguard Worker 
read_chip_with_dummyflasher_test_success(void ** state)284*0d6140beSAndroid Build Coastguard Worker void read_chip_with_dummyflasher_test_success(void **state)
285*0d6140beSAndroid Build Coastguard Worker {
286*0d6140beSAndroid Build Coastguard Worker 	(void) state; /* unused */
287*0d6140beSAndroid Build Coastguard Worker 
288*0d6140beSAndroid Build Coastguard Worker 	static struct io_mock_fallback_open_state data = {
289*0d6140beSAndroid Build Coastguard Worker 		.noc	= 0,
290*0d6140beSAndroid Build Coastguard Worker 		.paths	= { NULL },
291*0d6140beSAndroid Build Coastguard Worker 	};
292*0d6140beSAndroid Build Coastguard Worker 	const struct io_mock chip_io = {
293*0d6140beSAndroid Build Coastguard Worker 		.fallback_open_state = &data,
294*0d6140beSAndroid Build Coastguard Worker 	};
295*0d6140beSAndroid Build Coastguard Worker 
296*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_flashctx flashctx = { 0 };
297*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_layout *layout;
298*0d6140beSAndroid Build Coastguard Worker 	struct flashchip mock_chip = chip_W25Q128_V;
299*0d6140beSAndroid Build Coastguard Worker 	/*
300*0d6140beSAndroid Build Coastguard Worker 	 * Dummyflasher is capable to emulate W25Q128.V, so we ask it to do this.
301*0d6140beSAndroid Build Coastguard Worker 	 * Nothing to mock, dummy is taking care of this already.
302*0d6140beSAndroid Build Coastguard Worker 	 */
303*0d6140beSAndroid Build Coastguard Worker 	const char *param_dup = "bus=spi,emulate=W25Q128FV";
304*0d6140beSAndroid Build Coastguard Worker 
305*0d6140beSAndroid Build Coastguard Worker 	setup_chip(&flashctx, &layout, &mock_chip, param_dup, &chip_io);
306*0d6140beSAndroid Build Coastguard Worker 
307*0d6140beSAndroid Build Coastguard Worker 	const char *const filename = "read_chip.test";
308*0d6140beSAndroid Build Coastguard Worker 	unsigned long size = mock_chip.total_size * 1024;
309*0d6140beSAndroid Build Coastguard Worker 	unsigned char *buf = calloc(size, sizeof(unsigned char));
310*0d6140beSAndroid Build Coastguard Worker 	assert_non_null(buf);
311*0d6140beSAndroid Build Coastguard Worker 
312*0d6140beSAndroid Build Coastguard Worker 	printf("Read chip operation started.\n");
313*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_read(&flashctx, buf, size));
314*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, write_buf_to_file(buf, size, filename));
315*0d6140beSAndroid Build Coastguard Worker 	printf("Read chip operation done.\n");
316*0d6140beSAndroid Build Coastguard Worker 
317*0d6140beSAndroid Build Coastguard Worker 	teardown(&layout);
318*0d6140beSAndroid Build Coastguard Worker 
319*0d6140beSAndroid Build Coastguard Worker 	free(buf);
320*0d6140beSAndroid Build Coastguard Worker }
321*0d6140beSAndroid Build Coastguard Worker 
write_chip_test_success(void ** state)322*0d6140beSAndroid Build Coastguard Worker void write_chip_test_success(void **state)
323*0d6140beSAndroid Build Coastguard Worker {
324*0d6140beSAndroid Build Coastguard Worker 	(void) state; /* unused */
325*0d6140beSAndroid Build Coastguard Worker 
326*0d6140beSAndroid Build Coastguard Worker 	static struct io_mock_fallback_open_state data = {
327*0d6140beSAndroid Build Coastguard Worker 		.noc	= 0,
328*0d6140beSAndroid Build Coastguard Worker 		.paths	= { NULL },
329*0d6140beSAndroid Build Coastguard Worker 	};
330*0d6140beSAndroid Build Coastguard Worker 	const struct io_mock chip_io = {
331*0d6140beSAndroid Build Coastguard Worker 		.fallback_open_state = &data,
332*0d6140beSAndroid Build Coastguard Worker 	};
333*0d6140beSAndroid Build Coastguard Worker 
334*0d6140beSAndroid Build Coastguard Worker 	g_test_write_injector = write_chip;
335*0d6140beSAndroid Build Coastguard Worker 	g_test_read_injector = read_chip;
336*0d6140beSAndroid Build Coastguard Worker 	g_test_erase_injector = block_erase_chip;
337*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_flashctx flashctx = { 0 };
338*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_layout *layout;
339*0d6140beSAndroid Build Coastguard Worker 	struct flashchip mock_chip = chip_8MiB;
340*0d6140beSAndroid Build Coastguard Worker 	const char *param = ""; /* Default values for all params. */
341*0d6140beSAndroid Build Coastguard Worker 
342*0d6140beSAndroid Build Coastguard Worker 	setup_chip(&flashctx, &layout, &mock_chip, param, &chip_io);
343*0d6140beSAndroid Build Coastguard Worker 
344*0d6140beSAndroid Build Coastguard Worker 	/*
345*0d6140beSAndroid Build Coastguard Worker 	 * Providing filename "-" means content is taken from standard input.
346*0d6140beSAndroid Build Coastguard Worker 	 * This doesn't change much because all file operations are mocked.
347*0d6140beSAndroid Build Coastguard Worker 	 * However filename "-" makes a difference for
348*0d6140beSAndroid Build Coastguard Worker 	 * flashrom.c#read_buf_from_file and allows to avoid mocking
349*0d6140beSAndroid Build Coastguard Worker 	 * image_stat.st_size.
350*0d6140beSAndroid Build Coastguard Worker 	 *
351*0d6140beSAndroid Build Coastguard Worker 	 * Now this does mean test covers successful path only, but this test
352*0d6140beSAndroid Build Coastguard Worker 	 * is designed to cover only successful write operation anyway.
353*0d6140beSAndroid Build Coastguard Worker 	 *
354*0d6140beSAndroid Build Coastguard Worker 	 * To cover error path of image_stat.st_size != flash size, filename
355*0d6140beSAndroid Build Coastguard Worker 	 * needs to be provided and image_stat.st_size needs to be mocked.
356*0d6140beSAndroid Build Coastguard Worker 	 */
357*0d6140beSAndroid Build Coastguard Worker 	const char *const filename = "-";
358*0d6140beSAndroid Build Coastguard Worker 	unsigned long size = mock_chip.total_size * 1024;
359*0d6140beSAndroid Build Coastguard Worker 	uint8_t *const newcontents = malloc(size);
360*0d6140beSAndroid Build Coastguard Worker 	assert_non_null(newcontents);
361*0d6140beSAndroid Build Coastguard Worker 
362*0d6140beSAndroid Build Coastguard Worker 	printf("Write chip operation started.\n");
363*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, read_buf_from_file(newcontents, size, filename));
364*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_write(&flashctx, newcontents, size, NULL));
365*0d6140beSAndroid Build Coastguard Worker 	printf("Write chip operation done.\n");
366*0d6140beSAndroid Build Coastguard Worker 
367*0d6140beSAndroid Build Coastguard Worker 	teardown(&layout);
368*0d6140beSAndroid Build Coastguard Worker 
369*0d6140beSAndroid Build Coastguard Worker 	free(newcontents);
370*0d6140beSAndroid Build Coastguard Worker }
371*0d6140beSAndroid Build Coastguard Worker 
write_chip_with_dummyflasher_test_success(void ** state)372*0d6140beSAndroid Build Coastguard Worker void write_chip_with_dummyflasher_test_success(void **state)
373*0d6140beSAndroid Build Coastguard Worker {
374*0d6140beSAndroid Build Coastguard Worker 	(void) state; /* unused */
375*0d6140beSAndroid Build Coastguard Worker 
376*0d6140beSAndroid Build Coastguard Worker 	static struct io_mock_fallback_open_state data = {
377*0d6140beSAndroid Build Coastguard Worker 		.noc	= 0,
378*0d6140beSAndroid Build Coastguard Worker 		.paths	= { NULL },
379*0d6140beSAndroid Build Coastguard Worker 	};
380*0d6140beSAndroid Build Coastguard Worker 	const struct io_mock chip_io = {
381*0d6140beSAndroid Build Coastguard Worker 		.fallback_open_state = &data,
382*0d6140beSAndroid Build Coastguard Worker 	};
383*0d6140beSAndroid Build Coastguard Worker 
384*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_flashctx flashctx = { 0 };
385*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_layout *layout;
386*0d6140beSAndroid Build Coastguard Worker 	struct flashchip mock_chip = chip_W25Q128_V;
387*0d6140beSAndroid Build Coastguard Worker 	/*
388*0d6140beSAndroid Build Coastguard Worker 	 * Dummyflasher is capable to emulate W25Q128.V, so we ask it to do this.
389*0d6140beSAndroid Build Coastguard Worker 	 * Nothing to mock, dummy is taking care of this already.
390*0d6140beSAndroid Build Coastguard Worker 	 */
391*0d6140beSAndroid Build Coastguard Worker 	const char *param_dup = "bus=spi,emulate=W25Q128FV";
392*0d6140beSAndroid Build Coastguard Worker 
393*0d6140beSAndroid Build Coastguard Worker 	setup_chip(&flashctx, &layout, &mock_chip, param_dup, &chip_io);
394*0d6140beSAndroid Build Coastguard Worker 
395*0d6140beSAndroid Build Coastguard Worker 	/* See comment in write_chip_test_success */
396*0d6140beSAndroid Build Coastguard Worker 	const char *const filename = "-";
397*0d6140beSAndroid Build Coastguard Worker 	unsigned long size = mock_chip.total_size * 1024;
398*0d6140beSAndroid Build Coastguard Worker 	uint8_t *const newcontents = malloc(size);
399*0d6140beSAndroid Build Coastguard Worker 	assert_non_null(newcontents);
400*0d6140beSAndroid Build Coastguard Worker 
401*0d6140beSAndroid Build Coastguard Worker 	printf("Write chip operation started.\n");
402*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, read_buf_from_file(newcontents, size, filename));
403*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_write(&flashctx, newcontents, size, NULL));
404*0d6140beSAndroid Build Coastguard Worker 	printf("Write chip operation done.\n");
405*0d6140beSAndroid Build Coastguard Worker 
406*0d6140beSAndroid Build Coastguard Worker 	teardown(&layout);
407*0d6140beSAndroid Build Coastguard Worker 
408*0d6140beSAndroid Build Coastguard Worker 	free(newcontents);
409*0d6140beSAndroid Build Coastguard Worker }
410*0d6140beSAndroid Build Coastguard Worker 
write_chip_feature_no_erase(void ** state)411*0d6140beSAndroid Build Coastguard Worker void write_chip_feature_no_erase(void **state)
412*0d6140beSAndroid Build Coastguard Worker {
413*0d6140beSAndroid Build Coastguard Worker 	(void) state; /* unused */
414*0d6140beSAndroid Build Coastguard Worker 
415*0d6140beSAndroid Build Coastguard Worker 	static struct io_mock_fallback_open_state data = {
416*0d6140beSAndroid Build Coastguard Worker 		.noc	= 0,
417*0d6140beSAndroid Build Coastguard Worker 		.paths	= { NULL },
418*0d6140beSAndroid Build Coastguard Worker 	};
419*0d6140beSAndroid Build Coastguard Worker 	const struct io_mock chip_io = {
420*0d6140beSAndroid Build Coastguard Worker 		.fallback_open_state = &data,
421*0d6140beSAndroid Build Coastguard Worker 	};
422*0d6140beSAndroid Build Coastguard Worker 
423*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_flashctx flashctx = { 0 };
424*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_layout *layout;
425*0d6140beSAndroid Build Coastguard Worker 
426*0d6140beSAndroid Build Coastguard Worker 	/*
427*0d6140beSAndroid Build Coastguard Worker 	 * Tricking the dummyflasher by asking to emulate W25Q128FV but giving to it
428*0d6140beSAndroid Build Coastguard Worker 	 * mock chip with FEATURE_NO_ERASE.
429*0d6140beSAndroid Build Coastguard Worker 	 * As long as chip size is the same, this is fine.
430*0d6140beSAndroid Build Coastguard Worker 	 */
431*0d6140beSAndroid Build Coastguard Worker 	struct flashchip mock_chip = chip_no_erase;
432*0d6140beSAndroid Build Coastguard Worker 	const char *param_dup = "bus=spi,emulate=W25Q128FV";
433*0d6140beSAndroid Build Coastguard Worker 
434*0d6140beSAndroid Build Coastguard Worker 	setup_chip(&flashctx, &layout, &mock_chip, param_dup, &chip_io);
435*0d6140beSAndroid Build Coastguard Worker 
436*0d6140beSAndroid Build Coastguard Worker 	/* See comment in write_chip_test_success */
437*0d6140beSAndroid Build Coastguard Worker 	const char *const filename = "-";
438*0d6140beSAndroid Build Coastguard Worker 	unsigned long size = mock_chip.total_size * 1024;
439*0d6140beSAndroid Build Coastguard Worker 	uint8_t *const newcontents = malloc(size);
440*0d6140beSAndroid Build Coastguard Worker 	assert_non_null(newcontents);
441*0d6140beSAndroid Build Coastguard Worker 
442*0d6140beSAndroid Build Coastguard Worker 	printf("Write chip operation started.\n");
443*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, read_buf_from_file(newcontents, size, filename));
444*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_write(&flashctx, newcontents, size, NULL));
445*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_verify(&flashctx, newcontents, size));
446*0d6140beSAndroid Build Coastguard Worker 	printf("Write chip operation done.\n");
447*0d6140beSAndroid Build Coastguard Worker 
448*0d6140beSAndroid Build Coastguard Worker 	teardown(&layout);
449*0d6140beSAndroid Build Coastguard Worker 
450*0d6140beSAndroid Build Coastguard Worker 	free(newcontents);
451*0d6140beSAndroid Build Coastguard Worker }
452*0d6140beSAndroid Build Coastguard Worker 
write_nonaligned_region_with_dummyflasher_test_success(void ** state)453*0d6140beSAndroid Build Coastguard Worker void write_nonaligned_region_with_dummyflasher_test_success(void **state)
454*0d6140beSAndroid Build Coastguard Worker {
455*0d6140beSAndroid Build Coastguard Worker 	(void) state; /* unused */
456*0d6140beSAndroid Build Coastguard Worker 
457*0d6140beSAndroid Build Coastguard Worker 	static struct io_mock_fallback_open_state data = {
458*0d6140beSAndroid Build Coastguard Worker 		.noc	= 0,
459*0d6140beSAndroid Build Coastguard Worker 		.paths	= { NULL },
460*0d6140beSAndroid Build Coastguard Worker 	};
461*0d6140beSAndroid Build Coastguard Worker 	const struct io_mock chip_io = {
462*0d6140beSAndroid Build Coastguard Worker 		.fallback_open_state = &data,
463*0d6140beSAndroid Build Coastguard Worker 	};
464*0d6140beSAndroid Build Coastguard Worker 
465*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_flashctx flashctx = { 0 };
466*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_layout *layout;
467*0d6140beSAndroid Build Coastguard Worker 	struct flashchip mock_chip = chip_W25Q128_V;
468*0d6140beSAndroid Build Coastguard Worker 	const uint32_t mock_chip_size = mock_chip.total_size * KiB;
469*0d6140beSAndroid Build Coastguard Worker 	/*
470*0d6140beSAndroid Build Coastguard Worker 	 * Dummyflasher is capable to emulate W25Q128.V, so we ask it to do this.
471*0d6140beSAndroid Build Coastguard Worker 	 * Nothing to mock, dummy is taking care of this already.
472*0d6140beSAndroid Build Coastguard Worker 	 */
473*0d6140beSAndroid Build Coastguard Worker 	const char *param_dup = "bus=spi,emulate=W25Q128FV";
474*0d6140beSAndroid Build Coastguard Worker 
475*0d6140beSAndroid Build Coastguard Worker 	/* FIXME: MOCK_CHIP_CONTENT is buggy within setup_chip, it should also
476*0d6140beSAndroid Build Coastguard Worker 	 * not be either 0x00 or 0xFF as those are specific values related to
477*0d6140beSAndroid Build Coastguard Worker 	 * either a erased chip or zero'ed heap thus ambigous.
478*0d6140beSAndroid Build Coastguard Worker 	 */
479*0d6140beSAndroid Build Coastguard Worker #define MOCK_CHIP_SUBREGION_CONTENTS 0xCC
480*0d6140beSAndroid Build Coastguard Worker 	/**
481*0d6140beSAndroid Build Coastguard Worker 	 * Step 0 - Prepare newcontents as contiguous sample data bytes as follows:
482*0d6140beSAndroid Build Coastguard Worker 	 * {MOCK_CHIP_SUBREGION_CONTENTS, [..]}.
483*0d6140beSAndroid Build Coastguard Worker 	 */
484*0d6140beSAndroid Build Coastguard Worker 	uint8_t *newcontents = calloc(1, mock_chip_size);
485*0d6140beSAndroid Build Coastguard Worker 	assert_non_null(newcontents);
486*0d6140beSAndroid Build Coastguard Worker 	memset(newcontents, MOCK_CHIP_SUBREGION_CONTENTS, mock_chip_size);
487*0d6140beSAndroid Build Coastguard Worker 
488*0d6140beSAndroid Build Coastguard Worker 	setup_chip(&flashctx, &layout, &mock_chip, param_dup, &chip_io);
489*0d6140beSAndroid Build Coastguard Worker 	/* Expect to verify only the non-aligned write operation within the region. */
490*0d6140beSAndroid Build Coastguard Worker 	flashrom_flag_set(&flashctx, FLASHROM_FLAG_VERIFY_AFTER_WRITE, true);
491*0d6140beSAndroid Build Coastguard Worker 	flashrom_flag_set(&flashctx, FLASHROM_FLAG_VERIFY_WHOLE_CHIP, false);
492*0d6140beSAndroid Build Coastguard Worker 
493*0d6140beSAndroid Build Coastguard Worker 	/**
494*0d6140beSAndroid Build Coastguard Worker 	 * Prepare mock chip content and release setup_chip() layout for our
495*0d6140beSAndroid Build Coastguard Worker 	 * custom ones.
496*0d6140beSAndroid Build Coastguard Worker 	 */
497*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_write(&flashctx, newcontents, mock_chip_size, NULL));
498*0d6140beSAndroid Build Coastguard Worker 	flashrom_layout_release(layout);
499*0d6140beSAndroid Build Coastguard Worker 
500*0d6140beSAndroid Build Coastguard Worker 	/**
501*0d6140beSAndroid Build Coastguard Worker 	 * Create region smaller than erase granularity of chip.
502*0d6140beSAndroid Build Coastguard Worker 	 */
503*0d6140beSAndroid Build Coastguard Worker 	printf("Creating custom region layout... ");
504*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_layout_new(&layout));
505*0d6140beSAndroid Build Coastguard Worker 	printf("Adding and including region0... ");
506*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_layout_add_region(layout, 0, (1 * KiB), "region0"));
507*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_layout_include_region(layout, "region0"));
508*0d6140beSAndroid Build Coastguard Worker 	flashrom_layout_set(&flashctx, layout);
509*0d6140beSAndroid Build Coastguard Worker 	printf("Subregion layout configuration done.\n");
510*0d6140beSAndroid Build Coastguard Worker 
511*0d6140beSAndroid Build Coastguard Worker 	/**
512*0d6140beSAndroid Build Coastguard Worker 	 * Step 1 - Modify newcontents as non-contiguous sample data bytes as follows:
513*0d6140beSAndroid Build Coastguard Worker 	 * 0xAA 0xAA {MOCK_CHIP_SUBREGION_CONTENTS}, [..]}.
514*0d6140beSAndroid Build Coastguard Worker 	 */
515*0d6140beSAndroid Build Coastguard Worker 	printf("Subregion chip write op..\n");
516*0d6140beSAndroid Build Coastguard Worker 	memset(newcontents, 0xAA, 2);
517*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_write(&flashctx, newcontents, mock_chip_size, NULL));
518*0d6140beSAndroid Build Coastguard Worker 	printf("Subregion chip write op done.\n");
519*0d6140beSAndroid Build Coastguard Worker 
520*0d6140beSAndroid Build Coastguard Worker 	/**
521*0d6140beSAndroid Build Coastguard Worker 	 * FIXME: A 'NULL' layout should indicate a default layout however this
522*0d6140beSAndroid Build Coastguard Worker 	 * causes a crash for a unknown reason. For now prepare a new default
523*0d6140beSAndroid Build Coastguard Worker 	 * layout of the entire chip. flashrom_layout_set(&flashctx, NULL); // use default layout.
524*0d6140beSAndroid Build Coastguard Worker 	 */
525*0d6140beSAndroid Build Coastguard Worker 	flashrom_layout_release(layout);
526*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_layout_new(&layout));
527*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_layout_add_region(layout, 0, mock_chip_size - 1, "entire"));
528*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_layout_include_region(layout, "entire"));
529*0d6140beSAndroid Build Coastguard Worker 	flashrom_layout_set(&flashctx, layout);
530*0d6140beSAndroid Build Coastguard Worker 
531*0d6140beSAndroid Build Coastguard Worker 	/**
532*0d6140beSAndroid Build Coastguard Worker 	 * Expect a verification pass that the previous content within the region, however
533*0d6140beSAndroid Build Coastguard Worker 	 * outside the region write length, is untouched.
534*0d6140beSAndroid Build Coastguard Worker 	 */
535*0d6140beSAndroid Build Coastguard Worker 	printf("Entire chip verify op..\n");
536*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_verify(&flashctx, newcontents, mock_chip_size));
537*0d6140beSAndroid Build Coastguard Worker 	printf("Entire chip verify op done.\n");
538*0d6140beSAndroid Build Coastguard Worker 
539*0d6140beSAndroid Build Coastguard Worker 	teardown(&layout);
540*0d6140beSAndroid Build Coastguard Worker 	free(newcontents);
541*0d6140beSAndroid Build Coastguard Worker }
542*0d6140beSAndroid Build Coastguard Worker 
verify_chip_fread(void * state,void * buf,size_t size,size_t len,FILE * fp)543*0d6140beSAndroid Build Coastguard Worker static size_t verify_chip_fread(void *state, void *buf, size_t size, size_t len, FILE *fp)
544*0d6140beSAndroid Build Coastguard Worker {
545*0d6140beSAndroid Build Coastguard Worker 	/*
546*0d6140beSAndroid Build Coastguard Worker 	 * Verify operation compares contents of the file vs contents on the chip.
547*0d6140beSAndroid Build Coastguard Worker 	 * To emulate successful verification we emulate file contents to be the
548*0d6140beSAndroid Build Coastguard Worker 	 * same as what is on the chip.
549*0d6140beSAndroid Build Coastguard Worker 	 */
550*0d6140beSAndroid Build Coastguard Worker 	memset(buf, MOCK_CHIP_CONTENT, len);
551*0d6140beSAndroid Build Coastguard Worker 	return len;
552*0d6140beSAndroid Build Coastguard Worker }
553*0d6140beSAndroid Build Coastguard Worker 
verify_chip_test_success(void ** state)554*0d6140beSAndroid Build Coastguard Worker void verify_chip_test_success(void **state)
555*0d6140beSAndroid Build Coastguard Worker {
556*0d6140beSAndroid Build Coastguard Worker 	(void) state; /* unused */
557*0d6140beSAndroid Build Coastguard Worker 
558*0d6140beSAndroid Build Coastguard Worker 	static struct io_mock_fallback_open_state data = {
559*0d6140beSAndroid Build Coastguard Worker 		.noc	= 0,
560*0d6140beSAndroid Build Coastguard Worker 		.paths	= { NULL },
561*0d6140beSAndroid Build Coastguard Worker 	};
562*0d6140beSAndroid Build Coastguard Worker 	const struct io_mock verify_chip_io = {
563*0d6140beSAndroid Build Coastguard Worker 		.iom_fread = verify_chip_fread,
564*0d6140beSAndroid Build Coastguard Worker 		.fallback_open_state = &data,
565*0d6140beSAndroid Build Coastguard Worker 	};
566*0d6140beSAndroid Build Coastguard Worker 
567*0d6140beSAndroid Build Coastguard Worker 	g_test_write_injector = write_chip;
568*0d6140beSAndroid Build Coastguard Worker 	g_test_read_injector = read_chip;
569*0d6140beSAndroid Build Coastguard Worker 	g_test_erase_injector = block_erase_chip;
570*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_flashctx flashctx = { 0 };
571*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_layout *layout;
572*0d6140beSAndroid Build Coastguard Worker 	struct flashchip mock_chip = chip_8MiB;
573*0d6140beSAndroid Build Coastguard Worker 	const char *param = ""; /* Default values for all params. */
574*0d6140beSAndroid Build Coastguard Worker 
575*0d6140beSAndroid Build Coastguard Worker 	setup_chip(&flashctx, &layout, &mock_chip, param, &verify_chip_io);
576*0d6140beSAndroid Build Coastguard Worker 
577*0d6140beSAndroid Build Coastguard Worker 	/* See comment in write_chip_test_success */
578*0d6140beSAndroid Build Coastguard Worker 	const char *const filename = "-";
579*0d6140beSAndroid Build Coastguard Worker 	unsigned long size = mock_chip.total_size * 1024;
580*0d6140beSAndroid Build Coastguard Worker 	uint8_t *const newcontents = malloc(size);
581*0d6140beSAndroid Build Coastguard Worker 	assert_non_null(newcontents);
582*0d6140beSAndroid Build Coastguard Worker 
583*0d6140beSAndroid Build Coastguard Worker 	printf("Verify chip operation started.\n");
584*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, read_buf_from_file(newcontents, size, filename));
585*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_verify(&flashctx, newcontents, size));
586*0d6140beSAndroid Build Coastguard Worker 	printf("Verify chip operation done.\n");
587*0d6140beSAndroid Build Coastguard Worker 
588*0d6140beSAndroid Build Coastguard Worker 	teardown(&layout);
589*0d6140beSAndroid Build Coastguard Worker 
590*0d6140beSAndroid Build Coastguard Worker 	free(newcontents);
591*0d6140beSAndroid Build Coastguard Worker }
592*0d6140beSAndroid Build Coastguard Worker 
verify_chip_with_dummyflasher_test_success(void ** state)593*0d6140beSAndroid Build Coastguard Worker void verify_chip_with_dummyflasher_test_success(void **state)
594*0d6140beSAndroid Build Coastguard Worker {
595*0d6140beSAndroid Build Coastguard Worker 	(void) state; /* unused */
596*0d6140beSAndroid Build Coastguard Worker 
597*0d6140beSAndroid Build Coastguard Worker 	static struct io_mock_fallback_open_state data = {
598*0d6140beSAndroid Build Coastguard Worker 		.noc	= 0,
599*0d6140beSAndroid Build Coastguard Worker 		.paths	= { NULL },
600*0d6140beSAndroid Build Coastguard Worker 	};
601*0d6140beSAndroid Build Coastguard Worker 	const struct io_mock verify_chip_io = {
602*0d6140beSAndroid Build Coastguard Worker 		.iom_fread = verify_chip_fread,
603*0d6140beSAndroid Build Coastguard Worker 		.fallback_open_state = &data,
604*0d6140beSAndroid Build Coastguard Worker 	};
605*0d6140beSAndroid Build Coastguard Worker 
606*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_flashctx flashctx = { 0 };
607*0d6140beSAndroid Build Coastguard Worker 	struct flashrom_layout *layout;
608*0d6140beSAndroid Build Coastguard Worker 	struct flashchip mock_chip = chip_W25Q128_V;
609*0d6140beSAndroid Build Coastguard Worker 	/*
610*0d6140beSAndroid Build Coastguard Worker 	 * Dummyflasher is capable to emulate W25Q128.V, so we ask it to do this.
611*0d6140beSAndroid Build Coastguard Worker 	 * Nothing to mock, dummy is taking care of this already.
612*0d6140beSAndroid Build Coastguard Worker 	 */
613*0d6140beSAndroid Build Coastguard Worker 	const char *param_dup = "bus=spi,emulate=W25Q128FV";
614*0d6140beSAndroid Build Coastguard Worker 
615*0d6140beSAndroid Build Coastguard Worker 	setup_chip(&flashctx, &layout, &mock_chip, param_dup, &verify_chip_io);
616*0d6140beSAndroid Build Coastguard Worker 
617*0d6140beSAndroid Build Coastguard Worker 	/* See comment in write_chip_test_success */
618*0d6140beSAndroid Build Coastguard Worker 	const char *const filename = "-";
619*0d6140beSAndroid Build Coastguard Worker 	unsigned long size = mock_chip.total_size * 1024;
620*0d6140beSAndroid Build Coastguard Worker 	uint8_t *const newcontents = malloc(size);
621*0d6140beSAndroid Build Coastguard Worker 	assert_non_null(newcontents);
622*0d6140beSAndroid Build Coastguard Worker 
623*0d6140beSAndroid Build Coastguard Worker 	/*
624*0d6140beSAndroid Build Coastguard Worker 	 * Dummyflasher controls chip state and fully emulates reads and writes,
625*0d6140beSAndroid Build Coastguard Worker 	 * so to set up initial chip state we need to write on chip. Write
626*0d6140beSAndroid Build Coastguard Worker 	 * operation takes content from file and writes on chip. File content is
627*0d6140beSAndroid Build Coastguard Worker 	 * emulated in verify_chip_fread mock.
628*0d6140beSAndroid Build Coastguard Worker 	 */
629*0d6140beSAndroid Build Coastguard Worker 
630*0d6140beSAndroid Build Coastguard Worker 	printf("Write chip operation started.\n");
631*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, read_buf_from_file(newcontents, size, filename));
632*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_write(&flashctx, newcontents, size, NULL));
633*0d6140beSAndroid Build Coastguard Worker 	printf("Write chip operation done.\n");
634*0d6140beSAndroid Build Coastguard Worker 
635*0d6140beSAndroid Build Coastguard Worker 	printf("Verify chip operation started.\n");
636*0d6140beSAndroid Build Coastguard Worker 	assert_int_equal(0, flashrom_image_verify(&flashctx, newcontents, size));
637*0d6140beSAndroid Build Coastguard Worker 	printf("Verify chip operation done.\n");
638*0d6140beSAndroid Build Coastguard Worker 
639*0d6140beSAndroid Build Coastguard Worker 	teardown(&layout);
640*0d6140beSAndroid Build Coastguard Worker 
641*0d6140beSAndroid Build Coastguard Worker 	free(newcontents);
642*0d6140beSAndroid Build Coastguard Worker }
643