1178172Simp/* $OpenBSD: pio.h,v 1.2 1998/09/15 10:50:12 pefo Exp $ */ 2178172Simp 3206713Sjmallett/*- 4206713Sjmallett * Copyright (c) 2002-2004 Juli Mallett. All rights reserved. 5206713Sjmallett * 6206713Sjmallett * Redistribution and use in source and binary forms, with or without 7206713Sjmallett * modification, are permitted provided that the following conditions 8206713Sjmallett * are met: 9206713Sjmallett * 1. Redistributions of source code must retain the above copyright 10206713Sjmallett * notice, this list of conditions and the following disclaimer. 11206713Sjmallett * 2. Redistributions in binary form must reproduce the above copyright 12206713Sjmallett * notice, this list of conditions and the following disclaimer in the 13206713Sjmallett * documentation and/or other materials provided with the distribution. 14206713Sjmallett * 15206713Sjmallett * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16206713Sjmallett * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17206713Sjmallett * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18206713Sjmallett * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19206713Sjmallett * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20206713Sjmallett * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21206713Sjmallett * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22206713Sjmallett * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23206713Sjmallett * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24206713Sjmallett * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25206713Sjmallett * SUCH DAMAGE. 26206713Sjmallett */ 27178172Simp/* 28178172Simp * Copyright (c) 1995-1999 Per Fogelstrom. All rights reserved. 29178172Simp * 30178172Simp * Redistribution and use in source and binary forms, with or without 31178172Simp * modification, are permitted provided that the following conditions 32178172Simp * are met: 33178172Simp * 1. Redistributions of source code must retain the above copyright 34178172Simp * notice, this list of conditions and the following disclaimer. 35178172Simp * 2. Redistributions in binary form must reproduce the above copyright 36178172Simp * notice, this list of conditions and the following disclaimer in the 37178172Simp * documentation and/or other materials provided with the distribution. 38178172Simp * 3. All advertising materials mentioning features or use of this software 39178172Simp * must display the following acknowledgement: 40178172Simp * This product includes software developed by Per Fogelstrom. 41178172Simp * 4. The name of the author may not be used to endorse or promote products 42178172Simp * derived from this software without specific prior written permission 43178172Simp * 44178172Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 45178172Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 46178172Simp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47178172Simp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 48178172Simp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 49178172Simp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 50178172Simp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 51178172Simp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 52178172Simp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 53178172Simp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54178172Simp * 55178172Simp * JNPR: cpufunc.h,v 1.5 2007/08/09 11:23:32 katta 56178172Simp * $FreeBSD$ 57178172Simp */ 58178172Simp 59178172Simp#ifndef _MACHINE_CPUFUNC_H_ 60178172Simp#define _MACHINE_CPUFUNC_H_ 61178172Simp 62178172Simp#include <sys/types.h> 63178172Simp#include <machine/cpuregs.h> 64178172Simp 65178172Simp/* 66178172Simp * These functions are required by user-land atomi ops 67178172Simp */ 68178172Simp 69178172Simpstatic __inline void 70178172Simpmips_barrier(void) 71178172Simp{ 72227658Sjchandra#if defined(CPU_CNMIPS) || defined(CPU_RMI) || defined(CPU_NLM) 73241374Sattilio __compiler_membar(); 74218383Sjmallett#else 75178172Simp __asm __volatile (".set noreorder\n\t" 76178172Simp "nop\n\t" 77178172Simp "nop\n\t" 78178172Simp "nop\n\t" 79178172Simp "nop\n\t" 80178172Simp "nop\n\t" 81178172Simp "nop\n\t" 82178172Simp "nop\n\t" 83178172Simp "nop\n\t" 84178172Simp ".set reorder\n\t" 85178172Simp : : : "memory"); 86218383Sjmallett#endif 87178172Simp} 88178172Simp 89178172Simpstatic __inline void 90206713Sjmallettmips_cp0_sync(void) 91206713Sjmallett{ 92206713Sjmallett __asm __volatile (__XSTRING(COP0_SYNC)); 93206713Sjmallett} 94206713Sjmallett 95206713Sjmallettstatic __inline void 96178172Simpmips_wbflush(void) 97178172Simp{ 98218383Sjmallett#if defined(CPU_CNMIPS) 99218383Sjmallett __asm __volatile (".set noreorder\n\t" 100218383Sjmallett "syncw\n\t" 101218383Sjmallett ".set reorder\n" 102218383Sjmallett : : : "memory"); 103218383Sjmallett#else 104178172Simp __asm __volatile ("sync" : : : "memory"); 105178172Simp mips_barrier(); 106218383Sjmallett#endif 107178172Simp} 108178172Simp 109178172Simp#ifdef _KERNEL 110216947Sjmallett/* 111216947Sjmallett * XXX 112216947Sjmallett * It would be nice to add variants that read/write register_t, to avoid some 113216947Sjmallett * ABI checks. 114216947Sjmallett */ 115206713Sjmallett#if defined(__mips_n32) || defined(__mips_n64) 116216972Sjmallett#define MIPS_RW64_COP0(n,r) \ 117178172Simpstatic __inline uint64_t \ 118178172Simpmips_rd_ ## n (void) \ 119178172Simp{ \ 120178172Simp int v0; \ 121178172Simp __asm __volatile ("dmfc0 %[v0], $"__XSTRING(r)";" \ 122178172Simp : [v0] "=&r"(v0)); \ 123178172Simp mips_barrier(); \ 124178172Simp return (v0); \ 125178172Simp} \ 126178172Simpstatic __inline void \ 127178172Simpmips_wr_ ## n (uint64_t a0) \ 128178172Simp{ \ 129178172Simp __asm __volatile ("dmtc0 %[a0], $"__XSTRING(r)";" \ 130178172Simp __XSTRING(COP0_SYNC)";" \ 131178172Simp "nop;" \ 132178172Simp "nop;" \ 133178172Simp : \ 134178172Simp : [a0] "r"(a0)); \ 135178172Simp mips_barrier(); \ 136178172Simp} struct __hack 137178172Simp 138218383Sjmallett#define MIPS_RW64_COP0_SEL(n,r,s) \ 139218383Sjmallettstatic __inline uint64_t \ 140218383Sjmallettmips_rd_ ## n(void) \ 141218383Sjmallett{ \ 142218383Sjmallett int v0; \ 143218383Sjmallett __asm __volatile ("dmfc0 %[v0], $"__XSTRING(r)", "__XSTRING(s)";" \ 144218383Sjmallett : [v0] "=&r"(v0)); \ 145218383Sjmallett mips_barrier(); \ 146218383Sjmallett return (v0); \ 147218383Sjmallett} \ 148218383Sjmallettstatic __inline void \ 149218383Sjmallettmips_wr_ ## n(uint64_t a0) \ 150218383Sjmallett{ \ 151218383Sjmallett __asm __volatile ("dmtc0 %[a0], $"__XSTRING(r)", "__XSTRING(s)";" \ 152218383Sjmallett __XSTRING(COP0_SYNC)";" \ 153218383Sjmallett : \ 154218383Sjmallett : [a0] "r"(a0)); \ 155218383Sjmallett mips_barrier(); \ 156218383Sjmallett} struct __hack 157218383Sjmallett 158206713Sjmallett#if defined(__mips_n64) 159216972SjmallettMIPS_RW64_COP0(excpc, MIPS_COP_0_EXC_PC); 160216972SjmallettMIPS_RW64_COP0(entryhi, MIPS_COP_0_TLB_HI); 161216972SjmallettMIPS_RW64_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); 162218383Sjmallett#ifdef CPU_CNMIPS 163218383SjmallettMIPS_RW64_COP0_SEL(cvmcount, MIPS_COP_0_COUNT, 6); 164218383SjmallettMIPS_RW64_COP0_SEL(cvmctl, MIPS_COP_0_COUNT, 7); 165218383SjmallettMIPS_RW64_COP0_SEL(cvmmemctl, MIPS_COP_0_COMPARE, 7); 166218383SjmallettMIPS_RW64_COP0_SEL(icache_err, MIPS_COP_0_CACHE_ERR, 0); 167218383SjmallettMIPS_RW64_COP0_SEL(dcache_err, MIPS_COP_0_CACHE_ERR, 1); 168206713Sjmallett#endif 169218383Sjmallett#endif 170217354Sjchandra#if defined(__mips_n64) || defined(__mips_n32) /* PHYSADDR_64_BIT */ 171217354SjchandraMIPS_RW64_COP0(entrylo0, MIPS_COP_0_TLB_LO0); 172217354SjchandraMIPS_RW64_COP0(entrylo1, MIPS_COP_0_TLB_LO1); 173217354Sjchandra#endif 174216972SjmallettMIPS_RW64_COP0(xcontext, MIPS_COP_0_TLB_XCONTEXT); 175178172Simp 176216972Sjmallett#undef MIPS_RW64_COP0 177218383Sjmallett#undef MIPS_RW64_COP0_SEL 178178172Simp#endif 179178172Simp 180216972Sjmallett#define MIPS_RW32_COP0(n,r) \ 181178172Simpstatic __inline uint32_t \ 182178172Simpmips_rd_ ## n (void) \ 183178172Simp{ \ 184178172Simp int v0; \ 185178172Simp __asm __volatile ("mfc0 %[v0], $"__XSTRING(r)";" \ 186178172Simp : [v0] "=&r"(v0)); \ 187178172Simp mips_barrier(); \ 188178172Simp return (v0); \ 189178172Simp} \ 190178172Simpstatic __inline void \ 191178172Simpmips_wr_ ## n (uint32_t a0) \ 192178172Simp{ \ 193178172Simp __asm __volatile ("mtc0 %[a0], $"__XSTRING(r)";" \ 194178172Simp __XSTRING(COP0_SYNC)";" \ 195178172Simp "nop;" \ 196178172Simp "nop;" \ 197178172Simp : \ 198178172Simp : [a0] "r"(a0)); \ 199178172Simp mips_barrier(); \ 200178172Simp} struct __hack 201178172Simp 202216972Sjmallett#define MIPS_RW32_COP0_SEL(n,r,s) \ 203202031Simpstatic __inline uint32_t \ 204206829Sjmallettmips_rd_ ## n(void) \ 205202031Simp{ \ 206202031Simp int v0; \ 207202031Simp __asm __volatile ("mfc0 %[v0], $"__XSTRING(r)", "__XSTRING(s)";" \ 208202031Simp : [v0] "=&r"(v0)); \ 209202031Simp mips_barrier(); \ 210202031Simp return (v0); \ 211202031Simp} \ 212202031Simpstatic __inline void \ 213206829Sjmallettmips_wr_ ## n(uint32_t a0) \ 214202031Simp{ \ 215202031Simp __asm __volatile ("mtc0 %[a0], $"__XSTRING(r)", "__XSTRING(s)";" \ 216202031Simp __XSTRING(COP0_SYNC)";" \ 217202031Simp "nop;" \ 218202031Simp "nop;" \ 219202031Simp : \ 220202031Simp : [a0] "r"(a0)); \ 221202031Simp mips_barrier(); \ 222202031Simp} struct __hack 223202031Simp 224210311Sjmallett#ifdef CPU_CNMIPS 225178172Simpstatic __inline void mips_sync_icache (void) 226178172Simp{ 227202031Simp __asm __volatile ( 228202031Simp ".set push\n" 229202031Simp ".set mips64\n" 230202031Simp ".word 0x041f0000\n" /* xxx ICACHE */ 231202031Simp "nop\n" 232202031Simp ".set pop\n" 233202031Simp : : ); 234178172Simp} 235178172Simp#endif 236178172Simp 237216972SjmallettMIPS_RW32_COP0(compare, MIPS_COP_0_COMPARE); 238216972SjmallettMIPS_RW32_COP0(config, MIPS_COP_0_CONFIG); 239216972SjmallettMIPS_RW32_COP0_SEL(config1, MIPS_COP_0_CONFIG, 1); 240216972SjmallettMIPS_RW32_COP0_SEL(config2, MIPS_COP_0_CONFIG, 2); 241216972SjmallettMIPS_RW32_COP0_SEL(config3, MIPS_COP_0_CONFIG, 3); 242218383Sjmallett#ifdef CPU_CNMIPS 243218383SjmallettMIPS_RW32_COP0_SEL(config4, MIPS_COP_0_CONFIG, 4); 244218383Sjmallett#endif 245257528Sbrooks#ifdef BERI_LARGE_TLB 246257528SbrooksMIPS_RW32_COP0_SEL(config5, MIPS_COP_0_CONFIG, 5); 247257528Sbrooks#endif 248257528Sbrooks#if defined(CPU_NLM) || defined(BERI_LARGE_TLB) 249257528SbrooksMIPS_RW32_COP0_SEL(config6, MIPS_COP_0_CONFIG, 6); 250257528Sbrooks#endif 251224115Sjchandra#ifdef CPU_NLM 252224115SjchandraMIPS_RW32_COP0_SEL(config7, MIPS_COP_0_CONFIG, 7); 253224115Sjchandra#endif 254216972SjmallettMIPS_RW32_COP0(count, MIPS_COP_0_COUNT); 255216972SjmallettMIPS_RW32_COP0(index, MIPS_COP_0_TLB_INDEX); 256216972SjmallettMIPS_RW32_COP0(wired, MIPS_COP_0_TLB_WIRED); 257216972SjmallettMIPS_RW32_COP0(cause, MIPS_COP_0_CAUSE); 258216947Sjmallett#if !defined(__mips_n64) 259216972SjmallettMIPS_RW32_COP0(excpc, MIPS_COP_0_EXC_PC); 260216947Sjmallett#endif 261216972SjmallettMIPS_RW32_COP0(status, MIPS_COP_0_STATUS); 262178172Simp 263178172Simp/* XXX: Some of these registers are specific to MIPS32. */ 264206713Sjmallett#if !defined(__mips_n64) 265216972SjmallettMIPS_RW32_COP0(entryhi, MIPS_COP_0_TLB_HI); 266216972SjmallettMIPS_RW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); 267206713Sjmallett#endif 268227782Sjchandra#ifdef CPU_NLM 269227782SjchandraMIPS_RW32_COP0_SEL(pagegrain, MIPS_COP_0_TLB_PG_MASK, 1); 270227782Sjchandra#endif 271217354Sjchandra#if !defined(__mips_n64) && !defined(__mips_n32) /* !PHYSADDR_64_BIT */ 272217354SjchandraMIPS_RW32_COP0(entrylo0, MIPS_COP_0_TLB_LO0); 273217354SjchandraMIPS_RW32_COP0(entrylo1, MIPS_COP_0_TLB_LO1); 274217354Sjchandra#endif 275216972SjmallettMIPS_RW32_COP0(prid, MIPS_COP_0_PRID); 276206713Sjmallett/* XXX 64-bit? */ 277216972SjmallettMIPS_RW32_COP0_SEL(ebase, MIPS_COP_0_PRID, 1); 278216972SjmallettMIPS_RW32_COP0(watchlo, MIPS_COP_0_WATCH_LO); 279216972SjmallettMIPS_RW32_COP0_SEL(watchlo1, MIPS_COP_0_WATCH_LO, 1); 280216972SjmallettMIPS_RW32_COP0_SEL(watchlo2, MIPS_COP_0_WATCH_LO, 2); 281216972SjmallettMIPS_RW32_COP0_SEL(watchlo3, MIPS_COP_0_WATCH_LO, 3); 282216972SjmallettMIPS_RW32_COP0(watchhi, MIPS_COP_0_WATCH_HI); 283216972SjmallettMIPS_RW32_COP0_SEL(watchhi1, MIPS_COP_0_WATCH_HI, 1); 284216972SjmallettMIPS_RW32_COP0_SEL(watchhi2, MIPS_COP_0_WATCH_HI, 2); 285216972SjmallettMIPS_RW32_COP0_SEL(watchhi3, MIPS_COP_0_WATCH_HI, 3); 286204635Sgnn 287216972SjmallettMIPS_RW32_COP0_SEL(perfcnt0, MIPS_COP_0_PERFCNT, 0); 288216972SjmallettMIPS_RW32_COP0_SEL(perfcnt1, MIPS_COP_0_PERFCNT, 1); 289216972SjmallettMIPS_RW32_COP0_SEL(perfcnt2, MIPS_COP_0_PERFCNT, 2); 290216972SjmallettMIPS_RW32_COP0_SEL(perfcnt3, MIPS_COP_0_PERFCNT, 3); 291204635Sgnn 292216972Sjmallett#undef MIPS_RW32_COP0 293216972Sjmallett#undef MIPS_RW32_COP0_SEL 294178172Simp 295178172Simpstatic __inline register_t 296178172Simpintr_disable(void) 297178172Simp{ 298178172Simp register_t s; 299178172Simp 300178172Simp s = mips_rd_status(); 301178172Simp mips_wr_status(s & ~MIPS_SR_INT_IE); 302178172Simp 303206713Sjmallett return (s & MIPS_SR_INT_IE); 304178172Simp} 305178172Simp 306178172Simpstatic __inline register_t 307178172Simpintr_enable(void) 308178172Simp{ 309178172Simp register_t s; 310178172Simp 311178172Simp s = mips_rd_status(); 312178172Simp mips_wr_status(s | MIPS_SR_INT_IE); 313178172Simp 314178172Simp return (s); 315178172Simp} 316178172Simp 317206713Sjmallettstatic __inline void 318206713Sjmallettintr_restore(register_t ie) 319206713Sjmallett{ 320206713Sjmallett if (ie == MIPS_SR_INT_IE) { 321206713Sjmallett intr_enable(); 322206713Sjmallett } 323206713Sjmallett} 324178172Simp 325212532Sjchandrastatic __inline uint32_t 326212532Sjchandraset_intr_mask(uint32_t mask) 327212532Sjchandra{ 328212532Sjchandra uint32_t ostatus; 329212532Sjchandra 330212532Sjchandra ostatus = mips_rd_status(); 331212632Sneel mask = (ostatus & ~MIPS_SR_INT_MASK) | (mask & MIPS_SR_INT_MASK); 332212532Sjchandra mips_wr_status(mask); 333212532Sjchandra return (ostatus); 334212532Sjchandra} 335212532Sjchandra 336212532Sjchandrastatic __inline uint32_t 337212532Sjchandraget_intr_mask(void) 338212532Sjchandra{ 339212532Sjchandra 340212532Sjchandra return (mips_rd_status() & MIPS_SR_INT_MASK); 341212532Sjchandra} 342212532Sjchandra 343178172Simpstatic __inline void 344178172Simpbreakpoint(void) 345178172Simp{ 346178172Simp __asm __volatile ("break"); 347178172Simp} 348178172Simp 349205675Sneel#if defined(__GNUC__) && !defined(__mips_o32) 350232872Sjmallett#define mips3_ld(a) (*(const volatile uint64_t *)(a)) 351232872Sjmallett#define mips3_sd(a, v) (*(volatile uint64_t *)(a) = (v)) 352205675Sneel#else 353205675Sneeluint64_t mips3_ld(volatile uint64_t *va); 354205675Sneelvoid mips3_sd(volatile uint64_t *, uint64_t); 355205675Sneel#endif /* __GNUC__ */ 356205675Sneel 357178172Simp#endif /* _KERNEL */ 358178172Simp 359178172Simp#define readb(va) (*(volatile uint8_t *) (va)) 360178172Simp#define readw(va) (*(volatile uint16_t *) (va)) 361178172Simp#define readl(va) (*(volatile uint32_t *) (va)) 362249776Sbrooks#if defined(__GNUC__) && !defined(__mips_o32) 363249776Sbrooks#define readq(a) (*(volatile uint64_t *)(a)) 364249776Sbrooks#endif 365178172Simp 366178172Simp#define writeb(va, d) (*(volatile uint8_t *) (va) = (d)) 367178172Simp#define writew(va, d) (*(volatile uint16_t *) (va) = (d)) 368178172Simp#define writel(va, d) (*(volatile uint32_t *) (va) = (d)) 369249776Sbrooks#if defined(__GNUC__) && !defined(__mips_o32) 370249776Sbrooks#define writeq(va, d) (*(volatile uint64_t *) (va) = (d)) 371249776Sbrooks#endif 372178172Simp 373178172Simp#endif /* !_MACHINE_CPUFUNC_H_ */ 374