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 |