Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(495)

Side by Side Diff: dummyflasher.c

Issue 6791015: Support variable-size SPI chip for dummy programmer. (Closed) Base URL: ssh://gitrw.chromium.org:9222/flashrom.git@master
Patch Set: refine according to code review Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chipdrivers.h ('k') | flashchips.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
38
39 #if EMULATE_SPI_CHIP
40 /* The name of variable-size virtual chip. A 4MB flash example:
41 * flashrom -p dummy:emulate=VARIABLE_SIZE,size=4194304
42 */
43 #define VARIABLE_SIZE_CHIP_NAME "VARIABLE_SIZE"
44 #endif
37 #endif 45 #endif
38 46
39 #if EMULATE_CHIP 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_VARIABLE_SIZE,
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;
56 static int emu_jedec_ce_60_size = 0; 65 static int emu_jedec_ce_60_size = 0;
57 static int emu_jedec_ce_c7_size = 0; 66 static int emu_jedec_ce_c7_size = 0;
58 #endif 67 #endif
59 #endif 68 #endif
60 69
61 static int spi_write_256_chunksize = 256; 70 static int spi_write_256_chunksize = 256;
62 71
63 int dummy_init(void) 72 int dummy_init(void)
64 { 73 {
65 char *bustext = NULL; 74 char *bustext = NULL;
66 char *tmp = NULL; 75 char *tmp = NULL;
67 #if EMULATE_CHIP 76 #if EMULATE_CHIP
68 struct stat image_stat; 77 struct stat image_stat;
78 #if EMULATE_SPI_CHIP
79 int size = -1; /* size for generic chip */
80 #endif
69 #endif 81 #endif
70 82
71 msg_pspew("%s\n", __func__); 83 msg_pspew("%s\n", __func__);
72 84
73 bustext = extract_programmer_param("bus"); 85 bustext = extract_programmer_param("bus");
74 msg_pdbg("Requested buses are: %s\n", bustext ? bustext : "default"); 86 msg_pdbg("Requested buses are: %s\n", bustext ? bustext : "default");
75 if (!bustext) 87 if (!bustext)
76 bustext = strdup("parallel+lpc+fwh+spi"); 88 bustext = strdup("parallel+lpc+fwh+spi");
77 /* Convert the parameters to lowercase. */ 89 /* Convert the parameters to lowercase. */
78 tolower_string(bustext); 90 tolower_string(bustext);
(...skipping 24 matching lines...) Expand all
103 if (tmp) { 115 if (tmp) {
104 spi_write_256_chunksize = atoi(tmp); 116 spi_write_256_chunksize = atoi(tmp);
105 free(tmp); 117 free(tmp);
106 if (spi_write_256_chunksize < 1) { 118 if (spi_write_256_chunksize < 1) {
107 msg_perr("invalid spi_write_256_chunksize\n"); 119 msg_perr("invalid spi_write_256_chunksize\n");
108 return 1; 120 return 1;
109 } 121 }
110 } 122 }
111 123
112 #if EMULATE_CHIP 124 #if EMULATE_CHIP
125 #if EMULATE_SPI_CHIP
126 tmp = extract_programmer_param("size");
127 if (tmp) {
128 int multiplier = 1;
129 if (strlen(tmp)) {
130 int remove_last_char = 1;
131 switch (tmp[strlen(tmp) - 1]) {
132 case 'k': case 'K':
133 multiplier = 1024;
134 break;
135 case 'm': case 'M':
136 multiplier = 1024 * 1024;
137 break;
138 default:
139 remove_last_char = 0;
140 break;
141 }
142 if (remove_last_char) tmp[strlen(tmp) - 1] = '\0';
143 }
144 size = atoi(tmp) * multiplier;
145 }
146 #endif
147
113 tmp = extract_programmer_param("emulate"); 148 tmp = extract_programmer_param("emulate");
114 if (!tmp) { 149 if (!tmp) {
115 msg_pdbg("Not emulating any flash chip.\n"); 150 msg_pdbg("Not emulating any flash chip.\n");
116 /* Nothing else to do. */ 151 /* Nothing else to do. */
117 return 0; 152 return 0;
118 } 153 }
119 #if EMULATE_SPI_CHIP 154 #if EMULATE_SPI_CHIP
120 if (!strcmp(tmp, "M25P10.RES")) { 155 if (!strcmp(tmp, "M25P10.RES")) {
121 emu_chip = EMULATE_ST_M25P10_RES; 156 emu_chip = EMULATE_ST_M25P10_RES;
122 emu_chip_size = 128 * 1024; 157 emu_chip_size = 128 * 1024;
(...skipping 26 matching lines...) Expand all
149 emu_max_byteprogram_size = 1; 184 emu_max_byteprogram_size = 1;
150 emu_max_aai_size = 2; 185 emu_max_aai_size = 2;
151 emu_jedec_se_size = 4 * 1024; 186 emu_jedec_se_size = 4 * 1024;
152 emu_jedec_be_52_size = 32 * 1024; 187 emu_jedec_be_52_size = 32 * 1024;
153 emu_jedec_be_d8_size = 64 * 1024; 188 emu_jedec_be_d8_size = 64 * 1024;
154 emu_jedec_ce_60_size = emu_chip_size; 189 emu_jedec_ce_60_size = emu_chip_size;
155 emu_jedec_ce_c7_size = emu_chip_size; 190 emu_jedec_ce_c7_size = emu_chip_size;
156 msg_pdbg("Emulating SST SST25VF032B SPI flash chip (RDID, AAI " 191 msg_pdbg("Emulating SST SST25VF032B SPI flash chip (RDID, AAI "
157 "write)\n"); 192 "write)\n");
158 } 193 }
194 if (!strncmp(tmp, VARIABLE_SIZE_CHIP_NAME,
195 strlen(VARIABLE_SIZE_CHIP_NAME))) {
196 if (size == -1) {
197 msg_perr("%s: the size parameter is not given.\n",
198 __func__);
199 free(tmp);
200 return 1;
201 }
202 emu_chip = EMULATE_VARIABLE_SIZE;
203 emu_chip_size = size;
204 emu_max_byteprogram_size = 256;
205 emu_max_aai_size = 0;
206 emu_jedec_se_size = 4 * 1024;
207 emu_jedec_be_52_size = 32 * 1024;
208 emu_jedec_be_d8_size = 64 * 1024;
209 emu_jedec_ce_60_size = emu_chip_size;
210 emu_jedec_ce_c7_size = emu_chip_size;
211 msg_pdbg("Emulating generic SPI flash chip (size=%d bytes)\n",
212 emu_chip_size);
213 }
159 #endif 214 #endif
160 if (emu_chip == EMULATE_NONE) { 215 if (emu_chip == EMULATE_NONE) {
161 msg_perr("Invalid chip specified for emulation: %s\n", tmp); 216 msg_perr("Invalid chip specified for emulation: %s\n", tmp);
162 free(tmp); 217 free(tmp);
163 return 1; 218 return 1;
164 } 219 }
165 free(tmp); 220 free(tmp);
166 flashchip_contents = malloc(emu_chip_size); 221 flashchip_contents = malloc(emu_chip_size);
167 if (!flashchip_contents) { 222 if (!flashchip_contents) {
168 msg_perr("Out of memory!\n"); 223 msg_perr("Out of memory!\n");
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 case JEDEC_REMS: 353 case JEDEC_REMS:
299 if (emu_chip != EMULATE_SST_SST25VF040_REMS) 354 if (emu_chip != EMULATE_SST_SST25VF040_REMS)
300 break; 355 break;
301 /* Respond with SST_SST25VF040_REMS. */ 356 /* Respond with SST_SST25VF040_REMS. */
302 if (readcnt > 0) 357 if (readcnt > 0)
303 readarr[0] = 0xbf; 358 readarr[0] = 0xbf;
304 if (readcnt > 1) 359 if (readcnt > 1)
305 readarr[1] = 0x44; 360 readarr[1] = 0x44;
306 break; 361 break;
307 case JEDEC_RDID: 362 case JEDEC_RDID:
308 » » if (emu_chip != EMULATE_SST_SST25VF032B) 363 » » if (emu_chip == EMULATE_SST_SST25VF032B) {
309 » » » break; 364 » » » /* Respond with SST_SST25VF032B. */
310 » » /* Respond with SST_SST25VF032B. */ 365 » » » if (readcnt > 0)
311 » » if (readcnt > 0) 366 » » » » readarr[0] = 0xbf;
312 » » » readarr[0] = 0xbf; 367 » » » if (readcnt > 1)
313 » » if (readcnt > 1) 368 » » » » readarr[1] = 0x25;
314 » » » readarr[1] = 0x25; 369 » » » if (readcnt > 2)
315 » » if (readcnt > 2) 370 » » » » readarr[2] = 0x4a;
316 » » » readarr[2] = 0x4a; 371 » » } else if (emu_chip == EMULATE_VARIABLE_SIZE) {
372 » » » const uint16_t man_id = VARIABLE_SIZE_MANUF_ID;
373 » » » const uint16_t dev_id = VARIABLE_SIZE_DEVICE_ID;
374 » » » if (readcnt > 0) readarr[0] = man_id >> 8;
375 » » » if (readcnt > 1) readarr[1] = man_id & 0xff;
376 » » » if (readcnt > 2) readarr[2] = dev_id >> 8;
377 » » » if (readcnt > 3) readarr[3] = dev_id & 0xff;
378 » » }
317 break; 379 break;
318 case JEDEC_RDSR: 380 case JEDEC_RDSR:
319 memset(readarr, 0, readcnt); 381 memset(readarr, 0, readcnt);
320 if (aai_active) 382 if (aai_active)
321 memset(readarr, 1 << 6, readcnt); 383 memset(readarr, 1 << 6, readcnt);
322 break; 384 break;
323 case JEDEC_READ: 385 case JEDEC_READ:
324 offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3]; 386 offs = writearr[1] << 16 | writearr[2] << 8 | writearr[3];
325 /* Truncate to emu_chip_size. */ 387 /* Truncate to emu_chip_size. */
326 offs %= emu_chip_size; 388 offs %= emu_chip_size;
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 for (i = 0; i < writecnt; i++) 550 for (i = 0; i < writecnt; i++)
489 msg_pspew(" 0x%02x", writearr[i]); 551 msg_pspew(" 0x%02x", writearr[i]);
490 552
491 /* Response for unknown commands and missing chip is 0xff. */ 553 /* Response for unknown commands and missing chip is 0xff. */
492 memset(readarr, 0xff, readcnt); 554 memset(readarr, 0xff, readcnt);
493 #if EMULATE_SPI_CHIP 555 #if EMULATE_SPI_CHIP
494 switch (emu_chip) { 556 switch (emu_chip) {
495 case EMULATE_ST_M25P10_RES: 557 case EMULATE_ST_M25P10_RES:
496 case EMULATE_SST_SST25VF040_REMS: 558 case EMULATE_SST_SST25VF040_REMS:
497 case EMULATE_SST_SST25VF032B: 559 case EMULATE_SST_SST25VF032B:
560 case EMULATE_VARIABLE_SIZE:
498 if (emulate_spi_chip_response(writecnt, readcnt, writearr, 561 if (emulate_spi_chip_response(writecnt, readcnt, writearr,
499 readarr)) { 562 readarr)) {
500 msg_perr("Invalid command sent to flash chip!\n"); 563 msg_perr("Invalid command sent to flash chip!\n");
501 return 1; 564 return 1;
502 } 565 }
503 break; 566 break;
504 default: 567 default:
505 break; 568 break;
506 } 569 }
507 #endif 570 #endif
508 msg_pspew(" reading %u bytes:", readcnt); 571 msg_pspew(" reading %u bytes:", readcnt);
509 for (i = 0; i < readcnt; i++) { 572 for (i = 0; i < readcnt; i++) {
510 msg_pspew(" 0x%02x", readarr[i]); 573 msg_pspew(" 0x%02x", readarr[i]);
511 } 574 }
512 msg_pspew("\n"); 575 msg_pspew("\n");
513 return 0; 576 return 0;
514 } 577 }
515 578
516 int dummy_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) 579 int dummy_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
517 { 580 {
518 /* Maximum read length is unlimited, use 64kB. */ 581 /* Maximum read length is unlimited, use 64kB. */
519 return spi_read_chunked(flash, buf, start, len, 64 * 1024); 582 return spi_read_chunked(flash, buf, start, len, 64 * 1024);
520 } 583 }
521 584
522 int dummy_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int le n) 585 int dummy_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int le n)
523 { 586 {
524 return spi_write_chunked(flash, buf, start, len, 587 return spi_write_chunked(flash, buf, start, len,
525 spi_write_256_chunksize); 588 spi_write_256_chunksize);
526 } 589 }
590
591 #if EMULATE_CHIP && EMULATE_SPI_CHIP
592 int probe_variable_size(struct flashchip *flash)
593 {
594 int i;
595
596 /* Skip the probing if we don't emulate this chip. */
597 if (emu_chip != EMULATE_VARIABLE_SIZE)
598 return 0;
599
600 /*
601 * This will break if one day flashchip becomes read-only.
602 * Once that happens, we need to have special hacks in functions:
603 *
604 * erase_and_write_flash() in flashrom.c
605 * read_flash_to_file()
606 * handle_romentries()
607 * ...
608 *
609 * Search "total_size * 1024" in code.
610 */
611 if (emu_chip_size % 1024)
612 msg_perr("%s: emu_chip_size is not multipler of 1024.\n",
613 __func__);
614 flash->total_size = emu_chip_size / 1024;
615 msg_cdbg("%s: set flash->total_size to %dK bytes.\n", __func__,
616 flash->total_size);
617
618 /* Update eraser count */
619 for (i = 0; i < NUM_ERASEFUNCTIONS; i++) {
620 struct block_eraser *eraser = &flash->block_erasers[i];
621 if (eraser->block_erase == NULL)
622 break;
623
624 eraser->eraseblocks[0].count = emu_chip_size /
625 eraser->eraseblocks[0].size;
626 msg_cdbg("%s: eraser.size=%d, .count=%d\n",
627 __func__, eraser->eraseblocks[0].size,
628 eraser->eraseblocks[0].count);
629 }
630
631 return 1;
632 }
633 #endif
OLDNEW
« no previous file with comments | « chipdrivers.h ('k') | flashchips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698