? devs/flash/synth/current/tests/flash2.c Index: devs/flash/synth/current/cdl/flash_synth.cdl =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/synth/current/cdl/flash_synth.cdl,v retrieving revision 1.3 diff -u -r1.3 flash_synth.cdl --- devs/flash/synth/current/cdl/flash_synth.cdl 23 May 2002 23:01:05 -0000 1.3 +++ devs/flash/synth/current/cdl/flash_synth.cdl 16 Jul 2004 11:21:02 -0000 @@ -56,7 +56,7 @@ requires CYGINT_ISO_ERRNO_CODES implements CYGHWR_IO_FLASH_DEVICE - + include_dir . include_files ; # none _exported_ whatsoever description "FLASH memory device support for Synthetic target" @@ -121,7 +121,7 @@ display "Synth flash tests" flavor data no_define - calculated { "tests/flash1.c"} + calculated { "tests/flash1.c tests/flash2.c"} description " This option specifies the set of tests for the synth flash package." } Index: devs/flash/synth/current/src/synth.c =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/synth/current/src/synth.c,v retrieving revision 1.3 diff -u -r1.3 synth.c --- devs/flash/synth/current/src/synth.c 23 May 2002 23:01:06 -0000 1.3 +++ devs/flash/synth/current/src/synth.c 16 Jul 2004 11:21:02 -0000 @@ -149,7 +149,7 @@ return FLASH_ERR_HWR; } flash_info.start = cyg_dev_flash_synth_base; - flash_info.end = (void *)(((char *)cyg_dev_flash_synth_base) + + flash_info.end = (void *)(((char *)cyg_dev_flash_synth_base) -1 + (CYGNUM_FLASH_SYNTH_BLOCKSIZE * CYGNUM_FLASH_SYNTH_NUMBLOCKS)); return FLASH_ERR_OK; Index: devs/flash/synth/current/tests/flash1.c =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/synth/current/tests/flash1.c,v retrieving revision 1.4 diff -u -r1.4 flash1.c --- devs/flash/synth/current/tests/flash1.c 24 Nov 2003 11:21:28 -0000 1.4 +++ devs/flash/synth/current/tests/flash1.c 16 Jul 2004 11:21:03 -0000 @@ -1,59 +1,59 @@ -/* Hay, the copyright is usefull for something! */ +/* Hey, the copyright is usefull for something! */ -static char copyright[] = " -//========================================================================== -// -// flash1.c -// -// Test flash operations for the synth target synth flash driver -// -//========================================================================== -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// -// 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 -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): andrew.lunn@ascom.ch -// Contributors: andrew.lunn -// Date: 2000-10-31 -// Purpose: Test a flash driver -// Description: Try out a number of flash operations and make sure -// what is in the flash is what we expeect. -// -//####DESCRIPTIONEND#### -// -//========================================================================== -"; +static char copyright[] = +"//==========================================================================" +"//" +"// flash1.c" +"//" +"// Test flash operations for the synth target synth flash driver" +"//" +"//==========================================================================" +"//####ECOSGPLCOPYRIGHTBEGIN####" +"// -------------------------------------------" +"// This file is part of eCos, the Embedded Configurable Operating System." +"// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc." +"//" +"// 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" +"// Software Foundation; either version 2 or (at your option) any later version." +"//" +"// eCos is distributed in the hope that it will be useful, but WITHOUT ANY" +"// WARRANTY; without even the implied warranty of MERCHANTABILITY or" +"// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License" +"// for more details." +"//" +"// You should have received a copy of the GNU General Public License along" +"// with eCos; if not, write to the Free Software Foundation, Inc.," +"// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA." +"//" +"// As a special exception, if other files instantiate templates or use macros" +"// or inline functions from this file, or you compile this file and link it" +"// with other works to produce a work based on this file, this file does not" +"// by itself cause the resulting work to be covered by the GNU General Public" +"// License. However the source code for this file must still be made available" +"// in accordance with section (3) of the GNU General Public License." +"//" +"// This exception does not invalidate any other reasons why a work based on" +"// this file might be covered by the GNU General Public License." +"//" +"// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc." +"// at http://sources.redhat.com/ecos/ecos-license/" +"// -------------------------------------------" +"//####ECOSGPLCOPYRIGHTEND####" +"//==========================================================================" +"//#####DESCRIPTIONBEGIN####" +"//" +"// Author(s): andrew.lunn@ascom.ch" +"// Contributors: andrew.lunn" +"// Date: 2000-10-31" +"// Purpose: Test a flash driver" +"// Description: Try out a number of flash operations and make sure" +"// what is in the flash is what we expeect." +"// " +"//####DESCRIPTIONEND####" +"//" +"//==========================================================================" +; #include #include @@ -64,6 +64,9 @@ #ifndef CYGINT_ISO_STRING_STRFUNCS # define NA_MSG "Need string functions for test" #endif +#ifndef CYGSEM_IO_FLASH_LEGACY_API +# define NA_MSG "Need legacy IO FLASH API for test" +#endif #ifdef NA_MSG void cyg_user_start(void) Index: redboot/current/src/flash.c =================================================================== RCS file: /cvs/ecos/ecos/packages/redboot/current/src/flash.c,v retrieving revision 1.67 diff -u -r1.67 flash.c --- redboot/current/src/flash.c 25 Jun 2004 15:49:43 -0000 1.67 +++ redboot/current/src/flash.c 16 Jul 2004 11:21:05 -0000 @@ -163,11 +163,12 @@ ); // Local data used by these routines -void *flash_start, *flash_end; -int flash_block_size, flash_num_blocks; +cyg_flashaddr_t flash_start, flash_end; +size_t flash_block_size; +cyg_uint32 flash_num_blocks; #ifdef CYGOPT_REDBOOT_FIS void *fis_work_block; -void *fis_addr; +cyg_flashaddr_t fis_addr; int fisdir_size; // Size of FIS directory. #endif #ifdef CYGSEM_REDBOOT_FLASH_CONFIG @@ -186,8 +187,19 @@ static void _show_invalid_flash_address(CYG_ADDRESS flash_addr, int stat) { - diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); - diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); + cyg_uint32 i=0; + cyg_flash_info_t info; + int ret; + + diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, + cyg_flash_errmsg(stat)); + do { + ret = cyg_flash_get_info(i, &info); + if (ret == CYG_FLASH_ERR_OK) { + diag_printf(" valid range is %p - %p\n", info.start, info.end); + } + i++; + } while (ret != CYG_FLASH_ERR_INVALID); } #ifdef CYGOPT_REDBOOT_FIS @@ -196,9 +208,9 @@ { int i; struct fis_image_desc *img; - void *err_addr; + cyg_flashaddr_t err_addr; - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && @@ -214,27 +226,27 @@ fis_update_directory(void) { int stat; - void *err_addr; + cyg_flashaddr_t err_addr; #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG memcpy((char *)fis_work_block+fisdir_size, config, cfg_size); #endif #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Ensure [quietly] that the directory is unlocked before trying to update - flash_unlock((void *)fis_addr, flash_block_size, (void **)&err_addr); + cyg_flash_unlock((void *)fis_addr, flash_block_size, &err_addr); #endif - if ((stat = flash_erase(fis_addr, flash_block_size, (void **)&err_addr)) != 0) { - diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat)); + if ((stat = cyg_flash_erase(fis_addr, flash_block_size, &err_addr)) != 0) { + diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); } else { - if ((stat = flash_program(fis_addr, fis_work_block, flash_block_size, - (void **)&err_addr)) != 0) { + if ((stat = cyg_flash_program(fis_addr, fis_work_block, flash_block_size, + &err_addr)) != 0) { diag_printf("Error writing FIS directory at %p: %s\n", - err_addr, flash_errmsg(stat)); + err_addr, cyg_flash_errmsg(stat)); } } #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Ensure [quietly] that the directory is locked after the update - flash_lock((void *)fis_addr, flash_block_size, (void **)&err_addr); + cyg_flash_lock((void *)fis_addr, flash_block_size, &err_addr); #endif } @@ -243,7 +255,7 @@ { int stat; struct fis_image_desc *img; - void *err_addr; + cyg_flashaddr_t err_addr; bool full_init = false; struct option_info opts[1]; CYG_ADDRESS redboot_flash_start; @@ -377,10 +389,10 @@ erase_size = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; if ( erase_size > erase_start ) { erase_size -= erase_start; - if ((stat = flash_erase((void *)erase_start, erase_size, - (void **)&err_addr)) != 0) { + if ((stat = cyg_flash_erase((void *)erase_start, erase_size, + &err_addr)) != 0) { diag_printf(" initialization failed at %p: %s\n", - err_addr, flash_errmsg(stat)); + err_addr, cyg_flash_errmsg(stat)); } } #endif @@ -396,10 +408,10 @@ } else { erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data } - if ((stat = flash_erase((void *)erase_start, erase_size, - (void **)&err_addr)) != 0) { + if ((stat = cyg_flash_erase((void *)erase_start, erase_size, + &err_addr)) != 0) { diag_printf(" initialization failed %p: %s\n", - err_addr, flash_errmsg(stat)); + err_addr, cyg_flash_errmsg(stat)); } erase_start += (erase_size + flash_block_size); if (fis_addr > cfg_base) { @@ -407,27 +419,26 @@ } else { erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between fis and config data } - if ((stat = flash_erase((void *)erase_start, erase_size, - (void **)&err_addr)) != 0) { + if ((stat = cyg_flash_erase((void *)erase_start, erase_size, + &err_addr)) != 0) { diag_printf(" initialization failed %p: %s\n", - err_addr, flash_errmsg(stat)); + err_addr, cyg_flash_errmsg(stat)); } erase_start += (erase_size + flash_block_size); #else // !CYGSEM_REDBOOT_FLASH_CONFIG erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data - if ((stat = flash_erase((void *)erase_start, erase_size, - (void **)&err_addr)) != 0) { + if ((stat = cyg_flash_erase(erase_start, erase_size,&err_addr)) != 0) { diag_printf(" initialization failed %p: %s\n", - err_addr, flash_errmsg(stat)); + err_addr, cyg_flash_errmsg(stat)); } erase_start += (erase_size + flash_block_size); #endif // Lastly, anything at the end erase_size = ((CYG_ADDRESS)flash_end - erase_start) + 1; - if ((stat = flash_erase((void *)erase_start, erase_size, - (void **)&err_addr)) != 0) { + if ((stat = cyg_flash_erase(erase_start, erase_size, + &err_addr)) != 0) { diag_printf(" initialization failed at %p: %s\n", - err_addr, flash_errmsg(stat)); + err_addr, cyg_flash_errmsg(stat)); } #ifndef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS // In this case, 'fis free' works by scanning for erased blocks. Since the @@ -448,7 +459,7 @@ bool show_cksums = false; bool show_datalen = false; struct option_info opts[2]; - void *err_addr; + cyg_flashaddr_t err_addr; unsigned long last_addr, lowest_addr; bool image_found; @@ -471,7 +482,7 @@ if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) { return; } - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); // Let diag_printf do the formatting in both cases, rather than counting // cols by hand.... diag_printf("%-16s %-10s %-10s %-10s %-s\n", @@ -520,20 +531,37 @@ static int find_free(struct free_chunk *chunks) { - CYG_ADDRESS *fis_ptr, *fis_end; - void *err_addr; + cyg_flashaddr_t err_addr; + cyg_flash_info_t info; struct fis_image_desc *img; - int i, idx; - int num_chunks = 1; - - // Do not search the area reserved for pre-RedBoot systems: - fis_ptr = (CYG_ADDRESS *)((CYG_ADDRESS)flash_start + - CYGNUM_REDBOOT_FLASH_RESERVED_BASE + - CYGBLD_REDBOOT_MIN_IMAGE_SIZE); - fis_end = (CYG_ADDRESS *)flash_end; - chunks[num_chunks-1].start = (CYG_ADDRESS)fis_ptr; - chunks[num_chunks-1].end = (CYG_ADDRESS)fis_end; - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + int i=0, idx; + int num_chunks = 0; + int ret; + + do { + ret = cyg_flash_get_info(i, &info); + if (ret == CYG_FLASH_ERR_OK) { + if (i == 0 ) { + // Do not search the area reserved for pre-RedBoot systems: + chunks[num_chunks].start = (info.start + + CYGNUM_REDBOOT_FLASH_RESERVED_BASE + + CYGBLD_REDBOOT_MIN_IMAGE_SIZE); + chunks[num_chunks].end = info.end; + num_chunks++; + } else { // Contiguous flash? If so collapse the chunks together. + if (chunks[num_chunks-1].end == (info.start -1)) { + chunks[num_chunks-1].end = info.end; + } else { + chunks[num_chunks].start = info.start; + chunks[num_chunks].end = info.end; + num_chunks++; + } + } + } + i++; + } while (ret != CYG_FLASH_ERR_INVALID); + + cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); img = (struct fis_image_desc *) fis_work_block; for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { if (img->name[0] != (unsigned char)0xFF) { @@ -555,13 +583,11 @@ chunks[idx].end = img->flash_base; } else { // Split chunk into two parts - if ((img->flash_base+img->size) < (CYG_ADDRESS)fis_end) { - chunks[idx+1].start = img->flash_base + img->size; - chunks[idx+1].end = chunks[idx].end; - if (++num_chunks == CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS) { - diag_printf("Warning: too many free chunks\n"); - return num_chunks; - } + chunks[idx+1].start = img->flash_base + img->size; + chunks[idx+1].end = chunks[idx].end; + if (++num_chunks == CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS) { + diag_printf("Warning: too many free chunks\n"); + return num_chunks; } chunks[idx].end = img->flash_base; } @@ -700,12 +726,13 @@ bool length_set = false; bool img_size_set = false; bool no_copy = false; - void *err_addr; + cyg_flashaddr_t err_addr; struct fis_image_desc *img = NULL; bool defaults_assumed; struct option_info opts[7]; bool prog_ok = true; - + size_t block_size; + init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address"); init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, @@ -726,7 +753,7 @@ return; } - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); defaults_assumed = false; if (name) { // Search existing files to acquire defaults for params not specified: @@ -782,24 +809,6 @@ } // 'length' is size of FLASH image, 'img_size' is actual data size // Round up length to FLASH block size -#ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken - length = ((length + flash_block_size - 1) / flash_block_size) * flash_block_size; - if (length < img_size) { - diag_printf("Invalid FLASH image size/length combination\n"); - return; - } -#endif - if (flash_addr_set && - ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { - _show_invalid_flash_address(flash_addr, stat); - return; - } - if (flash_addr_set && ((flash_addr & (flash_block_size-1)) != 0)) { - diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); - diag_printf(" must be 0x%x aligned\n", flash_block_size); - return; - } if (strlen(name) >= sizeof(img->name)) { diag_printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name)); return; @@ -814,7 +823,30 @@ diag_printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length); return; } + flash_addr_set = true; } + if (flash_addr_set) { + block_size = cyg_flash_block_size(flash_addr + length); +#ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken + length = ((length + block_size - 1) / block_size) * block_size; + if (length < img_size) { + diag_printf("Invalid FLASH image size/length combination\n"); + return; + } +#endif + if ((stat = cyg_flash_verify_addr(flash_addr)) || + (stat = cyg_flash_verify_addr((flash_addr+length-1)))) { + _show_invalid_flash_address(flash_addr, stat); + return; + } + block_size = cyg_flash_block_size(flash_addr); + if ((flash_addr & (flash_block_size-1)) != 0) { + diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); + diag_printf(" must be 0x%x aligned\n", flash_block_size); + return; + } + } + // First, see if the image by this name has agreable properties if (img) { if (flash_addr_set && (img->flash_base != flash_addr)) { @@ -863,7 +895,7 @@ } } #endif - // If not image by that name, try and find an empty slot + // If no image by that name, try and find an empty slot img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { if (img->name[0] == (unsigned char)0xFF) { @@ -873,21 +905,23 @@ } if (!no_copy) { // Safety check - make sure the address range is not within the code we're running - if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) { + if (cyg_flash_code_overlaps(flash_addr, (flash_addr+img_size-1))) { diag_printf("Can't program this region - contains code in use!\n"); return; } if (prog_ok) { // Erase area to be programmed - if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { - diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); + if ((stat = cyg_flash_erase(flash_addr, length, &err_addr)) != 0) { + diag_printf("Can't erase region at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); prog_ok = false; } } if (prog_ok) { // Now program it - if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) { - diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); + if ((stat = cyg_flash_program(flash_addr, (void *)mem_addr, img_size, + &err_addr)) != 0) { + diag_printf("Can't program region at %p: %s\n", err_addr, + cyg_flash_errmsg(stat)); prog_ok = false; } } @@ -919,7 +953,7 @@ { char *name; int num_reserved, i, stat; - void *err_addr; + cyg_flashaddr_t err_addr; struct fis_image_desc *img; if (!scan_opts(argc, argv, 2, 0, 0, (void *)&name, OPTION_ARG_TYPE_STR, "image name")) @@ -967,8 +1001,8 @@ return; } // Erase Data blocks (free space) - if ((stat = flash_erase((void *)img->flash_base, img->size, (void **)&err_addr)) != 0) { - diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); + if ((stat = cyg_flash_erase(img->flash_base, img->size, &err_addr)) != 0) { + diag_printf("Error erasing at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); } else { img->name[0] = (unsigned char)0xFF; fis_update_directory(); @@ -991,7 +1025,7 @@ #if defined(CYGPRI_REDBOOT_ZLIB_FLASH) || defined(CYGSEM_REDBOOT_FIS_CRC_CHECK) bool decompress = false; #endif - void *err_addr; + cyg_flashaddr_t err_addr; init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, (void *)&mem_addr, (bool *)&mem_addr_set, "memory [load] base address"); @@ -1055,11 +1089,12 @@ load_address_end = (unsigned long)p->out_buf; // Reload fis directory - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); } else // dangling block #endif { - flash_read((void *)img->flash_base, (void *)mem_addr, img->data_length, (void **)&err_addr); + cyg_flash_read(img->flash_base, (void *)mem_addr, img->data_length, + &err_addr); // Set load address/top load_address = mem_addr; @@ -1093,10 +1128,11 @@ bool mem_addr_set = false; bool flash_addr_set = false; bool length_set = false; - void *err_addr; + cyg_flashaddr_t err_addr; struct option_info opts[3]; bool prog_ok; - + size_t block_size; + init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address"); init_opts(&opts[1], 'f', true, OPTION_ARG_TYPE_NUM, @@ -1115,18 +1151,20 @@ } // Round up length to FLASH block size + block_size = cyg_flash_block_size(flash_addr + length); #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken - length = ((length + flash_block_size - 1) / flash_block_size) * flash_block_size; + length = ((length + block_size - 1) / block_size) * block_size; #endif - if (flash_addr_set && - ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { + if ((stat = cyg_flash_verify_addr(flash_addr)) || + (stat = cyg_flash_verify_addr((flash_addr+length-1)))) { _show_invalid_flash_address(flash_addr, stat); return; } - if (flash_addr_set && flash_addr & (flash_block_size-1)) { + + block_size = cyg_flash_block_size(flash_addr); + if (flash_addr & (block_size-1)) { diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); - diag_printf(" must be 0x%x aligned\n", flash_block_size); + diag_printf(" must be 0x%x aligned\n", block_size); return; } if ((mem_addr < (CYG_ADDRESS)ram_start) || @@ -1135,7 +1173,7 @@ diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); } // Safety check - make sure the address range is not within the code we're running - if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) { + if (cyg_flash_code_overlaps(flash_addr, (flash_addr+length-1))) { diag_printf("Can't program this region - contains code in use!\n"); return; } @@ -1147,15 +1185,18 @@ prog_ok = true; if (prog_ok) { // Erase area to be programmed - if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { - diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); + if ((stat = cyg_flash_erase(flash_addr, length, &err_addr)) != 0) { + diag_printf("Can't erase region at %p: %s\n", err_addr, + cyg_flash_errmsg(stat)); prog_ok = false; } } if (prog_ok) { // Now program it - if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, length, (void **)&err_addr)) != 0) { - diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); + if ((stat = cyg_flash_program(flash_addr, (void *)mem_addr, length, + &err_addr)) != 0) { + diag_printf("Can't program region at %p: %s\n", err_addr, + cyg_flash_errmsg(stat)); prog_ok = false; } } @@ -1169,7 +1210,7 @@ CYG_ADDRESS flash_addr; bool flash_addr_set = false; bool length_set = false; - void *err_addr; + cyg_flashaddr_t err_addr; struct option_info opts[2]; init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, @@ -1187,23 +1228,23 @@ return; } if (flash_addr_set && - ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { + ((stat = cyg_flash_verify_addr(flash_addr)) || + (stat = cyg_flash_verify_addr((flash_addr+length-1))))) { _show_invalid_flash_address(flash_addr, stat); return; } - if (flash_addr_set && flash_addr & (flash_block_size-1)) { + if (flash_addr_set && flash_addr & (cyg_flash_block_size(flash_addr)-1)) { diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); diag_printf(" must be 0x%x aligned\n", flash_block_size); return; } // Safety check - make sure the address range is not within the code we're running - if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) { + if (cyg_flash_code_overlaps(flash_addr, (flash_addr+length-1))) { diag_printf("Can't erase this region - contains code in use!\n"); return; } - if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { - diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); + if ((stat = cyg_flash_erase(flash_addr, length, &err_addr)) != 0) { + diag_printf("Error erasing at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); } } @@ -1218,7 +1259,7 @@ CYG_ADDRESS flash_addr; bool flash_addr_set = false; bool length_set = false; - void *err_addr; + cyg_flashaddr_t err_addr; struct option_info opts[2]; init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, @@ -1246,13 +1287,13 @@ return; } if (flash_addr_set && - ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { + ((stat = cyg_flash_verify_addr(flash_addr)) || + (stat = cyg_flash_verify_addr((flash_addr+length-1))))) { _show_invalid_flash_address(flash_addr, stat); return; } - if ((stat = flash_lock((void *)flash_addr, length, (void **)&err_addr)) != 0) { - diag_printf("Error locking at %p: %s\n", err_addr, flash_errmsg(stat)); + if ((stat = cyg_flash_lock(flash_addr, length, &err_addr)) != 0) { + diag_printf("Error locking at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); } } @@ -1265,7 +1306,7 @@ CYG_ADDRESS flash_addr; bool flash_addr_set = false; bool length_set = false; - void *err_addr; + cyg_flashaddr_t err_addr; struct option_info opts[2]; init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, @@ -1292,14 +1333,14 @@ return; } if (flash_addr_set && - ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { + ((stat = cyg_flash_verify_addr(flash_addr)) || + (stat = cyg_flash_verify_addr((flash_addr+length-1))))) { _show_invalid_flash_address(flash_addr, stat); return; } - if ((stat = flash_unlock((void *)flash_addr, length, (void **)&err_addr)) != 0) { - diag_printf("Error unlocking at %p: %s\n", err_addr, flash_errmsg(stat)); + if ((stat = cyg_flash_unlock(flash_addr, length, &err_addr)) != 0) { + diag_printf("Error unlocking at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); } } #endif @@ -1309,28 +1350,44 @@ void _flash_info(void) -{ +{ + cyg_uint32 i=0,j; + cyg_flash_info_t info; + int ret; + if (!__flash_init) return; - diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", - flash_start, (CYG_ADDRWORD)flash_end + 1, flash_num_blocks, (void *)flash_block_size); + + do { + ret = cyg_flash_get_info(i, &info); + if (ret == CYG_FLASH_ERR_OK) { + diag_printf("FLASH: %p - %p ", info.start, info.end); + for (j=0;j < info.num_block_infos; j++) { + diag_printf("%d x 0x%x blocks ", + info.block_info[j].blocks, + info.block_info[j].block_size); + } + diag_printf("\n"); + } + i++; + } while (ret != CYG_FLASH_ERR_INVALID); } bool do_flash_init(void) { int stat; - void *err_addr; + cyg_flashaddr_t err_addr; if (!__flash_init) { __flash_init = 1; - if ((stat = flash_init(diag_printf)) != 0) { - diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat)); + if ((stat = cyg_flash_init(diag_printf)) != 0) { + diag_printf("FLASH: driver init failed: %s\n", cyg_flash_errmsg(stat)); return false; } - flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end); + cyg_flash_get_limits(&flash_start, &flash_end); // Keep 'end' address as last valid location, to avoid wrap around problems - flash_end = (void *)((CYG_ADDRESS)flash_end - 1); - flash_get_block_info(&flash_block_size, &flash_num_blocks); + flash_end = ((CYG_ADDRESS)flash_end - 1); + cyg_flash_get_block_info(&flash_block_size, &flash_num_blocks); #ifdef CYGOPT_REDBOOT_FIS fisdir_size = CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT * CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE; fisdir_size = ((fisdir_size + flash_block_size - 1) / flash_block_size) * flash_block_size; @@ -1345,17 +1402,17 @@ fis_work_block = workspace_end; # endif if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { - fis_addr = (void *)((CYG_ADDRESS)flash_end + 1 + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); + fis_addr = ((CYG_ADDRESS)flash_end + 1 + + (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); } else { - fis_addr = (void *)((CYG_ADDRESS)flash_start + - (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); + fis_addr = ((CYG_ADDRESS)flash_start + + (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); } if (((CYG_ADDRESS)fis_addr + fisdir_size - 1) > (CYG_ADDRESS)flash_end) { diag_printf("FIS directory doesn't fit\n"); return false; } - flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); + cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); #endif } return true; Index: redboot/current/src/io.c =================================================================== RCS file: /cvs/ecos/ecos/packages/redboot/current/src/io.c,v retrieving revision 1.32 diff -u -r1.32 io.c --- redboot/current/src/io.c 5 Dec 2003 12:51:55 -0000 1.32 +++ redboot/current/src/io.c 16 Jul 2004 11:21:06 -0000 @@ -387,6 +387,7 @@ mon_read_char(&c); } *eol = '\0'; + switch (c) { #define CTRL(c) ((c)&0x1F) #if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0 Index: fs/jffs2/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/ChangeLog,v retrieving revision 1.34 diff -u -r1.34 ChangeLog --- fs/jffs2/current/ChangeLog 29 Apr 2004 07:16:10 -0000 1.34 +++ fs/jffs2/current/ChangeLog 16 Jul 2004 11:21:07 -0000 @@ -1,3 +1,27 @@ +2004-07-14 Andrew Lunn + + * tests/fileio1.c (main): If we have two filesystem configured + mount the second one on /mnt and list the root of it. + * src/fs-ecos.c (jffs2_fo_write): Fixed a typo in a debug print + which is normally disabled. + +2004-07-12 Andrew Lunn + + * src/fs-ecos.c (jffs2_fo_lseek): Put back part of the fix for + lseeking past the end of the file which was removed during the last + merge with MTD. + +2004-07-10 Andrew Lunn + + * src/flashio.c (jffs2_flash_erase): Minor update for new + flash API. + +2004-06-21 Dirk Eibach +2004-06-21 Andrew Lunn + + * src/fs-ecos.c (jffs2_getinfo): Added support for + FS_INFO_{FREE|USED} on a filesystem. + 2004-04-19 Oyvind Harboe * src/build.c: JFFS2 can now be used as a write-once, read many mode Index: fs/jffs2/current/src/flashio.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/flashio.c,v retrieving revision 1.1 diff -u -r1.1 flashio.c --- fs/jffs2/current/src/flashio.c 11 Dec 2003 23:38:21 -0000 1.1 +++ fs/jffs2/current/src/flashio.c 16 Jul 2004 11:21:07 -0000 @@ -144,7 +144,7 @@ struct jffs2_eraseblock * jeb) { cyg_io_flash_getconfig_erase_t e; - void *err_addr; + cyg_flashaddr_t err_addr; Cyg_ErrNo err; cyg_uint32 len = sizeof (e); struct super_block *sb = OFNI_BS_2SFFJ(c); Index: fs/jffs2/current/src/fs-ecos.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/src/fs-ecos.c,v retrieving revision 1.27 diff -u -r1.27 fs-ecos.c --- fs/jffs2/current/src/fs-ecos.c 21 Apr 2004 18:51:21 -0000 1.27 +++ fs/jffs2/current/src/fs-ecos.c 16 Jul 2004 11:21:08 -0000 @@ -1360,7 +1360,7 @@ int err; D2(printf("jffs2_fo_write page_start_pos %d\n", pos)); - D2(printf("jffs2_fo_write transfer size %d\n", l)); + D2(printf("jffs2_fo_write transfer size %d\n", len)); err = jffs2_write_inode_range(c, f, &ri, buf, pos, len, &writtenlen); @@ -1420,7 +1420,7 @@ // Check that pos is still within current file size, or at the // very end. - if (pos < 0 || pos > node->i_size) + if (pos < 0 ) return EINVAL; // All OK, set fp offset and return new position. Index: fs/jffs2/current/tests/fileio1.c =================================================================== RCS file: /cvs/ecos/ecos/packages/fs/jffs2/current/tests/fileio1.c,v retrieving revision 1.3 diff -u -r1.3 fileio1.c --- fs/jffs2/current/tests/fileio1.c 11 Dec 2003 23:33:55 -0000 1.3 +++ fs/jffs2/current/tests/fileio1.c 16 Jul 2004 11:21:09 -0000 @@ -73,6 +73,8 @@ #include #include +#include + #include #include @@ -416,6 +418,14 @@ //int i; int existingdirents=-1; + struct mallinfo info; + + info = mallinfo(); + diag_printf("arenasize %d, freeblocks %d, totalallocated %d, totalfree %d, maxfree %d\n", + info.arena, info.ordblks, info.uordblks, info.fordblks, info.maxfree); + + + CYG_TEST_INIT(); // -------------------------------------------------------------- @@ -658,9 +668,33 @@ err = umount( "/jffs2" ); if( err < 0 ) SHOW_RESULT( umount, err ); +#ifdef CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_2 + diag_printf(": mounting second JFFS2 filesystem on /mnt\n"); + + err = mount( CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1, "/mnt", "jffs2" ); + if( err < 0 ) SHOW_RESULT( mount, err ); + + err = chdir( "/" ); + if( err < 0 ) SHOW_RESULT( chdir, err ); + + checkcwd( "/" ); + + listdir( "/", true, -1, &existingdirents ); + if ( existingdirents < 2 ) + CYG_TEST_FAIL("Not enough dir entries\n"); + + listdir( "/mnt", true, -1, &existingdirents ); + if ( existingdirents < 2 ) + CYG_TEST_FAIL("Not enough dir entries\n"); + + diag_printf(": umount /mnt\n"); + err = umount( "/mnt" ); +#endif + diag_printf(": umount /\n"); err = umount( "/" ); if( err < 0 ) SHOW_RESULT( umount, err ); + CYG_TEST_PASS_FINISH("fileio1"); }