1 /**************************************************************************/
2 /*   Copyright (c) Cadence Design Systems, Inc.                           */
3 /*                                                                        */
4 /* Permission is hereby granted, free of charge, to any person obtaining  */
5 /* a copy of this software and associated documentation files (the        */
6 /* "Software"), to deal in the Software without restriction, including    */
7 /* without limitation the rights to use, copy, modify, merge, publish,    */
8 /* distribute, sublicense, and/or sell copies of the Software, and to     */
9 /* permit persons to whom the Software is furnished to do so, subject to  */
10 /* the following conditions:                                              */
11 /*                                                                        */
12 /* The above copyright notice and this permission notice shall be         */
13 /* included in all copies or substantial portions of the Software.        */
14 /*                                                                        */
15 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */
16 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */
17 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
18 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */
19 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */
20 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */
21 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */
22 /**************************************************************************/
23 
24 
25 #include "tx_api.h"
26 #include "tx_port.h"
27 #include "xtensa_api.h"
28 
29 #if XCHAL_HAVE_ISL || XCHAL_HAVE_KSL || XCHAL_HAVE_PSL
30 #include <xtensa/tie/xt_exception_dispatch.h>
31 #endif
32 
33 
34 #if XCHAL_HAVE_XEA3
35 int32_t xt_sw_intnum    = -1;
36 int32_t xt_timer_intnum = -1;
37 #endif
38 
39 
40 /**************************************************************************/
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function is responsible for any low-level processor            */
45 /*    initialization, including setting up interrupt vectors, setting     */
46 /*    up a periodic timer interrupt source, saving the system stack       */
47 /*    pointer for use in ISR processing later, and finding the first      */
48 /*    available RAM memory address for tx_application_define.             */
49 /*    It also sets the default heap region for the optional C library.    */
50 /*                                                                        */
51 /*  RELEASE HISTORY                                                       */
52 /*                                                                        */
53 /*    DATE              NAME                      DESCRIPTION             */
54 /*                                                                        */
55 /*  12-31-2020      Cadence Design Systems  Initial Version 6.1.3         */
56 /*  04-25-2022      Scott Larson            Modified comments and updated */
57 /*                                            function names,             */
58 /*                                            resulting in version 6.1.11 */
59 /*                                                                        */
60 /**************************************************************************/
_tx_initialize_low_level(VOID)61 VOID   _tx_initialize_low_level(VOID)
62 {
63     extern char   _xt_interrupt_stack_top;
64     extern void   _tx_timer_interrupt(void *);
65     extern void * _tx_thread_system_stack_ptr;
66     extern void * _tx_initialize_unused_memory;
67     extern char   _end;
68 
69     #ifdef TX_THREAD_SAFE_CLIB
70     extern char __stack;
71     extern void _tx_clib_init(void);
72     #endif
73 
74     #if XCHAL_CP_NUM > 0
75     extern void _xt_coproc_init(void);
76     extern void _xt_coproc_exc(XtExcFrame * fp);
77     #endif
78 
79     #ifdef TX_ENABLE_STACK_CHECKING
80     extern VOID _tx_xtensa_stack_error_handler(TX_THREAD * thread);
81     #endif
82 
83     #if XCHAL_HAVE_XEA3
84     extern void xt_sched_handler(void * arg);
85     int32_t i;
86     #endif
87 
88     TX_INTERRUPT_SAVE_AREA
89 
90     /* Disable interrupts - don't want any that interact with ThreadX yet. */
91     TX_DISABLE
92 
93     /*
94     Disable stack limit checking if present. Whatever was set up earlier
95     is not going to work for us.
96     */
97 #if XCHAL_HAVE_KSL
98     XT_WSR_KSL(0);
99 #endif
100 #if XCHAL_HAVE_ISL
101     XT_WSR_ISL(0);
102 #endif
103 
104     /* Save the system stack pointer.  */
105     _tx_thread_system_stack_ptr = &(_xt_interrupt_stack_top);
106 
107     /* Save the first available memory address.  */
108     _tx_initialize_unused_memory = (void *)(((UINT)&_end + 15) & ~0xF);
109 
110     #ifdef TX_THREAD_SAFE_CLIB
111     /*
112     Pre-allocate default memory region for the C library heap.
113     Bisect the region from first available memory to end of system memory,
114     align to 16 byte boundary, and allocate the heap in the upper half.
115     */
116     _tx_clib_heap_end   = &(__stack);
117     _tx_clib_heap_start =
118         (void *)(((UINT)_tx_initialize_unused_memory/2 + (UINT)_tx_clib_heap_end/2) & ~0xF);
119     #endif
120 
121     #if XCHAL_CP_NUM > 0
122     /*
123     Initialize co-processor management for threads. Leave CPENABLE alone.
124     This is called from a normal Xtensa single-threaded run-time environment
125     before multi-threading has commenced. All co-processors are enabled.
126     It is important NOT to clear CPENABLE yet because tx_application_define()
127     is user code which might use a co-processor. The co-processor exception
128     handler does not expect to be called outside a thread.
129     */
130     _xt_coproc_init();
131 
132     #if XCHAL_HAVE_XEA3
133     /* Install the coprocessor exception handler. */
134     xt_set_exception_handler(EXCCAUSE_CP_DISABLED, _xt_coproc_exc);
135     #endif
136     #endif
137 
138     #if XCHAL_HAVE_XEA3
139     /* Select a software interrupt to use for scheduling. */
140     for (i = 0; i < XCHAL_NUM_INTERRUPTS; i++) {
141         if ((Xthal_inttype[i] == XTHAL_INTTYPE_SOFTWARE) && (Xthal_intlevel[i] == 1)) {
142             xt_sw_intnum = i;
143             break;
144         }
145     }
146 
147     if (xt_sw_intnum == -1) {
148         __asm__ volatile ("break 1, 1");
149     }
150 
151     /* Set the interrupt handler and enable the interrupt. */
152     xt_set_interrupt_handler(xt_sw_intnum, xt_sched_handler, 0);
153     xt_interrupt_enable(xt_sw_intnum);
154     #endif
155 
156     #ifndef TX_NO_TIMER
157 
158     /* Compute tick divisor if clock freq is not compile-time constant. */
159     #ifndef XT_CLOCK_FREQ
160     xt_tick_divisor_init();
161     #endif
162 
163     /* Set up the periodic tick timer (assume enough time to complete init). */
164     #ifdef XT_CLOCK_FREQ
165     XT_WSR_CCOMPARE(XT_RSR_CCOUNT() + XT_TICK_DIVISOR);
166     #else
167     XT_WSR_CCOMPARE(XT_RSR_CCOUNT() + xt_tick_divisor);
168     #endif
169 
170     #if XCHAL_HAVE_XEA3
171     xt_timer_intnum = XT_TIMER_INTNUM;
172     xt_set_interrupt_handler(xt_timer_intnum, _tx_timer_interrupt, 0);
173     #endif
174 
175     /* Enable the timer interrupt at the device level. */
176     xt_interrupt_enable(XT_TIMER_INTNUM);
177 
178     #endif /* TX_NO_TIMER */
179 
180     /* Initialize C library thread safety support. */
181     #ifdef TX_THREAD_SAFE_CLIB
182     _tx_clib_init();
183     #endif
184 
185     /* Install stack overflow notification callback. */
186     #ifdef TX_ENABLE_STACK_CHECKING
187     tx_thread_stack_error_notify(_tx_xtensa_stack_error_handler);
188     #endif
189 }
190 
191