--- /dev/null
+/*
+ * Modified verion of yramsim.c.
+ */
+#include "yaffs-rtems-flashsim.h"
+
+#include <string.h>
+#include "../yaffs_guts.h"
+
+
+
+#define N_RAM_SIM_DEVS 1
+
+#define DATA_SIZE 2048
+#define SPARE_SIZE 64
+#define PAGE_SIZE (DATA_SIZE + SPARE_SIZE)
+#define PAGES_PER_BLOCK 64
+
+
+typedef struct {
+ unsigned char page[PAGES_PER_BLOCK][PAGE_SIZE];
+ unsigned blockOk;
+} Block;
+
+typedef struct {
+ Block **blockList;
+ int nBlocks;
+} SimData;
+
+
+SimData *simDevs[N_RAM_SIM_DEVS];
+
+static SimData *DevToSim(struct yaffs_dev *dev)
+{
+ return (SimData*)(dev->driver_context);
+}
+
+
+static void CheckInitialised(void)
+{
+
+}
+
+static int yramsim_erase_internal(SimData *sim, unsigned blockId,int force)
+{
+ if(blockId < 0 || blockId >= sim->nBlocks){
+ return 0;
+ }
+
+ if(!sim->blockList[blockId]){
+ return 0;
+ }
+
+ if(!force && !sim->blockList[blockId]->blockOk){
+ return 0;
+ }
+
+ memset(sim->blockList[blockId],0xff,sizeof(Block));
+ sim->blockList[blockId]->blockOk = 1;
+
+ return 1;
+}
+
+
+
+
+static int yramsim_initialise(struct yaffs_dev *dev)
+{
+ SimData *sim = DevToSim(dev);
+ Block **blockList = sim->blockList;
+ return blockList != NULL;
+}
+
+
+static int yramsim_deinitialise(struct yaffs_dev *dev)
+{
+ return 1;
+}
+
+static int yramsim_rd_chunk (struct yaffs_dev *dev, int pageId,
+ u8 *data, int dataLength,
+ u8 *spare, int spareLength,
+ enum yaffs_ecc_result *ecc_result)
+{
+ SimData *sim = DevToSim(dev);
+ Block **blockList = sim->blockList;
+
+ unsigned blockId = pageId / PAGES_PER_BLOCK;
+ unsigned pageOffset = pageId % PAGES_PER_BLOCK;
+ unsigned char * d;
+ unsigned char *s;
+ if(blockId >= sim->nBlocks ||
+ pageOffset >= PAGES_PER_BLOCK ||
+ dataLength >DATA_SIZE ||
+ spareLength > SPARE_SIZE ||
+ !blockList[blockId]->blockOk){
+ return YAFFS_FAIL;
+ }
+
+ d = blockList[blockId]->page[pageOffset];
+ s = d + DATA_SIZE;
+
+ if(data)
+ memcpy(data,d,dataLength);
+
+ if(spare)
+ memcpy(spare,s,spareLength);
+
+ if (ecc_result)
+ *ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
+
+ return YAFFS_OK;
+}
+
+static int yramsim_wr_chunk (struct yaffs_dev *dev, int pageId,
+ const u8 *data, int dataLength,
+ const u8 *spare, int spareLength)
+{
+ SimData *sim = DevToSim(dev);
+ Block **blockList = sim->blockList;
+
+ unsigned blockId = pageId / PAGES_PER_BLOCK;
+ unsigned pageOffset = pageId % PAGES_PER_BLOCK;
+ unsigned char * d;
+ unsigned char *s;
+ if(blockId >= sim->nBlocks ||
+ pageOffset >= PAGES_PER_BLOCK ||
+ dataLength >DATA_SIZE ||
+ spareLength > SPARE_SIZE ||
+ !blockList[blockId]->blockOk){
+ return YAFFS_FAIL;
+ }
+
+ d = blockList[blockId]->page[pageOffset];
+ s = d + DATA_SIZE;
+
+ if(data)
+ memcpy(d,data,dataLength);
+
+ if(spare)
+ memcpy(s,spare,spareLength);
+
+ return YAFFS_OK;
+}
+
+
+static int yramsim_erase(struct yaffs_dev *dev, int blockId)
+{
+ SimData *sim = DevToSim(dev);
+
+ CheckInitialised();
+ return yramsim_erase_internal(sim,blockId,0);
+}
+
+static int yramsim_check_block_bad(struct yaffs_dev *dev, int blockId)
+{
+ SimData *sim = DevToSim(dev);
+ Block **blockList = sim->blockList;
+ if(blockId >= sim->nBlocks){
+ return YAFFS_FAIL;
+ }
+
+ return blockList[blockId]->blockOk ? YAFFS_OK : YAFFS_FAIL;
+}
+
+static int yramsim_mark_block_bad(struct yaffs_dev *dev, int blockId)
+{
+ SimData *sim = DevToSim(dev);
+ Block **blockList = sim->blockList;
+ if(blockId >= sim->nBlocks){
+ return YAFFS_FAIL;
+ }
+
+ blockList[blockId]->blockOk = 0;
+
+ return YAFFS_OK;
+}
+
+
+static SimData *yramsim_alloc_sim_data(u32 devId, u32 nBlocks)
+{
+ int ok = 1;
+
+ Block **blockList;
+ SimData *sim;
+ Block *b;
+ u32 i;
+
+ if(devId >= N_RAM_SIM_DEVS)
+ return NULL;
+
+ sim = simDevs[devId];
+
+ if(sim)
+ return sim;
+
+ sim = malloc(sizeof (SimData));
+ if(!sim)
+ return NULL;
+
+ simDevs[devId] = sim;
+
+ blockList = malloc(nBlocks * sizeof(Block *));
+
+ sim->blockList = blockList;
+ sim->nBlocks = nBlocks;
+ if(!blockList){
+ free(sim);
+ return NULL;
+ }
+
+ for(i = 0; i < nBlocks; i++)
+ blockList[i] = NULL;
+
+ for(i = 0; i < nBlocks && ok; i++){
+ b= malloc(sizeof(Block));
+ if(b){
+ blockList[i] = b;
+ yramsim_erase_internal(sim,i,1);
+ }
+ else
+ ok = 0;
+ }
+
+ if(!ok){
+ for(i = 0; i < nBlocks; i++)
+ if(blockList[i]){
+ free(blockList[i]);
+ blockList[i] = NULL;
+ }
+ free(blockList);
+ blockList = NULL;
+ free(sim);
+ sim = NULL;
+ }
+
+ return sim;
+}
+
+
+struct yaffs_dev *yramsim_CreateRamSim(const YCHAR *name,
+ u32 devId, u32 nBlocks,
+ u32 start_block, u32 end_block)
+{
+ SimData *sim;
+ struct yaffs_dev *dev;
+ struct yaffs_param *p;
+ struct yaffs_driver *d;
+
+ sim = yramsim_alloc_sim_data(devId, nBlocks);
+
+ dev = malloc(sizeof(*dev));
+
+ if(!sim || !dev){
+ free(sim);
+ free(dev);
+ printf("Flash Sim creation failed. sim = %p, dev = %p\n",
+ sim, dev);
+ return NULL;
+ }
+
+ memset(dev, 0, sizeof(*dev));
+
+ if(start_block >= sim->nBlocks)
+ start_block = 0;
+ if(end_block == 0 || end_block >= sim->nBlocks)
+ end_block = sim->nBlocks - 1;
+
+ p = &dev->param;
+ p->name = strdup(name);
+ p->start_block = start_block;
+ p->end_block = end_block;
+ p->total_bytes_per_chunk = DATA_SIZE;
+ p->spare_bytes_per_chunk= SPARE_SIZE;
+ p->chunks_per_block = PAGES_PER_BLOCK;
+ p->n_reserved_blocks = 2;
+ p->use_nand_ecc = 1;
+ p->inband_tags = 0;
+ p->is_yaffs2 = 1;
+
+ d= &dev->drv;
+ d->drv_initialise_fn = yramsim_initialise;
+ d->drv_deinitialise_fn = yramsim_deinitialise;
+ d->drv_read_chunk_fn = yramsim_rd_chunk;
+ d->drv_write_chunk_fn = yramsim_wr_chunk;
+ d->drv_erase_fn = yramsim_erase;
+ d->drv_check_bad_fn = yramsim_check_block_bad;
+ d->drv_mark_bad_fn = yramsim_mark_block_bad;
+
+ dev->driver_context= (void *)sim;
+
+ printf("Created simulated flash device %p\n", dev);
+ return dev;
+}
+
+struct yaffs_dev *yaffs_rtems_flashsim_setup(void)
+{
+ return yramsim_CreateRamSim("ramsim",
+ 0, 100,
+ 0, 99);
+}
+