1198629Srrs/*- 2198629Srrs * Copyright (c) 2003-2009 RMI Corporation 3198629Srrs * All rights reserved. 4198629Srrs * 5198629Srrs * Redistribution and use in source and binary forms, with or without 6198629Srrs * modification, are permitted provided that the following conditions 7198629Srrs * are met: 8198629Srrs * 1. Redistributions of source code must retain the above copyright 9198629Srrs * notice, this list of conditions and the following disclaimer. 10198629Srrs * 2. Redistributions in binary form must reproduce the above copyright 11198629Srrs * notice, this list of conditions and the following disclaimer in the 12198629Srrs * documentation and/or other materials provided with the distribution. 13198629Srrs * 3. Neither the name of RMI Corporation, nor the names of its contributors, 14198629Srrs * may be used to endorse or promote products derived from this software 15198629Srrs * without specific prior written permission. 16198629Srrs * 17198629Srrs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18198629Srrs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19198629Srrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20198629Srrs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21198629Srrs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22198629Srrs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23198629Srrs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24198629Srrs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25198629Srrs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26198629Srrs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27198629Srrs * SUCH DAMAGE. 28198629Srrs * 29211994Sjchandra * RMI_BSD 30211994Sjchandra * $FreeBSD$ 31211994Sjchandra */ 32198629Srrs#ifndef __MIPS_EXTS_H__ 33212366Sjchandra#define __MIPS_EXTS_H__ 34198629Srrs 35212366Sjchandra#define CPU_BLOCKID_IFU 0 36212366Sjchandra#define CPU_BLOCKID_ICU 1 37212366Sjchandra#define CPU_BLOCKID_IEU 2 38212366Sjchandra#define CPU_BLOCKID_LSU 3 39212366Sjchandra#define CPU_BLOCKID_MMU 4 40212366Sjchandra#define CPU_BLOCKID_PRF 5 41198629Srrs 42213441Sjchandra#define LSU_CERRLOG_REGID 9 43198629Srrs 44212366Sjchandra#if defined(__mips_n64) || defined(__mips_n32) 45212366Sjchandrastatic __inline uint64_t 46212366Sjchandraread_xlr_ctrl_register(int block, int reg) 47198629Srrs{ 48212366Sjchandra uint64_t res; 49198629Srrs 50212366Sjchandra __asm__ __volatile__( 51212366Sjchandra ".set push\n\t" 52212366Sjchandra ".set noreorder\n\t" 53212366Sjchandra "move $9, %1\n\t" 54212366Sjchandra ".word 0x71280018\n\t" /* mfcr $8, $9 */ 55212366Sjchandra "move %0, $8\n\t" 56212366Sjchandra ".set pop\n" 57212366Sjchandra : "=r" (res) : "r"((block << 8) | reg) 58212366Sjchandra : "$8", "$9" 59212366Sjchandra ); 60212366Sjchandra return (res); 61198629Srrs} 62198629Srrs 63212366Sjchandrastatic __inline void 64212366Sjchandrawrite_xlr_ctrl_register(int block, int reg, uint64_t value) 65198629Srrs{ 66212366Sjchandra __asm__ __volatile__( 67212366Sjchandra ".set push\n\t" 68212366Sjchandra ".set noreorder\n\t" 69212366Sjchandra "move $8, %0\n" 70212366Sjchandra "move $9, %1\n" 71212366Sjchandra ".word 0x71280019\n" /* mtcr $8, $9 */ 72212366Sjchandra ".set pop\n" 73212366Sjchandra : 74212366Sjchandra : "r" (value), "r" ((block << 8) | reg) 75212366Sjchandra : "$8", "$9" 76212366Sjchandra ); 77198629Srrs} 78198629Srrs 79212366Sjchandra#else /* !(defined(__mips_n64) || defined(__mips_n32)) */ 80212366Sjchandra 81212366Sjchandrastatic __inline uint64_t 82212366Sjchandraread_xlr_ctrl_register(int block, int reg) 83198629Srrs{ 84212366Sjchandra uint32_t high, low; 85212366Sjchandra 86212366Sjchandra __asm__ __volatile__( 87212366Sjchandra ".set push\n\t" 88212366Sjchandra ".set noreorder\n\t" 89212366Sjchandra ".set mips64\n\t" 90212366Sjchandra "move $9, %2\n" 91212366Sjchandra ".word 0x71280018\n" /* "mfcr $8, $9\n" */ 92212366Sjchandra "dsra32 %0, $8, 0\n\t" 93212366Sjchandra "sll %1, $8, 0\n\t" 94212366Sjchandra ".set pop" 95212366Sjchandra : "=r" (high), "=r"(low) 96212366Sjchandra : "r" ((block << 8) | reg) 97212366Sjchandra : "$8", "$9"); 98212366Sjchandra 99212366Sjchandra return ( (((uint64_t)high) << 32) | low); 100198629Srrs} 101198629Srrs 102212366Sjchandrastatic __inline void 103212366Sjchandrawrite_xlr_ctrl_register(int block, int reg, uint64_t value) 104198629Srrs{ 105212366Sjchandra uint32_t low, high; 106198629Srrs high = value >> 32; 107198629Srrs low = value & 0xffffffff; 108198629Srrs 109198629Srrs __asm__ __volatile__( 110212366Sjchandra ".set push\n\t" 111212366Sjchandra ".set noreorder\n\t" 112212366Sjchandra ".set mips64\n\t" 113212366Sjchandra "dsll32 $9, %0, 0\n\t" 114212366Sjchandra "dsll32 $8, %1, 0\n\t" 115212366Sjchandra "dsrl32 $8, $8, 0\n\t" 116212366Sjchandra "or $8, $9, $8\n\t" 117212366Sjchandra "move $9, %2\n\t" 118212366Sjchandra ".word 0x71280019\n\t" /* mtcr $8, $9 */ 119212366Sjchandra ".set pop\n" 120212366Sjchandra : /* No outputs */ 121212366Sjchandra : "r" (high), "r" (low), "r"((block << 8) | reg) 122212366Sjchandra : "$8", "$9"); 123212366Sjchandra} 124212366Sjchandra#endif /* defined(__mips_n64) || defined(__mips_n32) */ 125198629Srrs 126212366Sjchandra/* 127212366Sjchandra * 32 bit read write for c0 128212366Sjchandra */ 129212366Sjchandra#define read_c0_register32(reg, sel) \ 130212366Sjchandra({ \ 131212366Sjchandra uint32_t __rv; \ 132212366Sjchandra __asm__ __volatile__( \ 133212366Sjchandra ".set push\n\t" \ 134212366Sjchandra ".set mips32\n\t" \ 135212366Sjchandra "mfc0 %0, $%1, %2\n\t" \ 136212366Sjchandra ".set pop\n" \ 137212366Sjchandra : "=r" (__rv) : "i" (reg), "i" (sel) ); \ 138212366Sjchandra __rv; \ 139212366Sjchandra }) 140198629Srrs 141212366Sjchandra#define write_c0_register32(reg, sel, value) \ 142212366Sjchandra __asm__ __volatile__( \ 143212366Sjchandra ".set push\n\t" \ 144212366Sjchandra ".set mips32\n\t" \ 145212366Sjchandra "mtc0 %0, $%1, %2\n\t" \ 146212366Sjchandra ".set pop\n" \ 147212366Sjchandra : : "r" (value), "i" (reg), "i" (sel) ); 148198629Srrs 149212366Sjchandra#define read_c2_register32(reg, sel) \ 150212366Sjchandra({ \ 151212366Sjchandra uint32_t __rv; \ 152212366Sjchandra __asm__ __volatile__( \ 153212366Sjchandra ".set push\n\t" \ 154212366Sjchandra ".set mips32\n\t" \ 155212366Sjchandra "mfc2 %0, $%1, %2\n\t" \ 156212366Sjchandra ".set pop\n" \ 157212366Sjchandra : "=r" (__rv) : "i" (reg), "i" (sel) ); \ 158212366Sjchandra __rv; \ 159212366Sjchandra }) 160198629Srrs 161212366Sjchandra#define write_c2_register32(reg, sel, value) \ 162212366Sjchandra __asm__ __volatile__( \ 163212366Sjchandra ".set push\n\t" \ 164212366Sjchandra ".set mips32\n\t" \ 165212366Sjchandra "mtc2 %0, $%1, %2\n\t" \ 166212366Sjchandra ".set pop\n" \ 167212366Sjchandra : : "r" (value), "i" (reg), "i" (sel) ); 168198629Srrs 169212366Sjchandra#if defined(__mips_n64) || defined(__mips_n32) 170212366Sjchandra/* 171212366Sjchandra * On 64 bit compilation, the operations are simple 172212366Sjchandra */ 173212366Sjchandra#define read_c0_register64(reg, sel) \ 174212366Sjchandra({ \ 175212366Sjchandra uint64_t __rv; \ 176212366Sjchandra __asm__ __volatile__( \ 177212366Sjchandra ".set push\n\t" \ 178212366Sjchandra ".set mips64\n\t" \ 179212366Sjchandra "dmfc0 %0, $%1, %2\n\t" \ 180212366Sjchandra ".set pop\n" \ 181212366Sjchandra : "=r" (__rv) : "i" (reg), "i" (sel) ); \ 182212366Sjchandra __rv; \ 183212366Sjchandra }) 184198629Srrs 185212366Sjchandra#define write_c0_register64(reg, sel, value) \ 186212366Sjchandra __asm__ __volatile__( \ 187212366Sjchandra ".set push\n\t" \ 188212366Sjchandra ".set mips64\n\t" \ 189212366Sjchandra "dmtc0 %0, $%1, %2\n\t" \ 190212366Sjchandra ".set pop\n" \ 191212366Sjchandra : : "r" (value), "i" (reg), "i" (sel) ); 192211994Sjchandra 193212366Sjchandra#define read_c2_register64(reg, sel) \ 194212366Sjchandra({ \ 195212366Sjchandra uint64_t __rv; \ 196212366Sjchandra __asm__ __volatile__( \ 197212366Sjchandra ".set push\n\t" \ 198212366Sjchandra ".set mips64\n\t" \ 199212366Sjchandra "dmfc2 %0, $%1, %2\n\t" \ 200212366Sjchandra ".set pop\n" \ 201212366Sjchandra : "=r" (__rv) : "i" (reg), "i" (sel) ); \ 202212366Sjchandra __rv; \ 203212366Sjchandra }) 204211994Sjchandra 205212366Sjchandra#define write_c2_register64(reg, sel, value) \ 206212366Sjchandra __asm__ __volatile__( \ 207212366Sjchandra ".set push\n\t" \ 208212366Sjchandra ".set mips64\n\t" \ 209212366Sjchandra "dmtc2 %0, $%1, %2\n\t" \ 210212366Sjchandra ".set pop\n" \ 211212366Sjchandra : : "r" (value), "i" (reg), "i" (sel) ); 212211994Sjchandra 213212366Sjchandra#else /* ! (defined(__mips_n64) || defined(__mips_n32)) */ 214211994Sjchandra 215212366Sjchandra/* 216212366Sjchandra * 32 bit compilation, 64 bit values has to split 217212366Sjchandra */ 218212366Sjchandra#define read_c0_register64(reg, sel) \ 219212366Sjchandra({ \ 220212366Sjchandra uint32_t __high, __low; \ 221212366Sjchandra __asm__ __volatile__( \ 222212366Sjchandra ".set push\n\t" \ 223212366Sjchandra ".set noreorder\n\t" \ 224212366Sjchandra ".set mips64\n\t" \ 225212366Sjchandra "dmfc0 $8, $%2, %3\n\t" \ 226212366Sjchandra "dsra32 %0, $8, 0\n\t" \ 227212366Sjchandra "sll %1, $8, 0\n\t" \ 228212366Sjchandra ".set pop\n" \ 229212366Sjchandra : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel) \ 230212366Sjchandra : "$8"); \ 231212366Sjchandra ((uint64_t)__high << 32) | __low; \ 232212366Sjchandra}) 233211994Sjchandra 234212366Sjchandra#define write_c0_register64(reg, sel, value) \ 235212366Sjchandrado { \ 236212366Sjchandra uint32_t __high = value >> 32; \ 237212366Sjchandra uint32_t __low = value & 0xffffffff; \ 238212366Sjchandra __asm__ __volatile__( \ 239212366Sjchandra ".set push\n\t" \ 240212366Sjchandra ".set noreorder\n\t" \ 241212366Sjchandra ".set mips64\n\t" \ 242212366Sjchandra "dsll32 $8, %1, 0\n\t" \ 243212366Sjchandra "dsll32 $9, %0, 0\n\t" \ 244212366Sjchandra "dsrl32 $8, $8, 0\n\t" \ 245212366Sjchandra "or $8, $8, $9\n\t" \ 246212366Sjchandra "dmtc0 $8, $%2, %3\n\t" \ 247212366Sjchandra ".set pop" \ 248212366Sjchandra :: "r"(__high), "r"(__low), "i"(reg), "i"(sel) \ 249212366Sjchandra :"$8", "$9"); \ 250212366Sjchandra} while(0) 251211994Sjchandra 252212366Sjchandra#define read_c2_register64(reg, sel) \ 253212366Sjchandra({ \ 254212366Sjchandra uint32_t __high, __low; \ 255212366Sjchandra __asm__ __volatile__( \ 256212366Sjchandra ".set push\n\t" \ 257212366Sjchandra ".set noreorder\n\t" \ 258212366Sjchandra ".set mips64\n\t" \ 259212366Sjchandra "dmfc2 $8, $%2, %3\n\t" \ 260212366Sjchandra "dsra32 %0, $8, 0\n\t" \ 261212366Sjchandra "sll %1, $8, 0\n\t" \ 262212366Sjchandra ".set pop\n" \ 263212366Sjchandra : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel) \ 264212366Sjchandra : "$8"); \ 265212366Sjchandra ((uint64_t)__high << 32) | __low; \ 266212366Sjchandra}) 267211994Sjchandra 268212366Sjchandra#define write_c2_register64(reg, sel, value) \ 269212366Sjchandrado { \ 270212366Sjchandra uint32_t __high = value >> 32; \ 271212366Sjchandra uint32_t __low = value & 0xffffffff; \ 272212366Sjchandra __asm__ __volatile__( \ 273212366Sjchandra ".set push\n\t" \ 274212366Sjchandra ".set noreorder\n\t" \ 275212366Sjchandra ".set mips64\n\t" \ 276212366Sjchandra "dsll32 $8, %1, 0\n\t" \ 277212366Sjchandra "dsll32 $9, %0, 0\n\t" \ 278212366Sjchandra "dsrl32 $8, $8, 0\n\t" \ 279212366Sjchandra "or $8, $8, $9\n\t" \ 280212366Sjchandra "dmtc2 $8, $%2, %3\n\t" \ 281212366Sjchandra ".set pop" \ 282212366Sjchandra :: "r"(__high), "r"(__low), "i"(reg), "i"(sel) \ 283212366Sjchandra :"$8", "$9"); \ 284212366Sjchandra} while(0) 285211994Sjchandra 286212366Sjchandra#endif /* defined(__mips_n64) || defined(__mips_n32) */ 287211994Sjchandra 288212366Sjchandrastatic __inline int 289212366Sjchandraxlr_cpu_id(void) 290212366Sjchandra{ 291211994Sjchandra 292212366Sjchandra return (read_c0_register32(15, 1) & 0x1f); 293212366Sjchandra} 294211994Sjchandra 295212366Sjchandrastatic __inline int 296212366Sjchandraxlr_core_id(void) 297212366Sjchandra{ 298211994Sjchandra 299212366Sjchandra return (xlr_cpu_id() / 4); 300212366Sjchandra} 301211994Sjchandra 302212366Sjchandrastatic __inline int 303212366Sjchandraxlr_thr_id(void) 304212366Sjchandra{ 305211994Sjchandra 306212366Sjchandra return (read_c0_register32(15, 1) & 0x3); 307212366Sjchandra} 308212366Sjchandra 309212366Sjchandra/* Additional registers on the XLR */ 310212366Sjchandra#define MIPS_COP_0_OSSCRATCH 22 311212366Sjchandra#define XLR_CACHELINE_SIZE 32 312212366Sjchandra 313211994Sjchandra/* functions to write to and read from the extended 314211994Sjchandra * cp0 registers. 315211994Sjchandra * EIRR : Extended Interrupt Request Register 316211994Sjchandra * cp0 register 9 sel 6 317211994Sjchandra * bits 0...7 are same as cause register 8...15 318211994Sjchandra * EIMR : Extended Interrupt Mask Register 319211994Sjchandra * cp0 register 9 sel 7 320211994Sjchandra * bits 0...7 are same as status register 8...15 321211994Sjchandra */ 322212366Sjchandrastatic __inline uint64_t 323211994Sjchandraread_c0_eirr64(void) 324211994Sjchandra{ 325211994Sjchandra 326212366Sjchandra return (read_c0_register64(9, 6)); 327211994Sjchandra} 328211994Sjchandra 329212366Sjchandrastatic __inline void 330212366Sjchandrawrite_c0_eirr64(uint64_t val) 331211994Sjchandra{ 332211994Sjchandra 333212366Sjchandra write_c0_register64(9, 6, val); 334211994Sjchandra} 335211994Sjchandra 336212366Sjchandrastatic __inline uint64_t 337212366Sjchandraread_c0_eimr64(void) 338211994Sjchandra{ 339211994Sjchandra 340212366Sjchandra return (read_c0_register64(9, 7)); 341211994Sjchandra} 342211994Sjchandra 343212366Sjchandrastatic __inline void 344212366Sjchandrawrite_c0_eimr64(uint64_t val) 345211994Sjchandra{ 346211994Sjchandra 347212366Sjchandra write_c0_register64(9, 7, val); 348211994Sjchandra} 349211994Sjchandra 350212758Sjchandrastatic __inline int 351211994Sjchandraxlr_test_and_set(int *lock) 352211994Sjchandra{ 353211994Sjchandra int oldval = 0; 354211994Sjchandra 355212366Sjchandra __asm__ __volatile__( 356212366Sjchandra ".set push\n" 357212366Sjchandra ".set noreorder\n" 358212366Sjchandra "move $9, %2\n" 359212366Sjchandra "li $8, 1\n" 360211994Sjchandra // "swapw $8, $9\n" 361212366Sjchandra ".word 0x71280014\n" 362212366Sjchandra "move %1, $8\n" 363212366Sjchandra ".set pop\n" 364212366Sjchandra : "+m"(*lock), "=r"(oldval) 365212366Sjchandra : "r"((unsigned long)lock) 366212366Sjchandra : "$8", "$9" 367211994Sjchandra ); 368211994Sjchandra 369212758Sjchandra return (oldval == 0 ? 1 /* success */ : 0 /* failure */); 370211994Sjchandra} 371211994Sjchandra 372212758Sjchandrastatic __inline uint32_t 373211994Sjchandraxlr_mfcr(uint32_t reg) 374211994Sjchandra{ 375211994Sjchandra uint32_t val; 376211994Sjchandra 377211994Sjchandra __asm__ __volatile__( 378212366Sjchandra "move $8, %1\n" 379212366Sjchandra ".word 0x71090018\n" 380212366Sjchandra "move %0, $9\n" 381212366Sjchandra : "=r"(val) 382212366Sjchandra : "r"(reg):"$8", "$9"); 383211994Sjchandra 384211994Sjchandra return val; 385211994Sjchandra} 386211994Sjchandra 387212758Sjchandrastatic __inline void 388211994Sjchandraxlr_mtcr(uint32_t reg, uint32_t val) 389211994Sjchandra{ 390211994Sjchandra __asm__ __volatile__( 391212366Sjchandra "move $8, %1\n" 392212366Sjchandra "move $9, %0\n" 393212366Sjchandra ".word 0x71090019\n" 394212366Sjchandra :: "r"(val), "r"(reg) 395212366Sjchandra : "$8", "$9"); 396211994Sjchandra} 397211994Sjchandra 398212758Sjchandra/* 399212758Sjchandra * Atomic increment a unsigned int 400212758Sjchandra */ 401212758Sjchandrastatic __inline unsigned int 402212758Sjchandraxlr_ldaddwu(unsigned int value, unsigned int *addr) 403212758Sjchandra{ 404212758Sjchandra __asm__ __volatile__( 405212758Sjchandra ".set push\n" 406212758Sjchandra ".set noreorder\n" 407212758Sjchandra "move $8, %2\n" 408212758Sjchandra "move $9, %3\n" 409212758Sjchandra ".word 0x71280011\n" /* ldaddwu $8, $9 */ 410212758Sjchandra "move %0, $8\n" 411212758Sjchandra ".set pop\n" 412212758Sjchandra : "=&r"(value), "+m"(*addr) 413212758Sjchandra : "0"(value), "r" ((unsigned long)addr) 414212758Sjchandra : "$8", "$9"); 415212758Sjchandra 416212758Sjchandra return (value); 417212758Sjchandra} 418212758Sjchandra 419212366Sjchandra#if defined(__mips_n64) 420212896Sjchandrastatic __inline uint32_t 421212896Sjchandraxlr_paddr_lw(uint64_t paddr) 422212896Sjchandra{ 423212896Sjchandra 424212896Sjchandra paddr |= 0x9800000000000000ULL; 425212896Sjchandra return (*(uint32_t *)(uintptr_t)paddr); 426212896Sjchandra} 427212896Sjchandra 428212758Sjchandrastatic __inline uint64_t 429212758Sjchandraxlr_paddr_ld(uint64_t paddr) 430211994Sjchandra{ 431212366Sjchandra 432212366Sjchandra paddr |= 0x9800000000000000ULL; 433212758Sjchandra return (*(uint64_t *)(uintptr_t)paddr); 434212366Sjchandra} 435211994Sjchandra 436212366Sjchandra#elif defined(__mips_n32) 437212896Sjchandrastatic __inline uint32_t 438212957Sjchandraxlr_paddr_lw(uint64_t paddr) 439212896Sjchandra{ 440212896Sjchandra uint32_t val; 441212896Sjchandra 442212896Sjchandra paddr |= 0x9800000000000000ULL; 443212896Sjchandra __asm__ __volatile__( 444212896Sjchandra ".set push \n\t" 445212896Sjchandra ".set mips64 \n\t" 446212896Sjchandra "lw %0, 0(%1) \n\t" 447212896Sjchandra ".set pop \n" 448212896Sjchandra : "=r"(val) 449212896Sjchandra : "r"(paddr)); 450212896Sjchandra 451212896Sjchandra return (val); 452212896Sjchandra} 453212896Sjchandra 454212758Sjchandrastatic __inline uint64_t 455212758Sjchandraxlr_paddr_ld(uint64_t paddr) 456212366Sjchandra{ 457212758Sjchandra uint64_t val; 458211994Sjchandra 459212366Sjchandra paddr |= 0x9800000000000000ULL; 460212366Sjchandra __asm__ __volatile__( 461212366Sjchandra ".set push \n\t" 462212366Sjchandra ".set mips64 \n\t" 463212758Sjchandra "ld %0, 0(%1) \n\t" 464212366Sjchandra ".set pop \n" 465212366Sjchandra : "=r"(val) 466212366Sjchandra : "r"(paddr)); 467211994Sjchandra 468212366Sjchandra return (val); 469212366Sjchandra} 470212896Sjchandra 471212896Sjchandra#else /* o32 compilation */ 472212758Sjchandrastatic __inline uint32_t 473212896Sjchandraxlr_paddr_lw(uint64_t paddr) 474212896Sjchandra{ 475212896Sjchandra uint32_t addrh, addrl; 476212896Sjchandra uint32_t val; 477212896Sjchandra 478212896Sjchandra addrh = 0x98000000 | (paddr >> 32); 479212896Sjchandra addrl = paddr & 0xffffffff; 480212896Sjchandra 481212896Sjchandra __asm__ __volatile__( 482212896Sjchandra ".set push \n\t" 483212896Sjchandra ".set mips64 \n\t" 484213441Sjchandra "dsll32 $8, %1, 0 \n\t" 485213441Sjchandra "dsll32 $9, %2, 0 \n\t" /* get rid of the */ 486213441Sjchandra "dsrl32 $9, $9, 0 \n\t" /* sign extend */ 487213441Sjchandra "or $9, $8, $8 \n\t" 488213441Sjchandra "lw %0, 0($9) \n\t" 489212896Sjchandra ".set pop \n" 490213441Sjchandra : "=r"(val) 491213441Sjchandra : "r"(addrh), "r"(addrl) 492213441Sjchandra : "$8", "$9"); 493212896Sjchandra 494212896Sjchandra return (val); 495212896Sjchandra} 496212896Sjchandra 497212896Sjchandrastatic __inline uint64_t 498212758Sjchandraxlr_paddr_ld(uint64_t paddr) 499212366Sjchandra{ 500212758Sjchandra uint32_t addrh, addrl; 501212758Sjchandra uint32_t valh, vall; 502212366Sjchandra 503212758Sjchandra addrh = 0x98000000 | (paddr >> 32); 504212758Sjchandra addrl = paddr & 0xffffffff; 505212366Sjchandra 506212366Sjchandra __asm__ __volatile__( 507212896Sjchandra ".set push \n\t" 508212896Sjchandra ".set mips64 \n\t" 509213441Sjchandra "dsll32 %0, %2, 0 \n\t" 510213441Sjchandra "dsll32 %1, %3, 0 \n\t" /* get rid of the */ 511213441Sjchandra "dsrl32 %1, %1, 0 \n\t" /* sign extend */ 512213441Sjchandra "or %0, %0, %1 \n\t" 513212896Sjchandra "lw %1, 4(%0) \n\t" 514212896Sjchandra "lw %0, 0(%0) \n\t" 515212896Sjchandra ".set pop \n" 516213441Sjchandra : "=&r"(valh), "=&r"(vall) 517212758Sjchandra : "r"(addrh), "r"(addrl)); 518212366Sjchandra 519212758Sjchandra return (((uint64_t)valh << 32) | vall); 520211994Sjchandra} 521212366Sjchandra#endif 522211994Sjchandra 523212758Sjchandra/* 524212758Sjchandra * XXX: Not really needed in n32 or n64, retain for now 525212758Sjchandra */ 526212758Sjchandra#if defined(__mips_n64) || defined(__mips_n32) 527212758Sjchandrastatic __inline uint32_t 528212758Sjchandraxlr_enable_kx(void) 529212758Sjchandra{ 530212758Sjchandra 531212758Sjchandra return (0); 532212758Sjchandra} 533212758Sjchandra 534212758Sjchandrastatic __inline void 535212758Sjchandraxlr_restore_kx(uint32_t sr) 536212758Sjchandra{ 537212758Sjchandra} 538212896Sjchandra 539212896Sjchandra#else /* !defined(__mips_n64) && !defined(__mips_n32) */ 540212896Sjchandra/* 541212896Sjchandra * o32 compilation, we will disable interrupts and enable 542212896Sjchandra * the KX bit so that we can use XKPHYS to access any 40bit 543212896Sjchandra * physical address 544212896Sjchandra */ 545212758Sjchandrastatic __inline uint32_t 546212758Sjchandraxlr_enable_kx(void) 547212758Sjchandra{ 548212758Sjchandra uint32_t sr = mips_rd_status(); 549212758Sjchandra 550212758Sjchandra mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_KX); 551212758Sjchandra return (sr); 552212758Sjchandra} 553212758Sjchandra 554212758Sjchandrastatic __inline void 555212758Sjchandraxlr_restore_kx(uint32_t sr) 556212758Sjchandra{ 557212758Sjchandra 558212758Sjchandra mips_wr_status(sr); 559212758Sjchandra} 560212896Sjchandra#endif /* defined(__mips_n64) || defined(__mips_n32) */ 561212758Sjchandra 562213377Sjchandra/* 563213377Sjchandra * XLR/XLS processors have maximum 8 cores, and maximum 4 threads 564213377Sjchandra * per core 565213377Sjchandra */ 566213377Sjchandra#define XLR_MAX_CORES 8 567213377Sjchandra#define XLR_NTHREADS 4 568213377Sjchandra 569213377Sjchandra/* 570213377Sjchandra * FreeBSD can be started with few threads and cores turned off, 571213377Sjchandra * so have a hardware thread id to FreeBSD cpuid mapping. 572213377Sjchandra */ 573213377Sjchandraextern int xlr_ncores; 574213377Sjchandraextern int xlr_threads_per_core; 575211994Sjchandraextern uint32_t xlr_hw_thread_mask; 576211994Sjchandraextern int xlr_cpuid_to_hwtid[]; 577211994Sjchandraextern int xlr_hwtid_to_cpuid[]; 578211994Sjchandra 579198629Srrs#endif 580