comparison packages/fs/yaffs/current/src/direct/ynorsim.c @ 425:dea4d7d250ad ecos

Move sources into packages/fs/yaffs/current/src/
author Ross Younger <wry@ecoscentric.com>
date Fri, 14 May 2010 16:03:09 +0100
parents direct/ynorsim.c@866b8778acc1
children
comparison
equal deleted inserted replaced
424:d21d6fd33e63 425:dea4d7d250ad
1
2
3 #include "ynorsim.h"
4
5
6
7 #include <stdio.h>
8 #include <fcntl.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11 #include <time.h>
12
13 #define YNORSIM_FNAME "emfile-nor"
14
15 /* Set YNORSIM_BIT_CHANGES to a a value from 1..30 to
16 *simulate bit flipping as the programming happens.
17 * A low value results in faster simulation with less chance of encountering a partially programmed
18 * word.
19 */
20
21 //#define YNORSIM_BIT_CHANGES 15
22 #define YNORSIM_BIT_CHANGES 2
23
24 #if 0
25 /* Simulate 32MB of flash in 256k byte blocks.
26 * This stuff is x32.
27 */
28
29 #define YNORSIM_BLOCK_SIZE_U32 (256*1024/4)
30 #define YNORSIM_DEV_SIZE_U32 (32*1024 * 1024/4)
31 #else
32 /* Simulate 8MB of flash in 256k byte blocks.
33 * This stuff is x32.
34 */
35
36 #define YNORSIM_BLOCK_SIZE_U32 (256*1024/4)
37 #define YNORSIM_DEV_SIZE_U32 (8*1024 * 1024/4)
38 #endif
39
40 static __u32 word[YNORSIM_DEV_SIZE_U32];
41
42 extern int random_seed;
43 extern int simulate_power_failure;
44
45 static void NorError(void)
46 {
47 printf("Nor error\n");
48 while(1){}
49 }
50
51 static void ynorsim_SaveImage(void)
52 {
53 int h = open(YNORSIM_FNAME, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
54 write(h,word,sizeof(word));
55 close(h);
56 }
57
58 static void ynorsim_RestoreImage(void)
59 {
60 int h = open(YNORSIM_FNAME, O_RDONLY, S_IREAD | S_IWRITE);
61 memset(word,0xFF,sizeof(word));
62 read(h,word,sizeof(word));
63 close(h);
64 }
65
66
67 static void ynorsim_PowerFail(void)
68 {
69 ynorsim_SaveImage();
70 exit(1);
71 }
72
73 static int initialised = 0;
74 static int remaining_ops;
75 static int nops_so_far;
76
77 int ops_multiplier = 500;
78
79 static void ynorsim_MaybePowerFail(void)
80 {
81
82 nops_so_far++;
83
84
85 remaining_ops--;
86 if(simulate_power_failure &&
87 remaining_ops < 1){
88 printf("Simulated power failure after %d operations\n",nops_so_far);
89 ynorsim_PowerFail();
90 }
91 }
92
93 static void ynorsim_Ready(void)
94 {
95 if(initialised)
96 return;
97 srand(random_seed);
98 remaining_ops = 1000000000;
99 remaining_ops = (rand() % 10000) * ops_multiplier * YNORSIM_BIT_CHANGES;
100 ynorsim_RestoreImage();
101 }
102
103 void ynorsim_Read32(__u32 *addr,__u32 *buf, int nwords)
104 {
105 while(nwords > 0){
106 *buf = *addr;
107 buf++;
108 addr++;
109 nwords--;
110 }
111 }
112
113 void ynorsim_WriteOneWord32(__u32 *addr,__u32 val)
114 {
115 __u32 tmp;
116 __u32 m;
117 int i;
118
119 tmp = *addr;
120 if(val & ~tmp){
121 // Fail due to trying to change a zero into a 1
122 printf("attempt to set a zero to one (%x)->(%x)\n",tmp,val);
123 NorError();
124 }
125
126 for(i = 0; i < YNORSIM_BIT_CHANGES; i++){
127 m = 1 << (rand() & 31);
128 if(!(m & val)){
129 tmp &= ~m;
130 *addr = tmp;
131 ynorsim_MaybePowerFail();
132 }
133
134 }
135
136 *addr = tmp & val;
137 ynorsim_MaybePowerFail();
138 }
139
140 void ynorsim_Write32(__u32 *addr, __u32 *buf, int nwords)
141 {
142 while(nwords >0){
143 ynorsim_WriteOneWord32(addr,*buf);
144 addr++;
145 buf++;
146 nwords--;
147 }
148 }
149
150 void ynorsim_EraseBlock(__u32 *addr)
151 {
152 /* Todo... bit flipping */
153 memset(addr,0xFF,YNORSIM_BLOCK_SIZE_U32 * 4);
154 }
155
156 void ynorsim_Initialise(void)
157 {
158 ynorsim_Ready();
159 }
160
161 void ynorsim_Shutdown(void)
162 {
163 ynorsim_SaveImage();
164 initialised=0;
165 }
166
167 __u32 *ynorsim_GetBase(void)
168 {
169 return word;
170 }