1 #ifndef CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL
2 #define CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL
3 //==========================================================================
7 // Intel 28Fxxx series flash driver
9 //==========================================================================
10 //####ECOSGPLCOPYRIGHTBEGIN####
11 // -------------------------------------------
12 // This file is part of eCos, the Embedded Configurable Operating System.
13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
14 // Copyright (C) 2002 Gary Thomas
16 // eCos is free software; you can redistribute it and/or modify it under
17 // the terms of the GNU General Public License as published by the Free
18 // Software Foundation; either version 2 or (at your option) any later version.
20 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
21 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 // You should have received a copy of the GNU General Public License along
26 // with eCos; if not, write to the Free Software Foundation, Inc.,
27 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
29 // As a special exception, if other files instantiate templates or use macros
30 // or inline functions from this file, or you compile this file and link it
31 // with other works to produce a work based on this file, this file does not
32 // by itself cause the resulting work to be covered by the GNU General Public
33 // License. However the source code for this file must still be made available
34 // in accordance with section (3) of the GNU General Public License.
36 // This exception does not invalidate any other reasons why a work based on
37 // this file might be covered by the GNU General Public License.
39 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
40 // at http://sources.redhat.com/ecos/ecos-license/
41 // -------------------------------------------
42 //####ECOSGPLCOPYRIGHTEND####
43 //==========================================================================
44 //#####DESCRIPTIONBEGIN####
47 // Contributors: jskov
52 // Notes: Device table could use unions of flags to save some space
54 //####DESCRIPTIONEND####
56 //==========================================================================
58 #include <pkgconf/hal.h>
59 #include <pkgconf/io_flash.h>
60 #include <pkgconf/devs_flash_intel_28fxxx.h>
62 #include <cyg/hal/hal_arch.h>
63 #include <cyg/hal/hal_cache.h>
64 #include CYGHWR_MEMORY_LAYOUT_H
66 #include <cyg/hal/hal_io.h>
68 #define _FLASH_PRIVATE_
69 #include <cyg/io/flash.h>
74 typedef void (*call_t)(char* str, ...);
75 extern void diag_printf(char* str, ...);
76 call_t d_print = &diag_printf;
78 #define d_print(fmt,args...)
81 //----------------------------------------------------------------------------
82 // Common device details.
83 #define FLASH_Read_ID FLASHWORD( 0x90 )
84 #define FLASH_Reset FLASHWORD( 0xFF )
85 #define FLASH_Program FLASHWORD( 0x40 )
86 #define FLASH_Program_M18 FLASHWORD( 0x41 )
87 #define FLASH_Write_Buffer FLASHWORD( 0xE8 )
88 #define FLASH_Write_Buffer_M18 FLASHWORD( 0xE9 )
89 #define FLASH_Block_Erase FLASHWORD( 0x20 )
90 #define FLASH_Confirm FLASHWORD( 0xD0 )
91 #define FLASH_Resume FLASHWORD( 0xD0 )
93 #define FLASH_Set_Lock FLASHWORD( 0x60 )
94 #define FLASH_Set_Lock_Confirm FLASHWORD( 0x01 )
95 #define FLASH_Clear_Lock FLASHWORD( 0x60 )
96 #define FLASH_Clear_Lock_Confirm FLASHWORD( 0xd0 )
98 #define FLASH_Read_Status FLASHWORD( 0x70 )
99 #define FLASH_Clear_Status FLASHWORD( 0x50 )
100 #define FLASH_Status_Ready FLASHWORD( 0x80 )
102 // Status that we read back:
103 #define FLASH_ErrorMask FLASHWORD( 0x7E )
104 #define FLASH_ErrorProgram FLASHWORD( 0x10 )
105 #define FLASH_ErrorErase FLASHWORD( 0x20 )
106 #define FLASH_ErrorLock FLASHWORD( 0x30 )
107 #define FLASH_ErrorLowVoltage FLASHWORD( 0x08 )
108 #define FLASH_ErrorLocked FLASHWORD( 0x02 )
110 // Platform code must define the below
111 // #define CYGNUM_FLASH_INTERLEAVE : Number of interleaved devices (in parallel)
112 // #define CYGNUM_FLASH_SERIES : Number of devices in series
113 // #define CYGNUM_FLASH_WIDTH : Width of devices on platform
114 // #define CYGNUM_FLASH_BASE : Address of first device
116 #define CYGNUM_FLASH_BLANK (1)
117 #define CYGNUM_FLASH_DEVICES (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)
121 # define FLASH_P2V( _a_ ) ((volatile flash_data_t *)((CYG_ADDRWORD)(_a_)))
123 #ifndef CYGHWR_FLASH_28FXXX_PLF_INIT
124 # define CYGHWR_FLASH_28FXXX_PLF_INIT()
126 #ifndef CYGHWR_FLASH_WRITE_ENABLE
127 #define CYGHWR_FLASH_WRITE_ENABLE()
129 #ifndef CYGHWR_FLASH_WRITE_DISABLE
130 #define CYGHWR_FLASH_WRITE_DISABLE()
133 //----------------------------------------------------------------------------
134 // Now that device properties are defined, include magic for defining
135 // accessor type and constants.
136 #include <cyg/io/flash_dev.h>
138 //----------------------------------------------------------------------------
139 // Information about supported devices
140 typedef struct flash_dev_info {
141 flash_data_t device_id;
142 cyg_uint32 block_size;
143 cyg_int32 block_count;
144 cyg_uint32 base_mask;
145 cyg_uint32 device_size;
146 cyg_bool locking; // supports locking
147 cyg_bool buffered_w; // supports buffered writes
149 cyg_uint32 bootblocks[12]; // 0 is bootblock offset, 1-11 sub-sector sizes (or 0)
151 cyg_uint32 banks[2]; // bank offets, highest to lowest (lowest should be 0)
152 // (only one entry for now, increase to support devices
156 static const flash_dev_info_t* flash_dev_info;
157 static const flash_dev_info_t supported_devices[] = {
158 #include <cyg/io/flash_28fxxx_parts.inl>
160 #define NUM_DEVICES (sizeof(supported_devices)/sizeof(flash_dev_info_t))
162 //----------------------------------------------------------------------------
163 // Functions that put the flash device into non-read mode must reside
165 #ifndef MXCFLASH_SELECT_MULTI
166 void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
167 int flash_erase_block(void* block, unsigned int size)
168 __attribute__ ((section (".2ram.flash_erase_block")));
169 int flash_program_buf(void* addr, void* data, int len,
170 unsigned long block_mask, int buffer_size)
171 __attribute__ ((section (".2ram.flash_program_buf")));
172 int flash_lock_block(void* addr)
173 __attribute__ ((section (".2ram.flash_lock_block")));
174 int flash_unlock_block(void* block, int block_size, int blocks)
175 __attribute__ ((section (".2ram.flash_unlock_block")));
177 void norflash_query(void* data);
178 int norflash_erase_block(void* block, unsigned int block_size);
179 int norflash_program_buf(void* addr, void* data, int len,
180 unsigned long block_mask, int buffer_size);
181 int norflash_lock_block(void* addr);
182 int norflash_unlock_block(void* block, int block_size, int blocks);
183 #endif //MXCFLASH_SELECT_MULTI
185 //----------------------------------------------------------------------------
186 // Initialize driver details
187 #ifndef MXCFLASH_SELECT_MULTI
188 int flash_hwr_init(void)
190 int norflash_hwr_init(void)
196 CYGHWR_FLASH_28FXXX_PLF_INIT();
200 // Look through table for device data
201 flash_dev_info = supported_devices;
202 for (i = 0; i < NUM_DEVICES; i++) {
203 if (flash_dev_info->device_id == id[1])
208 // Did we find the device? If not, return error.
209 if (NUM_DEVICES == i)
210 return FLASH_ERR_DRV_WRONG_PART;
212 // Hard wired for now
213 flash_info.block_size = flash_dev_info->block_size;
214 flash_info.blocks = flash_dev_info->block_count * CYGNUM_FLASH_SERIES;
215 flash_info.start = (void *)CYGNUM_FLASH_BASE;
216 flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (flash_dev_info->device_size * CYGNUM_FLASH_SERIES));
221 //----------------------------------------------------------------------------
222 // Map a hardware status to a package error
223 #ifndef MXCFLASH_SELECT_MULTI
224 int flash_hwr_map_error(int e)
226 int norflash_hwr_map_error(int e)
233 //----------------------------------------------------------------------------
234 // See if a range of FLASH addresses overlaps currently running code
235 #ifndef MXCFLASH_SELECT_MULTI
236 bool flash_code_overlaps(void *start, void *end)
238 bool norflash_code_overlaps(void *start, void *end)
241 extern unsigned char _stext[], _etext[];
243 return ((((unsigned long)&_stext >= (unsigned long)start) &&
244 ((unsigned long)&_stext < (unsigned long)end)) ||
245 (((unsigned long)&_etext >= (unsigned long)start) &&
246 ((unsigned long)&_etext < (unsigned long)end)));
249 //----------------------------------------------------------------------------
252 // Only reads the manufacturer and part number codes for the first
253 // device(s) in series. It is assumed that any devices in series
254 // will be of the same type.
256 #ifndef MXCFLASH_SELECT_MULTI
257 void flash_query(void* data)
259 void norflash_query(void* data)
262 volatile flash_data_t *ROM;
263 flash_data_t* id = (flash_data_t*) data;
266 ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
270 CYGHWR_FLASH_WRITE_ENABLE();
272 ROM[0] = FLASH_Read_ID;
274 // Manufacturers' code
279 ROM[0] = FLASH_Reset;
281 CYGHWR_FLASH_WRITE_DISABLE();
283 // Stall, waiting for flash to return to read mode.
287 //----------------------------------------------------------------------------
289 #ifndef MXCFLASH_SELECT_MULTI
290 int flash_erase_block(void* block, unsigned int block_size)
292 int norflash_erase_block(void* block, unsigned int block_size)
295 int res = FLASH_ERR_OK;
300 volatile flash_data_t *ROM;
301 volatile flash_data_t *b_p = (flash_data_t*) block;
302 volatile flash_data_t *b_v;
305 ROM = FLASH_P2V((unsigned long)block & flash_dev_info->base_mask);
307 // Is this the boot sector?
308 bootblock = (flash_dev_info->bootblock &&
309 (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM)));
311 len = flash_dev_info->bootblocks[len_ix++];
313 len = flash_dev_info->block_size;
316 CYGHWR_FLASH_WRITE_ENABLE();
319 b_v = FLASH_P2V(b_p);
321 // Clear any error conditions
322 ROM[0] = FLASH_Clear_Status;
325 *b_v = FLASH_Block_Erase;
326 *b_v = FLASH_Confirm;
329 while(((stat = *b_v) & FLASH_Status_Ready) != FLASH_Status_Ready) {
330 if (--timeout == 0) break;
333 // Restore ROM to "normal" mode
336 if (stat & FLASH_ErrorMask) {
337 if (!(stat & FLASH_ErrorErase)) {
338 res = FLASH_ERR_HWR; // Unknown error
340 if (stat & FLASH_ErrorLowVoltage)
341 res = FLASH_ERR_LOW_VOLTAGE;
342 else if (stat & FLASH_ErrorLocked)
343 res = FLASH_ERR_PROTECT;
345 res = FLASH_ERR_ERASE;
349 // Check if block got erased
351 b_v = FLASH_P2V(b_p++);
352 if (*b_v != FLASH_BlankValue ) {
353 // Only update return value if erase operation was OK
354 if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
361 len = flash_dev_info->bootblocks[len_ix++];
364 CYGHWR_FLASH_WRITE_DISABLE();
369 //----------------------------------------------------------------------------
372 #ifndef MXCFLASH_SELECT_MULTI
373 int flash_program_buf(void* addr, void* data, int len,
374 unsigned long block_mask, int buffer_size)
376 int norflash_program_buf(void* addr, void* data, int len,
377 unsigned long block_mask, int buffer_size)
380 flash_data_t stat = 0;
383 volatile flash_data_t* ROM;
384 volatile flash_data_t* BA;
385 volatile flash_data_t* addr_v;
386 volatile flash_data_t* addr_p = (flash_data_t*) addr;
387 volatile flash_data_t* data_p = (flash_data_t*) data;
389 int res = FLASH_ERR_OK;
391 // Base address of device(s) being programmed.
392 ROM = FLASH_P2V((unsigned long)addr & flash_dev_info->base_mask);
393 BA = FLASH_P2V((unsigned long)addr & ~(flash_dev_info->block_size - 1));
395 #ifdef CYGPKG_HAL_ARM_MXC30031ADS
396 d_print("ROM=%p, BA=%p\n", ROM, BA);
399 CYGHWR_FLASH_WRITE_ENABLE();
401 // Clear any error conditions
402 BA[0] = FLASH_Clear_Status;
403 addr_v = FLASH_P2V(addr_p);
404 d_print("%s: len=0x%x, *addr_v=0x%x, *data_p=0x%x, addr_v=%p, addr_p=%p\n",
405 __FUNCTION__, len, *addr_v, *data_p, addr_v, addr_p);
408 int wc = (len >= 0x400) ? 0x400: len;
411 wc = (wc + 1) & ~0x1;
415 *addr_v = FLASH_Write_Buffer_M18;
416 if (--timeout == 0) {
417 res = FLASH_ERR_DRV_TIMEOUT;
418 d_print("flash_program_buf0: addr_v=0x%x, *addr_v=0x%x, *data_p=0x%x\n",
419 addr_v, *addr_v, *data_p);
422 } while(((stat = *addr_v) & FLASH_Status_Ready) != FLASH_Status_Ready);
424 *addr_v = (wc / 2) - 1;
425 //memcpy(addr_v, data_p, wc);
426 for (; wc > 0; wc -= 2) {
427 *addr_v++ = *data_p++;
431 *addr_p = FLASH_Confirm;
433 while(((stat = *addr_p) & FLASH_Status_Ready) != FLASH_Status_Ready) {
434 if (--timeout == 0) {
435 res = FLASH_ERR_DRV_TIMEOUT;
436 d_print("flash_program_buf0: addr_v=0x%x, *addr_v=0x%x, *data_p=0x%x\n",
437 addr_v, *addr_v, *data_p);
441 if (stat & FLASH_ErrorMask) {
442 if (!(stat & FLASH_ErrorProgram))
443 res = FLASH_ERR_HWR; // Unknown error
445 if (stat & FLASH_ErrorLowVoltage)
446 res = FLASH_ERR_LOW_VOLTAGE;
447 else if (stat & FLASH_ErrorLocked)
448 res = FLASH_ERR_PROTECT;
450 res = FLASH_ERR_PROGRAM;
454 addr_p[0] = FLASH_Clear_Status;
455 addr_p[0] = FLASH_Reset;
459 #else //CYGPKG_HAL_ARM_MXC30031ADS
461 CYGHWR_FLASH_WRITE_ENABLE();
463 // Clear any error conditions
464 ROM[0] = FLASH_Clear_Status;
466 #ifdef CYGHWR_DEVS_FLASH_INTEL_BUFFERED_WRITES
467 // FIXME: This code has not been adjusted to handle bootblock
469 // FIXME: This code does not appear to work anymore
470 if (0 && flash_dev_info->buffered_w) {
472 // Write any big chunks first
473 while (len >= buffer_size) {
475 if (wc > len) wc = len;
477 wc = wc / ((CYGNUM_FLASH_WIDTH/8)*CYGNUM_FLASH_INTERLEAVE); // Word count
480 *BA = FLASH_Write_Buffer;
481 while(((stat = BA[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
482 if (--timeout == 0) {
483 res = FLASH_ERR_DRV_TIMEOUT;
486 *BA = FLASH_Write_Buffer;
488 *BA = FLASHWORD(wc-1); // Count is 0..N-1
489 for (i = 0; i < wc; i++) {
490 addr_v = FLASH_P2V(addr_p++);
495 *BA = FLASH_Read_Status;
497 while(((stat = BA[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
498 if (--timeout == 0) {
499 res = FLASH_ERR_DRV_TIMEOUT;
505 #endif // CYGHWR_DEVS_FLASH_INTEL_BUFFERED_WRITES
508 addr_v = FLASH_P2V(addr_p++);
509 *addr_v = FLASH_Program;
512 while(((stat = *addr_v) & FLASH_Status_Ready) != FLASH_Status_Ready) {
513 if (--timeout == 0) {
514 res = FLASH_ERR_DRV_TIMEOUT;
515 d_print("flash_program_buf0: addr_v=0x%x, *addr_v=0x%x, *data_p=0x%x\n",
516 addr_v, *addr_v, *data_p);
520 if (stat & FLASH_ErrorMask) {
521 if (!(stat & FLASH_ErrorProgram))
522 res = FLASH_ERR_HWR; // Unknown error
524 if (stat & FLASH_ErrorLowVoltage)
525 res = FLASH_ERR_LOW_VOLTAGE;
526 else if (stat & FLASH_ErrorLocked)
527 res = FLASH_ERR_PROTECT;
529 res = FLASH_ERR_PROGRAM;
533 ROM[0] = FLASH_Clear_Status;
534 ROM[0] = FLASH_Reset;
535 if (*addr_v != *data_p++) {
536 d_print("flash_program_buf: addr_v=0x%x, *addr_v=0x%x, *data_p=0x%x\n",
537 addr_v, *addr_v, *data_p);
538 res = FLASH_ERR_DRV_VERIFY;
541 len -= sizeof( flash_data_t );
543 #endif //CYGPKG_HAL_ARM_MXC30031ADS
544 // Restore ROM to "normal" mode
546 ROM[0] = FLASH_Reset;
548 CYGHWR_FLASH_WRITE_DISABLE();
550 // Ideally, we'd want to return not only the failure code, but also
551 // the address/device that reported the error.
555 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
556 //----------------------------------------------------------------------------
558 #ifndef MXCFLASH_SELECT_MULTI
559 int flash_lock_block(void* block)
561 int norflash_lock_block(void* block)
564 volatile flash_data_t *ROM;
565 int res = FLASH_ERR_OK;
567 int timeout = 5000000;
568 volatile flash_data_t* b_p = (flash_data_t*) block;
569 volatile flash_data_t *b_v;
573 if (!flash_dev_info->locking)
576 d_print("flash_lock_block %08x\n", block);
578 ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask);
580 // Is this the boot sector?
581 bootblock = (flash_dev_info->bootblock &&
582 (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM)));
584 len = flash_dev_info->bootblocks[len_ix++];
585 d_print("\nboot block\n");
587 len = flash_dev_info->block_size;
590 CYGHWR_FLASH_WRITE_ENABLE();
593 b_v = FLASH_P2V(b_p);
594 #ifdef CYGPKG_HAL_ARM_MXC30031ADS
597 // Clear any error conditions
598 ROM[0] = FLASH_Clear_Status;
601 *b_v = FLASH_Set_Lock;
602 *b_v = FLASH_Set_Lock_Confirm; // Confirmation
603 while(((state = *b_v) & FLASH_Status_Ready) != FLASH_Status_Ready) {
604 if (--timeout == 0) {
605 res = FLASH_ERR_DRV_TIMEOUT;
610 // Restore ROM to "normal" mode
611 ROM[0] = FLASH_Reset;
614 b_p += len / sizeof( flash_data_t );
617 if (FLASH_ErrorLock == (state & FLASH_ErrorLock))
618 res = FLASH_ERR_LOCK;
620 if (res != FLASH_ERR_OK)
624 len = flash_dev_info->bootblocks[len_ix++];
627 CYGHWR_FLASH_WRITE_DISABLE();
632 //----------------------------------------------------------------------------
635 #ifndef MXCFLASH_SELECT_MULTI
636 int flash_unlock_block(void* block, int block_size, int blocks)
638 int norflash_unlock_block(void* block, int block_size, int blocks)
641 volatile flash_data_t *ROM;
642 int res = FLASH_ERR_OK;
644 int timeout = 5000000;
645 volatile flash_data_t* b_p = (flash_data_t*) block;
646 volatile flash_data_t *b_v;
648 #if (defined(CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4) || defined(CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_95) )
649 // The Sharp device follows all the same rules as the Intel 28x part,
650 // except that the unlocking mechanism unlocks all blocks at once. This
651 // is the way the Strata part seems to work. I will replace the
652 // flash_unlock_block function with one similar to the Strata function.
653 // As the Sharp part does not have the bootlock characteristics, I
656 // The difficulty with this operation is that the hardware does not support
657 // unlocking single blocks. However, the logical layer would like this to
658 // be the case, so this routine emulates it. The hardware can clear all of
659 // the locks in the device at once. This routine will use that approach and
660 // then reset the regions which are known to be locked.
663 #define MAX_FLASH_BLOCKS (flash_dev_info->block_count * CYGNUM_FLASH_SERIES)
665 unsigned char is_locked[MAX_FLASH_BLOCKS];
668 // Get base address and map addresses to virtual addresses
670 d_print("\nNow inside low level driver\n");
672 ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
673 block = FLASH_P2V(block);
675 // Clear any error conditions
676 ROM[0] = FLASH_Clear_Status;
678 // Get current block lock state. This needs to access each block on
679 // the device so currently locked blocks can be re-locked.
681 for (i = 0; i < blocks; i++) {
682 b_v = FLASH_P2V( b_p );
683 *b_v = FLASH_Read_ID;
687 if(b_v[2]){ /* it is possible that one of the interleaved devices
688 * is locked, but others are not. Coming out of this
689 * function, if one was locked, all will be locked.
698 b_p += block_size / sizeof(*b_p);
700 ROM[0] = FLASH_Reset;
702 for (i = 0; i < blocks; i++) {
703 d_print("\nblock %d %s", i,
704 is_locked[i] ? "LOCKED" : "UNLOCKED");
709 // Clears all lock bits
710 ROM[0] = FLASH_Clear_Lock;
711 ROM[0] = FLASH_Clear_Lock_Confirm; // Confirmation
713 while(((state = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
714 if (--timeout == 0) break;
717 // Restore the lock state
719 for (i = 0; i < blocks; i++) {
720 b_v = FLASH_P2V( b_p );
722 *b_v = FLASH_Set_Lock;
723 *b_v = FLASH_Set_Lock_Confirm; // Confirmation
725 while(((state = ROM[0]) & FLASH_Status_Ready)
726 != FLASH_Status_Ready) {
728 res = FLASH_ERR_DRV_TIMEOUT;
732 if (FLASH_ErrorLock == (state & FLASH_ErrorLock))
733 res = FLASH_ERR_LOCK;
735 if (res != FLASH_ERR_OK)
739 b_p += block_size / sizeof(*b_p);
742 // Restore ROM to "normal" mode
743 ROM[0] = FLASH_Reset;
747 #else // not CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4
752 if (!flash_dev_info->locking)
755 ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask);
758 d_print("flash_unlock_block dev %08x block %08x size %08x count %08x\n", ROM, block, block_size, blocks);
761 // Is this the boot sector?
762 bootblock = (flash_dev_info->bootblock &&
763 (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM)));
765 len = flash_dev_info->bootblocks[len_ix++];
766 d_print("\nboot block\n");
768 len = flash_dev_info->block_size;
771 CYGHWR_FLASH_WRITE_ENABLE();
775 b_v = FLASH_P2V(b_p);
777 // Clear any error conditions
778 #ifdef CYGPKG_HAL_ARM_MXC30031ADS
781 ROM[0] = FLASH_Clear_Status;
784 *b_v = FLASH_Clear_Lock;
785 *b_v = FLASH_Clear_Lock_Confirm; // Confirmation
786 while(((state = *b_v) & FLASH_Status_Ready) != FLASH_Status_Ready) {
787 if (--timeout == 0) {
788 res = FLASH_ERR_DRV_TIMEOUT;
793 // Restore ROM to "normal" mode
794 ROM[0] = FLASH_Reset;
797 b_p += len / sizeof( flash_data_t );
800 if (FLASH_ErrorLock == (state & FLASH_ErrorLock))
801 res = FLASH_ERR_LOCK;
803 if (res != FLASH_ERR_OK)
807 len = flash_dev_info->bootblocks[len_ix++];
810 CYGHWR_FLASH_WRITE_DISABLE();
814 // FIXME: Unlocking need to support some other parts in the future
815 // as well which take a little more diddling.
818 // The difficulty with this operation is that the hardware does not support
819 // unlocking single blocks. However, the logical layer would like this to
820 // be the case, so this routine emulates it. The hardware can clear all of
821 // the locks in the device at once. This routine will use that approach and
822 // then reset the regions which are known to be locked.
825 #define MAX_FLASH_BLOCKS (flash_dev_info->block_count * CYGNUM_FLASH_SERIES)
827 unsigned char is_locked[MAX_FLASH_BLOCKS];
829 // Get base address and map addresses to virtual addresses
830 ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)block );
831 block = FLASH_P2V(block);
833 // Clear any error conditions
834 ROM[0] = FLASH_Clear_Status;
836 // Get current block lock state. This needs to access each block on
837 // the device so currently locked blocks can be re-locked.
839 for (i = 0; i < blocks; i++) {
840 bpv = FLASH_P2V( bp );
841 *bpv = FLASH_Read_Query;
845 is_locked[i] = bpv[2];
847 bp += block_size / sizeof(*bp);
850 // Clears all lock bits
851 ROM[0] = FLASH_Clear_Locks;
852 ROM[0] = FLASH_Clear_Locks_Confirm; // Confirmation
854 while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
855 if (--timeout == 0) break;
858 // Restore the lock state
860 for (i = 0; i < blocks; i++) {
861 bpv = FLASH_P2V( bp );
863 *bpv = FLASH_Set_Lock;
864 *bpv = FLASH_Set_Lock_Confirm; // Confirmation
866 while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) {
867 if (--timeout == 0) break;
870 bp += block_size / sizeof(*bp);
873 // Restore ROM to "normal" mode
874 ROM[0] = FLASH_Reset;
876 #endif // #CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4
878 #endif // CYGHWR_IO_FLASH_BLOCK_LOCKING
880 #endif // CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL