1 /*
2 * xtruntime.h -- general C definitions for single-threaded run-time
3 *
4 * Copyright (c) 2002-2013 Tensilica Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 #ifndef XTRUNTIME_H
27 #define XTRUNTIME_H
28
29 #include <xtensa/config/core.h>
30 #include <xtensa/config/specreg.h>
31 #include <xtensa/xtruntime-core-state.h>
32
33 #ifndef XTSTR
34 #define _XTSTR(x) # x
35 #define XTSTR(x) _XTSTR(x)
36 #endif
37
38 /* _xtos_core_shutoff() flags parameter values: */
39 #define XTOS_KEEPON_MEM 0x00000100 /* ==PWRCTL_MEM_WAKEUP */
40 #define XTOS_KEEPON_MEM_SHIFT 8
41 #define XTOS_KEEPON_DEBUG 0x00001000 /* ==PWRCTL_DEBUG_WAKEUP */
42 #define XTOS_KEEPON_DEBUG_SHIFT 12
43
44 #define XTOS_IDMA_NO_WAIT 0x00010000 /* Do not wait for idma to finish. Disable if necessary */
45 #define XTOS_IDMA_WAIT_STANDBY 0x00020000 /* Also treat standby state as the end of wait */
46
47 #define XTOS_COREF_PSO 0x00000001 /* do power shutoff */
48 #define XTOS_COREF_PSO_SHIFT 0
49
50 #define _xtos_set_execption_handler _xtos_set_exception_handler /* backward compatibility */
51 #define _xtos_set_saved_intenable _xtos_ints_on /* backward compatibility */
52 #define _xtos_clear_saved_intenable _xtos_ints_off /* backward compatibility */
53
54 #if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
55
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59
60 #if defined(XTOS_MISRA)
61 typedef void (_xtos_handler_func)(void *);
62 #elif defined(__cplusplus)
63 typedef void (_xtos_handler_func)(...);
64 #else
65 typedef void (_xtos_handler_func)(void);
66 #endif
67 typedef _xtos_handler_func *_xtos_handler;
68
69 /*
70 * unsigned XTOS_SET_INTLEVEL(int intlevel);
71 * This macro sets the current interrupt level.
72 * The 'intlevel' parameter must be a constant.
73 * This macro returns a 32-bit value that must be passed to
74 * XTOS_RESTORE_INTLEVEL() to restore the previous interrupt level.
75 * XTOS_RESTORE_JUST_INTLEVEL() also does this, but in XEA2 configs
76 * it restores only PS.INTLEVEL rather than the entire PS register
77 * and thus is slower.
78 */
79 #if !XCHAL_HAVE_INTERRUPTS
80 # define XTOS_SET_INTLEVEL(intlevel) 0
81 # define XTOS_SET_MIN_INTLEVEL(intlevel) 0
82 # define XTOS_RESTORE_INTLEVEL(restoreval)
83 # define XTOS_RESTORE_JUST_INTLEVEL(restoreval)
84 #elif XCHAL_HAVE_XEA2
85 /* In XEA2, we can simply safely set PS.INTLEVEL directly: */
86 /* NOTE: these asm macros don't modify memory, but they are marked
87 * as such to act as memory access barriers to the compiler because
88 * these macros are sometimes used to delineate critical sections;
89 * function calls are natural barriers (the compiler does not know
90 * whether a function modifies memory) unless declared to be inlined. */
91 # define XTOS_SET_INTLEVEL(intlevel) __extension__({ unsigned __tmp; \
92 __asm__ __volatile__( "rsil %0, " XTSTR(intlevel) "\n" \
93 : "=a" (__tmp) : : "memory" ); \
94 __tmp;})
95 # define XTOS_SET_MIN_INTLEVEL(intlevel) ({ unsigned __tmp, __tmp2, __tmp3; \
96 __asm__ __volatile__( "rsr.ps %0\n" /* get old (current) PS.INTLEVEL */ \
97 "movi %2, " XTSTR(intlevel) "\n" \
98 "extui %1, %0, 0, 4\n" /* keep only INTLEVEL bits of parameter */ \
99 "blt %2, %1, 1f\n" \
100 "rsil %0, " XTSTR(intlevel) "\n" \
101 "1:\n" \
102 : "=a" (__tmp), "=&a" (__tmp2), "=&a" (__tmp3) : : "memory" ); \
103 __tmp;})
104 # define XTOS_RESTORE_INTLEVEL(restoreval) do{ unsigned __tmp = (restoreval); \
105 __asm__ __volatile__( "wsr.ps %0 ; rsync\n" \
106 : : "a" (__tmp) : "memory" ); \
107 }while(0)
108 # define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_intlevel(restoreval)
109 #else
110 /* In XEA1, we have to rely on INTENABLE register virtualization: */
111 extern unsigned _xtos_set_vpri( unsigned vpri );
112 extern unsigned _xtos_vpri_enabled; /* current virtual priority */
113 # define XTOS_SET_INTLEVEL(intlevel) _xtos_set_vpri(~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel))
114 # define XTOS_SET_MIN_INTLEVEL(intlevel) _xtos_set_vpri(_xtos_vpri_enabled & ~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel))
115 # define XTOS_RESTORE_INTLEVEL(restoreval) _xtos_set_vpri(restoreval)
116 # define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_vpri(restoreval)
117 #endif
118
119 /*
120 * The following macros build upon the above. They are generally used
121 * instead of invoking the SET_INTLEVEL and SET_MIN_INTLEVEL macros directly.
122 * They all return a value that can be used with XTOS_RESTORE_INTLEVEL()
123 * or _xtos_restore_intlevel() or _xtos_restore_just_intlevel() to restore
124 * the effective interrupt level to what it was before the macro was invoked.
125 * In XEA2, the DISABLE macros are much faster than the MASK macros
126 * (in all configs, DISABLE sets the effective interrupt level, whereas MASK
127 * makes ensures the effective interrupt level is at least the level given
128 * without lowering it; in XEA2 with INTENABLE virtualization, these macros
129 * affect PS.INTLEVEL only, not the virtual priority, so DISABLE has partial
130 * MASK semantics).
131 *
132 * A typical critical section sequence might be:
133 * unsigned rval = XTOS_DISABLE_EXCM_INTERRUPTS;
134 * ... critical section ...
135 * XTOS_RESTORE_INTLEVEL(rval);
136 */
137 /* Enable all interrupts (those activated with _xtos_ints_on()): */
138 #define XTOS_ENABLE_INTERRUPTS XTOS_SET_INTLEVEL(0)
139 /* Disable low priority level interrupts (they can interact with the OS): */
140 #define XTOS_DISABLE_LOWPRI_INTERRUPTS XTOS_SET_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS)
141 #define XTOS_MASK_LOWPRI_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS)
142 /* Disable interrupts that can interact with the OS: */
143 #define XTOS_DISABLE_EXCM_INTERRUPTS XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL)
144 #define XTOS_MASK_EXCM_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XCHAL_EXCM_LEVEL)
145 #if 0 /* XTOS_LOCK_LEVEL is not exported to applications */
146 /* Disable interrupts that can interact with the OS, or manipulate virtual INTENABLE: */
147 #define XTOS_DISABLE_LOCK_INTERRUPTS XTOS_SET_INTLEVEL(XTOS_LOCK_LEVEL)
148 #define XTOS_MASK_LOCK_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XTOS_LOCK_LEVEL)
149 #endif
150 /* Disable ALL interrupts (not for common use, particularly if one's processor
151 * configuration has high-level interrupts and one cares about their latency): */
152 #define XTOS_DISABLE_ALL_INTERRUPTS XTOS_SET_INTLEVEL(15)
153
154 /* These two are deprecated. Use the newer functions below. */
155 extern unsigned int _xtos_ints_off( unsigned int mask );
156 extern unsigned int _xtos_ints_on( unsigned int mask );
157
158 /* Newer functions to enable/disable the specified interrupt. */
_xtos_interrupt_enable(unsigned int intnum)159 static inline void _xtos_interrupt_enable(unsigned int intnum)
160 {
161 _xtos_ints_on(1U << intnum);
162 }
163
_xtos_interrupt_disable(unsigned int intnum)164 static inline void _xtos_interrupt_disable(unsigned int intnum)
165 {
166 _xtos_ints_off(1U << intnum);
167 }
168
169 extern unsigned _xtos_set_intlevel( int intlevel );
170 extern unsigned _xtos_set_min_intlevel( int intlevel );
171 extern unsigned _xtos_restore_intlevel( unsigned restoreval );
172 extern unsigned _xtos_restore_just_intlevel( unsigned restoreval );
173 extern _xtos_handler _xtos_set_interrupt_handler( int n, _xtos_handler f );
174 extern _xtos_handler _xtos_set_interrupt_handler_arg( int n, _xtos_handler f, void *arg );
175 extern _xtos_handler _xtos_set_exception_handler( int n, _xtos_handler f );
176
177 extern void _xtos_memep_initrams( void );
178 extern void _xtos_memep_enable( int flags );
179
180 /* For use with the tiny LSP (see LSP reference manual). */
181 #if XCHAL_NUM_INTLEVELS >= 1
182 extern void _xtos_dispatch_level1_interrupts( void );
183 #endif
184 #if XCHAL_NUM_INTLEVELS >= 2
185 extern void _xtos_dispatch_level2_interrupts( void );
186 #endif
187 #if XCHAL_NUM_INTLEVELS >= 3
188 extern void _xtos_dispatch_level3_interrupts( void );
189 #endif
190 #if XCHAL_NUM_INTLEVELS >= 4
191 extern void _xtos_dispatch_level4_interrupts( void );
192 #endif
193 #if XCHAL_NUM_INTLEVELS >= 5
194 extern void _xtos_dispatch_level5_interrupts( void );
195 #endif
196 #if XCHAL_NUM_INTLEVELS >= 6
197 extern void _xtos_dispatch_level6_interrupts( void );
198 #endif
199
200 /* Deprecated (but kept because they were documented): */
201 extern unsigned int _xtos_read_ints( void );
202 extern void _xtos_clear_ints( unsigned int mask );
203
204
205 /* Power shut-off related routines. */
206 extern int _xtos_core_shutoff(unsigned flags);
207 extern int _xtos_core_save(unsigned flags, XtosCoreState *savearea, void *code);
208 extern void _xtos_core_restore(unsigned retvalue, XtosCoreState *savearea);
209
210
211 #if XCHAL_NUM_CONTEXTS > 1
212 extern unsigned _xtos_init_context(int context_num, int stack_size,
213 _xtos_handler_func *start_func, int arg1);
214 #endif
215
216 /* Deprecated: */
217 #if XCHAL_NUM_TIMERS > 0
218 extern void _xtos_timer_0_delta( int cycles );
219 #endif
220 #if XCHAL_NUM_TIMERS > 1
221 extern void _xtos_timer_1_delta( int cycles );
222 #endif
223 #if XCHAL_NUM_TIMERS > 2
224 extern void _xtos_timer_2_delta( int cycles );
225 #endif
226 #if XCHAL_NUM_TIMERS > 3
227 extern void _xtos_timer_3_delta( int cycles );
228 #endif
229
230 #ifdef __cplusplus
231 }
232 #endif
233
234 #endif /* !_ASMLANGUAGE && !__ASSEMBLER__ */
235
236 #endif /* XTRUNTIME_H */
237