Setting up repository
[linux-libre-firmware.git] / ath9k_htc / sboot / include / xtensa-elf / xtensa / xtruntime.h
1 /*
2  * xtruntime.h  --  general C definitions for single-threaded run-time
3  *
4  * Copyright (c) 2002-2006 by Tensilica Inc.  ALL RIGHTS RESERVED.
5  * These coded instructions, statements, and computer programs are the
6  * copyrighted works and confidential proprietary information of Tensilica Inc.
7  * They may not be modified, copied, reproduced, distributed, or disclosed to
8  * third parties in any manner, medium, or form, in whole or in part, without
9  * the prior written consent of Tensilica Inc.
10  */
11
12 #ifndef XTRUNTIME_H
13 #define XTRUNTIME_H
14
15 #include <xtensa/config/core.h>
16 #include <xtensa/config/specreg.h>
17
18 #ifndef XTSTR
19 #define _XTSTR(x)       # x
20 #define XTSTR(x)        _XTSTR(x)
21 #endif
22
23 #define _xtos_set_execption_handler _xtos_set_exception_handler /* backward compatibility */
24 #define _xtos_set_saved_intenable       _xtos_ints_on   /* backward compatibility */
25 #define _xtos_clear_saved_intenable     _xtos_ints_off  /* backward compatibility */
26
27 #if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33 /*typedef void (_xtos_timerdelta_func)(int);*/
34 #ifdef __cplusplus
35 typedef void (_xtos_handler_func)(...);
36 #else
37 typedef void (_xtos_handler_func)();
38 #endif
39 typedef _xtos_handler_func *_xtos_handler;
40
41 /*
42  *  unsigned XTOS_SET_INTLEVEL(int intlevel);
43  *  This macro sets the current interrupt level.
44  *  The 'intlevel' parameter must be a constant.
45  *  This macro returns a 32-bit value that must be passed to
46  *  XTOS_RESTORE_INTLEVEL() to restore the previous interrupt level.
47  *  XTOS_RESTORE_JUST_INTLEVEL() also does this, but in XEA2 configs
48  *  it restores only PS.INTLEVEL rather than the entire PS register
49  *  and thus is slower.
50  */
51 #if !XCHAL_HAVE_INTERRUPTS
52 # define XTOS_SET_INTLEVEL(intlevel)
53 # define XTOS_SET_MIN_INTLEVEL(intlevel)
54 # define XTOS_RESTORE_INTLEVEL(restoreval)
55 # define XTOS_RESTORE_JUST_INTLEVEL(restoreval)
56 #elif XCHAL_HAVE_XEA2
57 /*  In XEA2, we can simply safely set PS.INTLEVEL directly:  */
58 /*  NOTE: these asm macros don't modify memory, but they are marked
59  *  as such to act as memory access barriers to the compiler because
60  *  these macros are sometimes used to delineate critical sections;
61  *  function calls are natural barriers (the compiler does not know
62  *  whether a function modifies memory) unless declared to be inlined.  */
63 # define XTOS_SET_INTLEVEL(intlevel)            ({ unsigned __tmp; \
64                         __asm__ __volatile__(   "rsil   %0, " XTSTR(intlevel) "\n" \
65                                                 : "=a" (__tmp) : : "memory" ); \
66                         __tmp;})
67 # define XTOS_SET_MIN_INTLEVEL(intlevel)                ({ unsigned __tmp, __tmp2, __tmp3; \
68                         __asm__ __volatile__(   "rsr    %0, " XTSTR(PS) "\n"    /* get old (current) PS.INTLEVEL */ \
69                                                 "movi   %2, " XTSTR(intlevel) "\n" \
70                                                 "extui  %1, %0, 0, 4\n" /* keep only INTLEVEL bits of parameter */ \
71                                                 "blt    %2, %1, 1f\n" \
72                                                 "rsil   %0, " XTSTR(intlevel) "\n" \
73                                                 "1:\n" \
74                                                 : "=a" (__tmp), "=&a" (__tmp2), "=&a" (__tmp3) : : "memory" ); \
75                         __tmp;})
76 # define XTOS_RESTORE_INTLEVEL(restoreval)      do{ unsigned __tmp = (restoreval); \
77                         __asm__ __volatile__(   "wsr    %0, " XTSTR(PS) " ; rsync\n" \
78                                                 : : "a" (__tmp) : "memory" ); \
79                         }while(0)
80 # define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_intlevel(restoreval)
81 #else
82 /*  In XEA1, we have to rely on INTENABLE register virtualization:  */
83 extern unsigned         _xtos_set_vpri( unsigned vpri );
84 extern unsigned         _xtos_vpri_enabled;     /* current virtual priority */
85 # define XTOS_SET_INTLEVEL(intlevel)            _xtos_set_vpri(~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel))
86 # define XTOS_SET_MIN_INTLEVEL(intlevel)        _xtos_set_vpri(_xtos_vpri_enabled & ~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel))
87 # define XTOS_RESTORE_INTLEVEL(restoreval)      _xtos_set_vpri(restoreval)
88 # define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_vpri(restoreval)
89 #endif
90
91 /*
92  *  The following macros build upon the above.  They are generally used
93  *  instead of invoking the SET_INTLEVEL and SET_MIN_INTLEVEL macros directly.
94  *  They all return a value that can be used with XTOS_RESTORE_INTLEVEL()
95  *  or _xtos_restore_intlevel() or _xtos_restore_just_intlevel() to restore
96  *  the effective interrupt level to what it was before the macro was invoked.
97  *  In XEA2, the DISABLE macros are much faster than the MASK macros
98  *  (in all configs, DISABLE sets the effective interrupt level, whereas MASK
99  *  makes ensures the effective interrupt level is at least the level given
100  *  without lowering it; in XEA2 with INTENABLE virtualization, these macros
101  *  affect PS.INTLEVEL only, not the virtual priority, so DISABLE has partial
102  *  MASK semantics).
103  *
104  *  A typical critical section sequence might be:
105  *      unsigned rval = XTOS_DISABLE_EXCM_INTERRUPTS;
106  *      ... critical section ...
107  *      XTOS_RESTORE_INTLEVEL(rval);
108  */
109 /*  Enable all interrupts (those activated with _xtos_ints_on()):  */
110 #define XTOS_ENABLE_INTERRUPTS          XTOS_SET_INTLEVEL(0)
111 /*  Disable low priority level interrupts (they can interact with the OS):  */
112 #define XTOS_DISABLE_LOWPRI_INTERRUPTS  XTOS_SET_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS)
113 #define XTOS_MASK_LOWPRI_INTERRUPTS     XTOS_SET_MIN_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS)
114 /*  Disable interrupts that can interact with the OS:  */
115 #define XTOS_DISABLE_EXCM_INTERRUPTS    XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL)
116 #define XTOS_MASK_EXCM_INTERRUPTS       XTOS_SET_MIN_INTLEVEL(XCHAL_EXCM_LEVEL)
117 #if 0 /* XTOS_LOCK_LEVEL is not exported to applications */
118 /*  Disable interrupts that can interact with the OS, or manipulate virtual INTENABLE:  */
119 #define XTOS_DISABLE_LOCK_INTERRUPTS    XTOS_SET_INTLEVEL(XTOS_LOCK_LEVEL)
120 #define XTOS_MASK_LOCK_INTERRUPTS       XTOS_SET_MIN_INTLEVEL(XTOS_LOCK_LEVEL)
121 #endif
122 /*  Disable ALL interrupts (not for common use, particularly if one's processor
123  *  configuration has high-level interrupts and one cares about their latency):  */
124 #define XTOS_DISABLE_ALL_INTERRUPTS     XTOS_SET_INTLEVEL(15)
125
126
127 extern unsigned int     _xtos_ints_off( unsigned int mask );
128 extern unsigned int     _xtos_ints_on( unsigned int mask );
129 extern unsigned         _xtos_set_intlevel( int intlevel );
130 extern unsigned         _xtos_set_min_intlevel( int intlevel );
131 extern unsigned         _xtos_restore_intlevel( unsigned restoreval );
132 extern unsigned         _xtos_restore_just_intlevel( unsigned restoreval );
133 extern _xtos_handler    _xtos_set_interrupt_handler( int n, _xtos_handler f );
134 extern _xtos_handler    _xtos_set_interrupt_handler_arg( int n, _xtos_handler f, void *arg );
135 extern _xtos_handler    _xtos_set_exception_handler( int n, _xtos_handler f );
136
137 extern void             _xtos_memep_initrams( void );
138 extern void             _xtos_memep_enable( int flags );
139
140 /*  Deprecated (but kept because they were documented):  */
141 extern unsigned int     _xtos_read_ints( void );                /* use xthal_get_interrupt() instead */
142 extern void             _xtos_clear_ints( unsigned int mask );  /* use xthal_set_intclear() instead */
143
144 #if XCHAL_NUM_CONTEXTS > 1
145 extern unsigned         _xtos_init_context(int context_num, int stack_size,
146                                             _xtos_handler_func *start_func, int arg1);
147 #endif
148
149 /*  Deprecated:  */
150 #if XCHAL_NUM_TIMERS > 0
151 extern void             _xtos_timer_0_delta( int cycles );
152 #endif
153 #if XCHAL_NUM_TIMERS > 1
154 extern void             _xtos_timer_1_delta( int cycles );
155 #endif
156 #if XCHAL_NUM_TIMERS > 2
157 extern void             _xtos_timer_2_delta( int cycles );
158 #endif
159 #if XCHAL_NUM_TIMERS > 3
160 extern void             _xtos_timer_3_delta( int cycles );
161 #endif
162
163 #ifdef __cplusplus
164 }
165 #endif
166
167 #endif /* !_ASMLANGUAGE && !__ASSEMBLER__ */
168
169 #endif /* XTRUNTIME_H */