summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/mips/rtems/score/mips.h
blob: 97307b6f9793ca1e926156c5c59efe83366a8fa1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/**
 * @file rtems/score/mips.h
 */

/*
 *  COPYRIGHT (c) 1989-2001.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 *
 *  $Id$
 */

#ifndef _RTEMS_SCORE_MIPS_H
#define _RTEMS_SCORE_MIPS_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef ASM
#include <rtems/mips/idtcpu.h>
#endif

/*
 *  SR bits that enable/disable interrupts
 *
 *  NOTE: XXX what about SR_ERL?
 */

#if (__mips == 3) || (__mips == 32)
#ifdef ASM
#define SR_INTERRUPT_ENABLE_BITS 0x01
#else
#define SR_INTERRUPT_ENABLE_BITS SR_IE
#endif

#elif __mips == 1
#define SR_INTERRUPT_ENABLE_BITS SR_IEC

#else
#error "mips interrupt enable bits: unknown architecture level!"
#endif

/*
 *  This file contains the information required to build
 *  RTEMS for a particular member of the "no cpu"
 *  family when executing in protected mode.  It does
 *  this by setting variables to indicate which implementation
 *  dependent features are present in a particular member
 *  of the family.
 */
 
#if defined(__mips_soft_float)
#define MIPS_HAS_FPU 0
#else
#define MIPS_HAS_FPU 1
#endif 


#if (__mips == 1)
#define CPU_MODEL_NAME  "ISA Level 1 or 2"
#elif (__mips == 3) || (__mips == 32)
#if defined(__mips64)
#define CPU_MODEL_NAME  "ISA Level 4"
#else
#define CPU_MODEL_NAME  "ISA Level 3"
#endif
#else
#error "Unknown MIPS ISA level"
#endif

/*
 *  Define the name of the CPU family.
 */

#define CPU_NAME "MIPS"

/*
 *  RTEMS Vector numbers for exception conditions.  This is a direct
 *  map to the causes.
 */

#define MIPS_EXCEPTION_BASE 0

#define MIPS_EXCEPTION_INT              MIPS_EXCEPTION_BASE+0
#define MIPS_EXCEPTION_MOD              MIPS_EXCEPTION_BASE+1
#define MIPS_EXCEPTION_TLBL             MIPS_EXCEPTION_BASE+2
#define MIPS_EXCEPTION_TLBS             MIPS_EXCEPTION_BASE+3
#define MIPS_EXCEPTION_ADEL             MIPS_EXCEPTION_BASE+4
#define MIPS_EXCEPTION_ADES             MIPS_EXCEPTION_BASE+5
#define MIPS_EXCEPTION_IBE              MIPS_EXCEPTION_BASE+6
#define MIPS_EXCEPTION_DBE              MIPS_EXCEPTION_BASE+7
#define MIPS_EXCEPTION_SYSCALL          MIPS_EXCEPTION_BASE+8
#define MIPS_EXCEPTION_BREAK            MIPS_EXCEPTION_BASE+9
#define MIPS_EXCEPTION_RI               MIPS_EXCEPTION_BASE+10
#define MIPS_EXCEPTION_CPU              MIPS_EXCEPTION_BASE+11
#define MIPS_EXCEPTION_OVERFLOW         MIPS_EXCEPTION_BASE+12
#define MIPS_EXCEPTION_TRAP             MIPS_EXCEPTION_BASE+13
#define MIPS_EXCEPTION_VCEI             MIPS_EXCEPTION_BASE+14
/* FPE only on mips2 and higher */
#define MIPS_EXCEPTION_FPE              MIPS_EXCEPTION_BASE+15
#define MIPS_EXCEPTION_C2E              MIPS_EXCEPTION_BASE+16
/* 17-22 reserved */
#define MIPS_EXCEPTION_WATCH            MIPS_EXCEPTION_BASE+23
/* 24-30 reserved */
#define MIPS_EXCEPTION_VCED             MIPS_EXCEPTION_BASE+31

#define MIPS_INTERRUPT_BASE             MIPS_EXCEPTION_BASE+32

/*
 *  Some macros to access registers
 */

#define mips_get_sr( _x ) \
  do { \
    asm volatile( "mfc0 %0, $12; nop" : "=r" (_x) : ); \
  } while (0)

#define mips_set_sr( _x ) \
  do { \
    register unsigned int __x = (_x); \
    asm volatile( "mtc0 %0, $12; nop" : : "r" (__x) ); \
  } while (0)


/*
 *  Access the Cause register
 */

#define mips_get_cause( _x ) \
  do { \
    asm volatile( "mfc0 %0, $13; nop" : "=r" (_x) : ); \
  } while (0)


#define mips_set_cause( _x ) \
  do { \
    register unsigned int __x = (_x); \
    asm volatile( "mtc0 %0, $13; nop" : : "r" (__x) ); \
  } while (0)




/*
 *  Access the Debug Cache Invalidate Control register
 */

#define mips_get_dcic( _x ) \
  do { \
    asm volatile( "mfc0 %0, $7; nop" : "=r" (_x) : ); \
  } while (0)


#define mips_set_dcic( _x ) \
  do { \
    register unsigned int __x = (_x); \
    asm volatile( "mtc0 %0, $7; nop" : : "r" (__x) ); \
  } while (0)




/*
 *  Access the Breakpoint Program Counter & Mask registers 
 *  (_x for BPC, _y for mask)
 */

#define mips_get_bpcrm( _x, _y ) \
  do { \
    asm volatile( "mfc0 %0, $3; nop" : "=r" (_x) : ); \
    asm volatile( "mfc0 %0, $11; nop" : "=r" (_y) : ); \
  } while (0)


#define mips_set_bpcrm( _x, _y ) \
  do { \
    register unsigned int __x = (_x); \
    register unsigned int __y = (_y); \
    asm volatile( "mtc0 %0, $11; nop" : : "r" (__y) ); \
    asm volatile( "mtc0 %0, $3; nop" : : "r" (__x) ); \
  } while (0)






/*
 *  Access the Breakpoint Data Address & Mask registers 
 *  (_x for BDA, _y for mask)
 */

#define mips_get_bdarm( _x, _y ) \
  do { \
    asm volatile( "mfc0 %0, $5; nop" : "=r" (_x) : ); \
    asm volatile( "mfc0 %0, $9; nop" : "=r" (_y) : ); \
  } while (0)


#define mips_set_bdarm( _x, _y ) \
  do { \
    register unsigned int __x = (_x); \
    register unsigned int __y = (_y); \
    asm volatile( "mtc0 %0, $9; nop" : : "r" (__y) ); \
    asm volatile( "mtc0 %0, $5; nop" : : "r" (__x) ); \
  } while (0)







/*
 *  Access FCR31
 */

#if ( MIPS_HAS_FPU == 1 )

#define mips_get_fcr31( _x ) \
  do { \
    asm volatile( "cfc1 %0, $31; nop" : "=r" (_x) : ); \
  } while(0)


#define mips_set_fcr31( _x ) \
  do { \
    register unsigned int __x = (_x); \
    asm volatile( "ctc1 %0, $31; nop" : : "r" (__x) ); \
  } while(0)

#else

#define mips_get_fcr31( _x )
#define mips_set_fcr31( _x )

#endif

/*
 *  Manipulate interrupt mask 
 *
 *  mips_unmask_interrupt( _mask) 
 *    enables interrupts - mask is positioned so it only needs to be or'ed
 *    into the status reg. This also does some other things !!!! Caution
 *    should be used if invoking this while in the middle of a debugging
 *    session where the client may have nested interrupts.
 *
 *  mips_mask_interrupt( _mask )
 *    disable the interrupt - mask is the complement of the bits to be
 *    cleared - i.e. to clear ext int 5 the mask would be - 0xffff7fff
 *
 *
 *  NOTE: mips_mask_interrupt() used to be disable_int().
 *        mips_unmask_interrupt() used to be enable_int().
 *
 */

#define mips_enable_in_interrupt_mask( _mask ) \
  do { \
    unsigned int _sr; \
    mips_get_sr( _sr ); \
    _sr |= (_mask); \
    mips_set_sr( _sr ); \
  } while (0)

#define mips_disable_in_interrupt_mask( _mask ) \
  do { \
    unsigned int _sr; \
    mips_get_sr( _sr ); \
    _sr &= ~(_mask); \
    mips_set_sr( _sr ); \
  } while (0)

#ifdef __cplusplus
}
#endif

#endif /* _RTEMS_SCORE_MIPS_H */
/* end of include file */