Mercurial > flash_v2
diff packages/io/flash/current/src/flashiodev.c @ 1706:3845779eca10
* src/flash.c: Major rewrite to implement a new API
* src/legacy_api.c: Support the legacy API
* src/legacy_drv.c: Support the legacy driver API
* src/flashiodev.c: Support the new API and multiple devices
* include/flash_priv.h: Interface devices should use
* cdl/io_flash.cdl: Updates for new interface and multiple devices.
| author | asl |
|---|---|
| date | Thu, 05 Aug 2004 13:50:00 +0000 |
| parents | 5118f42e7e62 |
| children | 3bafac44ac03 |
line wrap: on
line diff
--- a/packages/io/flash/current/src/flashiodev.c +++ b/packages/io/flash/current/src/flashiodev.c @@ -9,6 +9,7 @@ // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// Copyright (C) 2004 Andrew Lunn // // eCos is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free @@ -41,7 +42,7 @@ //#####DESCRIPTIONBEGIN#### // // Author(s): jlarmour -// Contributors: woehler +// Contributors: woehler, Andrew Lunn // Date: 2002-01-16 // Purpose: // Description: @@ -62,110 +63,121 @@ #include <cyg/hal/hal_if.h> #define MIN(x,y) ((x)<(y) ? (x) : (y)) +#define MAX(x,y) ((x)>(y) ? (x) : (y)) struct flashiodev_priv_t{ - char *start; - char *end; + cyg_flashaddr_t start; + cyg_flashaddr_t end; + cyg_bool use_fis; + cyg_bool use_absolute; + cyg_bool use_offset; + char * fis_name; + cyg_uint32 block_size; }; -static struct flashiodev_priv_t flashiodev_priv[1]; - static int dummy_printf( const char *fmt, ... ) {return 0;} static bool flashiodev_init( struct cyg_devtab_entry *tab ) { - struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv; - int stat = flash_init( &dummy_printf ); - if ( stat == 0 ) { -#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_FIS_1 - CYG_ADDRESS flash_base; - unsigned long size; + struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv; + cyg_flash_info_t info; + cyg_uint32 i; + + int stat = cyg_flash_init( &dummy_printf ); + if ( stat == 0 ) { + if (dev->use_fis) { + CYG_ADDRESS flash_base; + unsigned long size; + + if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_FLASH_BASE, + dev->fis_name, + &flash_base)) + return false; + if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_SIZE, + dev->fis_name, + &size)) + return false; + + dev->start = flash_base; + dev->end = flash_base + size; + } + if (dev->use_offset) { + // dev->start the contain the offset to the beginning of the block + // dev->end is the length of the block + cyg_flashaddr_t start, end; + cyg_flash_get_limits(&start, &end); + dev->start = dev->start + start; + dev->end = dev->start + dev->end; + } + if (dev->use_absolute) { + // dev->start is the absolute address of the start + // dev->end is the length; + dev->end = dev->start + dev->end; + } - if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_FLASH_BASE, - CYGDAT_IO_FLASH_BLOCK_FIS_NAME_1, - &flash_base)) - return false; - if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_SIZE, - CYGDAT_IO_FLASH_BLOCK_FIS_NAME_1, - &size)) - return false; - - dev->start = (char *)flash_base; - dev->end = (char *)flash_base + size; -#else - dev->start = (char *)flash_info.start + CYGNUM_IO_FLASH_BLOCK_OFFSET_1; - dev->end = (char *)flash_info.start + CYGNUM_IO_FLASH_BLOCK_OFFSET_1 + - CYGNUM_IO_FLASH_BLOCK_LENGTH_1; -#endif - return true; - } else - return false; + stat = cyg_flash_get_info_addr(dev->start, &info); + if (stat != CYG_FLASH_ERR_OK) { + return false; + } + dev->block_size = 0; + for (i=0; i < info.num_block_infos; i++){ + dev->block_size = MAX(dev->block_size, info.block_info[i].block_size); + } + + return true; + } else + return false; } // flashiodev_init() -#if 0 -static Cyg_ErrNo -flashiodev_lookup( struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ -} // flashiodev_lookup() -#endif - static Cyg_ErrNo flashiodev_bread( cyg_io_handle_t handle, void *buf, cyg_uint32 *len, cyg_uint32 pos) { - struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle; - struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv; - - char *startpos = dev->start + pos; - void *erraddr; - Cyg_ErrNo err = ENOERR; - - + struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle; + struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv; + + cyg_flashaddr_t startpos = dev->start + pos; + Cyg_ErrNo err; + + #ifdef CYGPKG_INFRA_DEBUG // don't bother checking this all the time - char *endpos = startpos + *len - 1; - char *flashend = MIN( (char *)flash_info.end - 1, dev->end - 1); - if ( startpos < dev->start ) - return -EINVAL; - if ( endpos > flashend ) - return -EINVAL; + cyg_flashaddr_t endpos = startpos + *len - 1; + if ( startpos < dev->start ) + return -EINVAL; + if ( endpos > dev->end ) + return -EINVAL; #endif - - err = flash_read( startpos, - (void *)buf, *len, &erraddr ); - - if ( err ) - err = -EIO; // just something sane - return err; + + err = cyg_flash_read( startpos,(void *)buf, *len, NULL ); + + if ( err != CYG_FLASH_ERR_OK ) + err = -EIO; // just something sane + return err; } // flashiodev_bread() static Cyg_ErrNo flashiodev_bwrite( cyg_io_handle_t handle, const void *buf, cyg_uint32 *len, cyg_uint32 pos ) -{ - struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle; - struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv; - - Cyg_ErrNo err = ENOERR; - void *erraddr; - char *startpos = dev->start + pos; - +{ + struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle; + struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv; + + Cyg_ErrNo err; + cyg_flashaddr_t startpos = dev->start + pos; + #ifdef CYGPKG_INFRA_DEBUG // don't bother checking this all the time - char *endpos = startpos + *len - 1; - char *flashend = MIN( (char *)flash_info.end - 1, dev->end - 1); - if ( startpos < dev->start ) - return -EINVAL; - if ( endpos > flashend ) - return -EINVAL; + cyg_flashaddr_t endpos = startpos + *len - 1; + if ( startpos < dev->start ) + return -EINVAL; + if ( endpos > dev->end ) + return -EINVAL; #endif - err = flash_program( startpos, - (void *)buf, *len, &erraddr ); - - if ( err ) - err = -EIO; // just something sane - return err; + err = cyg_flash_program( startpos, (void *)buf, *len, NULL ); + + if ( err ) + err = -EIO; // just something sane + return err; } // flashiodev_bwrite() static Cyg_ErrNo @@ -174,68 +186,65 @@ flashiodev_get_config( cyg_io_handle_t h void* buf, cyg_uint32* len) { - struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle; - struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv; - - switch (key) { - case CYG_IO_GET_CONFIG_FLASH_ERASE: + struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle; + struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv; + + switch (key) { + case CYG_IO_GET_CONFIG_FLASH_ERASE: { - if ( *len != sizeof( cyg_io_flash_getconfig_erase_t ) ) - return -EINVAL; - { - cyg_io_flash_getconfig_erase_t *e = (cyg_io_flash_getconfig_erase_t *)buf; - char *startpos = dev->start + e->offset; - + if ( *len != sizeof( cyg_io_flash_getconfig_erase_t ) ) + return -EINVAL; + { + cyg_io_flash_getconfig_erase_t *e = (cyg_io_flash_getconfig_erase_t *)buf; + cyg_flashaddr_t startpos = dev->start + e->offset; + #ifdef CYGPKG_INFRA_DEBUG // don't bother checking this all the time - char *endpos = startpos + e->len - 1; - char *flashend = MIN( (char *)flash_info.end - 1, dev->end - 1); - if ( startpos < dev->start ) - return -EINVAL; - if ( endpos > flashend ) - return -EINVAL; + cyg_flashaddr_t endpos = startpos + e->len - 1; + if ( startpos < dev->start ) + return -EINVAL; + if ( endpos > dev->end ) + return -EINVAL; #endif - e->flasherr = flash_erase( startpos, e->len, e->err_address ); - } - return ENOERR; + e->flasherr = cyg_flash_erase( startpos, e->len, e->err_address ); + } + return ENOERR; } - case CYG_IO_GET_CONFIG_FLASH_DEVSIZE: + case CYG_IO_GET_CONFIG_FLASH_DEVSIZE: { - if ( *len != sizeof( cyg_io_flash_getconfig_devsize_t ) ) - return -EINVAL; - { - cyg_io_flash_getconfig_devsize_t *d = - (cyg_io_flash_getconfig_devsize_t *)buf; - - //d->dev_size = flash_info.blocks * flash_info.block_size; - d->dev_size = dev->end - dev->start; - } - return ENOERR; + if ( *len != sizeof( cyg_io_flash_getconfig_devsize_t ) ) + return -EINVAL; + { + cyg_io_flash_getconfig_devsize_t *d = + (cyg_io_flash_getconfig_devsize_t *)buf; + + d->dev_size = dev->end - dev->start; + } + return ENOERR; } - - case CYG_IO_GET_CONFIG_FLASH_BLOCKSIZE: + + case CYG_IO_GET_CONFIG_FLASH_BLOCKSIZE: { - cyg_io_flash_getconfig_blocksize_t *b = - (cyg_io_flash_getconfig_blocksize_t *)buf; + cyg_io_flash_getconfig_blocksize_t *b = + (cyg_io_flash_getconfig_blocksize_t *)buf; #ifdef CYGPKG_INFRA_DEBUG // don't bother checking this all the time - char *startpos = dev->start + b->offset; - char *flashend = MIN( (char *)flash_info.end - 1, dev->end - 1); - - if ( startpos < dev->start ) - return -EINVAL; - if ( startpos > flashend ) - return -EINVAL; + cyg_flashaddr_t startpos = dev->start + b->offset; + + if ( startpos < dev->start ) + return -EINVAL; + if ( startpos > dev->end ) + return -EINVAL; #endif - if ( *len != sizeof( cyg_io_flash_getconfig_blocksize_t ) ) - return -EINVAL; - - // offset unused for now - b->block_size = flash_info.block_size; - return ENOERR; + if ( *len != sizeof( cyg_io_flash_getconfig_blocksize_t ) ) + return -EINVAL; + + // offset unused for now + b->block_size = dev->block_size; + return ENOERR; } - - default: - return -EINVAL; - } + + default: + return -EINVAL; + } } // flashiodev_get_config() static Cyg_ErrNo @@ -244,46 +253,88 @@ flashiodev_set_config( cyg_io_handle_t h const void* buf, cyg_uint32* len) { -#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_FIS_1 - struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle; - struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv; -#endif - - switch (key) { -#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_FIS_1 - case CYG_IO_SET_CONFIG_FLASH_FIS_NAME: + struct cyg_devtab_entry *tab = (struct cyg_devtab_entry *)handle; + struct flashiodev_priv_t *dev = (struct flashiodev_priv_t *)tab->priv; + + switch (key) { + case CYG_IO_SET_CONFIG_FLASH_FIS_NAME: { - CYG_ADDRESS flash_base; - unsigned long size; + cyg_flashaddr_t flash_base; + unsigned long size; + cyg_flash_info_t info; + cyg_uint32 i; + int stat; + + if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_FLASH_BASE, + (char *)buf, &flash_base)) + return -ENOENT; + if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_SIZE, + (char *)buf, &size)) + return -ENOENT; + + dev->start = flash_base; + dev->end = flash_base + size; - if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_FLASH_BASE, - (char *)buf, &flash_base)) - return -ENOENT; - if(!CYGACC_CALL_IF_FLASH_FIS_OP(CYGNUM_CALL_IF_FLASH_FIS_GET_SIZE, - (char *)buf, &size)) - return -ENOENT; - - dev->start = (char *)flash_base; - dev->end = (char *)flash_base + size; - return ENOERR; + stat = cyg_flash_get_info_addr(dev->start, &info); + if (stat != CYG_FLASH_ERR_OK) { + return -ENOENT; + } + dev->block_size = 0; + for (i=0; i < info.num_block_infos; i++){ + dev->block_size = MAX(dev->block_size, info.block_info[i].block_size); + } + return ENOERR; } -#endif - default: - return -EINVAL; - } + default: + return -EINVAL; + } } // flashiodev_set_config() // get_config/set_config should be added later to provide the other flash // operations possible, like erase etc. +#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_FIS_1 +static struct flashiodev_priv_t priv1 = { + 0, // start + 0, // end + 1, // use_fis + 0, // use_static + 0. // use_offset + CYGDAT_IO_FLASH_BLOCK_FIS_NAME_1, + 0 // blocksize +}; + +#endif +#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_STATIC_ABSOLUTE_1 +static struct flashiodev_priv_t priv1 = { + CYGNUM_IO_FLASH_BLOCK_ABSOLUTE_START_1, // start + CYGNUM_IO_FLASH_BLOCK_ABSOLUTE_START_1 + CYGNUM_IO_FLASH_BLOCK_ABSOLUTE_LENGTH_1, + 0, // use_fis + 1, // use_static + 0, // use_offset + "", // fis_name + 0 // blocksize +}; +#else +static struct flashiodev_priv_t priv1 = { + CYGNUM_IO_FLASH_BLOCK_OFFSET_1, // start + CYGNUM_IO_FLASH_BLOCK_LENGTH_1, // end + 0, // use_fis + 0, // use_static + 1, // use_offset + "", // fis_name + 0 // blocksize +}; +#endif + BLOCK_DEVIO_TABLE( cyg_io_flashdev1_ops, &flashiodev_bwrite, &flashiodev_bread, 0, // no select &flashiodev_get_config, &flashiodev_set_config - ); - + ); + BLOCK_DEVTAB_ENTRY( cyg_io_flashdev1, CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, @@ -291,6 +342,51 @@ BLOCK_DEVTAB_ENTRY( cyg_io_flashdev1, &cyg_io_flashdev1_ops, &flashiodev_init, 0, // No lookup required - &flashiodev_priv[0] ); + &priv1 ); + + +#ifdef CYGSEM_IO_FLASH_BLOCK_DEVICE_2 +#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_FIS_2 +static struct flashiodev_priv_t priv2 = { + 0, // start + 0, // end + 1, // use_fis + 0, // use_static + 0. // use_offset + CYGDAT_IO_FLASH_BLOCK_FIS_NAME_2, + 0 // blocksize +}; + +#endif +#ifdef CYGNUM_IO_FLASH_BLOCK_CFG_STATIC_ABSOLUTE_2 +static struct flashiodev_priv_t priv2 = { + CYGNUM_IO_FLASH_BLOCK_ABSOLUTE_START_2, // start + CYGNUM_IO_FLASH_BLOCK_ABSOLUTE_START_2 + CYGNUM_IO_FLASH_BLOCK_ABSOLUTE_LENGTH_2, + 0, // use_fis + 1, // use_static + 0, // use_offset + "", // fis_name + 0 // blocksize +}; +#else +static struct flashiodev_priv_t priv2 = { + CYGNUM_IO_FLASH_BLOCK_OFFSET_2, // start + CYGNUM_IO_FLASH_BLOCK_LENGTH_2, // end + 0, // use_fis + 0, // use_static + 1, // use_offset + "", // fis_name + 0 // blocksize +}; +#endif + +BLOCK_DEVTAB_ENTRY( cyg_io_flashdev2, + CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_2, + 0, + &cyg_io_flashdev1_ops, + &flashiodev_init, + 0, // No lookup required + &priv2 ); +#endif // EOF flashiodev.c
