]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/mips/rmi/xlrconfig.h
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.git] / sys / mips / rmi / xlrconfig.h
1 /*-
2  * Copyright (c) 2003-2009 RMI Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of RMI Corporation, nor the names of its contributors,
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * RMI_BSD */
30 #ifndef XLRCONFIG_H
31 #define XLRCONFIG_H
32
33 #include <sys/types.h>
34 #include <mips/rmi/shared_structs.h>
35 #include <mips/rmi/shared_structs_func.h>
36
37 #define read_c0_register32(reg, sel)                            \
38 ({ unsigned int __rv;                                           \
39         __asm__ __volatile__(                                   \
40         ".set\tpush\n\t"                                        \
41         ".set mips32\n\t"                                       \
42         "mfc0\t%0,$%1,%2\n\t"                                   \
43         ".set\tpop"                                             \
44         : "=r" (__rv) : "i" (reg), "i" (sel) );                 \
45         __rv;})
46
47 #define write_c0_register32(reg,  sel, value)                   \
48         __asm__ __volatile__(                                   \
49         ".set\tpush\n\t"                                        \
50         ".set mips32\n\t"                                       \
51         "mtc0\t%0,$%1,%2\n\t"                                   \
52         ".set\tpop"                                             \
53         : : "r" (value), "i" (reg), "i" (sel) );
54
55 #define read_c0_register64(reg, sel)                            \
56    ({ unsigned int __high, __low;                               \
57         __asm__ __volatile__(                                   \
58         ".set\tpush\n\t"                                        \
59         ".set mips64\n\t"                                       \
60         "dmfc0\t $8, $%2, %3\n\t"                               \
61         "dsrl32\t%0, $8, 0\n\t"                                 \
62         "dsll32\t$8, $8, 0\n\t"                                 \
63         "dsrl32\t%1, $8, 0\n\t"                                 \
64         ".set\tpop"                                             \
65         : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\
66         (((unsigned long long)__high << 32) | __low);})
67
68 #define write_c0_register64(reg, sel, value)                    \
69  do{                                                            \
70        unsigned int __high = val>>32;                           \
71        unsigned int __low = val & 0xffffffff;                   \
72         __asm__ __volatile__(                                   \
73         ".set\tpush\n\t"                                        \
74         ".set mips64\n\t"                                       \
75         "dsll32\t$8, %1, 0\n\t"                                 \
76         "dsll32\t$9, %0, 0\n\t"                                 \
77         "or\t    $8, $8, $9\n\t"                                \
78         "dmtc0\t $8, $%2, %3\n\t"                               \
79         ".set\tpop"                                             \
80         :: "r"(high), "r"(low),  "i"(reg), "i"(sel):"$8", "$9");\
81    } while(0)
82
83 #define read_c2_register32(reg, sel)                            \
84 ({ unsigned int __rv;                                           \
85         __asm__ __volatile__(                                   \
86         ".set\tpush\n\t"                                        \
87         ".set mips32\n\t"                                       \
88         "mfc2\t%0,$%1,%2\n\t"                                   \
89         ".set\tpop"                                             \
90         : "=r" (__rv) : "i" (reg), "i" (sel) );                 \
91         __rv;})
92
93 #define write_c2_register32(reg,  sel, value)                   \
94         __asm__ __volatile__(                                   \
95         ".set\tpush\n\t"                                        \
96         ".set mips32\n\t"                                       \
97         "mtc2\t%0,$%1,%2\n\t"                                   \
98         ".set\tpop"                                             \
99         : : "r" (value), "i" (reg), "i" (sel) );
100
101 #define read_c2_register64(reg, sel)                            \
102    ({ unsigned int __high, __low;                               \
103         __asm__ __volatile__(                                   \
104         ".set mips64\n\t"                                       \
105         "dmfc2\t $8, $%2, %3\n\t"                               \
106         "dsrl32\t%0, $8, 0\n\t"                                 \
107         "dsll32\t$8, $8, 0\n\t"                                 \
108         "dsrl32\t%1, $8, 0\n\t"                                 \
109         ".set\tmips0"                                           \
110         : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\
111         (((unsigned long long)__high << 32) | __low);})
112
113 #define write_c2_register64(reg, sel, value)                    \
114  do{                                                            \
115        unsigned int __high = value>>32;                         \
116        unsigned int __low = value & 0xffffffff;                 \
117         __asm__ __volatile__(                                   \
118         ".set mips64\n\t"                                       \
119         "dsll32\t$8, %1, 0\n\t"                                 \
120         "dsll32\t$9, %0, 0\n\t"                                 \
121         "dsrl32\t$8, $8, 0\n\t"                                 \
122         "or\t    $8, $8, $9\n\t"                                \
123         "dmtc2\t $8, $%2, %3\n\t"                               \
124         ".set\tmips0"                                           \
125         :: "r"(__high), "r"(__low),                             \
126            "i"(reg), "i"(sel)                                   \
127         :"$8", "$9");                                           \
128    } while(0)
129
130 #if 0
131 #define xlr_processor_id()                                      \
132 ({int __id;                                                     \
133  __asm__ __volatile__ (                                         \
134            ".set push\n"                                        \
135            ".set noreorder\n"                                   \
136            ".word 0x40088007\n"                                 \
137            "srl  $8, $8, 10\n"                                  \
138            "andi %0, $8, 0x3f\n"                                \
139            ".set pop\n"                                         \
140            : "=r" (__id) : : "$8");                             \
141  __id;})
142 #endif
143
144 #define xlr_cpu_id()                                        \
145 ({int __id;                                                     \
146  __asm__ __volatile__ (                                         \
147            ".set push\n"                                        \
148            ".set noreorder\n"                                   \
149            ".word 0x40088007\n"                                 \
150            "srl  $8, $8, 4\n"                                   \
151            "andi %0, $8, 0x7\n"                                \
152            ".set pop\n"                                         \
153            : "=r" (__id) : : "$8");                             \
154  __id;})
155
156 #define xlr_thr_id()                                        \
157 ({int __id;                                                     \
158  __asm__ __volatile__ (                                         \
159            ".set push\n"                                        \
160            ".set noreorder\n"                                   \
161            ".word 0x40088007\n"                                 \
162            "andi %0, $8, 0x03\n"                                \
163            ".set pop\n"                                         \
164            : "=r" (__id) : : "$8");                             \
165  __id;})
166
167
168 /* Additional registers on the XLR */
169 #define MIPS_COP_0_OSSCRATCH   22
170
171 #define XLR_CACHELINE_SIZE 32
172
173 #define XLR_MAX_CORES 8
174
175 /* functions to write to and read from the extended
176  * cp0 registers.
177  * EIRR : Extended Interrupt Request Register
178  *        cp0 register 9 sel 6
179  *        bits 0...7 are same as cause register 8...15
180  * EIMR : Extended Interrupt Mask Register
181  *        cp0 register 9 sel 7
182  *        bits 0...7 are same as status register 8...15
183  */
184
185 static inline uint64_t 
186 read_c0_eirr64(void)
187 {
188         __uint32_t high, low;
189
190         __asm__ __volatile__(
191                     ".set push\n"
192                     ".set noreorder\n"
193                     ".set noat\n"
194                     ".set mips4\n"
195
196                     ".word 0x40214806  \n\t"
197                     "nop               \n\t"
198                     "dsra32 %0, $1, 0  \n\t"
199                     "sll    %1, $1, 0  \n\t"
200
201                     ".set pop\n"
202
203             :       "=r"(high), "=r"(low)
204         );
205
206         return (((__uint64_t) high) << 32) | low;
207 }
208
209 static inline __uint64_t 
210 read_c0_eimr64(void)
211 {
212         __uint32_t high, low;
213
214         __asm__ __volatile__(
215                     ".set push\n"
216                     ".set noreorder\n"
217                     ".set noat\n"
218                     ".set mips4\n"
219
220                     ".word 0x40214807  \n\t"
221                     "nop               \n\t"
222                     "dsra32 %0, $1, 0  \n\t"
223                     "sll    %1, $1, 0  \n\t"
224
225                     ".set pop\n"
226
227             :       "=r"(high), "=r"(low)
228         );
229
230         return (((__uint64_t) high) << 32) | low;
231 }
232
233 static inline void 
234 write_c0_eirr64(__uint64_t value)
235 {
236         __uint32_t low, high;
237
238         high = value >> 32;
239         low = value & 0xffffffff;
240
241         __asm__ __volatile__(
242                     ".set push\n"
243                     ".set noreorder\n"
244                     ".set noat\n"
245                     ".set mips4\n\t"
246
247                     "dsll32 $2, %1, 0  \n\t"
248                     "dsll32 $1, %0, 0  \n\t"
249                     "dsrl32 $2, $2, 0  \n\t"
250                     "or     $1, $1, $2 \n\t"
251                     ".word  0x40a14806 \n\t"
252                     "nop               \n\t"
253
254                     ".set pop\n"
255
256             :
257             :       "r"(high), "r"(low)
258             :       "$1", "$2");
259 }
260
261 static inline void 
262 write_c0_eimr64(__uint64_t value)
263 {
264         __uint32_t low, high;
265
266         high = value >> 32;
267         low = value & 0xffffffff;
268
269         __asm__ __volatile__(
270                     ".set push\n"
271                     ".set noreorder\n"
272                     ".set noat\n"
273                     ".set mips4\n\t"
274
275                     "dsll32 $2, %1, 0  \n\t"
276                     "dsll32 $1, %0, 0  \n\t"
277                     "dsrl32 $2, $2, 0  \n\t"
278                     "or     $1, $1, $2 \n\t"
279                     ".word  0x40a14807 \n\t"
280                     "nop               \n\t"
281
282                     ".set pop\n"
283
284             :
285             :       "r"(high), "r"(low)
286             :       "$1", "$2");
287 }
288
289 static __inline__ int 
290 xlr_test_and_set(int *lock)
291 {
292         int oldval = 0;
293
294         __asm__ __volatile__(".set push\n"
295                     ".set noreorder\n"
296                     "move $9, %2\n"
297                     "li $8, 1\n"
298             //      "swapw $8, $9\n"
299                     ".word 0x71280014\n"
300                     "move %1, $8\n"
301                     ".set pop\n"
302             :       "+m"(*lock), "=r"(oldval)
303             :       "r"((unsigned long)lock)
304             :       "$8", "$9"
305         );
306
307         return (oldval == 0 ? 1 /* success */ : 0 /* failure */ );
308 }
309
310 static __inline__ uint32_t 
311 xlr_mfcr(uint32_t reg)
312 {
313         uint32_t val;
314
315         __asm__ __volatile__(
316                     "move   $8, %1\n"
317                     ".word  0x71090018\n"
318                     "move   %0, $9\n"
319             :       "=r"(val)
320             :       "r"(reg):"$8", "$9");
321
322         return val;
323 }
324
325 static __inline__ void 
326 xlr_mtcr(uint32_t reg, uint32_t val)
327 {
328         __asm__ __volatile__(
329                     "move   $8, %1\n"
330                     "move   $9, %0\n"
331                     ".word  0x71090019\n"
332             ::      "r"(val), "r"(reg)
333             :       "$8", "$9");
334 }
335
336 #endif