2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
4 * Copyright (C) 2002-2011 Aleph One Ltd.
5 * for Toby Churchill Ltd and Brightstar Engineering
7 * Created by Charles Manning <charles@aleph1.co.uk>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
22 #include "pios_trace.h"
24 #define YNORSIM_FNAME "emfile-nor"
26 /* Set YNORSIM_BIT_CHANGES to a a value from 1..30 to
27 * simulate bit flipping as the programming happens.
28 * A low value results in faster simulation with less chance of encountering a partially programmed
32 // #define YNORSIM_BIT_CHANGES 15
33 #define YNORSIM_BIT_CHANGES 2
36 /* Simulate 32MB of flash in 256k byte blocks.
40 #define YNORSIM_BLOCK_SIZE_U32 (256 * 1024 / 4)
41 #define YNORSIM_DEV_SIZE_U32 (32 * 1024 * 1024 / 4)
43 /* Simulate 8MB of flash in 256k byte blocks.
47 #define YNORSIM_BLOCK_SIZE_U32 (256 * 1024 / 4)
48 #define YNORSIM_DEV_SIZE_U32 (8 * 1024 * 1024 / 4)
62 int ops_multiplier
= 500;
63 extern int random_seed
;
64 extern int simulate_power_failure
;
66 static void NorError(struct nor_sim
*sim
)
68 printf("Nor error on device %s\n", sim
->fname
);
72 static void ynorsim_save_image(struct nor_sim
*sim
)
76 pios_trace(PIOS_TRACE_TEST
, "ynorsim_save_image");
77 h
= open(sim
->fname
, O_RDWR
| O_CREAT
| O_TRUNC
, S_IREAD
| S_IWRITE
);
78 write(h
, sim
->word
, sim
->file_size
);
82 static void ynorsim_restore_image(struct nor_sim
*sim
)
86 pios_trace(PIOS_TRACE_TEST
, "ynorsim_restore_image");
87 h
= open(sim
->fname
, O_RDONLY
, S_IREAD
| S_IWRITE
);
88 memset(sim
->word
, 0xFF, sim
->file_size
);
89 read(h
, sim
->word
, sim
->file_size
);
93 static void ynorsim_power_fail(struct nor_sim
*sim
)
95 ynorsim_save_image(sim
);
99 static void ynorsim_maybe_power_fail(struct nor_sim
*sim
)
102 sim
->remaining_ops
--;
103 if (simulate_power_failure
&& sim
->remaining_ops
< 1) {
104 printf("Simulated power failure after %d operations\n",
106 ynorsim_power_fail(sim
);
110 static void ynorsim_ready(struct nor_sim
*sim
)
112 if (sim
->initialised
) {
116 sim
->remaining_ops
= 1000000000;
118 (rand() % 10000) * ops_multiplier
* YNORSIM_BIT_CHANGES
;
119 ynorsim_restore_image(sim
);
120 sim
->initialised
= 1;
123 /* Public functions. */
125 void ynorsim_rd32(struct nor_sim
*sim
, u32
*addr
, u32
*buf
, int nwords
)
136 void ynorsim_wr_one_word32(struct nor_sim
*sim
, u32
*addr
, u32 val
)
144 /* Fail due to trying to change a zero into a 1 */
145 printf("attempt to set a zero to one (%x)->(%x)\n", tmp
, val
);
149 for (i
= 0; i
< YNORSIM_BIT_CHANGES
; i
++) {
150 m
= 1 << (rand() & 31);
154 ynorsim_maybe_power_fail(sim
);
159 ynorsim_maybe_power_fail(sim
);
162 void ynorsim_wr32(struct nor_sim
*sim
, u32
*addr
, u32
*buf
, int nwords
)
165 ynorsim_wr_one_word32(sim
, addr
, *buf
);
172 void ynorsim_erase(struct nor_sim
*sim
, u32
*addr
)
174 /* Todo... bit flipping */
175 pios_trace(PIOS_TRACE_TEST
, "ynorsim_erase");
176 memset(addr
, 0xFF, sim
->block_size_bytes
);
179 struct nor_sim
*ynorsim_initialise(char *name
, int n_blocks
,
180 int block_size_bytes
)
184 sim
= malloc(sizeof(*sim
));
189 memset(sim
, 0, sizeof(*sim
));
190 sim
->n_blocks
= n_blocks
;
191 sim
->block_size_bytes
= block_size_bytes
;
192 sim
->file_size
= n_blocks
* block_size_bytes
;
193 sim
->word
= malloc(sim
->file_size
);
194 sim
->fname
= strdup(name
);
204 void ynorsim_shutdown(struct nor_sim
*sim
)
206 ynorsim_save_image(sim
);
207 sim
->initialised
= 0;
210 u32
*ynorsim_get_base(struct nor_sim
*sim
)