txm_module_port.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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. /** ThreadX Component */
  14. /** */
  15. /** Module */
  16. /** */
  17. /**************************************************************************/
  18. /**************************************************************************/
  19. /**************************************************************************/
  20. /* */
  21. /* APPLICATION INTERFACE DEFINITION RELEASE */
  22. /* */
  23. /* txm_module_port.h Nuclei RISC-V */
  24. /* 6.2.1 */
  25. /* AUTHOR */
  26. /* */
  27. /* Scott Larson, Microsoft Corporation */
  28. /* */
  29. /* DESCRIPTION */
  30. /* */
  31. /* This file defines the basic module constants, interface structures, */
  32. /* and function prototypes. */
  33. /* */
  34. /* RELEASE HISTORY */
  35. /* */
  36. /* DATE NAME DESCRIPTION */
  37. /* */
  38. /* 10-15-2021 Scott Larson Initial Version 6.1.9 */
  39. /* 01-31-2022 Scott Larson Modified comments and made */
  40. /* heap user-configurable, */
  41. /* resulting in version 6.1.10 */
  42. /* 07-29-2022 Scott Larson Enabled user-defined and */
  43. /* default MPU settings, */
  44. /* resulting in version 6.1.12 */
  45. /* 10-31-2022 Scott Larson Configure heap size, */
  46. /* resulting in version 6.2.0 */
  47. /* 03-08-2023 Scott Larson Set default values for RBAR, */
  48. /* unify this file for all */
  49. /* compilers, */
  50. /* resulting in version 6.2.1 */
  51. /* */
  52. /**************************************************************************/
  53. #ifndef TXM_MODULE_PORT_H
  54. #define TXM_MODULE_PORT_H
  55. /* Determine if the optional Modules user define file should be used. */
  56. #ifdef TXM_MODULE_INCLUDE_USER_DEFINE_FILE
  57. /* Yes, include the user defines in txm_module_user.h. The defines in this file may
  58. alternately be defined on the command line. */
  59. #include "txm_module_user.h"
  60. #endif
  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. #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
  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. ULONG tx_thread_module_saved_lr; \
  70. VOID *tx_thread_module_kernel_stack_start; \
  71. VOID *tx_thread_module_kernel_stack_end; \
  72. ULONG tx_thread_module_kernel_stack_size; \
  73. VOID *tx_thread_module_stack_ptr; \
  74. VOID *tx_thread_module_stack_start; \
  75. VOID *tx_thread_module_stack_end; \
  76. ULONG tx_thread_module_stack_size; \
  77. VOID *tx_thread_module_reserved; \
  78. VOID *tx_thread_iar_tls_pointer;
  79. #else
  80. #define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \
  81. VOID *tx_thread_module_entry_info_ptr; \
  82. ULONG tx_thread_module_current_user_mode; \
  83. ULONG tx_thread_module_user_mode; \
  84. ULONG tx_thread_module_saved_lr; \
  85. VOID *tx_thread_module_kernel_stack_start; \
  86. VOID *tx_thread_module_kernel_stack_end; \
  87. ULONG tx_thread_module_kernel_stack_size; \
  88. VOID *tx_thread_module_stack_ptr; \
  89. VOID *tx_thread_module_stack_start; \
  90. VOID *tx_thread_module_stack_end; \
  91. ULONG tx_thread_module_stack_size; \
  92. VOID *tx_thread_module_reserved;
  93. #endif
  94. The following extensions must also be defined in tx_port.h:
  95. #define TX_EVENT_FLAGS_GROUP_EXTENSION VOID *tx_event_flags_group_module_instance; \
  96. VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr);
  97. #define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \
  98. VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr);
  99. #define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \
  100. VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
  101. #define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \
  102. VOID (*tx_timer_module_expiration_function)(ULONG id);
  103. */
  104. /* Users can define the module heap size. */
  105. #ifndef TXM_MODULE_HEAP_SIZE
  106. #define TXM_MODULE_HEAP_SIZE 512
  107. #endif
  108. /* Define the kernel stack size for a module thread. */
  109. #ifndef TXM_MODULE_KERNEL_STACK_SIZE
  110. #define TXM_MODULE_KERNEL_STACK_SIZE 768
  111. #endif
  112. /* Define constants specific to the tools the module can be built with for this particular modules port. */
  113. #define TXM_MODULE_IAR_COMPILER 0x00000000
  114. #define TXM_MODULE_GNU_COMPILER 0x02000000
  115. #define TXM_MODULE_COMPILER_MASK 0xFF000000
  116. #define TXM_MODULE_OPTIONS_MASK 0x000000FF
  117. /* Define the properties for this particular module port. */
  118. // #define TXM_MODULE_MEMORY_PROTECTION_ENABLED
  119. #ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED
  120. #define TXM_MODULE_REQUIRE_ALLOCATED_OBJECT_MEMORY
  121. #else
  122. #define TXM_MODULE_REQUIRE_LOCAL_OBJECT_MEMORY
  123. #endif
  124. #define TXM_MODULE_USER_MODE 0x00000001
  125. #define TXM_MODULE_MEMORY_PROTECTION 0x00000002
  126. #define TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS 0x00000004
  127. /* Define the supported options for this module. */
  128. #define TXM_MODULE_MANAGER_SUPPORTED_OPTIONS (0)
  129. #define TXM_MODULE_MANAGER_REQUIRED_OPTIONS 0
  130. /* Define offset adjustments according to the compiler used to build the module. */
  131. #define TXM_MODULE_IAR_SHELL_ADJUST (6 * sizeof(ULONG))
  132. #define TXM_MODULE_IAR_START_ADJUST (7 * sizeof(ULONG))
  133. #define TXM_MODULE_IAR_STOP_ADJUST (8 * sizeof(ULONG))
  134. #define TXM_MODULE_IAR_CALLBACK_ADJUST (11 * sizeof(ULONG))
  135. #define TXM_MODULE_GNU_SHELL_ADJUST (6 * sizeof(ULONG))
  136. #define TXM_MODULE_GNU_START_ADJUST (7 * sizeof(ULONG))
  137. #define TXM_MODULE_GNU_STOP_ADJUST (8 * sizeof(ULONG))
  138. #define TXM_MODULE_GNU_CALLBACK_ADJUST (11 * sizeof(ULONG))
  139. /* Define other module port-specific constants. */
  140. /* Define INLINE_DECLARE to inline for this compiler. */
  141. #define INLINE_DECLARE inline
  142. /* Shared memory region attributes. */
  143. #define TXM_MODULE_MANAGER_SHARED_ATTRIBUTE_WRITE 1
  144. #ifdef TXM_MODULE_MANAGER_PMP
  145. /* Define the port-extensions to the module manager instance structure. */
  146. #define TXM_MODULE_MANAGER_PORT_EXTENSION
  147. #else /* TXM_MODULE_MANAGER_PMP is not defined */
  148. /* Define the port-extensions to the module manager instance structure. */
  149. #define TXM_MODULE_MANAGER_PORT_EXTENSION
  150. #endif /* TXM_MODULE_MANAGER_PMP */
  151. /* Define the memory fault information structure that is populated when a memory fault occurs. */
  152. typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT
  153. {
  154. TX_THREAD *txm_module_manager_memory_fault_info_thread_ptr;
  155. VOID *txm_module_manager_memory_fault_info_code_location;
  156. ULONG txm_module_manager_memory_fault_info_shcsr;
  157. ULONG txm_module_manager_memory_fault_info_cfsr;
  158. ULONG txm_module_manager_memory_fault_info_mmfar;
  159. ULONG txm_module_manager_memory_fault_info_bfar;
  160. ULONG txm_module_manager_memory_fault_info_control;
  161. ULONG txm_module_manager_memory_fault_info_sp;
  162. ULONG txm_module_manager_memory_fault_info_r0;
  163. ULONG txm_module_manager_memory_fault_info_r1;
  164. ULONG txm_module_manager_memory_fault_info_r2;
  165. ULONG txm_module_manager_memory_fault_info_r3;
  166. ULONG txm_module_manager_memory_fault_info_r4;
  167. ULONG txm_module_manager_memory_fault_info_r5;
  168. ULONG txm_module_manager_memory_fault_info_r6;
  169. ULONG txm_module_manager_memory_fault_info_r7;
  170. ULONG txm_module_manager_memory_fault_info_r8;
  171. ULONG txm_module_manager_memory_fault_info_r9;
  172. ULONG txm_module_manager_memory_fault_info_r10;
  173. ULONG txm_module_manager_memory_fault_info_r11;
  174. ULONG txm_module_manager_memory_fault_info_r12;
  175. ULONG txm_module_manager_memory_fault_info_lr;
  176. ULONG txm_module_manager_memory_fault_info_xpsr;
  177. } TXM_MODULE_MANAGER_MEMORY_FAULT_INFO;
  178. #define TXM_MODULE_MANAGER_FAULT_INFO \
  179. TXM_MODULE_MANAGER_MEMORY_FAULT_INFO _txm_module_manager_memory_fault_info;
  180. /* Define the macro to check the code alignment. */
  181. #define TXM_MODULE_MANAGER_CHECK_CODE_ALIGNMENT(module_location, code_alignment) \
  182. { \
  183. ULONG temp; \
  184. temp = (ULONG) module_location; \
  185. temp = temp & (code_alignment - 1); \
  186. if (temp) \
  187. { \
  188. _tx_mutex_put(&_txm_module_manager_mutex); \
  189. return(TXM_MODULE_ALIGNMENT_ERROR); \
  190. } \
  191. }
  192. /* Define the macro to adjust the alignment and size for code/data areas. */
  193. #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);
  194. /* Define the macro to adjust the symbols in the module preamble. */
  195. #define TXM_MODULE_MANAGER_CALCULATE_ADJUSTMENTS(properties, shell_function_adjust, start_function_adjust, stop_function_adjust, callback_function_adjust) \
  196. if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_IAR_COMPILER) \
  197. { \
  198. shell_function_adjust = TXM_MODULE_IAR_SHELL_ADJUST; \
  199. start_function_adjust = TXM_MODULE_IAR_START_ADJUST; \
  200. stop_function_adjust = TXM_MODULE_IAR_STOP_ADJUST; \
  201. callback_function_adjust = TXM_MODULE_IAR_CALLBACK_ADJUST; \
  202. } \
  203. else \
  204. { \
  205. shell_function_adjust = TXM_MODULE_GNU_SHELL_ADJUST; \
  206. start_function_adjust = TXM_MODULE_GNU_START_ADJUST; \
  207. stop_function_adjust = TXM_MODULE_GNU_STOP_ADJUST; \
  208. callback_function_adjust = TXM_MODULE_GNU_CALLBACK_ADJUST; \
  209. }
  210. /* Define the macro to populate the thread control block with module port-specific information.
  211. Check if the module is in user mode and set up txm_module_thread_entry_info_kernel_call_dispatcher accordingly.
  212. */
  213. // TODO only M-mode execution is supported now
  214. #define TXM_MODULE_MANAGER_THREAD_SETUP(thread_ptr, module_instance) \
  215. thread_ptr -> tx_thread_module_current_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_USER_MODE; \
  216. thread_ptr -> tx_thread_module_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_USER_MODE; \
  217. if (thread_ptr -> tx_thread_module_user_mode) \
  218. { \
  219. thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_user_mode_entry; \
  220. } \
  221. else \
  222. { \
  223. thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_kernel_dispatch; \
  224. }
  225. /* Define the macro to populate the module control block with module port-specific information.
  226. If memory protection is enabled, set up the MPU registers.
  227. */
  228. #define TXM_MODULE_MANAGER_MODULE_SETUP(module_instance) \
  229. if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_USER_MODE) \
  230. { \
  231. if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION) \
  232. { \
  233. _txm_module_manager_mm_register_setup(module_instance); \
  234. } \
  235. } \
  236. else \
  237. { \
  238. /* Do nothing. */ \
  239. }
  240. /* Define the macro to perform port-specific functions when unloading the module. */
  241. /* Nothing needs to be done for this port. */
  242. #define TXM_MODULE_MANAGER_MODULE_UNLOAD(module_instance)
  243. /* Define the macros to perform port-specific checks when passing pointers to the kernel. */
  244. /* Define macro to make sure object is inside the module's data. */
  245. /* TODO: TXM_MODULE_MANAGER_PMP is not implemented */
  246. #ifdef TXM_MODULE_MANAGER_PMP
  247. #define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \
  248. _txm_module_manager_inside_data_check(module_instance, obj_ptr, obj_size)
  249. #else
  250. #define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \
  251. /* Check for overflow. */ \
  252. (((obj_ptr) < ((obj_ptr) + (obj_size))) && \
  253. /* Check if it's inside module data. */ \
  254. ((((obj_ptr) >= (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) && \
  255. (((obj_ptr) + (obj_size)) <= ((ALIGN_TYPE) module_instance -> txm_module_instance_data_end + 1)))))
  256. #endif
  257. /* Define some internal prototypes to this module port. */
  258. #ifndef TX_SOURCE_CODE
  259. #define txm_module_manager_memory_fault_notify _txm_module_manager_memory_fault_notify
  260. #endif
  261. #define TXM_MODULE_MANAGER_ADDITIONAL_PROTOTYPES \
  262. VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *code_size, ULONG *code_alignment, ULONG *data_size, ULONG *data_alignment); \
  263. VOID _txm_module_manager_memory_fault_handler(VOID); \
  264. UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *)); \
  265. VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance); \
  266. UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE obj_ptr, UINT obj_size);
  267. #define TXM_MODULE_MANAGER_VERSION_ID \
  268. CHAR _txm_module_manager_version_id[] = \
  269. "Copyright (c) 2024 Microsoft Corporation. * ThreadX Module Nuclei RISC-V Version 6.4.1 *";
  270. #endif