int flash_lock_block(volatile unsigned char *block) { volatile unsigned char *ROM; unsigned short stat; int timeout = 5000000; int cache_on; ROM = FLASH_P2V((unsigned long)block & 0xFF800000); HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Set lock bit FLASH_P2V(block)[0] = FLASH_Set_Lock; FLASH_P2V(block)[0] = FLASH_Set_Lock_Confirm; // Confirmation while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
/* check block lock configuration and display status of 64 blocks, 1=locked, 0=unlocked */ void check_lock_bit_status (void) { int block; volatile FLASH_TYPE *block_addr; /* address bit A0 is not used when obtaining identifier codes */ /* 11/01/00 */ /* unsigned long addr = 0x2<<1; */ unsigned long addr = 0x4; unsigned char block_lock_status[64]; block_addr = (volatile FLASH_TYPE *) addr; /* printf("Checking lock status of %d blocks, 1=locked, 0=unlocked...\n", block ); */ /* address bit A0 is not used when obtaining identifier codes */ for (block=0; block<=63; block++) { *FLASH_P2V(block_addr) = READ_ID_CMD; block_lock_status[block] = *FLASH_P2V(block_addr); *FLASH_P2V(block_addr) = RESET_CMD; do_nothing(); /* 11/01/00 */ do_nothing(); block_lock_status[block] &= 0x01; /* Checking lock status of block, 1=locked, 0=unlocked */ block_addr = (volatile FLASH_TYPE *)((unsigned long)block_addr + (unsigned long)FLASH_BLOCK_SIZE); /* block address offset for byte wide data storage */ } for (block=0; block<=63; block++) { if (block == 32) { printf("\n\r"); } printf("%d ", block_lock_status[block] ); } printf("\nDone!\n\n" ); /** return; **/ }
int flash_erase_block(volatile unsigned char *block) { volatile unsigned char *ROM; unsigned short stat; int timeout = 50000; int cache_on; int len; HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // First 4K page of flash at physcial address zero is // virtually mapped to address 0xa0000000. ROM = FLASH_P2V((unsigned)block & 0xFF800000); // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Erase block ROM[0] = FLASH_Block_Erase; *FLASH_P2V(block) = FLASH_Confirm; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; // If an error was reported, see if the block erased anyway if (stat & 0x7E) { len = FLASH_BLOCK_SIZE; while (len > 0) { if (*FLASH_P2V(block) != 0xFF) break; block++; len -= sizeof(*block); } if (len == 0) stat = 0; } if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
int check_program_lock(volatile FLASH_TYPE *flash) { FLASH_TYPE stat; flash = FLASH_P2V(flash); *flash = READ_STAT_REG; stat = *flash; /* poll and wait for Write State Machine Ready */ while (!(stat & WSM_READY)) stat = *flash; /* now check completion status */ if (stat & VPP_LOW_DETECT) { *flash = CLEAR_STAT_REG; return VPP_LOW_DETECT; } if (stat & PROGRAM_LOCK_ERROR) { *flash = CLEAR_STAT_REG; return PROGRAM_LOCK_ERROR; } if ((stat & ALL_FLASH_STATUS) == (WSM_READY | PROGRAM_LOCK_SUCCESS)) { *flash = CLEAR_STAT_REG; return OK; } else { *flash = CLEAR_STAT_REG; return UNKNOWN_ERR; } }
int check_op_status(int cmd, volatile FLASH_TYPE *flash) { FLASH_TYPE stat; flash = FLASH_P2V(flash); if (cmd == TRUE) { *flash = READ_STAT_REG; } stat = *flash; /* poll and wait for Write State Machine Ready */ while ((stat & WSM_READY) == WSM_BUSY) { stat = *flash; } /* now check completion status */ if ((stat & ALL_FLASH_STATUS) == WSM_READY) { *flash = CLEAR_STAT_REG; return OK; } else { *flash = CLEAR_STAT_REG; return stat; } }
int check_bstat(int block_num) { volatile FLASH_TYPE *lock_data_addr; FLASH_TYPE lock_data; /* shut the compiler up */ lock_data_addr = 0x00000000; /* derive the address for block lock configuration data */ if ((block_num >= 0) && (block_num <= NUM_FLASH_BLOCKS)) lock_data_addr = (FLASH_TYPE*)(FLASH_ADDR + (FLASH_BLOCK_SIZE * block_num) + 2); else if (block_num == -1) lock_data_addr = (FLASH_TYPE*)(FLASH_ADDR + 3); else return (2); lock_data_addr = FLASH_P2V(lock_data_addr); /* read block lock configuration data from address */ *lock_data_addr = READ_ID_CMD; lock_data = *lock_data_addr; /* reset flash to read mode */ *lock_data_addr = RESET_CMD; delay_and_flush(); /* wait for Flash to re-enter Read Array mode */ /* now check data to see if block is indeed locked */ if (lock_data & BLOCK_LOCKED) return (BLOCK_LOCKED); else return (BLOCK_UNLOCKED); }
int flash_unlock_block(volatile unsigned char *block, int block_size, int blocks) { volatile unsigned short *ROM, *bp; unsigned short stat; int timeout = 5000000; unsigned short is_locked[MAX_FLASH_BLOCKS]; int i; ROM = (unsigned short *) FLASH_P2V((unsigned long)block & 0xFF800000); // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Get current block lock state. This needs to access each block on // the device so currently locked blocks can be re-locked. bp = (unsigned short *)((unsigned long)block & 0xFF800000); for (i = 0; i < blocks; i++) { if (bp == (unsigned short *) block) { is_locked[i] = 0; } else { *(volatile unsigned short *)FLASH_P2V(bp) = FLASH_Read_Query; is_locked[i] = ((volatile unsigned short *)FLASH_P2V(bp))[2]; } bp += block_size / sizeof(*bp); } // Clears all lock bits FLASH_P2V(block)[0] = FLASH_Clear_Locks; FLASH_P2V(block)[0] = FLASH_Clear_Locks_Confirm; // Confirmation timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) goto done; } // Restore the lock state bp = (unsigned short *)((unsigned long)block & 0xFF800000); for (i = 0; i < blocks; i++) { if (is_locked[i]) { *FLASH_P2V(bp) = FLASH_Set_Lock; *FLASH_P2V(bp) = FLASH_Set_Lock_Confirm; // Confirmation timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) goto done; } } bp += block_size / sizeof(*bp); } done: // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; return stat; }
void init_eeprom() { #if 1 unsigned char MfgCode=MADE_BY_INTEL; unsigned char DevCode=I28F640J3A; eeprom_size = 0x800000; #else unsigned char MfgCode=0; unsigned char DevCode=0; flash_addr = FLASH_ADDR; flash_base = FLASH_BASE_ADDR; /* Set defaults */ eeprom_size = 0; /* Note: the PCI-700 platform has only 1 memory bank */ /* *( volatile unsigned char * ) FLASH_BASE_ADDR = RESET_CMD; printf( "Wrote 1rst Read Array Command\n"); */ *FLASH_P2V(FLASH_BASE_ADDR) = RESET_CMD; /* issue read array command */ delay_and_flush(); /* wait for Flash to re-enter Read Array mode */ *FLASH_P2V(FLASH_BASE_ADDR) = READ_ID_CMD; /* issue read id command */ MfgCode = *FLASH_P2V(FLASH_BASE_ADDR); /* read a manufacturer code at addr 0, address bit A0 is not used */ DevCode = *FLASH_P2V(DEV_CODE_ADDR); /* read a device code at addr 1 */ if (MfgCode == (MADE_BY_INTEL)) { switch ( DevCode ) /* device code stored in addr 1, address bit A0 is not used, must shift 0x00000001<<1=0x00000002 */ { case I28F640J3A: eeprom_size += 0x800000 * FLASH_WIDTH; /* I28F640J3A */ break; default: break; } } *FLASH_P2V(FLASH_BASE_ADDR) = READ_ID_CMD; /* issue 2nd read id command */ *FLASH_P2V(FLASH_BASE_ADDR) = RESET_CMD; /* issue read array command */ delay_and_flush(); /* wait for Flash to re-enter Read Array mode */ #endif printf( "\nManufacturer Code = 0x%x\n", MfgCode); printf( "Device Code = %x\n", DevCode); printf( "Flash Memory size = 0x%x\n", eeprom_size); return; }
int flash_lock_block(volatile flash_t *block) { volatile flash_t *ROM; flash_t stat; int timeout = 5000000; int cache_on; volatile int j; // Get base address and map addresses to virtual addresses ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block); block = FLASH_P2V(block); HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Set lock bit block[0] = FLASH_Set_Lock; block[0] = FLASH_Set_Lock_Confirm; // Confirmation for (j = 0; j < FLASH_Delay; ++j); while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; for (j = 0; j < FLASH_Delay; ++j); if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
int check_eeprom(ADDR addr, unsigned long length) { FLASH_TYPE *p, *end; if (eeprom_size == 0) { cmd_stat = E_NO_FLASH; return ERR; } if (addr == NO_ADDR) { addr = FLASH_BLK4_BASE_ADDR; /* start at base address of block */ length = eeprom_size - RESERVED_AREA_SIZE; } else if (length == 0) length = 1; p = (FLASH_TYPE *)addr; end = (FLASH_TYPE *)FLASH_TOP_ADDR; /* search for first non blank address starting at base address of Flash Block 2 */ while (p != end) { if (*FLASH_P2V(p) != 0xff) { eeprom_prog_first = (ADDR)p; /* found first non blank memory cell */ /* now find last non blank memory cell starting from top of Flash memory */ for (p = end - 1; *FLASH_P2V(p) == 0xff; --p) ; eeprom_prog_last = (ADDR)p; /* found last non blank memory cell */ cmd_stat = E_EEPROM_PROG; return ERR; } p++; } return OK; }
int flash_query(unsigned char *data) { volatile flash_t *ROM; int i, cnt; int cache_on; HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Get base address and map addresses to virtual addresses ROM = FLASH_P2V( CYGNUM_FLASH_BASE ); #ifdef CYGOPT_FLASH_IS_BOOTBLOCK // BootBlock flash does not support full Read_Query - we have do a // table oriented thing above, after getting just two bytes of results: ROM[0] = FLASH_Read_ID; i = 2; #else // StrataFlash supports the full Read_Query op: ROM[0] = FLASH_Read_Query; i = sizeof(struct FLASH_query); #endif // Not CYGOPT_FLASH_IS_BOOTBLOCK for (cnt = CNT; cnt > 0; cnt--) ; for ( /* i */; i > 0; i-- ) { // It is very deliberate that data is chars NOT flash_t: // The info comes out in bytes regardless of device. *data++ = (unsigned char) (*ROM++); #ifndef CYGOPT_FLASH_IS_BOOTBLOCK # if 8 == CYGNUM_FLASH_WIDTH // strata flash with 'byte-enable' contains the configuration data // at even addresses ++ROM; # endif #endif } ROM[0] = FLASH_Reset; if (cache_on) { HAL_DCACHE_ENABLE(); } return 0; }
int flash_query(unsigned char *data) { volatile unsigned short *ROM; int i, cnt; ROM = (unsigned short *) FLASH_P2V(0); ROM[0] = FLASH_Read_Query; for (cnt = CNT; cnt > 0; cnt--) ; for (i = 0; i < sizeof(struct FLASH_query); i++) { *data++ = ROM[i]; } ROM[0] = FLASH_Reset; return 0; }
int check_erase_unlock(volatile FLASH_TYPE *flash) { FLASH_TYPE stat; flash = FLASH_P2V(flash); *flash = READ_STAT_REG ; stat = *flash; /* poll and wait for Write State Machine Ready */ while ((stat & WSM_READY) == WSM_BUSY) { stat = *flash; } /* now check completion status */ if (stat & VPP_LOW_DETECT) { *flash = CLEAR_STAT_REG; return VPP_LOW_DETECT; } if ((stat & CMD_SEQ_ERR) == CMD_SEQ_ERR) { *flash = CLEAR_STAT_REG; return CMD_SEQ_ERR; } if (stat & ERASE_UNLOCK_ERROR) { *flash = CLEAR_STAT_REG; return ERASE_UNLOCK_ERROR; } if ((stat & ALL_FLASH_STATUS) == WSM_READY) { *flash = CLEAR_STAT_REG; return OK; } else { *flash = CLEAR_STAT_REG; return UNKNOWN_ERR; } }
int flash_program_buf(volatile flash_t *addr, flash_t *data, int len, unsigned long block_mask, int buffer_size) { volatile flash_t *ROM; volatile flash_t *BA; flash_t stat = 0; int timeout = 50000; int cache_on; #ifdef FLASH_Write_Buffer int i, wc; #endif HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Get base address and map addresses to virtual addresses ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)addr ); BA = FLASH_P2V( block_mask & (unsigned int)addr ); addr = FLASH_P2V(addr); // Clear any error conditions ROM[0] = FLASH_Clear_Status; #ifdef FLASH_Write_Buffer // Write any big chunks first while (len >= buffer_size) { wc = buffer_size; if (wc > len) wc = len; len -= wc; // convert 'wc' in bytes to 'wc' in 'flash_t' wc = wc / sizeof(flash_t); // Word count *BA = FLASH_Write_Buffer; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { goto bad; } *BA = FLASH_Write_Buffer; } *BA = FLASHWORD(wc-1); // Count is 0..N-1 for (i = 0; i < wc; i++) { #ifdef CYGHWR_FLASH_WRITE_ELEM CYGHWR_FLASH_WRITE_ELEM(addr+i, data+i); #else *(addr+i) = *(data+i); #endif } *BA = FLASH_Confirm; ROM[0] = FLASH_Read_Status; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { goto bad; } } // Jump out if there was an error if (stat & FLASH_ErrorMask) { goto bad; } // And verify the data - also increments the pointers. *BA = FLASH_Reset; for (i = 0; i < wc; i++) { if ( *addr++ != *data++ ) { stat = FLASH_ErrorNotVerified; goto bad; } } } #endif while (len > 0) { ROM[0] = FLASH_Program; #ifdef CYGHWR_FLASH_WRITE_ELEM CYGHWR_FLASH_WRITE_ELEM(addr, data); #else *addr = *data; #endif timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { goto bad; } } if (stat & FLASH_ErrorMask) { break; } ROM[0] = FLASH_Reset; if (*addr++ != *data++) { stat = FLASH_ErrorNotVerified; break; } len -= sizeof( flash_t ); } // Restore ROM to "normal" mode bad: ROM[0] = FLASH_Reset; if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
int flash_unlock_block(volatile flash_t *block, int block_size, int blocks) { volatile flash_t *ROM; flash_t stat; int timeout = 5000000; #ifndef CYGOPT_FLASH_IS_SYNCHRONOUS int i; volatile flash_t *bp, *bpv; unsigned char is_locked[CYGNUM_DEVS_FLASH_STRATA_MAX_BLOCKS]; #endif // Get base address and map addresses to virtual addresses ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)block ); block = FLASH_P2V(block); // Clear any error conditions ROM[0] = FLASH_Clear_Status; #ifdef CYGOPT_FLASH_IS_SYNCHRONOUS // Clear lock bit block[0] = FLASH_Clear_Locks; block[0] = FLASH_Clear_Locks_Confirm; // Confirmation while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } #else // Get current block lock state. This needs to access each block on // the device so currently locked blocks can be re-locked. bp = ROM; for (i = 0; i < blocks; i++) { bpv = FLASH_P2V( bp ); *bpv = FLASH_Read_Query; if (bpv == block) { is_locked[i] = 0; } else { #if 8 == CYGNUM_FLASH_WIDTH is_locked[i] = bpv[4] & FLASH_LOCK_MASK; #else is_locked[i] = bpv[2] & FLASH_LOCK_MASK; # endif } bp += block_size / sizeof(*bp); } // Clears all lock bits ROM[0] = FLASH_Clear_Locks; ROM[0] = FLASH_Clear_Locks_Confirm; // Confirmation timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } // Restore the lock state bp = ROM; for (i = 0; i < blocks; i++) { bpv = FLASH_P2V( bp ); if (is_locked[i]) { *bpv = FLASH_Set_Lock; *bpv = FLASH_Set_Lock_Confirm; // Confirmation timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } } bp += block_size / sizeof(*bp); } #endif // CYGOPT_FLASH_IS_SYNCHRONOUS // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; return stat; }
int flash_erase_block(volatile flash_t *block, unsigned int block_size) { volatile flash_t *ROM; flash_t stat = 0; int timeout = 50000; int cache_on; int len, block_len, erase_block_size; volatile flash_t *eb; HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Get base address and map addresses to virtual addresses ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block); eb = block = FLASH_P2V(block); block_len = block_size; #ifdef CYGOPT_FLASH_IS_BOOTBLOCK #define BLOCKSIZE (0x10000*CYGNUM_FLASH_DEVICES) #define ERASE_BLOCKSIZE (0x2000*CYGNUM_FLASH_DEVICES) if ((eb - ROM) < BLOCKSIZE) { // FIXME - Handle 'boot' blocks erase_block_size = ERASE_BLOCKSIZE; } else { erase_block_size = block_size; } #else erase_block_size = block_size; #endif // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Erase block while (block_len > 0) { ROM[0] = FLASH_Block_Erase; *eb = FLASH_Confirm; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } block_len -= erase_block_size; eb = FLASH_P2V((unsigned int)eb + erase_block_size); } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; // If an error was reported, see if the block erased anyway if (stat & FLASH_ErrorMask ) { len = block_size; while (len > 0) { if (*block++ != FLASH_BlankValue ) break; len -= sizeof(*block); } if (len == 0) stat = 0; } if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
int flash_program_buf(volatile unsigned char *addr, unsigned char *data, int len) { volatile unsigned char *ROM; volatile unsigned char *BA; unsigned short stat; int timeout = 5000000; int i, wc; ROM = FLASH_P2V((unsigned long)addr & 0xFF800000); BA = FLASH_P2V((unsigned long)addr & 0xFFFE0000); // Clear any error conditions ROM[0] = FLASH_Clear_Status; wc = 32; while (len >= wc) { len -= wc; // The IQ803010 has a hole in flash which must be avoided. if (((unsigned char *)0x1000) <= addr && addr < ((unsigned char *)0x2000)) { addr += wc; data += wc; continue; } *BA = FLASH_Write_Buffer; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { stat |= 0x0100; goto bad; } *BA = FLASH_Write_Buffer; } *BA = wc-1; // Count is 0..N-1 if (FLASH_P2V(addr) != addr) { volatile unsigned char *tmp; tmp = FLASH_P2V(addr); for (i = 0; i < wc; i++) *tmp++ = *data++; addr += wc; } else { for (i = 0; i < wc; i++) *addr++ = *data++; } *BA = FLASH_Confirm; stat = *BA; } ROM[0] = FLASH_Read_Status; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { stat |= 0x0200; goto bad; } } while (len > 0) { ROM[0] = FLASH_Program; *FLASH_P2V(addr) = *data++; addr++; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { stat |= 0x0300; goto bad; } } --len; } // Restore ROM to "normal" mode bad: ROM[0] = FLASH_Reset; return stat; }