2 * Modified verion of yramsim.c.
4 #include "yaffs-rtems-flashsim.h"
7 #include "../yaffs_guts.h"
11 #define N_RAM_SIM_DEVS 1
13 #define DATA_SIZE 2048
15 #define PAGE_SIZE (DATA_SIZE + SPARE_SIZE)
16 #define PAGES_PER_BLOCK 64
20 unsigned char page[PAGES_PER_BLOCK][PAGE_SIZE];
30 SimData *simDevs[N_RAM_SIM_DEVS];
32 static SimData *DevToSim(struct yaffs_dev *dev)
34 return (SimData*)(dev->driver_context);
38 static void CheckInitialised(void)
43 static int yramsim_erase_internal(SimData *sim, unsigned blockId,int force)
45 if(blockId < 0 || blockId >= sim->nBlocks){
49 if(!sim->blockList[blockId]){
53 if(!force && !sim->blockList[blockId]->blockOk){
57 memset(sim->blockList[blockId],0xff,sizeof(Block));
58 sim->blockList[blockId]->blockOk = 1;
66 static int yramsim_initialise(struct yaffs_dev *dev)
68 SimData *sim = DevToSim(dev);
69 Block **blockList = sim->blockList;
70 return blockList != NULL;
74 static int yramsim_deinitialise(struct yaffs_dev *dev)
79 static int yramsim_rd_chunk (struct yaffs_dev *dev, int pageId,
80 u8 *data, int dataLength,
81 u8 *spare, int spareLength,
82 enum yaffs_ecc_result *ecc_result)
84 SimData *sim = DevToSim(dev);
85 Block **blockList = sim->blockList;
87 unsigned blockId = pageId / PAGES_PER_BLOCK;
88 unsigned pageOffset = pageId % PAGES_PER_BLOCK;
91 if(blockId >= sim->nBlocks ||
92 pageOffset >= PAGES_PER_BLOCK ||
93 dataLength >DATA_SIZE ||
94 spareLength > SPARE_SIZE ||
95 !blockList[blockId]->blockOk){
99 d = blockList[blockId]->page[pageOffset];
103 memcpy(data,d,dataLength);
106 memcpy(spare,s,spareLength);
109 *ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
114 static int yramsim_wr_chunk (struct yaffs_dev *dev, int pageId,
115 const u8 *data, int dataLength,
116 const u8 *spare, int spareLength)
118 SimData *sim = DevToSim(dev);
119 Block **blockList = sim->blockList;
121 unsigned blockId = pageId / PAGES_PER_BLOCK;
122 unsigned pageOffset = pageId % PAGES_PER_BLOCK;
125 if(blockId >= sim->nBlocks ||
126 pageOffset >= PAGES_PER_BLOCK ||
127 dataLength >DATA_SIZE ||
128 spareLength > SPARE_SIZE ||
129 !blockList[blockId]->blockOk){
133 d = blockList[blockId]->page[pageOffset];
137 memcpy(d,data,dataLength);
140 memcpy(s,spare,spareLength);
146 static int yramsim_erase(struct yaffs_dev *dev, int blockId)
148 SimData *sim = DevToSim(dev);
151 return yramsim_erase_internal(sim,blockId,0);
154 static int yramsim_check_block_bad(struct yaffs_dev *dev, int blockId)
156 SimData *sim = DevToSim(dev);
157 Block **blockList = sim->blockList;
158 if(blockId >= sim->nBlocks){
162 return blockList[blockId]->blockOk ? YAFFS_OK : YAFFS_FAIL;
165 static int yramsim_mark_block_bad(struct yaffs_dev *dev, int blockId)
167 SimData *sim = DevToSim(dev);
168 Block **blockList = sim->blockList;
169 if(blockId >= sim->nBlocks){
173 blockList[blockId]->blockOk = 0;
179 static SimData *yramsim_alloc_sim_data(u32 devId, u32 nBlocks)
188 if(devId >= N_RAM_SIM_DEVS)
191 sim = simDevs[devId];
196 sim = malloc(sizeof (SimData));
200 simDevs[devId] = sim;
202 blockList = malloc(nBlocks * sizeof(Block *));
204 sim->blockList = blockList;
205 sim->nBlocks = nBlocks;
211 for(i = 0; i < nBlocks; i++)
214 for(i = 0; i < nBlocks && ok; i++){
215 b= malloc(sizeof(Block));
218 yramsim_erase_internal(sim,i,1);
225 for(i = 0; i < nBlocks; i++)
240 struct yaffs_dev *yramsim_CreateRamSim(const YCHAR *name,
241 u32 devId, u32 nBlocks,
242 u32 start_block, u32 end_block)
245 struct yaffs_dev *dev;
246 struct yaffs_param *p;
247 struct yaffs_driver *d;
249 sim = yramsim_alloc_sim_data(devId, nBlocks);
251 dev = malloc(sizeof(*dev));
256 printf("Flash Sim creation failed. sim = %p, dev = %p\n",
261 memset(dev, 0, sizeof(*dev));
263 if(start_block >= sim->nBlocks)
265 if(end_block == 0 || end_block >= sim->nBlocks)
266 end_block = sim->nBlocks - 1;
269 p->name = strdup(name);
270 p->start_block = start_block;
271 p->end_block = end_block;
272 p->total_bytes_per_chunk = DATA_SIZE;
273 p->spare_bytes_per_chunk= SPARE_SIZE;
274 p->chunks_per_block = PAGES_PER_BLOCK;
275 p->n_reserved_blocks = 2;
281 d->drv_initialise_fn = yramsim_initialise;
282 d->drv_deinitialise_fn = yramsim_deinitialise;
283 d->drv_read_chunk_fn = yramsim_rd_chunk;
284 d->drv_write_chunk_fn = yramsim_wr_chunk;
285 d->drv_erase_fn = yramsim_erase;
286 d->drv_check_bad_fn = yramsim_check_block_bad;
287 d->drv_mark_bad_fn = yramsim_mark_block_bad;
289 dev->driver_context= (void *)sim;
291 printf("Created simulated flash device %p\n", dev);
295 struct yaffs_dev *yaffs_rtems_flashsim_setup(void)
297 return yramsim_CreateRamSim("ramsim",