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 /** ThreadX Component */ 17 /** */ 18 /** Module */ 19 /** */ 20 /**************************************************************************/ 21 /**************************************************************************/ 22 23 24 /**************************************************************************/ 25 /* */ 26 /* APPLICATION INTERFACE DEFINITION RELEASE */ 27 /* */ 28 /* txm_module_port.h RXv2/IAR */ 29 /* 6.1.10 */ 30 /* AUTHOR */ 31 /* */ 32 /* Scott Larson, Microsoft Corporation */ 33 /* */ 34 /* DESCRIPTION */ 35 /* */ 36 /* This file defines the basic module constants, interface structures, */ 37 /* and function prototypes. */ 38 /* */ 39 /* RELEASE HISTORY */ 40 /* */ 41 /* DATE NAME DESCRIPTION */ 42 /* */ 43 /* 01-31-2022 Scott Larson Initial Version 6.1.10 */ 44 /* */ 45 /**************************************************************************/ 46 47 #ifndef TXM_MODULE_PORT_H 48 #define TXM_MODULE_PORT_H 49 50 /* Determine if the optional Modules user define file should be used. */ 51 52 #ifdef TXM_MODULE_INCLUDE_USER_DEFINE_FILE 53 54 55 /* Yes, include the user defines in txm_module_user.h. The defines in this file may 56 alternately be defined on the command line. */ 57 58 #include "txm_module_user.h" 59 #endif 60 61 /* It is assumed that the base ThreadX tx_port.h file has been modified to add the 62 following extensions to the ThreadX thread control block (this code should replace 63 the corresponding macro define in tx_port.h): 64 65 #define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ 66 VOID *tx_thread_module_entry_info_ptr; \ 67 ULONG tx_thread_module_current_user_mode; \ 68 ULONG tx_thread_module_user_mode; \ 69 VOID *tx_thread_module_kernel_stack_start; \ 70 VOID *tx_thread_module_kernel_stack_end; \ 71 ULONG tx_thread_module_kernel_stack_size; \ 72 VOID *tx_thread_module_stack_ptr; \ 73 VOID *tx_thread_module_stack_start; \ 74 VOID *tx_thread_module_stack_end; \ 75 ULONG tx_thread_module_stack_size; \ 76 VOID *tx_thread_module_reserved; \ 77 VOID *tx_thread_iar_tls_pointer; 78 79 The following extensions must also be defined in tx_port.h: 80 81 #define TX_EVENT_FLAGS_GROUP_EXTENSION VOID *tx_event_flags_group_module_instance; \ 82 VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr); 83 84 #define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \ 85 VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr); 86 87 #define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \ 88 VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr); 89 90 #define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \ 91 VOID (*tx_timer_module_expiration_function)(ULONG id); 92 */ 93 94 #define TXM_MODULE_THREAD_ENTRY_INFO_USER_EXTENSION 95 96 /* Define constants specific to the tools the module can be built with for this particular modules port. */ 97 98 #define TXM_MODULE_IAR_COMPILER 0x00000000 99 #define TXM_MODULE_RVDS_COMPILER 0x01000000 100 #define TXM_MODULE_GNU_COMPILER 0x02000000 101 #define TXM_MODULE_COMPILER_MASK 0xFF000000 102 #define TXM_MODULE_OPTIONS_MASK 0x000000FF 103 104 105 /* Define the properties for this particular module port. */ 106 107 #define TXM_MODULE_MEMORY_PROTECTION_ENABLED 108 #ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED 109 #define TXM_MODULE_REQUIRE_ALLOCATED_OBJECT_MEMORY 110 #else 111 #define TXM_MODULE_REQUIRE_LOCAL_OBJECT_MEMORY 112 #endif 113 114 #define TXM_MODULE_USER_MODE 0x00000001 115 #define TXM_MODULE_MEMORY_PROTECTION 0x00000002 116 #define TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS 0x00000004 117 118 /* Define the kernel stack size for a module thread. */ 119 #ifndef TXM_MODULE_KERNEL_STACK_SIZE 120 #define TXM_MODULE_KERNEL_STACK_SIZE 512 121 #endif 122 123 124 /* Define the supported options for this module. */ 125 126 #define TXM_MODULE_MANAGER_SUPPORTED_OPTIONS (TXM_MODULE_USER_MODE | TXM_MODULE_MEMORY_PROTECTION | TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS) 127 #define TXM_MODULE_MANAGER_REQUIRED_OPTIONS 0 128 129 130 /* Define offset adjustments according to the compiler used to build the module. */ 131 132 #define TXM_MODULE_IAR_SHELL_ADJUST 24 133 #define TXM_MODULE_IAR_START_ADJUST 28 134 #define TXM_MODULE_IAR_STOP_ADJUST 32 135 #define TXM_MODULE_IAR_CALLBACK_ADJUST 44 136 137 #define TXM_MODULE_RVDS_SHELL_ADJUST 0 138 #define TXM_MODULE_RVDS_START_ADJUST 0 139 #define TXM_MODULE_RVDS_STOP_ADJUST 0 140 #define TXM_MODULE_RVDS_CALLBACK_ADJUST 0 141 142 #define TXM_MODULE_GNU_SHELL_ADJUST 24 143 #define TXM_MODULE_GNU_START_ADJUST 28 144 #define TXM_MODULE_GNU_STOP_ADJUST 32 145 #define TXM_MODULE_GNU_CALLBACK_ADJUST 44 146 147 148 /* Define other module port-specific constants. */ 149 150 /* Define INLINE_DECLARE to inline for IAR compiler. */ 151 152 #define INLINE_DECLARE inline 153 154 /* Define the data area alignment mask, must be a power of 2. */ 155 156 #ifndef TXM_MODULE_DATA_ALIGNMENT 157 #define TXM_MODULE_DATA_ALIGNMENT 16 158 #endif 159 160 161 /* Define the code area alignment mask, must be a power of 2. */ 162 163 #ifndef TXM_MODULE_CODE_ALIGNMENT 164 #define TXM_MODULE_CODE_ALIGNMENT 16 165 #endif 166 167 168 /* Define the number of MPU entries assigned to the code and data sections. */ 169 170 #define TXM_MODULE_MANAGER_CODE_MPU_ENTRIES 2 171 #define TXM_MODULE_MANAGER_DATA_MPU_ENTRIES 1 172 173 /* Total MPU entries available. */ 174 #define TXM_MODULE_MANAGER_RX_MPU_ENTRIES 8 175 #define TXM_MODULE_MANAGER_REGISTERS_PER_MPU_ENTRY 2 176 #define TXM_MODULE_MANAGER_MPU_TABLE_SIZE (TXM_MODULE_MANAGER_RX_MPU_ENTRIES * TXM_MODULE_MANAGER_REGISTERS_PER_MPU_ENTRY) 177 178 /* Shared memory MPU index. */ 179 #define TXM_MODULE_MANAGER_SHARED_MPU_INDEX 6 180 181 /* Addresses of MPU registers for trampoline protection. */ 182 #define RSPAGE0 (*(ULONG *) 0x00086400) 183 #define REPAGE0 (*(ULONG *) 0x00086404) 184 185 /* Shared memory region attributes. */ 186 #define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_EXECUTE 1 187 #define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE 2 188 #define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_READ 4 189 190 #define TXM_MODULE_MANAGER_ATTRIBUTE_EXECUTE_MPU_BIT (TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_EXECUTE << 1) 191 #define TXM_MODULE_MANAGER_ATTRIBUTE_WRITE_MPU_BIT (TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE << 1) 192 #define TXM_MODULE_MANAGER_ATTRIBUTE_READ_MPU_BIT (TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_READ << 1) 193 194 /* Define the port-extensions to the module manager instance structure. */ 195 196 #define TXM_MODULE_MANAGER_PORT_EXTENSION \ 197 ULONG txm_module_instance_mpu_registers[TXM_MODULE_MANAGER_MPU_TABLE_SIZE]; \ 198 ULONG txm_module_instance_shared_memory_address; \ 199 ULONG txm_module_instance_shared_memory_length; 200 201 202 /* Define the memory fault information structure that is populated when a memory fault occurs. */ 203 204 205 typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT 206 { 207 TX_THREAD *txm_module_manager_memory_fault_info_thread_ptr; 208 VOID *txm_module_manager_memory_fault_info_code_location; 209 ULONG txm_module_manager_memory_fault_info_mpests; 210 ULONG txm_module_manager_memory_fault_info_mpdea; 211 ULONG txm_module_manager_memory_fault_info_mhiti; 212 ULONG txm_module_manager_memory_fault_info_mhitd; 213 ULONG txm_module_manager_memory_fault_info_psw; 214 ULONG txm_module_manager_memory_fault_info_sp; 215 ULONG txm_module_manager_memory_fault_info_r1; 216 ULONG txm_module_manager_memory_fault_info_r2; 217 ULONG txm_module_manager_memory_fault_info_r3; 218 ULONG txm_module_manager_memory_fault_info_r4; 219 ULONG txm_module_manager_memory_fault_info_r5; 220 ULONG txm_module_manager_memory_fault_info_r6; 221 ULONG txm_module_manager_memory_fault_info_r7; 222 ULONG txm_module_manager_memory_fault_info_r8; 223 ULONG txm_module_manager_memory_fault_info_r9; 224 ULONG txm_module_manager_memory_fault_info_r10; 225 ULONG txm_module_manager_memory_fault_info_r11; 226 ULONG txm_module_manager_memory_fault_info_r12; 227 ULONG txm_module_manager_memory_fault_info_r13; 228 ULONG txm_module_manager_memory_fault_info_r14; 229 ULONG txm_module_manager_memory_fault_info_r15; 230 } TXM_MODULE_MANAGER_MEMORY_FAULT_INFO; 231 232 233 #define TXM_MODULE_MANAGER_FAULT_INFO \ 234 TXM_MODULE_MANAGER_MEMORY_FAULT_INFO _txm_module_manager_memory_fault_info; 235 236 /* Define the macro to check the stack available in dispatch. */ 237 //#define TXM_MODULE_MANAGER_CHECK_STACK_AVAILABLE \ 238 // ULONG stack_available; \ 239 // __asm("MOV SP, %0" : "=r"(stack_available)); \ 240 // stack_available -= (ULONG)_tx_thread_current_ptr->tx_thread_stack_start; \ 241 // if((stack_available < TXM_MODULE_MINIMUM_STACK_AVAILABLE) || \ 242 // (stack_available > _tx_thread_current_ptr->tx_thread_stack_size)) \ 243 // { \ 244 // return(TX_SIZE_ERROR); \ 245 // } 246 247 /* Define the macro to check the module version ID. */ 248 249 #define TXM_MODULE_MANAGER_CHECK_PROPERTIES(properties) \ 250 if ((properties & _txm_module_manager_properties_supported) != (properties & ~((ULONG) TXM_MODULE_COMPILER_MASK))) \ 251 { \ 252 _tx_mutex_put(&_txm_module_manager_mutex); \ 253 return(TXM_MODULE_INVALID_PROPERTIES); \ 254 } \ 255 if ((_txm_module_manager_properties_required & properties) != _txm_module_manager_properties_required) \ 256 { \ 257 _tx_mutex_put(&_txm_module_manager_mutex); \ 258 return(TXM_MODULE_INVALID_PROPERTIES); \ 259 } 260 261 262 /* Define the macro to check the code alignment. */ 263 264 #define TXM_MODULE_MANAGER_CHECK_CODE_ALIGNMENT(module_location, code_alignment) \ 265 { \ 266 ULONG temp; \ 267 temp = (ULONG) module_location; \ 268 temp = temp & (code_alignment - 1); \ 269 if (temp) \ 270 { \ 271 _tx_mutex_put(&_txm_module_manager_mutex); \ 272 return(TXM_MODULE_ALIGNMENT_ERROR); \ 273 } \ 274 } 275 276 277 /* Define the macro to adjust the alignment and size for code/data areas. */ 278 279 #define TXM_MODULE_MANAGER_ALIGNMENT_ADJUST(module_preamble, code_size, code_alignment, data_size, data_alignment) _txm_module_manager_alignment_adjust(module_preamble, &code_size, &code_alignment, &data_size, &data_alignment); 280 281 282 /* Define the macro to adjust the symbols in the module preamble. */ 283 284 #define TXM_MODULE_MANAGER_CALCULATE_ADJUSTMENTS(properties, shell_function_adjust, start_function_adjust, stop_function_adjust, callback_function_adjust) \ 285 if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_IAR_COMPILER) \ 286 { \ 287 shell_function_adjust = TXM_MODULE_IAR_SHELL_ADJUST; \ 288 start_function_adjust = TXM_MODULE_IAR_START_ADJUST - (ULONG)(module_instance -> txm_module_instance_code_start); \ 289 stop_function_adjust = TXM_MODULE_IAR_STOP_ADJUST - (ULONG)(module_instance -> txm_module_instance_code_start); \ 290 callback_function_adjust = TXM_MODULE_IAR_CALLBACK_ADJUST - (ULONG)(module_instance -> txm_module_instance_code_start); \ 291 } \ 292 else if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_RVDS_COMPILER) \ 293 { \ 294 shell_function_adjust = TXM_MODULE_RVDS_SHELL_ADJUST; \ 295 start_function_adjust = TXM_MODULE_RVDS_START_ADJUST; \ 296 stop_function_adjust = TXM_MODULE_RVDS_STOP_ADJUST; \ 297 callback_function_adjust = TXM_MODULE_RVDS_CALLBACK_ADJUST; \ 298 } \ 299 else \ 300 { \ 301 shell_function_adjust = TXM_MODULE_GNU_SHELL_ADJUST; \ 302 start_function_adjust = TXM_MODULE_GNU_START_ADJUST; \ 303 stop_function_adjust = TXM_MODULE_GNU_STOP_ADJUST; \ 304 callback_function_adjust = TXM_MODULE_GNU_CALLBACK_ADJUST; \ 305 } 306 307 308 /* Define the macro to populate the thread control block with module port-specific information. 309 Check if the module is in user mode and set up txm_module_thread_entry_info_kernel_call_dispatcher accordingly. 310 */ 311 #define TXM_MODULE_MANAGER_THREAD_SETUP(thread_ptr, module_instance) \ 312 thread_ptr -> tx_thread_module_current_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_USER_MODE; \ 313 thread_ptr -> tx_thread_module_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_USER_MODE; \ 314 if (thread_ptr -> tx_thread_module_user_mode) \ 315 { \ 316 *(ULONG*)&(thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher) = \ 317 (ULONG)_txm_module_manager_user_mode_entry - (ULONG)module_instance -> txm_module_instance_code_start; \ 318 } \ 319 else \ 320 { \ 321 *(ULONG*)&(thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher) = \ 322 (ULONG)_txm_module_manager_kernel_dispatch - (ULONG)module_instance -> txm_module_instance_code_start; \ 323 } 324 325 /* Define the macro to populate the module control block with module port-specific information. 326 If memory protection is enabled, set up the MPU registers. 327 */ 328 #define TXM_MODULE_MANAGER_MODULE_SETUP(module_instance) \ 329 if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_USER_MODE) \ 330 { \ 331 if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION) \ 332 { \ 333 _txm_module_manager_setup_mpu_registers(module_instance); \ 334 } \ 335 } \ 336 else \ 337 { \ 338 /* Do nothing. */ \ 339 } 340 341 /* Define the macro to perform port-specific functions when unloading the module. */ 342 /* Nothing needs to be done for this port. */ 343 #define TXM_MODULE_MANAGER_MODULE_UNLOAD(module_instance) 344 345 346 /* Define the macro to perform port-specific functions when passing pointer to kernel. */ 347 /* Determine if the pointer is within the module's data or shared memory. */ 348 //#define TXM_MODULE_MANAGER_CHECK_DATA_POINTER(module_instance, pointer) \ 349 // if ((pointer < (ULONG) module_instance -> txm_module_instance_data_start) || \ 350 // ((pointer+sizeof(pointer)) > (ULONG) module_instance -> txm_module_instance_data_end)) \ 351 // { \ 352 // if((pointer < module_instance -> txm_module_instance_shared_memory_address) || \ 353 // ((pointer+sizeof(pointer)) > module_instance -> txm_module_instance_shared_memory_address \ 354 // + module_instance -> txm_module_instance_shared_memory_length)) \ 355 // { \ 356 // return(TXM_MODULE_INVALID_MEMORY); \ 357 // } \ 358 // } 359 360 /* Define the macro to perform port-specific functions when passing function pointer to kernel. */ 361 /* Determine if the pointer is within the module's code memory. */ 362 //#define TXM_MODULE_MANAGER_CHECK_FUNCTION_POINTER(module_instance, pointer) \ 363 // if (((pointer < sizeof(TXM_MODULE_PREAMBLE)) || \ 364 // ((pointer+sizeof(pointer)) > ((ULONG) module_instance -> txm_module_instance_code_end - \ 365 // (ULONG) module_instance -> txm_module_instance_code_start))) \ 366 // && (pointer != (ULONG) TX_NULL)) \ 367 // { \ 368 // return(TX_PTR_ERROR); \ 369 // } 370 371 /* Define macro to make sure object is inside the module's data. */ 372 #define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \ 373 /* Check for overflow. */ \ 374 (((obj_ptr) < ((obj_ptr) + (obj_size))) && \ 375 /* Check if it's inside module data. */ \ 376 ((((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) && \ 377 (((obj_ptr) + (obj_size)) <= ((ALIGN_TYPE) module_instance -> txm_module_instance_data_end + 1))) || \ 378 /* Check if it's inside shared memory. */ \ 379 (((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_shared_memory_address) && \ 380 (((obj_ptr) + (obj_size)) <= (ALIGN_TYPE) (module_instance -> txm_module_instance_shared_memory_address + module_instance -> txm_module_instance_shared_memory_length))))) 381 382 383 /* Define some internal prototypes to this module port. */ 384 385 #ifndef TX_SOURCE_CODE 386 #define txm_module_manager_memory_fault_notify _txm_module_manager_memory_fault_notify 387 #endif 388 389 390 #define TXM_MODULE_MANAGER_ADDITIONAL_PROTOTYPES \ 391 VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *code_size, ULONG *code_alignment, ULONG *data_size, ULONG *data_alignment); \ 392 VOID _txm_module_manager_memory_fault_handler(VOID); \ 393 UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *)); \ 394 VOID _txm_module_manager_setup_mpu_registers(TXM_MODULE_INSTANCE *module_instance); 395 396 397 #define TXM_MODULE_MANAGER_VERSION_ID \ 398 CHAR _txm_module_manager_version_id[] = \ 399 "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module RXv2/IAR Version 6.3.0 *"; 400 401 #endif 402