1 
2 /***************************************************************************
3  * Copyright (c) 2024 Microsoft Corporation
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the MIT License which is available at
7  * https://opensource.org/licenses/MIT.
8  *
9  * SPDX-License-Identifier: MIT
10  **************************************************************************/
11 
12 /**************************************************************************/
13 /**                                                                       */
14 /** ThreadX Component                                                     */
15 /**                                                                       */
16 /**   Port Specific                                                       */
17 /**                                                                       */
18 /**************************************************************************/
19 
20 /**************************************************************************/
21 /*                                                                        */
22 /*  DESCRIPTION                                                           */
23 /*                                                                        */
24 /*    This file contains data type definitions that make the ThreadX      */
25 /*    real-time kernel function identically on a variety of different     */
26 /*    processor architectures.  For example, the size or number of bits   */
27 /*    in an "int" data type vary between microprocessor architectures and */
28 /*    even C compilers for the same microprocessor.  ThreadX does not     */
29 /*    directly use native C data types.  Instead, ThreadX creates its     */
30 /*    own special types that can be mapped to actual data types by this   */
31 /*    file to guarantee consistency in the interface and functionality.   */
32 /*                                                                        */
33 /*  RELEASE HISTORY                                                       */
34 /*                                                                        */
35 /*    DATE              NAME                      DESCRIPTION             */
36 /*                                                                        */
37 /*  11-09-2020      Cadence Design Systems  Initial Version 6.1.2         */
38 /*  04-02-2021      Bhupendra Naphade       Modified comment(s), updated  */
39 /*                                            macro definition,           */
40 /*                                            resulting in version 6.1.6  */
41 /*  10-31-2022      Scott Larson            Modified comment(s), removed  */
42 /*                                            EPK extension,              */
43 /*                                            resulting in version 6.2.0  */
44 /*                                                                        */
45 /**************************************************************************/
46 
47 #ifndef TX_PORT_H
48 #define TX_PORT_H
49 
50 /* Determine if the optional ThreadX user define file should be used.  */
51 
52 #ifdef TX_INCLUDE_USER_DEFINE_FILE
53 #include "tx_user.h"
54 #endif
55 
56 /* Comment this out to disable thread-safe C library support. */
57 #define TX_THREAD_SAFE_CLIB    1
58 
59 /* Include the glue to Xtensa-generic parts of this ThreadX port. */
60 #include "xtensa_rtos.h"
61 
62 /* Parts of this file should not been seen by assembler sources. */
63 #ifndef __ASSEMBLER__
64 
65 /* Some generic C sources call memset() and need this (else compiler warns).
66    Until the generic sources take care of this, do it here. */
67 
68 #include <string.h>
69 
70 
71 /* Define compiler library include files and library-specific macros. */
72 
73 /*
74     Thread-safety support for the supported C libraries. At this time
75     only the newlib and Xtensa C libraries are supported.
76 
77     The C library reent structure can be quite large so it is placed
78     at the end of TX_THREAD, and a pointer to it is defined near the
79     beginning of TX_THREAD where assembly code can easily get to it
80     at a fixed offset.
81 */
82 
83 #ifdef TX_THREAD_SAFE_CLIB
84 struct TX_THREAD_STRUCT;
85 
86 extern char *_tx_clib_heap_start, *_tx_clib_heap_end;
87 extern void _tx_clib_reent_init (struct TX_THREAD_STRUCT *thread_ptr);
88 extern void _tx_clib_reent_cleanup (struct TX_THREAD_STRUCT *thread_ptr, int partial);
89 extern void _tx_clib_thread_setup(struct TX_THREAD_STRUCT *thread_ptr);
90 
91 #include    <sys/reent.h>
92 
93 #define TX_CLIB_THREAD_EXTENSION \
94     VOID                (*tx_real_thread_entry)(ULONG id);  /* Actual entry point */ \
95     struct _reent *     tx_thread_clib_ptr;                 /* C lib reentrancy ptr */
96 #define TX_CLIB_THREAD_EXTENSION_END \
97     struct _reent       tx_thread_clib_reent;               /* C lib reentrancy struct */
98 #define TX_CLIB_THREAD_CREATE_EXTENSION(thread_ptr)
99 #define TX_CLIB_THREAD_DELETE_EXTENSION(thread_ptr)
100 #define TX_CLIB_THREAD_EXIT_EXTENSION(thread_ptr)
101 #define TX_THREAD_CLIB_EXTENSION(thread_ptr) \
102     _tx_clib_thread_setup(thread_ptr);
103 #else
104 #define TX_CLIB_THREAD_EXTENSION
105 #define TX_CLIB_THREAD_EXTENSION_END
106 #define TX_CLIB_THREAD_CREATE_EXTENSION(thread_ptr)
107 #define TX_CLIB_THREAD_DELETE_EXTENSION(thread_ptr)
108 #define TX_CLIB_THREAD_EXIT_EXTENSION(thread_ptr)
109 #define TX_THREAD_CLIB_EXTENSION(thread_ptr)
110 #endif
111 
112 
113 /* Define ThreadX basic types for this port.  */
114 
115 #define VOID                                    void
116 typedef char                                    CHAR;
117 typedef unsigned char                           UCHAR;
118 typedef int                                     INT;
119 typedef unsigned int                            UINT;
120 typedef long                                    LONG;
121 typedef unsigned long                           ULONG;
122 typedef short                                   SHORT;
123 typedef unsigned short                          USHORT;
124 
125 
126 #endif /* #ifndef __ASSEMBLER__ */
127 
128 
129 /* Define the priority levels for ThreadX.  Legal values range
130    from 32 to 1024 and MUST be evenly divisible by 32.  */
131 
132 #ifndef TX_MAX_PRIORITIES
133 #define TX_MAX_PRIORITIES                       32
134 #endif
135 
136 
137 /*
138     Define the minimum stack size for a thread on this processor.
139     If the size supplied during thread creation is less than TX_MINIMUM_STACK,
140     the thread create call will return an error. The minimum allows for a
141     thread whose entry function makes no calls and needs no local frame.
142     TX_MINIMUM_STACK_BASIC allows the entry function to at least call
143     tx_thread_relinquish(). An extra 0x10 bytes is allowed in all cases to
144     allow for stack pointer alignment to 16 bytes. There is an additional premium
145     for the stack checking functionality of TX_ENABLE_STACK_CHECKING.
146     In Xtensa, all these amounts depend on the function call ABI used by the
147     configuration (in general, Call0 ABI needs about 0x20 bytes less stack space
148     per function call frame). These amounts assume no compiler optimization (-O0).
149     Optimization usually requires less stack.
150 
151     TX_MINIMUM_STACK_BASIC is a MINIMUM for threads that call tx_thread_relinquish()
152     only. Threads that do more, and in particular call C library functions such as
153     printf(), need much more stack space and it is up to the application developer
154     to determine how much.
155 */
156 
157 #ifdef __XTENSA_CALL0_ABI__
158         /* Call0 ABI */
159 
160 #ifndef TX_MINIMUM_STACK
161 #define TX_MINIMUM_STACK                        (XT_STK_FRMSZ + 0x10)
162 #endif
163 #ifdef  TX_ENABLE_STACK_CHECKING
164 #define TX_STACK_CHECK_PREMIUM                  0x30
165 #else
166 #define TX_STACK_CHECK_PREMIUM                  0
167 #endif
168 #ifndef TX_MINIMUM_STACK_BASIC
169 #define TX_MINIMUM_STACK_BASIC                  (XT_STK_FRMSZ + 0x70 + TX_STACK_CHECK_PREMIUM)
170 #endif
171 
172 #else   /* Windowed ABI */
173 
174 #ifndef TX_MINIMUM_STACK
175 #define TX_MINIMUM_STACK                        (XT_STK_FRMSZ + 0x20)
176 #endif
177 #ifdef  TX_ENABLE_STACK_CHECKING
178 #define TX_STACK_CHECK_PREMIUM                  0x50
179 #else
180 #define TX_STACK_CHECK_PREMIUM                  0
181 #endif
182 #ifndef TX_MINIMUM_STACK_BASIC
183 #define TX_MINIMUM_STACK_BASIC                  (XT_STK_FRMSZ + 0x100 + TX_STACK_CHECK_PREMIUM)
184 #endif
185 
186 #endif
187 
188 /*
189     Minimum stack size for the ThreadX system stack on this processor.
190     This is just a useful starting point for an application, it is not
191     checked by ThreadX. The minimum system stack size allows for the
192     possible depth of interrupt nesting (XCHAL_EXCM_LEVEL-1 interrupt
193     stack frames and XCHAL_EXCM_LEVEL interrupt handlers including timer),
194     assuming very basic interrupt handlers (allows 1 call12). It needs to
195     be increased to support the application's real interrupt handlers (and
196     timer interrupt if TX_TIMER_PROCESS_IN_ISR). The system stack is located
197     where the stack pointer is inside tx_kernel_enter() which is usually from
198     main(), and so is determined by the development tools. It grows downward
199     toward the first available memory pointer passed to tx_application_define().
200     An application should allow sufficient space for the system stack.
201 
202     For XEA3, allow a minimum of XCHAL_NUM_INTLEVELS nested interrupts. The stack
203     frames are minimal-sized and may need to be increased to support real applications.
204 */
205 
206 #if XCHAL_HAVE_XEA3
207 #define TX_SYSTEM_STACK_MINIMUM                 (XCHAL_NUM_INTLEVELS * 0x40)
208 #ifndef TX_SYSTEM_STACK_SIZE
209 #if TX_SYSTEM_STACK_MINIMUM > 2048
210 #define TX_SYSTEM_STACK_SIZE                    TX_SYSTEM_STACK_MINIMUM
211 #else
212 #define TX_SYSTEM_STACK_SIZE                    2048
213 #endif
214 #endif
215 #else
216 #define TX_SYSTEM_STACK_MINIMUM                 (((XCHAL_EXCM_LEVEL-1) * (0x40 + XT_STK_FRMSZ)) + 0x40)
217 #ifndef TX_SYSTEM_STACK_SIZE
218 #define TX_SYSTEM_STACK_SIZE                    4096
219 #endif
220 #endif
221 
222 /*
223     Define the system timer thread's default stack size and priority.
224     These are only applicable if TX_TIMER_PROCESS_IN_ISR is not defined.
225 */
226 
227 #ifndef TX_TIMER_THREAD_STACK_SIZE
228 #ifdef __XTENSA_CALL0_ABI__
229 #define TX_TIMER_THREAD_STACK_SIZE              (TX_MINIMUM_STACK_BASIC + 0x100)
230 #else
231 #define TX_TIMER_THREAD_STACK_SIZE              (TX_MINIMUM_STACK_BASIC + 0x200)
232 #endif
233 #endif
234 
235 
236 /* Parts of this file should not been seen by assembler sources. */
237 #ifndef __ASSEMBLER__
238 
239 
240 #ifndef TX_TIMER_THREAD_PRIORITY
241 #define TX_TIMER_THREAD_PRIORITY                0           /* Default timer thread priority    */
242 #endif
243 
244 
245 /* Define various constants for the ThreadX Xtensa port.  */
246 
247 #if XCHAL_HAVE_XEA3
248 #define TX_INT_DISABLE                          0x8               /* Disable interrupts value */
249 #define TX_INT_ENABLE                           0x0               /* Enable interrupt value   */
250 #else
251 #define TX_INT_DISABLE                          XCHAL_EXCM_LEVEL  /* Disable interrupts value */
252 #define TX_INT_ENABLE                           0x0               /* Enable interrupt value   */
253 #endif
254 
255 
256 /*
257     Define the clock source for trace event entry time stamp. The following
258     two item are port specific. For example, if the time source is at the
259     address 0x0a800024 and is 16-bits in size, the clock source constants
260     would be:
261 
262     #define TX_TRACE_TIME_SOURCE                *((ULONG *) 0x0a800024)
263     #define TX_TRACE_TIME_MASK                  0x0000FFFFUL
264 */
265 
266 #ifndef TX_TRACE_TIME_SOURCE
267 #define TX_TRACE_TIME_SOURCE                    ++_tx_trace_simulated_time
268 #endif
269 #ifndef TX_TRACE_TIME_MASK
270 #define TX_TRACE_TIME_MASK                      0xFFFFFFFFUL
271 #endif
272 
273 
274 /*
275     Define the port specific options for the _tx_build_options variable.
276     This variable indicates how the ThreadX library was built.
277 */
278 
279 #if defined(XT_SIMULATOR) || !defined(XT_BOARD)
280 #define TX_XT_OPT_SIMULATOR                     (1UL << 0)
281 #else
282 #define TX_XT_OPT_SIMULATOR                     0
283 #endif
284 
285 #if defined(XT_BOARD)
286 #define TX_XT_OPT_BOARD                         (1UL << 1)
287 #else
288 #define TX_XT_OPT_BOARD                         0
289 #endif
290 
291 #if defined(XT_INTEXC_HOOKS)
292 #define TX_XT_OPT_INTEXC_HOOKS                  (1UL << 2)
293 #else
294 #define TX_XT_OPT_INTEXC_HOOKS                  0
295 #endif
296 
297 #if defined(TX_THREAD_SAFE_CLIB)
298 #define TX_XT_OPT_CLIB                          (1UL << 3)
299 #else
300 #define TX_XT_OPT_CLIB                          0
301 #endif
302 
303 #define TX_PORT_SPECIFIC_BUILD_OPTIONS          (TX_XT_OPT_SIMULATOR | TX_XT_OPT_BOARD \
304                                                 | TX_XT_OPT_INTEXC_HOOKS | TX_XT_OPT_CLIB)
305 
306 
307 /*
308     Define the in-line initialization constant so that modules with in-line
309     initialization capabilities can prevent their initialization from being
310     a function call.
311 */
312 
313 #define TX_INLINE_INITIALIZATION
314 
315 
316 /*
317     Determine whether or not stack checking is enabled. By default, ThreadX
318     stack checking is disabled. When the following is defined, ThreadX thread
319     stack checking is enabled. If enabled (TX_ENABLE_STACK_CHECKING is defined),
320     the TX_DISABLE_STACK_FILLING define is canceled, thereby forcing the stack
321     fill which is necessary for the stack checking logic.
322 */
323 
324 #ifdef TX_ENABLE_STACK_CHECKING
325 #undef TX_DISABLE_STACK_FILLING
326 #endif
327 
328 
329 /*
330     Define the TX_THREAD control block extensions for this port. The main
331     reason for the multiple macros is so that backward compatibility can
332     be maintained with existing ThreadX kernel awareness modules.
333 */
334 
335 #if XCHAL_CP_NUM > 0
336 #define TX_CP_THREAD_EXTENSION  \
337     /* Co-proc state save areas, with padding for alignment: */ \
338     UINT                tx_thread_cp_state[(XT_CP_SIZE+3)/4];
339 #else
340 #define TX_CP_THREAD_EXTENSION
341 #endif
342 
343 #define TX_THREAD_EXTENSION_0 \
344     /* These extensions needs to be accessed from assembly code at context switches */ \
345     UINT                tx_thread_solicited;    /* Non-zero indicates solicited entry */ \
346     TX_CLIB_THREAD_EXTENSION                    /* Ptr to C library re-ent struct */ \
347     TX_CP_THREAD_EXTENSION          /* Coprocessor state save areas */
348 
349 #define TX_THREAD_EXTENSION_1 \
350     TX_CLIB_THREAD_EXTENSION_END
351 
352 #define TX_THREAD_EXTENSION_2
353 
354 /* Execution profile related */
355 #define TX_THREAD_EXTENSION_3
356 
357 /* Define the port extensions of the remaining ThreadX objects.  */
358 
359 #define TX_BLOCK_POOL_EXTENSION
360 #define TX_BYTE_POOL_EXTENSION
361 #define TX_EVENT_FLAGS_GROUP_EXTENSION
362 #define TX_MUTEX_EXTENSION
363 #define TX_QUEUE_EXTENSION
364 #define TX_SEMAPHORE_EXTENSION
365 #define TX_TIMER_EXTENSION
366 
367 
368 /* Define the user extension field of the thread control block.  Nothing
369    additional is needed for this port so it is defined as white space.  */
370 
371 #ifndef TX_THREAD_USER_EXTENSION
372 #define TX_THREAD_USER_EXTENSION
373 #endif
374 
375 
376 /* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
377    tx_thread_shell_entry, and tx_thread_terminate.  */
378 
379 #if XCHAL_CP_NUM > 0
380 extern void _xt_coproc_release(void * coproc_sa_base);
381 
382 #define TX_THREAD_DELETE_EXTENSION(thread_ptr) \
383         _xt_coproc_release(&thread_ptr->tx_thread_cp_state);
384 #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) \
385         _xt_coproc_release(&thread_ptr->tx_thread_cp_state);
386 #define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) \
387         _xt_coproc_release(&thread_ptr->tx_thread_cp_state);
388 #define TX_THREAD_CP_EXTENSION(thread_ptr) \
389     /* Initialize XT_CP_ASA ptr to aligned save area: */ \
390     /* NOTE: keep this matched with xtensa_context.h. */ \
391     thread_ptr->tx_thread_cp_state[0] = 0; \
392     thread_ptr->tx_thread_cp_state[1] = 0; \
393     thread_ptr->tx_thread_cp_state[2] = \
394         ((((UINT)thread_ptr->tx_thread_cp_state)+12+XCHAL_TOTAL_SA_ALIGN-1) \
395             & -XCHAL_TOTAL_SA_ALIGN);
396 #else
397 #define TX_THREAD_DELETE_EXTENSION(thread_ptr)
398 #define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
399 #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
400 #define TX_THREAD_CP_EXTENSION(thread_ptr)
401 #endif
402 
403 #define TX_THREAD_CREATE_EXTENSION(thread_ptr) \
404     TX_THREAD_CLIB_EXTENSION(thread_ptr) \
405     TX_THREAD_CP_EXTENSION(thread_ptr)
406 
407 
408 /* Define the ThreadX object creation extensions for the remaining objects.  */
409 
410 #define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
411 #define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
412 #define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
413 #define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
414 #define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
415 #define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
416 #define TX_TIMER_CREATE_EXTENSION(timer_ptr)
417 
418 
419 /* Define the ThreadX object deletion extensions for the remaining objects.  */
420 
421 #define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
422 #define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
423 #define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
424 #define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
425 #define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
426 #define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
427 #define TX_TIMER_DELETE_EXTENSION(timer_ptr)
428 
429 
430 /*
431     Define ThreadX interrupt lockout and restore macros for protection
432     on access of critical kernel information. The restore interrupt macro
433     must restore the interrupt posture of the running thread prior to the
434     value present prior to the disable macro. In most cases, the save area
435     macro is used to define a local function save area for the disable and
436     restore macros.
437 */
438 
439 extern unsigned int                 _tx_thread_interrupt_control(unsigned int new_posture);
440 
441 #define TX_INTERRUPT_SAVE_AREA      register UINT interrupt_save;
442 
443 #ifdef TX_DISABLE_INLINE_MACROS
444 #define TX_DISABLE                  interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
445 #define TX_RESTORE                  _tx_thread_interrupt_control(interrupt_save);
446 #else
447 #define TX_DISABLE                  interrupt_save = xthal_disable_interrupts();
448 #define TX_RESTORE                  xthal_restore_interrupts(interrupt_save);
449 #endif
450 
451 
452 /* Define the interrupt lockout macros for each ThreadX object.  */
453 
454 #define TX_BLOCK_POOL_DISABLE                   TX_DISABLE
455 #define TX_BYTE_POOL_DISABLE                    TX_DISABLE
456 #define TX_EVENT_FLAGS_GROUP_DISABLE            TX_DISABLE
457 #define TX_MUTEX_DISABLE                        TX_DISABLE
458 #define TX_QUEUE_DISABLE                        TX_DISABLE
459 #define TX_SEMAPHORE_DISABLE                    TX_DISABLE
460 
461 
462 #if XCHAL_HAVE_XEA3
463 /* Variables that keep track of the timer and software interrupt numbers in use. */
464 extern int xt_sw_intnum;
465 extern int xt_timer_intnum;
466 #endif
467 
468 
469 /* Define the version ID of ThreadX.  This may be utilized by the application.  */
470 
471 #ifdef TX_THREAD_INIT
472 CHAR                            _tx_version_id[] =
473                                     "Copyright (c) 2024 Microsoft Corporation. * Azure RTOS Xtensa Version 6.4.1 *";
474 #else
475 extern  CHAR                    _tx_version_id[];
476 #endif
477 
478 #endif /* #ifndef __ASSEMBLER__ */
479 
480 #endif
481 
482