OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [ebsa285/] [v2_0/] [support/] [linux/] [safl_util/] [sa_flash.c] - Blame information for rev 401

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
 
2
#include <stdio.h>
3
#include <unistd.h>
4
#include <stdlib.h>
5
#include <fcntl.h>
6
#include <errno.h>
7
#include <sys/mman.h>
8
#include <sys/ioctl.h>
9
 
10
#define FLASH_SZ (4 * 1024 * 1024)
11
#define FLASH_BLOCK_SZ (256 * 1024)
12
 
13
volatile void *flash_base;
14
int  driver_fd;
15
 
16
/*
17
 * sync PCI transactions
18
 */
19
static void
20
pci_sync(void)
21
{
22
    volatile unsigned int x;
23
 
24
    x = *(unsigned int *)flash_base;
25
}
26
 
27
static void
28
flash_write_mode(void)
29
{
30
    pci_sync();
31
    *(volatile int *)flash_base = 0x40404040;
32
}
33
 
34
 
35
static void
36
flash_normal_mode(void)
37
{
38
    pci_sync();
39
    *(volatile int *)flash_base = 0xffffffff;
40
}
41
 
42
 
43
/*
44
 *  Check to see if there is some flash at the location specified.
45
 */
46
static int
47
flash_verify(void)
48
{
49
    volatile unsigned int *fp = (volatile unsigned int *)flash_base;
50
    unsigned int mfg, id ;
51
 
52
    flash_normal_mode();
53
 
54
    /* read the manufacturer's id. */
55
    pci_sync();
56
    *fp = 0x90909090;
57
    mfg = *fp;
58
 
59
    if (mfg != 0x89898989) {
60
        flash_normal_mode();
61
        return 0;
62
    }
63
 
64
    id = *(fp + 1) ;
65
 
66
    flash_normal_mode();
67
 
68
    if (id < 0xA1A1A1A1)
69
        return 0;
70
 
71
    return 1;
72
}
73
 
74
 
75
static unsigned int
76
flash_read_dword(int offset)
77
{
78
    /* swap initial 32 byte blocks when accessing flash from PCI */
79
    if (offset < 32)
80
        offset += 32;
81
    else if (offset < 64)
82
        offset -= 32;
83
 
84
    offset &= ~3;  /* dword alignment */
85
 
86
    return *(volatile unsigned int *)(flash_base + offset);
87
}
88
 
89
 
90
static int
91
flash_write_dword(int offset, unsigned int data)
92
{
93
    volatile unsigned int *fp;
94
    int status;
95
 
96
    /* swap initial 32 byte blocks when accessing flash from PCI */
97
    if (offset < 32)
98
        offset += 32;
99
    else if (offset < 64)
100
        offset -= 32;
101
 
102
    offset &= ~3;  /* dword alignment */
103
 
104
    fp = (volatile unsigned int *)(flash_base + offset) ;
105
 
106
    flash_write_mode();
107
 
108
    /* write the data */
109
    *fp = data;
110
 
111
    /* wait till done */
112
    do {
113
        pci_sync();
114
        *fp = 0x70707070;
115
        status = *fp;
116
    } while ((status & 0x80808080) != 0x80808080);
117
 
118
    *fp = 0x50505050; /* Clear status register */
119
    flash_normal_mode();
120
 
121
    if ( (status & 0x02020202) != 0) {
122
        fprintf(stderr,"WRITE LOCKED %08x :", status);
123
        return 0;
124
    }
125
    if ( (status & 0x10101010) != 0) {
126
        fprintf(stderr,"WRITE FAILURE %08x :", status);
127
        return 0;
128
    }
129
    return 1;
130
}
131
 
132
 
133
static int
134
flash_erase_block(int block)
135
{
136
    volatile unsigned int *fp;
137
    int status;
138
 
139
    fp = (volatile unsigned int *)(flash_base + (block * FLASH_BLOCK_SZ));
140
 
141
    /* write delete block command followed by confirm */
142
    pci_sync();
143
    *fp = 0x20202020;
144
    pci_sync();
145
    *fp = 0xd0d0d0d0;
146
 
147
    /* wait till done */
148
    do {
149
        pci_sync();
150
        *fp = 0x70707070;
151
        status = *fp;
152
    } while ((status & 0x80808080) != 0x80808080);
153
 
154
    *fp = 0x50505050; /* Clear status register */
155
    flash_normal_mode();
156
 
157
    if ( (status & 0x02020202) != 0) {
158
        fprintf(stderr,"ERASE LOCKED %08x :", status);
159
        return 0;
160
    }
161
    if ( (status & 0x20202020) != 0) {
162
        fprintf(stderr,"ERASE FAILURE %08x :", status);
163
        return 0;
164
    }
165
 
166
    return 1;
167
}
168
 
169
 
170
int
171
main(int argc, char *argv[])
172
{
173
    int in_fd = STDIN_FILENO, i=0, got, offset, extra;
174
    int buf[256];
175
    int fw = 1, fv = 1, fr = 0, verbose = 0;
176
    char *name = NULL;
177
    int block = 0;
178
 
179
    if ( argc > 2 ) {
180
        if ( '-' == argv[1][0] && 'b' == argv[1][1] && 0 == argv[1][3] ) {
181
            char c = argv[1][2];
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 */
186
            argv++, argc--;
187
        }
188
    }
189
 
190
    switch (argc) {
191
    case 1:
192
        in_fd = STDIN_FILENO;
193
        fv = 0; /* Cannot rewind stdin, so do not verify */
194
        break;
195
    case 2:
196
        if ( '-' == argv[1][0] ) {
197
            if ( 'r' != argv[1][1] || 0 != argv[1][2]) goto usage;
198
            fr = 1;
199
            fw = fv = 0;
200
            break;
201
        }
202
        name = argv[1];
203
        in_fd = open(argv[1], O_RDONLY);
204
        if (in_fd < 0) {
205
            fprintf(stderr, "Can't open %s", argv[1]);
206
            perror(": ");
207
            exit(1);
208
        }
209
        break;
210
    case 3:
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;
215
        else                                       goto usage;
216
 
217
        name = argv[2];
218
        in_fd = open(argv[2], O_RDONLY);
219
        if (in_fd < 0) {
220
            fprintf(stderr, "Can't open %s", argv[2]);
221
            perror(": ");
222
            exit(1);
223
        }
224
        break;
225
    default:
226
    usage:
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");
232
        exit(1);
233
    }
234
 
235
    driver_fd = open("/dev/safl", O_RDWR);
236
    if (driver_fd < 0) {
237
        perror("Can't open device: ");
238
        exit (1);
239
    }
240
 
241
    flash_base = mmap(NULL, FLASH_SZ, PROT_READ|PROT_WRITE,
242
                      MAP_SHARED, driver_fd, 0);
243
 
244
    if (flash_base == NULL) {
245
        perror("mmap failed: ");
246
        close(driver_fd);
247
        return 0;
248
    }
249
 
250
    if (!flash_verify()) {
251
        fprintf(stderr, "Couldn't find flash.\n");
252
        exit(1);
253
    }
254
 
255
    if ( fw ) {
256
        if ( ! flash_erase_block(block) ) {
257
            fprintf(stderr,"Erase error block %x\n", block);
258
            exit(1);
259
        }
260
 
261
        extra = 0;
262
        offset = block * FLASH_BLOCK_SZ;
263
        while ((got = read(in_fd, ((char *)buf) + extra, sizeof(buf) - extra)) > 0) {
264
            got += extra;
265
 
266
            extra = got & 3;
267
            got /= 4;
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);
271
 
272
            if (extra)
273
                buf[0] = buf[i];
274
 
275
            printf("*"); fflush(stdout);
276
        }
277
        if (extra)
278
            if ( ! flash_write_dword(offset, buf[i]) )
279
                fprintf(stderr,"Write error offset %06x\n",offset);
280
        printf("\n");
281
    }
282
 
283
    flash_normal_mode();
284
 
285
    if ( fv ) {
286
        int badwords = 0;
287
        int skipping = 0;
288
        close( in_fd );
289
        in_fd = open(name, O_RDONLY);
290
        if (in_fd < 0) {
291
            fprintf(stderr, "Can't re-open %s", argv[2]);
292
            perror(": ");
293
            exit(1);
294
        }
295
 
296
        extra = 0;
297
        offset = block * FLASH_BLOCK_SZ;
298
        while ((got = read(in_fd, ((char *)buf) + extra, sizeof(buf) - extra)) > 0) {
299
            got += extra;
300
 
301
            extra = got & 3;
302
            got /= 4;
303
            for (i = 0; i < got; ++i, offset += 4) {
304
                int data = flash_read_dword(offset);
305
                if ( data != buf[i] ) {
306
                    badwords++;
307
                    if ( !skipping ) {
308
                        fprintf(stderr, "Bad data at offset %06x: %08x read %08x wanted\n",
309
                                offset, data, buf[i] );
310
                        if ( !verbose && badwords > 15 ) {
311
                            skipping = 1;
312
                            fprintf(stderr, "(Too many errors, skipping...)\n");
313
                        }
314
                    }
315
                }
316
            }
317
            if (extra)
318
                buf[0] = buf[i];
319
 
320
            printf("+"); fflush(stdout);
321
        }
322
        if (extra) {
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] );
327
            }
328
        }
329
        printf("\n");
330
        if ( badwords )
331
            fprintf(stderr, "Bad data: %d bad words out of %d (end offset %06x)\n",
332
                    badwords, offset/4, offset );
333
    }
334
 
335
    flash_normal_mode();
336
 
337
    if ( fr ) {
338
        for ( offset = block * FLASH_BLOCK_SZ;
339
              offset < (block+1) * FLASH_BLOCK_SZ;
340
              offset += 4 ) {
341
            for ( i = 0; i < (sizeof(buf)/sizeof(int)); ++i, offset += 4 ) {
342
                buf[i] = flash_read_dword(offset);
343
            }
344
            if ( sizeof(buf) != write( STDOUT_FILENO, buf, sizeof(buf) ) ) {
345
                perror("Stdout write failed: ");
346
                exit(1);
347
            }
348
            fprintf(stderr,"r");
349
            fflush(stderr);
350
        }
351
        fprintf(stderr,"\n");
352
    }
353
 
354
    munmap((void *)flash_base, FLASH_SZ);
355
    close(driver_fd);
356
    return 0;
357
}
358
 
359
 
360
 
361
 
362
/*
363
 * Local variables:
364
 *  compile-command: "cc -g -O2 -Wall sa_flash.c -o sa_flash"
365
 * End:
366
 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.