OLD | NEW |
---|---|
1 /* | 1 /* |
2 * This file is part of the flashrom project. | 2 * This file is part of the flashrom project. |
3 * | 3 * |
4 * Copyright (C) 2009,2010 Carl-Daniel Hailfinger | 4 * Copyright (C) 2009,2010 Carl-Daniel Hailfinger |
5 * | 5 * |
6 * This program is free software; you can redistribute it and/or modify | 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 | 7 * it under the terms of the GNU General Public License as published by |
8 * the Free Software Foundation; version 2 of the License. | 8 * the Free Software Foundation; version 2 of the License. |
9 * | 9 * |
10 * This program is distributed in the hope that it will be useful, | 10 * This program is distributed in the hope that it will be useful, |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 * GNU General Public License for more details. | 13 * GNU General Public License for more details. |
14 * | 14 * |
15 * You should have received a copy of the GNU General Public License | 15 * You should have received a copy of the GNU General Public License |
16 * along with this program; if not, write to the Free Software | 16 * along with this program; if not, write to the Free Software |
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
18 */ | 18 */ |
19 | 19 |
20 #include <string.h> | 20 #include <string.h> |
21 #include <stdlib.h> | 21 #include <stdlib.h> |
22 #include "flash.h" | 22 #include "flash.h" |
23 #include "chipdrivers.h" | 23 #include "chipdrivers.h" |
24 #include "programmer.h" | 24 #include "programmer.h" |
25 #include "flashchips.h" | |
25 | 26 |
26 /* Remove the #define below if you don't want SPI flash chip emulation. */ | 27 /* Remove the #define below if you don't want SPI flash chip emulation. */ |
27 #define EMULATE_SPI_CHIP 1 | 28 #define EMULATE_SPI_CHIP 1 |
28 | 29 |
29 #if EMULATE_SPI_CHIP | 30 #if EMULATE_SPI_CHIP |
30 #define EMULATE_CHIP 1 | 31 #define EMULATE_CHIP 1 |
31 #include "spi.h" | 32 #include "spi.h" |
32 #endif | 33 #endif |
33 | 34 |
34 #if EMULATE_CHIP | 35 #if EMULATE_CHIP |
35 #include <sys/types.h> | 36 #include <sys/types.h> |
36 #include <sys/stat.h> | 37 #include <sys/stat.h> |
37 #endif | 38 #endif |
38 | 39 |
39 #if EMULATE_CHIP | 40 #if EMULATE_CHIP |
41 /* The name of variable-size virtual chip. A 4MB flash example: | |
42 * flashrom -p dummy:emulate=VIRTUAL-4194304 | |
43 */ | |
44 #define VIRTUAL_CHIP_NAME "VIRTUAL" | |
45 #endif | |
46 | |
47 #if EMULATE_CHIP | |
40 static uint8_t *flashchip_contents = NULL; | 48 static uint8_t *flashchip_contents = NULL; |
41 enum emu_chip { | 49 enum emu_chip { |
42 EMULATE_NONE, | 50 EMULATE_NONE, |
43 EMULATE_ST_M25P10_RES, | 51 EMULATE_ST_M25P10_RES, |
44 EMULATE_SST_SST25VF040_REMS, | 52 EMULATE_SST_SST25VF040_REMS, |
45 EMULATE_SST_SST25VF032B, | 53 EMULATE_SST_SST25VF032B, |
54 EMULATE_VIRTUAL, | |
Stefan Reinauer
2011/04/01 17:47:06
Since this emulates a Winbond, should it be called
Louis
2011/04/02 01:48:52
My initial attempt is to emulate any size of flash
dhendrix
2011/04/02 23:43:32
SGTM.
Louis
2011/04/07 02:28:14
Done.
| |
46 }; | 55 }; |
47 static enum emu_chip emu_chip = EMULATE_NONE; | 56 static enum emu_chip emu_chip = EMULATE_NONE; |
48 static char *emu_persistent_image = NULL; | 57 static char *emu_persistent_image = NULL; |
49 static int emu_chip_size = 0; | 58 static int emu_chip_size = 0; |
50 #if EMULATE_SPI_CHIP | 59 #if EMULATE_SPI_CHIP |
51 static int emu_max_byteprogram_size = 0; | 60 static int emu_max_byteprogram_size = 0; |
52 static int emu_max_aai_size = 0; | 61 static int emu_max_aai_size = 0; |
53 static int emu_jedec_se_size = 0; | 62 static int emu_jedec_se_size = 0; |
54 static int emu_jedec_be_52_size = 0; | 63 static int emu_jedec_be_52_size = 0; |
55 static int emu_jedec_be_d8_size = 0; | 64 static int emu_jedec_be_d8_size = 0; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 emu_max_byteprogram_size = 1; | 158 emu_max_byteprogram_size = 1; |
150 emu_max_aai_size = 2; | 159 emu_max_aai_size = 2; |
151 emu_jedec_se_size = 4 * 1024; | 160 emu_jedec_se_size = 4 * 1024; |
152 emu_jedec_be_52_size = 32 * 1024; | 161 emu_jedec_be_52_size = 32 * 1024; |
153 emu_jedec_be_d8_size = 64 * 1024; | 162 emu_jedec_be_d8_size = 64 * 1024; |
154 emu_jedec_ce_60_size = emu_chip_size; | 163 emu_jedec_ce_60_size = emu_chip_size; |
155 emu_jedec_ce_c7_size = emu_chip_size; | 164 emu_jedec_ce_c7_size = emu_chip_size; |
156 msg_pdbg("Emulating SST SST25VF032B SPI flash chip (RDID, AAI " | 165 msg_pdbg("Emulating SST SST25VF032B SPI flash chip (RDID, AAI " |
157 "write)\n"); | 166 "write)\n"); |
158 } | 167 } |
168 if (!strncmp(tmp, VIRTUAL_CHIP_NAME, strlen(VIRTUAL_CHIP_NAME))) { | |
169 char *size_str; | |
170 emu_chip = EMULATE_VIRTUAL; | |
171 strtok(tmp, "-"); // prefix is discarded. | |
172 if (NULL == (size_str = strtok(NULL, "-")) || !*size_str) { | |
173 msg_perr("Please specify flash size, " | |
174 "example: %s-65536\n", VIRTUAL_CHIP_NAME); | |
Stefan Reinauer
2011/04/01 17:47:06
Can we use KB instead of bytes here? 64, 128, 256,
Louis
2011/04/02 01:48:52
This is intentional for
-p dummy:VIRTUAL-`stat
dhendrix
2011/04/02 23:43:32
Good point... if desired, maybe we can add somethi
dhendrix
2011/04/02 23:43:32
I think it would be better to treat size (and pote
Louis
2011/04/07 02:28:14
Done.
Louis
2011/04/07 02:28:14
Done.
| |
175 free(tmp); | |
176 return 1; | |
177 } | |
178 emu_chip_size = atoi(size_str); | |
179 if (emu_chip_size & (emu_chip_size - 1)) { | |
180 msg_perr("Specified flash size is not power of 2.\n"); | |
181 free(tmp); | |
182 return 1; | |
183 } | |
184 emu_max_byteprogram_size = 256; | |
185 emu_max_aai_size = 0; | |
186 emu_jedec_se_size = 4 * 1024; | |
187 emu_jedec_be_52_size = 32 * 1024; | |
188 emu_jedec_be_d8_size = 64 * 1024; | |
189 emu_jedec_ce_60_size = emu_chip_size; | |
190 emu_jedec_ce_c7_size = emu_chip_size; | |
191 msg_pdbg("Emulating virtual SPI flash chip (size=%d bytes)\n", | |
192 emu_chip_size); | |
193 } | |
159 #endif | 194 #endif |
160 if (emu_chip == EMULATE_NONE) { | 195 if (emu_chip == EMULATE_NONE) { |
161 msg_perr("Invalid chip specified for emulation: %s\n", tmp); | 196 msg_perr("Invalid chip specified for emulation: %s\n", tmp); |
162 free(tmp); | 197 free(tmp); |
163 return 1; | 198 return 1; |
164 } | 199 } |
165 free(tmp); | 200 free(tmp); |
166 flashchip_contents = malloc(emu_chip_size); | 201 flashchip_contents = malloc(emu_chip_size); |
167 if (!flashchip_contents) { | 202 if (!flashchip_contents) { |
168 msg_perr("Out of memory!\n"); | 203 msg_perr("Out of memory!\n"); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
298 case JEDEC_REMS: | 333 case JEDEC_REMS: |
299 if (emu_chip != EMULATE_SST_SST25VF040_REMS) | 334 if (emu_chip != EMULATE_SST_SST25VF040_REMS) |
300 break; | 335 break; |
301 /* Respond with SST_SST25VF040_REMS. */ | 336 /* Respond with SST_SST25VF040_REMS. */ |
302 if (readcnt > 0) | 337 if (readcnt > 0) |
303 readarr[0] = 0xbf; | 338 readarr[0] = 0xbf; |
304 if (readcnt > 1) | 339 if (readcnt > 1) |
305 readarr[1] = 0x44; | 340 readarr[1] = 0x44; |
306 break; | 341 break; |
307 case JEDEC_RDID: | 342 case JEDEC_RDID: |
308 » » if (emu_chip != EMULATE_SST_SST25VF032B) | 343 » » if (emu_chip == EMULATE_SST_SST25VF032B) { |
309 » » » break; | 344 » » » /* Respond with SST_SST25VF032B. */ |
310 » » /* Respond with SST_SST25VF032B. */ | 345 » » » if (readcnt > 0) |
311 » » if (readcnt > 0) | 346 » » » » readarr[0] = 0xbf; |
312 » » » readarr[0] = 0xbf; | 347 » » » if (readcnt > 1) |
313 » » if (readcnt > 1) | 348 » » » » readarr[1] = 0x25; |
314 » » » readarr[1] = 0x25; | 349 » » » if (readcnt > 2) |
315 » » if (readcnt > 2) | 350 » » » » readarr[2] = 0x4a; |
316 » » » readarr[2] = 0x4a; | 351 » » } else if (emu_chip == EMULATE_VIRTUAL) { |
352 » » » /* Winbond W25X series flashes are easy to map. | |
353 » » » * 128KB -- ID: 0x3011 | |
354 » » » * 256KB -- ID: 0x3012 | |
355 » » » * : : | |
356 » » » * 8192KB -- ID: 0x3017 | |
357 » » » * TODO: map more chips in future for other sizes. | |
Stefan Reinauer
2011/04/01 17:47:06
Should we make sure we only pass sizes supported b
Louis
2011/04/02 01:48:52
Will refine this to support any size.
On 2011/04/
| |
358 » » » */ | |
359 » » » uint16_t dev_id = WINBOND_NEX_W25X10; | |
360 » » » int size = emu_chip_size >> 17; | |
361 » » » for (; size >>= 1; dev_id++); | |
362 » » » if (readcnt > 0) readarr[0] = WINBOND_NEX_ID; | |
363 » » » if (readcnt > 1) readarr[1] = dev_id >> 8; | |
364 » » » if (readcnt > 2) readarr[2] = dev_id & 0xff; | |
365 » » } | |
317 break; | 366 break; |
318 case JEDEC_RDSR: | 367 case JEDEC_RDSR: |
319 memset(readarr, 0, readcnt); | 368 memset(readarr, 0, readcnt); |
320 if (aai_active) | 369 if (aai_active) |
321 memset(readarr, 1 << 6, readcnt); | 370 memset(readarr, 1 << 6, readcnt); |
322 break; | 371 break; |
323 case JEDEC_READ: | 372 case JEDEC_READ: |
324 offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3]; | 373 offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3]; |
325 /* Truncate to emu_chip_size. */ | 374 /* Truncate to emu_chip_size. */ |
326 offs %= emu_chip_size; | 375 offs %= emu_chip_size; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
488 for (i = 0; i < writecnt; i++) | 537 for (i = 0; i < writecnt; i++) |
489 msg_pspew(" 0x%02x", writearr[i]); | 538 msg_pspew(" 0x%02x", writearr[i]); |
490 | 539 |
491 /* Response for unknown commands and missing chip is 0xff. */ | 540 /* Response for unknown commands and missing chip is 0xff. */ |
492 memset(readarr, 0xff, readcnt); | 541 memset(readarr, 0xff, readcnt); |
493 #if EMULATE_SPI_CHIP | 542 #if EMULATE_SPI_CHIP |
494 switch (emu_chip) { | 543 switch (emu_chip) { |
495 case EMULATE_ST_M25P10_RES: | 544 case EMULATE_ST_M25P10_RES: |
496 case EMULATE_SST_SST25VF040_REMS: | 545 case EMULATE_SST_SST25VF040_REMS: |
497 case EMULATE_SST_SST25VF032B: | 546 case EMULATE_SST_SST25VF032B: |
547 case EMULATE_VIRTUAL: | |
498 if (emulate_spi_chip_response(writecnt, readcnt, writearr, | 548 if (emulate_spi_chip_response(writecnt, readcnt, writearr, |
499 readarr)) { | 549 readarr)) { |
500 msg_perr("Invalid command sent to flash chip!\n"); | 550 msg_perr("Invalid command sent to flash chip!\n"); |
501 return 1; | 551 return 1; |
502 } | 552 } |
503 break; | 553 break; |
504 default: | 554 default: |
505 break; | 555 break; |
506 } | 556 } |
507 #endif | 557 #endif |
508 msg_pspew(" reading %u bytes:", readcnt); | 558 msg_pspew(" reading %u bytes:", readcnt); |
509 for (i = 0; i < readcnt; i++) { | 559 for (i = 0; i < readcnt; i++) { |
510 msg_pspew(" 0x%02x", readarr[i]); | 560 msg_pspew(" 0x%02x", readarr[i]); |
511 } | 561 } |
512 msg_pspew("\n"); | 562 msg_pspew("\n"); |
513 return 0; | 563 return 0; |
514 } | 564 } |
515 | 565 |
516 int dummy_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) | 566 int dummy_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) |
517 { | 567 { |
518 /* Maximum read length is unlimited, use 64kB. */ | 568 /* Maximum read length is unlimited, use 64kB. */ |
519 return spi_read_chunked(flash, buf, start, len, 64 * 1024); | 569 return spi_read_chunked(flash, buf, start, len, 64 * 1024); |
520 } | 570 } |
521 | 571 |
522 int dummy_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int le n) | 572 int dummy_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int le n) |
523 { | 573 { |
524 return spi_write_chunked(flash, buf, start, len, | 574 return spi_write_chunked(flash, buf, start, len, |
525 spi_write_256_chunksize); | 575 spi_write_256_chunksize); |
526 } | 576 } |
OLD | NEW |