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