10 #define FLASH_SZ (4 * 1024 * 1024)
11 #define FLASH_BLOCK_SZ (256 * 1024)
13 volatile void *flash_base;
17 * sync PCI transactions
22 volatile unsigned int x;
24 x = *(unsigned int *)flash_base;
28 flash_write_mode(void)
31 *(volatile int *)flash_base = 0x40404040;
36 flash_normal_mode(void)
39 *(volatile int *)flash_base = 0xffffffff;
44 * Check to see if there is some flash at the location specified.
49 volatile unsigned int *fp = (volatile unsigned int *)flash_base;
50 unsigned int mfg, id ;
54 /* read the manufacturer's id. */
59 if (mfg != 0x89898989) {
76 flash_read_dword(int offset)
78 /* swap initial 32 byte blocks when accessing flash from PCI */
84 offset &= ~3; /* dword alignment */
86 return *(volatile unsigned int *)(flash_base + offset);
91 flash_write_dword(int offset, unsigned int data)
93 volatile unsigned int *fp;
96 /* swap initial 32 byte blocks when accessing flash from PCI */
102 offset &= ~3; /* dword alignment */
104 fp = (volatile unsigned int *)(flash_base + offset) ;
116 } while ((status & 0x80808080) != 0x80808080);
118 *fp = 0x50505050; /* Clear status register */
121 if ( (status & 0x02020202) != 0) {
122 fprintf(stderr,"WRITE LOCKED %08x :", status);
125 if ( (status & 0x10101010) != 0) {
126 fprintf(stderr,"WRITE FAILURE %08x :", status);
134 flash_erase_block(int block)
136 volatile unsigned int *fp;
139 fp = (volatile unsigned int *)(flash_base + (block * FLASH_BLOCK_SZ));
141 /* write delete block command followed by confirm */
152 } while ((status & 0x80808080) != 0x80808080);
154 *fp = 0x50505050; /* Clear status register */
157 if ( (status & 0x02020202) != 0) {
158 fprintf(stderr,"ERASE LOCKED %08x :", status);
161 if ( (status & 0x20202020) != 0) {
162 fprintf(stderr,"ERASE FAILURE %08x :", status);
171 main(int argc, char *argv[])
173 int in_fd = STDIN_FILENO, i=0, got, offset, extra;
175 int fw = 1, fv = 1, fr = 0, verbose = 0;
180 if ( '-' == argv[1][0] && 'b' == argv[1][1] && 0 == argv[1][3] ) {
182 if ( '0' <= c && c <= '9') block = c - '0';
183 else if ( 'a' <= c && c <= 'f') block = c - 'a' + 10;
184 else if ( 'A' <= c && c <= 'F') block = c - 'A' + 10;
185 else argc = 1; /* get usage message below */
192 in_fd = STDIN_FILENO;
193 fv = 0; /* Cannot rewind stdin, so do not verify */
196 if ( '-' == argv[1][0] ) {
197 if ( 'r' != argv[1][1] || 0 != argv[1][2]) goto usage;
203 in_fd = open(argv[1], O_RDONLY);
205 fprintf(stderr, "Can't open %s", argv[1]);
211 if ( '-' != argv[1][0] || 0 != argv[1][2]) goto usage;
212 if ( 'v' == argv[1][1] ) fw = 0;
213 else if ( 'V' == argv[1][1] ) fw = 0, verbose = 1;
214 else if ( 'w' == argv[1][1] ) fv = 0;
218 in_fd = open(argv[2], O_RDONLY);
220 fprintf(stderr, "Can't open %s", argv[2]);
227 fprintf(stderr, "Usage: sa_flash [filename]\n");
228 fprintf(stderr, "Block number: sa_flash -bN [filename]\n");
229 fprintf(stderr, "Write only: sa_flash [-bN] -w filename\n");
230 fprintf(stderr, "Verify only: sa_flash [-bN] -v|-V filename\n");
231 fprintf(stderr, "Read to stdout: sa_flash [-bN] -r\n");
235 driver_fd = open("/dev/safl", O_RDWR);
237 perror("Can't open device: ");
241 flash_base = mmap(NULL, FLASH_SZ, PROT_READ|PROT_WRITE,
242 MAP_SHARED, driver_fd, 0);
244 if (flash_base == NULL) {
245 perror("mmap failed: ");
250 if (!flash_verify()) {
251 fprintf(stderr, "Couldn't find flash.\n");
256 if ( ! flash_erase_block(block) ) {
257 fprintf(stderr,"Erase error block %x\n", block);
262 offset = block * FLASH_BLOCK_SZ;
263 while ((got = read(in_fd, ((char *)buf) + extra, sizeof(buf) - extra)) > 0) {
268 for (i = 0; i < got; ++i, offset += 4)
269 if ( ! flash_write_dword(offset, buf[i]) )
270 fprintf(stderr,"Write error offset %06x\n",offset);
275 printf("*"); fflush(stdout);
278 if ( ! flash_write_dword(offset, buf[i]) )
279 fprintf(stderr,"Write error offset %06x\n",offset);
289 in_fd = open(name, O_RDONLY);
291 fprintf(stderr, "Can't re-open %s", argv[2]);
297 offset = block * FLASH_BLOCK_SZ;
298 while ((got = read(in_fd, ((char *)buf) + extra, sizeof(buf) - extra)) > 0) {
303 for (i = 0; i < got; ++i, offset += 4) {
304 int data = flash_read_dword(offset);
305 if ( data != buf[i] ) {
308 fprintf(stderr, "Bad data at offset %06x: %08x read %08x wanted\n",
309 offset, data, buf[i] );
310 if ( !verbose && badwords > 15 ) {
312 fprintf(stderr, "(Too many errors, skipping...)\n");
320 printf("+"); fflush(stdout);
323 int data = flash_read_dword(offset);
324 if ( data != buf[0] ) {
325 fprintf(stderr, "End data at offset %06x: %08x read %08x wanted\n",
326 offset, data, buf[0] );
331 fprintf(stderr, "Bad data: %d bad words out of %d (end offset %06x)\n",
332 badwords, offset/4, offset );
338 for ( offset = block * FLASH_BLOCK_SZ;
339 offset < (block+1) * FLASH_BLOCK_SZ;
341 for ( i = 0; i < (sizeof(buf)/sizeof(int)); ++i, offset += 4 ) {
342 buf[i] = flash_read_dword(offset);
344 if ( sizeof(buf) != write( STDOUT_FILENO, buf, sizeof(buf) ) ) {
345 perror("Stdout write failed: ");
351 fprintf(stderr,"\n");
354 munmap((void *)flash_base, FLASH_SZ);
364 * compile-command: "cc -g -O2 -Wall sa_flash.c -o sa_flash"