Sorry, somehow messed up the patch :) Here we go ...
diff -r 2edda4c0b910 packages/devs/flash/synth/current/ChangeLog --- a/packages/devs/flash/synth/current/ChangeLog Fri Dec 19 17:33:12 2008 +0100 +++ b/packages/devs/flash/synth/current/ChangeLog Tue Dec 23 09:30:41 2008 +0100 @@ -1,3 +1,9 @@ +2008-12-23 Simon Kallweit <[email protected]> + + * src/flash_erase_block.c: + * src/flash_program_buf.c: + Implemented simulation of proper NOR flash writes. General cleanup. + 2008-12-18 Simon Kallweit <[email protected]> * src/synth.c: Fixed error check of mmap call. diff -r 2edda4c0b910 packages/devs/flash/synth/current/src/flash_erase_block.c --- a/packages/devs/flash/synth/current/src/flash_erase_block.c Fri Dec 19 17:33:12 2008 +0100 +++ b/packages/devs/flash/synth/current/src/flash_erase_block.c Tue Dec 23 09:30:41 2008 +0100 @@ -56,17 +56,24 @@ #include <pkgconf/devs_flash_synth.h> #include <cyg/infra/cyg_ass.h> #include <cyg/io/flash.h> +#include <cyg/io/flash_dev.h> #include <string.h> // memset -/* This helps speed up the erase. */ -static char empty[4096]; -static cyg_bool empty_inited = false; +#ifndef MIN +#define MIN(x,y) ((x)<(y) ? (x) : (y)) +#endif int flash_erase_block(volatile flash_t *block, unsigned int block_size) { - int i; - int offset = (int)block; - offset -= (int)cyg_dev_flash_synth_base; + unsigned int offset = (unsigned int) block; + size_t remaining; + int write_size; + + // This helps speed up the erasing + static cyg_uint8 empty[4096]; + static cyg_bool empty_inited; + + offset -= (unsigned int) cyg_dev_flash_synth_base; cyg_hal_sys_lseek(cyg_dev_flash_synth_flashfd, offset, CYG_HAL_SYS_SEEK_SET); @@ -75,16 +82,14 @@ memset(empty, 0xff, sizeof(empty)); empty_inited = true; } + + remaining = flash_info.block_size; - CYG_ASSERT(sizeof(empty) < block_size, - "Eckk! Can't work with such small blocks"); - CYG_ASSERT((block_size % sizeof(empty)) == 0, - "Eckk! Can't work with that odd size block"); + while (remaining) { + write_size = MIN(remaining, sizeof(empty)); + cyg_hal_sys_write(cyg_dev_flash_synth_flashfd, empty, write_size); + remaining -= write_size; + } - for (i=0; (i * sizeof(empty)) < block_size; i++) { - cyg_hal_sys_write(cyg_dev_flash_synth_flashfd, empty, sizeof(empty)); - } return FLASH_ERR_OK; } - - diff -r 2edda4c0b910 packages/devs/flash/synth/current/src/flash_program_buf.c --- a/packages/devs/flash/synth/current/src/flash_program_buf.c Fri Dec 19 17:33:12 2008 +0100 +++ b/packages/devs/flash/synth/current/src/flash_program_buf.c Tue Dec 23 09:30:41 2008 +0100 @@ -56,16 +56,39 @@ #include <cyg/hal/hal_io.h> #include <cyg/io/flash.h> +#ifndef MIN +#define MIN(x,y) ((x)<(y) ? (x) : (y)) +#endif + int flash_program_buf(volatile flash_t *addr, flash_t *data, int len, unsigned long block_mask, int buffer_size) { - - int offset = (int)addr; - offset -= (int)cyg_dev_flash_synth_base; + unsigned int offset = (unsigned int) addr; + cyg_uint8 *buf = (cyg_uint8 *) data; - cyg_hal_sys_lseek(cyg_dev_flash_synth_flashfd, offset, CYG_HAL_SYS_SEEK_SET); - cyg_hal_sys_write(cyg_dev_flash_synth_flashfd, data, len); - + // This helps speed up the programming + static cyg_uint8 tmp[4096]; + + offset -= (unsigned int) cyg_dev_flash_synth_base; + + while (len > 0) { + int i; + int write_size = MIN(len, sizeof(tmp)); + // Writing to NOR flash only sets bits from 1 to 0, not vice-versa + cyg_hal_sys_lseek(cyg_dev_flash_synth_flashfd, offset, + CYG_HAL_SYS_SEEK_SET); + cyg_hal_sys_read(cyg_dev_flash_synth_flashfd, tmp, write_size); + for (i = 0; i < write_size; i++) + tmp[i] = tmp[i] & buf[i]; + cyg_hal_sys_lseek(cyg_dev_flash_synth_flashfd, offset, + CYG_HAL_SYS_SEEK_SET); + cyg_hal_sys_write(cyg_dev_flash_synth_flashfd, tmp, write_size); + // Process next chunk + buf += write_size; + offset += write_size; + len -= write_size; + } + return FLASH_ERR_OK; } diff -r 2edda4c0b910 packages/devs/flash/synthv2/current/ChangeLog --- a/packages/devs/flash/synthv2/current/ChangeLog Fri Dec 19 17:33:12 2008 +0100 +++ b/packages/devs/flash/synthv2/current/ChangeLog Tue Dec 23 09:30:41 2008 +0100 @@ -1,3 +1,8 @@ +2008-12-23 Simon Kallweit <[email protected]> + + * src/synth.c: Implemented simulation of proper NOR flash writes. + General cleanup. + 2008-12-18 Simon Kallweit <[email protected]> * src/synth.c: Fixed error check of mmap call. diff -r 2edda4c0b910 packages/devs/flash/synthv2/current/src/synth.c --- a/packages/devs/flash/synthv2/current/src/synth.c Fri Dec 19 17:33:12 2008 +0100 +++ b/packages/devs/flash/synthv2/current/src/synth.c Tue Dec 23 09:30:41 2008 +0100 @@ -67,15 +67,16 @@ static int synth_flash_init(struct cyg_flash_dev *dev) { - struct cyg_flash_synth_priv *priv = (struct cyg_flash_synth_priv*)dev->priv; + struct cyg_flash_synth_priv *priv = + (struct cyg_flash_synth_priv *) dev->priv; cyg_flashaddr_t base; - int flags=CYG_HAL_SYS_MAP_SHARED; + int flags = CYG_HAL_SYS_MAP_SHARED; - priv->flashfd = - cyg_hal_sys_open(priv->filename, - CYG_HAL_SYS_O_RDWR, - CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG| - CYG_HAL_SYS_S_IRWXO); + priv->flashfd = cyg_hal_sys_open( + priv->filename, + CYG_HAL_SYS_O_RDWR, + CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO); + if (priv->flashfd == -ENOENT) { long w, bytesleft; char buf[128]; @@ -84,46 +85,43 @@ priv->filename, CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT, CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO); - CYG_ASSERT( priv->flashfd >= 0, - "Opening of the file for the synth flash failed!"); - // fill with 0xff - memset( buf, 0xff, sizeof(buf) ); + CYG_ASSERT(priv->flashfd >= 0, + "Opening of the file for the synth flash failed!"); + + // Fill with 0xff + memset(buf, 0xff, sizeof(buf)); bytesleft = priv->block_size * priv->blocks + priv->boot_block_size * priv->boot_blocks; - while (bytesleft > 0) { int bytesneeded; - bytesneeded = bytesleft < sizeof(buf) ? - bytesleft : sizeof(buf); - - w = cyg_hal_sys_write( priv->flashfd, buf, - bytesneeded ); - CYG_ASSERT(w == bytesneeded, - "initialization of flash file failed"); + bytesneeded = bytesleft < sizeof(buf) ? bytesleft : sizeof(buf); + w = cyg_hal_sys_write(priv->flashfd, buf, bytesneeded); + CYG_ASSERT(w == bytesneeded, "initialization of flash file failed"); bytesleft -= bytesneeded; - } // while + } } - CYG_ASSERT( priv->flashfd >= 0, - "Opening of the file for the synth flash failed!"); - if ( priv->flashfd <= 0 ) { + + CYG_ASSERT(priv->flashfd >= 0, + "Opening of the file for the synth flash failed!"); + + if (priv->flashfd <= 0) return CYG_FLASH_ERR_HWR; - } - if (dev->start != 0) { + if (dev->start != 0) flags |= CYG_HAL_SYS_MAP_FIXED; - } - base = (cyg_flashaddr_t)cyg_hal_sys_mmap( - (void *)dev->start, + + base = (cyg_flashaddr_t) cyg_hal_sys_mmap( + (void *) dev->start, priv->blocks * priv->block_size + priv->boot_block_size * priv->boot_blocks, CYG_HAL_SYS_PROT_READ, flags, priv->flashfd, 0l); - CYG_ASSERT( base != -1, "mmap of flash file failed!" ); - if (base == -1) { + CYG_ASSERT(base != -1, "mmap of flash file failed!"); + if (base == -1) return CYG_FLASH_ERR_HWR; - } + dev->start = base; dev->end = base + (priv->blocks * priv->block_size) + (priv->boot_blocks * priv->boot_block_size) - 1; @@ -150,30 +148,26 @@ return CYG_FLASH_ERR_OK; } -/* This helps speed up the erase. */ -static char empty[4096]; -static cyg_bool empty_inited = false; - // Return the size of the block which is at the given address. // __inline__ so that we know it will be in RAM, not ROM. static __inline__ size_t flash_block_size(struct cyg_flash_dev *dev, const cyg_flashaddr_t addr) { - int i; - size_t offset; + int i; + cyg_flashaddr_t offset; + CYG_ASSERT((addr >= dev->start) && (addr <= dev->end), "Not inside device"); - CYG_ASSERT((addr >= dev->start) && (addr <= dev->end), "Not inside device"); - - offset = addr - dev->start; - for (i=0; i < dev->num_block_infos; i++) { - if (offset < (dev->block_info[i].blocks * dev->block_info[i].block_size)) - return dev->block_info[i].block_size; - offset = offset - - (dev->block_info[i].blocks * dev->block_info[i].block_size); - } - CYG_FAIL("Programming error"); - return 0; + offset = addr - dev->start; + for (i=0; i < dev->num_block_infos; i++) { + if (offset < (dev->block_info[i].blocks * + dev->block_info[i].block_size)) + return dev->block_info[i].block_size; + offset = offset - + (dev->block_info[i].blocks * dev->block_info[i].block_size); + } + CYG_FAIL("Programming error"); + return 0; } static int @@ -181,14 +175,17 @@ cyg_flashaddr_t block_base) { const struct cyg_flash_synth_priv *priv = dev->priv; - int offset = (int)block_base; + cyg_flashaddr_t offset = block_base; size_t remaining; int write_size; + + // This helps speed up the erasing + static cyg_uint8 empty[4096]; + static cyg_bool empty_inited; offset -= dev->start; - cyg_hal_sys_lseek(priv->flashfd, offset, - CYG_HAL_SYS_SEEK_SET); + cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET); if (!empty_inited) { memset(empty, 0xff, sizeof(empty)); @@ -202,6 +199,7 @@ cyg_hal_sys_write(priv->flashfd, empty, write_size); remaining -= write_size; } + return CYG_FLASH_ERR_OK; } @@ -211,22 +209,39 @@ const void* data, size_t len) { const struct cyg_flash_synth_priv *priv = dev->priv; - int offset = base; + cyg_flashaddr_t offset = base; + cyg_uint8 *buf = (cyg_uint8 *) data; + + // This helps speed up the programming + static cyg_uint8 tmp[4096]; + offset -= dev->start; - cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET); - cyg_hal_sys_write(priv->flashfd, data, len); - + while (len > 0) { + int i; + int write_size = MIN(len, sizeof(tmp)); + // Writing to NOR flash only sets bits from 1 to 0, not vice-versa + cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET); + cyg_hal_sys_read(priv->flashfd, tmp, write_size); + for (i = 0; i < write_size; i++) + tmp[i] = tmp[i] & buf[i]; + cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET); + cyg_hal_sys_write(priv->flashfd, tmp, write_size); + // Process next chunk + buf += write_size; + offset += write_size; + len -= write_size; + } + return CYG_FLASH_ERR_OK; } #define QUERY "Linux Synthetic Flash" static size_t -synth_flash_query(struct cyg_flash_dev *dev, void * data, - size_t len) +synth_flash_query(struct cyg_flash_dev *dev, void * data, size_t len) { - memcpy(data,QUERY,sizeof(QUERY)); + memcpy(data, QUERY, sizeof(QUERY)); return sizeof(QUERY); }
