From 497c3cfe39bd95fe6e5a4e9a5938fddf97bbed11 Mon Sep 17 00:00:00 2001 From: Charles Manning Date: Wed, 4 Aug 2010 12:09:58 +1200 Subject: [PATCH] yaffs Update RAM simulator to support start and end blocks This makes it more versatile for simulation of different usage patterns. Signed-off-by: Charles Manning --- direct/basic-test/yaffsnewcfg.c | 6 +- direct/basic-test/yramsim.c | 541 ++++++++++++++++---------------- direct/basic-test/yramsim.h | 25 +- 3 files changed, 296 insertions(+), 276 deletions(-) diff --git a/direct/basic-test/yaffsnewcfg.c b/direct/basic-test/yaffsnewcfg.c index 6f1a9e4..6ee43b7 100644 --- a/direct/basic-test/yaffsnewcfg.c +++ b/direct/basic-test/yaffsnewcfg.c @@ -101,9 +101,9 @@ int yaffs_StartUp(void) // Stuff to configure YAFFS // Stuff to initialise anything special (eg lock semaphore). yaffsfs_LocalInitialisation(); - - yramsim_CreateSim("yaffs2",200); - yramsim_CreateSim("yaffs2-2",50); + yramsim_CreateRamSim("yaffs2",1,200,0,0); + yramsim_CreateRamSim("p0",0,0x400,1,0xff); + yramsim_CreateRamSim("p1",0,0x400,1,0); return 0; } diff --git a/direct/basic-test/yramsim.c b/direct/basic-test/yramsim.c index 69b5b78..caa1aac 100644 --- a/direct/basic-test/yramsim.c +++ b/direct/basic-test/yramsim.c @@ -1,263 +1,280 @@ -// NAND Simulator for testing YAFFS - -#include - -#include "yramsim.h" - -#include "yaffs_nandif.h" - - -#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; -} SymData; - - -static SymData *DevToSym(yaffs_Device *dev) -{ - ynandif_Geometry *geom = (ynandif_Geometry *)(dev->driverContext); - SymData * sym = (SymData*)(geom->privateData); - return sym; -} - - -static void CheckInitialised(void) -{ - -} - -static int yramsim_EraseBlockInternal(SymData *sym, unsigned blockId,int force) -{ - if(blockId < 0 || blockId >= sym->nBlocks){ - return 0; - } - - if(!sym->blockList[blockId]){ - return 0; - } - - if(!force && !sym->blockList[blockId]->blockOk){ - return 0; - } - - memset(sym->blockList[blockId],0xff,sizeof(Block)); - sym->blockList[blockId]->blockOk = 1; - - return 1; -} - - - - -static int yramsim_Initialise(yaffs_Device *dev) -{ - SymData *sym = DevToSym(dev); - Block **blockList = sym->blockList; - return blockList != NULL; -} - - -static int yramsim_Deinitialise(yaffs_Device *dev) -{ - return 1; -} - -static int yramsim_ReadChunk (yaffs_Device *dev, unsigned pageId, - unsigned char *data, unsigned dataLength, - unsigned char *spare, unsigned spareLength, - int *eccStatus) -{ - SymData *sym = DevToSym(dev); - Block **blockList = sym->blockList; - - unsigned blockId = pageId / PAGES_PER_BLOCK; - unsigned pageOffset = pageId % PAGES_PER_BLOCK; - unsigned char * d; - unsigned char *s; - if(blockId >= sym->nBlocks || - pageOffset >= PAGES_PER_BLOCK || - dataLength >DATA_SIZE || - spareLength > SPARE_SIZE || - !eccStatus || - !blockList[blockId]->blockOk){ - return 0; - } - - d = blockList[blockId]->page[pageOffset]; - s = d + DATA_SIZE; - - if(data) - memcpy(data,d,dataLength); - - if(spare) - memcpy(spare,s,spareLength); - - *eccStatus = 0; // 0 = no error, -1 = unfixable error, 1 = fixable - - return 1; - -} - -static int yramsim_WriteChunk (yaffs_Device *dev,unsigned pageId, - const unsigned char *data, unsigned dataLength, - const unsigned char *spare, unsigned spareLength) -{ - SymData *sym = DevToSym(dev); - Block **blockList = sym->blockList; - - unsigned blockId = pageId / PAGES_PER_BLOCK; - unsigned pageOffset = pageId % PAGES_PER_BLOCK; - unsigned char * d; - unsigned char *s; - if(blockId >= sym->nBlocks || - pageOffset >= PAGES_PER_BLOCK || - dataLength >DATA_SIZE || - spareLength > SPARE_SIZE || - !blockList[blockId]->blockOk){ - return 0; - } - - d = blockList[blockId]->page[pageOffset]; - s = d + DATA_SIZE; - - if(data) - memcpy(d,data,dataLength); - - if(spare) - memcpy(s,spare,spareLength); - - return 1; - -} - - -static int yramsim_EraseBlock(yaffs_Device *dev,unsigned blockId) -{ - SymData *sym = DevToSym(dev); - - CheckInitialised(); - return yramsim_EraseBlockInternal(sym,blockId,0); -} - -static int yramsim_CheckBlockOk(yaffs_Device *dev,unsigned blockId) -{ - SymData *sym = DevToSym(dev); - Block **blockList = sym->blockList; - if(blockId >= sym->nBlocks){ - return 0; - } - - return blockList[blockId]->blockOk ? 1 : 0; -} - -static int yramsim_MarkBlockBad(yaffs_Device *dev,unsigned blockId) -{ - SymData *sym = DevToSym(dev); - Block **blockList = sym->blockList; - if(blockId >= sym->nBlocks){ - return 0; - } - - blockList[blockId]->blockOk = 0; - - return 1; -} - - -static SymData *yramsim_AllocSymData(int nBlocks) -{ - int ok = 1; - - Block **blockList; - SymData *sym; - Block *b; - int i; - - sym = malloc(sizeof (SymData)); - if(!sym) - return NULL; - - blockList = malloc(nBlocks * sizeof(Block *)); - - sym->blockList = blockList; - sym->nBlocks = nBlocks; - if(!blockList){ - free(sym); - 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_EraseBlockInternal(sym,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(sym); - sym = NULL; - } - - return sym; -} - - -struct yaffs_DeviceStruct *yramsim_CreateSim(const YCHAR *name,int nBlocks) -{ - void *sym = (void *)yramsim_AllocSymData(nBlocks); - ynandif_Geometry *g; - - g = YMALLOC(sizeof(ynandif_Geometry)); - - if(!sym || !g){ - if(sym) - YFREE(sym); - if(g) - YFREE(g); - return NULL; - } - - memset(g,0,sizeof(ynandif_Geometry)); - g->startBlock = 0; - g->endBlock = nBlocks - 1; - g->dataSize = DATA_SIZE; - g->spareSize= SPARE_SIZE; - g->pagesPerBlock = PAGES_PER_BLOCK; - g->hasECC = 1; - g->inbandTags = 0; - g->useYaffs2 = 1; - g->initialise = yramsim_Initialise; - g->deinitialise = yramsim_Deinitialise; - g->readChunk = yramsim_ReadChunk, - g->writeChunk = yramsim_WriteChunk, - g->eraseBlock = yramsim_EraseBlock, - g->checkBlockOk = yramsim_CheckBlockOk, - g->markBlockBad = yramsim_MarkBlockBad, - g->privateData = sym; - - return yaffs_AddDeviceFromGeometry(name,g); +// NAND Simulator for testing YAFFS + +#include + +#include "yramsim.h" + +#include "yaffs_nandif.h" + + +#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(yaffs_Device *dev) +{ + ynandif_Geometry *geom = (ynandif_Geometry *)(dev->driverContext); + SimData * sim = (SimData*)(geom->privateData); + return sim; +} + + +static void CheckInitialised(void) +{ + +} + +static int yramsim_EraseBlockInternal(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(yaffs_Device *dev) +{ + SimData *sim = DevToSim(dev); + Block **blockList = sim->blockList; + return blockList != NULL; +} + + +static int yramsim_Deinitialise(yaffs_Device *dev) +{ + return 1; +} + +static int yramsim_ReadChunk (yaffs_Device *dev, unsigned pageId, + unsigned char *data, unsigned dataLength, + unsigned char *spare, unsigned spareLength, + int *eccStatus) +{ + 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 || + !eccStatus || + !blockList[blockId]->blockOk){ + return 0; + } + + d = blockList[blockId]->page[pageOffset]; + s = d + DATA_SIZE; + + if(data) + memcpy(data,d,dataLength); + + if(spare) + memcpy(spare,s,spareLength); + + *eccStatus = 0; // 0 = no error, -1 = unfixable error, 1 = fixable + + return 1; +} + +static int yramsim_WriteChunk (yaffs_Device *dev,unsigned pageId, + const unsigned char *data, unsigned dataLength, + const unsigned char *spare, unsigned 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 0; + } + + d = blockList[blockId]->page[pageOffset]; + s = d + DATA_SIZE; + + if(data) + memcpy(d,data,dataLength); + + if(spare) + memcpy(s,spare,spareLength); + + return 1; +} + + +static int yramsim_EraseBlock(yaffs_Device *dev,unsigned blockId) +{ + SimData *sim = DevToSim(dev); + + CheckInitialised(); + return yramsim_EraseBlockInternal(sim,blockId,0); +} + +static int yramsim_CheckBlockOk(yaffs_Device *dev,unsigned blockId) +{ + SimData *sim = DevToSim(dev); + Block **blockList = sim->blockList; + if(blockId >= sim->nBlocks){ + return 0; + } + + return blockList[blockId]->blockOk ? 1 : 0; +} + +static int yramsim_MarkBlockBad(yaffs_Device *dev,unsigned blockId) +{ + SimData *sim = DevToSim(dev); + Block **blockList = sim->blockList; + if(blockId >= sim->nBlocks){ + return 0; + } + + blockList[blockId]->blockOk = 0; + + return 1; +} + + +static SimData *yramsim_AllocSimData(__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_EraseBlockInternal(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_DeviceStruct *yramsim_CreateRamSim(const YCHAR *name, + __u32 devId, __u32 nBlocks, + __u32 startBlock, __u32 endBlock) +{ + SimData *sim; + ynandif_Geometry *g; + + sim = yramsim_AllocSimData(devId, nBlocks); + + g = YMALLOC(sizeof(ynandif_Geometry)); + + if(!sim || !g){ + if(g) + YFREE(g); + return NULL; + } + + if(startBlock >= sim->nBlocks) + startBlock = 0; + if(endBlock == 0 || endBlock >= sim->nBlocks) + endBlock = sim->nBlocks - 1; + + memset(g,0,sizeof(ynandif_Geometry)); + g->startBlock = startBlock; + g->endBlock = endBlock; + g->dataSize = DATA_SIZE; + g->spareSize= SPARE_SIZE; + g->pagesPerBlock = PAGES_PER_BLOCK; + g->hasECC = 1; + g->inbandTags = 0; + g->useYaffs2 = 1; + g->initialise = yramsim_Initialise; + g->deinitialise = yramsim_Deinitialise; + g->readChunk = yramsim_ReadChunk, + g->writeChunk = yramsim_WriteChunk, + g->eraseBlock = yramsim_EraseBlock, + g->checkBlockOk = yramsim_CheckBlockOk, + g->markBlockBad = yramsim_MarkBlockBad, + g->privateData = (void *)sim; + + return yaffs_AddDeviceFromGeometry(name,g); } diff --git a/direct/basic-test/yramsim.h b/direct/basic-test/yramsim.h index 694ceaf..d842848 100644 --- a/direct/basic-test/yramsim.h +++ b/direct/basic-test/yramsim.h @@ -1,11 +1,14 @@ -// NAND Simulator for testing YAFFS -#ifndef __YAFF_RAM_SIM_H__ -#define __YAFF_RAM_SIM_H__ - - -#include "yaffs_guts.h" - -struct yaffs_DeviceStruct *yramsim_CreateSim(const YCHAR *name, int nBlocks); - - -#endif +// NAND RAM Simulator for testing YAFFS +#ifndef __YAFFS_RAM_SIM_H__ +#define __YAFFS_RAM_SIM_H__ + + +#include "yaffs_guts.h" + +#define N_RAM_SIM_DEVS 2 + +struct yaffs_DeviceStruct *yramsim_CreateSim(const YCHAR *name, + __u32 devId, __u32 nBlocks, + __u32 startBlock, __u32 endBlock); + +#endif -- 2.30.2