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