xref: /aosp_15_r20/external/flashrom/dummyflasher.c (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
1 /*
2  * This file is part of the flashrom project.
3  *
4  * Copyright (C) 2009,2010 Carl-Daniel Hailfinger
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15 
16 #include <assert.h>
17 #include <string.h>
18 #include <stdbool.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include "flash.h"
26 #include "chipdrivers.h"
27 #include "programmer.h"
28 #include "flashchips.h"
29 #include "spi.h"
30 #include "writeprotect.h"
31 
32 enum emu_chip {
33 	EMULATE_NONE,
34 	EMULATE_ST_M25P10_RES,
35 	EMULATE_SST_SST25VF040_REMS,
36 	EMULATE_SST_SST25VF032B,
37 	EMULATE_MACRONIX_MX25L6436,
38 	EMULATE_WINBOND_W25Q128FV,
39 	EMULATE_SPANSION_S25FL128L,
40 	EMULATE_VARIABLE_SIZE,
41 };
42 
43 struct emu_data {
44 	enum emu_chip emu_chip;
45 	char *emu_persistent_image;
46 	unsigned int emu_chip_size;
47 	/* Note: W25Q128FV doesn't change value of SR2 if it's not provided, but
48 	 *       even its previous generations do, so don't forget to update
49 	 *       WRSR code on enabling WRSR_EXT2 for more chips. */
50 	bool emu_wrsr_ext2;
51 	bool emu_wrsr_ext3;
52 	bool erase_to_zero;
53 	bool emu_modified;	/* is the image modified since reading it? */
54 	uint8_t emu_status[3];
55 	uint8_t emu_status_len;	/* number of emulated status registers */
56 	/* If "freq" parameter is passed in from command line, commands will delay
57 	 * for this period before returning. */
58 	unsigned long long delay_ns;
59 	unsigned int emu_max_byteprogram_size;
60 	unsigned int emu_max_aai_size;
61 	unsigned int emu_jedec_se_size;
62 	unsigned int emu_jedec_be_52_size;
63 	unsigned int emu_jedec_be_d8_size;
64 	unsigned int emu_jedec_ce_60_size;
65 	unsigned int emu_jedec_ce_c7_size;
66 	unsigned char spi_blacklist[256];
67 	unsigned char spi_ignorelist[256];
68 	unsigned int spi_blacklist_size;
69 	unsigned int spi_ignorelist_size;
70 
71 	bool hwwp;	/* state of hardware write protection */
72 	/* wp_start == wp_end when write-protection is disabled */
73 	uint32_t wp_start;
74 	uint32_t wp_end;
75 
76 	unsigned int spi_write_256_chunksize;
77 	uint8_t *flashchip_contents;
78 
79 	/* An instance of this structure is shared between multiple masters, so
80 	 * store the number of references to clean up only once at shutdown time. */
81 	uint8_t refs_cnt;
82 };
83 
84 /* A legit complete SFDP table based on the MX25L6436E (rev. 1.8) datasheet. */
85 static const uint8_t sfdp_table[] = {
86 	0x53, 0x46, 0x44, 0x50, // @0x00: SFDP signature
87 	0x00, 0x01, 0x01, 0xFF, // @0x04: revision 1.0, 2 headers
88 	0x00, 0x00, 0x01, 0x09, // @0x08: JEDEC SFDP header rev. 1.0, 9 DW long
89 	0x1C, 0x00, 0x00, 0xFF, // @0x0C: PTP0 = 0x1C (instead of 0x30)
90 	0xC2, 0x00, 0x01, 0x04, // @0x10: Macronix header rev. 1.0, 4 DW long
91 	0x48, 0x00, 0x00, 0xFF, // @0x14: PTP1 = 0x48 (instead of 0x60)
92 	0xFF, 0xFF, 0xFF, 0xFF, // @0x18: hole.
93 	0xE5, 0x20, 0xC9, 0xFF, // @0x1C: SFDP parameter table start
94 	0xFF, 0xFF, 0xFF, 0x03, // @0x20
95 	0x00, 0xFF, 0x08, 0x6B, // @0x24
96 	0x08, 0x3B, 0x00, 0xFF, // @0x28
97 	0xEE, 0xFF, 0xFF, 0xFF, // @0x2C
98 	0xFF, 0xFF, 0x00, 0x00, // @0x30
99 	0xFF, 0xFF, 0x00, 0xFF, // @0x34
100 	0x0C, 0x20, 0x0F, 0x52, // @0x38
101 	0x10, 0xD8, 0x00, 0xFF, // @0x3C: SFDP parameter table end
102 	0xFF, 0xFF, 0xFF, 0xFF, // @0x40: hole.
103 	0xFF, 0xFF, 0xFF, 0xFF, // @0x44: hole.
104 	0x00, 0x36, 0x00, 0x27, // @0x48: Macronix parameter table start
105 	0xF4, 0x4F, 0xFF, 0xFF, // @0x4C
106 	0xD9, 0xC8, 0xFF, 0xFF, // @0x50
107 	0xFF, 0xFF, 0xFF, 0xFF, // @0x54: Macronix parameter table end
108 };
109 
dummy_map(const char * descr,uintptr_t phys_addr,size_t len)110 static void *dummy_map(const char *descr, uintptr_t phys_addr, size_t len)
111 {
112 	msg_pspew("%s: Mapping %s, 0x%zx bytes at 0x%0*" PRIxPTR "\n",
113 		  __func__, descr, len, PRIxPTR_WIDTH, phys_addr);
114 	return (void *)phys_addr;
115 }
116 
dummy_unmap(void * virt_addr,size_t len)117 static void dummy_unmap(void *virt_addr, size_t len)
118 {
119 	msg_pspew("%s: Unmapping 0x%zx bytes at %p\n", __func__, len, virt_addr);
120 }
121 
dummy_spi_write_256(struct flashctx * flash,const uint8_t * buf,unsigned int start,unsigned int len)122 static int dummy_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
123 {
124 	struct emu_data *emu_data = flash->mst->spi.data;
125 	return spi_write_chunked(flash, buf, start, len,
126 				 emu_data->spi_write_256_chunksize);
127 }
128 
dummy_spi_probe_opcode(const struct flashctx * flash,uint8_t opcode)129 static bool dummy_spi_probe_opcode(const struct flashctx *flash, uint8_t opcode)
130 {
131 	size_t i;
132 	const struct emu_data *emu_data = flash->mst->spi.data;
133 	for (i = 0; i < emu_data->spi_blacklist_size; i++) {
134 		if (emu_data->spi_blacklist[i] == opcode)
135 			return false;
136 	}
137 	return true;
138 }
139 
probe_variable_size(struct flashctx * flash)140 static int probe_variable_size(struct flashctx *flash)
141 {
142 	const struct emu_data *emu_data = flash->mst->opaque.data;
143 
144 	/* Skip the probing if we don't emulate "variable size" chip. */
145 	if (!emu_data || emu_data->emu_chip != EMULATE_VARIABLE_SIZE)
146 		return 0;
147 
148 	flash->chip->total_size = emu_data->emu_chip_size / 1024;
149 	msg_cdbg("%s: set flash->total_size to %dK bytes.\n", __func__,
150 	         flash->chip->total_size);
151 
152 	flash->chip->tested = TEST_OK_PREWB;
153 
154 	if (emu_data->erase_to_zero)
155 		flash->chip->feature_bits |= FEATURE_ERASED_ZERO;
156 
157 	/*
158 	 * Update the first count of the block_eraser.
159 	 * Opaque flash chip entry in flashchips.c has only one block eraser.
160 	 *
161 	 * If this changes in future, the code below needs to be adjusted
162 	 * to update all block erasers.
163 	 */
164 	struct block_eraser *eraser = &flash->chip->block_erasers[0];
165 	if (!eraser->block_erase)
166 		return 1;
167 
168 	eraser->eraseblocks[0].count = 1;
169 	eraser->eraseblocks[0].size = emu_data->emu_chip_size;
170 	msg_cdbg("%s: eraser.size=%d, .count=%d\n",
171 		 __func__, eraser->eraseblocks[0].size,
172 		 eraser->eraseblocks[0].count);
173 
174 	return 1;
175 }
176 
dummy_opaque_read(struct flashctx * flash,uint8_t * buf,unsigned int start,unsigned int len)177 static int dummy_opaque_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
178 {
179 	const struct emu_data *emu_data = flash->mst->opaque.data;
180 
181 	memcpy(buf, emu_data->flashchip_contents + start, len);
182 
183 	return 0;
184 }
185 
dummy_opaque_write(struct flashctx * flash,const uint8_t * buf,unsigned int start,unsigned int len)186 static int dummy_opaque_write(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
187 {
188 	struct emu_data *emu_data = flash->mst->opaque.data;
189 
190 	memcpy(emu_data->flashchip_contents + start, buf, len);
191 	emu_data->emu_modified = true;
192 
193 	return 0;
194 }
195 
dummy_opaque_erase(struct flashctx * flash,unsigned int blockaddr,unsigned int blocklen)196 static int dummy_opaque_erase(struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen)
197 {
198 	struct emu_data *emu_data = flash->mst->opaque.data;
199 
200 	memset(emu_data->flashchip_contents + blockaddr, emu_data->erase_to_zero ? 0x00 : 0xff, blocklen);
201 	emu_data->emu_modified = true;
202 
203 	return 0;
204 }
205 
dummy_chip_writeb(const struct flashctx * flash,uint8_t val,chipaddr addr)206 static void dummy_chip_writeb(const struct flashctx *flash, uint8_t val, chipaddr addr)
207 {
208 	msg_pspew("%s: addr=0x%" PRIxPTR ", val=0x%02x\n", __func__, addr, val);
209 }
210 
dummy_chip_writew(const struct flashctx * flash,uint16_t val,chipaddr addr)211 static void dummy_chip_writew(const struct flashctx *flash, uint16_t val, chipaddr addr)
212 {
213 	msg_pspew("%s: addr=0x%" PRIxPTR ", val=0x%04x\n", __func__, addr, val);
214 }
215 
dummy_chip_writel(const struct flashctx * flash,uint32_t val,chipaddr addr)216 static void dummy_chip_writel(const struct flashctx *flash, uint32_t val, chipaddr addr)
217 {
218 	msg_pspew("%s: addr=0x%" PRIxPTR ", val=0x%08"PRIx32"\n", __func__, addr, val);
219 }
220 
dummy_chip_writen(const struct flashctx * flash,const uint8_t * buf,chipaddr addr,size_t len)221 static void dummy_chip_writen(const struct flashctx *flash, const uint8_t *buf, chipaddr addr, size_t len)
222 {
223 	size_t i;
224 	msg_pspew("%s: addr=0x%" PRIxPTR ", len=0x%zx, writing data (hex):", __func__, addr, len);
225 	for (i = 0; i < len; i++) {
226 		if ((i % 16) == 0)
227 			msg_pspew("\n");
228 		msg_pspew("%02x ", buf[i]);
229 	}
230 }
231 
dummy_chip_readb(const struct flashctx * flash,const chipaddr addr)232 static uint8_t dummy_chip_readb(const struct flashctx *flash, const chipaddr addr)
233 {
234 	msg_pspew("%s:  addr=0x%" PRIxPTR ", returning 0xff\n", __func__, addr);
235 	return 0xff;
236 }
237 
dummy_chip_readw(const struct flashctx * flash,const chipaddr addr)238 static uint16_t dummy_chip_readw(const struct flashctx *flash, const chipaddr addr)
239 {
240 	msg_pspew("%s:  addr=0x%" PRIxPTR ", returning 0xffff\n", __func__, addr);
241 	return 0xffff;
242 }
243 
dummy_chip_readl(const struct flashctx * flash,const chipaddr addr)244 static uint32_t dummy_chip_readl(const struct flashctx *flash, const chipaddr addr)
245 {
246 	msg_pspew("%s:  addr=0x%" PRIxPTR ", returning 0xffffffff\n", __func__, addr);
247 	return 0xffffffff;
248 }
249 
dummy_chip_readn(const struct flashctx * flash,uint8_t * buf,const chipaddr addr,size_t len)250 static void dummy_chip_readn(const struct flashctx *flash, uint8_t *buf, const chipaddr addr, size_t len)
251 {
252 	msg_pspew("%s:  addr=0x%" PRIxPTR ", len=0x%zx, returning array of 0xff\n", __func__, addr, len);
253 	memset(buf, 0xff, len);
254 	return;
255 }
256 
get_reg_ro_bit_mask(const struct emu_data * data,enum flash_reg reg)257 static uint8_t get_reg_ro_bit_mask(const struct emu_data *data, enum flash_reg reg)
258 {
259 	/* Whoever adds a new register must not forget to update this function
260 	   or at least shouldn't use it incorrectly. */
261 	assert(reg == STATUS1 || reg == STATUS2 || reg == STATUS3);
262 
263 	uint8_t ro_bits = reg == STATUS1 ? SPI_SR_WIP : 0;
264 
265 	if (data->emu_chip == EMULATE_WINBOND_W25Q128FV) {
266 		const bool srp0 = (data->emu_status[0] >> 7);
267 		const bool srp1 = (data->emu_status[1] & 1);
268 
269 		const bool wp_active = (srp1 || (srp0 && data->hwwp));
270 
271 		if (wp_active) {
272 			ro_bits = 0xff;
273 		} else if (reg == STATUS2) {
274 			/* SUS (bit_7) and (R) (bit_2). */
275 			ro_bits = 0x84;
276 			/* Once any of the lock bits (LB[1..3]) are set, they
277 			   can't be unset. */
278 			ro_bits |= data->emu_status[1] & (1 << 3);
279 			ro_bits |= data->emu_status[1] & (1 << 4);
280 			ro_bits |= data->emu_status[1] & (1 << 5);
281 		} else if (reg == STATUS3) {
282 			/* Four reserved bits. */
283 			ro_bits = 0x1b;
284 		}
285 	}
286 
287 	if (data->emu_chip == EMULATE_SPANSION_S25FL128L) {
288 		const bool srp0 = (data->emu_status[0] >> 7);
289 		const bool srp1 = (data->emu_status[1] & 1);
290 
291 		const bool wp_active = (srp1 || (srp0 && data->hwwp));
292 
293 		if (wp_active) {
294 			ro_bits = 0xff;
295 		} else if (reg == STATUS2) {
296 			/* SUS (bit_7) */
297 			ro_bits = 0x80;
298 			/* Once any of the lock bits (LB[0..3]) are set, they
299 			   can't be unset. */
300 			ro_bits |= data->emu_status[1] & (1 << 2);
301 			ro_bits |= data->emu_status[1] & (1 << 3);
302 			ro_bits |= data->emu_status[1] & (1 << 4);
303 			ro_bits |= data->emu_status[1] & (1 << 5);
304 		} else if (reg == STATUS3) {
305 			/* Two reserved bits. */
306 			ro_bits = 0x11;
307 		}
308 	}
309 
310 	return ro_bits;
311 }
312 
update_write_protection(struct emu_data * data)313 static void update_write_protection(struct emu_data *data)
314 {
315 	if (data->emu_chip != EMULATE_WINBOND_W25Q128FV &&
316 	    data->emu_chip != EMULATE_SPANSION_S25FL128L)
317 		return;
318 
319 	const struct wp_bits bits = {
320 		.srp = data->emu_status[0] >> 7,
321 		.srl = data->emu_status[1] & 1,
322 
323 		.bp_bit_count = 3,
324 		.bp =
325 		{
326 			(data->emu_status[0] >> 2) & 1,
327 			(data->emu_status[0] >> 3) & 1,
328 			(data->emu_status[0] >> 4) & 1
329 		},
330 
331 		.tb_bit_present = true,
332 		.tb = (data->emu_status[0] >> 5) & 1,
333 
334 		.sec_bit_present = true,
335 		.sec = (data->emu_status[0] >> 6) & 1,
336 
337 		.cmp_bit_present = true,
338 		.cmp = (data->emu_status[1] >> 6) & 1,
339 	};
340 
341 	size_t start;
342 	size_t len;
343 	decode_range_spi25(&start, &len, &bits, data->emu_chip_size);
344 
345 	data->wp_start = start;
346 	data->wp_end = start + len;
347 }
348 
349 /* Checks whether range intersects a write-protected area of the flash if one is
350  * defined. */
is_write_protected(const struct emu_data * data,uint32_t start,uint32_t len)351 static bool is_write_protected(const struct emu_data *data, uint32_t start, uint32_t len)
352 {
353 	if (len == 0)
354 		return false;
355 
356 	const uint32_t last = start + len - 1;
357 	return (start < data->wp_end && last >= data->wp_start);
358 }
359 
360 /* Returns non-zero on error. */
write_flash_data(struct emu_data * data,uint32_t start,uint32_t len,const uint8_t * buf)361 static int write_flash_data(struct emu_data *data, uint32_t start, uint32_t len, const uint8_t *buf)
362 {
363 	if (is_write_protected(data, start, len)) {
364 		msg_perr("At least part of the write range is write protected!\n");
365 		return 1;
366 	}
367 
368 	memcpy(data->flashchip_contents + start, buf, len);
369 	data->emu_modified = true;
370 	return 0;
371 }
372 
373 /* Returns non-zero on error. */
erase_flash_data(struct emu_data * data,uint32_t start,uint32_t len)374 static int erase_flash_data(struct emu_data *data, uint32_t start, uint32_t len)
375 {
376 	if (is_write_protected(data, start, len)) {
377 		msg_perr("At least part of the erase range is write protected!\n");
378 		return 1;
379 	}
380 
381 	/* FIXME: Maybe use ERASED_VALUE(flash) instead of 0xff ? */
382 	memset(data->flashchip_contents + start, 0xff, len);
383 	data->emu_modified = true;
384 	return 0;
385 }
386 
emulate_spi_chip_response(unsigned int writecnt,unsigned int readcnt,const unsigned char * writearr,unsigned char * readarr,struct emu_data * data)387 static int emulate_spi_chip_response(unsigned int writecnt,
388 				     unsigned int readcnt,
389 				     const unsigned char *writearr,
390 				     unsigned char *readarr,
391 				     struct emu_data *data)
392 {
393 	unsigned int offs, i, toread;
394 	uint8_t ro_bits;
395 	bool wrsr_ext2, wrsr_ext3;
396 	static int unsigned aai_offs;
397 	const unsigned char sst25vf040_rems_response[2] = {0xbf, 0x44};
398 	const unsigned char sst25vf032b_rems_response[2] = {0xbf, 0x4a};
399 	const unsigned char mx25l6436_rems_response[2] = {0xc2, 0x16};
400 	const unsigned char w25q128fv_rems_response[2] = {0xef, 0x17};
401 
402 	if (writecnt == 0) {
403 		msg_perr("No command sent to the chip!\n");
404 		return 1;
405 	}
406 	/* spi_blacklist has precedence over spi_ignorelist. */
407 	for (i = 0; i < data->spi_blacklist_size; i++) {
408 		if (writearr[0] == data->spi_blacklist[i]) {
409 			msg_pdbg("Refusing blacklisted SPI command 0x%02x\n",
410 				 data->spi_blacklist[i]);
411 			return SPI_INVALID_OPCODE;
412 		}
413 	}
414 	for (i = 0; i < data->spi_ignorelist_size; i++) {
415 		if (writearr[0] == data->spi_ignorelist[i]) {
416 			msg_cdbg("Ignoring ignorelisted SPI command 0x%02x\n",
417 				 data->spi_ignorelist[i]);
418 			/* Return success because the command does not fail,
419 			 * it is simply ignored.
420 			 */
421 			return 0;
422 		}
423 	}
424 
425 	if (data->emu_max_aai_size && (data->emu_status[0] & SPI_SR_AAI)) {
426 		if (writearr[0] != JEDEC_AAI_WORD_PROGRAM &&
427 		    writearr[0] != JEDEC_WRDI &&
428 		    writearr[0] != JEDEC_RDSR) {
429 			msg_perr("Forbidden opcode (0x%02x) attempted during "
430 				 "AAI sequence!\n", writearr[0]);
431 			return 0;
432 		}
433 	}
434 
435 	switch (writearr[0]) {
436 	case JEDEC_RES:
437 		if (writecnt < JEDEC_RES_OUTSIZE)
438 			break;
439 		/* offs calculation is only needed for SST chips which treat RES like REMS. */
440 		offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
441 		offs += writecnt - JEDEC_REMS_OUTSIZE;
442 		switch (data->emu_chip) {
443 		case EMULATE_ST_M25P10_RES:
444 			if (readcnt > 0)
445 				memset(readarr, 0x10, readcnt);
446 			break;
447 		case EMULATE_SST_SST25VF040_REMS:
448 			for (i = 0; i < readcnt; i++)
449 				readarr[i] = sst25vf040_rems_response[(offs + i) % 2];
450 			break;
451 		case EMULATE_SST_SST25VF032B:
452 			for (i = 0; i < readcnt; i++)
453 				readarr[i] = sst25vf032b_rems_response[(offs + i) % 2];
454 			break;
455 		case EMULATE_MACRONIX_MX25L6436:
456 			if (readcnt > 0)
457 				memset(readarr, 0x16, readcnt);
458 			break;
459 		case EMULATE_WINBOND_W25Q128FV:
460 			if (readcnt > 0)
461 				memset(readarr, 0x17, readcnt);
462 			break;
463 		case EMULATE_SPANSION_S25FL128L:
464 			if (readcnt > 0)
465 				readarr[0] = 0x60;
466 			if (readcnt > 1)
467 				readarr[1] = 0x18;
468 			break;
469 		default: /* ignore */
470 			break;
471 		}
472 		break;
473 	case JEDEC_REMS:
474 		/* REMS response has wraparound and uses an address parameter. */
475 		if (writecnt < JEDEC_REMS_OUTSIZE)
476 			break;
477 		offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
478 		offs += writecnt - JEDEC_REMS_OUTSIZE;
479 		switch (data->emu_chip) {
480 		case EMULATE_SST_SST25VF040_REMS:
481 			for (i = 0; i < readcnt; i++)
482 				readarr[i] = sst25vf040_rems_response[(offs + i) % 2];
483 			break;
484 		case EMULATE_SST_SST25VF032B:
485 			for (i = 0; i < readcnt; i++)
486 				readarr[i] = sst25vf032b_rems_response[(offs + i) % 2];
487 			break;
488 		case EMULATE_MACRONIX_MX25L6436:
489 			for (i = 0; i < readcnt; i++)
490 				readarr[i] = mx25l6436_rems_response[(offs + i) % 2];
491 			break;
492 		case EMULATE_WINBOND_W25Q128FV:
493 			for (i = 0; i < readcnt; i++)
494 				readarr[i] = w25q128fv_rems_response[(offs + i) % 2];
495 			break;
496 		default: /* ignore */
497 			break;
498 		}
499 		break;
500 	case JEDEC_RDID:
501 		switch (data->emu_chip) {
502 		case EMULATE_SST_SST25VF032B:
503 			if (readcnt > 0)
504 				readarr[0] = 0xbf;
505 			if (readcnt > 1)
506 				readarr[1] = 0x25;
507 			if (readcnt > 2)
508 				readarr[2] = 0x4a;
509 			break;
510 		case EMULATE_MACRONIX_MX25L6436:
511 			if (readcnt > 0)
512 				readarr[0] = 0xc2;
513 			if (readcnt > 1)
514 				readarr[1] = 0x20;
515 			if (readcnt > 2)
516 				readarr[2] = 0x17;
517 			break;
518 		case EMULATE_WINBOND_W25Q128FV:
519 			if (readcnt > 0)
520 				readarr[0] = 0xef;
521 			if (readcnt > 1)
522 				readarr[1] = 0x40;
523 			if (readcnt > 2)
524 				readarr[2] = 0x18;
525 			break;
526 		case EMULATE_SPANSION_S25FL128L:
527 			if (readcnt > 0)
528 				readarr[0] = 0x01;
529 			if (readcnt > 1)
530 				readarr[1] = 0x60;
531 			if (readcnt > 2)
532 				readarr[2] = 0x18;
533 			break;
534 		case EMULATE_VARIABLE_SIZE:
535 			if (readcnt > 0)
536 				readarr[0] = (PROGMANUF_ID >> 8) & 0xff;
537 			if (readcnt > 1)
538 				readarr[1] = PROGMANUF_ID & 0xff;
539 			if (readcnt > 2)
540 				readarr[2] = (PROGDEV_ID >> 8) & 0xff;
541 			if (readcnt > 3)
542 				readarr[3] = PROGDEV_ID & 0xff;
543 			break;
544 		default: /* ignore */
545 			break;
546 		}
547 		break;
548 	case JEDEC_RDSR:
549 		memset(readarr, data->emu_status[0], readcnt);
550 		break;
551 	case JEDEC_RDSR2:
552 		if (data->emu_status_len >= 2)
553 			memset(readarr, data->emu_status[1], readcnt);
554 		break;
555 	case JEDEC_RDSR3:
556 		if (data->emu_status_len >= 3)
557 			memset(readarr, data->emu_status[2], readcnt);
558 		break;
559 	/* FIXME: this should be chip-specific. */
560 	case JEDEC_EWSR:
561 	case JEDEC_WREN:
562 		data->emu_status[0] |= SPI_SR_WEL;
563 		break;
564 	case JEDEC_WRSR:
565 		if (!(data->emu_status[0] & SPI_SR_WEL)) {
566 			msg_perr("WRSR attempted, but WEL is 0!\n");
567 			break;
568 		}
569 
570 		wrsr_ext2 = (writecnt == 3 && data->emu_wrsr_ext2);
571 		wrsr_ext3 = (writecnt == 4 && data->emu_wrsr_ext3);
572 
573 		/* FIXME: add some reasonable simulation of the busy flag */
574 
575 		ro_bits = get_reg_ro_bit_mask(data, STATUS1);
576 		data->emu_status[0] &= ro_bits;
577 		data->emu_status[0] |= writearr[1] & ~ro_bits;
578 		if (wrsr_ext2 || wrsr_ext3) {
579 			ro_bits = get_reg_ro_bit_mask(data, STATUS2);
580 			data->emu_status[1] &= ro_bits;
581 			data->emu_status[1] |= writearr[2] & ~ro_bits;
582 		}
583 		if (wrsr_ext3) {
584 			ro_bits = get_reg_ro_bit_mask(data, STATUS3);
585 			data->emu_status[2] &= ro_bits;
586 			data->emu_status[2] |= writearr[3] & ~ro_bits;
587 		}
588 
589 		if (wrsr_ext3)
590 			msg_pdbg2("WRSR wrote 0x%02x%02x%02x.\n", data->emu_status[2], data->emu_status[1], data->emu_status[0]);
591 		else if (wrsr_ext2)
592 			msg_pdbg2("WRSR wrote 0x%02x%02x.\n", data->emu_status[1], data->emu_status[0]);
593 		else
594 			msg_pdbg2("WRSR wrote 0x%02x.\n", data->emu_status[0]);
595 
596 		update_write_protection(data);
597 		break;
598 	case JEDEC_WRSR2:
599 		if (data->emu_status_len < 2)
600 			break;
601 		if (!(data->emu_status[0] & SPI_SR_WEL)) {
602 			msg_perr("WRSR2 attempted, but WEL is 0!\n");
603 			break;
604 		}
605 
606 		ro_bits = get_reg_ro_bit_mask(data, STATUS2);
607 		data->emu_status[1] &= ro_bits;
608 		data->emu_status[1] |= (writearr[1] & ~ro_bits);
609 
610 		msg_pdbg2("WRSR2 wrote 0x%02x.\n", data->emu_status[1]);
611 
612 		update_write_protection(data);
613 		break;
614 	case JEDEC_WRSR3:
615 		if (data->emu_status_len < 3)
616 			break;
617 		if (!(data->emu_status[0] & SPI_SR_WEL)) {
618 			msg_perr("WRSR3 attempted, but WEL is 0!\n");
619 			break;
620 		}
621 
622 		ro_bits = get_reg_ro_bit_mask(data, STATUS3);
623 		data->emu_status[2] &= ro_bits;
624 		data->emu_status[2] |= (writearr[1] & ~ro_bits);
625 
626 		msg_pdbg2("WRSR3 wrote 0x%02x.\n", data->emu_status[2]);
627 		break;
628 	case JEDEC_READ:
629 		offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
630 		/* Truncate to emu_chip_size. */
631 		offs %= data->emu_chip_size;
632 		if (readcnt > 0)
633 			memcpy(readarr, data->flashchip_contents + offs, readcnt);
634 		break;
635 	case JEDEC_READ_4BA:
636 		offs = writearr[1] << 24 | writearr[2] << 16 | writearr[3] << 8 | writearr[4];
637 		/* Truncate to emu_chip_size. */
638 		offs %= data->emu_chip_size;
639 		if (readcnt > 0)
640 			memcpy(readarr, data->flashchip_contents + offs, readcnt);
641 		break;
642 	case JEDEC_BYTE_PROGRAM:
643 		offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
644 		/* Truncate to emu_chip_size. */
645 		offs %= data->emu_chip_size;
646 		if (writecnt < 5) {
647 			msg_perr("BYTE PROGRAM size too short!\n");
648 			return 1;
649 		}
650 		if (writecnt - 4 > data->emu_max_byteprogram_size) {
651 			msg_perr("Max BYTE PROGRAM size exceeded!\n");
652 			return 1;
653 		}
654 		if (write_flash_data(data, offs, writecnt - 4, writearr + 4)) {
655 			msg_perr("Failed to program flash!\n");
656 			return 1;
657 		}
658 		break;
659 	case JEDEC_BYTE_PROGRAM_4BA:
660 		offs = writearr[1] << 24 | writearr[2] << 16 | writearr[3] << 8 | writearr[4];
661 		/* Truncate to emu_chip_size. */
662 		offs %= data->emu_chip_size;
663 		if (writecnt < 6) {
664 			msg_perr("BYTE PROGRAM size too short!\n");
665 			return 1;
666 		}
667 		if (writecnt - 5 > data->emu_max_byteprogram_size) {
668 			msg_perr("Max BYTE PROGRAM size exceeded!\n");
669 			return 1;
670 		}
671 		if (write_flash_data(data, offs, writecnt - 5, writearr + 5)) {
672 			msg_perr("Failed to program flash!\n");
673 			return 1;
674 		}
675 		break;
676 	case JEDEC_AAI_WORD_PROGRAM:
677 		if (!data->emu_max_aai_size)
678 			break;
679 		if (!(data->emu_status[0] & SPI_SR_AAI)) {
680 			if (writecnt < JEDEC_AAI_WORD_PROGRAM_OUTSIZE) {
681 				msg_perr("Initial AAI WORD PROGRAM size too "
682 					 "short!\n");
683 				return 1;
684 			}
685 			if (writecnt > JEDEC_AAI_WORD_PROGRAM_OUTSIZE) {
686 				msg_perr("Initial AAI WORD PROGRAM size too "
687 					 "long!\n");
688 				return 1;
689 			}
690 			data->emu_status[0] |= SPI_SR_AAI;
691 			aai_offs = writearr[1] << 16 | writearr[2] << 8 |
692 				   writearr[3];
693 			/* Truncate to emu_chip_size. */
694 			aai_offs %= data->emu_chip_size;
695 			if (write_flash_data(data, aai_offs, 2, writearr + 4)) {
696 				msg_perr("Failed to program flash!\n");
697 				return 1;
698 			}
699 			aai_offs += 2;
700 		} else {
701 			if (writecnt < JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE) {
702 				msg_perr("Continuation AAI WORD PROGRAM size "
703 					 "too short!\n");
704 				return 1;
705 			}
706 			if (writecnt > JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE) {
707 				msg_perr("Continuation AAI WORD PROGRAM size "
708 					 "too long!\n");
709 				return 1;
710 			}
711 			if (write_flash_data(data, aai_offs, 2, writearr + 1)) {
712 				msg_perr("Failed to program flash!\n");
713 				return 1;
714 			}
715 			aai_offs += 2;
716 		}
717 		break;
718 	case JEDEC_WRDI:
719 		if (data->emu_max_aai_size)
720 			data->emu_status[0] &= ~SPI_SR_AAI;
721 		break;
722 	case JEDEC_SE:
723 		if (!data->emu_jedec_se_size)
724 			break;
725 		if (writecnt != JEDEC_SE_OUTSIZE) {
726 			msg_perr("SECTOR ERASE 0x20 outsize invalid!\n");
727 			return 1;
728 		}
729 		if (readcnt != JEDEC_SE_INSIZE) {
730 			msg_perr("SECTOR ERASE 0x20 insize invalid!\n");
731 			return 1;
732 		}
733 		offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
734 		if (offs & (data->emu_jedec_se_size - 1))
735 			msg_pdbg("Unaligned SECTOR ERASE 0x20: 0x%x\n", offs);
736 		offs &= ~(data->emu_jedec_se_size - 1);
737 		if (erase_flash_data(data, offs, data->emu_jedec_se_size)) {
738 			msg_perr("Failed to erase flash!\n");
739 			return 1;
740 		}
741 		break;
742 	case JEDEC_BE_52:
743 		if (!data->emu_jedec_be_52_size)
744 			break;
745 		if (writecnt != JEDEC_BE_52_OUTSIZE) {
746 			msg_perr("BLOCK ERASE 0x52 outsize invalid!\n");
747 			return 1;
748 		}
749 		if (readcnt != JEDEC_BE_52_INSIZE) {
750 			msg_perr("BLOCK ERASE 0x52 insize invalid!\n");
751 			return 1;
752 		}
753 		offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
754 		if (offs & (data->emu_jedec_be_52_size - 1))
755 			msg_pdbg("Unaligned BLOCK ERASE 0x52: 0x%x\n", offs);
756 		offs &= ~(data->emu_jedec_be_52_size - 1);
757 		if (erase_flash_data(data, offs, data->emu_jedec_be_52_size)) {
758 			msg_perr("Failed to erase flash!\n");
759 			return 1;
760 		}
761 		break;
762 	case JEDEC_BE_D8:
763 		if (!data->emu_jedec_be_d8_size)
764 			break;
765 		if (writecnt != JEDEC_BE_D8_OUTSIZE) {
766 			msg_perr("BLOCK ERASE 0xd8 outsize invalid!\n");
767 			return 1;
768 		}
769 		if (readcnt != JEDEC_BE_D8_INSIZE) {
770 			msg_perr("BLOCK ERASE 0xd8 insize invalid!\n");
771 			return 1;
772 		}
773 		offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
774 		if (offs & (data->emu_jedec_be_d8_size - 1))
775 			msg_pdbg("Unaligned BLOCK ERASE 0xd8: 0x%x\n", offs);
776 		offs &= ~(data->emu_jedec_be_d8_size - 1);
777 		if (erase_flash_data(data, offs, data->emu_jedec_be_d8_size)) {
778 			msg_perr("Failed to erase flash!\n");
779 			return 1;
780 		}
781 		break;
782 	case JEDEC_CE_60:
783 		if (!data->emu_jedec_ce_60_size)
784 			break;
785 		if (writecnt != JEDEC_CE_60_OUTSIZE) {
786 			msg_perr("CHIP ERASE 0x60 outsize invalid!\n");
787 			return 1;
788 		}
789 		if (readcnt != JEDEC_CE_60_INSIZE) {
790 			msg_perr("CHIP ERASE 0x60 insize invalid!\n");
791 			return 1;
792 		}
793 		/* JEDEC_CE_60_OUTSIZE is 1 (no address) -> no offset. */
794 		/* emu_jedec_ce_60_size is emu_chip_size. */
795 		if (erase_flash_data(data, 0, data->emu_jedec_ce_60_size)) {
796 			msg_perr("Failed to erase flash!\n");
797 			return 1;
798 		}
799 		break;
800 	case JEDEC_CE_C7:
801 		if (!data->emu_jedec_ce_c7_size)
802 			break;
803 		if (writecnt != JEDEC_CE_C7_OUTSIZE) {
804 			msg_perr("CHIP ERASE 0xc7 outsize invalid!\n");
805 			return 1;
806 		}
807 		if (readcnt != JEDEC_CE_C7_INSIZE) {
808 			msg_perr("CHIP ERASE 0xc7 insize invalid!\n");
809 			return 1;
810 		}
811 		/* JEDEC_CE_C7_OUTSIZE is 1 (no address) -> no offset. */
812 		/* emu_jedec_ce_c7_size is emu_chip_size. */
813 		if (erase_flash_data(data, 0, data->emu_jedec_ce_c7_size)) {
814 			msg_perr("Failed to erase flash!\n");
815 			return 1;
816 		}
817 		break;
818 	case JEDEC_SFDP:
819 		if (data->emu_chip != EMULATE_MACRONIX_MX25L6436)
820 			break;
821 		if (writecnt < 4)
822 			break;
823 		offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
824 
825 		/* SFDP expects one dummy byte after the address. */
826 		if (writecnt == 4) {
827 			/* The dummy byte was not written, make sure it is read instead.
828 			 * Shifting and shortening the read array does achieve this goal.
829 			 */
830 			readarr++;
831 			readcnt--;
832 		} else {
833 			/* The response is shifted if more than 5 bytes are written, because SFDP data is
834 			 * already shifted out by the chip while those superfluous bytes are written. */
835 			offs += writecnt - 5;
836 		}
837 
838 		/* The SFDP spec implies that the start address of an SFDP read may be truncated to fit in the
839 		 * SFDP table address space, i.e. the start address may be wrapped around at SFDP table size.
840 		 * This is a reasonable implementation choice in hardware because it saves a few gates. */
841 		if (offs >= sizeof(sfdp_table)) {
842 			msg_pdbg("Wrapping the start address around the SFDP table boundary (using 0x%x "
843 				 "instead of 0x%x).\n", (unsigned int)(offs % sizeof(sfdp_table)), offs);
844 			offs %= sizeof(sfdp_table);
845 		}
846 		toread = min(sizeof(sfdp_table) - offs, readcnt);
847 		memcpy(readarr, sfdp_table + offs, toread);
848 		if (toread < readcnt)
849 			msg_pdbg("Crossing the SFDP table boundary in a single "
850 				 "continuous chunk produces undefined results "
851 				 "after that point.\n");
852 		break;
853 	default:
854 		/* No special response. */
855 		break;
856 	}
857 	if (writearr[0] != JEDEC_WREN && writearr[0] != JEDEC_EWSR)
858 		data->emu_status[0] &= ~SPI_SR_WEL;
859 	return 0;
860 }
861 
dummy_spi_send_command(const struct flashctx * flash,unsigned int writecnt,unsigned int readcnt,const unsigned char * writearr,unsigned char * readarr)862 static int dummy_spi_send_command(const struct flashctx *flash, unsigned int writecnt,
863 				  unsigned int readcnt,
864 				  const unsigned char *writearr,
865 				  unsigned char *readarr)
866 {
867 	unsigned int i;
868 	struct emu_data *emu_data = flash->mst->spi.data;
869 	if (!emu_data) {
870 		msg_perr("No data in flash context!\n");
871 		return 1;
872 	}
873 
874 	msg_pspew("%s:", __func__);
875 
876 	msg_pspew(" writing %u bytes:", writecnt);
877 	for (i = 0; i < writecnt; i++)
878 		msg_pspew(" 0x%02x", writearr[i]);
879 
880 	/* Response for unknown commands and missing chip is 0xff. */
881 	memset(readarr, 0xff, readcnt);
882 	switch (emu_data->emu_chip) {
883 	case EMULATE_ST_M25P10_RES:
884 	case EMULATE_SST_SST25VF040_REMS:
885 	case EMULATE_SST_SST25VF032B:
886 	case EMULATE_MACRONIX_MX25L6436:
887 	case EMULATE_WINBOND_W25Q128FV:
888 	case EMULATE_SPANSION_S25FL128L:
889 	case EMULATE_VARIABLE_SIZE:
890 		if (emulate_spi_chip_response(writecnt, readcnt, writearr,
891 					      readarr, emu_data)) {
892 			msg_pdbg("Invalid command sent to flash chip!\n");
893 			return 1;
894 		}
895 		break;
896 	default:
897 		break;
898 	}
899 	msg_pspew(" reading %u bytes:", readcnt);
900 	for (i = 0; i < readcnt; i++)
901 		msg_pspew(" 0x%02x", readarr[i]);
902 	msg_pspew("\n");
903 
904 	default_delay(((writecnt + readcnt) * emu_data->delay_ns) / 1000);
905 	return 0;
906 }
907 
dummy_shutdown(void * data)908 static int dummy_shutdown(void *data)
909 {
910 	msg_pspew("%s\n", __func__);
911 	struct emu_data *emu_data = (struct emu_data *)data;
912 
913 	emu_data->refs_cnt--;
914 	if (emu_data->refs_cnt != 0)
915 		return 0;
916 
917 	if (emu_data->emu_chip != EMULATE_NONE) {
918 		if (emu_data->emu_persistent_image && emu_data->emu_modified) {
919 			msg_pdbg("Writing %s\n", emu_data->emu_persistent_image);
920 			write_buf_to_file(emu_data->flashchip_contents,
921 					  emu_data->emu_chip_size,
922 					  emu_data->emu_persistent_image);
923 		}
924 		free(emu_data->emu_persistent_image);
925 		free(emu_data->flashchip_contents);
926 	}
927 	free(data);
928 	return 0;
929 }
930 
dummy_nop_delay(const struct flashctx * flash,unsigned int usecs)931 static void dummy_nop_delay(const struct flashctx *flash, unsigned int usecs)
932 {
933 }
934 
dummy_wp_read_cfg(struct flashrom_wp_cfg * cfg,struct flashctx * flash)935 static enum flashrom_wp_result dummy_wp_read_cfg(struct flashrom_wp_cfg *cfg, struct flashctx *flash)
936 {
937 	cfg->mode = FLASHROM_WP_MODE_DISABLED;
938 	cfg->range.start = 0;
939 	cfg->range.len = 0;
940 
941 	return FLASHROM_WP_OK;
942 }
943 
dummy_wp_write_cfg(struct flashctx * flash,const struct flashrom_wp_cfg * cfg)944 static enum flashrom_wp_result dummy_wp_write_cfg(struct flashctx *flash, const struct flashrom_wp_cfg *cfg)
945 {
946 	if (cfg->mode != FLASHROM_WP_MODE_DISABLED)
947 		return FLASHROM_WP_ERR_MODE_UNSUPPORTED;
948 
949 	if (cfg->range.start != 0 || cfg->range.len != 0)
950 		return FLASHROM_WP_ERR_RANGE_UNSUPPORTED;
951 
952 	return FLASHROM_WP_OK;
953 }
954 
dummy_wp_get_available_ranges(struct flashrom_wp_ranges ** list,struct flashctx * flash)955 static enum flashrom_wp_result dummy_wp_get_available_ranges(struct flashrom_wp_ranges **list, struct flashctx *flash)
956 {
957 	/* Not supported */
958 	return FLASHROM_WP_ERR_RANGE_LIST_UNAVAILABLE;
959 }
960 
961 
962 static const struct spi_master spi_master_dummyflasher = {
963 	.map_flash_region	= dummy_map,
964 	.unmap_flash_region	= dummy_unmap,
965 	.features	= SPI_MASTER_4BA,
966 	.max_data_read	= MAX_DATA_READ_UNLIMITED,
967 	.max_data_write	= MAX_DATA_UNSPECIFIED,
968 	.command	= dummy_spi_send_command,
969 	.read		= default_spi_read,
970 	.write_256	= dummy_spi_write_256,
971 	.shutdown	= dummy_shutdown,
972 	.probe_opcode	= dummy_spi_probe_opcode,
973 	.delay		= dummy_nop_delay,
974 };
975 
976 static const struct par_master par_master_dummyflasher = {
977 	.map_flash_region	= dummy_map,
978 	.unmap_flash_region	= dummy_unmap,
979 	.chip_readb	= dummy_chip_readb,
980 	.chip_readw	= dummy_chip_readw,
981 	.chip_readl	= dummy_chip_readl,
982 	.chip_readn	= dummy_chip_readn,
983 	.chip_writeb	= dummy_chip_writeb,
984 	.chip_writew	= dummy_chip_writew,
985 	.chip_writel	= dummy_chip_writel,
986 	.chip_writen	= dummy_chip_writen,
987 	.shutdown	= dummy_shutdown,
988 	.delay		= dummy_nop_delay,
989 };
990 
991 static const struct opaque_master opaque_master_dummyflasher = {
992 	.probe		= probe_variable_size,
993 	.read		= dummy_opaque_read,
994 	.write		= dummy_opaque_write,
995 	.erase		= dummy_opaque_erase,
996 	.shutdown	= dummy_shutdown,
997 	.delay		= dummy_nop_delay,
998 	.wp_read_cfg	= dummy_wp_read_cfg,
999 	.wp_write_cfg	= dummy_wp_write_cfg,
1000 	.wp_get_ranges	= dummy_wp_get_available_ranges,
1001 };
1002 
init_data(const struct programmer_cfg * cfg,struct emu_data * data,enum chipbustype * dummy_buses_supported)1003 static int init_data(const struct programmer_cfg *cfg,
1004 		struct emu_data *data, enum chipbustype *dummy_buses_supported)
1005 {
1006 	char *bustext = NULL;
1007 	char *tmp = NULL;
1008 	unsigned int i;
1009 	char *endptr;
1010 	char *status = NULL;
1011 	int size = -1;  /* size for VARIABLE_SIZE chip device */
1012 
1013 	bustext = extract_programmer_param_str(cfg, "bus");
1014 	msg_pdbg("Requested buses are: %s\n", bustext ? bustext : "default");
1015 	if (!bustext)
1016 		bustext = strdup("parallel+lpc+fwh+spi+prog");
1017 	/* Convert the parameters to lowercase. */
1018 	tolower_string(bustext);
1019 
1020 	*dummy_buses_supported = BUS_NONE;
1021 	if (strstr(bustext, "parallel")) {
1022 		*dummy_buses_supported |= BUS_PARALLEL;
1023 		msg_pdbg("Enabling support for %s flash.\n", "parallel");
1024 	}
1025 	if (strstr(bustext, "lpc")) {
1026 		*dummy_buses_supported |= BUS_LPC;
1027 		msg_pdbg("Enabling support for %s flash.\n", "LPC");
1028 	}
1029 	if (strstr(bustext, "fwh")) {
1030 		*dummy_buses_supported |= BUS_FWH;
1031 		msg_pdbg("Enabling support for %s flash.\n", "FWH");
1032 	}
1033 	if (strstr(bustext, "spi")) {
1034 		*dummy_buses_supported |= BUS_SPI;
1035 		msg_pdbg("Enabling support for %s flash.\n", "SPI");
1036 	}
1037 	if (strstr(bustext, "prog")) {
1038 		*dummy_buses_supported |= BUS_PROG;
1039 		msg_pdbg("Enabling support for %s flash.\n", "PROG");
1040 	}
1041 	if (*dummy_buses_supported == BUS_NONE)
1042 		msg_pdbg("Support for all flash bus types disabled.\n");
1043 	free(bustext);
1044 
1045 	tmp = extract_programmer_param_str(cfg, "spi_write_256_chunksize");
1046 	if (tmp) {
1047 		data->spi_write_256_chunksize = strtoul(tmp, &endptr, 0);
1048 		if (*endptr != '\0' || data->spi_write_256_chunksize < 1) {
1049 			msg_perr("invalid spi_write_256_chunksize\n");
1050 			free(tmp);
1051 			return 1;
1052 		}
1053 	}
1054 	free(tmp);
1055 
1056 	tmp = extract_programmer_param_str(cfg, "spi_blacklist");
1057 	if (tmp) {
1058 		i = strlen(tmp);
1059 		if (!strncmp(tmp, "0x", 2)) {
1060 			i -= 2;
1061 			memmove(tmp, tmp + 2, i + 1);
1062 		}
1063 		if ((i > 512) || (i % 2)) {
1064 			msg_perr("Invalid SPI command blacklist length\n");
1065 			free(tmp);
1066 			return 1;
1067 		}
1068 		data->spi_blacklist_size = i / 2;
1069 		for (i = 0; i < data->spi_blacklist_size * 2; i++) {
1070 			if (!isxdigit((unsigned char)tmp[i])) {
1071 				msg_perr("Invalid char \"%c\" in SPI command "
1072 					 "blacklist\n", tmp[i]);
1073 				free(tmp);
1074 				return 1;
1075 			}
1076 		}
1077 		for (i = 0; i < data->spi_blacklist_size; i++) {
1078 			unsigned int tmp2;
1079 			/* SCNx8 is apparently not supported by MSVC (and thus
1080 			 * MinGW), so work around it with an extra variable
1081 			 */
1082 			sscanf(tmp + i * 2, "%2x", &tmp2);
1083 			data->spi_blacklist[i] = (uint8_t)tmp2;
1084 		}
1085 		msg_pdbg("SPI blacklist is ");
1086 		for (i = 0; i < data->spi_blacklist_size; i++)
1087 			msg_pdbg("%02x ", data->spi_blacklist[i]);
1088 		msg_pdbg(", size %u\n", data->spi_blacklist_size);
1089 	}
1090 	free(tmp);
1091 
1092 	tmp = extract_programmer_param_str(cfg, "spi_ignorelist");
1093 	if (tmp) {
1094 		i = strlen(tmp);
1095 		if (!strncmp(tmp, "0x", 2)) {
1096 			i -= 2;
1097 			memmove(tmp, tmp + 2, i + 1);
1098 		}
1099 		if ((i > 512) || (i % 2)) {
1100 			msg_perr("Invalid SPI command ignorelist length\n");
1101 			free(tmp);
1102 			return 1;
1103 		}
1104 		data->spi_ignorelist_size = i / 2;
1105 		for (i = 0; i < data->spi_ignorelist_size * 2; i++) {
1106 			if (!isxdigit((unsigned char)tmp[i])) {
1107 				msg_perr("Invalid char \"%c\" in SPI command "
1108 					 "ignorelist\n", tmp[i]);
1109 				free(tmp);
1110 				return 1;
1111 			}
1112 		}
1113 		for (i = 0; i < data->spi_ignorelist_size; i++) {
1114 			unsigned int tmp2;
1115 			/* SCNx8 is apparently not supported by MSVC (and thus
1116 			 * MinGW), so work around it with an extra variable
1117 			 */
1118 			sscanf(tmp + i * 2, "%2x", &tmp2);
1119 			data->spi_ignorelist[i] = (uint8_t)tmp2;
1120 		}
1121 		msg_pdbg("SPI ignorelist is ");
1122 		for (i = 0; i < data->spi_ignorelist_size; i++)
1123 			msg_pdbg("%02x ", data->spi_ignorelist[i]);
1124 		msg_pdbg(", size %u\n", data->spi_ignorelist_size);
1125 	}
1126 	free(tmp);
1127 
1128 	/* frequency to emulate in Hz (default), KHz, or MHz */
1129 	tmp = extract_programmer_param_str(cfg, "freq");
1130 	if (tmp) {
1131 		unsigned long long freq;
1132 		char *units = tmp;
1133 		char *end = tmp + strlen(tmp);
1134 
1135 		errno = 0;
1136 		freq = strtoul(tmp, &units, 0);
1137 		if (errno) {
1138 			msg_perr("Invalid frequency \"%s\", %s\n",
1139 					tmp, strerror(errno));
1140 			free(tmp);
1141 			return 1;
1142 		}
1143 
1144 		if ((units > tmp) && (units < end)) {
1145 			bool units_valid = false;
1146 
1147 			if (units < end - 3) {
1148 				;
1149 			} else if (units == end - 2) {
1150 				if (!strcasecmp(units, "hz"))
1151 					units_valid = true;
1152 			} else if (units == end - 3) {
1153 				if (!strcasecmp(units, "khz")) {
1154 					freq *= 1000;
1155 					units_valid = true;
1156 				} else if (!strcasecmp(units, "mhz")) {
1157 					freq *= 1000000;
1158 					units_valid = true;
1159 				}
1160 			}
1161 
1162 			if (!units_valid) {
1163 				msg_perr("Invalid units: %s\n", units);
1164 				free(tmp);
1165 				return 1;
1166 			}
1167 		}
1168 
1169 		if (freq == 0 || freq > 8000000000) {
1170 			msg_perr("%s: invalid value %llu for freq parameter\n", __func__, freq);
1171 			free(tmp);
1172 			return 1;
1173 		}
1174 		/* Assume we only work with bytes and transfer at 1 bit/Hz */
1175 		data->delay_ns = (1000000000ull * 8) / freq;
1176 	}
1177 	free(tmp);
1178 
1179 	tmp = extract_programmer_param_str(cfg, "size");
1180 	if (tmp) {
1181 		size = strtol(tmp, NULL, 10);
1182 		if (size <= 0 || (size % 1024 != 0)) {
1183 			msg_perr("%s: Chip size is not a multiple of 1024: %s\n",
1184 					 __func__, tmp);
1185 			free(tmp);
1186 			return 1;
1187 		}
1188 		free(tmp);
1189 	}
1190 
1191 	tmp = extract_programmer_param_str(cfg, "hwwp");
1192 	if (tmp) {
1193 		if (!strcmp(tmp, "yes")) {
1194 			msg_pdbg("Emulated chip will have hardware WP enabled\n");
1195 			data->hwwp = true;
1196 		} else if (!strcmp(tmp, "no")) {
1197 			msg_pdbg("Emulated chip will have hardware WP disabled\n");
1198 		} else {
1199 			msg_perr("hwwp can be \"yes\" or \"no\"\n");
1200 			free(tmp);
1201 			return 1;
1202 		}
1203 		free(tmp);
1204 	}
1205 
1206 	tmp = extract_programmer_param_str(cfg, "emulate");
1207 	if (!tmp) {
1208 		if (size != -1) {
1209 			msg_perr("%s: size parameter is only valid for VARIABLE_SIZE chip.\n", __func__);
1210 			return 1;
1211 		}
1212 		msg_pdbg("Not emulating any flash chip.\n");
1213 		/* Nothing else to do. */
1214 		return 0;
1215 	}
1216 
1217 	if (!strcmp(tmp, "M25P10.RES")) {
1218 		data->emu_chip = EMULATE_ST_M25P10_RES;
1219 		data->emu_chip_size = 128 * 1024;
1220 		data->emu_max_byteprogram_size = 128;
1221 		data->emu_max_aai_size = 0;
1222 		data->emu_status_len = 1;
1223 		data->emu_jedec_se_size = 0;
1224 		data->emu_jedec_be_52_size = 0;
1225 		data->emu_jedec_be_d8_size = 32 * 1024;
1226 		data->emu_jedec_ce_60_size = 0;
1227 		data->emu_jedec_ce_c7_size = data->emu_chip_size;
1228 		msg_pdbg("Emulating ST M25P10.RES SPI flash chip (RES, page "
1229 			 "write)\n");
1230 	}
1231 	if (!strcmp(tmp, "SST25VF040.REMS")) {
1232 		data->emu_chip = EMULATE_SST_SST25VF040_REMS;
1233 		data->emu_chip_size = 512 * 1024;
1234 		data->emu_max_byteprogram_size = 1;
1235 		data->emu_max_aai_size = 0;
1236 		data->emu_status_len = 1;
1237 		data->emu_jedec_se_size = 4 * 1024;
1238 		data->emu_jedec_be_52_size = 32 * 1024;
1239 		data->emu_jedec_be_d8_size = 0;
1240 		data->emu_jedec_ce_60_size = data->emu_chip_size;
1241 		data->emu_jedec_ce_c7_size = 0;
1242 		msg_pdbg("Emulating SST SST25VF040.REMS SPI flash chip (REMS, "
1243 			 "byte write)\n");
1244 	}
1245 	if (!strcmp(tmp, "SST25VF032B")) {
1246 		data->emu_chip = EMULATE_SST_SST25VF032B;
1247 		data->emu_chip_size = 4 * 1024 * 1024;
1248 		data->emu_max_byteprogram_size = 1;
1249 		data->emu_max_aai_size = 2;
1250 		data->emu_status_len = 1;
1251 		data->emu_jedec_se_size = 4 * 1024;
1252 		data->emu_jedec_be_52_size = 32 * 1024;
1253 		data->emu_jedec_be_d8_size = 64 * 1024;
1254 		data->emu_jedec_ce_60_size = data->emu_chip_size;
1255 		data->emu_jedec_ce_c7_size = data->emu_chip_size;
1256 		msg_pdbg("Emulating SST SST25VF032B SPI flash chip (RDID, AAI "
1257 			 "write)\n");
1258 	}
1259 	if (!strcmp(tmp, "MX25L6436")) {
1260 		data->emu_chip = EMULATE_MACRONIX_MX25L6436;
1261 		data->emu_chip_size = 8 * 1024 * 1024;
1262 		data->emu_max_byteprogram_size = 256;
1263 		data->emu_max_aai_size = 0;
1264 		data->emu_status_len = 1;
1265 		data->emu_jedec_se_size = 4 * 1024;
1266 		data->emu_jedec_be_52_size = 32 * 1024;
1267 		data->emu_jedec_be_d8_size = 64 * 1024;
1268 		data->emu_jedec_ce_60_size = data->emu_chip_size;
1269 		data->emu_jedec_ce_c7_size = data->emu_chip_size;
1270 		msg_pdbg("Emulating Macronix MX25L6436 SPI flash chip (RDID, "
1271 			 "SFDP)\n");
1272 	}
1273 	if (!strcmp(tmp, "W25Q128FV")) {
1274 		data->emu_chip = EMULATE_WINBOND_W25Q128FV;
1275 		data->emu_wrsr_ext2 = true;
1276 		data->emu_chip_size = 16 * 1024 * 1024;
1277 		data->emu_max_byteprogram_size = 256;
1278 		data->emu_max_aai_size = 0;
1279 		data->emu_status_len = 3;
1280 		data->emu_jedec_se_size = 4 * 1024;
1281 		data->emu_jedec_be_52_size = 32 * 1024;
1282 		data->emu_jedec_be_d8_size = 64 * 1024;
1283 		data->emu_jedec_ce_60_size = data->emu_chip_size;
1284 		data->emu_jedec_ce_c7_size = data->emu_chip_size;
1285 		msg_pdbg("Emulating Winbond W25Q128FV SPI flash chip (RDID)\n");
1286 	}
1287 	if (!strcmp(tmp, "S25FL128L")) {
1288 		data->emu_chip = EMULATE_SPANSION_S25FL128L;
1289 		data->emu_wrsr_ext2 = true;
1290 		data->emu_wrsr_ext3 = true;
1291 		data->emu_chip_size = 16 * 1024 * 1024;
1292 		data->emu_max_byteprogram_size = 256;
1293 		data->emu_max_aai_size = 0;
1294 		data->emu_status_len = 3;
1295 		data->emu_jedec_se_size = 4 * 1024;
1296 		data->emu_jedec_be_52_size = 32 * 1024;
1297 		data->emu_jedec_be_d8_size = 64 * 1024;
1298 		data->emu_jedec_ce_60_size = data->emu_chip_size;
1299 		data->emu_jedec_ce_c7_size = data->emu_chip_size;
1300 		msg_pdbg("Emulating Spansion S25FL128L SPI flash chip (RES, RDID, WP)\n");
1301 	}
1302 
1303 	/* The name of variable-size virtual chip. A 4 MiB flash example:
1304 	 *   flashrom -p dummy:emulate=VARIABLE_SIZE,size=4194304
1305 	 */
1306 	if (!strcmp(tmp, "VARIABLE_SIZE")) {
1307 		if (size == -1) {
1308 			msg_perr("%s: the size parameter is not given.\n", __func__);
1309 			free(tmp);
1310 			return 1;
1311 		}
1312 		data->emu_chip = EMULATE_VARIABLE_SIZE;
1313 		data->emu_chip_size = size;
1314 		msg_pdbg("Emulating generic SPI flash chip (size=%d bytes)\n",
1315 		         data->emu_chip_size);
1316 	} else if (size != -1) {
1317 		msg_perr("%s: size parameter is only valid for VARIABLE_SIZE chip.\n", __func__);
1318 		free(tmp);
1319 		return 1;
1320 	}
1321 
1322 	if (data->emu_chip == EMULATE_NONE) {
1323 		msg_perr("Invalid chip specified for emulation: %s\n", tmp);
1324 		free(tmp);
1325 		return 1;
1326 	}
1327 	free(tmp);
1328 
1329 	/* Should emulated flash erase to zero (yes/no)? */
1330 	tmp = extract_programmer_param_str(cfg, "erase_to_zero");
1331 	if (tmp) {
1332 		if (data->emu_chip != EMULATE_VARIABLE_SIZE) {
1333 			msg_perr("%s: erase_to_zero parameter is not valid for real chip.\n", __func__);
1334 			free(tmp);
1335 			return 1;
1336 		}
1337 		if (!strcmp(tmp, "yes")) {
1338 			msg_pdbg("Emulated chip will erase to 0x00\n");
1339 			data->erase_to_zero = true;
1340 		} else if (!strcmp(tmp, "no")) {
1341 			msg_pdbg("Emulated chip will erase to 0xff\n");
1342 		} else {
1343 			msg_perr("erase_to_zero can be \"yes\" or \"no\"\n");
1344 			free(tmp);
1345 			return 1;
1346 		}
1347 	}
1348 	free(tmp);
1349 
1350 	status = extract_programmer_param_str(cfg, "spi_status");
1351 	if (status) {
1352 		unsigned int emu_status;
1353 
1354 		errno = 0;
1355 		emu_status = strtoul(status, &endptr, 0);
1356 		if (errno != 0 || status == endptr) {
1357 			free(status);
1358 			msg_perr("Error: initial status register specified, "
1359 				 "but the value could not be converted.\n");
1360 			return 1;
1361 		}
1362 		free(status);
1363 
1364 		data->emu_status[0] = emu_status;
1365 		data->emu_status[1] = emu_status >> 8;
1366 		data->emu_status[2] = emu_status >> 16;
1367 
1368 		if (data->emu_status_len == 3) {
1369 			msg_pdbg("Initial status registers:\n"
1370 				 "\tSR1 is set to 0x%02x\n"
1371 				 "\tSR2 is set to 0x%02x\n"
1372 				 "\tSR3 is set to 0x%02x\n",
1373 				 data->emu_status[0], data->emu_status[1], data->emu_status[2]);
1374 		} else if (data->emu_status_len == 2) {
1375 			msg_pdbg("Initial status registers:\n"
1376 				 "\tSR1 is set to 0x%02x\n"
1377 				 "\tSR2 is set to 0x%02x\n",
1378 				 data->emu_status[0], data->emu_status[1]);
1379 		} else {
1380 			msg_pdbg("Initial status register is set to 0x%02x.\n",
1381 				 data->emu_status[0]);
1382 		}
1383 	}
1384 
1385 	data->flashchip_contents = malloc(data->emu_chip_size);
1386 	if (!data->flashchip_contents) {
1387 		msg_perr("Out of memory!\n");
1388 		return 1;
1389 	}
1390 
1391 	return 0;
1392 }
1393 
dummy_init(const struct programmer_cfg * cfg)1394 static int dummy_init(const struct programmer_cfg *cfg)
1395 {
1396 	int ret = 0;
1397 	struct stat image_stat;
1398 
1399 	struct emu_data *data = calloc(1, sizeof(*data));
1400 	if (!data) {
1401 		msg_perr("Out of memory!\n");
1402 		return 1;
1403 	}
1404 	data->emu_chip = EMULATE_NONE;
1405 	data->delay_ns = 0;
1406 	data->spi_write_256_chunksize = 256;
1407 
1408 	msg_pspew("%s\n", __func__);
1409 
1410 	enum chipbustype dummy_buses_supported;
1411 	if (init_data(cfg, data, &dummy_buses_supported)) {
1412 		free(data);
1413 		return 1;
1414 	}
1415 
1416 	if (data->emu_chip == EMULATE_NONE) {
1417 		msg_pdbg("Not emulating any flash chip.\n");
1418 		/* Nothing else to do. */
1419 		goto dummy_init_out;
1420 	}
1421 
1422 	msg_pdbg("Filling fake flash chip with 0x%02x, size %i\n",
1423 			data->erase_to_zero ? 0x00 : 0xff, data->emu_chip_size);
1424 	memset(data->flashchip_contents, data->erase_to_zero ? 0x00 : 0xff, data->emu_chip_size);
1425 
1426 	/* Will be freed by shutdown function if necessary. */
1427 	data->emu_persistent_image = extract_programmer_param_str(cfg, "image");
1428 	if (!data->emu_persistent_image) {
1429 		/* Nothing else to do. */
1430 		goto dummy_init_out;
1431 	}
1432 	/* We will silently (in default verbosity) ignore the file if it does not exist (yet) or the size does
1433 	 * not match the emulated chip. */
1434 	if (!stat(data->emu_persistent_image, &image_stat)) {
1435 		msg_pdbg("Found persistent image %s, %jd B ",
1436 			 data->emu_persistent_image, (intmax_t)image_stat.st_size);
1437 		if ((uintmax_t)image_stat.st_size == data->emu_chip_size) {
1438 			msg_pdbg("matches.\n");
1439 			msg_pdbg("Reading %s\n", data->emu_persistent_image);
1440 			if (read_buf_from_file(data->flashchip_contents, data->emu_chip_size,
1441 					   data->emu_persistent_image)) {
1442 				msg_perr("Unable to read %s\n", data->emu_persistent_image);
1443 				free(data->emu_persistent_image);
1444 				free(data->flashchip_contents);
1445 				free(data);
1446 				return 1;
1447 			}
1448 		} else {
1449 			msg_pdbg("doesn't match.\n");
1450 		}
1451 	}
1452 
1453 dummy_init_out:
1454 	if (dummy_buses_supported & BUS_PROG) {
1455 		data->refs_cnt++;
1456 		ret |= register_opaque_master(&opaque_master_dummyflasher, data);
1457 	}
1458 	if ((dummy_buses_supported & BUS_NONSPI) && !ret) {
1459 		data->refs_cnt++;
1460 		ret |= register_par_master(&par_master_dummyflasher,
1461 					   dummy_buses_supported & BUS_NONSPI,
1462 					   data);
1463 	}
1464 	if ((dummy_buses_supported & BUS_SPI) && !ret) {
1465 		data->refs_cnt++;
1466 		ret |= register_spi_master(&spi_master_dummyflasher, data);
1467 	}
1468 
1469 	return ret;
1470 }
1471 
1472 const struct programmer_entry programmer_dummy = {
1473 	.name			= "dummy",
1474 	.type			= OTHER,
1475 				/* FIXME */
1476 	.devs.note		= "Dummy device, does nothing and logs all accesses\n",
1477 	.init			= dummy_init,
1478 };
1479