int oper_flash_erase_block(void* block) /* */ /* INPUTS : o block Block address */ /* OUTPUTS : ---- */ /* RETURNS : o --- */ /* DESCRIPTION: */ /* This function is used to erase a block */ /* $rtn_hdr_end */ /*****************************************************************************/ { int stat = 0; #ifndef IROSBOOT unsigned long cur_interrupt_state; HAL_FLASH_CACHES_STATE(d_cache, i_cache); HAL_DISABLE_INTERRUPTS(cur_interrupt_state); HAL_FLASH_CACHES_OFF(d_cache, i_cache); #endif #ifdef HAVE_SERIAL_FLASH flash_erase_block((cs_uint32)block,0); #else typedef int c_fun(unsigned short *, unsigned int); c_fun *_flash_erase_block; _flash_erase_block = (c_fun*) __anonymizer(&flash_erase_block); stat = (*_flash_erase_block)(block, flash_dev_info->block_size); #endif /* HAVE_SERIAL_FLASH */ #ifndef IROSBOOT HAL_FLASH_CACHES_ON(d_cache, i_cache); HAL_RESTORE_INTERRUPTS(cur_interrupt_state); #endif return stat; }
void oper_flash_read_id(void* data) /* */ /* INPUTS : o data Point to a variable to read the ID */ /* OUTPUTS : o data The ID is stored in data */ /* RETURNS : o --- */ /* DESCRIPTION: */ /* Only reads the manufacturer and part number codes for the first */ /* device(s) in series. It is assumed that any devices in series */ /* will be of the same type. */ /* $rtn_hdr_end */ /*****************************************************************************/ { #ifndef HAVE_SERIAL_FLASH typedef void c_fun(void*); c_fun *_flash_query; #ifndef IROSBOOT unsigned long cur_interrupt_state; HAL_FLASH_CACHES_STATE(d_cache, i_cache); #endif _flash_query = (c_fun*) __anonymizer(&flash_query); #ifndef IROSBOOT HAL_DISABLE_INTERRUPTS(cur_interrupt_state); HAL_FLASH_CACHES_OFF(d_cache, i_cache); #endif (*_flash_query)(data); #ifndef IROSBOOT HAL_FLASH_CACHES_ON(d_cache, i_cache); HAL_RESTORE_INTERRUPTS(cur_interrupt_state); #endif #else flash_query(data); #endif /* HAVE_SERIAL_FLASH */ return; }
int oper_flash_unlock_block(void* block) /* */ /* INPUTS : o block Block start address */ /* OUTPUTS : ---- */ /* RETURNS : o Status of unlock operation */ /* DESCRIPTION: */ /* This function will unlock the blocks. */ /* $rtn_hdr_end */ /*****************************************************************************/ { int stat = 0; #ifndef HAVE_SERIAL_FLASH typedef int c_fun(unsigned short *, int, int); c_fun *_flash_unlock_block; #ifndef IROSBOOT unsigned long cur_interrupt_state; HAL_FLASH_CACHES_STATE(d_cache, i_cache); #endif _flash_unlock_block = (c_fun*) __anonymizer(&flash_unlock_block); #ifndef IROSBOOT HAL_DISABLE_INTERRUPTS(cur_interrupt_state); HAL_FLASH_CACHES_OFF(d_cache, i_cache); #endif stat = (*_flash_unlock_block)(block, flash_dev_info->block_size, 0x1); #ifndef IROSBOOT HAL_FLASH_CACHES_ON(d_cache, i_cache); HAL_RESTORE_INTERRUPTS(cur_interrupt_state); #endif #endif /* HAVE_SERIAL_FLASH */ return stat; }
int oper_flash_write(void* addr, int data) /* */ /* INPUTS : o addr Address to which data to be written */ /* o data Data that need to be written */ /* OUTPUTS : ---- */ /* RETURNS : o Status of the write operation */ /* DESCRIPTION: */ /* This function writes the data to the flash */ /* THIS FUNCTION CONSIDERES THE BLOCK IN UNLOCKED */ /* WRITE ONLY 2 BYTE */ /* $rtn_hdr_end */ /*****************************************************************************/ { int stat = 0; #ifndef IROSBOOT unsigned long cur_interrupt_state; HAL_FLASH_CACHES_STATE(d_cache, i_cache); HAL_DISABLE_INTERRUPTS(cur_interrupt_state); HAL_FLASH_CACHES_OFF(d_cache, i_cache); #endif #ifdef HAVE_SERIAL_FLASH flash_program_buf_word(addr,(cs_uint32)data); #else typedef int c_fun(void *, int); c_fun *_flash_program_buf_word; _flash_program_buf_word = (c_fun*) __anonymizer(&flash_program_buf_word); stat = (*_flash_program_buf_word)(addr, data); #endif /* HAVE_SERIAL_FLASH */ #ifndef IROSBOOT HAL_FLASH_CACHES_ON(d_cache, i_cache); HAL_RESTORE_INTERRUPTS(cur_interrupt_state); #endif return stat; }
int oper_flash_bulk_write(void* _addr, void* _data, int len) /* */ /* INPUTS : o addr Address to which data to be written */ /* o data Address of Data that need to be written */ /* o len Length of data hat need to be written */ /* OUTPUTS : ---- */ /* RETURNS : o Status of the write operation */ /* DESCRIPTION: */ /* This function writes the bulk data to the flash */ /* THIS FUNCTION UNLOCKS THE BLOCK FIRST BEFORE IT WRITES */ /* $rtn_hdr_end */ /*****************************************************************************/ { int stat = 0; #ifndef IROSBOOT unsigned long cur_interrupt_state; HAL_FLASH_CACHES_STATE(d_cache, i_cache); HAL_DISABLE_INTERRUPTS(cur_interrupt_state); HAL_FLASH_CACHES_OFF(d_cache, i_cache); #endif #ifdef HAVE_SERIAL_FLASH flash_program_buf((cs_uint32)_addr,(cs_uint32)_data,len,0,0); #else int size; typedef int c_fun(void *, void *, int, unsigned long, int); c_fun *_flash_program_buf; unsigned char *addr = (unsigned char *)_addr; unsigned char *data = (unsigned char *)_data; unsigned long tmp; _flash_program_buf = (c_fun*) __anonymizer(&flash_program_buf); while (len > 0) { size = len; if (size > flash_dev_info->block_size) size = flash_dev_info->block_size; tmp = (unsigned long) addr & (~flash_dev_info->block_mask); if (tmp) { tmp = flash_dev_info->block_size - tmp; if (size > tmp) size = tmp; } stat = (*_flash_program_buf)(addr, data, size, flash_dev_info->block_mask, 0x0); if (stat != FLASH_ERR_OK) { break; } len -= size; addr += size/sizeof(*addr); data += size/sizeof(*data); } #endif /* HAVE_SERIAL_FLASH */ #ifndef IROSBOOT HAL_FLASH_CACHES_ON(d_cache, i_cache); HAL_RESTORE_INTERRUPTS(cur_interrupt_state); #endif return (stat); }
// FIXME: Want to change all drivers to use this function. But it may // make sense to wait till device structure pointer arguments get // added as well. void flash_dev_query(void* data) { typedef void code_fun(void*); code_fun *_flash_query; int d_cache, i_cache; _flash_query = (code_fun*) __anonymizer(&flash_query); HAL_FLASH_CACHES_OFF(d_cache, i_cache); (*_flash_query)(data); HAL_FLASH_CACHES_ON(d_cache, i_cache); }
int flash_unlock(void *addr, int len, void **err_addr) { unsigned short *block, *end_addr; int stat = 0; typedef int code_fun(unsigned short *, int, int); code_fun *_flash_unlock_block; int d_cache, i_cache; if (!flash_info.init) { return FLASH_ERR_NOT_INIT; } #ifdef CYGSEM_IO_FLASH_SOFT_WRITE_PROTECT if (plf_flash_query_soft_wp(addr,len)) return FLASH_ERR_PROTECT; #endif _flash_unlock_block = (code_fun*) __anonymizer(&flash_unlock_block); block = (unsigned short *)((CYG_ADDRESS)addr & flash_info.block_mask); end_addr = (unsigned short *)((CYG_ADDRESS)addr+len); /* Check to see if end_addr overflowed */ if( (end_addr < block) && (len > 0) ){ end_addr = (unsigned short *) ((CYG_ADDRESS) flash_info.end - 1); } #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("... Unlock from %p-%p: ", block, end_addr); #endif HAL_FLASH_CACHES_OFF(d_cache, i_cache); FLASH_Enable(block, end_addr); while (block < end_addr) { unsigned short *tmp_block; stat = (*_flash_unlock_block)(block, flash_info.block_size, flash_info.blocks); stat = flash_hwr_map_error(stat); if (stat) { *err_addr = (void *)block; break; } tmp_block = block + flash_info.block_size / sizeof(*block); if(tmp_block < block){ // If block address overflows, set block value to end on this loop block = end_addr; } else{ block = tmp_block; } #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("."); #endif } FLASH_Disable(block, end_addr); HAL_FLASH_CACHES_ON(d_cache, i_cache); #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("\n"); #endif return (stat); }
int flash_read(void *_addr, void *_data, int len, void **err_addr) { #ifdef CYGSEM_IO_FLASH_READ_INDIRECT int stat = 0; int size; typedef int code_fun(void *, void *, int, unsigned long, int); code_fun *_flash_read_buf; unsigned char *addr = (unsigned char *)_addr; unsigned char *data = (unsigned char *)_data; CYG_ADDRESS tmp; int d_cache, i_cache; if (!flash_info.init) { return FLASH_ERR_NOT_INIT; } _flash_read_buf = (code_fun*) __anonymizer(&flash_read_buf); #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("... Read from %p-%p at %p: ", (void*)data, (void*)(((CYG_ADDRESS)data)+len), (void*)addr); #endif HAL_FLASH_CACHES_OFF(d_cache, i_cache); FLASH_Enable((unsigned short*)addr, (unsigned short *)(addr+len)); while (len > 0) { size = len; if (size > flash_info.block_size) size = flash_info.block_size; tmp = (CYG_ADDRESS)addr & ~flash_info.block_mask; if (tmp) { tmp = flash_info.block_size - tmp; if (size>tmp) size = tmp; } stat = (*_flash_read_buf)(addr, data, size, flash_info.block_mask, flash_info.buffer_size); stat = flash_hwr_map_error(stat); #ifdef CYGSEM_IO_FLASH_VERIFY_PROGRAM_ if (0 == stat) // Claims to be OK if (memcmp(addr, data, size) != 0) { stat = 0x0BAD; #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("V"); #endif } #endif if (stat) { *err_addr = (void *)addr; break; } #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("."); #endif len -= size; addr += size/sizeof(*addr); data += size/sizeof(*data); } FLASH_Disable((unsigned short*)addr, (unsigned short *)(addr+len)); HAL_FLASH_CACHES_ON(d_cache, i_cache); #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("\n"); #endif return (stat); #else // CYGSEM_IO_FLASH_READ_INDIRECT // Direct access to FLASH memory is possible - just move the requested bytes if (!flash_info.init) { return FLASH_ERR_NOT_INIT; } memcpy(_data, _addr, len); return FLASH_ERR_OK; #endif }
int flash_program(void *_addr, void *_data, int len, void **err_addr) { int stat = 0; int size; typedef int code_fun(void *, void *, int, unsigned long, int); code_fun *_flash_program_buf; unsigned char *addr = (unsigned char *)_addr; unsigned char *data = (unsigned char *)_data; CYG_ADDRESS tmp; int d_cache, i_cache; if (!flash_info.init) { return FLASH_ERR_NOT_INIT; } #ifdef CYGSEM_IO_FLASH_SOFT_WRITE_PROTECT if (plf_flash_query_soft_wp(addr,len)) return FLASH_ERR_PROTECT; #endif _flash_program_buf = (code_fun*) __anonymizer(&flash_program_buf); #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("... Program from %p-%p at %p: ", (void*)data, (void*)(((CYG_ADDRESS)data)+len), (void*)addr); #endif HAL_FLASH_CACHES_OFF(d_cache, i_cache); FLASH_Enable((unsigned short*)addr, (unsigned short *)(addr+len)); while (len > 0) { size = len; if (size > flash_info.block_size) size = flash_info.block_size; tmp = (CYG_ADDRESS)addr & ~flash_info.block_mask; if (tmp) { tmp = flash_info.block_size - tmp; if (size>tmp) size = tmp; } stat = (*_flash_program_buf)(addr, data, size, flash_info.block_mask, flash_info.buffer_size); stat = flash_hwr_map_error(stat); #ifdef CYGSEM_IO_FLASH_VERIFY_PROGRAM if (0 == stat) // Claims to be OK if (memcmp(addr, data, size) != 0) { stat = 0x0BAD; #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("V"); #endif } #endif if (stat) { *err_addr = (void *)addr; break; } #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("."); #endif len -= size; addr += size/sizeof(*addr); data += size/sizeof(*data); } FLASH_Disable((unsigned short*)addr, (unsigned short *)(addr+len)); HAL_FLASH_CACHES_ON(d_cache, i_cache); #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("\n"); #endif return (stat); }
int flash_erase(void *addr, int len, void **err_addr) { unsigned short *block, *end_addr; int stat = 0; typedef int code_fun(unsigned short *, unsigned int); code_fun *_flash_erase_block; int d_cache, i_cache; if (!flash_info.init) { return FLASH_ERR_NOT_INIT; } #ifdef CYGSEM_IO_FLASH_SOFT_WRITE_PROTECT if (plf_flash_query_soft_wp(addr,len)) return FLASH_ERR_PROTECT; #endif _flash_erase_block = (code_fun*) __anonymizer(&flash_erase_block); block = (unsigned short *)((CYG_ADDRESS)addr & flash_info.block_mask); end_addr = (unsigned short *)((CYG_ADDRESS)addr+len); /* Check to see if end_addr overflowed */ if( (end_addr < block) && (len > 0) ){ end_addr = (unsigned short *) ((CYG_ADDRESS) flash_info.end - 1); } #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("... Erase from %p-%p: ", (void*)block, (void*)end_addr); #endif HAL_FLASH_CACHES_OFF(d_cache, i_cache); FLASH_Enable(block, end_addr); while (block < end_addr) { // Supply the blocksize for a gross check for erase success unsigned short *tmp_block; #if !defined(CYGSEM_IO_FLASH_READ_INDIRECT) int i; unsigned char *dp; bool erased = true; dp = (unsigned char *)block; for (i = 0; i < flash_info.block_size; i++) { if (*dp++ != (unsigned char)0xFF) { erased = false; break; } } #else bool erased = false; #endif if (!erased) { stat = (*_flash_erase_block)(block, flash_info.block_size); stat = flash_hwr_map_error(stat); } if (stat) { *err_addr = (void *)block; break; } // Check to see if block will overflow tmp_block = block + flash_info.block_size / sizeof(*block); if(tmp_block < block){ // If block address overflows, set block value to end on this loop block = end_addr; } else{ block = tmp_block; } #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("."); #endif } FLASH_Disable(block, end_addr); HAL_FLASH_CACHES_ON(d_cache, i_cache); #ifdef CYGSEM_IO_FLASH_CHATTER (*flash_info.pf)("\n"); #endif return (stat); }