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 /**   Application Interface (API)                                         */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 
24 /**************************************************************************/
25 /*                                                                        */
26 /*  APPLICATION INTERFACE DEFINITION                       RELEASE        */
27 /*                                                                        */
28 /*    lx_api.h                                            PORTABLE C      */
29 /*                                                           6.2.1       */
30 /*  AUTHOR                                                                */
31 /*                                                                        */
32 /*    William E. Lamie, Microsoft Corporation                             */
33 /*                                                                        */
34 /*  DESCRIPTION                                                           */
35 /*                                                                        */
36 /*    This file defines the basic Application Interface (API) to the      */
37 /*    high-performance LevelX. All service prototypes and data structure  */
38 /*    definitions are defined in this file.                               */
39 /*                                                                        */
40 /*  RELEASE HISTORY                                                       */
41 /*                                                                        */
42 /*    DATE              NAME                      DESCRIPTION             */
43 /*                                                                        */
44 /*  05-19-2020     William E. Lamie         Initial Version 6.0           */
45 /*  09-30-2020     William E. Lamie         Modified comment(s), and      */
46 /*                                            updated product constants,  */
47 /*                                            resulting in version 6.1    */
48 /*  11-09-2020     William E. Lamie         Modified comment(s), and      */
49 /*                                            added support for lx_user.h */
50 /*                                            so user can specify values, */
51 /*                                            resulting in version 6.1.2  */
52 /*  12-31-2020     William E. Lamie         Modified comment(s), and      */
53 /*                                            updated product constants,  */
54 /*                                            resulting in version 6.1.3  */
55 /*  06-02-2021     Bhupendra Naphade        Modified comment(s),          */
56 /*                                            added standalone support,   */
57 /*                                            resulting in version 6.1.7  */
58 /*  08-02-2021     William E. Lamie         Modified comment(s), and      */
59 /*                                            updated product constants,  */
60 /*                                            resulting in version 6.1.8  */
61 /*  10-15-2021     Bhupendra Naphade        Modified comment(s),          */
62 /*                                            updated configuration for   */
63 /*                                            nand flash                  */
64 /*                                            resulting in version 6.1.9  */
65 /*  01-31-2022     Bhupendra Naphade        Modified comment(s),          */
66 /*                                            updated include order for   */
67 /*                                            standalone mode,            */
68 /*                                            resulting in version 6.1.10 */
69 /*  04-25-2022     William E. Lamie         Modified comment(s), and      */
70 /*                                            updated product constants,  */
71 /*                                            resulting in version 6.1.11 */
72 /*  07-29-2022     William E. Lamie         Modified comment(s), and      */
73 /*                                            updated product constants,  */
74 /*                                            resulting in version 6.1.12 */
75 /*  10-31-2022     Xiuwen Cai               Modified comment(s), and      */
76 /*                                            updated product constants,  */
77 /*                                            resulting in version 6.2.0  */
78 /*  03-08-2023     Xiuwen Cai               Modified comment(s),          */
79 /*                                            modified NAND logic,        */
80 /*                                            added new driver interface  */
81 /*                                            and user extension,         */
82 /*                                            resulting in version 6.2.1 */
83 /*                                                                        */
84 /**************************************************************************/
85 
86 #ifndef LX_API_H
87 #define LX_API_H
88 
89 
90 /* Determine if a C++ compiler is being used.  If so, ensure that standard
91    C is used to process the API information.  */
92 
93 #ifdef __cplusplus
94 
95 /* Yes, C++ compiler is present.  Use standard C.  */
96 extern   "C" {
97 
98 #endif
99 
100 /* Determine if the optional LevelX user define file should be used.  */
101 
102 #ifdef LX_INCLUDE_USER_DEFINE_FILE
103 
104 
105 /* Yes, include the user defines in lx_user.h. The defines in this file may
106    alternately be defined on the command line.  */
107 
108 #include "lx_user.h"
109 #endif
110 
111 /* Include the ThreadX api file.  */
112 
113 #ifndef LX_STANDALONE_ENABLE
114 #include "tx_api.h"
115 #endif
116 
117 
118 #ifdef LX_STANDALONE_ENABLE
119 
120 /* Define compiler library include files.  */
121 
122 #include <stdint.h>
123 #include <stdlib.h>
124 #include <string.h>
125 
126 #ifndef VOID
127 #define VOID                                    void
128 typedef char                                    CHAR;
129 typedef char                                    BOOL;
130 typedef unsigned char                           UCHAR;
131 typedef int                                     INT;
132 typedef unsigned int                            UINT;
133 typedef long                                    LONG;
134 typedef unsigned long                           ULONG;
135 typedef short                                   SHORT;
136 typedef unsigned short                          USHORT;
137 #endif
138 
139 #ifndef ULONG64_DEFINED
140 #define ULONG64_DEFINED
141 typedef unsigned long long                      ULONG64;
142 #endif
143 
144 /* Define basic alignment type used in block and byte pool operations. This data type must
145    be at least 32-bits in size and also be large enough to hold a pointer type.  */
146 
147 #ifndef ALIGN_TYPE_DEFINED
148 #define ALIGN_TYPE_DEFINED
149 #define ALIGN_TYPE                              ULONG
150 #endif
151 
152 /* Define the LX_MEMSET macro to the standard library function, if not already defined.  */
153 #ifndef LX_MEMSET
154 #define LX_MEMSET(a,b,c)                        memset((a),(b),(c))
155 #endif
156 
157 #ifndef LX_MEMCPY
158 #define LX_MEMCPY(a,b,c)                        memcpy((a),(b),(c))
159 #endif
160 
161 /* Disable usage of ThreadX mutex in standalone mode */
162 #ifdef LX_THREAD_SAFE_ENABLE
163 #undef LX_THREAD_SAFE_ENABLE
164 #endif
165 
166 #define LX_INTERRUPT_SAVE_AREA
167 #define LX_DISABLE
168 #define LX_RESTORE
169 
170 #else
171 
172 #define LX_MEMSET                               TX_MEMSET
173 #ifndef LX_MEMCPY
174 #include <string.h>
175 #define LX_MEMCPY(a,b,c)                        memcpy((a),(b),(c))
176 #endif
177 
178 #define LX_INTERRUPT_SAVE_AREA                  TX_INTERRUPT_SAVE_AREA
179 #define LX_DISABLE                              TX_DISABLE
180 #define LX_RESTORE                              TX_RESTORE
181 
182 #endif
183 
184 
185 /* Disable warning of parameter not used. */
186 #ifndef LX_PARAMETER_NOT_USED
187 #define LX_PARAMETER_NOT_USED(p) ((void)(p))
188 #endif /* LX_PARAMETER_NOT_USED */
189 
190 
191 /* Define basic constants for the LevelX Stack.  */
192 #define AZURE_RTOS_LEVELX
193 #define LEVELX_MAJOR_VERSION                        6
194 #define LEVELX_MINOR_VERSION                        2
195 #define LEVELX_PATCH_VERSION                        1
196 
197 
198 /* Define general LevelX Constants.  */
199 
200 #define LX_FALSE                                    0
201 #define LX_TRUE                                     1
202 #define LX_NULL                                     0
203 #define LX_BLOCK_ERASE_COUNT_MASK                   0x7FFFFFFF
204 #define LX_BLOCK_ERASE_COUNT_MAX                    0x7FFFFFFF
205 #define LX_BLOCK_ERASED                             0x80000000
206 #define LX_BLOCK_ERASE_STARTED                      0
207 #define LX_ALL_ONES                                 0xFFFFFFFF
208 
209 
210 /* Define error codes.  */
211 
212 #define LX_SUCCESS                                  0
213 #define LX_ERROR                                    1
214 #define LX_NO_SECTORS                               2
215 #define LX_SECTOR_NOT_FOUND                         3
216 #define LX_NO_PAGES                                 4
217 #define LX_INVALID_WRITE                            5
218 #define LX_NAND_ERROR_CORRECTED                     6
219 #define LX_NAND_ERROR_NOT_CORRECTED                 7
220 #define LX_NO_MEMORY                                8
221 #define LX_DISABLED                                 9
222 #define LX_BAD_BLOCK                                10
223 #define LX_NO_BLOCKS                                11
224 #define LX_NOT_SUPPORTED                            12
225 #define LX_SYSTEM_INVALID_FORMAT                    90
226 #define LX_SYSTEM_INVALID_BLOCK                     91
227 #define LX_SYSTEM_ALLOCATION_FAILED                 92
228 #define LX_SYSTEM_MUTEX_CREATE_FAILED               93
229 #define LX_SYSTEM_INVALID_SECTOR_MAP                94
230 
231 
232 /* Define NOR flash constants.  */
233 
234 #define LX_NOR_FLASH_OPENED                         ((ULONG) 0x4E4F524F)
235 #define LX_NOR_FLASH_CLOSED                         ((ULONG) 0x4E4F5244)
236 #define LX_NOR_SECTOR_SIZE                          (512/sizeof(ULONG))
237 #define LX_NOR_FLASH_MIN_LOGICAL_SECTOR_OFFSET      1
238 #define LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET      2
239 #ifndef LX_NOR_FLASH_MAX_ERASE_COUNT_DELTA
240 #define LX_NOR_FLASH_MAX_ERASE_COUNT_DELTA          4
241 #endif
242 #define LX_NOR_SECTOR_MAPPING_CACHE_DEPTH           4
243 #ifndef LX_NOR_SECTOR_MAPPING_CACHE_SIZE
244 #define LX_NOR_SECTOR_MAPPING_CACHE_SIZE            16          /* Minimum value of 8, all sizes must be a power of 2.  */
245 #endif
246 #ifndef LX_NOR_EXTENDED_CACHE_SIZE
247 #define LX_NOR_EXTENDED_CACHE_SIZE                  8           /* Maximum number of extended cache sectors.            */
248 #endif
249 
250 
251 /* Define the mask for the hash index into the sector mapping cache table.  The sector mapping cache is divided
252    into 4 entry pieces that are indexed by the formula:
253 
254             index =  (sector & LX_NOR_SECTOR_MAPPING_CACHE_HASH_MASK) * LX_NOR_SECTOR_MAPPING_CACHE_DEPTH
255 
256    The LX_NOR_SECTOR_MAPPING_CACHE_DEPTH define must not be changed unless the related source code is also changed.  */
257 
258 #define LX_NOR_SECTOR_MAPPING_CACHE_HASH_MASK       ((LX_NOR_SECTOR_MAPPING_CACHE_SIZE/LX_NOR_SECTOR_MAPPING_CACHE_DEPTH)-1)
259 #define LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_MASK      0x7FFFFFFF
260 #define LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID     0x80000000
261 
262 #define LX_NOR_PHYSICAL_SECTOR_VALID                0x80000000
263 #define LX_NOR_PHYSICAL_SECTOR_SUPERCEDED           0x40000000
264 #define LX_NOR_PHYSICAL_SECTOR_MAPPING_NOT_VALID    0x20000000
265 #define LX_NOR_LOGICAL_SECTOR_MASK                  0x1FFFFFFF
266 #define LX_NOR_PHYSICAL_SECTOR_FREE                 0xFFFFFFFF
267 
268 
269 /* Define NAND flash constants.  */
270 
271 #define LX_NAND_GOOD_BLOCK                          0xFF
272 #define LX_NAND_BAD_BLOCK                           0x00
273 #define LX_NAND_FLASH_OPENED                        ((ULONG) 0x4E4F524F)
274 #define LX_NAND_FLASH_CLOSED                        ((ULONG) 0x4E4F5244)
275 #ifndef LX_NAND_FLASH_MAX_ERASE_COUNT_DELTA
276 #define LX_NAND_FLASH_MAX_ERASE_COUNT_DELTA         64
277 #endif
278 
279 /* Define the NAND sector mapping cache.  */
280 
281 #define LX_NAND_SECTOR_MAPPING_CACHE_DEPTH          4           /* Not required if LX_NAND_FLASH_DIRECT_MAPPING_CACHE is defined.  */
282 #ifndef LX_NAND_SECTOR_MAPPING_CACHE_SIZE
283 #define LX_NAND_SECTOR_MAPPING_CACHE_SIZE           128         /* Minimum value of 8, all sizes must be a power of 2, unless direct
284                                                                    mapping is defined, in which there is no power of 2 requirement.  */
285 #endif
286 #ifndef LX_NAND_ERASE_COUNT_WRITE_SIZE
287 #define LX_NAND_ERASE_COUNT_WRITE_SIZE              (nand_flash -> lx_nand_flash_pages_per_block + 1)
288 #endif
289 
290 #ifndef LX_NAND_FLASH_MAPPING_LIST_UPDATE_DISABLE
291 #define LX_NAND_FLASH_MAPPING_LIST_UPDATE_DISABLE
292 #endif
293 
294 #ifndef LX_NAND_FLASH_MAX_METADATA_BLOCKS
295 #define LX_NAND_FLASH_MAX_METADATA_BLOCKS           4
296 #endif
297 
298 #ifndef LX_UTILITY_SHORT_SET
299 #define LX_UTILITY_SHORT_SET(address, value)        *((USHORT*)(address)) = (USHORT)(value)
300 #endif
301 
302 #ifndef LX_UTILITY_LONG_SET
303 #define LX_UTILITY_LONG_SET(address, value)         *((ULONG*)(address)) = (ULONG)(value)
304 #endif
305 
306 #ifndef LX_UTILITY_SHORT_GET
307 #define LX_UTILITY_SHORT_GET(address)               (*((USHORT*)(address)))
308 #endif
309 
310 #ifndef LX_UTILITY_LONG_GET
311 #define LX_UTILITY_LONG_GET(address)                (*((ULONG*)(address)))
312 #endif
313 
314 /* Define the mask for the hash index into the NAND sector mapping cache table.  The sector mapping cache is divided
315    into 4 entry pieces that are indexed by the formula:
316 
317             index =  (sector & LX_NAND_SECTOR_MAPPING_CACHE_HASH_MASK) * LX_NAND_SECTOR_MAPPING_CACHE_DEPTH
318 
319    The LX_NAND_SECTOR_MAPPING_CACHE_DEPTH define must not be changed unless the related source code is also changed.  */
320 
321 #define LX_NAND_SECTOR_MAPPING_CACHE_HASH_MASK      ((LX_NAND_SECTOR_MAPPING_CACHE_SIZE/LX_NAND_SECTOR_MAPPING_CACHE_DEPTH)-1)
322 #define LX_NAND_SECTOR_MAPPING_CACHE_ENTRY_MASK     0x7FFFFFFF
323 #define LX_NAND_SECTOR_MAPPING_CACHE_ENTRY_VALID    0x80000000
324 
325 #define LX_NAND_BLOCK_VALID                         0x80000000
326 #define LX_NAND_BLOCK_EMPTY                         0x40000000
327 #define LX_NAND_BLOCK_FULL                          0x20000000
328 #define LX_NAND_PAGE_VALID                          0x80000000
329 #define LX_NAND_PAGE_SUPERCEDED                     0x40000000
330 #define LX_NAND_PAGE_MAPPING_NOT_VALID              0x20000000
331 #define LX_NAND_LOGICAL_SECTOR_MASK                 0x1FFFFFFF
332 #define LX_NAND_PAGE_FREE                           0xFFFFFFFF
333 #define LX_NAND_PAGE_LIST_VALID                     0xF0F0F0F0
334 
335 #define LX_NAND_PAGE_TYPE_DEVICE_INFO               0x10000000u
336 #define LX_NAND_PAGE_TYPE_ERASE_COUNT_TABLE         0x20000000u
337 #define LX_NAND_PAGE_TYPE_BLOCK_MAPPING_TABLE       0x30000000u
338 #define LX_NAND_PAGE_TYPE_USER_DATA                 0x40000000u
339 #define LX_NAND_PAGE_TYPE_USER_DATA_RELEASED        0x50000000u
340 #define LX_NAND_PAGE_TYPE_READ_COUNT_TABLE          0x60000000u
341 #define LX_NAND_PAGE_TYPE_PAGE_MAPPING_TABLE        0x70000000u
342 #define LX_NAND_PAGE_TYPE_BLOCK_STATUS_TABLE        0x80000000u
343 #define LX_NAND_PAGE_TYPE_BLOCK_LINK                0x90000000u
344 #define LX_NAND_PAGE_TYPE_USER_DATA_MASK            0x0FFFFFFFu
345 #define LX_NAND_PAGE_TYPE_PAGE_NUMBER_MASK          0x000000FFu
346 
347 #define LX_NAND_PAGE_TYPE_FREE_PAGE                 0xFFFFFF00u
348 
349 #define LX_NAND_BLOCK_STATUS_FULL                   0x4000u
350 #define LX_NAND_BLOCK_STATUS_NON_SEQUENTIAL         0x2000u
351 #define LX_NAND_BLOCK_STATUS_MAPPING_PRESENT        0x1000u
352 #define LX_NAND_BLOCK_STATUS_PAGE_NUMBER_MASK       0x0FFFu
353 #define LX_NAND_BLOCK_STATUS_FREE                   0xFFFFu
354 #define LX_NAND_BLOCK_STATUS_BAD                    0xFF00u
355 #define LX_NAND_BLOCK_STATUS_ALLOCATED              0x8000u
356 
357 #define LX_NAND_BLOCK_LINK_MAIN_METADATA_OFFSET     0
358 #define LX_NAND_BLOCK_LINK_BACKUP_METADATA_OFFSET   4
359 
360 #define LX_NAND_MAX_BLOCK_COUNT                     32768
361 #define LX_NAND_MAX_PAGE_PER_BLOCK                  4096
362 
363 
364 
365 #define LX_NAND_BLOCK_UNMAPPED                      0xFFFF
366 
367 #define LX_NAND_DEVICE_INFO_SIGNATURE1              0x76654C20
368 #define LX_NAND_DEVICE_INFO_SIGNATURE2              0x20586C65
369 
370 #define LX_NAND_DEVICE_INFO_METADATA_TYPE_MAIN      0x01
371 #define LX_NAND_DEVICE_INFO_METADATA_TYPE_SECONDARY 0x02
372 
373 
374 
375 
376 /* Define the NAND device information structure. This will be set in the spare area.  */
377 
378 typedef struct LX_NAND_DEVICE_INFO_STRUCT
379 {
380     ULONG                           lx_nand_device_info_signature1;
381     ULONG                           lx_nand_device_info_signature2;
382     ULONG                           lx_nand_device_info_major_version;
383     ULONG                           lx_nand_device_info_minor_version;
384     ULONG                           lx_nand_device_info_patch_version;
385     ULONG                           lx_nand_device_info_metadata_block_number;
386     ULONG                           lx_nand_device_info_backup_metadata_block_number;
387     ULONG                           lx_nand_device_info_base_erase_count;
388 } LX_NAND_DEVICE_INFO;
389 
390 
391 /* Determine if the flash control block has an extension defined. If not,
392    define the extension to whitespace.  */
393 
394 #ifndef LX_NAND_FLASH_USER_EXTENSION
395 #define LX_NAND_FLASH_USER_EXTENSION
396 #endif
397 
398 /* Define the NAND flash control block structure.  */
399 
400 typedef struct LX_NAND_FLASH_STRUCT
401 {
402     ULONG                           lx_nand_flash_state;
403     ULONG                           lx_nand_flash_total_blocks;
404     ULONG                           lx_nand_flash_pages_per_block;
405     ULONG                           lx_nand_flash_bytes_per_page;
406     ULONG                           lx_nand_flash_words_per_block;
407     ULONG                           lx_nand_flash_words_per_page;
408     ULONG                           lx_nand_flash_total_pages;
409 
410     ULONG                           lx_nand_flash_bad_blocks;
411     ULONG                           lx_nand_flash_base_erase_count;
412 
413     ULONG                           lx_nand_flash_page_corrections;
414     ULONG                           lx_nand_flash_last_block_correction;
415     ULONG                           lx_nand_flash_last_page_correction;
416 
417     USHORT                         *lx_nand_flash_block_mapping_table;
418     ULONG                           lx_nand_flash_block_mapping_table_size;
419     USHORT                         *lx_nand_flash_block_status_table;
420     ULONG                           lx_nand_flash_block_status_table_size;
421     UCHAR                          *lx_nand_flash_erase_count_table;
422     ULONG                           lx_nand_flash_erase_count_table_size;
423     USHORT                         *lx_nand_flash_block_list;
424     ULONG                           lx_nand_flash_block_list_size;
425     ULONG                           lx_nand_flash_free_block_list_tail;
426     ULONG                           lx_nand_flash_mapped_block_list_head;
427 
428     ULONG                           lx_nand_flash_metadata_block_number;
429     ULONG                           lx_nand_flash_metadata_block_number_current;
430     ULONG                           lx_nand_flash_metadata_block_number_next;
431     ULONG                           lx_nand_flash_metadata_block_current_page;
432     ULONG                           lx_nand_flash_metadata_block_count;
433     USHORT                          lx_nand_flash_metadata_block[LX_NAND_FLASH_MAX_METADATA_BLOCKS];
434 
435     ULONG                           lx_nand_flash_backup_metadata_block_number;
436     ULONG                           lx_nand_flash_backup_metadata_block_number_current;
437     ULONG                           lx_nand_flash_backup_metadata_block_number_next;
438     ULONG                           lx_nand_flash_backup_metadata_block_current_page;
439     USHORT                          lx_nand_flash_backup_metadata_block[LX_NAND_FLASH_MAX_METADATA_BLOCKS];
440 
441     ULONG                           lx_nand_flash_spare_data1_offset;
442     ULONG                           lx_nand_flash_spare_data1_length;
443     ULONG                           lx_nand_flash_spare_data2_offset;
444     ULONG                           lx_nand_flash_spare_data2_length;
445     ULONG                           lx_nand_flash_spare_total_length;
446 
447     ULONG                           lx_nand_flash_diagnostic_system_errors;
448     ULONG                           lx_nand_flash_diagnostic_system_error;
449     ULONG                           lx_nand_flash_diagnostic_sector_write_requests;
450     ULONG                           lx_nand_flash_diagnostic_sector_read_requests;
451     ULONG                           lx_nand_flash_diagnostic_sector_release_requests;
452     ULONG                           lx_nand_flash_diagnostic_page_allocates;
453     ULONG                           lx_nand_flash_diagnostic_page_allocate_errors;
454 
455     ULONG                           lx_nand_flash_diagnostic_block_reclaim_attempts;
456     ULONG                           lx_nand_flash_diagnostic_block_erases;
457     ULONG                           lx_nand_flash_diagnostic_block_status_gets;
458     ULONG                           lx_nand_flash_diagnostic_block_status_sets;
459     ULONG                           lx_nand_flash_diagnostic_page_extra_bytes_sets;
460     ULONG                           lx_nand_flash_diagnostic_page_writes;
461     ULONG                           lx_nand_flash_diagnostic_page_extra_bytes_gets;
462     ULONG                           lx_nand_flash_diagnostic_page_reads;
463     ULONG                           lx_nand_flash_diagnostic_moved_pages;
464     ULONG                           lx_nand_flash_diagnostic_block_erased_verifies;
465     ULONG                           lx_nand_flash_diagnostic_page_erased_verifies;
466 
467 #ifdef LX_NAND_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
468     UINT                            (*lx_nand_flash_driver_read)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG block, ULONG page, ULONG *destination, ULONG words);
469     UINT                            (*lx_nand_flash_driver_write)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG block, ULONG page, ULONG *source, ULONG words);
470     UINT                            (*lx_nand_flash_driver_block_erase)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG block, ULONG erase_count);
471     UINT                            (*lx_nand_flash_driver_block_erased_verify)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG block);
472     UINT                            (*lx_nand_flash_driver_page_erased_verify)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG block, ULONG page);
473     UINT                            (*lx_nand_flash_driver_block_status_get)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG block, UCHAR *bad_block_flag);
474     UINT                            (*lx_nand_flash_driver_block_status_set)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG block, UCHAR bad_block_flag);
475     UINT                            (*lx_nand_flash_driver_extra_bytes_get)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG block, ULONG page, UCHAR *destination, UINT size);
476     UINT                            (*lx_nand_flash_driver_extra_bytes_set)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG block, ULONG page, UCHAR *source, UINT size);
477     UINT                            (*lx_nand_flash_driver_system_error)(struct LX_NAND_FLASH_STRUCT *nand_flash, UINT error_code, ULONG block, ULONG page);
478 
479     UINT                            (*lx_nand_flash_driver_pages_read)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG block, ULONG page, UCHAR* main_buffer, UCHAR* spare_buffer, ULONG pages);
480     UINT                            (*lx_nand_flash_driver_pages_write)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG block, ULONG page, UCHAR* main_buffer, UCHAR* spare_buffer, ULONG pages);
481     UINT                            (*lx_nand_flash_driver_pages_copy)(struct LX_NAND_FLASH_STRUCT *nand_flash, ULONG source_block, ULONG source_page, ULONG destination_block, ULONG destination_page, ULONG pages, UCHAR* data_buffer);
482 #else
483     UINT                            (*lx_nand_flash_driver_read)(ULONG block, ULONG page, ULONG *destination, ULONG words);
484     UINT                            (*lx_nand_flash_driver_write)(ULONG block, ULONG page, ULONG *source, ULONG words);
485     UINT                            (*lx_nand_flash_driver_block_erase)(ULONG block, ULONG erase_count);
486     UINT                            (*lx_nand_flash_driver_block_erased_verify)(ULONG block);
487     UINT                            (*lx_nand_flash_driver_page_erased_verify)(ULONG block, ULONG page);
488     UINT                            (*lx_nand_flash_driver_block_status_get)(ULONG block, UCHAR *bad_block_flag);
489     UINT                            (*lx_nand_flash_driver_block_status_set)(ULONG block, UCHAR bad_block_flag);
490     UINT                            (*lx_nand_flash_driver_extra_bytes_get)(ULONG block, ULONG page, UCHAR *destination, UINT size);
491     UINT                            (*lx_nand_flash_driver_extra_bytes_set)(ULONG block, ULONG page, UCHAR *source, UINT size);
492     UINT                            (*lx_nand_flash_driver_system_error)(UINT error_code, ULONG block, ULONG page);
493 
494     UINT                            (*lx_nand_flash_driver_pages_read)(ULONG block, ULONG page, UCHAR* main_buffer, UCHAR* spare_buffer, ULONG pages);
495     UINT                            (*lx_nand_flash_driver_pages_write)(ULONG block, ULONG page, UCHAR* main_buffer, UCHAR* spare_buffer, ULONG pages);
496     UINT                            (*lx_nand_flash_driver_pages_copy)(ULONG source_block, ULONG source_page, ULONG destination_block, ULONG destination_page, ULONG pages, UCHAR* data_buffer);
497 #endif
498     UCHAR                           *lx_nand_flash_page_buffer;
499     UINT                            lx_nand_flash_page_buffer_size;
500 
501 #ifdef LX_THREAD_SAFE_ENABLE
502 
503     /* When this conditional is used, the LevelX code utilizes a ThreadX mutex for thread
504        safe operation. Generally, this is not required since FileX ensures thread safe operation at
505        a higher layer.  */
506     TX_MUTEX                        lx_nand_flash_mutex;
507 #endif
508 
509     /* Define the NAND flash control block open next/previous pointers.  */
510     struct LX_NAND_FLASH_STRUCT     *lx_nand_flash_open_next,
511                                     *lx_nand_flash_open_previous;
512 
513     /* Define the user extension in the flash control block. This
514        is typically defined in lx_user.h.  */
515     LX_NAND_FLASH_USER_EXTENSION
516 
517 } LX_NAND_FLASH;
518 
519 
520 
521 /* Define the NOR flash sector cache entry structure.  */
522 
523 typedef struct LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_STRUCT
524 {
525     ULONG                           lx_nor_sector_mapping_cache_logical_sector;
526     ULONG                           *lx_nor_sector_mapping_cache_physical_sector_map_entry;
527     ULONG                           *lx_nor_sector_mapping_cache_physical_sector_address;
528 } LX_NOR_SECTOR_MAPPING_CACHE_ENTRY;
529 
530 
531 /* Define the NOR flash extended cache entry structure.  */
532 
533 typedef struct LX_NOR_FLASH_EXTENDED_CACHE_ENTRY_STRUCT
534 {
535     ULONG                           *lx_nor_flash_extended_cache_entry_sector_address;
536     ULONG                           *lx_nor_flash_extended_cache_entry_sector_memory;
537     ULONG                           lx_nor_flash_extended_cache_entry_access_count;
538 } LX_NOR_FLASH_EXTENDED_CACHE_ENTRY;
539 
540 
541 /* Determine if the flash control block has an extension defined. If not,
542    define the extension to whitespace.  */
543 
544 #ifndef LX_NOR_FLASH_USER_EXTENSION
545 #define LX_NOR_FLASH_USER_EXTENSION
546 #endif
547 
548 /* Define the NOR flash control block structure.  */
549 
550 typedef struct LX_NOR_FLASH_STRUCT
551 {
552     ULONG                           lx_nor_flash_state;
553     ULONG                           lx_nor_flash_total_blocks;
554     ULONG                           lx_nor_flash_words_per_block;
555     ULONG                           lx_nor_flash_total_physical_sectors;
556     ULONG                           lx_nor_flash_physical_sectors_per_block;
557 
558     ULONG                           *lx_nor_flash_base_address;
559     ULONG                           lx_nor_flash_block_free_bit_map_offset;
560     ULONG                           lx_nor_flash_block_bit_map_words;
561     ULONG                           lx_nor_flash_block_bit_map_mask;
562     ULONG                           lx_nor_flash_block_physical_sector_mapping_offset;
563     ULONG                           lx_nor_flash_block_physical_sector_offset;
564 
565     ULONG                           lx_nor_flash_free_physical_sectors;
566     ULONG                           lx_nor_flash_mapped_physical_sectors;
567     ULONG                           lx_nor_flash_obsolete_physical_sectors;
568     ULONG                           lx_nor_flash_minimum_erase_count;
569     ULONG                           lx_nor_flash_maximum_erase_count;
570 
571     ULONG                           lx_nor_flash_free_block_search;
572     ULONG                           lx_nor_flash_found_block_search;
573     ULONG                           lx_nor_flash_found_sector_search;
574 
575     ULONG                           lx_nor_flash_write_requests;
576     ULONG                           lx_nor_flash_read_requests;
577     ULONG                           lx_nor_flash_sector_mapping_cache_hits;
578     ULONG                           lx_nor_flash_sector_mapping_cache_misses;
579     ULONG                           lx_nor_flash_physical_block_allocates;
580     ULONG                           lx_nor_flash_physical_block_allocate_errors;
581     ULONG                           lx_nor_flash_diagnostic_system_errors;
582     ULONG                           lx_nor_flash_diagnostic_system_error;
583     ULONG                           lx_nor_flash_diagnostic_initial_format;
584     ULONG                           lx_nor_flash_diagnostic_erased_block;
585     ULONG                           lx_nor_flash_diagnostic_re_erase_block;
586     ULONG                           lx_nor_flash_diagnostic_sector_being_obsoleted;
587     ULONG                           lx_nor_flash_diagnostic_sector_obsoleted;
588     ULONG                           lx_nor_flash_diagnostic_mapping_invalidated;
589     ULONG                           lx_nor_flash_diagnostic_mapping_write_interrupted;
590     ULONG                           lx_nor_flash_diagnostic_sector_not_free;
591     ULONG                           lx_nor_flash_diagnostic_sector_data_not_free;
592 
593 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
594     UINT                            (*lx_nor_flash_driver_read)(struct LX_NOR_FLASH_STRUCT *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words);
595     UINT                            (*lx_nor_flash_driver_write)(struct LX_NOR_FLASH_STRUCT *nor_flash, ULONG *flash_address, ULONG *source, ULONG words);
596     UINT                            (*lx_nor_flash_driver_block_erase)(struct LX_NOR_FLASH_STRUCT *nor_flash, ULONG block, ULONG erase_count);
597     UINT                            (*lx_nor_flash_driver_block_erased_verify)(struct LX_NOR_FLASH_STRUCT *nor_flash, ULONG block);
598     UINT                            (*lx_nor_flash_driver_system_error)(struct LX_NOR_FLASH_STRUCT *nor_flash, UINT error_code);
599 #else
600     UINT                            (*lx_nor_flash_driver_read)(ULONG *flash_address, ULONG *destination, ULONG words);
601     UINT                            (*lx_nor_flash_driver_write)(ULONG *flash_address, ULONG *source, ULONG words);
602     UINT                            (*lx_nor_flash_driver_block_erase)(ULONG block, ULONG erase_count);
603     UINT                            (*lx_nor_flash_driver_block_erased_verify)(ULONG block);
604     UINT                            (*lx_nor_flash_driver_system_error)(UINT error_code);
605 #endif
606 
607     ULONG                           *lx_nor_flash_sector_buffer;
608     UINT                            lx_nor_flash_sector_mapping_cache_enabled;
609     LX_NOR_SECTOR_MAPPING_CACHE_ENTRY
610                                     lx_nor_flash_sector_mapping_cache[LX_NOR_SECTOR_MAPPING_CACHE_SIZE];
611 
612 #ifndef LX_NOR_DISABLE_EXTENDED_CACHE
613 
614     UINT                            lx_nor_flash_extended_cache_entries;
615     LX_NOR_FLASH_EXTENDED_CACHE_ENTRY
616                                     lx_nor_flash_extended_cache[LX_NOR_EXTENDED_CACHE_SIZE];
617     ULONG                           lx_nor_flash_extended_cache_hits;
618     ULONG                           lx_nor_flash_extended_cache_misses;
619 #endif
620 
621 #ifdef LX_THREAD_SAFE_ENABLE
622 
623     /* When this conditional is used, the LevelX code utilizes a ThreadX mutex for thread
624        safe operation. Generally, this is not required since FileX ensures thread safe operation at
625        a higher layer.  */
626     TX_MUTEX                        lx_nor_flash_mutex;
627 #endif
628 
629     /* Define the NOR flash control block open next/previous pointers.  */
630     struct LX_NOR_FLASH_STRUCT      *lx_nor_flash_open_next,
631                                     *lx_nor_flash_open_previous;
632 
633     /* Define the user extension in the flash control block. This
634        is typically defined in lx_user.h.  */
635     LX_NOR_FLASH_USER_EXTENSION
636 
637 } LX_NOR_FLASH;
638 
639 
640 /* Each physical NOR block has the following structure at the beginning of the block:
641 
642     Offset              Meaning
643 
644     0           Erase count
645     4           Minimum logical sector number - only when the block is full
646     8           Maximum logical sector number - only when the block is full
647     12          Free physical sector bit map, where a value of 1 indicates a
648                 free physical sector. The bit map is evenly divisible by 4
649     .           Array of physical sector mapping information (4 bytes per entry,
650                 one entry for each physical sector in block). Each entry looks
651                 like the following:
652 
653                         Bit(s)                 Meaning
654 
655                         0-29                Logical sector mapped if not 0x3FFFFFFF
656                         30                  If 0, entry is being superceded
657                         31                  If 1, entry is valid
658 
659              Array of physical sectors, with each of size LX_NOR_SECTOR_SIZE
660 */
661 
662 
663 typedef struct LX_NOR_FLASH_BLOCK_HEADER_STRUCT
664 {
665     ULONG                           lx_nor_flash_block_erase_count;              /* Bit 31: 1 -> not used, 0 -> used      */
666     ULONG                           lx_nor_flash_block_min_logical_sector;       /* On full block, minimum valid sector   */
667     ULONG                           lx_nor_flash_block_max_logical_sector;       /* On full block, maximum valid sector   */
668 } LX_NOR_FLASH_BLOCK_HEADER;
669 
670 
671 /* Define external structure references.   */
672 
673 extern LX_NAND_FLASH                                    *_lx_nand_flash_opened_ptr;
674 extern ULONG                                            _lx_nand_flash_opened_count;
675 extern LX_NOR_FLASH                                     *_lx_nor_flash_opened_ptr;
676 extern ULONG                                            _lx_nor_flash_opened_count;
677 
678 
679 /* Map internal functions.  */
680 
681 #ifndef LX_SOURCE_CODE
682 #define lx_nand_flash_close                             _lx_nand_flash_close
683 #define lx_nand_flash_defragment                        _lx_nand_flash_defragment
684 #define lx_nand_flash_partial_defragment                _lx_nand_flash_partial_defragment
685 #define lx_nand_flash_extended_cache_enable             _lx_nand_flash_extended_cache_enable
686 #define lx_nand_flash_format                            _lx_nand_flash_format
687 #define lx_nand_flash_initialize                        _lx_nand_flash_initialize
688 #define lx_nand_flash_open                              _lx_nand_flash_open
689 #define lx_nand_flash_page_ecc_check                    _lx_nand_flash_page_ecc_check
690 #define lx_nand_flash_page_ecc_compute                  _lx_nand_flash_page_ecc_compute
691 #define lx_nand_flash_sector_read                       _lx_nand_flash_sector_read
692 #define lx_nand_flash_sector_release                    _lx_nand_flash_sector_release
693 #define lx_nand_flash_sector_write                      _lx_nand_flash_sector_write
694 #define lx_nand_flash_sectors_read                      _lx_nand_flash_sectors_read
695 #define lx_nand_flash_sectors_release                   _lx_nand_flash_sectors_release
696 #define lx_nand_flash_sectors_write                     _lx_nand_flash_sectors_write
697 #define lx_nand_flash_256byte_ecc_check                 _lx_nand_flash_256byte_ecc_check
698 #define lx_nand_flash_256byte_ecc_compute               _lx_nand_flash_256byte_ecc_compute
699 
700 #define lx_nor_flash_close                              _lx_nor_flash_close
701 #define lx_nor_flash_defragment                         _lx_nor_flash_defragment
702 #define lx_nor_flash_partial_defragment                 _lx_nor_flash_partial_defragment
703 #define lx_nor_flash_extended_cache_enable              _lx_nor_flash_extended_cache_enable
704 #define lx_nor_flash_initialize                         _lx_nor_flash_initialize
705 #define lx_nor_flash_open                               _lx_nor_flash_open
706 #define lx_nor_flash_sector_read                        _lx_nor_flash_sector_read
707 #define lx_nor_flash_sector_release                     _lx_nor_flash_sector_release
708 #define lx_nor_flash_sector_write                       _lx_nor_flash_sector_write
709 #endif
710 
711 
712 /* External LevelX API prototypes.  */
713 
714 UINT    _lx_nand_flash_close(LX_NAND_FLASH *nand_flash);
715 UINT    _lx_nand_flash_defragment(LX_NAND_FLASH *nand_flash);
716 UINT    _lx_nand_flash_initialize(void);
717 UINT    _lx_nand_flash_extended_cache_enable(LX_NAND_FLASH  *nand_flash, VOID *memory, ULONG size);
718 UINT    _lx_nand_flash_format(LX_NAND_FLASH* nand_flash, CHAR* name,
719                                 UINT(*nand_driver_initialize)(LX_NAND_FLASH*),
720                                 ULONG* memory_ptr, UINT memory_size);
721 UINT    _lx_nand_flash_open(LX_NAND_FLASH  *nand_flash, CHAR *name, UINT (*nand_driver_initialize)(LX_NAND_FLASH *), ULONG* memory_ptr, UINT memory_size);
722 UINT    _lx_nand_flash_page_ecc_check(LX_NAND_FLASH *nand_flash, UCHAR *page_buffer, UCHAR *ecc_buffer);
723 UINT    _lx_nand_flash_page_ecc_compute(LX_NAND_FLASH *nand_flash, UCHAR *page_buffer, UCHAR *ecc_buffer);
724 UINT    _lx_nand_flash_partial_defragment(LX_NAND_FLASH *nand_flash, UINT max_blocks);
725 UINT    _lx_nand_flash_sector_read(LX_NAND_FLASH *nand_flash, ULONG logical_sector, VOID *buffer);
726 UINT    _lx_nand_flash_sector_release(LX_NAND_FLASH *nand_flash, ULONG logical_sector);
727 UINT    _lx_nand_flash_sector_write(LX_NAND_FLASH *nand_flash, ULONG logical_sector, VOID *buffer);
728 UINT    _lx_nand_flash_sectors_read(LX_NAND_FLASH* nand_flash, ULONG logical_sector, VOID* buffer, ULONG sector_count);
729 UINT    _lx_nand_flash_sectors_release(LX_NAND_FLASH* nand_flash, ULONG logical_sector, ULONG sector_count);
730 UINT    _lx_nand_flash_sectors_write(LX_NAND_FLASH* nand_flash, ULONG logical_sector, VOID* buffer, ULONG sector_count);
731 
732 UINT    _lx_nor_flash_close(LX_NOR_FLASH *nor_flash);
733 UINT    _lx_nor_flash_defragment(LX_NOR_FLASH *nor_flash);
734 UINT    _lx_nor_flash_extended_cache_enable(LX_NOR_FLASH *nor_flash, VOID *memory, ULONG size);
735 UINT    _lx_nor_flash_initialize(void);
736 UINT    _lx_nor_flash_open(LX_NOR_FLASH  *nor_flash, CHAR *name, UINT (*nor_driver_initialize)(LX_NOR_FLASH *));
737 UINT    _lx_nor_flash_partial_defragment(LX_NOR_FLASH *nor_flash, UINT max_blocks);
738 UINT    _lx_nor_flash_sector_read(LX_NOR_FLASH *nor_flash, ULONG logical_sector, VOID *buffer);
739 UINT    _lx_nor_flash_sector_release(LX_NOR_FLASH *nor_flash, ULONG logical_sector);
740 UINT    _lx_nor_flash_sector_write(LX_NOR_FLASH *nor_flash, ULONG logical_sector, VOID *buffer);
741 
742 
743 /* Internal LevelX prototypes.  */
744 
745 UINT    _lx_nand_flash_driver_block_erase(LX_NAND_FLASH *nand_flash, ULONG block, ULONG erase_count);
746 UINT    _lx_nand_flash_driver_block_erased_verify(LX_NAND_FLASH *nand_flash, ULONG block);
747 UINT    _lx_nand_flash_driver_page_erased_verify(LX_NAND_FLASH *nand_flash, ULONG block, ULONG page);
748 UINT    _lx_nand_flash_driver_block_status_get(LX_NAND_FLASH *nand_flash, ULONG block, UCHAR *bad_block_flag);
749 UINT    _lx_nand_flash_driver_block_status_set(LX_NAND_FLASH *nand_flash, ULONG block, UCHAR bad_block_flag);
750 
751 VOID    _lx_nand_flash_internal_error(LX_NAND_FLASH *nand_flash, ULONG error_code);
752 UINT    _lx_nand_flash_block_find(LX_NAND_FLASH *nand_flash, ULONG logical_sector, ULONG *block, USHORT *block_status);
753 UINT    _lx_nand_flash_block_allocate(LX_NAND_FLASH *nand_flash, ULONG *block);
754 UINT    _lx_nand_flash_block_data_move(LX_NAND_FLASH* nand_flash, ULONG new_block);
755 UINT    _lx_nand_flash_block_status_set(LX_NAND_FLASH *nand_flash, ULONG block, ULONG block_status);
756 UINT    _lx_nand_flash_erase_count_set(LX_NAND_FLASH* nand_flash, ULONG block, UCHAR erase_count);
757 UINT    _lx_nand_flash_block_mapping_set(LX_NAND_FLASH* nand_flash, ULONG logical_sector, ULONG block);
758 UINT    _lx_nand_flash_data_page_copy(LX_NAND_FLASH* nand_flash, ULONG logical_sector, ULONG source_block, USHORT src_block_status,
759                                         ULONG destination_block, USHORT* dest_block_status_ptr, ULONG sectors);
760 UINT    _lx_nand_flash_free_block_list_add(LX_NAND_FLASH* nand_flash, ULONG block);
761 UINT    _lx_nand_flash_mapped_block_list_add(LX_NAND_FLASH* nand_flash, ULONG block_mapping_index);
762 UINT    _lx_nand_flash_mapped_block_list_get(LX_NAND_FLASH* nand_flash, ULONG *block_mapping_index);
763 UINT    _lx_nand_flash_mapped_block_list_remove(LX_NAND_FLASH* nand_flash, ULONG block_mapping_index);
764 UINT    _lx_nand_flash_memory_initialize(LX_NAND_FLASH* nand_flash, ULONG* memory_ptr, UINT memory_size);
765 UINT    _lx_nand_flash_metadata_allocate(LX_NAND_FLASH* nand_flash);
766 UINT    _lx_nand_flash_metadata_build(LX_NAND_FLASH* nand_flash);
767 UINT    _lx_nand_flash_metadata_write(LX_NAND_FLASH *nand_flash, UCHAR* main_buffer, ULONG spare_value);
768 VOID    _lx_nand_flash_system_error(LX_NAND_FLASH *nand_flash, UINT error_code, ULONG block, ULONG page);
769 UINT    _lx_nand_flash_256byte_ecc_check(UCHAR *page_buffer, UCHAR *ecc_buffer);
770 UINT    _lx_nand_flash_256byte_ecc_compute(UCHAR *page_buffer, UCHAR *ecc_buffer);
771 
772 UINT    _lx_nor_flash_block_reclaim(LX_NOR_FLASH *nor_flash);
773 UINT    _lx_nor_flash_driver_block_erase(LX_NOR_FLASH *nor_flash, ULONG block, ULONG erase_count);
774 UINT    _lx_nor_flash_driver_read(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words);
775 UINT    _lx_nor_flash_driver_write(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *source, ULONG words);
776 VOID    _lx_nor_flash_internal_error(LX_NOR_FLASH *nor_flash, ULONG error_code);
777 UINT    _lx_nor_flash_logical_sector_find(LX_NOR_FLASH *nor_flash, ULONG logical_sector, ULONG superceded_check, ULONG **physical_sector_map_entry, ULONG **physical_sector_address);
778 UINT    _lx_nor_flash_next_block_to_erase_find(LX_NOR_FLASH *nor_flash, ULONG *return_erase_block, ULONG *return_erase_count, ULONG *return_mapped_sectors, ULONG *return_obsolete_sectors);
779 UINT    _lx_nor_flash_physical_sector_allocate(LX_NOR_FLASH *nor_flash, ULONG logical_sector, ULONG **physical_sector_map_entry, ULONG **physical_sector_address);
780 VOID    _lx_nor_flash_sector_mapping_cache_invalidate(LX_NOR_FLASH *nor_flash, ULONG logical_sector);
781 VOID    _lx_nor_flash_system_error(LX_NOR_FLASH *nor_flash, UINT error_code);
782 
783 
784 #ifdef __cplusplus
785 }
786 #endif
787 
788 #endif
789 
790