yaffs Update RAM simulator to support start and end blocks
authorCharles Manning <cdhmanning@gmail.com>
Wed, 4 Aug 2010 00:09:58 +0000 (12:09 +1200)
committerCharles Manning <cdhmanning@gmail.com>
Wed, 4 Aug 2010 00:09:58 +0000 (12:09 +1200)
This makes it more versatile for simulation of different usage patterns.

Signed-off-by: Charles Manning <cdhmanning@gmail.com>
direct/basic-test/yaffsnewcfg.c
direct/basic-test/yramsim.c
direct/basic-test/yramsim.h

index 6f1a9e409c98aee3c256f7cc369fee00203c16cc..6ee43b78137cc454b05d342f7445742488212d93 100644 (file)
@@ -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;
 }
index 69b5b78368a06e5165b9d8882b3fc2cc7ce54026..caa1aac809ba05e1ca4534f9c656088392a1c63e 100644 (file)
-// NAND Simulator for testing YAFFS\r
-\r
-#include <string.h>\r
-\r
-#include "yramsim.h"\r
-\r
-#include "yaffs_nandif.h"\r
-\r
-\r
-#define DATA_SIZE      2048\r
-#define SPARE_SIZE     64\r
-#define PAGE_SIZE      (DATA_SIZE + SPARE_SIZE)\r
-#define PAGES_PER_BLOCK        64\r
-\r
-\r
-typedef struct {\r
-       unsigned char page[PAGES_PER_BLOCK][PAGE_SIZE];\r
-       unsigned blockOk;\r
-} Block;\r
-\r
-typedef struct {\r
-       Block **blockList;\r
-       int nBlocks;\r
-} SymData;\r
-\r
-\r
-static SymData *DevToSym(yaffs_Device *dev)\r
-{\r
-       ynandif_Geometry *geom = (ynandif_Geometry *)(dev->driverContext);\r
-       SymData * sym = (SymData*)(geom->privateData);\r
-       return sym;\r
-} \r
-\r
-\r
-static void CheckInitialised(void)\r
-{\r
-\r
-}\r
-\r
-static int yramsim_EraseBlockInternal(SymData *sym, unsigned blockId,int force)\r
-{\r
-       if(blockId < 0 || blockId >= sym->nBlocks){\r
-               return 0;\r
-       }\r
-\r
-       if(!sym->blockList[blockId]){\r
-               return 0;\r
-       }\r
-\r
-       if(!force && !sym->blockList[blockId]->blockOk){\r
-               return 0;\r
-       }\r
-\r
-       memset(sym->blockList[blockId],0xff,sizeof(Block));\r
-       sym->blockList[blockId]->blockOk = 1;\r
-\r
-       return 1;\r
-}\r
-\r
-\r
-\r
-\r
-static int yramsim_Initialise(yaffs_Device *dev)\r
-{\r
-       SymData *sym = DevToSym(dev);\r
-       Block **blockList = sym->blockList;\r
-       return blockList != NULL;\r
-}\r
-\r
-\r
-static int yramsim_Deinitialise(yaffs_Device *dev)\r
-{\r
-       return 1;\r
-}\r
-\r
-static int yramsim_ReadChunk (yaffs_Device *dev, unsigned pageId, \r
-                                         unsigned char *data, unsigned dataLength,\r
-                                         unsigned char *spare, unsigned spareLength,\r
-                                         int *eccStatus)\r
-{\r
-       SymData *sym = DevToSym(dev);\r
-       Block **blockList = sym->blockList;\r
-\r
-       unsigned blockId = pageId / PAGES_PER_BLOCK;\r
-       unsigned pageOffset = pageId % PAGES_PER_BLOCK;\r
-       unsigned char * d;\r
-       unsigned char *s;\r
-       if(blockId >= sym->nBlocks ||\r
-          pageOffset >= PAGES_PER_BLOCK ||\r
-          dataLength >DATA_SIZE ||\r
-          spareLength > SPARE_SIZE ||\r
-          !eccStatus ||\r
-          !blockList[blockId]->blockOk){\r
-                  return 0;\r
-       }\r
-\r
-       d = blockList[blockId]->page[pageOffset];\r
-       s = d + DATA_SIZE;\r
-\r
-       if(data)\r
-               memcpy(data,d,dataLength);\r
-\r
-       if(spare)\r
-               memcpy(spare,s,spareLength);\r
-\r
-       *eccStatus = 0; // 0 = no error, -1 = unfixable error, 1 = fixable\r
-\r
-       return 1;\r
-       \r
-}\r
-\r
-static int yramsim_WriteChunk (yaffs_Device *dev,unsigned pageId, \r
-                                          const unsigned char *data, unsigned dataLength,\r
-                                          const unsigned char *spare, unsigned spareLength)\r
-{\r
-       SymData *sym = DevToSym(dev);\r
-       Block **blockList = sym->blockList;\r
-\r
-       unsigned blockId = pageId / PAGES_PER_BLOCK;\r
-       unsigned pageOffset = pageId % PAGES_PER_BLOCK;\r
-       unsigned char * d;\r
-       unsigned char *s;\r
-       if(blockId >= sym->nBlocks ||\r
-          pageOffset >= PAGES_PER_BLOCK ||\r
-          dataLength >DATA_SIZE ||\r
-          spareLength > SPARE_SIZE ||\r
-          !blockList[blockId]->blockOk){\r
-                  return 0;\r
-       }\r
-\r
-       d = blockList[blockId]->page[pageOffset];\r
-       s = d + DATA_SIZE;\r
-\r
-       if(data)\r
-               memcpy(d,data,dataLength);\r
-\r
-       if(spare)\r
-               memcpy(s,spare,spareLength);\r
-\r
-       return 1;\r
-       \r
-}\r
-\r
-\r
-static int yramsim_EraseBlock(yaffs_Device *dev,unsigned blockId)\r
-{\r
-       SymData *sym = DevToSym(dev);\r
-\r
-       CheckInitialised();\r
-       return yramsim_EraseBlockInternal(sym,blockId,0);\r
-}\r
-\r
-static int yramsim_CheckBlockOk(yaffs_Device *dev,unsigned blockId)\r
-{\r
-       SymData *sym = DevToSym(dev);\r
-       Block **blockList = sym->blockList;\r
-       if(blockId >= sym->nBlocks){\r
-               return 0;\r
-       }\r
-\r
-       return blockList[blockId]->blockOk ? 1 : 0;\r
-}\r
-\r
-static int yramsim_MarkBlockBad(yaffs_Device *dev,unsigned blockId)\r
-{\r
-       SymData *sym = DevToSym(dev);\r
-       Block **blockList = sym->blockList;\r
-       if(blockId >= sym->nBlocks){\r
-               return 0;\r
-       }\r
-\r
-       blockList[blockId]->blockOk = 0;\r
-\r
-       return 1;\r
-}\r
-\r
-\r
-static SymData *yramsim_AllocSymData(int nBlocks)\r
-{\r
-       int ok = 1;\r
-\r
-       Block **blockList;\r
-       SymData *sym;\r
-       Block *b;\r
-       int i;\r
-\r
-       sym = malloc(sizeof (SymData));\r
-       if(!sym)\r
-               return NULL;\r
-\r
-       blockList = malloc(nBlocks * sizeof(Block *));\r
-       \r
-       sym->blockList = blockList;\r
-       sym->nBlocks = nBlocks;\r
-       if(!blockList){\r
-               free(sym);\r
-               return NULL;\r
-       }\r
-\r
-       for(i = 0; i < nBlocks; i++)\r
-               blockList[i] = NULL;\r
-\r
-       for(i = 0; i < nBlocks && ok; i++){\r
-               b=  malloc(sizeof(Block));\r
-               if(b){\r
-                       blockList[i] = b;\r
-                       yramsim_EraseBlockInternal(sym,i,1);\r
-               }\r
-               else\r
-                       ok = 0;\r
-       }\r
-\r
-       if(!ok){\r
-               for(i = 0; i < nBlocks; i++)\r
-                       if(blockList[i]){\r
-                               free(blockList[i]);\r
-                               blockList[i] = NULL;\r
-                       }\r
-               free(blockList);\r
-               blockList = NULL;\r
-               free(sym);\r
-               sym = NULL;\r
-       }\r
-\r
-       return sym;\r
-}\r
-\r
-\r
-struct yaffs_DeviceStruct *yramsim_CreateSim(const YCHAR *name,int nBlocks)\r
-{\r
-       void *sym = (void *)yramsim_AllocSymData(nBlocks);\r
-       ynandif_Geometry *g;\r
-\r
-       g = YMALLOC(sizeof(ynandif_Geometry));\r
-       \r
-       if(!sym || !g){\r
-               if(sym)\r
-                       YFREE(sym);\r
-               if(g)\r
-                       YFREE(g);\r
-               return NULL;\r
-       }\r
-\r
-       memset(g,0,sizeof(ynandif_Geometry));\r
-       g->startBlock = 0;\r
-       g->endBlock = nBlocks - 1;\r
-       g->dataSize = DATA_SIZE;\r
-       g->spareSize= SPARE_SIZE;\r
-       g->pagesPerBlock = PAGES_PER_BLOCK;\r
-       g->hasECC = 1;\r
-       g->inbandTags = 0;\r
-       g->useYaffs2 = 1;\r
-       g->initialise = yramsim_Initialise;\r
-       g->deinitialise = yramsim_Deinitialise; \r
-       g->readChunk = yramsim_ReadChunk, \r
-       g->writeChunk = yramsim_WriteChunk,\r
-       g->eraseBlock = yramsim_EraseBlock,\r
-       g->checkBlockOk = yramsim_CheckBlockOk,\r
-       g->markBlockBad = yramsim_MarkBlockBad,\r
-       g->privateData = sym;\r
-\r
-       return yaffs_AddDeviceFromGeometry(name,g);\r
+// NAND Simulator for testing YAFFS
+
+#include <string.h>
+
+#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);
 }
index 694ceaf552c138e55770168e5ffe1c8772cb5240..d842848f696111683c6cd767b6cd12f53bc1dec8 100644 (file)
@@ -1,11 +1,14 @@
-// NAND Simulator for testing YAFFS\r
-#ifndef __YAFF_RAM_SIM_H__\r
-#define __YAFF_RAM_SIM_H__\r
-\r
-\r
-#include "yaffs_guts.h"\r
-\r
-struct yaffs_DeviceStruct *yramsim_CreateSim(const YCHAR *name, int nBlocks);\r
-\r
-\r
-#endif\r
+// 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