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