Deleted Added
full compact
rmi_mips_exts.h (211994) rmi_mips_exts.h (212366)
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

--- 13 unchanged lines hidden (view full) ---

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
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

--- 13 unchanged lines hidden (view full) ---

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 * $FreeBSD: head/sys/mips/rmi/rmi_mips_exts.h 211994 2010-08-30 13:05:21Z jchandra $
30 * $FreeBSD: head/sys/mips/rmi/rmi_mips_exts.h 212366 2010-09-09 17:45:48Z jchandra $
31 */
32#ifndef __MIPS_EXTS_H__
31 */
32#ifndef __MIPS_EXTS_H__
33#define __MIPS_EXTS_H__
33#define __MIPS_EXTS_H__
34
34
35#define CPU_BLOCKID_IFU 0
36#define CPU_BLOCKID_ICU 1
37#define CPU_BLOCKID_IEU 2
38#define CPU_BLOCKID_LSU 3
39#define CPU_BLOCKID_MMU 4
40#define CPU_BLOCKID_PRF 5
35#define CPU_BLOCKID_IFU 0
36#define CPU_BLOCKID_ICU 1
37#define CPU_BLOCKID_IEU 2
38#define CPU_BLOCKID_LSU 3
39#define CPU_BLOCKID_MMU 4
40#define CPU_BLOCKID_PRF 5
41
41
42#define LSU_CERRLOG_REGID 9
42#define LSU_CERRLOG_REGID 9
43
43
44static __inline__ unsigned int read_32bit_phnx_ctrl_reg(int block, int reg)
44#if defined(__mips_n64) || defined(__mips_n32)
45static __inline uint64_t
46read_xlr_ctrl_register(int block, int reg)
45{
47{
46 unsigned int __res;
48 uint64_t res;
47
49
48 __asm__ __volatile__(
49 ".set\tpush\n\t"
50 ".set\tnoreorder\n\t"
51 "move $9, %1\n"
52 /* "mfcr\t$8, $9\n\t" */
53 ".word 0x71280018\n"
54 "move %0, $8\n"
55 ".set\tpop"
56 : "=r" (__res) : "r"((block<<8)|reg)
57 : "$8", "$9"
58 );
59 return __res;
50 __asm__ __volatile__(
51 ".set push\n\t"
52 ".set noreorder\n\t"
53 "move $9, %1\n\t"
54 ".word 0x71280018\n\t" /* mfcr $8, $9 */
55 "move %0, $8\n\t"
56 ".set pop\n"
57 : "=r" (res) : "r"((block << 8) | reg)
58 : "$8", "$9"
59 );
60 return (res);
60}
61
61}
62
62static __inline__ void write_32bit_phnx_ctrl_reg(int block, int reg, unsigned int value)
63static __inline void
64write_xlr_ctrl_register(int block, int reg, uint64_t value)
63{
65{
64 __asm__ __volatile__(
65 ".set\tpush\n\t"
66 ".set\tnoreorder\n\t"
67 "move $8, %0\n"
68 "move $9, %1\n"
69 /* "mtcr\t$8, $9\n\t" */
70 ".word 0x71280019\n"
71 ".set\tpop"
72 :
73 : "r" (value), "r"((block<<8)|reg)
74 : "$8", "$9"
75 );
66 __asm__ __volatile__(
67 ".set push\n\t"
68 ".set noreorder\n\t"
69 "move $8, %0\n"
70 "move $9, %1\n"
71 ".word 0x71280019\n" /* mtcr $8, $9 */
72 ".set pop\n"
73 :
74 : "r" (value), "r" ((block << 8) | reg)
75 : "$8", "$9"
76 );
76}
77
77}
78
78static __inline__ unsigned long long read_64bit_phnx_ctrl_reg(int block, int reg)
79#else /* !(defined(__mips_n64) || defined(__mips_n32)) */
80
81static __inline uint64_t
82read_xlr_ctrl_register(int block, int reg)
79{
83{
80 unsigned int high, low;
81
82 __asm__ __volatile__(
83 ".set\tmips64\n\t"
84 "move $9, %2\n"
85 /* "mfcr $8, $9\n" */
86 ".word 0x71280018\n"
87 "dsrl32 %0, $8, 0\n\t"
88 "dsll32 $8, $8, 0\n\t"
89 "dsrl32 %1, $8, 0\n\t"
90 ".set mips0"
91 : "=r" (high), "=r"(low)
92 : "r"((block<<8)|reg)
93 : "$8", "$9"
94 );
95
96 return ( (((unsigned long long)high)<<32) | low);
84 uint32_t high, low;
85
86 __asm__ __volatile__(
87 ".set push\n\t"
88 ".set noreorder\n\t"
89 ".set mips64\n\t"
90 "move $9, %2\n"
91 ".word 0x71280018\n" /* "mfcr $8, $9\n" */
92 "dsra32 %0, $8, 0\n\t"
93 "sll %1, $8, 0\n\t"
94 ".set pop"
95 : "=r" (high), "=r"(low)
96 : "r" ((block << 8) | reg)
97 : "$8", "$9");
98
99 return ( (((uint64_t)high) << 32) | low);
97}
98
100}
101
99static __inline__ void write_64bit_phnx_ctrl_reg(int block, int reg,unsigned long long value)
102static __inline void
103write_xlr_ctrl_register(int block, int reg, uint64_t value)
100{
104{
101 __uint32_t low, high;
105 uint32_t low, high;
102 high = value >> 32;
103 low = value & 0xffffffff;
104
105 __asm__ __volatile__(
106 high = value >> 32;
107 low = value & 0xffffffff;
108
109 __asm__ __volatile__(
106 ".set push\n"
107 ".set noreorder\n"
108 ".set mips4\n\t"
109 /* Set up "rs" */
110 "move $9, %0\n"
110 ".set push\n\t"
111 ".set noreorder\n\t"
112 ".set mips64\n\t"
113 "dsll32 $9, %0, 0\n\t"
114 "dsll32 $8, %1, 0\n\t"
115 "dsrl32 $8, $8, 0\n\t"
116 "or $8, $9, $8\n\t"
117 "move $9, %2\n\t"
118 ".word 0x71280019\n\t" /* mtcr $8, $9 */
119 ".set pop\n"
120 : /* No outputs */
121 : "r" (high), "r" (low), "r"((block << 8) | reg)
122 : "$8", "$9");
123}
124#endif /* defined(__mips_n64) || defined(__mips_n32) */
111
125
112 /* Store 64 bit value in "rt" */
113 "dsll32 $10, %1, 0 \n\t"
114 "dsll32 $8, %2, 0 \n\t"
115 "dsrl32 $8, $8, 0 \n\t"
116 "or $10, $8, $8 \n\t"
126/*
127 * 32 bit read write for c0
128 */
129#define read_c0_register32(reg, sel) \
130({ \
131 uint32_t __rv; \
132 __asm__ __volatile__( \
133 ".set push\n\t" \
134 ".set mips32\n\t" \
135 "mfc0 %0, $%1, %2\n\t" \
136 ".set pop\n" \
137 : "=r" (__rv) : "i" (reg), "i" (sel) ); \
138 __rv; \
139 })
117
140
118 ".word 0x71280019\n" /* mtcr $8, $9 */
141#define write_c0_register32(reg, sel, value) \
142 __asm__ __volatile__( \
143 ".set push\n\t" \
144 ".set mips32\n\t" \
145 "mtc0 %0, $%1, %2\n\t" \
146 ".set pop\n" \
147 : : "r" (value), "i" (reg), "i" (sel) );
119
148
120 ".set pop\n"
149#define read_c2_register32(reg, sel) \
150({ \
151 uint32_t __rv; \
152 __asm__ __volatile__( \
153 ".set push\n\t" \
154 ".set mips32\n\t" \
155 "mfc2 %0, $%1, %2\n\t" \
156 ".set pop\n" \
157 : "=r" (__rv) : "i" (reg), "i" (sel) ); \
158 __rv; \
159 })
121
160
122 : /* No outputs */
123 : "r"((block<<8)|reg), "r" (high), "r" (low)
124 : "$8", "$9", "$10"
125 );
126}
161#define write_c2_register32(reg, sel, value) \
162 __asm__ __volatile__( \
163 ".set push\n\t" \
164 ".set mips32\n\t" \
165 "mtc2 %0, $%1, %2\n\t" \
166 ".set pop\n" \
167 : : "r" (value), "i" (reg), "i" (sel) );
127
168
128#define read_c0_register32(reg, sel) \
129({ unsigned int __rv; \
130 __asm__ __volatile__( \
131 ".set\tpush\n\t" \
132 ".set mips32\n\t" \
133 "mfc0\t%0,$%1,%2\n\t" \
134 ".set\tpop" \
135 : "=r" (__rv) : "i" (reg), "i" (sel) ); \
136 __rv;})
169#if defined(__mips_n64) || defined(__mips_n32)
170/*
171 * On 64 bit compilation, the operations are simple
172 */
173#define read_c0_register64(reg, sel) \
174({ \
175 uint64_t __rv; \
176 __asm__ __volatile__( \
177 ".set push\n\t" \
178 ".set mips64\n\t" \
179 "dmfc0 %0, $%1, %2\n\t" \
180 ".set pop\n" \
181 : "=r" (__rv) : "i" (reg), "i" (sel) ); \
182 __rv; \
183 })
137
184
138#define write_c0_register32(reg, sel, value) \
139 __asm__ __volatile__( \
140 ".set\tpush\n\t" \
141 ".set mips32\n\t" \
142 "mtc0\t%0,$%1,%2\n\t" \
143 ".set\tpop" \
144 : : "r" (value), "i" (reg), "i" (sel) );
185#define write_c0_register64(reg, sel, value) \
186 __asm__ __volatile__( \
187 ".set push\n\t" \
188 ".set mips64\n\t" \
189 "dmtc0 %0, $%1, %2\n\t" \
190 ".set pop\n" \
191 : : "r" (value), "i" (reg), "i" (sel) );
145
192
146#define read_c0_register64(reg, sel) \
147 ({ unsigned int __high, __low; \
148 __asm__ __volatile__( \
149 ".set\tpush\n\t" \
150 ".set mips64\n\t" \
151 "dmfc0\t $8, $%2, %3\n\t" \
152 "dsrl32\t%0, $8, 0\n\t" \
153 "dsll32\t$8, $8, 0\n\t" \
154 "dsrl32\t%1, $8, 0\n\t" \
155 ".set\tpop" \
156 : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\
157 (((unsigned long long)__high << 32) | __low);})
193#define read_c2_register64(reg, sel) \
194({ \
195 uint64_t __rv; \
196 __asm__ __volatile__( \
197 ".set push\n\t" \
198 ".set mips64\n\t" \
199 "dmfc2 %0, $%1, %2\n\t" \
200 ".set pop\n" \
201 : "=r" (__rv) : "i" (reg), "i" (sel) ); \
202 __rv; \
203 })
158
204
159#define write_c0_register64(reg, sel, value) \
160 do{ \
161 unsigned int __high = val>>32; \
162 unsigned int __low = val & 0xffffffff; \
163 __asm__ __volatile__( \
164 ".set\tpush\n\t" \
165 ".set mips64\n\t" \
166 "dsll32\t$8, %1, 0\n\t" \
167 "dsll32\t$9, %0, 0\n\t" \
168 "or\t $8, $8, $9\n\t" \
169 "dmtc0\t $8, $%2, %3\n\t" \
170 ".set\tpop" \
171 :: "r"(high), "r"(low), "i"(reg), "i"(sel):"$8", "$9");\
172 } while(0)
205#define write_c2_register64(reg, sel, value) \
206 __asm__ __volatile__( \
207 ".set push\n\t" \
208 ".set mips64\n\t" \
209 "dmtc2 %0, $%1, %2\n\t" \
210 ".set pop\n" \
211 : : "r" (value), "i" (reg), "i" (sel) );
173
212
174#define read_c2_register32(reg, sel) \
175({ unsigned int __rv; \
176 __asm__ __volatile__( \
177 ".set\tpush\n\t" \
178 ".set mips32\n\t" \
179 "mfc2\t%0,$%1,%2\n\t" \
180 ".set\tpop" \
181 : "=r" (__rv) : "i" (reg), "i" (sel) ); \
182 __rv;})
213#else /* ! (defined(__mips_n64) || defined(__mips_n32)) */
183
214
184#define write_c2_register32(reg, sel, value) \
185 __asm__ __volatile__( \
186 ".set\tpush\n\t" \
187 ".set mips32\n\t" \
188 "mtc2\t%0,$%1,%2\n\t" \
189 ".set\tpop" \
190 : : "r" (value), "i" (reg), "i" (sel) );
215/*
216 * 32 bit compilation, 64 bit values has to split
217 */
218#define read_c0_register64(reg, sel) \
219({ \
220 uint32_t __high, __low; \
221 __asm__ __volatile__( \
222 ".set push\n\t" \
223 ".set noreorder\n\t" \
224 ".set mips64\n\t" \
225 "dmfc0 $8, $%2, %3\n\t" \
226 "dsra32 %0, $8, 0\n\t" \
227 "sll %1, $8, 0\n\t" \
228 ".set pop\n" \
229 : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel) \
230 : "$8"); \
231 ((uint64_t)__high << 32) | __low; \
232})
191
233
192#define read_c2_register64(reg, sel) \
193 ({ unsigned int __high, __low; \
194 __asm__ __volatile__( \
195 ".set mips64\n\t" \
196 "dmfc2\t $8, $%2, %3\n\t" \
197 "dsrl32\t%0, $8, 0\n\t" \
198 "dsll32\t$8, $8, 0\n\t" \
199 "dsrl32\t%1, $8, 0\n\t" \
200 ".set\tmips0" \
201 : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel): "$8" );\
202 (((unsigned long long)__high << 32) | __low);})
234#define write_c0_register64(reg, sel, value) \
235do { \
236 uint32_t __high = value >> 32; \
237 uint32_t __low = value & 0xffffffff; \
238 __asm__ __volatile__( \
239 ".set push\n\t" \
240 ".set noreorder\n\t" \
241 ".set mips64\n\t" \
242 "dsll32 $8, %1, 0\n\t" \
243 "dsll32 $9, %0, 0\n\t" \
244 "dsrl32 $8, $8, 0\n\t" \
245 "or $8, $8, $9\n\t" \
246 "dmtc0 $8, $%2, %3\n\t" \
247 ".set pop" \
248 :: "r"(__high), "r"(__low), "i"(reg), "i"(sel) \
249 :"$8", "$9"); \
250} while(0)
203
251
204#define write_c2_register64(reg, sel, value) \
205 do{ \
206 unsigned int __high = value>>32; \
207 unsigned int __low = value & 0xffffffff; \
208 __asm__ __volatile__( \
209 ".set mips64\n\t" \
210 "dsll32\t$8, %1, 0\n\t" \
211 "dsll32\t$9, %0, 0\n\t" \
212 "dsrl32\t$8, $8, 0\n\t" \
213 "or\t $8, $8, $9\n\t" \
214 "dmtc2\t $8, $%2, %3\n\t" \
215 ".set\tmips0" \
216 :: "r"(__high), "r"(__low), \
217 "i"(reg), "i"(sel) \
218 :"$8", "$9"); \
219 } while(0)
252#define read_c2_register64(reg, sel) \
253({ \
254 uint32_t __high, __low; \
255 __asm__ __volatile__( \
256 ".set push\n\t" \
257 ".set noreorder\n\t" \
258 ".set mips64\n\t" \
259 "dmfc2 $8, $%2, %3\n\t" \
260 "dsra32 %0, $8, 0\n\t" \
261 "sll %1, $8, 0\n\t" \
262 ".set pop\n" \
263 : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel) \
264 : "$8"); \
265 ((uint64_t)__high << 32) | __low; \
266})
220
267
221#define xlr_cpu_id() \
222({int __id; \
223 __asm__ __volatile__ ( \
224 ".set push\n" \
225 ".set noreorder\n" \
226 "mfc0 $8, $15, 1\n" \
227 "andi %0, $8, 0x1f\n" \
228 ".set pop\n" \
229 : "=r" (__id) : : "$8"); \
230 __id;})
268#define write_c2_register64(reg, sel, value) \
269do { \
270 uint32_t __high = value >> 32; \
271 uint32_t __low = value & 0xffffffff; \
272 __asm__ __volatile__( \
273 ".set push\n\t" \
274 ".set noreorder\n\t" \
275 ".set mips64\n\t" \
276 "dsll32 $8, %1, 0\n\t" \
277 "dsll32 $9, %0, 0\n\t" \
278 "dsrl32 $8, $8, 0\n\t" \
279 "or $8, $8, $9\n\t" \
280 "dmtc2 $8, $%2, %3\n\t" \
281 ".set pop" \
282 :: "r"(__high), "r"(__low), "i"(reg), "i"(sel) \
283 :"$8", "$9"); \
284} while(0)
231
285
232#define xlr_core_id() \
233({int __id; \
234 __asm__ __volatile__ ( \
235 ".set push\n" \
236 ".set noreorder\n" \
237 "mfc0 $8, $15, 1\n" \
238 "andi %0, $8, 0x1f\n" \
239 ".set pop\n" \
240 : "=r" (__id) : : "$8"); \
241 __id/4;})
286#endif /* defined(__mips_n64) || defined(__mips_n32) */
242
287
243#define xlr_thr_id() \
244({int __id; \
245 __asm__ __volatile__ ( \
246 ".set push\n" \
247 ".set noreorder\n" \
248 "mfc0 $8, $15, 1\n" \
249 "andi %0, $8, 0x3\n" \
250 ".set pop\n" \
251 : "=r" (__id) : : "$8"); \
252 __id;})
288static __inline int
289xlr_cpu_id(void)
290{
253
291
292 return (read_c0_register32(15, 1) & 0x1f);
293}
254
294
255/* Additional registers on the XLR */
256#define MIPS_COP_0_OSSCRATCH 22
295static __inline int
296xlr_core_id(void)
297{
257
298
258#define XLR_CACHELINE_SIZE 32
299 return (xlr_cpu_id() / 4);
300}
259
301
260#define XLR_MAX_CORES 8
302static __inline int
303xlr_thr_id(void)
304{
261
305
306 return (read_c0_register32(15, 1) & 0x3);
307}
308
309/* Additional registers on the XLR */
310#define MIPS_COP_0_OSSCRATCH 22
311#define XLR_CACHELINE_SIZE 32
312#define XLR_MAX_CORES 8
313
262/* functions to write to and read from the extended
263 * cp0 registers.
264 * EIRR : Extended Interrupt Request Register
265 * cp0 register 9 sel 6
266 * bits 0...7 are same as cause register 8...15
267 * EIMR : Extended Interrupt Mask Register
268 * cp0 register 9 sel 7
269 * bits 0...7 are same as status register 8...15
270 */
314/* functions to write to and read from the extended
315 * cp0 registers.
316 * EIRR : Extended Interrupt Request Register
317 * cp0 register 9 sel 6
318 * bits 0...7 are same as cause register 8...15
319 * EIMR : Extended Interrupt Mask Register
320 * cp0 register 9 sel 7
321 * bits 0...7 are same as status register 8...15
322 */
271
272static inline uint64_t
323static __inline uint64_t
273read_c0_eirr64(void)
274{
324read_c0_eirr64(void)
325{
275 __uint32_t high, low;
276
326
277 __asm__ __volatile__(
278 ".set push\n"
279 ".set noreorder\n"
280 ".set noat\n"
281 ".set mips4\n"
282
283 ".word 0x40214806 \n\t"
284 "nop \n\t"
285 "dsra32 %0, $1, 0 \n\t"
286 "sll %1, $1, 0 \n\t"
287
288 ".set pop\n"
289
290 : "=r"(high), "=r"(low)
291 );
292
293 return (((__uint64_t) high) << 32) | low;
327 return (read_c0_register64(9, 6));
294}
295
328}
329
296static inline __uint64_t
297read_c0_eimr64(void)
330static __inline void
331write_c0_eirr64(uint64_t val)
298{
332{
299 __uint32_t high, low;
300
333
301 __asm__ __volatile__(
302 ".set push\n"
303 ".set noreorder\n"
304 ".set noat\n"
305 ".set mips4\n"
306
307 ".word 0x40214807 \n\t"
308 "nop \n\t"
309 "dsra32 %0, $1, 0 \n\t"
310 "sll %1, $1, 0 \n\t"
311
312 ".set pop\n"
313
314 : "=r"(high), "=r"(low)
315 );
316
317 return (((__uint64_t) high) << 32) | low;
334 write_c0_register64(9, 6, val);
318}
319
335}
336
320static inline void
321write_c0_eirr64(__uint64_t value)
337static __inline uint64_t
338read_c0_eimr64(void)
322{
339{
323 __uint32_t low, high;
324
340
325 high = value >> 32;
326 low = value & 0xffffffff;
327
328 __asm__ __volatile__(
329 ".set push\n"
330 ".set noreorder\n"
331 ".set noat\n"
332 ".set mips4\n\t"
333
334 "dsll32 $2, %1, 0 \n\t"
335 "dsll32 $1, %0, 0 \n\t"
336 "dsrl32 $2, $2, 0 \n\t"
337 "or $1, $1, $2 \n\t"
338 ".word 0x40a14806 \n\t"
339 "nop \n\t"
340
341 ".set pop\n"
342
343 :
344 : "r"(high), "r"(low)
345 : "$1", "$2");
341 return (read_c0_register64(9, 7));
346}
347
342}
343
348static inline void
349write_c0_eimr64(__uint64_t value)
344static __inline void
345write_c0_eimr64(uint64_t val)
350{
346{
351 __uint32_t low, high;
352
347
353 high = value >> 32;
354 low = value & 0xffffffff;
355
356 __asm__ __volatile__(
357 ".set push\n"
358 ".set noreorder\n"
359 ".set noat\n"
360 ".set mips4\n\t"
361
362 "dsll32 $2, %1, 0 \n\t"
363 "dsll32 $1, %0, 0 \n\t"
364 "dsrl32 $2, $2, 0 \n\t"
365 "or $1, $1, $2 \n\t"
366 ".word 0x40a14807 \n\t"
367 "nop \n\t"
368
369 ".set pop\n"
370
371 :
372 : "r"(high), "r"(low)
373 : "$1", "$2");
348 write_c0_register64(9, 7, val);
374}
375
376static __inline__ int
377xlr_test_and_set(int *lock)
378{
379 int oldval = 0;
380
349}
350
351static __inline__ int
352xlr_test_and_set(int *lock)
353{
354 int oldval = 0;
355
381 __asm__ __volatile__(".set push\n"
382 ".set noreorder\n"
383 "move $9, %2\n"
384 "li $8, 1\n"
356 __asm__ __volatile__(
357 ".set push\n"
358 ".set noreorder\n"
359 "move $9, %2\n"
360 "li $8, 1\n"
385 // "swapw $8, $9\n"
361 // "swapw $8, $9\n"
386 ".word 0x71280014\n"
387 "move %1, $8\n"
388 ".set pop\n"
389 : "+m"(*lock), "=r"(oldval)
390 : "r"((unsigned long)lock)
391 : "$8", "$9"
362 ".word 0x71280014\n"
363 "move %1, $8\n"
364 ".set pop\n"
365 : "+m"(*lock), "=r"(oldval)
366 : "r"((unsigned long)lock)
367 : "$8", "$9"
392 );
393
394 return (oldval == 0 ? 1 /* success */ : 0 /* failure */ );
395}
396
397static __inline__ uint32_t
398xlr_mfcr(uint32_t reg)
399{
400 uint32_t val;
401
402 __asm__ __volatile__(
368 );
369
370 return (oldval == 0 ? 1 /* success */ : 0 /* failure */ );
371}
372
373static __inline__ uint32_t
374xlr_mfcr(uint32_t reg)
375{
376 uint32_t val;
377
378 __asm__ __volatile__(
403 "move $8, %1\n"
404 ".word 0x71090018\n"
405 "move %0, $9\n"
406 : "=r"(val)
407 : "r"(reg):"$8", "$9");
379 "move $8, %1\n"
380 ".word 0x71090018\n"
381 "move %0, $9\n"
382 : "=r"(val)
383 : "r"(reg):"$8", "$9");
408
409 return val;
410}
411
412static __inline__ void
413xlr_mtcr(uint32_t reg, uint32_t val)
414{
415 __asm__ __volatile__(
384
385 return val;
386}
387
388static __inline__ void
389xlr_mtcr(uint32_t reg, uint32_t val)
390{
391 __asm__ __volatile__(
416 "move $8, %1\n"
417 "move $9, %0\n"
418 ".word 0x71090019\n"
419 :: "r"(val), "r"(reg)
420 : "$8", "$9");
392 "move $8, %1\n"
393 "move $9, %0\n"
394 ".word 0x71090019\n"
395 :: "r"(val), "r"(reg)
396 : "$8", "$9");
421}
422
397}
398
399#if defined(__mips_n64)
423static __inline__ uint32_t
424xlr_paddr_lw(uint64_t paddr)
425{
400static __inline__ uint32_t
401xlr_paddr_lw(uint64_t paddr)
402{
426 uint32_t high, low, tmp;
403
404 paddr |= 0x9800000000000000ULL;
405 return (*(uint32_t *)(uintptr_t)paddr);
406}
427
407
428 high = 0x98000000 | (paddr >> 32);
429 low = paddr & 0xffffffff;
408#elif defined(__mips_n32)
409static __inline__ uint32_t
410xlr_paddr_lw(uint64_t paddr)
411{
412 uint32_t val;
430
413
431 __asm__ __volatile__(
432 ".set push \n\t"
433 ".set mips64 \n\t"
434 "dsll32 %1, %1, 0 \n\t"
435 "dsll32 %2, %2, 0 \n\t" /* get rid of the */
436 "dsrl32 %2, %2, 0 \n\t" /* sign extend */
437 "or %1, %1, %2 \n\t"
438 "lw %0, 0(%1) \n\t"
439 ".set pop \n"
440 : "=r"(tmp)
441 : "r"(high), "r"(low));
414 paddr |= 0x9800000000000000ULL;
415 __asm__ __volatile__(
416 ".set push \n\t"
417 ".set mips64 \n\t"
418 "lw %0, 0(%1) \n\t"
419 ".set pop \n"
420 : "=r"(val)
421 : "r"(paddr));
442
422
423 return (val);
424}
425#else
426static __inline__ uint32_t
427xlr_paddr_lw(uint64_t paddr)
428{
429 uint32_t high, low, tmp;
430
431 high = 0x98000000 | (paddr >> 32);
432 low = paddr & 0xffffffff;
433
434 __asm__ __volatile__(
435 ".set push \n\t"
436 ".set mips64 \n\t"
437 "dsll32 %1, %1, 0 \n\t"
438 "dsll32 %2, %2, 0 \n\t" /* get rid of the */
439 "dsrl32 %2, %2, 0 \n\t" /* sign extend */
440 "or %1, %1, %2 \n\t"
441 "lw %0, 0(%1) \n\t"
442 ".set pop \n"
443 : "=r"(tmp)
444 : "r"(high), "r"(low));
445
443 return tmp;
444}
446 return tmp;
447}
448#endif
445
446/* for cpuid to hardware thread id mapping */
447extern uint32_t xlr_hw_thread_mask;
448extern int xlr_cpuid_to_hwtid[];
449extern int xlr_hwtid_to_cpuid[];
450
451#endif
449
450/* for cpuid to hardware thread id mapping */
451extern uint32_t xlr_hw_thread_mask;
452extern int xlr_cpuid_to_hwtid[];
453extern int xlr_hwtid_to_cpuid[];
454
455#endif