2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
4 * Copyright (C) 2002-2018 Aleph One Ltd.
6 * Created by Charles Manning <charles@aleph1.co.uk>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
21 #define YNORSIM_FNAME "emfile-nor"
23 /* Set YNORSIM_BIT_CHANGES to a a value from 1..30 to
24 *simulate bit flipping as the programming happens.
25 * A low value results in faster simulation with less chance of encountering a partially programmed
29 //#define YNORSIM_BIT_CHANGES 15
30 #define YNORSIM_BIT_CHANGES 2
33 /* Simulate 32MB of flash in 256k byte blocks.
37 #define YNORSIM_BLOCK_SIZE_U32 (256*1024/4)
38 #define YNORSIM_DEV_SIZE_U32 (32*1024 * 1024/4)
40 /* Simulate 8MB of flash in 256k byte blocks.
44 #define YNORSIM_BLOCK_SIZE_U32 (256*1024/4)
45 #define YNORSIM_DEV_SIZE_U32 (8*1024 * 1024/4)
59 int ops_multiplier = 500;
60 extern int random_seed;
61 extern int simulate_power_failure;
63 static void NorError(struct nor_sim *sim)
65 printf("Nor error on device %s\n", sim->fname);
70 static void ynorsim_save_image(struct nor_sim *sim)
74 h = open(sim->fname, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
75 write(h, sim->word, sim->file_size);
79 static void ynorsim_restore_image(struct nor_sim *sim)
83 h = open(sim->fname, O_RDONLY, S_IREAD | S_IWRITE);
84 memset(sim->word, 0xFF, sim->file_size);
85 read(h, sim->word, sim->file_size);
89 static void ynorsim_power_fail(struct nor_sim *sim)
91 ynorsim_save_image(sim);
95 static void ynorsim_maybe_power_fail(struct nor_sim *sim)
99 if (simulate_power_failure && sim->remaining_ops < 1) {
100 printf("Simulated power failure after %d operations\n",
102 ynorsim_power_fail(sim);
106 static void ynorsim_ready(struct nor_sim *sim)
108 if (sim->initialised)
111 sim->remaining_ops = 1000000000;
113 (rand() % 10000) * ops_multiplier * YNORSIM_BIT_CHANGES;
114 ynorsim_restore_image(sim);
115 sim->initialised = 1;
118 /* Public functions. */
120 void ynorsim_rd32(struct nor_sim *sim, u32 * addr, u32 * buf, int nwords)
131 void ynorsim_wr_one_word32(struct nor_sim *sim, u32 * addr, u32 val)
139 /* Fail due to trying to change a zero into a 1 */
140 printf("attempt to set a zero to one (%x)->(%x)\n", tmp, val);
144 for (i = 0; i < YNORSIM_BIT_CHANGES; i++) {
145 m = 1 << (rand() & 31);
149 ynorsim_maybe_power_fail(sim);
155 ynorsim_maybe_power_fail(sim);
158 void ynorsim_wr32(struct nor_sim *sim, u32 * addr, u32 * buf, int nwords)
161 ynorsim_wr_one_word32(sim, addr, *buf);
168 void ynorsim_erase(struct nor_sim *sim, u32 * addr)
170 /* Todo... bit flipping */
171 memset(addr, 0xFF, sim->block_size_bytes);
174 struct nor_sim *ynorsim_initialise(char *name, int n_blocks,
175 int block_size_bytes)
179 sim = malloc(sizeof(*sim));
183 memset(sim, 0, sizeof(*sim));
184 sim->n_blocks = n_blocks;
185 sim->block_size_bytes = block_size_bytes;
186 sim->file_size = n_blocks * block_size_bytes;
187 sim->word = malloc(sim->file_size);
188 sim->fname = strdup(name);
197 void ynorsim_shutdown(struct nor_sim *sim)
199 ynorsim_save_image(sim);
200 sim->initialised = 0;
203 u32 *ynorsim_get_base(struct nor_sim *sim)