X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=direct%2Ftest-framework%2Fynorsim.c;h=38a4632e800f4f69386d77a9e4d30a7b01945e23;hp=36bfa625ca346b91e29d186aebc736ae2e527470;hb=fd65eb6c02fba80b81f6e6f327ebb73250cbd9f5;hpb=c08faae4258b29a794ad55ca160c5a247145c838 diff --git a/direct/test-framework/ynorsim.c b/direct/test-framework/ynorsim.c index 36bfa62..38a4632 100644 --- a/direct/test-framework/ynorsim.c +++ b/direct/test-framework/ynorsim.c @@ -13,8 +13,6 @@ #include "ynorsim.h" - - #include #include #include @@ -23,12 +21,12 @@ #define YNORSIM_FNAME "emfile-nor" -/* Set YNORSIM_BIT_CHANGES to a a value from 1..30 to - *simulate bit flipping as the programming happens. +/* Set YNORSIM_BIT_CHANGES to a a value from 1..30 to + *simulate bit flipping as the programming happens. * A low value results in faster simulation with less chance of encountering a partially programmed - * word. + * word. */ - + //#define YNORSIM_BIT_CHANGES 15 #define YNORSIM_BIT_CHANGES 2 @@ -48,134 +46,162 @@ #define YNORSIM_DEV_SIZE_U32 (8*1024 * 1024/4) #endif -static u32 word[YNORSIM_DEV_SIZE_U32]; +struct nor_sim { + int n_blocks; + int block_size_bytes; + int file_size; + u32 *word; + int initialised; + char *fname; + int remaining_ops; + int nops_so_far; +}; +int ops_multiplier = 500; extern int random_seed; extern int simulate_power_failure; -static void NorError(void) +static void NorError(struct nor_sim *sim) { - printf("Nor error\n"); - while(1){} + printf("Nor error on device %s\n", sim->fname); + while (1) { + } } -static void ynorsim_save_image(void) +static void ynorsim_save_image(struct nor_sim *sim) { - int h = open(YNORSIM_FNAME, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); - write(h,word,sizeof(word)); - close(h); + int h; + + h = open(sim->fname, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); + write(h, sim->word, sim->file_size); + close(h); } -static void ynorsim_restore_image(void) +static void ynorsim_restore_image(struct nor_sim *sim) { - int h = open(YNORSIM_FNAME, O_RDONLY, S_IREAD | S_IWRITE); - memset(word,0xFF,sizeof(word)); - read(h,word,sizeof(word)); - close(h); -} + int h; + h = open(sim->fname, O_RDONLY, S_IREAD | S_IWRITE); + memset(sim->word, 0xFF, sim->file_size); + read(h, sim->word, sim->file_size); + close(h); +} -static void ynorsim_power_fail(void) +static void ynorsim_power_fail(struct nor_sim *sim) { - ynorsim_save_image(); - exit(1); + ynorsim_save_image(sim); + exit(1); } -static int initialised = 0; -static int remaining_ops; -static int nops_so_far; - -int ops_multiplier = 500; - -static void ynorsim_maybe_power_fail(void) +static void ynorsim_maybe_power_fail(struct nor_sim *sim) { - - nops_so_far++; - - - remaining_ops--; - if(simulate_power_failure && - remaining_ops < 1){ - printf("Simulated power failure after %d operations\n",nops_so_far); - ynorsim_power_fail(); - } + sim->nops_so_far++; + sim->remaining_ops--; + if (simulate_power_failure && sim->remaining_ops < 1) { + printf("Simulated power failure after %d operations\n", + sim->nops_so_far); + ynorsim_power_fail(sim); + } } -static void ynorsim_ready(void) +static void ynorsim_ready(struct nor_sim *sim) { - if(initialised) - return; - srand(random_seed); - remaining_ops = 1000000000; - remaining_ops = (rand() % 10000) * ops_multiplier * YNORSIM_BIT_CHANGES; - ynorsim_restore_image(); + if (sim->initialised) + return; + srand(random_seed); + sim->remaining_ops = 1000000000; + sim->remaining_ops = + (rand() % 10000) * ops_multiplier * YNORSIM_BIT_CHANGES; + ynorsim_restore_image(sim); + sim->initialised = 1; } -void ynorsim_rd32(u32 *addr,u32 *buf, int nwords) -{ - while(nwords > 0){ - *buf = *addr; - buf++; - addr++; - nwords--; - } +/* Public functions. */ + +void ynorsim_rd32(struct nor_sim *sim, u32 * addr, u32 * buf, int nwords) +{ + sim = sim; + while (nwords > 0) { + *buf = *addr; + buf++; + addr++; + nwords--; + } } -void ynorsim_wr_one_word32(u32 *addr,u32 val) +void ynorsim_wr_one_word32(struct nor_sim *sim, u32 * addr, u32 val) { - u32 tmp; - u32 m; - int i; - - tmp = *addr; - if(val & ~tmp){ - // Fail due to trying to change a zero into a 1 - printf("attempt to set a zero to one (%x)->(%x)\n",tmp,val); - NorError(); - } - - for(i = 0; i < YNORSIM_BIT_CHANGES; i++){ - m = 1 << (rand() & 31); - if(!(m & val)){ - tmp &= ~m; - *addr = tmp; - ynorsim_maybe_power_fail(); - } - - } - - *addr = tmp & val; - ynorsim_maybe_power_fail(); + u32 tmp; + u32 m; + int i; + + tmp = *addr; + if (val & ~tmp) { + /* Fail due to trying to change a zero into a 1 */ + printf("attempt to set a zero to one (%x)->(%x)\n", tmp, val); + NorError(sim); + } + + for (i = 0; i < YNORSIM_BIT_CHANGES; i++) { + m = 1 << (rand() & 31); + if (!(m & val)) { + tmp &= ~m; + *addr = tmp; + ynorsim_maybe_power_fail(sim); + } + + } + + *addr = tmp & val; + ynorsim_maybe_power_fail(sim); } -void ynorsim_wr32(u32 *addr, u32 *buf, int nwords) +void ynorsim_wr32(struct nor_sim *sim, u32 * addr, u32 * buf, int nwords) { - while(nwords >0){ - ynorsim_wr_one_word32(addr,*buf); - addr++; - buf++; - nwords--; - } + while (nwords > 0) { + ynorsim_wr_one_word32(sim, addr, *buf); + addr++; + buf++; + nwords--; + } } -void ynorsim_erase(u32 *addr) +void ynorsim_erase(struct nor_sim *sim, u32 * addr) { - /* Todo... bit flipping */ - memset(addr,0xFF,YNORSIM_BLOCK_SIZE_U32 * 4); + /* Todo... bit flipping */ + memset(addr, 0xFF, sim->block_size_bytes); } -void ynorsim_initialise(void) +struct nor_sim *ynorsim_initialise(char *name, int n_blocks, + int block_size_bytes) { - ynorsim_ready(); + struct nor_sim *sim; + + sim = malloc(sizeof(*sim)); + if (!sim) + return NULL; + + memset(sim, 0, sizeof(*sim)); + sim->n_blocks = n_blocks; + sim->block_size_bytes = block_size_bytes; + sim->file_size = n_blocks * block_size_bytes; + sim->word = malloc(sim->file_size); + sim->fname = strdup(name); + + if(!sim->word) + return NULL; + + ynorsim_ready(sim); + return sim; } -void ynorsim_shutdown(void) +void ynorsim_shutdown(struct nor_sim *sim) { - ynorsim_save_image(); - initialised=0; + ynorsim_save_image(sim); + sim->initialised = 0; } -u32 *ynorsim_get_base(void) +u32 *ynorsim_get_base(struct nor_sim *sim) { - return word; + return sim->word; }