1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** LevelX Component */
17 /** */
18 /** NOR Flash Simulator */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23
24 /* Include necessary files. */
25
26 #include "lx_api.h"
27
28 /* Define constants for the NOR flash simulation. */
29
30 /* This configuration is for one physical sector of overhead. */
31
32
33 #define TOTAL_BLOCKS 8
34 #define PHYSICAL_SECTORS_PER_BLOCK 16 /* Min value of 2, max value of 120 for 1 sector of overhead. */
35 #define WORDS_PER_PHYSICAL_SECTOR 128
36 #define FREE_BIT_MAP_WORDS ((PHYSICAL_SECTORS_PER_BLOCK-1)/32)+1
37 #define USABLE_SECTORS_PER_BLOCK (PHYSICAL_SECTORS_PER_BLOCK-1)
38 #define UNUSED_METADATA_WORDS_PER_BLOCK (WORDS_PER_PHYSICAL_SECTOR-(3+FREE_BIT_MAP_WORDS+USABLE_SECTORS_PER_BLOCK))
39
40
41 typedef struct PHYSICAL_SECTOR_STRUCT
42 {
43 unsigned long memory[WORDS_PER_PHYSICAL_SECTOR];
44 } PHYSICAL_SECTOR;
45
46
47 typedef struct FLASH_BLOCK_STRUCT
48 {
49 unsigned long erase_count;
50 unsigned long min_log_sector;
51 unsigned long max_log_sector;
52 unsigned long free_bit_map[FREE_BIT_MAP_WORDS];
53 unsigned long sector_metadata[USABLE_SECTORS_PER_BLOCK];
54 unsigned long unused_words[UNUSED_METADATA_WORDS_PER_BLOCK];
55 PHYSICAL_SECTOR physical_sectors[USABLE_SECTORS_PER_BLOCK];
56 } FLASH_BLOCK;
57
58 FLASH_BLOCK nor_memory_area[TOTAL_BLOCKS];
59
60 ULONG nor_sector_memory[WORDS_PER_PHYSICAL_SECTOR];
61
62 UINT _lx_nor_flash_simulator_initialize(LX_NOR_FLASH *nor_flash);
63 UINT _lx_nor_flash_simulator_erase_all(VOID);
64 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
65 UINT _lx_nor_flash_simulator_read(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words);
66 UINT _lx_nor_flash_simulator_write(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *source, ULONG words);
67 UINT _lx_nor_flash_simulator_block_erase(LX_NOR_FLASH *nor_flash, ULONG block, ULONG erase_count);
68 UINT _lx_nor_flash_simulator_block_erased_verify(LX_NOR_FLASH *nor_flash, ULONG block);
69 UINT _lx_nor_flash_simulator_system_error(LX_NOR_FLASH *nor_flash, UINT error_code, ULONG block, ULONG sector);
70 #else
71 UINT _lx_nor_flash_simulator_read(ULONG *flash_address, ULONG *destination, ULONG words);
72 UINT _lx_nor_flash_simulator_write(ULONG *flash_address, ULONG *source, ULONG words);
73 UINT _lx_nor_flash_simulator_block_erase(ULONG block, ULONG erase_count);
74 UINT _lx_nor_flash_simulator_block_erased_verify(ULONG block);
75 UINT _lx_nor_flash_simulator_system_error(UINT error_code, ULONG block, ULONG sector);
76 #endif
77
78
_lx_nor_flash_simulator_initialize(LX_NOR_FLASH * nor_flash)79 UINT _lx_nor_flash_simulator_initialize(LX_NOR_FLASH *nor_flash)
80 {
81
82 /* Setup the base address of the flash memory. */
83 nor_flash -> lx_nor_flash_base_address = (ULONG *) &nor_memory_area[0];
84
85 /* Setup geometry of the flash. */
86 nor_flash -> lx_nor_flash_total_blocks = TOTAL_BLOCKS;
87 nor_flash -> lx_nor_flash_words_per_block = sizeof(FLASH_BLOCK)/sizeof(ULONG);
88
89 /* Setup function pointers for the NOR flash services. */
90 nor_flash -> lx_nor_flash_driver_read = _lx_nor_flash_simulator_read;
91 nor_flash -> lx_nor_flash_driver_write = _lx_nor_flash_simulator_write;
92 nor_flash -> lx_nor_flash_driver_block_erase = _lx_nor_flash_simulator_block_erase;
93 nor_flash -> lx_nor_flash_driver_block_erased_verify = _lx_nor_flash_simulator_block_erased_verify;
94
95 /* Setup local buffer for NOR flash operation. This buffer must be the sector size of the NOR flash memory. */
96 nor_flash -> lx_nor_flash_sector_buffer = &nor_sector_memory[0];
97
98 /* Return success. */
99 return(LX_SUCCESS);
100 }
101
102 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
_lx_nor_flash_simulator_read(LX_NOR_FLASH * nor_flash,ULONG * flash_address,ULONG * destination,ULONG words)103 UINT _lx_nor_flash_simulator_read(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words)
104 #else
105 UINT _lx_nor_flash_simulator_read(ULONG *flash_address, ULONG *destination, ULONG words)
106 #endif
107 {
108
109 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
110 LX_PARAMETER_NOT_USED(nor_flash);
111 #endif
112
113 /* Loop to read flash. */
114 while (words--)
115 {
116 /* Copy word. */
117 *destination++ = *flash_address++;
118 }
119
120 return(LX_SUCCESS);
121 }
122
123
124 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
_lx_nor_flash_simulator_write(LX_NOR_FLASH * nor_flash,ULONG * flash_address,ULONG * source,ULONG words)125 UINT _lx_nor_flash_simulator_write(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *source, ULONG words)
126 #else
127 UINT _lx_nor_flash_simulator_write(ULONG *flash_address, ULONG *source, ULONG words)
128 #endif
129 {
130
131 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
132 LX_PARAMETER_NOT_USED(nor_flash);
133 #endif
134
135 /* Loop to write flash. */
136 while (words--)
137 {
138
139 /* Copy word. */
140 *flash_address++ = *source++;
141 }
142
143 return(LX_SUCCESS);
144 }
145
146 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
_lx_nor_flash_simulator_block_erase(LX_NOR_FLASH * nor_flash,ULONG block,ULONG erase_count)147 UINT _lx_nor_flash_simulator_block_erase(LX_NOR_FLASH *nor_flash, ULONG block, ULONG erase_count)
148 #else
149 UINT _lx_nor_flash_simulator_block_erase(ULONG block, ULONG erase_count)
150 #endif
151 {
152
153 ULONG *pointer;
154 ULONG words;
155
156 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
157 LX_PARAMETER_NOT_USED(nor_flash);
158 #endif
159 LX_PARAMETER_NOT_USED(erase_count);
160
161 /* Setup pointer. */
162 pointer = (ULONG *) &nor_memory_area[block];
163
164 /* Loop to erase block. */
165 words = sizeof(FLASH_BLOCK)/sizeof(ULONG);
166 while (words--)
167 {
168
169 /* Erase word of block. */
170 *pointer++ = (ULONG) 0xFFFFFFFF;
171 }
172
173 return(LX_SUCCESS);
174 }
175
176
_lx_nor_flash_simulator_erase_all(VOID)177 UINT _lx_nor_flash_simulator_erase_all(VOID)
178 {
179
180 ULONG *pointer;
181 ULONG words;
182
183
184 /* Setup pointer. */
185 pointer = (ULONG *) &nor_memory_area[0];
186
187 /* Loop to erase block. */
188 words = sizeof(nor_memory_area)/(sizeof(ULONG));
189 while (words--)
190 {
191
192 /* Erase word of block. */
193 *pointer++ = (ULONG) 0xFFFFFFFF;
194 }
195
196 return(LX_SUCCESS);
197 }
198
199
200 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
_lx_nor_flash_simulator_block_erased_verify(LX_NOR_FLASH * nor_flash,ULONG block)201 UINT _lx_nor_flash_simulator_block_erased_verify(LX_NOR_FLASH *nor_flash, ULONG block)
202 #else
203 UINT _lx_nor_flash_simulator_block_erased_verify(ULONG block)
204 #endif
205 {
206
207 ULONG *word_ptr;
208 ULONG words;
209
210 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
211 LX_PARAMETER_NOT_USED(nor_flash);
212 #endif
213
214 /* Determine if the block is completely erased. */
215
216 /* Pickup the pointer to the first word of the block. */
217 word_ptr = (ULONG *) &nor_memory_area[block].erase_count;
218
219 /* Calculate the number of words in a block. */
220 words = sizeof(FLASH_BLOCK)/sizeof(ULONG);
221
222 /* Loop to check if the block is erased. */
223 while (words--)
224 {
225
226 /* Is this word erased? */
227 if (*word_ptr++ != 0xFFFFFFFF)
228 return(LX_ERROR);
229 }
230
231 /* Return success. */
232 return(LX_SUCCESS);
233 }
234
235 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
_lx_nor_flash_simulator_system_error(LX_NOR_FLASH * nor_flash,UINT error_code,ULONG block,ULONG sector)236 UINT _lx_nor_flash_simulator_system_error(LX_NOR_FLASH *nor_flash, UINT error_code, ULONG block, ULONG sector)
237 #else
238 UINT _lx_nor_flash_simulator_system_error(UINT error_code, ULONG block, ULONG sector)
239 #endif
240 {
241
242 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
243 LX_PARAMETER_NOT_USED(nor_flash);
244 #endif
245 LX_PARAMETER_NOT_USED(error_code);
246 LX_PARAMETER_NOT_USED(block);
247 LX_PARAMETER_NOT_USED(sector);
248
249 /* Custom processing goes here... all errors are fatal. */
250 return(LX_ERROR);
251 }
252
253