GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_nand_flash_simulated_driver.c Lines: 0 80 0.0 %
Date: 2026-03-06 18:45:40 Branches: 0 30 0.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** FileX Component                                                       */
17
/**                                                                       */
18
/**   FileX NAND FLASH Simulator Driver                                   */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
24
/* Include necessary system files.  */
25
26
#include "fx_api.h"
27
#include "lx_api.h"
28
29
30
/* Create a NAND flash control block.  */
31
32
LX_NAND_FLASH       nand_flash;
33
34
/* Memory buffer size should be at least 7 * total block count + 2 * page size,
35
   that is 7 * 1024 + 2 * 528 = 8224 bytes */
36
ULONG               lx_memory_buffer[8224 / sizeof (ULONG)];
37
38
/* Define the NAND flash simulation initialization function.  */
39
40
UINT  _lx_nand_flash_simulator_initialize(LX_NAND_FLASH *nand_flash);
41
VOID  _fx_nand_flash_read_sectors(ULONG logical_sector, ULONG sectors, UCHAR *destination_buffer);
42
VOID  _fx_nand_flash_write_sectors(ULONG logical_sector, ULONG sectors, UCHAR *source_buffer);
43
44
45
/* The simulated NAND driver relies on the fx_media_format call to be made prior to
46
   the fx_media_open call.
47
48
        fx_media_format(&ram_disk,
49
                            _fx_nand_sim_driver,    // Driver entry
50
                            FX_NULL,                // Unused
51
                            media_memory,           // Media buffer pointer
52
                            sizeof(media_memory),   // Media buffer size
53
                            "MY_NAND_DISK",         // Volume Name
54
                            1,                      // Number of FATs
55
                            32,                     // Directory Entries
56
                            0,                      // Hidden sectors
57
                            120,                    // Total sectors
58
                            2048,                   // Sector size
59
                            1,                      // Sectors per cluster
60
                            1,                      // Heads
61
                            1);                     // Sectors per track
62
63
*/
64
65
66
VOID  _fx_nand_flash_simulator_driver(FX_MEDIA *media_ptr);
67
68
69
/**************************************************************************/
70
/*                                                                        */
71
/*  FUNCTION                                               RELEASE        */
72
/*                                                                        */
73
/*    _fx_nand_simulator_driver                           PORTABLE C      */
74
/*                                                           6.2.1       */
75
/*  AUTHOR                                                                */
76
/*                                                                        */
77
/*    William E. Lamie, Microsoft Corporation                             */
78
/*                                                                        */
79
/*  DESCRIPTION                                                           */
80
/*                                                                        */
81
/*    This function is the entry point to the generic NAND simulated      */
82
/*    disk driver that is delivered with the flash wear leveling product  */
83
/*    LevelX.                                                             */
84
/*                                                                        */
85
/*    This driver also serves as a template for developing other LevelX   */
86
/*    NAND flash drivers for actual flash devices. Simply replace the     */
87
/*    read/write sector logic with calls to read/write from the           */
88
/*    appropriate physical device access functions.                       */
89
/*                                                                        */
90
/*    FileX NAND FLASH structures look like the following:                */
91
/*                                                                        */
92
/*          Logical Sector                  Contents                      */
93
/*                                                                        */
94
/*              0                       Boot record                       */
95
/*              1                       FAT Area Start                    */
96
/*              +FAT Sectors            Root Directory Start              */
97
/*              +Directory Sectors      Data Sector Start                 */
98
/*                                                                        */
99
/*                                                                        */
100
/*  INPUT                                                                 */
101
/*                                                                        */
102
/*    media_ptr                             Media control block pointer   */
103
/*                                                                        */
104
/*  OUTPUT                                                                */
105
/*                                                                        */
106
/*    None                                                                */
107
/*                                                                        */
108
/*  CALLS                                                                 */
109
/*                                                                        */
110
/*    _lx_nand_flash_close                  Close NAND flash manager      */
111
/*    _lx_nand_flash_open                   Open NAND flash manager       */
112
/*    _lx_nand_flash_sector_read            Read a NAND sector            */
113
/*    _lx_nand_flash_sector_release         Release a NAND sector         */
114
/*    _lx_nand_flash_sector_write           Write a NAND sector           */
115
/*                                                                        */
116
/*  CALLED BY                                                             */
117
/*                                                                        */
118
/*    FileX System Functions                                              */
119
/*                                                                        */
120
/**************************************************************************/
121
VOID  _fx_nand_flash_simulator_driver(FX_MEDIA *media_ptr)
122
{
123
124
ULONG   logical_sector;
125
ULONG   count;
126
UCHAR   *buffer;
127
UINT    status;
128
129
130
    /* There are several useful/important pieces of information contained in the media
131
       structure, some of which are supplied by FileX and others are for the driver to
132
       setup. The following is a summary of the necessary FX_MEDIA structure members:
133
134
            FX_MEDIA Member                              Meaning
135
136
        fx_media_driver_request             FileX request type. Valid requests from FileX are
137
                                            as follows:
138
139
                                                    FX_DRIVER_READ
140
                                                    FX_DRIVER_WRITE
141
                                                    FX_DRIVER_FLUSH
142
                                                    FX_DRIVER_ABORT
143
                                                    FX_DRIVER_INIT
144
                                                    FX_DRIVER_BOOT_READ
145
                                                    FX_DRIVER_RELEASE_SECTORS
146
                                                    FX_DRIVER_BOOT_WRITE
147
                                                    FX_DRIVER_UNINIT
148
149
        fx_media_driver_status              This value is RETURNED by the driver. If the
150
                                            operation is successful, this field should be
151
                                            set to FX_SUCCESS for before returning. Otherwise,
152
                                            if an error occurred, this field should be set
153
                                            to FX_IO_ERROR.
154
155
        fx_media_driver_buffer              Pointer to buffer to read or write sector data.
156
                                            This is supplied by FileX.
157
158
        fx_media_driver_logical_sector      Logical sector FileX is requesting.
159
160
        fx_media_driver_sectors             Number of sectors FileX is requesting.
161
162
163
       The following is a summary of the optional FX_MEDIA structure members:
164
165
            FX_MEDIA Member                              Meaning
166
167
        fx_media_driver_info                Pointer to any additional information or memory.
168
                                            This is optional for the driver use and is setup
169
                                            from the fx_media_open call. The RAM disk uses
170
                                            this pointer for the RAM disk memory itself.
171
172
        fx_media_driver_write_protect       The DRIVER sets this to FX_TRUE when media is write
173
                                            protected. This is typically done in initialization,
174
                                            but can be done anytime.
175
176
        fx_media_driver_free_sector_update  The DRIVER sets this to FX_TRUE when it needs to
177
                                            know when clusters are released. This is important
178
                                            for FLASH wear-leveling drivers.
179
180
        fx_media_driver_system_write        FileX sets this flag to FX_TRUE if the sector being
181
                                            written is a system sector, e.g., a boot, FAT, or
182
                                            directory sector. The driver may choose to use this
183
                                            to initiate error recovery logic for greater fault
184
                                            tolerance.
185
186
        fx_media_driver_data_sector_read    FileX sets this flag to FX_TRUE if the sector(s) being
187
                                            read are file data sectors, i.e., NOT system sectors.
188
189
        fx_media_driver_sector_type         FileX sets this variable to the specific type of
190
                                            sector being read or written. The following sector
191
                                            types are identified:
192
193
                                                    FX_UNKNOWN_SECTOR
194
                                                    FX_BOOT_SECTOR
195
                                                    FX_FAT_SECTOR
196
                                                    FX_DIRECTORY_SECTOR
197
                                                    FX_DATA_SECTOR
198
    */
199
200
    /* Process the driver request specified in the media control block.  */
201
    switch(media_ptr -> fx_media_driver_request)
202
    {
203
204
        case FX_DRIVER_READ:
205
        {
206
207
            /* Read sector(s) from NAND flash.  */
208
            logical_sector =  media_ptr -> fx_media_driver_logical_sector;
209
            count =  media_ptr -> fx_media_driver_sectors;
210
            buffer = (UCHAR *) media_ptr -> fx_media_driver_buffer;
211
            while (count)
212
            {
213
214
                /* Call LevelX to read one flash sector.  */
215
                status =  _lx_nand_flash_sector_read(&nand_flash, logical_sector, buffer);
216
217
                /* Determine if the read was successful.  */
218
                if (status != LX_SUCCESS)
219
                {
220
221
                    /* Return an I/O error to FileX.  */
222
                    media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
223
224
                    return;
225
                }
226
227
                /* Successful sector read.  */
228
                count--;
229
                logical_sector++;
230
                buffer += media_ptr -> fx_media_bytes_per_sector;
231
            }
232
            /* Successful driver request.  */
233
            media_ptr -> fx_media_driver_status =  FX_SUCCESS;
234
            break;
235
        }
236
237
        case FX_DRIVER_WRITE:
238
        {
239
240
            /* Write sector(s) to NAND flash.  */
241
            logical_sector =  media_ptr -> fx_media_driver_logical_sector;
242
            count =  media_ptr -> fx_media_driver_sectors;
243
            buffer = (UCHAR *) media_ptr -> fx_media_driver_buffer;
244
            while (count)
245
            {
246
247
                /* Call LevelX to write a sector.  */
248
                status =  _lx_nand_flash_sector_write(&nand_flash, logical_sector, buffer);
249
250
                /* Determine if the write was successful.  */
251
                if (status != LX_SUCCESS)
252
                {
253
254
                    /* Return an I/O error to FileX.  */
255
                    media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
256
257
                    return;
258
                }
259
260
                /* Successful sector write.  */
261
                count--;
262
                logical_sector++;
263
                buffer += media_ptr -> fx_media_bytes_per_sector;
264
            }
265
266
            /* Successful driver request.  */
267
            media_ptr -> fx_media_driver_status =  FX_SUCCESS;
268
            break;
269
        }
270
271
        case FX_DRIVER_RELEASE_SECTORS:
272
        {
273
274
            /* Release the mapping of this sector.  */
275
            logical_sector =  media_ptr -> fx_media_driver_logical_sector;
276
            count =  media_ptr -> fx_media_driver_sectors;
277
            while (count)
278
            {
279
280
                /* Call LevelX to release a sector mapping.  */
281
                status =  _lx_nand_flash_sector_release(&nand_flash, logical_sector);
282
283
                /* Determine if the sector release was successful.  */
284
                if (status != LX_SUCCESS)
285
                {
286
287
                    /* Return an I/O error to FileX.  */
288
                    media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
289
290
                    return;
291
                }
292
293
                /* Successful sector release.  */
294
                count--;
295
                logical_sector++;
296
            }
297
298
            /* Successful driver request.  */
299
            media_ptr -> fx_media_driver_status =  FX_SUCCESS;
300
            break;
301
        }
302
303
        case FX_DRIVER_FLUSH:
304
        {
305
306
            /* Return driver success.  */
307
            media_ptr -> fx_media_driver_status =  FX_SUCCESS;
308
            break;
309
        }
310
311
        case FX_DRIVER_ABORT:
312
        {
313
314
            /* Return driver success.  */
315
            media_ptr -> fx_media_driver_status =  FX_SUCCESS;
316
            break;
317
        }
318
319
        case FX_DRIVER_INIT:
320
        {
321
322
            /* FLASH drivers are responsible for setting several fields in the
323
               media structure, as follows:
324
325
                    media_ptr -> fx_media_driver_free_sector_update
326
                    media_ptr -> fx_media_driver_write_protect
327
328
               The fx_media_driver_free_sector_update flag is used to instruct
329
               FileX to inform the driver whenever sectors are not being used.
330
               This is especially useful for FLASH managers so they don't have
331
               maintain mapping for sectors no longer in use.
332
333
               The fx_media_driver_write_protect flag can be set anytime by the
334
               driver to indicate the media is not writable.  Write attempts made
335
               when this flag is set are returned as errors.  */
336
337
            /* Perform basic initialization here... since the boot record is going
338
               to be read subsequently and again for volume name requests.  */
339
340
            /* With flash wear leveling, FileX should tell wear leveling when sectors
341
               are no longer in use.  */
342
            media_ptr -> fx_media_driver_free_sector_update =  FX_TRUE;
343
344
            /* Open the NAND flash simulation.  */
345
            status =  _lx_nand_flash_open(&nand_flash, "sim nand flash", _lx_nand_flash_simulator_initialize, lx_memory_buffer, sizeof(lx_memory_buffer));
346
347
            /* Determine if the flash open was successful.  */
348
            if (status != LX_SUCCESS)
349
            {
350
351
                /* Return an I/O error to FileX.  */
352
                media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
353
354
                return;
355
            }
356
357
            /* Successful driver request.  */
358
            media_ptr -> fx_media_driver_status =  FX_SUCCESS;
359
            break;
360
        }
361
362
        case FX_DRIVER_UNINIT:
363
        {
364
365
            /* There is nothing to do in this case for the RAM driver.  For actual
366
               devices some shutdown processing may be necessary.  */
367
368
            /* Close the NAND flash simulation.  */
369
            status =  _lx_nand_flash_close(&nand_flash);
370
371
            /* Determine if the flash close was successful.  */
372
            if (status != LX_SUCCESS)
373
            {
374
375
                /* Return an I/O error to FileX.  */
376
                media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
377
378
                return;
379
            }
380
381
            /* Successful driver request.  */
382
            media_ptr -> fx_media_driver_status =  FX_SUCCESS;
383
            break;
384
        }
385
386
        case FX_DRIVER_BOOT_READ:
387
        {
388
389
            /* Read the boot record and return to the caller.  */
390
            status =  _lx_nand_flash_sector_read(&nand_flash, 0, (UCHAR *) media_ptr -> fx_media_driver_buffer);
391
392
            /* Determine if the read was successful.  */
393
            if (status != LX_SUCCESS)
394
            {
395
396
                /* Return an I/O error to FileX.  */
397
                media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
398
399
                return;
400
            }
401
402
            /* Successful driver request.  */
403
            media_ptr -> fx_media_driver_status =  FX_SUCCESS;
404
            break;
405
        }
406
407
        case FX_DRIVER_BOOT_WRITE:
408
        {
409
410
            /* Write the boot record and return to the caller.  */
411
            status =  _lx_nand_flash_sector_write(&nand_flash, 0, (UCHAR *) media_ptr -> fx_media_driver_buffer);
412
413
            /* Determine if the write was successful.  */
414
            if (status != LX_SUCCESS)
415
            {
416
417
                /* Return an I/O error to FileX.  */
418
                media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
419
420
                return;
421
            }
422
423
            /* Successful driver request.  */
424
            media_ptr -> fx_media_driver_status =  FX_SUCCESS;
425
            break ;
426
        }
427
428
        default:
429
        {
430
431
            /* Invalid driver request.  */
432
            media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
433
            break;
434
        }
435
    }
436
}
437