]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/arm/xscale/iq80310/v2_0/src/diag/flash.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / xscale / iq80310 / v2_0 / src / diag / flash.c
1 //=============================================================================
2 //
3 //      flash.c - Cyclone Diagnostics
4 //
5 //=============================================================================
6 //####ECOSGPLCOPYRIGHTBEGIN####
7 // -------------------------------------------
8 // This file is part of eCos, the Embedded Configurable Operating System.
9 // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
10 //
11 // eCos is free software; you can redistribute it and/or modify it under
12 // the terms of the GNU General Public License as published by the Free
13 // Software Foundation; either version 2 or (at your option) any later version.
14 //
15 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
16 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 // for more details.
19 //
20 // You should have received a copy of the GNU General Public License along
21 // with eCos; if not, write to the Free Software Foundation, Inc.,
22 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 //
24 // As a special exception, if other files instantiate templates or use macros
25 // or inline functions from this file, or you compile this file and link it
26 // with other works to produce a work based on this file, this file does not
27 // by itself cause the resulting work to be covered by the GNU General Public
28 // License. However the source code for this file must still be made available
29 // in accordance with section (3) of the GNU General Public License.
30 //
31 // This exception does not invalidate any other reasons why a work based on
32 // this file might be covered by the GNU General Public License.
33 //
34 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
35 // at http://sources.redhat.com/ecos/ecos-license/
36 // -------------------------------------------
37 //####ECOSGPLCOPYRIGHTEND####
38 //=============================================================================
39 //#####DESCRIPTIONBEGIN####
40 //
41 // Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden
42 // Contributors:
43 // Date:        2001-01-25
44 // Purpose:     
45 // Description: 
46 //
47 //####DESCRIPTIONEND####
48 //
49 //===========================================================================*/
50
51 #include <redboot.h>
52 #ifdef CYGPKG_IO_FLASH
53 #include <cyg/io/flash.h>
54
55 #include "iq80310.h"    /* 80310 chip set specific */
56 #include "7_segment_displays.h"
57 #include "test_menu.h"
58
59 typedef unsigned char FLASH_TYPE;
60 #define MASK 0xff  /* for 1 bank */
61
62 /* 28F016S5/28F640J3A Command Definitions  - First Bus Cycle */
63 #define RESET_CMD               (0xffffffff & MASK)
64 #define WRITE_TO_BUF_CMD        (0xe8e8e8e8 & MASK)
65 #define WRITE_CONFIRM_CMD       (0xd0d0d0d0 & MASK)
66 #define READ_ID_CMD             (0x90909090 & MASK)
67 #define READ_STAT_REG           (0x70707070 & MASK)
68 #define CLEAR_STAT_REG          (0x50505050 & MASK)
69 #define ERASE_CMD               (0x20202020 & MASK)
70 #define PROGRAM_CMD             (0x40404040 & MASK)
71 #define BEP_SUSPEND             (0xb0b0b0b0 & MASK)
72 #define BEP_RESUME              (0xd0d0d0d0 & MASK)
73 #define LOCK_CMD                (0x60606060 & MASK)
74 #define CLEAR_LOCK_BIT_SETUP    (0x60606060 & MASK)     /* 10/06/00 */
75
76 /* 28F016S5/28F640J3A Command Definitions  - Second Bus Cycle */
77 #define ERASE_CONFIRM           (0xd0d0d0d0 & MASK)
78 #define LOCK_BLOCK_CONFIRM      (0x01010101 & MASK)
79 #define MASTER_LOCK_CONFIRM     (0xf1f1f1f1 & MASK)  /* DO NOT EVER set master enable bit!!! */
80 #define UNLOCK_BLOCK_CONFIRM    (0xd0d0d0d0 & MASK)
81 #define CLEAR_LOCK_BIT_CONFIRM  (0xd0d0d0d0 & MASK)     /* 10/06/00 */
82
83 /* Flash category definitions */
84 #define SECTOR_PROG     0
85 #define BLOCK_PROG      1
86
87 /* status register bits */
88 #define WSM_READY               (FLASH_TYPE) (1 << 7)
89 #define WSM_BUSY                (FLASH_TYPE) (0 << 7)
90 #define BE_SUSPENDED            (FLASH_TYPE) (1 << 6)
91 #define BE_COMPLETED            (FLASH_TYPE) (0 << 6)
92 #define ERASE_UNLOCK_ERROR      (FLASH_TYPE) (1 << 5)
93 #define ERASE_UNLOCK_SUCCESS    (FLASH_TYPE) (0 << 5)
94 #define CLEAR_LOCK_BIT_ERROR    (FLASH_TYPE) (1 << 5)   /* 10/06/00 */
95 #define CLEAR_LOCK_BIT_SUCCESS  (FLASH_TYPE) (0 << 5)   /* 10/06/00 */
96 #define PROGRAM_LOCK_ERROR      (FLASH_TYPE) (1 << 4)
97 #define PROGRAM_LOCK_SUCCESS    (FLASH_TYPE) (0 << 4)
98 #define SET_LOCK_BIT_ERROR      (FLASH_TYPE) (1 << 4)   /* 10/17/00 */
99 #define SET_LOCK_BIT_SUCCESS    (FLASH_TYPE) (0 << 4)   /* 10/17/00 */
100 #define VPP_LOW_DETECT          (FLASH_TYPE) (1 << 3)
101 #define VPP_OK                  (FLASH_TYPE) (0 << 3)
102 #define PROGRAM_SUSPENDED       (FLASH_TYPE) (1 << 2)
103 #define PROGRAM_COMPLETED       (FLASH_TYPE) (0 << 2)
104 #define DEVICE_PROTECTED        (FLASH_TYPE) (1 << 1)
105 #define DEVICE_UNLOCKED         (FLASH_TYPE) (0 << 1)
106
107
108 /* Other Intel 28F016S5/28F640J3A definitions */
109 #define CMD_SEQ_ERR             (FLASH_TYPE) (ERASE_UNLOCK_ERROR | PROGRAM_LOCK_ERROR)
110 #define ALL_FLASH_STATUS        (FLASH_TYPE) (0xfe)
111 #define UNKNOWN_ERR             (FLASH_TYPE) (0xff)
112
113 #define TEST_BUF_LONGS          16384
114 #define TEST_BUF_CHARS          65536
115
116 #define MADE_BY_INTEL           (0x89898989 & MASK)             /* Manufacturer Code, read at address 0, note that address bit A0 is not used in x8 or x16 mode when obtaining identifier code */
117
118 #define I28F640J3A              (0x17171717 & MASK)             /* Device Code, read at address 1, note that bit address A0 is not used in x8 or x16 mode when obtaining identifier code */
119
120 /*#define FLASH_BLOCK_SIZE      0x10000*/       /* 28F016S5 */
121 #define FLASH_BLOCK_SIZE        0x20000         /* 28F640J3A */
122
123 #define BLOCK_LOCKED            1
124 #define BLOCK_UNLOCKED          0
125
126 // First 4K page of flash at physical address zero is
127 // virtually mapped at address 0xd0000000.
128 #define FLASH_P2V(x) ((volatile FLASH_TYPE *)(((unsigned)(x) < 0x1000) ?  \
129                            ((unsigned)(x) | 0xd0000000) :  \
130                            (unsigned)(x)))
131
132
133 unsigned long *flash_buffer = (unsigned long *)0xa1000000;
134
135 int cmd_stat;                                           
136
137 extern void _flushICache(void);
138 extern void _enableICache(void);
139 extern void _disableICache(void);
140 extern void _switchMMUpageTables(void);
141 extern void _usec_delay(void);
142 extern void _msec_delay(void);
143
144 unsigned long eeprom_size;
145 unsigned long flash_base;
146
147 ADDR eeprom_prog_first, eeprom_prog_last;
148
149 extern long hexIn(void);
150 extern char *sgets(char *s);
151
152 /* forward declarations */
153 void init_eeprom(void) RAM_FUNC_SECT;
154 int check_eeprom(ADDR addr, unsigned long length) RAM_FUNC_SECT;
155 int check_bstat(int block_num) RAM_FUNC_SECT;
156 int set_all_lock_bits(void) RAM_FUNC_SECT;              /* 10/11/00 added */
157 int clear_all_lock_bits(ADDR addr) RAM_FUNC_SECT;       /* 10/06/00 added */
158 int erase_eeprom(ADDR addr, unsigned long length) RAM_FUNC_SECT;
159 int write_eeprom(ADDR start_addr, const void *data_arg, int data_size) RAM_FUNC_SECT;
160 void flash_test(MENU_ARG arg) RAM_FUNC_SECT;
161 void display_val(int num) RAM_FUNC_SECT;
162 void display_out (int msb_flag, unsigned char val) RAM_FUNC_SECT;
163
164 #define MSB_DISPLAY_REG         (volatile unsigned char *)0xfe840000
165 #define LSB_DISPLAY_REG         (volatile unsigned char *)0xfe850000
166
167 void display_out (int msb_flag, unsigned char val)
168 {
169     volatile unsigned char *ledPtr;
170
171     if (msb_flag)
172         ledPtr = MSB_DISPLAY_REG;
173     else
174         ledPtr = LSB_DISPLAY_REG;
175
176     *ledPtr = SevSegDecode[val & 0xf];
177 }
178
179 void display_val (int number)
180 {
181     unsigned char disp_val = number % 256;
182     unsigned char msb, lsb;
183
184     lsb = disp_val & 0x0f;
185     msb = (disp_val & 0xf0) >> 4;
186
187     display_out (0, lsb);
188     display_out (1, msb);
189 }
190
191 /********************************************************/
192 /* INIT FLASH                                           */
193 /*                                                      */
194 /* This routine initializes the variables for timing    */
195 /* with any board configuration.  This is used to get   */
196 /* exact timing every time.                             */
197 /********************************************************/
198 void init_eeprom(void)
199 {
200     unsigned char MfgCode=MADE_BY_INTEL;
201     unsigned char DevCode=I28F640J3A;
202
203     eeprom_size = 0x800000;
204
205     printf( "\nManufacturer Code = 0x%x\n", MfgCode);
206     printf( "Device Code = %x\n", DevCode);
207     printf( "Flash Memory size = 0x%x\n", eeprom_size);
208
209     return;
210 }
211
212 /********************************************************/
213 /* CHECK EEPROM                                         */
214 /* Check if Flash is Blank                              */
215 /*                                                      */
216 /* returns OK if it is; returns ERROR and sets cmd_stat */
217 /* to an error code if memory region is not Flash or if */
218 /* it is not blank.                                     */
219 /*                                                      */
220 /********************************************************/
221 int check_eeprom(ADDR addr, unsigned long length)
222 {
223     FLASH_TYPE *p, *end;
224
225     if (eeprom_size == 0) {
226         cmd_stat = E_NO_FLASH;
227         return ERR;
228     }
229
230     if (addr == NO_ADDR) {
231         addr = FLASH_BLK4_BASE_ADDR;    /* start at base address of block */
232         length = eeprom_size - RESERVED_AREA_SIZE;
233     } else if (length == 0)
234         length = 1;
235
236     p = (FLASH_TYPE *)addr;
237
238     end = (FLASH_TYPE *)FLASH_TOP_ADDR; 
239     /* search for first non blank address starting at base address of Flash Block 2 */
240     while (p != end) {
241         if (*FLASH_P2V(p) != 0xff) {
242             eeprom_prog_first = (ADDR)p;        /* found first non blank memory cell */
243             
244             /* now find last non blank memory cell starting from top of Flash memory */
245             for (p = end - 1; *FLASH_P2V(p) == 0xff; --p)
246                 ;
247             eeprom_prog_last = (ADDR)p; /* found last non blank memory cell */ 
248             
249             cmd_stat = E_EEPROM_PROG;
250
251             return ERR;
252         }
253         p++;
254     }
255     return OK;
256 }
257
258 /********************************************************/
259 /* SET ALL LOCK BITS                                    */
260 /*                                                      */
261 /* returns OK if successful; otherwise returns ERROR    */
262 /* and sets cmd_stat to an error code                   */
263 /* The 28F640J3A is divided into 64, 128Kbyte blocks    */
264 /* This routine sets a lock bit in the block specified  */
265 /* by a given address                                   */
266 /********************************************************/
267 int set_all_lock_bits()
268 {
269     unsigned long addr = 0x0; 
270     void *err_addr;
271     int stat;
272
273     if ((stat = flash_lock((void *)addr, 4 * FLASH_BLOCK_SIZE, (void **)&err_addr)) != 0)
274         return stat;
275
276     return( OK );
277 }
278
279
280 /********************************************************/
281 /* CLEAR ALL LOCK BITS                                  */
282 /*                                                      */
283 /* returns OK if successful; otherwise returns ERROR    */
284 /* and sets cmd_stat to an error code                   */
285 /* The 28F640J3A is divided into 64, 128Kbyte blocks    */
286 /* This routine clears all block lock bits              */
287 /********************************************************/
288 int clear_all_lock_bits(ADDR addr)
289 {
290     void *err_addr;
291     int stat;
292
293     if ((stat = flash_unlock((void *)0, eeprom_size, (void **)&err_addr)) != 0)
294         return stat;
295     return OK;
296 }
297
298
299 /********************************************************/
300 /* ERASE EEPROM                                         */
301 /*                                                      */
302 /* returns OK if erase was successful,                  */
303 /* otherwise returns ERROR                              */
304 /* and sets cmd_stat to an error code                   */
305 /*                                                      */
306 /********************************************************/
307 int erase_eeprom(ADDR addr, unsigned long length)
308 {
309     void *err_addr;
310     int num_blocks;
311
312     /********************************************************/
313     /* The 28F640J3A is divided into 64, 128Kbyte blocks    */
314     /* each of which must be individually erased.           */
315     /* This routine and erases a whole number of blocks     */
316     /********************************************************/
317
318     /* don't erase boot area even if entire eeprom is specified */
319     if (addr == NO_ADDR) {
320         addr = FLASH_BLK4_BASE_ADDR;
321         length = eeprom_size - RESERVED_AREA_SIZE;
322     }
323
324     if (length == 0) {
325         /* 10/06/00 */
326         printf( "erase_eeprom, return OK, length=0\n");
327         return OK;
328     }
329
330     /* start address must be block-aligned */
331     if ((addr % FLASH_BLOCK_SIZE) != 0) {
332         cmd_stat = E_EEPROM_ADDR;
333         printf( "erase_eeprom, addr = 0x%x\n", addr);
334         printf( "erase_eeprom, FLASH_BLOCK_SIZE = 0x%x\n", FLASH_BLOCK_SIZE);
335         printf( "erase_eeprom, return ERR, (addr %% FLASH_BLOCK_SIZE) = %d\n", addr % FLASH_BLOCK_SIZE);
336
337         return ERR;
338     }
339
340     /* figure out how many blocks require erasure - round up using integer division */
341     if (length % FLASH_BLOCK_SIZE)              /* non-multiple, round up */
342         num_blocks = (length + FLASH_BLOCK_SIZE) / FLASH_BLOCK_SIZE;
343     else                                        /* multiple number of blocks */
344         num_blocks = length / FLASH_BLOCK_SIZE;
345
346     if (eeprom_size == 0) {
347         cmd_stat = E_NO_FLASH;
348         return ERR;
349     }
350
351     if (flash_erase((void *)addr, num_blocks * FLASH_BLOCK_SIZE, (void **)&err_addr) != 0) {
352         cmd_stat = E_EEPROM_FAIL;
353         return ERR;
354     }
355
356     return OK;
357 }
358
359
360 /********************************************************/
361 /* WRITE EEPROM                                         */
362 /*                                                      */
363 /* returns OK if successful; otherwise returns ERROR    */
364 /* and sets cmd_stat to an error code                   */
365 /*                                                      */
366 /********************************************************/
367 int
368 write_eeprom(ADDR start_addr, const void *data_arg, int data_size)
369 {
370     void *err_addr;
371
372     if (flash_program((void *)start_addr, data_arg, data_size, &err_addr) != 0) {
373         cmd_stat = E_EEPROM_FAIL;
374         return ERR;
375     }
376     return OK;
377 }
378
379
380 /*****************************************************************************
381 *
382 * flash_test - System Flash ROM diagnostics
383 *
384 * A destructive Flash ROM Read/Write test.  Note that the area of Flash
385 * which is tested changes based on whether the diagnostic is being invoked
386 * from the System code or from the Factory code (can't write over MON960).
387 *
388 * This test basically does a Longword Address test to the Flash area.
389 *
390 */
391 void flash_test(MENU_ARG arg)
392 {
393
394     ADDR start_addr = (ADDR)FLASH_ADDR; /* Original */
395
396     int i;
397     unsigned long *f_ptr = (unsigned long *)FLASH_ADDR;
398     int bytes_written = 0;
399     unsigned long flash_data;
400     char answer[20];
401
402 /* 10/31/00 */
403     int status;
404
405     init_eeprom();
406
407     printf("***********************************\n");
408     printf("***           WARNING           ***\n");
409     printf("*** This test is destructive to ***\n");
410     printf("*** all contents of the FLASH!  ***\n");
411     printf("***********************************\n");
412
413     printf("\nDo you wish to continue? (y/n)\n");
414     sgets(answer);
415     printf("\n\n");
416     if ((answer[0] != 'y') && (answer[0] != 'Y'))
417         return; 
418
419     printf ("FLASH begins at 0x%X\n", FLASH_ADDR);
420     printf ("Total FLASH size = 0x%X\n\n", eeprom_size);
421     printf ("Checking FLASH ...\n");
422     if (check_eeprom(NO_ADDR, 0) == OK)
423         printf("FLASH is erased\n\n");
424     else
425         printf("FLASH is programmed between 0x%X and 0x%X\n\n",
426                 eeprom_prog_first, eeprom_prog_last);
427
428     printf ("\nClearing Block Lock Bits... \n");
429     if(clear_all_lock_bits(NO_ADDR)==OK)
430         printf("Done!\n\n");
431     else
432         printf("Error!\n\n");
433         
434     printf ("Erasing FLASH...\n");
435     if (erase_eeprom(NO_ADDR, 0) != OK)
436         printf("Error on erase_eeprom()\n\n");
437     else
438         printf("Done Erasing FLASH!\n\n");
439  
440     (ADDR)start_addr = (ADDR)FLASH_BLK4_BASE_ADDR;
441
442     printf ("Writing Longword Data to FLASH...\n");
443  
444     /* write to all of available Flash ROM.  Don't do this thousands of times
445        since the Flash has only 100,000 write cycles in its lifespan */
446
447     while (bytes_written < (eeprom_size - RESERVED_AREA_SIZE)) {
448         flash_data = (unsigned long)start_addr;
449         for (i=0; i<TEST_BUF_LONGS; i++) {
450             flash_buffer[i] = flash_data;       /* put address in buffer */
451             flash_data += 4;                    /* increment address     */
452         }
453         if (write_eeprom (start_addr, (void *)flash_buffer, TEST_BUF_CHARS) != OK) {
454             printf("Error on write_eeprom()\n");
455             goto finish;
456         }
457         start_addr = (unsigned long)start_addr + TEST_BUF_CHARS;
458         bytes_written += TEST_BUF_CHARS;
459     }
460
461     printf ("Write Complete, Verifying Data...\n");
462     bytes_written = 0;
463  
464     f_ptr = (unsigned long *)FLASH_BLK4_BASE_ADDR;
465     
466     while (bytes_written < (eeprom_size - RESERVED_AREA_SIZE)) {
467         if (*f_ptr != (unsigned long)f_ptr) {
468             printf ("Data verification error at 0x%X\n", (unsigned long)f_ptr);
469             printf ("Expected 0x%X Got 0x%X\n", (unsigned long)f_ptr, *f_ptr);
470             goto finish;
471         }
472         f_ptr++;
473         bytes_written += 4;
474     }
475     printf ("Done Verifying Longword Data!\n\n");
476
477     printf ("Checking FLASH...\n");
478     if (check_eeprom(NO_ADDR, 0) == OK)
479         printf("FLASH is erased\n\n");
480     else
481         printf("FLASH is programmed between 0x%X and 0x%X\n\n",
482                 eeprom_prog_first, eeprom_prog_last);
483
484     printf ("Erasing FLASH...\n");
485     if (erase_eeprom(NO_ADDR, 0) != OK)
486         printf("Error on erase_eeprom()\n\n");
487     else
488         printf("Done Erasing FLASH!\n\n");
489
490     printf ("Checking FLASH...\n");
491     if (check_eeprom(NO_ADDR, 0) == OK)
492         printf("FLASH is erased\n\n");
493     else
494         printf("FLASH is programmed between 0x%X and 0x%X\n\n",
495                eeprom_prog_first, eeprom_prog_last);
496
497     /* reinitialize variables */
498     bytes_written = 0;
499  
500     start_addr = (ADDR)FLASH_BLK4_BASE_ADDR;
501     f_ptr = (unsigned long *)FLASH_BLK4_BASE_ADDR;
502
503     printf ("Writing Inverted Longword Data to FLASH...\n");
504  
505     /* write to all of available Flash ROM.  Don't do this thousands of times
506        since the Flash has only 100,000 write cycles in its lifespan */
507
508     while (bytes_written < (eeprom_size - RESERVED_AREA_SIZE)) {
509         flash_data = (unsigned long)start_addr;
510         for (i=0; i<TEST_BUF_LONGS; i++) {
511             flash_buffer[i] = ~flash_data;      /* put address BAR in buffer */
512             flash_data += 4;                    /* increment address     */
513         }
514         if (write_eeprom (start_addr, (void *)flash_buffer, TEST_BUF_CHARS) != OK) {
515             printf("Error on write_eeprom()\n");
516             goto finish;
517         }
518         start_addr = (unsigned long)start_addr + TEST_BUF_CHARS;
519         bytes_written += TEST_BUF_CHARS;
520     }
521  
522     printf ("Write Complete, Verifying Data...\n");
523     bytes_written = 0;
524  
525     while (bytes_written < (eeprom_size - RESERVED_AREA_SIZE)) {
526         if (*f_ptr != (~(unsigned long)f_ptr)) {
527             printf ("Data verification error at 0x%X\n", (unsigned long)f_ptr);
528             printf ("Expected 0x%X Got 0x%X\n", (~(unsigned long)f_ptr), *f_ptr);
529             goto finish;
530         }
531         f_ptr++;
532         bytes_written += 4;
533     }
534     printf ("Done Verifying Inverted Longword Data!\n\n");
535
536
537     printf ("Checking FLASH...\n");
538     if (check_eeprom(NO_ADDR, 0) == OK)
539         printf("FLASH is erased\n\n");
540     else {
541         printf("FLASH is programmed between 0x%X and 0x%X\n\n",
542                eeprom_prog_first, eeprom_prog_last);
543     }
544
545     printf ("Erasing FLASH...\n");
546     if (erase_eeprom(NO_ADDR, 0) != OK)
547         printf("Error on erase_eeprom()\n\n");
548     else
549         printf("Done Erasing FLASH!\n\n");
550
551     printf ("Checking FLASH...\n");
552     if (check_eeprom(NO_ADDR, 0) == OK)
553         printf("FLASH is erased\n\n");
554     else
555         printf("FLASH is programmed between 0x%X and 0x%X\n\n",
556                eeprom_prog_first, eeprom_prog_last);
557
558 /* 11/02/00 */
559     printf ("Setting Lock Bits for Blocks 0-3... \n");
560     if( (status = set_all_lock_bits() ) == OK )
561         printf("Done!\n");
562     else
563         printf("Error! status =0x%x\n", status);
564
565 finish:
566     _flushICache();
567
568     printf ("\nHit <CR> to Continue...\n");
569     (void)hexIn();
570     return;
571 }
572
573 #endif // CYGPKG_IO_FLASH