rmi_mips_exts.h revision 212957
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: head/sys/mips/rmi/rmi_mips_exts.h 212957 2010-09-21 07:58:47Z jchandra $ 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 42212366Sjchandra#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#define XLR_MAX_CORES 8 313212366Sjchandra 314211994Sjchandra/* functions to write to and read from the extended 315211994Sjchandra * cp0 registers. 316211994Sjchandra * EIRR : Extended Interrupt Request Register 317211994Sjchandra * cp0 register 9 sel 6 318211994Sjchandra * bits 0...7 are same as cause register 8...15 319211994Sjchandra * EIMR : Extended Interrupt Mask Register 320211994Sjchandra * cp0 register 9 sel 7 321211994Sjchandra * bits 0...7 are same as status register 8...15 322211994Sjchandra */ 323212366Sjchandrastatic __inline uint64_t 324211994Sjchandraread_c0_eirr64(void) 325211994Sjchandra{ 326211994Sjchandra 327212366Sjchandra return (read_c0_register64(9, 6)); 328211994Sjchandra} 329211994Sjchandra 330212366Sjchandrastatic __inline void 331212366Sjchandrawrite_c0_eirr64(uint64_t val) 332211994Sjchandra{ 333211994Sjchandra 334212366Sjchandra write_c0_register64(9, 6, val); 335211994Sjchandra} 336211994Sjchandra 337212366Sjchandrastatic __inline uint64_t 338212366Sjchandraread_c0_eimr64(void) 339211994Sjchandra{ 340211994Sjchandra 341212366Sjchandra return (read_c0_register64(9, 7)); 342211994Sjchandra} 343211994Sjchandra 344212366Sjchandrastatic __inline void 345212366Sjchandrawrite_c0_eimr64(uint64_t val) 346211994Sjchandra{ 347211994Sjchandra 348212366Sjchandra write_c0_register64(9, 7, val); 349211994Sjchandra} 350211994Sjchandra 351212758Sjchandrastatic __inline int 352211994Sjchandraxlr_test_and_set(int *lock) 353211994Sjchandra{ 354211994Sjchandra int oldval = 0; 355211994Sjchandra 356212366Sjchandra __asm__ __volatile__( 357212366Sjchandra ".set push\n" 358212366Sjchandra ".set noreorder\n" 359212366Sjchandra "move $9, %2\n" 360212366Sjchandra "li $8, 1\n" 361211994Sjchandra // "swapw $8, $9\n" 362212366Sjchandra ".word 0x71280014\n" 363212366Sjchandra "move %1, $8\n" 364212366Sjchandra ".set pop\n" 365212366Sjchandra : "+m"(*lock), "=r"(oldval) 366212366Sjchandra : "r"((unsigned long)lock) 367212366Sjchandra : "$8", "$9" 368211994Sjchandra ); 369211994Sjchandra 370212758Sjchandra return (oldval == 0 ? 1 /* success */ : 0 /* failure */); 371211994Sjchandra} 372211994Sjchandra 373212758Sjchandrastatic __inline uint32_t 374211994Sjchandraxlr_mfcr(uint32_t reg) 375211994Sjchandra{ 376211994Sjchandra uint32_t val; 377211994Sjchandra 378211994Sjchandra __asm__ __volatile__( 379212366Sjchandra "move $8, %1\n" 380212366Sjchandra ".word 0x71090018\n" 381212366Sjchandra "move %0, $9\n" 382212366Sjchandra : "=r"(val) 383212366Sjchandra : "r"(reg):"$8", "$9"); 384211994Sjchandra 385211994Sjchandra return val; 386211994Sjchandra} 387211994Sjchandra 388212758Sjchandrastatic __inline void 389211994Sjchandraxlr_mtcr(uint32_t reg, uint32_t val) 390211994Sjchandra{ 391211994Sjchandra __asm__ __volatile__( 392212366Sjchandra "move $8, %1\n" 393212366Sjchandra "move $9, %0\n" 394212366Sjchandra ".word 0x71090019\n" 395212366Sjchandra :: "r"(val), "r"(reg) 396212366Sjchandra : "$8", "$9"); 397211994Sjchandra} 398211994Sjchandra 399212758Sjchandra/* 400212758Sjchandra * Atomic increment a unsigned int 401212758Sjchandra */ 402212758Sjchandrastatic __inline unsigned int 403212758Sjchandraxlr_ldaddwu(unsigned int value, unsigned int *addr) 404212758Sjchandra{ 405212758Sjchandra __asm__ __volatile__( 406212758Sjchandra ".set push\n" 407212758Sjchandra ".set noreorder\n" 408212758Sjchandra "move $8, %2\n" 409212758Sjchandra "move $9, %3\n" 410212758Sjchandra ".word 0x71280011\n" /* ldaddwu $8, $9 */ 411212758Sjchandra "move %0, $8\n" 412212758Sjchandra ".set pop\n" 413212758Sjchandra : "=&r"(value), "+m"(*addr) 414212758Sjchandra : "0"(value), "r" ((unsigned long)addr) 415212758Sjchandra : "$8", "$9"); 416212758Sjchandra 417212758Sjchandra return (value); 418212758Sjchandra} 419212758Sjchandra 420212366Sjchandra#if defined(__mips_n64) 421212896Sjchandrastatic __inline uint32_t 422212896Sjchandraxlr_paddr_lw(uint64_t paddr) 423212896Sjchandra{ 424212896Sjchandra 425212896Sjchandra paddr |= 0x9800000000000000ULL; 426212896Sjchandra return (*(uint32_t *)(uintptr_t)paddr); 427212896Sjchandra} 428212896Sjchandra 429212758Sjchandrastatic __inline uint64_t 430212758Sjchandraxlr_paddr_ld(uint64_t paddr) 431211994Sjchandra{ 432212366Sjchandra 433212366Sjchandra paddr |= 0x9800000000000000ULL; 434212758Sjchandra return (*(uint64_t *)(uintptr_t)paddr); 435212366Sjchandra} 436211994Sjchandra 437212366Sjchandra#elif defined(__mips_n32) 438212896Sjchandrastatic __inline uint32_t 439212957Sjchandraxlr_paddr_lw(uint64_t paddr) 440212896Sjchandra{ 441212896Sjchandra uint32_t val; 442212896Sjchandra 443212896Sjchandra paddr |= 0x9800000000000000ULL; 444212896Sjchandra __asm__ __volatile__( 445212896Sjchandra ".set push \n\t" 446212896Sjchandra ".set mips64 \n\t" 447212896Sjchandra "lw %0, 0(%1) \n\t" 448212896Sjchandra ".set pop \n" 449212896Sjchandra : "=r"(val) 450212896Sjchandra : "r"(paddr)); 451212896Sjchandra 452212896Sjchandra return (val); 453212896Sjchandra} 454212896Sjchandra 455212758Sjchandrastatic __inline uint64_t 456212758Sjchandraxlr_paddr_ld(uint64_t paddr) 457212366Sjchandra{ 458212758Sjchandra uint64_t val; 459211994Sjchandra 460212366Sjchandra paddr |= 0x9800000000000000ULL; 461212366Sjchandra __asm__ __volatile__( 462212366Sjchandra ".set push \n\t" 463212366Sjchandra ".set mips64 \n\t" 464212758Sjchandra "ld %0, 0(%1) \n\t" 465212366Sjchandra ".set pop \n" 466212366Sjchandra : "=r"(val) 467212366Sjchandra : "r"(paddr)); 468211994Sjchandra 469212366Sjchandra return (val); 470212366Sjchandra} 471212896Sjchandra 472212896Sjchandra#else /* o32 compilation */ 473212758Sjchandrastatic __inline uint32_t 474212896Sjchandraxlr_paddr_lw(uint64_t paddr) 475212896Sjchandra{ 476212896Sjchandra uint32_t addrh, addrl; 477212896Sjchandra uint32_t val; 478212896Sjchandra 479212896Sjchandra addrh = 0x98000000 | (paddr >> 32); 480212896Sjchandra addrl = paddr & 0xffffffff; 481212896Sjchandra 482212896Sjchandra __asm__ __volatile__( 483212896Sjchandra ".set push \n\t" 484212896Sjchandra ".set mips64 \n\t" 485212896Sjchandra "dsll32 %1, %1, 0 \n\t" 486212896Sjchandra "dsll32 %2, %2, 0 \n\t" /* get rid of the */ 487212896Sjchandra "dsrl32 %2, %2, 0 \n\t" /* sign extend */ 488212896Sjchandra "or %0, %1, %2 \n\t" 489212896Sjchandra "lw %0, 0(%0) \n\t" 490212896Sjchandra ".set pop \n" 491212896Sjchandra : "=&r"(val) 492212896Sjchandra : "r"(addrh), "r"(addrl)); 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" 509212896Sjchandra "dsll32 %2, %2, 0 \n\t" 510212896Sjchandra "dsll32 %3, %3, 0 \n\t" /* get rid of the */ 511212896Sjchandra "dsrl32 %3, %3, 0 \n\t" /* sign extend */ 512212896Sjchandra "or %0, %2, %3 \n\t" 513212896Sjchandra "lw %1, 4(%0) \n\t" 514212896Sjchandra "lw %0, 0(%0) \n\t" 515212896Sjchandra ".set pop \n" 516212758Sjchandra : "=&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 562211994Sjchandra/* for cpuid to hardware thread id mapping */ 563211994Sjchandraextern uint32_t xlr_hw_thread_mask; 564211994Sjchandraextern int xlr_cpuid_to_hwtid[]; 565211994Sjchandraextern int xlr_hwtid_to_cpuid[]; 566211994Sjchandra 567198629Srrs#endif 568