2 * Copyright (c) 2013 Tensilica Inc.
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:
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
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.
27 #include <xtensa/config/core.h>
28 #include <xtensa/config/specreg.h>
32 #define XTSTR(x) _XTSTR(x)
35 #define _xtos_set_execption_handler _xtos_set_exception_handler /* backward compatibility */
36 #define _xtos_set_saved_intenable _xtos_ints_on /* backward compatibility */
37 #define _xtos_clear_saved_intenable _xtos_ints_off /* backward compatibility */
39 #if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
45 /*typedef void (_xtos_timerdelta_func)(int);*/
47 typedef void (_xtos_handler_func)(...);
49 typedef void (_xtos_handler_func)();
51 typedef _xtos_handler_func *_xtos_handler;
54 * unsigned XTOS_SET_INTLEVEL(int intlevel);
55 * This macro sets the current interrupt level.
56 * The 'intlevel' parameter must be a constant.
57 * This macro returns a 32-bit value that must be passed to
58 * XTOS_RESTORE_INTLEVEL() to restore the previous interrupt level.
59 * XTOS_RESTORE_JUST_INTLEVEL() also does this, but in XEA2 configs
60 * it restores only PS.INTLEVEL rather than the entire PS register
63 #if !XCHAL_HAVE_INTERRUPTS
64 # define XTOS_SET_INTLEVEL(intlevel)
65 # define XTOS_SET_MIN_INTLEVEL(intlevel)
66 # define XTOS_RESTORE_INTLEVEL(restoreval)
67 # define XTOS_RESTORE_JUST_INTLEVEL(restoreval)
69 /* In XEA2, we can simply safely set PS.INTLEVEL directly: */
70 /* NOTE: these asm macros don't modify memory, but they are marked
71 * as such to act as memory access barriers to the compiler because
72 * these macros are sometimes used to delineate critical sections;
73 * function calls are natural barriers (the compiler does not know
74 * whether a function modifies memory) unless declared to be inlined. */
75 # define XTOS_SET_INTLEVEL(intlevel) ({ unsigned __tmp; \
76 __asm__ __volatile__( "rsil %0, " XTSTR(intlevel) "\n" \
77 : "=a" (__tmp) : : "memory" ); \
79 # define XTOS_SET_MIN_INTLEVEL(intlevel) ({ unsigned __tmp, __tmp2, __tmp3; \
80 __asm__ __volatile__( "rsr %0, " XTSTR(PS) "\n" /* get old (current) PS.INTLEVEL */ \
81 "movi %2, " XTSTR(intlevel) "\n" \
82 "extui %1, %0, 0, 4\n" /* keep only INTLEVEL bits of parameter */ \
84 "rsil %0, " XTSTR(intlevel) "\n" \
86 : "=a" (__tmp), "=&a" (__tmp2), "=&a" (__tmp3) : : "memory" ); \
88 # define XTOS_RESTORE_INTLEVEL(restoreval) do{ unsigned __tmp = (restoreval); \
89 __asm__ __volatile__( "wsr %0, " XTSTR(PS) " ; rsync\n" \
90 : : "a" (__tmp) : "memory" ); \
92 # define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_intlevel(restoreval)
94 /* In XEA1, we have to rely on INTENABLE register virtualization: */
95 extern unsigned _xtos_set_vpri( unsigned vpri );
96 extern unsigned _xtos_vpri_enabled; /* current virtual priority */
97 # define XTOS_SET_INTLEVEL(intlevel) _xtos_set_vpri(~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel))
98 # define XTOS_SET_MIN_INTLEVEL(intlevel) _xtos_set_vpri(_xtos_vpri_enabled & ~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel))
99 # define XTOS_RESTORE_INTLEVEL(restoreval) _xtos_set_vpri(restoreval)
100 # define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_vpri(restoreval)
104 * The following macros build upon the above. They are generally used
105 * instead of invoking the SET_INTLEVEL and SET_MIN_INTLEVEL macros directly.
106 * They all return a value that can be used with XTOS_RESTORE_INTLEVEL()
107 * or _xtos_restore_intlevel() or _xtos_restore_just_intlevel() to restore
108 * the effective interrupt level to what it was before the macro was invoked.
109 * In XEA2, the DISABLE macros are much faster than the MASK macros
110 * (in all configs, DISABLE sets the effective interrupt level, whereas MASK
111 * makes ensures the effective interrupt level is at least the level given
112 * without lowering it; in XEA2 with INTENABLE virtualization, these macros
113 * affect PS.INTLEVEL only, not the virtual priority, so DISABLE has partial
116 * A typical critical section sequence might be:
117 * unsigned rval = XTOS_DISABLE_EXCM_INTERRUPTS;
118 * ... critical section ...
119 * XTOS_RESTORE_INTLEVEL(rval);
121 /* Enable all interrupts (those activated with _xtos_ints_on()): */
122 #define XTOS_ENABLE_INTERRUPTS XTOS_SET_INTLEVEL(0)
123 /* Disable low priority level interrupts (they can interact with the OS): */
124 #define XTOS_DISABLE_LOWPRI_INTERRUPTS XTOS_SET_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS)
125 #define XTOS_MASK_LOWPRI_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS)
126 /* Disable interrupts that can interact with the OS: */
127 #define XTOS_DISABLE_EXCM_INTERRUPTS XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL)
128 #define XTOS_MASK_EXCM_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XCHAL_EXCM_LEVEL)
129 #if 0 /* XTOS_LOCK_LEVEL is not exported to applications */
130 /* Disable interrupts that can interact with the OS, or manipulate virtual INTENABLE: */
131 #define XTOS_DISABLE_LOCK_INTERRUPTS XTOS_SET_INTLEVEL(XTOS_LOCK_LEVEL)
132 #define XTOS_MASK_LOCK_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XTOS_LOCK_LEVEL)
134 /* Disable ALL interrupts (not for common use, particularly if one's processor
135 * configuration has high-level interrupts and one cares about their latency): */
136 #define XTOS_DISABLE_ALL_INTERRUPTS XTOS_SET_INTLEVEL(15)
139 extern unsigned int _xtos_ints_off( unsigned int mask );
140 extern unsigned int _xtos_ints_on( unsigned int mask );
141 extern unsigned _xtos_set_intlevel( int intlevel );
142 extern unsigned _xtos_set_min_intlevel( int intlevel );
143 extern unsigned _xtos_restore_intlevel( unsigned restoreval );
144 extern unsigned _xtos_restore_just_intlevel( unsigned restoreval );
145 extern _xtos_handler _xtos_set_interrupt_handler( int n, _xtos_handler f );
146 extern _xtos_handler _xtos_set_interrupt_handler_arg( int n, _xtos_handler f, void *arg );
147 extern _xtos_handler _xtos_set_exception_handler( int n, _xtos_handler f );
149 extern void _xtos_memep_initrams( void );
150 extern void _xtos_memep_enable( int flags );
152 /* Deprecated (but kept because they were documented): */
153 extern unsigned int _xtos_read_ints( void ); /* use xthal_get_interrupt() instead */
154 extern void _xtos_clear_ints( unsigned int mask ); /* use xthal_set_intclear() instead */
156 #if XCHAL_NUM_CONTEXTS > 1
157 extern unsigned _xtos_init_context(int context_num, int stack_size,
158 _xtos_handler_func *start_func, int arg1);
162 #if XCHAL_NUM_TIMERS > 0
163 extern void _xtos_timer_0_delta( int cycles );
165 #if XCHAL_NUM_TIMERS > 1
166 extern void _xtos_timer_1_delta( int cycles );
168 #if XCHAL_NUM_TIMERS > 2
169 extern void _xtos_timer_2_delta( int cycles );
171 #if XCHAL_NUM_TIMERS > 3
172 extern void _xtos_timer_3_delta( int cycles );
179 #endif /* !_ASMLANGUAGE && !__ASSEMBLER__ */
181 #endif /* XTRUNTIME_H */