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