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 /**   Thread                                                              */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 
24 /**************************************************************************/
25 /*                                                                        */
26 /*  PORT SPECIFIC C INFORMATION                            RELEASE        */
27 /*                                                                        */
28 /*    tx_port.h                             MIPS32_interAptiv/Green Hills */
29 /*                                                           6.2.1        */
30 /*                                                                        */
31 /*  AUTHOR                                                                */
32 /*                                                                        */
33 /*    Scott Larson, Microsoft Corporation                                 */
34 /*                                                                        */
35 /*  DESCRIPTION                                                           */
36 /*                                                                        */
37 /*    This file contains data type definitions that make the ThreadX      */
38 /*    real-time kernel function identically on a variety of different     */
39 /*    processor architectures.  For example, the size or number of bits   */
40 /*    in an "int" data type vary between microprocessor architectures and */
41 /*    even C compilers for the same microprocessor.  ThreadX does not     */
42 /*    directly use native C data types.  Instead, ThreadX creates its     */
43 /*    own special types that can be mapped to actual data types by this   */
44 /*    file to guarantee consistency in the interface and functionality.   */
45 /*                                                                        */
46 /*  RELEASE HISTORY                                                       */
47 /*                                                                        */
48 /*    DATE              NAME                      DESCRIPTION             */
49 /*                                                                        */
50 /*  03-08-2023      Scott Larson            Initial release version 6.2.1 */
51 /*                                                                        */
52 /**************************************************************************/
53 
54 #ifndef TX_PORT_H
55 #define TX_PORT_H
56 
57 
58 
59 /************* Define ThreadX SMP constants.  *************/
60 
61 /* Define the ThreadX SMP maximum number of cores.  */
62 
63 #ifndef TX_THREAD_SMP_MAX_CORES
64 #define TX_THREAD_SMP_MAX_CORES                 6               /* 3 cores, 2 VPEs per core   */
65 #endif
66 
67 
68 /* Define the ThreadX SMP core mask. */
69 
70 #ifndef TX_THREAD_SMP_CORE_MASK
71 #define TX_THREAD_SMP_CORE_MASK                 0x3F            /* here bit 0 represents Core 0, bit 1 represents Core 1, etc.  */
72 #endif
73 
74 
75 /* Define dynamic number of cores option.  When commented out, the number of cores is static.  */
76 
77 /* #define TX_THREAD_SMP_DYNAMIC_CORE_MAX  */
78 
79 
80 /* Define ThreadX SMP initialization macro.  */
81 
82 #define TX_PORT_SPECIFIC_PRE_INITIALIZATION
83 
84 
85 /* Define ThreadX SMP pre-scheduler initialization.  */
86 
87 #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION
88 
89 
90 /* Enable the inter-core interrupt logic.  When commented out, inter-core interrupts are not enabled.  */
91 
92 /* #define TX_THREAD_SMP_INTER_CORE_INTERRUPT  */
93 
94 
95 /* For GHS debugger compatibility, map the structure SMP members to the previous names.  */
96 
97 #define tx_thread_smp_core_mapped           tx_thread_mips32_mapped_vpe
98 #define tx_thread_smp_core_control          tx_thread_mips32_vpe_control
99 
100 
101 /* Determine if the optional wakeup macro has been defined. This definition can be
102    made here or prior to this file being included. When TX_THREAD_SMP_WAKEUP(i) is
103    defined (where "i" is the core), the wakeup logic is also brought in.  */
104 
105 #ifdef TX_THREAD_SMP_WAKEUP
106 #define TX_THREAD_SMP_WAKEUP_LOGIC
107 #endif
108 
109 
110 /* Determine if there is customer-specific wakeup logic needed.  */
111 
112 #ifdef TX_THREAD_SMP_WAKEUP_LOGIC
113 
114 /* Include customer-specific wakeup code.  */
115 
116 #include "tx_thread_smp_core_wakeup.h"
117 #endif
118 
119 
120 /* Ensure that the in-line resume/suspend define is not allowed.  */
121 
122 #ifdef TX_INLINE_THREAD_RESUME_SUSPEND
123 #undef TX_INLINE_THREAD_RESUME_SUSPEND
124 #endif
125 
126 
127 /************* End ThreadX SMP constants.  *************/
128 
129 
130 /* Determine if the optional ThreadX user define file should be used.  */
131 
132 #ifdef TX_INCLUDE_USER_DEFINE_FILE
133 
134 
135 /* Yes, include the user defines in tx_user.h. The defines in this file may
136    alternately be defined on the command line.  */
137 
138 #include "tx_user.h"
139 #endif
140 
141 /* Define the TX_MEMSET macro to remove library reference.  */
142 
143 #define TX_MEMSET(a,b,c)                                    {                                       \
144                                                             UCHAR *ptr;                             \
145                                                             UCHAR value;                            \
146                                                             UINT  i, size;                          \
147                                                                 ptr =    (UCHAR *) ((VOID *) a);    \
148                                                                 value =  (UCHAR) b;                 \
149                                                                 size =   (UINT) c;                  \
150                                                                 for (i = 0; i < size; i++)          \
151                                                                 {                                   \
152                                                                     *ptr++ =  value;                \
153                                                                 }                                   \
154                                                             }
155 
156 
157 /* Ensure that the in-line resume/suspend define is not allowed.  */
158 
159 #ifdef TX_INLINE_THREAD_RESUME_SUSPEND
160 #undef TX_INLINE_THREAD_RESUME_SUSPEND
161 #endif
162 
163 
164 /* Define compiler library include files.  */
165 
166 #include <stdlib.h>
167 #include <string.h>
168 #include <mips_ghs.h>
169 #ifdef TX_SOURCE_CODE
170 #include "tx_ghs.h"
171 #endif
172 
173 
174 /* Define ThreadX basic types for this port.  */
175 
176 #define VOID                                                void
177 typedef char                                                CHAR;
178 typedef unsigned char                                       UCHAR;
179 typedef int                                                 INT;
180 typedef unsigned int                                        UINT;
181 typedef long                                                LONG;
182 typedef unsigned long                                       ULONG;
183 typedef short                                               SHORT;
184 typedef unsigned short                                      USHORT;
185 
186 
187 /* Define the priority levels for ThreadX.  Legal values range
188    from 32 to 1024 and MUST be evenly divisible by 32.  */
189 
190 #ifndef TX_MAX_PRIORITIES
191 #define TX_MAX_PRIORITIES                                   32
192 #endif
193 
194 
195 /* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
196    thread creation is less than this value, the thread create call will return an error.  */
197 
198 #ifndef TX_MINIMUM_STACK
199 #define TX_MINIMUM_STACK                                    1024        /* Minimum stack size for this port  */
200 #endif
201 
202 
203 /* Define the system timer thread's default stack size and priority.  These are only applicable
204    if TX_TIMER_PROCESS_IN_ISR is not defined.  */
205 
206 #ifndef TX_TIMER_THREAD_STACK_SIZE
207 #define TX_TIMER_THREAD_STACK_SIZE                          2048        /* Default timer thread stack size  */
208 #endif
209 
210 #ifndef TX_TIMER_THREAD_PRIORITY
211 #define TX_TIMER_THREAD_PRIORITY                            0           /* Default timer thread priority    */
212 #endif
213 
214 
215 /* Define various constants for the ThreadX MIPS port.  */
216 
217 #define TX_INT_DISABLE                                      0x00000000  /* Disable interrupts value */
218 #define TX_INT_ENABLE                                       0x00000001  /* Enable interrupt value   */
219 
220 
221 /* Define constants for Green Hills EventAnalyzer.  */
222 
223 /* Define the number of ticks per second. This informs the EventAnalyzer what the timestamps
224    represent.  By default, this is set to 1,000,000 i.e., one tick every microsecond. */
225 
226 #define TX_EL_TICKS_PER_SECOND                              1000000
227 
228 
229 /* Define prototype of internal time get function.  */
230 
231 ULONG   _tx_thread_smp_time_get(void);
232 ULONG   _tx_thread_smp_time_get_upper(void);
233 
234 
235 /* Define the method of how to get the upper and lower 32-bits of the time stamp. By default, simply
236    simulate the time-stamp source with a counter.  */
237 
238 #define read_tbu()                                          _tx_thread_smp_time_get_upper()
239 #define read_tbl()                                          _tx_thread_smp_time_get()
240 
241 
242 /* Define the clock source for trace event entry time stamp. The following two item are port specific.
243    For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
244    source constants would be:
245 
246 #define TX_TRACE_TIME_SOURCE                                *((ULONG *) 0x0a800024)
247 #define TX_TRACE_TIME_MASK                                  0x0000FFFFUL
248 
249 */
250 
251 #ifndef TX_MISRA_ENABLE
252 #ifndef TX_TRACE_TIME_SOURCE
253 #define TX_TRACE_TIME_SOURCE                                _tx_thread_smp_time_get()
254 #endif
255 #else
256 #ifndef TX_TRACE_TIME_SOURCE
257 ULONG   _tx_misra_time_stamp_get(VOID);
258 #define TX_TRACE_TIME_SOURCE                                _tx_misra_time_stamp_get()
259 #endif
260 #endif
261 #ifndef TX_TRACE_TIME_MASK
262 #define TX_TRACE_TIME_MASK                                  0xFFFFFFFFUL
263 #endif
264 
265 
266 /* Define the in-line initialization constant so that modules with in-line
267    initialization capabilities can prevent their initialization from being
268    a function call.  */
269 
270 #ifdef TX_MISRA_ENABLE
271 #define TX_DISABLE_INLINE
272 #else
273 #define TX_INLINE_INITIALIZATION
274 #endif
275 
276 
277 /* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
278    disabled. When the following is defined, ThreadX thread stack checking is enabled.  If stack
279    checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
280    define is negated, thereby forcing the stack fill which is necessary for the stack checking
281    logic.  */
282 
283 #ifndef TX_MISRA_ENABLE
284 #ifdef TX_ENABLE_STACK_CHECKING
285 #undef TX_DISABLE_STACK_FILLING
286 #endif
287 #endif
288 
289 
290 /* Define the TX_THREAD control block extensions for this port. The main reason
291    for the multiple macros is so that backward compatibility can be maintained with
292    existing ThreadX kernel awareness modules.  */
293 
294 #define TX_THREAD_EXTENSION_0
295 #define TX_THREAD_EXTENSION_1                               VOID *  tx_thread_eh_globals;
296 #define TX_THREAD_EXTENSION_2
297 #define TX_THREAD_EXTENSION_3                               int     Errno;  \
298                                                             char *  strtok_saved_pos;
299 
300 
301 
302 /* Define the port extensions of the remaining ThreadX objects.  */
303 
304 #define TX_BLOCK_POOL_EXTENSION
305 #define TX_BYTE_POOL_EXTENSION
306 #define TX_EVENT_FLAGS_GROUP_EXTENSION
307 #define TX_MUTEX_EXTENSION
308 #define TX_QUEUE_EXTENSION
309 #define TX_SEMAPHORE_EXTENSION
310 #define TX_TIMER_EXTENSION
311 
312 
313 /* Define the user extension field of the thread control block.  Nothing
314    additional is needed for this port so it is defined as white space.  */
315 
316 #ifndef TX_THREAD_USER_EXTENSION
317 #define TX_THREAD_USER_EXTENSION
318 #endif
319 
320 
321 /* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
322    tx_thread_shell_entry, and tx_thread_terminate.  */
323 
324 #if (__GHS_VERSION_NUMBER >= 500)
325 #define TX_THREAD_CREATE_EXTENSION(thread_ptr)                                  \
326     {                                                                           \
327         extern void __tx_cpp_exception_init(TX_THREAD *thread_ptr);             \
328         __tx_cpp_exception_init(thread_ptr);                                    \
329     }
330 #else
331 #define TX_THREAD_CREATE_EXTENSION(thread_ptr)                                  \
332     {                                                                           \
333         #pragma weak __cpp_exception_init                                       \
334         extern void __cpp_exception_init(void **);                              \
335         static void (*const cpp_init_funcp)(void **) = __cpp_exception_init;    \
336         if (cpp_init_funcp)                                                     \
337             __cpp_exception_init(&(thread_ptr -> tx_thread_eh_globals));        \
338     }
339 #endif
340 
341 #if (__GHS_VERSION_NUMBER >= 500)
342 #define TX_THREAD_DELETE_EXTENSION(thread_ptr)                                  \
343     {                                                                           \
344         extern void __tx_cpp_exception_cleanup(TX_THREAD *thread_ptr);          \
345         __tx_cpp_exception_cleanup(thread_ptr);                                 \
346     }
347 #else
348 #define TX_THREAD_DELETE_EXTENSION(thread_ptr)                                  \
349     {                                                                           \
350         #pragma weak __cpp_exception_cleanup                                    \
351         extern void __cpp_exception_cleanup(void **);                           \
352         static void (*const cpp_cleanup_funcp)(void **) =                       \
353             __cpp_exception_cleanup;                                            \
354         if (cpp_cleanup_funcp)                                                  \
355             __cpp_exception_cleanup(&(thread_ptr -> tx_thread_eh_globals));     \
356     }
357 #endif
358 
359 #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
360 #define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
361 
362 
363 /* Define the ThreadX object creation extensions for the remaining objects.  */
364 
365 #define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
366 #define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
367 #define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
368 #define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
369 #define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
370 #define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
371 #define TX_TIMER_CREATE_EXTENSION(timer_ptr)
372 
373 
374 /* Define the ThreadX object deletion extensions for the remaining objects.  */
375 
376 #define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
377 #define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
378 #define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
379 #define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
380 #define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
381 #define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
382 #define TX_TIMER_DELETE_EXTENSION(timer_ptr)
383 
384 /* The MIPS32 architecture has the CLZ instruction. Redefine the macro for calculating the
385    lowest bit set to use this instruction.  */
386 #ifndef TX_DISABLE_INLINE
387 
388 #define TX_LOWEST_SET_BIT_CALCULATE(m, b)       m = m & ((ULONG) (-((LONG) m))); \
389                                                 b = __CLZ32(m); \
390                                                 b = 31 - b;
391 
392 #endif
393 
394 
395 /************* Define ThreadX SMP data types and function prototypes.  *************/
396 
397 
398 struct TX_THREAD_STRUCT;
399 
400 
401 /* Define the ThreadX SMP protection structure.   */
402 
403 typedef struct TX_THREAD_SMP_PROTECT_STRUCT
404 {
405     ULONG           tx_thread_smp_protect_in_force;
406     struct TX_THREAD_STRUCT *
407                     tx_thread_smp_protect_thread;
408     ULONG           tx_thread_smp_protect_core;
409     ULONG           tx_thread_smp_protect_count;
410 
411     /* Implementation specific information follows.  */
412 
413     ULONG           tx_thread_smp_protect_get_caller;
414     ULONG           tx_thread_smp_protect_sr;
415     ULONG           tx_thread_smp_protect_release_caller;
416 } TX_THREAD_SMP_PROTECT;
417 
418 
419 #ifndef TX_DISABLE_INLINE
420 
421 /* Define the get thread in-line assembly.   */
422 
423 struct TX_THREAD_STRUCT;
424 
_tx_thread_smp_current_thread_get(void)425 asm struct TX_THREAD_STRUCT *_tx_thread_smp_current_thread_get(void)
426 {
427 %
428     di      $9                                  # Disable interrupts
429     mfc0    $25, $4,2                           # Pickup VPE ID (UserLocal)
430     la      $12, _tx_thread_current_ptr         # Pickup the current thread pointer
431     sll     $25, $25, 2                         # Build index based on VPE number
432     addu    $12, $12, $25                       # Build address of current thread pointer for this VPE
433     lw      $2, ($12)                           # Pickup current thread pointer
434     mtc0    $9, $12                             # Restore interrupts
435 %error
436 }
437 
438 
439 /* Define the get thread macro. Without in-line assembly, this would map to _tx_thread_smp_current_thread_get(). */
440 
441 /* Define the get core ID in-line assembly.  */
442 
_tx_thread_smp_core_get(void)443 asm UINT _tx_thread_smp_core_get(void)
444 {
445 %
446     mfc0    $2, $4,2                            # Pickup VPE ID (UserLocal)
447 %error
448 }
449 
450 #endif
451 
452 
453 /* Define ThreadX interrupt lockout and restore macros for protection on
454    access of critical kernel information.  The restore interrupt macro must
455    restore the interrupt posture of the running thread prior to the value
456    present prior to the disable macro.  In most cases, the save area macro
457    is used to define a local function save area for the disable and restore
458    macros.  */
459 
460 #define TX_INTERRUPT_SAVE_AREA                  unsigned int interrupt_save;
461 
462 #define TX_DISABLE                              interrupt_save =  _tx_thread_smp_protect();
463 #define TX_RESTORE                              _tx_thread_smp_unprotect(interrupt_save);
464 
465 
466 
467 /* Define some extra variables used by the MIPS interAptiv SMP implementation.  */
468 
469 #ifdef TX_THREAD_INIT
470 #define THREAD_SMP_DECLARE
471 #else
472 #define THREAD_SMP_DECLARE extern
473 #endif
474 
475 THREAD_SMP_DECLARE ULONG    _tx_thread_smp_detected_cores;
476 THREAD_SMP_DECLARE ULONG    _tx_thread_smp_detected_vpes_per_core;
477 THREAD_SMP_DECLARE ULONG    _tx_thread_smp_system_error;
478 #ifdef TX_ENABLE_64BIT_FPU_SUPPORT
479 THREAD_SMP_DECLARE ULONG    _tx_thread_smp_initial_fpu_control_register;
480 #endif
481 
482 /************* End ThreadX SMP data type and function prototype definitions.  *************/
483 
484 
485 /* Define the interrupt lockout macros for each ThreadX object.  */
486 
487 #define TX_BLOCK_POOL_DISABLE                               TX_DISABLE
488 #define TX_BYTE_POOL_DISABLE                                TX_DISABLE
489 #define TX_EVENT_FLAGS_GROUP_DISABLE                        TX_DISABLE
490 #define TX_MUTEX_DISABLE                                    TX_DISABLE
491 #define TX_QUEUE_DISABLE                                    TX_DISABLE
492 #define TX_SEMAPHORE_DISABLE                                TX_DISABLE
493 
494 
495 /* Define the port specific options for the _tx_build_options variable. This variable indicates
496    how the ThreadX library was built.  */
497 
498 #ifdef TX_ENABLE_64BIT_FPU_SUPPORT
499 #define TX_FPU64_ENABLED                                    2
500 #else
501 #define TX_FPU64_ENABLED                                    0
502 #endif
503 
504 #ifdef TX_ENABLE_DSP_SUPPORT
505 #define TX_DSP_ENABLED                                      4
506 #else
507 #define TX_DSP_ENABLED                                      0
508 #endif
509 
510 #define TX_PORT_SPECIFIC_BUILD_OPTIONS                      (TX_FPU64_ENABLED | TX_DSP_ENABLED)
511 
512 
513 
514 /* Define the version ID of ThreadX.  This may be utilized by the application.  */
515 
516 #ifdef TX_THREAD_INIT
517 CHAR                            _tx_version_id[] =
518                                     "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX SMP MIPS32_interAptiv/Green Hills Version 6.2.1 *";
519 #else
520 extern  CHAR                    _tx_version_id[];
521 #endif
522 
523 #endif
524