Mercurial > yaffs-ecoscentric-gpl
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 } |
