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 /**   Port Specific                                                       */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 
23 /**************************************************************************/
24 /*                                                                        */
25 /*  PORT SPECIFIC C INFORMATION                            RELEASE        */
26 /*                                                                        */
27 /*    fx_port.h                                           Linux/GCC       */
28 /*                                                           6.3.0        */
29 /*                                                                        */
30 /*  AUTHOR                                                                */
31 /*                                                                        */
32 /*    William E. Lamie, Microsoft Corporation                             */
33 /*                                                                        */
34 /*  DESCRIPTION                                                           */
35 /*                                                                        */
36 /*    This file contains data type definitions that make the FileX FAT    */
37 /*    compatible file system function identically on a variety of         */
38 /*    different processor architectures.  For example, the byte offset of */
39 /*    various entries in the boot record, and directory entries are       */
40 /*    defined in this file.                                               */
41 /*                                                                        */
42 /*  RELEASE HISTORY                                                       */
43 /*                                                                        */
44 /*    DATE              NAME                      DESCRIPTION             */
45 /*                                                                        */
46 /*  09-30-2020     William E. Lamie         Initial Version 6.1           */
47 /*  03-02-2021     William E. Lamie         Modified comment(s), and      */
48 /*                                            added standalone support,   */
49 /*                                            resulting in version 6.1.5  */
50 /*  08-02-2021     William E. Lamie         Modified comment(s),          */
51 /*                                            resulting in version 6.1.8  */
52 /*  10-31-2023     Xiuwen Cai               Modified comment(s),          */
53 /*                                            added basic types guards,   */
54 /*                                            resulting in version 6.3.0  */
55 /*                                                                        */
56 /**************************************************************************/
57 
58 #ifndef FX_PORT_H
59 #define FX_PORT_H
60 
61 
62 /* Determine if the optional FileX user define file should be used.  */
63 
64 #ifdef FX_INCLUDE_USER_DEFINE_FILE
65 
66 
67 /* Yes, include the user defines in fx_user.h. The defines in this file may
68    alternately be defined on the command line.  */
69 
70 #include "fx_user.h"
71 #endif
72 #include <stdio.h>
73 
74 
75 /* Include the ThreadX api file.  */
76 
77 #ifndef FX_STANDALONE_ENABLE
78 
79 #include "tx_api.h"
80 
81 #else
82 
83 /* Define compiler library include files.  */
84 
85 #include <stdint.h>
86 #include <stdlib.h>
87 
88 #ifndef VOID
89 #define VOID                                    void
90 typedef char                                    CHAR;
91 typedef char                                    BOOL;
92 typedef unsigned char                           UCHAR;
93 typedef int                                     INT;
94 typedef unsigned int                            UINT;
95 typedef long                                    LONG;
96 typedef unsigned long                           ULONG;
97 typedef short                                   SHORT;
98 typedef unsigned short                          USHORT;
99 #endif
100 
101 #ifndef ULONG64_DEFINED
102 #define ULONG64_DEFINED
103 typedef unsigned long long                      ULONG64;
104 #endif
105 
106 /* Define basic alignment type used in block and byte pool operations. This data type must
107    be at least 32-bits in size and also be large enough to hold a pointer type.  */
108 
109 #ifndef ALIGN_TYPE_DEFINED
110 #define ALIGN_TYPE_DEFINED
111 #define ALIGN_TYPE                              ULONG
112 #endif
113 
114 #endif
115 
116 #ifdef FX_REGRESSION_TEST
117 /* Define parameters for regression test suite.  */
118 
119 #define FX_MAX_SECTOR_CACHE                    256
120 #define FX_MAX_FAT_CACHE                       64
121 #define FX_FAT_MAP_SIZE                        1
122 
123 
124 /* Define variables and macros used to introduce errors for the regression test suite.  */
125 
126 extern  ULONG   _fx_ram_driver_io_error_request;
127 extern  ULONG   _fx_ram_driver_io_request_count;
128 extern  ULONG   _fx_file_open_max_file_size_request;
129 extern  ULONG   _fx_directory_entry_read_count;
130 extern  ULONG   _fx_directory_entry_read_error_request;
131 extern  ULONG   _fx_directory_entry_write_count;
132 extern  ULONG   _fx_directory_entry_write_error_request;
133 extern  ULONG   _fx_utility_fat_entry_write_count;
134 extern  ULONG   _fx_utility_fat_entry_write_error_request;
135 extern  ULONG   _fx_utility_fat_entry_read_count;
136 extern  ULONG   _fx_utility_fat_entry_read_error_request;
137 extern  ULONG   _fx_utility_logical_sector_flush_count;
138 extern  ULONG   _fx_utility_logical_sector_flush_error_request;
139 extern  ULONG   _fx_utility_logical_sector_write_count;
140 extern  ULONG   _fx_utility_logical_sector_write_error_request;
141 extern  ULONG   _fx_utility_logical_sector_read_count;
142 extern  ULONG   _fx_utility_logical_sector_read_error_request;
143 extern  ULONG   _fx_utility_logical_sector_read_1_count;
144 extern  ULONG   _fx_utility_logical_sector_read_1_error_request;
145 
146 #ifdef FX_ENABLE_FAULT_TOLERANT
147 struct FX_MEDIA_STRUCT;
148 extern VOID fault_tolerant_enable_callback(struct FX_MEDIA_STRUCT *media_ptr,
149                                            UCHAR *fault_tolerant_memory_buffer,
150                                            ULONG log_size);
151 extern VOID fault_tolerant_apply_log_callback(struct FX_MEDIA_STRUCT *media_ptr,
152                                               UCHAR *fault_tolerant_memory_buffer,
153                                               ULONG log_size);
154 #endif /* FX_ENABLE_FAULT_TOLERANT */
155 
156 
157 #define FX_DIRECTORY_ENTRY_READ_EXTENSION               _fx_directory_entry_read_count++;                               \
158                                                         if (_fx_directory_entry_read_error_request)                     \
159                                                         {                                                               \
160                                                             _fx_directory_entry_read_error_request--;                   \
161                                                             if (_fx_directory_entry_read_error_request == 0)            \
162                                                             {                                                           \
163                                                                 return(FX_IO_ERROR);                                    \
164                                                             }                                                           \
165                                                         }
166 
167 #define FX_DIRECTORY_ENTRY_WRITE_EXTENSION              _fx_directory_entry_write_count++;                              \
168                                                         if (_fx_directory_entry_write_error_request)                    \
169                                                         {                                                               \
170                                                             _fx_directory_entry_write_error_request--;                  \
171                                                             if (_fx_directory_entry_write_error_request == 0)           \
172                                                             {                                                           \
173                                                                 return(FX_IO_ERROR);                                    \
174                                                             }                                                           \
175                                                         }
176 
177 #define FX_UTILITY_FAT_ENTRY_READ_EXTENSION             _fx_utility_fat_entry_read_count++;                             \
178                                                         if (_fx_utility_fat_entry_read_error_request)                   \
179                                                         {                                                               \
180                                                             _fx_utility_fat_entry_read_error_request--;                 \
181                                                             if (_fx_utility_fat_entry_read_error_request == 0)          \
182                                                             {                                                           \
183                                                                 return(FX_IO_ERROR);                                    \
184                                                             }                                                           \
185                                                             if (_fx_utility_fat_entry_read_error_request == 10000)      \
186                                                             {                                                           \
187                                                                 *entry_ptr =  1;                                        \
188                                                                 _fx_utility_fat_entry_read_error_request =  0;          \
189                                                                 return(FX_SUCCESS);                                     \
190                                                             }                                                           \
191                                                             if (_fx_utility_fat_entry_read_error_request == 20000)      \
192                                                             {                                                           \
193                                                                 *entry_ptr =  media_ptr -> fx_media_fat_reserved;       \
194                                                                 _fx_utility_fat_entry_read_error_request =  0;          \
195                                                                 return(FX_SUCCESS);                                     \
196                                                             }                                                           \
197                                                             if (_fx_utility_fat_entry_read_error_request == 30000)      \
198                                                             {                                                           \
199                                                                 *entry_ptr =  cluster;                                  \
200                                                                 _fx_utility_fat_entry_read_error_request =  0;          \
201                                                                 return(FX_SUCCESS);                                     \
202                                                             }                                                           \
203                                                             if (_fx_utility_fat_entry_read_error_request == 40000)      \
204                                                             {                                                           \
205                                                                 media_ptr -> fx_media_total_clusters =  0;              \
206                                                                 _fx_utility_fat_entry_read_error_request =  0;          \
207                                                                 return(FX_SUCCESS);                                     \
208                                                             }                                                           \
209                                                         }
210 
211 #define FX_UTILITY_FAT_ENTRY_WRITE_EXTENSION            _fx_utility_fat_entry_write_count++;                            \
212                                                         if (_fx_utility_fat_entry_write_error_request)                  \
213                                                         {                                                               \
214                                                             _fx_utility_fat_entry_write_error_request--;                \
215                                                             if (_fx_utility_fat_entry_write_error_request == 0)         \
216                                                             {                                                           \
217                                                                 return(FX_IO_ERROR);                                    \
218                                                             }                                                           \
219                                                         }
220 
221 #define FX_UTILITY_LOGICAL_SECTOR_FLUSH_EXTENSION       _fx_utility_logical_sector_flush_count++;                       \
222                                                         if (_fx_utility_logical_sector_flush_error_request)             \
223                                                         {                                                               \
224                                                             _fx_utility_logical_sector_flush_error_request--;           \
225                                                             if (_fx_utility_logical_sector_flush_error_request == 0)    \
226                                                             {                                                           \
227                                                                 return(FX_IO_ERROR);                                    \
228                                                             }                                                           \
229                                                         }
230 
231 #define FX_UTILITY_LOGICAL_SECTOR_READ_EXTENSION       _fx_utility_logical_sector_read_count++;                         \
232                                                         if (_fx_utility_logical_sector_read_error_request)              \
233                                                         {                                                               \
234                                                             _fx_utility_logical_sector_read_error_request--;            \
235                                                             if (_fx_utility_logical_sector_read_error_request == 0)     \
236                                                             {                                                           \
237                                                                 return(FX_IO_ERROR);                                    \
238                                                             }                                                           \
239                                                         }
240 
241 #define FX_UTILITY_LOGICAL_SECTOR_READ_EXTENSION_1      _fx_utility_logical_sector_read_1_count++;                      \
242                                                         if (_fx_utility_logical_sector_read_1_error_request)            \
243                                                         {                                                               \
244                                                             _fx_utility_logical_sector_read_1_error_request--;          \
245                                                             if (_fx_utility_logical_sector_read_1_error_request == 0)   \
246                                                             {                                                           \
247                                                                 cache_entry =  FX_NULL;                                 \
248                                                             }                                                           \
249                                                         }
250 
251 #define FX_UTILITY_LOGICAL_SECTOR_WRITE_EXTENSION       _fx_utility_logical_sector_write_count++;                       \
252                                                         if (_fx_utility_logical_sector_write_error_request)             \
253                                                         {                                                               \
254                                                             _fx_utility_logical_sector_write_error_request--;           \
255                                                             if (_fx_utility_logical_sector_write_error_request == 0)    \
256                                                             {                                                           \
257                                                                 return(FX_IO_ERROR);                                    \
258                                                             }                                                           \
259                                                         }
260 
261 #define FX_FAULT_TOLERANT_ENABLE_EXTENSION              fault_tolerant_enable_callback(media_ptr, media_ptr -> fx_media_fault_tolerant_memory_buffer, total_size);
262 #define FX_FAULT_TOLERANT_APPLY_LOGS_EXTENSION          fault_tolerant_apply_log_callback(media_ptr, media_ptr -> fx_media_fault_tolerant_memory_buffer, size);
263 #endif /* FX_REGRESSION_TEST */
264 
265 
266 
267 /* Define FileX internal protection macros.  If FX_SINGLE_THREAD is defined,
268    these protection macros are effectively disabled.  However, for multi-thread
269    uses, the macros are setup to utilize a ThreadX mutex for multiple thread
270    access control into an open media.  */
271 
272 /* Reduce the mutex error checking for testing purpose.  */
273 
274 #if defined(FX_SINGLE_THREAD) || defined(FX_STANDALONE_ENABLE)
275 #define FX_PROTECT
276 #define FX_UNPROTECT
277 #else
278 #define FX_PROTECT                      tx_mutex_get(&(media_ptr -> fx_media_protect), TX_WAIT_FOREVER);
279 #define FX_UNPROTECT                    tx_mutex_put(&(media_ptr -> fx_media_protect));
280 #endif
281 
282 
283 /* Define interrupt lockout constructs to protect the system date/time from being updated
284    while they are being read.  */
285 
286 #ifndef FX_STANDALONE_ENABLE
287 #define FX_INT_SAVE_AREA                unsigned int  old_interrupt_posture;
288 #define FX_DISABLE_INTS                 old_interrupt_posture =  tx_interrupt_control(TX_INT_DISABLE);
289 #define FX_RESTORE_INTS                 tx_interrupt_control(old_interrupt_posture);
290 #else
291 /* Disable use of ThreadX protection in standalone mode for FileX */
292 #ifndef FX_LEGACY_INTERRUPT_PROTECTION
293 #define FX_LEGACY_INTERRUPT_PROTECTION
294 #endif
295 #define FX_INT_SAVE_AREA
296 #define FX_DISABLE_INTS
297 #define FX_RESTORE_INTS
298 #endif
299 
300 /* Define the error checking logic to determine if there is a caller error in the FileX API.
301    The default definitions assume ThreadX is being used.  This code can be completely turned
302    off by just defining these macros to white space.  */
303 
304 #ifndef FX_STANDALONE_ENABLE
305 #ifndef TX_TIMER_PROCESS_IN_ISR
306 
307 #define FX_CALLER_CHECKING_EXTERNS      extern  TX_THREAD      *_tx_thread_current_ptr; \
308                                         extern  TX_THREAD       _tx_timer_thread; \
309                                         extern  volatile ULONG  _tx_thread_system_state;
310 
311 #define FX_CALLER_CHECKING_CODE         if ((_tx_thread_system_state) || \
312                                             (_tx_thread_current_ptr == TX_NULL) || \
313                                             (_tx_thread_current_ptr == &_tx_timer_thread)) \
314                                             return(FX_CALLER_ERROR);
315 
316 #else
317 #define FX_CALLER_CHECKING_EXTERNS      extern  TX_THREAD      *_tx_thread_current_ptr; \
318                                         extern  volatile ULONG  _tx_thread_system_state;
319 
320 #define FX_CALLER_CHECKING_CODE         if ((_tx_thread_system_state) || \
321                                             (_tx_thread_current_ptr == TX_NULL)) \
322                                             return(FX_CALLER_ERROR);
323 #endif
324 #else
325 #define FX_CALLER_CHECKING_EXTERNS
326 #define FX_CALLER_CHECKING_CODE
327 #endif
328 
329 /* Define the update rate of the system timer.  These values may also be defined at the command
330    line when compiling the fx_system_initialize.c module in the FileX library build.  Alternatively, they can
331    be modified in this file.  Note: the update rate must be an even number of seconds greater
332    than or equal to 2, which is the minimal update rate for FAT time. */
333 
334 #ifndef FX_UPDATE_RATE_IN_SECONDS
335 #define FX_UPDATE_RATE_IN_SECONDS       10     /* Update time at 10 second intervals */
336 #endif
337 
338 #ifndef FX_UPDATE_RATE_IN_TICKS
339 #define FX_UPDATE_RATE_IN_TICKS         1000   /* Same update rate, but in ticks  */
340 #endif
341 
342 
343 /* Define the version ID of FileX.  This may be utilized by the application.  */
344 
345 #ifdef FX_SYSTEM_INIT
346 CHAR                            _fx_version_id[] =
347                                     "Copyright (c) 2024 Microsoft Corporation.  *  FileX Linux/GCC Version 6.4.1 *";
348 #else
349 extern  CHAR                    _fx_version_id[];
350 #endif
351 
352 #endif
353 
354