RTEMS  5.1
sh.h
Go to the documentation of this file.
1 
10 /*
11  * Authors: Ralf Corsepius (corsepiu@faw.uni-ulm.de) and
12  * Bernd Becker (becker@faw.uni-ulm.de)
13  *
14  * COPYRIGHT (c) 1997-1998, FAW Ulm, Germany
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
19  *
20  *
21  * COPYRIGHT (c) 1998-2001.
22  * On-Line Applications Research Corporation (OAR).
23  *
24  * The license and distribution terms for this file may be
25  * found in the file LICENSE in this distribution or at
26  * http://www.rtems.org/license/LICENSE.
27  */
28 
29 #ifndef _RTEMS_SCORE_SH_H
30 #define _RTEMS_SCORE_SH_H
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 /*
37  * This file contains the information required to build
38  * RTEMS for a particular member of the "SH" family.
39  *
40  * It does this by setting variables to indicate which implementation
41  * dependent features are present in a particular member of the family.
42  */
43 
44 /*
45  * Figure out all CPU Model Feature Flags based upon compiler
46  * predefines.
47  */
48 
49 #if defined(__SH2E__) || defined(__SH3E__)
50 
51 /* FIXME: SH-DSP context not currently supported */
52 #define SH_HAS_FPU 0
53 
54 #elif defined(__SH4__) || defined(__SH4_SINGLE_ONLY__)
55 
56 /*
57  * Define this if you want to use XD-registers.
58  * Then this registers will be saved/restored on context switch.
59  * ! They will not be saved/restored on interrupts!
60  */
61 #define SH4_USE_X_REGISTERS 0
62 
63 #if defined(__LITTLE_ENDIAN__)
64 #define SH_HAS_FPU 1
65 #else
66 /* FIXME: Context_Control_fp does not support big endian */
67 #warning FPU not supported
68 #define SH_HAS_FPU 0
69 #endif
70 
71 #elif defined(__sh1__) || defined(__sh2__) || defined(__sh3__)
72 #define SH_HAS_FPU 0
73 #else
74 #warning Cannot detect FPU support, assuming no FPU
75 #define SH_HAS_FPU 0
76 #endif
77 
78 /* this should not be here */
79 #ifndef CPU_MODEL_NAME
80 #define CPU_MODEL_NAME "SH-Multilib"
81 #endif
82 
83 /*
84  * If the following macro is set to 0 there will be no software irq stack
85  */
86 
87 #ifndef SH_HAS_SEPARATE_STACKS
88 #define SH_HAS_SEPARATE_STACKS 1
89 #endif
90 
91 /*
92  * Define the name of the CPU family.
93  */
94 
95 #define CPU_NAME "Hitachi SH"
96 
97 #ifndef ASM
98 
99 #if defined(__sh1__) || defined(__sh2__)
100 
101 /*
102  * Mask for disabling interrupts
103  */
104 #define SH_IRQDIS_VALUE 0xf0
105 
106 #define sh_disable_interrupts( _level ) \
107  __asm__ volatile ( \
108  "stc sr,%0\n\t" \
109  "ldc %1,sr\n\t"\
110  : "=&r" (_level ) \
111  : "r" (SH_IRQDIS_VALUE) );
112 
113 #define sh_enable_interrupts( _level ) \
114  __asm__ volatile( "ldc %0,sr\n\t" \
115  "nop\n\t" \
116  :: "r" (_level) );
117 
118 /*
119  * This temporarily restores the interrupt to _level before immediately
120  * disabling them again. This is used to divide long RTEMS critical
121  * sections into two or more parts. The parameter _level is not
122  * modified.
123  */
124 
125 #define sh_flash_interrupts( _level ) \
126  __asm__ volatile( \
127  "ldc %1,sr\n\t" \
128  "nop\n\t" \
129  "ldc %0,sr\n\t" \
130  "nop\n\t" \
131  : : "r" (SH_IRQDIS_VALUE), "r" (_level) );
132 
133 #else
134 
135 #define SH_IRQDIS_MASK 0xf0
136 
137 #define sh_disable_interrupts( _level ) \
138  __asm__ volatile ( \
139  "stc sr,%0\n\t" \
140  "mov %0,r5\n\t" \
141  "or %1,r5\n\t" \
142  "ldc r5,sr\n\t"\
143  : "=&r" (_level ) \
144  : "r" (SH_IRQDIS_MASK) \
145  : "r5" );
146 
147 #define sh_enable_interrupts( _level ) \
148  __asm__ volatile( "ldc %0,sr\n\t" \
149  "nop\n\t" \
150  :: "r" (_level) );
151 
152 /*
153  * This temporarily restores the interrupt to _level before immediately
154  * disabling them again. This is used to divide long RTEMS critical
155  * sections into two or more parts. The parameter _level is not
156  * modified.
157  */
158 
159 #define sh_flash_interrupts( _level ) \
160  __asm__ volatile( \
161  "stc sr,r5\n\t" \
162  "ldc %1,sr\n\t" \
163  "nop\n\t" \
164  "or %0,r5\n\t" \
165  "ldc r5,sr\n\t" \
166  "nop\n\t" \
167  : : "r" (SH_IRQDIS_MASK), "r" (_level) : "r5");
168 
169 #endif
170 
171 #define sh_get_interrupt_level( _level ) \
172 { \
173  uint32_t _tmpsr ; \
174  \
175  __asm__ volatile( "stc sr, %0" : "=r" (_tmpsr) ); \
176  _level = (_tmpsr & 0xf0) >> 4 ; \
177 }
178 
179 #define sh_set_interrupt_level( _newlevel ) \
180 { \
181  uint32_t _tmpsr; \
182  \
183  __asm__ volatile ( "stc sr, %0" : "=r" (_tmpsr) ); \
184  _tmpsr = ( _tmpsr & ~0xf0 ) | ((_newlevel) << 4) ; \
185  __asm__ volatile( "ldc %0,sr" :: "r" (_tmpsr) ); \
186 }
187 
188 /*
189  * The following routine swaps the endian format of an unsigned int.
190  * It must be static because it is referenced indirectly.
191  */
192 
193 static inline uint32_t sh_swap_u32(
194  uint32_t value
195 )
196 {
197  uint32_t swapped;
198 
199  __asm__ volatile (
200  "swap.b %1,%0; "
201  "swap.w %0,%0; "
202  "swap.b %0,%0"
203  : "=r" (swapped)
204  : "r" (value) );
205 
206  return( swapped );
207 }
208 
209 static inline uint16_t sh_swap_u16(
210  uint16_t value
211 )
212 {
213  uint16_t swapped ;
214 
215  __asm__ volatile ( "swap.b %1,%0" : "=r" (swapped) : "r" (value) );
216 
217  return( swapped );
218 }
219 
220 #define CPU_swap_u32( value ) sh_swap_u32( value )
221 #define CPU_swap_u16( value ) sh_swap_u16( value )
222 
223 extern unsigned int sh_set_irq_priority(
224  unsigned int irq,
225  unsigned int prio );
226 
227 #endif /* !ASM */
228 
229 /*
230  * Bits on SH-4 registers.
231  * See SH-4 Programming manual for more details.
232  *
233  * Added by Alexandra Kossovsky <sasha@oktet.ru>
234  */
235 
236 #if defined(__SH4__)
237 #define SH4_SR_MD 0x40000000 /* Priveleged mode */
238 #define SH4_SR_RB 0x20000000 /* General register bank specifier */
239 #define SH4_SR_BL 0x10000000 /* Exeption/interrupt masking bit */
240 #define SH4_SR_FD 0x00008000 /* FPU disable bit */
241 #define SH4_SR_M 0x00000200 /* For signed division:
242  divisor (module) is negative */
243 #define SH4_SR_Q 0x00000100 /* For signed division:
244  dividend (and quotient) is negative */
245 #define SH4_SR_IMASK 0x000000f0 /* Interrupt mask level */
246 #define SH4_SR_IMASK_S 4
247 #define SH4_SR_S 0x00000002 /* Saturation for MAC instruction:
248  if set, data in MACH/L register
249  is restricted to 48/32 bits
250  for MAC.W/L instructions */
251 #define SH4_SR_T 0x00000001 /* 1 if last condiyion was true */
252 #define SH4_SR_RESERV 0x8fff7d0d /* Reserved bits, read/write as 0 */
253 
254 /* FPSCR -- FPU Status/Control Register */
255 #define SH4_FPSCR_FR 0x00200000 /* FPU register bank specifier */
256 #define SH4_FPSCR_SZ 0x00100000 /* FMOV 64-bit transfer mode */
257 #define SH4_FPSCR_PR 0x00080000 /* Double-percision floating-point
258  operations flag */
259  /* SH4_FPSCR_SZ & SH4_FPSCR_PR != 1 */
260 #define SH4_FPSCR_DN 0x00040000 /* Treat denormalized number as zero */
261 #define SH4_FPSCR_CAUSE 0x0003f000 /* FPU exeption cause field */
262 #define SH4_FPSCR_CAUSE_S 12
263 #define SH4_FPSCR_ENABLE 0x00000f80 /* FPU exeption enable field */
264 #define SH4_FPSCR_ENABLE_s 7
265 #define SH4_FPSCR_FLAG 0x0000007d /* FPU exeption flag field */
266 #define SH4_FPSCR_FLAG_S 2
267 #define SH4_FPSCR_RM 0x00000001 /* Rounding mode:
268  1/0 -- round to zero/nearest */
269 #define SH4_FPSCR_RESERV 0xffd00000 /* Reserved bits, read/write as 0 */
270 
271 #endif
272 
273 #ifdef __cplusplus
274 }
275 #endif
276 
277 #endif
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.