GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: fx_nand_flash_simulated_driver.c Lines: 0 80 0.0 %
Date: 2024-03-11 05:20:25 Branches: 0 30 0.0 %

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